From 804addf725ead81ad27001cb269fcf8bf65ea72b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=85=E5=BF=B5?= Date: Mon, 24 Aug 2026 11:25:33 +0800 Subject: [PATCH] =?UTF-8?q?feat(staff):=20=E5=91=98=E5=B7=A5=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E6=8E=92=E5=BA=8F=E5=AF=B9=E9=BD=90=E4=BA=91=E5=AE=A2?= =?UTF-8?q?API=E8=BF=94=E5=9B=9E=E9=A1=BA=E5=BA=8F(list=5Forder=E5=88=97+?= =?UTF-8?q?=E6=8A=93=E5=8F=96=E8=AE=B0=E5=BA=8F+API=E6=8C=89=E5=BA=8F?= =?UTF-8?q?=E6=8E=92)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - wechat_account 加 list_order 列(云客 wxUser/list 返回顺序) - 抓取器记录每行在API响应中的序号 - /api/accounts ORDER BY list_order(对齐云客员工列表排列) Co-Authored-By: Claude --- yunke-server/app/api/routers/organization.py | 9 ++++++++- yunke-server/app/db/models.py | 2 ++ yunke-server/scripts/scrape_via_page.py | 7 ++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/yunke-server/app/api/routers/organization.py b/yunke-server/app/api/routers/organization.py index dec8b56..8c4d31c 100644 --- a/yunke-server/app/api/routers/organization.py +++ b/yunke-server/app/api/routers/organization.py @@ -115,6 +115,7 @@ async def list_accounts( WechatAccount.group_num.label("group_num"), WechatAccount.is_on_job.label("is_on_job"), WechatAccount.raw_json.label("raw_json"), + WechatAccount.list_order.label("list_order"), ) whatsapp_q = sa.select( WhatsappAccount.uid.label("account_id"), @@ -127,6 +128,7 @@ async def list_accounts( WhatsappAccount.group_num.label("group_num"), WhatsappAccount.is_on_job.label("is_on_job"), WhatsappAccount.raw_json.label("raw_json"), + sa.literal(None).label("list_order"), ) if channel == "wechat": @@ -148,7 +150,12 @@ async def list_accounts( page_q = ( sa.select(sub) - .order_by(sub.c.channel.asc(), sub.c.account_id.asc()) + .order_by( + sub.c.channel.asc(), + # list_order 优先(云客员工列表排列顺序,2026-08-24),NULL 排后 + sa.nullslast(sa.cast(sub.c.list_order, sa.Integer).asc()), + sub.c.account_id.asc(), + ) .offset((page - 1) * page_size) .limit(page_size) ) diff --git a/yunke-server/app/db/models.py b/yunke-server/app/db/models.py index 0b4bee7..a72e587 100644 --- a/yunke-server/app/db/models.py +++ b/yunke-server/app/db/models.py @@ -166,6 +166,8 @@ class WechatAccount(Base): last_update: Mapped[int | None] = mapped_column(BigInteger, nullable=True) version: Mapped[str | None] = mapped_column(String(64), nullable=True) + # 云客 wxUser/list 返回顺序(对齐云客员工列表排列;NULL=未回填按 wx_id 排) + list_order: Mapped[int | None] = mapped_column(Integer, nullable=True) raw_json: Mapped[dict[str, Any] | None] = mapped_column(JSON, nullable=True) fetched_at: Mapped[dt.datetime] = _fetched_at() updated_at: Mapped[dt.datetime] = _updated_at() diff --git a/yunke-server/scripts/scrape_via_page.py b/yunke-server/scripts/scrape_via_page.py index b91f62b..7117816 100644 --- a/yunke-server/scripts/scrape_via_page.py +++ b/yunke-server/scripts/scrape_via_page.py @@ -1171,7 +1171,12 @@ async def scrape_accounts(cookie_str: str, max_pages: int = 100): max_pages=max_pages, ) - records = [_normalize_wxuser_account(row) for row in rows] + records = [] + for idx, row in enumerate(rows): + rec = _normalize_wxuser_account(row) + # 记录云客 API 返回顺序(对齐员工列表排列) + rec["list_order"] = idx + records.append(rec) await _upsert_all(upsert_wechat_account, records) total = len(records) logger.info(f"DONE: accounts fetched={total}, upserted={total}")