mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-30 03:01:53 +08:00
【新增】新增 @TenantIgnore
注解,标记指定方法,忽略多租户的自动过滤,适合实现跨租户的逻辑
This commit is contained in:
parent
2598c033a9
commit
4d53944771
@ -0,0 +1,106 @@
|
|||||||
|
package cn.iocoder.yudao.framework.tenant.config;
|
||||||
|
|
||||||
|
import cn.hutool.core.annotation.AnnotationUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
|
||||||
|
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
|
||||||
|
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.TenantJob;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.job.TenantJobHandlerDecorator;
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.mq.TenantRedisMessageInterceptor;
|
||||||
|
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.web.TenantContextWebFilter;
|
||||||
|
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
||||||
|
import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||||
|
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.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) // 允许使用 yudao.tenant.enable=false 禁用多租户
|
||||||
|
@EnableConfigurationProperties(TenantProperties.class)
|
||||||
|
public class YudaoTenantAutoConfiguration {
|
||||||
|
|
||||||
|
// ========== 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> tenantContextWebFilter() {
|
||||||
|
FilterRegistrationBean<TenantContextWebFilter> registrationBean = new FilterRegistrationBean<>();
|
||||||
|
registrationBean.setFilter(new TenantContextWebFilter());
|
||||||
|
registrationBean.setOrder(WebFilterOrderEnum.TENANT_CONTEXT_FILTER);
|
||||||
|
return registrationBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== Security ==========
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public FilterRegistrationBean<TenantSecurityWebFilter> tenantSecurityWebFilter(TenantProperties tenantProperties,
|
||||||
|
WebProperties webProperties,
|
||||||
|
GlobalExceptionHandler globalExceptionHandler,
|
||||||
|
TenantFrameworkService tenantFrameworkService) {
|
||||||
|
FilterRegistrationBean<TenantSecurityWebFilter> 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== Job ==========
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
||||||
|
public BeanPostProcessor jobHandlerBeanPostProcessor(TenantFrameworkService tenantFrameworkService) {
|
||||||
|
return new BeanPostProcessor() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||||
|
if (!(bean instanceof JobHandler)) {
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
// 有 TenantJob 注解的情况下,才会进行处理
|
||||||
|
if (!AnnotationUtil.hasAnnotation(bean.getClass(), TenantJob.class)) {
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 TenantJobHandlerDecorator 装饰
|
||||||
|
return new TenantJobHandlerDecorator(tenantFrameworkService, (JobHandler) bean);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,33 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.tenant.config;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
|
|
||||||
import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多租户针对 DB 的自动配置
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
// 允许使用 yudao.tenant.enable=false 禁用多租户
|
|
||||||
@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true)
|
|
||||||
@EnableConfigurationProperties(TenantProperties.class)
|
|
||||||
public class YudaoTenantDatabaseAutoConfiguration {
|
|
||||||
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.tenant.config;
|
|
||||||
|
|
||||||
import cn.hutool.core.annotation.AnnotationUtil;
|
|
||||||
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
|
|
||||||
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
|
|
||||||
import cn.iocoder.yudao.framework.tenant.core.job.TenantJobHandlerDecorator;
|
|
||||||
import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
|
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多租户针对 Job 的自动配置
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
// 允许使用 yudao.tenant.enable=false 禁用多租户
|
|
||||||
@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true)
|
|
||||||
public class YudaoTenantJobAutoConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
|
||||||
public BeanPostProcessor jobHandlerBeanPostProcessor(TenantFrameworkService tenantFrameworkService) {
|
|
||||||
return new BeanPostProcessor() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
|
||||||
if (!(bean instanceof JobHandler)) {
|
|
||||||
return bean;
|
|
||||||
}
|
|
||||||
// 有 TenantJob 注解的情况下,才会进行处理
|
|
||||||
if (!AnnotationUtil.hasAnnotation(bean.getClass(), TenantJob.class)) {
|
|
||||||
return bean;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用 TenantJobHandlerDecorator 装饰
|
|
||||||
return new TenantJobHandlerDecorator(tenantFrameworkService, (JobHandler) bean);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.tenant.config;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.tenant.core.mq.TenantRedisMessageInterceptor;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多租户针对 MQ 的自动配置
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
// 允许使用 yudao.tenant.enable=false 禁用多租户
|
|
||||||
@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true)
|
|
||||||
public class YudaoTenantMQAutoConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public TenantRedisMessageInterceptor tenantRedisMessageInterceptor() {
|
|
||||||
return new TenantRedisMessageInterceptor();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.tenant.config;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
|
|
||||||
import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter;
|
|
||||||
import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
|
|
||||||
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
|
||||||
import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
|
|
||||||
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.Configuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多租户针对 Web 的自动配置
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
// 允许使用 yudao.tenant.enable=false 禁用多租户
|
|
||||||
@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true)
|
|
||||||
@EnableConfigurationProperties(TenantProperties.class)
|
|
||||||
public class YudaoTenantSecurityAutoConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public FilterRegistrationBean<TenantSecurityWebFilter> tenantSecurityWebFilter(TenantProperties tenantProperties,
|
|
||||||
WebProperties webProperties,
|
|
||||||
GlobalExceptionHandler globalExceptionHandler,
|
|
||||||
TenantFrameworkService tenantFrameworkService) {
|
|
||||||
FilterRegistrationBean<TenantSecurityWebFilter> registrationBean = new FilterRegistrationBean<>();
|
|
||||||
registrationBean.setFilter(new TenantSecurityWebFilter(tenantProperties, webProperties,
|
|
||||||
globalExceptionHandler, tenantFrameworkService));
|
|
||||||
registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER);
|
|
||||||
return registrationBean;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.tenant.config;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
|
|
||||||
import cn.iocoder.yudao.framework.tenant.core.web.TenantContextWebFilter;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多租户针对 Web 的自动配置
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
// 允许使用 yudao.tenant.enable=false 禁用多租户
|
|
||||||
@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true)
|
|
||||||
public class YudaoTenantWebAutoConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public FilterRegistrationBean<TenantContextWebFilter> tenantContextWebFilter() {
|
|
||||||
FilterRegistrationBean<TenantContextWebFilter> registrationBean = new FilterRegistrationBean<>();
|
|
||||||
registrationBean.setFilter(new TenantContextWebFilter());
|
|
||||||
registrationBean.setOrder(WebFilterOrderEnum.TENANT_CONTEXT_FILTER);
|
|
||||||
return registrationBean;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,18 @@
|
|||||||
|
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 {
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package cn.iocoder.yudao.framework.tenant.core.aop;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||||
|
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} 注解实现,用于一些全局的逻辑。
|
||||||
|
* 例如说,一个定时任务,读取所有数据,进行处理。
|
||||||
|
* 又例如说,读取所有数据,进行缓存。
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -9,8 +9,16 @@ import com.alibaba.ttl.TransmittableThreadLocal;
|
|||||||
*/
|
*/
|
||||||
public class TenantContextHolder {
|
public class TenantContextHolder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前租户编号
|
||||||
|
*/
|
||||||
private static final ThreadLocal<Long> TENANT_ID = new TransmittableThreadLocal<>();
|
private static final ThreadLocal<Long> TENANT_ID = new TransmittableThreadLocal<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否忽略租户
|
||||||
|
*/
|
||||||
|
private static final ThreadLocal<Boolean> IGNORE = new TransmittableThreadLocal<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得租户编号。
|
* 获得租户编号。
|
||||||
*
|
*
|
||||||
@ -37,8 +45,22 @@ public class TenantContextHolder {
|
|||||||
TENANT_ID.set(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() {
|
public static void clear() {
|
||||||
TENANT_ID.remove();
|
TENANT_ID.remove();
|
||||||
|
IGNORE.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
|
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import net.sf.jsqlparser.expression.Expression;
|
import net.sf.jsqlparser.expression.Expression;
|
||||||
import net.sf.jsqlparser.expression.StringValue;
|
import net.sf.jsqlparser.expression.LongValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于 MyBatis Plus 多租户的功能,实现 DB 层面的多租户的功能
|
* 基于 MyBatis Plus 多租户的功能,实现 DB 层面的多租户的功能
|
||||||
@ -20,12 +20,13 @@ public class TenantDatabaseInterceptor implements TenantLineHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Expression getTenantId() {
|
public Expression getTenantId() {
|
||||||
return new StringValue(TenantContextHolder.getRequiredTenantId().toString());
|
return new LongValue( TenantContextHolder.getRequiredTenantId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean ignoreTable(String tableName) {
|
public boolean ignoreTable(String tableName) {
|
||||||
return CollUtil.contains(properties.getIgnoreTables(), tableName);
|
return TenantContextHolder.isIgnore() // 情况一,全局忽略多租户
|
||||||
|
|| CollUtil.contains(properties.getIgnoreTables(), tableName); // 情况二,忽略多租户的表
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.tenant.core.job;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多租户 JobHandlerInvoker 拓展实现类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
public class TenantJobHandlerInvoker extends JobHandlerInvoker {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -12,17 +12,23 @@ public class TenantUtils {
|
|||||||
/**
|
/**
|
||||||
* 使用指定租户,执行对应的逻辑
|
* 使用指定租户,执行对应的逻辑
|
||||||
*
|
*
|
||||||
|
* 注意,如果当前是忽略租户的情况下,会被强制设置成不忽略租户
|
||||||
|
* 当然,执行完成后,还是会恢复回去
|
||||||
|
*
|
||||||
* @param tenantId 租户编号
|
* @param tenantId 租户编号
|
||||||
* @param runnable 逻辑
|
* @param runnable 逻辑
|
||||||
*/
|
*/
|
||||||
public static void execute(Long tenantId, Runnable runnable) {
|
public static void execute(Long tenantId, Runnable runnable) {
|
||||||
Long oldTenantId = TenantContextHolder.getTenantId();
|
Long oldTenantId = TenantContextHolder.getTenantId();
|
||||||
|
Boolean oldIgnore = TenantContextHolder.isIgnore();
|
||||||
try {
|
try {
|
||||||
TenantContextHolder.setTenantId(tenantId);
|
TenantContextHolder.setTenantId(tenantId);
|
||||||
|
TenantContextHolder.setIgnore(false);
|
||||||
// 执行逻辑
|
// 执行逻辑
|
||||||
runnable.run();
|
runnable.run();
|
||||||
} finally {
|
} finally {
|
||||||
TenantContextHolder.setTenantId(oldTenantId);
|
TenantContextHolder.setTenantId(oldTenantId);
|
||||||
|
TenantContextHolder.setIgnore(oldIgnore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,2 @@
|
|||||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||||
cn.iocoder.yudao.framework.tenant.config.YudaoTenantDatabaseAutoConfiguration,\
|
cn.iocoder.yudao.framework.tenant.config.YudaoTenantAutoConfiguration
|
||||||
cn.iocoder.yudao.framework.tenant.config.YudaoTenantWebAutoConfiguration,\
|
|
||||||
cn.iocoder.yudao.framework.tenant.config.YudaoTenantJobAutoConfiguration,\
|
|
||||||
cn.iocoder.yudao.framework.tenant.config.YudaoTenantMQAutoConfiguration,\
|
|
||||||
cn.iocoder.yudao.framework.tenant.config.YudaoTenantSecurityAutoConfiguration
|
|
||||||
|
@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
|||||||
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.FilePageReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.FilePageReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
||||||
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,12 +30,10 @@ public interface FileMapper extends BaseMapperX<FileDO> {
|
|||||||
/**
|
/**
|
||||||
* 基于 Path 获取文件
|
* 基于 Path 获取文件
|
||||||
* 实际上,是基于 ID 查询
|
* 实际上,是基于 ID 查询
|
||||||
* 由于前端使用 <img /> 的方式获取图片,所以需要忽略租户的查询
|
|
||||||
*
|
*
|
||||||
* @param path 路径
|
* @param path 路径
|
||||||
* @return 文件
|
* @return 文件
|
||||||
*/
|
*/
|
||||||
@InterceptorIgnore(tenantLine = "true")
|
|
||||||
default FileDO selectByPath(String path) {
|
default FileDO selectByPath(String path) {
|
||||||
return selectById(path);
|
return selectById(path);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
package cn.iocoder.yudao.module.pay.dal.mysql.merchant;
|
package cn.iocoder.yudao.module.pay.dal.mysql.merchant;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
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.QueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelExportReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelExportReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelPageReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelPageReqVO;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
|
||||||
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Select;
|
import org.apache.ibatis.annotations.Select;
|
||||||
@ -23,7 +22,6 @@ public interface PayChannelMapper extends BaseMapperX<PayChannelDO> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Select("SELECT id FROM pay_channel WHERE update_time > #{maxUpdateTime} LIMIT 1")
|
@Select("SELECT id FROM pay_channel WHERE update_time > #{maxUpdateTime} LIMIT 1")
|
||||||
@InterceptorIgnore(tenantLine = "true") // 该方法忽略多租户。原因:该方法被异步 task 调用,此时获取不到租户编号
|
|
||||||
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
|
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
|
||||||
|
|
||||||
default PageResult<PayChannelDO> selectPage(PayChannelPageReqVO reqVO) {
|
default PageResult<PayChannelDO> selectPage(PayChannelPageReqVO reqVO) {
|
||||||
|
@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
|||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||||
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Select;
|
import org.apache.ibatis.annotations.Select;
|
||||||
@ -30,12 +29,6 @@ public interface DeptMapper extends BaseMapperX<DeptDO> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Select("SELECT id FROM system_dept WHERE update_time > #{maxUpdateTime} LIMIT 1")
|
@Select("SELECT id FROM system_dept WHERE update_time > #{maxUpdateTime} LIMIT 1")
|
||||||
@InterceptorIgnore(tenantLine = "true") // 该方法忽略多租户。原因:该方法被异步 task 调用,此时获取不到租户编号
|
|
||||||
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
|
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
|
||||||
|
|
||||||
// TODO 芋艿:后续想想,有没可能优化下。大体思路,是支持某个方法,忽略租户
|
|
||||||
@Select("SELECT * FROM system_dept")
|
|
||||||
@InterceptorIgnore(tenantLine = "true")
|
|
||||||
List<DeptDO> selectListIgnoreTenant();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package cn.iocoder.yudao.module.system.dal.mysql.permission;
|
package cn.iocoder.yudao.module.system.dal.mysql.permission;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants;
|
import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
|
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
@ -29,7 +28,6 @@ public interface MenuMapper extends BaseMapperX<MenuDO> {
|
|||||||
.eqIfPresent(MenuDO::getStatus, reqVO.getStatus()));
|
.eqIfPresent(MenuDO::getStatus, reqVO.getStatus()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@InterceptorIgnore(tenantLine = "true") // 该方法忽略多租户。原因:该方法被异步 task 调用,此时获取不到租户编号
|
|
||||||
default boolean selectExistsByUpdateTimeAfter(Date maxUpdateTime) {
|
default boolean selectExistsByUpdateTimeAfter(Date maxUpdateTime) {
|
||||||
return selectOne(new LambdaQueryWrapper<MenuDO>().select(MenuDO::getId)
|
return selectOne(new LambdaQueryWrapper<MenuDO>().select(MenuDO::getId)
|
||||||
.gt(MenuDO::getUpdateTime, maxUpdateTime).last(SqlConstants.LIMIT1)) != null;
|
.gt(MenuDO::getUpdateTime, maxUpdateTime).last(SqlConstants.LIMIT1)) != null;
|
||||||
|
@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.system.dal.mysql.permission;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
|
||||||
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Select;
|
import org.apache.ibatis.annotations.Select;
|
||||||
@ -44,7 +43,6 @@ public interface RoleMenuMapper extends BaseMapperX<RoleMenuDO> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Select("SELECT id FROM system_role_menu WHERE update_time > #{maxUpdateTime} LIMIT 1")
|
@Select("SELECT id FROM system_role_menu WHERE update_time > #{maxUpdateTime} LIMIT 1")
|
||||||
@InterceptorIgnore(tenantLine = "true") // 该方法忽略多租户。原因:该方法被异步 task 调用,此时获取不到租户编号
|
|
||||||
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
|
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package cn.iocoder.yudao.module.system.dal.mysql.sms;
|
package cn.iocoder.yudao.module.system.dal.mysql.sms;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
||||||
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Select;
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
@ -23,7 +22,6 @@ public interface SmsChannelMapper extends BaseMapperX<SmsChannelDO> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Select("SELECT id FROM system_sms_channel WHERE update_time > #{maxUpdateTime} LIMIT 1")
|
@Select("SELECT id FROM system_sms_channel WHERE update_time > #{maxUpdateTime} LIMIT 1")
|
||||||
@InterceptorIgnore(tenantLine = "true") // 该方法忽略多租户。原因:该方法被异步 task 调用,此时获取不到租户编号
|
|
||||||
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
|
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
package cn.iocoder.yudao.module.system.dal.mysql.sms;
|
package cn.iocoder.yudao.module.system.dal.mysql.sms;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
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.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateExportReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateExportReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplatePageReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplatePageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
|
||||||
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Select;
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
@ -17,7 +16,6 @@ import java.util.List;
|
|||||||
public interface SmsTemplateMapper extends BaseMapperX<SmsTemplateDO> {
|
public interface SmsTemplateMapper extends BaseMapperX<SmsTemplateDO> {
|
||||||
|
|
||||||
@Select("SELECT id FROM system_sms_template WHERE update_time > #{maxUpdateTime} LIMIT 1")
|
@Select("SELECT id FROM system_sms_template WHERE update_time > #{maxUpdateTime} LIMIT 1")
|
||||||
@InterceptorIgnore(tenantLine = "true") // 该方法忽略多租户。原因:该方法被异步 task 调用,此时获取不到租户编号
|
|
||||||
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
|
Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
|
||||||
|
|
||||||
default SmsTemplateDO selectByCode(String code) {
|
default SmsTemplateDO selectByCode(String code) {
|
||||||
|
Loading…
Reference in New Issue
Block a user