| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- <template>
- <div class="reset-password-container">
- <!-- 面包屑导航 -->
- <div class="breadcrumb">
- <span class="breadcrumb-item" @click="$router.push('/')">首页</span>
- <span class="separator">></span>
- <span class="breadcrumb-item" @click="$router.push('/enterprise/companyInfo')">客户中心</span>
- <span class="separator">></span>
- <span class="breadcrumb-item" @click="$router.push('/enterprise/securitySetting')">安全设置</span>
- <span class="separator">></span>
- <span class="breadcrumb-item active">重置密码</span>
- </div>
- <!-- 主体内容 -->
- <div class="reset-content">
- <div class="reset-title">重置密码</div>
- <!-- 步骤条 -->
- <div class="steps-container">
- <div class="step-item" :class="{ active: currentStep >= 1, done: currentStep > 1 }">
- <div class="step-circle">
- <el-icon v-if="currentStep > 1"><Check /></el-icon>
- <span v-else>1</span>
- </div>
- <div class="step-label">验证身份</div>
- </div>
- <div class="step-line" :class="{ active: currentStep > 1 }"></div>
- <div class="step-item" :class="{ active: currentStep >= 2, done: currentStep > 2 }">
- <div class="step-circle">
- <el-icon v-if="currentStep > 2"><Check /></el-icon>
- <span v-else>2</span>
- </div>
- <div class="step-label">设置新密码</div>
- </div>
- <div class="step-line" :class="{ active: currentStep > 2 }"></div>
- <div class="step-item" :class="{ active: currentStep >= 3 }">
- <div class="step-circle">
- <span>3</span>
- </div>
- <div class="step-label">完成</div>
- </div>
- </div>
- <!-- 步骤1:验证身份 -->
- <div class="step-content" v-if="currentStep === 1">
- <el-form ref="step1FormRef" :model="step1Form" :rules="step1Rules" label-width="100px" class="verify-form">
- <el-form-item label="手机号码:" prop="phone">
- <el-input v-model="step1Form.phone" disabled class="form-input" />
- <span class="form-tip">若该手机号已无法使用请联系客服</span>
- </el-form-item>
- <el-form-item label="验证码:" prop="code">
- <el-input v-model="step1Form.code" placeholder="短信验证码" class="form-input code-input" />
- <el-button link type="primary" class="send-code-btn" :disabled="countdown > 0" @click="handleSendCode">
- {{ countdown > 0 ? `${countdown}s后重发` : '发送验证码' }}
- </el-button>
- </el-form-item>
- <el-form-item label="" class="verify-checkbox">
- <el-checkbox v-model="step1Form.verified">点击验证</el-checkbox>
- </el-form-item>
- </el-form>
- <div class="step-actions">
- <el-button type="danger" class="next-btn" @click="handleNextStep">下一步</el-button>
- </div>
- </div>
- <!-- 步骤2:设置新密码 -->
- <div class="step-content" v-if="currentStep === 2">
- <el-form ref="step2FormRef" :model="step2Form" :rules="step2Rules" label-width="100px" class="password-form">
- <el-form-item label="新密码:" prop="newPassword">
- <el-input v-model="step2Form.newPassword" type="password" show-password placeholder="请输入新密码" class="form-input" />
- </el-form-item>
- <el-form-item label="确认密码:" prop="confirmPassword">
- <el-input v-model="step2Form.confirmPassword" type="password" show-password placeholder="请再次输入新密码" class="form-input" />
- </el-form-item>
- </el-form>
- <div class="step-actions">
- <el-button @click="currentStep = 1">上一步</el-button>
- <el-button type="danger" class="next-btn" @click="handleSubmit">确认修改</el-button>
- </div>
- </div>
- <!-- 步骤3:完成 -->
- <div class="step-content" v-if="currentStep === 3">
- <div class="success-content">
- <el-icon class="success-icon" color="#e60012" :size="60"><CircleCheckFilled /></el-icon>
- <div class="success-title">密码重置成功!</div>
- <div class="success-desc">您的登录密码已重置成功,请使用新密码登录</div>
- <el-button type="danger" @click="$router.push('/enterprise/securitySetting')">返回安全设置</el-button>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { ref, reactive } from 'vue';
- import { Check, CircleCheckFilled } from '@element-plus/icons-vue';
- import { ElMessage } from 'element-plus';
- import { useRoute } from 'vue-router';
- import { changePwd } from '@/api/pc/enterprise/index';
- const currentStep = ref(1);
- const route = useRoute();
- // 步骤1表单
- const step1FormRef = ref();
- const step1Form = reactive({
- phone: route.query.phone as any,
- code: '',
- verified: false
- });
- const countdown = ref(0);
- const step1Rules = {
- code: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
- };
- // 步骤2表单
- const step2FormRef = ref();
- const step2Form = reactive({
- newPassword: '',
- confirmPassword: ''
- });
- const validateConfirmPassword = (_rule: any, value: string, callback: any) => {
- if (value !== step2Form.newPassword) {
- callback(new Error('两次输入的密码不一致'));
- } else {
- callback();
- }
- };
- const step2Rules = {
- newPassword: [
- { required: true, message: '请输入新密码', trigger: 'blur' },
- { min: 6, max: 20, message: '密码长度为6-20位', trigger: 'blur' }
- ],
- confirmPassword: [
- { required: true, message: '请再次输入新密码', trigger: 'blur' },
- { validator: validateConfirmPassword, trigger: 'blur' }
- ]
- };
- // 发送验证码
- const handleSendCode = () => {
- countdown.value = 60;
- const timer = setInterval(() => {
- countdown.value--;
- if (countdown.value <= 0) {
- clearInterval(timer);
- }
- }, 1000);
- ElMessage.success('验证码已发送');
- };
- // 下一步
- const handleNextStep = async () => {
- const valid = await step1FormRef.value?.validate().catch(() => false);
- if (!valid) return;
- if (!step1Form.verified) {
- ElMessage.warning('请先点击验证');
- return;
- }
- currentStep.value = 2;
- };
- // 提交
- const handleSubmit = async () => {
- const valid = await step2FormRef.value?.validate().catch(() => false);
- if (!valid) return;
- try {
- const submitData = {
- phone: step1Form.phone,
- code: step1Form.code,
- password: step2Form.newPassword,
- confirmPassword: step2Form.confirmPassword
- };
- const res: any = await changePwd(submitData);
- if (res.code === 200) {
- ElMessage.success('密码重置成功');
- currentStep.value = 3;
- } else {
- ElMessage.error(res.msg || '密码修改失败');
- }
- } catch (error) {
- console.error('修改密码失败:', error);
- }
- };
- </script>
- <style scoped lang="scss">
- .reset-password-container {
- background: #f5f5f5;
- min-height: 100%;
- padding: 0;
- }
- // 面包屑
- .breadcrumb {
- padding: 15px 20px;
- font-size: 13px;
- color: #666;
- background: #fff;
- border-bottom: 1px solid #eee;
- .breadcrumb-item {
- cursor: pointer;
- &:hover {
- color: #e60012;
- }
- &.active {
- color: #333;
- cursor: default;
- &:hover {
- color: #333;
- }
- }
- }
- .separator {
- margin: 0 8px;
- color: #999;
- }
- }
- // 主体内容
- .reset-content {
- max-width: 800px;
- margin: 30px auto;
- padding: 30px 40px;
- background: #fff;
- border-radius: 4px;
- }
- .reset-title {
- font-size: 18px;
- font-weight: 500;
- color: #333;
- margin-bottom: 30px;
- }
- // 步骤条
- .steps-container {
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 50px;
- padding: 0 60px;
- }
- .step-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- .step-circle {
- width: 32px;
- height: 32px;
- border-radius: 50%;
- border: 2px solid #ddd;
- background: #fff;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 14px;
- color: #999;
- margin-bottom: 10px;
- }
- .step-label {
- font-size: 14px;
- color: #999;
- }
- &.active {
- .step-circle {
- border-color: #e60012;
- color: #e60012;
- }
- .step-label {
- color: #e60012;
- }
- }
- &.done {
- .step-circle {
- border-color: #e60012;
- background: #e60012;
- color: #fff;
- }
- .step-label {
- color: #e60012;
- }
- }
- }
- .step-line {
- flex: 1;
- height: 2px;
- background: #ddd;
- margin: 0 20px;
- margin-bottom: 30px;
- &.active {
- background: #e60012;
- }
- }
- // 表单
- .step-content {
- padding: 0 60px;
- }
- .verify-form,
- .password-form {
- max-width: 500px;
- margin: 0 auto;
- .form-input {
- width: 280px;
- }
- .code-input {
- width: 180px;
- }
- .form-tip {
- margin-left: 15px;
- font-size: 12px;
- color: #e60012;
- cursor: pointer;
- }
- .send-code-btn {
- margin-left: 15px;
- color: #e60012;
- }
- .verify-checkbox {
- :deep(.el-form-item__content) {
- margin-left: 100px !important;
- }
- }
- }
- // 操作按钮
- .step-actions {
- display: flex;
- justify-content: center;
- margin-top: 40px;
- .next-btn {
- width: 200px;
- height: 40px;
- }
- }
- // 成功页面
- .success-content {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 40px 0;
- .success-icon {
- margin-bottom: 20px;
- }
- .success-title {
- font-size: 20px;
- font-weight: 500;
- color: #333;
- margin-bottom: 10px;
- }
- .success-desc {
- font-size: 14px;
- color: #999;
- margin-bottom: 30px;
- }
- }
- </style>
|