| | |
| | | package org.dromara.common.tenant.helper; |
| | | |
| | | import cn.dev33.satoken.context.SaHolder; |
| | | import cn.dev33.satoken.spring.SpringMVCUtil; |
| | | import cn.dev33.satoken.stp.StpUtil; |
| | | import cn.hutool.core.convert.Convert; |
| | | import com.alibaba.ttl.TransmittableThreadLocal; |
| | | import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy; |
| | | import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | 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.redis.utils.RedisUtils; |
| | | import org.dromara.common.satoken.utils.LoginHelper; |
| | | import lombok.AccessLevel; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.util.function.Supplier; |
| | | |
| | | /** |
| | | * 租户助手 |
| | |
| | | |
| | | private static final String DYNAMIC_TENANT_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "dynamicTenant"; |
| | | |
| | | private static final ThreadLocal<String> TEMP_DYNAMIC_TENANT = new TransmittableThreadLocal<>(); |
| | | private static final ThreadLocal<String> TEMP_DYNAMIC_TENANT = new ThreadLocal<>(); |
| | | |
| | | /** |
| | | * 租户功能是否启用 |
| | |
| | | } |
| | | |
| | | /** |
| | | * 在忽略租户中执行 |
| | | * |
| | | * @param handle 处理执行方法 |
| | | */ |
| | | public static void ignore(Runnable handle) { |
| | | enableIgnore(); |
| | | try { |
| | | handle.run(); |
| | | } finally { |
| | | disableIgnore(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 在忽略租户中执行 |
| | | * |
| | | * @param handle 处理执行方法 |
| | | */ |
| | | public static <T> T ignore(Supplier<T> handle) { |
| | | enableIgnore(); |
| | | try { |
| | | return handle.get(); |
| | | } finally { |
| | | disableIgnore(); |
| | | } |
| | | } |
| | | |
| | | public static void setDynamic(String tenantId) { |
| | | setDynamic(tenantId, false); |
| | | } |
| | | |
| | | /** |
| | | * 设置动态租户(一直有效 需要手动清理) |
| | | * <p> |
| | | * 如果为非web环境 那么只在当前线程内生效 |
| | | * 如果为未登录状态下 那么只在当前线程内生效 |
| | | * |
| | | * @param tenantId 租户id |
| | | * @param global 是否全局生效 |
| | | */ |
| | | public static void setDynamic(String tenantId) { |
| | | if (!SpringMVCUtil.isWeb()) { |
| | | public static void setDynamic(String tenantId, boolean global) { |
| | | if (!isEnable()) { |
| | | return; |
| | | } |
| | | if (!isLogin() || !global) { |
| | | TEMP_DYNAMIC_TENANT.set(tenantId); |
| | | return; |
| | | } |
| | | String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId(); |
| | | RedisUtils.setCacheObject(cacheKey, tenantId); |
| | | SaHolder.getStorage().set(cacheKey, tenantId); |
| | | } |
| | | |
| | | /** |
| | | * 获取动态租户(一直有效 需要手动清理) |
| | | * <p> |
| | | * 如果为非web环境 那么只在当前线程内生效 |
| | | * 如果为未登录状态下 那么只在当前线程内生效 |
| | | */ |
| | | public static String getDynamic() { |
| | | if (!SpringMVCUtil.isWeb()) { |
| | | if (!isEnable()) { |
| | | return null; |
| | | } |
| | | if (!isLogin()) { |
| | | return TEMP_DYNAMIC_TENANT.get(); |
| | | } |
| | | String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId(); |
| | | String tenantId = (String) SaHolder.getStorage().get(cacheKey); |
| | | // 如果线程内有值 优先返回 |
| | | String tenantId = TEMP_DYNAMIC_TENANT.get(); |
| | | if (StringUtils.isNotBlank(tenantId)) { |
| | | return tenantId; |
| | | } |
| | | String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId(); |
| | | tenantId = RedisUtils.getCacheObject(cacheKey); |
| | | SaHolder.getStorage().set(cacheKey, tenantId); |
| | | return tenantId; |
| | | } |
| | | |
| | |
| | | * 清除动态租户 |
| | | */ |
| | | public static void clearDynamic() { |
| | | if (!SpringMVCUtil.isWeb()) { |
| | | if (!isEnable()) { |
| | | return; |
| | | } |
| | | if (!isLogin()) { |
| | | TEMP_DYNAMIC_TENANT.remove(); |
| | | return; |
| | | } |
| | | TEMP_DYNAMIC_TENANT.remove(); |
| | | String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId(); |
| | | RedisUtils.deleteObject(cacheKey); |
| | | SaHolder.getStorage().delete(cacheKey); |
| | | } |
| | | |
| | | /** |
| | | * 在动态租户中执行 |
| | | * |
| | | * @param handle 处理执行方法 |
| | | */ |
| | | public static void dynamic(String tenantId, Runnable handle) { |
| | | setDynamic(tenantId); |
| | | try { |
| | | handle.run(); |
| | | } finally { |
| | | clearDynamic(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 在动态租户中执行 |
| | | * |
| | | * @param handle 处理执行方法 |
| | | */ |
| | | public static <T> T dynamic(String tenantId, Supplier<T> handle) { |
| | | setDynamic(tenantId); |
| | | try { |
| | | return handle.get(); |
| | | } finally { |
| | | clearDynamic(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取当前租户id(动态租户优先) |
| | | */ |
| | | public static String getTenantId() { |
| | | if (!isEnable()) { |
| | | return null; |
| | | } |
| | | String tenantId = TenantHelper.getDynamic(); |
| | | if (StringUtils.isBlank(tenantId)) { |
| | | tenantId = LoginHelper.getTenantId(); |
| | |
| | | return tenantId; |
| | | } |
| | | |
| | | private static boolean isLogin() { |
| | | try { |
| | | StpUtil.checkLogin(); |
| | | return true; |
| | | } catch (Exception e) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | } |