diff --git a/app/browser/bind.tsx b/app/browser/bind.tsx index e27cce2..1af2f76 100644 --- a/app/browser/bind.tsx +++ b/app/browser/bind.tsx @@ -269,17 +269,11 @@ const INJECTED_JS = `(function(){ var giveUp=window.__talentTries>=8; function retry(){ if(giveUp){ - finish('bindingFailed'); + finish('profileUnavailable',{identityUnavailable:true}); return; } setTimeout(fetchTalentInfo,1000); } - function retryStudent(reason,stu,onlyFinal){ - if(stu!==undefined && (!onlyFinal || giveUp)){ - diagnostic('studentInfo','invalid-response',undefined,reason,stu); - } - retry(); - } function pick(arr,code){ var field=(arr||[]).find(function(item){return item.fieldCode===code;}); return field?String(field.fieldValue==null?'':field.fieldValue):''; @@ -296,6 +290,17 @@ const INJECTED_JS = `(function(){ } var sn=String(u.data.sn); var name=u.data.name||''; + function retryStudent(reason,stu,onlyFinal){ + if(stu!==undefined && (!onlyFinal || giveUp)){ + diagnostic('studentInfo','invalid-response',undefined,reason,stu); + } + if(giveUp){ + // 资料异常时只保留已验证的身份 + finish('info',{name:name,studentId:sn,cardId:'',college:'',eduLevel:''}); + return; + } + retry(); + } return Promise.all([ getJson('studentInfo','/information-center/xd/user/findStudentInfoWechat/'+encodeURIComponent(sn)).catch(function(){return undefined;}), getDictionary('colleges','/information-center/xd/commons/getColleges'), @@ -363,6 +368,7 @@ export default function BindScreen() { } | null>(null); const flowFinished = useRef(false); const preserveSession = useRef(false); + const screenActive = useRef(true); const reportBindError = useRef(createBindErrorReporter(reportError)).current; const setWebviewRef = useCallback((view: WebView | null) => { @@ -371,13 +377,19 @@ export default function BindScreen() { }, []); const handleLoadEnd = useCallback(() => { - if (webviewAttempt.id !== activeAttemptId.current || flowFinished.current) + if ( + !screenActive.current || + webviewAttempt.id !== activeAttemptId.current || + flowFinished.current + ) return; webview.current?.injectJavaScript(INJECTED_JS); }, [webviewAttempt.id]); useEffect(() => { + screenActive.current = true; return () => { + screenActive.current = false; if (!preserveSession.current) { CookieManager.clearAll(true).catch(() => {}); } @@ -398,7 +410,11 @@ export default function BindScreen() { const recoverAppEntry = (failure: TalentLoginFailure) => { // 忽略旧 WebView 的延迟回调 - if (webviewAttempt.id !== activeAttemptId.current || flowFinished.current) + if ( + !screenActive.current || + webviewAttempt.id !== activeAttemptId.current || + flowFinished.current + ) return true; if (webviewAttempt.id !== 0 || !isRecoverableTalentRootError(failure)) return false; @@ -450,11 +466,14 @@ export default function BindScreen() { }; const onMessage = async (event: { nativeEvent: { data: string } }) => { - if (webviewAttempt.id !== activeAttemptId.current) return; + if (!screenActive.current || webviewAttempt.id !== activeAttemptId.current) + return; try { const msg = JSON.parse(event.nativeEvent.data); if (msg.type === "diagnostic") { reportBindError(msg); + } else if (flowFinished.current) { + return; } else if (msg.type === "bindingFailed") { handleFailure(); } else if (msg.type === "credentials") { @@ -463,7 +482,6 @@ export default function BindScreen() { password: msg.password, }; } else if (msg.type === "profileUnavailable") { - if (flowFinished.current) return; flowFinished.current = true; preserveSession.current = true; useOnboardingStore.getState().reset(); @@ -477,22 +495,42 @@ export default function BindScreen() { pathname: "/onboarding", params: { step: "setup" }, }); - } else if (msg.type === "info" && pendingCredentials.current) { - if (flowFinished.current) return; + } else if (msg.type === "info") { + if (!pendingCredentials.current) { + reportError(new Error("Bind credentials unavailable"), { + module: "bind", + }); + handleFailure(); + return; + } flowFinished.current = true; + // 保存完成前保留会话,避免页面卸载时提前清除 Cookie preserveSession.current = true; const { username, password } = pendingCredentials.current; - await useUserBindStore - .getState() - .bind( - username, - msg.name, - password, - msg.cardId, - msg.college, - msg.eduLevel, - ); + try { + await useUserBindStore + .getState() + .bind( + username, + msg.name, + password, + msg.cardId, + msg.college, + msg.eduLevel, + ); + } catch (error) { + reportError(error, { module: "bind" }); + if (!screenActive.current) { + CookieManager.clearAll(true).catch(() => {}); + return; + } + preserveSession.current = false; + flowFinished.current = false; + handleFailure(); + return; + } + if (!screenActive.current) return; Toast.show({ type: "success", diff --git a/lib/i18n/locales/en.json b/lib/i18n/locales/en.json index 08d2db7..e3232ba 100644 --- a/lib/i18n/locales/en.json +++ b/lib/i18n/locales/en.json @@ -260,9 +260,9 @@ "bindFailed": "Link failed", "bindPasswordError": "Incorrect password", "bindPasswordErrorSub": "Please link your WHUT account again", - "bindFailedSub": "iWUT is temporarily unavailable, please try again later", - "bindProfileUnavailable": "Account verified", - "bindProfileUnavailableSub": "Your profile is not available yet, but you can continue and import your timetable", + "bindFailedSub": "Unable to link your account. Please try again later", + "bindProfileUnavailable": "There is an issue with your user information", + "bindProfileUnavailableSub": "You can finish setting up the app and try linking your account again later", "menuTools": "Tools", "menuSettings": "Settings", "menuOther": "Other", diff --git a/lib/i18n/locales/zh.json b/lib/i18n/locales/zh.json index f00bf0b..2b75c6b 100644 --- a/lib/i18n/locales/zh.json +++ b/lib/i18n/locales/zh.json @@ -260,9 +260,9 @@ "bindFailed": "绑定失败", "bindPasswordError": "密码错误", "bindPasswordErrorSub": "请重新绑定智慧理工大账号", - "bindFailedSub": "智慧理工大暂时无法访问,请稍后重试", - "bindProfileUnavailable": "账号验证成功", - "bindProfileUnavailableSub": "暂未获取到个人资料,可先继续导入课表", + "bindFailedSub": "无法绑定账号,请稍后重试", + "bindProfileUnavailable": "用户信息异常", + "bindProfileUnavailableSub": "您可以继续完成 App 设置,稍后再尝试绑定账号", "menuTools": "工具", "menuSettings": "设置", "menuOther": "其他",