|
@@ -0,0 +1,206 @@
|
|
|
+<template>
|
|
|
+ <el-dialog
|
|
|
+ v-model="visible"
|
|
|
+ title="授权码确认"
|
|
|
+ width="500px"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ :close-on-press-escape="false"
|
|
|
+ align-center
|
|
|
+ append-to-body
|
|
|
+ @close="handleClose"
|
|
|
+ @open="modalBeforeOpen"
|
|
|
+ >
|
|
|
+ <div class="code-confirm-content">
|
|
|
+ <div class="progress-info">
|
|
|
+ <p>当前进度:{{ progress }}%</p>
|
|
|
+ <p>需要输入授权码 {{ requiredTimes }} 次进行确认</p>
|
|
|
+ <p>已输入次数:{{ inputHistory.length }}</p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-form
|
|
|
+ ref="formRef"
|
|
|
+ :model="formModel"
|
|
|
+ :rules="rules"
|
|
|
+ label-width="80px"
|
|
|
+ >
|
|
|
+ <el-form-item label="授权码" prop="currentCode">
|
|
|
+ <el-input
|
|
|
+ v-model.trim="formModel.currentCode"
|
|
|
+ type="password"
|
|
|
+ placeholder="请输入授权码"
|
|
|
+ show-password
|
|
|
+ maxlength="20"
|
|
|
+ @keyup.enter="confirmCurrentCode"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <span class="dialog-footer">
|
|
|
+ <el-button @click="close">取消</el-button>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ :loading="loading"
|
|
|
+ :disabled="!canSubmit"
|
|
|
+ @click="confirmCurrentCode"
|
|
|
+ >
|
|
|
+ {{ isLastStep ? '提交' : '确认' }}
|
|
|
+ </el-button>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+ import { ref, reactive, computed } from 'vue';
|
|
|
+ import type { FormInstance, FormRules } from 'element-plus';
|
|
|
+ import { ElMessage } from 'element-plus';
|
|
|
+ import useModal from '@/hooks/modal';
|
|
|
+
|
|
|
+ defineOptions({
|
|
|
+ name: 'CodeConfirmDialog',
|
|
|
+ });
|
|
|
+
|
|
|
+ interface Props {
|
|
|
+ progress: number; // 进度值
|
|
|
+ }
|
|
|
+
|
|
|
+ const props = defineProps<Props>();
|
|
|
+ const emit = defineEmits(['confirmed', 'cancelled']);
|
|
|
+
|
|
|
+ /* modal */
|
|
|
+ const { visible, open, close } = useModal();
|
|
|
+ defineExpose({ open, close });
|
|
|
+
|
|
|
+ const formRef = ref<FormInstance>();
|
|
|
+
|
|
|
+ interface FormModel {
|
|
|
+ currentCode: string;
|
|
|
+ }
|
|
|
+
|
|
|
+ const initialFormState: FormModel = {
|
|
|
+ currentCode: '',
|
|
|
+ };
|
|
|
+
|
|
|
+ const formModel = reactive<FormModel>({ ...initialFormState });
|
|
|
+ const inputHistory = ref<string[]>([]);
|
|
|
+ const currentStep = ref(1);
|
|
|
+
|
|
|
+ // 计算需要输入的次数
|
|
|
+ const requiredTimes = computed(() => {
|
|
|
+ if (props.progress <= 80) {
|
|
|
+ return 2;
|
|
|
+ }
|
|
|
+ if (props.progress > 80 && props.progress < 100) {
|
|
|
+ return 3;
|
|
|
+ }
|
|
|
+ if (props.progress === 100) {
|
|
|
+ return 4;
|
|
|
+ }
|
|
|
+ return 2;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 是否是最后一步
|
|
|
+ const isLastStep = computed(() => {
|
|
|
+ return currentStep.value === requiredTimes.value;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 是否可以提交
|
|
|
+ const canSubmit = computed(() => {
|
|
|
+ return formModel.currentCode.trim().length > 0;
|
|
|
+ });
|
|
|
+
|
|
|
+ const rules: FormRules<keyof FormModel> = {
|
|
|
+ currentCode: [
|
|
|
+ { required: true, message: '请输入授权码', trigger: 'blur' },
|
|
|
+ {
|
|
|
+ validator: (rule, value, callback) => {
|
|
|
+ // 如果不是第一次输入,需要与上一次输入进行比对
|
|
|
+ if (inputHistory.value.length > 0) {
|
|
|
+ const lastCode = inputHistory.value[inputHistory.value.length - 1];
|
|
|
+ if (value !== lastCode) {
|
|
|
+ callback(new Error('授权码与上一次输入不一致,请重新输入'));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ callback();
|
|
|
+ },
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+
|
|
|
+ // 确认当前输入的授权码
|
|
|
+ async function confirmCurrentCode() {
|
|
|
+ if (!formRef.value) return;
|
|
|
+
|
|
|
+ const valid = await formRef.value.validate().catch(() => false);
|
|
|
+ if (!valid) return;
|
|
|
+
|
|
|
+ const currentCode = formModel.currentCode.trim();
|
|
|
+
|
|
|
+ // 记录当前输入
|
|
|
+ inputHistory.value.push(currentCode);
|
|
|
+
|
|
|
+ // 检查是否已完成所有输入
|
|
|
+ if (inputHistory.value.length >= requiredTimes.value) {
|
|
|
+ // 提交授权码
|
|
|
+ submitCode(currentCode);
|
|
|
+ } else {
|
|
|
+ // 继续下一次输入
|
|
|
+ currentStep.value++;
|
|
|
+ formModel.currentCode = '';
|
|
|
+ ElMessage.success(`第${inputHistory.value.length}次确认成功,请继续输入`);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提交授权码
|
|
|
+ function submitCode(code: string) {
|
|
|
+ emit('confirmed', code);
|
|
|
+ close();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重置表单状态
|
|
|
+ const handleClose = () => {
|
|
|
+ formRef.value?.resetFields();
|
|
|
+ Object.assign(formModel, initialFormState);
|
|
|
+ inputHistory.value = [];
|
|
|
+ currentStep.value = 1;
|
|
|
+ emit('cancelled');
|
|
|
+ };
|
|
|
+
|
|
|
+ // 弹窗打开前的初始化
|
|
|
+ function modalBeforeOpen() {
|
|
|
+ // 重置所有状态
|
|
|
+ Object.assign(formModel, initialFormState);
|
|
|
+ inputHistory.value = [];
|
|
|
+ currentStep.value = 1;
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+ .code-confirm-content {
|
|
|
+ padding: 10px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-info {
|
|
|
+ margin-bottom: 20px;
|
|
|
+ padding: 15px;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ border-radius: 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-info p {
|
|
|
+ margin: 0;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ color: #606266;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .progress-info p:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #409eff;
|
|
|
+ }
|
|
|
+</style>
|