diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java index 2afe9ee47..8f67a937e 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java @@ -2,14 +2,15 @@ package org.dromara.common.mybatis.helper; import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.context.model.SaStorage; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy; import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.dromara.common.core.utils.reflect.ReflectUtils; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.function.Supplier; /** @@ -24,6 +25,23 @@ public class DataPermissionHelper { private static final String DATA_PERMISSION_KEY = "data:permission"; + private static final ThreadLocal> REENTRANT_IGNORE_PERMISSION = new ThreadLocal<>(); + + private static Stack getReentrantIgnorePermissionStack() { + return Optional.ofNullable(REENTRANT_IGNORE_PERMISSION.get()).orElseGet(() -> { + REENTRANT_IGNORE_PERMISSION.set(new Stack<>()); + return REENTRANT_IGNORE_PERMISSION.get(); + }); + } + + private static void clearReentrantIgnore() { + REENTRANT_IGNORE_PERMISSION.remove(); + } + + private static void reentrantIgnoreIncrement() { + Stack reentrantStack = getReentrantIgnorePermissionStack(); + reentrantStack.push(reentrantStack.size() + 1); + } /** * 从上下文中获取指定键的变量值,并将其转换为指定的类型 * @@ -70,14 +88,41 @@ public class DataPermissionHelper { * 开启忽略数据权限(开启后需手动调用 {@link #disableIgnore()} 关闭) */ public static void enableIgnore() { - InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().dataPermission(true).build()); + ThreadLocal IGNORE_STRATEGY_LOCAL = (ThreadLocal) ReflectUtils.getStaticFieldValue(ReflectUtils.getField(InterceptorIgnoreHelper.class, "IGNORE_STRATEGY_LOCAL")); + IgnoreStrategy ignoreStrategy = IGNORE_STRATEGY_LOCAL.get(); + if (ignoreStrategy == null) { + InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().dataPermission(true).build()); + } else { + if (!Boolean.TRUE.equals(ignoreStrategy.getDataPermission())) { + ignoreStrategy.setDataPermission(true); + } + } + reentrantIgnoreIncrement(); } /** * 关闭忽略数据权限 */ public static void disableIgnore() { - InterceptorIgnoreHelper.clearIgnoreStrategy(); + ThreadLocal IGNORE_STRATEGY_LOCAL = (ThreadLocal) ReflectUtils.getStaticFieldValue(ReflectUtils.getField(InterceptorIgnoreHelper.class, "IGNORE_STRATEGY_LOCAL")); + IgnoreStrategy ignoreStrategy = IGNORE_STRATEGY_LOCAL.get(); + if (ignoreStrategy != null) { + boolean noOtherIgnoreStrategy = !Boolean.TRUE.equals(ignoreStrategy.getTenantLine()) + && !Boolean.TRUE.equals(ignoreStrategy.getDynamicTableName()) + && !Boolean.TRUE.equals(ignoreStrategy.getBlockAttack()) + && !Boolean.TRUE.equals(ignoreStrategy.getIllegalSql()) + && CollectionUtil.isEmpty(ignoreStrategy.getOthers()); + Stack reentrantStack = getReentrantIgnorePermissionStack(); + boolean empty = reentrantStack.isEmpty() || reentrantStack.pop() == 1; + if (noOtherIgnoreStrategy && empty) { + InterceptorIgnoreHelper.clearIgnoreStrategy(); + } else if (empty) { + if (Boolean.TRUE.equals(ignoreStrategy.getDataPermission())) { + ignoreStrategy.setDataPermission(false); + clearReentrantIgnore(); + } + } + } } /** diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java index 6d12b6f49..af86fc77c 100644 --- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java @@ -1,6 +1,7 @@ package org.dromara.common.tenant.helper; import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy; import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; @@ -10,9 +11,12 @@ import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.GlobalConstants; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.core.utils.reflect.ReflectUtils; import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.satoken.utils.LoginHelper; +import java.util.Optional; +import java.util.Stack; import java.util.function.Supplier; /** @@ -28,6 +32,24 @@ public class TenantHelper { private static final ThreadLocal TEMP_DYNAMIC_TENANT = new ThreadLocal<>(); + + private static final ThreadLocal> REENTRANT_IGNORE_TENANT = new ThreadLocal<>(); + + private static Stack getReentrantIgnoreTenantStack() { + return Optional.ofNullable(REENTRANT_IGNORE_TENANT.get()).orElseGet(() -> { + REENTRANT_IGNORE_TENANT.set(new Stack<>()); + return REENTRANT_IGNORE_TENANT.get(); + }); + } + + private static void clearReentrantIgnore() { + REENTRANT_IGNORE_TENANT.remove(); + } + + private static void reentrantIgnoreIncrement() { + Stack reentrantStack = getReentrantIgnoreTenantStack(); + reentrantStack.push(reentrantStack.size() + 1); + } /** * 租户功能是否启用 */ @@ -39,14 +61,40 @@ public class TenantHelper { * 开启忽略租户(开启后需手动调用 {@link #disableIgnore()} 关闭) */ public static void enableIgnore() { - InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build()); + ThreadLocal IGNORE_STRATEGY_LOCAL = (ThreadLocal) ReflectUtils.getStaticFieldValue(ReflectUtils.getField(InterceptorIgnoreHelper.class, "IGNORE_STRATEGY_LOCAL")); + IgnoreStrategy ignoreStrategy = IGNORE_STRATEGY_LOCAL.get(); + if (ignoreStrategy == null) { + InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build()); + } else { + if (!Boolean.TRUE.equals(ignoreStrategy.getTenantLine())) { + ignoreStrategy.setTenantLine(true); + } + } + reentrantIgnoreIncrement(); } /** * 关闭忽略租户 */ public static void disableIgnore() { - InterceptorIgnoreHelper.clearIgnoreStrategy(); + ThreadLocal IGNORE_STRATEGY_LOCAL = (ThreadLocal) ReflectUtils.getStaticFieldValue(ReflectUtils.getField(InterceptorIgnoreHelper.class, "IGNORE_STRATEGY_LOCAL")); + IgnoreStrategy ignoreStrategy = IGNORE_STRATEGY_LOCAL.get(); + if (ignoreStrategy != null) { + boolean noOtherIgnoreStrategy = !Boolean.TRUE.equals(ignoreStrategy.getDynamicTableName()) + && !Boolean.TRUE.equals(ignoreStrategy.getBlockAttack()) + && !Boolean.TRUE.equals(ignoreStrategy.getIllegalSql()) + && !Boolean.TRUE.equals(ignoreStrategy.getDataPermission()) + && CollectionUtil.isEmpty(ignoreStrategy.getOthers()); + Stack reentrantStack = getReentrantIgnoreTenantStack(); + boolean empty = reentrantStack.isEmpty() || reentrantStack.pop() == 1; + if (noOtherIgnoreStrategy && empty) { + InterceptorIgnoreHelper.clearIgnoreStrategy(); + clearReentrantIgnore(); + } else if (empty) { + ignoreStrategy.setDataPermission(false); + clearReentrantIgnore(); + } + } } /**