SmartAdmin角色管理使用说明
背景
大数据与智能计算实验室下有三个技术部,分别是技术一部、技术二部、技术三部,不同部门的同学查看的数据范围可分为仅看本人或本部门或本部门及子部门或全部(相当于超级管理员)。
SmartAdmin的权限认证框架使用的是sa-token,他的使用方法有别于诸如若依的Spring Security等,这里简单介绍一下操作说明和演示一个实战案例。
//sa-token版本
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.37.0</version>
</dependency>
//SmartAdmin版本
SmartAdmin v3.X操作
注意跟此相关的重要的数据库表
- t_role 角色表 
- t_role_menu 角色菜单表 
- t_role_employee 角色员工表 
- t_menu 菜单表 
- t_employee 员工表 这个表只要关注 administrator_flag这个字段 
功能权限(能点什么)
- 两个注解 - @SaCheckPermission("api_perms") 这里的取值关注表t_menu 
- @SaCheckRole("role_code") 这里的取值关注表t_role 
 
- 设置显示权限 - v-privilege="'web_perms'" 这里的取值关注表t_menu 
 
- 添加按钮,应用权限 
实战演示
这个生产模块通过“下达”按钮控制指令单生产,这个决定应该交给管理层来做,普通员工不应该具有这种高级权限。

- 给这个“下达”按钮添加进菜单管理  
- 这里的前端权限和后端权限的值就是t_menu表的web_perms和api_perms 
 
- 给这个接口添加注解@SaCheckPermission以权限符号 - /** * 当个下达指令单 */ @Operation(summary = "单个下达指令单 @author cyz") @GetMapping("/produceInstructOrder/issued/{id}") @SaCheckPermission("system:produce:issued") //注解的值就是api_perms public ResponseDTO<String> issued(@PathVariable Long id) { return produceInstructOrderService.issued(id); }
- 测试效果,无法点击是因为还未给员工“林炜俊”分配权限 
- 通过管理员分配权限 - 给员工分配角色,这个角色名称为bdic,存在表t_role 
 
- 分配权限 
 
- 再次测试  
 
- 第二种注解@SaCheckRole以角色代码 
    @Operation(summary = "单个下达指令单 @author cyz")
    @GetMapping("/produceInstructOrder/issued/{id}")
    @SaCheckRole("zscbdic")
    public ResponseDTO<String> issued(@PathVariable Long id) {
        return produceInstructOrderService.issued(id);
    }如果需要对显示做权限分离的话需要到前端代码里在相应的组件上添加v-privilege修饰。
数据范围(能看什么)
- 注解 - @DataScope,一般只需要填写dataScope,whereInType,joinSql这三个属性即可 
 
- 分配角色和可查看范围 
 
- 给表添加用于权限区分的字段,默认分为以员工id区分或部门id区分 
- 解读:SmartAdmin对这个功能的实现是基于Mybatis的拦截器Incepter,它目前只配置了针对查询这个请求的拦截,最终的效果就是在你查询语句后面拼接where条件 
实战演示
这个单位管理界面展示所有单位信息,现在希望每个登陆用户只能看到属于自己数据范围的数据

在数据访问层Dao添加注解DataScope
@Mapper
@Component
public interface UnitDao extends BaseMapper<UnitEntity> {
    /**
     * 分页 查询
     *
     * @param page
     * @param queryForm
     * @return
     */
@DataScope(dataScopeType = DataScopeTypeEnum.NOTICE,whereInType = DataScopeWhereInTypeEnum.EMPLOYEE,joinSql = "t_mes_unit.employee_id in (#employeeIds)")
    List<UnitVO> queryPage(Page page, @Param("queryForm") UnitQueryForm queryForm);- dataScopeType:使用DataScopeTypeEnum枚举类的值 
- whereInType:以员工id区分还是以部门id区分,使用DataScopeWhereInTypeEnum枚举类的值 
- joinSql:拼接的sql语句 
演示效果:这里以员工id作为区分
查看本人数据


查看本部门
测试部有三位成员,而员工”陈佳明“属于测试部的下属部门测试部1

调整为本部门


查看本部门及下属部门,而员工”陈佳明“属于测试部的下属部门测试部1


查看全部

可以看到一位其他部门的员工

通过查看sql语句可以看出当选择全部的时候,它直接去除了where筛选条件
SELECT * FROM t_mes_unit WHERE t_mes_unit.deleted_flag = 0 LIMIT 10

