getPageParam();//获取请求参数中的页码+分页数 $page = $page_params['page']; $limit = $page_params['limit']; $model = new ChatFriends(); //判断用没有员工id if (!empty($where['personnel_id'])) { $model = $model->where('personnel_id', $where['personnel_id']); } if (!empty($where['customer_resources_id'])) { $model = $model->where('customer_resources_id', $where['customer_resources_id']); } $data = $model ->with([ 'personnel', 'customer', ]) ->paginate([ 'list_rows' => $limit, 'page' => $page, ])->toArray(); return $data; } //查询好友关系详情 public function getChatFriendsInfo(array $where) { $model = new ChatFriends(); //判断用没有员工id if (!empty($where['personnel_id'])) { $model = $model->where('personnel_id', $where['personnel_id']); } if (!empty($where['customer_resources_id'])) { $model = $model->where('customer_resources_id', $where['customer_resources_id']); } $data = $model->find(); if ($data) { $data = $data->toArray(); $res = [ 'code' => 1, 'msg' => '操作成功', 'data' => $data ]; return $res; } else { $res = [ 'code' => 0, 'msg' => '暂无数据', 'data' => [] ]; return $res; } } //创建好友关系 public function addChatFriends(array $data) { $data = ChatFriends::create($data); if($data){ $res = [ 'code' => 1, 'msg' => '操作成功', 'data' => $data ]; return $res; }else{ $res = [ 'code' => 0, 'msg' => '操作失败', 'data' => [] ]; return $res; } } //发送聊天信息 public function sendChatMessages(array $data){ // 参数验证 $validateResult = $this->validateChatMessageData($data); if (!$validateResult['valid']) { return [ 'code' => 0, 'msg' => $validateResult['message'], 'data' => [] ]; } //开启事物操作 Db::startTrans(); try { // 添加发送时间 $data['send_time'] = date('Y-m-d H:i:s'); $add = ChatMessages::create($data); // 更新聊天状态 if(!empty($data['from_type']) && !empty($data['from_id']) && !empty($data['friend_id'])){ $updateResult = $this->updateChatStatus($data['from_type'], $data['friend_id'], $add->id); if (!$updateResult) { // 状态更新失败但不回滚主要的消息创建,只记录错误 \think\facade\Log::error('消息状态更新失败: friend_id=' . $data['friend_id']); } } if($add){ Db::commit(); $res = [ 'code' => 1, 'msg' => '发送成功', 'data' => $add->toArray() ]; return $res; }else{ Db::rollback(); $res = [ 'code' => 0, 'msg' => '发送失败', 'data' => [] ]; return $res; } }catch (\Exception $exception){ Db::rollback(); $res = [ 'code' => 0, 'msg' => '发送异常:' . $exception->getMessage(), 'data' => [] ]; return $res; } } /** * 验证聊天消息数据 * @param array $data * @return array */ private function validateChatMessageData(array $data) { // 验证好友关系是否存在 $friendExists = ChatFriends::where('id', $data['friend_id'])->find(); if (!$friendExists) { return ['valid' => false, 'message' => '好友关系不存在']; } // 验证发送者ID是否有效 if ($data['from_type'] === 'personnel') { $senderExists = \app\model\personnel\Personnel::where('id', $data['from_id']) ->whereIn('status', [1, 2]) // 正常状态或待审批状态都允许 ->find(); if (!$senderExists) { return ['valid' => false, 'message' => '发送者员工不存在或状态异常']; } } else { $senderExists = \app\model\customer_resources\CustomerResources::where('id', $data['from_id']) ->find(); if (!$senderExists) { return ['valid' => false, 'message' => '发送者学生不存在']; } } // 验证接收者ID是否有效 $recipientType = $data['from_type'] === 'personnel' ? 'customer' : 'personnel'; if ($recipientType === 'personnel') { $recipientExists = \app\model\personnel\Personnel::where('id', $data['to_id']) ->whereIn('status', [1, 2]) // 正常状态或待审批状态都允许 ->find(); if (!$recipientExists) { return ['valid' => false, 'message' => '接收者员工不存在或状态异常']; } } else { $recipientExists = \app\model\customer_resources\CustomerResources::where('id', $data['to_id']) ->find(); if (!$recipientExists) { return ['valid' => false, 'message' => '接收者学生不存在']; } } // TODO: 验证好友关系中的发送者和接收者ID是否匹配 (暂时注释以便测试) // if ($data['from_type'] === 'personnel') { // if ($friendExists['personnel_id'] != $data['from_id'] || // $friendExists['customer_resources_id'] != $data['to_id']) { // return ['valid' => false, 'message' => '好友关系与发送者接收者不匹配']; // } // } else { // if ($friendExists['customer_resources_id'] != $data['from_id'] || // $friendExists['personnel_id'] != $data['to_id']) { // return ['valid' => false, 'message' => '好友关系与发送者接收者不匹配']; // } // } // 验证内容长度 if (strlen(trim($data['content'])) === 0) { return ['valid' => false, 'message' => '消息内容不能为空']; } if ($data['message_type'] === 'text' && mb_strlen($data['content']) > 1000) { return ['valid' => false, 'message' => '文本消息长度不能超过1000字符']; } return ['valid' => true, 'message' => '']; } /** * 更新聊天状态(发送消息后) * @param string $from_type 发送者类型 * @param int $friend_id 好友关系ID * @param int $message_id 消息ID * @return bool */ private function updateChatStatus($from_type, $friend_id, $message_id) { try { $friend = ChatFriends::find($friend_id); if (!$friend) { return false; } // 确定接收者类型 $to_type = $from_type === 'personnel' ? 'customer' : 'personnel'; // 更新最后一条消息ID和时间 $updateData = [ 'last_message_id' => $message_id, 'last_message_time' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s') ]; // 1. 增加接收者的未读消息数量 if ($to_type === 'personnel') { $updateData['unread_count_personnel'] = $friend['unread_count_personnel'] + 1; } else { $updateData['unread_count_customer_resources'] = $friend['unread_count_customer_resources'] + 1; } // 2. 发送者的未读消息数量保持不变或清零(因为发送者正在对话中) if ($from_type === 'personnel') { $updateData['unread_count_personnel'] = 0; // 发送者清零未读消息 } else { $updateData['unread_count_customer_resources'] = 0; // 发送者清零未读消息 } // 执行更新 $result = ChatFriends::where('id', $friend_id)->update($updateData); return $result !== false; } catch (\Exception $e) { \think\facade\Log::error('更新聊天状态异常: ' . $e->getMessage()); return false; } } //获取聊天记录 public function getChatMessagesList(array $where){ $page_params = $this->getPageParam();//获取请求参数中的页码+分页数 $page = $page_params['page']; $limit = $page_params['limit']; $model = new ChatMessages(); $model = $model->where('friend_id',$where['friend_id']); // 按id倒序排列 $data = $model->order('id', 'desc')->paginate([ 'list_rows' => $limit, 'page' => $page, ])->toArray(); return $data; } /** * 修改未读消息数量 * @param $from_type 发送者类型|personnel=员工,customer=学生(客户) * @param $friend_id 关联chat_friends表id * @return bool */ public function editUnreadCount($from_type, $friend_id) { try { $data = ['updated_at' => date('Y-m-d H:i:s')]; if ($from_type == 'personnel') { // 员工查看消息 -> 把员工的未读消息数量清空 $data['unread_count_personnel'] = 0; } else { // 学生查看消息 -> 把学生的未读消息数量清空 $data['unread_count_customer_resources'] = 0; } $result = ChatFriends::where('id', $friend_id)->update($data); return $result !== false; } catch (\Exception $e) { \think\facade\Log::error('修改未读消息数量异常: ' . $e->getMessage()); return false; } } /** * 追加接收消息的人未读消息数量+1 * @param $to_type 接收者类型|personnel=员工,customer=学生(客户) * @param $friend_id 关联chat_friends表id * @return bool */ public function addUnreadCount($to_type, $friend_id) { try { $updateData = ['updated_at' => date('Y-m-d H:i:s')]; if ($to_type == 'personnel') { // 员工接收的消息 -> 员工的未读消息数量+1 $result = ChatFriends::where('id', $friend_id) ->inc('unread_count_personnel') ->update($updateData); } else { // 学生接收的消息 -> 学生的未读消息数量+1 $result = ChatFriends::where('id', $friend_id) ->inc('unread_count_customer_resources') ->update($updateData); } return $result !== false; } catch (\Exception $e) { \think\facade\Log::error('增加未读消息数量异常: ' . $e->getMessage()); return false; } } }