Java系列文章
文章目錄
- Java系列文章
- 前言
- 一、基礎概念
- 1.1 RBAC模型核心概念
- 1.2 Sa-Token核心功能
- 1.3 環境準備
- 二、表結構設計
- 2.1 ER圖示例
- 2.2 數據庫表設計
- 2.2.1 用戶表
- 2.2.2 角色表
- 2.2.3 部門表
- 2.2.4 權限表
- 三、SpringBoot整合Sa-Token
- 3.1 sa-token基礎配置
- 3.1.1 Maven配置
- 3.1.2 application.yml
- 3.1.3 StpUtil鑒權工具類
- 3.1.4 編寫鑒權類
- 四、RBAC模型設計與實現
- 4.1 用戶管理及登陸實現
- 4.1.1 定義UserDao類實現接口
- 4.1.2 配置UserDao.xml映射信息
- 4.1.3 Service 業務層
- 4.1.4 Controller Web層
- 4.1.5 登錄返回權限列表
- 4.1.6 用戶分配角色
- 4.2 角色管理實現
- 4.2.1 定義RoleDao類實現接口
- 4.2.2 配置RoleDao.xml映射信息
- 4.2.3 Service 業務層
- 4.2.4 Controller Web層
- 4.2.5 角色分配權限
- 4.3 部門管理實現
- 4.31 定義DeptDao類實現接口
- 4.3.2 配置DeptDao.xml映射信息
- 4.3.3 Service 業務層
- 4.3.4 Controller Web層
- 4.3.5 部門頁面編輯
- 4.4 權限管理實現
- 4.4.1 定義PermissionDao類實現接口
- 4.4.2 配置PermissionDao.xml映射信息
- 4.4.3 Service 業務層
- 4.4.4 Controller Web層
- 4.4.5 權限列表編輯
前言
本文將介紹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 '角色',`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 DEFAULT 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.logout(); // 會話注銷
StpUtil.logout(10001); // 會話注銷,根據賬號id
StpUtil.logout(10001, "PC"); // 會話注銷,根據賬號id 和 設備類型
3.1.4 編寫鑒權類
提示:鑒權類是需要我們自己實現的,必須要擴展StpInterface接口才可以。
@Component
class StpInterfaceImpl implements StpInterface {@Resourceprivate UserDao userDao;/*** 返回一個用戶所擁有的權限集合*/@Overridepublic 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;}/*** 返回一個用戶所擁有的角色標識集合*/@Overridepublic 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 mapperPUBLIC "-//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"/><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_nameFROM tb_user uJOIN 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.iconFROM tb_user uJOIN 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 idfrom tb_userwhere 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_roleWHERE JSON_CONTAINS ( u.role, CONVERT (id, CHAR) )) AS rolesFROM tb_user uJOIN 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_userSETusername=#{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_userSETname=#{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 {@Resourceprivate UserDao userMapper;// 用戶管理-查詢idpublic 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 {@Resourceprivate UserService userService;@Resourceprivate 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傳遞userIdStpUtil.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 mapperPUBLIC "-//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">SELECTr.id,r.role_name AS roleName,COUNT( u.id ) AS users,JSON_LENGTH ( r.permissions ) AS permissionsLength,r.permissions,r.desc,r.systemic,r.echoFROM tb_role rLEFT 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.idORDER BY r.id</select><!-- 角色管理-新增 --><insert id="insertRole">insert into tb_roleSETrole_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 {@Resourceprivate 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 {@Resourceprivate 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 mapperPUBLIC "-//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">selectd.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 = 1AND 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_deptset `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 {@Resourceprivate 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;}//部門列表-查詢idpublic 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 {@Resourceprivate 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(@RequestParam(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 mapperPUBLIC "-//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_permissionset `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 {@Resourceprivate 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 {@Resourceprivate 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);}
}