fix(groups): 微信群排序复刻云客+群详情去掉重复的「成员列表」字段
用户报:①群详情有成员墙后「成员列表」原始串字段重复;②排序与云客不一致。 - 排序:云客「微信群统计」真机判别=员工分组(云客员工列表序)+ 组内 chatRoomId 字符串升序——/api/groups 微信路径改 JOIN wechat_account 按 list_order(NULL 垫底按 owner asc)+room_id asc; WA 保持最近活跃优先 - 群详情:memberIds 从「其他字段」兜底区排除(成员墙已替代,不再 以原始 wxid 串重复出现) 726 测试绿(默认排序断言更新为员工分组序)。 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -101,6 +101,25 @@ async def list_groups(
|
|||||||
list_stmt = sa.select(ChatGroup)
|
list_stmt = sa.select(ChatGroup)
|
||||||
if conditions:
|
if conditions:
|
||||||
list_stmt = list_stmt.where(*conditions)
|
list_stmt = list_stmt.where(*conditions)
|
||||||
|
if (channel or "wechat") == "wechat":
|
||||||
|
# 云客「微信群统计」同款排序(2026-09-10 真机判别):员工分组——
|
||||||
|
# 按云客员工列表序(wechat_account.list_order,NULL 垫底按 wx_id)、
|
||||||
|
# 组内按 room_id(chatRoomId)字符串升序。WA 保持最近活跃优先。
|
||||||
|
list_stmt = (
|
||||||
|
list_stmt.outerjoin(
|
||||||
|
WechatAccount,
|
||||||
|
WechatAccount.wx_id == ChatGroup.owner_account_id,
|
||||||
|
)
|
||||||
|
.order_by(
|
||||||
|
WechatAccount.list_order.is_(None),
|
||||||
|
WechatAccount.list_order.asc(),
|
||||||
|
ChatGroup.owner_account_id.asc(),
|
||||||
|
ChatGroup.room_id.asc(),
|
||||||
|
)
|
||||||
|
.limit(page_size)
|
||||||
|
.offset((page - 1) * page_size)
|
||||||
|
)
|
||||||
|
else:
|
||||||
list_stmt = (
|
list_stmt = (
|
||||||
list_stmt.order_by(
|
list_stmt.order_by(
|
||||||
sa.nullslast(ChatGroup.last_chat_time.desc()),
|
sa.nullslast(ChatGroup.last_chat_time.desc()),
|
||||||
|
|||||||
@@ -64,17 +64,20 @@ async def _seed(session: AsyncSession) -> None:
|
|||||||
|
|
||||||
|
|
||||||
async def test_default_list_returns_all_ordered_desc(make_client):
|
async def test_default_list_returns_all_ordered_desc(make_client):
|
||||||
"""No filters -> 3 groups, ordered by ``last_chat_time desc`` (nulls last)."""
|
"""No filters -> 3 groups;微信排序=员工分组(list_order NULL 按 owner asc)
|
||||||
|
+组内 room_id 字符串升序(云客群统计同款,2026-09-10)。
|
||||||
|
seed 无 wechat_account 行 → list_order 全 NULL → owner 字符串序:
|
||||||
|
wa_owner_1 < wx_owner_1 < wx_owner_2 → [wa_room_x, room_a, room_b]。
|
||||||
|
"""
|
||||||
client = await make_client(_seed)
|
client = await make_client(_seed)
|
||||||
r = await client.get("/api/groups")
|
r = await client.get("/api/groups")
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
body = r.json()
|
body = r.json()
|
||||||
assert body["total"] == 3
|
assert body["total"] == 3
|
||||||
# 2000, 1000, null -> [room_a, room_b, wa_room_x]
|
|
||||||
assert [it["room_id"] for it in body["items"]] == [
|
assert [it["room_id"] for it in body["items"]] == [
|
||||||
|
"wa_room_x@s.whatsapp.net",
|
||||||
"room_a@chatroom",
|
"room_a@chatroom",
|
||||||
"room_b@chatroom",
|
"room_b@chatroom",
|
||||||
"wa_room_x@s.whatsapp.net",
|
|
||||||
]
|
]
|
||||||
for key in (
|
for key in (
|
||||||
"room_id",
|
"room_id",
|
||||||
|
|||||||
@@ -105,7 +105,11 @@ export const GROUP_FIELD_GROUPS: GroupFieldGroup[] = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
/** Every key already surfaced via a group (so 其他 can skip duplicates). */
|
/** Every key already surfaced via a group (so 其他 can skip duplicates). */
|
||||||
const KNOWN_KEYS = new Set(GROUP_FIELD_GROUPS.flatMap((g) => g.keys))
|
const KNOWN_KEYS = new Set([
|
||||||
|
...GROUP_FIELD_GROUPS.flatMap((g) => g.keys),
|
||||||
|
// 原始 wxid 串由群详情成员墙替代,不在任何区(含「其他」)显示(2026-09-10)
|
||||||
|
'memberIds',
|
||||||
|
])
|
||||||
|
|
||||||
/** Resolve the 中文 label for a raw_json key (falls back to the key). */
|
/** Resolve the 中文 label for a raw_json key (falls back to the key). */
|
||||||
export function fieldLabel(key: string): string {
|
export function fieldLabel(key: string): string {
|
||||||
|
|||||||
Reference in New Issue
Block a user