|
|
@@ -0,0 +1,408 @@
|
|
|
+<template>
|
|
|
+ <div class="change-phone-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="change-content">
|
|
|
+ <div class="change-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">
|
|
|
+ <div class="phone-info">
|
|
|
+ <span>已绑定的手机:</span>
|
|
|
+ <span class="phone-number">180****7722</span>
|
|
|
+ </div>
|
|
|
+ <div class="phone-tip">若该手机号已无法使用请联系客服</div>
|
|
|
+
|
|
|
+ <el-form ref="step1FormRef" :model="step1Form" :rules="step1Rules" class="verify-form">
|
|
|
+ <el-form-item label="验证码:" prop="code">
|
|
|
+ <el-input v-model="step1Form.code" placeholder="短信验证码" class="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 class="verify-checkbox">
|
|
|
+ <el-checkbox v-model="step1Form.verified">点击验证</el-checkbox>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <div class="step-actions">
|
|
|
+ <el-button type="success" class="next-btn" @click="handleNextStep">下一步</el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 温馨提醒 -->
|
|
|
+ <div class="tips-box">
|
|
|
+ <div class="tips-title">温馨提醒</div>
|
|
|
+ <ul class="tips-list">
|
|
|
+ <li>为保障您的帐号安全,变更重要信息需要身份验证</li>
|
|
|
+ <li>若有疑问请联系在线客服或拨打400-111-0027(周一至周日 8:00-18:00)</li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 步骤2:修改手机号码 -->
|
|
|
+ <div class="step-content" v-if="currentStep === 2">
|
|
|
+ <el-form ref="step2FormRef" :model="step2Form" :rules="step2Rules" label-width="120px" class="phone-form">
|
|
|
+ <el-form-item label="新手机号码:" prop="newPhone">
|
|
|
+ <el-input v-model="step2Form.newPhone" placeholder="请输入新手机号码" class="form-input" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="验证码:" prop="newCode">
|
|
|
+ <el-input v-model="step2Form.newCode" placeholder="短信验证码" class="code-input" />
|
|
|
+ <el-button link type="primary" class="send-code-btn" :disabled="newCountdown > 0" @click="handleSendNewCode">
|
|
|
+ {{ newCountdown > 0 ? `${newCountdown}s后重发` : '发送验证码' }}
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div class="step-actions">
|
|
|
+ <el-button @click="currentStep = 1">上一步</el-button>
|
|
|
+ <el-button type="success" 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="#52c41a" :size="60"><CircleCheckFilled /></el-icon>
|
|
|
+ <div class="success-title">手机号码更换成功!</div>
|
|
|
+ <div class="success-desc">您的安全手机已更换为 {{ step2Form.newPhone }}</div>
|
|
|
+ <el-button type="success" @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'
|
|
|
+
|
|
|
+const currentStep = ref(1)
|
|
|
+
|
|
|
+// 步骤1表单
|
|
|
+const step1FormRef = ref()
|
|
|
+const step1Form = reactive({
|
|
|
+ code: '',
|
|
|
+ verified: false
|
|
|
+})
|
|
|
+
|
|
|
+const countdown = ref(0)
|
|
|
+
|
|
|
+const step1Rules = {
|
|
|
+ code: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
|
|
|
+}
|
|
|
+
|
|
|
+// 步骤2表单
|
|
|
+const step2FormRef = ref()
|
|
|
+const step2Form = reactive({
|
|
|
+ newPhone: '',
|
|
|
+ newCode: ''
|
|
|
+})
|
|
|
+
|
|
|
+const newCountdown = ref(0)
|
|
|
+
|
|
|
+const step2Rules = {
|
|
|
+ newPhone: [
|
|
|
+ { required: true, message: '请输入新手机号码', trigger: 'blur' },
|
|
|
+ { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ newCode: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
|
|
|
+}
|
|
|
+
|
|
|
+// 发送验证码(旧手机)
|
|
|
+const handleSendCode = () => {
|
|
|
+ countdown.value = 60
|
|
|
+ const timer = setInterval(() => {
|
|
|
+ countdown.value--
|
|
|
+ if (countdown.value <= 0) {
|
|
|
+ clearInterval(timer)
|
|
|
+ }
|
|
|
+ }, 1000)
|
|
|
+ ElMessage.success('验证码已发送')
|
|
|
+}
|
|
|
+
|
|
|
+// 发送验证码(新手机)
|
|
|
+const handleSendNewCode = () => {
|
|
|
+ if (!step2Form.newPhone) {
|
|
|
+ ElMessage.warning('请先输入新手机号码')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ newCountdown.value = 60
|
|
|
+ const timer = setInterval(() => {
|
|
|
+ newCountdown.value--
|
|
|
+ if (newCountdown.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
|
|
|
+
|
|
|
+ // TODO: 调用更换手机接口
|
|
|
+ ElMessage.success('手机号码更换成功')
|
|
|
+ currentStep.value = 3
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.change-phone-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; }
|
|
|
+}
|
|
|
+
|
|
|
+// 主体内容
|
|
|
+.change-content {
|
|
|
+ max-width: 800px;
|
|
|
+ margin: 30px auto;
|
|
|
+ padding: 30px 40px;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.change-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: #52c41a;
|
|
|
+ color: #52c41a;
|
|
|
+ }
|
|
|
+ .step-label { color: #52c41a; }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.done {
|
|
|
+ .step-circle {
|
|
|
+ border-color: #52c41a;
|
|
|
+ background: #52c41a;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ .step-label { color: #52c41a; }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.step-line {
|
|
|
+ flex: 1;
|
|
|
+ height: 2px;
|
|
|
+ background: #ddd;
|
|
|
+ margin: 0 20px;
|
|
|
+ margin-bottom: 30px;
|
|
|
+
|
|
|
+ &.active { background: #52c41a; }
|
|
|
+}
|
|
|
+
|
|
|
+// 步骤内容
|
|
|
+.step-content {
|
|
|
+ padding: 0 40px;
|
|
|
+}
|
|
|
+
|
|
|
+.phone-info {
|
|
|
+ text-align: center;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 10px;
|
|
|
+
|
|
|
+ .phone-number {
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.phone-tip {
|
|
|
+ text-align: center;
|
|
|
+ font-size: 13px;
|
|
|
+ color: #999;
|
|
|
+ margin-bottom: 30px;
|
|
|
+}
|
|
|
+
|
|
|
+// 表单
|
|
|
+.verify-form, .phone-form {
|
|
|
+ max-width: 400px;
|
|
|
+ margin: 0 auto;
|
|
|
+
|
|
|
+ .code-input {
|
|
|
+ width: 180px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-input {
|
|
|
+ width: 280px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .send-code-btn {
|
|
|
+ margin-left: 15px;
|
|
|
+ color: #52c41a;
|
|
|
+ }
|
|
|
+
|
|
|
+ .verify-checkbox {
|
|
|
+ :deep(.el-form-item__content) {
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 操作按钮
|
|
|
+.step-actions {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ margin-top: 30px;
|
|
|
+ gap: 15px;
|
|
|
+
|
|
|
+ .next-btn {
|
|
|
+ width: 200px;
|
|
|
+ height: 40px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 温馨提醒
|
|
|
+.tips-box {
|
|
|
+ margin-top: 40px;
|
|
|
+ padding: 20px;
|
|
|
+ background: #fffbe6;
|
|
|
+ border: 1px solid #ffe58f;
|
|
|
+ border-radius: 4px;
|
|
|
+
|
|
|
+ .tips-title {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #d48806;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .tips-list {
|
|
|
+ margin: 0;
|
|
|
+ padding-left: 20px;
|
|
|
+ font-size: 13px;
|
|
|
+ color: #666;
|
|
|
+ line-height: 1.8;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 成功页面
|
|
|
+.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>
|