ChatRecord.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <?php
  2. declare (strict_types = 1);
  3. namespace app\model\api;
  4. use library\basic\BaseModel;
  5. use library\traits\ModelTrait;
  6. use think\facade\Db;
  7. use think\Model;
  8. /**
  9. * 聊天记录模型
  10. * @mixin \think\Model
  11. */
  12. class ChatRecord extends BaseModel
  13. {
  14. use ModelTrait;
  15. protected $name = 'chat_record';
  16. // 消息类型
  17. const TYPE_TEXT = 1; // 文字
  18. const TYPE_VOICE = 2; // 语音
  19. const TYPE_IMAGE = 3; // 图片
  20. // 未读
  21. const UNREAD = 0;
  22. // 已读
  23. const READ = 1;
  24. // 来源类型
  25. const FROM_PC = 0; // PC端
  26. const FROM_WECHAT = 1; // 微信
  27. const FROM_MINIAPP = 2; // 小程序
  28. const FROM_H5 = 3; // H5
  29. /**
  30. * 保存聊天记录
  31. * @param int $userId 发送者ID
  32. * @param int $toUserId 接收者ID
  33. * @param string $content 消息内容
  34. * @param int $type 消息类型
  35. * @param int $formType 来源类型 0=PC, 1=微信, 2=小程序, 3=H5
  36. * @return self
  37. */
  38. public static function saveRecord(int $userId, int $toUserId, string $content, int $type = self::TYPE_TEXT, int $formType = self::FROM_PC): self
  39. {
  40. return self::create([
  41. 'user_id' => $userId,
  42. 'to_user_id' => $toUserId,
  43. 'content' => $content,
  44. 'type' => $type,
  45. 'form_type' => $formType,
  46. 'is_read' => self::UNREAD,
  47. 'create_time' => time(),
  48. ]);
  49. }
  50. /**
  51. * 获取与某用户的聊天记录
  52. * @param int $userId 当前用户ID
  53. * @param int $toUserId 对方用户ID
  54. * @param int $page 页码
  55. * @param int $limit 每页数量
  56. * @return array
  57. */
  58. public static function getChatRecords(int $userId, int $toUserId, int $page = 1, int $limit = 20): array
  59. {
  60. $where = function ($query) use ($userId, $toUserId) {
  61. $query->where(function ($q) use ($userId, $toUserId) {
  62. $q->where('user_id', $userId)->where('to_user_id', $toUserId);
  63. })->whereOr(function ($q) use ($userId, $toUserId) {
  64. $q->where('user_id', $toUserId)->where('to_user_id', $userId);
  65. });
  66. };
  67. $data = self::where($where)
  68. ->order('create_time desc')
  69. ->page($page, $limit)
  70. ->select();
  71. $total = self::where($where)->count();
  72. // 标记为已读
  73. self::markAsRead($userId, $toUserId);
  74. return [
  75. 'list' => $data ? array_reverse($data->toArray()) : [],
  76. 'total' => $total,
  77. 'page' => $page,
  78. 'limit' => $limit,
  79. ];
  80. }
  81. /**
  82. * 标记消息为已读
  83. * @param int $userId 当前用户ID
  84. * @param int $fromUserId 发送者ID
  85. * @return bool
  86. */
  87. public static function markAsRead(int $userId, int $fromUserId): bool
  88. {
  89. $affected = Db::name('chat_record')
  90. ->where('user_id', $fromUserId)
  91. ->where('to_user_id', $userId)
  92. ->where('is_read', 0)
  93. ->update(['is_read' => 1]);
  94. @file_put_contents('quanju.txt', $affected."-何意啊333\r\n", 8);
  95. // 调试:记录执行的SQL和影响行数
  96. // $sql = Db::name('chat_record')->getLastSql();
  97. // trace('【markAsRead】SQL: ' . $sql . ' | 影响行数: ' . $affected, 'chat_debug');
  98. //
  99. return $affected > 0;
  100. }
  101. /**
  102. * 获取未读消息数
  103. * @param int $userId 用户ID
  104. * @param int|null $fromUserId 指定发送者(可选)
  105. * @return int
  106. */
  107. public static function getUnreadCount(int $userId, ?int $fromUserId = null): int
  108. {
  109. $query = Db::name('chat_record')
  110. ->where('to_user_id', $userId)
  111. ->where('is_read', 0);
  112. if ($fromUserId !== null && $fromUserId > 0) {
  113. $query->where('user_id', $fromUserId);
  114. }
  115. $count = $query->count();
  116. // // 调试:记录执行的SQL和结果
  117. // $sql = Db::name('chat_record')->getLastSql();
  118. // trace('【getUnreadCount】SQL: ' . $sql . ' | 结果: ' . $count, 'chat_debug');
  119. //
  120. return $count;
  121. }
  122. /**
  123. * 获取所有未读消息数
  124. * @param int $userId 用户ID
  125. * @return int
  126. */
  127. public static function getTotalUnreadCount(int $userId): int
  128. {
  129. $count = Db::name('chat_record')
  130. ->where('to_user_id', $userId)
  131. ->where('is_read', 0)
  132. ->count();
  133. // // 调试:记录执行的SQL和结果
  134. // $sql = Db::name('chat_record')->getLastSql();
  135. // trace('【getTotalUnreadCount】SQL: ' . $sql . ' | 结果: ' . $count, 'chat_debug');
  136. //
  137. return $count;
  138. }
  139. /**
  140. * 获取消息类型文本
  141. * @param int $type 类型
  142. * @return string
  143. */
  144. public static function getTypeText(int $type): string
  145. {
  146. $typeMap = [
  147. self::TYPE_TEXT => '文字',
  148. self::TYPE_VOICE => '语音',
  149. self::TYPE_IMAGE => '图片',
  150. ];
  151. return $typeMap[$type] ?? '未知';
  152. }
  153. /**
  154. * 获取来源类型文本
  155. * @param int $formType 来源类型
  156. * @return string
  157. */
  158. public static function getFormTypeText(int $formType): string
  159. {
  160. $formTypeMap = [
  161. self::FROM_PC => 'PC端',
  162. self::FROM_WECHAT => '微信',
  163. self::FROM_MINIAPP => '小程序',
  164. self::FROM_H5 => 'H5',
  165. ];
  166. return $formTypeMap[$formType] ?? '未知';
  167. }
  168. }