From 9b4433fddf5b401edb0aace8a404ac733b122702 Mon Sep 17 00:00:00 2001
From: 田源 <tianyuan@vci-tech.com>
Date: 星期四, 03 四月 2025 14:35:02 +0800
Subject: [PATCH] 添加非密字段显示
---
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