feat: 重置密码倒计时机制修改
This commit is contained in:
@@ -22,7 +22,6 @@
|
||||
v-else-if="step === 'verify'"
|
||||
:ct="emailCode"
|
||||
@nextStep="handleCheckVerifyCode"
|
||||
@resend="handleSendVerifyCode"
|
||||
/>
|
||||
<Password v-else-if="step === 'password'" @sucess="handleSuccess" />
|
||||
</div>
|
||||
@@ -42,7 +41,7 @@ import Mail from './components/Mail.vue'
|
||||
import Verify from './components/Verify.vue'
|
||||
import Password from './components/Password.vue'
|
||||
import { showToast } from 'vant'
|
||||
import { precheckEmail, resetPassword } from '@/api/login'
|
||||
import { resetPassword } from '@/api/login'
|
||||
import { encryptPassword } from '@/utils/tools'
|
||||
|
||||
const router = useRouter()
|
||||
@@ -80,10 +79,8 @@ const handleSendVerifyCode = (data: any) => {
|
||||
if (data?.email) {
|
||||
fromData.value.email = data?.email
|
||||
}
|
||||
precheckEmail({ email: fromData.value.email }).then(() => {
|
||||
showToast('the verification code has been sent to your email')
|
||||
// 只切换步骤,验证码的发送由 Verify 组件负责
|
||||
handleStep('verify')
|
||||
})
|
||||
}
|
||||
|
||||
const handleCheckVerifyCode = (data: any) => {
|
||||
|
||||
@@ -31,8 +31,10 @@
|
||||
<div class="btn" @click="handleConfirmCaptcha">Confirm</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, onMounted, nextTick } from 'vue'
|
||||
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
|
||||
import { showToast } from 'vant'
|
||||
import { getLocal, removeLocal, setLocal } from '@/utils/local'
|
||||
import { precheckEmail } from '@/api/login'
|
||||
|
||||
// Props
|
||||
const props = defineProps({
|
||||
@@ -48,7 +50,7 @@ const props = defineProps({
|
||||
|
||||
const agreePolicy = ref(false)
|
||||
// Emits
|
||||
const emit = defineEmits(['nextStep','resend'])
|
||||
const emit = defineEmits(['nextStep'])
|
||||
|
||||
// Reactive data
|
||||
const loading = ref(false)
|
||||
@@ -66,24 +68,88 @@ const cIndex = computed(() => {
|
||||
// const lastCode = computed(() => getCtData.value[ctSize.value - 1])
|
||||
|
||||
const countdown = ref(60)
|
||||
const handleCountdown = () => {
|
||||
const timer = setInterval(() => {
|
||||
const countdownTimer = ref<number | null>(null)
|
||||
const COUNTDOWN_KEY = 'verify_code_countdown'
|
||||
const COUNTDOWN_EMAIL_KEY = 'verify_code_email'
|
||||
const COUNTDOWN_DURATION = 60 // 60秒倒计时
|
||||
|
||||
// 清除倒计时数据
|
||||
const clearCountdownData = () => {
|
||||
removeLocal(COUNTDOWN_KEY)
|
||||
removeLocal(COUNTDOWN_EMAIL_KEY)
|
||||
}
|
||||
|
||||
// 保存倒计时开始时间
|
||||
const saveCountdownStart = () => {
|
||||
const timestamp = Date.now()
|
||||
setLocal(String(timestamp), COUNTDOWN_KEY)
|
||||
setLocal(props.email, COUNTDOWN_EMAIL_KEY)
|
||||
}
|
||||
|
||||
// 从 localStorage 恢复倒计时
|
||||
const restoreCountdown = () => {
|
||||
const savedTimestamp = getLocal(COUNTDOWN_KEY)
|
||||
const savedEmail = getLocal(COUNTDOWN_EMAIL_KEY)
|
||||
|
||||
// 检查是否有保存的倒计时,且是同一个邮箱
|
||||
if (savedTimestamp && savedEmail === props.email) {
|
||||
const elapsed = Math.floor((Date.now() - Number(savedTimestamp)) / 1000)
|
||||
const remaining = COUNTDOWN_DURATION - elapsed
|
||||
|
||||
if (remaining > 0) {
|
||||
// 如果还有剩余时间,恢复倒计时
|
||||
countdown.value = remaining
|
||||
startCountdown()
|
||||
return true
|
||||
} else {
|
||||
// 如果已经过期,清除数据
|
||||
clearCountdownData()
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 开始倒计时
|
||||
const startCountdown = () => {
|
||||
// 清除之前的定时器
|
||||
if (countdownTimer.value) {
|
||||
clearInterval(countdownTimer.value)
|
||||
}
|
||||
|
||||
countdownTimer.value = setInterval(() => {
|
||||
countdown.value--
|
||||
if (countdown.value <= 0) {
|
||||
clearInterval(timer)
|
||||
if (countdownTimer.value) {
|
||||
clearInterval(countdownTimer.value)
|
||||
countdownTimer.value = null
|
||||
}
|
||||
}, 1000)
|
||||
clearCountdownData()
|
||||
}
|
||||
}, 1000) as unknown as number
|
||||
}
|
||||
|
||||
const handleSendVerifyCode = () => {
|
||||
handleCountdown()
|
||||
// 发送验证码
|
||||
const handleSendVerifyCode = async () => {
|
||||
if (loading.value) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
await precheckEmail({ email: props.email })
|
||||
showToast('the verification code has been sent to your email')
|
||||
countdown.value = COUNTDOWN_DURATION
|
||||
saveCountdownStart()
|
||||
startCountdown()
|
||||
} catch (error) {
|
||||
console.error('发送验证码失败:', error)
|
||||
showToast('Failed to send verification code, please try again')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleResend = () => {
|
||||
const handleResend = async () => {
|
||||
if (countdown.value > 0) return
|
||||
countdown.value = 60
|
||||
handleSendVerifyCode()
|
||||
emit('resend')
|
||||
await handleSendVerifyCode()
|
||||
}
|
||||
|
||||
const handleConfirmCaptcha = () => {
|
||||
@@ -97,6 +163,12 @@ const handleConfirmCaptcha = () => {
|
||||
showToast('please enter the correct verification code.')
|
||||
return
|
||||
}
|
||||
// 验证成功后清除倒计时数据
|
||||
clearCountdownData()
|
||||
if (countdownTimer.value) {
|
||||
clearInterval(countdownTimer.value)
|
||||
countdownTimer.value = null
|
||||
}
|
||||
emit('nextStep', { code: password })
|
||||
}
|
||||
|
||||
@@ -208,7 +280,24 @@ watch(cIndex, () => {
|
||||
// Lifecycle
|
||||
onMounted(() => {
|
||||
resetCaret()
|
||||
// 尝试恢复倒计时,如果无法恢复则发送验证码
|
||||
const restored = restoreCountdown()
|
||||
if (!restored) {
|
||||
// 如果没有恢复倒计时,说明倒计时已结束或不存在,需要发送验证码
|
||||
handleSendVerifyCode()
|
||||
}
|
||||
// 如果恢复了倒计时,说明倒计时还未结束,不发送验证码
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
// 组件卸载时清理定时器
|
||||
if (countdownTimer.value) {
|
||||
clearInterval(countdownTimer.value)
|
||||
countdownTimer.value = null
|
||||
}
|
||||
if (timeout.value) {
|
||||
clearTimeout(timeout.value)
|
||||
}
|
||||
})
|
||||
|
||||
// Expose methods for parent component
|
||||
|
||||
Reference in New Issue
Block a user