| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- <?php
- declare (strict_types = 1);
- namespace app\api\controller;
- use app\model\api\ChatRecord;
- use app\model\api\ChatUserRelation;
- use app\model\api\User;
- use app\services\chat\ChatBalanceService;
- use library\JwtAuth;
- use library\LoginSession;
- use think\Request;
- use think\Response;
- /**
- * 聊天控制器
- */
- class Chat extends JwtAuth
- {
- protected $noNeedLogin = ['recordList'];
-
- /**
- * 获取会话列表
- * @return Response
- */
- public function sessionList(): Response
- {
- $sessions = ChatUserRelation::getUserSessions($this->userId);
-
- return $this->success('获取成功', [
- 'list' => $sessions,
- ]);
- }
-
- /**
- * 初始化会话(首次聊天扣次数)
- * @return Response
- */
- public function initSession(): Response
- {
- $data = $this->request->post();
- $toUserId = (int)($data['to_user_id'] ?? 0);
-
- if ($toUserId <= 0) {
- return $this->fail('对方用户ID错误');
- }
-
- if ($toUserId == $this->userId) {
- return $this->fail('不能和自己聊天');
- }
-
- // 检查对方用户是否存在
- $toUser = User::find($toUserId);
- if (!$toUser) {
- return $this->fail('用户不存在');
- }
-
- // 创建或获取会话关系
- $relation = ChatUserRelation::getOrCreate($this->userId, $toUserId);
-
- // 如果未扣过次数,则扣除
- if ($relation && $relation->is_deduct == ChatUserRelation::NOT_DEDUCT) {
- $result = ChatBalanceService::checkAndDeductFirstChat($this->userId, $toUserId);
-
- if (!$result['success']) {
- return $this->fail($result['message']);
- }
- }
-
- $balance = ChatBalanceService::getBalance($this->userId);
-
- return $this->success('会话创建成功', [
- 'to_user_id' => $toUserId,
- 'to_nickname' => $toUser->nickname ?? '',
- 'to_avatar' => $toUser->avatar ?? '',
- 'balance' => $balance,
- ]);
- }
-
- /**
- * 发送消息
- * @return Response
- */
- public function send(): Response
- {
- $data = $this->request->post();
- $toUserId = (int)($data['to_user_id'] ?? 0);
- $content = trim($data['content'] ?? '');
- $type = (int)($data['type'] ?? ChatRecord::TYPE_TEXT);
- $formType = (int)($data['form_type'] ?? ChatRecord::FROM_PC);
-
- // 验证 form_type 有效值
- if (!in_array($formType, [ChatRecord::FROM_PC, ChatRecord::FROM_WECHAT, ChatRecord::FROM_MINIAPP, ChatRecord::FROM_H5])) {
- $formType = ChatRecord::FROM_PC;
- }
-
- if ($toUserId <= 0) {
- return $this->fail('对方用户ID错误');
- }
-
- if (empty($content) && $type == ChatRecord::TYPE_TEXT) {
- return $this->fail('消息内容不能为空');
- }
-
- if ($toUserId == $this->userId) {
- return $this->fail('不能和自己聊天');
- }
-
- // 检查对方用户是否存在
- $toUser = User::find($toUserId);
- if (!$toUser) {
- return $this->fail('用户不存在');
- }
-
- // 检查会话关系是否存在,不存在则创建
- $relation = ChatUserRelation::getOrCreate($this->userId, $toUserId);
-
- // 如果未扣过次数,则扣除
- if ($relation && $relation->is_deduct == ChatUserRelation::NOT_DEDUCT) {
- $result = ChatBalanceService::checkAndDeductFirstChat($this->userId, $toUserId);
-
- if (!$result['success']) {
- return $this->fail($result['message']);
- }
- }
-
- // 保存聊天记录(包含来源类型)
- $record = ChatRecord::saveRecord($this->userId, $toUserId, $content, $type, $formType);
-
- // 更新会话关系时间
- ChatUserRelation::where('id', $relation->id)->update(['update_time' => time()]);
-
- // 广播消息给在线用户
- self::broadcastMessage($toUserId, [
- 'type' => 'new_message',
- 'data' => [
- 'id' => $record->id,
- 'from_user_id' => $this->userId,
- 'to_user_id' => $toUserId,
- 'content' => $content,
- 'msg_type' => $type,
- 'form_type' => $formType,
- 'create_time' => $record->create_time,
- ],
- ]);
-
- return $this->success('发送成功', [
- 'record_id' => $record->id,
- 'create_time' => $record->create_time,
- ]);
- }
-
- /**
- * 获取聊天记录
- * @return Response
- */
- public function recordList(): Response
- {
- $data = $this->request->get();
- $toUserId = (int)($data['to_user_id'] ?? 0);
- $page = (int)($data['page'] ?? 1);
- $limit = (int)($data['limit'] ?? 20);
-
- if ($toUserId <= 0) {
- return $this->fail('对方用户ID错误');
- }
-
- $result = ChatRecord::getChatRecords($this->userId, $toUserId, $page, $limit);
-
- // 处理消息类型文本
- foreach ($result['list'] as &$item) {
- $item['type_text'] = ChatRecord::getTypeText($item['type']);
- $item['form_type_text'] = ChatRecord::getFormTypeText($item['form_type'] ?? 0);
- // 判断是否是自己发送的
- $item['is_mine'] = $item['user_id'] == $this->userId;
- }
-
- return $this->success('获取成功', $result);
- }
-
- /**
- * 标记消息已读
- * @return Response
- */
- public function markRead(): Response
- {
- $data = $this->request->post();
- $fromUserId = (int)($data['from_user_id'] ?? 0);
-
- if ($fromUserId <= 0) {
- return $this->fail('用户ID错误');
- }
-
- ChatRecord::markAsRead($this->userId, $fromUserId);
-
- return $this->success('标记成功');
- }
-
- /**
- * 获取未读消息数
- * @return Response
- */
- public function unreadCount(): Response
- {
- $data = $this->request->get();
- $fromUserId = $data['from_user_id'] ?? null;
-
- if ($fromUserId !== null) {
- $count = ChatRecord::getUnreadCount($this->userId, (int)$fromUserId);
- } else {
- $count = ChatRecord::getTotalUnreadCount($this->userId);
- }
-
- return $this->success('获取成功', [
- 'count' => $count,
- ]);
- }
-
- /**
- * 删除会话
- * @return Response
- */
- public function deleteSession(): Response
- {
- $data = $this->request->post();
- $toUserId = (int)($data['to_user_id'] ?? 0);
-
- if ($toUserId <= 0) {
- return $this->fail('对方用户ID错误');
- }
-
- $result = ChatUserRelation::deleteSession($this->userId, $toUserId);
-
- if ($result) {
- return $this->success('删除成功');
- }
-
- return $this->fail('删除失败');
- }
-
- /**
- * 获取用户信息
- * @return Response
- */
- public function getUserInfo(): Response
- {
- $data = $this->request->get();
- $userId = (int)($data['user_id'] ?? 0);
-
- if ($userId <= 0) {
- return $this->fail('用户ID错误');
- }
-
- $user = User::find($userId);
- if (!$user) {
- return $this->fail('用户不存在');
- }
-
- return $this->success('获取成功', [
- 'user_id' => $user->id,
- 'nickname' => $user->nickname ?? '',
- 'avatar' => $user->avatar ?? '',
- ]);
- }
-
- /**
- * 广播消息给指定用户
- * @param int $userId 用户ID
- * @param array $data 消息数据
- */
- protected static function broadcastMessage(int $userId, array $data): void
- {
- try {
- \Channel\Client::getInstance()->send('muyinjie_chat_' . $userId, $data);
- } catch (\Throwable $e) {
- // 忽略广播失败
- }
- }
- }
|