本文主要是介绍SpringBoot整合Sa-Token实现RBAC权限模型的过程解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《SpringBoot整合Sa-Token实现RBAC权限模型的过程解析》:本文主要介绍SpringBoot整合Sa-Token实现RBAC权限模型的过程解析,本文给大家介绍的非常详细,对大家的学...
前言
本文将介绍SpringBoot结合sa-token实现RBAC权限模型。
一、基础概念
1.1 RBAC模型核心概念
- 用户(User)、角色(Role)、权限(Permission)的关系。
- 模型分层:用户-角色-权限的三层结构。
- RBAC的基本思想是,对系统操作的各种权限不是直接授予具体的用户,而是在用户集合与权限集合之间建立一个角色集合。每一种角色对应一组相应的权限。一旦用户被分配了适当的角色后,该用户就拥有此角色的所有操作权限。
1.2 Sa-Token核心功能
- 登录认证(StpUtil)、权限校验、会话管理、踢人下线等。
- 关键注解:@SaCheckLogin、@SaCheckRole、@SaCheckPermission。
1.3 环境准备
- JDK 1.8+、Maven、SpringBoot 2.x。
- 初始化SpringBoot项目(可通过Spring Initializr生成)。
- mysql5.x/8.x
二、表结构设计
2.1 ER图示例
2.2 数据库表设计
2.2.1 用户表
CREATE TABLE `tb_user` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '主键', `username` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '用户名', `password` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '密码', `open_id` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '长期授权字符串', `photo` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '头像网址', `name` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '姓名', `sex` enum('男','女') CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '性别', `tel` char(11) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '手机号码', `email` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '邮箱', `hiredate` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '入职日期', `role` json DEFAULT NULL COMMENT http://www.chinasem.cn'角色', `root` tinyint(1) DEFAULT '0' COMMENT '是否是超级管理员', `dept_id` int DEFAULT NULL COMMENT '部门编号', `status` tinyint DEFAULT NULL COMMENT '状态', `create_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=72 DEChina编程FAULT CHARSET=utf8mb3 COMMENT='用户表';
2.2.2 角色表
CREATE TABLE `tb_role` ( `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', `role_name` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '角色名称', `permissions` json NOT NULL COMMENT '权限集合', `desc` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '描述', `default_permissions` json DEFAULT NULL COMMENT '系统角色内置权限', `systemic` int DEFAULT '0' COMMENT '是否为系统内置角色', `echo` json DEFAULT NULL COMMENT '权限回显集合', PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb3 COMMENT='角色表';
2.2.3 部门表
CREATE TABLE `tb_dept` ( `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', `dept_name` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '部门名称', `tel` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '部门电话', `email` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '部门邮箱', `desc` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '备注', PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3 COMMENT='部门表';
2.2.4 权限表
CREATE TABLE `tb_permission` ( `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', `parent_id` int DEFAULT NULL COMMENT '父级id', `permission_name` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '权限', `module_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '模块名称', `menu_type` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '菜单类型', `icon` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '菜单图标', `path` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '菜单路由', `create_time` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '创建时间', `sort` varchar(255) DEFAULT NULL COMMENT '菜单排序', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `unq_permission` (`permission_name`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=166 DEFAULT CHARSET=utf8mb3 COMMENT='权限表';
三、SpringBoot整合Sa-Token
3.1 sa-token基础配置
3.1.1 Maven配置
<!--SaToken--> <dependency> <groupId>cn.dev33</groupId> <artifactId>sa-token-spring-boot-starter</artifactId> <version>1.34.0</version> </dependency> <dependency> <groupId>cn.dev33</groupId> <artifactId>sa-token-spring-aop</artifactId> <version>1.34.0</version> </dependency>
3.1.2 application.yml
sa-token: # token 名称(同时也是 cookie 名称) token-name: token # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 active-timeout: -1 # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: false # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 is-log: false
3.1.3 StpUtil鉴权工具类
StpUtil.login(10001); // 会话登录 StpUtil.login(10001, "APP"); // 会话登录,并指定设备类型 StpUtil.getTokenValueByLoginId(10001); // 获取指定账号id的tokenValue StpUtil.getTokenValueByLoginId(10001, "PC"); // 获取指定账号id指定设备类型端的tokenValue StpUtil.getPermissionList(); // 获取:当前账号的权限集合 StpUtil.getPermissionList(10001); // 获取:指定账号的权限集合 StpUtil.logoutcDBwgS(); // 会话注销 StpUtil.logout(10001); // 会话注销,根据账号id StpUtil.logout(10001, "PC"); // 会话注销,根据账号id 和 设备类型
3.1.4 编写鉴权类
提示:鉴权类是需要我们自己实现的,必须要扩展StpInterface接口才可以。
@Component class StpInterfaceImpl implements StpInterface { @Resource private UserDao userDao; /** * 返回一个用户所拥有的权限集合 */ @Override public List<String> getPermissionList(Object loginId, String loginType) { List<String> list = new ArrayList<>(); int userId = Integer.parseInt(loginId.toString()); Set<String> set = userDao.searchUserPermissions(userId); list.addAll(set); return list; } /** * 返回一个用户所拥有的角色标识集合 */ @Override public List<String> getRoleList(Object loginId, String loginKey) { ArrayList<String> list = new ArrayList(); return list; } }
四、RBAC模型设计与实现
4.1 用户管理及登陆实现
4.1.1 定义UserDao类实现接口
** * @author lenovo * @description 针对表【tb_user(用户表)】的数据库操作Mapper * @createDate 2025-02-06 10:28:09 * @Entity com.example.his.api.db.pojo.UserEntity */ public interface UserDao { // 查询用户权限集合 public Set<String> searchUserPermissions(int userId); // 查询用户路由限集合 public ArrayList<HashMap> searchUserRouterPermissions(int userId); // 查询指定用户 public int searchUserById(Map param); // 用户管理-查询分页 public ArrayList<HashMap> searchUserByPage(Map param); // 用户管理-新增 public int insertUser(Map param); // 用户管理-编辑 public int updateUser(Map param); // 用户管理-删除 public int deleteUserById(Map param); }
4.1.2 配置UserDao.xml映射信息
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//myBATis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.his.api.db.dao.UserDao"> <resultMap id="BaseResultMap" type="com.example.his.api.db.pojo.UserEntity"> <id property="id" column="id" jdbcType="INTEGER"/> <result property="username" column="username" jdbcType="VARCHAR"/> <result property="password" column="password" jdbcType="VARCHAR"/> <result property="openId" column="open_id" jdbcType="VARCHAR"/> <result property="photo" column="photo" jdbcType="VARCHAR"/> <result property="name" column="name" jdbcType="VARCHAR"/> <result property="sex" column="sex" jdbcType="OTHER"/> <result property="tel" column="tel" jdbcType="CHAR"/> <result property="email" column="email" jdbcType="VARCHAR"/> <result property="hiredate" column="hiredate" jdbcType="VARCHAR"/> <result property="role" column="role" jdbcType="OTHER"/> 编程China编程 <result property="root" column="root" jdbcType="TINYINT"/> <result property="deptId" column="dept_id" jdbcType="INTEGER"/> <result property="status" column="status" jdbcType="TINYINT"/> <result property="createTime" column="create_time" jdbcType="VARCHAR"/> </resultMap> <!-- 查询用户权限集合 --> <select id="searchUserPermissions" parameterType="int" resultType="String"> SELECT DISTINCT p.permission_name FROM tb_user u JOIN tb_role r ON JSON_CONTAINS(u.role, CAST(r.id AS CHAR)) JOIN tb_permission p ON JSON_CONTAINS(r.permissions, CAST(p.id AS CHAR)) WHERE u.id = #{userId} AND u.`status` = 1 </select> <!-- 查询用户权限列表 --> <select id="searchUserRouterPermissions" parameterType="arraylist" resultType="hashmap"> SELECT DISTINCT p.module_name as name, p.path, p.icon FROM tb_user u JOIN tb_role r ON JSON_CONTAINS(u.role, CAST(r.id AS CHAR)) JOIN tb_permission p ON JSON_CONTAINS(r.permissions, CAST(p.id AS CHAR)) WHERE u.id = #{userId} AND u.`status` = 1 </select> <!-- 查询指定用户 --> <select id="searchUserById" parameterType="Map" resultType="integer"> select id from tb_user where username = #{username} and password = #{password} limit 1; </select> <!-- 用户管理-查询分页 --> <select id="searchUserByPage" parameterType="arraylist" resultType="HashMap"> SELECT DISTINCT u.id, u.name, u.sex, u.tel, u.email, d.dept_name AS dept, d.id AS deptId, u.role AS roleId, DATE_FORMAT(u.hiredate,"%Y-%m-%d") AS hiredate, u.root, u.status, ( SELECT GROUP_CONCAT( role_name ) FROM tb_role WHERE JSON_CONTAINS ( u.role, CONVERT (id, CHAR) ) ) AS roles FROM tb_user u JOIN tb_role r ON JSON_CONTAINS ( u.role, CONVERT (r.id, CHAR) ) LEFT JOIN tb_dept d ON u.dept_id = d.id <where> <if test="searchKeyWord != null and searchKeyWord != ''"> OR d.dept_name LIKE '%${searchKeyWord}%' </if> <if test="searchKeyWord != null and searchKeyWord != ''"> OR u.name LIKE '%${searchKeyWord}%' </if> <if test="searchKeyWord != null and searchKeyWord != ''"> OR u.status LIKE '%${searchKeyWord}%' </if> <if test="searchKeyWord != null and searchKeyWord != ''"> OR u.sex LIKE '%${searchKeyWord}%' </if> <if test="searchKeyWord != null and searchKeyWord != ''"> OR u.tel LIKE '%${searchKeyWord}%' </if> <if test="searchKeyWord != null and searchKeyWord != ''"> OR u.email LIKE '%${searchKeyWord}%' </if> </where> ORDER BY u.id ASC </select> <!-- 用户管理-新增 --> <insert id="insertUser"> insert into tb_user SET username=#{username}, password=#{password}, name=#{name}, sex=#{sex}, tel=#{tel}, email=#{email}, status=#{status}, dept_id=#{deptId}, hiredate=#{hiredate}, role=#{role} <if test="openId!=null"> ,`openId`=#{openId} </if> <if test="photo!=null"> ,`photo`=#{photo} </if> <if test="root!=null"> ,`root`=#{root} </if> </insert> <!-- 用户管理-编辑 --> <update id="updateUser"> update tb_user SET name=#{name}, sex=#{sex}, tel=#{tel}, email=#{email}, status=#{status}, dept_id=#{deptId}, hiredate=#{hiredate}, role=#{role} <if test="username!=null"> ,`username`=#{username} </if> <if test="password!=null"> ,`password`=#{password} </if> <if test="openId!=null"> ,`openId`=#{openId} </if> <if test="photo!=null"> ,`photo`=#{photo} </if> <if test="root!=null"> ,`root`=#{root} </if> where id = #{id} </update> <!-- 用户管理-删除 --> <delete id="deleteUserById"> delete from tb_user where id in <foreach collection="ids" item="id" open="(" separator="," close=")"> #{id} </foreach> </delete> </mapper>
4.1.3 Service 业务层
@Service public class UserService { @Resource private UserDao userMapper; // 用户管理-查询id public int searchUserById(Map param) { return userMapper.searchUserById(param); } // 用户管理-查询分页 public PageInfo<HashMap> searchUserByPage(Map param) { PageHelper.startPage(MapUtil.getInt(param, "pageNum"), MapUtil.getInt(param, "pageSize")); ArrayList<HashMap> list = userMapper.searchUserByPage(param); PageInfo<HashMap> pageInfo = new PageInfo<>(list); return pageInfo; } // 用户管理-新增 public int insertUser(Map param) { return userMapper.insertUser(param); } // 用户管理-更新 public int updateUser(Map param) { return userMapper.updateUser(param); } // 用户管理-删除 public int deleteUserById(Map param) { return userMapper.deleteUserById(param); } // 查询用户路由限集合 public ArrayList<HashMap> searchUserRouterPermissions(int userId) { ArrayList<HashMap> routerList = userMapper.searchUserRouterPermissions(userId); ArrayList<HashMap> newRouterList = new ArrayList<>(); routerList.forEach(item -> { if(!ObjectUtil.isEmpty(item.get("path"))) { newRouterList.add(item); } }); return newRouterList; } }
4.1.4 Controller Web层
@RestController @RequestMapping("/admin") public class UserController { @Resource private UserService userService; @Resource private UserDao userDao; /** * 用户登录 * @param form * @return */ @PostMapping("/user/login") public R login(@RequestBody @Valid UserLoginForm form) { Map param = BeanUtil.beanToMap(form); Integer userId = userService.searchUserById(param); if (userId != null) { StpUtil.logout(userId, "Web"); // 通过会话对象,向SaToken传递userId StpUtil.login(userId, "Web"); // 生成新的令牌字符串,标记该令牌是给Web端用户使用的 String token = StpUtil.getTokenValueByLoginId(userId, "Web"); // 获取用户的权限列表 List<String> permissionNames = StpUtil.getPermissionList(); // 使用 Collections.sort() 排序 Collections.sort(permissionNames); // 查询用户路由限集合 ArrayList<HashMap> routerList = userService.searchUserRouterPermissions(userId); HashMap map = new HashMap<>(); map.put("token", token); map.put("permissionNames", permissionNames); map.put("routerList", routerList); return R.success(map); } return R.error(); } /** * 用户管理-查询分页 * @param form * @return */ @PostMapping("/user/searchUserByPage") @SaCheckPermission(value = {"SYSTEM:USER:SELECT"}, mode = SaMode.OR) public R searchUserByPage(@RequestBody @Valid UserSearchForm form) { Map param = BeanUtil.beanToMap(form); PageInfo<HashMap> list = userService.searchUserByPage(param); return R.success(list); } /** * 用户管理-编辑 * @param form * @return */ @PostMapping("/user/edittUser") @SaCheckPermission(value = {"SYSTEM:USER:EDIT"}, mode = SaMode.OR) public R edittUser(@RequestBody @Valid UserEditForm form) { Map param = BeanUtil.beanToMap(form); param.replace("role", JSONUtil.parseArray(form.getRole()).toString()); int rows; if (ObjectUtil.isAllEmpty(param.get("id"))) { rows = userService.insertUser(param); } else { rows = userService.updateUser(param); } return R.success(rows); } /** * 用户管理-删除 * @param form * @return */ @PostMapping("/user/deleteUserById") @SaCheckPermission(value = {"SYSTEM:USER:DELETE"}, mode = SaMode.OR) public R deleteUserById(@RequestBody @Valid UserDeleteForm form) { Map param = BeanUtil.beanToMap(form); int rows = userService.deleteUserById(param); return R.success(rows); } }
4.1.5 登录返回权限列表
用户登陆,会根据当前用户id去关联角色表和权限表,查询对应的权限集合列表。
4.1.6 用户分配角色
用户管理增删改查实现,并对用户分配不同角色
4.2 角色管理实现
4.2.1 定义RoleDao类实现接口
/** * @author lenovo * @description 针对表【tb_role(角色表)】的数据库操作Mapper * @createDate 2025-02-06 10:35:25 * @Entity com.example.his.api.db.pojo.RoleEntity */ public interface RoleDao { // 角色管理-查询全部 public ArrayList<HashMap> searchRoleAll(); // 角色管理-查询分页 public ArrayList<HashMap> searchRoleByPage(Map param); // 角色管理-新增 public int insertRole(Map param); // 角色管理-更新 public int updateRole(Map param); // 角色管理-删除 public int deleteRole(Map param); }
4.2.2 配置RoleDao.xml映射信息
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.his.api.db.dao.RoleDao"> <resultMap id="BaseResultMap" type="com.example.his.api.db.pojo.RoleEntity"> <id property="id" column="id" jdbcType="INTEGER"/> <result property="roleName" column="role_name" jdbcType="VARCHAR"/> <result property="permissions" column="permissions" jdbcType="OTHER"/> <result property="desc" column="desc" jdbcType="VARCHAR"/> <result property="defaultPermissions" column="default_permissions" jdbcType="OTHER"/> <result property="systemic" column="systemic" jdbcType="INTEGER"/> <result property="echo" column="echo" jdbcType="OTHER"/> </resultMap> <!-- 角色管理-查询全部 --> <select id="searchRoleAll" parameterType="arraylist" resultType="hashmap"> SELECT id,role_name AS roleName FROM tb_role ORDER BY id </select> <!-- 角色管理-查询分页 --> <select id="searchRoleByPage" parameterType="arraylist" resultType="hashmap"> SELECT r.id, r.role_name AS roleName, COUNT( u.id ) AS users, JSON_LENGTH ( r.permissions ) AS permissionsLength, r.permissions, r.desc, r.systemic, r.echo FROM tb_role r LEFT JOIN tb_user u ON JSON_CONTAINS ( u.role, CONVERT ( r.id, CHAR ) ) <where> <if test="searchKeyWord != null and searchKeyWord != ''"> AND r.role_name LIKE '%${searchKeyWord}%' </if> </where> GROUP BY r.id ORDER BY r.id </select> <!-- 角色管理-新增 --> <insert id="insertRole"> insert into tb_role SET role_name=#{roleName}, permissions=#{permissions}, echo=#{echo} <if test="desc!=null"> ,`desc`=#{desc} </if> </insert> <!-- 角色管理-更新 --> <update id="updateRole"> update tb_role set `role_name` = #{roleName}, `permissions` = #{permissions}, `echo` = #{echo} <if test="desc!=null"> ,`desc`=#{desc} </if> <if test="systemic!=null"> ,`systemic`=#{systemic} </if> where id = #{id} </update> <!-- 角色管理-删除 --> <delete id="deleteRole"> delete from tb_role where id in <foreach collection="ids" item="id" open="(" separator="," close=")"> #{id} </foreach> </delete> </mapper>
4.2.3 Service 业务层
@Service public class RoleService { @Resource private RoleDao roleDao; // 角色管理-查询全部 public ArrayList<HashMap> searchRoleAll(){ return roleDao.searchRoleAll(); } // 角色管理-查询分页 public PageInfo<HashMap> searchRoleByPage(Map param) { PageHelper.startPage(MapUtil.getInt(param, "pageNum"), MapUtil.getInt(param, "pageSize")); ArrayList<HashMap> roleList = roleDao.searchRoleByPage(param); PageInfo<HashMap> pageInfo = new PageInfo<>(roleList); return pageInfo; } // 角色管理-新增 public int insertRole(Map param) { return roleDao.insertRole(param); } // 角色管理-更新 public int updateRole(Map param) { return roleDao.updateRole(param); } // 角色管理-删除 public int deleteRole(Map param) { return roleDao.deleteRole(param); } }
4.2.4 Controller Web层
@RestController @RequestMapping("/admin") public class RoleController { @Resource private RoleService roleService; /** * 角色管理-查询全部 * @return */ @GetMapping("/role/searchRoleAll") @SaCheckPermission(value = {"SYSTEM:ROLE:SELECT"}, mode = SaMode.OR) public R searchRoleAll() { ArrayList<HashMap> roleList = roleService.searchRoleAll(); return R.success(roleList); } /** * 角色管理-分页查询 * @param form * @return */ @PostMapping("/role/searchRoleByPage") @SaCheckPermission(value = {"SYSTEM:ROLE:SELECT"}, mode = SaMode.OR) public R searchRoleByPage(@RequestBody @Valid RoleSearchForm form) { Map param = BeanUtil.beanToMap(form); PageInfo<HashMap> roleList = roleService.searchRoleByPage(param); return R.success(roleList); } /** * 角色管理-编辑 * @param form * @return */ @PostMapping("/role/editRole") @SaCheckPermission(value = {"SYSTEM:ROLE:EDIT"}, mode = SaMode.OR) public R editRole(@RequestBody @Valid RoleEditForm form) { Map param = BeanUtil.beanToMap(form); param.replace("permissions", JSONUtil.parseArray(form.getPermissions()).toString()); param.replace("echo", JSONUtil.parseArray(form.getEcho()).toString()); int rows; if(ObjectUtil.isEmpty(param.get("id"))) { rows = roleService.insertRole(param); }else { rows = roleService.updateRole(param); } return R.success(rows); } /** * 角色管理-删除 * @param form * @return */ @PostMapping("/role/deleteRole") @SaCheckPermission(value = {"SYSTEM:ROLE:DELETE"}, mode = SaMode.OR) public R deleteRole(@RequestBody @Valid RoleDeleteForm form) { Map param = BeanUtil.beanToMap(form); int rows = roleService.deleteRole(param); return R.success(rows); } }
4.2.5 角色分配权限
4.3 部门管理实现
4.31 定义DeptDao类实现接口
/** * @author lenovo * @description 针对表【tb_dept(部门表)】的数据库操作Mapper * @createDate 2025-02-10 08:57:44 * @Entity com.example.his.api.db.pojo.DeptEntity */ public interface DeptDao { // 部门列表查询 public ArrayList<HashMap> searchAllDept(); public ArrayList<HashMap> searchDept(Map param); public HashMap searchDeptById(Integer id); // 部门列表新增和编辑 public int insertDept(Map param); public int updateDept(Map param); public int deleteBatchDept(Map param); }
4.3.2 配置DeptDao.xml映射信息
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.his.api.db.dao.DeptDao"> <resultMap id="BaseResultMap" type="com.example.his.api.db.pojo.DeptEntity"> <id property="id" column="id" jdbcType="INTEGER"/> <result property="deptName" column="dept_name" jdbcType="VARCHAR"/> <result property="tel" column="tel" jdbcType="VARCHAR"/> <result property="email" column="email" jdbcType="VARCHAR"/> <result property="desc" column="desc" jdbcType="VARCHAR"/> </resultMap> <!-- 部门列表查询全部 --> <select id="searchAllDept" resultMap="BaseResultMap"> select * from tb_dept </select> <!-- 部门列表分页查询 --> <select id="searchDept" resultType="HashMap"> select d.id, d.dept_name as deptName, d.tel, d.email, d.desc, COUNT(u.id) AS emps from tb_dept d left join tb_user u on u.dept_id = d.id <where> <if test="searchKeyWord != null and searchKeyWord != ''"> 1 = 1 AND d.dept_name like "%${searchKeyWord}%" OR d.tel = #{searchKeyWord} OR d.email = #{searchKeyWord} OR d.desc like "%${searchKeyWord}%" </if> </where> GROUP BY d.id </select> <!-- 部门列表查询id --> <select id="searchDeptById" resultType="HashMap"> select * from tb_dept where id = #{id} </select> <!-- 部门列表新增 --> <insert id="insertDept"> insert into tb_dept values(#{id},#{deptName},#{tel},#{email},#{desc}) </insert> <!-- 部门列表更新 --> <update id="updateDept"> update tb_dept set `dept_name` = #{deptName}, `tel` = #{tel}, `email` = #{email}, `desc` = #{desc} where `id` = #{id} </update> <!-- 部门列表批量删除 --> <delete id="deleteBatchDept"> delete from tb_dept where id in <foreach collection="ids" item="id" open="(" separator="," close=")"> #{id} </foreach> </delete> </mapper>
4.3.3 Service 业务层
@Service public class DeptService { @Resource private DeptDao deptDao; //部门列表-查询全部 public ArrayList<HashMap> searchAllDept() { ArrayList<HashMap> list = deptDao.searchAllDept(); return list; } //部门列表-分页查询 public PageInfo<HashMap> searchDept(Map param) { PageHelper.startPage(MapUtil.getInt(param,"pageNum"), MapUtil.getInt(param,"pageSize")); ArrayList<HashMap> list = deptDao.searchDept(param); PageInfo<HashMap> pageInfo = new PageInfo<>(list); return pageInfo; } //部门列表-查询id public HashMap searchDeptById(Integer id) { HashMap map = deptDao.searchDeptById(id); return map; } //部门列表-新增 public int insertDept(Map param) { return deptDao.insertDept(param); } //部门列表-更新 public int updateDept(Map param) { return deptDao.updateDept(param); } //部门列表-批量删除 public int deleteBatchDept(Map param) { return deptDao.deleteBatchDept(param); } }
4.3.4 Controller Web层
@RestController @RequestMapping("/admin") public class DeptController { @Resource private DeptService deptService; /** * 部门管理-查询全部 * @return */ @GetMapping("/dept/searchAllDept") @SaCheckPermission(value = {"SYSTEM:DEPT:SELECT"}, mode = SaMode.OR) public R searchAllDept() { ArrayList<HashMap> list = deptService.searchAllDept(); return R.success(list); } /** * 部门管理-分页查询 * @param deptSearchReq * @return */ @PostMapping("/dept/searchDeptByPage") @SaCheckPermission(value = {"SYSTEM:DEPT:SELECT"}, mode = SaMode.OR) public R searchDept(@Valid @RequestBody DeptSearchForm deptSearchReq) { Map param = BeanUtil.beanToMap(deptSearchReq); PageInfo<HashMap> list = deptService.searchDept(param); return R.success(list); } /** * 部门管理-查询id * @param id * @return */ @GetMapping("/dept/searchDeptById") @SaCheckPermission(value = {"SYSTEM:DEPT:SELECT"}, mode = SaMode.OR) public R searchDeptById(@RequecDBwgSstParam(value = "id") Integer id) { HashMap map = deptService.searchDeptById(id); if(ObjectUtil.isEmpty(map)) { return R.success("200","id不存在"); } return R.success(map); } /** * 部门管理-编辑 * @param deptEditReq * @return */ @PostMapping("/dept/editDept") @SaCheckPermission(value = {"SYSTEM:DEPT:EDIT"}, mode = SaMode.OR) public R insertDept(@Valid @RequestBody DeptEditForm deptEditReq) { Map param = BeanUtil.beanToMap(deptEditReq); if(ObjectUtil.isEmpty(deptEditReq.getId())) { deptService.insertDept(param); }else { deptService.updateDept(param); } return R.success(); } /** * 部门管理-批量删除 * @param deptDeleteReq * @return */ @PostMapping("/dept/deleteBatchDept") @SaCheckPermission(value = {"SYSTEM:DEPT:DELETE"}, mode = SaMode.OR) public R deleteBatchDept(@Valid @RequestBody DeptDeleteForm deptDeleteReq) { Map param = BeanUtil.beanToMap(deptDeleteReq); int rows = deptService.deleteBatchDept(param); return R.success(rows); } }
4.3.5 部门页面编辑
4.4 权限管理实现
4.4.1 定义PermissionDao类实现接口
/** * @author lenovo * @description 针对表【tb_permission(权限表)】的数据库操作Mapper * @createDate 2025-02-06 10:35:25 * @Entity com.example.his.api.db.pojo.PermissionEntity */ public interface PermissionDao { // 查询递归菜单权限 public ArrayList<PermissionMenuResp> searchPermissions(); // 权限管理-编辑 public int insertPermission(Map param); public int updatePermission(Map param); // 权限管理-批量删除 public int deleteBatchPermission(Map param); }
4.4.2 配置PermissionDao.xml映射信息
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.his.api.db.dao.PermissionDao"> <resultMap id="PermissionMenu" type="com.example.his.api.resp.PermissionMenuResp"> <id property="id" column="id" jdbcType="INTEGER"/> <result property="parentId" column="parent_id" jdbcType="INTEGER"/> <result property="permissionName" column="permission_name" jdbcType="VARCHAR"/> <result property="moduleName" column="module_name" jdbcType="VARCHAR"/> <result property="menuType" column="menu_type" jdbcType="VARCHAR"/> <result property="icon" column="icon" jdbcType="VARCHAR"/> <result property="path" column="path" jdbcType="VARCHAR"/> <result property="createTime" column="create_time" jdbcType="VARCHAR"/> </resultMap> <!-- <sql id="Base_Column_List">--> <!-- id,parent_id,permission_name,--> <!-- module_name,menu_type,icon,--> <!-- path,create_time--> <!-- </sql>--> <!-- 查询用户现有权限 --> <select id="searchPermissions" resultMap="PermissionMenu"> select * from tb_permission order by sort asc </select> <!-- 权限管理-新增 --> <insert id="insertPermission"> insert into tb_permission values(#{id},#{parentId},#{permissionName},#{moduleName},#{menuType},#{icon},#{path},#{createTime}) </insert> <!-- 权限管理-更新 --> <update id="updatePermission"> update tb_permission set `parent_id` = #{parentId}, `permission_name` = #{permissionName}, `module_name` = #{moduleName}, `menu_type` = #{menuType}, `icon` = #{icon}, `path` = #{path}, `create_time` = #{createTime} where id = #{id} </update> <!-- 权限管理-批量删除 --> <delete id="deleteBatchPermission"> delete from tb_permission where id in <foreach collection="ids" item="id" open="(" separator="," close=")">#{id}</foreach> </delete> </mapper>
4.4.3 Service 业务层
@Service public class PermissionService { @Resource private PermissionDao permissionDao; // 权限管理-递归菜单 public ArrayList<PermissionMenuResp> searchPermissions() { return deepTree(permissionDao.searchPermissions()); } // 权限管理-编辑 public int insertPermission(Map param) { return permissionDao.insertPermission(param); } public int updatePermission(Map param) { return permissionDao.updatePermission(param); } // 权限管理-批量删除 public int deleteBatchPermission(Map param) { return permissionDao.deleteBatchPermission(param); } /** * 转换树形结构 * @param menuList * @return */ public ArrayList<PermissionMenuResp> deepTree(ArrayList<PermissionMenuResp> menuList) { //创建list集合,用于数据最终封装 ArrayList<PermissionMenuResp> finalNode = new ArrayList<>(); for (PermissionMenuResp menus : menuList) { Integer topId = 0; //判断Pid是否等于0 0是最高的节点 将查询出的数据放进list集合 if (topId.equals(menus.getParentId())) { finalNode.add(selectTree(menus, menuList)); } } // 递归设置节点层级 for (PermissionMenuResp menu : finalNode) { setNodeLevel(menu,1); } return finalNode; } public PermissionMenuResp selectTree(PermissionMenuResp m1, ArrayList<PermissionMenuResp> menuList) { //因为向一层菜单里面放二层菜单,二层里面还要放三层,把对象初始化 m1.setChildren(new ArrayList<PermissionMenuResp>()); //遍历所有菜单list集合,进行判断比较,比较id和pid值是否相同 for (PermissionMenuResp m2 : menuList) { //判断 id和pid值是否相同 if (m1.getId().equals(m2.getParentId())) { //如果children为空,进行初始化操作 if (m1.getChildren() == null) { m1.setChildren(new ArrayList<PermissionMenuResp>()); } //把查询出来的子菜单放到父菜单里面 m1.getChildren().add(selectTree(m2, menuList)); } } return m1; } // 递归设置节点层级 public void setNodeLevel(PermissionMenuResp node, int level) { node.setLevel(level); node.setKey(node.getId()); for (PermissionMenuResp child : node.getChildren()) { setNodeLevel(child, level + 1); } } }
4.4.4 Controller Web层
@RestController @RequestMapping("/admin") public class PermissionController { @Resource private PermissionService permissionService; /** * 权限管理-递归菜单 * @return */ @GetMapping("/permissions/searchPermissions") @SaCheckPermission(value = {"SYSTEM:PERMISSION:SELECT"}, mode = SaMode.OR) public R searchPermissions() { ArrayList<PermissionMenuResp> permissions = permissionService.searchPermissions(); return R.success(permissions); } /** * 权限管理-编辑 * @param permissionEditReq * @return */ @PostMapping("/permissions/editPermissions") @SaCheckPermission(value = {"SYSTEM:PERMISSION:EDIT"}, mode = SaMode.OR) public R editPermissions(@Valid @RequestBody PermissionEditReq permissionEditReq) { Map param = BeanUtil.beanToMap(permissionEditReq); if(ObjectUtil.isEmpty(permissionEditReq.getId())) { permissionService.insertPermission(param); }else { permissionService.updatePermission(param); } return R.success(); } /** * 权限管理-批量删除 * @param permissionDeleteReq * @return */ @PostMapping("/permissions/deleteBatchPermission") @SaCheckPermission(value = {"SYSTEM:PERMISSION:DELETE"}, mode = SaMode.OR) public R deleteBatchPermission(@Valid @RequestBody PermissionDeleteReq permissionDeleteReq) { Map param = BeanUtil.beanToMap(permissionDeleteReq); Integer rows = permissionService.deleteBatchPermission(param); return R.success(rows); } }
4.4.5 权限列表编辑
到此这篇关于SpringBoot整合Sa-Token:实现RBAC权限模型的文章就介绍到这了,更多相关SpringBoot Sa-Token RBAC权限模型内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!
这篇关于SpringBoot整合Sa-Token实现RBAC权限模型的过程解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!