ChatMessage.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. namespace App\Models;
  3. use Illuminate\Database\Eloquent\Factories\HasFactory;
  4. use Illuminate\Database\Eloquent\Model;
  5. use Illuminate\Support\Str;
  6. class ChatMessage extends Model
  7. {
  8. use HasFactory;
  9. protected $fillable = [
  10. 'uid',
  11. 'chat_id',
  12. 'parent_id',
  13. 'session_id',
  14. 'role',
  15. 'content',
  16. 'model_name',
  17. 'tool_calls',
  18. 'tool_call_id',
  19. 'is_active'
  20. ];
  21. protected $dates = [
  22. 'deleted_at'
  23. ];
  24. protected $casts = [
  25. 'id' => 'string',
  26. 'tool_calls' => 'array',
  27. 'is_active' => 'boolean',
  28. 'created_at' => 'datetime',
  29. 'updated_at' => 'datetime',
  30. 'deleted_at' => 'datetime',
  31. ];
  32. protected static function boot()
  33. {
  34. parent::boot();
  35. static::creating(function ($model) {
  36. if (empty($model->uid)) {
  37. $model->uid = (string) Str::uuid();
  38. }
  39. if (empty($model->session_id)) {
  40. $model->session_id = (string) Str::uuid();
  41. }
  42. });
  43. }
  44. /**
  45. * 关联聊天
  46. */
  47. public function chat()
  48. {
  49. return $this->belongsTo(Chat::class);
  50. }
  51. /**
  52. * 关联父消息
  53. */
  54. public function parent()
  55. {
  56. return $this->belongsTo(ChatMessage::class, 'parent_id', 'uid');
  57. }
  58. /**
  59. * 关联子消息
  60. */
  61. public function children()
  62. {
  63. return $this->hasMany(ChatMessage::class, 'parent_id', 'uid');
  64. }
  65. /**
  66. * 关联激活状态的子消息
  67. */
  68. public function activeChildren()
  69. {
  70. return $this->hasMany(ChatMessage::class, 'parent_id', 'uid')
  71. ->where('is_active', true);
  72. }
  73. /**
  74. * Scope: 只查询激活状态的消息
  75. */
  76. public function scopeActive($query)
  77. {
  78. return $query->where('is_active', true);
  79. }
  80. /**
  81. * Scope: 根据角色查询
  82. */
  83. public function scopeByRole($query, string $role)
  84. {
  85. return $query->where('role', $role);
  86. }
  87. /**
  88. * Scope: 根据会话ID查询
  89. */
  90. public function scopeBySession($query, string $sessionId)
  91. {
  92. return $query->where('session_id', $sessionId);
  93. }
  94. /**
  95. * Scope: 根据聊天ID查询
  96. */
  97. public function scopeByChat($query, string $chatId)
  98. {
  99. return $query->where('chat_id', $chatId);
  100. }
  101. /**
  102. * 获取消息路径(从根到当前消息)
  103. */
  104. public function getPath(): array
  105. {
  106. $path = [];
  107. $current = $this;
  108. while ($current) {
  109. array_unshift($path, $current);
  110. $current = $current->parent;
  111. }
  112. return $path;
  113. }
  114. /**
  115. * 获取消息树的所有叶子节点
  116. */
  117. public function getLeaves(): \Illuminate\Database\Eloquent\Collection
  118. {
  119. return ChatMessage::where('chat_id', $this->chat_id)
  120. ->whereNotNull('parent_id')
  121. ->whereDoesntHave('children')
  122. ->get();
  123. }
  124. /**
  125. * 获取Token使用情况
  126. */
  127. public function getTokenUsage(): ?array
  128. {
  129. return $this->metadata['token_usage'] ?? null;
  130. }
  131. /**
  132. * 获取生成参数
  133. */
  134. public function getGenerationParams(): ?array
  135. {
  136. return $this->metadata['generation_params'] ?? null;
  137. }
  138. /**
  139. * 设置Token使用情况
  140. */
  141. public function setTokenUsage(array $tokenUsage): void
  142. {
  143. $metadata = $this->metadata ?? [];
  144. $metadata['token_usage'] = $tokenUsage;
  145. $this->update(['metadata' => $metadata]);
  146. }
  147. /**
  148. * 设置生成参数
  149. */
  150. public function setGenerationParams(array $params): void
  151. {
  152. $metadata = $this->metadata ?? [];
  153. $metadata['generation_params'] = $params;
  154. $this->update(['metadata' => $metadata]);
  155. }
  156. public function siblings()
  157. {
  158. return $this->where('parent_id', $this->parent_id)
  159. ->where('role', $this->role)
  160. ->where('id', '!=', $this->id);
  161. }
  162. public function getRouteKeyName()
  163. {
  164. return 'uid';
  165. }
  166. }