修正864在线态识别并补强资料同步等待

This commit is contained in:
liuwei
2026-05-07 15:52:24 +08:00
parent 0b59bc4a0a
commit 904c20bb62
2 changed files with 82 additions and 2 deletions

View File

@@ -24,16 +24,32 @@ class LoginMixin(Server864APIClientBase):
normalized_login_state = self._normalize_online_text( normalized_login_state = self._normalize_online_text(
self._pick_first(payload, "loginState", "LoginState", "status_text", "statusText") self._pick_first(payload, "loginState", "LoginState", "status_text", "statusText")
) )
raw_login_state = self._pick_first(payload, "loginState", "LoginState")
normalized_status = self._normalize_online_text( normalized_status = self._normalize_online_text(
self._pick_first(payload, "status", "Status", "state_text", "stateText") self._pick_first(payload, "status", "Status", "state_text", "stateText")
) )
state_value = self._pick_first(payload, "state", "State") state_value = self._pick_first(payload, "state", "State")
login_flag = self._pick_first(payload, "isLogin", "IsLogin", "online", "Online", "isOnline", "IsOnline") login_flag = self._pick_first(payload, "isLogin", "IsLogin", "online", "Online", "isOnline", "IsOnline")
login_err_msg = self._normalize_online_text(
self._pick_first(payload, "loginErrMsg", "LoginErrMsg", "msg", "message")
)
if normalized_login_state in {"online", "已登录", "在线"}: if normalized_login_state in {"online", "已登录", "在线"}:
return True return True
# 864 的 `GetLoginStatus` 在你当前这版 server 里会直接返回 `loginState: 1`
# 1. 这不是扫码阶段的 `CheckLoginStatus.state`,而是服务端自身维护的登录态枚举;
# 2. 之前这里只识别到了字符串 `"online"`,导致明明已经在线却仍被判成未登录;
# 3. 这里把常见数字态一并纳入在线判定,避免后续资料拉取与前端显示被卡住。
try:
normalized_login_state_value = int(raw_login_state or 0)
except (TypeError, ValueError):
normalized_login_state_value = 0
if normalized_login_state_value in {1, 2}:
return True
if normalized_status in {"online", "已登录", "在线"}: if normalized_status in {"online", "已登录", "在线"}:
return True return True
if "在线状态良好" in login_err_msg or "账号在线" in login_err_msg:
return True
if isinstance(login_flag, bool): if isinstance(login_flag, bool):
return login_flag return login_flag
if str(login_flag or "").strip().lower() in {"true", "1", "online"}: if str(login_flag or "").strip().lower() in {"true", "1", "online"}:

View File

@@ -28,6 +28,57 @@ class Server864RuntimeMixin:
def is_runtime_running(self) -> bool: def is_runtime_running(self) -> bool:
return bool(getattr(self, "_runtime_running", False)) return bool(getattr(self, "_runtime_running", False))
async def _wait_login_identity_ready(
self,
*,
logger,
on_login_qr_update: AsyncCallback | None = None,
uuid: str = "",
url: str = "",
scan_url: str = "",
login_qr_api: str = "new_x",
login_way: str = "mac",
retry_times: int = 12,
retry_interval_seconds: int = 5,
) -> bool:
"""在 864 已判定在线后,继续等待资料接口把账号身份补齐。"""
for attempt in range(1, retry_times + 1):
if await self._refresh_identity_from_profile(logger=logger):
return True
try:
login_status = await self.get_login_status(auto_login=False)
except Exception as e:
logger.warning(f"server_864 等待账号资料就绪时获取登录状态失败: {e}")
else:
if self._is_online_from_login_status_payload(login_status):
# 服务端已在线但资料还没取到时,前端不应继续停在“未登录”语义:
# 1. 用户当前最困惑的点正是“明明在线了,为什么页面还不显示登录成功”;
# 2. 这类场景更接近“服务端在线,账号资料同步中”,需要一个更准确的中间态提示;
# 3. 因此这里主动把状态更新到“资料同步中”,让首页知道并非扫码失败。
await self._safe_callback(
on_login_qr_update,
{
"uuid": uuid,
"url": url,
"scan_url": scan_url,
"status": "confirmed",
"status_text": f"864 服务端已在线,正在同步账号资料(第 {attempt}/{retry_times} 次)",
"login_source": "fresh_qr",
"provider_name": "server_864",
"provider_stage": "login_finalizing",
"connection_ready": True,
"login_required": False,
"login_qr_api": login_qr_api,
"login_way": login_way,
},
logger=logger,
callback_name="on_login_qr_update",
)
if attempt < retry_times:
await asyncio.sleep(retry_interval_seconds)
return False
@staticmethod @staticmethod
def _normalize_login_runtime_message(message: str) -> str: def _normalize_login_runtime_message(message: str) -> str:
"""把 864 登录阶段抛出的原始错误整理成更适合前端展示的短文本。""" """把 864 登录阶段抛出的原始错误整理成更适合前端展示的短文本。"""
@@ -153,7 +204,12 @@ class Server864RuntimeMixin:
) -> None: ) -> None:
"""确保 864 已完成登录。""" """确保 864 已完成登录。"""
if await self.is_logged_in(): if await self.is_logged_in():
identity_ready = await self._refresh_identity_from_profile(logger=logger) identity_ready = await self._wait_login_identity_ready(
logger=logger,
on_login_qr_update=on_login_qr_update,
login_qr_api=login_qr_api,
login_way=login_way,
)
if not identity_ready: if not identity_ready:
raise RuntimeError("当前未拿到可用账号身份,请重新扫码登录") raise RuntimeError("当前未拿到可用账号身份,请重新扫码登录")
# 864 在“服务端已经在线、ABOT 只是后启动”的场景下会直接走这里: # 864 在“服务端已经在线、ABOT 只是后启动”的场景下会直接走这里:
@@ -450,7 +506,15 @@ class Server864RuntimeMixin:
try: try:
await self._wait_init_ready(logger=logger) await self._wait_init_ready(logger=logger)
identity_ready = await self._refresh_identity_from_profile(logger=logger) identity_ready = await self._wait_login_identity_ready(
logger=logger,
on_login_qr_update=on_login_qr_update,
uuid=uuid,
url=url,
scan_url=scan_url,
login_qr_api=login_qr_api,
login_way=login_way,
)
if not identity_ready: if not identity_ready:
raise RuntimeError("扫码完成后未获取到可用账号身份,请重新扫码登录") raise RuntimeError("扫码完成后未获取到可用账号身份,请重新扫码登录")
ipad_config["wxid"] = self.wxid ipad_config["wxid"] = self.wxid