diff --git a/pom.xml b/pom.xml index c80a91b..057222b 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,8 @@ yudao-module-system yudao-module-infra - + yudao-module-alert + diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index 02bde5f..8817c19 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -107,11 +107,11 @@ - - cn.iocoder.boot - yudao-spring-boot-starter-biz-tenant - ${revision} - + + + + + cn.iocoder.boot yudao-spring-boot-starter-biz-data-permission diff --git a/yudao-framework/pom.xml b/yudao-framework/pom.xml index d22b463..873f3d0 100644 --- a/yudao-framework/pom.xml +++ b/yudao-framework/pom.xml @@ -24,7 +24,7 @@ yudao-spring-boot-starter-excel - yudao-spring-boot-starter-biz-tenant + yudao-spring-boot-starter-biz-data-permission yudao-spring-boot-starter-biz-ip diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-tenant/pom.xml deleted file mode 100644 index b831767..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/pom.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - yudao-framework - cn.iocoder.boot - ${revision} - - 4.0.0 - yudao-spring-boot-starter-biz-tenant - jar - - ${project.artifactId} - 多租户 - https://github.com/YunaiV/ruoyi-vue-pro - - - - cn.iocoder.boot - yudao-common - - - - - cn.iocoder.boot - yudao-spring-boot-starter-security - - - - - cn.iocoder.boot - yudao-spring-boot-starter-mybatis - - - - cn.iocoder.boot - yudao-spring-boot-starter-redis - - - - - cn.iocoder.boot - yudao-spring-boot-starter-job - - - - - cn.iocoder.boot - yudao-spring-boot-starter-mq - true - - - org.springframework.kafka - spring-kafka - true - - - org.springframework.amqp - spring-rabbit - true - - - org.apache.rocketmq - rocketmq-spring-boot-starter - true - - - - - com.google.guava - guava - - - - diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/TenantProperties.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/TenantProperties.java deleted file mode 100644 index b0c0217..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/TenantProperties.java +++ /dev/null @@ -1,49 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.config; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; - -import java.util.Collections; -import java.util.Set; - -/** - * 多租户配置 - * - * @author 芋道源码 - */ -@ConfigurationProperties(prefix = "yudao.tenant") -@Data -public class TenantProperties { - - /** - * 租户是否开启 - */ - private static final Boolean ENABLE_DEFAULT = true; - - /** - * 是否开启 - */ - private Boolean enable = ENABLE_DEFAULT; - - /** - * 需要忽略多租户的请求 - * - * 默认情况下,每个请求需要带上 tenant-id 的请求头。但是,部分请求是无需带上的,例如说短信回调、支付回调等 Open API! - */ - private Set ignoreUrls = Collections.emptySet(); - - /** - * 需要忽略多租户的表 - * - * 即默认所有表都开启多租户的功能,所以记得添加对应的 tenant_id 字段哟 - */ - private Set ignoreTables = Collections.emptySet(); - - /** - * 需要忽略多租户的 Spring Cache 缓存 - * - * 即默认所有缓存都开启多租户的功能,所以记得添加对应的 tenant_id 字段哟 - */ - private Set ignoreCaches = Collections.emptySet(); - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java deleted file mode 100644 index a804cce..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java +++ /dev/null @@ -1,133 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.config; - -import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; -import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; -import cn.iocoder.yudao.framework.redis.config.YudaoCacheProperties; -import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnoreAspect; -import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor; -import cn.iocoder.yudao.framework.tenant.core.job.TenantJobAspect; -import cn.iocoder.yudao.framework.tenant.core.mq.rabbitmq.TenantRabbitMQInitializer; -import cn.iocoder.yudao.framework.tenant.core.mq.redis.TenantRedisMessageInterceptor; -import cn.iocoder.yudao.framework.tenant.core.mq.rocketmq.TenantRocketMQInitializer; -import cn.iocoder.yudao.framework.tenant.core.redis.TenantRedisCacheManager; -import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter; -import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService; -import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkServiceImpl; -import cn.iocoder.yudao.framework.tenant.core.web.TenantContextWebFilter; -import cn.iocoder.yudao.framework.web.config.WebProperties; -import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler; -import cn.iocoder.yudao.module.system.api.tenant.TenantApi; -import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; -import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import org.springframework.data.redis.cache.BatchStrategies; -import org.springframework.data.redis.cache.RedisCacheConfiguration; -import org.springframework.data.redis.cache.RedisCacheManager; -import org.springframework.data.redis.cache.RedisCacheWriter; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.data.redis.core.RedisTemplate; - -import java.util.Objects; - -@AutoConfiguration -@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) // 允许使用 yudao.tenant.enable=false 禁用多租户 -@EnableConfigurationProperties(TenantProperties.class) -public class YudaoTenantAutoConfiguration { - - @Bean - public TenantFrameworkService tenantFrameworkService(TenantApi tenantApi) { - return new TenantFrameworkServiceImpl(tenantApi); - } - - // ========== AOP ========== - - @Bean - public TenantIgnoreAspect tenantIgnoreAspect() { - return new TenantIgnoreAspect(); - } - - // ========== DB ========== - - @Bean - public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantProperties properties, - MybatisPlusInterceptor interceptor) { - TenantLineInnerInterceptor inner = new TenantLineInnerInterceptor(new TenantDatabaseInterceptor(properties)); - // 添加到 interceptor 中 - // 需要加在首个,主要是为了在分页插件前面。这个是 MyBatis Plus 的规定 - MyBatisUtils.addInterceptor(interceptor, inner, 0); - return inner; - } - - // ========== WEB ========== - - @Bean - public FilterRegistrationBean tenantContextWebFilter() { - FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); - registrationBean.setFilter(new TenantContextWebFilter()); - registrationBean.setOrder(WebFilterOrderEnum.TENANT_CONTEXT_FILTER); - return registrationBean; - } - - // ========== Security ========== - - @Bean - public FilterRegistrationBean tenantSecurityWebFilter(TenantProperties tenantProperties, - WebProperties webProperties, - GlobalExceptionHandler globalExceptionHandler, - TenantFrameworkService tenantFrameworkService) { - FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); - registrationBean.setFilter(new TenantSecurityWebFilter(tenantProperties, webProperties, - globalExceptionHandler, tenantFrameworkService)); - registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER); - return registrationBean; - } - - // ========== MQ ========== - - @Bean - public TenantRedisMessageInterceptor tenantRedisMessageInterceptor() { - return new TenantRedisMessageInterceptor(); - } - - @Bean - @ConditionalOnClass(name = "org.springframework.amqp.rabbit.core.RabbitTemplate") - public TenantRabbitMQInitializer tenantRabbitMQInitializer() { - return new TenantRabbitMQInitializer(); - } - - @Bean - @ConditionalOnClass(name = "org.apache.rocketmq.spring.core.RocketMQTemplate") - public TenantRocketMQInitializer tenantRocketMQInitializer() { - return new TenantRocketMQInitializer(); - } - - // ========== Job ========== - - @Bean - public TenantJobAspect tenantJobAspect(TenantFrameworkService tenantFrameworkService) { - return new TenantJobAspect(tenantFrameworkService); - } - - // ========== Redis ========== - - @Bean - @Primary // 引入租户时,tenantRedisCacheManager 为主 Bean - public RedisCacheManager tenantRedisCacheManager(RedisTemplate redisTemplate, - RedisCacheConfiguration redisCacheConfiguration, - YudaoCacheProperties yudaoCacheProperties, - TenantProperties tenantProperties) { - // 创建 RedisCacheWriter 对象 - RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory()); - RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory, - BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize())); - // 创建 TenantRedisCacheManager 对象 - return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration, tenantProperties.getIgnoreCaches()); - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/aop/TenantIgnore.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/aop/TenantIgnore.java deleted file mode 100644 index f2fec50..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/aop/TenantIgnore.java +++ /dev/null @@ -1,18 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.aop; - -import java.lang.annotation.*; - -/** - * 忽略租户,标记指定方法不进行租户的自动过滤 - * - * 注意,只有 DB 的场景会过滤,其它场景暂时不过滤: - * 1、Redis 场景:因为是基于 Key 实现多租户的能力,所以忽略没有意义,不像 DB 是一个 column 实现的 - * 2、MQ 场景:有点难以抉择,目前可以通过 Consumer 手动在消费的方法上,添加 @TenantIgnore 进行忽略 - * - * @author 芋道源码 - */ -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -@Inherited -public @interface TenantIgnore { -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/aop/TenantIgnoreAspect.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/aop/TenantIgnoreAspect.java deleted file mode 100644 index b7d0fa3..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/aop/TenantIgnoreAspect.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.aop; - -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; -import lombok.extern.slf4j.Slf4j; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; - -/** - * 忽略多租户的 Aspect,基于 {@link TenantIgnore} 注解实现,用于一些全局的逻辑。 - * 例如说,一个定时任务,读取所有数据,进行处理。 - * 又例如说,读取所有数据,进行缓存。 - * - * 整体逻辑的实现,和 {@link TenantUtils#executeIgnore(Runnable)} 需要保持一致 - * - * @author 芋道源码 - */ -@Aspect -@Slf4j -public class TenantIgnoreAspect { - - @Around("@annotation(tenantIgnore)") - public Object around(ProceedingJoinPoint joinPoint, TenantIgnore tenantIgnore) throws Throwable { - Boolean oldIgnore = TenantContextHolder.isIgnore(); - try { - TenantContextHolder.setIgnore(true); - // 执行逻辑 - return joinPoint.proceed(); - } finally { - TenantContextHolder.setIgnore(oldIgnore); - } - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java deleted file mode 100644 index 4e7b5e0..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java +++ /dev/null @@ -1,68 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.context; - -import cn.iocoder.yudao.framework.common.enums.DocumentEnum; -import com.alibaba.ttl.TransmittableThreadLocal; - -/** - * 多租户上下文 Holder - * - * @author 芋道源码 - */ -public class TenantContextHolder { - - /** - * 当前租户编号 - */ - private static final ThreadLocal TENANT_ID = new TransmittableThreadLocal<>(); - - /** - * 是否忽略租户 - */ - private static final ThreadLocal IGNORE = new TransmittableThreadLocal<>(); - - /** - * 获得租户编号 - * - * @return 租户编号 - */ - public static Long getTenantId() { - return TENANT_ID.get(); - } - - /** - * 获得租户编号。如果不存在,则抛出 NullPointerException 异常 - * - * @return 租户编号 - */ - public static Long getRequiredTenantId() { - Long tenantId = getTenantId(); - if (tenantId == null) { - throw new NullPointerException("TenantContextHolder 不存在租户编号!可参考文档:" - + DocumentEnum.TENANT.getUrl()); - } - return tenantId; - } - - public static void setTenantId(Long tenantId) { - TENANT_ID.set(tenantId); - } - - public static void setIgnore(Boolean ignore) { - IGNORE.set(ignore); - } - - /** - * 当前是否忽略租户 - * - * @return 是否忽略 - */ - public static boolean isIgnore() { - return Boolean.TRUE.equals(IGNORE.get()); - } - - public static void clear() { - TENANT_ID.remove(); - IGNORE.remove(); - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantBaseDO.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantBaseDO.java deleted file mode 100644 index f4f0ea5..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantBaseDO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.db; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * 拓展多租户的 BaseDO 基类 - * - * @author 芋道源码 - */ -@Data -@EqualsAndHashCode(callSuper = true) -public abstract class TenantBaseDO extends BaseDO { - - /** - * 多租户编号 - */ - private Long tenantId; - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java deleted file mode 100644 index 8f1c8ac..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.db; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.tenant.config.TenantProperties; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; -import com.baomidou.mybatisplus.extension.toolkit.SqlParserUtils; -import net.sf.jsqlparser.expression.Expression; -import net.sf.jsqlparser.expression.LongValue; - -import java.util.HashSet; -import java.util.Set; - -/** - * 基于 MyBatis Plus 多租户的功能,实现 DB 层面的多租户的功能 - * - * @author 芋道源码 - */ -public class TenantDatabaseInterceptor implements TenantLineHandler { - - private final Set ignoreTables = new HashSet<>(); - - public TenantDatabaseInterceptor(TenantProperties properties) { - // 不同 DB 下,大小写的习惯不同,所以需要都添加进去 - properties.getIgnoreTables().forEach(table -> { - ignoreTables.add(table.toLowerCase()); - ignoreTables.add(table.toUpperCase()); - }); - // 在 OracleKeyGenerator 中,生成主键时,会查询这个表,查询这个表后,会自动拼接 TENANT_ID 导致报错 - ignoreTables.add("DUAL"); - } - - @Override - public Expression getTenantId() { - return new LongValue(TenantContextHolder.getRequiredTenantId()); - } - - @Override - public boolean ignoreTable(String tableName) { - return TenantContextHolder.isIgnore() // 情况一,全局忽略多租户 - || CollUtil.contains(ignoreTables, SqlParserUtils.removeWrapperSymbol(tableName)); // 情况二,忽略多租户的表 - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/job/TenantJob.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/job/TenantJob.java deleted file mode 100644 index 23474bb..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/job/TenantJob.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.job; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * 多租户 Job 注解 - */ -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -public @interface TenantJob { -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/job/TenantJobAspect.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/job/TenantJobAspect.java deleted file mode 100644 index a58887a..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/job/TenantJobAspect.java +++ /dev/null @@ -1,59 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.job; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.exceptions.ExceptionUtil; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService; -import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * 多租户 JobHandler AOP - * 任务执行时,会按照租户逐个执行 Job 的逻辑 - * - * 注意,需要保证 JobHandler 的幂等性。因为 Job 因为某个租户执行失败重试时,之前执行成功的租户也会再次执行。 - * - * @author 芋道源码 - */ -@Aspect -@RequiredArgsConstructor -@Slf4j -public class TenantJobAspect { - - private final TenantFrameworkService tenantFrameworkService; - - @Around("@annotation(tenantJob)") - public String around(ProceedingJoinPoint joinPoint, TenantJob tenantJob) { - // 获得租户列表 - List tenantIds = tenantFrameworkService.getTenantIds(); - if (CollUtil.isEmpty(tenantIds)) { - return null; - } - - // 逐个租户,执行 Job - Map results = new ConcurrentHashMap<>(); - tenantIds.parallelStream().forEach(tenantId -> { - // TODO 芋艿:先通过 parallel 实现并行;1)多个租户,是一条执行日志;2)异常的情况 - TenantUtils.execute(tenantId, () -> { - try { - Object result = joinPoint.proceed(); - results.put(tenantId, StrUtil.toStringOrEmpty(result)); - } catch (Throwable e) { - log.error("[execute][租户({}) 执行 Job 发生异常", tenantId, e); - results.put(tenantId, ExceptionUtil.getRootCauseMessage(e)); - } - }); - }); - return JsonUtils.toJsonString(results); - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/kafka/TenantKafkaEnvironmentPostProcessor.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/kafka/TenantKafkaEnvironmentPostProcessor.java deleted file mode 100644 index 8bf7cc1..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/kafka/TenantKafkaEnvironmentPostProcessor.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.mq.kafka; - -import cn.hutool.core.util.StrUtil; -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.env.EnvironmentPostProcessor; -import org.springframework.core.env.ConfigurableEnvironment; - -/** - * 多租户的 Kafka 的 {@link EnvironmentPostProcessor} 实现类 - * - * Kafka Producer 发送消息时,增加 {@link TenantKafkaProducerInterceptor} 拦截器 - * - * @author 芋道源码 - */ -@Slf4j -public class TenantKafkaEnvironmentPostProcessor implements EnvironmentPostProcessor { - - private static final String PROPERTY_KEY_INTERCEPTOR_CLASSES = "spring.kafka.producer.properties.interceptor.classes"; - - @Override - public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - // 添加 TenantKafkaProducerInterceptor 拦截器 - try { - String value = environment.getProperty(PROPERTY_KEY_INTERCEPTOR_CLASSES); - if (StrUtil.isEmpty(value)) { - value = TenantKafkaProducerInterceptor.class.getName(); - } else { - value += "," + TenantKafkaProducerInterceptor.class.getName(); - } - environment.getSystemProperties().put(PROPERTY_KEY_INTERCEPTOR_CLASSES, value); - } catch (NoClassDefFoundError ignore) { - // 如果触发 NoClassDefFoundError 异常,说明 TenantKafkaProducerInterceptor 类不存在,即没引入 kafka-spring 依赖 - } - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/kafka/TenantKafkaProducerInterceptor.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/kafka/TenantKafkaProducerInterceptor.java deleted file mode 100644 index 8ded801..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/kafka/TenantKafkaProducerInterceptor.java +++ /dev/null @@ -1,47 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.mq.kafka; - -import cn.hutool.core.util.ReflectUtil; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import org.apache.kafka.clients.producer.ProducerInterceptor; -import org.apache.kafka.clients.producer.ProducerRecord; -import org.apache.kafka.clients.producer.RecordMetadata; -import org.apache.kafka.common.header.Headers; -import org.springframework.messaging.handler.invocation.InvocableHandlerMethod; - -import java.util.Map; - -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; - -/** - * Kafka 消息队列的多租户 {@link ProducerInterceptor} 实现类 - * - * 1. Producer 发送消息时,将 {@link TenantContextHolder} 租户编号,添加到消息的 Header 中 - * 2. Consumer 消费消息时,将消息的 Header 的租户编号,添加到 {@link TenantContextHolder} 中,通过 {@link InvocableHandlerMethod} 实现 - * - * @author 芋道源码 - */ -public class TenantKafkaProducerInterceptor implements ProducerInterceptor { - - @Override - public ProducerRecord onSend(ProducerRecord record) { - Long tenantId = TenantContextHolder.getTenantId(); - if (tenantId != null) { - Headers headers = (Headers) ReflectUtil.getFieldValue(record, "headers"); // private 属性,没有 get 方法,智能反射 - headers.add(HEADER_TENANT_ID, tenantId.toString().getBytes()); - } - return record; - } - - @Override - public void onAcknowledgement(RecordMetadata metadata, Exception exception) { - } - - @Override - public void close() { - } - - @Override - public void configure(Map configs) { - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rabbitmq/TenantRabbitMQInitializer.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rabbitmq/TenantRabbitMQInitializer.java deleted file mode 100644 index b856ce9..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rabbitmq/TenantRabbitMQInitializer.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.mq.rabbitmq; - -import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; - -/** - * 多租户的 RabbitMQ 初始化器 - * - * @author 芋道源码 - */ -public class TenantRabbitMQInitializer implements BeanPostProcessor { - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof RabbitTemplate) { - RabbitTemplate rabbitTemplate = (RabbitTemplate) bean; - rabbitTemplate.addBeforePublishPostProcessors(new TenantRabbitMQMessagePostProcessor()); - } - return bean; - } - -} \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rabbitmq/TenantRabbitMQMessagePostProcessor.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rabbitmq/TenantRabbitMQMessagePostProcessor.java deleted file mode 100644 index 3e6969c..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rabbitmq/TenantRabbitMQMessagePostProcessor.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.mq.rabbitmq; - -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import org.apache.kafka.clients.producer.ProducerInterceptor; -import org.springframework.amqp.AmqpException; -import org.springframework.amqp.core.Message; -import org.springframework.amqp.core.MessagePostProcessor; -import org.springframework.messaging.handler.invocation.InvocableHandlerMethod; - -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; - -/** - * RabbitMQ 消息队列的多租户 {@link ProducerInterceptor} 实现类 - * - * 1. Producer 发送消息时,将 {@link TenantContextHolder} 租户编号,添加到消息的 Header 中 - * 2. Consumer 消费消息时,将消息的 Header 的租户编号,添加到 {@link TenantContextHolder} 中,通过 {@link InvocableHandlerMethod} 实现 - * - * @author 芋道源码 - */ -public class TenantRabbitMQMessagePostProcessor implements MessagePostProcessor { - - @Override - public Message postProcessMessage(Message message) throws AmqpException { - Long tenantId = TenantContextHolder.getTenantId(); - if (tenantId != null) { - message.getMessageProperties().getHeaders().put(HEADER_TENANT_ID, tenantId); - } - return message; - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/redis/TenantRedisMessageInterceptor.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/redis/TenantRedisMessageInterceptor.java deleted file mode 100644 index f6b7747..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/redis/TenantRedisMessageInterceptor.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.mq.redis; - -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.mq.redis.core.interceptor.RedisMessageInterceptor; -import cn.iocoder.yudao.framework.mq.redis.core.message.AbstractRedisMessage; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; - -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; - -/** - * 多租户 {@link AbstractRedisMessage} 拦截器 - * - * 1. Producer 发送消息时,将 {@link TenantContextHolder} 租户编号,添加到消息的 Header 中 - * 2. Consumer 消费消息时,将消息的 Header 的租户编号,添加到 {@link TenantContextHolder} 中 - * - * @author 芋道源码 - */ -public class TenantRedisMessageInterceptor implements RedisMessageInterceptor { - - @Override - public void sendMessageBefore(AbstractRedisMessage message) { - Long tenantId = TenantContextHolder.getTenantId(); - if (tenantId != null) { - message.addHeader(HEADER_TENANT_ID, tenantId.toString()); - } - } - - @Override - public void consumeMessageBefore(AbstractRedisMessage message) { - String tenantIdStr = message.getHeader(HEADER_TENANT_ID); - if (StrUtil.isNotEmpty(tenantIdStr)) { - TenantContextHolder.setTenantId(Long.valueOf(tenantIdStr)); - } - } - - @Override - public void consumeMessageAfter(AbstractRedisMessage message) { - // 注意,Consumer 是一个逻辑的入口,所以不考虑原本上下文就存在租户编号的情况 - TenantContextHolder.clear(); - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rocketmq/TenantRocketMQConsumeMessageHook.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rocketmq/TenantRocketMQConsumeMessageHook.java deleted file mode 100644 index d9d7334..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rocketmq/TenantRocketMQConsumeMessageHook.java +++ /dev/null @@ -1,46 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.mq.rocketmq; - -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import org.apache.rocketmq.client.hook.ConsumeMessageContext; -import org.apache.rocketmq.client.hook.ConsumeMessageHook; -import org.apache.rocketmq.common.message.MessageExt; -import org.springframework.messaging.handler.invocation.InvocableHandlerMethod; - -import java.util.List; - -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; - -/** - * RocketMQ 消息队列的多租户 {@link ConsumeMessageHook} 实现类 - * - * Consumer 消费消息时,将消息的 Header 的租户编号,添加到 {@link TenantContextHolder} 中,通过 {@link InvocableHandlerMethod} 实现 - * - * @author 芋道源码 - */ -public class TenantRocketMQConsumeMessageHook implements ConsumeMessageHook { - - @Override - public String hookName() { - return getClass().getSimpleName(); - } - - @Override - public void consumeMessageBefore(ConsumeMessageContext context) { - // 校验,消息必须是单条,不然设置租户可能不正确 - List messages = context.getMsgList(); - Assert.isTrue(messages.size() == 1, "消息条数({})不正确", messages.size()); - // 设置租户编号 - String tenantId = messages.get(0).getUserProperty(HEADER_TENANT_ID); - if (StrUtil.isNotEmpty(tenantId)) { - TenantContextHolder.setTenantId(Long.parseLong(tenantId)); - } - } - - @Override - public void consumeMessageAfter(ConsumeMessageContext context) { - TenantContextHolder.clear(); - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rocketmq/TenantRocketMQInitializer.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rocketmq/TenantRocketMQInitializer.java deleted file mode 100644 index 7f12ac5..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rocketmq/TenantRocketMQInitializer.java +++ /dev/null @@ -1,53 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.mq.rocketmq; - -import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; -import org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl; -import org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl; -import org.apache.rocketmq.client.producer.DefaultMQProducer; -import org.apache.rocketmq.spring.core.RocketMQTemplate; -import org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; - -/** - * 多租户的 RocketMQ 初始化器 - * - * @author 芋道源码 - */ -public class TenantRocketMQInitializer implements BeanPostProcessor { - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof DefaultRocketMQListenerContainer) { - DefaultRocketMQListenerContainer container = (DefaultRocketMQListenerContainer) bean; - initTenantConsumer(container.getConsumer()); - } else if (bean instanceof RocketMQTemplate) { - RocketMQTemplate template = (RocketMQTemplate) bean; - initTenantProducer(template.getProducer()); - } - return bean; - } - - private void initTenantProducer(DefaultMQProducer producer) { - if (producer == null) { - return; - } - DefaultMQProducerImpl producerImpl = producer.getDefaultMQProducerImpl(); - if (producerImpl == null) { - return; - } - producerImpl.registerSendMessageHook(new TenantRocketMQSendMessageHook()); - } - - private void initTenantConsumer(DefaultMQPushConsumer consumer) { - if (consumer == null) { - return; - } - DefaultMQPushConsumerImpl consumerImpl = consumer.getDefaultMQPushConsumerImpl(); - if (consumerImpl == null) { - return; - } - consumerImpl.registerConsumeMessageHook(new TenantRocketMQConsumeMessageHook()); - } - -} \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rocketmq/TenantRocketMQSendMessageHook.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rocketmq/TenantRocketMQSendMessageHook.java deleted file mode 100644 index 4f03074..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rocketmq/TenantRocketMQSendMessageHook.java +++ /dev/null @@ -1,36 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.mq.rocketmq; - -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import org.apache.rocketmq.client.hook.SendMessageContext; -import org.apache.rocketmq.client.hook.SendMessageHook; - -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; - -/** - * RocketMQ 消息队列的多租户 {@link SendMessageHook} 实现类 - * - * Producer 发送消息时,将 {@link TenantContextHolder} 租户编号,添加到消息的 Header 中 - * - * @author 芋道源码 - */ -public class TenantRocketMQSendMessageHook implements SendMessageHook { - - @Override - public String hookName() { - return getClass().getSimpleName(); - } - - @Override - public void sendMessageBefore(SendMessageContext sendMessageContext) { - Long tenantId = TenantContextHolder.getTenantId(); - if (tenantId == null) { - return; - } - sendMessageContext.getMessage().putUserProperty(HEADER_TENANT_ID, tenantId.toString()); - } - - @Override - public void sendMessageAfter(SendMessageContext sendMessageContext) { - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/redis/TenantRedisCacheManager.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/redis/TenantRedisCacheManager.java deleted file mode 100644 index aeea4b5..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/redis/TenantRedisCacheManager.java +++ /dev/null @@ -1,46 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.redis; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.redis.core.TimeoutRedisCacheManager; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import lombok.extern.slf4j.Slf4j; -import org.springframework.cache.Cache; -import org.springframework.data.redis.cache.RedisCacheConfiguration; -import org.springframework.data.redis.cache.RedisCacheManager; -import org.springframework.data.redis.cache.RedisCacheWriter; - -import java.util.Set; - -/** - * 多租户的 {@link RedisCacheManager} 实现类 - * - * 操作指定 name 的 {@link Cache} 时,自动拼接租户后缀,格式为 name + ":" + tenantId + 后缀 - * - * @author airhead - */ -@Slf4j -public class TenantRedisCacheManager extends TimeoutRedisCacheManager { - - private final Set ignoreCaches; - - public TenantRedisCacheManager(RedisCacheWriter cacheWriter, - RedisCacheConfiguration defaultCacheConfiguration, - Set ignoreCaches) { - super(cacheWriter, defaultCacheConfiguration); - this.ignoreCaches = ignoreCaches; - } - - @Override - public Cache getCache(String name) { - // 如果开启多租户,则 name 拼接租户后缀 - if (!TenantContextHolder.isIgnore() - && TenantContextHolder.getTenantId() != null - && !CollUtil.contains(ignoreCaches, name)) { - name = name + ":" + TenantContextHolder.getTenantId(); - } - - // 继续基于父方法 - return super.getCache(name); - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java deleted file mode 100644 index c6d4d5e..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java +++ /dev/null @@ -1,117 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.security; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; -import cn.iocoder.yudao.framework.security.core.LoginUser; -import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; -import cn.iocoder.yudao.framework.tenant.config.TenantProperties; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService; -import cn.iocoder.yudao.framework.web.config.WebProperties; -import cn.iocoder.yudao.framework.web.core.filter.ApiRequestFilter; -import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler; -import lombok.extern.slf4j.Slf4j; -import org.springframework.util.AntPathMatcher; - -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.Objects; - -/** - * 多租户 Security Web 过滤器 - * 1. 如果是登陆的用户,校验是否有权限访问该租户,避免越权问题。 - * 2. 如果请求未带租户的编号,检查是否是忽略的 URL,否则也不允许访问。 - * 3. 校验租户是合法,例如说被禁用、到期 - * - * @author 芋道源码 - */ -@Slf4j -public class TenantSecurityWebFilter extends ApiRequestFilter { - - private final TenantProperties tenantProperties; - - private final AntPathMatcher pathMatcher; - - private final GlobalExceptionHandler globalExceptionHandler; - private final TenantFrameworkService tenantFrameworkService; - - public TenantSecurityWebFilter(TenantProperties tenantProperties, - WebProperties webProperties, - GlobalExceptionHandler globalExceptionHandler, - TenantFrameworkService tenantFrameworkService) { - super(webProperties); - this.tenantProperties = tenantProperties; - this.pathMatcher = new AntPathMatcher(); - this.globalExceptionHandler = globalExceptionHandler; - this.tenantFrameworkService = tenantFrameworkService; - } - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) - throws ServletException, IOException { - Long tenantId = TenantContextHolder.getTenantId(); - // 1. 登陆的用户,校验是否有权限访问该租户,避免越权问题。 - LoginUser user = SecurityFrameworkUtils.getLoginUser(); - if (user != null) { - // 如果获取不到租户编号,则尝试使用登陆用户的租户编号 - if (tenantId == null) { - tenantId = user.getTenantId(); - TenantContextHolder.setTenantId(tenantId); - // 如果传递了租户编号,则进行比对租户编号,避免越权问题 - } else if (!Objects.equals(user.getTenantId(), TenantContextHolder.getTenantId())) { - log.error("[doFilterInternal][租户({}) User({}/{}) 越权访问租户({}) URL({}/{})]", - user.getTenantId(), user.getId(), user.getUserType(), - TenantContextHolder.getTenantId(), request.getRequestURI(), request.getMethod()); - ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.FORBIDDEN.getCode(), - "您无权访问该租户的数据")); - return; - } - } - - // 如果非允许忽略租户的 URL,则校验租户是否合法 - if (!isIgnoreUrl(request)) { - // 2. 如果请求未带租户的编号,不允许访问。 - if (tenantId == null) { - log.error("[doFilterInternal][URL({}/{}) 未传递租户编号]", request.getRequestURI(), request.getMethod()); - ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), - "请求的租户标识未传递,请进行排查")); - return; - } - // 3. 校验租户是合法,例如说被禁用、到期 - try { - tenantFrameworkService.validTenant(tenantId); - } catch (Throwable ex) { - CommonResult result = globalExceptionHandler.allExceptionHandler(request, ex); - ServletUtils.writeJSON(response, result); - return; - } - } else { // 如果是允许忽略租户的 URL,若未传递租户编号,则默认忽略租户编号,避免报错 - if (tenantId == null) { - TenantContextHolder.setIgnore(true); - } - } - - // 继续过滤 - chain.doFilter(request, response); - } - - private boolean isIgnoreUrl(HttpServletRequest request) { - // 快速匹配,保证性能 - if (CollUtil.contains(tenantProperties.getIgnoreUrls(), request.getRequestURI())) { - return true; - } - // 逐个 Ant 路径匹配 - for (String url : tenantProperties.getIgnoreUrls()) { - if (pathMatcher.match(url, request.getRequestURI())) { - return true; - } - } - return false; - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkService.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkService.java deleted file mode 100644 index 2ca474d..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkService.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.service; - -import java.util.List; - -/** - * Tenant 框架 Service 接口,定义获取租户信息 - * - * @author 芋道源码 - */ -public interface TenantFrameworkService { - - /** - * 获得所有租户 - * - * @return 租户编号数组 - */ - List getTenantIds(); - - /** - * 校验租户是否合法 - * - * @param id 租户编号 - */ - void validTenant(Long id); - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkServiceImpl.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkServiceImpl.java deleted file mode 100644 index f2b7b27..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkServiceImpl.java +++ /dev/null @@ -1,73 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.service; - -import cn.iocoder.yudao.framework.common.exception.ServiceException; -import cn.iocoder.yudao.framework.common.util.cache.CacheUtils; -import cn.iocoder.yudao.module.system.api.tenant.TenantApi; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import lombok.RequiredArgsConstructor; -import lombok.SneakyThrows; - -import java.time.Duration; -import java.util.List; - -/** - * Tenant 框架 Service 实现类 - * - * @author 芋道源码 - */ -@RequiredArgsConstructor -public class TenantFrameworkServiceImpl implements TenantFrameworkService { - - private static final ServiceException SERVICE_EXCEPTION_NULL = new ServiceException(); - - private final TenantApi tenantApi; - - /** - * 针对 {@link #getTenantIds()} 的缓存 - */ - private final LoadingCache> getTenantIdsCache = CacheUtils.buildAsyncReloadingCache( - Duration.ofMinutes(1L), // 过期时间 1 分钟 - new CacheLoader>() { - - @Override - public List load(Object key) { - return tenantApi.getTenantIdList(); - } - - }); - - /** - * 针对 {@link #validTenant(Long)} 的缓存 - */ - private final LoadingCache validTenantCache = CacheUtils.buildAsyncReloadingCache( - Duration.ofMinutes(1L), // 过期时间 1 分钟 - new CacheLoader() { - - @Override - public ServiceException load(Long id) { - try { - tenantApi.validateTenant(id); - return SERVICE_EXCEPTION_NULL; - } catch (ServiceException ex) { - return ex; - } - } - - }); - - @Override - @SneakyThrows - public List getTenantIds() { - return getTenantIdsCache.get(Boolean.TRUE); - } - - @Override - public void validTenant(Long id) { - ServiceException serviceException = validTenantCache.getUnchecked(id); - if (serviceException != SERVICE_EXCEPTION_NULL) { - throw serviceException; - } - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/util/TenantUtils.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/util/TenantUtils.java deleted file mode 100644 index b05b3c0..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/util/TenantUtils.java +++ /dev/null @@ -1,113 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.util; - -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; - -import java.util.Map; -import java.util.concurrent.Callable; - -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; - -/** - * 多租户 Util - * - * @author 芋道源码 - */ -public class TenantUtils { - - /** - * 使用指定租户,执行对应的逻辑 - * - * 注意,如果当前是忽略租户的情况下,会被强制设置成不忽略租户 - * 当然,执行完成后,还是会恢复回去 - * - * @param tenantId 租户编号 - * @param runnable 逻辑 - */ - public static void execute(Long tenantId, Runnable runnable) { - Long oldTenantId = TenantContextHolder.getTenantId(); - Boolean oldIgnore = TenantContextHolder.isIgnore(); - try { - TenantContextHolder.setTenantId(tenantId); - TenantContextHolder.setIgnore(false); - // 执行逻辑 - runnable.run(); - } finally { - TenantContextHolder.setTenantId(oldTenantId); - TenantContextHolder.setIgnore(oldIgnore); - } - } - - /** - * 使用指定租户,执行对应的逻辑 - * - * 注意,如果当前是忽略租户的情况下,会被强制设置成不忽略租户 - * 当然,执行完成后,还是会恢复回去 - * - * @param tenantId 租户编号 - * @param callable 逻辑 - * @return 结果 - */ - public static V execute(Long tenantId, Callable callable) { - Long oldTenantId = TenantContextHolder.getTenantId(); - Boolean oldIgnore = TenantContextHolder.isIgnore(); - try { - TenantContextHolder.setTenantId(tenantId); - TenantContextHolder.setIgnore(false); - // 执行逻辑 - return callable.call(); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - TenantContextHolder.setTenantId(oldTenantId); - TenantContextHolder.setIgnore(oldIgnore); - } - } - - /** - * 忽略租户,执行对应的逻辑 - * - * @param runnable 逻辑 - */ - public static void executeIgnore(Runnable runnable) { - Boolean oldIgnore = TenantContextHolder.isIgnore(); - try { - TenantContextHolder.setIgnore(true); - // 执行逻辑 - runnable.run(); - } finally { - TenantContextHolder.setIgnore(oldIgnore); - } - } - - /** - * 忽略租户,执行对应的逻辑 - * - * @param callable 逻辑 - * @return 结果 - */ - public static V executeIgnore(Callable callable) { - Boolean oldIgnore = TenantContextHolder.isIgnore(); - try { - TenantContextHolder.setIgnore(true); - // 执行逻辑 - return callable.call(); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - TenantContextHolder.setIgnore(oldIgnore); - } - } - - /** - * 将多租户编号,添加到 header 中 - * - * @param headers HTTP 请求 headers - * @param tenantId 租户编号 - */ - public static void addTenantHeader(Map headers, Long tenantId) { - if (tenantId != null) { - headers.put(HEADER_TENANT_ID, tenantId.toString()); - } - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/web/TenantContextWebFilter.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/web/TenantContextWebFilter.java deleted file mode 100644 index 41b7b4d..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/web/TenantContextWebFilter.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.framework.tenant.core.web; - -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; -import org.springframework.web.filter.OncePerRequestFilter; - -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * 多租户 Context Web 过滤器 - * 将请求 Header 中的 tenant-id 解析出来,添加到 {@link TenantContextHolder} 中,这样后续的 DB 等操作,可以获得到租户编号。 - * - * @author 芋道源码 - */ -public class TenantContextWebFilter extends OncePerRequestFilter { - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) - throws ServletException, IOException { - // 设置 - Long tenantId = WebFrameworkUtils.getTenantId(request); - if (tenantId != null) { - TenantContextHolder.setTenantId(tenantId); - } - try { - chain.doFilter(request, response); - } finally { - // 清理 - TenantContextHolder.clear(); - } - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/package-info.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/package-info.java deleted file mode 100644 index aa22cdb..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/package-info.java +++ /dev/null @@ -1,17 +0,0 @@ -/** - * 多租户,支持如下层面: - * 1. DB:基于 MyBatis Plus 多租户的功能实现。 - * 2. Redis:通过在 Redis Key 上拼接租户编号的方式,进行隔离。 - * 3. Web:请求 HTTP API 时,解析 Header 的 tenant-id 租户编号,添加到租户上下文。 - * 4. Security:校验当前登陆的用户,是否越权访问其它租户的数据。 - * 5. Job:在 JobHandler 执行任务时,会按照每个租户,都独立并行执行一次。 - * 6. MQ:在 Producer 发送消息时,Header 带上 tenant-id 租户编号;在 Consumer 消费消息时,将 Header 的 tenant-id 租户编号,添加到租户上下文。 - * 7. Async:异步需要保证 ThreadLocal 的传递性,通过使用阿里开源的 TransmittableThreadLocal 实现。相关的改造点,可见: - * 1)Spring Async: - * {@link cn.iocoder.yudao.framework.quartz.config.YudaoAsyncAutoConfiguration#threadPoolTaskExecutorBeanPostProcessor()} - * 2)Spring Security: - * TransmittableThreadLocalSecurityContextHolderStrategy - * 和 YudaoSecurityAutoConfiguration#securityContextHolderMethodInvokingFactoryBean() 方法 - * - */ -package cn.iocoder.yudao.framework.tenant; diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java deleted file mode 100644 index de330fd..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright 2002-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.messaging.handler.invocation; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.util.Arrays; - -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; -import org.springframework.core.DefaultParameterNameDiscoverer; -import org.springframework.core.MethodParameter; -import org.springframework.core.ParameterNameDiscoverer; -import org.springframework.core.ResolvableType; -import org.springframework.lang.Nullable; -import org.springframework.messaging.Message; -import org.springframework.messaging.handler.HandlerMethod; -import org.springframework.util.ObjectUtils; - -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; - -/** - * Extension of {@link HandlerMethod} that invokes the underlying method with - * argument values resolved from the current HTTP request through a list of - * {@link HandlerMethodArgumentResolver}. - * - * 针对 rabbitmq-spring 和 kafka-spring,不存在合适的拓展点,可以实现 Consumer 消费前,读取 Header 中的 tenant-id 设置到 {@link TenantContextHolder} 中 - * TODO 芋艿:持续跟进,看看有没新的拓展点 - * - * @author Rossen Stoyanchev - * @author Juergen Hoeller - * @since 4.0 - */ -public class InvocableHandlerMethod extends HandlerMethod { - - private static final Object[] EMPTY_ARGS = new Object[0]; - - - private HandlerMethodArgumentResolverComposite resolvers = new HandlerMethodArgumentResolverComposite(); - - private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer(); - - - /** - * Create an instance from a {@code HandlerMethod}. - */ - public InvocableHandlerMethod(HandlerMethod handlerMethod) { - super(handlerMethod); - } - - /** - * Create an instance from a bean instance and a method. - */ - public InvocableHandlerMethod(Object bean, Method method) { - super(bean, method); - } - - /** - * Construct a new handler method with the given bean instance, method name and parameters. - * @param bean the object bean - * @param methodName the method name - * @param parameterTypes the method parameter types - * @throws NoSuchMethodException when the method cannot be found - */ - public InvocableHandlerMethod(Object bean, String methodName, Class... parameterTypes) - throws NoSuchMethodException { - - super(bean, methodName, parameterTypes); - } - - - /** - * Set {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers} to use for resolving method argument values. - */ - public void setMessageMethodArgumentResolvers(HandlerMethodArgumentResolverComposite argumentResolvers) { - this.resolvers = argumentResolvers; - } - - /** - * Set the ParameterNameDiscoverer for resolving parameter names when needed - * (e.g. default request attribute name). - *

Default is a {@link org.springframework.core.DefaultParameterNameDiscoverer}. - */ - public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) { - this.parameterNameDiscoverer = parameterNameDiscoverer; - } - - - /** - * Invoke the method after resolving its argument values in the context of the given message. - *

Argument values are commonly resolved through - * {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}. - * The {@code providedArgs} parameter however may supply argument values to be used directly, - * i.e. without argument resolution. - *

Delegates to {@link #getMethodArgumentValues} and calls {@link #doInvoke} with the - * resolved arguments. - * @param message the current message being processed - * @param providedArgs "given" arguments matched by type, not resolved - * @return the raw value returned by the invoked method - * @throws Exception raised if no suitable argument resolver can be found, - * or if the method raised an exception - * @see #getMethodArgumentValues - * @see #doInvoke - */ - @Nullable - public Object invoke(Message message, Object... providedArgs) throws Exception { - Object[] args = getMethodArgumentValues(message, providedArgs); - if (logger.isTraceEnabled()) { - logger.trace("Arguments: " + Arrays.toString(args)); - } - // 注意:如下是本类的改动点!!! - // 情况一:无租户编号的情况 - Long tenantId= parseTenantId(message); - if (tenantId == null) { - return doInvoke(args); - } - // 情况二:有租户的情况下 - return TenantUtils.execute(tenantId, () -> doInvoke(args)); - } - - private Long parseTenantId(Message message) { - Object tenantId = message.getHeaders().get(HEADER_TENANT_ID); - if (tenantId == null) { - return null; - } - if (tenantId instanceof Long) { - return (Long) tenantId; - } - if (tenantId instanceof Number) { - return ((Number) tenantId).longValue(); - } - if (tenantId instanceof String) { - return Long.parseLong((String) tenantId); - } - if (tenantId instanceof byte[]) { - return Long.parseLong(new String((byte[]) tenantId)); - } - throw new IllegalArgumentException("未知的数据类型:" + tenantId); - } - - /** - * Get the method argument values for the current message, checking the provided - * argument values and falling back to the configured argument resolvers. - *

The resulting array will be passed into {@link #doInvoke}. - * @since 5.1.2 - */ - protected Object[] getMethodArgumentValues(Message message, Object... providedArgs) throws Exception { - MethodParameter[] parameters = getMethodParameters(); - if (ObjectUtils.isEmpty(parameters)) { - return EMPTY_ARGS; - } - - Object[] args = new Object[parameters.length]; - for (int i = 0; i < parameters.length; i++) { - MethodParameter parameter = parameters[i]; - parameter.initParameterNameDiscovery(this.parameterNameDiscoverer); - args[i] = findProvidedArgument(parameter, providedArgs); - if (args[i] != null) { - continue; - } - if (!this.resolvers.supportsParameter(parameter)) { - throw new MethodArgumentResolutionException( - message, parameter, formatArgumentError(parameter, "No suitable resolver")); - } - try { - args[i] = this.resolvers.resolveArgument(parameter, message); - } - catch (Exception ex) { - // Leave stack trace for later, exception may actually be resolved and handled... - if (logger.isDebugEnabled()) { - String exMsg = ex.getMessage(); - if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) { - logger.debug(formatArgumentError(parameter, exMsg)); - } - } - throw ex; - } - } - return args; - } - - /** - * Invoke the handler method with the given argument values. - */ - @Nullable - protected Object doInvoke(Object... args) throws Exception { - try { - return getBridgedMethod().invoke(getBean(), args); - } - catch (IllegalArgumentException ex) { - assertTargetBean(getBridgedMethod(), getBean(), args); - String text = (ex.getMessage() == null || ex.getCause() instanceof NullPointerException) ? - "Illegal argument": ex.getMessage(); - throw new IllegalStateException(formatInvokeError(text, args), ex); - } - catch (InvocationTargetException ex) { - // Unwrap for HandlerExceptionResolvers ... - Throwable targetException = ex.getTargetException(); - if (targetException instanceof RuntimeException runtimeException) { - throw runtimeException; - } - else if (targetException instanceof Error error) { - throw error; - } - else if (targetException instanceof Exception exception) { - throw exception; - } - else { - throw new IllegalStateException(formatInvokeError("Invocation failure", args), targetException); - } - } - } - - MethodParameter getAsyncReturnValueType(@Nullable Object returnValue) { - return new AsyncResultMethodParameter(returnValue); - } - - - private class AsyncResultMethodParameter extends AnnotatedMethodParameter { - - @Nullable - private final Object returnValue; - - private final ResolvableType returnType; - - public AsyncResultMethodParameter(@Nullable Object returnValue) { - super(-1); - this.returnValue = returnValue; - this.returnType = ResolvableType.forType(super.getGenericParameterType()).getGeneric(); - } - - protected AsyncResultMethodParameter(AsyncResultMethodParameter original) { - super(original); - this.returnValue = original.returnValue; - this.returnType = original.returnType; - } - - @Override - public Class getParameterType() { - if (this.returnValue != null) { - return this.returnValue.getClass(); - } - if (!ResolvableType.NONE.equals(this.returnType)) { - return this.returnType.toClass(); - } - return super.getParameterType(); - } - - @Override - public Type getGenericParameterType() { - return this.returnType.getType(); - } - - @Override - public AsyncResultMethodParameter clone() { - return new AsyncResultMethodParameter(this); - } - } - -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/resources/META-INF/spring.factories b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/resources/META-INF/spring.factories deleted file mode 100644 index a495842..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.env.EnvironmentPostProcessor=\ - cn.iocoder.yudao.framework.tenant.core.mq.kafka.TenantKafkaEnvironmentPostProcessor diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index 603831e..0000000 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1 +0,0 @@ -cn.iocoder.yudao.framework.tenant.config.YudaoTenantAutoConfiguration \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-websocket/pom.xml b/yudao-framework/yudao-spring-boot-starter-websocket/pom.xml index b534f10..282077c 100644 --- a/yudao-framework/yudao-spring-boot-starter-websocket/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-websocket/pom.xml @@ -60,14 +60,14 @@ - - - cn.iocoder.boot - yudao-spring-boot-starter-biz-tenant - provided - + + + + + + + + \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/handler/JsonWebSocketMessageHandler.java b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/handler/JsonWebSocketMessageHandler.java index 120f529..f9a52e5 100644 --- a/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/handler/JsonWebSocketMessageHandler.java +++ b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/handler/JsonWebSocketMessageHandler.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.websocket.core.handler; import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.TypeUtil; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; +//import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.framework.websocket.core.listener.WebSocketMessageListener; import cn.iocoder.yudao.framework.websocket.core.message.JsonWebSocketMessage; import cn.iocoder.yudao.framework.websocket.core.util.WebSocketFrameworkUtils; @@ -74,7 +74,7 @@ public class JsonWebSocketMessageHandler extends TextWebSocketHandler { Type type = TypeUtil.getTypeArgument(messageListener.getClass(), 0); Object messageObj = JsonUtils.parseObject(jsonMessage.getContent(), type); Long tenantId = WebSocketFrameworkUtils.getTenantId(session); - TenantUtils.execute(tenantId, () -> messageListener.onMessage(session, messageObj)); +// TenantUtils.execute(tenantId, () -> messageListener.onMessage(session, messageObj)); } catch (Throwable ex) { log.error("[handleTextMessage][session({}) message({}) 处理异常]", session.getId(), message.getPayload()); } diff --git a/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/session/WebSocketSessionManagerImpl.java b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/session/WebSocketSessionManagerImpl.java index 6dba898..54311d2 100644 --- a/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/session/WebSocketSessionManagerImpl.java +++ b/yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/session/WebSocketSessionManagerImpl.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.framework.websocket.core.session; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.security.core.LoginUser; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +//import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.framework.websocket.core.util.WebSocketFrameworkUtils; import org.springframework.web.socket.WebSocketSession; @@ -95,18 +95,18 @@ public class WebSocketSessionManagerImpl implements WebSocketSessionManager { return new ArrayList<>(); } LinkedList result = new LinkedList<>(); // 避免扩容 - Long contextTenantId = TenantContextHolder.getTenantId(); +// Long contextTenantId = TenantContextHolder.getTenantId(); for (List sessions : userSessionsMap.values()) { if (CollUtil.isEmpty(sessions)) { continue; } // 特殊:如果租户不匹配,则直接排除 - if (contextTenantId != null) { - Long userTenantId = WebSocketFrameworkUtils.getTenantId(sessions.get(0)); - if (!contextTenantId.equals(userTenantId)) { - continue; - } - } +// if (contextTenantId != null) { +// Long userTenantId = WebSocketFrameworkUtils.getTenantId(sessions.get(0)); +// if (!contextTenantId.equals(userTenantId)) { +// continue; +// } +// } result.addAll(sessions); } return result; diff --git a/yudao-module-alert/yudao-moudle-alert-api/pom.xml b/yudao-module-alert/yudao-moudle-alert-api/pom.xml new file mode 100644 index 0000000..c4ef07d --- /dev/null +++ b/yudao-module-alert/yudao-moudle-alert-api/pom.xml @@ -0,0 +1,26 @@ + + + + cn.iocoder.boot + yudao-module-alert + ${revision} + + 4.0.0 + yudao-module-alert-api + jar + + ${project.artifactId} + + alert 模块 API,暴露给其它模块调用 + + + + + cn.iocoder.boot + yudao-common + + + + diff --git a/yudao-module-infra/yudao-module-infra-biz/pom.xml b/yudao-module-infra/yudao-module-infra-biz/pom.xml index 2416812..d59965b 100644 --- a/yudao-module-infra/yudao-module-infra-biz/pom.xml +++ b/yudao-module-infra/yudao-module-infra-biz/pom.xml @@ -30,11 +30,11 @@ ${revision} - - - cn.iocoder.boot - yudao-spring-boot-starter-biz-tenant - + + + + + diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/job/JobLogCleanJob.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/job/JobLogCleanJob.java index f2e6f42..39e9193 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/job/JobLogCleanJob.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/job/JobLogCleanJob.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.infra.job.job; import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; -import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; +//import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.infra.service.job.JobLogService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -30,7 +30,7 @@ public class JobLogCleanJob implements JobHandler { private static final Integer DELETE_LIMIT = 100; @Override - @TenantIgnore +// @TenantIgnore public String execute(String param) { Integer count = jobLogService.cleanJobLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT); log.info("[execute][定时执行清理定时任务日志数量 ({}) 个]", count); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/AccessLogCleanJob.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/AccessLogCleanJob.java index 23a277b..87a6fcf 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/AccessLogCleanJob.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/AccessLogCleanJob.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.infra.job.logger; import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; -import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; +//import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.infra.service.logger.ApiAccessLogService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -31,7 +31,7 @@ public class AccessLogCleanJob implements JobHandler { private static final Integer DELETE_LIMIT = 100; @Override - @TenantIgnore +// @TenantIgnore public String execute(String param) { Integer count = apiAccessLogService.cleanAccessLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT); log.info("[execute][定时执行清理访问日志数量 ({}) 个]", count); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/ErrorLogCleanJob.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/ErrorLogCleanJob.java index 8b3b566..d028cba 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/ErrorLogCleanJob.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/ErrorLogCleanJob.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.infra.job.logger; import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; -import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; +//import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.infra.service.logger.ApiErrorLogService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -31,7 +31,7 @@ public class ErrorLogCleanJob implements JobHandler { private static final Integer DELETE_LIMIT = 100; @Override - @TenantIgnore +// @TenantIgnore public String execute(String param) { Integer count = apiErrorLogService.cleanErrorLog(JOB_CLEAN_RETAIN_DAY,DELETE_LIMIT); log.info("[execute][定时执行清理错误日志数量 ({}) 个]", count); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiAccessLogServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiAccessLogServiceImpl.java index 4433fc2..4813cec 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiAccessLogServiceImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiAccessLogServiceImpl.java @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.infra.service.logger; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.string.StrUtils; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; +//import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +//import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO; import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO; import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiAccessLogDO; @@ -37,12 +37,13 @@ public class ApiAccessLogServiceImpl implements ApiAccessLogService { ApiAccessLogDO apiAccessLog = BeanUtils.toBean(createDTO, ApiAccessLogDO.class); apiAccessLog.setRequestParams(StrUtils.maxLength(apiAccessLog.getRequestParams(), REQUEST_PARAMS_MAX_LENGTH)); apiAccessLog.setResultMsg(StrUtils.maxLength(apiAccessLog.getResultMsg(), RESULT_MSG_MAX_LENGTH)); - if (TenantContextHolder.getTenantId() != null) { - apiAccessLogMapper.insert(apiAccessLog); - } else { - // 极端情况下,上下文中没有租户时,此时忽略租户上下文,避免插入失败! - TenantUtils.executeIgnore(() -> apiAccessLogMapper.insert(apiAccessLog)); - } +// if (TenantContextHolder.getTenantId() != null) { +// apiAccessLogMapper.insert(apiAccessLog); +// } else { +// // 极端情况下,上下文中没有租户时,此时忽略租户上下文,避免插入失败! +// TenantUtils.executeIgnore(() -> apiAccessLogMapper.insert(apiAccessLog)); +// } + apiAccessLogMapper.insert(apiAccessLog); } @Override diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImpl.java index 1fcbc8d..ef2b582 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImpl.java @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.infra.service.logger; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.string.StrUtils; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; +//import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +//import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO; import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO; import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO; @@ -40,12 +40,13 @@ public class ApiErrorLogServiceImpl implements ApiErrorLogService { ApiErrorLogDO apiErrorLog = BeanUtils.toBean(createDTO, ApiErrorLogDO.class) .setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus()); apiErrorLog.setRequestParams(StrUtils.maxLength(apiErrorLog.getRequestParams(), REQUEST_PARAMS_MAX_LENGTH)); - if (TenantContextHolder.getTenantId() != null) { - apiErrorLogMapper.insert(apiErrorLog); - } else { - // 极端情况下,上下文中没有租户时,此时忽略租户上下文,避免插入失败! - TenantUtils.executeIgnore(() -> apiErrorLogMapper.insert(apiErrorLog)); - } +// if (TenantContextHolder.getTenantId() != null) { +// apiErrorLogMapper.insert(apiErrorLog); +// } else { +// // 极端情况下,上下文中没有租户时,此时忽略租户上下文,避免插入失败! +// TenantUtils.executeIgnore(() -> apiErrorLogMapper.insert(apiErrorLog)); +// } + apiErrorLogMapper.insert(apiErrorLog); } @Override diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApi.java deleted file mode 100644 index 1fad83e..0000000 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApi.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.system.api.tenant; - -import java.util.List; - -/** - * 多租户的 API 接口 - * - * @author 芋道源码 - */ -public interface TenantApi { - - /** - * 获得所有租户 - * - * @return 租户编号数组 - */ - List getTenantIdList(); - - /** - * 校验租户是否合法 - * - * @param id 租户编号 - */ - void validateTenant(Long id); - -} diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index 6db0e56..c692b4a 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java @@ -102,18 +102,18 @@ public interface ErrorCodeConstants { ErrorCode SMS_CODE_SEND_TOO_FAST = new ErrorCode(1_002_014_005, "短信发送过于频繁"); // ========== 租户信息 1-002-015-000 ========== - ErrorCode TENANT_NOT_EXISTS = new ErrorCode(1_002_015_000, "租户不存在"); - ErrorCode TENANT_DISABLE = new ErrorCode(1_002_015_001, "名字为【{}】的租户已被禁用"); - ErrorCode TENANT_EXPIRE = new ErrorCode(1_002_015_002, "名字为【{}】的租户已过期"); - ErrorCode TENANT_CAN_NOT_UPDATE_SYSTEM = new ErrorCode(1_002_015_003, "系统租户不能进行修改、删除等操作!"); - ErrorCode TENANT_NAME_DUPLICATE = new ErrorCode(1_002_015_004, "名字为【{}】的租户已存在"); - ErrorCode TENANT_WEBSITE_DUPLICATE = new ErrorCode(1_002_015_005, "域名为【{}】的租户已存在"); +// ErrorCode TENANT_NOT_EXISTS = new ErrorCode(1_002_015_000, "租户不存在"); +// ErrorCode TENANT_DISABLE = new ErrorCode(1_002_015_001, "名字为【{}】的租户已被禁用"); +// ErrorCode TENANT_EXPIRE = new ErrorCode(1_002_015_002, "名字为【{}】的租户已过期"); +// ErrorCode TENANT_CAN_NOT_UPDATE_SYSTEM = new ErrorCode(1_002_015_003, "系统租户不能进行修改、删除等操作!"); +// ErrorCode TENANT_NAME_DUPLICATE = new ErrorCode(1_002_015_004, "名字为【{}】的租户已存在"); +// ErrorCode TENANT_WEBSITE_DUPLICATE = new ErrorCode(1_002_015_005, "域名为【{}】的租户已存在"); // ========== 租户套餐 1-002-016-000 ========== - ErrorCode TENANT_PACKAGE_NOT_EXISTS = new ErrorCode(1_002_016_000, "租户套餐不存在"); - ErrorCode TENANT_PACKAGE_USED = new ErrorCode(1_002_016_001, "租户正在使用该套餐,请给租户重新设置套餐后再尝试删除"); - ErrorCode TENANT_PACKAGE_DISABLE = new ErrorCode(1_002_016_002, "名字为【{}】的租户套餐已被禁用"); - ErrorCode TENANT_PACKAGE_NAME_DUPLICATE = new ErrorCode(1_002_016_003, "已经存在该名字的租户套餐"); +// ErrorCode TENANT_PACKAGE_NOT_EXISTS = new ErrorCode(1_002_016_000, "租户套餐不存在"); +// ErrorCode TENANT_PACKAGE_USED = new ErrorCode(1_002_016_001, "租户正在使用该套餐,请给租户重新设置套餐后再尝试删除"); +// ErrorCode TENANT_PACKAGE_DISABLE = new ErrorCode(1_002_016_002, "名字为【{}】的租户套餐已被禁用"); +// ErrorCode TENANT_PACKAGE_NAME_DUPLICATE = new ErrorCode(1_002_016_003, "已经存在该名字的租户套餐"); // ========== 社交用户 1-002-018-000 ========== ErrorCode SOCIAL_USER_AUTH_FAILURE = new ErrorCode(1_002_018_000, "社交授权失败,原因是:{}"); diff --git a/yudao-module-system/yudao-module-system-biz/pom.xml b/yudao-module-system/yudao-module-system-biz/pom.xml index 9d91162..bb028f8 100644 --- a/yudao-module-system/yudao-module-system-biz/pom.xml +++ b/yudao-module-system/yudao-module-system-biz/pom.xml @@ -34,10 +34,10 @@ cn.iocoder.boot yudao-spring-boot-starter-biz-data-permission - - cn.iocoder.boot - yudao-spring-boot-starter-biz-tenant - + + + + cn.iocoder.boot yudao-spring-boot-starter-biz-ip diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApiImpl.java deleted file mode 100644 index a25eac6..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApiImpl.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.system.api.tenant; - -import cn.iocoder.yudao.module.system.service.tenant.TenantService; -import org.springframework.stereotype.Service; - -import jakarta.annotation.Resource; -import java.util.List; - -/** - * 多租户的 API 实现类 - * - * @author 芋道源码 - */ -@Service -public class TenantApiImpl implements TenantApi { - - @Resource - private TenantService tenantService; - - @Override - public List getTenantIdList() { - return tenantService.getTenantIdList(); - } - - @Override - public void validateTenant(Long id) { - tenantService.validTenant(id); - } - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/PermissionController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/PermissionController.java index a7b7325..f2cee18 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/PermissionController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/PermissionController.java @@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.system.controller.admin.permission.vo.permission. import cn.iocoder.yudao.module.system.controller.admin.permission.vo.permission.PermissionAssignRoleMenuReqVO; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.permission.PermissionAssignUserRoleReqVO; import cn.iocoder.yudao.module.system.service.permission.PermissionService; -import cn.iocoder.yudao.module.system.service.tenant.TenantService; +//import cn.iocoder.yudao.module.system.service.tenant.TenantService; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Operation; @@ -32,8 +32,8 @@ public class PermissionController { @Resource private PermissionService permissionService; - @Resource - private TenantService tenantService; +// @Resource +// private TenantService tenantService; @Operation(summary = "获得角色拥有的菜单编号") @Parameter(name = "roleId", description = "角色编号", required = true) @@ -48,7 +48,7 @@ public class PermissionController { @PreAuthorize("@ss.hasPermission('system:permission:assign-role-menu')") public CommonResult assignRoleMenu(@Validated @RequestBody PermissionAssignRoleMenuReqVO reqVO) { // 开启多租户的情况下,需要过滤掉未开通的菜单 - tenantService.handleTenantMenu(menuIds -> reqVO.getMenuIds().removeIf(menuId -> !CollUtil.contains(menuIds, menuId))); +// tenantService.handleTenantMenu(menuIds -> reqVO.getMenuIds().removeIf(menuId -> !CollUtil.contains(menuIds, menuId))); // 执行菜单的分配 permissionService.assignRoleMenu(reqVO.getRoleId(), reqVO.getMenuIds()); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.http b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.http deleted file mode 100644 index 38aa594..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.http +++ /dev/null @@ -1,21 +0,0 @@ -### 获取租户编号 /admin-api/system/get-id-by-name -GET {{baseUrl}}/system/tenant/get-id-by-name?name=芋道源码 - -### 创建租户 /admin-api/system/tenant/create -POST {{baseUrl}}/system/tenant/create -Content-Type: application/json -Authorization: Bearer {{token}} -tenant-id: {{adminTenantId}} - -{ - "name": "芋道", - "contactName": "芋艿", - "contactMobile": "15601691300", - "status": 0, - "domain": "https://www.iocoder.cn", - "packageId": 110, - "expireTime": 1699545600000, - "accountCount": 20, - "username": "admin", - "password": "123321" -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java deleted file mode 100644 index f698b92..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java +++ /dev/null @@ -1,123 +0,0 @@ -package cn.iocoder.yudao.module.system.controller.admin.tenant; - -import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO; -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantRespVO; -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO; -import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO; -import cn.iocoder.yudao.module.system.service.tenant.TenantService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.annotation.Resource; -import jakarta.annotation.security.PermitAll; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.Valid; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.*; - -import java.io.IOException; -import java.util.List; - -import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; - -@Tag(name = "管理后台 - 租户") -@RestController -@RequestMapping("/system/tenant") -public class TenantController { - - @Resource - private TenantService tenantService; - - @GetMapping("/get-id-by-name") - @PermitAll - @Operation(summary = "使用租户名,获得租户编号", description = "登录界面,根据用户的租户名,获得租户编号") - @Parameter(name = "name", description = "租户名", required = true, example = "1024") - public CommonResult getTenantIdByName(@RequestParam("name") String name) { - TenantDO tenant = tenantService.getTenantByName(name); - return success(tenant != null ? tenant.getId() : null); - } - - @GetMapping({ "simple-list" }) - @PermitAll - @Operation(summary = "获取租户精简信息列表", description = "只包含被开启的租户,用于【首页】功能的选择租户选项") - public CommonResult> getTenantSimpleList() { - List list = tenantService.getTenantListByStatus(CommonStatusEnum.ENABLE.getStatus()); - return success(convertList(list, tenantDO -> - new TenantRespVO().setId(tenantDO.getId()).setName(tenantDO.getName()))); - } - - @GetMapping("/get-by-website") - @PermitAll - @Operation(summary = "使用域名,获得租户信息", description = "登录界面,根据用户的域名,获得租户信息") - @Parameter(name = "website", description = "域名", required = true, example = "www.iocoder.cn") - public CommonResult getTenantByWebsite(@RequestParam("website") String website) { - TenantDO tenant = tenantService.getTenantByWebsite(website); - if (tenant == null || CommonStatusEnum.isDisable(tenant.getStatus())) { - return success(null); - } - return success(new TenantRespVO().setId(tenant.getId()).setName(tenant.getName())); - } - - @PostMapping("/create") - @Operation(summary = "创建租户") - @PreAuthorize("@ss.hasPermission('system:tenant:create')") - public CommonResult createTenant(@Valid @RequestBody TenantSaveReqVO createReqVO) { - return success(tenantService.createTenant(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新租户") - @PreAuthorize("@ss.hasPermission('system:tenant:update')") - public CommonResult updateTenant(@Valid @RequestBody TenantSaveReqVO updateReqVO) { - tenantService.updateTenant(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除租户") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('system:tenant:delete')") - public CommonResult deleteTenant(@RequestParam("id") Long id) { - tenantService.deleteTenant(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得租户") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('system:tenant:query')") - public CommonResult getTenant(@RequestParam("id") Long id) { - TenantDO tenant = tenantService.getTenant(id); - return success(BeanUtils.toBean(tenant, TenantRespVO.class)); - } - - @GetMapping("/page") - @Operation(summary = "获得租户分页") - @PreAuthorize("@ss.hasPermission('system:tenant:query')") - public CommonResult> getTenantPage(@Valid TenantPageReqVO pageVO) { - PageResult pageResult = tenantService.getTenantPage(pageVO); - return success(BeanUtils.toBean(pageResult, TenantRespVO.class)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出租户 Excel") - @PreAuthorize("@ss.hasPermission('system:tenant:export')") - @ApiAccessLog(operateType = EXPORT) - public void exportTenantExcel(@Valid TenantPageReqVO exportReqVO, HttpServletResponse response) throws IOException { - exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = tenantService.getTenantPage(exportReqVO).getList(); - // 导出 Excel - ExcelUtils.write(response, "租户.xls", "数据", TenantRespVO.class, - BeanUtils.toBean(list, TenantRespVO.class)); - } - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantPackageController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantPackageController.java deleted file mode 100644 index ad9ab3d..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantPackageController.java +++ /dev/null @@ -1,80 +0,0 @@ -package cn.iocoder.yudao.module.system.controller.admin.tenant; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.*; -import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO; -import cn.iocoder.yudao.module.system.service.tenant.TenantPackageService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import jakarta.annotation.Resource; -import jakarta.validation.Valid; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "管理后台 - 租户套餐") -@RestController -@RequestMapping("/system/tenant-package") -@Validated -public class TenantPackageController { - - @Resource - private TenantPackageService tenantPackageService; - - @PostMapping("/create") - @Operation(summary = "创建租户套餐") - @PreAuthorize("@ss.hasPermission('system:tenant-package:create')") - public CommonResult createTenantPackage(@Valid @RequestBody TenantPackageSaveReqVO createReqVO) { - return success(tenantPackageService.createTenantPackage(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新租户套餐") - @PreAuthorize("@ss.hasPermission('system:tenant-package:update')") - public CommonResult updateTenantPackage(@Valid @RequestBody TenantPackageSaveReqVO updateReqVO) { - tenantPackageService.updateTenantPackage(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除租户套餐") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('system:tenant-package:delete')") - public CommonResult deleteTenantPackage(@RequestParam("id") Long id) { - tenantPackageService.deleteTenantPackage(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得租户套餐") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('system:tenant-package:query')") - public CommonResult getTenantPackage(@RequestParam("id") Long id) { - TenantPackageDO tenantPackage = tenantPackageService.getTenantPackage(id); - return success(BeanUtils.toBean(tenantPackage, TenantPackageRespVO.class)); - } - - @GetMapping("/page") - @Operation(summary = "获得租户套餐分页") - @PreAuthorize("@ss.hasPermission('system:tenant-package:query')") - public CommonResult> getTenantPackagePage(@Valid TenantPackagePageReqVO pageVO) { - PageResult pageResult = tenantPackageService.getTenantPackagePage(pageVO); - return success(BeanUtils.toBean(pageResult, TenantPackageRespVO.class)); - } - - @GetMapping({"/get-simple-list", "simple-list"}) - @Operation(summary = "获取租户套餐精简信息列表", description = "只包含被开启的租户套餐,主要用于前端的下拉选项") - public CommonResult> getTenantPackageList() { - List list = tenantPackageService.getTenantPackageListByStatus(CommonStatusEnum.ENABLE.getStatus()); - return success(BeanUtils.toBean(list, TenantPackageSimpleRespVO.class)); - } - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java deleted file mode 100644 index 525a5da..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@Schema(description = "管理后台 - 租户套餐分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class TenantPackagePageReqVO extends PageParam { - - @Schema(description = "套餐名", example = "VIP") - private String name; - - @Schema(description = "状态", example = "1") - private Integer status; - - @Schema(description = "备注", example = "好") - private String remark; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(description = "创建时间") - private LocalDateTime[] createTime; -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java deleted file mode 100644 index 16ffd81..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; -import java.util.Set; - -@Schema(description = "管理后台 - 租户套餐 Response VO") -@Data -public class TenantPackageRespVO { - - @Schema(description = "套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long id; - - @Schema(description = "套餐名", requiredMode = Schema.RequiredMode.REQUIRED, example = "VIP") - private String name; - - @Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer status; - - @Schema(description = "备注", example = "好") - private String remark; - - @Schema(description = "关联的菜单编号", requiredMode = Schema.RequiredMode.REQUIRED) - private Set menuIds; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime createTime; - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSaveReqVO.java deleted file mode 100644 index 748283b..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSaveReqVO.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import java.util.Set; - -@Schema(description = "管理后台 - 租户套餐创建/修改 Request VO") -@Data -public class TenantPackageSaveReqVO { - - @Schema(description = "套餐编号", example = "1024") - private Long id; - - @Schema(description = "套餐名", requiredMode = Schema.RequiredMode.REQUIRED, example = "VIP") - @NotEmpty(message = "套餐名不能为空") - private String name; - - @Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "状态不能为空") - @InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}") - private Integer status; - - @Schema(description = "备注", example = "好") - private String remark; - - @Schema(description = "关联的菜单编号", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "关联的菜单编号不能为空") - private Set menuIds; - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSimpleRespVO.java deleted file mode 100644 index 5611731..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSimpleRespVO.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import jakarta.validation.constraints.NotNull; - -@Schema(description = "管理后台 - 租户套餐精简 Response VO") -@Data -public class TenantPackageSimpleRespVO { - - @Schema(description = "套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - @NotNull(message = "套餐编号不能为空") - private Long id; - - @Schema(description = "套餐名", requiredMode = Schema.RequiredMode.REQUIRED, example = "VIP") - @NotNull(message = "套餐名不能为空") - private String name; - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java deleted file mode 100644 index 512a4a7..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java +++ /dev/null @@ -1,36 +0,0 @@ -package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@Schema(description = "管理后台 - 租户分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class TenantPageReqVO extends PageParam { - - @Schema(description = "租户名", example = "芋道") - private String name; - - @Schema(description = "联系人", example = "芋艿") - private String contactName; - - @Schema(description = "联系手机", example = "15601691300") - private String contactMobile; - - @Schema(description = "租户状态(0正常 1停用)", example = "1") - private Integer status; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(description = "创建时间") - private LocalDateTime[] createTime; - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java deleted file mode 100644 index 5a444b5..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java +++ /dev/null @@ -1,55 +0,0 @@ -package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant; - -import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; -import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; -import cn.iocoder.yudao.module.system.enums.DictTypeConstants; -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.excel.annotation.ExcelProperty; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 租户 Response VO") -@Data -@ExcelIgnoreUnannotated -public class TenantRespVO { - - @Schema(description = "租户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - @ExcelProperty("租户编号") - private Long id; - - @Schema(description = "租户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") - @ExcelProperty("租户名") - private String name; - - @Schema(description = "联系人", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") - @ExcelProperty("联系人") - private String contactName; - - @Schema(description = "联系手机", example = "15601691300") - @ExcelProperty("联系手机") - private String contactMobile; - - @Schema(description = "租户状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @ExcelProperty(value = "状态", converter = DictConvert.class) - @DictFormat(DictTypeConstants.COMMON_STATUS) - private Integer status; - - @Schema(description = "绑定域名", example = "https://www.iocoder.cn") - private String website; - - @Schema(description = "租户套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long packageId; - - @Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime expireTime; - - @Schema(description = "账号数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Integer accountCount; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("创建时间") - private LocalDateTime createTime; - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantSaveReqVO.java deleted file mode 100644 index 175afa3..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantSaveReqVO.java +++ /dev/null @@ -1,70 +0,0 @@ -package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant; - -import cn.hutool.core.util.ObjectUtil; -import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import org.hibernate.validator.constraints.Length; - -import jakarta.validation.constraints.AssertTrue; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Pattern; -import jakarta.validation.constraints.Size; -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 租户创建/修改 Request VO") -@Data -public class TenantSaveReqVO { - - @Schema(description = "租户编号", example = "1024") - private Long id; - - @Schema(description = "租户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") - @NotNull(message = "租户名不能为空") - private String name; - - @Schema(description = "联系人", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") - @NotNull(message = "联系人不能为空") - private String contactName; - - @Schema(description = "联系手机", example = "15601691300") - private String contactMobile; - - @Schema(description = "租户状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "租户状态") - private Integer status; - - @Schema(description = "绑定域名", example = "https://www.iocoder.cn") - private String website; - - @Schema(description = "租户套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - @NotNull(message = "租户套餐编号不能为空") - private Long packageId; - - @Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "过期时间不能为空") - private LocalDateTime expireTime; - - @Schema(description = "账号数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - @NotNull(message = "账号数量不能为空") - private Integer accountCount; - - // ========== 仅【创建】时,需要传递的字段 ========== - - @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao") - @Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成") - @Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符") - private String username; - - @Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456") - @Length(min = 4, max = 16, message = "密码长度为 4-16 位") - private String password; - - @AssertTrue(message = "用户账号、密码不能为空") - @JsonIgnore - public boolean isUsernameValid() { - return id != null // 修改时,不需要传递 - || (ObjectUtil.isAllNotEmpty(username, password)); // 新增时,必须都传递 username、password - } - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/tenant/TenantConvert.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/tenant/TenantConvert.java deleted file mode 100644 index 669954d..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/tenant/TenantConvert.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.system.convert.tenant; - -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO; -import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -/** - * 租户 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface TenantConvert { - - TenantConvert INSTANCE = Mappers.getMapper(TenantConvert.class); - - default UserSaveReqVO convert02(TenantSaveReqVO bean) { - UserSaveReqVO reqVO = new UserSaveReqVO(); - reqVO.setUsername(bean.getUsername()); - reqVO.setPassword(bean.getPassword()); - reqVO.setNickname(bean.getContactName()).setMobile(bean.getContactMobile()); - return reqVO; - } - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java index a59fa8b..530c927 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java @@ -1,7 +1,8 @@ package cn.iocoder.yudao.module.system.dal.dataobject.dept; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +//import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; @@ -19,7 +20,7 @@ import lombok.EqualsAndHashCode; @KeySequence("system_dept_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data @EqualsAndHashCode(callSuper = true) -public class DeptDO extends TenantBaseDO { +public class DeptDO extends BaseDO { public static final Long PARENT_ID_ROOT = 0L; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/oauth2/OAuth2AccessTokenDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/oauth2/OAuth2AccessTokenDO.java index ef235ed..381ac9d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/oauth2/OAuth2AccessTokenDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/oauth2/OAuth2AccessTokenDO.java @@ -1,7 +1,8 @@ package cn.iocoder.yudao.module.system.dal.dataobject.oauth2; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +//import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; @@ -26,7 +27,7 @@ import java.util.Map; @KeySequence("system_oauth2_access_token_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data @EqualsAndHashCode(callSuper = true) -public class OAuth2AccessTokenDO extends TenantBaseDO { +public class OAuth2AccessTokenDO extends BaseDO { /** * 编号,数据库递增 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/oauth2/OAuth2RefreshTokenDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/oauth2/OAuth2RefreshTokenDO.java index 99d153e..a2e8b2b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/oauth2/OAuth2RefreshTokenDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/oauth2/OAuth2RefreshTokenDO.java @@ -1,7 +1,8 @@ package cn.iocoder.yudao.module.system.dal.dataobject.oauth2; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +//import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; @@ -24,7 +25,7 @@ import java.util.List; @Data @EqualsAndHashCode(callSuper = true) @Accessors(chain = true) -public class OAuth2RefreshTokenDO extends TenantBaseDO { +public class OAuth2RefreshTokenDO extends BaseDO { /** * 编号,数据库字典 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleDO.java index 482a4b5..a5d2cd2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleDO.java @@ -1,7 +1,8 @@ package cn.iocoder.yudao.module.system.dal.dataobject.permission; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +//import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; @@ -23,7 +24,7 @@ import java.util.Set; @KeySequence("system_role_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data @EqualsAndHashCode(callSuper = true) -public class RoleDO extends TenantBaseDO { +public class RoleDO extends BaseDO { /** * 角色ID diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleMenuDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleMenuDO.java index 4978b0e..18cdfb8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleMenuDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleMenuDO.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.system.dal.dataobject.permission; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +//import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -16,7 +17,7 @@ import lombok.EqualsAndHashCode; @KeySequence("system_role_menu_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data @EqualsAndHashCode(callSuper = true) -public class RoleMenuDO extends TenantBaseDO { +public class RoleMenuDO extends BaseDO { /** * 自增主键 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialClientDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialClientDO.java index 71fc1bc..0603abb 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialClientDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialClientDO.java @@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.system.dal.dataobject.social; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +//import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; @@ -24,7 +25,7 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class SocialClientDO extends TenantBaseDO { +public class SocialClientDO extends BaseDO { /** * 编号,自增 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantDO.java deleted file mode 100644 index 0b78b7d..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantDO.java +++ /dev/null @@ -1,80 +0,0 @@ -package cn.iocoder.yudao.module.system.dal.dataobject.tenant; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -import java.time.LocalDateTime; - -/** - * 租户 DO - * - * @author 芋道源码 - */ -@TableName(value = "system_tenant", autoResultMap = true) -@KeySequence("system_tenant_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class TenantDO extends BaseDO { - - /** - * 套餐编号 - 系统 - */ - public static final Long PACKAGE_ID_SYSTEM = 0L; - - /** - * 租户编号,自增 - */ - private Long id; - /** - * 租户名,唯一 - */ - private String name; - /** - * 联系人的用户编号 - * - * 关联 {@link AdminUserDO#getId()} - */ - private Long contactUserId; - /** - * 联系人 - */ - private String contactName; - /** - * 联系手机 - */ - private String contactMobile; - /** - * 租户状态 - * - * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - /** - * 绑定域名 - */ - private String website; - /** - * 租户套餐编号 - * - * 关联 {@link TenantPackageDO#getId()} - * 特殊逻辑:系统内置租户,不使用套餐,暂时使用 {@link #PACKAGE_ID_SYSTEM} 标识 - */ - private Long packageId; - /** - * 过期时间 - */ - private LocalDateTime expireTime; - /** - * 账号数量 - */ - private Integer accountCount; - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantPackageDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantPackageDO.java deleted file mode 100644 index 60efbc8..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantPackageDO.java +++ /dev/null @@ -1,52 +0,0 @@ -package cn.iocoder.yudao.module.system.dal.dataobject.tenant; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; -import lombok.*; - -import java.util.Set; - -/** - * 租户套餐 DO - * - * @author 芋道源码 - */ -@TableName(value = "system_tenant_package", autoResultMap = true) -@KeySequence("system_tenant_package_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class TenantPackageDO extends BaseDO { - - /** - * 套餐编号,自增 - */ - private Long id; - /** - * 套餐名,唯一 - */ - private String name; - /** - * 租户套餐状态 - * - * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - /** - * 备注 - */ - private String remark; - /** - * 关联的菜单编号 - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private Set menuIds; - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java index 2f07a30..2433d9a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java @@ -1,7 +1,8 @@ package cn.iocoder.yudao.module.system.dal.dataobject.user; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +//import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.system.enums.common.SexEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableField; @@ -26,7 +27,7 @@ import java.util.Set; @Builder @NoArgsConstructor @AllArgsConstructor -public class AdminUserDO extends TenantBaseDO { +public class AdminUserDO extends BaseDO { /** * 用户ID diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2AccessTokenMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2AccessTokenMapper.java index 81ca13f..342a675 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2AccessTokenMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2AccessTokenMapper.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.system.dal.mysql.oauth2; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; +//import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.token.OAuth2AccessTokenPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; import org.apache.ibatis.annotations.Mapper; @@ -14,7 +14,7 @@ import java.util.List; @Mapper public interface OAuth2AccessTokenMapper extends BaseMapperX { - @TenantIgnore // 获取 token 的时候,需要忽略租户编号。原因是:一些场景下,可能不会传递 tenant-id 请求头,例如说文件上传、积木报表等等 +// @TenantIgnore // 获取 token 的时候,需要忽略租户编号。原因是:一些场景下,可能不会传递 tenant-id 请求头,例如说文件上传、积木报表等等 default OAuth2AccessTokenDO selectByAccessToken(String accessToken) { return selectOne(OAuth2AccessTokenDO::getAccessToken, accessToken); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2RefreshTokenMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2RefreshTokenMapper.java index bf91457..8bcf2f0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2RefreshTokenMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2RefreshTokenMapper.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.system.dal.mysql.oauth2; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; +//import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2RefreshTokenDO; import org.apache.ibatis.annotations.Mapper; @@ -14,7 +14,7 @@ public interface OAuth2RefreshTokenMapper extends BaseMapperX { - - default PageResult selectPage(TenantPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(TenantDO::getName, reqVO.getName()) - .likeIfPresent(TenantDO::getContactName, reqVO.getContactName()) - .likeIfPresent(TenantDO::getContactMobile, reqVO.getContactMobile()) - .eqIfPresent(TenantDO::getStatus, reqVO.getStatus()) - .betweenIfPresent(TenantDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(TenantDO::getId)); - } - - default TenantDO selectByName(String name) { - return selectOne(TenantDO::getName, name); - } - - default TenantDO selectByWebsite(String website) { - return selectOne(TenantDO::getWebsite, website); - } - - default Long selectCountByPackageId(Long packageId) { - return selectCount(TenantDO::getPackageId, packageId); - } - - default List selectListByPackageId(Long packageId) { - return selectList(TenantDO::getPackageId, packageId); - } - - default List selectListByStatus(Integer status) { - return selectList(TenantDO::getStatus, status); - } - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenant/TenantPackageMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenant/TenantPackageMapper.java deleted file mode 100644 index 2918617..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenant/TenantPackageMapper.java +++ /dev/null @@ -1,36 +0,0 @@ -package cn.iocoder.yudao.module.system.dal.mysql.tenant; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO; -import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -/** - * 租户套餐 Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface TenantPackageMapper extends BaseMapperX { - - default PageResult selectPage(TenantPackagePageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(TenantPackageDO::getName, reqVO.getName()) - .eqIfPresent(TenantPackageDO::getStatus, reqVO.getStatus()) - .likeIfPresent(TenantPackageDO::getRemark, reqVO.getRemark()) - .betweenIfPresent(TenantPackageDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(TenantPackageDO::getId)); - } - - default List selectListByStatus(Integer status) { - return selectList(TenantPackageDO::getStatus, status); - } - - default TenantPackageDO selectByName(String name) { - return selectOne(TenantPackageDO::getName, name); - } -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/DemoJob.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/DemoJob.java index 62b8862..9830e78 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/DemoJob.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/DemoJob.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.system.job; import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; +//import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +//import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper; import org.springframework.stereotype.Component; @@ -17,9 +17,9 @@ public class DemoJob implements JobHandler { private AdminUserMapper adminUserMapper; @Override - @TenantJob // 标记多租户 +// @TenantJob // 标记多租户 public String execute(String param) { - System.out.println("当前租户:" + TenantContextHolder.getTenantId()); +// System.out.println("当前租户:" + TenantContextHolder.getTenantId()); List users = adminUserMapper.selectList(); return "用户数量:" + users.size(); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java index fb0e756..59f58ed 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java @@ -11,8 +11,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.security.core.LoginUser; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; +//import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +//import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.token.OAuth2AccessTokenPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO; @@ -165,7 +165,7 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { .setClientId(clientDO.getClientId()).setScopes(refreshTokenDO.getScopes()) .setRefreshToken(refreshTokenDO.getRefreshToken()) .setExpiresTime(LocalDateTime.now().plusSeconds(clientDO.getAccessTokenValiditySeconds())); - accessTokenDO.setTenantId(TenantContextHolder.getTenantId()); // 手动设置租户编号,避免缓存到 Redis 的时候,无对应的租户编号 +// accessTokenDO.setTenantId(TenantContextHolder.getTenantId()); // 手动设置租户编号,避免缓存到 Redis 的时候,无对应的租户编号 oauth2AccessTokenMapper.insert(accessTokenDO); // 记录到 Redis 中 oauth2AccessTokenRedisDAO.set(accessTokenDO); @@ -184,8 +184,9 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { private OAuth2AccessTokenDO convertToAccessToken(OAuth2RefreshTokenDO refreshTokenDO) { OAuth2AccessTokenDO accessTokenDO = BeanUtils.toBean(refreshTokenDO, OAuth2AccessTokenDO.class) .setAccessToken(refreshTokenDO.getRefreshToken()); - TenantUtils.execute(refreshTokenDO.getTenantId(), - () -> accessTokenDO.setUserInfo(buildUserInfo(refreshTokenDO.getUserId(), refreshTokenDO.getUserType()))); +// TenantUtils.execute(refreshTokenDO.getTenantId(), +// () -> accessTokenDO.setUserInfo(buildUserInfo(refreshTokenDO.getUserId(), refreshTokenDO.getUserType()))); + accessTokenDO.setUserInfo(buildUserInfo(refreshTokenDO.getUserId(), refreshTokenDO.getUserType())); return accessTokenDO; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java index 5378108..58aca4a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java @@ -11,7 +11,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper; import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants; import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum; -import cn.iocoder.yudao.module.system.service.tenant.TenantService; +//import cn.iocoder.yudao.module.system.service.tenant.TenantService; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; import jakarta.annotation.Resource; @@ -43,9 +43,9 @@ public class MenuServiceImpl implements MenuService { private MenuMapper menuMapper; @Resource private PermissionService permissionService; - @Resource - @Lazy // 延迟,避免循环依赖报错 - private TenantService tenantService; +// @Resource +// @Lazy // 延迟,避免循环依赖报错 +// private TenantService tenantService; @Override @CacheEvict(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST, key = "#createReqVO.permission", @@ -114,7 +114,7 @@ public class MenuServiceImpl implements MenuService { // 查询所有菜单,并过滤掉关闭的节点 List menus = getMenuList(reqVO); // 开启多租户的情况下,需要过滤掉未开通的菜单 - tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId()))); +// tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId()))); return menus; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageService.java deleted file mode 100644 index 05318f8..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageService.java +++ /dev/null @@ -1,72 +0,0 @@ -package cn.iocoder.yudao.module.system.service.tenant; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO; -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageSaveReqVO; -import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO; - -import jakarta.validation.Valid; -import java.util.List; - -/** - * 租户套餐 Service 接口 - * - * @author 芋道源码 - */ -public interface TenantPackageService { - - /** - * 创建租户套餐 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createTenantPackage(@Valid TenantPackageSaveReqVO createReqVO); - - /** - * 更新租户套餐 - * - * @param updateReqVO 更新信息 - */ - void updateTenantPackage(@Valid TenantPackageSaveReqVO updateReqVO); - - /** - * 删除租户套餐 - * - * @param id 编号 - */ - void deleteTenantPackage(Long id); - - /** - * 获得租户套餐 - * - * @param id 编号 - * @return 租户套餐 - */ - TenantPackageDO getTenantPackage(Long id); - - /** - * 获得租户套餐分页 - * - * @param pageReqVO 分页查询 - * @return 租户套餐分页 - */ - PageResult getTenantPackagePage(TenantPackagePageReqVO pageReqVO); - - /** - * 校验租户套餐 - * - * @param id 编号 - * @return 租户套餐 - */ - TenantPackageDO validTenantPackage(Long id); - - /** - * 获得指定状态的租户套餐列表 - * - * @param status 状态 - * @return 租户套餐 - */ - List getTenantPackageListByStatus(Integer status); - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageServiceImpl.java deleted file mode 100644 index 34209e5..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageServiceImpl.java +++ /dev/null @@ -1,139 +0,0 @@ -package cn.iocoder.yudao.module.system.service.tenant; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO; -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageSaveReqVO; -import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO; -import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO; -import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantPackageMapper; -import com.baomidou.dynamic.datasource.annotation.DSTransactional; -import com.google.common.annotations.VisibleForTesting; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import jakarta.annotation.Resource; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; - -/** - * 租户套餐 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class TenantPackageServiceImpl implements TenantPackageService { - - @Resource - private TenantPackageMapper tenantPackageMapper; - - @Resource - @Lazy // 避免循环依赖的报错 - private TenantService tenantService; - - @Override - public Long createTenantPackage(TenantPackageSaveReqVO createReqVO) { - // 校验套餐名是否重复 - validateTenantPackageNameUnique(null, createReqVO.getName()); - // 插入 - TenantPackageDO tenantPackage = BeanUtils.toBean(createReqVO, TenantPackageDO.class); - tenantPackageMapper.insert(tenantPackage); - // 返回 - return tenantPackage.getId(); - } - - @Override - @DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换 - public void updateTenantPackage(TenantPackageSaveReqVO updateReqVO) { - // 校验存在 - TenantPackageDO tenantPackage = validateTenantPackageExists(updateReqVO.getId()); - // 校验套餐名是否重复 - validateTenantPackageNameUnique(updateReqVO.getId(), updateReqVO.getName()); - // 更新 - TenantPackageDO updateObj = BeanUtils.toBean(updateReqVO, TenantPackageDO.class); - tenantPackageMapper.updateById(updateObj); - // 如果菜单发生变化,则修改每个租户的菜单 - if (!CollUtil.isEqualList(tenantPackage.getMenuIds(), updateReqVO.getMenuIds())) { - List tenants = tenantService.getTenantListByPackageId(tenantPackage.getId()); - tenants.forEach(tenant -> tenantService.updateTenantRoleMenu(tenant.getId(), updateReqVO.getMenuIds())); - } - } - - @Override - public void deleteTenantPackage(Long id) { - // 校验存在 - validateTenantPackageExists(id); - // 校验正在使用 - validateTenantUsed(id); - // 删除 - tenantPackageMapper.deleteById(id); - } - - private TenantPackageDO validateTenantPackageExists(Long id) { - TenantPackageDO tenantPackage = tenantPackageMapper.selectById(id); - if (tenantPackage == null) { - throw exception(TENANT_PACKAGE_NOT_EXISTS); - } - return tenantPackage; - } - - private void validateTenantUsed(Long id) { - if (tenantService.getTenantCountByPackageId(id) > 0) { - throw exception(TENANT_PACKAGE_USED); - } - } - - @Override - public TenantPackageDO getTenantPackage(Long id) { - return tenantPackageMapper.selectById(id); - } - - @Override - public PageResult getTenantPackagePage(TenantPackagePageReqVO pageReqVO) { - return tenantPackageMapper.selectPage(pageReqVO); - } - - @Override - public TenantPackageDO validTenantPackage(Long id) { - TenantPackageDO tenantPackage = tenantPackageMapper.selectById(id); - if (tenantPackage == null) { - throw exception(TENANT_PACKAGE_NOT_EXISTS); - } - if (tenantPackage.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { - throw exception(TENANT_PACKAGE_DISABLE, tenantPackage.getName()); - } - return tenantPackage; - } - - @Override - public List getTenantPackageListByStatus(Integer status) { - return tenantPackageMapper.selectListByStatus(status); - } - - - @VisibleForTesting - void validateTenantPackageNameUnique(Long id, String name) { - if (StrUtil.isBlank(name)) { - return; - } - TenantPackageDO tenantPackage = tenantPackageMapper.selectByName(name); - if (tenantPackage == null) { - return; - } - // 如果 id 为空,说明不用比较是否为相同 id 的用户 - if (id == null) { - throw exception(TENANT_PACKAGE_NAME_DUPLICATE); - } - if (!tenantPackage.getId().equals(id)) { - throw exception(TENANT_PACKAGE_NAME_DUPLICATE); - } - } - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantService.java deleted file mode 100644 index 425d18d..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantService.java +++ /dev/null @@ -1,138 +0,0 @@ -package cn.iocoder.yudao.module.system.service.tenant; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO; -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO; -import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO; -import cn.iocoder.yudao.module.system.service.tenant.handler.TenantInfoHandler; -import cn.iocoder.yudao.module.system.service.tenant.handler.TenantMenuHandler; - -import jakarta.validation.Valid; -import java.util.List; -import java.util.Set; - -/** - * 租户 Service 接口 - * - * @author 芋道源码 - */ -public interface TenantService { - - /** - * 创建租户 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createTenant(@Valid TenantSaveReqVO createReqVO); - - /** - * 更新租户 - * - * @param updateReqVO 更新信息 - */ - void updateTenant(@Valid TenantSaveReqVO updateReqVO); - - /** - * 更新租户的角色菜单 - * - * @param tenantId 租户编号 - * @param menuIds 菜单编号数组 - */ - void updateTenantRoleMenu(Long tenantId, Set menuIds); - - /** - * 删除租户 - * - * @param id 编号 - */ - void deleteTenant(Long id); - - /** - * 获得租户 - * - * @param id 编号 - * @return 租户 - */ - TenantDO getTenant(Long id); - - /** - * 获得租户分页 - * - * @param pageReqVO 分页查询 - * @return 租户分页 - */ - PageResult getTenantPage(TenantPageReqVO pageReqVO); - - /** - * 获得名字对应的租户 - * - * @param name 租户名 - * @return 租户 - */ - TenantDO getTenantByName(String name); - - /** - * 获得域名对应的租户 - * - * @param website 域名 - * @return 租户 - */ - TenantDO getTenantByWebsite(String website); - - /** - * 获得使用指定套餐的租户数量 - * - * @param packageId 租户套餐编号 - * @return 租户数量 - */ - Long getTenantCountByPackageId(Long packageId); - - /** - * 获得使用指定套餐的租户数组 - * - * @param packageId 租户套餐编号 - * @return 租户数组 - */ - List getTenantListByPackageId(Long packageId); - - /** - * 获得指定状态的租户列表 - * - * @param status 状态 - * @return 租户列表 - */ - List getTenantListByStatus(Integer status); - - /** - * 进行租户的信息处理逻辑 - * 其中,租户编号从 {@link TenantContextHolder} 上下文中获取 - * - * @param handler 处理器 - */ - void handleTenantInfo(TenantInfoHandler handler); - - /** - * 进行租户的菜单处理逻辑 - * 其中,租户编号从 {@link TenantContextHolder} 上下文中获取 - * - * @param handler 处理器 - */ - void handleTenantMenu(TenantMenuHandler handler); - - /** - * 获得所有租户 - * - * @return 租户编号数组 - */ - List getTenantIdList(); - - /** - * 校验租户是否合法 - * - * @param id 租户编号 - */ - void validTenant(Long id); - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java deleted file mode 100644 index c3b09ec..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java +++ /dev/null @@ -1,311 +0,0 @@ -package cn.iocoder.yudao.module.system.service.tenant; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.date.DateUtils; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.framework.tenant.config.TenantProperties; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; -import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleSaveReqVO; -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO; -import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO; -import cn.iocoder.yudao.module.system.convert.tenant.TenantConvert; -import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; -import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; -import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO; -import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO; -import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper; -import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum; -import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum; -import cn.iocoder.yudao.module.system.service.permission.MenuService; -import cn.iocoder.yudao.module.system.service.permission.PermissionService; -import cn.iocoder.yudao.module.system.service.permission.RoleService; -import cn.iocoder.yudao.module.system.service.tenant.handler.TenantInfoHandler; -import cn.iocoder.yudao.module.system.service.tenant.handler.TenantMenuHandler; -import cn.iocoder.yudao.module.system.service.user.AdminUserService; -import com.baomidou.dynamic.datasource.annotation.DSTransactional; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import jakarta.annotation.Resource; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; -import static java.util.Collections.singleton; - -/** - * 租户 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -@Slf4j -public class TenantServiceImpl implements TenantService { - - @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") - @Autowired(required = false) // 由于 yudao.tenant.enable 配置项,可以关闭多租户的功能,所以这里只能不强制注入 - private TenantProperties tenantProperties; - - @Resource - private TenantMapper tenantMapper; - - @Resource - private TenantPackageService tenantPackageService; - @Resource - @Lazy // 延迟,避免循环依赖报错 - private AdminUserService userService; - @Resource - private RoleService roleService; - @Resource - private MenuService menuService; - @Resource - private PermissionService permissionService; - - @Override - public List getTenantIdList() { - List tenants = tenantMapper.selectList(); - return CollectionUtils.convertList(tenants, TenantDO::getId); - } - - @Override - public void validTenant(Long id) { - TenantDO tenant = getTenant(id); - if (tenant == null) { - throw exception(TENANT_NOT_EXISTS); - } - if (tenant.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { - throw exception(TENANT_DISABLE, tenant.getName()); - } - if (DateUtils.isExpired(tenant.getExpireTime())) { - throw exception(TENANT_EXPIRE, tenant.getName()); - } - } - - @Override - @DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换 - public Long createTenant(TenantSaveReqVO createReqVO) { - // 校验租户名称是否重复 - validTenantNameDuplicate(createReqVO.getName(), null); - // 校验租户域名是否重复 - validTenantWebsiteDuplicate(createReqVO.getWebsite(), null); - // 校验套餐被禁用 - TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(createReqVO.getPackageId()); - - // 创建租户 - TenantDO tenant = BeanUtils.toBean(createReqVO, TenantDO.class); - tenantMapper.insert(tenant); - // 创建租户的管理员 - TenantUtils.execute(tenant.getId(), () -> { - // 创建角色 - Long roleId = createRole(tenantPackage); - // 创建用户,并分配角色 - Long userId = createUser(roleId, createReqVO); - // 修改租户的管理员 - tenantMapper.updateById(new TenantDO().setId(tenant.getId()).setContactUserId(userId)); - }); - return tenant.getId(); - } - - private Long createUser(Long roleId, TenantSaveReqVO createReqVO) { - // 创建用户 - Long userId = userService.createUser(TenantConvert.INSTANCE.convert02(createReqVO)); - // 分配角色 - permissionService.assignUserRole(userId, singleton(roleId)); - return userId; - } - - private Long createRole(TenantPackageDO tenantPackage) { - // 创建角色 - RoleSaveReqVO reqVO = new RoleSaveReqVO(); - reqVO.setName(RoleCodeEnum.TENANT_ADMIN.getName()).setCode(RoleCodeEnum.TENANT_ADMIN.getCode()) - .setSort(0).setRemark("系统自动生成"); - Long roleId = roleService.createRole(reqVO, RoleTypeEnum.SYSTEM.getType()); - // 分配权限 - permissionService.assignRoleMenu(roleId, tenantPackage.getMenuIds()); - return roleId; - } - - @Override - @DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换 - public void updateTenant(TenantSaveReqVO updateReqVO) { - // 校验存在 - TenantDO tenant = validateUpdateTenant(updateReqVO.getId()); - // 校验租户名称是否重复 - validTenantNameDuplicate(updateReqVO.getName(), updateReqVO.getId()); - // 校验租户域名是否重复 - validTenantWebsiteDuplicate(updateReqVO.getWebsite(), updateReqVO.getId()); - // 校验套餐被禁用 - TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(updateReqVO.getPackageId()); - - // 更新租户 - TenantDO updateObj = BeanUtils.toBean(updateReqVO, TenantDO.class); - tenantMapper.updateById(updateObj); - // 如果套餐发生变化,则修改其角色的权限 - if (ObjectUtil.notEqual(tenant.getPackageId(), updateReqVO.getPackageId())) { - updateTenantRoleMenu(tenant.getId(), tenantPackage.getMenuIds()); - } - } - - private void validTenantNameDuplicate(String name, Long id) { - TenantDO tenant = tenantMapper.selectByName(name); - if (tenant == null) { - return; - } - // 如果 id 为空,说明不用比较是否为相同名字的租户 - if (id == null) { - throw exception(TENANT_NAME_DUPLICATE, name); - } - if (!tenant.getId().equals(id)) { - throw exception(TENANT_NAME_DUPLICATE, name); - } - } - - private void validTenantWebsiteDuplicate(String website, Long id) { - if (StrUtil.isEmpty(website)) { - return; - } - TenantDO tenant = tenantMapper.selectByWebsite(website); - if (tenant == null) { - return; - } - // 如果 id 为空,说明不用比较是否为相同名字的租户 - if (id == null) { - throw exception(TENANT_WEBSITE_DUPLICATE, website); - } - if (!tenant.getId().equals(id)) { - throw exception(TENANT_WEBSITE_DUPLICATE, website); - } - } - - @Override - @DSTransactional - public void updateTenantRoleMenu(Long tenantId, Set menuIds) { - TenantUtils.execute(tenantId, () -> { - // 获得所有角色 - List roles = roleService.getRoleList(); - roles.forEach(role -> Assert.isTrue(tenantId.equals(role.getTenantId()), "角色({}/{}) 租户不匹配", - role.getId(), role.getTenantId(), tenantId)); // 兜底校验 - // 重新分配每个角色的权限 - roles.forEach(role -> { - // 如果是租户管理员,重新分配其权限为租户套餐的权限 - if (Objects.equals(role.getCode(), RoleCodeEnum.TENANT_ADMIN.getCode())) { - permissionService.assignRoleMenu(role.getId(), menuIds); - log.info("[updateTenantRoleMenu][租户管理员({}/{}) 的权限修改为({})]", role.getId(), role.getTenantId(), menuIds); - return; - } - // 如果是其他角色,则去掉超过套餐的权限 - Set roleMenuIds = permissionService.getRoleMenuListByRoleId(role.getId()); - roleMenuIds = CollUtil.intersectionDistinct(roleMenuIds, menuIds); - permissionService.assignRoleMenu(role.getId(), roleMenuIds); - log.info("[updateTenantRoleMenu][角色({}/{}) 的权限修改为({})]", role.getId(), role.getTenantId(), roleMenuIds); - }); - }); - } - - @Override - public void deleteTenant(Long id) { - // 校验存在 - validateUpdateTenant(id); - // 删除 - tenantMapper.deleteById(id); - } - - private TenantDO validateUpdateTenant(Long id) { - TenantDO tenant = tenantMapper.selectById(id); - if (tenant == null) { - throw exception(TENANT_NOT_EXISTS); - } - // 内置租户,不允许删除 - if (isSystemTenant(tenant)) { - throw exception(TENANT_CAN_NOT_UPDATE_SYSTEM); - } - return tenant; - } - - @Override - public TenantDO getTenant(Long id) { - return tenantMapper.selectById(id); - } - - @Override - public PageResult getTenantPage(TenantPageReqVO pageReqVO) { - return tenantMapper.selectPage(pageReqVO); - } - - @Override - public TenantDO getTenantByName(String name) { - return tenantMapper.selectByName(name); - } - - @Override - public TenantDO getTenantByWebsite(String website) { - return tenantMapper.selectByWebsite(website); - } - - @Override - public Long getTenantCountByPackageId(Long packageId) { - return tenantMapper.selectCountByPackageId(packageId); - } - - @Override - public List getTenantListByPackageId(Long packageId) { - return tenantMapper.selectListByPackageId(packageId); - } - - @Override - public List getTenantListByStatus(Integer status) { - return tenantMapper.selectListByStatus(status); - } - - @Override - public void handleTenantInfo(TenantInfoHandler handler) { - // 如果禁用,则不执行逻辑 - if (isTenantDisable()) { - return; - } - // 获得租户 - TenantDO tenant = getTenant(TenantContextHolder.getRequiredTenantId()); - // 执行处理器 - handler.handle(tenant); - } - - @Override - public void handleTenantMenu(TenantMenuHandler handler) { - // 如果禁用,则不执行逻辑 - if (isTenantDisable()) { - return; - } - // 获得租户,然后获得菜单 - TenantDO tenant = getTenant(TenantContextHolder.getRequiredTenantId()); - Set menuIds; - if (isSystemTenant(tenant)) { // 系统租户,菜单是全量的 - menuIds = CollectionUtils.convertSet(menuService.getMenuList(), MenuDO::getId); - } else { - menuIds = tenantPackageService.getTenantPackage(tenant.getPackageId()).getMenuIds(); - } - // 执行处理器 - handler.handle(menuIds); - } - - private static boolean isSystemTenant(TenantDO tenant) { - return Objects.equals(tenant.getPackageId(), TenantDO.PACKAGE_ID_SYSTEM); - } - - private boolean isTenantDisable() { - return tenantProperties == null || Boolean.FALSE.equals(tenantProperties.getEnable()); - } - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/handler/TenantInfoHandler.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/handler/TenantInfoHandler.java deleted file mode 100644 index 5b5b9fe..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/handler/TenantInfoHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.system.service.tenant.handler; - -import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO; - -/** - * 租户信息处理 - * 目的:尽量减少租户逻辑耦合到系统中 - * - * @author 芋道源码 - */ -public interface TenantInfoHandler { - - /** - * 基于传入的租户信息,进行相关逻辑的执行 - * 例如说,创建用户时,超过最大账户配额 - * - * @param tenant 租户信息 - */ - void handle(TenantDO tenant); - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/handler/TenantMenuHandler.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/handler/TenantMenuHandler.java deleted file mode 100644 index 2e1be43..0000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/handler/TenantMenuHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.system.service.tenant.handler; - -import java.util.Set; - -/** - * 租户菜单处理 - * 目的:尽量减少租户逻辑耦合到系统中 - * - * @author 芋道源码 - */ -public interface TenantMenuHandler { - - /** - * 基于传入的租户菜单【全】列表,进行相关逻辑的执行 - * 例如说,返回可分配菜单的时候,可以移除多余的 - * - * @param menuIds 菜单列表 - */ - void handle(Set menuIds); - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index 09e7b61..2a50842 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java @@ -28,7 +28,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper; import cn.iocoder.yudao.module.system.service.dept.DeptService; import cn.iocoder.yudao.module.system.service.dept.PostService; import cn.iocoder.yudao.module.system.service.permission.PermissionService; -import cn.iocoder.yudao.module.system.service.tenant.TenantService; +//import cn.iocoder.yudao.module.system.service.tenant.TenantService; import com.google.common.annotations.VisibleForTesting; import com.mzt.logapi.context.LogRecordContext; import com.mzt.logapi.service.impl.DiffParseFunction; @@ -72,9 +72,9 @@ public class AdminUserServiceImpl implements AdminUserService { private PermissionService permissionService; @Resource private PasswordEncoder passwordEncoder; - @Resource - @Lazy // 延迟,避免循环依赖报错 - private TenantService tenantService; +// @Resource +// @Lazy // 延迟,避免循环依赖报错 +// private TenantService tenantService; @Resource private UserPostMapper userPostMapper; @@ -90,12 +90,12 @@ public class AdminUserServiceImpl implements AdminUserService { success = SYSTEM_USER_CREATE_SUCCESS) public Long createUser(UserSaveReqVO createReqVO) { // 1.1 校验账户配合 - tenantService.handleTenantInfo(tenant -> { - long count = userMapper.selectCount(); - if (count >= tenant.getAccountCount()) { - throw exception(USER_COUNT_MAX, tenant.getAccountCount()); - } - }); +// tenantService.handleTenantInfo(tenant -> { +// long count = userMapper.selectCount(); +// if (count >= tenant.getAccountCount()) { +// throw exception(USER_COUNT_MAX, tenant.getAccountCount()); +// } +// }); // 1.2 校验正确性 validateUserForCreateOrUpdate(null, createReqVO.getUsername(), createReqVO.getMobile(), createReqVO.getEmail(), createReqVO.getDeptId(), createReqVO.getPostIds()); @@ -118,12 +118,12 @@ public class AdminUserServiceImpl implements AdminUserService { @Override public Long registerUser(AuthRegisterReqVO registerReqVO) { // 1.1 校验账户配合 - tenantService.handleTenantInfo(tenant -> { - long count = userMapper.selectCount(); - if (count >= tenant.getAccountCount()) { - throw exception(USER_COUNT_MAX, tenant.getAccountCount()); - } - }); +// tenantService.handleTenantInfo(tenant -> { +// long count = userMapper.selectCount(); +// if (count >= tenant.getAccountCount()) { +// throw exception(USER_COUNT_MAX, tenant.getAccountCount()); +// } +// }); // 1.2 校验正确性 validateUserForCreateOrUpdate(null, registerReqVO.getUsername(), null, null, null, null); diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index 6d6232f..8bdc67c 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -31,6 +31,11 @@ yudao-module-infra-biz ${revision} + + cn.iocoder.boot + yudao-module-alert-biz + ${revision} +