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('群不存在'); } if($chatType == 2) { // 构建查询条件 $query = Db::name('chat_message')->where(['group_id' => $group_id]); }else { // 构建查询条件 $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,type,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' => $toId ])->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']):''; $v['nick'] = $v['nick_name']; // 判断是谁发的 if($v['from_id'] == $this->uid) { $v['is_user_send'] = 1; // 自己发的 }else { $v['is_user_send'] = 2; // 别人发的 } // 判断是不是商家发的 if($v['type'] == 2) { $v['is_shop'] = 1; // 商家 }else { $v['is_shop'] = 2; // 不是商家 } $v['content'] = decodeEmojiFromDb($v['content']); } $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'])) { if($session['chat_type'] == 2) { if($session['member_status']) { // 最后一条消息 $lastMsg = Db::name('chat_message') ->where('group_id', $session['group_id']) ->order('send_time', 'desc') ->find(); } }else { $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['to_id']])->value('count')?:0; } if($session['chat_type'] == 2) { if($lastMsg) { $chat_user = Db::name('chat_user')->where(['user_id' => $lastMsg['from_id']])->field('type')->find(); // 如果是用户 if($chat_user['type'] == 1) { $chat_user = Db::name('tb_user_info')->where(['id' => $lastMsg['from_id']])->field('nick_name,head_img as avatar')->find(); }else { $chat_user = Db::name('sys_user')->where(['id' => $lastMsg['from_id']])->field('nick_name,avatar')->find(); } } } $msg = ''; $data[$k]['send_time_origin'] = 0; if($lastMsg) { switch ($lastMsg['msg_type']) { case 1: $content = $lastMsg['content']; break; case 2: $content = '[图片]'; break; case 3: $content = '[订单]'; break; case 4: $content = '[优惠券]'; break; case 5: $content = '[视频]'; break; } // 如果是自己发的不显示发送人 if($lastMsg['from_id'] == $this->uid) { $msg = $content; }else { // 如果是别人发的显示昵称 $msg = $chat_user['nick_name'] . ':' . $content; } $data[$k]['send_time_origin'] = $lastMsg['send_time']; $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); } $data = param_sort($data, 'send_time_origin'); 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(); } }