From 5aa43c19e99b74d0f1fc84641b35ea9f2256c102 Mon Sep 17 00:00:00 2001 From: wangxiang <1827945911@qq.com> Date: Wed, 11 May 2022 15:41:35 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=A3=20=E9=87=8D=E6=9E=84=E5=BA=95?= =?UTF-8?q?=E5=B1=82=E5=A4=9A=E7=A7=9F=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/handler/KiccTenantLineHandler.java | 4 +- .../data/override/TenantLikeExpression.java | 70 ++++++++++++++++ .../KiccTenantLineInnerInterceptor.java | 80 +++++++++++++------ .../system/service/impl/UserServiceImpl.java | 14 +++- 4 files changed, 136 insertions(+), 32 deletions(-) create mode 100644 kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/override/TenantLikeExpression.java diff --git a/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/handler/KiccTenantLineHandler.java b/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/handler/KiccTenantLineHandler.java index d75121b2..60d0948c 100644 --- a/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/handler/KiccTenantLineHandler.java +++ b/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/handler/KiccTenantLineHandler.java @@ -3,9 +3,9 @@ package com.cloud.kicc.common.data.handler; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; import com.cloud.kicc.common.data.entity.KiccUser; +import com.cloud.kicc.common.data.override.TenantLikeExpression; import com.cloud.kicc.common.data.properties.TenantProperties; import net.sf.jsqlparser.expression.Expression; -import net.sf.jsqlparser.expression.StringValue; import net.sf.jsqlparser.schema.Column; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -57,7 +57,7 @@ public class KiccTenantLineHandler implements TenantLineHandler { @Override public Expression getTenantId() { // 返回当前用户所属的多租户ID进行条件拼接 - return ObjectUtil.isNotEmpty(getUser()) ? new StringValue(getUser().getTenantId()) : null; + return ObjectUtil.isNotEmpty(getUser()) ? new TenantLikeExpression(getUser().getTenantId()) : null; } /** diff --git a/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/override/TenantLikeExpression.java b/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/override/TenantLikeExpression.java new file mode 100644 index 00000000..eb5c4ddb --- /dev/null +++ b/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/override/TenantLikeExpression.java @@ -0,0 +1,70 @@ +package com.cloud.kicc.common.data.override; + +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.ExpressionVisitor; +import net.sf.jsqlparser.parser.ASTNodeAccessImpl; + +import java.util.Objects; + +/** + *

+ * 重写StringValue,支持多租户like拼接查询 + * 由于内部StringExpression会拼接默认会加'' + * 而多租户like条件经过处理不许需要加'',如果加上会导致数据查不出 + *

+ * + * @Author: entfrm开发团队-王翔 + * @Date: 2022/5/11 + */ +public class TenantLikeExpression extends ASTNodeAccessImpl implements Expression { + + private String value = ""; + + public TenantLikeExpression() { + } + + public TenantLikeExpression(String escapedValue) { + this.value = escapedValue; + } + + public String getValue() { + return this.value; + } + + + public void setValue(String string) { + this.value = string; + } + + + @Override + public void accept(ExpressionVisitor expressionVisitor) { + } + + @Override + public String toString() { + return this.value; + } + + public TenantLikeExpression withValue(String value) { + this.setValue(value); + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } else if (o != null && this.getClass() == o.getClass()) { + TenantLikeExpression that = (TenantLikeExpression)o; + return Objects.equals(this.value, that.value); + } else { + return false; + } + } + + @Override + public int hashCode() { + return Objects.hash(new Object[]{this.value}); + } +} diff --git a/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/plugins/KiccTenantLineInnerInterceptor.java b/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/plugins/KiccTenantLineInnerInterceptor.java index e0efaa35..1c80a67c 100644 --- a/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/plugins/KiccTenantLineInnerInterceptor.java +++ b/kicc-common/kicc-common-data/src/main/java/com/cloud/kicc/common/data/plugins/KiccTenantLineInnerInterceptor.java @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils; import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; +import com.cloud.kicc.common.data.override.TenantLikeExpression; import lombok.NoArgsConstructor; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.Parenthesis; @@ -13,8 +14,8 @@ import net.sf.jsqlparser.expression.StringValue; import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.expression.operators.conditional.OrExpression; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; -import net.sf.jsqlparser.expression.operators.relational.InExpression; import net.sf.jsqlparser.expression.operators.relational.ItemsList; +import net.sf.jsqlparser.expression.operators.relational.LikeExpression; import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; @@ -37,7 +38,7 @@ import java.util.stream.Collectors; /** *

* 租户线路内部拦截器 - * 重构租户线路内部拦截器,支持查询多个多租户ID,默认只支持一个多租户id查询 + * 重构租户线路内部拦截器,支持查询多个多租户ID,还支持查询多个租户的共享数据,默认只支持一个多租户id查询 * 支持多租户ID不存在时,查询所有租户ID数据 *

* @@ -76,12 +77,21 @@ public class KiccTenantLineInnerInterceptor extends TenantLineInnerInterceptor { String tenantIdColumn = this.tenantLineHandler.getTenantIdColumn(); if (!this.tenantLineHandler.ignoreInsert(columns, tenantIdColumn)) { columns.add(new Column(tenantIdColumn)); + List duplicateUpdateColumns = insert.getDuplicateUpdateExpressionList(); if (CollectionUtils.isNotEmpty(duplicateUpdateColumns)) { - // 替换InExpression支持查询多个租户ID的条件 - InExpression inExpression = new InExpression(); - inExpression.setLeftExpression(new StringValue(tenantIdColumn)); - inExpression.setRightItemsList(new ExpressionList(this.tenantLineHandler.getTenantId())); + // 替换likeExpression支持查询多个租户ID的条件,包括查询数据对应多个多租户ID的数据 + List tenantIds = StrUtil.split(this.tenantLineHandler.getTenantId().toString(), ","); + StringBuilder statementBuilder = new StringBuilder(); + tenantIds.forEach(tenantId -> { + LikeExpression likeExpression = new LikeExpression(); + likeExpression.setLeftExpression(new Column(tenantIdColumn)); + likeExpression.setRightExpression(new StringValue("%" + tenantId + "%")); + statementBuilder.append(likeExpression + " OR "); + }); + statementBuilder.delete(statementBuilder.length()-4, statementBuilder.length()); + TenantLikeExpression tenantLikeExpression = new TenantLikeExpression(statementBuilder.toString()); + duplicateUpdateColumns.add(tenantLikeExpression); } Select select = insert.getSelect(); @@ -111,27 +121,34 @@ public class KiccTenantLineInnerInterceptor extends TenantLineInnerInterceptor { protected void processUpdate(Update update, int index, String sql, Object obj) { Table table = update.getTable(); if (!this.tenantLineHandler.ignoreTable(table.getName())) { - update.setWhere(this.andInExpression(table, update.getWhere())); + update.setWhere(this.andLikeExpression(table, update.getWhere())); } } @Override protected void processDelete(Delete delete, int index, String sql, Object obj) { if (!this.tenantLineHandler.ignoreTable(delete.getTable().getName())) { - delete.setWhere(this.andInExpression(delete.getTable(), delete.getWhere())); + delete.setWhere(this.andLikeExpression(delete.getTable(), delete.getWhere())); } } - /** 重写andExpression表达式,支持in查询多个参数 */ - protected Expression andInExpression(Table table, Expression where) { - // 替换InExpression支持查询多个租户ID的条件 - InExpression inExpression = new InExpression(); - inExpression.setLeftExpression(this.getAliasColumn(table)); - inExpression.setRightItemsList(new ExpressionList(this.tenantLineHandler.getTenantId())); + /** 重写andExpression表达式,支持like查询多个参数 */ + protected Expression andLikeExpression(Table table, Expression where) { + // 替换likeExpression支持查询多个租户ID的条件,包括查询数据对应多个多租户ID的数据 + List tenantIds = StrUtil.split(this.tenantLineHandler.getTenantId().toString(), ","); + StringBuilder statementBuilder = new StringBuilder(); + tenantIds.forEach(tenantId -> { + LikeExpression likeExpression = new LikeExpression(); + likeExpression.setLeftExpression(this.getAliasColumn(table)); + likeExpression.setRightExpression(new StringValue("%" + tenantId + "%")); + statementBuilder.append(likeExpression + " OR "); + }); + statementBuilder.delete(statementBuilder.length()-4, statementBuilder.length()); + TenantLikeExpression tenantLikeExpression = new TenantLikeExpression(statementBuilder.toString()); if (null != where) { - return where instanceof OrExpression ? new AndExpression(inExpression, new Parenthesis(where)) : new AndExpression(inExpression, where); + return where instanceof OrExpression ? new AndExpression(tenantLikeExpression, new Parenthesis(where)) : new AndExpression(tenantLikeExpression, where); } else { - return inExpression; + return tenantLikeExpression; } } @@ -140,18 +157,29 @@ public class KiccTenantLineInnerInterceptor extends TenantLineInnerInterceptor { if (CollectionUtils.isEmpty(tables)) { return currentExpression; } else { - Expression tenantId = this.tenantLineHandler.getTenantId(); - // 替换InExpression支持查询多个租户ID的条件 - List inExpressions = tables.stream() - .filter(x -> !this.tenantLineHandler.ignoreTable(x.getName())) - .map(item -> new InExpression(this.getAliasColumn(item), new ExpressionList(tenantId))).collect(Collectors.toList()); - if (CollectionUtils.isEmpty(inExpressions)) { + // 替换likeExpression支持查询多个租户ID的条件,包括查询数据对应多个多租户ID的数据 + List strExpressions = tables.stream() + .filter(x -> !this.tenantLineHandler.ignoreTable(x.getName())) + .map(item -> { + List tenantIds = StrUtil.split(this.tenantLineHandler.getTenantId().toString(), ","); + StringBuilder statementBuilder = new StringBuilder(); + tenantIds.forEach(tenantId -> { + LikeExpression likeExpression = new LikeExpression(); + likeExpression.setLeftExpression(this.getAliasColumn(item)); + likeExpression.setRightExpression(new StringValue("%" + tenantId + "%")); + statementBuilder.append(likeExpression + " OR "); + }); + statementBuilder.delete(statementBuilder.length()-4, statementBuilder.length()); + TenantLikeExpression tenantLikeExpression = new TenantLikeExpression(statementBuilder.toString()); + return tenantLikeExpression; + }).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(strExpressions)) { return currentExpression; } else { - Expression injectExpression = inExpressions.get(0); - if (inExpressions.size() > 1) { - for(int i = 1; i < inExpressions.size(); ++i) { - injectExpression = new AndExpression(injectExpression, inExpressions.get(i)); + Expression injectExpression = strExpressions.get(0); + if (strExpressions.size() > 1) { + for(int i = 1; i < strExpressions.size(); ++i) { + injectExpression = new AndExpression(injectExpression, strExpressions.get(i)); } } diff --git a/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/service/impl/UserServiceImpl.java b/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/service/impl/UserServiceImpl.java index bb98a812..b3096903 100644 --- a/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/service/impl/UserServiceImpl.java +++ b/kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/service/impl/UserServiceImpl.java @@ -5,19 +5,21 @@ import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cloud.kicc.common.core.constant.SecurityConstants; +import com.cloud.kicc.common.core.exception.CheckedException; import com.cloud.kicc.system.api.entity.Dept; import com.cloud.kicc.system.api.entity.Role; import com.cloud.kicc.system.api.entity.User; import com.cloud.kicc.system.api.entity.UserRole; import com.cloud.kicc.system.mapper.UserMapper; import com.cloud.kicc.system.service.*; -import com.cloud.kicc.common.core.constant.SecurityConstants; -import com.cloud.kicc.common.core.exception.CheckedException; import lombok.AllArgsConstructor; +import lombok.SneakyThrows; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.server.ServerErrorException; import java.util.HashSet; import java.util.List; @@ -63,7 +65,9 @@ public class UserServiceImpl extends ServiceImpl implements Us } } + @Override + @SneakyThrows public User getUserAuthority(User user) { // 设置角色列表 List roleList = roleService.selectMyRolesByUserId(user.getId()); @@ -89,8 +93,10 @@ public class UserServiceImpl extends ServiceImpl implements Us tenantCode.addAll(codes); }); // 检测多租户信息是否存在,不存在抛出异常 - - + if (tenantCode.size() == 0) { + throw new Exception("当前用户多租户不存在,请联系统管理员检查多租户是否过期或者冻结!"); + } + user.setTenantId(String.join(",", tenantCode)); user.setPermissions(ArrayUtil.toArray(permissions, String.class)); return user; }