记录学习ruoyi 第七节: 用户权限管理

目录

后端源码解析

Controller

DataScope

AOP 类DataScopeAspect 

handleDataScope

dataScopeFilter

前端展示效果


不同权限思维导图图

后端源码解析

Controller

        1.前端发送请求,后端接收get,里面做的是分页需要继续深入selectUserList才能看到对应的修改。

@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController
{
    ......
    @GetMapping("/list")
    public TableDataInfo list(SysUser user)
    {
        startPage();
        List<SysUser> list = userService.selectUserList(user);
        return getDataTable(list);
    }
    .....
}

DataScope

在selectUserList中有注解DataScope

注意

        1.部门别名和用户别名用在SQL 语句中,
        2.需要跟SQL 语句给部门和用户表名的别名保持一致

@Service
public class SysUserServiceImpl implements ISysUserService
{
    ......
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<SysUser> selectUserList(SysUser user)
    {

        return userMapper.selectUserList(user);
    }
    ......
}

注解@DataScope 定义

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataScope
{
    /**
     * 部门表的别名
     */
    public String deptAlias() default "";

    /**
     * 用户表的别名
     */
    public String userAlias() default "";

    /**
     * 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来
     */
    public String permission() default "";
}

AOP 类DataScopeAspect 

        注意:加上注解@DataScope的函数要被执行时,先执行doBefore,这里相当于前面的selectUserList在执行时被doBefore拦截,先执行了doBefore里的语句再执行加上注解@DataScope的函数

@Aspect
@Component
public class DataScopeAspect
{
    ......
    @Before("@annotation(controllerDataScope)")
    public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable
    {
        clearDataScope(point);
        handleDataScope(point, controllerDataScope);
    }
    ......
}

handleDataScope

        doBefore继续进入函数handleDataScope,这里会获取当前登录的用户,然后通过dataScopeFilter函数来组件对应XML里的${params.dataScope}

        if(条件是不为空并且不为管理员):管理员不需要加过滤数据,不为Admin则进入if中进入dataScopeFilter

protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope)
    {
        // 获取当前的用户
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (StringUtils.isNotNull(loginUser))
        {
            SysUser currentUser = loginUser.getUser();
            // 如果是超级管理员,则不过滤数据
            if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin())
            {
                String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext());
                dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
                        controllerDataScope.userAlias(), permission);
            }
        }
    }

dataScopeFilter

                                

DATA_SCOPE_DEPT.equals(dataScope)

 在其中dataScope是满足本部门数据权限就会给DATA_SCOPE_DEPT常量赋值,对应值1-5  

这里因为有有测试3中情况但超级管理员不传入函数所以DATA_SCOPE_DEPT会是3和5两种

等效与1:自定义权限(OR {}.dept_id = {} ", deptAlias, user.getDeptId()) =  OR d.dept_id = 105。(自定义权限跟部门表有关,需要通过dept_id去找,SQL返回部门全部数据)

           2:本人权限(OR {}.user_id = {} ", userAlias, user.getUserId() =  OR u.user_id = 用户的编码(本人权限只有找到自己的user_id返回,这里提供humou的例子u.user_id被改为100,SQL只能返回自己这条数据)

 

public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission)
{
    ......
    else if (DATA_SCOPE_DEPT.equals(dataScope))
    {
         sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
     }
    ......
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));
                }
            }
    ......
            
    if (StringUtils.isNotBlank(sqlString.toString()))
        {
            Object params = joinPoint.getArgs()[0];
            if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
            {
                BaseEntity baseEntity = (BaseEntity) params;
                baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
            }
        }

}

这里就是对应的XML里的sql语句,然后会根据dataScopeFilter函数组装的AND + sql语句赋值给${params.dataScope},通过查询的的结果返回给前端List

<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') &gt;= 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') &lt;= 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>

前端展示效果

这里新建两个用户(一个为普通员工(本人数据权限),一个为项目负责人(自定义数据权限))

超级管理员对应的sql查询 where是没有做任何的其他条件

注意若输入框如(用户名称,手机号码,状态等都为空)否则XML里也是会对where进行附加条件的。

两个角色都是财务部,自定义数据权限这里给与财务部权限

 普通员工就只有本人权限

使用humoumou登录可以看到财务部门的全部用户,但ry用户因为不是同一个部门所以看不到

d.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = 3 ) 找的是测试部门的id,select返回测试部门的所以数据 

使用humou登录因为是本人权限前端只展示有自己一个人

本人数据全选对应的sql条件也就是找user里找到对应人员的id

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光总在风雨后i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值