动态路由菜单:根据用户角色动态生成菜单栏的实践(包含子菜单)
前言
在现代后台管理系统中,不同角色的用户通常需要访问不同的功能模块。动态路由菜单技术正是解决这一需求的关键方案。本文将介绍如何基于用户角色实现动态菜单路由,让每个用户登录后只能看到自己权限范围内的菜单项。
核心思路
实现动态路由菜单的核心流程如下:
用户登录认证:验证用户身份并获取用户角色信息
角色权限关联:查询该角色对应的菜单权限
菜单树构建:将扁平化的菜单数据转换为树形结构
前端渲染:将菜单树传递给前端进行动态渲染
代码实现解析
下面是一个基于Spring Boot的实现示例:
接口返回样例:
{
"msg": "操作成功",
"code": 200,
"data": {
"userId": 1,
"username": "admin",
"password": "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
"realName": "管理员",
"contact": "",
"mobile": "15679711120",
"status": 1
},
"roles": "超级管理员",
"routers": [
{
"name": "系统管理",
"path": "/sys",
"hidden": "false",
"redirect": "noRedirect",
"component": "Layout",
"alwaysShow": true,
"meta": {
"title": "系统管理",
"icon": "system"
},
"children": [
{
"name": "管理员管理",
"path": "/user",
"hidden": "false",
"component": "sys/user/index",
"meta": {
"title": "管理员管理",
"icon": "user"
}
}
]
}
]
}
@Autowiredprivate UserMapper userMapper;@Overridepublic List<MenuRouterVO> GetMenuByID(Integer userId) {//1.根据用户的id查询该用所对应的角色以及该角色所对应的菜单List<Menu> menuList=userMapper.GetMenuByID(userId);//2.创建一个集合List<MenuRouterVO> 最终的集合List<MenuRouterVO> list=new ArrayList<MenuRouterVO>();//3.遍历该用户所能查看的所有菜单找到一级菜单封装进MenuRouterVOfor (Menu menu : menuList) {//前提prentId=0才可以if(menu.getParentId()==0){//创建一个新的父级菜单对象MenuRouterVO menuRouterVO = new MenuRouterVO();//给父级菜单对象赋值 bean实体类的封装工具类 框架提供的//将指定对象中的相同属性赋值给新对象(目标对象)BeanUtils.copyProperties(menu,menuRouterVO);//再将没有的属性进行赋值MenuMetaVO metaVO = new MenuMetaVO();metaVO.setTitle(menu.getName());metaVO.setIcon(menu.getIcon());menuRouterVO.setMeta(metaVO);//父级菜单的最后一个属性children 赋值List<MenuChildrenVO> children = new ArrayList<>();//生成childrenInteger menuId = menu.getMenuId();//二次遍历 找子菜单//4.不是一级菜单的继续遍历找到属于哪个一级菜单下挂在该菜单下for (Menu child : menuList) {if(child.getParentId() == menuId){//5.封装子菜单ChildMenuRouterVO 在放进集合List<ChildMenuRouterVO>MenuChildrenVO childVO = new MenuChildrenVO();BeanUtils.copyProperties(child, childVO);MenuMetaVO childMetaVO = new MenuMetaVO();childMetaVO.setTitle(child.getName());childMetaVO.setIcon(child.getIcon());childVO.setMeta(childMetaVO);children.add(childVO);}}//6.将子菜单集合挂在MenuRouterVO的children的集合属性下menuRouterVO.setChildren(children);//7.将每一个MenuRouterVO放进大集合list.add(menuRouterVO);}}//8.返回外层大集合List<MenuRouterVO>return list;}
博主这里有三个表,人员表(包含角色ID),人员角色中间表(人员id,角色id),角色表
本方法适用于二级菜单大家可以根据上面的思路和自己系统的需要设计自己需要的接口