From 8d46016d8b830955b485f26c3b98d0a1ec09c15e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Thu, 16 Jul 2026 21:33:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(passport):=20=E4=BC=98=E5=8C=96=E6=89=8B?= =?UTF-8?q?=E6=9C=BA=E5=8F=B7=E6=8E=88=E6=9D=83=E6=B5=81=E7=A8=8B=E5=8F=8A?= =?UTF-8?q?=E8=B6=85=E6=97=B6=E5=A4=84=E7=90=86=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增手机号授权等待状态及定时器,防止重复触发授权操作 - 增加手机号授权超时弹窗提示,支持切换短信验证码登录 - 修改手机号授权冷却时间由3000ms调整为8000ms,减少频繁操作 - 控制手机号授权按钮状态,确保用户协议同意且无冷却或等待中才能操作 - 清理手机号授权等待定时器,防止内存泄露 - 调整加载状态时按钮UI表现,提高用户交互体验 --- src/passport/login.tsx | 63 ++++++++++++++++++++++++++++++++++++++---- src/utils/phoneAuth.ts | 2 +- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/passport/login.tsx b/src/passport/login.tsx index 3d9bc82..179b470 100644 --- a/src/passport/login.tsx +++ b/src/passport/login.tsx @@ -105,14 +105,17 @@ async function fetchUserInfo(token: string) { const Login = () => { const [isAgree, setIsAgree] = useState(false) const [loading, setLoading] = useState(false) + const [phoneAuthPending, setPhoneAuthPending] = useState(false) const [phoneAuthCooling, setPhoneAuthCooling] = useState(isPhoneAuthCoolingDown()) const [showContent, setShowContent] = useState(false) const phoneAuthInFlightRef = useRef(false) + const phoneAuthPendingRef = useRef(false) const phoneAuthTimerRef = useRef | null>(null) + const phoneAuthPendingTimerRef = useRef | null>(null) const router = Taro.getCurrentInstance().router const isWeapp = IS_WEAPP - const canUsePhoneAuth = isAgree && !loading && !phoneAuthCooling + const canUsePhoneAuth = isAgree && !loading && !phoneAuthPending && !phoneAuthCooling /** 页面加载动画 */ useEffect(() => { @@ -125,6 +128,10 @@ const Login = () => { clearTimeout(phoneAuthTimerRef.current) phoneAuthTimerRef.current = null } + if (phoneAuthPendingTimerRef.current) { + clearTimeout(phoneAuthPendingTimerRef.current) + phoneAuthPendingTimerRef.current = null + } } }, []) @@ -138,6 +145,49 @@ const Login = () => { }, remaining) } + const clearPhoneAuthPending = () => { + phoneAuthPendingRef.current = false + setPhoneAuthPending(false) + if (phoneAuthPendingTimerRef.current) { + clearTimeout(phoneAuthPendingTimerRef.current) + phoneAuthPendingTimerRef.current = null + } + } + + const startPhoneAuthPending = () => { + phoneAuthPendingRef.current = true + setPhoneAuthPending(true) + markPhoneAuthCalled() + startPhoneAuthCooldown() + if (phoneAuthPendingTimerRef.current) clearTimeout(phoneAuthPendingTimerRef.current) + phoneAuthPendingTimerRef.current = setTimeout(() => { + clearPhoneAuthPending() + Taro.showModal({ + title: '手机号授权超时', + content: '微信手机号授权暂时无响应,请稍后重试或改用短信验证码登录。', + confirmText: '短信登录', + cancelText: '稍后重试', + confirmColor: '#07c160', + success: (res) => { + if (res.confirm) goSmsLogin() + }, + }) + }, 12000) + } + + const handlePhoneAuthTap = () => { + if (!isAgree) { + Taro.showToast({ title: '请先勾选同意协议', icon: 'none' }) + return + } + if (loading || phoneAuthInFlightRef.current || phoneAuthPendingRef.current || isPhoneAuthCoolingDown()) { + startPhoneAuthCooldown() + Taro.showToast({ title: '请稍后再试', icon: 'none' }) + return + } + startPhoneAuthPending() + } + /** 解析 redirect 参数 */ const redirectUrl = (() => { const raw = (router?.params as Record | undefined)?.redirect @@ -226,18 +276,19 @@ const Login = () => { /** 手机号快捷登录 */ const handleGetPhoneNumber = async ({ detail }: GetPhoneNumberEvent) => { + clearPhoneAuthPending() + if (!isAgree) { Taro.showToast({ title: '请先勾选同意协议', icon: 'none' }) return } - if (loading || phoneAuthInFlightRef.current || isPhoneAuthCoolingDown()) { + if (loading || phoneAuthInFlightRef.current) { startPhoneAuthCooldown() Taro.showToast({ title: '请稍后再试', icon: 'none' }) return } phoneAuthInFlightRef.current = true - markPhoneAuthCalled() startPhoneAuthCooldown() const { code: phoneCode, encryptedData, iv, errMsg } = detail || {} @@ -312,6 +363,7 @@ const Login = () => { Taro.showToast({ title: e?.message || '登录失败', icon: 'none' }) } finally { phoneAuthInFlightRef.current = false + clearPhoneAuthPending() setLoading(false) } } @@ -351,14 +403,15 @@ const Login = () => { color: '#ffffff', fontWeight: '600', textAlign: 'center', - opacity: (!isAgree || loading) ? 0.5 : 1, + opacity: canUsePhoneAuth ? 1 : 0.5, margin: 0, padding: 0, }} openType={canUsePhoneAuth ? 'getPhoneNumber' : undefined} + onClick={handlePhoneAuthTap} onGetPhoneNumber={handleGetPhoneNumber} disabled={!canUsePhoneAuth} - loading={loading} + loading={loading || phoneAuthPending} > 手机号快捷登录 diff --git a/src/utils/phoneAuth.ts b/src/utils/phoneAuth.ts index af0dec0..bb201fa 100644 --- a/src/utils/phoneAuth.ts +++ b/src/utils/phoneAuth.ts @@ -11,7 +11,7 @@ let lastPhoneAuthTime = 0 /** 冷却期(ms),在此期间不允许再次触发 getPhoneNumber */ -const PHONE_AUTH_COOLDOWN = 3000 +const PHONE_AUTH_COOLDOWN = 8000 /** * 检查当前是否在冷却期内。