• Ruo-Yi前后端分离的数据过滤


    Ruo-Yi前后端分离的数据过滤

    若依官网的介绍:http://doc.ruoyi.vip/ruoyi/document/htsc.html#%E6%95%B0%E6%8D%AE%E6%9D%83%E9%99%90

    1、数据过滤的实现

    ​ 其实是在mybatis 的 sql 上添加了${params.dataScope}这个东西,实现了数据过滤。

        <select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
    		select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from sys_user u
    		left join sys_dept d on u.dept_id = d.dept_id
    		where u.del_flag = '0'
    		<if test="userId != null and userId != 0">
    			AND u.user_id = #{userId}
    		if>
    		<if test="userName != null and userName != ''">
    			AND u.user_name like concat('%', #{userName}, '%')
    		if>
    		<if test="status != null and status != ''">
    			AND u.status = #{status}
    		if>
    		<if test="phonenumber != null and phonenumber != ''">
    			AND u.phonenumber like concat('%', #{phonenumber}, '%')
    		if>
    		<if test="params.beginTime != null and params.beginTime != ''">
    			AND date_format(u.create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
    		if>
    		<if test="params.endTime != null and params.endTime != ''">
    			AND date_format(u.create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
    		if>
    		<if test="deptId != null and deptId != 0">
    			AND (u.dept_id = #{deptId} OR u.dept_id IN ( SELECT t.dept_id FROM sys_dept t WHERE find_in_set(#{deptId}, ancestors) ))
    		if>
    		
    		${params.dataScope}
    	select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    为什么加这个就可以实现呢?我们根据/system/user/list这个请求路径来分析?

    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysUser user)
    {
        // 设置 分页 参数
        startPage();
        // 根据分页参数查询数据 表:sys_user 和 sys_dept
        List<SysUser> list = userService.selectUserList(user);
        // 封装前台需要的数据
        return getDataTable(list);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    然后我们进入selectUserList方法

    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<SysUser> selectUserList(SysUser user)
    {
        return userMapper.selectUserList(user);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ​ 在这里我们发现了关键,就是==@DataScope==注解,其实若依框架的数据过滤就是通过这个注解实现的。这个是一个AOP知识点的利用,我们需要找到标注了@Aspect的注解,我们找到了类DataScopeAspect。之后我们要进入 selectUserList()方法之前,我们先要进入DataScopeAspect类。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YCKvTkYQ-1666165318913)(数据权限.assets/image-20221019151535820.png)]

    方法的调用流程:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-izkviK1k-1666165318913)(数据权限.assets/image-20221019152129069.png)]

    进入切面类 DataScopeAspect ,首先进入

    @Before("@annotation(controllerDataScope)")
    public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable
    {
        clearDataScope(point); // 拼接权限sql前先清空params.dataScope参数防止注入
        handleDataScope(point, controllerDataScope);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    然后:

    protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope)
    {
        // 获取当前的用户
        LoginUser loginUser = SecurityUtils.getLoginUser(); // 获取当前登陆的用户
        if (StringUtils.isNotNull(loginUser))
        { // 如果 loginUser 不为空的话
            SysUser currentUser = loginUser.getUser();
            // 如果是超级管理员,则不过滤数据
            if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin())
            {// 下面就要过滤数据了
                String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext());
    
                // 这里其实就是 想给 每一个实体类都会继承的 BaseEntity 里面的 Map params; 属性添加一些过滤条件
                // 之后再 mapper 生成sql的时候就可以用来 过滤数据了
                dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
                                controllerDataScope.userAlias(), permission);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    然后:

    public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission)
    {
        StringBuilder sqlString = new StringBuilder();
        List<String> conditions = new ArrayList<String>(); // 存储 数据权限 1,2,3,4,5
        // 获取当前用户 的全部角色信息
        for (SysRole role : user.getRoles())
        {
            String dataScope = role.getDataScope(); // 获取 当前角色的数据权限
            // String DATA_SCOPE_CUSTOM = "2"; => 自定数据权限
            // 如果当前的 数据权限 不是 自定数据权限  并且 conditions 里面不包含当前的 数据权限
            if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope))
            {
                continue;
            }
            // 如果 ①permission 不为空 并且 ② 角色的权限信息不为空 并且 ③角色的权限不包含传递过来的角色权限
            if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions())
                && !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
            {
                continue;
            }
    
    
            //===================================== 从这里之后,sqlString 前面被赋值后,后面要是再次赋值会覆盖前面的 ====================================
    
    
            // String DATA_SCOPE_ALL = "1"; 全部数据权限
            // 如果当前的 数据权限是 全部数据权限
            if (DATA_SCOPE_ALL.equals(dataScope))
            {
                // 如果遍历到 一个 角色的数据权限为1的时候,就是  全部数据权限 就不需要过滤了,直接返回
                sqlString = new StringBuilder();
                break;
            }
            // String DATA_SCOPE_CUSTOM = "2"; =>  自定数据权限
            // 如果当前的 数据权限是 自定数据权限
            else if (DATA_SCOPE_CUSTOM.equals(dataScope))
            {
                sqlString.append(StringUtils.format(
                    " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,
                    role.getRoleId()));
            }
            // String DATA_SCOPE_DEPT = "3"; => 部门数据权限
            // 如果当前的 数据权限是 部门数据权限
            else if (DATA_SCOPE_DEPT.equals(dataScope))
            {
                sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
            }
            // String DATA_SCOPE_DEPT_AND_CHILD = "4"; => 部门及以下数据权限
            // 如果当前的 数据权限是 部门及以下数据权限
            else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
            {
                sqlString.append(StringUtils.format(
                    " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
                    deptAlias, user.getDeptId(), user.getDeptId()));
            }
            // String DATA_SCOPE_SELF = "5"; => 仅本人数据权限
            // 如果当前的 数据权限是 仅本人数据权限
            else if (DATA_SCOPE_SELF.equals(dataScope))
            {
                if (StringUtils.isNotBlank(userAlias))
                {
                    sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
                }
                else
                {
                    // 数据权限为仅本人且没有userAlias别名不查询任何数据
                    sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
                }
            }
            conditions.add(dataScope);
        }
        
        //====================上面是为了 设置 需要拼接的sql,下面是为将 sql 设置到实体类里面 =======================
    
        // 如果 sqlString不为 空的话
        if (StringUtils.isNotBlank(sqlString.toString()))
        {
            Object params = joinPoint.getArgs()[0];
            if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
            {
                BaseEntity baseEntity = (BaseEntity) params;
                // DATA_SCOPE = "dataScope";
                // 因为每一个实体类都继承了 BaseEntity 类,所以,每一个类也就有里面的每一个属性
                // 这里进行的操作就是给,实体类的 Map params; 字段 put("dataScope","xxxx")
                baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    然后就进入:

    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<SysUser> selectUserList(SysUser user)
    {
        return userMapper.selectUserList(user);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ​ 执行sql去了,这个时候 user 对象因为经过 DataScopeAspect类的一大堆骚操作,因为每一个实体类都继承了 BaseEntity 类,所以,每一个类也就有里面的每一个属性,经过上面的方法 给 params属性增加了key :"dataScope"值:“xxxx”

    ​ 然后再 mybatis 的sql里面就可以取到${params.dataScope},这个东西取到的就是sqlString字符串

    <select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
    	....
        
        ${params.dataScope}
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    总结:

    1、如果我们再若依项目里面想用数据过滤其实就只需要再 service 层加上一个 @DataScope注解即可

    2、若依框架能实现数据过滤的主要原因就是利用了AOP切面,再进入 service 方法之前先进入切面类里面的方法,执行完毕后再进入 service 层的方法。

    2、数据过滤测试每一种情况

    下面我们根据系统管理下的用户管理页面作为分析,查看每一种数据权限。

    调用的接口:

    http://localhost/dev-api/system/user/list?pageNum=1&pageSize=10
    
    • 1

    测试的数据

    INSERT INTO `sys_user` VALUES (1, 103, 'admin', '若依', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2022-10-19 14:22:42', 'admin', '2022-09-30 22:02:23', '', '2022-10-19 14:22:42', '管理员');
    INSERT INTO `sys_user` VALUES (2, 105, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2022-09-30 22:02:23', 'admin', '2022-09-30 22:02:23', 'admin', '2022-10-17 11:51:08', '测试员');
    INSERT INTO `sys_user` VALUES (100, NULL, '111', '1', '00', '', '', '0', '', '$2a$10$t0cnTqGNcOZlx99Hj3FIk.C3.4tFvtperOpp8nmhlhOl/vax.DjZq', '0', '0', '', NULL, 'admin', '2022-10-13 14:09:55', 'admin', '2022-10-17 11:51:10', NULL);
    INSERT INTO `sys_user` VALUES (101, 101, 'zs', 'zs', '00', '', '', '0', '', '$2a$10$MI9C2H3sw6orfGUcGOQoZushCERPPYmF0RCJFapI8ShBrU27bH8s6', '0', '0', '127.0.0.1', '2022-10-19 14:16:16', 'admin', '2022-10-13 17:48:39', 'admin', '2022-10-19 14:16:16', NULL);
    INSERT INTO `sys_user` VALUES (102, 101, 'sz', '深圳总公司', '00', '', '', '0', '', '$2a$10$Z1qGn6CKHZ9UgMpCILsKoO3Bgsc.oOOswqhChqrFpgAklFrDMzy6C', '0', '0', '', NULL, 'admin', '2022-10-19 11:45:10', '', NULL, NULL);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    2.1、① 仅自己权限

    现象

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lW0sSfsf-1666165318914)(数据权限.assets/image-20221019141523757.png)]

    登陆zs用户查询,zs用户的数据权限只有仅自己。查询结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t6inGdNY-1666165318915)(数据权限.assets/image-20221019141623670.png)]

    分析

    相当于查询用户id只为当前登陆用户

    if (StringUtils.isNotBlank(userAlias))
    {
        sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
    }
    else
    {
        // 数据权限为仅本人且没有userAlias别名不查询任何数据
        sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    查询的SQL:

    SELECT
    	u.user_id,
    	u.dept_id,
    	u.nick_name,
    	u.user_name,
    	u.email,
    	u.avatar,
    	u.phonenumber,
    	u.sex,
    	u.STATUS,
    	u.del_flag,
    	u.login_ip,
    	u.login_date,
    	u.create_by,
    	u.create_time,
    	u.remark,
    	d.dept_name,
    	d.leader 
    FROM
    	sys_user u
    	LEFT JOIN sys_dept d ON u.dept_id = d.dept_id 
    WHERE
    	u.del_flag = '0' 
    	AND ( u.user_id = 101 ) 
    	LIMIT 10;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    2.2、② 本部门

    现象:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H5NGi5gy-1666165318915)(数据权限.assets/image-20221019115431318.png)]

    登陆zs用户查询,zs用户的数据权限只有本部门。查询结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XeKDrMeV-1666165318915)(数据权限.assets/image-20221019115645550.png)]

    分析

    根据当前用户的部门信息过滤数据

    sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
    
    • 1
    SELECT
    	u.user_id,
    	u.dept_id,
    	u.nick_name,
    	u.user_name,
    	u.email,
    	u.avatar,
    	u.phonenumber,
    	u.sex,
    	u.STATUS,
    	u.del_flag,
    	u.login_ip,
    	u.login_date,
    	u.create_by,
    	u.create_time,
    	u.remark,
    	d.dept_name,
    	d.leader 
    FROM
    	sys_user u
    	LEFT JOIN sys_dept d ON u.dept_id = d.dept_id 
    WHERE
    	u.del_flag = '0' 
    	AND ( d.dept_id = 101 ) 
    	LIMIT 10;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    其实是给原本的SQL拼接了:

    AND ( d.dept_id = 101 ) 
    
    • 1
    2.3、③ 本部门及以下数据权限

    现象

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JTsuJbb7-1666165318916)(数据权限.assets/image-20221019133902852.png)]

    登陆zs用户查询,zs用户的数据权限只有本部门及以下数据权限。查询结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0jPIPw1m-1666165318917)(数据权限.assets/image-20221019134006401.png)]

    分析

    根据当前用户本部门及以下数据权限信息过滤数据

    sqlString.append(StringUtils.format(
        " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", deptAlias, user.getDeptId(), user.getDeptId()));
    
    • 1
    • 2
    SELECT
    	u.user_id,
    	u.dept_id,
    	u.nick_name,
    	u.user_name,
    	u.email,
    	u.avatar,
    	u.phonenumber,
    	u.sex,
    	u.STATUS,
    	u.del_flag,
    	u.login_ip,
    	u.login_date,
    	u.create_by,
    	u.create_time,
    	u.remark,
    	d.dept_name,
    	d.leader 
    FROM
    	sys_user u
    	LEFT JOIN sys_dept d ON u.dept_id = d.dept_id 
    WHERE
    	u.del_flag = '0' 
    	AND (d.dept_id IN (SELECT dept_id FROM sys_dept WHERE dept_id = 101 OR find_in_set(101, ancestors) )) 
    	LIMIT 10;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    其实是给原本的 SQL 拼接了:

    AND (d.dept_id IN (SELECT dept_id FROM sys_dept WHERE dept_id = 101 OR find_in_set(101, ancestors) )) 
    
    • 1
    2.4、④ 全部数据权限

    现象

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8QVuH9Aa-1666165318917)(数据权限.assets/image-20221019134937313.png)]

    登陆zs用户查询,zs用户的数据权限只有全部数据权限。查询结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N4elxONG-1666165318917)(数据权限.assets/image-20221019135141590.png)]

    全部都可以查询出来

    分析

    相当于给原本的 sql 后面什么 都不拼接

    sqlString = new StringBuilder();
    break;
    
    • 1
    • 2

    查询数据的sql语句:

    SELECT
    	u.user_id,
    	u.dept_id,
    	u.nick_name,
    	u.user_name,
    	u.email,
    	u.avatar,
    	u.phonenumber,
    	u.sex,
    	u.STATUS,
    	u.del_flag,
    	u.login_ip,
    	u.login_date,
    	u.create_by,
    	u.create_time,
    	u.remark,
    	d.dept_name,
    	d.leader 
    FROM
    	sys_user u
    	LEFT JOIN sys_dept d ON u.dept_id = d.dept_id 
    WHERE
    	u.del_flag = '0' 
    	LIMIT 10;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    相当于什么数据没有过滤。

    2.5、⑤ 自定数据权限

    现象

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fynpBReo-1666165318918)(数据权限.assets/image-20221019135603747.png)]

    设置自定义数据权限只能看到研发部门。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tlwqfsTf-1666165318919)(数据权限.assets/image-20221019135737731.png)]

    # 题外话:后面会详细讲解
    # 1
    在按下确定的这一瞬间其实发起了请求`http://localhost/dev-api/system/role/dataScope`
    这个请求往数据库表`sys_role_dept`插入数据,这个表就是 自定义数据权限才会用到的表
    # 2 
    这里 还存在一个 父子联动的问题,按照我这里显示的问题,这里我们选择父子联动
    - 如果选择父子联动: 用户属于若依科技、深圳总公司、研发部门,这三个任意一个都可以查询出来
    - 如果不选择父子联动:只能查询用户属于 深圳总公司下研发部门的用户
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    登陆zs用户查询,zs用户的数据权限只有自定数据权限。查询结果

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2pkBPBXw-1666165318919)(数据权限.assets/image-20221019140139543.png)]

    分析

    根据当前用户本部门及以下数据权限信息过滤数据

    相当于根据角色idssys_role_dept表里面找到部门id,然后根据部门id进行过滤数据

    sqlString.append(StringUtils.format(
    		" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,
        role.getRoleId()));
    
    • 1
    • 2
    • 3
    SELECT
    	u.user_id,
    	u.dept_id,
    	u.nick_name,
    	u.user_name,
    	u.email,
    	u.avatar,
    	u.phonenumber,
    	u.sex,
    	u.STATUS,
    	u.del_flag,
    	u.login_ip,
    	u.login_date,
    	u.create_by,
    	u.create_time,
    	u.remark,
    	d.dept_name,
    	d.leader 
    FROM
    	sys_user u
    	LEFT JOIN sys_dept d ON u.dept_id = d.dept_id 
    WHERE
    	u.del_flag = '0' 
    	AND ( d.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = 104 ) ) 
    	LIMIT 10;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    3、父子联动问题

    ​ 前面我们不是有说到一个 父子联动的按钮吗,我们现在就来详细来看看,这里为了更加能说明问题,我在数据库有添加了一个用户。她是属于长沙分公司的研发部门员工。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nyDjCvmx-1666165318920)(数据权限.assets/image-20221019142533118.png)]

    INSERT INTO `sys_user` VALUES (103, 205, 'csyf', '长沙-研发1', '00', '', '', '0', '', '$2a$10$VdGvUO.ZHGgAFCGBXMNBA.sjOtnYoODeqYYkrJhuqC4etrh/m.sXK', '0', '0', '', NULL, 'admin', '2022-10-19 14:08:46', '', NULL, NULL);
    
    • 1
    3.1、① 不勾选父子联动

    ​ 我们先来看第①种情况,父子不联动,我们只选择 深圳分公司下面的 研发部门

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZvoW7QBv-1666165318920)(数据权限.assets/image-20221019142929643.png)]

    点击确定后,我们发现请求了地址:http://localhost/dev-api/system/role/dataScope

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BVSQ5D9x-1666165318920)(数据权限.assets/image-20221019143226204.png)]

    保存到数据库表sys_role_dept里面的也只有一条数据

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EN6TXbUN-1666165318920)(数据权限.assets/image-20221019143322052.png)]

    admin用户的页面:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zwg3LB7e-1666165318921)(数据权限.assets/image-20221019143624004.png)]

    ​ 我们现在再使用zs用户登陆系统。根据我们上面的分析,过滤的时候过滤的时候是查询当前角色下的部门id,根据这些部门id进行过滤的。所以 我们也就只能看到 深圳分公司下面研发部门的用户,即只能看到zs用户。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LcCgrhdj-1666165318921)(数据权限.assets/image-20221019143558083.png)]

    3.2、② 勾选父子联动

    ​ 下面我们再看一下勾选父子联动,选择深圳分公司下面的研发部门会发生什么。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wa3WFvVt-1666165318921)(数据权限.assets/image-20221019143810568.png)]

    点击确定后,我们发现请求了地址:http://localhost/dev-api/system/role/dataScope

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uM9wUVqh-1666165318921)(数据权限.assets/image-20221019143939974.png)]

    再看看数据库:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2Bpdgjc5-1666165318921)(数据权限.assets/image-20221019144000199.png)]

    admin用户的页面:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0NiRrFLP-1666165318922)(数据权限.assets/image-20221019144026824.png)]

    ​ 我们现在再使用zs用户登陆系统。根据我们上面的分析,过滤的时候过滤的时候是查询当前角色下的部门id,根据这些部门id进行过滤的。所以 我们也就只能看到 深圳分公司下面研发部门的用户,即我们可以看到 admin、zs、sz这三个用户。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B7PGn2Ga-1666165318922)(数据权限.assets/image-20221019144206933.png)]

  • 相关阅读:
    重装系统后要安装哪些驱动
    近年GDC服务器分享合集(四): 《火箭联盟》:为免费游玩而进行的扩展
    每日五问(java)
    【Java】循环语句for、while、do-while
    【MySQL】MySql常见面试题总结
    基于python的django框架选题推荐生鲜超市供应平台
    计算机毕业设计 基于SpringBoot高校毕业与学位资格审核系统的设计与实现 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试
    java计算机毕业设计家教平台系统源码+mysql数据库+系统+lw文档+部署
    ORB-LSAM2:ComputeKeyPointsOctTree()提取特征:maxY = iniY + hCell + 6 为怎么是+6而不是+3?
    SpringBoot排除不需要的自动配置类
  • 原文地址:https://blog.csdn.net/H_Q_Li/article/details/127409426