88 行
2.9 KiB
Vue
88 行
2.9 KiB
Vue
|
|
<template>
|
||
|
|
<div class="page">
|
||
|
|
<el-card class="card">
|
||
|
|
<h2 class="title">找回密码</h2>
|
||
|
|
<el-steps :active="step" finish-status="success" style="margin-bottom:24px">
|
||
|
|
<el-step title="验证邮箱" />
|
||
|
|
<el-step title="重置密码" />
|
||
|
|
</el-steps>
|
||
|
|
|
||
|
|
<template v-if="step === 0">
|
||
|
|
<el-form ref="step0Ref" :model="form">
|
||
|
|
<el-form-item prop="email" :rules="[{required:true, type:'email', message:'邮箱格式错误'}]">
|
||
|
|
<el-input v-model="form.email" placeholder="注册邮箱" prefix-icon="Message" />
|
||
|
|
</el-form-item>
|
||
|
|
<el-form-item>
|
||
|
|
<div class="code-row">
|
||
|
|
<el-input v-model="form.code" placeholder="验证码" style="flex:1" />
|
||
|
|
<el-button :disabled="countdown > 0" @click="sendCode">
|
||
|
|
{{ countdown > 0 ? `${countdown}s` : '获取验证码' }}
|
||
|
|
</el-button>
|
||
|
|
</div>
|
||
|
|
</el-form-item>
|
||
|
|
<el-button type="primary" style="width:100%" @click="nextStep">下一步</el-button>
|
||
|
|
</el-form>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<template v-else>
|
||
|
|
<el-form ref="step1Ref" :model="form">
|
||
|
|
<el-form-item prop="newPassword" :rules="[{required:true, min:6}]">
|
||
|
|
<el-input v-model="form.newPassword" type="password" placeholder="新密码" show-password />
|
||
|
|
</el-form-item>
|
||
|
|
<el-button type="primary" style="width:100%" :loading="loading" @click="handleReset">
|
||
|
|
确认重置
|
||
|
|
</el-button>
|
||
|
|
</el-form>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<div style="text-align:center;margin-top:16px">
|
||
|
|
<router-link to="/login">返回登录</router-link>
|
||
|
|
</div>
|
||
|
|
</el-card>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup lang="ts">
|
||
|
|
import { ref, reactive } from 'vue'
|
||
|
|
import { useRouter } from 'vue-router'
|
||
|
|
import { ElMessage } from 'element-plus'
|
||
|
|
import { authApi } from '@/api/auth'
|
||
|
|
|
||
|
|
const router = useRouter()
|
||
|
|
const step = ref(0)
|
||
|
|
const loading = ref(false)
|
||
|
|
const countdown = ref(0)
|
||
|
|
const form = reactive({ email: '', code: '', newPassword: '' })
|
||
|
|
|
||
|
|
async function sendCode() {
|
||
|
|
if (!form.email) { ElMessage.warning('请输入邮箱'); return }
|
||
|
|
await authApi.forgotPassword(form.email)
|
||
|
|
ElMessage.success('验证码已发送')
|
||
|
|
countdown.value = 60
|
||
|
|
const t = setInterval(() => { if (--countdown.value <= 0) clearInterval(t) }, 1000)
|
||
|
|
}
|
||
|
|
|
||
|
|
function nextStep() {
|
||
|
|
if (!form.code) { ElMessage.warning('请输入验证码'); return }
|
||
|
|
step.value = 1
|
||
|
|
}
|
||
|
|
|
||
|
|
async function handleReset() {
|
||
|
|
loading.value = true
|
||
|
|
try {
|
||
|
|
await authApi.resetPassword(form.email, form.code, form.newPassword)
|
||
|
|
ElMessage.success('密码重置成功')
|
||
|
|
router.push('/login')
|
||
|
|
} finally {
|
||
|
|
loading.value = false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
.page { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: #f0f2f5; }
|
||
|
|
.card { width: 420px; }
|
||
|
|
.title { text-align: center; margin-bottom: 20px; }
|
||
|
|
.code-row { display: flex; gap: 8px; width: 100%; }
|
||
|
|
</style>
|