124 lines
2.7 KiB
Vue
124 lines
2.7 KiB
Vue
<template>
|
|
<div class="visible-code">
|
|
<div class="title">{{ $t('Login.verifyEmail') }}</div>
|
|
<div class="tip" v-html="$t('Login.verifyCodeHasSent', { email: props.email })"></div>
|
|
<input-code @submit="onVerify" v-model="code" />
|
|
<el-button class="verify" @click="onVerify">{{ $t('Login.verify') }}</el-button>
|
|
<p class="time" v-if="time > 0">{{ $t('Login.resendCodeIn', { time: timeStr }) }}</p>
|
|
<p class="time" v-if="time === 0">
|
|
<span @click="onResend">{{ $t('Login.resendCode') }}</span>
|
|
</p>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { SendVerificationCode } from '@/api/login'
|
|
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
|
import { CountDown } from '@/utils/tools'
|
|
import InputCode from '@/components/input-code.vue'
|
|
import { useRouter } from 'vue-router'
|
|
const router = useRouter()
|
|
const emit = defineEmits(['submit'])
|
|
const props = defineProps({
|
|
email: ''
|
|
})
|
|
const code = ref('')
|
|
const time = ref(60)
|
|
const timeStr = computed(() => CountDown(time.value))
|
|
const timeout = ref(null)
|
|
const setTime = (s = 120) => {
|
|
clearTime()
|
|
time.value = s
|
|
timeout.value = setInterval(() => {
|
|
time.value--
|
|
if (time.value <= 0) {
|
|
clearTime()
|
|
time.value = 0
|
|
}
|
|
}, 1000)
|
|
}
|
|
const clearTime = () => {
|
|
time.value = -1
|
|
clearTimeout(timeout.value)
|
|
}
|
|
onBeforeUnmount(() => {
|
|
clearTime()
|
|
})
|
|
onMounted(() => {
|
|
// onSendCode()
|
|
})
|
|
const onSendCode = async () => {
|
|
const email = props.email
|
|
if (!email) {
|
|
console.warn('请输入邮箱')
|
|
return Promise.reject('请输入邮箱')
|
|
}
|
|
await SendVerificationCode({ email })
|
|
setTime()
|
|
return Promise.resolve()
|
|
}
|
|
const onResend = () => {
|
|
if (time.value > 0) return
|
|
onSendCode()
|
|
}
|
|
const onVerify = () => {
|
|
if (code.value.length !== 6) return
|
|
emit('submit', code.value)
|
|
}
|
|
defineExpose({
|
|
onSendCode
|
|
})
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.visible-code {
|
|
width: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
> .title {
|
|
font-weight: 600;
|
|
font-size: 4rem;
|
|
color: #252727;
|
|
font-family: SemiBold;
|
|
}
|
|
> .tip {
|
|
margin-top: 2rem;
|
|
font-size: 1.8rem;
|
|
color: #666;
|
|
font-family: Regular;
|
|
&:deep(span) {
|
|
color: #252727;
|
|
font-family: Medium;
|
|
}
|
|
}
|
|
> .input-code {
|
|
margin: 8.6rem 0;
|
|
}
|
|
> .verify {
|
|
width: 100%;
|
|
height: 6rem;
|
|
background: #252727;
|
|
font-size: 2rem;
|
|
border-radius: 0.8rem;
|
|
color: #fff;
|
|
font-weight: 600;
|
|
font-family: SemiBold;
|
|
}
|
|
> .time {
|
|
user-select: none;
|
|
margin-top: 2rem;
|
|
font-size: 1.6rem;
|
|
color: #666;
|
|
font-family: Regular;
|
|
> span {
|
|
color: #ff7a50;
|
|
text-decoration: underline;
|
|
cursor: pointer;
|
|
font-weight: 500;
|
|
font-family: Medium;
|
|
}
|
|
}
|
|
}
|
|
</style>
|