perf: 合并用户平台框架修改
This commit is contained in:
@@ -83,15 +83,15 @@ async function getCheckCode() {
|
||||
<AButton type="primary" block size="large" shape="round" :loading="authStore.loginLoading" @click="handleSubmit">
|
||||
{{ $t('common.confirm') }}
|
||||
</AButton>
|
||||
<div class="flex-y-center justify-between">
|
||||
<!-- <div class="flex-y-center justify-between">-->
|
||||
<!-- <AButton class="h-34px flex-1" block @click="toggleLoginModule('code-login')">-->
|
||||
<!-- {{ t(loginModuleRecord['code-login']) }}-->
|
||||
<!-- </AButton>-->
|
||||
<div class="w-12px"></div>
|
||||
<AButton class="h-34px flex-1" block @click="toggleLoginModule('register')">
|
||||
{{ t(loginModuleRecord.register) }}
|
||||
</AButton>
|
||||
</div>
|
||||
<!-- <div class="w-12px"></div>-->
|
||||
<!-- <AButton class="h-34px flex-1" block @click="toggleLoginModule('register')">-->
|
||||
<!-- {{ t(loginModuleRecord.register) }}-->
|
||||
<!-- </AButton>-->
|
||||
<!-- </div>-->
|
||||
</ASpace>
|
||||
</AForm>
|
||||
</template>
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import {computed, reactive, ref} from 'vue';
|
||||
import {useI18n} from 'vue-i18n'; // 添加这行
|
||||
import {useAuthStore} from '@/store/modules/auth';
|
||||
import {useRouterPush} from '@/hooks/common/router';
|
||||
import {useAntdForm, useFormRules} from '@/hooks/common/form';
|
||||
import {useCaptcha} from '@/hooks/business/captcha';
|
||||
import {useWindowSize} from '@vueuse/core';
|
||||
import {registerTerms} from '@/views/_builtin/login/modules/terms';
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useAuthStore } from '@/store/modules/auth';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { useFormRules } from '@/hooks/common/form';
|
||||
import { useCaptcha } from '@/hooks/business/captcha';
|
||||
import { useWindowSize } from '@vueuse/core';
|
||||
import { registerTerms } from '@/views/_builtin/login/modules/terms';
|
||||
import dayjs from 'dayjs';
|
||||
import type {Rule} from 'ant-design-vue/es/form';
|
||||
import type { Rule } from 'ant-design-vue/es/form';
|
||||
|
||||
const { t } = useI18n();
|
||||
const authStore = useAuthStore();
|
||||
// 添加两个表单引用
|
||||
const basicFormRef = ref();
|
||||
const securityFormRef = ref();
|
||||
|
||||
defineOptions({
|
||||
name: 'Register'
|
||||
});
|
||||
|
||||
const { toggleLoginModule } = useRouterPush();
|
||||
const { formRef, validate } = useAntdForm();
|
||||
const { label, isCounting, loading, getCaptcha } = useCaptcha();
|
||||
|
||||
const { width } = useWindowSize();
|
||||
@@ -29,17 +31,19 @@ const currentStep = ref(0);
|
||||
|
||||
// 是否同意协议
|
||||
const agreeTerms = ref(false);
|
||||
|
||||
// 定义一个统一的数据模型
|
||||
interface RegisterModel {
|
||||
username: string;
|
||||
password: string;
|
||||
email: string;
|
||||
fullName: string;
|
||||
age:0,
|
||||
age: number;
|
||||
gender: string;
|
||||
phone: string;
|
||||
address: string;
|
||||
code: string;
|
||||
uuid: string;
|
||||
authType: string;
|
||||
}
|
||||
|
||||
@@ -49,11 +53,12 @@ const model = reactive<RegisterModel>({
|
||||
password: '',
|
||||
email: '',
|
||||
fullName: '',
|
||||
age:0,
|
||||
age: 0,
|
||||
gender: '',
|
||||
phone: '',
|
||||
address: '',
|
||||
code: '',
|
||||
uuid: '',
|
||||
authType: 'u'
|
||||
});
|
||||
|
||||
@@ -64,7 +69,6 @@ interface BasicFormModel {
|
||||
birthDate: string;
|
||||
gender: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
address: string;
|
||||
}
|
||||
|
||||
@@ -74,7 +78,6 @@ const basicModel = reactive<BasicFormModel>({
|
||||
birthDate: '',
|
||||
gender: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
address: ''
|
||||
});
|
||||
|
||||
@@ -82,6 +85,7 @@ const basicModel = reactive<BasicFormModel>({
|
||||
interface SecurityFormModel {
|
||||
email: string;
|
||||
code: string;
|
||||
uuid: string;
|
||||
password: string;
|
||||
confirmPassword: string;
|
||||
}
|
||||
@@ -89,27 +93,85 @@ interface SecurityFormModel {
|
||||
const securityModel = reactive<SecurityFormModel>({
|
||||
email: '',
|
||||
code: '',
|
||||
uuid: '',
|
||||
password: '',
|
||||
confirmPassword: ''
|
||||
});
|
||||
|
||||
// 第一步表单验证规则
|
||||
const basicRules = computed<Record<string, Rule | Rule[]>>(() => {
|
||||
const { formRules } = useFormRules();
|
||||
const validateUsername = async (_rule: Rule, value: string) => {
|
||||
if (value && (value.length < 4 || value.length > 20)) {
|
||||
return Promise.reject(t('page.login.register.usernameLengthLimit'));
|
||||
}
|
||||
if (value) {
|
||||
const { exists } = await authStore.checkUserRepeat({ username: value, authType: 'u' });
|
||||
if (exists) {
|
||||
return Promise.reject(t('page.login.register.usernameExists'));
|
||||
}
|
||||
}
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
const validatePhone = async (_rule: Rule, value: string) => {
|
||||
if (!value) return Promise.resolve();
|
||||
|
||||
const phonePattern = /^1[3-9]\d{9}$/;
|
||||
|
||||
if (!phonePattern.test(value)) {
|
||||
return Promise.reject(t('page.login.register.phoneInvalid'));
|
||||
}
|
||||
|
||||
const { exists } = await authStore.checkUserRepeat({ phonenumber: value, authType: 'u' });
|
||||
if (exists) {
|
||||
return Promise.reject(t('page.login.register.phoneExists'));
|
||||
}
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
return {
|
||||
username: formRules.username,
|
||||
email: formRules.email,
|
||||
username: [
|
||||
{ required: true, message: t('page.login.register.usernameRequired'), trigger: 'change' },
|
||||
{ validator: validateUsername, trigger: 'blur' }
|
||||
],
|
||||
phone: [{ validator: validatePhone, trigger: 'blur' }],
|
||||
birthDate: [{ required: true, message: t('page.login.register.birthDateRequired') }],
|
||||
phone: [{ pattern: /^1[3-9]\d{9}$/, message: t('form.phone.invalid'), trigger: 'blur' }]
|
||||
fullName: []
|
||||
};
|
||||
});
|
||||
|
||||
// 第三步表单验证规则
|
||||
const securityRules = computed<Record<string, Rule | Rule[]>>(() => {
|
||||
const { formRules, createConfirmPwdRule } = useFormRules();
|
||||
const { createConfirmPwdRule } = useFormRules();
|
||||
|
||||
const validateEmail = async (_rule: Rule, value: string) => {
|
||||
if (!value) {
|
||||
return Promise.reject(t('page.login.register.emailRequired'));
|
||||
}
|
||||
|
||||
const emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
|
||||
|
||||
if (!emailPattern.test(value)) {
|
||||
return Promise.reject(t('page.login.register.emailInvalid'));
|
||||
}
|
||||
|
||||
const { exists } = await authStore.checkUserRepeat({ email: value, authType: 'u' });
|
||||
if (exists) {
|
||||
return Promise.reject(t('page.login.register.emailExists'));
|
||||
}
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
return {
|
||||
code: formRules.code,
|
||||
password: formRules.pwd,
|
||||
email: [
|
||||
{ required: true, message: t('page.login.register.emailRequired'), trigger: 'change' },
|
||||
{ validator: validateEmail, trigger: 'blur' }
|
||||
],
|
||||
code: [{ required: true, message: t('page.login.register.codeRequired') }],
|
||||
password: [
|
||||
{ required: true, message: t('page.login.register.passwordRequired') },
|
||||
{ min: 6, message: t('page.login.register.passwordLength') }
|
||||
],
|
||||
confirmPassword: createConfirmPwdRule(securityModel.password)
|
||||
};
|
||||
});
|
||||
@@ -122,43 +184,61 @@ const terms = computed(() => {
|
||||
|
||||
// 步骤控制函数
|
||||
async function nextStep() {
|
||||
if (currentStep.value === 0) {
|
||||
await validate();
|
||||
// 复制电话号码到第三步
|
||||
securityModel.email = basicModel.email;
|
||||
}
|
||||
if (currentStep.value === 1) {
|
||||
if (!agreeTerms.value) {
|
||||
window.$message?.error(t('page.login.register.agreeTermsFirst'));
|
||||
return;
|
||||
try {
|
||||
if (currentStep.value === 0) {
|
||||
// 验证第一步表单
|
||||
await basicFormRef.value?.validate();
|
||||
}
|
||||
if (currentStep.value === 1) {
|
||||
if (!agreeTerms.value) {
|
||||
window.$message?.error(t('page.login.register.agreeTermsFirst'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 验证通过后增加步骤
|
||||
currentStep.value += 1;
|
||||
} catch (error) {
|
||||
// 验证失败时不增加步骤
|
||||
console.error('Validation failed:', error);
|
||||
}
|
||||
currentStep.value += 1;
|
||||
}
|
||||
|
||||
// 返回
|
||||
function prevStep() {
|
||||
currentStep.value -= 1;
|
||||
}
|
||||
//注册按钮
|
||||
|
||||
async function handleCaptcha() {
|
||||
const res = await getCaptcha(securityModel.email);
|
||||
if (res) {
|
||||
securityModel.uuid = res.data.uuid;
|
||||
if (res.data?.text) {
|
||||
securityModel.code = res.data.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 注册按钮
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
await validate();
|
||||
await securityFormRef.value?.validate();
|
||||
|
||||
// 整合表单数据
|
||||
model.username = basicModel.username;
|
||||
model.password = securityModel.password;
|
||||
model.email = securityModel.email;
|
||||
model.email = securityModel.email; // 使用第三步的 email
|
||||
model.fullName = basicModel.fullName;
|
||||
model.gender = basicModel.gender; // 直接使用 gender 值
|
||||
model.gender = basicModel.gender;
|
||||
model.phone = basicModel.phone;
|
||||
model.address = basicModel.address;
|
||||
model.code = securityModel.code;
|
||||
model.uuid = securityModel.uuid;
|
||||
|
||||
const success = await authStore.register({
|
||||
...model,
|
||||
age: dayjs().diff(dayjs(basicModel.birthDate), 'year'),
|
||||
sex: model.gender, // 直接使用 gender 值,不需要转换
|
||||
phonenumber: model.phone,
|
||||
sex: model.gender,
|
||||
phonenumber: model.phone
|
||||
});
|
||||
|
||||
if (success) {
|
||||
@@ -175,187 +255,196 @@ const showSteps = computed(() => !isMobile.value);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ASteps
|
||||
v-if="showSteps"
|
||||
:current="currentStep"
|
||||
size="small"
|
||||
class="max-w-full mb-16px"
|
||||
direction="horizontal"
|
||||
:responsive="false"
|
||||
>
|
||||
<AStep :title="t('page.login.register.basicInfo')" />
|
||||
<AStep :title="t('page.login.register.terms')" />
|
||||
<AStep :title="t('page.login.register.security')" />
|
||||
</ASteps>
|
||||
<div class="register-container">
|
||||
<ASteps
|
||||
v-if="showSteps"
|
||||
:current="currentStep"
|
||||
size="small"
|
||||
class="max-w-full mb-16px"
|
||||
direction="horizontal"
|
||||
:responsive="false"
|
||||
>
|
||||
<AStep :title="t('page.login.register.basicInfo')" />
|
||||
<AStep :title="t('page.login.register.terms')" />
|
||||
<AStep :title="t('page.login.register.security')" />
|
||||
</ASteps>
|
||||
|
||||
<div v-else class="mobile-step-indicator mb-16px text-center">
|
||||
{{ currentStep + 1 }}/3: {{
|
||||
currentStep === 0
|
||||
? t('page.login.register.basicInfo')
|
||||
: currentStep === 1
|
||||
? t('page.login.register.terms')
|
||||
: t('page.login.register.security')
|
||||
}}
|
||||
</div>
|
||||
<div v-else class="mobile-step-indicator mb-16px text-center">
|
||||
{{ currentStep + 1 }}/3: {{
|
||||
currentStep === 0
|
||||
? t('page.login.register.basicInfo')
|
||||
: currentStep === 1
|
||||
? t('page.login.register.terms')
|
||||
: t('page.login.register.security')
|
||||
}}
|
||||
</div>
|
||||
|
||||
<div class="step-content">
|
||||
<!-- 第一步:基本信息 -->
|
||||
<div v-if="currentStep === 0">
|
||||
<AForm
|
||||
ref="formRef"
|
||||
:model="basicModel"
|
||||
:rules="basicRules"
|
||||
:label-wrap="true"
|
||||
:label-col="{ span: 8 }"
|
||||
:wrapper-col="{ span: 16 }"
|
||||
>
|
||||
<ARow :gutter="[8,2]">
|
||||
<ACol :span="24" :lg="24">
|
||||
<AFormItem name="username" :label="t('page.login.register.username')">
|
||||
<AInput v-model:value="basicModel.username" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
<ACol :span="24" :lg="24">
|
||||
<AFormItem name="fullName" :label="t('page.login.register.fullName')">
|
||||
<AInput v-model:value="basicModel.fullName" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
<ACol :xs="12" :sm="12" :lg="24">
|
||||
<AFormItem name="birthDate" :label="t('page.login.register.birthDate')">
|
||||
<ADatePicker
|
||||
v-model:value="basicModel.birthDate"
|
||||
class="!w-full birth-date-picker"
|
||||
:placeholder="t('page.login.register.birthDatePlaceholder')"
|
||||
:disabled-date="(current: dayjs.Dayjs) => current && current.isAfter(dayjs())"
|
||||
<div class="step-content">
|
||||
<!-- 第一步:基本信息 -->
|
||||
<div v-show="currentStep === 0">
|
||||
<AForm
|
||||
ref="basicFormRef"
|
||||
:model="basicModel"
|
||||
:rules="basicRules"
|
||||
:label-wrap="true"
|
||||
:label-col="{ span: 8 }"
|
||||
:wrapper-col="{ span: 16 }"
|
||||
>
|
||||
<ARow :gutter="[8,2]">
|
||||
<ACol :span="24" :lg="24">
|
||||
<AFormItem name="username" :label="t('page.login.register.username')">
|
||||
<AInput v-model:value="basicModel.username" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
<ACol :span="24" :lg="24">
|
||||
<AFormItem name="fullName" :label="t('page.login.register.fullName')">
|
||||
<AInput v-model:value="basicModel.fullName" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
<ACol :xs="12" :sm="12" :lg="24">
|
||||
<AFormItem name="birthDate" :label="t('page.login.register.birthDate')">
|
||||
<ADatePicker
|
||||
v-model:value="basicModel.birthDate"
|
||||
class="!w-full birth-date-picker"
|
||||
:placeholder="t('page.login.register.birthDatePlaceholder')"
|
||||
:disabled-date="(current: dayjs.Dayjs) => current && current.isAfter(dayjs())"
|
||||
/>
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
<ACol :xs="12" :sm="12" :lg="24">
|
||||
<AFormItem name="gender" :label="t('page.login.register.gender')">
|
||||
<ASelect v-model:value="basicModel.gender">
|
||||
<ASelectOption value="0">{{ t('page.login.register.male') }}</ASelectOption>
|
||||
<ASelectOption value="1">{{ t('page.login.register.female') }}</ASelectOption>
|
||||
</ASelect>
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
<ACol :lg="24" :span="24">
|
||||
<AFormItem name="phone" :label="t('page.login.register.phone')">
|
||||
<AInput v-model:value="basicModel.phone" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
<ACol :lg="24" :span="24">
|
||||
<AFormItem name="address" :label="t('page.login.register.address')">
|
||||
<ATextarea v-model:value="basicModel.address" :rows="2" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
<ACol :lg="24" :span="24">
|
||||
<ASpace direction="vertical" size="small" class="w-full">
|
||||
<AButton type="primary" block size="small" @click="nextStep">
|
||||
{{ t('page.login.register.next') }}
|
||||
</AButton>
|
||||
<AButton block size="small" @click="toggleLoginModule('pwd-login')">
|
||||
{{ t('page.login.common.back') }}
|
||||
</AButton>
|
||||
</ASpace>
|
||||
</ACol>
|
||||
</ARow>
|
||||
</AForm>
|
||||
</div>
|
||||
|
||||
<!-- 第二步:协议 -->
|
||||
<div v-show="currentStep === 1">
|
||||
<ATextarea
|
||||
:value="terms"
|
||||
:rows="12"
|
||||
readonly
|
||||
class="mb-16px"
|
||||
size="small"
|
||||
:style="{ fontSize: '14px', lineHeight: '1.6' }"
|
||||
/>
|
||||
<div class="mb-16px">
|
||||
<ACheckbox
|
||||
v-model:checked="agreeTerms"
|
||||
class="terms-checkbox"
|
||||
>
|
||||
{{ t('page.login.register.agreeTerms') }}
|
||||
</ACheckbox>
|
||||
</div>
|
||||
<ASpace direction="vertical" size="small" class="w-full">
|
||||
<AButton type="primary" block size="small" :disabled="!agreeTerms" @click="nextStep">
|
||||
{{ t('page.login.register.next') }}
|
||||
</AButton>
|
||||
<AButton block size="small" @click="prevStep">
|
||||
{{ t('page.login.register.prev') }}
|
||||
</AButton>
|
||||
</ASpace>
|
||||
</div>
|
||||
|
||||
<!-- 第三步:安全信息 -->
|
||||
<div v-show="currentStep === 2">
|
||||
<AForm
|
||||
ref="securityFormRef"
|
||||
:model="securityModel"
|
||||
:rules="securityRules"
|
||||
:label-wrap="true"
|
||||
:label-col="{ span: 8 }"
|
||||
:wrapper-col="{ span: 16 }"
|
||||
class="compact-form"
|
||||
>
|
||||
<AFormItem name="email" :label="t('page.login.register.email')">
|
||||
<AInput
|
||||
v-model:value="securityModel.email"
|
||||
:placeholder="t('page.login.common.emailPlaceholder')"
|
||||
/>
|
||||
</AFormItem>
|
||||
<AFormItem name="code" :label="t('page.login.register.code')">
|
||||
<div class="w-full flex-y-center gap-8px">
|
||||
<AInput
|
||||
v-model:value="securityModel.code"
|
||||
:placeholder="t('page.login.common.codePlaceholder')"
|
||||
/>
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
<ACol :xs="12" :sm="12" :lg="24">
|
||||
<AFormItem name="gender" :label="t('page.login.register.gender')">
|
||||
<ASelect v-model:value="basicModel.gender">
|
||||
<ASelectOption value="male">{{ t('page.login.register.male') }}</ASelectOption>
|
||||
<ASelectOption value="female">{{ t('page.login.register.female') }}</ASelectOption>
|
||||
</ASelect>
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
<ACol :lg="24" :span="24">
|
||||
<AFormItem name="phone" :label="t('page.login.register.phone')">
|
||||
<AInput v-model:value="basicModel.phone" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
<ACol :lg="24" :span="24">
|
||||
<AFormItem name="email" :label="t('page.login.register.email')">
|
||||
<AInput v-model:value="basicModel.email" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
<ACol :lg="24" :span="24">
|
||||
<AFormItem name="address" :label="t('page.login.register.address')">
|
||||
<ATextarea v-model:value="basicModel.address" :rows="2" />
|
||||
</AFormItem>
|
||||
</ACol>
|
||||
<ACol :lg="24" :span="24">
|
||||
<ASpace direction="vertical" size="small" class="w-full">
|
||||
<AButton type="primary" block size="small" @click="nextStep">
|
||||
{{ t('page.login.register.next') }}
|
||||
<AButton
|
||||
size="small"
|
||||
:disabled="isCounting"
|
||||
:loading="loading"
|
||||
@click="handleCaptcha()"
|
||||
>
|
||||
{{ label }}
|
||||
</AButton>
|
||||
<AButton block size="small" @click="toggleLoginModule('pwd-login')">
|
||||
{{ t('page.login.common.back') }}
|
||||
</div>
|
||||
</AFormItem>
|
||||
<AFormItem name="password" :label="t('page.login.register.password')">
|
||||
<AInputPassword
|
||||
v-model:value="securityModel.password"
|
||||
:placeholder="t('page.login.common.passwordPlaceholder')"
|
||||
/>
|
||||
</AFormItem>
|
||||
<AFormItem name="confirmPassword" :label="t('page.login.register.confirmPassword')">
|
||||
<AInputPassword
|
||||
v-model:value="securityModel.confirmPassword"
|
||||
:placeholder="t('page.login.common.confirmPasswordPlaceholder')"
|
||||
/>
|
||||
</AFormItem>
|
||||
<AFormItem :wrapper-col="{ xs: { span: 24 }, sm: { span: 24 } }">
|
||||
<ASpace direction="vertical" size="small" class="w-full">
|
||||
<AButton type="primary" block size="small" @click="handleSubmit">
|
||||
{{ t('common.confirm') }}
|
||||
</AButton>
|
||||
<AButton block size="small" @click="prevStep">
|
||||
{{ t('page.login.register.prev') }}
|
||||
</AButton>
|
||||
</ASpace>
|
||||
</ACol>
|
||||
</ARow>
|
||||
</AForm>
|
||||
</div>
|
||||
|
||||
<!-- 第二步:协议 -->
|
||||
<div v-if="currentStep === 1">
|
||||
<ATextarea
|
||||
:value="terms"
|
||||
:rows="12"
|
||||
readonly
|
||||
class="mb-16px"
|
||||
size="small"
|
||||
:style="{ fontSize: '14px', lineHeight: '1.6' }"
|
||||
/>
|
||||
<div class="mb-16px">
|
||||
<ACheckbox
|
||||
v-model:checked="agreeTerms"
|
||||
class="terms-checkbox"
|
||||
>
|
||||
{{ t('page.login.register.agreeTerms') }}
|
||||
</ACheckbox>
|
||||
</AFormItem>
|
||||
</AForm>
|
||||
</div>
|
||||
<ASpace direction="vertical" size="small" class="w-full">
|
||||
<AButton type="primary" block size="small" :disabled="!agreeTerms" @click="nextStep">
|
||||
{{ t('page.login.register.next') }}
|
||||
</AButton>
|
||||
<AButton block size="small" @click="prevStep">
|
||||
{{ t('page.login.register.prev') }}
|
||||
</AButton>
|
||||
</ASpace>
|
||||
</div>
|
||||
|
||||
<!-- 第三步:安全信息 -->
|
||||
<div v-if="currentStep === 2">
|
||||
<AForm
|
||||
ref="formRef"
|
||||
:model="securityModel"
|
||||
:rules="securityRules"
|
||||
:label-wrap="true"
|
||||
:label-col="{ span: 8 }"
|
||||
:wrapper-col="{ span: 16 }"
|
||||
class="compact-form"
|
||||
>
|
||||
<AFormItem name="email" :label="t('page.login.register.email')">
|
||||
<AInput
|
||||
v-model:value="securityModel.email"
|
||||
:placeholder="t('page.login.common.emailPlaceholder')"
|
||||
/>
|
||||
</AFormItem>
|
||||
<AFormItem name="code" :label="t('page.login.register.code')">
|
||||
<div class="w-full flex-y-center gap-8px">
|
||||
<AInput
|
||||
v-model:value="securityModel.code"
|
||||
:placeholder="t('page.login.common.codePlaceholder')"
|
||||
/>
|
||||
<AButton
|
||||
size="small"
|
||||
:disabled="isCounting"
|
||||
:loading="loading"
|
||||
@click="getCaptcha(securityModel.email)"
|
||||
>
|
||||
{{ label }}
|
||||
</AButton>
|
||||
</div>
|
||||
</AFormItem>
|
||||
<AFormItem name="password" :label="t('page.login.register.password')">
|
||||
<AInputPassword
|
||||
v-model:value="securityModel.password"
|
||||
:placeholder="t('page.login.common.passwordPlaceholder')"
|
||||
/>
|
||||
</AFormItem>
|
||||
<AFormItem name="confirmPassword" :label="t('page.login.register.confirmPassword')">
|
||||
<AInputPassword
|
||||
v-model:value="securityModel.confirmPassword"
|
||||
:placeholder="t('page.login.common.confirmPasswordPlaceholder')"
|
||||
/>
|
||||
</AFormItem>
|
||||
<AFormItem :wrapper-col="{ xs: { span: 24 }, sm: { span: 24 } }">
|
||||
<ASpace direction="vertical" size="small" class="w-full">
|
||||
<AButton type="primary" block size="small" @click="handleSubmit">
|
||||
{{ t('common.confirm') }}
|
||||
</AButton>
|
||||
<AButton block size="small" @click="prevStep">
|
||||
{{ t('page.login.register.prev') }}
|
||||
</AButton>
|
||||
</ASpace>
|
||||
</AFormItem>
|
||||
</AForm>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.register-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.step-content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.step-form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
:deep(.ant-form) {
|
||||
.ant-form-item {
|
||||
@@ -433,6 +522,7 @@ const showSteps = computed(() => !isMobile.value);
|
||||
:deep(.ant-form-item-label) {
|
||||
white-space: normal;
|
||||
text-align: left;
|
||||
|
||||
> label {
|
||||
height: auto !important;
|
||||
padding-bottom: 4px;
|
||||
|
||||
@@ -80,10 +80,18 @@ async function init() {
|
||||
function clearChecks() {
|
||||
menuIds.value = [];
|
||||
}
|
||||
|
||||
const rootIds = ref([]);
|
||||
function fnModalTreeChecked(keys: any, info: any ) {
|
||||
let ids = Array.isArray(keys) ? keys : keys.checked;
|
||||
// ids = ids.concat(info.halfCheckedKeys);
|
||||
rootIds.value = info.halfCheckedKeys;
|
||||
menuIds.value = ids;
|
||||
}
|
||||
defineExpose({
|
||||
clearChecks,
|
||||
checkedKeys: menuIds,
|
||||
checkedKeys: ()=> {
|
||||
return menuIds.value.concat(rootIds.value).concat()
|
||||
},
|
||||
tree
|
||||
});
|
||||
</script>
|
||||
@@ -92,13 +100,15 @@ defineExpose({
|
||||
<div class="border-0.5 border-gray-300 rounded-md p-2 transition-all dark:border-dark-300" hover="border-gray-500">
|
||||
<SimpleScrollbar>
|
||||
<ATree
|
||||
v-model:checked-keys="menuIds"
|
||||
:selectable="false"
|
||||
:virtual="false"
|
||||
:tree-data="tree"
|
||||
checkable
|
||||
block-node
|
||||
/>
|
||||
:selectable="false"
|
||||
@check="fnModalTreeChecked"
|
||||
v-model:checked-keys="menuIds"
|
||||
:check-strictly="false"
|
||||
:tree-data="tree"
|
||||
>
|
||||
</ATree>
|
||||
</SimpleScrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { SimpleScrollbar } from '@sa/materials';
|
||||
import { useAntdForm, useFormRules } from '@/hooks/common/form';
|
||||
import { $t } from '@/locales';
|
||||
import { enableStatusOptions } from '@/constants/business';
|
||||
import { doPostRole, doPutRole } from '@/service/api/role';
|
||||
import {SimpleScrollbar} from '@sa/materials';
|
||||
import {useAntdForm, useFormRules} from '@/hooks/common/form';
|
||||
import {$t} from '@/locales';
|
||||
import {enableStatusOptions} from '@/constants/business';
|
||||
import {doPostRole, doPutRole} from '@/service/api/role';
|
||||
import MenuAuth from './menu-auth.vue';
|
||||
|
||||
defineOptions({
|
||||
@@ -32,8 +32,8 @@ const menuAuthRef = ref<InstanceType<typeof MenuAuth> | null>(null);
|
||||
|
||||
const authStore = useAuthStore();
|
||||
|
||||
const { formRef, validate, resetFields } = useAntdForm();
|
||||
const { defaultRequiredRule } = useFormRules();
|
||||
const {formRef, validate, resetFields} = useAntdForm();
|
||||
const {defaultRequiredRule} = useFormRules();
|
||||
|
||||
const title = computed(() => {
|
||||
const titles: Record<AntDesign.TableOperateType, string> = {
|
||||
@@ -73,7 +73,7 @@ function handleUpdateModelWhenEdit() {
|
||||
}
|
||||
|
||||
if (props.operateType === 'edit' && props.rowData) {
|
||||
model.value = { ...props.rowData, menuIds: [] };
|
||||
model.value = {...props.rowData, menuIds: []};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,9 +83,9 @@ function closeDrawer() {
|
||||
|
||||
async function handleSubmit() {
|
||||
await validate();
|
||||
const menuIds = transformMenuChildWithRootIds(menuAuthRef.value?.tree || [], model.value.menuIds);
|
||||
const menuIds = menuAuthRef.value?.checkedKeys();
|
||||
|
||||
const { error } = await (props.operateType === 'edit' ? doPutRole : doPostRole)({
|
||||
const {error} = await (props.operateType === 'edit' ? doPutRole : doPostRole)({
|
||||
...model.value,
|
||||
menuIds,
|
||||
menuCheckStrictly: true
|
||||
@@ -122,10 +122,10 @@ watch(
|
||||
<SimpleScrollbar>
|
||||
<AForm ref="formRef" py-20px pr-20px layout="vertical" :model="model" :rules="rules">
|
||||
<AFormItem :label="$t('page.manage.role.roleName')" name="roleName">
|
||||
<AInput v-model:value="model.roleName" :placeholder="$t('page.manage.role.form.roleName')" />
|
||||
<AInput v-model:value="model.roleName" :placeholder="$t('page.manage.role.form.roleName')"/>
|
||||
</AFormItem>
|
||||
<AFormItem :label="$t('page.manage.role.roleCode')" name="roleKey">
|
||||
<AInput v-model:value="model.roleKey" :placeholder="$t('page.manage.role.form.roleCode')" />
|
||||
<AInput v-model:value="model.roleKey" :placeholder="$t('page.manage.role.form.roleCode')"/>
|
||||
</AFormItem>
|
||||
<AFormItem :label="$t('page.manage.role.roleStatus')" name="status">
|
||||
<ARadioGroup v-model:value="model.status">
|
||||
@@ -135,7 +135,7 @@ watch(
|
||||
</ARadioGroup>
|
||||
</AFormItem>
|
||||
<AFormItem :label="$t('page.manage.role.roleDesc')" name="roleDesc">
|
||||
<AInput v-model:value="model.remark" :placeholder="$t('page.manage.role.form.roleDesc')" />
|
||||
<AInput v-model:value="model.remark" :placeholder="$t('page.manage.role.form.roleDesc')"/>
|
||||
</AFormItem>
|
||||
|
||||
<AFormItem>
|
||||
|
||||
Reference in New Issue
Block a user