前言
本文将介绍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 { @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"/> <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(@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 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权限模型内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论