Spring--04--2--AOP自定义注解,数据过滤处理

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


数据过滤处理

1.DataColumn、DataScope

java 复制代码
import java.lang.annotation.*;


@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Repeatable(DataScope.class)
public @interface DataColumn {

    /**
     * 主表别名
     *
     * @return string
     */
    String alias() default "";

    /**
     * 字段名称 create_by
     *
     * @return string
     */
    String name();

    /**
     * 用户id user_id 或 we_user_id
     *
     * @return string
     */
    String userid();

}

DataScope

java 复制代码
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 数据权限过滤注解
 *
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataScope {

    /**
     * 业务类型 1-按照部门查询 2-按照员工id查询
     *
     * @return string
     */
    public String type() default "1";

    /**
     * 部门表的别名
     *
     * @return the string
     */
    public String deptAlias() default "";

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


    /**
     * Value data column [ ].
     *
     * @return the data column [ ]
     */
    DataColumn[] value() default {};
}

2.Aspect

java 复制代码
/**
 * 数据过滤处理
 *
 */
@Aspect
@Component
@Slf4j
public class DataScopeAspect {

    /**
     * 数据权限过滤关键字
     */
    public static final String DATA_SCOPE = "dataScope";

    /**
     * Do before.
     *
     * @param point               the point
     * @param controllerDataScope the controller data scope
     * @throws Throwable the throwable
     */
    @Before("@annotation(controllerDataScope)")
    public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable {
        clearDataScope(point);
        handleDataScope(point, controllerDataScope);
    }

    /**
     * Handle data scope.
     *
     * @param joinPoint           the join point
     * @param controllerDataScope the controller data scope
     */
    protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) {
        // 获取当前的用户
        LoginUser loginUser = SecurityUtils.getLoginUser();


        log.info("数据权限拦截:" + loginUser);

        if (StringUtils.isNotNull(loginUser)) {
            SysUser currentUser = loginUser.getSysUser();
            // 如果是超级管理员,则不过滤数据
            if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) {
                dataScopeFilterForSysUser(joinPoint, currentUser, controllerDataScope);
            }
        }
    }

    /**
     * 数据范围过滤(员工绑定数据权限)
     *
     * @param joinPoint           切点
     * @param user                用户
     * @param controllerDataScope 部门别名
     */
    public static void dataScopeFilterForSysUser(JoinPoint joinPoint, SysUser user, DataScope controllerDataScope) {
        StringBuilder sqlString = new StringBuilder();

        if (null != user) {
            DataScopeType type = DataScopeType.of(String.valueOf(user.getDataScope()));
            log.info("DataScopeType" + type);
            switch (type) {
                case DATA_SCOPE_ALL:
                    sqlString = new StringBuilder();
                    return;
                case DATA_SCOPE_CUSTOM:
                    sqlString.append(DataScopeSqlUtils.setWhereForSysUser(controllerDataScope, user));
                    break;
                case DATA_SCOPE_DEPT:
                    sqlString.append(DataScopeSqlUtils.setWhereForDept(controllerDataScope, user));
                    break;
                case DATA_SCOPE_DEPT_AND_CHILD:
                    sqlString.append(DataScopeSqlUtils.setWhereForDeptAndChild(controllerDataScope, user));
                    break;
                case DATA_SCOPE_SELF:
                    sqlString.append(DataScopeSqlUtils.setWhereForSelf(controllerDataScope, user));
                    break;
                default:
                    break;

            }


        }


        if (StringUtils.isNotBlank(sqlString.toString()) && joinPoint.getArgs().length > 0) {
            Object params = joinPoint.getArgs()[0];
            if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {
                BaseEntity baseEntity = (BaseEntity) params;
                baseEntity.getParams().put(DATA_SCOPE, " (" + sqlString.substring(4) + ")");
            }
        }


    }


    /**
     * 拼接权限sql前先清空params.dataScope参数防止注入
     *
     * @param joinPoint the join point
     */
    private void clearDataScope(final JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        if (ArrayUtil.isNotEmpty(args)) {
            Object params = joinPoint.getArgs()[0];
            if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {
                BaseEntity baseEntity = (BaseEntity) params;
                baseEntity.getParams().put(DATA_SCOPE, "");
            }
        }

    }
}

DataScopeSqlUtils

java 复制代码
/**
 * 数据权限sql构造
 */
public class DataScopeSqlUtils {

    private static final String ONE = "1";

    /**
     * 自定数据权限
     *
     * @param dataScope the data scope
     * @param sysUser   the sys user
     * @return where for sys user
     */
    public static String setWhereForSysUser(DataScope dataScope, SysUser sysUser) {

        StringBuilder sqlPart = new StringBuilder();
        if (ONE.equals(dataScope.type())) {
            sqlPart.append(StringUtils.format(
                    " or {}.dept_id IN ( SELECT dept_id FROM sys_user_manage_scop WHERE user_id = {} ) ", dataScope.deptAlias(),
                    sysUser.getUserId()));
        } else {
            DataColumn dataColumn = dataScope.value()[0];
            if (StringUtils.isNotEmpty(dataColumn.alias())) {
                sqlPart.append(StringUtils.format(
                        " or {}.{} in ( SELECT DISTINCT {} FROM sys_user_dept WHERE del_flag=0 AND dept_id IN (SELECT dept_id FROM sys_user_manage_scop where user_id={}) )",
                        dataColumn.alias(), dataColumn.name(), dataColumn.userid(), sysUser.getUserId()));
            } else {

                sqlPart.append(StringUtils.format(
                        " or {} in ( SELECT DISTINCT {} FROM sys_user_dept WHERE del_flag=0 AND dept_id IN (SELECT dept_id FROM sys_user_manage_scop where user_id={}) )",
                        dataColumn.name(), dataColumn.userid(), sysUser.getUserId()));

            }
        }
        return sqlPart.toString();
    }


    /**
     * 本部门数据权限
     *
     * @param dataScope 数据范围注解
     * @param sysUser   the sys user
     * @return the where for dept
     * @throws JSQLParserException SQL解析异常
     */
    public static String setWhereForDept(DataScope dataScope, SysUser sysUser) {

        StringBuilder sqlPart = new StringBuilder();
        if (ONE.equals(dataScope.type())) {
            sqlPart.append(StringUtils.format(" or {}.dept_id = {} ", dataScope.deptAlias(), sysUser.getDeptId()));
        } else {
            DataColumn dataColumn = dataScope.value()[0];
            if (StringUtils.isNotEmpty(dataColumn.alias())) {
                sqlPart.append(StringUtils.format(" or {}.{} in ( SELECT {} from sys_user_dept where dept_id in ({}) ) ",
                        dataColumn.alias(), dataColumn.name(), dataColumn.userid(), StringUtils.isEmpty(sysUser.getDeptIds()) ? sysUser.getDeptId() : sysUser.getDeptIds()));

            } else {
                sqlPart.append(StringUtils.format(" or {} in ( SELECT {} from sys_user_dept where dept_id in ({}) ) ",
                        dataColumn.name(), dataColumn.userid(), StringUtils.isEmpty(sysUser.getDeptIds()) ? sysUser.getDeptId() : sysUser.getDeptIds()));
            }


        }
        return sqlPart.toString();

    }


    /**
     * 部门及以下数据权限
     *
     * @param dataScope 数据范围注解
     * @param sysUser   the sys user
     * @return the where for dept and child
     * @throws JSQLParserException SQL解析异常
     */
    public static String setWhereForDeptAndChild(DataScope dataScope, SysUser sysUser) {

        StringBuilder sqlPart = new StringBuilder();
        if (ONE.equals(dataScope.type())) {
            sqlPart.append(StringUtils.format(
                    " or {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
                    dataScope.deptAlias(), sysUser.getDeptId(), sysUser.getDeptId()));
        } else {
            DataColumn dataColumn = dataScope.value()[0];
            if (StringUtils.isNotEmpty(dataColumn.alias())) {
                sqlPart.append(StringUtils.format(" or {}.{} in ( SELECT sud.{} FROM sys_user_dept sud WHERE sud.dept_id IN (SELECT dept_id FROM sys_dept WHERE FIND_IN_SET({},ancestors) or dept_id={} ) ) ",
                        dataColumn.alias(), dataColumn.name(), dataColumn.userid(), sysUser.getDeptId(), sysUser.getDeptId()));
            } else {
                sqlPart.append(StringUtils.format(" or {} in ( SELECT sud.{} FROM sys_user_dept sud WHERE sud.dept_id IN (SELECT dept_id FROM sys_dept WHERE FIND_IN_SET({},ancestors)  or dept_id={} ) ) ",
                        dataColumn.name(), dataColumn.userid(), sysUser.getDeptId(), sysUser.getDeptId()));
            }
        }
        return sqlPart.toString();
    }


    /**
     * 仅本人数据权限
     *
     * @param dataScope 数据范围注解
     * @param sysUser   the sys user
     * @return the where for self
     * @throws JSQLParserException SQL解析异常
     */
    public static String setWhereForSelf(DataScope dataScope, SysUser sysUser) {

        StringBuilder sqlPart = new StringBuilder();
        if (ONE.equals(dataScope.type())) {
            sqlPart.append(StringUtils.format(" AND {}.user_id = {} ", dataScope.userAlias(), sysUser.getUserId()));
        } else {
            DataColumn dataColumn = dataScope.value()[0];
            if (StringUtils.isNotEmpty(dataColumn.alias())) {
                sqlPart.append(StringUtils.format(" or {}.{} in ( select {} from sys_user where user_id = {} and del_flag = 0 ) ",
                        dataColumn.alias(), dataColumn.name(), dataColumn.userid(), sysUser.getUserId()));
            } else {
                sqlPart.append(StringUtils.format(" or {} in ( select {} from sys_user where user_id = {} and del_flag = 0 ) ",
                        dataColumn.name(), dataColumn.userid(), sysUser.getUserId()));
            }

        }
        return sqlPart.toString();
    }

}

DataScopeType

java 复制代码
import java.util.Objects;

/**
 * @description 数据权限枚举
 **/
public enum DataScopeType {
    /**
     * 全部数据权限
     */
    DATA_SCOPE_ALL("1"),
    /**
     * 自定数据权限
     */
    DATA_SCOPE_CUSTOM("2"),
    /**
     * 部门数据权限
     */
    DATA_SCOPE_DEPT("3"),
    /**
     * 部门及以下数据权限
     */
    DATA_SCOPE_DEPT_AND_CHILD("4"),
    /**
     * 仅本人数据权限
     */
    DATA_SCOPE_SELF("5");

    /**
     * The Code.
     */
    private String code;

    /**
     * Gets code.
     *
     * @return the code
     */
    public String getCode() {
        return code;
    }

    /**
     * Instantiates a new Data scope type.
     *
     * @param code the code
     */
    DataScopeType(String code) {
        this.code = code;
    }

    /**
     * Of data scope type.
     *
     * @param code the code
     * @return the data scope type
     */
    public static DataScopeType of(String code) {

        Objects.requireNonNull(code, "数据范围权限类型不允许为空");

        for (DataScopeType dataScopeType : DataScopeType.values()) {
            if (dataScopeType.getCode().equals(code)) {
                return dataScopeType;
            }
        }

        throw new IllegalArgumentException(String.format("未识别的数据范围权限类型值[%s]", code));
    }
}

3.应用

java 复制代码
public interface WeMomentsTaskMapper extends BaseMapper<WeMomentsTask> {

    /**
     * 列表
     */
    @DataScope(type = "2", value = @DataColumn(alias = "t1", name = "create_by_id", userid = "user_id"))
    List<WeMomentsTaskVO> list(WeMomentsTaskListRequest request);

}






相关推荐
小醉你真好3 分钟前
Spring Boot + ShardingSphere 实现分库分表 + 读写分离实战
spring boot·后端·mysql
杰克尼15 分钟前
Java基础-stream流的使用
java·windows·python
超级小忍17 分钟前
深入解析 Apache Tomcat 配置文件
java·tomcat·apache
我爱娃哈哈32 分钟前
微服务拆分粒度,拆得太细还是太粗?一线架构师实战指南!
后端·微服务
终是蝶衣梦晓楼36 分钟前
HiC-Pro Manual
java·开发语言·算法
泉城老铁41 分钟前
EasyPoi实现百万级数据导出的性能优化方案
java·后端·excel
斜月42 分钟前
Spring 自动装配原理即IOC创建流程
spring boot·后端·spring
贰拾wan1 小时前
抛出自定义异常
java
weisian1511 小时前
Prometheus-3--Prometheus是怎么抓取Java应用,Redis中间件,服务器环境的指标的?
java·redis·prometheus
界面开发小八哥1 小时前
「Java EE开发指南」如何用MyEclipse创建企业应用项目?(二)
java·ide·java-ee·开发工具·myeclipse