Spring--04--2--AOP自定义注解,数据过滤处理
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 数据过滤处理
- 1.DataColumn、DataScope
- 2.Aspect
- 3.应用
数据过滤处理
1.DataColumn、DataScope
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
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
/*** 数据过滤处理**/
@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
/*** 数据权限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
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.应用
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);}