diff --git a/yunke-server/app/api/routers/groups.py b/yunke-server/app/api/routers/groups.py index b5c2e69..9bafa3c 100644 --- a/yunke-server/app/api/routers/groups.py +++ b/yunke-server/app/api/routers/groups.py @@ -35,19 +35,23 @@ async def list_groups( channel: Annotated[str | None, Query()] = None, owner_account_id: Annotated[str | None, Query()] = None, user_id: Annotated[str | None, Query()] = None, + room_id: Annotated[str | None, Query()] = None, ) -> Page[GroupOut]: """List chat groups with optional ``channel`` / ``owner_account_id`` / - ``user_id`` filters. + ``user_id`` / ``room_id`` filters. ``user_id`` maps to the ``ChatGroup.owner_user_id`` column (the staff ``userId`` who owns the chatroom account), mirroring the ``user_id`` - filter on ``GET /api/customers``. + filter on ``GET /api/customers``. ``room_id`` is an exact-match single- + row lookup (chat page group-name resolution). """ conditions = [] if channel is not None: conditions.append(ChatGroup.channel == channel) if owner_account_id is not None: conditions.append(ChatGroup.owner_account_id == owner_account_id) + if room_id is not None: + conditions.append(ChatGroup.room_id == room_id) if user_id is not None: conditions.append(ChatGroup.owner_user_id == user_id) diff --git a/yunke-server/tests/test_api_groups.py b/yunke-server/tests/test_api_groups.py index 5ad1e6e..d54ed8d 100644 --- a/yunke-server/tests/test_api_groups.py +++ b/yunke-server/tests/test_api_groups.py @@ -235,3 +235,23 @@ async def test_members_empty_room_is_200(make_client): r = await client.get("/api/groups/room_b@chatroom/members") assert r.status_code == 200 assert r.json() == [] + + +# --------------------------------------------------------------------------- +# room_id 精确过滤(2026-08-20:群聊页群名单行直查,替代超上限的大页拉取) +# --------------------------------------------------------------------------- + +async def test_room_id_filter_returns_single_group(make_client): + async def seed(session): + session.add_all([ + ChatGroup(room_id="r1@chatroom", channel="wechat", room_name="群一", owner_account_id="o1"), + ChatGroup(room_id="r2@chatroom", channel="wechat", room_name="群二", owner_account_id="o1"), + ]) + await session.commit() + + client = await make_client(seed) + r = await client.get("/api/groups", params={"room_id": "r2@chatroom"}) + assert r.status_code == 200 + body = r.json() + assert body["total"] == 1 + assert body["items"][0]["room_name"] == "群二" diff --git a/yunkes/src/api/index.ts b/yunkes/src/api/index.ts index 838c169..1ceb316 100644 --- a/yunkes/src/api/index.ts +++ b/yunkes/src/api/index.ts @@ -140,6 +140,8 @@ export interface GroupQuery { channel?: Channel | 'all' owner_account_id?: string user_id?: string + /** 精确单行直查(群聊页群名解析)。 */ + room_id?: string page?: number page_size?: number } @@ -151,6 +153,7 @@ export function getGroups(query: GroupQuery = {}): Promise> { channel: query.channel === 'all' ? undefined : query.channel, owner_account_id: query.owner_account_id, user_id: query.user_id, + room_id: query.room_id, page: query.page ?? 1, page_size: query.page_size ?? 20, }), diff --git a/yunkes/src/views/ChatTimeline.vue b/yunkes/src/views/ChatTimeline.vue index 38474b6..9bc9ba3 100644 --- a/yunkes/src/views/ChatTimeline.vue +++ b/yunkes/src/views/ChatTimeline.vue @@ -76,10 +76,9 @@ async function loadTalkerName(): Promise { if (!hasActive.value) return try { if (isGroup.value && props.roomId) { - // 群名 - const res = await getGroups({ channel: channelTyped.value, owner_account_id: props.ownerId, page: 1, page_size: 200 }) - const g = res.items.find(g => g.room_id === props.roomId) - talkerName.value = g?.room_name || null + // 群名(room_id 精确单行直查,不再拉整页群列表) + const res = await getGroups({ channel: channelTyped.value, room_id: props.roomId, page: 1, page_size: 1 }) + talkerName.value = res.items[0]?.room_name || null } else if (props.talkerId) { // 客户昵称 const res = await getCustomers({