Chat.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <?php
  2. declare (strict_types = 1);
  3. namespace app\api\controller;
  4. use app\BaseController;
  5. use app\model\api\ChatRecord;
  6. use app\model\api\ChatUserRelation;
  7. use app\model\api\User;
  8. use app\Request;
  9. use app\services\chat\ChatBalanceService;
  10. /**
  11. * 聊天控制器
  12. */
  13. class Chat extends BaseController
  14. {
  15. /**
  16. * 获取会话列表
  17. */
  18. public function sessionList(Request $request)
  19. {
  20. $userId = $request->user['uid'];
  21. $sessions = ChatUserRelation::getUserSessions($userId);
  22. return app('json')->success('获取成功', [
  23. 'list' => $sessions,
  24. ]);
  25. }
  26. /**
  27. * 初始化会话(首次聊天扣次数)
  28. */
  29. public function initSession(Request $request)
  30. {
  31. $data = $request->post();
  32. $toUserId = (int)($data['to_user_id'] ?? 0);
  33. $userId = $request->user['uid'];
  34. if ($toUserId <= 0) {
  35. return app('json')->fail('对方用户ID错误');
  36. }
  37. if ($toUserId == $userId) {
  38. return app('json')->fail('不能和自己聊天');
  39. }
  40. // 检查对方用户是否存在
  41. $toUser = User::find($toUserId);
  42. if (!$toUser) {
  43. return app('json')->fail('用户不存在');
  44. }
  45. // 创建或获取会话关系
  46. $relation = ChatUserRelation::getOrCreate($userId, $toUserId);
  47. // 如果未扣过次数,则扣除
  48. if ($relation && $relation->is_deduct == ChatUserRelation::NOT_DEDUCT) {
  49. $result = ChatBalanceService::checkAndDeductFirstChat($userId, $toUserId);
  50. if (!$result['success']) {
  51. return app('json')->fail($result['message']);
  52. }
  53. }
  54. $balance = ChatBalanceService::getBalance($userId);
  55. return app('json')->success('会话创建成功', [
  56. 'to_user_id' => $toUserId,
  57. 'to_nickname' => $toUser->nickname ?? '',
  58. 'to_avatar' => $toUser->avatar ?? '',
  59. 'balance' => $balance,
  60. ]);
  61. }
  62. /**
  63. * 发送消息
  64. */
  65. public function send(Request $request)
  66. {
  67. $data = $request->post();
  68. $toUserId = (int)($data['to_user_id'] ?? 0);
  69. $content = trim($data['content'] ?? '');
  70. $type = (int)($data['type'] ?? ChatRecord::TYPE_TEXT);
  71. $formType = (int)($data['form_type'] ?? ChatRecord::FROM_PC);
  72. $userId = $request->user['uid'];
  73. // 验证 form_type 有效值
  74. if (!in_array($formType, [ChatRecord::FROM_PC, ChatRecord::FROM_WECHAT, ChatRecord::FROM_MINIAPP, ChatRecord::FROM_H5])) {
  75. $formType = ChatRecord::FROM_PC;
  76. }
  77. if ($toUserId <= 0) {
  78. return app('json')->fail('对方用户ID错误');
  79. }
  80. if (empty($content) && $type == ChatRecord::TYPE_TEXT) {
  81. return app('json')->fail('消息内容不能为空');
  82. }
  83. if ($toUserId == $userId) {
  84. return app('json')->fail('不能和自己聊天');
  85. }
  86. // 检查对方用户是否存在
  87. $toUser = User::find($toUserId);
  88. if (!$toUser) {
  89. return app('json')->fail('用户不存在');
  90. }
  91. // 检查会话关系是否存在,不存在则创建
  92. $relation = ChatUserRelation::getOrCreate($userId, $toUserId);
  93. // 如果未扣过次数,则扣除
  94. if ($relation && $relation->is_deduct == ChatUserRelation::NOT_DEDUCT) {
  95. $result = ChatBalanceService::checkAndDeductFirstChat($userId, $toUserId);
  96. if (!$result['success']) {
  97. return app('json')->fail($result['message']);
  98. }
  99. }
  100. // 保存聊天记录(包含来源类型)
  101. $record = ChatRecord::saveRecord($userId, $toUserId, $content, $type, $formType);
  102. // 更新会话关系时间
  103. ChatUserRelation::where('id', $relation->id)->update(['update_time' => time()]);
  104. return app('json')->success('发送成功', [
  105. 'record_id' => $record->id,
  106. 'create_time' => $record->create_time,
  107. ]);
  108. }
  109. /**
  110. * 获取聊天记录
  111. */
  112. public function recordList(Request $request)
  113. {
  114. $data = $request->get();
  115. $toUserId = (int)($data['to_user_id'] ?? 0);
  116. $page = (int)($data['page'] ?? 1);
  117. $limit = (int)($data['limit'] ?? 20);
  118. $userId = $request->user['uid'];
  119. if ($toUserId <= 0) {
  120. return app('json')->fail('对方用户ID错误');
  121. }
  122. $result = ChatRecord::getChatRecords($userId, $toUserId, $page, $limit);
  123. // 处理消息类型文本
  124. foreach ($result['list'] as &$item) {
  125. $item['type_text'] = ChatRecord::getTypeText($item['type']);
  126. $item['form_type_text'] = ChatRecord::getFormTypeText($item['form_type'] ?? 0);
  127. // 判断是否是自己发送的
  128. $item['is_mine'] = $item['user_id'] == $userId;
  129. }
  130. return app('json')->success('获取成功', $result);
  131. }
  132. /**
  133. * 标记消息已读
  134. */
  135. public function markRead(Request $request)
  136. {
  137. $data = $request->post();
  138. $fromUserId = (int)($data['from_user_id'] ?? 0);
  139. $userId = $request->user['uid'];
  140. if ($fromUserId <= 0) {
  141. return app('json')->fail('用户ID错误');
  142. }
  143. ChatRecord::markAsRead($userId, $fromUserId);
  144. return app('json')->success('标记成功');
  145. }
  146. /**
  147. * 获取未读消息数
  148. */
  149. public function unreadCount(Request $request)
  150. {
  151. $data = $request->get();
  152. $fromUserId = $data['from_user_id'] ?? null;
  153. $userId = $request->user['uid'];
  154. if ($fromUserId !== null) {
  155. $count = ChatRecord::getUnreadCount($userId, (int)$fromUserId);
  156. } else {
  157. $count = ChatRecord::getTotalUnreadCount($userId);
  158. }
  159. return app('json')->success('获取成功', [
  160. 'count' => $count,
  161. ]);
  162. }
  163. /**
  164. * 删除会话
  165. */
  166. public function deleteSession(Request $request)
  167. {
  168. $data = $request->post();
  169. $toUserId = (int)($data['to_user_id'] ?? 0);
  170. $userId = $request->user['uid'];
  171. if ($toUserId <= 0) {
  172. return app('json')->fail('对方用户ID错误');
  173. }
  174. $result = ChatUserRelation::deleteSession($userId, $toUserId);
  175. if ($result) {
  176. return app('json')->success('删除成功');
  177. }
  178. return app('json')->fail('删除失败');
  179. }
  180. /**
  181. * 获取用户信息
  182. */
  183. public function getUserInfo(Request $request)
  184. {
  185. $data = $request->get();
  186. $userId = (int)($data['user_id'] ?? 0);
  187. if ($userId <= 0) {
  188. return app('json')->fail('用户ID错误');
  189. }
  190. $user = User::find($userId);
  191. if (!$user) {
  192. return app('json')->fail('用户不存在');
  193. }
  194. return app('json')->success('获取成功', [
  195. 'user_id' => $user->id,
  196. 'nickname' => $user->nickname ?? '',
  197. 'avatar' => $user->avatar ?? '',
  198. ]);
  199. }
  200. }