162 lines
4.3 KiB
Vue
162 lines
4.3 KiB
Vue
<template>
|
||
<div class="auth-container">
|
||
<div class="tech-decoration">
|
||
<div class="tech-circle"></div>
|
||
<div class="tech-circle"></div>
|
||
<div class="tech-circle"></div>
|
||
</div>
|
||
|
||
<div class="auth-card">
|
||
<div class="auth-header">
|
||
<h1 class="auth-title">找回密码</h1>
|
||
<p class="auth-subtitle">输入您的邮箱,我们将发送重置密码链接</p>
|
||
</div>
|
||
|
||
<el-form ref="forgotFormRef" :model="forgotForm" :rules="forgotRules" class="auth-form" @submit.prevent="handleSubmit">
|
||
<el-form-item prop="email">
|
||
<el-input v-model="forgotForm.email" placeholder="请输入注册邮箱" size="large" clearable @keyup.enter="handleSubmit">
|
||
<template #prefix>
|
||
<el-icon>
|
||
<Message />
|
||
</el-icon>
|
||
</template>
|
||
</el-input>
|
||
</el-form-item>
|
||
|
||
<el-form-item prop="captcha" v-if="showCaptcha">
|
||
<div style="display: flex; gap: 12px">
|
||
<el-input v-model="forgotForm.captcha" placeholder="请输入验证码" size="large" style="flex: 1">
|
||
<template #prefix>
|
||
<el-icon>
|
||
<Key />
|
||
</el-icon>
|
||
</template>
|
||
</el-input>
|
||
<el-button type="info" size="large" :disabled="captchaDisabled" @click="sendCaptcha">
|
||
{{ captchaButtonText }}
|
||
</el-button>
|
||
</div>
|
||
</el-form-item>
|
||
|
||
<el-button type="primary" :loading="loading" size="large" style="width: 100%" @click="handleSubmit">
|
||
{{ loading ? '提交中...' : '发送重置链接' }}
|
||
</el-button>
|
||
</el-form>
|
||
|
||
<div class="auth-footer">
|
||
<p class="auth-footer-text">
|
||
想起密码了?
|
||
<router-link to="/login" class="auth-link"> 返回登录 </router-link>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { reactive, ref } from 'vue'
|
||
import { useRouter } from 'vue-router'
|
||
import { ElMessage } from 'element-plus'
|
||
import '@/assets/style/auth.scss'
|
||
|
||
const router = useRouter()
|
||
const forgotFormRef = ref(null)
|
||
const loading = ref(false)
|
||
const showCaptcha = ref(false)
|
||
const captchaDisabled = ref(false)
|
||
const countdown = ref(60)
|
||
|
||
// Forgot password form data
|
||
const forgotForm = reactive({
|
||
email: '',
|
||
captcha: '',
|
||
})
|
||
|
||
// Captcha button text
|
||
const captchaButtonText = ref('获取验证码')
|
||
|
||
// Form validation rules
|
||
const forgotRules = {
|
||
email: [
|
||
{ required: true, message: '请输入邮箱地址', trigger: 'blur' },
|
||
{ type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' },
|
||
],
|
||
captcha: [
|
||
{ required: true, message: '请输入验证码', trigger: 'blur' },
|
||
{ len: 6, message: '验证码为6位数字', trigger: 'blur' },
|
||
],
|
||
}
|
||
|
||
// Send captcha code
|
||
const sendCaptcha = async () => {
|
||
if (!forgotForm.email) {
|
||
ElMessage.warning('请先输入邮箱地址')
|
||
return
|
||
}
|
||
|
||
// Validate email format
|
||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||
if (!emailRegex.test(forgotForm.email)) {
|
||
ElMessage.warning('请输入正确的邮箱地址')
|
||
return
|
||
}
|
||
|
||
try {
|
||
// Simulate API call - Replace with actual API call
|
||
// Example: const response = await sendCaptchaApi(forgotForm.email)
|
||
|
||
await new Promise((resolve) => setTimeout(resolve, 500))
|
||
|
||
ElMessage.success('验证码已发送至您的邮箱')
|
||
|
||
// Start countdown
|
||
captchaDisabled.value = true
|
||
const timer = setInterval(() => {
|
||
countdown.value--
|
||
captchaButtonText.value = `${countdown.value}秒后重试`
|
||
|
||
if (countdown.value <= 0) {
|
||
clearInterval(timer)
|
||
captchaDisabled.value = false
|
||
captchaButtonText.value = '获取验证码'
|
||
countdown.value = 60
|
||
}
|
||
}, 1000)
|
||
|
||
showCaptcha.value = true
|
||
} catch (error) {
|
||
console.error('Send captcha failed:', error)
|
||
ElMessage.error('发送验证码失败,请稍后重试')
|
||
}
|
||
}
|
||
|
||
// Handle submit
|
||
const handleSubmit = async () => {
|
||
if (!forgotFormRef.value) return
|
||
|
||
try {
|
||
await forgotFormRef.value.validate()
|
||
loading.value = true
|
||
|
||
// Simulate API call - Replace with actual API call
|
||
// Example: const response = await forgotPasswordApi(forgotForm)
|
||
|
||
// Simulated delay
|
||
await new Promise((resolve) => setTimeout(resolve, 1500))
|
||
|
||
// Success message
|
||
ElMessage.success('密码重置链接已发送至您的邮箱,请注意查收')
|
||
|
||
// Redirect to login page
|
||
setTimeout(() => {
|
||
router.push('/login')
|
||
}, 2000)
|
||
} catch (error) {
|
||
console.error('Forgot password failed:', error)
|
||
ElMessage.error('提交失败,请检查邮箱地址和验证码')
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
</script>
|