perf: 错误信息提示调整

This commit is contained in:
rd
2025-09-08 17:19:56 +08:00
parent 0217d92bc0
commit b8a58091ad
2 changed files with 99 additions and 65 deletions

View File

@ -3,16 +3,22 @@
<div class="flex items-center w-400 h-100%"> <div class="flex items-center w-400 h-100%">
<div class="w-full bg-#fff rounded-16px px-40px py-32px flex flex-col items-center"> <div class="w-full bg-#fff rounded-16px px-40px py-32px flex flex-col items-center">
<img src="@/assets/img/icon-logo.png" alt="" width="144" height="36" class="mb-24px" /> <img src="@/assets/img/icon-logo.png" alt="" width="144" height="36" class="mb-24px" />
<Tabs v-model:activeKey="activeKey" class="mb-24px"> <Tabs v-model:activeKey="activeKey" class="mb-24px" @change="onTabChange">
<TabPane tab="密码登录" key="1" /> <TabPane tab="密码登录" key="1" />
<TabPane tab="短信登录" key="2" /> <TabPane tab="短信登录" key="2" />
</Tabs> </Tabs>
<Form ref="formRef" :model="loginForm" :rules="formRules" class="w-320 form-wrap"> <Form ref="formRef" :model="loginForm" :rules="formRules" class="w-320 form-wrap">
<FormItem name="mobile"> <FormItem name="mobile">
<Input v-model:value="loginForm.mobile" placeholder="请输入手机号" allowClear :maxlength="11" /> <Input
v-model:value="loginForm.mobile"
placeholder="请输入手机号"
allowClear
:maxlength="11"
@change="clearErrorMsg"
/>
</FormItem> </FormItem>
<FormItem v-if="isCaptchaLogin" name="captcha" class="captcha-form-item"> <FormItem v-if="isCaptchaLogin" name="captcha" class="captcha-form-item">
<Input v-model:value="loginForm.captcha" placeholder="请输入验证码" :maxlength="6"> <Input v-model:value="loginForm.captcha" placeholder="请输入验证码" :maxlength="6" @change="clearErrorMsg">
<template #suffix> <template #suffix>
<div class="w-79px flex justify-center whitespace-nowrap"> <div class="w-79px flex justify-center whitespace-nowrap">
<span <span
@ -27,13 +33,19 @@
</div> </div>
</template> </template>
</Input> </Input>
<p class="color-#F64B31 text-12px font-400 lh-20px font-family-regular" v-if="errMsg">
{{ errMsg }}
</p>
</FormItem> </FormItem>
<FormItem v-else name="password" class="password-form-item"> <FormItem v-else name="password" class="password-form-item">
<Input.Password v-model:value="loginForm.password" placeholder="请输入密码"> <Input.Password v-model:value="loginForm.password" placeholder="请输入密码" @change="clearErrorMsg">
<template #iconRender="visible"> <template #iconRender="visible">
<img :src="visible ? icon2 : icon1" width="20" height="20" class="cursor-pointer" /> <img :src="visible ? icon2 : icon1" width="20" height="20" class="cursor-pointer" />
</template> </template>
</Input.Password> </Input.Password>
<p class="color-#F64B31 text-12px font-400 lh-20px font-family-regular" v-if="errMsg">
{{ errMsg }}
</p>
</FormItem> </FormItem>
<FormItem class="mt-52px"> <FormItem class="mt-52px">
@ -134,6 +146,7 @@ const selectAccountModalRef = ref(null);
const accounts = ref([]); const accounts = ref([]);
const activeKey = ref('1'); const activeKey = ref('1');
const isLegalMobile = ref(false); const isLegalMobile = ref(false);
const errMsg = ref('');
const loginForm = reactive({ const loginForm = reactive({
mobile: '', mobile: '',
@ -149,9 +162,9 @@ const formRules = {
validator: (_rule: any, value: string) => { validator: (_rule: any, value: string) => {
if (!value) { if (!value) {
isLegalMobile.value = false; isLegalMobile.value = false;
return Promise.reject('手机号不能为空'); // return Promise.reject('手机号不能为空');
} }
if (!/^1[3-9]\d{9}$/.test(value)) { if (value && !/^1[3-9]\d{9}$/.test(value)) {
isLegalMobile.value = false; isLegalMobile.value = false;
return Promise.reject('手机号格式不正确'); return Promise.reject('手机号格式不正确');
} else { } else {
@ -164,33 +177,33 @@ const formRules = {
], ],
password: [ password: [
{ {
required: true, // required: true,
validator: (_rule: any, value: string) => { // validator: (_rule: any, value: string) => {
if (!value) { // if (!value) {
return Promise.reject('请输入密码'); // return Promise.reject('请输入密码');
} // }
if (value.length < 6) { // if (value.length < 6) {
return Promise.reject('密码长度不能小于6位'); // return Promise.reject('密码长度不能小于6位');
} // }
return Promise.resolve(); // return Promise.resolve();
}, // },
trigger: ['blur'], // trigger: ['blur'],
}, },
], ],
captcha: [ captcha: [
{ {
required: true, // required: true,
validator: (_rule: any, value: string) => { // validator: (_rule: any, value: string) => {
if (!value) { // if (!value) {
return Promise.reject('请输入验证码'); // return Promise.reject('请输入验证码');
} // }
if (!/^\d{6}$/.test(value)) { // if (!/^\d{6}$/.test(value)) {
return Promise.reject('验证码必须是6位数字'); // return Promise.reject('验证码必须是6位数字');
} else { // } else {
return Promise.resolve(); // return Promise.resolve();
} // }
}, // },
trigger: ['blur'], // trigger: ['blur'],
}, },
], ],
}; };
@ -202,6 +215,10 @@ const canGetCaptcha = computed(() => {
return isLegalMobile.value && countdown.value === 0; return isLegalMobile.value && countdown.value === 0;
}); });
const clearErrorMsg = () => {
errMsg.value = '';
};
const disabledSubmitBtn = computed(() => { const disabledSubmitBtn = computed(() => {
if (isCaptchaLogin.value) { if (isCaptchaLogin.value) {
return !hasCheck.value || !isLegalMobile.value || !loginForm.captcha.trim() || !/^\d{6}$/.test(loginForm.captcha); return !hasCheck.value || !isLegalMobile.value || !loginForm.captcha.trim() || !/^\d{6}$/.test(loginForm.captcha);
@ -243,6 +260,10 @@ const handleVerificationSubmit = async () => {
} }
}; };
const onTabChange = () => {
errMsg.value = '';
};
// 获取用户信息 // 获取用户信息
const getProfileInfo = async () => { const getProfileInfo = async () => {
const { code, data } = await fetchProfileInfo(); const { code, data } = await fetchProfileInfo();
@ -280,7 +301,7 @@ const handleSubmit = async () => {
submitting.value = true; submitting.value = true;
const _fn = isCaptchaLogin.value ? fetchAuthorizationsCaptcha : postLoginPassword; const _fn = isCaptchaLogin.value ? fetchAuthorizationsCaptcha : postLoginPassword;
const { code, data } = await _fn(loginForm); const { code, data, message: errorInfo } = await _fn(loginForm);
if (code === 200) { if (code === 200) {
// 处理登录成功逻辑 // 处理登录成功逻辑
@ -298,7 +319,9 @@ const handleSubmit = async () => {
getProfileInfo(); getProfileInfo();
} }
} catch (error) { } catch (error) {
// 错误信息会显示在输入框下方 if (error?.status === 400) {
errMsg.value = error.data?.message;
}
} finally { } finally {
submitting.value = false; submitting.value = false;
} }

View File

@ -10,24 +10,30 @@
</div> </div>
<Form ref="formRef" :model="formData" :rules="formRules" auto-label-width class="w-320 form-wrap"> <Form ref="formRef" :model="formData" :rules="formRules" auto-label-width class="w-320 form-wrap">
<FormItem name="mobile"> <FormItem name="mobile">
<Input v-model:value="formData.mobile" placeholder="请输入手机号" allowClear :maxlength="11" /> <Input
v-model:value="formData.mobile"
placeholder="请输入手机号"
allowClear
:maxlength="11"
@change="clearErrorMsg"
/>
</FormItem> </FormItem>
<FormItem name="password" class="password-form-item"> <FormItem name="password" class="password-form-item">
<Input.Password v-model:value="formData.password" placeholder="新密码"> <Input.Password v-model:value="formData.password" placeholder="新密码" @change="clearErrorMsg">
<template #iconRender="visible"> <template #iconRender="visible">
<img :src="visible ? icon2 : icon1" width="20" height="20" class="cursor-pointer" /> <img :src="visible ? icon2 : icon1" width="20" height="20" class="cursor-pointer" />
</template> </template>
</Input.Password> </Input.Password>
</FormItem> </FormItem>
<FormItem name="confirm_password" class="password-form-item"> <FormItem name="confirm_password" class="password-form-item">
<Input.Password v-model:value="formData.confirm_password" placeholder="密码确认"> <Input.Password v-model:value="formData.confirm_password" placeholder="密码确认" @change="clearErrorMsg">
<template #iconRender="visible"> <template #iconRender="visible">
<img :src="visible ? icon2 : icon1" width="20" height="20" class="cursor-pointer" /> <img :src="visible ? icon2 : icon1" width="20" height="20" class="cursor-pointer" />
</template> </template>
</Input.Password> </Input.Password>
</FormItem> </FormItem>
<FormItem name="captcha" class="captcha-form-item"> <FormItem name="captcha" class="captcha-form-item">
<Input v-model:value="formData.captcha" placeholder="请输入验证码" :maxlength="6"> <Input v-model:value="formData.captcha" placeholder="请输入验证码" :maxlength="6" @change="clearErrorMsg">
<template #suffix> <template #suffix>
<div class="w-79px flex justify-center whitespace-nowrap"> <div class="w-79px flex justify-center whitespace-nowrap">
<span <span
@ -140,9 +146,8 @@ const formRules = {
validator: (_rule, value) => { validator: (_rule, value) => {
if (!value) { if (!value) {
isLegalMobile.value = false; isLegalMobile.value = false;
return Promise.reject('手机号不能为空');
} }
if (!/^1[3-9]\d{9}$/.test(value)) { if (value && !/^1[3-9]\d{9}$/.test(value)) {
isLegalMobile.value = false; isLegalMobile.value = false;
return Promise.reject('手机号格式不正确'); return Promise.reject('手机号格式不正确');
} else { } else {
@ -157,12 +162,12 @@ const formRules = {
{ {
required: true, required: true,
validator: (_rule, value) => { validator: (_rule, value) => {
if (!value) { // if (!value) {
return Promise.reject('请输入新密码'); // return Promise.reject('请输入新密码');
} // }
if (value.length < 6) { // if (value.length < 6) {
return Promise.reject('密码长度不能小于6位'); // return Promise.reject('密码长度不能小于6位');
} // }
if(formData.value.confirm_password) { if(formData.value.confirm_password) {
formRef.value.validateFields('confirm_password'); formRef.value.validateFields('confirm_password');
} }
@ -175,12 +180,12 @@ const formRules = {
{ {
required: true, required: true,
validator: (_rule, value) => { validator: (_rule, value) => {
if (!value) { // if (!value) {
return Promise.reject('请输入密码确认'); // return Promise.reject('请输入密码确认');
} // }
if (value.length < 6) { // if (value.length < 6) {
return Promise.reject('密码长度不能小于6位'); // return Promise.reject('密码长度不能小于6位');
} // }
if (value !== formData.value.password) { if (value !== formData.value.password) {
return Promise.reject('确认密码与设置的密码不同'); return Promise.reject('确认密码与设置的密码不同');
} }
@ -190,20 +195,20 @@ const formRules = {
}, },
], ],
captcha: [ captcha: [
{ // {
required: true, // required: true,
validator: (_rule, value) => { // validator: (_rule, value) => {
if (!value) { // // if (!value) {
return Promise.reject('请输入验证码'); // // return Promise.reject('请输入验证码');
} // // }
if (!/^\d{6}$/.test(value)) { // if (value && !/^\d{6}$/.test(value)) {
return Promise.reject('验证码必须是6位数字'); // return Promise.reject('验证码必须是6位数字');
} else { // } else {
return Promise.resolve(); // return Promise.resolve();
} // }
}, // },
trigger: ['blur'], // trigger: ['blur'],
}, // },
], ],
}; };
@ -227,6 +232,10 @@ const disabledSubmitBtn = computed(() => {
return !isPassPassword.value || !hasCheck.value || !isLegalMobile.value || !formData.value.password.trim(); return !isPassPassword.value || !hasCheck.value || !isLegalMobile.value || !formData.value.password.trim();
}); });
const clearErrorMsg = () => {
errMsg.value = '';
};
const validateField = (field) => { const validateField = (field) => {
formRef.value.validateFields(field); formRef.value.validateFields(field);
}; };
@ -304,7 +313,7 @@ const handleSubmit = async () => {
submitting.value = true; submitting.value = true;
const _fn = isResetPassword.value ? postForgetPassword : postRegister; const _fn = isResetPassword.value ? postForgetPassword : postRegister;
const { code, data } = await _fn(formData.value); const { code, data, message: errorInfo } = await _fn(formData.value);
if (code === 200) { if (code === 200) {
message.success(isResetPassword.value ? '重置成功' : '注册成功'); message.success(isResetPassword.value ? '重置成功' : '注册成功');
@ -329,7 +338,9 @@ const handleSubmit = async () => {
getProfileInfo(); getProfileInfo();
} }
} catch (error) { } catch (error) {
// 错误信息会显示在输入框下方 if (error?.status === 400) {
errMsg.value = error.data?.message;
}
} finally { } finally {
submitting.value = false; submitting.value = false;
} }