Add ResetPassword Page.

hikari
PeterAlbus 1 year ago
parent 53680f5f78
commit 251b7a0266

@ -1,7 +1,8 @@
import { createRouter, createWebHashHistory } from "vue-router";
import Nprogress from 'nprogress';
import Nprogress from "nprogress";
import { useUserStore } from "@/stores/user";
import { isLogin } from "@/services/userApi";
const router = createRouter({
history: createWebHashHistory(),
routes: [
@ -9,182 +10,191 @@ const router = createRouter({
path: "/",
name: "home",
component: () => import("../views/Home.vue"),
meta:{
title:'主页——PeterAlbus的博客',
content:{
keywords:'PeterAlbus,Vue,个人博客',
description:'PeterAlbus的博客主页'
meta: {
title: "主页——PeterAlbus的博客",
content: {
keywords: "PeterAlbus,Vue,个人博客",
description: "PeterAlbus的博客主页"
}
}
},
{
path: '/login',
name: 'Login',
component: () => import("../views/Login.vue"),
meta:{
title:'登录——PeterAlbus的博客',
content:{
keywords:'PeterAlbus,Vue',
description:'PeterAlbus的博客登录页'
path: "/login",
name: "Login",
component: () => import("../views/user/Login.vue"),
meta: {
title: "登录——PeterAlbus的博客",
content: {
keywords: "PeterAlbus,Vue",
description: "PeterAlbus的博客登录页"
}
}
},
{
path: '/register',
name: 'Register',
component: () => import("../views/Register.vue"),
meta:{
title:'注册——PeterAlbus的博客',
content:{
keywords:'PeterAlbus,Vue',
description:'PeterAlbus的博客注册页'
path: "/register",
name: "Register",
component: () => import("../views/user/Register.vue"),
meta: {
title: "注册——PeterAlbus的博客",
content: {
keywords: "PeterAlbus,Vue",
description: "PeterAlbus的博客注册页"
}
}
},
{
path: '/userCenter',
name: 'UserCenter',
component: () => import("../views/UserCenter.vue"),
meta:{
title:'用户中心——PeterAlbus的博客',
content:{
keywords:'PeterAlbus,Vue',
description:'PeterAlbus的博客用户中心'
path: "/userCenter",
name: "UserCenter",
component: () => import("../views/user/UserCenter.vue"),
meta: {
title: "用户中心——PeterAlbus的博客",
content: {
keywords: "PeterAlbus,Vue",
description: "PeterAlbus的博客用户中心"
}
}
},
{
path: '/blog',
name: 'Blog',
component: () => import("../views/Blog.vue"),
meta:{
title:'博文——PeterAlbus的博客',
content:{
keywords:'PeterAlbus,Vue',
description:'PeterAlbus的博客博文页'
path: "/blog",
name: "Blog",
component: () => import("../views/blog/Blog.vue"),
meta: {
title: "博文——PeterAlbus的博客",
content: {
keywords: "PeterAlbus,Vue",
description: "PeterAlbus的博客博文页"
}
}
},
{
path: '/about',
name: 'About',
component: () => import("../views/About.vue"),
meta:{
title:'关于我——PeterAlbus的博客',
content:{
keywords:'PeterAlbus,Vue',
description:'PeterAlbus的个人介绍'
path: "/about",
name: "About",
component: () => import("../views/blog/About.vue"),
meta: {
title: "关于我——PeterAlbus的博客",
content: {
keywords: "PeterAlbus,Vue",
description: "PeterAlbus的个人介绍"
}
}
},
{
path: '/document',
name: 'Document',
component: () => import("../views/Document.vue"),
meta:{
title:'归档——PeterAlbus的博客',
content:{
keywords:'PeterAlbus,Vue',
description:'PeterAlbus的博客归档页'
path: "/document",
name: "Document",
component: () => import("../views/blog/Document.vue"),
meta: {
title: "归档——PeterAlbus的博客",
content: {
keywords: "PeterAlbus,Vue",
description: "PeterAlbus的博客归档页"
}
}
},
{
path: '/photo',
name: 'Photo',
component: () => import("../views/Photo.vue"),
meta:{
title:'照片墙——PeterAlbus的博客',
content:{
keywords:'PeterAlbus,Vue',
description:'PeterAlbus的照片墙'
path: "/photo",
name: "Photo",
component: () => import("../views/photo/Photo.vue"),
meta: {
title: "照片墙——PeterAlbus的博客",
content: {
keywords: "PeterAlbus,Vue",
description: "PeterAlbus的照片墙"
}
}
},
{
path: '/types',
name: 'Types',
component: () => import("../views/Types.vue"),
meta:{
title:'分类查看——PeterAlbus的博客',
content:{
keywords:'PeterAlbus,Vue',
description:'PeterAlbus的博客列表'
path: "/types",
name: "Types",
component: () => import("../views/blog/Types.vue"),
meta: {
title: "分类查看——PeterAlbus的博客",
content: {
keywords: "PeterAlbus,Vue",
description: "PeterAlbus的博客列表"
}
}
},
{
path: '/editBlog',
name: 'EditBlog',
component: () => import("../views/EditBlog.vue"),
meta:{
title:'编辑/创建博客——PeterAlbus的博客',
content:{
keywords:'PeterAlbus,Vue',
description:'PeterAlbus的博客编辑页'
path: "/editBlog",
name: "EditBlog",
component: () => import("../views/blog/EditBlog.vue"),
meta: {
title: "编辑/创建博客——PeterAlbus的博客",
content: {
keywords: "PeterAlbus,Vue",
description: "PeterAlbus的博客编辑页"
}
}
},
{
path: '/uploadPhoto',
name: 'UploadPhoto',
component: () => import("../views/UploadPhoto.vue"),
meta:{
title:'上传照片——PeterAlbus的博客',
content:{
keywords:'PeterAlbus,Vue',
description:'PeterAlbus的博客'
path: "/uploadPhoto",
name: "UploadPhoto",
component: () => import("../views/photo/UploadPhoto.vue"),
meta: {
title: "上传照片——PeterAlbus的博客",
content: {
keywords: "PeterAlbus,Vue",
description: "PeterAlbus的博客"
}
}
},
{
path: '/addFriendLink',
name: 'AddFriendLink',
component: () => import("../views/AddFriendLink.vue"),
meta:{
title:'添加友情链接——PeterAlbus的博客',
content:{
keywords:'PeterAlbus,Vue,个人博客',
description:'PeterAlbus的博客'
path: "/addFriendLink",
name: "AddFriendLink",
component: () => import("../views/user/AddFriendLink.vue"),
meta: {
title: "添加友情链接——PeterAlbus的博客",
content: {
keywords: "PeterAlbus,Vue,个人博客",
description: "PeterAlbus的博客"
}
}
},
{
path: "/resetPassword",
name: "ResetPassword",
component: () => import("../views/user/ResetPassword.vue"),
meta: {
title: "重置密码——PeterAlbus的博客",
content: {
keywords: "PeterAlbus,Vue,个人博客",
description: "PeterAlbus的博客"
}
}
}
],
]
});
router.beforeEach((to, from, next) => {
Nprogress.start();
const userStore = useUserStore();
if (userStore.userId===''&&localStorage.getItem("token")) {
if (userStore.userId === "" && localStorage.getItem("token")) {
isLogin().then(res => {
userStore.updateUser(res.data)
userStore.updateUser(res.data);
}).catch(err => {
console.log(err)
localStorage.removeItem("token")
})
}
else if (userStore.userId!=''&&!localStorage.getItem("token")) {
userStore.logout()
}
else if (userStore.userId!=''&&localStorage.getItem("token")) {
console.log(err);
localStorage.removeItem("token");
});
} else if (userStore.userId != "" && !localStorage.getItem("token")) {
userStore.logout();
} else if (userStore.userId != "" && localStorage.getItem("token")) {
isLogin().then(res => {
userStore.updateUser(res.data)
userStore.updateUser(res.data);
}).catch(() => {
userStore.logout()
})
userStore.logout();
});
}
if((to.name=='Login'||to.name=='Register')&&userStore.userId!='')
{
next('/userCenter')
return
if ((to.name == "Login" || to.name == "Register") && userStore.userId != "") {
next("/userCenter");
return;
}
if(to.meta.content) {
const content = to.meta.content as any
document.querySelector('meta[name="keywords"]')?.setAttribute('content',content.keywords)
document.querySelector('meta[name="description"]')?.setAttribute('content',content.description)
if (to.meta.content) {
const content = to.meta.content as any;
document.querySelector("meta[name=\"keywords\"]")?.setAttribute("content", content.keywords);
document.querySelector("meta[name=\"description\"]")?.setAttribute("content", content.description);
}
if(to.meta.title) {
document.title = to.meta.title as string
if (to.meta.title) {
document.title = to.meta.title as string;
}
next();
});

@ -1,7 +1,7 @@
const env:string=import.meta.env.VITE_APP_ENV
export const BASE_URL:string|undefined = {
dev: "https://www.peteralbus.com:8089/",
dev: "http://localhost:8089/",
prod: "https://www.peteralbus.com:8089/",
test: "https://api.testserver.com/base/url",
}[env]

@ -28,4 +28,10 @@ export const changePhone = (data:object) => http.get(data, userUrl.setPhone);
export const changeMail = (data:object) => http.get(data, userUrl.setMail);
export const fetchResetPasswordVerifyCode = (account: string, type: string) =>
http.get({ account, type }, userUrl.applyResetPasswordVerifyCode);
export const resetPassword = (data:object) =>
http.get(data, userUrl.resetPassword);

@ -12,8 +12,8 @@
<h2 v-if="!loginByPhone"></h2>
<h2 v-if="loginByPhone"></h2>
<div class="switch">
<span v-if="!loginByPhone" @click="loginByPhone=true">使</span>
<span v-if="loginByPhone" @click="loginByPhone=false">使</span>
<span v-if="!loginByPhone" @click="loginByPhone=true;loginForm.userPhone=loginForm.userMail">使</span>
<span v-if="loginByPhone" @click="loginByPhone=false;loginForm.userMail=loginForm.userPhone">使</span>
</div>
</div>
<el-form
@ -41,6 +41,7 @@
<el-button plain color="#63a35c">注册</el-button>
</router-link>
</div>
<div class="reset_pass"><router-link to="/resetPassword">忘记密码?</router-link></div>
</el-form>
</el-col>
</el-row>
@ -157,4 +158,11 @@ const submitForm = async (formEl: FormInstance | undefined) => {
.switch:hover {
color: #63a35c;
}
.reset_pass {
margin-top: 10px;
text-align: center;
font-size: 0.8em;
color: #4B6186;
}
</style>

@ -64,8 +64,6 @@
import Banner from "@/components/Banner.vue";
import { computed, reactive, ref } from "vue";
import { ElMessage, ElMessageBox, FormInstance } from "element-plus";
import axios from "axios";
import qs from "qs";
import { useRouter } from "vue-router";
import { fetchMailVerifyCode, fetchPhoneVerifyCode, register } from "@/services/userApi";

@ -0,0 +1,244 @@
<template>
<Banner title="重置密码"></Banner>
<div class="main-container flex-box">
<div class="form-box">
<el-row style="height: 100%" justify="space-between">
<el-col :sm="12" :xs="0">
<el-image style="width: 100%;height: 100%;border-radius: 5px 0 0 5px;"
src="https://file.peteralbus.com/assets/blog/imgs/photo/DJI_0422.JPG" fit="cover" />
</el-col>
<el-col :sm="12" :xs="24" class="flex-box" style="padding: 20px">
<div style="margin: 0 30px 30px 30px">
<h2 v-if="!resetByPhone"></h2>
<h2 v-if="resetByPhone"></h2>
<div class="switch">
<span v-if="!resetByPhone" @click="resetByPhone=true;resetForm.userPhone=resetForm.userMail">使</span>
<span v-if="resetByPhone" @click="resetByPhone=false;resetForm.userMail=resetForm.userPhone">使</span>
</div>
</div>
<el-form
ref="ruleFormRef"
:model="resetForm"
:rules="rules"
label-width="100px"
class="demo-ruleForm"
size="default"
style="width: 100%;max-width: 400px"
>
<el-form-item label="邮箱" prop="userMail" v-if="!resetByPhone">
<el-input v-model="resetForm.userMail" />
</el-form-item>
<el-form-item label="手机" prop="userPhone" v-if="resetByPhone">
<el-input v-model="resetForm.userPhone" />
</el-form-item>
<el-form-item label="新密码" prop="userPassword">
<el-input v-model="resetForm.userPassword" type="password" />
</el-form-item>
<el-form-item label="确认密码" prop="userConfirmPassword">
<el-input v-model="resetForm.userConfirmPassword" type="password" />
</el-form-item>
<el-form-item label="验证码" prop="userVerifyCode" style="justify-content: space-between!important;">
<el-input v-model="resetForm.userVerifyCode" style="width: 70%" />
<el-button type="primary" class="get_verify_button" :disabled="!canGetVerifyCode"
@click="applyVerifyCode">
{{ verifyText }}
</el-button>
</el-form-item>
<div>
<el-button type="primary" style="color: white"
@click="submitForm(ruleFormRef)" color="#63a35c">重置密码
</el-button>&emsp;
</div>
<div class="go_login">
<router-link to="/login">前往登录</router-link>
</div>
</el-form>
</el-col>
</el-row>
</div>
</div>
</template>
<script setup lang="ts">
import Banner from "@/components/Banner.vue";
import { useRouter } from "vue-router";
import { reactive, ref } from "vue";
import { ElMessage, ElMessageBox, FormInstance } from "element-plus";
import { fetchResetPasswordVerifyCode, resetPassword } from "@/services/userApi";
const router = useRouter();
const ruleFormRef = ref<FormInstance>();
const resetForm = reactive({
userPhone: "",
userMail: "",
userPassword: "",
userConfirmPassword: "",
userVerifyCode: ""
});
const resetByPhone = ref(true);
const verifyText = ref("获取");
let time = 0;
const canGetVerifyCode = ref(true);
const timer = () => {
if (time > 0) {
verifyText.value = time + "s";
time--;
canGetVerifyCode.value = false;
setTimeout(timer, 1000);
} else {
canGetVerifyCode.value = true;
verifyText.value = "发送验证码";
}
};
const validatePass = (rule: any, value: any, callback: any) => {
if (value === "") {
callback(new Error("请输入密码"));
} else {
if (resetForm.userConfirmPassword !== "") {
if (!ruleFormRef.value) return;
ruleFormRef.value.validateField("userConfirmPassword", () => null);
}
callback();
}
};
const validateConfirmPass = (rule: any, value: any, callback: any) => {
if (value === "") {
callback(new Error("请再次输入密码"));
} else if (value !== resetForm.userPassword) {
callback(new Error("输入的两次密码不一致!"));
} else {
callback();
}
};
const validateEmail = (rule: any, value: any, callback: any) => {
if (resetByPhone.value) {
callback();
} else if (!value) {
callback(new Error("请输入邮箱"));
} else if (value.indexOf("@") == -1) {
callback(new Error("请输入正确格式的邮箱"));
} else {
callback();
}
};
const validatePhone = (rule: any, value: any, callback: any) => {
if (!resetByPhone.value) {
callback();
} else if (!value) {
callback(new Error("请输入手机号"));
} else if (!Number(value)) {
callback(new Error("请输入数字"));
} else if (value.length != 11) {
callback(new Error("请输入正确格式的11位手机号"));
} else {
callback();
}
};
const rules = reactive({
userMail: [
{ validator: validateEmail, trigger: "blur" }
],
userPhone: [
{ validator: validatePhone, trigger: "blur" }
],
userVerifyCode: [
{ required: true, message: "请输入验证码", trigger: "change" }
],
userPassword: [
{ validator: validatePass, trigger: "blur" },
{ min: 6, max: 60, message: "密码长度必须在6到60位之间", trigger: "blur" }
],
userConfirmPassword: [
{ validator: validateConfirmPass, trigger: "blur" },
{ min: 6, max: 60, message: "密码长度必须在6到60位之间", trigger: "blur" }
]
});
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
const account = resetByPhone.value ? resetForm.userPhone : resetForm.userMail;
resetPassword({
account,
newPassword: resetForm.userPassword,
verifyCode: resetForm.userVerifyCode
}).then(() => {
ElMessage.success("重置密码成功,请登录!");
router.push("/login")
});
}
});
};
const applyVerifyCode = () => {
const type = resetByPhone.value ? "phone" : "mail";
const account = resetByPhone.value ? resetForm.userPhone : resetForm.userMail;
fetchResetPasswordVerifyCode(account, type).then(() => {
ElMessage.success("验证码已发送");
time = 60 * 10;
timer();
}).catch((err) => {
if (err == "验证码已发送请10分钟后重试") {
ElMessageBox.alert("请求验证码过于频繁,请检查收件箱", "验证码已发送", { confirmButtonText: "确认" });
} else if (err == "该账号尚未注册") {
ElMessageBox.alert("该账号尚未注册,请检查", "未注册", { confirmButtonText: "确认" });
} else {
ElMessageBox.alert("发送失败,请联系管理员或确认账号可用性", "验证码发送失败", { confirmButtonText: "确认" });
}
});
};
</script>
<style scoped>
.form-box {
background-color: white;
width: 75vw;
height: 500px;
box-shadow: 0 3px 8px 6px rgba(7, 17, 27, 0.05);
border-radius: 5px;
}
.form-box:hover {
box-shadow: 0 5px 12px 8px rgba(7, 17, 27, 0.1);
}
.flex-box {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.switch {
margin: 5px;
cursor: pointer;
color: #4B6186;
font-size: 0.8em;
}
.switch:hover {
color: #63a35c;
}
.go_login {
margin-top: 10px;
text-align: center;
font-size: 0.8em;
color: #4B6186;
}
.get_verify_button {
border-width: 0;
width: 30%;
}
</style>

@ -493,6 +493,7 @@ const userIdentity = computed(() => {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
}
.user-center-info {
Loading…
Cancel
Save