diff --git a/docs/wechat_ipad多版本Server适配路线图.md b/docs/wechat_ipad多版本Server适配路线图.md index ce93c06..51967d7 100644 --- a/docs/wechat_ipad多版本Server适配路线图.md +++ b/docs/wechat_ipad多版本Server适配路线图.md @@ -31,6 +31,7 @@ - 已在 [wechat_ipad/gateway.py](/d:/learn/abot/wechat_ipad/gateway.py:1) 中注册 `server_864 / 864` 别名 - 已实现 864 第一版登录、初始化等待、HTTP 消息轮询、联系人、群信息、资料与朋友圈基础接口 - 已在 [robot.py](/d:/learn/abot/robot.py:1) 中为 864 增加登录态硬隔离,默认不再回读 855 的历史 `config.toml` 与动态字段 +- 已基于真实 864 服务联调修正首批路由差异:二维码返回结构、联系人详情路由、群公告路由、二维码有效期倒计时同步 当前尚未完成的关键项: diff --git a/wechat_ipad/providers/server_864/friends.py b/wechat_ipad/providers/server_864/friends.py index b63c54b..7a821b0 100644 --- a/wechat_ipad/providers/server_864/friends.py +++ b/wechat_ipad/providers/server_864/friends.py @@ -19,7 +19,11 @@ class FriendMixin(Server864APIClientBase): room_wxid_list = [chatroom] if chatroom else [] data = await self._request_data( "post", - "/friend/GetContactDetail", + # 864 的联系人详情最终要以 router 注册路由为准: + # 1. controller 方法名虽然叫 `GetContactContactApi`; + # 2. 但真正暴露出来的 URL 是 `/friend/GetContactDetailsList`; + # 3. 因此这里按 router.go 的真实注册结果适配,避免继续命中 404。 + "/friend/GetContactDetailsList", json_body={"UserNames": user_names, "RoomWxIDList": room_wxid_list}, timeout=30, ) diff --git a/wechat_ipad/providers/server_864/group.py b/wechat_ipad/providers/server_864/group.py index 1d5b799..26a2127 100644 --- a/wechat_ipad/providers/server_864/group.py +++ b/wechat_ipad/providers/server_864/group.py @@ -49,7 +49,11 @@ class ChatroomMixin(Server864APIClientBase): """获取群公告详情。""" data = await self._request_data( "post", - "/group/GetChatRoomInfoDetail", + # 864 的群公告接口路由名保留了历史命名 `SetGetChatRoomInfoDetail`: + # 1. controller 中实际导出的就是这个路径; + # 2. 直接用语义更自然的 `GetChatRoomInfoDetail` 会 404; + # 3. 对外方法名继续保持 `get_chatroom_announce`,内部路径单独适配即可。 + "/group/SetGetChatRoomInfoDetail", json_body={"ChatRoomName": chatroom}, timeout=30, ) diff --git a/wechat_ipad/providers/server_864/runtime.py b/wechat_ipad/providers/server_864/runtime.py index 5dc6c41..c9685eb 100644 --- a/wechat_ipad/providers/server_864/runtime.py +++ b/wechat_ipad/providers/server_864/runtime.py @@ -137,13 +137,24 @@ class Server864RuntimeMixin: ) break + # 864 的登录状态查询会回传当前 uuid 和有效期: + # 1. 真实联调中已确认 `CheckLoginStatus` 会返回 `uuid/effective_time`; + # 2. 这些值应优先作为 Dashboard 的二维码倒计时与当前扫码目标来源; + # 3. 一旦 server 侧切换了新的 uuid,这里也要及时覆盖本地展示态,避免前端一直盯着旧码。 + latest_uuid = str(login_status.get("uuid", "") or uuid).strip() or uuid + effective_time = int(login_status.get("effective_time", 0) or 0) + if latest_uuid != uuid: + uuid = latest_uuid + scan_url = f"http://weixin.qq.com/x/{uuid}" if uuid else "" + url = f"https://api.2dcode.biz/v1/create-qr-code?data={scan_url}" if scan_url else url + await self._safe_callback( on_login_qr_update, { "uuid": uuid, "url": url, "scan_url": scan_url, - "expires_in": None, + "expires_in": effective_time if effective_time > 0 else None, "status": "waiting", "status_text": str(login_status.get("msg") or login_status.get("loginState") or "等待扫码登录"), "login_source": "fresh_qr", @@ -151,6 +162,28 @@ class Server864RuntimeMixin: logger=logger, callback_name="on_login_qr_update", ) + + # 若 server 已明确告知二维码失效,则立即重新申请一张新码: + # 1. 这能避免 Dashboard 一直展示一张已经不可扫的旧二维码; + # 2. 也能让新环境登录时的交互与 855 保持一致,都是“过期就自动刷新”; + # 3. 重新申请后直接回到当前 while 顶部继续轮询新的 uuid 状态。 + if effective_time <= 0: + uuid, url = await self.get_qr_code(print_qr=True) + scan_url = f"http://weixin.qq.com/x/{uuid}" if uuid else "" + await self._safe_callback( + on_login_qr_update, + { + "uuid": uuid, + "url": url, + "scan_url": scan_url, + "expires_in": None, + "status": "waiting", + "status_text": "二维码已刷新,等待扫码登录", + "login_source": "refresh_qr", + }, + logger=logger, + callback_name="on_login_qr_update", + ) await asyncio.sleep(5) await self._wait_init_ready(logger=logger)