vue+springboot实验个人信息,修改密码,忘记密码功能实现

server/2024/9/24 9:19:41/

前端部分

新增Person(个人页面),Password(修改密码页面),还需要对Manager,login页面进行修改

router文件夹下的index.js:

 

import Vue from 'vue'
import VueRouter from 'vue-router'
import Manager from '../views/Manager.vue'
// 解决导航栏或者底部导航tabBar中的vue-router在3.0版本以上频繁点击菜单报错的问题。
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push (location) {return originalPush.call(this, location).catch(err => err)
}
Vue.use(VueRouter)const routes = [{path: '/',name: 'manager',component: Manager,children:[{path:'home',name:'Home',meta:{ name:'系统首页' },component:()=>import('../views/manager/Home.vue')},{path:'user',name:'User',meta:{ name:'用户信息' },component:()=>import('../views/manager/User.vue')},{path:'403',name:'Auth',meta:{ name:'无权限' },component:()=>import('../views/Auth.vue')},{path:'Person',name:'person',meta:{ name:'个人信息' },component:()=>import('../views/manager/Person.vue')},{path:'Password',name:'password',meta:{ name:'修改密码' },component:()=>import('../views/manager/Password.vue')}],redirect:'/home'},{path: '/about',name: 'about',// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')},{path:'/login',name:'login',meta:{ name:'登录' },component: ()=>import('../views/login.vue')},{path:'/register',name:'register',meta:{ name:'注册' },component: ()=>import('../views/register.vue')},{path:'*',name:'404',meta:{ name:'无法访问' },component: ()=>import('../views/404.vue')}
]const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes
})
router.beforeEach((to,from,next)=>{let adminPaths=['/user']let user=JSON.parse(localStorage.getItem('honey-user')||'{}')if(user.role !== '管理员' && adminPaths.includes(to.path)){next('/403')}else{next()}
})
export default router

Person.vue

<template><div><el-card style="width: 50%"><el-form :model="user" label-width="80px" style="padding-right: 20px"><div style="margin: 15px;text-align: center"><el-uploadclass="avatar-uploader"action="http://localhost:9090/file/upload":headers="{ token: user.token }":show-file-list="false":on-success="handleAvatarSuccess"><img v-if="user.avatar" :src="user.avatar" class="avatar"><i v-else class="el-icon-plus avatar-uploader-icon"></i></el-upload></div><el-form-item label="用户名" prop="username"><el-input v-model="user.username" disabled></el-input></el-form-item><el-form-item label="姓名" prop="name"><el-input v-model="user.name"></el-input></el-form-item><el-form-item label="电话" prop="phone"><el-input v-model="user.phone"></el-input></el-form-item><el-form-item label="邮箱" prop="email"><el-input v-model="user.email"></el-input></el-form-item><el-form-item label="地址" prop="address"><el-input type="textarea" v-model="user.address"></el-input></el-form-item></el-form><div style="text-align: center;margin-bottom: 20px"><el-button type="primary" @click="update">保存</el-button></div></el-card></div>
</template><script>
export default {data(){return{user:JSON.parse(localStorage.getItem('honey-user'||'{}'))}},methods:{update(){this.$request.put('/user/update',this.user).then(res=>{if(res.code==='200'){this.$message.success('保存成功')localStorage.setItem('honey-user',JSON.stringify(this.user))this.$emit('update:user',this.user)}else{this.$message.error(res.msg)}})},handleAvatarSuccess(response,file,fileList){console.log(response)this.user.avatar=response.data}}
}
</script><style scoped>
/deep/.el-form-item__label{font-weight: bold;
}
/deep/.el-upload{border-radius: 50%;
}
/deep/.avatar-uploader .el-upload {border: 1px dashed #d9d9d9;cursor: pointer;position: relative;overflow: hidden;border-radius: 50%;
}
/deep/.avatar-uploader .el-upload:hover {border-color: #409EFF;
}
.avatar-uploader-icon {font-size: 28px;color: #8c939d;width: 178px;height: 178px;line-height: 178px;text-align: center;border-radius: 50%;
}
.avatar {width: 178px;height: 178px;display: block;border-radius: 50%;
}
</style>

Password.vue:

<template><div><el-card style="width: 50%"><el-form ref="fromRef" :model="user" label-width="80px" style="padding-right: 20px" :rules="rules"><el-form-item label="原始密码" prop="password"><el-input v-model="user.password" show-password></el-input></el-form-item><el-form-item label="新密码" prop="newPassword"><el-input v-model="user.newPassword"></el-input></el-form-item><el-form-item label="确认密码" prop="confirmPassword"><el-input v-model="user.confirmPassword"></el-input></el-form-item><div style="text-align: center;margin-bottom: 20px"><el-button type="primary" @click="update">确认修改</el-button></div></el-form></el-card></div>
</template><script>
export default {data(){const validatePassword = (rule, value, callback) => {if (value === '') {callback(new Error('请输入确认密码'));} else if(value !== this.user.newPassword){callback(new Error('两次密码不一致'));} else {callback();}};return{user:JSON.parse(localStorage.getItem('honey-user'||'{}')),rules:{password:[{required:true,message:'请输入原始密码',trigger:'blur'}],newPassword:[{required:true,message:'请输入新密码',trigger:'blur'}],confirmPassword:[{validator:validatePassword,required:true,trigger:'blur',}]}}},methods:{update(){this.$refs.fromRef.validate((valid)=>{if(valid){this.user.password=this.user.newPasswordthis.$request.put('/user/update',this.user).then(res=>{if(res.code==='200'){this.$message.success('保存成功')this.$router.push('/login')}else{this.$message.error(res.msg)}})}})},}
}
</script><style scoped>
/deep/.el-form-item__label{font-weight: bold;
}
</style>

 Manager.vue:

<template><div><el-container><!--    侧边栏  --><el-aside :width="asideWidth" style="min-height: 100vh; background-color: #001529"><div style="height: 60px; color: white; display: flex; align-items: center; justify-content: center"><img src="@/assets/logo1.png" alt="" style="width: 40px; height: 40px"><span class="logo-title" v-show="!isCollapse">honey2024</span></div><el-menu :collapse="isCollapse" :collapse-transition="false" router background-color="#001529" text-color="rgba(255, 255, 255, 0.65)" active-text-color="#fff" style="border: none" :default-active="$route.path"><el-menu-item index="/home"><i class="el-icon-s-home"></i><span slot="title">系统首页</span></el-menu-item><el-submenu index="info" v-if="user.role === '管理员'"><template slot="title"><i class="el-icon-menu"></i><span>信息管理</span></template><el-menu-item index="/user">用户信息</el-menu-item></el-submenu></el-menu></el-aside><el-container><!--        头部区域--><el-header><i :class="collapseIcon" style="font-size: 26px" @click="handleCollapse"></i><el-breadcrumb separator-class="el-icon-arrow-right" style="margin-left: 20px"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item><el-breadcrumb-item :to="{ path: $route.path }">{{ $route.meta.name }}</el-breadcrumb-item></el-breadcrumb><div style="flex: 1; width: 0; display: flex; align-items: center; justify-content: flex-end"><i class="el-icon-quanping" style="font-size: 26px" @click="handleFull"></i><el-dropdown placement="bottom"><div style="display: flex; align-items: center; cursor: default"><img :src="user.avatar||'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'" alt="" style="width: 40px; height: 40px; margin: 0 5px;border-radius: 50%"><span>{{user.name}}</span></div><el-dropdown-menu slot="dropdown"><el-dropdown-item @click.native="$router.push('/person')">个人信息</el-dropdown-item><el-dropdown-item @click.native="$router.push('/password')">修改密码</el-dropdown-item><el-dropdown-item @click.native="logout">退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></div></el-header><!--        主体区域--><el-main><router-view @update:user="updateUser"></router-view></el-main></el-container></el-container></div>
</template><script>
import axios from "axios";
import request from '@/utils/request'export default {name: 'HomeView',data() {return {isCollapse: false,  // 不收缩asideWidth: '200px',collapseIcon: 'el-icon-s-fold',user:JSON.parse(localStorage.getItem('honey-user')||'{}'),}},mounted() {// axios.get('http://localhost:9090/user/selectall').then(res=>{//   console.log(res.data);//   this.users=res.data.data// })// request.get('/user/selectall').then(res => {//   this.users = res.data// })},methods: {updateUser(user){this.user=JSON.parse(JSON.stringify(user))},handleFileUpload(response,file,fileList){this.fileList=fileListconsole.log(response,file,fileList)},logout() {localStorage.removeItem("honey-user")this.$router.push('/login')},handleFull() {document.documentElement.requestFullscreen()},handleCollapse() {this.isCollapse = !this.isCollapsethis.asideWidth = this.isCollapse ? '64px' : '200px'this.collapseIcon = this.isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'}}
}
</script><style>
.el-menu--inline {background-color: #000c17 !important;
}.el-menu--inline .el-menu-item {background-color: #000c17 !important;padding-left: 49px !important;
}.el-menu-item:hover, .el-submenu__title:hover {color: #fff !important;
}.el-submenu__title:hover i {color: #fff !important;
}.el-menu-item:hover i {color: #fff !important;
}.el-menu-item.is-active {background-color: #1890ff !important;border-radius: 5px !important;width: calc(100% - 8px);margin-left: 4px;
}.el-menu-item.is-active i, .el-menu-item.is-active .el-tooltip {margin-left: -4px;
}.el-menu-item {height: 40px !important;line-height: 40px !important;
}.el-submenu__title {height: 40px !important;line-height: 40px !important;
}.el-submenu .el-menu-item {min-width: 0 !important;
}.el-menu--inline .el-menu-item.is-active {padding-left: 45px !important;
}/*.el-submenu__icon-arrow {*/
/*  margin-top: -5px;*/
/*}*/.el-aside {transition: width .3s;box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
}.logo-title {margin-left: 5px;font-size: 20px;transition: all .3s; /* 0.3s */
}.el-header {box-shadow: 2px 0 6px rgba(0, 21, 41, .35);display: flex;align-items: center;
}
</style>

login.vue:

<template><div style="display: flex;align-items: center;justify-content: center;background-color: aquamarine;height: 100vh;"><div style="display: flex;width: 50%;background-color: white;border-radius: 5px;overflow: hidden;"><div style="flex: 1;"><img src="@/assets/login.png" alt="" style="width: 100%;"></div><div style="flex: 1;display: flex;align-items: center;justify-content: center;"><el-form :model="user" style="width: 80%;" :rules="rules" ref="loginRef"><div style="font-weight: bold; font-size: 20px;margin-bottom: 20px;text-align: center;">欢迎登陆后台管理系统</div><el-form-item prop="username"><el-input placeholder="请输入用户名" v-model="user.username" prefix-icon="el-icon-user"></el-input></el-form-item><el-form-item prop="password"><el-input placeholder="请输入密码" v-model="user.password" show-password prefix-icon="el-icon-lock"></el-input></el-form-item><el-form-item prop="code"><div style="display: flex;"><el-input prefix-icon="el-icon-circle-check" v-model="user.code"></el-input><div style="flex: 1;height: 32px"><valid-code @update:value="getCode"></valid-code></div></div></el-form-item><el-form-item><el-button type="primary" style="width: 100%;" @click="login">登录</el-button></el-form-item><div style="display: flex;"><div style="flex: 1;">还没有账号?去<span style="color:aquamarine;cursor: pointer;" @click="$router.push('/register')">注册</span></div><div style="flex: 1;text-align: right;cursor: pointer;color: aquamarine;" @click="handleForgetPass">忘记密码</div></div></el-form></div></div><el-dialog title="忘记密码" :visible.sync="forgetPassDialogVis" width="30%"><el-form :model="forgetUserForm" label-width="80px" style="padding-right: 20px"><el-form-item label="用户名"><el-input v-model="forgetUserForm.username" autocomplete="off"></el-input></el-form-item><el-form-item label="手机号"><el-input v-model="forgetUserForm.phone" autocomplete="off"></el-input></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="forgetPassDialogVis = false">取 消</el-button><el-button type="primary" @click="resetPassword">确 定</el-button></div></el-dialog></div>
</template><script>
import ValidCode from "@/components/ValidCode.vue";
export default {name:'login',components:{ValidCode},data() {const validateCode = (rule, value, callback) => {if (value === '') {callback(new Error('请输入验证码'));} else if(value.toLowerCase() !== this.code){callback(new Error('验证码错误'));} else {callback();}};return {forgetUserForm:{},forgetPassDialogVis:false,code:'',user: {code:'',username: '',password: ''},rules:{username:[{required:'true',message:'请输入账号',trigger:'blur'}],password:[{required:'true',message:'请输入密码',trigger:'blur'}],code:[{validator:validateCode,trigger:'blur'}]},}},methods:{handleForgetPass(){this.forgetUserForm={}this.forgetPassDialogVis=true},getCode(code){this.code=code.toLowerCase()},resetPassword(){this.$request.put('/password',this.forgetUserForm).then(res=>{if(res.code==='200'){this.$message.success('密码重置成功')this.forgetPassDialogVis=false}else{this.$message.error(res.msg)}})},login(){this.$refs['loginRef'].validate((valid=>{if(valid){this.$request.post("/login",this.user).then(res=>{if(res.code === '200'){this.$router.push('/')this.$message.success('登录成功')localStorage.setItem('honey-user',JSON.stringify(res.data))}else{this.$message.error(res.msg)}console.log(res);})}}))}}
}
</script><style scoped></style>

后端部分 

只需要为忘记密码编写一个新接口即可:

 WebController:

package com.example.springboot.controller;import cn.hutool.core.util.StrUtil;
import com.example.springboot.common.AuthAccess;
import com.example.springboot.common.Result;
import com.example.springboot.entity.User;
import com.example.springboot.exception.ServiceException;
import com.example.springboot.service.UserService;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;@RestController
public class WebController {@ResourceUserService userService;@AuthAccess@GetMapping("/")public Result hello(){return Result.success("success");}@PostMapping("/login")public Result login(@RequestBody User user){if(StrUtil.isBlank(user.getUsername())||StrUtil.isBlank(user.getPassword())){return Result.error("数据输入错误");}user=userService.login(user);return Result.success(user);}@AuthAccess@PostMapping("/register")public Result register(@RequestBody User user){if(StrUtil.isBlank(user.getUsername())||StrUtil.isBlank(user.getPassword())){throw new ServiceException("输入不合法");}if(user.getUsername().length()>10||user.getPassword().length()>20){throw new ServiceException("长度过长");}user=userService.register(user);return Result.success(user);}@AuthAccess@PutMapping("/password")public Result password(@RequestBody User user){if(StrUtil.isBlank(user.getUsername())||StrUtil.isBlank(user.getPhone())){throw new ServiceException("输入不合法");}userService.resetPassword(user);return Result.success();}
}

 UserService:

package com.example.springboot.service;import com.example.springboot.entity.User;
import com.example.springboot.exception.ServiceException;
import com.example.springboot.mapper.UserMapper;
import com.example.springboot.utils.TokenUtils;
import jdk.nashorn.internal.parser.Token;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;import java.util.List;@Service
public class UserService {@AutowiredUserMapper userMapper;public void insertUser(User user){userMapper.insert(user);}public void updateUser(User user) {userMapper.updateUser(user);}public void deleteUser(Integer id) {userMapper.deleteUser(id);}public void batchdeleteUser(List<Integer> ids) {for(Integer id : ids){userMapper.deleteUser(id);}}public List<User> selectall() {return userMapper.selectall();}public User selectbyid(Integer id) {return userMapper.selectbyid(id);}public List<User> selectbyname(String name) {return userMapper.selectbyname(name);}public List<User> selectbymore(String username, String name) {return userMapper.selectbymore(username,name);}public List<User> selectbymo(String username, String name) {return userMapper.selectbymo(username,name);}public User login(User user) {User dbuser=userMapper.selectbyUsername(user.getUsername());if(dbuser == null){throw new ServiceException("账号不存在");}if(!user.getPassword().equals(dbuser.getPassword())){throw new ServiceException("账号或者密码错误");}String token=TokenUtils.createToken(dbuser.getId().toString(),dbuser.getPassword());dbuser.setToken(token);return dbuser;}public User register(User user) {User dbuser=userMapper.selectbyUsername(user.getUsername());if(dbuser != null){throw new ServiceException("用户名已存在");}userMapper.insert(user);return user;}public void resetPassword(User user) {User dbuser=userMapper.selectbyUsername(user.getUsername());if(dbuser==null){throw new ServiceException("用户不存在");}if(!user.getPhone().equals(dbuser.getPhone())){throw new ServiceException("验证错误");}dbuser.setPassword("123");userMapper.updateUser(dbuser);}
}


http://www.ppmy.cn/server/13882.html

相关文章

JEECG表格选中状态怎么去掉

官网代码&#xff08;在取消选中状态的时候不生效&#xff09; rowSelection() {return {onChange: (selectedRowKeys, selectedRows) > {console.log(selectedRowKeys: ${selectedRowKeys}, selectedRows: , selectedRows);},getCheckboxProps: record > ({props: {disa…

编译原理 LR(0)

讲解视频&#xff1a;编译原理LR&#xff08;0&#xff09;分析表&#xff08;上&#xff09;_哔哩哔哩_bilibili 【编译原理】LR(0)分析表分析输入串_哔哩哔哩_bilibili 拓广文法 已知G&#xff1a;S->(S)S | ε 拓广文法&#xff1a; S -> S S -> (S)S S -> ε…

Java之二维数组

使用二维数组&#xff1a; 引用二维数组元素需要指明行下标和列下标。二维数组有两个指标&#xff0c;行数使用“数组名.length",每行的列数使用“数组名[i].length”。遍历是二维数组的基本算法&#xff0c;使用双重循环遍历二维数组。外层循环控制行&#xff0c;内存循环…

设计模式之模板方法模式详解(上)

模板方法模式 1&#xff09;概述 1.定义 定义一个操作中算法的框架&#xff0c;而将一些步骤延迟到子类中&#xff0c;模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 2.方案 背景&#xff1a;某个方法的实现需要多个步骤&#xff08;类似…

Ribbon 添加右侧区域菜单项

效果图如下所示&#xff1a; 类似与上图效果所示&#xff0c;代码如下&#xff1a; RibbonPage* pageHome1 ribbonBar()->addPage(tr("Home")); //实现代码&#xff1a; { QMenu* menuOptions ribbonBar()->addMenu(tr("Options"))…

Java 的 Apache Commons 工具库 助力开发

Apache Commons 是什么&#xff1f; Apache Commons 是由 Apache 软件基金会提供的一系列开源、高质量的 Java 组件集合。它包含了各种常用的、经过严格测试的工具类&#xff0c;弥补了 Java 标准库在功能上的不足。这些组件广泛应用于字符串处理、数据转换、集合操作、文件处…

[可达鸭四月月赛——入门赛第六场(周六) T4]原初数题解

本题解署名&#xff1a;王胤皓 正文开始 题意 时间限制&#xff1a;1秒 内存限制&#xff1a;256M 题目描述 如果一个数字只由若干个不同的质数相乘得到&#xff0c;那么我们就称这个数字为“原初数”。本题中指的数字都是大于 1 1 1 的数字。 小可认为&#xff0c;原初…

【Interconnection Networks 互连网络】Dragonfly Topology 蜻蜓网络拓扑

蜻蜓拓扑 Dragonfly Topology 1. 拓扑参数2. Topology Description 拓扑描述3. Topology Variations 拓扑变体 蜻蜓拓扑 Dragonfly Topology 1. 拓扑参数 Dragonfly拓扑参数&#xff1a; N N N: 网络中终端(terminal)的总数量 p p p: 连接到每个路由器的终端数量 a a a: 每…