代码整理

This commit is contained in:
Github_lizhw 2026-04-03 23:00:27 +08:00
parent 0bd6440608
commit aadb561575
48 changed files with 235 additions and 496 deletions

View File

@ -5,7 +5,7 @@ import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.redis.handler.KeyPrefixHandler;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.satoken.utils.LoginHelper;
/**
* 多租户redis缓存key前缀处理
@ -33,7 +33,7 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
return super.map(name);
}
String tenantId = TenantHelper.getTenantId();
String tenantId = LoginHelper.getTenantId();
if (StringUtils.isBlank(tenantId)) {
log.error("无法获取有效的租户id -> Null");
}
@ -59,7 +59,7 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
return super.unmap(name);
}
String tenantId = TenantHelper.getTenantId();
String tenantId = LoginHelper.getTenantId();
if (StringUtils.isBlank(tenantId)) {
log.error("无法获取有效的租户id -> Null");
}

View File

@ -1,67 +0,0 @@
package org.dromara.common.tenant.helper;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.dromara.common.core.constant.TenantConstants;
import org.dromara.common.core.constant.UserConstants;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.enums.UserType;
import java.util.Set;
/**
* 登录鉴权助手
* <p>
* user_type 用户类型 同一个用户表 可以有多种用户类型 例如 pc,app
* deivce 设备类型 同一个用户类型 可以有 多种设备类型 例如 web,ios
* 可以组成 用户类型与设备类型多对多的 权限灵活控制
* <p>
* 多用户体系 针对 多种用户类型 但权限控制不一致
* 可以组成 多用户类型表与多设备类型 分别控制权限
*
* @author Lion Li
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class LoginHelper {
public static final String TENANT_KEY = "tenantId";
public static final String USER_KEY = "userId";
public static final String CLIENT_KEY = "clientid";
/**
* 获取用户id
*/
public static Long getUserId() {
return Convert.toLong(getExtra(USER_KEY));
}
/**
* 获取租户ID
*/
public static String getTenantId() {
return Convert.toStr(getExtra(TENANT_KEY));
}
/**
* 获取当前 Token 的扩展信息
*
* @param key 键值
* @return 对应的扩展数据
*/
private static Object getExtra(String key) {
try {
return StpUtil.getExtra(key);
} catch (Exception e) {
return null;
}
}
}

View File

@ -1,19 +1,13 @@
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 cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
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.core.utils.reflect.ReflectUtils;
import org.dromara.common.redis.utils.RedisUtils;
import java.util.Stack;
import java.util.function.Supplier;
@ -26,67 +20,42 @@ import java.util.function.Supplier;
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class TenantHelper {
private static final String DYNAMIC_TENANT_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "dynamicTenant";
private static final ThreadLocal<String> TEMP_DYNAMIC_TENANT = new ThreadLocal<>();
private static final ThreadLocal<Stack<Integer>> REENTRANT_IGNORE = ThreadLocal.withInitial(Stack::new);
/**
* 租户功能是否启用
*/
public static boolean isEnable() {
return Convert.toBool(SpringUtils.getProperty("tenant.enable"), false);
}
private static IgnoreStrategy getIgnoreStrategy() {
Object ignoreStrategyLocal = ReflectUtils.getStaticFieldValue(ReflectUtils.getField(InterceptorIgnoreHelper.class, "IGNORE_STRATEGY_LOCAL"));
if (ignoreStrategyLocal instanceof ThreadLocal<?> IGNORE_STRATEGY_LOCAL) {
if (IGNORE_STRATEGY_LOCAL.get() instanceof IgnoreStrategy ignoreStrategy) {
return ignoreStrategy;
}
}
return null;
}
/**
* 开启忽略租户(开启后需手动调用 {@link #disableIgnore()} 关闭)
*/
public static void enableIgnore() {
IgnoreStrategy ignoreStrategy = getIgnoreStrategy();
if (ObjectUtil.isNull(ignoreStrategy)) {
InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build());
} else {
ignoreStrategy.setTenantLine(true);
}
private static void enableIgnore() {
Stack<Integer> reentrantStack = REENTRANT_IGNORE.get();
if (reentrantStack.isEmpty()) {
// 只有当栈为空时才真正开启忽略
InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build());
}
reentrantStack.push(reentrantStack.size() + 1);
}
/**
* 关闭忽略租户
*/
public static void disableIgnore() {
IgnoreStrategy ignoreStrategy = getIgnoreStrategy();
if (ObjectUtil.isNotNull(ignoreStrategy)) {
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<Integer> reentrantStack = REENTRANT_IGNORE.get();
boolean empty = reentrantStack.isEmpty() || reentrantStack.pop() == 1;
if (noOtherIgnoreStrategy && empty) {
private static void disableIgnore() {
Stack<Integer> reentrantStack = REENTRANT_IGNORE.get();
if (!reentrantStack.isEmpty()) {
reentrantStack.pop(); // 出栈操作
if (reentrantStack.isEmpty()) {
// 当栈为空时才真正关闭忽略
InterceptorIgnoreHelper.clearIgnoreStrategy();
} else if (empty) {
ignoreStrategy.setTenantLine(false);
} else {
log.info("重入忽略租户");
}
} else {
log.error("关闭忽略租户失败,当前方法栈: {}", Thread.getAllStackTraces());
}
}
/**
* 在忽略租户中执行
* 在忽略租户中执行可重入
*
* @param handle 处理执行方法
*/
@ -100,7 +69,7 @@ public class TenantHelper {
}
/**
* 在忽略租户中执行
* 在忽略租户中执行可重入
*
* @param handle 处理执行方法
*/
@ -113,8 +82,11 @@ public class TenantHelper {
}
}
public static void setDynamic(String tenantId) {
setDynamic(tenantId, false);
/**
* 租户功能是否启用
*/
public static boolean isEnable() {
return Convert.toBool(SpringUtils.getProperty("tenant.enable"), false);
}
/**
@ -123,18 +95,12 @@ public class TenantHelper {
* 如果为未登录状态下 那么只在当前线程内生效
*
* @param tenantId 租户id
* @param global 是否全局生效
*/
public static void setDynamic(String tenantId, boolean global) {
private static void setDynamic(String tenantId) {
if (!isEnable()) {
return;
}
if (!isLogin() || !global) {
TEMP_DYNAMIC_TENANT.set(tenantId);
return;
}
String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
RedisUtils.setCacheObject(cacheKey, tenantId);
TEMP_DYNAMIC_TENANT.set(tenantId);
}
/**
@ -142,41 +108,25 @@ public class TenantHelper {
* <p>
* 如果为未登录状态下 那么只在当前线程内生效
*/
public static String getDynamic() {
private static String getDynamic() {
if (!isEnable()) {
return null;
}
if (!isLogin()) {
return TEMP_DYNAMIC_TENANT.get();
}
// 如果线程内有值 优先返回
String tenantId = TEMP_DYNAMIC_TENANT.get();
if (StringUtils.isNotBlank(tenantId)) {
return tenantId;
}
String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
tenantId = RedisUtils.getCacheObject(cacheKey);
return tenantId;
return TEMP_DYNAMIC_TENANT.get();
}
/**
* 清除动态租户
*/
public static void clearDynamic() {
private static void clearDynamic() {
if (!isEnable()) {
return;
}
if (!isLogin()) {
TEMP_DYNAMIC_TENANT.remove();
return;
}
TEMP_DYNAMIC_TENANT.remove();
String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
RedisUtils.deleteObject(cacheKey);
}
/**
* 在动态租户中执行
* 在动态租户中执行不支持嵌套使用
*
* @param handle 处理执行方法
*/
@ -190,7 +140,7 @@ public class TenantHelper {
}
/**
* 在动态租户中执行
* 在动态租户中执行,不支持嵌套使用推荐在controller中使用
*
* @param handle 处理执行方法
*/
@ -204,26 +154,31 @@ public class TenantHelper {
}
/**
* 获取当前租户id(动态租户优先)
* 获取id写到satoken里面
* @return
*/
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;
public static Long getDynamicTenantId(Long loginTenantId) {
String dynamic = getDynamic();
if (StrUtil.isBlank(dynamic)) {
log.info("获取 token 租户id: {}", loginTenantId);
return loginTenantId;
} else {
log.info("获取 dynamic 租户id: {}", dynamic);
return Long.parseLong(dynamic);
}
}
/**
* 获取id写到satoken里面
* @return
*/
public static String getDynamicTenantId(String loginTenantId) {
String dynamic = getDynamic();
if (StrUtil.isBlank(dynamic)) {
log.info("获取 token 租户id: {}", loginTenantId);
return loginTenantId;
} else {
log.info("获取 dynamic 租户id: {}", dynamic);
return dynamic;
}
}
}

View File

@ -5,7 +5,7 @@ import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.redis.manager.PlusSpringCacheManager;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.satoken.utils.LoginHelper;
import org.springframework.cache.Cache;
/**
@ -27,7 +27,7 @@ public class TenantSpringCacheManager extends PlusSpringCacheManager {
if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
return super.getCache(name);
}
String tenantId = TenantHelper.getTenantId();
String tenantId = LoginHelper.getTenantId();
if (StringUtils.isBlank(tenantId)) {
log.error("无法获取有效的租户id -> Null");
}

View File

@ -48,6 +48,10 @@
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-tenant</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-satoken</artifactId>
</dependency>
<!-- Apache POI 核心库 -->
<dependency>
<groupId>org.apache.poi</groupId>

View File

@ -1,5 +1,7 @@
package org.dromara.md.form.controller;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.md.form.api.constant.BaseConstant;
import org.dromara.md.form.mybatis.entity.Form;
import org.dromara.md.form.mybatis.entity.FormTemplate;
@ -8,11 +10,9 @@ import org.dromara.md.form.service.FormService;
import org.dromara.md.form.service.FormTemplateFieldService;
import org.dromara.md.form.service.FormTemplateService;
import org.dromara.md.form.service.TenantInitializationService;
import org.dromara.md.form.utils.TenantHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.tenant.helper.LoginHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

View File

@ -1,6 +1,7 @@
package org.dromara.md.form.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.md.form.api.constant.BaseConstant;
import org.dromara.md.form.api.dto.FormDictDTO;
import org.dromara.md.form.api.dto.FormDictImportDTO;
@ -12,7 +13,6 @@ import org.dromara.md.form.service.TenantInitializationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.tenant.helper.LoginHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

View File

@ -9,7 +9,7 @@ import org.dromara.md.form.api.vo.FormFieldDictVO;
import org.dromara.md.form.mybatis.entity.FormFieldDict;
import org.dromara.md.form.service.FormDictService;
import org.dromara.md.form.service.FormFieldDictService;
import org.dromara.md.form.utils.TenantHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;

View File

@ -5,7 +5,7 @@ import org.dromara.md.form.api.constant.BaseConstant;
import org.dromara.md.form.api.dto.FormDictDTO;
import org.dromara.md.form.mybatis.entity.FormDict;
import org.dromara.md.form.service.FormDictService;
import org.dromara.md.form.utils.TenantHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;

View File

@ -8,7 +8,7 @@ import org.dromara.md.form.api.vo.FormFieldDictDifyVo;
import org.dromara.md.form.api.vo.FormFieldDictVO;
import org.dromara.md.form.mybatis.entity.FormFieldDict;
import org.dromara.md.form.service.FormFieldDictService;
import org.dromara.md.form.utils.TenantHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;

View File

@ -8,7 +8,7 @@ import org.dromara.md.form.api.vo.FormFieldDictVO;
import org.dromara.md.form.feign.FormFieldDictFeignClient;
import org.dromara.md.form.service.FormDictService;
import org.dromara.md.form.service.FormFieldDictService;
import org.dromara.md.form.utils.TenantHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import jodd.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;

View File

@ -4,7 +4,7 @@ import org.dromara.md.form.api.constant.BaseConstant;
import org.dromara.md.form.api.vo.FormPrintConfigVO;
import org.dromara.md.form.feign.FormPrintConfigFeignClient;
import org.dromara.md.form.service.FormPrintConfigService;
import org.dromara.md.form.utils.TenantHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

View File

@ -3,7 +3,7 @@ package org.dromara.md.form.controller.feign;
import org.dromara.md.form.api.constant.BaseConstant;
import org.dromara.md.form.api.vo.FormTemplateVO;
import org.dromara.md.form.feign.FormTemplateFeignClient;
import org.dromara.md.form.utils.TenantHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.md.form.service.FormTemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;

View File

@ -4,7 +4,7 @@ import org.dromara.md.form.api.constant.BaseConstant;
import org.dromara.md.form.api.dto.ModifyLogRecordDTO;
import org.dromara.md.form.feign.ModifyLogRecordFeignClient;
import org.dromara.md.form.service.ModifyLogRecordService;
import org.dromara.md.form.utils.TenantHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

View File

@ -5,7 +5,7 @@ import org.dromara.md.form.api.dto.FormFieldDictQ;
import org.dromara.md.form.api.vo.FormFieldDictVO;
import org.dromara.md.form.feign.SystemDictFeignClient;
import org.dromara.md.form.service.FormFieldDictService;
import org.dromara.md.form.utils.TenantHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.md.form.api.dto.FormDictDTO;
import org.dromara.md.form.api.dto.FormDictImportDTO;
import org.dromara.md.form.api.dto.FormFieldDictImportDTO;
@ -16,7 +17,6 @@ import org.dromara.md.form.mybatis.entity.FormDict;
import org.dromara.md.form.mybatis.mapper.FormDictMapper;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.tenant.helper.LoginHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

View File

@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.md.form.api.constant.FormFieldDictType;
import org.dromara.md.form.api.dto.DictCodesDTO;
import org.dromara.md.form.api.dto.FormFieldDictDTO;
@ -19,7 +20,6 @@ import org.dromara.md.form.mybatis.mapper.FormFieldDictMapper;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.tenant.helper.LoginHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

View File

@ -3,6 +3,7 @@ package org.dromara.md.form.service;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.md.form.api.dto.FormPrintConfigDTO;
import org.dromara.md.form.api.dto.FormPrintConfigModeDTO;
import org.dromara.md.form.api.dto.FormPrintConfigUploadDTO;
@ -17,7 +18,6 @@ import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.oss.core.OssClient;
import org.dromara.common.oss.entity.UploadResult;
import org.dromara.common.oss.factory.OssFactory;
import org.dromara.common.tenant.helper.LoginHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

View File

@ -5,13 +5,13 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.md.form.api.constant.FormTemplateFieldType;
import org.dromara.md.form.api.dto.FormTemplateDTO;
import org.dromara.md.form.mybatis.entity.FormTemplateField;
import org.dromara.md.form.mybatis.mapper.FormTemplateFieldMapper;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.tenant.helper.LoginHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

View File

@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.EncryptUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.md.form.api.dto.FormTemplateDTO;
import org.dromara.md.form.api.vo.FormTemplateVO;
import org.dromara.md.form.mybatis.entity.Form;
@ -15,7 +16,6 @@ import org.dromara.md.form.mybatis.mapper.FormTemplateMapper;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.tenant.helper.LoginHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

View File

@ -6,7 +6,7 @@ import org.dromara.md.form.mybatis.entity.Form;
import org.dromara.md.form.mybatis.entity.FormDict;
import org.dromara.md.form.mybatis.entity.FormTemplate;
import org.dromara.md.form.mybatis.entity.FormTemplateField;
import org.dromara.md.form.utils.TenantHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.redis.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;

View File

@ -1,165 +0,0 @@
package org.dromara.md.form.utils;
import cn.hutool.core.util.StrUtil;
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.tenant.helper.LoginHelper;
import java.util.Stack;
import java.util.function.Supplier;
/**
* 租户助手
*
*/
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class TenantHelper {
private static final ThreadLocal<String> TEMP_DYNAMIC_TENANT = new ThreadLocal<>();
private static final ThreadLocal<Stack<Integer>> REENTRANT_IGNORE = ThreadLocal.withInitial(Stack::new);
/**
* 开启忽略租户(开启后需手动调用 {@link #disableIgnore()} 关闭)
*/
private static void enableIgnore() {
Stack<Integer> reentrantStack = REENTRANT_IGNORE.get();
if (reentrantStack.isEmpty()) {
// 只有当栈为空时才真正开启忽略
InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build());
}
reentrantStack.push(reentrantStack.size() + 1);
}
/**
* 关闭忽略租户
*/
private static void disableIgnore() {
Stack<Integer> reentrantStack = REENTRANT_IGNORE.get();
if (!reentrantStack.isEmpty()) {
reentrantStack.pop(); // 出栈操作
if (reentrantStack.isEmpty()) {
// 当栈为空时才真正关闭忽略
InterceptorIgnoreHelper.clearIgnoreStrategy();
} else {
log.info("重入忽略租户");
}
} else {
log.error("关闭忽略租户失败,当前方法栈: {}", Thread.getAllStackTraces());
}
}
/**
* 在忽略租户中执行可重入
*
* @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 boolean isEnable() {
//TODO 是否开启未开发
return true;
}
/**
* 设置动态租户(一直有效 需要手动清理)
* <p>
* 如果为未登录状态下 那么只在当前线程内生效
*
* @param tenantId 租户id
*/
private static void setDynamic(String tenantId) {
if (!isEnable()) {
return;
}
TEMP_DYNAMIC_TENANT.set(tenantId);
}
/**
* 获取动态租户(一直有效 需要手动清理)
* <p>
* 如果为未登录状态下 那么只在当前线程内生效
*/
private static String getDynamic() {
if (!isEnable()) {
return null;
}
return TEMP_DYNAMIC_TENANT.get();
}
/**
* 清除动态租户
*/
private static void clearDynamic() {
if (!isEnable()) {
return;
}
TEMP_DYNAMIC_TENANT.remove();
}
/**
* 在动态租户中执行不支持嵌套使用
*
* @param handle 处理执行方法
*/
public static void dynamic(String tenantId, Runnable handle) {
setDynamic(tenantId);
try {
handle.run();
} finally {
clearDynamic();
}
}
/**
* 在动态租户中执行,不支持嵌套使用推荐在controller中使用
*
* @param handle 处理执行方法
*/
public static <T> T dynamic(String tenantId, Supplier<T> handle) {
setDynamic(tenantId);
try {
return handle.get();
} finally {
clearDynamic();
}
}
public static Long getTenantId() {
String dynamic = getDynamic();
if (StrUtil.isBlank(dynamic)) {
Long tenantId = Long.valueOf(LoginHelper.getTenantId());
log.info("获取 token 租户id: {}", tenantId);
return tenantId;
} else {
log.info("获取 dynamic 租户id: {}", dynamic);
return Long.parseLong(dynamic);
}
}
}

View File

@ -3,7 +3,7 @@ package org.dromara.md.h5.controller;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.dromara.md.form.api.constant.BaseConstant;
import org.dromara.md.form.utils.TenantHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.md.h5.api.constant.ProjectStatus;
import org.dromara.md.h5.api.dto.H5ProjectContentDTO;
import org.dromara.md.h5.api.dto.query.H5ProjectQueryDTO;

View File

@ -2,8 +2,9 @@ package org.dromara.md.h5.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.md.form.api.constant.BaseConstant;
import org.dromara.md.form.utils.TenantHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.md.h5.api.constant.ProjectStatus;
import org.dromara.md.h5.api.dto.H5ProjectContentDTO;
import org.dromara.md.h5.api.dto.query.H5ProjectQueryDTO;
@ -13,7 +14,6 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.tenant.helper.LoginHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

View File

@ -146,19 +146,19 @@ public class SysSaasTenantController extends BaseController {
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@GetMapping("/dynamic/{tenantId}")
public R<Void> dynamicTenant(@NotBlank(message = "租户ID不能为空") @PathVariable String tenantId) {
TenantHelper.setDynamic(tenantId, true);
// TenantHelper.setDynamic(tenantId, true);
return R.ok();
}
/**
* 清除动态租户
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@GetMapping("/dynamic/clear")
public R<Void> dynamicClear() {
TenantHelper.clearDynamic();
return R.ok();
}
// /**
// * 清除动态租户
// */
// @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
// @GetMapping("/dynamic/clear")
// public R<Void> dynamicClear() {
// TenantHelper.clearDynamic();
// return R.ok();
// }
/**

View File

@ -106,11 +106,16 @@ public class SysSaasUserController extends BaseController {
public R<TwoUserInfoVo> getInfo() {
TwoUserInfoVo twoUserInfoVo = new TwoUserInfoVo();
LoginUser loginUser = LoginHelper.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
return R.fail("登录用户不存在!");
}
SysSaasUserVo user;
if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
// 超级管理员 如果重新加载用户信息需清除动态租户
TenantHelper.clearDynamic();
user = TenantHelper.ignore(() -> userService.selectUserById(loginUser.getUserId()));
} else {
user = userService.selectUserById(loginUser.getUserId());
}
SysSaasUserVo user = userService.selectUserById(loginUser.getUserId());
if (ObjectUtil.isNull(user)) {
return R.fail("没有权限访问用户数据!");
}
@ -165,7 +170,7 @@ public class SysSaasUserController extends BaseController {
return R.fail("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
if (TenantHelper.isEnable()) {
if (!tenantService.checkAccountBalance(TenantHelper.getTenantId())) {
if (!tenantService.checkAccountBalance(LoginHelper.getTenantId())) {
return R.fail("当前租户下用户名额不足,请联系管理员");
}
}

View File

@ -7,13 +7,13 @@ import java.io.Serial;
import java.io.Serializable;
/**
* 租户和应用关联对象 sys2_tenant_application
* 租户和应用关联对象 sys_saas_tenant_application
*
* @author Lion Li
* @date 2024-09-22
*/
@Data
@TableName("sys2_tenant_application")
@TableName("sys_saas_tenant_application")
public class SysSaasTenantApplication implements Serializable {
@Serial

View File

@ -9,7 +9,7 @@ import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
/**
* 租户和应用关联业务对象 sys2_tenant_application
* 租户和应用关联业务对象 sys_saas_tenant_application
*
* @author Lion Li
* @date 2024-09-22

View File

@ -11,7 +11,7 @@ import java.io.Serializable;
/**
* 租户和应用关联视图对象 sys2_tenant_application
* 租户和应用关联视图对象 sys_saas_tenant_application
*
* @author Lion Li
* @date 2024-09-22

View File

@ -146,19 +146,19 @@ public class SysTenantController extends BaseController {
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@GetMapping("/dynamic/{tenantId}")
public R<Void> dynamicTenant(@NotBlank(message = "租户ID不能为空") @PathVariable String tenantId) {
TenantHelper.setDynamic(tenantId, true);
// TenantHelper.setDynamic(tenantId, true);
return R.ok();
}
/**
* 清除动态租户
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@GetMapping("/dynamic/clear")
public R<Void> dynamicClear() {
TenantHelper.clearDynamic();
return R.ok();
}
// /**
// * 清除动态租户
// */
// @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
// @GetMapping("/dynamic/clear")
// public R<Void> dynamicClear() {
// TenantHelper.clearDynamic();
// return R.ok();
// }
/**

View File

@ -106,11 +106,15 @@ public class SysUserController extends BaseController {
public R<UserInfoVo> getInfo() {
UserInfoVo userInfoVo = new UserInfoVo();
LoginUser loginUser = LoginHelper.getLoginUser();
if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
// 超级管理员 如果重新加载用户信息需清除动态租户
TenantHelper.clearDynamic();
if (ObjectUtil.isNull(loginUser)) {
return R.fail("登录用户信息为空!");
}
SysUserVo user;
if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
user = TenantHelper.ignore(() -> userService.selectUserById(loginUser.getUserId()));
} else {
user = userService.selectUserById(loginUser.getUserId());
}
SysUserVo user = userService.selectUserById(loginUser.getUserId());
if (ObjectUtil.isNull(user)) {
return R.fail("没有权限访问用户数据!");
}
@ -165,7 +169,7 @@ public class SysUserController extends BaseController {
return R.fail("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
if (TenantHelper.isEnable()) {
if (!tenantService.checkAccountBalance(TenantHelper.getTenantId())) {
if (!tenantService.checkAccountBalance(LoginHelper.getTenantId())) {
return R.fail("当前租户下用户名额不足,请联系管理员");
}
}

View File

@ -2,6 +2,7 @@ package org.dromara.workflow.flowable.config;
import cn.hutool.core.collection.CollUtil;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.workflow.common.enums.TaskStatusEnum;
import org.dromara.workflow.flowable.handler.TaskTimeoutJobHandler;
@ -78,7 +79,7 @@ public class GlobalFlowableListener implements FlowableEventListener {
}
//创建job对象
TimerJobEntity timer = timerJobService.createTimerJob();
timer.setTenantId(TenantHelper.getTenantId());
timer.setTenantId(LoginHelper.getTenantId());
//设置job类型
timer.setJobType(JobEntity.JOB_TYPE_TIMER);
timer.setJobHandlerType(TaskTimeoutJobHandler.TYPE);

View File

@ -3,6 +3,7 @@ package org.dromara.workflow.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.workflow.domain.ActHiProcinst;
import org.dromara.workflow.mapper.ActHiProcinstMapper;
@ -33,7 +34,7 @@ public class ActHiProcinstServiceImpl implements IActHiProcinstService {
public List<ActHiProcinst> selectByBusinessKeyIn(List<String> businessKeys) {
return baseMapper.selectList(new LambdaQueryWrapper<ActHiProcinst>()
.in(ActHiProcinst::getBusinessKey, businessKeys)
.eq(TenantHelper.isEnable(), ActHiProcinst::getTenantId, TenantHelper.getTenantId()));
.eq(TenantHelper.isEnable(), ActHiProcinst::getTenantId, LoginHelper.getTenantId()));
}
/**
@ -45,7 +46,7 @@ public class ActHiProcinstServiceImpl implements IActHiProcinstService {
public ActHiProcinst selectByBusinessKey(String businessKey) {
return baseMapper.selectOne(new LambdaQueryWrapper<ActHiProcinst>()
.eq(ActHiProcinst::getBusinessKey, businessKey)
.eq(TenantHelper.isEnable(), ActHiProcinst::getTenantId, TenantHelper.getTenantId()));
.eq(TenantHelper.isEnable(), ActHiProcinst::getTenantId, LoginHelper.getTenantId()));
}
}

View File

@ -17,6 +17,7 @@ import org.apache.batik.transcoder.image.PNGTranscoder;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.workflow.common.constant.FlowConstant;
import org.dromara.workflow.domain.WfNodeConfig;
@ -129,7 +130,7 @@ public class ActModelServiceImpl implements IActModelService {
model.setVersion(version);
model.setCategory(categoryCode);
model.setMetaInfo(description);
model.setTenantId(TenantHelper.getTenantId());
model.setTenantId(LoginHelper.getTenantId());
//保存初始化的模型基本信息数据
repositoryService.saveModel(model);
repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(xml));
@ -286,7 +287,7 @@ public class ActModelServiceImpl implements IActModelService {
// bpmn20.xml资源
.addBytes(processName, xmlBytes)
// 租户id
.tenantId(TenantHelper.getTenantId())
.tenantId(LoginHelper.getTenantId())
.deploy();
// 更新 部署id 到流程定义模型数据表中
@ -411,7 +412,7 @@ public class ActModelServiceImpl implements IActModelService {
newModel.setCategory(modelBo.getCategoryCode());
newModel.setVersion(1);
newModel.setMetaInfo(modelBo.getDescription());
newModel.setTenantId(TenantHelper.getTenantId());
newModel.setTenantId(LoginHelper.getTenantId());
String xml = StrUtil.utf8Str(modelEditorSource);
BpmnModel bpmnModel = ModelUtils.xmlToBpmnModel(xml);
Process mainProcess = bpmnModel.getMainProcess();

View File

@ -15,6 +15,7 @@ import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.workflow.common.constant.FlowConstant;
import org.dromara.workflow.domain.WfCategory;
@ -336,7 +337,7 @@ public class ActProcessDefinitionServiceImpl implements IActProcessDefinitionSer
ProcessDefinition oldProcessDefinition = QueryUtils.definitionQuery().processDefinitionKey(processKey).latestVersion().singleResult();
DeploymentBuilder builder = repositoryService.createDeployment();
Deployment deployment = builder.addInputStream(filename, zipInputStream)
.tenantId(TenantHelper.getTenantId())
.tenantId(LoginHelper.getTenantId())
.name(processName).key(processKey).category(categoryCode).deploy();
ProcessDefinition definition = QueryUtils.definitionQuery().deploymentId(deployment.getId()).singleResult();
repositoryService.setProcessDefinitionCategory(definition.getId(), categoryCode);
@ -367,7 +368,7 @@ public class ActProcessDefinitionServiceImpl implements IActProcessDefinitionSer
ProcessDefinition oldProcessDefinition = QueryUtils.definitionQuery().processDefinitionKey(processKey).latestVersion().singleResult();
DeploymentBuilder builder = repositoryService.createDeployment();
Deployment deployment = builder.addInputStream(originalFilename, inputStream)
.tenantId(TenantHelper.getTenantId())
.tenantId(LoginHelper.getTenantId())
.name(processName).key(processKey).category(categoryCode).deploy();
// 更新分类
ProcessDefinition definition = QueryUtils.definitionQuery().deploymentId(deployment.getId()).singleResult();

View File

@ -134,7 +134,7 @@ public class ActTaskServiceImpl implements IActTaskService {
ProcessInstance pi;
try {
if (TenantHelper.isEnable()) {
pi = runtimeService.startProcessInstanceByKeyAndTenantId(wfDefinitionConfigVo.getProcessKey(), startProcessBo.getBusinessKey(), variables, TenantHelper.getTenantId());
pi = runtimeService.startProcessInstanceByKeyAndTenantId(wfDefinitionConfigVo.getProcessKey(), startProcessBo.getBusinessKey(), variables, LoginHelper.getTenantId());
} else {
pi = runtimeService.startProcessInstanceByKey(wfDefinitionConfigVo.getProcessKey(), startProcessBo.getBusinessKey(), variables);
}
@ -265,7 +265,7 @@ public class ActTaskServiceImpl implements IActTaskService {
List<String> roleIds = StreamUtils.toList(roles, e -> String.valueOf(e.getRoleId()));
String userId = String.valueOf(LoginHelper.getUserId());
queryWrapper.eq("t.business_status_", BusinessStatusEnum.WAITING.getStatus());
queryWrapper.eq(TenantHelper.isEnable(), "t.tenant_id_", TenantHelper.getTenantId());
queryWrapper.eq(TenantHelper.isEnable(), "t.tenant_id_", LoginHelper.getTenantId());
String ids = StreamUtils.join(roleIds, x -> "'" + x + "'");
queryWrapper.and(w1 -> w1.eq("t.assignee_", userId).or(w2 -> w2.isNull("t.assignee_").apply("exists ( select LINK.ID_ from ACT_RU_IDENTITYLINK LINK where LINK.TASK_ID_ = t.ID_ and LINK.TYPE_ = 'candidate' and (LINK.USER_ID_ = {0} or ( LINK.GROUP_ID_ IN (" + ids + ") ) ))", userId)));
if (StringUtils.isNotBlank(taskBo.getName())) {

View File

@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.workflow.domain.vo.TaskVo;
import org.flowable.engine.ProcessEngine;
@ -35,7 +36,7 @@ public class QueryUtils {
public static ModelQuery modelQuery() {
ModelQuery query = PROCESS_ENGINE.getRepositoryService().createModelQuery();
if (TenantHelper.isEnable()) {
query.modelTenantId(TenantHelper.getTenantId());
query.modelTenantId(LoginHelper.getTenantId());
}
return query;
}
@ -43,7 +44,7 @@ public class QueryUtils {
public static ProcessDefinitionQuery definitionQuery() {
ProcessDefinitionQuery query = PROCESS_ENGINE.getRepositoryService().createProcessDefinitionQuery();
if (TenantHelper.isEnable()) {
query.processDefinitionTenantId(TenantHelper.getTenantId());
query.processDefinitionTenantId(LoginHelper.getTenantId());
}
return query;
}
@ -51,7 +52,7 @@ public class QueryUtils {
public static DeploymentQuery deploymentQuery() {
DeploymentQuery query = PROCESS_ENGINE.getRepositoryService().createDeploymentQuery();
if (TenantHelper.isEnable()) {
query.deploymentTenantId(TenantHelper.getTenantId());
query.deploymentTenantId(LoginHelper.getTenantId());
}
return query;
}
@ -67,7 +68,7 @@ public class QueryUtils {
public static HistoricTaskInstanceQuery hisTaskInstanceQuery() {
HistoricTaskInstanceQuery query = PROCESS_ENGINE.getHistoryService().createHistoricTaskInstanceQuery();
if (TenantHelper.isEnable()) {
query.taskTenantId(TenantHelper.getTenantId());
query.taskTenantId(LoginHelper.getTenantId());
}
return query;
}
@ -83,7 +84,7 @@ public class QueryUtils {
public static ProcessInstanceQuery instanceQuery() {
ProcessInstanceQuery query = PROCESS_ENGINE.getRuntimeService().createProcessInstanceQuery();
if (TenantHelper.isEnable()) {
query.processInstanceTenantId(TenantHelper.getTenantId());
query.processInstanceTenantId(LoginHelper.getTenantId());
}
return query;
}
@ -103,7 +104,7 @@ public class QueryUtils {
public static HistoricProcessInstanceQuery hisInstanceQuery() {
HistoricProcessInstanceQuery query = PROCESS_ENGINE.getHistoryService().createHistoricProcessInstanceQuery();
if (TenantHelper.isEnable()) {
query.processInstanceTenantId(TenantHelper.getTenantId());
query.processInstanceTenantId(LoginHelper.getTenantId());
}
return query;
}
@ -123,7 +124,7 @@ public class QueryUtils {
public static HistoricActivityInstanceQuery hisActivityInstanceQuery() {
HistoricActivityInstanceQuery query = PROCESS_ENGINE.getHistoryService().createHistoricActivityInstanceQuery();
if (TenantHelper.isEnable()) {
query.activityTenantId(TenantHelper.getTenantId());
query.activityTenantId(LoginHelper.getTenantId());
}
return query;
}
@ -135,7 +136,7 @@ public class QueryUtils {
public static TaskQuery taskQuery() {
TaskQuery query = PROCESS_ENGINE.getTaskService().createTaskQuery();
if (TenantHelper.isEnable()) {
query.taskTenantId(TenantHelper.getTenantId());
query.taskTenantId(LoginHelper.getTenantId());
}
return query;
}

View File

@ -69,7 +69,7 @@ public class WorkflowUtils {
task.setTaskDefinitionKey(currentTask.getTaskDefinitionKey());
task.setPriority(currentTask.getPriority());
task.setCreateTime(new Date());
task.setTenantId(TenantHelper.getTenantId());
task.setTenantId(LoginHelper.getTenantId());
PROCESS_ENGINE.getTaskService().saveTask(task);
}
if (ObjectUtil.isNotNull(task)) {
@ -87,7 +87,7 @@ public class WorkflowUtils {
*/
public static void createCopyTask(List<Task> parentTaskList, List<Long> userIds) {
List<Task> list = new ArrayList<>();
String tenantId = TenantHelper.getTenantId();
String tenantId = LoginHelper.getTenantId();
for (Task parentTask : parentTaskList) {
for (Long userId : userIds) {
TaskEntity newTask = (TaskEntity) PROCESS_ENGINE.getTaskService().newTask();

View File

@ -8,6 +8,7 @@ import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.StringValue;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.tenant.properties.TenantProperties;
@ -26,7 +27,7 @@ public class PlusTenantLineHandler implements TenantLineHandler {
@Override
public Expression getTenantId() {
String tenantId = TenantHelper.getTenantId();
String tenantId = TenantHelper.getDynamicTenantId(LoginHelper.getTenantId());
if (StringUtils.isBlank(tenantId)) {
log.error("无法获取有效的租户id -> Null");
return new NullValue();
@ -37,7 +38,7 @@ public class PlusTenantLineHandler implements TenantLineHandler {
@Override
public boolean ignoreTable(String tableName) {
String tenantId = TenantHelper.getTenantId();
String tenantId = TenantHelper.getDynamicTenantId(LoginHelper.getTenantId());
// 判断是否有租户
if (StringUtils.isNotBlank(tenantId)) {
// 不需要过滤租户的表

View File

@ -12,6 +12,7 @@ import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.UserConstants;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginBody;
@ -171,7 +172,12 @@ public class AuthController {
*/
@PostMapping("/logout")
public R<Void> logout() {
loginService.logout();
if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
// 超级管理员 登出清除动态租户
TenantHelper.ignore(loginService::logout);
} else {
loginService.logout();
}
return R.ok("退出成功");
}

View File

@ -111,10 +111,6 @@ public class SysLoginService {
if (ObjectUtil.isNull(loginUser)) {
return;
}
if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
// 超级管理员 登出清除动态租户
TenantHelper.clearDynamic();
}
recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success"));
} catch (NotLoginException ignored) {
} finally {

View File

@ -2,7 +2,9 @@ package org.dromara.h5.config;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import org.dromara.md.form.utils.TenantHelper;
import net.sf.jsqlparser.expression.LongValue;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
@ -31,18 +33,18 @@ public class PlusTenantLineHandler implements TenantLineHandler {
@Override
public Expression getTenantId() {
String tenantId = TenantHelper.getTenantId() + "";
String tenantId = TenantHelper.getDynamicTenantId(LoginHelper.getTenantId());
if (StringUtils.isBlank(tenantId)) {
log.error("无法获取有效的租户id -> Null");
return new NullValue();
}
// 返回固定租户
return new StringValue(tenantId);
return new LongValue(tenantId);
}
@Override
public boolean ignoreTable(String tableName) {
String tenantId = TenantHelper.getTenantId() + "";
String tenantId = TenantHelper.getDynamicTenantId(LoginHelper.getTenantId());
// 判断是否有租户
if (StringUtils.isNotBlank(tenantId)) {
// 不需要过滤租户的表

View File

@ -27,17 +27,19 @@
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-redis</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-satoken</artifactId>
</dependency>
<!-- 租户模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-tenant</artifactId>
<version>${revision}</version>
</dependency>
<!-- 远程调用模块 TODO rename -->
<!-- 远程调用模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-md-system-saas-api</artifactId>
@ -87,20 +89,7 @@
</dependency>
<!-- Sa-Token 整合 jwt -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jwt</artifactId>
</dependency>
<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- Sa-Token 插件整合SSO -->
<dependency>

View File

@ -1,52 +1,52 @@
package org.dromara.sso.config.satoken;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.hutool.http.HttpStatus;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* SaToken异常处理器
*
* @author Lion Li
*/
@Slf4j
@RestControllerAdvice
public class SaTokenExceptionHandler {
/**
* 权限码异常
*/
@ExceptionHandler(NotPermissionException.class)
public R<Void> handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage());
return R.fail(HttpStatus.HTTP_FORBIDDEN, "没有访问权限,请联系管理员授权");
}
/**
* 角色权限异常
*/
@ExceptionHandler(NotRoleException.class)
public R<Void> handleNotRoleException(NotRoleException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',角色权限校验失败'{}'", requestURI, e.getMessage());
return R.fail(HttpStatus.HTTP_FORBIDDEN, "没有访问权限,请联系管理员授权");
}
/**
* 认证失败
*/
@ExceptionHandler(NotLoginException.class)
public R<Void> handleNotLoginException(NotLoginException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',认证失败'{}',无法访问系统资源", requestURI, e.getMessage());
return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认证失败,无法访问系统资源");
}
}
//package org.dromara.sso.config.satoken;
//
//import cn.dev33.satoken.exception.NotLoginException;
//import cn.dev33.satoken.exception.NotPermissionException;
//import cn.dev33.satoken.exception.NotRoleException;
//import cn.hutool.http.HttpStatus;
//import jakarta.servlet.http.HttpServletRequest;
//import lombok.extern.slf4j.Slf4j;
//import org.dromara.common.core.domain.R;
//import org.springframework.web.bind.annotation.ExceptionHandler;
//import org.springframework.web.bind.annotation.RestControllerAdvice;
//
///**
// * SaToken异常处理器
// *
// * @author Lion Li
// */
//@Slf4j
//@RestControllerAdvice
//public class SaTokenExceptionHandler {
//
// /**
// * 权限码异常
// */
// @ExceptionHandler(NotPermissionException.class)
// public R<Void> handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {
// String requestURI = request.getRequestURI();
// log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage());
// return R.fail(HttpStatus.HTTP_FORBIDDEN, "没有访问权限,请联系管理员授权");
// }
//
// /**
// * 角色权限异常
// */
// @ExceptionHandler(NotRoleException.class)
// public R<Void> handleNotRoleException(NotRoleException e, HttpServletRequest request) {
// String requestURI = request.getRequestURI();
// log.error("请求地址'{}',角色权限校验失败'{}'", requestURI, e.getMessage());
// return R.fail(HttpStatus.HTTP_FORBIDDEN, "没有访问权限,请联系管理员授权");
// }
//
// /**
// * 认证失败
// */
// @ExceptionHandler(NotLoginException.class)
// public R<Void> handleNotLoginException(NotLoginException e, HttpServletRequest request) {
// String requestURI = request.getRequestURI();
// log.error("请求地址'{}',认证失败'{}',无法访问系统资源", requestURI, e.getMessage());
// return R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认证失败,无法访问系统资源");
// }
//
//}

View File

@ -4,6 +4,7 @@ import cn.dev33.satoken.exception.NotLoginException;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.sso.form.RegisterBody;
import org.dromara.sso.form.SocialLoginBody;
import org.dromara.sso.service.IAuthStrategy;
@ -161,7 +162,12 @@ public class TokenController {
*/
@PostMapping("logout")
public R<Void> logout() {
sysLoginService.logout();
if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
// 超级管理员 登出清除动态租户
TenantHelper.ignore(sysLoginService::logout);
} else {
sysLoginService.logout();
}
return R.ok();
}

View File

@ -118,10 +118,6 @@ public class SysLoginService {
if (ObjectUtil.isNull(loginUser)) {
return;
}
if (TenantHelper.isEnable() && LoginSaasHelper.isSuperAdmin()) {
// 超级管理员 登出清除动态租户
TenantHelper.clearDynamic();
}
recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGOUT, MessageUtils.message("user.logout.success"));
} catch (NotLoginException ignored) {
} finally {

View File

@ -9,6 +9,7 @@ import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.StringValue;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.config.MybatisPlusConfig;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.tenant.properties.TenantProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration;
@ -30,7 +31,7 @@ public class MybatisPlusAutoConfigTenant {
@Override
public Expression getTenantId() {
String tenantId = TenantHelper.getTenantId();
String tenantId = LoginHelper.getTenantId();
if (StringUtils.isBlank(tenantId)) {
log.error("无法获取有效的租户id -> Null");
return new NullValue();
@ -41,7 +42,7 @@ public class MybatisPlusAutoConfigTenant {
@Override
public boolean ignoreTable(String tableName) {
String tenantId = TenantHelper.getTenantId();
String tenantId = LoginHelper.getTenantId();
// 判断是否有租户
if (StringUtils.isNotBlank(tenantId)) {
// 不需要过滤租户的表

View File

@ -9,6 +9,7 @@ import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.StringValue;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.config.MybatisPlusConfig;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.tenant.properties.TenantProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration;
@ -30,7 +31,7 @@ public class MybatisPlusAutoConfigTenant {
@Override
public Expression getTenantId() {
String tenantId = TenantHelper.getTenantId();
String tenantId = LoginHelper.getTenantId();
if (StringUtils.isBlank(tenantId)) {
log.error("无法获取有效的租户id -> Null");
return new NullValue();
@ -41,7 +42,7 @@ public class MybatisPlusAutoConfigTenant {
@Override
public boolean ignoreTable(String tableName) {
String tenantId = TenantHelper.getTenantId();
String tenantId = LoginHelper.getTenantId();
// 判断是否有租户
if (StringUtils.isNotBlank(tenantId)) {
// 不需要过滤租户的表