目录
2、角色分配菜单代码: node-key="id" ,:props="props"
问题1:http://localhost:8080/ 报404
一、Java服务端代码
1、模版自动生成后端菜单和角色代码
MenuController.java
package com.example.demo.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
import com.example.demo.common.Result;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.web.bind.annotation.PathVariable;
import com.example.demo.service.IMenuService;
import com.example.demo.entity.Menu;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
*
* </p>
*
* @author cizhu
* @since 2023-11-22
*/
@RestController
@RequestMapping("/menu")
public class MenuController {
@Resource
private IMenuService menuService;
// 新增或者更新
/***********************************
* 用途说明:
* @param menu
* 返回值说明:
* @return Result
***********************************/
@PostMapping
public Result save(@RequestBody Menu menu) {
return Result.success(menuService.saveOrUpdate(menu));
}
/***********************************
* 用途说明:
* @param id
* 返回值说明:
* @return Result
***********************************/
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
return Result.success(menuService.removeById(id));
}
/***********************************
* 用途说明:
* @param ids
* 返回值说明:
* @return Result
***********************************/
@PostMapping("/del/batch")
public Result deleteBatch(@RequestBody List<Integer> ids) {
return Result.success(menuService.removeByIds(ids));
}
/***********************************
* 用途说明:
* @param:
* 返回值说明:
* @return Result
***********************************/
@GetMapping
public Result findAll(@RequestParam(defaultValue ="") String name) {
QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name",name);
List<Menu> list = menuService.list(queryWrapper);
//找pid=null的一级菜单
List<Menu> parentNode = list.stream().filter(menu -> menu.getPid()==null).collect(Collectors.toList());
//找出一级菜单的子菜单
for(Menu menu:parentNode){
menu.setChildren(list.stream().filter(m ->menu.getId().equals(m.getPid())).collect(Collectors.toList()));
}
//返回一级菜单
return Result.success(parentNode);
}
/***********************************
* 用途说明:
* @param id
* 返回值说明:
* @return Result
***********************************/
@GetMapping("/{id}")
public Result findOne(@PathVariable Integer id) {
return Result.success(menuService.getById(id));
}
/***********************************
* 用途说明:
* @param pageNum pageSize menu
* 返回值说明:
* @return Result
***********************************/
@GetMapping("/page")
public Result findPage(@RequestParam Integer pageNum,
@RequestParam Integer pageSize, @RequestParam String name) {
QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("id");
queryWrapper.like("name",name);
return Result.success(menuService.page(new Page<>(pageNum, pageSize), queryWrapper));
}
}
RoleController.java
package com.example.demo.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.common.Result;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.web.bind.annotation.PathVariable;
import com.example.demo.service.IRoleService;
import com.example.demo.entity.Role;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
*
* </p>
*
* @author cizhu
* @since 2023-11-22
*/
@RestController
@RequestMapping("/role")
public class RoleController {
@Resource
private IRoleService roleService;
// 新增或者更新
/***********************************
* 用途说明:
* @param role
* 返回值说明:
* @return Result
***********************************/
@PostMapping
public Result save(@RequestBody Role role) {
return Result.success(roleService.saveOrUpdate(role));
}
/***********************************
* 用途说明:
* @param id
* 返回值说明:
* @return Result
***********************************/
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
return Result.success(roleService.removeById(id));
}
/***********************************
* 用途说明:
* @param ids
* 返回值说明:
* @return Result
***********************************/
@PostMapping("/del/batch")
public Result deleteBatch(@RequestBody List<Integer> ids) {
return Result.success(roleService.removeByIds(ids));
}
/***********************************
* 用途说明:
* @param:
* 返回值说明:
* @return Result
***********************************/
@GetMapping
public Result findAll() {
return Result.success(roleService.list());
}
/***********************************
* 用途说明:
* @param id
* 返回值说明:
* @return Result
***********************************/
@GetMapping("/{id}")
public Result findOne(@PathVariable Integer id) {
return Result.success(roleService.getById(id));
}
/***********************************
* 用途说明:
* @param pageNum pageSize role
* 返回值说明:
* @return Result
***********************************/
@GetMapping("/page")
public Result findPage(@RequestParam Integer pageNum,
@RequestParam Integer pageSize,
@RequestParam String name) {
QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name",name);
queryWrapper.orderByDesc("id");
return Result.success(roleService.page(new Page<>(pageNum, pageSize), queryWrapper));
}
}
2、父子菜单列表
@GetMapping
public Result findAll(@RequestParam(defaultValue ="") String name) {
QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name",name);
List<Menu> list = menuService.list(queryWrapper);
//找pid=null的一级菜单
List<Menu> parentNode = list.stream().filter(menu -> menu.getPid()==null).collect(Collectors.toList());
//找出一级菜单的子菜单
for(Menu menu:parentNode){
menu.setChildren(list.stream().filter(m ->menu.getId().equals(m.getPid())).collect(Collectors.toList()));
}
//返回一级菜单
return Result.success(parentNode);
}
二、Vue前端代码
1、菜单树形表格代码
- 表单中添加row-key="id" default-expand-all 属性
- 新增分配子菜单操作代码
<el-table :data="tableData" border stripe
:header-cell-class-name="headerBg"
row-key="id" default-expand-all
@selection-change="handleSelectionChange">
>
<el-table-column type="selection" width="55"> </el-table-column>
<el-table-column prop="id" label="ID" width="80" align="center">
</el-table-column>
<el-table-column prop="name" label="名称" align="center">
</el-table-column>
<el-table-column prop="path" label="路径" align="center">
</el-table-column>
<el-table-column prop="icon" label="图标" align="center">
</el-table-column>
<el-table-column prop="description" label="描述" align="center">
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="primary" @click="handleAdd(scope.row.id)" v-if="!scope.row.pid &&!scope.row.path">新增子菜单<i class="el-icon-plus"></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>
2、角色分配菜单代码: node-key="id" ,:props="props"
<el-dialog title="菜单分配" :visible.sync="menuDialogVis" width="30%" style="padding: 0 30px;">
<el-tree
:props="props"
:data="menuData"
show-checkbox
node-key="id"
:default-expanded-keys="[1]"
:default-checked-keys="[4]"
@check-change="handleCheckChange">
</el-tree>
<div slot="footer" class="dialog-footer">
<el-button @click="menuDialogVis = false">取 消</el-button>
<el-button type="primary" @click="save">确 定</el-button>
</div>
</el-dialog>
selectMenu(roleId) {
this.menuDialogVis = true
//请求菜单数据
this.request.get("/menu", {}).then(res => {
this.menuData = res.data
})
}
问题1:http://localhost:8080/ 报404
{
path: '/404',
name: '404',
component: () => import( '../views/404.vue')
}
router.js
问题2、修改个人信息和修改密码404
添加页面和权限,位置移动先弹窗出现,tree对象存在再执行。
先处理数据,等对象出来后展示
问题3: 新增菜单和权限,点击页面报404
路由没有添加到登录后的用户中
//提供一个重置路由方法
export const resetRouter=()=>{
router.matcher = new VueRouter({
mode:'history',
base:process.env.BASE_URL,
routes
})
}
import router,{resetRouter} from '@/router'
mutations:{
setPath(state){
state.currentPathName= localStorage.getItem("currentPathName")
},
logOut(){
localStorage.removeItem("user")
localStorage.removeItem("menus")
router.push("/login")
//重置路由
resetRouter()
}
}
export const setRoutes = ()=>{
const storeMenus = localStorage.getItem("menus")
if(storeMenus){
//获取当前路由数组名称
const currentRoutesNames = router.getRoutes().map(v=>v.name)
if(!currentRoutesNames.includes('Manage')){
const manageRoute = {path: '/',name: 'Manage',component: () => import('../views/Manage.vue'),redirect: '/home',children:[
{path: 'person',name: '个人信息',component: () => import('../views/Person.vue')},
{path: 'password',name: '修改密码',component: () => import('../views/Password.vue')}
]}
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)
}
})
}
})
//拼装动态路由
router.addRoute(manageRoute)
}
// router.addRoute(manageRoute)
}
}
//提供一个重置路由方法
export const resetRouter=()=>{
router.matcher = new VueRouter({
mode:'history',
base:process.env.BASE_URL,
routes
})
}