谷粒学院权限管理模块
文章目录
- 谷粒学院项目权限管理模块
- 1.数据库表
- 2.菜单相关操作
- 2.1 递归查询全部菜单
- 2.2 递归删除菜单
- 2.3 给角色分配权限
- 2.4 根据角色获取菜单
- 2.5 添加菜单
- 2.6 修改菜单
- 3.角色相关操作
- 3.1 获取角色分页列表
- 3.2 其他操作
- 4.用户相关操作
- 4.1 获取管理用户分页列表
- 4.2 根据用户获取角色数据
- 4.3 根据用户分配角色
- 4.4 其他操作
谷粒学院项目权限管理模块
1.数据库表
这里系统权限控制采用的访问控制模型是 RBAC 模型
RBAC模型:
RBAC 即基于角色的权限访问控制(Role-Based Access Control)。这是一种通过角色关联权限,角色同时又关联用户的授权的方式。
简单地说:一个用户可以拥有若干角色,每一个角色又可以被分配若干权限,这样就构造成“用户-角色-权限” 的授权模型。在这种模型中,用户与角色、角色与权限之间构成了多对多的关系,如下图:
在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。
菜单表
acl_permission
角色表
acl_role
用户表
acl_user
角色—菜单表
acl_role_permission
用户—角色表
acl_user_role
几个表之间的关系:
2.菜单相关操作
2.1 递归查询全部菜单
controller
:
/*** 递归获取全部菜单 √* @return R*/
@GetMapping
public R indexAllPermission() {List<Permission> list = permissionService.queryAllMenuGuli();return R.ok().data("children",list);
}
service
:
/*** 递归查询所有菜单** @return*/
@Override
public List<Permission> queryAllMenuGuli() {//1.查询菜单表所有数据LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();//按id从大到小排序queryWrapper.orderByDesc(Permission::getId);List<Permission> permissionList = baseMapper.selectList(queryWrapper);//2.把查询所有的菜单按照要求封装List<Permission> resultList = bulidPermission(permissionList);return resultList;
}
把返回所有菜单list集合进行封装,具体分为这几步:
- 创建list集合,用于数据最终封装
- 把所有菜单list集合遍历,得到顶层菜单
pid=0
菜单,设置level=1
- 根据顶层菜单,向里面进行查询子菜单,封装到最终返回结果
finalNode
里面
/*** 把返回所有菜单list集合进行封装的方法** @param permissionList* @return*/
public static List<Permission> bulidPermission(List<Permission> permissionList) {//1.创建list集合,用于数据最终封装List<Permission> finalNode = new ArrayList<>();//2.把所有菜单list集合遍历,得到顶层菜单 pid=0菜单,设置level是1for (Permission permission : permissionList) {//得到顶层菜单 pid=0菜单if ("0".equals(permission.getPid())) {//设置顶层菜单的level是1permission.setLevel(1);//3.根据顶层菜单,向里面进行查询子菜单,封装到finalNode里面finalNode.add(selectChildren(permission, permissionList));}}return finalNode;
}
递归查找当前菜单的所有子菜单,具体分这几步:
- 因为向一层菜单里面放二层菜单,二层里面还要放三层,所以先把把子菜单集合初始化
- 遍历所有菜单list集合,进行判断比较,比较当前菜单pid和传过来的父菜单id值是否相同,相同就是该父菜单的子菜单
- 设置当前菜单level为父菜单level+1
- 设置子菜单,子菜单依然需要递归查询子菜单是否也有子菜单
/*** 递归查找当前菜单的所有子菜单** @param permissionNode 需要查找子菜单的当前菜单* @param permissionList 所有菜单的集合* @return*/
private static Permission selectChildren(Permission permissionNode, List<Permission> permissionList) {//因为向一层菜单里面放二层菜单,二层里面还要放三层,把对象初始化permissionNode.setChildren(new ArrayList<Permission>());//遍历所有菜单list集合,进行判断比较,比较id和pid值是否相同,是不是当前菜单的子菜单for (Permission permission : permissionList) {//当前菜单的pid=上级菜单idif (permission.getPid().equals(permissionNode.getId())) {int level = permissionNode.getLevel() + 1;//设置当前菜单level为父菜单level+1permission.setLevel(level);//设置子菜单,子菜单依然需要递归查询子菜单是否也有子菜单permissionNode.getChildren().add(selectChildren(permission, permissionList));}}return permissionNode;
}
2.2 递归删除菜单
controller
:
/*** 递归删除菜单 √* @param id* @return*/
@DeleteMapping("remove/{id}")
public R remove(@PathVariable String id) {permissionService.removeChildByIdGuli(id);return R.ok();
}
service
:
/*** 递归删除菜单** @param id 菜单id*/
@Override
public void removeChildByIdGuli(String id) {//1.创建list集合,用于封装所有删除菜单id值List<String> idList = new ArrayList<>();//2.加入所有子菜单的idthis.selectPermissionChildById(id, idList);//3.加入自己的ididList.add(id);//4.批量根据id删除菜单baseMapper.deleteBatchIds(idList);
}
根据当前菜单id,查询其所有的子菜单的id并放入idList,分为这几步:
- 根据id查询下一层子菜单
- 循环变量子菜单list,将id放入idList
- 递归求子id的子id,也放入idList,以此类推
/*** 根据当前菜单id,查询菜单里面子菜单id,封装到list集合** @param id 当前菜单id* @param idList 最终封装要删除的id集合*/
private void selectPermissionChildById(String id, List<String> idList) {LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();//1.查询菜单里面子菜单idqueryWrapper.eq(Permission::getPid, id);//2.只需要idqueryWrapper.select(Permission::getId);List<Permission> childIdList = baseMapper.selectList(queryWrapper);//3.遍历子id集合,加入idList,然后递归遍历子菜单的子菜单childIdList.stream().forEach(item -> {idList.add(item.getId());selectPermissionChildById(item.getId(), idList);});
}
2.3 给角色分配权限
controller
:
根据角色id和菜单id集合,一个角色分配多个菜单(权限):
/*** 给角色分配权限 √* @param roleId 角色id* @param permissionId 分配的菜单id集合* @return*/
@PostMapping("/doAssign")
public R doAssign(String roleId,String[] permissionId) {permissionService.saveRolePermissionRealtionShipGuli(roleId,permissionId);return R.ok();
}
service
:
/*** 角色分配菜单** @param roleId 角色id* @param permissionIds 菜单id集合*/
@Override
public void saveRolePermissionRealtionShipGuli(String roleId, String[] permissionIds) {//1.创建list集合,用于封装添加数据List<RolePermission> permissionList = new ArrayList<>();for (String permissionId : permissionIds) {if (StringUtils.isEmpty(permissionId)) continue;RolePermission rolePermission = new RolePermission();rolePermission.setPermissionId(permissionId);rolePermission.setRoleId(roleId);permissionList.add(rolePermission);}//2.批量保存到acl_role_permission表rolePermissionService.saveBatch(permissionList);
}
2.4 根据角色获取菜单
controller
:
根据角色id获取对应的拥有的菜单集合:
/*** 根据角色获取菜单* @param roleId* @return*/
@GetMapping("toAssign/{roleId}")
public R toAssign(@PathVariable String roleId) {List<Permission> list = permissionService.selectAllMenu(roleId);return R.ok().data("children", list);
}
service
:
根据角色id获取菜单集合,具体分为这几步:
- 查询所有Perssion,并按id排序得到permissionList
- 根据roleId查询在acl_role_permission表里查询所有RolePerssion得到rolePermissionList
- 用stream将rolePermissionList所有对应的permissionId提取出来得到permissionIdList
- 遍历permissionList,如果对象的id是目标集合permissionIdList里的id,则设置select为true
- 把所有的菜单list集合permissionList进行树状封装,递归封装,最终返回
/*** 根据角色获取菜单** @param roleId 角色id* @return*/
@Override
public List<Permission> selectAllMenu(String roleId) {//1.查询所有Perssion,并按id排序List<Permission> permissionList = baseMapper.selectList(new LambdaQueryWrapper<Permission>().orderByDesc(Permission::getId));//2.根据roleId查询在acl_role_permission表里查询所有RolePerssionList<RolePermission> rolePermissionList = rolePermissionService.list(new LambdaQueryWrapper<RolePermission>().eq(RolePermission::getRoleId, roleId));//3.用stream将rolePermissionList所有对应的permissionId提取出来List<String> permissionIdList = rolePermissionList.stream().map(e -> e.getPermissionId()).collect(Collectors.toList());//4.遍历permissionList,如果对象的id是目标集合permissionIdList里的id,则设置select为truepermissionList.forEach(permission->{if(permissionIdList.contains(permission.getId())){permission.setSelect(true);}else{permission.setSelect(false);}});//5.把所有的菜单list集合进行树状封装,递归封装List<Permission> resPermission = bulidPermission(permissionList);return resPermission;
}
2.5 添加菜单
controller
:
直接调用mybatis-plus提供的方法:
/*** 新增菜单 √* @param permission* @return*/
@PostMapping("save")
public R save(@RequestBody Permission permission) {permissionService.save(permission);return R.ok();
}
2.6 修改菜单
controller
:
根据菜单id修改菜单,直接调用mybatis-plus提供的方法:
/*** 修改菜单 √* @param permission* @return*/
@PutMapping("update")
public R updateById(@RequestBody Permission permission) {//直接根据id修改permissionService.updateById(permission);return R.ok();
}
3.角色相关操作
3.1 获取角色分页列表
/*** 获取角色分页列表* @param page 当前页* @param limit 每页数量* @param role 查询的角色,根据名字模糊查询* @return*/
@GetMapping("{page}/{limit}")
public R index(@PathVariable Long page, @PathVariable Long limit, Role role) {//构造page对象Page<Role> pageParam=new Page<>(page,limit);//构造查询,如果有名字查询则进行like模糊查询LambdaQueryWrapper<Role> queryWrapper=new LambdaQueryWrapper<>();if(StringUtils.isNotBlank(role.getRoleName())){queryWrapper.like(Role::getRoleName,role.getRoleName());}//进行带条件的分页查询roleService.page(pageParam,queryWrapper);//返回最终的数据集合和总条数return R.ok().data("items",pageParam.getRecords()).data("total",pageParam.getTotal());
}
3.2 其他操作
根据id获取角色:
/*** 根据id获取角色** @param id 角色id* @return*/
@GetMapping("get/{id}")
public R get(@PathVariable String id) {Role role = roleService.getById(id);return R.ok().data("item", role);
}
新增角色:
/*** 保存角色** @param role 角色对象* @return*/
@PostMapping("save")
public R save(@RequestBody Role role) {roleService.save(role);return R.ok();
}
根据id修改角色:
/*** 根据id修改角色** @param role* @return*/
@PutMapping("update")
public R updateById(@RequestBody Role role) {roleService.updateById(role);return R.ok();
}
根据id删除角色:
/*** 根据id删除角色** @param id* @return*/
@DeleteMapping("remove/{id}")
public R remove(@PathVariable String id) {roleService.removeById(id);return R.ok();
}
批量删除角色:
/*** 批量删除角色** @param idList 要删除角色的id集合* @return*/
@DeleteMapping("batchRemove")
public R batchRemove(@RequestBody List<String> idList) {roleService.removeByIds(idList);return R.ok();
}
4.用户相关操作
4.1 获取管理用户分页列表
/*** 获取管理用户分页列表** @param page 当前页* @param limit 每页数量* @param userQueryVo 查询条件,根据用户名字模糊查询* @return*/
@GetMapping("{page}/{limit}")
public R index(@PathVariable Long page, @PathVariable Long limit, User userQueryVo) {//构造page对象Page<User> pageParam = new Page<>(page, limit);构造查询,如果有名字查询则进行like模糊查询LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();if (StringUtils.isNotBlank(userQueryVo.getUsername())) {queryWrapper.like(User::getUsername, userQueryVo.getUsername());}//进行带条件的分页查询userService.page(pageParam, queryWrapper);//返回最终的数据集合和总条数return R.ok().data("items", pageParam.getRecords()).data("total", pageParam.getTotal());
}
4.2 根据用户获取角色数据
controller
:
/*** 根据用户获取角色数据* @param userId 用户id* @return*/
@GetMapping("/toAssign/{userId}")
public R toAssign(@PathVariable String userId) {Map<String, Object> roleMap = roleService.findRoleByUserId(userId);return R.ok().data(roleMap);
}
service
:
/*** 根据用户获取角色数据** @param userId* @return*/
@Override
public Map<String, Object> findRoleByUserId(String userId) {//1.查询所有的角色List<Role> roleList = baseMapper.selectList(null);//2.根据用户id查询对应UserRole对象List<UserRole> userRoleList = userRoleService.list(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userId).select(UserRole::getRoleId));//3.将UserRole对象等价转换为Role集合,这些角色就是该用户拥有的List<Role> resRoles = userRoleList.stream().map(e -> baseMapper.selectById(e.getRoleId())).collect(Collectors.toList());Map<String, Object> map = new HashMap<>();//4.告诉前端哪些是角色是该用户已经拥有的map.put("assignRoles", resRoles);//5.为了前端显示所有的角色map.put("allRolesList", roleList);return map;
}
4.3 根据用户分配角色
controller
:
/*** 根据用户分配角色* @param userId 用户id* @param roleId 角色id集合* @return*/
@PostMapping("/doAssign")
public R doAssign(@RequestParam String userId, @RequestParam String[] roleId) {roleService.saveUserRoleRealtionShip(userId, roleId);return R.ok();
}
service
:
/*** 根据用户分配角色* @param userId* @param roleIds*/
@Override
public void saveUserRoleRealtionShip(String userId, String[] roleIds) {//分配前,先将原有的删除userRoleService.remove(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, userId));List<UserRole> userRoleList = new ArrayList<>();//遍历roleIds,一个个封装到UserRolefor (String roleId : roleIds) {if (StringUtils.isEmpty(roleId)) continue;UserRole userRole = new UserRole();userRole.setRoleId(roleId);userRole.setUserId(userId);userRoleList.add(userRole);}//批量保存userRoleService.saveBatch(userRoleList);
}
4.4 其他操作
新增管理用户:
/*** 新增管理用户** @param user* @return*/
@PostMapping("save")
public R save(@RequestBody User user) {//需要先把密码进行MD5加密在存入数据库user.setPassword(MD5.encrypt(user.getPassword()));userService.save(user);return R.ok();
}
根据id修改管理用户:
/*** 修改管理用户* @param user* @return*/
@PutMapping("update")
public R updateById(@RequestBody User user) {userService.updateById(user);return R.ok();
}
根据id删除管理用户:
/*** 删除管理用户* @param id* @return*/
@DeleteMapping("remove/{id}")
public R remove(@PathVariable String id) {userService.removeById(id);return R.ok();
}
批量删除管理用户:
/*** 根据id列表删除管理用户* @param idList* @return*/
@DeleteMapping("batchRemove")
public R batchRemove(@RequestBody List<String> idList) {userService.removeByIds(idList);return R.ok();
}
谷粒学院权限管理模块相关推荐
- 谷粒学院订单管理 server-order 模块
谷粒学院订单管理 server-order 模块 模块介绍 主要实现前台页面购买课程后,生成订单,并实现微信支付的功能. ![]](https://img-blog.csdnimg.cn/7b821f ...
- Expo大作战(三十)--expo sdk api之Permissions(权限管理模块),Pedometer(计步器api)
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- 一个权限管理模块的设计(转载)
一 个用户权限管理模块的设计思路: 1. 权 限资源(功能资源) 系统的所有权限信息.权限具有上下级关系,是一个树状的结构.如下: <!--[if !supportLists]-->u ...
- 一个简易实用的web权限管理模块的应用与实现
本文介绍一个简易实用的web权限管理模块的应用与实现. 先介绍数据模型和应用界面,后继对实现细节做选择性阐述. 数据表关系如下: 该图标明了登陆用户.角色.部门(机构).用户组.角色和模块功能之间的关 ...
- Yii框架中使用SRBAC作为权限管理模块时遇到的问题
Yii框架中使用SRBAC作为权限管理模块时遇到的问题 Yii框架中使用SRBAC作为权限管理模块时遇到的问题 看到Yii中提供RBAC的插件,SRBAC,就想用用. 结果按照手册上的安装办法,整来整 ...
- 6. 添加权限管理模块
本文主要是以权限管理模块为例来介绍使用springboot+mybatis完成增删改查的功能. 1. 添加Permission实体类 1 package com.lvniao.blog.model; ...
- 通俗易懂权限管理模块设计-Java
最近一直在做CMS系统,发现一些内容其实都是重复出现的,例如权限管理模块.权限管理模块就是为了管理用户是否有权利访问某个权限,如果不能则拒绝访问.其实Java中已经有很成熟的权限管理框架,例如 Shi ...
- 谷粒学院——后台管理系统功能模块
在线教育 普通用户前台使用系统 管理员后台管理系统 讲师管理模块 环境搭建 讲师列表查询 讲师删除(逻辑删除) 整合swagger 统一结果数据返回 分页查询讲师 新增讲师 统一异常处理 日志 登录功 ...
- 如何设计一个权限管理模块?
我们每天都在使用各种各样的办公自动化系统,也叫OA.ERP系统.不同的用户登录能看到的菜单和数据资源都不一样. 比如,管理员登入财务系统,能看见员工模块,员工登录就看不见,这就是菜单权限:员工登录财务 ...
- Java代码生成器codeMan重磅更新——添加权限管理模块生成功能,实现动态菜单和按钮级别的权限控制
前言 转眼又过去了两个多月,时间就像一个隐形的精灵,总是在不经意间从眼皮底下溜走,不知不觉已经8月底了,金九银十近在眼前,不知道小伙伴们有没有跳槽的打算呢?相信此时你的心中已经有了自己的答案.闲言少叙 ...
最新文章
- 自动添加端口添加至Windows防火墙脚本
- 【小白学习PyTorch教程】十九、 基于torch实现UNet 图像分割模型
- linux通过c语言编程访问远程mysql
- destroy 方法_线程方法destroy()和stop(Throwable)在JDK 11中删除
- MySQL学习(三)
- 对比 SQL Server 2005 和 Oracle
- c++ 字符串转数字
- ESP32开发 0.windows Vscode开发环境搭建,基于esp-idf-V4.2 | Cmake | Vscode插件
- IE浏览器使用Validation Engine表单重复提交问题
- 常用RAID类型以及它们的区别
- Android每日一记
- Leetcode 122.买卖股票的最佳时机II
- php 打印所有常量,php中输出常量
- linux最新的发布版本号,求问Linux最新内核版本以及发布日期。
- 关于attachEvent与addEventListener事件绑定兼容问题
- 联想笔记本prtsc不能截图_Win10系统下怎么截屏
- 攻防世界 REVERSE 新手区/logmein
- 【12306购票】测试运行以及完整代码
- 如何修改PDF中图片的大小尺寸
- 如何解决浏览器提示“您与此网站之间建立的连接不安全”