LoongPanel-Asp/web/pages/changePassword.vue

166 lines
4.3 KiB
Vue
Raw Normal View History

2024-07-02 14:28:15 +08:00
<script setup lang="ts">
definePageMeta({
layout: 'login',
})
//导入yup
import * as yup from 'yup'
import {useToast} from "vue-toastification";
import Vcode from 'vue3-puzzle-vcode';
//创建表单
const form = reactive({
password: '',
confirmPassword: ''
})
2024-07-02 16:08:07 +08:00
const userId = useRoute().query.id;
2024-07-02 14:28:15 +08:00
const isShow=ref(false);
const toast=useToast()
const schema = yup.object().shape({
password: yup.string()
.required('密码为必填项')
.min(8, '密码至少需要8个字符')
.matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/, '密码必须包含至少一个小写字母、一个大写字母、一个数字和一个特殊字符(如 @$!%*?&')
.test('no-chinese', '密码不能包含中文字符', (value) => {
if (!value) return true; // 如果密码为空,不进行此测试
return !/[\u4e00-\u9fa5]/.test(value);
}),
confirmPassword: yup.string()
.required('确认密码为必填项')
.oneOf([yup.ref('password')], '两次输入的密码不一致')
.min(8, '确认密码至少需要8个字符')
.test('no-chinese', '确认密码不能包含中文字符', (value) => {
if (!value) return true; // 如果确认密码为空,不进行此测试
return !/[\u4e00-\u9fa5]/.test(value);
})
});
//表单提交事件
const handleSubmit = async () => {
try {
await schema.validate(form,{abortEarly: false})
// 表单验证通过,处理登录逻辑
isShow.value = true;
} catch (error:any) {
//收集每个错误
error.inner.forEach((e: any) => {
toast.error(e.message)
})
}
}
const onSuccess=()=>{
$fetch('/Api/Account/ChangePassword', {
method: 'GET',
params:{
2024-07-02 16:08:07 +08:00
userId:userId,
2024-07-02 14:28:15 +08:00
NewPassword:form.password,
2024-07-02 16:08:07 +08:00
token:useCookie('tokenPassword').value??""
2024-07-02 14:28:15 +08:00
},
baseURL: useRuntimeConfig().public.baseUrl,
}).then((res) => {
//清除临时token
2024-07-02 16:08:07 +08:00
useCookie('tokenPassword').value = ""
2024-07-02 14:28:15 +08:00
toast.success(res)
setTimeout(()=>{
navigateTo("/SignIn")
},2000)
}).finally(()=>{
isShow.value=false
}).catch(err=>{
toast.error(err.response._data)
})
}
</script>
<template>
<div class="change-password-layout">
<Vcode :show="isShow" @success="onSuccess"/>
<NuxtLink href="/signIn">< 返回</NuxtLink>
2024-07-02 16:08:07 +08:00
<div class="info" v-if="userId">
2024-07-02 14:28:15 +08:00
<h1>修改你的密码 👍</h1>
<h2>当前账号密码已过期,请重新设置以继续登录</h2>
2024-07-02 16:08:07 +08:00
</div >
<form class="form-box" @submit.prevent="handleSubmit" v-if="userId">
2024-07-02 14:28:15 +08:00
<div class="form-item">
<label>新的密码</label>
<input placeholder="最少8位" required type="password" minlength="8" v-model="form.password">
</div>
<div class="form-item">
<label>确认密码</label>
<input placeholder="最少8位" required type="password" minlength="8" v-model="form.confirmPassword">
</div>
<button type="submit">提交</button>
</form>
2024-07-02 16:08:07 +08:00
<h1 v-else>错误的请求</h1>
2024-07-02 14:28:15 +08:00
</div>
</template>
<style scoped lang="scss">
2024-07-02 16:08:07 +08:00
@import "../base";
2024-07-02 14:28:15 +08:00
.change-password-layout{
display: grid;
grid-template-rows: repeat(3,auto);
gap: 48px;
*{
@include SC_Font
}
}
.info{
display: flex;
flex-direction: column;
gap: 28px;
h1{
color: #0C1421;
text-align: center;
font-size: 36px;
font-style: normal;
font-weight: 800;
line-height: 100%; /* 36px */
letter-spacing: 0.36px;
}
h2{
color: #313957;
font-size: 20px;
font-style: normal;
font-weight: 400;
line-height: 160%; /* 32px */
letter-spacing: 0.2px;
}
}
.form-box{
display: flex;
gap: 24px;
flex-direction: column;
.form-item{
display: flex;
flex-direction: column;
gap: 8px;
label{
color: #0C1421;
font-feature-settings: 'clig' off, 'liga' off;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: 100%; /* 16px */
letter-spacing: 0.16px;
}
input{
padding: 16px;
border-radius: 12px;
border: 1px solid #D4D7E3;
background: #F7FBFF;
}
}
button{
display: flex;
padding: 16px 0;
align-items: center;
justify-content: center;
border-radius: 12px;
background: #162D3A;
color: #FFF;
text-align: center;
font-size: 20px;
font-weight: 400;
line-height: 100%; /* 20px */
letter-spacing: 2px;
}
}
</style>