feat(auth): 添加验证码功能并优化登录注册页面 #1

Merged
minglipro merged 1 commits from dev into master 2025-08-20 14:07:42 +08:00
6 changed files with 147 additions and 41 deletions
Showing only changes of commit 5cc696b468 - Show all commits

View File

@ -1,5 +1,5 @@
import alova, { type AlovaResponse } from '@/plugins/alova';
import type { LoginBody, RegisterBody, ResUserInfo } from '@/apis/auth/type.ts';
import type { LoginBody, RegisterBody, ResCaptcha, ResUserInfo } from '@/apis/auth/type.ts';
export const login = (lb: LoginBody) =>
alova.Post<AlovaResponse<string>>('/auth/login', lb, {
@ -14,3 +14,8 @@ export const register = (rb: RegisterBody) => {
export const info = () => {
return alova.Get<AlovaResponse<ResUserInfo>>('/auth/info', { meta: { notbefore: true } });
};
export const captcha = () =>
alova.Get<AlovaResponse<ResCaptcha>>('/auth/captcha', {
meta: { notbefore: true },
});

View File

@ -1,6 +1,7 @@
export interface LoginBody {
passWold: string;
userName: string;
uuid: string;
}
export interface RegisterBody {
@ -27,3 +28,7 @@ export interface ResUserInfo {
user: User;
login: boolean;
}
export interface ResCaptcha {
captcha: string;
uuid: string;
}

View File

@ -14,10 +14,18 @@
<div v-loading="regis_login" class="card" style="margin-top: 20px">
<div f-c-c>
<NGradientText v-if="data.carData.p_result === 2 && data.carData.status === 2" size="65">可上磅</NGradientText>
<NGradientText v-if="data.carData.p_result === 40 && data.carData.status === 1" size="65">已出库</NGradientText>
<NGradientText v-if="data.carData.p_result === 2 && data.carData.status === 0" size="65">已入库</NGradientText>
<NGradientText v-if="data.carData.p_result === 40 && data.carData.status === 2" size="65">已撤销</NGradientText>
<NGradientText v-if="data.carData.p_result === 2 && data.carData.status === 1" size="65">已出库</NGradientText>
<NGradientText v-else-if="data.carData.p_result === 40 && data.carData.status === 1" size="65">
已撤销
</NGradientText>
<NGradientText v-else-if="data.carData.p_result === 2 && data.carData.status === 0" size="65">
已入库
</NGradientText>
<NGradientText v-else-if="data.carData.p_result === 40 && data.carData.status === 2" size="65">
已撤销
</NGradientText>
<NGradientText v-else-if="data.carData.p_result === 2 && data.carData.status === 1" size="65">
已出库
</NGradientText>
<NGradientText v-else size="65" type="error">不可上磅</NGradientText>
</div>
<div class="card-line"></div>
@ -58,13 +66,7 @@ import { onMounted, ref } from 'vue';
import { getMyCar } from '@/apis/bacth';
import { UserStore } from '@/plugins';
import {
NAlert,
NButton,
NDescriptions,
NDescriptionsItem,
NGradientText
} from 'naive-ui';
import { NAlert, NButton, NDescriptions, NDescriptionsItem, NGradientText } from 'naive-ui';
import type { CarDataResType } from '@/apis/bacth/type.ts';
import UseApiLoading from '@/utils/UseApiLoading.ts';
@ -99,6 +101,7 @@ function getdata() {
getMyCars().then((a) => {
console.log(a.json().Data);
data.value = a.json().Data;
console.log(data.value);
});
}
onMounted(() => {

View File

@ -17,6 +17,21 @@
<NFormItem label="密码" path="passWold">
<NInput v-model:value="fromdata.passWold" placeholder="请输入密码" type="password" />
</NFormItem>
<NFormItem label="验证码" path="captcha">
<div style="display: flex; width: 100%">
<NInput
v-model:value="fromdata.captcha"
placeholder="请输入验证码"
style="flex-grow: 1; border-bottom-right-radius: 0; border-top-right-radius: 0" />
<img
:src="cpaimg"
b-r
height="34"
style="border-bottom-right-radius: 3px; border-top-right-radius: 3px"
width="85"
@click="captchas" />
</div>
</NFormItem>
<NFormItem label=" ">
<NCheckbox v-model:checked="userStore.userDataRemberData.renb">记住我</NCheckbox>
</NFormItem>
@ -33,20 +48,33 @@
</div>
</template>
<script lang="ts" setup>
import { type FormInst, NButton, NCheckbox, NForm, NFormItem, NGradientText, NInput, NText } from 'naive-ui';
import {
type FormInst,
type FormItemRule,
NButton,
NCheckbox,
NForm,
NFormItem,
NGradientText,
NInput,
NText,
} from 'naive-ui';
import { onMounted, reactive, ref } from 'vue';
import message from '@/utils/message.ts';
import { login } from '@/apis/auth';
import { captcha, login } from '@/apis/auth';
import { UserStore } from '@/plugins';
import UseApiLoading from '@/utils/UseApiLoading.ts';
const formRef = ref<FormInst | null>(null);
const cpaimg = ref('');
const userStore = UserStore();
const fromdata = reactive({
passWold: '',
userName: '',
captcha: '',
uuid: '',
});
onMounted(() => {
@ -54,6 +82,7 @@ onMounted(() => {
fromdata.userName = userStore.userDataRemberData.user;
fromdata.passWold = userStore.userDataRemberData.pass;
}
captchas();
});
const [[loading_login], logins] = UseApiLoading(login);
@ -61,7 +90,8 @@ const [[loading_login], logins] = UseApiLoading(login);
const regis = () => {
formRef.value?.validate((errors: any) => {
if (!errors) {
logins(fromdata).then((a) => {
logins(fromdata)
.then((a) => {
userStore.ishaslogin = true;
userStore.token = a.json().Data;
if (userStore.userDataRemberData.renb) {
@ -69,12 +99,22 @@ const regis = () => {
userStore.userDataRemberData.pass = fromdata.passWold;
}
window.location.replace('/');
})
.catch(() => {
captchas();
fromdata.captcha = '';
});
} else {
message.error('请确认 填写信息是否正确');
}
});
};
const captchas = () => {
captcha().then((a) => {
fromdata.uuid = a.json().Data.uuid;
cpaimg.value = a.json().Data.captcha;
});
};
const rules = {
userName: {
@ -89,6 +129,17 @@ const rules = {
message: '请输入密码',
trigger: ['input'],
},
captcha: {
key: 'captcha',
required: true,
message: '验证码格式不正确 4位数字',
trigger: ['input'],
validator(rule: FormItemRule, value: string) {
const a = RegExp('^\\d{4}$').test(value);
console.log(a);
return a;
},
},
};
</script>
<style lang="scss" scoped></style>

View File

@ -23,6 +23,21 @@
<NFormItem label="确认密码" path="passre">
<NInput v-model:value="fromdata.passre" placeholder="请输入确认密码" type="password" />
</NFormItem>
<NFormItem label="验证码" path="captcha">
<div style="display: flex; width: 100%">
<NInput
v-model:value="fromdata.captcha"
placeholder="请输入验证码"
style="flex-grow: 1; border-bottom-right-radius: 0; border-top-right-radius: 0" />
<img
:src="cpaimg"
b-r
height="34"
style="border-bottom-right-radius: 3px; border-top-right-radius: 3px"
width="85"
@click="captchas" />
</div>
</NFormItem>
</NForm>
<div f-c-c>
<NText style="padding-right: 5px">我已已经有账号了</NText>
@ -46,33 +61,44 @@ import {
NInput,
NText
} from 'naive-ui';
import { reactive, ref } from 'vue';
import { onMounted, reactive, ref } from 'vue';
import message from '@/utils/message.ts';
import { register } from '@/apis/auth';
import { router, UserStore } from '@/plugins';
import { captcha, register } from '@/apis/auth';
import { UserStore } from '@/plugins';
import UseApiLoading from '@/utils/UseApiLoading.ts';
const cpaimg = ref('');
const formRef = ref<FormInst | null>(null);
const userStore = UserStore();
const fromdata = reactive({ tel: '', car: '', pass: '', passre: '' });
const fromdata = reactive({ tel: '', car: '', pass: '', passre: '', captcha: '', uuid: '' });
const [[regis_login], regise] = UseApiLoading(register);
const regis = () => {
formRef.value?.validate((errors: any) => {
if (!errors) {
regise(fromdata).then((a) => {
regise(fromdata)
.then((a) => {
userStore.ishaslogin = true;
userStore.token = a.json().Data;
userStore.getLogin();
router.push({ name: 'index' });
window.location.replace('/');
})
.catch(() => {
captchas();
fromdata.captcha = '';
});
} else {
message.error('请确认 填写信息是否正确');
}
});
};
const captchas = () => {
captcha().then((a) => {
fromdata.uuid = a.json().Data.uuid;
cpaimg.value = a.json().Data.captcha;
});
};
const rules = {
tel: {
key: 'tel',
@ -97,14 +123,10 @@ const rules = {
pass: {
key: 'pass',
required: true,
message:
'密码强度低\n至少包含字母、数字、特殊字符最少9位并且不能连续出现3个大小连续或相同的数字(如456、654、888)',
message: '最小8位最大256位',
trigger: ['input'],
validator(rule: FormItemRule, value: string) {
return RegExp(
'^(?=.*\\d)(?!.*(\\d)\\1{2})(?!.*(012|123|234|345|456|567|678|789|987|876|765|654|543|432|321|210))(?=.*[a-zA-Z])(?=.*[^\\da-zA-Z\\s]).{1,9}$',
).test(value);
},
min: 8,
max: 256,
},
passre: {
key: 'passre',
@ -115,6 +137,18 @@ const rules = {
return fromdata.pass === value;
},
},
captcha: {
key: 'captcha',
required: true,
message: '验证码格式不正确 4位数字',
trigger: ['input'],
validator(rule: FormItemRule, value: string) {
const a = RegExp('^\\d{4}$').test(value);
console.log(a);
return a;
},
},
};
onMounted(captchas);
</script>
<style lang="scss" scoped></style>

View File

@ -3,6 +3,10 @@
html[theme="dark"] {
background-color: #202020;
color: #d8d8d8;
*[b-r] {
border: 1px solid rgb(62, 62, 62);
}
}
*[f-c-c] {
@ -15,3 +19,7 @@ a {
color: #1bbb44;
text-decoration: none;
}
*[b-r] {
border: 1px solid rgba(194, 194, 194, 1);
}