2
0

Chat.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <?php
  2. namespace App\Models;
  3. use Illuminate\Database\Eloquent\Factories\HasFactory;
  4. use Illuminate\Database\Eloquent\SoftDeletes; // ← 加这行
  5. use Illuminate\Database\Eloquent\Model;
  6. use Illuminate\Support\Str;
  7. class Chat extends Model
  8. {
  9. use HasFactory, SoftDeletes;
  10. protected $fillable = [
  11. 'uid',
  12. 'title',
  13. 'user_id'
  14. ];
  15. protected $casts = [
  16. 'id' => 'string',
  17. 'uid' => 'string',
  18. 'created_at' => 'datetime',
  19. 'updated_at' => 'datetime',
  20. 'deleted_at' => 'datetime',
  21. ];
  22. protected $primaryKey = 'uid';
  23. protected static function boot()
  24. {
  25. parent::boot();
  26. static::creating(function ($model) {
  27. if (empty($model->uid)) {
  28. $model->uid = (string) Str::uuid();
  29. }
  30. });
  31. // 级联软删除:删除Chat时同时软删除所有相关消息
  32. static::deleting(function ($chat) {
  33. if ($chat->isForceDeleting()) {
  34. // 强制删除时,物理删除所有消息
  35. $chat->messages()->forceDelete();
  36. } else {
  37. // 软删除时,级联软删除所有消息
  38. $chat->messages()->delete();
  39. }
  40. });
  41. // 恢复Chat时同时恢复所有相关消息
  42. static::restoring(function ($chat) {
  43. $chat->messages()->withTrashed()->restore();
  44. });
  45. }
  46. // 使用 uid 作为路由键
  47. public function messages()
  48. {
  49. return $this->hasMany(ChatMessage::class);
  50. }
  51. public function getRouteKeyName()
  52. {
  53. return 'uid';
  54. }
  55. /**
  56. * 获取根消息(没有parent_id的消息)
  57. */
  58. public function rootMessages()
  59. {
  60. return $this->hasMany(ChatMessage::class, 'chat_id', 'uid')
  61. ->whereNull('parent_id')
  62. ->where('is_active', true);
  63. }
  64. /**
  65. * 获取token使用统计
  66. */
  67. public function getTokenStats()
  68. {
  69. return $this->messages()
  70. ->where('role', 'assistant')
  71. ->whereNotNull('metadata')
  72. ->selectRaw('
  73. SUM(JSON_EXTRACT(metadata, "$.token_usage.total_tokens")) as total_tokens,
  74. SUM(JSON_EXTRACT(metadata, "$.token_usage.prompt_tokens")) as prompt_tokens,
  75. SUM(JSON_EXTRACT(metadata, "$.token_usage.completion_tokens")) as completion_tokens,
  76. AVG(JSON_EXTRACT(metadata, "$.performance.response_time_ms")) as avg_response_time
  77. ')
  78. ->first();
  79. }
  80. /**
  81. * 批量软删除多个聊天
  82. */
  83. public static function batchSoftDelete(array $chatIds): int
  84. {
  85. return static::whereIn('uid', $chatIds)->delete();
  86. }
  87. /**
  88. * 批量恢复多个聊天
  89. */
  90. public static function batchRestore(array $chatIds): int
  91. {
  92. return static::withTrashed()->whereIn('uid', $chatIds)->restore();
  93. }
  94. }