Merge branch 'main' of http://18.167.251.121:10003/aidlab/lanecarford_front
This commit is contained in:
@@ -22,7 +22,6 @@
|
|||||||
v-else-if="step === 'verify'"
|
v-else-if="step === 'verify'"
|
||||||
:ct="emailCode"
|
:ct="emailCode"
|
||||||
@nextStep="handleCheckVerifyCode"
|
@nextStep="handleCheckVerifyCode"
|
||||||
@resend="handleSendVerifyCode"
|
|
||||||
/>
|
/>
|
||||||
<Password v-else-if="step === 'password'" @sucess="handleSuccess" />
|
<Password v-else-if="step === 'password'" @sucess="handleSuccess" />
|
||||||
</div>
|
</div>
|
||||||
@@ -42,7 +41,7 @@ import Mail from './components/Mail.vue'
|
|||||||
import Verify from './components/Verify.vue'
|
import Verify from './components/Verify.vue'
|
||||||
import Password from './components/Password.vue'
|
import Password from './components/Password.vue'
|
||||||
import { showToast } from 'vant'
|
import { showToast } from 'vant'
|
||||||
import { precheckEmail, resetPassword } from '@/api/login'
|
import { resetPassword } from '@/api/login'
|
||||||
import { encryptPassword } from '@/utils/tools'
|
import { encryptPassword } from '@/utils/tools'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -80,10 +79,8 @@ const handleSendVerifyCode = (data: any) => {
|
|||||||
if (data?.email) {
|
if (data?.email) {
|
||||||
fromData.value.email = data?.email
|
fromData.value.email = data?.email
|
||||||
}
|
}
|
||||||
precheckEmail({ email: fromData.value.email }).then(() => {
|
// 只切换步骤,验证码的发送由 Verify 组件负责
|
||||||
showToast('the verification code has been sent to your email')
|
handleStep('verify')
|
||||||
handleStep('verify')
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCheckVerifyCode = (data: any) => {
|
const handleCheckVerifyCode = (data: any) => {
|
||||||
|
|||||||
@@ -31,8 +31,10 @@
|
|||||||
<div class="btn" @click="handleConfirmCaptcha">Confirm</div>
|
<div class="btn" @click="handleConfirmCaptcha">Confirm</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<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 { showToast } from 'vant'
|
||||||
|
import { getLocal, removeLocal, setLocal } from '@/utils/local'
|
||||||
|
import { precheckEmail } from '@/api/login'
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -48,7 +50,7 @@ const props = defineProps({
|
|||||||
|
|
||||||
const agreePolicy = ref(false)
|
const agreePolicy = ref(false)
|
||||||
// Emits
|
// Emits
|
||||||
const emit = defineEmits(['nextStep','resend'])
|
const emit = defineEmits(['nextStep'])
|
||||||
|
|
||||||
// Reactive data
|
// Reactive data
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
@@ -66,24 +68,88 @@ const cIndex = computed(() => {
|
|||||||
// const lastCode = computed(() => getCtData.value[ctSize.value - 1])
|
// const lastCode = computed(() => getCtData.value[ctSize.value - 1])
|
||||||
|
|
||||||
const countdown = ref(60)
|
const countdown = ref(60)
|
||||||
const handleCountdown = () => {
|
const countdownTimer = ref<number | null>(null)
|
||||||
const timer = setInterval(() => {
|
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--
|
countdown.value--
|
||||||
if (countdown.value <= 0) {
|
if (countdown.value <= 0) {
|
||||||
clearInterval(timer)
|
if (countdownTimer.value) {
|
||||||
|
clearInterval(countdownTimer.value)
|
||||||
|
countdownTimer.value = null
|
||||||
|
}
|
||||||
|
clearCountdownData()
|
||||||
}
|
}
|
||||||
}, 1000)
|
}, 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
|
if (countdown.value > 0) return
|
||||||
countdown.value = 60
|
await handleSendVerifyCode()
|
||||||
handleSendVerifyCode()
|
|
||||||
emit('resend')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleConfirmCaptcha = () => {
|
const handleConfirmCaptcha = () => {
|
||||||
@@ -97,6 +163,12 @@ const handleConfirmCaptcha = () => {
|
|||||||
showToast('please enter the correct verification code.')
|
showToast('please enter the correct verification code.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// 验证成功后清除倒计时数据
|
||||||
|
clearCountdownData()
|
||||||
|
if (countdownTimer.value) {
|
||||||
|
clearInterval(countdownTimer.value)
|
||||||
|
countdownTimer.value = null
|
||||||
|
}
|
||||||
emit('nextStep', { code: password })
|
emit('nextStep', { code: password })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +280,24 @@ watch(cIndex, () => {
|
|||||||
// Lifecycle
|
// Lifecycle
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
resetCaret()
|
resetCaret()
|
||||||
handleSendVerifyCode()
|
// 尝试恢复倒计时,如果无法恢复则发送验证码
|
||||||
|
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
|
// Expose methods for parent component
|
||||||
|
|||||||
Reference in New Issue
Block a user