diff --git a/frontend/web/src/admin/modules/channels/WeixinLogin.tsx b/frontend/web/src/admin/modules/channels/WeixinLogin.tsx index 8e2a1f0..e99fa4b 100644 --- a/frontend/web/src/admin/modules/channels/WeixinLogin.tsx +++ b/frontend/web/src/admin/modules/channels/WeixinLogin.tsx @@ -118,14 +118,15 @@ export function WeixinLogin({ // Track tab visibility: while hidden, do NOT swap the QR (show "过期" overlay instead); // on returning, re-mint a fresh code if we were still waiting. useEffect(() => { + // Restoring the tab must NOT re-mint a QR: if the user has already scanned + // (but not confirmed) the on-screen code, swapping it mid-flow cancels the + // in-progress bind and WeChat's confirm never lands. Re-minting is only done + // by the periodic timer or the explicit 刷新二维码 button. const onVis = () => { - const h = document.hidden; - setHidden(h); - if (!h && statusRef.current === "waiting") refreshQR(); + setHidden(document.hidden); }; const onFocus = () => { setHidden(false); - if (statusRef.current === "waiting") refreshQR(); }; document.addEventListener("visibilitychange", onVis); window.addEventListener("focus", onFocus);