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) { // 忽略广播失败 } } }