diff --git a/robot.py b/robot.py index ea8bd1f..b2a761e 100644 --- a/robot.py +++ b/robot.py @@ -525,8 +525,13 @@ class Robot: provider_stage = str(self.ipad_login_qr_state.get("provider_stage", "bootstrap") or "bootstrap").strip() connection_ready = bool(self.ipad_login_qr_state.get("connection_ready", False)) login_required = bool(self.ipad_login_qr_state.get("login_required", False)) + # 首页弹窗是否关闭,必须优先以“当前二维码运行态”本身为准: + # 1. 之前这里把 `self.wxid` 也算进了 logged_in,导致旧身份缓存会把新一轮扫码流程误判成“已经登录”; + # 2. 864 收口失败后虽然 provider 已经回到扫码引导态,但 Robot 上残留的旧 wxid 仍会让前端直接收起弹窗; + # 3. 因此这里收紧为只认当前二维码状态机明确给出的 logged_in / confirmed 信号,不再混入历史缓存身份。 + logged_in = login_state_flag or (qr_status in {"confirmed", "logged_in"} and not login_required) state = { - "logged_in": bool(self.wxid) or login_state_flag or qr_status in {"confirmed", "logged_in"}, + "logged_in": logged_in, "active": bool(self.ipad_login_qr_state.get("active", False)), "status": qr_status, "provider_name": provider_name, @@ -577,6 +582,12 @@ class Robot: head_img_url = str((payload or {}).get("head_img_url", "") or "").strip() expires_in = (payload or {}).get("expires_in") expires_in = None if expires_in in (None, "") else max(0, int(expires_in)) + # 一旦重新进入扫码链路,就主动清掉 Robot 侧残留的账号身份: + # 1. 864 登录收口失败时,provider 已明确告诉前端“当前没有可用账号”,此时继续保留旧 wxid 会误导首页状态; + # 2. Dashboard 的当前账号、健康卡片、二维码弹窗都共享这份运行态缓存,必须确保未登录时不再展示历史账号; + # 3. 这里只在非成功态下清空,不影响真正登录完成后的账号信息展示。 + if status not in {"confirmed", "logged_in"}: + self._clear_ipad_identity_cache() current_record = { "uuid": uuid_value, "scan_url": scan_url, @@ -615,6 +626,24 @@ class Robot: "updated_at": now_ts, } + def _clear_ipad_identity_cache(self) -> None: + """清理 Robot 侧缓存的 wechat 账号身份,避免未登录时误显示旧号。""" + self.wxid = "" + self.nickname = "" + self.alias = "" + self.phone = "" + self.signature = "" + # `ipad_bot` 可能还未初始化完成,因此这里做一次存在性保护: + # 1. 登录引导状态会在 provider 创建早期就被推给 Dashboard; + # 2. 这时 bot 对象不一定已经完整可用,不能因为清理缓存反而引入新的 AttributeError; + # 3. 所以只在对象存在时尽量同步清空,做成纯兜底动作。 + if self.ipad_bot is not None: + self.ipad_bot.wxid = "" + self.ipad_bot.nickname = "" + self.ipad_bot.alias = "" + self.ipad_bot.phone = "" + self.ipad_bot.signature = "" + async def _handle_ipad_login_qr_cleared(self, payload: dict | None = None) -> None: """在登录完成或识别到已有登录态后关闭首页二维码引导。""" now_ts = time.time()