SpringBoot+VUE前后端分离项目学习笔记 - 【23 权限菜单 续】
BUG1 : 路由跳转问题
访问错误路由: 已登录用户返回404,未登录用户返回登录页面
Route/index.js
路由守卫增加判断
router.beforeEach((to, from, next) => {
localStorage.setItem("currentPathName", to.name) // 设置当前的路由名称
store.commit("setPath")
// 未找到路由的情况
if (!to.matched.length) {
const storeMenus = localStorage.getItem("menus")
if (storeMenus) {
next("/404")
} else {
// 跳回登录页面
next("/login")
}
}
// 其他的情况都放行
next()
})
页面测试
角色管理界面分配菜单按钮点击没反应
解决办法1
解决办法2
新建菜单访问404问题。
●新建一个Vue页面
●给页面加一个菜单
●给管理员分配菜单
●重新登录
●点击刚才分配的菜单
●出现404
解决方法:
// 在router的 index.js中提供一个重置路由的方法
export const resetRouter = () => {
router.matcher = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
}
然后在 store的index.js的logout()中调用一下这个重置路由的方法即可
logout() {
// 清空缓存
localStorage.removeItem("user")
localStorage.removeItem("menus")
router.push("/login")
// 重置路由
resetRouter()
}
增加修改密码
前端
Password.vue
<template>
<el-card style="width: 500px;">
<el-form label-width="120px" size="small" :model="form" :rules="rules" ref="pass">
<el-form-item label="原密码" prop="password">
<el-input v-model="form.password" autocomplete="off" show-password></el-input>
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="form.newPassword" autocomplete="off" show-password></el-input>
</el-form-item>
<el-form-item label="确认新密码" prop="confirmPassword">
<el-input v-model="form.confirmPassword" autocomplete="off" show-password></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="save">确 定</el-button>
</el-form-item>
</el-form>
</el-card>
</template>
<script>
export default {
name: "Password",
data() {
return {
form: {},
user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},
rules: {
password: [
{ required: true, message: '请输入原密码', trigger: 'blur' },
{ min: 3, message: '长度不少于3位', trigger: 'blur' }
],
newPassword: [
{ required: true, message: '请输入新密码', trigger: 'blur' },
{ min: 3, message: '长度不少于3位', trigger: 'blur' }
],
confirmPassword: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 3, message: '长度不少于3位', trigger: 'blur' }
],
}
}
},
created() {
this.form.username = this.user.username
},
methods: {
save() {
this.$refs.pass.validate((valid) => {
if (valid) {
if (this.form.newPassword !== this.form.confirmPassword) {
this.$message.error("2次输入的新密码不相同")
return false
}
this.request.post("/user/password", this.form).then(res => {
if (res.code === '200') {
this.$message.success("修改成功")
this.$store.commit("logout")
} else {
this.$message.error(res.msg)
}
})
}
})
},
}
}
</script>
<style>
.avatar-uploader {
text-align: center;
padding-bottom: 10px;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 138px;
height: 138px;
line-height: 138px;
text-align: center;
}
.avatar {
width: 138px;
height: 138px;
display: block;
}
</style>
Header.vue
<template>
<div style="line-height: 60px; display: flex">
<div style="flex: 1;">
<span :class="collapseBtnClass" style="cursor: pointer; font-size: 18px" @click="collapse"></span>
<el-breadcrumb separator="/" style="display: inline-block; margin-left: 10px">
<el-breadcrumb-item :to="'/'">
首页</el-breadcrumb-item>
<el-breadcrumb-item>{{ currentPathName }}</el-breadcrumb-item>
</el-breadcrumb>
</div>
<el-dropdown style="width: 150px; cursor: pointer;text-align: right">
<div style="display: inline-block">
<img :src="user.avatarUrl" alt=""
style="width: 30px; height: 30px; border-radius: 50%; position: relative; top:8px; right: 8px">
<span>{{user.nickname}}</span><i class="el-icon-arrow-down" style="margin-left: 5px"></i>
</div>
<el-dropdown-menu slot="dropdown" style="width: 100px; text-align: center">
<el-dropdown-item style="font-size: 14px; padding: 5px 0">
<router-link to="/password">修改密码</router-link>
</el-dropdown-item>
<el-dropdown-item style="font-size: 14px; padding: 5px 0">
<router-link to="/person">个人信息</router-link>
</el-dropdown-item>
<el-dropdown-item style="font-size: 14px; padding: 5px 0">
<span style="text-decoration: none" @click="logout">退出</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</template>
<script>
export default {
name: "Header",
props: {
collapseBtnClass: String,
user: Object
},
computed: {
currentPathName () {
return this.$store.state.currentPathName; //需要监听的数据
}
},
data() {
return {
}
},
methods: {
collapse() {
// this.$parent.$parent.$parent.$parent.collapse() // 通过4个 $parent 找到父组件,从而调用其折叠方法
this.$emit("asideCollapse")
},
logout() {
this.$store.commit("logout")
this.$message.success("退出成功")
}
}
}
</script>
<style scoped>
</style>
后端
UserPasswordDTO.java
package com.zj.demo.controller.dao;
import lombok.Data;
@Data
public class UserPasswordDTO {
private String username;
private String password;
private String newPassword;
}
UserController.java
/**
* 修改密码
* @param userPasswordDTO
* @return
*/
@PostMapping("/password")
public Result password(@RequestBody UserPasswordDTO userPasswordDTO)
{
userPasswordDTO.setPassword(userPasswordDTO.getPassword());
userPasswordDTO.setNewPassword(userPasswordDTO.getNewPassword());
userService.updatePassword(userPasswordDTO);
return Result.success();
}
IUserService.java
public interface IUserService extends IService<User> {
UserDTO login(UserDTO userDTO);
User register(UserDTO userDTO);
void updatePassword(UserPasswordDTO userPasswordDTO);
}
UseServiceImpl.java
@Override
public void updatePassword(UserPasswordDTO userPasswordDTO) {
int update = userMapper.updatePassword(userPasswordDTO);
if (update < 1) {
throw new ServiceException(Constants.CODE_600, "密码错误");
}
}
UserMapper.java
/**
* <p>
* Mapper 接口
* </p>
*
* @author Joyce
* @since 2023-01-04
*/
public interface UserMapper extends BaseMapper<User> {
@Update("update sys_user set password = #{newPassword} where username = #{username} and password = #{password}")
int updatePassword(UserPasswordDTO userPasswordDTO);
}
页面测试