Chat.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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. * page=1 为最新的一批消息,页码递增则获取更早的消息
  112. */
  113. public function recordList(Request $request)
  114. {
  115. $data = $request->get();
  116. $toUserId = (int)($data['to_user_id'] ?? 0);
  117. $page = (int)($data['page'] ?? 1);
  118. $limit = (int)($data['limit'] ?? 20);
  119. $userId = $request->user['uid'];
  120. if ($toUserId <= 0) {
  121. return app('json')->fail('对方用户ID错误');
  122. }
  123. if ($page < 1) $page = 1;
  124. if ($limit < 1) $limit = 20;
  125. if ($limit > 100) $limit = 100;
  126. $result = ChatRecord::getChatRecords($userId, $toUserId, $page, $limit);
  127. // 处理附加字段
  128. foreach ($result['list'] as &$item) {
  129. $item['type_text'] = ChatRecord::getTypeText($item['type']);
  130. $item['form_type_text'] = ChatRecord::getFormTypeText($item['form_type'] ?? 0);
  131. $item['is_mine'] = $item['user_id'] == $userId;
  132. }
  133. unset($item);
  134. return app('json')->success('获取成功', $result);
  135. }
  136. /**
  137. * 标记消息已读
  138. */
  139. public function markRead(Request $request)
  140. {
  141. $data = $request->post();
  142. $fromUserId = (int)($data['from_user_id'] ?? 0);
  143. $userId = $request->user['uid'];
  144. if ($fromUserId <= 0) {
  145. return app('json')->fail('用户ID错误');
  146. }
  147. // @file_put_contents('quanju.txt', $userId."-何意啊111\r\n", 8);
  148. // @file_put_contents('quanju.txt', $fromUserId."-何意啊222\r\n", 8);
  149. ChatRecord::markAsRead($userId, $fromUserId);
  150. return app('json')->success('标记成功');
  151. }
  152. /**
  153. * 获取未读消息数
  154. */
  155. public function unreadCount(Request $request)
  156. {
  157. $data = $request->get();
  158. $fromUserId = $data['from_user_id'] ?? null;
  159. $userId = $request->user['uid'];
  160. // @file_put_contents('quanju.txt', $userId."-何意啊111444\r\n", 8);
  161. // @file_put_contents('quanju.txt', $fromUserId."-何意啊222555\r\n", 8);
  162. // 处理空字符串等无效值
  163. if ($fromUserId !== null && $fromUserId !== '' && (int)$fromUserId > 0) {
  164. $count = ChatRecord::getUnreadCount($userId, (int)$fromUserId);
  165. } else {
  166. $count = ChatRecord::getTotalUnreadCount($userId);
  167. }
  168. return app('json')->success('获取成功', [
  169. 'count' => $count,
  170. ]);
  171. }
  172. /**
  173. * 删除会话
  174. */
  175. public function deleteSession(Request $request)
  176. {
  177. $data = $request->post();
  178. $toUserId = (int)($data['to_user_id'] ?? 0);
  179. $userId = $request->user['uid'];
  180. if ($toUserId <= 0) {
  181. return app('json')->fail('对方用户ID错误');
  182. }
  183. $result = ChatUserRelation::deleteSession($userId, $toUserId);
  184. if ($result) {
  185. return app('json')->success('删除成功');
  186. }
  187. return app('json')->fail('删除失败');
  188. }
  189. /**
  190. * 获取用户信息
  191. */
  192. public function getUserInfo(Request $request)
  193. {
  194. $data = $request->get();
  195. $userId = (int)($data['user_id'] ?? 0);
  196. if ($userId <= 0) {
  197. return app('json')->fail('用户ID错误');
  198. }
  199. $user = User::find($userId);
  200. if (!$user) {
  201. return app('json')->fail('用户不存在');
  202. }
  203. return app('json')->success('获取成功', [
  204. 'user_id' => $user->id,
  205. 'nickname' => $user->nickname ?? '',
  206. 'avatar' => $user->avatar ?? '',
  207. ]);
  208. }
  209. }