SpringBoot+VUE前后端分离项目学习笔记 - 【23 权限菜单 续】

news2024/11/25 20:46:32

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);
}

页面测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/167547.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【墙角数枝梅,凌寒独自开】代码改变未来

墙角数枝梅&#xff0c;凌寒独自开 “墙角数枝梅&#xff0c;凌寒独自开。” 出自王安石的《梅花》 诗句是集语言中的精华&#xff0c;浓缩为七言、五言和四言等&#xff0c;寥寥几句道尽人生酸甜苦辣&#xff0c;儿女情长。 而我更愿把现代的程序员称作诗人&#xff0c;语言是…

ESP32设备驱动-TCS34725颜色传感器驱动

TCS34725颜色传感器驱动 文章目录 TCS34725颜色传感器驱动1、TCS34725介绍2、硬件准备3、软件准备4、驱动实现1、TCS34725介绍 TCS3472 器件提供红色、绿色、蓝色 (RGB) 和清晰光感应值的数字返回。 集成在芯片上并定位于颜色传感光电二极管的 IR 阻挡滤光片可最大限度地减少入…

并发场景使用SimpleDateFormat异常问题和解决

SimpleDateFormat类主要是负责日期的格式化与转换操作&#xff0c;因为它不是线程安全的&#xff0c;所以使用SimpleDateFormat时&#xff0c;务必确保同一个SimpleDateFormat对象不要与其他线程共享&#xff0c;否则并发情况下会出现问题 目录异常示例解决方案1&#xff1a;创…

Camera | 2.MIPI、CSI基础

瑞芯微专栏 上一篇我们讲解了camera的一些基础概念和知识。 我们说了&#xff0c;现在的手机由于高分辨率的要求&#xff0c;现在基本上都是基于MIPI、CSI协议来实现的&#xff0c; 本篇讲解MIPI、CSI的一些基础知识。 摄像头常用术语 下面这些术语是camera驱动中经常用到的…

9.6 容器适配器

文章目录定义一个适配器stack队列适配器queuepriority_queue 优先队列适配器是标准库的一个通用概念&#xff0c;容器、迭代器和函数等都有适配器。适配器是一种机制&#xff0c;接受一种已有容器类型。标准库有三个顺序容器适配器&#xff1a;stack&#xff0c;queue和priorit…

Elasticsearch:关于在 Python 中使用 Elasticsearch 你需要知道的一切 - 8.x

在本文中&#xff0c;我们将讨论如何在 Python 中使用 Elasticsearch。 如果你还不了解 Elasticsearch&#xff0c;可以阅读这篇文章 “Elasticsearch 简介” 进行快速介绍。在我之前的文章 “Elasticsearch&#xff1a;使用最新的 Python client 8.0 来创建索引并搜索”&#…

Pytorch自定义数据集模型训练流程

文章目录Pytorch模型自定义数据集训练流程1、任务描述2、导入各种需要用到的包3、分割数据集4、将数据转成pytorch标准的DataLoader输入格式5、导入预训练模型&#xff0c;并修改分类层6、开始模型训练7、利用训好的模型做预测Pytorch模型自定义数据集训练流程 我们以kaggle竞…

响应式流的核心机制——背压机制

一、响应式流是什么&#xff1f; Reactive Streams 是 2013 年底由 Netflix、Lightbend 和 Pivotal&#xff08;Spring 背后的公司&#xff09;的工程师发起的一项计划&#xff0c;响应式流旨在为无阻塞异步流处理提供一个标准。它旨在解决处理元素流的问题——如何将元素流从…

【BP靶场portswigger-客户端14】点击劫持-5个实验(全)

前言&#xff1a; 介绍&#xff1a; 博主&#xff1a;网络安全领域狂热爱好者&#xff08;承诺在CSDN永久无偿分享文章&#xff09;。 殊荣&#xff1a;CSDN网络安全领域优质创作者&#xff0c;2022年双十一业务安全保卫战-某厂第一名&#xff0c;某厂特邀数字业务安全研究员&…

Fastdfs分布式文件系统原理浅析

文章目录1、fastdfs文件系统原理简述2、storage server状态2.1 组内新增加一台storage server A时&#xff0c;由系统自动完成已有数据同步&#xff0c;处理逻辑如下&#xff1a;第一步&#xff1a;第二步&#xff1a;第三步&#xff1a;第四步&#xff1a;3、同步时间管理4、B…

[有人@你]请查收你的年终总结报告

嗨&#xff0c;兄dei&#xff0c;我是建模助手。 新年伊始&#xff0c;最近大家想必已经被各大平台的2022年度报告刷屏了。 听歌软件伴你度过的失眠夜&#xff0c;外卖软件拯救你的饥饿时刻&#xff0c;还有某俩宝账单告诉你&#xff0c;其实你是有钱的&#xff0c;只是你看不到…

基于有向图的邻接矩阵计算其割点、割边、压缩图,并用networkx可视化绘制

基于有向图的邻接矩阵计算其割点、割边、压缩图&#xff0c;并用networkx可视化绘制为什么基于邻接矩阵计算图的割点、割边、压缩图实现python代码代码运行效果结论&#xff1a;为什么基于邻接矩阵计算图的割点、割边、压缩图 由于矩阵计算过程&#xff0c;被广泛优化&#xf…

Linux关于 gdb 调试器的使用

坚持看完&#xff0c;结尾有思维导图总结 这里写目录标题debug 和 release 版本gdb 常见命令断点逐行调试和观察变量总结debug 和 release 版本 首先要说的是 &#xff0c;在 Linux 中 gcc 直接编译是不能进行调试的 而是要在加上 -g 选项才能得到可调试的文件 以下程序用一个…

算法第十二期——BFS-双向广搜

双向广搜 应用场景&#xff1a;有确定的起点s和终点t&#xff1b;把从起点到终点的单向搜索&#xff0c;变换为分别从起点出发和从终点出发的“相遇”问题。操作&#xff1a;从起点s(正向搜索&#xff09;和终点t(逆向搜索&#xff09;同时开始搜索&#xff0c;当两个搜索产生…

Spring入门-Spring事务管理

文章目录1&#xff0c;Spring事务管理1.1 Spring事务简介1.1.1 相关概念介绍1.1.2 转账案例-需求分析1.1.3 转账案例-环境搭建步骤1:准备数据库表步骤2:创建项目导入jar包步骤3:根据表创建模型类步骤4:创建Dao接口步骤5:创建Service接口和实现类步骤6:添加jdbc.properties文件步…

数据治理与档案信息资源体系建设

如果要评选大数据或者数字化转型领域中哪个词最让人费解、最讲不清楚&#xff0c;“数据治理&#xff08;Data Governance&#xff09;”绝对是候选之一。说实话&#xff0c;笔者到现在也没有完全整明白&#xff0c;因为数据治理包含的范围太广了&#xff0c;可以说是包罗万象&…

高潜人才的自我要求

前言&#xff0c;上次写了个《潜力出众的你有这样的特质吗&#xff1f;》&#xff0c;地址如下&#xff1a;点我查看&#xff0c;这次在写个高潜人才的自我要求。本次以6个纬度来进行分析&#xff1b;3是基本要求&#xff0c;4是追求卓越&#xff0c;看你目前做到了哪个级别&am…

跨平台API对接(Python)的使用

Jenkins 是一个开源的、提供友好操作界面的持续集成(CI)工具&#xff0c;起源于 Hudson&#xff08;Hudson 是商用的&#xff09;&#xff0c;主要用于持续、自动的构建/测试软件项目、监控外部任务的运行。后端可以利用 Jenkins 对任务进行调度运行&#xff1a;后端可利用 HTT…

【进阶】Spring更简单的读取和存储对象

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录一、存储Bean对象一&#xff09;前置工作&#xff1a;配置扫描路径&#xff08;重要&#xff09;二&#xff09;添加注解存储Bean对象3. 五大类注解&#xff1a;4. 方法注解&#xff1a;6. 相关问题7. 补充【结论、查…

ROS2机器人编程简述humble-第二章-DEVELOPING THE FIRST NODE .2

0.1ROS2机器人编程简述新书推荐-A Concise Introduction to Robot Programming with ROS21.1ROS2机器人编程简述humble-第一章-Introduction2.1ROS2机器人编程简述humble-第二章-First Steps with ROS2 .12.2主要内容是全手工创建一个最简单的自定义节点&#xff0c;其实没啥具…