init
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
package cn.datax.common.mybatis.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 数据权限过滤注解
|
||||
* 参考 https://gitee.com/cancerGit/Crown
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
public @interface DataScopeAop {
|
||||
|
||||
/**
|
||||
* 表的别名
|
||||
*/
|
||||
String alias() default "sys_user";
|
||||
/**
|
||||
* 表的部门字段
|
||||
*/
|
||||
String deptScopeName() default "create_dept";
|
||||
/**
|
||||
* 表的用户字段
|
||||
*/
|
||||
String userScopeName() default "create_by";
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package cn.datax.common.mybatis.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import cn.datax.common.base.BaseQueryParams;
|
||||
import cn.datax.common.core.DataConstant;
|
||||
import cn.datax.common.core.DataRole;
|
||||
import cn.datax.common.core.DataUser;
|
||||
import cn.datax.common.mybatis.annotation.DataScopeAop;
|
||||
import cn.datax.common.utils.SecurityUtil;
|
||||
import cn.datax.service.system.api.dto.JwtUserDto;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.Signature;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
|
||||
/**
|
||||
* 数据过滤处理(基于注解式,用于自定义sql)
|
||||
*/
|
||||
@Slf4j
|
||||
@Aspect
|
||||
public class DataScopeAspect {
|
||||
|
||||
// 配置织入点
|
||||
@Pointcut("@annotation(cn.datax.common.mybatis.annotation.DataScopeAop)")
|
||||
public void dataScopePointCut() {
|
||||
}
|
||||
|
||||
@Before("dataScopePointCut()")
|
||||
public void doBefore(JoinPoint point) {
|
||||
handleDataScope(point);
|
||||
}
|
||||
|
||||
protected void handleDataScope(final JoinPoint joinPoint) {
|
||||
// 获得注解
|
||||
DataScopeAop dataScope = getAnnotationLog(joinPoint);
|
||||
if (dataScope == null) {
|
||||
return;
|
||||
}
|
||||
JwtUserDto currentUser = SecurityUtil.getDataUser();
|
||||
if (null != currentUser) {
|
||||
// 如果是超级管理员,则不过滤数据
|
||||
// if (!currentUser.getUser().isAdmin) {
|
||||
// dataScopeFilter(joinPoint, currentUser, dataScope);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 数据范围过滤
|
||||
// *
|
||||
// * @param user
|
||||
// * @param dataScope
|
||||
// */
|
||||
// private void dataScopeFilter(JoinPoint joinPoint, JwtUserDto user, DataScopeAop dataScope) {
|
||||
// StringBuilder sqlString = new StringBuilder();
|
||||
// Set<String> roles = user.getRoles();
|
||||
// if (CollUtil.isNotEmpty(roles)){
|
||||
// for (String role : roles){
|
||||
// String roleDataScope = role.getDataScope();
|
||||
// if (DataConstant.DataScope.ALL.getKey().equals(roleDataScope)) {
|
||||
// sqlString = new StringBuilder();
|
||||
// break;
|
||||
// } else if (DataConstant.DataScope.CUSTOM.getKey().equals(roleDataScope)) {
|
||||
// sqlString.append(StrUtil.format(
|
||||
// " OR {}.{} IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) "
|
||||
// ,dataScope.alias()
|
||||
// ,dataScope.deptScopeName()
|
||||
// ,"'" + role.getId() + "'"
|
||||
// ));
|
||||
// } else if (DataConstant.DataScope.DEPT.getKey().equals(roleDataScope)) {
|
||||
// sqlString.append(StrUtil.format(
|
||||
// " OR {}.{} = {} "
|
||||
// ,dataScope.alias()
|
||||
// ,dataScope.deptScopeName()
|
||||
// ,"'" + user.getDept() + "'"
|
||||
// ));
|
||||
// } else if (DataConstant.DataScope.DEPTANDCHILD.getKey().equals(roleDataScope)) {
|
||||
// sqlString.append(StrUtil.format(
|
||||
// " OR {}.{} IN ( SELECT descendant FROM sys_dept_relation WHERE ancestor = {} )"
|
||||
// ,dataScope.alias()
|
||||
// ,dataScope.deptScopeName()
|
||||
// ,"'" + user.getDept() + "'"
|
||||
// ));
|
||||
// } else if (DataConstant.DataScope.SELF.getKey().equals(roleDataScope)) {
|
||||
// if (StrUtil.isNotBlank(dataScope.alias())) {
|
||||
// sqlString.append(StrUtil.format(" OR {}.{} = {} "
|
||||
// ,dataScope.alias()
|
||||
// ,dataScope.userScopeName()
|
||||
// ,user.getId()));
|
||||
// } else {
|
||||
// // 数据权限为仅本人且没有alias别名不查询任何数据
|
||||
// sqlString.append(" OR 1=0 ");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (StrUtil.isNotBlank(sqlString.toString())) {
|
||||
// BaseQueryParams baseQueryParams = (BaseQueryParams) joinPoint.getArgs()[0];
|
||||
// baseQueryParams.setDataScope(" AND (" + sqlString.substring(4) + ")");
|
||||
// }
|
||||
// log.info("数据范围过滤:{}", sqlString);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 是否存在注解,如果存在就获取
|
||||
*/
|
||||
private DataScopeAop getAnnotationLog(JoinPoint joinPoint) {
|
||||
Signature signature = joinPoint.getSignature();
|
||||
MethodSignature methodSignature = (MethodSignature) signature;
|
||||
Method method = methodSignature.getMethod();
|
||||
|
||||
if (method != null) {
|
||||
return method.getAnnotation(DataScopeAop.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package cn.datax.common.mybatis.config;
|
||||
|
||||
import cn.datax.common.mybatis.aspectj.DataScopeAspect;
|
||||
import cn.datax.common.mybatis.injector.DataLogicSqlInjector;
|
||||
import cn.datax.common.mybatis.interceptor.DataScopeInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
@MapperScan({"cn.datax.service.**.dao","com.platform.dts.mapper"})
|
||||
@EnableTransactionManagement
|
||||
public class DataBatisPlusConfig {
|
||||
|
||||
/**
|
||||
* 分页插件
|
||||
*
|
||||
* @return PaginationInterceptor
|
||||
*/
|
||||
@Bean
|
||||
public PaginationInterceptor paginationInterceptor() {
|
||||
return new PaginationInterceptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据权限插件
|
||||
*
|
||||
* @return DataScopeInterceptor
|
||||
*/
|
||||
@Bean
|
||||
public DataScopeInterceptor dataScopeInterceptor() {
|
||||
return new DataScopeInterceptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据过滤处理(基于注解式)
|
||||
*
|
||||
* @return dataScopeAspect
|
||||
*/
|
||||
@Bean
|
||||
public DataScopeAspect dataScopeAspect() {
|
||||
return new DataScopeAspect();
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义 SqlInjector
|
||||
* 里面包含自定义的全局方法
|
||||
*/
|
||||
@Bean
|
||||
public DataLogicSqlInjector myLogicSqlInjector() {
|
||||
return new DataLogicSqlInjector();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataMetaObjectHandler dataMetaObjectHandler() {
|
||||
return new DataMetaObjectHandler();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package cn.datax.common.mybatis.config;
|
||||
|
||||
import cn.datax.common.core.DataConstant;
|
||||
import cn.datax.common.utils.SecurityUtil;
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class DataMetaObjectHandler implements MetaObjectHandler {
|
||||
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
|
||||
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
|
||||
this.strictInsertFill(metaObject, "status", String.class, DataConstant.EnableState.ENABLE.getKey());
|
||||
this.strictInsertFill(metaObject, "createBy", String.class, SecurityUtil.getUserId());
|
||||
this.strictInsertFill(metaObject, "updateBy", String.class, SecurityUtil.getUserId());
|
||||
boolean bolCreateDept = metaObject.hasSetter("createDept");
|
||||
if (bolCreateDept) {
|
||||
this.strictInsertFill(metaObject, "createDept", String.class, SecurityUtil.getUserDeptId());
|
||||
}
|
||||
boolean bolFlowStatus = metaObject.hasSetter("flowStatus");
|
||||
if (bolFlowStatus) {
|
||||
this.strictInsertFill(metaObject, "flowStatus", String.class, DataConstant.AuditState.WAIT.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
|
||||
this.strictUpdateFill(metaObject, "updateBy", String.class, SecurityUtil.getUserId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.datax.common.mybatis.injector;
|
||||
|
||||
import cn.datax.common.mybatis.injector.methods.SelectListDataScope;
|
||||
import cn.datax.common.mybatis.injector.methods.SelectPageDataScope;
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 自定义 SqlInjector
|
||||
*/
|
||||
public class DataLogicSqlInjector extends DefaultSqlInjector {
|
||||
|
||||
/**
|
||||
* 如果只需增加方法,保留MP自带方法
|
||||
* 可以super.getMethodList() 再add
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
|
||||
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
|
||||
methodList.add(new SelectListDataScope());
|
||||
methodList.add(new SelectPageDataScope());
|
||||
return methodList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.datax.common.mybatis.injector.methods;
|
||||
|
||||
import com.baomidou.mybatisplus.core.enums.SqlMethod;
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.mapping.SqlSource;
|
||||
|
||||
public class SelectListDataScope extends AbstractMethod {
|
||||
|
||||
public SelectListDataScope() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
|
||||
SqlMethod sqlMethod = SqlMethod.SELECT_LIST;
|
||||
String sql = String.format(sqlMethod.getSql(), this.sqlFirst(), this.sqlSelectColumns(tableInfo, true), tableInfo.getTableName(), this.sqlWhereEntityWrapper(true, tableInfo), this.sqlComment());
|
||||
SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
|
||||
return this.addSelectMappedStatementForTable(mapperClass, "selectListDataScope", sqlSource, tableInfo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.datax.common.mybatis.injector.methods;
|
||||
|
||||
import com.baomidou.mybatisplus.core.enums.SqlMethod;
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.mapping.SqlSource;
|
||||
|
||||
public class SelectPageDataScope extends AbstractMethod {
|
||||
|
||||
public SelectPageDataScope() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
|
||||
SqlMethod sqlMethod = SqlMethod.SELECT_PAGE;
|
||||
String sql = String.format(sqlMethod.getSql(), this.sqlFirst(), this.sqlSelectColumns(tableInfo, true), tableInfo.getTableName(), this.sqlWhereEntityWrapper(true, tableInfo), this.sqlComment());
|
||||
SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
|
||||
return this.addSelectMappedStatementForTable(mapperClass, "selectPageDataScope", sqlSource, tableInfo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
package cn.datax.common.mybatis.interceptor;
|
||||
|
||||
import cn.datax.common.base.DataScope;
|
||||
import cn.datax.common.core.DataConstant;
|
||||
import cn.datax.common.core.DataRole;
|
||||
import cn.datax.common.core.DataUser;
|
||||
import cn.datax.common.utils.SecurityUtil;
|
||||
import cn.datax.service.system.api.dto.JwtUserDto;
|
||||
import cn.datax.service.system.api.dto.UserLoginDto;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
|
||||
import com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ibatis.executor.statement.StatementHandler;
|
||||
import org.apache.ibatis.mapping.BoundSql;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.mapping.SqlCommandType;
|
||||
import org.apache.ibatis.plugin.*;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
import org.apache.ibatis.reflection.SystemMetaObject;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* mybatis 数据权限拦截器
|
||||
*/
|
||||
@Slf4j
|
||||
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
|
||||
public class DataScopeInterceptor extends AbstractSqlParserHandler implements Interceptor {
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public Object intercept(Invocation invocation) {
|
||||
StatementHandler statementHandler = (StatementHandler) PluginUtils.realTarget(invocation.getTarget());
|
||||
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
|
||||
this.sqlParser(metaObject);
|
||||
// 先判断是不是SELECT操作
|
||||
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
|
||||
if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
|
||||
String originalSql = boundSql.getSql();
|
||||
Object parameterObject = boundSql.getParameterObject();
|
||||
|
||||
//查找参数中包含DataScope类型的参数
|
||||
DataScope dataScope = findDataScopeObject(parameterObject);
|
||||
|
||||
if (dataScope != null) {
|
||||
// 获取当前的用户
|
||||
JwtUserDto currentUser = SecurityUtil.getDataUser();
|
||||
if (null != currentUser) {
|
||||
UserLoginDto user = currentUser.getUser();
|
||||
// 如果是超级管理员,则不过滤数据
|
||||
// if (!user.isAdmin) {
|
||||
// String sqlString = dataScopeFilter(currentUser, dataScope);
|
||||
// if (StrUtil.isNotBlank(sqlString)) {
|
||||
// originalSql = "SELECT * FROM (" + originalSql + ") TEMP_DATA_SCOPE WHERE 1=1 AND (" + sqlString.substring(4) + ")";
|
||||
// metaObject.setValue("delegate.boundSql.sql", originalSql);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 数据范围过滤
|
||||
// *
|
||||
// * @param user
|
||||
// * @param dataScope
|
||||
// */
|
||||
// private String dataScopeFilter(JwtUserDto user, DataScope dataScope) {
|
||||
// StringBuilder sqlString = new StringBuilder();
|
||||
// Set<String> roles = user.getRoles();
|
||||
// if (CollUtil.isNotEmpty(roles)){
|
||||
// for (String role : roles){
|
||||
//// String roleDataScope = role.getDataScope();
|
||||
// if (DataConstant.DataScope.ALL.getKey().equals(roleDataScope)) {
|
||||
// sqlString = new StringBuilder();
|
||||
// break;
|
||||
// } else if (DataConstant.DataScope.CUSTOM.getKey().equals(roleDataScope)) {
|
||||
// sqlString.append(StrUtil.format(
|
||||
// " OR {} IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) "
|
||||
// ,dataScope.getDeptScopeName()
|
||||
// ,"'" + role + "'"
|
||||
// ));
|
||||
// } else if (DataConstant.DataScope.DEPT.getKey().equals(roleDataScope)) {
|
||||
// sqlString.append(StrUtil.format(
|
||||
// " OR {} = {} "
|
||||
// ,dataScope.getDeptScopeName()
|
||||
// ,"'" + user.getUser().getDept() + "'"
|
||||
// ));
|
||||
// } else if (DataConstant.DataScope.DEPTANDCHILD.getKey().equals(roleDataScope)) {
|
||||
// sqlString.append(StrUtil.format(
|
||||
// " OR {} IN ( SELECT descendant FROM sys_dept_relation WHERE ancestor = {} )"
|
||||
// ,dataScope.getDeptScopeName()
|
||||
// ,"'" + user.getUser().getDept() + "'"
|
||||
// ));
|
||||
// } else if (DataConstant.DataScope.SELF.getKey().equals(roleDataScope)) {
|
||||
// sqlString.append(StrUtil.format(" OR {} = {} "
|
||||
// ,dataScope.getUserScopeName()
|
||||
// ,"'" + user.getUser().getId() + "'"
|
||||
// ));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// log.info("数据范围过滤:{}", sqlString);
|
||||
// return sqlString.toString();
|
||||
// }
|
||||
|
||||
/**
|
||||
* 生成拦截对象的代理
|
||||
*
|
||||
* @param target 目标对象
|
||||
* @return 代理对象
|
||||
*/
|
||||
@Override
|
||||
public Object plugin(Object target) {
|
||||
if (target instanceof StatementHandler) {
|
||||
return Plugin.wrap(target, this);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* mybatis配置的属性
|
||||
*
|
||||
* @param properties mybatis配置的属性
|
||||
*/
|
||||
@Override
|
||||
public void setProperties(Properties properties) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找参数是否包括DataScope对象
|
||||
*
|
||||
* @param parameterObj 参数列表
|
||||
* @return DataScope
|
||||
*/
|
||||
private DataScope findDataScopeObject(Object parameterObj) {
|
||||
if (parameterObj instanceof DataScope) {
|
||||
return (DataScope) parameterObj;
|
||||
} else if (parameterObj instanceof Map) {
|
||||
for (Object val : ((Map<?, ?>) parameterObj).values()) {
|
||||
if (val instanceof DataScope) {
|
||||
return (DataScope) val;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
cn.datax.common.mybatis.config.DataBatisPlusConfig
|
||||
Reference in New Issue
Block a user