一、实现逻辑分析

整体上用注解通过AOP对sql进行修改,从而实现数据筛选

1.Controller调用Service层方法

2.Service层方法上注解@DataScope

3.注解@DataScope 通过切面类DataScopeAspect获取前
端传输的参数,结合通过SpringSecurity获得的用户信息,
将参数[BaseEntity的子类]属性param赋值

4.xml Mapper [通过子类属性params 使用SQL 语句过滤
数据]

二、代码分析

1.Controller层

该接口startpage()为数据分页所需函数
该接口调用Service层中selectUserList函数
@PreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/list")
public TableDataInfo list(SysUser user)
{
    startPage();
    List<SysUser> list = userService.selectUserList(user);
    return getDataTable(list);
    }

2.Service层

该方法使用注解@DataScope传参为部门和用户
@Override
@DataScope(deptAlias = "d", userAlias = "u")
public List<SysUser> selectUserList(SysUser user)
{
    return userMapper.selectUserList(user);
}

3.注解

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

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

4.注解对应的切面类

监听注解,类型为controllerDataScope 对应的注解类
型@DataScope
@Before("@annotation(controllerDataScope)")
    public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable
    {
        clearDataScope(point);
        handleDataScope(point, controllerDataScope);
    }
函数clearDataScope判断传入参数是否为BaseEntity的
子类,从而防止SQL注入
private void clearDataScope(final JoinPoint joinPoint)
    {
        Object params = joinPoint.getArgs()[0];
        if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
        {
            BaseEntity baseEntity = (BaseEntity) params;
            baseEntity.getParams().put(DATA_SCOPE, "");
        }
    }

4.1当角色拥有全部权限

代码调试结果中,datascop为1,即切面类定义
的DATA_SCOPE_ALL

在这里插入图片描述

4.1当角色拥有自定义权限

代码调试结果中,datascop为2,即切面类定义
的DATA_SCOPE_CUSTOM

在这里插入图片描述

4.1当角色拥有本人权限

代码调试结果中,datascop为5,即切面类定义
的DATA_SCOPE_SELF

在这里插入图片描述

5.Mapper层 java代码

    public List<SysUser> selectUserList(SysUser sysUser);

5.Mapper层 xml代码

<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.password, 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>

三、测试结果

1.角色拥有全部权限

代码调试结果中,datascop为1,即切面类定义
的DATA_SCOPE_ALL

在这里插入图片描述

没有添加对应SQL

在这里插入图片描述

2.角色拥有自定义权限

代码调试结果中,datascop为2,即切面类定义
的DATA_SCOPE_CUSTOM

在这里插入图片描述

添加用户所拥有的对应查询SQL

在这里插入图片描述

3.角色拥有本人权限

代码调试结果中,datascop为5,即切面类定义
的DATA_SCOPE_SELF

在这里插入图片描述

添加用户所拥有的对应查询SQL

在这里插入图片描述

Logo

快速构建 Web 应用程序

更多推荐