uid; $chatType = $request->post('chat_type'); // 1=单聊,2=群聊 $toId = $request->post('to_id'); // 单聊=对方ID,群聊=群ID $session_id = $request->post('session_id'); // 会话ID $group_id = $request->post('group_id'); // 会话ID $page = $request->post('page', 1)?:1; $size = $request->post('size', 20)?:20; if (!$toId || !$chatType || !$session_id || !$group_id) { return $this->error('参数不完整'); } $group = Db::name('chat_group')->where(['id' => $group_id])->find(); if (!$group) { return $this->error('群不存在'); } // 构建查询条件 $query = Db::name('chat_message')->where(['session_id' => $session_id]); $role = 2; // 群聊需验证是否在群内 if ($chatType == 2) { $isMember = Db::name('chat_group_member')->where([ 'group_id' => $toId, 'user_id' => $uid, 'quit_time' => null, 'is_kicked' => 0 ])->find(); if (!$isMember) { return $this->error('不在群内,无法获取历史消息'); } $role = $isMember['role']; } // 分页查询(倒序取,再正序返回) $total = $query->count(); $messages = $query->alias('msg')->order('send_time', 'desc') ->leftJoin('chat_user user', 'msg.from_id = user.user_id') ->field('msg.id,from_id,to_id,chat_type,msg_type,content,image_url,order_id,is_read,send_time,session_id,nick_name,user_id,avatar,type,coupon,coupon_claim,chat_coupon_id') ->page($page, $size) ->select()->toArray(); // 单聊自动标记已读 // if ($chatType == 1) { Db::name('chat_message')->where([ 'session_id' => $session_id, 'to_id' => $uid, 'is_read' => 0 ])->update(['is_read' => 1]); // 重置未读计数 Db::name('chat_unread_count')->where([ 'user_id' => $uid, 'session_id' => $session_id ])->update(['count' => 0, 'updated_time' => d()]); // } foreach ($messages as $k => &$v) { $v['send_time'] = formatWeChatTime($v['send_time']); $v['coupon'] = !empty($v['coupon'])?json_decode($v['coupon']):''; // 判断是谁发的 if($v['from_id'] == $this->uid) { $v['is_user_send'] = 1; // 自己发的 }else { $v['is_user_send'] = 2; // 别人发的 } } $mute = Db::name('chat_group_mute')->where(['group_id' => $group_id, 'user_id' => 0])->find(); $group['is_mute'] = $mute?1:0; $group['role'] = $role; return $this->success([ 'group' => $group, 'list' => $messages, 'page' => $page, 'size' => $size, 'total' => $total]); } /** * 标记消息已读(批量) */ public function markRead(Request $request): Response { $msgIds = $request->post('msg_ids'); if (empty($msgIds) || !is_string($msgIds)) { return $this->error('请传入有效消息ID'); } $msgIds = explode(',', $msgIds); $query = Db::name('chat_message')->whereIn('id', $msgIds)->where('to_id', $this->uid) ->where('is_read', 0); // 标记已读(仅自己接收的消息) $count = $query->count(); if (empty($count)) { return $this->error('无未读消息可标记'); } try { Db::startTrans(); $sessionIds = $query->group('session_id')->column('session_id'); // 更新未读计数 foreach ($sessionIds as $sessionId) { Db::name('chat_unread_count')->where(['user_id' => $this->uid, 'session_id' => $sessionId])->update(['count' => 0, 'updated_time' => d()]); } // 批量更新 $query->update(['is_read' => 1]); Db::commit(); return $this->success(true); }catch (\Throwable $exception) { Db::rollback(); return $this->error($exception->getMessage()); } } /** * 标记会话全部已读 */ public function markReadAll(Request $request): Response { $msgIds = $request->post('session_ids'); if (empty($msgIds) || !is_string($msgIds)) { return $this->error('请传入有效会话ID'); } $msgIds = explode(',', $msgIds); $query = Db::name('chat_message')->whereIn('session_id', $msgIds)->where('to_id', $this->uid) ->where('is_read', 0); try { Db::startTrans(); // 更新未读计数 foreach ($msgIds as $sessionId) { Db::name('chat_unread_count')->where(['user_id' => $this->uid, 'session_id' => $sessionId])->update(['count' => 0, 'updated_time' => d()]); } // 批量更新 $query->update(['is_read' => 1]); Db::commit(); return $this->success(true); }catch (\Throwable $exception) { Db::rollback(); return $this->error($exception->getMessage()); } } /** * 获取未读消息总数 */ public function getUnreadCount(Request $request): Response { $total = Db::name('chat_unread_count')->where('user_id', $this->uid)->sum('count'); return $this->success(['total' => $total]); } /** * 获取会话列表(含置顶、未读、最后消息) */ public function getSessionList(Request $request): Response { // 获取所有会话ID $sessionIds = Db::name('chat_message')->where('from_id', $this->uid)->WhereOr('to_id', $this->uid) ->group('session_id')->column('session_id'); if (empty($sessionIds)) { return $this->success(); } $list = Redis::get('usermsg:list:' . $this->user_type . ':' . $this->uid); if($list) { $data = json_decode($list, true); }else { $data = ChatMessage::getconverlist($this->uid, $this->user_type); } // 最新一条消息 foreach ($data as $k => $session) { $lastMsg = ''; $unreadCount = 0; if(!empty($session['session_id'])) { // 最后一条消息 $lastMsg = Db::name('chat_message') ->where('session_id', $session['session_id']) ->order('send_time', 'desc') ->find(); // 未读计数 $unreadCount = Db::name('chat_unread_count')->where(['user_id' => $this->uid, 'session_id' => $session['session_id']])->value('count')?:0; } if($session['chat_type'] == 2) { if($lastMsg) { $chat_user = Db::name('chat_user')->where(['user_id' => $lastMsg['from_id']])->field('nick_name,avatar')->find(); } } $msg = ''; if($lastMsg) { // 如果是自己发的不显示发送人 if($lastMsg['from_id'] == $this->uid) { $msg = $lastMsg['content']; }else { // 如果是别人发的显示昵称 $msg = $chat_user['nick_name'] . ':' . $lastMsg['content']; } $data[$k]['send_time'] = formatWeChatTime($lastMsg['send_time']); } $data[$k]['msg'] = $msg; $data[$k]['unread_count'] = $unreadCount; $data[$k]['is_th'] = ChatGroup::isTh($session['group_id'], $this->uid); } return $this->success(['list' => $data]); } /** * 删除会话列表 */ public function getSessionListDel(Request $request): Response { $session_id = $request->post('session_id'); if(empty($session_id)) { return $this->error('参数不完整'); } $list_json = Redis::get('usermsg:list:' . $this->user_type . ':' . $this->uid); if($list_json) { $list_arr = json_decode($list_json, true); foreach ($list_arr as $k => &$list) { if($list['session_id'] == $session_id) { $list['is_del'] = 1; } } if(count($list_arr) >= 1) { Redis::set('usermsg:list:' . $this->user_type . ':' . $this->uid, json_encode($list_arr)); }else { Redis::del('usermsg:list:' . $this->user_type . ':' . $this->uid); } } return $this->success(); } }