验证码用户手动输入期间延长倒计时,防止用户输入一半之前60秒结束终止了输验证码步骤

This commit is contained in:
xuxin
2026-06-05 09:54:27 +08:00
parent 403e5e9fc9
commit 8d6282c3e6
+31 -18
View File
@@ -116,10 +116,6 @@
<span class="login-view__spinner"></span>
<span>登录中</span>
</template>
<!-- 即将返回提示 -->
<template v-else-if="isReturning">
即将返回发送验证码
</template>
<!-- 倒计时状态 -->
<template v-else>
{{ countdown }} 秒后可继续发送
@@ -174,10 +170,14 @@ const countdown = ref(0)
let countdownTimer: ReturnType<typeof setInterval> | null = null
/** 是否正在调用登录接口 */
const isLoggingIn = ref(false)
/** 是否处于"即将返回"提示阶段 */
const isReturning = ref(false)
/** 用户最后一次输入验证码的时间戳 */
let lastOtpInputTime = 0
/** 倒计时结束后等待用户输入冷却的定时器 */
let returnWaitTimer: ReturnType<typeof setTimeout> | null = null
/** 延长倒计时的定时器(每秒递减) */
let extendTimer: ReturnType<typeof setInterval> | null = null
/** 标记60秒倒计时已结束,等待返回中 */
let countdownFinished = false
/** OTP 输入框引用 */
const otpInputRef = ref<HTMLInputElement | null>(null)
@@ -215,21 +215,27 @@ function startCountdown() {
/** 倒计时结束后的返回逻辑 — 考虑用户最近操作 */
function triggerReturn() {
// 计算距离用户最后一次输入过了多久
const elapsed = Date.now() - lastOtpInputTime
// 如果用户5秒内还在输入,则等待剩余时间后再提示
const waitTime = Math.max(0, 5000 - elapsed)
countdownFinished = true
scheduleReturn()
}
// 先等用户操作冷却
setTimeout(() => {
// 显示"即将返回发送验证码"提示5秒
isReturning.value = true
setTimeout(() => {
isReturning.value = false
/** 安排返回:用户停止输入5秒后回步骤一,每次输入都重置5秒 */
function scheduleReturn() {
// 清除之前所有定时器,重新开始5秒倒计时
if (returnWaitTimer) { clearTimeout(returnWaitTimer); returnWaitTimer = null }
if (extendTimer) { clearInterval(extendTimer); extendTimer = null }
// 直接重置为5秒倒计时
countdown.value = 5
extendTimer = setInterval(() => {
countdown.value--
if (countdown.value <= 0) {
if (extendTimer) { clearInterval(extendTimer); extendTimer = null }
countdownFinished = false
step.value = 1
otpValue.value = ''
}, 5000)
}, waitTime)
}
}, 1000)
}
/** 步骤一:发送验证码 */
@@ -272,8 +278,15 @@ function handleOtpInput() {
otpValue.value = otpValue.value.replace(/\D/g, '').slice(0, 6)
// 记录用户最后输入时间
lastOtpInputTime = Date.now()
// 如果倒计时已结束且用户还在输入(未满6位),重新安排返回计时
if (countdownFinished && otpValue.value.length < 6) {
scheduleReturn()
}
// 满6位自动触发登录
if (otpValue.value.length === 6) {
// 取消返回流程
if (returnWaitTimer) { clearTimeout(returnWaitTimer); returnWaitTimer = null }
if (extendTimer) { clearInterval(extendTimer); extendTimer = null }
handleLogin()
}
}