request->param('page', 1); $limit = $this->request->param('limit', 10); $accountId = $this->getUserInfo('s2_accountId'); if (empty($accountId)) { return ResponseHelper::error('请先登录'); } $friends = Db::table('s2_wechat_friend') ->where(['accountId' => $accountId, 'isDeleted' => 0]) ->column('id,nickname,avatar,conRemark,labels,groupId,wechatAccountId,wechatId,extendFields,phone,region,isTop'); // 构建好友子查询 $friendSubQuery = Db::table('s2_wechat_friend') ->where(['accountId' => $accountId, 'isDeleted' => 0]) ->field('id') ->buildSql(); // 优化后的查询:使用MySQL兼容的查询方式 $unionQuery = " (SELECT m.id, m.content, m.wechatFriendId, m.wechatChatroomId, m.createTime, m.wechatTime,m.wechatAccountId, 2 as msgType, wc.nickname, wc.chatroomAvatar as avatar, wc.chatroomId, wc.isTop FROM s2_wechat_chatroom wc INNER JOIN s2_wechat_message m ON wc.id = m.wechatChatroomId AND m.type = 2 INNER JOIN ( SELECT wechatChatroomId, MAX(wechatTime) as maxTime, MAX(id) as maxId FROM s2_wechat_message WHERE type = 2 GROUP BY wechatChatroomId ) latest ON m.wechatChatroomId = latest.wechatChatroomId AND m.wechatTime = latest.maxTime AND m.id = latest.maxId WHERE wc.accountId = {$accountId} AND wc.isDeleted = 0 ) UNION ALL (SELECT m.id, m.content, m.wechatFriendId, m.wechatChatroomId, m.createTime, m.wechatTime, 1 as msgType, 1 as nickname, 1 as avatar, 1 as chatroomId, 1 as wechatAccountId, 0 as isTop FROM s2_wechat_message m INNER JOIN ( SELECT wechatFriendId, MAX(wechatTime) as maxTime, MAX(id) as maxId FROM s2_wechat_message WHERE type = 1 AND wechatFriendId IN {$friendSubQuery} GROUP BY wechatFriendId ) latest ON m.wechatFriendId = latest.wechatFriendId AND m.wechatTime = latest.maxTime AND m.id = latest.maxId WHERE m.type = 1 AND m.wechatFriendId IN {$friendSubQuery} ) ORDER BY wechatTime DESC LIMIT " . (($page - 1) * $limit) . ", {$limit} "; $list = Db::query($unionQuery); // 对分页后的结果进行排序(按wechatTime降序) usort($list, function ($a, $b) { return $b['wechatTime'] <=> $a['wechatTime']; }); // 批量统计未读数量(isRead=0),按好友/群聊分别聚合 $friendIds = []; $chatroomIds = []; foreach ($list as $row) { if (!empty($row['wechatFriendId'])) { $friendIds[] = $row['wechatFriendId']; } if (!empty($row['wechatChatroomId'])) { $chatroomIds[] = $row['wechatChatroomId']; } } $friendIds = array_values(array_unique(array_filter($friendIds))); $chatroomIds = array_values(array_unique(array_filter($chatroomIds))); $friendUnreadMap = []; if (!empty($friendIds)) { // 获取未读消息数量 $friendUnreadMap = Db::table('s2_wechat_message') ->where(['isRead' => 0]) ->whereIn('wechatFriendId', $friendIds) ->group('wechatFriendId') ->column('COUNT(*) AS cnt', 'wechatFriendId'); } $chatroomUnreadMap = []; if (!empty($chatroomIds)) { // 获取未读消息数量 $chatroomUnreadMap = Db::table('s2_wechat_message') ->where(['isRead' => 0]) ->whereIn('wechatChatroomId', $chatroomIds) ->group('wechatChatroomId') ->column('COUNT(*) AS cnt', 'wechatChatroomId'); } $aiTypeData = []; if (!empty($friendIds)) { $aiTypeData = FriendSettings::where('friendId', 'in', $friendIds)->column('friendId,type'); } foreach ($list as $k => &$v) { $createTime = !empty($v['createTime']) ? date('Y-m-d H:i:s', $v['createTime']) : ''; $wechatTime = !empty($v['wechatTime']) ? date('Y-m-d H:i:s', $v['wechatTime']) : ''; $unreadCount = 0; $v['aiType'] = 0; if (!empty($v['wechatFriendId'])) { $v['nickname'] = !empty($friends[$v['wechatFriendId']]) ? $friends[$v['wechatFriendId']]['nickname'] : ''; $v['avatar'] = !empty($friends[$v['wechatFriendId']]) ? $friends[$v['wechatFriendId']]['avatar'] : ''; $v['conRemark'] = !empty($friends[$v['wechatFriendId']]) ? $friends[$v['wechatFriendId']]['conRemark'] : ''; $v['groupId'] = !empty($friends[$v['wechatFriendId']]) ? $friends[$v['wechatFriendId']]['groupId'] : ''; $v['wechatAccountId'] = !empty($friends[$v['wechatFriendId']]) ? $friends[$v['wechatFriendId']]['wechatAccountId'] : ''; $v['wechatId'] = !empty($friends[$v['wechatFriendId']]) ? $friends[$v['wechatFriendId']]['wechatId'] : ''; $v['extendFields'] = !empty($friends[$v['wechatFriendId']]) ? $friends[$v['wechatFriendId']]['extendFields'] : []; $v['region'] = !empty($friends[$v['wechatFriendId']]) ? $friends[$v['wechatFriendId']]['region'] : ''; $v['phone'] = !empty($friends[$v['wechatFriendId']]) ? $friends[$v['wechatFriendId']]['phone'] : ''; $v['isTop'] = !empty($friends[$v['wechatFriendId']]) ? $friends[$v['wechatFriendId']]['isTop'] : 0; $v['labels'] = !empty($friends[$v['wechatFriendId']]) ? json_decode($friends[$v['wechatFriendId']]['labels'], true) : []; $unreadCount = isset($friendUnreadMap[$v['wechatFriendId']]) ? (int)$friendUnreadMap[$v['wechatFriendId']] : 0; $v['aiType'] = isset($aiTypeData[$v['wechatFriendId']]) ? $aiTypeData[$v['wechatFriendId']] : 0; unset($v['chatroomId']); } if (!empty($v['wechatChatroomId'])) { $v['conRemark'] = ''; $unreadCount = isset($chatroomUnreadMap[$v['wechatChatroomId']]) ? (int)$chatroomUnreadMap[$v['wechatChatroomId']] : 0; } $v['id'] = !empty($v['wechatFriendId']) ? $v['wechatFriendId'] : $v['wechatChatroomId']; $v['config'] = [ 'top' => !empty($v['isTop']) ? true : false, 'unreadCount' => $unreadCount, 'chat' => true, 'msgTime' => $v['wechatTime'], ]; $v['createTime'] = $createTime; $v['lastUpdateTime'] = $wechatTime; // 最新消息内容已经在UNION查询中获取,直接使用 $v['latestMessage'] = [ 'content' => $v['content'], 'wechatTime' => $wechatTime ]; unset($v['wechatFriendId'], $v['wechatChatroomId'],$v['isTop']); } unset($v); return ResponseHelper::success($list); } public function readMessage() { $wechatFriendId = $this->request->param('wechatFriendId', ''); $wechatChatroomId = $this->request->param('wechatChatroomId', ''); $accountId = $this->getUserInfo('s2_accountId'); if (empty($accountId)) { return ResponseHelper::error('请先登录'); } if (empty($wechatChatroomId) && empty($wechatFriendId)) { return ResponseHelper::error('参数缺失'); } $where = []; if (!empty($wechatChatroomId)) { $where[] = ['wechatChatroomId', '=', $wechatChatroomId]; } if (!empty($wechatFriendId)) { $where[] = ['wechatFriendId', '=', $wechatFriendId]; } Db::table('s2_wechat_message')->where($where)->update(['isRead' => 1]); return ResponseHelper::success([]); } public function details() { $wechatFriendId = $this->request->param('wechatFriendId', ''); $wechatChatroomId = $this->request->param('wechatChatroomId', ''); $wechatAccountId = $this->request->param('wechatAccountId', ''); $page = $this->request->param('page', 1); $limit = $this->request->param('limit', 10); $from = $this->request->param('From', ''); $to = $this->request->param('To', ''); $olderData = $this->request->param('olderData', false); $accountId = $this->getUserInfo('s2_accountId'); if (empty($accountId)) { return ResponseHelper::error('请先登录'); } if (empty($wechatChatroomId) && empty($wechatFriendId)) { return ResponseHelper::error('参数缺失'); } $where = []; if (!empty($wechatChatroomId)) { $where[] = ['wechatChatroomId', '=', $wechatChatroomId]; } if (!empty($wechatFriendId)) { $where[] = ['wechatFriendId', '=', $wechatFriendId]; } if (!empty($From) && !empty($To)) { $where[] = ['wechatTime', 'between', [$from, $to]]; } $total = Db::table('s2_wechat_message')->where($where)->count(); $list = Db::table('s2_wechat_message')->where($where)->page($page, $limit)->order('id DESC')->select(); foreach ($list as $k => &$v) { $v['wechatTime'] = !empty($v['wechatTime']) ? date('Y-m-d H:i:s', $v['wechatTime']) : ''; } return ResponseHelper::success(['total' => $total, 'list' => $list]); } }