最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot整合Sa-Token實現(xiàn)RBAC權(quán)限模型的過程解析

 更新時間:2025年05月29日 10:59:11   作者:黎黎黎明??  
這篇文章主要介紹了SpringBoot整合Sa-Token實現(xiàn)RBAC權(quán)限模型的過程解析,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧

前言

本文將介紹SpringBoot結(jié)合sa-token實現(xiàn)RBAC權(quán)限模型。

一、基礎(chǔ)概念

1.1 RBAC模型核心概念

  • 用戶(User)、角色(Role)、權(quán)限(Permission)的關(guān)系。
  • 模型分層:用戶-角色-權(quán)限的三層結(jié)構(gòu)。
  • RBAC的基本思想是,對系統(tǒng)操作的各種權(quán)限不是直接授予具體的用戶,而是在用戶集合與權(quán)限集合之間建立一個角色集合。每一種角色對應(yīng)一組相應(yīng)的權(quán)限。一旦用戶被分配了適當(dāng)?shù)慕巧?,該用戶就擁有此角色的所有操作?quán)限。

1.2 Sa-Token核心功能

  • 登錄認(rèn)證(StpUtil)、權(quán)限校驗、會話管理、踢人下線等。
  • 關(guān)鍵注解:@SaCheckLogin、@SaCheckRole、@SaCheckPermission。

1.3 環(huán)境準(zhǔn)備

  • JDK 1.8+、Maven、SpringBoot 2.x。
  • 初始化SpringBoot項目(可通過Spring Initializr生成)。
  • Mysql5.x/8.x

二、表結(jié)構(gòu)設(shè)計

2.1 ER圖示例

2.2 數(shù)據(jù)庫表設(shè)計

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 '長期授權(quán)字符串',
  `photo` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '頭像網(wǎng)址',
  `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 '手機(jī)號碼',
  `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 '狀態(tài)',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  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 '權(quán)限集合',
  `desc` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '描述',
  `default_permissions` json DEFAULT NULL COMMENT '系統(tǒng)角色內(nèi)置權(quán)限',
  `systemic` int DEFAULT '0' COMMENT '是否為系統(tǒng)內(nèi)置角色',
  `echo` json DEFAULT NULL COMMENT '權(quán)限回顯集合',
  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 權(quán)限表

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 '權(quán)限',
  `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 '菜單圖標(biāo)',
  `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 '創(chuàng)建時間',
  `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='權(quán)限表';

三、SpringBoot整合Sa-Token

3.1 sa-token基礎(chǔ)配置

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 有效期(單位:秒) 默認(rèn)30天,-1 代表永久有效
  timeout: 2592000
  # token 最低活躍頻率(單位:秒),如果 token 超過此時間沒有訪問系統(tǒng)就會被凍結(jié),默認(rèn)-1 代表不限制,永不凍結(jié)
  active-timeout: -1
  # 是否允許同一賬號多地同時登錄 (為 true 時允許一起登錄, 為 false 時新登錄擠掉舊登錄)
  is-concurrent: true
  # 在多人登錄同一賬號時,是否共用一個 token (為 true 時所有登錄共用一個 token, 為 false 時每次登錄新建一個 token)
  is-share: false
  # token 風(fēng)格(默認(rèn)可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
  token-style: uuid
  # 是否輸出操作日志
  is-log: false

3.1.3 StpUtil鑒權(quán)工具類

StpUtil.login(10001);   // 會話登錄
StpUtil.login(10001, "APP");   // 會話登錄,并指定設(shè)備類型
StpUtil.getTokenValueByLoginId(10001);   // 獲取指定賬號id的tokenValue 
StpUtil.getTokenValueByLoginId(10001, "PC");   // 獲取指定賬號id指定設(shè)備類型端的tokenValue
StpUtil.getPermissionList();   // 獲?。寒?dāng)前賬號的權(quán)限集合
StpUtil.getPermissionList(10001);   // 獲?。褐付ㄙ~號的權(quán)限集合 
StpUtil.logout();   // 會話注銷 
StpUtil.logout(10001);   // 會話注銷,根據(jù)賬號id
StpUtil.logout(10001, "PC");   // 會話注銷,根據(jù)賬號id 和 設(shè)備類型

3.1.4 編寫鑒權(quán)類

提示:鑒權(quán)類是需要我們自己實現(xiàn)的,必須要擴(kuò)展StpInterface接口才可以。

@Component
class StpInterfaceImpl implements StpInterface {
    @Resource
    private UserDao userDao;
    /**
     * 返回一個用戶所擁有的權(quán)限集合
     */
    @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;
    }
    /**
     * 返回一個用戶所擁有的角色標(biāo)識集合
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginKey) {
        ArrayList<String> list = new ArrayList();
        return list;
    }
}

四、RBAC模型設(shè)計與實現(xiàn)

4.1 用戶管理及登陸實現(xiàn)

4.1.1 定義UserDao類實現(xiàn)接口

**
* @author lenovo
* @description 針對表【tb_user(用戶表)】的數(shù)據(jù)庫操作Mapper
* @createDate 2025-02-06 10:28:09
* @Entity com.example.his.api.db.pojo.UserEntity
*/
public interface UserDao {
    // 查詢用戶權(quán)限集合
    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"/>
        <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>
    <!-- 查詢用戶權(quán)限集合 -->
    <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>
    <!-- 查詢用戶權(quán)限列表 -->
    <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 業(yè)務(wù)層

@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");
            // 生成新的令牌字符串,標(biāo)記該令牌是給Web端用戶使用的
            String token = StpUtil.getTokenValueByLoginId(userId, "Web");
            // 獲取用戶的權(quán)限列表
            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 登錄返回權(quán)限列表

用戶登陸,會根據(jù)當(dāng)前用戶id去關(guān)聯(lián)角色表和權(quán)限表,查詢對應(yīng)的權(quán)限集合列表。

4.1.6 用戶分配角色

用戶管理增刪改查實現(xiàn),并對用戶分配不同角色

4.2 角色管理實現(xiàn)

4.2.1 定義RoleDao類實現(xiàn)接口

/**
* @author lenovo
* @description 針對表【tb_role(角色表)】的數(shù)據(jù)庫操作Mapper
* @createDate 2025-02-06 10:35:25
* @Entity com.example.his.api.db.pojo.RoleEntity
*/
public interface RoleDao {
    // 角色管理-查詢?nèi)?
    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>
    <!-- 角色管理-查詢?nèi)?-->
    <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 業(yè)務(wù)層

@Service
public class RoleService {
    @Resource
    private RoleDao roleDao;
    // 角色管理-查詢?nèi)?
    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;
    /**
     * 角色管理-查詢?nèi)?
     * @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 角色分配權(quán)限

4.3 部門管理實現(xiàn)

4.31 定義DeptDao類實現(xiàn)接口

/**
* @author lenovo
* @description 針對表【tb_dept(部門表)】的數(shù)據(jù)庫操作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>
    <!--  部門列表查詢?nèi)? -->
    <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 業(yè)務(wù)層

@Service
public class DeptService {
    @Resource
    private DeptDao deptDao;
    //部門列表-查詢?nèi)?
    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;
    /**
     * 部門管理-查詢?nèi)?
     * @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 權(quán)限管理實現(xiàn)

4.4.1 定義PermissionDao類實現(xiàn)接口

/**
* @author lenovo
* @description 針對表【tb_permission(權(quán)限表)】的數(shù)據(jù)庫操作Mapper
* @createDate 2025-02-06 10:35:25
* @Entity com.example.his.api.db.pojo.PermissionEntity
*/
public interface PermissionDao {
    // 查詢遞歸菜單權(quán)限
    public ArrayList<PermissionMenuResp> searchPermissions();
    // 權(quán)限管理-編輯
    public int insertPermission(Map param);
    public int updatePermission(Map param);
    // 權(quán)限管理-批量刪除
    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>-->
    <!-- 查詢用戶現(xiàn)有權(quán)限 -->
    <select id="searchPermissions" resultMap="PermissionMenu">
        select * from tb_permission order by sort asc
    </select>
    <!-- 權(quán)限管理-新增 -->
    <insert id="insertPermission">
        insert into tb_permission values(#{id},#{parentId},#{permissionName},#{moduleName},#{menuType},#{icon},#{path},#{createTime})
    </insert>
    <!-- 權(quán)限管理-更新 -->
    <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>
    <!-- 權(quán)限管理-批量刪除 -->
    <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 業(yè)務(wù)層

@Service
public class PermissionService {
    @Resource
    private PermissionDao permissionDao;
    // 權(quán)限管理-遞歸菜單
    public ArrayList<PermissionMenuResp> searchPermissions() {
        return deepTree(permissionDao.searchPermissions());
    }
    // 權(quán)限管理-編輯
    public int insertPermission(Map param) {
        return permissionDao.insertPermission(param);
    }
    public int updatePermission(Map param) {
        return permissionDao.updatePermission(param);
    }
    // 權(quán)限管理-批量刪除
    public int deleteBatchPermission(Map param) {
        return permissionDao.deleteBatchPermission(param);
    }
    /**
     * 轉(zhuǎn)換樹形結(jié)構(gòu)
     * @param menuList
     * @return
     */
    public ArrayList<PermissionMenuResp> deepTree(ArrayList<PermissionMenuResp> menuList) {
        //創(chuàng)建list集合,用于數(shù)據(jù)最終封裝
        ArrayList<PermissionMenuResp> finalNode = new ArrayList<>();
        for (PermissionMenuResp menus : menuList) {
            Integer topId = 0;
            //判斷Pid是否等于0  0是最高的節(jié)點 將查詢出的數(shù)據(jù)放進(jìn)list集合
            if (topId.equals(menus.getParentId())) {
                finalNode.add(selectTree(menus, menuList));
            }
        }
        // 遞歸設(shè)置節(jié)點層級
        for (PermissionMenuResp menu : finalNode) {
            setNodeLevel(menu,1);
        }
        return finalNode;
    }
    public PermissionMenuResp selectTree(PermissionMenuResp m1, ArrayList<PermissionMenuResp> menuList) {
        //因為向一層菜單里面放二層菜單,二層里面還要放三層,把對象初始化
        m1.setChildren(new ArrayList<PermissionMenuResp>());
        //遍歷所有菜單list集合,進(jìn)行判斷比較,比較id和pid值是否相同
        for (PermissionMenuResp m2 : menuList) {
            //判斷 id和pid值是否相同
            if (m1.getId().equals(m2.getParentId())) {
                //如果children為空,進(jìn)行初始化操作
                if (m1.getChildren() == null) {
                    m1.setChildren(new ArrayList<PermissionMenuResp>());
                }
                //把查詢出來的子菜單放到父菜單里面
                m1.getChildren().add(selectTree(m2, menuList));
            }
        }
        return m1;
    }
    // 遞歸設(shè)置節(jié)點層級
    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;
    /**
     * 權(quán)限管理-遞歸菜單
     * @return
     */
    @GetMapping("/permissions/searchPermissions")
    @SaCheckPermission(value = {"SYSTEM:PERMISSION:SELECT"}, mode = SaMode.OR)
    public R searchPermissions() {
        ArrayList<PermissionMenuResp> permissions = permissionService.searchPermissions();
        return  R.success(permissions);
    }
    /**
     * 權(quán)限管理-編輯
     * @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();
    }
    /**
     * 權(quán)限管理-批量刪除
     * @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 權(quán)限列表編輯

到此這篇關(guān)于SpringBoot整合Sa-Token:實現(xiàn)RBAC權(quán)限模型的文章就介紹到這了,更多相關(guān)SpringBoot Sa-Token RBAC權(quán)限模型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java解析XML格式數(shù)據(jù)的方法詳解

    Java解析XML格式數(shù)據(jù)的方法詳解

    這篇文章主要介紹了Java解析XML格式數(shù)據(jù)的方法,并展示了較為常用的Java dom來解析XML的例子,需要的朋友可以參考下
    2015-10-10
  • java不用循環(huán)語句打印數(shù)組元素的實例

    java不用循環(huán)語句打印數(shù)組元素的實例

    下面小編就為大家?guī)硪黄猨ava不用循環(huán)語句打印數(shù)組元素的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • Java的微信開發(fā)中使用XML格式和JSON格式數(shù)據(jù)的示例

    Java的微信開發(fā)中使用XML格式和JSON格式數(shù)據(jù)的示例

    這篇文章主要介紹了Java微信開發(fā)中使用XML格式和JSON格式數(shù)據(jù)的示例,注意一下json-lib所需要的jar包,需要的朋友可以參考下
    2016-02-02
  • 從0構(gòu)建Oauth2Server服務(wù)之Refreshing-access-tokens

    從0構(gòu)建Oauth2Server服務(wù)之Refreshing-access-tokens

    這篇文章主要為大家介紹了從0構(gòu)建Oauth2Server服務(wù)之Refreshing-access-tokens刷新令牌示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • 深入了解SpringAOP中的jdk動態(tài)代理與CGlib

    深入了解SpringAOP中的jdk動態(tài)代理與CGlib

    這篇文章主要介紹了深入了解SpringAOP中的jdk動態(tài)代理與CGlib,一般我們編寫程序的思想是縱向的,也就是一個方法代碼從該方法第一行開始往下一步一步走,直到走完最后一行代碼,也就是說很多業(yè)務(wù)都需要的比如用戶鑒權(quán),資源釋放等,需要的朋友可以參考下
    2023-12-12
  • Java 數(shù)組分析及簡單實例

    Java 數(shù)組分析及簡單實例

    這篇文章主要介紹了Java 數(shù)組分析及簡單實例的相關(guān)資料,在Java中它就是對象,一個比較特殊的對象,需要的朋友可以參考下
    2017-03-03
  • java創(chuàng)建以任意圖片為背景的窗口

    java創(chuàng)建以任意圖片為背景的窗口

    這篇文章主要為大家詳細(xì)介紹了java創(chuàng)建以任意圖片為背景的窗口,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • 老生常談Java反射機(jī)制(必看篇)

    老生常談Java反射機(jī)制(必看篇)

    下面小編就為大家?guī)硪黄仙U凧ava反射機(jī)制(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • Java 通過反射變更String的值過程詳解

    Java 通過反射變更String的值過程詳解

    這篇文章主要介紹了Java 通過反射變更String的值過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • 利用Springboot實現(xiàn)Jwt認(rèn)證的示例代碼

    利用Springboot實現(xiàn)Jwt認(rèn)證的示例代碼

    這篇文章主要介紹了利用Springboot實現(xiàn)Jwt認(rèn)證的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12

最新評論

博爱县| 赣州市| 三明市| 怀来县| 花莲县| 保靖县| 阿尔山市| 会同县| 隆子县| 南木林县| 团风县| 喀喇沁旗| 平度市| 北海市| 徐闻县| 苗栗市| 昌黎县| 岢岚县| 凌海市| 文成县| 阿尔山市| 仪征市| 扎鲁特旗| 轮台县| 晴隆县| 牟定县| 陆河县| 浦县| 长兴县| 穆棱市| 玛沁县| 松潘县| 莒南县| 乌拉特前旗| 太和县| 正镶白旗| 碌曲县| 登封市| 石柱| 新田县| 锦州市|