['roomid', 'msgtype'], ]; } private function resolveScope(): array { $sessionId = (int) ($this->params['session_id'] ?? 0); if ($sessionId > 0) { $session = \app\common\model\QywxMsgSession::find($sessionId); if ($session) { return [ 'staff_userid' => (string) $session['staff_userid'], 'external_userid' => (string) $session['external_userid'], 'roomid' => (string) $session['roomid'], ]; } } return [ 'staff_userid' => trim((string) ($this->params['staff_userid'] ?? '')), 'external_userid' => trim((string) ($this->params['external_userid'] ?? '')), 'roomid' => trim((string) ($this->params['roomid'] ?? '')), ]; } private function baseQuery() { $scope = $this->resolveScope(); $query = QywxMsgArchive::where($this->searchWhere); if ($scope['roomid'] !== '') { $query->where('roomid', $scope['roomid']); } else { // 单聊:两端顺序不定,from_user/tolist 都可能为员工或客户 $staff = $scope['staff_userid']; $external = $scope['external_userid']; if ($staff === '' && $external === '') { $query->where('id', 0); } else { $query->where('roomid', ''); if ($staff !== '' && $external !== '') { $query->where(function ($q) use ($staff, $external) { $q->where(function ($sub) use ($staff, $external) { $sub->where('from_user', $staff)->whereLike('to_list', '%"' . $external . '"%'); })->whereOr(function ($sub) use ($staff, $external) { $sub->where('from_user', $external)->whereLike('to_list', '%"' . $staff . '"%'); }); }); } elseif ($staff !== '') { $query->where(function ($q) use ($staff) { $q->where('from_user', $staff)->whereOr('to_list', 'like', '%"' . $staff . '"%'); }); } else { $query->where(function ($q) use ($external) { $q->where('from_user', $external)->whereOr('to_list', 'like', '%"' . $external . '"%'); }); } } } if (!empty($this->params['before_time'])) { $query->where('send_time', '<', (int) $this->params['before_time']); } if (!empty($this->params['after_time'])) { $query->where('send_time', '>', (int) $this->params['after_time']); } return $query; } public function lists(): array { $rows = $this->baseQuery() ->order('send_time', 'desc') ->order('id', 'desc') ->limit($this->limitOffset, $this->limitLength) ->select() ->toArray(); if (empty($rows)) { return []; } $rows = array_reverse($rows); // 前端按时间升序渲染 $users = []; foreach ($rows as $r) { $users[$r['from_user']] = true; $toList = $r['to_list']; if (is_array($toList)) { foreach ($toList as $to) { $users[$to] = true; } } } $users = array_keys(array_filter($users, fn ($_, $k) => $k !== '', ARRAY_FILTER_USE_BOTH)); $adminMap = []; $extMap = []; if ($users) { $adminMap = Admin::whereIn('work_wechat_userid', $users) ->column('id,name,avatar,work_wechat_userid', 'work_wechat_userid'); $extMap = QywxExternalContact::whereIn('external_userid', $users) ->column('external_userid,name,avatar,type,unionid', 'external_userid'); } $msgIds = array_column($rows, 'msgid'); $mediaMap = []; if ($msgIds) { $mediaList = QywxMsgArchiveMedia::whereIn('msgid', $msgIds)->select()->toArray(); foreach ($mediaList as $m) { $mediaMap[$m['msgid']][] = $m; } } foreach ($rows as &$r) { $fromId = (string) $r['from_user']; $r['from_is_staff'] = isset($adminMap[$fromId]); $r['from_profile'] = $adminMap[$fromId] ?? ($extMap[$fromId] ?? null); $r['media'] = $mediaMap[$r['msgid']] ?? []; } unset($r); return $rows; } public function count(): int { return $this->baseQuery()->count(); } }