最近有个需求:指定某些超管只能看到某些租户下的数据,因为超管默认是能看全部数据的,所以这块要更改下
框架自带的租户逻辑是在BladeTenantInterceptor这个类里面,继承了TenantLineInnerInterceptor这个类,TenantLineInnerInterceptor是mybatis-plus的租户拦截器
原先BladeTenantInterceptor的租户拼接方法,核心就是processPlainSelect方法下的this.builderExpression(where, fromTable)这个方法了,我们要扩展下超管逻辑
自定义写法
因为默认是EqualsTo来连接的,也就是mysql中的=操作,我们选择In是为了一个超管要看多个租户下的数据
/**
* mysql的in连接
*/
public class InTo extends ComparisonOperator {
public InTo() {
super("in");
}
@Override
public void accept(ExpressionVisitor expressionVisitor) {
expressionVisitor.visit(new InExpression());
}
}
自定义个租户拦截器,源码直接照抄,修改核心的就行了
public class MyBladeTenantInterceptor extends TenantLineInnerInterceptor {
红框的是自定义超管过滤配置,注意,下方的mapper调用要加@InterceptorIgnore(tenantLine=“true”)注解,不然会一直循环下去,直到溢出
一些核心代码
//自定义不需要拼接租户id的类,
public boolean ignoreTable(String tableName) {
return this.excludeTables.contains(tableName);
}
//核心方法
protected Expression builderExpressionIn(Expression currentExpression, Table table) {
//自定义配置
InTo equalsTo = this.builderInTo(table);
if (currentExpression == null) {
return equalsTo;
} else {
return currentExpression instanceof OrExpression ? new AndExpression(new Parenthesis(currentExpression), equalsTo) : new AndExpression(currentExpression, equalsTo);
}
}
/**
* 自定义处理
*
* @param table
* @return
*/
@SneakyThrows
public InTo builderInTo(Table table) {
//in连接 因为可能自定义多个租户,不能用equalsTo
InTo equalsTo = new InTo();
Expression leftExpression = this.getAliasColumn(table);
//超管拿自定义的组合id 扩展
User user = userMapper.getOneNoTenant(AuthUtil.getUserId());
List<Expression> childlist = new ArrayList<>();
//组装
List<String> stringList = Arrays.asList(user.getExtensionId().split("[,]"));
for (String s : stringList) {
childlist.add(new StringValue(s));
}
//定义分隔符
MultipleExpression multipleExpression = new MultipleExpression(childlist) {
@Override
public String getStringExpression() {
return ",";
}
};
equalsTo.setLeftExpression(leftExpression);
equalsTo.setRightExpression(multipleExpression);
return equalsTo;
}