From 80b6cbfc9c861469146318d0b3dd5f8b8b525b8a Mon Sep 17 00:00:00 2001 From: xiejun <xiejun@vci-tech.com> Date: 星期五, 01 十一月 2024 15:11:19 +0800 Subject: [PATCH] Revert "集成获取mdm分发通用数据格式接口集成" --- Source/BladeX-Tool/blade-starter-tenant/src/main/java/org/springblade/core/tenant/BladeTenantInterceptor.java | 419 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 419 insertions(+), 0 deletions(-) diff --git a/Source/BladeX-Tool/blade-starter-tenant/src/main/java/org/springblade/core/tenant/BladeTenantInterceptor.java b/Source/BladeX-Tool/blade-starter-tenant/src/main/java/org/springblade/core/tenant/BladeTenantInterceptor.java new file mode 100644 index 0000000..9667309 --- /dev/null +++ b/Source/BladeX-Tool/blade-starter-tenant/src/main/java/org/springblade/core/tenant/BladeTenantInterceptor.java @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: Chill 搴勯獮 (smallchill@163.com) + */ +package org.springblade.core.tenant; + +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 lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import net.sf.jsqlparser.expression.*; +import net.sf.jsqlparser.expression.operators.conditional.AndExpression; +import net.sf.jsqlparser.expression.operators.conditional.OrExpression; +import net.sf.jsqlparser.expression.operators.relational.EqualsTo; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; +import net.sf.jsqlparser.expression.operators.relational.ItemsList; +import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList; +import net.sf.jsqlparser.schema.Column; +import net.sf.jsqlparser.schema.Table; +import net.sf.jsqlparser.statement.delete.Delete; +import net.sf.jsqlparser.statement.insert.Insert; +import net.sf.jsqlparser.statement.select.*; +import net.sf.jsqlparser.statement.update.Update; +import org.springblade.core.secure.utils.AuthUtil; +import org.springblade.core.tool.utils.CollectionUtil; +import org.springblade.core.tool.utils.StringPool; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 绉熸埛鎷︽埅鍣� + * + * @author Chill + */ +@Data +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) +public class BladeTenantInterceptor extends TenantLineInnerInterceptor { + + /** + * 绉熸埛澶勭悊鍣� + */ + private TenantLineHandler tenantLineHandler; + /** + * 绉熸埛閰嶇疆鏂囦欢 + */ + private BladeTenantProperties tenantProperties; + /** + * 瓒呯闇�瑕佸惎鐢ㄧ鎴疯繃婊ょ殑琛� + */ + private List<String> adminTenantTables = Arrays.asList("blade_top_menu", "blade_dict_biz"); + + @Override + public void setTenantLineHandler(TenantLineHandler tenantLineHandler) { + super.setTenantLineHandler(tenantLineHandler); + this.tenantLineHandler = tenantLineHandler; + } + + @Override + protected void processInsert(Insert insert, int index, String sql, Object obj) { + // 鏈惎鐢ㄧ鎴峰寮猴紝鍒欎娇鐢ㄥ師鐗堥�昏緫 + if (!tenantProperties.getEnhance()) { + super.processInsert(insert, index, sql, obj); + return; + } + if (tenantLineHandler.ignoreTable(insert.getTable().getName())) { + // 杩囨护閫�鍑烘墽琛� + return; + } + List<Column> columns = insert.getColumns(); + if (CollectionUtils.isEmpty(columns)) { + // 閽堝涓嶇粰鍒楀悕鐨刬nsert 涓嶅鐞� + return; + } + String tenantIdColumn = tenantLineHandler.getTenantIdColumn(); + if (columns.stream().map(Column::getColumnName).anyMatch(i -> i.equals(tenantIdColumn))) { + // 閽堝宸茬粰鍑虹鎴峰垪鐨刬nsert 涓嶅鐞� + return; + } + columns.add(new Column(tenantIdColumn)); + + // fixed gitee pulls/141 duplicate update + List<Expression> duplicateUpdateColumns = insert.getDuplicateUpdateExpressionList(); + if (CollectionUtils.isNotEmpty(duplicateUpdateColumns)) { + EqualsTo equalsTo = new EqualsTo(); + equalsTo.setLeftExpression(new StringValue(tenantIdColumn)); + equalsTo.setRightExpression(tenantLineHandler.getTenantId()); + duplicateUpdateColumns.add(equalsTo); + } + + Select select = insert.getSelect(); + if (select != null) { + this.processInsertSelect(select.getSelectBody()); + } else if (insert.getItemsList() != null) { + // fixed github pull/295 + ItemsList itemsList = insert.getItemsList(); + if (itemsList instanceof MultiExpressionList) { + ((MultiExpressionList) itemsList).getExpressionLists().forEach(el -> el.getExpressions().add(tenantLineHandler.getTenantId())); + } else { + ((ExpressionList) itemsList).getExpressions().add(tenantLineHandler.getTenantId()); + } + } else { + throw ExceptionUtils.mpe("Failed to process multiple-table update, please exclude the tableName or statementId"); + } + } + + /** + * 澶勭悊 PlainSelect + */ + @Override + protected void processPlainSelect(PlainSelect plainSelect) { + //#3087 github + List<SelectItem> selectItems = plainSelect.getSelectItems(); + if (CollectionUtils.isNotEmpty(selectItems)) { + selectItems.forEach(this::processSelectItem); + } + + // 澶勭悊 where 涓殑瀛愭煡璇� + Expression where = plainSelect.getWhere(); + processWhereSubSelect(where); + + // 澶勭悊 fromItem + FromItem fromItem = plainSelect.getFromItem(); + List<Table> list = processFromItem(fromItem); + List<Table> mainTables = new ArrayList<>(list); + + // 澶勭悊 join + List<Join> joins = plainSelect.getJoins(); + if (CollectionUtils.isNotEmpty(joins)) { + mainTables = processJoins(mainTables, joins); + } + + // 褰撴湁 mainTable 鏃讹紝杩涜 where 鏉′欢杩藉姞 + if (CollectionUtils.isNotEmpty(mainTables) && !doTenantFilters(mainTables)) { + plainSelect.setWhere(builderExpression(where, mainTables)); + } + } + + /** + * update 璇彞澶勭悊 + */ + @Override + protected void processUpdate(Update update, int index, String sql, Object obj) { + final Table table = update.getTable(); + if (tenantLineHandler.ignoreTable(table.getName())) { + // 杩囨护閫�鍑烘墽琛� + return; + } + if (doTenantFilter(table.getName())) { + // 杩囨护閫�鍑烘墽琛� + return; + } + update.setWhere(this.andExpression(table, update.getWhere())); + } + + /** + * delete 璇彞澶勭悊 + */ + @Override + protected void processDelete(Delete delete, int index, String sql, Object obj) { + final Table table = delete.getTable(); + if (tenantLineHandler.ignoreTable(table.getName())) { + // 杩囨护閫�鍑烘墽琛� + return; + } + if (doTenantFilter(table.getName())) { + // 杩囨护閫�鍑烘墽琛� + return; + } + delete.setWhere(this.andExpression(table, delete.getWhere())); + } + + /** + * delete update 璇彞 where 澶勭悊 + */ + @Override + protected BinaryExpression andExpression(Table table, Expression where) { + //鑾峰緱鏉′欢琛ㄨ揪寮� + EqualsTo equalsTo = new EqualsTo(); + Expression leftExpression = this.getAliasColumn(table); + Expression rightExpression = tenantLineHandler.getTenantId(); + // 鑻ユ槸瓒呯鍒欎笉杩涜杩囨护 + if (doTenantFilter(table.getName())) { + leftExpression = rightExpression = new StringValue(StringPool.ONE); + } + equalsTo.setLeftExpression(leftExpression); + equalsTo.setRightExpression(rightExpression); + if (null != where) { + if (where instanceof OrExpression) { + return new AndExpression(equalsTo, new Parenthesis(where)); + } else { + return new AndExpression(equalsTo, where); + } + } + return equalsTo; + } + + /** + * 澧炲己鎻掍欢浣胯秴绾х鐞嗗憳鍙互鐪嬪埌鎵�鏈夌鎴锋暟鎹� + */ + @Override + protected Expression builderExpression(Expression currentExpression, List<Table> tables) { + // 娌℃湁琛ㄩ渶瑕佸鐞嗙洿鎺ヨ繑鍥� + if (CollectionUtils.isEmpty(tables)) { + return currentExpression; + } + // 绉熸埛 + Expression tenantId = tenantLineHandler.getTenantId(); + // 鏋勯�犳瘡寮犺〃鐨勬潯浠� + List<EqualsTo> equalsTos = tables.stream() + // 绉熸埛蹇界暐琛� + .filter(x -> !tenantLineHandler.ignoreTable(x.getName())) + // 瓒呯蹇界暐琛� + .filter(x -> !doTenantFilter(x.getName())) + .map(item -> new EqualsTo(getAliasColumn(item), tenantId)) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(equalsTos)) { + return currentExpression; + } + + // 娉ㄥ叆鐨勮〃杈惧紡 + Expression injectExpression = equalsTos.get(0); + // 濡傛灉鏈夊琛紝鍒欑敤 and 杩炴帴 + if (equalsTos.size() > 1) { + for (int i = 1; i < equalsTos.size(); i++) { + injectExpression = new AndExpression(injectExpression, equalsTos.get(i)); + } + } + + if (currentExpression == null) { + return injectExpression; + } + if (currentExpression instanceof OrExpression) { + return new AndExpression(new Parenthesis(currentExpression), injectExpression); + } else { + return new AndExpression(currentExpression, injectExpression); + } + + } + + private List<Table> processFromItem(FromItem fromItem) { + // 澶勭悊鎷彿鎷捣鏉ョ殑琛ㄨ揪寮� + while (fromItem instanceof ParenthesisFromItem) { + fromItem = ((ParenthesisFromItem) fromItem).getFromItem(); + } + + List<Table> mainTables = new ArrayList<>(); + // 鏃� join 鏃剁殑澶勭悊閫昏緫 + if (fromItem instanceof Table) { + Table fromTable = (Table) fromItem; + mainTables.add(fromTable); + } else if (fromItem instanceof SubJoin) { + // SubJoin 绫诲瀷鍒欒繕闇�瑕佹坊鍔犱笂 where 鏉′欢 + List<Table> tables = processSubJoin((SubJoin) fromItem); + mainTables.addAll(tables); + } else { + // 澶勭悊涓� fromItem + processOtherFromItem(fromItem); + } + return mainTables; + } + + /** + * 澶勭悊 sub join + * + * @param subJoin subJoin + * @return Table subJoin 涓殑涓昏〃 + */ + private List<Table> processSubJoin(SubJoin subJoin) { + List<Table> mainTables = new ArrayList<>(); + if (subJoin.getJoinList() != null) { + List<Table> list = processFromItem(subJoin.getLeft()); + mainTables.addAll(list); + mainTables = processJoins(mainTables, subJoin.getJoinList()); + } + return mainTables; + } + + /** + * 澶勭悊 joins + * + * @param mainTables 鍙互涓� null + * @param joins join 闆嗗悎 + * @return List<Table> 鍙宠繛鎺ユ煡璇㈢殑 Table 鍒楄〃 + */ + private List<Table> processJoins(List<Table> mainTables, List<Join> joins) { + // join 琛ㄨ揪寮忎腑鏈�缁堢殑涓昏〃 + Table mainTable = null; + // 褰撳墠 join 鐨勫乏琛� + Table leftTable = null; + + if (mainTables == null) { + mainTables = new ArrayList<>(); + } else if (mainTables.size() == 1) { + mainTable = mainTables.get(0); + leftTable = mainTable; + } + + //瀵逛簬 on 琛ㄨ揪寮忓啓鍦ㄦ渶鍚庣殑 join锛岄渶瑕佽褰曚笅鍓嶉潰澶氫釜 on 鐨勮〃鍚� + Deque<List<Table>> onTableDeque = new LinkedList<>(); + for (Join join : joins) { + // 澶勭悊 on 琛ㄨ揪寮� + FromItem joinItem = join.getRightItem(); + + // 鑾峰彇褰撳墠 join 鐨勮〃锛宻ubJoint 鍙互鐪嬩綔鏄竴寮犺〃 + List<Table> joinTables = null; + if (joinItem instanceof Table) { + joinTables = new ArrayList<>(); + joinTables.add((Table) joinItem); + } else if (joinItem instanceof SubJoin) { + joinTables = processSubJoin((SubJoin) joinItem); + } + + if (joinTables != null) { + + // 濡傛灉鏄殣寮忓唴杩炴帴 + if (join.isSimple()) { + mainTables.addAll(joinTables); + continue; + } + + // 褰撳墠琛ㄦ槸鍚﹀拷鐣� + Table joinTable = joinTables.get(0); + + List<Table> onTables = null; + // 濡傛灉涓嶈蹇界暐锛屼笖鏄彸杩炴帴锛屽垯璁板綍涓嬪綋鍓嶈〃 + if (join.isRight()) { + mainTable = joinTable; + if (leftTable != null) { + onTables = Collections.singletonList(leftTable); + } + } else if (join.isLeft()) { + onTables = Collections.singletonList(joinTable); + } else if (join.isInner()) { + if (mainTable == null) { + onTables = Collections.singletonList(joinTable); + } else { + onTables = Arrays.asList(mainTable, joinTable); + } + mainTable = null; + } + + mainTables = new ArrayList<>(); + if (mainTable != null) { + mainTables.add(mainTable); + } + + // 鑾峰彇 join 灏剧紑鐨� on 琛ㄨ揪寮忓垪琛� + Collection<Expression> originOnExpressions = join.getOnExpressions(); + // 姝e父 join on 琛ㄨ揪寮忓彧鏈変竴涓紝绔嬪埢澶勭悊 + if (originOnExpressions.size() == 1 && onTables != null) { + List<Expression> onExpressions = new LinkedList<>(); + onExpressions.add(builderExpression(originOnExpressions.iterator().next(), onTables)); + join.setOnExpressions(onExpressions); + leftTable = joinTable; + continue; + } + // 琛ㄥ悕鍘嬫爤锛屽拷鐣ョ殑琛ㄥ帇鍏� null锛屼互渚垮悗缁笉澶勭悊 + onTableDeque.push(onTables); + // 灏剧紑澶氫釜 on 琛ㄨ揪寮忕殑鏃跺�欑粺涓�澶勭悊 + if (originOnExpressions.size() > 1) { + Collection<Expression> onExpressions = new LinkedList<>(); + for (Expression originOnExpression : originOnExpressions) { + List<Table> currentTableList = onTableDeque.poll(); + if (CollectionUtils.isEmpty(currentTableList)) { + onExpressions.add(originOnExpression); + } else { + onExpressions.add(builderExpression(originOnExpression, currentTableList)); + } + } + join.setOnExpressions(onExpressions); + } + leftTable = joinTable; + } else { + processOtherFromItem(joinItem); + leftTable = null; + } + } + + return mainTables; + } + + /** + * 鍒ゆ柇褰撳墠鎿嶄綔鏄惁闇�瑕佽繘琛岃繃婊� + * + * @param tableName 琛ㄥ悕 + */ + public boolean doTenantFilter(String tableName) { + return AuthUtil.isAdministrator() && !adminTenantTables.contains(tableName); + } + + /** + * 鍒ゆ柇褰撳墠鎿嶄綔鏄惁闇�瑕佽繘琛岃繃婊� + * + * @param tables 琛ㄥ悕 + */ + public boolean doTenantFilters(List<Table> tables) { + List<String> tableNames = tables.stream().map(Table::getName).collect(Collectors.toList()); + return AuthUtil.isAdministrator() && !CollectionUtil.containsAny(adminTenantTables, tableNames); + } + +} -- Gitblit v1.9.3