SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)

系列文章目录

  1. 系统功能演示——基于SpringBoot和Vue的后台管理系统项目系列博客(一)
  2. Vue2安装并集成ElementUI——基于SpringBoot和Vue的后台管理系统项目系列博客(二)
  3. Vue2前端主体框架搭建——基于SpringBoot和Vue的后台管理系统项目系列博客(三)
  4. SpringBoot后端初始框架搭建——基于SpringBoot和Vue的后台管理系统项目系列博客(四)
  5. SpringBoot集成Mybatis——基于SpringBoot和Vue的后台管理系统项目系列博客(五)
  6. SpringBoot实现增删改查——基于SpringBoot和Vue的后台管理系统项目系列博客(六)
  7. SpringBoot实现分页查询——基于SpringBoot和Vue的后台管理系统项目系列博客(七)
  8. SpringBoot实现集成Mybatis-Plus和SwaggerUI——基于SpringBoot和Vue的后台管理系统项目系列博客(八)
  9. Vue实现增删改查——基于SpringBoot和Vue的后台管理系统项目系列博客(九)
  10. SpringBoot实现代码生成器——基于SpringBoot和Vue的后台管理系统项目系列博客(十)
  11. Vue使用路由——基于SpringBoot和Vue的后台管理系统项目系列博客(十一)
  12. SpringBoot和Vue实现导入导出——基于SpringBoot和Vue的后台管理系统项目系列博客(十二)
  13. SpringBoot和Vue实现用户登录注册与异常处理——基于SpringBoot和Vue的后台管理系统项目系列博客(十三)
  14. SpringBoot和Vue实现用户个人信息展示与保存与集成JWT——基于SpringBoot和Vue的后台管理系统项目系列博客(十四)
  15. SpringBoot和Vue实现文件上传与下载——基于SpringBoot和Vue的后台管理系统项目系列博客(十五)
  16. SpringBoot和Vue整合ECharts——基于SpringBoot和Vue的后台管理系统项目系列博客(十六)
  17. SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)
  18. SpringBoot实现1对1、1对多、多对多关联查询——基于SpringBoot和Vue的后台管理系统项目系列博客(十八)
  19. 待更新……

项目资源下载

  1. GitHub下载地址
  2. Gitee下载地址

文章目录

  • 系列文章目录
  • 项目资源下载
  • 前言
  • 一、新建角色数据表
  • 二、使用代码生成器生成角色代码
  • 三、测试生成的角色代码
  • 四、新建菜单数据表
  • 五、使用代码生成器生成菜单代码
  • 六、测试生成的菜单代码
  • 七、分配权限菜单基础功能实现
  • 八、分配权限菜单图标显示与编辑功能
  • 九、分配权限菜单的授权保存功能
  • 十、赋予用户以角色
  • 十一、实现用户角色的动态菜单
  • 十二、实现用户菜单的动态路由
  • 十三、完成404提示界面
  • 十四、配置管理员修改用户权限后重新登陆
  • 十五、父级菜单不显示的Bug解决
  • 十六、选择部分子菜单后子菜单全部选中的Bug解决
  • 十七、随机访问某一界面却进入404界面Bug的解决
  • 十八、访问修改密码界面却进入404界面Bug的解决
  • 十九、提交新增一级菜单信息没反应Bug的解决
  • 二十、新增菜单页面后授权给用户重新登陆再点击新增的菜单页面却出现404页面Bug的解决
  • 总结


前言

  今天的主要内容包括:新建角色数据表、使用代码生成器生成角色代码、测试生成的角色代码、新建菜单数据表、使用代码生成器生成菜单代码、测试生成的菜单代码、分配权限菜单基础功能实现、分配权限菜单图表显示与编辑功能、分配权限菜单的授权保存功能、赋予用户以角色、实现用户角色的动态菜单、实现用户菜单的动态路由、完成404提示界面、配置管理员修改用户权限后重新登录、父级菜单不显示的Bug解决、选择部分子菜单后子菜单全部选中的Bug解决、随机访问某一界面却进入404界面Bug的解决、访问修改密码界面却进入404界面Bug的解决、提交新增一级菜单信息没反应Bug的解决、新增菜单页面后授权给用户重新登录再点击新增菜单页面却出现404页面Bug的解决。可以看到今天的内容非常多,也有一定的难度,请各位读者一定要仔细跟着我做。废话不多少,下面就开始今天的学习!


一、新建角色数据表

  1. 在Mysql中新建数据表,添加如下字段
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第1张图片
  2. 表名如下
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第2张图片

二、使用代码生成器生成角色代码

  1. 在CodeGenerator.java中生成加入刚创建的表名
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第3张图片
  2. 在controller.java.vm中修改此部分为entity参数
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第4张图片
  3. 然后右键运行CodeGenerator.java,生成代码即可,最后我们发现已经成功生成了所需代码,非常方便
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第5张图片
  4. 然后加入如下两处代码,为后面的搜索做准备
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第6张图片

三、测试生成的角色代码

  1. 然后在前端中新建Role.vue,在其中加入如下代码
<template>
    
    <div>
        
        <div style="margin: 10px 0">
            <el-input style="width: 200px" placeholder="请输入名称" suffix-icon="el-icon-search"
                      v-model="name">el-input>
            <el-button class="ml-5" type="primary" @click="load">搜索el-button>
            <el-button type="warning" @click="reset">重置el-button>
        div>

        
        <div style="margin: 10px 0">
            <el-button type="primary" @click="handleAdd">新增 <i class="el-icon-circle-plus-outline">i>el-button>
            <el-popconfirm
                    class="ml-5"
                    confirm-button-text='确定'
                    cancel-button-text='我再想想'
                    icon="el-icon-info"
                    icon-color="red"
                    title="您确定批量删除这些数据吗?"
                    @confirm="delBatch"
            >
                <el-button type="danger" slot="reference">批量删除 <i class="el-icon-remove-outline">i>el-button>
            el-popconfirm>
        div>

        
        <el-table :data="tableData" border stripe :header-cell-class-name="'headerBg'"
                  @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="55">el-table-column>
            <el-table-column prop="id" label="ID" width="80">el-table-column>
            <el-table-column prop="name" label="名称">el-table-column>
            <el-table-column prop="description" label="描述">el-table-column>
            <el-table-column label="操作" width="200" align="center">
                <template slot-scope="scope">
                    <el-button type="success" @click="handleEdit(scope.row)">编辑 <i class="el-icon-edit">i>el-button>
                    <el-popconfirm
                            class="ml-5"
                            confirm-button-text='确定'
                            cancel-button-text='我再想想'
                            icon="el-icon-info"
                            icon-color="red"
                            title="您确定删除吗?"
                            @confirm="del(scope.row.id)"
                    >
                        <el-button type="danger" slot="reference">删除 <i class="el-icon-remove-outline">i>el-button>
                    el-popconfirm>
                template>
            el-table-column>
        el-table>

        
        <div style="padding: 10px 0">
            <el-pagination
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                    :current-page="pageNum"
                    :page-sizes="[2, 5, 10, 20]"
                    :page-size="pageSize"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="total">
            el-pagination>
        div>

        <el-dialog title="角色信息" :visible.sync="dialogFormVisible" width="30%">
            <el-form label-width="80px" size="small">
                <el-form-item label="名称">
                    <el-input v-model="form.name" autocomplete="off">el-input>
                el-form-item>
                <el-form-item label="描述">
                    <el-input v-model="form.description" autocomplete="off">el-input>
                el-form-item>
            el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogFormVisible = false">取 消el-button>
                <el-button type="primary" @click="save">确 定el-button>
            div>
        el-dialog>
    div>
template>


<script>
    export default {
        name: "Role",
        data() {
            return {
                tableData: [],
                total: 0,
                pageNum: 1,
                pageSize: 10,
                name: "",
                form: {},
                dialogFormVisible: false,
                multipleSelection: []
            }
        },
        // 请求分页查询数据
        created() {
            this.load()
        },
        methods: {
            // 将数据库查询操作封装
            load() {
                this.request.get("/role/page", {
                    params: {
                        pageNum: this.pageNum,
                        pageSize: this.pageSize,
                        name: this.name,
                    }
                }).then(res => {
                    console.log(res)
                    this.tableData = res.records
                    this.total = res.total

                })
            },
            save() {
                this.request.post("/role", this.form).then(res => {
                    if (res) {
                        this.$message.success("保存成功")
                        this.dialogFormVisible = false
                        this.load()
                    } else {
                        this.$message.error("保存失败")
                    }
                })
            },
            handleAdd() {
                this.dialogFormVisible = true
                this.form = {}
            },
            handleEdit(row) {
                this.form = row
                this.dialogFormVisible = true
            },
            del(id) {
                this.request.delete("/role/" + id).then(res => {
                    if (res) {
                        this.$message.success("删除成功")
                        this.load()
                    } else {
                        this.$message.error("删除失败")
                    }
                })
            },
            handleSelectionChange(val) {
                console.log(val)
                this.multipleSelection = val
            },
            delBatch() {
                let ids = this.multipleSelection.map(v => v.id)  // [{}, {}, {}] => [1,2,3]
                this.request.post("/role/del/batch", ids).then(res => {
                    if (res) {
                        this.$message.success("批量删除成功")
                        this.load()
                    } else {
                        this.$message.error("批量删除失败")
                    }
                })
            },
            reset() {
                this.name = ""
                this.load()
            },
            // 动态分页请求
            handleSizeChange(pageSize) {
                console.log(pageSize)
                this.pageSize = pageSize
                this.load()
            },
            handleCurrentChange(pageNum) {
                console.log(pageNum)
                this.pageNum = pageNum
                this.load()
            },
            exp() {
                window.open("http://localhost:9090/role/export")
            },
            handleExcelImportSuccess(){
                this.$message.success("文件导入成功!")
                this.load()
            }
        }
    }
script>


<style>
    .headerBg {
        background: #eee !important;
    }
style>
  1. 然后在index.js中加入路由
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第7张图片
  2. 然后在Aside.vue中加入角色管理侧边栏
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第8张图片
  3. 最后在前端测试一下,发现功能均完好
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第9张图片

四、新建菜单数据表

  1. 在Mysql中新建数据表,添加如下字段
    在这里插入图片描述
  2. 表名如下
    在这里插入图片描述

五、使用代码生成器生成菜单代码

  1. 在CodeGenerator.java中设置刚才的数据库名称
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第10张图片
  2. 然后运行代码生成器,我们发现已经成功生成所需代码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第11张图片
  3. 在生成的MenuController.java中加入如下两行代码,为了实现后面的搜索功能
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第12张图片

六、测试生成的菜单代码

  1. 在Menu.vue中加入如下代码
<template>
    
    <div>
        
        <div style="margin: 10px 0">
            <el-input style="width: 200px" placeholder="请输入名称" suffix-icon="el-icon-search"
                      v-model="name">el-input>
            <el-button class="ml-5" type="primary" @click="load">搜索el-button>
            <el-button type="warning" @click="reset">重置el-button>
        div>

        
        <div style="margin: 10px 0">
            <el-button type="primary" @click="handleAdd">新增 <i class="el-icon-circle-plus-outline">i>el-button>
            <el-popconfirm
                    class="ml-5"
                    confirm-button-text='确定'
                    cancel-button-text='我再想想'
                    icon="el-icon-info"
                    icon-color="red"
                    title="您确定批量删除这些数据吗?"
                    @confirm="delBatch"
            >
                <el-button type="danger" slot="reference">批量删除 <i class="el-icon-remove-outline">i>el-button>
            el-popconfirm>
        div>

        
        <el-table :data="tableData" border stripe :header-cell-class-name="'headerBg'"
                  @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="55">el-table-column>
            <el-table-column prop="id" label="ID" width="80">el-table-column>
            <el-table-column prop="name" label="名称">el-table-column>
            <el-table-column prop="path" label="路径">el-table-column>
            <el-table-column prop="icon" label="图标">el-table-column>
            <el-table-column prop="description" label="描述">el-table-column>
            <el-table-column label="操作" width="200" align="center">
                <template slot-scope="scope">
                    <el-button type="success" @click="handleEdit(scope.row)">编辑 <i class="el-icon-edit">i>el-button>
                    <el-popconfirm
                            class="ml-5"
                            confirm-button-text='确定'
                            cancel-button-text='我再想想'
                            icon="el-icon-info"
                            icon-color="red"
                            title="您确定删除吗?"
                            @confirm="del(scope.row.id)"
                    >
                        <el-button type="danger" slot="reference">删除 <i class="el-icon-remove-outline">i>el-button>
                    el-popconfirm>
                template>
            el-table-column>
        el-table>

        
        <div style="padding: 10px 0">
            <el-pagination
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                    :current-page="pageNum"
                    :page-sizes="[2, 5, 10, 20]"
                    :page-size="pageSize"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="total">
            el-pagination>
        div>

        <el-dialog title="菜单信息" :visible.sync="dialogFormVisible" width="30%">
            <el-form label-width="80px" size="small">
                <el-form-item label="名称">
                    <el-input v-model="form.name" autocomplete="off">el-input>
                el-form-item>
                <el-form-item label="路径">
                    <el-input v-model="form.path" autocomplete="off">el-input>
                el-form-item>
                <el-form-item label="图标">
                    <el-input v-model="form.icon" autocomplete="off">el-input>
                el-form-item>
                <el-form-item label="描述">
                    <el-input v-model="form.description" autocomplete="off">el-input>
                el-form-item>
            el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogFormVisible = false">取 消el-button>
                <el-button type="primary" @click="save">确 定el-button>
            div>
        el-dialog>
    div>
template>


<script>
    export default {
        name: "Role",
        data() {
            return {
                tableData: [],
                total: 0,
                pageNum: 1,
                pageSize: 10,
                name: "",
                form: {},
                dialogFormVisible: false,
                multipleSelection: []
            }
        },
        // 请求分页查询数据
        created() {
            this.load()
        },
        methods: {
            // 将数据库查询操作封装
            load() {
                this.request.get("/menu/page", {
                    params: {
                        pageNum: this.pageNum,
                        pageSize: this.pageSize,
                        name: this.name,
                    }
                }).then(res => {
                    console.log(res)
                    this.tableData = res.records
                    this.total = res.total

                })
            },
            save() {
                this.request.post("/menu", this.form).then(res => {
                    if (res) {
                        this.$message.success("保存成功")
                        this.dialogFormVisible = false
                        this.load()
                    } else {
                        this.$message.error("保存失败")
                    }
                })
            },
            handleAdd() {
                this.dialogFormVisible = true
                this.form = {}
            },
            handleEdit(row) {
                this.form = row
                this.dialogFormVisible = true
            },
            del(id) {
                this.request.delete("/menu/" + id).then(res => {
                    if (res) {
                        this.$message.success("删除成功")
                        this.load()
                    } else {
                        this.$message.error("删除失败")
                    }
                })
            },
            handleSelectionChange(val) {
                console.log(val)
                this.multipleSelection = val
            },
            delBatch() {
                let ids = this.multipleSelection.map(v => v.id)  // [{}, {}, {}] => [1,2,3]
                this.request.post("/menu/del/batch", ids).then(res => {
                    if (res) {
                        this.$message.success("批量删除成功")
                        this.load()
                    } else {
                        this.$message.error("批量删除失败")
                    }
                })
            },
            reset() {
                this.name = ""
                this.load()
            },
            // 动态分页请求
            handleSizeChange(pageSize) {
                console.log(pageSize)
                this.pageSize = pageSize
                this.load()
            },
            handleCurrentChange(pageNum) {
                console.log(pageNum)
                this.pageNum = pageNum
                this.load()
            },
            exp() {
                window.open("http://localhost:9090/menu/export")
            },
            handleExcelImportSuccess(){
                this.$message.success("文件导入成功!")
                this.load()
            }
        }
    }
script>


<style>
    .headerBg {
        background: #eee !important;
    }
style>
  1. 在index.js中设置路由
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第13张图片
  2. 在Aside.vue中加入菜单管理侧边栏
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第14张图片
  3. 最后测试一下,发现所有功能均完好
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第15张图片

七、分配权限菜单基础功能实现

  1. 在Role.vue中加入分配权限菜单功能的按钮
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第16张图片
  2. 效果如下图所示
    在这里插入图片描述
  3. 在Menu.vue中加入如下代码,方便后面的权限分配
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第17张图片
  4. 在Menu.java中加入如下字段
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第18张图片
  5. 在sys_menu表中加入如下父级字段
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第19张图片
  6. 并加入内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第20张图片
  7. 修改MenuController.java中的内容,为了后面的父子级菜单功能
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第21张图片
  8. 来到前端测试,发现成功显示父子目录
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第22张图片
  9. 加入新增子菜单按钮
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第23张图片
  10. 然后完善此函数功能
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第24张图片
  11. 最终效果如下图所示
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第25张图片
  12. 最后将其修改为如下形式,需要注意的是以上操作都在Menu.vue中进行
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第26张图片
  13. 然后在Role.vue中加入菜单分配输入框
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第27张图片
  14. 然后加入相关信息
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第28张图片
  15. 然后新增请求菜单数据的函数
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第29张图片
  16. 最终效果如下图所示,已经成功请求到动态数据了,需要注意以上操作都在Role.vue中完成
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第30张图片

八、分配权限菜单图标显示与编辑功能

  1. 新建数据表
    在这里插入图片描述
  2. 设置表名为sys_dict
    在这里插入图片描述
  3. 在其中输入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第31张图片
  4. 在entity下新建Dict实体类
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第32张图片
  5. 在Dict.java中输入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第33张图片
  6. 在mapper下新建DictMapper,方便后面的增删改查
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第34张图片
  7. 在其中输入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第35张图片
  8. 在MenuController.java中引入DictMapper,方便后续操作
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第36张图片
  9. 然后在MenuController.java中增加查找图标的函数
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第37张图片
  10. 在Constants.java中加入图标类型变量
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第38张图片
  11. 在MenuController.java中加入查询图标类型的代码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第39张图片
  12. 在Menu.vue中加入如下三处代码,为了选择图标
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第40张图片
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第41张图片
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第42张图片
  13. 然后我们来到前台测试,发现已经成功显示图标下拉菜单了
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第43张图片
  14. 然后点击保存,发现已经成功保存图标的代码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第44张图片
  15. 但是现在只能显示图标代码,为了显示真正的图标,我们在Menu.vue中加入如下两处代码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第45张图片
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第46张图片
  16. 然后来到前端测试,我们发现已经成功显示图标样式了
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第47张图片
  17. 但是角色管理那里还没有显示图标也没有默认展开,为了显示图标和默认展开我们同样在Role.vue中修改如下三处代码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第48张图片
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第49张图片
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第50张图片
  18. 然后我们来到角色管理页面,我们发现已经成功显示图标了,而且默认展开
    在这里插入图片描述

九、分配权限菜单的授权保存功能

  1. 新建表输入如下字段内容
    在这里插入图片描述
  2. 将此表命名为sys_role_menu
    在这里插入图片描述
  3. 在entity中新建RoleMenu.java
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第51张图片
  4. 在RoleMenu.java中输入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第52张图片
  5. 然后在mapper中新建RoleMenuMapper.java
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第53张图片
  6. 在RoleMenuMapper.java中输入如下代码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第54张图片
  7. 在RoleMenuMapper.java中输入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第55张图片
  8. 将IRoleService.java替换为如下内容,注意自己的路径
package com.ironmanjay.springboot.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ironmanjay.springboot.entity.Menu;
import com.ironmanjay.springboot.entity.Role;
import com.ironmanjay.springboot.entity.RoleMenu;
import com.ironmanjay.springboot.mapper.RoleMapper;
import com.ironmanjay.springboot.mapper.RoleMenuMapper;
import com.ironmanjay.springboot.service.IMenuService;
import com.ironmanjay.springboot.service.IRoleService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 

* 服务实现类 *

* * @author IronmanJay * @since 2022-09-14 */
@Service public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService { @Resource private RoleMenuMapper roleMenuMapper; @Resource private IMenuService menuService; @Override public void setRoleMenu(Integer roleId, List<Integer> menuIds) { // 先删除当前角色id所有的绑定关系 roleMenuMapper.deleteByRoleId(roleId); // 再把前端传过来的菜单id数组绑定到当前的这个角色id上去 for (Integer menuId : menuIds) { RoleMenu roleMenu = new RoleMenu(); roleMenu.setRoleId(roleId); roleMenu.setMenuId(menuId); roleMenuMapper.insert(roleMenu); } } @Override public List<Integer> getRoleMenu(Integer roleId) { return roleMenuMapper.selectByRoleId(roleId); } }
  1. 在RoleController.java中输入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第56张图片
  2. 然后将Role.vue全部替换为如下内容
<template>
    
    <div>
        
        <div style="margin: 10px 0">
            <el-input style="width: 200px" placeholder="请输入名称" suffix-icon="el-icon-search"
                      v-model="name">el-input>
            <el-button class="ml-5" type="primary" @click="load">搜索el-button>
            <el-button type="warning" @click="reset">重置el-button>
        div>

        
        <div style="margin: 10px 0">
            <el-button type="primary" @click="handleAdd">新增 <i class="el-icon-circle-plus-outline">i>el-button>
            <el-popconfirm
                    class="ml-5"
                    confirm-button-text='确定'
                    cancel-button-text='我再想想'
                    icon="el-icon-info"
                    icon-color="red"
                    title="您确定批量删除这些数据吗?"
                    @confirm="delBatch"
            >
                <el-button type="danger" slot="reference">批量删除 <i class="el-icon-remove-outline">i>el-button>
            el-popconfirm>
        div>

        
        <el-table :data="tableData" border stripe :header-cell-class-name="'headerBg'"
                  @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="55">el-table-column>
            <el-table-column prop="id" label="ID" width="80">el-table-column>
            <el-table-column prop="name" label="名称">el-table-column>
            <el-table-column prop="description" label="描述">el-table-column>
            <el-table-column label="操作" width="280" align="center">
                <template slot-scope="scope">
                    <el-button type="info" @click="selectMenu(scope.row.id)">分配菜单 <i class="el-icon-menu">i>
                    el-button>
                    <el-button type="success" @click="handleEdit(scope.row)">编辑 <i class="el-icon-edit">i>el-button>
                    <el-popconfirm
                            class="ml-5"
                            confirm-button-text='确定'
                            cancel-button-text='我再想想'
                            icon="el-icon-info"
                            icon-color="red"
                            title="您确定删除吗?"
                            @confirm="del(scope.row.id)"
                    >
                        <el-button type="danger" slot="reference">删除 <i class="el-icon-remove-outline">i>el-button>
                    el-popconfirm>
                template>
            el-table-column>
        el-table>

        
        <div style="padding: 10px 0">
            <el-pagination
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                    :current-page="pageNum"
                    :page-sizes="[2, 5, 10, 20]"
                    :page-size="pageSize"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="total">
            el-pagination>
        div>

        <el-dialog title="角色信息" :visible.sync="dialogFormVisible" width="30%">
            <el-form label-width="80px" size="small">
                <el-form-item label="名称">
                    <el-input v-model="form.name" autocomplete="off">el-input>
                el-form-item>
                <el-form-item label="描述">
                    <el-input v-model="form.description" autocomplete="off">el-input>
                el-form-item>
            el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogFormVisible = false">取 消el-button>
                <el-button type="primary" @click="save">确 定el-button>
            div>
        el-dialog>

        <el-dialog title="菜单分配" :visible.sync="menuDialogVis" width="30%">
            <el-tree
                    :props="props"
                    :data="menuData"
                    show-checkbox
                    node-key="id"
                    ref="tree"
                    :default-expanded-keys="expends"
                    :default-checked-keys="checks">
                <span class="custom-tree-node" slot-scope="{ node, data }">
                    <span><i :class="data.icon">i> {{ data.name }}span>
                span>
            el-tree>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogFormVisible = false">取 消el-button>
                <el-button type="primary" @click="saveRoleMenu">确 定el-button>
            div>
        el-dialog>
    div>
template>


<script>
    export default {
        name: "Role",
        data() {
            return {
                tableData: [],
                total: 0,
                pageNum: 1,
                pageSize: 10,
                name: "",
                form: {},
                dialogFormVisible: false,
                menuDialogVis: false,
                multipleSelection: [],
                menuData: [],
                props: {
                    label: 'name',
                },
                expends: [],
                checks: [],
                roleId: 0
            }
        },
        // 请求分页查询数据
        created() {
            this.load()
        },
        methods: {
            // 将数据库查询操作封装
            load() {
                this.request.get("/role/page", {
                    params: {
                        pageNum: this.pageNum,
                        pageSize: this.pageSize,
                        name: this.name,
                    }
                }).then(res => {
                    console.log(res)
                    this.tableData = res.records
                    this.total = res.total

                });
            },
            save() {
                this.request.post("/role", this.form).then(res => {
                    if (res) {
                        this.$message.success("保存成功")
                        this.dialogFormVisible = false
                        this.load()
                    } else {
                        this.$message.error("保存失败")
                    }
                })
            },
            saveRoleMenu() {
                this.request.post("/role/roleMenu/" + this.roleId, this.$refs.tree.getCheckedKeys()).then(res => {
                    if (res.code === '200') {
                        this.$message.success("绑定成功")
                        this.menuDialogVis = false
                    } else {
                        this.$message.error(res.msg)
                    }
                })
            },
            handleAdd() {
                this.dialogFormVisible = true
                this.form = {}
            },
            handleEdit(row) {
                this.form = row
                this.dialogFormVisible = true
            },
            del(id) {
                this.request.delete("/role/" + id).then(res => {
                    if (res) {
                        this.$message.success("删除成功")
                        this.load()
                    } else {
                        this.$message.error("删除失败")
                    }
                })
            },
            handleSelectionChange(val) {
                console.log(val)
                this.multipleSelection = val
            },
            delBatch() {
                let ids = this.multipleSelection.map(v => v.id)  // [{}, {}, {}] => [1,2,3]
                this.request.post("/role/del/batch", ids).then(res => {
                    if (res) {
                        this.$message.success("批量删除成功")
                        this.load()
                    } else {
                        this.$message.error("批量删除失败")
                    }
                })
            },
            reset() {
                this.name = ""
                this.load()
            },
            // 动态分页请求
            handleSizeChange(pageSize) {
                console.log(pageSize)
                this.pageSize = pageSize
                this.load()
            },
            handleCurrentChange(pageNum) {
                console.log(pageNum)
                this.pageNum = pageNum
                this.load()
            },
            selectMenu(roleId) {
                this.menuDialogVis = true;
                this.roleId = roleId;
                // 请求菜单数据
                this.request.get("/menu", {}).then(res => {
                    console.log(res);
                    this.menuData = res.data;
                    // 把后台返回的菜单数据处理成id数组
                    this.expends = this.menuData.map(v => v.id)
                })
                this.request.get("/role/roleMenu/" + this.roleId).then(res => {
                    this.checks = res.data;
                })
            },
        }
    }
script>


<style>
    .headerBg {
        background: #eee !important;
    }
style>
  1. 来到前端测试授权功能
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第57张图片
  2. 最后发现已经将授权信息成功保存到数据库中,这样我们现阶段任务已经完成了
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第58张图片

十、赋予用户以角色

  1. 在sys_user中新增role字段
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第59张图片
  2. 在sys_role中新增flag字段
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第60张图片
  3. 并在sys_role中输入数据
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第61张图片
  4. 在User.java中加入角色字段
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第62张图片
  5. 在Role.java中加入唯一标识字段
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第63张图片
  6. 在Role.vue中添加如下两处代码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第64张图片
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第65张图片
  7. 在User.vue中添加如下四处代码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第66张图片
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第67张图片
    在这里插入图片描述
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第68张图片
  8. 然后来到前端测试
    在这里插入图片描述
  9. 发现已经成功保存了用户的角色信息
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第69张图片

十一、实现用户角色的动态菜单

  1. 在UserDTO中加入两个新的字段
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第70张图片
  2. 在common中新建枚举类型RoleEnum.java
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第71张图片
  3. 在其中输入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第72张图片
  4. 在RoleMapper.java中加入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第73张图片
  5. 在MenuServiceImpl.java中输入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第74张图片
  6. 在IMenuService.java中输入以下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第75张图片
  7. 然后在MenuController.java中将此方法封装
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第76张图片
  8. 在UserServiceImpl.java中引入IMenuService
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第77张图片
  9. 在UserServiceImpl.java中加入如下函数,获取当前角色的菜单信息
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第78张图片
  10. 在UserServiceImpl.java中修改login函数,在登陆的时候设置用户的菜单列表
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第79张图片
  11. 在UserController.java中的login方法中增加如下代码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第80张图片
  12. 然后来到前端测试,发现可以针对不同的用户显示不同的菜单
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第81张图片
  13. 在Login.vue中加入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第82张图片
  14. 然后将Aside.vue全部替换为以下内容

<template>
    <el-menu :default-openeds="opens" style="min-height: 100%; overflow-x: hidden"
             background-color="rgb(48, 65, 86)"
             text-color="#fff"
             active-text-color="#ffd04b"
             :collapse-transition="false"
             :collapse="isCollapse"
             router
    >
        <div style="height: 60px; line-height: 60px; text-align: center">
            <img src="../assets/logo.png" alt="" style="width: 20px; position: relative; top: 5px; right: 5px">
            <b style="color: white" v-show="logoTextShow">后台管理系统b>
        div>
        <div v-for="item in menus" :key="item.id">
            <div v-if="item.path">
                <el-menu-item :index="item.path">
                    <i :class="item.icon">i>
                    <span slot="title">{{ item.name }}span>
                el-menu-item>
            div>
            <div v-else>
                <el-submenu :index="item.id + ''">
                    <template slot="title">
                        <i :class="item.icon">i>
                        <span slot="title">{{ item.name }}span>
                    template>
                    <div v-for="subItem in item.children" :key="subItem.id">
                        <el-menu-item :index="subItem.path">
                            <i :class="subItem.icon">i>
                            <span slot="title">{{ subItem.name }}span>
                        el-menu-item>
                    div>
                el-submenu>
            div>
        div>
    el-menu>
template>

<script>
    export default {
        name: "Aside",
        props: {
            isCollapse: Boolean,
            logoTextShow: Boolean,
        },
        data() {
            return {
                menus: localStorage.getItem("menus") ? JSON.parse(localStorage.getItem("menus")) : [],
                opens: localStorage.getItem("menus") ? JSON.parse(localStorage.getItem("menus")).map(v => v.id + '') : [],
            }
        }
    }
script>

<style scoped>

style>
  1. 然后来到前端发现,不同的用户角色会显示不同的菜单,这样就实现了我们的功能
    ①:普通用户
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第83张图片
    ②:超级用户
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第84张图片

十二、实现用户菜单的动态路由

  1. 在sys_menu中加入新的字段,用来保存页面路径
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第85张图片
  2. 在Menu.java中加入新的对应字段
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第86张图片
  3. 在Menu.vue中加入两处对应字段
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第87张图片
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第88张图片
  4. 然后来到前端测试,给每个页面输入对应的页面路径
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第89张图片
  5. 然后将其保存成如下形式即可
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第90张图片
  6. 将router/index.js中的全部内容替换为如下内容
import Vue from 'vue'
import VueRouter from 'vue-router'
import store from "@/store/store";

Vue.use(VueRouter)

const routes = [
    // 用户登陆页面
    {
        path: '/login',
        name: 'Login',
        component: () => import('../views/Login.vue')
    },
    // 用户注册页面
    {
        path: '/register',
        name: 'Register',
        component: () => import('../views/Register.vue')
    },
    {
        path: '/404',
        name: '404',
        component: () => import('../views/404.vue')
    },
]

const router = new VueRouter({
    mode: 'history',
    base: process.env.BASE_URL,
    routes
})

// 注意:刷新页面会导致页面路由重置
export const setRoutes = () => {
    const storeMenus = localStorage.getItem("menus");
    if (storeMenus) {
        // 拼装动态路由
        const manageRoute = {
            path: '/',
            name: 'Manage',
            component: () => import('../views/Manage.vue'),
            redirect: "/home",
            children: []
        }
        const menus = JSON.parse(storeMenus)
        menus.forEach(item => {
            if (item.path) { // 当且仅当path不为空的时候才去设置路由
                let itemMenu = {
                    path: item.path.replace("/", ""),
                    name: item.name,
                    component: () => import('../views/' + item.pagePath + '.vue')
                }
                manageRoute.children.push(itemMenu)
            } else if (item.children.length) {
                item.children.forEach(item => {
                    if (item.path) {
                        let itemMenu = {
                            path: item.path.replace("/", ""),
                            name: item.name,
                            component: () => import('../views/' + item.pagePath + '.vue')
                        }
                        manageRoute.children.push(itemMenu)
                    }
                })
            }
        })
        // 获取当前的路由对象名称数组
        const currentRouteNames = router.getRoutes().map(v => v.name)
        if (!currentRouteNames.includes("Manage")) {
            // 动态添加到现在的路由对象中去
            router.addRoute(manageRoute)
        }
    }
}

// 重置我就再set一次路由
setRoutes()

// 路由守卫
router.beforeEach((to, from, next) => {
    localStorage.setItem("currentPathName", to.name)  // 设置当前的路由名称,为了在Header组件中去使用
    store.commit("setPath")  // 触发store的数据更新
    // 未找到路由的情况
    if (!to.matched.length) {
        const storeMenus = localStorage.getItem("menus")
        if (storeMenus) {
            next("/404")
        } else {
            // 跳回登录页面
            next("/login")
        }
    }
    next()  // 放行路由
})

export default router
  1. 然后在Login.vue中添加如下两处代码
    在这里插入图片描述
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第91张图片
  2. 然后来到前端发现,已经可以针对不同的用户角色,产生不同的动态菜单路由了
    在这里插入图片描述

十三、完成404提示界面

  1. 在此目录下新建404.vue
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第92张图片
  2. 在router/index.js中写入固定路由404
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第93张图片
  3. 然后上网上随便找一张404的图片,放在此目录下
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第94张图片
  4. 然后将404.vue中全部替换为如下内容
<template>
    <div style="overflow: hidden; height: 100vh">
        <img src="../assets/404.png" alt="" style="width: 100%; height: 100%">
    div>
template>

<script>
    export default {
        name: "NotFound"
    }
script>

<style>
    .bgImg {
        background: url("../assets/404.png") no-repeat;
        background-size: 100% 100vh;
    }
style>
  1. 然后来到前端发现,访问其他非法界面已经可以显示404的提示了,说明成功了
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第95张图片

十四、配置管理员修改用户权限后重新登陆

  1. 在store/store.js中加入如下两处代码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第96张图片
  2. 然后在Header.vue中加入如下代码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第97张图片
  3. 在Role.vue中修改如下四处代码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第98张图片
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第99张图片
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第100张图片
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第101张图片
  4. 然后来到前端测试,发现权限修改后已经成功登录了
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第102张图片

十五、父级菜单不显示的Bug解决

  1. 当我们给普通用户分配子菜单后
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第103张图片
  2. 但是当我们登录普通用户时,明明已经给这个用户分配了子菜单,但是并没有显示,如下图所示,我们要解决这个问题
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第104张图片
  3. 我们只需要在RoleServiceImpl.java中加入如下代码即可
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第105张图片
  4. 然后我们来到前端测试,发现已经成功针对不同的用户显示不同的菜单了
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第106张图片

十六、选择部分子菜单后子菜单全部选中的Bug解决

  1. 当我们只给某个角色赋予部分子菜单后,发现显示的时候展示了全部子菜单内容,这不是我们想要的,我们就要解决这个问题
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第107张图片
  2. 首先在MenuController.java中加入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第108张图片
  3. 然后在Role.vue中加入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第109张图片
  4. 当我们来到前端测试后发现,当我们选中子菜单后,全部的子菜单也并没有选中,而且侧边栏也没有选中,这样就解决了我们的Bug
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第110张图片

十七、随机访问某一界面却进入404界面Bug的解决

  1. 目前有一个Bug,就是当我们点击某个界面的时候,却是打开了404的界面,我们要解决这个问题
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第111张图片
  2. 首先在index.js中修改如下一处代码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第112张图片
  3. 然后再在index.js中修改如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第113张图片
  4. 然后来到前端测试发现问题已经解决
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第114张图片

十八、访问修改密码界面却进入404界面Bug的解决

  1. 首先在如下位置新建UserPasswordDTO.java,并在其中输入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第115张图片
  2. 然后在UserMapper.java中输入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第116张图片
  3. 然后在mapper中新建UserMapper.java,然后在其中输入如下内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第117张图片
  4. 然后在impl中的UserServiceImpl.java中引入此mapper
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第118张图片
  5. 然后还是在UserServiceImpl.java中新建修改密码的函数
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第119张图片
  6. 然后在IUserService.java中新建修改密码的接口
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第120张图片
  7. 然后在UserController.java中新建修改密码的函数
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第121张图片
  8. 然后在views中新建Password.vue
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第122张图片
  9. 然后将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>
  1. 然后在index.js中加入如下路由内容
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第123张图片
  2. 然后来到前端测试发现已经可以成功修改密码
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第124张图片
  3. 修改密码后回要求重新登陆
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第125张图片

十九、提交新增一级菜单信息没反应Bug的解决

  1. 当我们在菜单管理中,新增一级菜单,点击提交后发现没反应
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第126张图片
  2. 此时我们修改Menu.vue中此部分内容即可
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第127张图片
  3. 然后来到前端测试发现已经成功了
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第128张图片

二十、新增菜单页面后授权给用户重新登陆再点击新增的菜单页面却出现404页面Bug的解决

  1. 当我们新增菜单后,将此菜单的权限授予用户,重新登陆后,点击新增的菜单页面却产生了404错误,我们要解决这个问题
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第129张图片
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第130张图片
  2. 为了解决这个问题,我们首先在index.js中新建一个重置路由的方法
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第131张图片
  3. 然后在store.js中引用这个方法用来重置路由
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第132张图片
  4. 再来到前端用同样的方法测试,发现问题已经成功解决了,不会出现404异常界面了(Ps:我使用的文件管理的界面进行测试的,读者也可以新建测试页面)
    SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)_第133张图片

总结

  以上就是今天学习的全部内容了,可以看到内容非常多,而且难度确实不小,但是只要跟着我一步一步做肯定是没问题的,今天就暂时到这里。明天给大家带来关于SpringBoot实现1对1、1对多、多对多关联查询的相关内容。明天见!

你可能感兴趣的:(vue.js,spring,boot,前端,后端,java)