fix(h5-shop): harden iOS WeChat scan after login with hard nav and recover UI

Root cause is JSSDK entry-URL mismatch after SPA post-OAuth, not camera permission. Hard-navigate on iOS, keep OAuth query in sign URL, skip redundant bind OAuth, and prompt refresh/re-auth on failure.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-07 13:08:13 +08:00
parent 2a9493165b
commit e4e9eb2169
12 changed files with 192 additions and 47 deletions
+39 -5
View File
@@ -58,9 +58,9 @@ function formatScanError(e: unknown, opts?: { afterAuth?: boolean }): string {
const msg = e instanceof Error ? e.message : '扫码失败,请重试';
if (/invalid signature/i.test(msg)) {
if (/invalid signature|config:fail|signature/i.test(msg)) {
return '微信 JSSDK 签名校验失败:请确认公众号已配置 JS 接口安全域名,并刷新页面后重试';
return '微信扫码签名校验失败,请刷新页面或重新授权微信后重试';
}
@@ -68,11 +68,11 @@ function formatScanError(e: unknown, opts?: { afterAuth?: boolean }): string {
if (opts?.afterAuth) {
return '微信授权已完成,扫码权限仍在准备中,请再点一次「扫码核销」';
return '微信授权后扫码仍未就绪,请刷新页面或重新授权微信';
}
return '微信权限校验尚未完成,请等待 1~2 秒后再次点击扫码(首次绑定微信时较常见)';
return '微信扫码能力未就绪,请刷新页面或重新授权微信';
}
@@ -80,6 +80,12 @@ function formatScanError(e: unknown, opts?: { afterAuth?: boolean }): string {
}
function isScanRecoverableError(msg: string): boolean {
return isScanPermissionWarmupError(msg) || /签名校验失败|扫码能力未就绪|请刷新页面/i.test(msg);
}
export default function HomePage() {
@@ -100,6 +106,8 @@ export default function HomePage() {
const [authModalOpen, setAuthModalOpen] = useState(false);
const [authModalMode, setAuthModalMode] = useState<'bind' | 'recover'>('bind');
const [authLoading, setAuthLoading] = useState(false);
const [authError, setAuthError] = useState('');
@@ -229,7 +237,19 @@ export default function HomePage() {
} catch (e) {
setScanMsg(formatScanError(e, { afterAuth: opts?.postAuthWarmup }));
const tip = formatScanError(e, { afterAuth: opts?.postAuthWarmup });
setScanMsg(tip);
if (isScanRecoverableError(tip)) {
setAuthModalMode('recover');
setAuthError(tip);
setAuthModalOpen(true);
}
} finally {
@@ -305,6 +325,10 @@ export default function HomePage() {
pendingScanStartedRef.current = false;
setAuthModalMode('bind');
setAuthError('');
setAuthModalOpen(true);
return;
@@ -561,16 +585,26 @@ export default function HomePage() {
open={authModalOpen}
mode={authModalMode}
loading={authLoading}
error={authError}
onAuthorize={() => void startWechatAuth()}
onRefresh={() => {
window.location.reload();
}}
onCancel={() => {
setAuthModalOpen(false);
setAuthModalMode('bind');
setAuthError('');
clearPendingScanAfterAuth();