Commit 79311ecc71f0c6beabe0e5f84e1423ce745a5f09
1 parent
27c30279
* 【新增】后端 `yudao.tenant.enable` 配置项,前端 `VUE_APP_TENANT_ENABLE` 配置项,用于开关租户功能
* 【优化】调整默认所有表开启多租户的特性,可通过 `yudao.tenant.ignore-tables` 配置项进行忽略,替代原本默认不开启的策略 * 【新增】通过 `yudao.tenant.ignore-urls` 配置忽略多租户的请求,例如说 ,例如说短信回调、支付回调等 Open API
Showing
36 changed files
with
220 additions
and
122 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java
| @@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.common.enums; | @@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.common.enums; | ||
| 3 | /** | 3 | /** |
| 4 | * Web 过滤器顺序的枚举类,保证过滤器按照符合我们的预期 | 4 | * Web 过滤器顺序的枚举类,保证过滤器按照符合我们的预期 |
| 5 | * | 5 | * |
| 6 | - * 考虑到每个 starter 都需要用到该工具类,所以放到 common 模块下的 util 包下 | 6 | + * 考虑到每个 starter 都需要用到该工具类,所以放到 common 模块下的 util 包下 |
| 7 | * | 7 | * |
| 8 | * @author 芋道源码 | 8 | * @author 芋道源码 |
| 9 | */ | 9 | */ |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/TenantProperties.java
| @@ -14,22 +14,28 @@ import java.util.Set; | @@ -14,22 +14,28 @@ import java.util.Set; | ||
| 14 | @Data | 14 | @Data |
| 15 | public class TenantProperties { | 15 | public class TenantProperties { |
| 16 | 16 | ||
| 17 | -// /** | ||
| 18 | -// * 租户是否开启 | ||
| 19 | -// */ | ||
| 20 | -// private static final Boolean ENABLE_DEFAULT = true; | ||
| 21 | -// | ||
| 22 | -// /** | ||
| 23 | -// * 是否开启 | ||
| 24 | -// */ | ||
| 25 | -// private Boolean enable = ENABLE_DEFAULT; | 17 | + /** |
| 18 | + * 租户是否开启 | ||
| 19 | + */ | ||
| 20 | + private static final Boolean ENABLE_DEFAULT = true; | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * 是否开启 | ||
| 24 | + */ | ||
| 25 | + private Boolean enable = ENABLE_DEFAULT; | ||
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * 需要忽略多租户的请求 | ||
| 29 | + * | ||
| 30 | + * 默认情况下,每个请求需要带上 tenant-id 的请求头。但是,部分请求是无需带上的,例如说短信回调、支付回调等 Open API! | ||
| 31 | + */ | ||
| 32 | + private Set<String> ignoreUrls; | ||
| 26 | 33 | ||
| 27 | /** | 34 | /** |
| 28 | - * 需要多租户的表 | 35 | + * 需要忽略多租户的表 |
| 29 | * | 36 | * |
| 30 | - * 由于多租户并不作为 yudao 项目的重点功能,更多是扩展性的功能,所以采用正向配置需要多租户的表。 | ||
| 31 | - * 如果需要,你可以改成 ignoreTables 来取消部分不需要的表 | 37 | + * 即默认所有表都开启多租户的功能,所以记得添加对应的 tenant_id 字段哟 |
| 32 | */ | 38 | */ |
| 33 | - private Set<String> tables; | 39 | + private Set<String> ignoreTables; |
| 34 | 40 | ||
| 35 | } | 41 | } |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantDatabaseAutoConfiguration.java
| @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; | @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; | ||
| 4 | import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor; | 4 | import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor; |
| 5 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; | 5 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
| 6 | import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; | 6 | import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; |
| 7 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
| 7 | import org.springframework.boot.context.properties.EnableConfigurationProperties; | 8 | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| 8 | import org.springframework.context.annotation.Bean; | 9 | import org.springframework.context.annotation.Bean; |
| 9 | import org.springframework.context.annotation.Configuration; | 10 | import org.springframework.context.annotation.Configuration; |
| @@ -14,6 +15,8 @@ import org.springframework.context.annotation.Configuration; | @@ -14,6 +15,8 @@ import org.springframework.context.annotation.Configuration; | ||
| 14 | * @author 芋道源码 | 15 | * @author 芋道源码 |
| 15 | */ | 16 | */ |
| 16 | @Configuration | 17 | @Configuration |
| 18 | +// 允许使用 yudao.tenant.enable=false 禁用多租户 | ||
| 19 | +@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) | ||
| 17 | @EnableConfigurationProperties(TenantProperties.class) | 20 | @EnableConfigurationProperties(TenantProperties.class) |
| 18 | public class YudaoTenantDatabaseAutoConfiguration { | 21 | public class YudaoTenantDatabaseAutoConfiguration { |
| 19 | 22 |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantJobAutoConfiguration.java
| @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.tenant.core.job.TenantJobHandlerDecorator; | @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.tenant.core.job.TenantJobHandlerDecorator; | ||
| 7 | import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService; | 7 | import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService; |
| 8 | import org.springframework.beans.BeansException; | 8 | import org.springframework.beans.BeansException; |
| 9 | import org.springframework.beans.factory.config.BeanPostProcessor; | 9 | import org.springframework.beans.factory.config.BeanPostProcessor; |
| 10 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
| 10 | import org.springframework.context.annotation.Bean; | 11 | import org.springframework.context.annotation.Bean; |
| 11 | import org.springframework.context.annotation.Configuration; | 12 | import org.springframework.context.annotation.Configuration; |
| 12 | 13 | ||
| @@ -16,6 +17,8 @@ import org.springframework.context.annotation.Configuration; | @@ -16,6 +17,8 @@ import org.springframework.context.annotation.Configuration; | ||
| 16 | * @author 芋道源码 | 17 | * @author 芋道源码 |
| 17 | */ | 18 | */ |
| 18 | @Configuration | 19 | @Configuration |
| 20 | +// 允许使用 yudao.tenant.enable=false 禁用多租户 | ||
| 21 | +@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) | ||
| 19 | public class YudaoTenantJobAutoConfiguration { | 22 | public class YudaoTenantJobAutoConfiguration { |
| 20 | 23 | ||
| 21 | @Bean | 24 | @Bean |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantMQAutoConfiguration.java
| 1 | package cn.iocoder.yudao.framework.tenant.config; | 1 | package cn.iocoder.yudao.framework.tenant.config; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.tenant.core.mq.TenantRedisMessageInterceptor; | 3 | import cn.iocoder.yudao.framework.tenant.core.mq.TenantRedisMessageInterceptor; |
| 4 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
| 4 | import org.springframework.context.annotation.Bean; | 5 | import org.springframework.context.annotation.Bean; |
| 5 | import org.springframework.context.annotation.Configuration; | 6 | import org.springframework.context.annotation.Configuration; |
| 6 | 7 | ||
| @@ -10,6 +11,8 @@ import org.springframework.context.annotation.Configuration; | @@ -10,6 +11,8 @@ import org.springframework.context.annotation.Configuration; | ||
| 10 | * @author 芋道源码 | 11 | * @author 芋道源码 |
| 11 | */ | 12 | */ |
| 12 | @Configuration | 13 | @Configuration |
| 14 | +// 允许使用 yudao.tenant.enable=false 禁用多租户 | ||
| 15 | +@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) | ||
| 13 | public class YudaoTenantMQAutoConfiguration { | 16 | public class YudaoTenantMQAutoConfiguration { |
| 14 | 17 | ||
| 15 | @Bean | 18 | @Bean |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantSecurityAutoConfiguration.java
| @@ -2,6 +2,9 @@ package cn.iocoder.yudao.framework.tenant.config; | @@ -2,6 +2,9 @@ package cn.iocoder.yudao.framework.tenant.config; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; | 3 | import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; |
| 4 | import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter; | 4 | import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter; |
| 5 | +import cn.iocoder.yudao.framework.web.config.WebProperties; | ||
| 6 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
| 7 | +import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
| 5 | import org.springframework.boot.web.servlet.FilterRegistrationBean; | 8 | import org.springframework.boot.web.servlet.FilterRegistrationBean; |
| 6 | import org.springframework.context.annotation.Bean; | 9 | import org.springframework.context.annotation.Bean; |
| 7 | import org.springframework.context.annotation.Configuration; | 10 | import org.springframework.context.annotation.Configuration; |
| @@ -12,12 +15,16 @@ import org.springframework.context.annotation.Configuration; | @@ -12,12 +15,16 @@ import org.springframework.context.annotation.Configuration; | ||
| 12 | * @author 芋道源码 | 15 | * @author 芋道源码 |
| 13 | */ | 16 | */ |
| 14 | @Configuration | 17 | @Configuration |
| 18 | +// 允许使用 yudao.tenant.enable=false 禁用多租户 | ||
| 19 | +@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) | ||
| 20 | +@EnableConfigurationProperties(TenantProperties.class) | ||
| 15 | public class YudaoTenantSecurityAutoConfiguration { | 21 | public class YudaoTenantSecurityAutoConfiguration { |
| 16 | 22 | ||
| 17 | @Bean | 23 | @Bean |
| 18 | - public FilterRegistrationBean<TenantSecurityWebFilter> tenantSecurityWebFilter() { | 24 | + public FilterRegistrationBean<TenantSecurityWebFilter> tenantSecurityWebFilter(TenantProperties tenantProperties, |
| 25 | + WebProperties webProperties) { | ||
| 19 | FilterRegistrationBean<TenantSecurityWebFilter> registrationBean = new FilterRegistrationBean<>(); | 26 | FilterRegistrationBean<TenantSecurityWebFilter> registrationBean = new FilterRegistrationBean<>(); |
| 20 | - registrationBean.setFilter(new TenantSecurityWebFilter()); | 27 | + registrationBean.setFilter(new TenantSecurityWebFilter(tenantProperties, webProperties)); |
| 21 | registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER); | 28 | registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER); |
| 22 | return registrationBean; | 29 | return registrationBean; |
| 23 | } | 30 | } |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantWebAutoConfiguration.java
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.tenant.config; | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.tenant.config; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; | 3 | import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; |
| 4 | import cn.iocoder.yudao.framework.tenant.core.web.TenantContextWebFilter; | 4 | import cn.iocoder.yudao.framework.tenant.core.web.TenantContextWebFilter; |
| 5 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
| 5 | import org.springframework.boot.web.servlet.FilterRegistrationBean; | 6 | import org.springframework.boot.web.servlet.FilterRegistrationBean; |
| 6 | import org.springframework.context.annotation.Bean; | 7 | import org.springframework.context.annotation.Bean; |
| 7 | import org.springframework.context.annotation.Configuration; | 8 | import org.springframework.context.annotation.Configuration; |
| @@ -12,6 +13,8 @@ import org.springframework.context.annotation.Configuration; | @@ -12,6 +13,8 @@ import org.springframework.context.annotation.Configuration; | ||
| 12 | * @author 芋道源码 | 13 | * @author 芋道源码 |
| 13 | */ | 14 | */ |
| 14 | @Configuration | 15 | @Configuration |
| 16 | +// 允许使用 yudao.tenant.enable=false 禁用多租户 | ||
| 17 | +@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) | ||
| 15 | public class YudaoTenantWebAutoConfiguration { | 18 | public class YudaoTenantWebAutoConfiguration { |
| 16 | 19 | ||
| 17 | @Bean | 20 | @Bean |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java
| @@ -33,7 +33,7 @@ public class TenantContextHolder { | @@ -33,7 +33,7 @@ public class TenantContextHolder { | ||
| 33 | public static Long getRequiredTenantId() { | 33 | public static Long getRequiredTenantId() { |
| 34 | Long tenantId = getTenantId(); | 34 | Long tenantId = getTenantId(); |
| 35 | if (tenantId == null) { | 35 | if (tenantId == null) { |
| 36 | - throw new NullPointerException("TenantContextHolder 不存在租户编号"); | 36 | + throw new NullPointerException("TenantContextHolder 不存在租户编号"); // TODO 芋艿:增加文档链接 |
| 37 | } | 37 | } |
| 38 | return tenantId; | 38 | return tenantId; |
| 39 | } | 39 | } |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java
| @@ -3,8 +3,6 @@ package cn.iocoder.yudao.framework.tenant.core.db; | @@ -3,8 +3,6 @@ package cn.iocoder.yudao.framework.tenant.core.db; | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.iocoder.yudao.framework.tenant.config.TenantProperties; | 4 | import cn.iocoder.yudao.framework.tenant.config.TenantProperties; |
| 5 | import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | 5 | import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; |
| 6 | -import com.baomidou.mybatisplus.core.metadata.TableInfo; | ||
| 7 | -import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; | ||
| 8 | import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; | 6 | import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; |
| 9 | import lombok.AllArgsConstructor; | 7 | import lombok.AllArgsConstructor; |
| 10 | import net.sf.jsqlparser.expression.Expression; | 8 | import net.sf.jsqlparser.expression.Expression; |
| @@ -27,13 +25,7 @@ public class TenantDatabaseInterceptor implements TenantLineHandler { | @@ -27,13 +25,7 @@ public class TenantDatabaseInterceptor implements TenantLineHandler { | ||
| 27 | 25 | ||
| 28 | @Override | 26 | @Override |
| 29 | public boolean ignoreTable(String tableName) { | 27 | public boolean ignoreTable(String tableName) { |
| 30 | - // 如果实体类继承 TenantBaseDO 类,则是多租户表,不进行忽略 | ||
| 31 | - TableInfo tableInfo = TableInfoHelper.getTableInfo(tableName); | ||
| 32 | - if (tableInfo != null && TenantBaseDO.class.isAssignableFrom(tableInfo.getEntityType())) { | ||
| 33 | - return false; | ||
| 34 | - } | ||
| 35 | - // 不包含,说明要过滤 | ||
| 36 | - return !CollUtil.contains(properties.getTables(), tableName); | 28 | + return CollUtil.contains(properties.getIgnoreTables(), tableName); |
| 37 | } | 29 | } |
| 38 | 30 | ||
| 39 | } | 31 | } |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java
| 1 | package cn.iocoder.yudao.framework.tenant.core.security; | 1 | package cn.iocoder.yudao.framework.tenant.core.security; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 3 | import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; | 4 | import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; | 6 | import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; |
| 6 | import cn.iocoder.yudao.framework.security.core.LoginUser; | 7 | import cn.iocoder.yudao.framework.security.core.LoginUser; |
| 7 | import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; | 8 | import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; |
| 9 | +import cn.iocoder.yudao.framework.tenant.config.TenantProperties; | ||
| 8 | import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | 10 | import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; |
| 11 | +import cn.iocoder.yudao.framework.web.config.WebProperties; | ||
| 12 | +import cn.iocoder.yudao.framework.web.core.filter.ApiRequestFilter; | ||
| 9 | import lombok.extern.slf4j.Slf4j; | 13 | import lombok.extern.slf4j.Slf4j; |
| 10 | -import org.springframework.web.filter.OncePerRequestFilter; | 14 | +import org.springframework.util.AntPathMatcher; |
| 11 | 15 | ||
| 12 | import javax.servlet.FilterChain; | 16 | import javax.servlet.FilterChain; |
| 13 | import javax.servlet.ServletException; | 17 | import javax.servlet.ServletException; |
| @@ -18,34 +22,72 @@ import java.util.Objects; | @@ -18,34 +22,72 @@ import java.util.Objects; | ||
| 18 | 22 | ||
| 19 | /** | 23 | /** |
| 20 | * 多租户 Security Web 过滤器 | 24 | * 多租户 Security Web 过滤器 |
| 21 | - * 校验用户访问的租户,是否是其所在的租户,避免越权问题 | 25 | + * 1. 如果是登陆的用户,校验是否有权限访问该租户,避免越权问题。 |
| 26 | + * 2. 如果请求未带租户的编号,检查是否是忽略的 URL,否则也不允许访问。 | ||
| 27 | + * | ||
| 28 | + * 校验用户访问的租户,是否是其所在的租户, | ||
| 22 | * | 29 | * |
| 23 | * @author 芋道源码 | 30 | * @author 芋道源码 |
| 24 | */ | 31 | */ |
| 25 | @Slf4j | 32 | @Slf4j |
| 26 | -public class TenantSecurityWebFilter extends OncePerRequestFilter { | 33 | +public class TenantSecurityWebFilter extends ApiRequestFilter { |
| 34 | + | ||
| 35 | + private final TenantProperties tenantProperties; | ||
| 36 | + private final AntPathMatcher pathMatcher; | ||
| 37 | + | ||
| 38 | + public TenantSecurityWebFilter(TenantProperties tenantProperties, | ||
| 39 | + WebProperties webProperties) { | ||
| 40 | + super(webProperties); | ||
| 41 | + this.tenantProperties = tenantProperties; | ||
| 42 | + this.pathMatcher = new AntPathMatcher(); | ||
| 43 | + } | ||
| 27 | 44 | ||
| 28 | @Override | 45 | @Override |
| 29 | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) | 46 | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) |
| 30 | throws ServletException, IOException { | 47 | throws ServletException, IOException { |
| 48 | + Long tenantId = TenantContextHolder.getTenantId(); | ||
| 49 | + // 1. 登陆的用户,校验是否有权限访问该租户,避免越权问题。 | ||
| 31 | LoginUser user = SecurityFrameworkUtils.getLoginUser(); | 50 | LoginUser user = SecurityFrameworkUtils.getLoginUser(); |
| 32 | - assert user != null; // shouldNotFilter 已经校验 | ||
| 33 | - // 校验租户是否匹配。 | ||
| 34 | - if (!Objects.equals(user.getTenantId(), TenantContextHolder.getTenantId())) { | ||
| 35 | - log.error("[doFilterInternal][租户({}) User({}/{}) 越权访问租户({}) URL({}/{})]", | ||
| 36 | - user.getTenantId(), user.getId(), user.getUserType(), | ||
| 37 | - TenantContextHolder.getTenantId(), request.getRequestURI(), request.getMethod()); | ||
| 38 | - ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.FORBIDDEN.getCode(), | ||
| 39 | - "您无权访问该租户的数据")); | 51 | + if (user != null) { |
| 52 | + // 如果获取不到租户编号,则尝试使用登陆用户的租户编号 | ||
| 53 | + if (tenantId == null) { | ||
| 54 | + tenantId = user.getTenantId(); | ||
| 55 | + TenantContextHolder.setTenantId(tenantId); | ||
| 56 | + // 如果传递了租户编号,则进行比对租户编号,避免越权问题 | ||
| 57 | + } else if (!Objects.equals(user.getTenantId(), TenantContextHolder.getTenantId())) { | ||
| 58 | + log.error("[doFilterInternal][租户({}) User({}/{}) 越权访问租户({}) URL({}/{})]", | ||
| 59 | + user.getTenantId(), user.getId(), user.getUserType(), | ||
| 60 | + TenantContextHolder.getTenantId(), request.getRequestURI(), request.getMethod()); | ||
| 61 | + ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.FORBIDDEN.getCode(), | ||
| 62 | + "您无权访问该租户的数据")); | ||
| 63 | + return; | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + // 2. 如果请求未带租户的编号,检查是否是忽略的 URL,否则也不允许访问。 | ||
| 68 | + if (tenantId == null && !isIgnoreUrl(request)) { | ||
| 69 | + log.error("[doFilterInternal][URL({}/{}) 未传递租户编号]", request.getRequestURI(), request.getMethod()); | ||
| 70 | + ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), | ||
| 71 | + "租户的请求未传递,请进行排查")); | ||
| 40 | return; | 72 | return; |
| 41 | } | 73 | } |
| 74 | + | ||
| 42 | // 继续过滤 | 75 | // 继续过滤 |
| 43 | chain.doFilter(request, response); | 76 | chain.doFilter(request, response); |
| 44 | } | 77 | } |
| 45 | 78 | ||
| 46 | - @Override | ||
| 47 | - protected boolean shouldNotFilter(HttpServletRequest request) { | ||
| 48 | - return SecurityFrameworkUtils.getLoginUser() == null; | 79 | + private boolean isIgnoreUrl(HttpServletRequest request) { |
| 80 | + // 快速匹配,保证性能 | ||
| 81 | + if (CollUtil.contains(tenantProperties.getIgnoreUrls(), request.getRequestURI())) { | ||
| 82 | + return true; | ||
| 83 | + } | ||
| 84 | + // 逐个 Ant 路径匹配 | ||
| 85 | + for (String url : tenantProperties.getIgnoreUrls()) { | ||
| 86 | + if (pathMatcher.match(url, request.getRequestURI())) { | ||
| 87 | + return true; | ||
| 88 | + } | ||
| 89 | + } | ||
| 90 | + return false; | ||
| 49 | } | 91 | } |
| 50 | 92 | ||
| 51 | } | 93 | } |
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java
| @@ -8,15 +8,9 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties | @@ -8,15 +8,9 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties | ||
| 8 | import org.springframework.context.annotation.Bean; | 8 | import org.springframework.context.annotation.Bean; |
| 9 | import org.springframework.context.annotation.Configuration; | 9 | import org.springframework.context.annotation.Configuration; |
| 10 | import org.springframework.http.HttpHeaders; | 10 | import org.springframework.http.HttpHeaders; |
| 11 | -import springfox.documentation.RequestHandler; | ||
| 12 | import springfox.documentation.builders.ApiInfoBuilder; | 11 | import springfox.documentation.builders.ApiInfoBuilder; |
| 13 | import springfox.documentation.builders.PathSelectors; | 12 | import springfox.documentation.builders.PathSelectors; |
| 14 | -import springfox.documentation.service.ApiInfo; | ||
| 15 | -import springfox.documentation.service.ApiKey; | ||
| 16 | -import springfox.documentation.service.AuthorizationScope; | ||
| 17 | -import springfox.documentation.service.Contact; | ||
| 18 | -import springfox.documentation.service.SecurityReference; | ||
| 19 | -import springfox.documentation.service.SecurityScheme; | 13 | +import springfox.documentation.service.*; |
| 20 | import springfox.documentation.spi.DocumentationType; | 14 | import springfox.documentation.spi.DocumentationType; |
| 21 | import springfox.documentation.spi.service.contexts.SecurityContext; | 15 | import springfox.documentation.spi.service.contexts.SecurityContext; |
| 22 | import springfox.documentation.spring.web.plugins.Docket; | 16 | import springfox.documentation.spring.web.plugins.Docket; |
| @@ -24,7 +18,6 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; | @@ -24,7 +18,6 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; | ||
| 24 | 18 | ||
| 25 | import java.util.Collections; | 19 | import java.util.Collections; |
| 26 | import java.util.List; | 20 | import java.util.List; |
| 27 | -import java.util.function.Predicate; | ||
| 28 | 21 | ||
| 29 | import static springfox.documentation.builders.RequestHandlerSelectors.basePackage; | 22 | import static springfox.documentation.builders.RequestHandlerSelectors.basePackage; |
| 30 | 23 | ||
| @@ -37,8 +30,8 @@ import static springfox.documentation.builders.RequestHandlerSelectors.basePacka | @@ -37,8 +30,8 @@ import static springfox.documentation.builders.RequestHandlerSelectors.basePacka | ||
| 37 | @EnableSwagger2 | 30 | @EnableSwagger2 |
| 38 | @EnableKnife4j | 31 | @EnableKnife4j |
| 39 | @ConditionalOnClass({Docket.class, ApiInfoBuilder.class}) | 32 | @ConditionalOnClass({Docket.class, ApiInfoBuilder.class}) |
| 40 | -@ConditionalOnProperty(prefix = "yudao.swagger", value = "enable", matchIfMissing = true) | ||
| 41 | // 允许使用 swagger.enable=false 禁用 Swagger | 33 | // 允许使用 swagger.enable=false 禁用 Swagger |
| 34 | +@ConditionalOnProperty(prefix = "yudao.swagger", value = "enable", matchIfMissing = true) | ||
| 42 | @EnableConfigurationProperties(SwaggerProperties.class) | 35 | @EnableConfigurationProperties(SwaggerProperties.class) |
| 43 | public class YudaoSwaggerAutoConfiguration { | 36 | public class YudaoSwaggerAutoConfiguration { |
| 44 | 37 |
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/ApiRequestFilter.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.web.core.filter; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.util.StrUtil; | ||
| 4 | +import cn.iocoder.yudao.framework.web.config.WebProperties; | ||
| 5 | +import lombok.RequiredArgsConstructor; | ||
| 6 | +import org.springframework.web.filter.OncePerRequestFilter; | ||
| 7 | + | ||
| 8 | +import javax.servlet.http.HttpServletRequest; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * 过滤 /admin-api、/app-api 等 API 请求的过滤器 | ||
| 12 | + * | ||
| 13 | + * @author 芋道源码 | ||
| 14 | + */ | ||
| 15 | +@RequiredArgsConstructor | ||
| 16 | +public abstract class ApiRequestFilter extends OncePerRequestFilter { | ||
| 17 | + | ||
| 18 | + protected final WebProperties webProperties; | ||
| 19 | + | ||
| 20 | + @Override | ||
| 21 | + protected boolean shouldNotFilter(HttpServletRequest request) { | ||
| 22 | + // 只过滤 API 请求的地址 | ||
| 23 | + return !StrUtil.startWithAny(request.getRequestURI(), webProperties.getAdminApi().getPrefix(), | ||
| 24 | + webProperties.getAppApi().getPrefix()); | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | +} |
yudao-module-infra/yudao-module-infra-impl/pom.xml
| @@ -39,10 +39,6 @@ | @@ -39,10 +39,6 @@ | ||
| 39 | <groupId>cn.iocoder.boot</groupId> | 39 | <groupId>cn.iocoder.boot</groupId> |
| 40 | <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId> | 40 | <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId> |
| 41 | </dependency> | 41 | </dependency> |
| 42 | - <dependency> | ||
| 43 | - <groupId>cn.iocoder.boot</groupId> | ||
| 44 | - <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> | ||
| 45 | - </dependency> | ||
| 46 | 42 | ||
| 47 | <!-- Web 相关 --> | 43 | <!-- Web 相关 --> |
| 48 | <dependency> | 44 | <dependency> |
| @@ -67,6 +63,12 @@ | @@ -67,6 +63,12 @@ | ||
| 67 | <artifactId>yudao-spring-boot-starter-config</artifactId> | 63 | <artifactId>yudao-spring-boot-starter-config</artifactId> |
| 68 | </dependency> | 64 | </dependency> |
| 69 | 65 | ||
| 66 | + <!-- Job 定时任务相关 --> | ||
| 67 | + <dependency> | ||
| 68 | + <groupId>cn.iocoder.boot</groupId> | ||
| 69 | + <artifactId>yudao-spring-boot-starter-job</artifactId> | ||
| 70 | + </dependency> | ||
| 71 | + | ||
| 70 | <!-- 消息队列相关 --> | 72 | <!-- 消息队列相关 --> |
| 71 | <dependency> | 73 | <dependency> |
| 72 | <groupId>cn.iocoder.boot</groupId> | 74 | <groupId>cn.iocoder.boot</groupId> |
yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java
| @@ -4,7 +4,6 @@ import cn.hutool.core.io.IoUtil; | @@ -4,7 +4,6 @@ import cn.hutool.core.io.IoUtil; | ||
| 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; | 6 | import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; |
| 7 | -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | ||
| 8 | import cn.iocoder.yudao.module.infra.controller.admin.file.vo.FilePageReqVO; | 7 | import cn.iocoder.yudao.module.infra.controller.admin.file.vo.FilePageReqVO; |
| 9 | import cn.iocoder.yudao.module.infra.controller.admin.file.vo.FileRespVO; | 8 | import cn.iocoder.yudao.module.infra.controller.admin.file.vo.FileRespVO; |
| 10 | import cn.iocoder.yudao.module.infra.convert.file.FileConvert; | 9 | import cn.iocoder.yudao.module.infra.convert.file.FileConvert; |
| @@ -62,7 +61,6 @@ public class FileController { | @@ -62,7 +61,6 @@ public class FileController { | ||
| 62 | @ApiOperation("下载文件") | 61 | @ApiOperation("下载文件") |
| 63 | @ApiImplicitParam(name = "path", value = "文件附件", required = true, dataTypeClass = MultipartFile.class) | 62 | @ApiImplicitParam(name = "path", value = "文件附件", required = true, dataTypeClass = MultipartFile.class) |
| 64 | public void getFile(HttpServletResponse response, @PathVariable("path") String path) throws IOException { | 63 | public void getFile(HttpServletResponse response, @PathVariable("path") String path) throws IOException { |
| 65 | - TenantContextHolder.setNullTenantId(); | ||
| 66 | FileDO file = fileService.getFile(path); | 64 | FileDO file = fileService.getFile(path); |
| 67 | if (file == null) { | 65 | if (file == null) { |
| 68 | log.warn("[getFile][path({}) 文件不存在]", path); | 66 | log.warn("[getFile][path({}) 文件不存在]", path); |
yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/file/FileDO.java
| 1 | package cn.iocoder.yudao.module.infra.dal.dataobject.file; | 1 | package cn.iocoder.yudao.module.infra.dal.dataobject.file; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | import com.baomidou.mybatisplus.annotation.IdType; | 4 | import com.baomidou.mybatisplus.annotation.IdType; |
| 5 | import com.baomidou.mybatisplus.annotation.TableField; | 5 | import com.baomidou.mybatisplus.annotation.TableField; |
| 6 | import com.baomidou.mybatisplus.annotation.TableId; | 6 | import com.baomidou.mybatisplus.annotation.TableId; |
| @@ -21,7 +21,7 @@ import java.io.InputStream; | @@ -21,7 +21,7 @@ import java.io.InputStream; | ||
| 21 | @Builder | 21 | @Builder |
| 22 | @NoArgsConstructor | 22 | @NoArgsConstructor |
| 23 | @AllArgsConstructor | 23 | @AllArgsConstructor |
| 24 | -public class FileDO extends TenantBaseDO { | 24 | +public class FileDO extends BaseDO { |
| 25 | 25 | ||
| 26 | /** | 26 | /** |
| 27 | * 文件路径 | 27 | * 文件路径 |
yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/logger/ApiAccessLogDO.java
| @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.logger; | @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.logger; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | 5 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 6 | import com.baomidou.mybatisplus.annotation.TableId; | 6 | import com.baomidou.mybatisplus.annotation.TableId; |
| 7 | import com.baomidou.mybatisplus.annotation.TableName; | 7 | import com.baomidou.mybatisplus.annotation.TableName; |
| 8 | import lombok.*; | 8 | import lombok.*; |
| @@ -21,7 +21,7 @@ import java.util.Date; | @@ -21,7 +21,7 @@ import java.util.Date; | ||
| 21 | @Builder | 21 | @Builder |
| 22 | @NoArgsConstructor | 22 | @NoArgsConstructor |
| 23 | @AllArgsConstructor | 23 | @AllArgsConstructor |
| 24 | -public class ApiAccessLogDO extends TenantBaseDO { | 24 | +public class ApiAccessLogDO extends BaseDO { |
| 25 | 25 | ||
| 26 | /** | 26 | /** |
| 27 | * 编号 | 27 | * 编号 |
yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/logger/ApiErrorLogDO.java
| 1 | package cn.iocoder.yudao.module.infra.dal.dataobject.logger; | 1 | package cn.iocoder.yudao.module.infra.dal.dataobject.logger; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |
| 4 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | 4 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 5 | import cn.iocoder.yudao.module.infra.enums.logger.ApiErrorLogProcessStatusEnum; | 5 | import cn.iocoder.yudao.module.infra.enums.logger.ApiErrorLogProcessStatusEnum; |
| 6 | import com.baomidou.mybatisplus.annotation.TableId; | 6 | import com.baomidou.mybatisplus.annotation.TableId; |
| 7 | import com.baomidou.mybatisplus.annotation.TableName; | 7 | import com.baomidou.mybatisplus.annotation.TableName; |
| @@ -21,7 +21,7 @@ import java.util.Date; | @@ -21,7 +21,7 @@ import java.util.Date; | ||
| 21 | @Builder | 21 | @Builder |
| 22 | @NoArgsConstructor | 22 | @NoArgsConstructor |
| 23 | @AllArgsConstructor | 23 | @AllArgsConstructor |
| 24 | -public class ApiErrorLogDO extends TenantBaseDO { | 24 | +public class ApiErrorLogDO extends BaseDO { |
| 25 | 25 | ||
| 26 | /** | 26 | /** |
| 27 | * 编号 | 27 | * 编号 |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/LoginLogCreateReqDTO.java
| @@ -54,8 +54,9 @@ public class LoginLogCreateReqDTO { | @@ -54,8 +54,9 @@ public class LoginLogCreateReqDTO { | ||
| 54 | private String userIp; | 54 | private String userIp; |
| 55 | /** | 55 | /** |
| 56 | * 浏览器 UserAgent | 56 | * 浏览器 UserAgent |
| 57 | + * | ||
| 58 | + * 允许空,原因:Job 过期登出时,是无法传递 UserAgent 的 | ||
| 57 | */ | 59 | */ |
| 58 | - @NotEmpty(message = "浏览器 UserAgent 不能为空") | ||
| 59 | private String userAgent; | 60 | private String userAgent; |
| 60 | 61 | ||
| 61 | } | 62 | } |
yudao-module-system/yudao-module-system-impl/pom.xml
| @@ -53,11 +53,11 @@ | @@ -53,11 +53,11 @@ | ||
| 53 | </dependency> | 53 | </dependency> |
| 54 | <dependency> | 54 | <dependency> |
| 55 | <groupId>cn.iocoder.boot</groupId> | 55 | <groupId>cn.iocoder.boot</groupId> |
| 56 | - <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> | 56 | + <artifactId>yudao-spring-boot-starter-biz-social</artifactId> |
| 57 | </dependency> | 57 | </dependency> |
| 58 | <dependency> | 58 | <dependency> |
| 59 | <groupId>cn.iocoder.boot</groupId> | 59 | <groupId>cn.iocoder.boot</groupId> |
| 60 | - <artifactId>yudao-spring-boot-starter-biz-social</artifactId> | 60 | + <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> |
| 61 | </dependency> | 61 | </dependency> |
| 62 | 62 | ||
| 63 | <!-- Web 相关 --> | 63 | <!-- Web 相关 --> |
| @@ -77,6 +77,12 @@ | @@ -77,6 +77,12 @@ | ||
| 77 | <artifactId>yudao-spring-boot-starter-redis</artifactId> | 77 | <artifactId>yudao-spring-boot-starter-redis</artifactId> |
| 78 | </dependency> | 78 | </dependency> |
| 79 | 79 | ||
| 80 | + <!-- Job 定时任务相关 --> | ||
| 81 | + <dependency> | ||
| 82 | + <groupId>cn.iocoder.boot</groupId> | ||
| 83 | + <artifactId>yudao-spring-boot-starter-job</artifactId> | ||
| 84 | + </dependency> | ||
| 85 | + | ||
| 80 | <!-- 消息队列相关 --> | 86 | <!-- 消息队列相关 --> |
| 81 | <dependency> | 87 | <dependency> |
| 82 | <groupId>cn.iocoder.boot</groupId> | 88 | <groupId>cn.iocoder.boot</groupId> |
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/auth/UserSessionDO.java
| 1 | package cn.iocoder.yudao.module.system.dal.dataobject.auth; | 1 | package cn.iocoder.yudao.module.system.dal.dataobject.auth; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 4 | import cn.iocoder.yudao.framework.security.core.LoginUser; | 5 | import cn.iocoder.yudao.framework.security.core.LoginUser; |
| 5 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | ||
| 6 | import com.baomidou.mybatisplus.annotation.IdType; | 6 | import com.baomidou.mybatisplus.annotation.IdType; |
| 7 | import com.baomidou.mybatisplus.annotation.TableId; | 7 | import com.baomidou.mybatisplus.annotation.TableId; |
| 8 | import com.baomidou.mybatisplus.annotation.TableName; | 8 | import com.baomidou.mybatisplus.annotation.TableName; |
| @@ -25,7 +25,7 @@ import java.util.Date; | @@ -25,7 +25,7 @@ import java.util.Date; | ||
| 25 | @Data | 25 | @Data |
| 26 | @Builder | 26 | @Builder |
| 27 | @EqualsAndHashCode(callSuper = true) | 27 | @EqualsAndHashCode(callSuper = true) |
| 28 | -public class UserSessionDO extends TenantBaseDO { | 28 | +public class UserSessionDO extends BaseDO { |
| 29 | 29 | ||
| 30 | /** | 30 | /** |
| 31 | * 会话编号, 即 sessionId | 31 | * 会话编号, 即 sessionId |
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java
| 1 | package cn.iocoder.yudao.module.system.dal.dataobject.dept; | 1 | package cn.iocoder.yudao.module.system.dal.dataobject.dept; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; | ||
| 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 3 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 5 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | 4 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 5 | +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; | ||
| 6 | import com.baomidou.mybatisplus.annotation.TableId; | 6 | import com.baomidou.mybatisplus.annotation.TableId; |
| 7 | import com.baomidou.mybatisplus.annotation.TableName; | 7 | import com.baomidou.mybatisplus.annotation.TableName; |
| 8 | import lombok.Data; | 8 | import lombok.Data; |
| @@ -17,7 +17,7 @@ import lombok.EqualsAndHashCode; | @@ -17,7 +17,7 @@ import lombok.EqualsAndHashCode; | ||
| 17 | @TableName("system_dept") | 17 | @TableName("system_dept") |
| 18 | @Data | 18 | @Data |
| 19 | @EqualsAndHashCode(callSuper = true) | 19 | @EqualsAndHashCode(callSuper = true) |
| 20 | -public class DeptDO extends TenantBaseDO { | 20 | +public class DeptDO extends BaseDO { |
| 21 | 21 | ||
| 22 | /** | 22 | /** |
| 23 | * 部门ID | 23 | * 部门ID |
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/PostDO.java
| 1 | package cn.iocoder.yudao.module.system.dal.dataobject.dept; | 1 | package cn.iocoder.yudao.module.system.dal.dataobject.dept; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 3 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 4 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | 4 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 5 | import com.baomidou.mybatisplus.annotation.TableId; | 5 | import com.baomidou.mybatisplus.annotation.TableId; |
| 6 | import com.baomidou.mybatisplus.annotation.TableName; | 6 | import com.baomidou.mybatisplus.annotation.TableName; |
| 7 | import lombok.Data; | 7 | import lombok.Data; |
| @@ -15,7 +15,7 @@ import lombok.EqualsAndHashCode; | @@ -15,7 +15,7 @@ import lombok.EqualsAndHashCode; | ||
| 15 | @TableName("system_post") | 15 | @TableName("system_post") |
| 16 | @Data | 16 | @Data |
| 17 | @EqualsAndHashCode(callSuper = true) | 17 | @EqualsAndHashCode(callSuper = true) |
| 18 | -public class PostDO extends TenantBaseDO { | 18 | +public class PostDO extends BaseDO { |
| 19 | 19 | ||
| 20 | /** | 20 | /** |
| 21 | * 岗位序号 | 21 | * 岗位序号 |
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogDO.java
| @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.system.dal.dataobject.logger; | @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.system.dal.dataobject.logger; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | 3 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 5 | import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum; | 6 | import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum; |
| 6 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | ||
| 7 | import com.baomidou.mybatisplus.annotation.TableField; | 7 | import com.baomidou.mybatisplus.annotation.TableField; |
| 8 | import com.baomidou.mybatisplus.annotation.TableId; | 8 | import com.baomidou.mybatisplus.annotation.TableId; |
| 9 | import com.baomidou.mybatisplus.annotation.TableName; | 9 | import com.baomidou.mybatisplus.annotation.TableName; |
| @@ -22,7 +22,7 @@ import java.util.Map; | @@ -22,7 +22,7 @@ import java.util.Map; | ||
| 22 | @TableName(value = "system_operate_log", autoResultMap = true) | 22 | @TableName(value = "system_operate_log", autoResultMap = true) |
| 23 | @Data | 23 | @Data |
| 24 | @EqualsAndHashCode(callSuper = true) | 24 | @EqualsAndHashCode(callSuper = true) |
| 25 | -public class OperateLogDO extends TenantBaseDO { | 25 | +public class OperateLogDO extends BaseDO { |
| 26 | 26 | ||
| 27 | /** | 27 | /** |
| 28 | * {@link #javaMethodArgs} 的最大长度 | 28 | * {@link #javaMethodArgs} 的最大长度 |
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/notice/NoticeDO.java
| 1 | package cn.iocoder.yudao.module.system.dal.dataobject.notice; | 1 | package cn.iocoder.yudao.module.system.dal.dataobject.notice; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.system.enums.notice.NoticeTypeEnum; | ||
| 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 3 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 5 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | 4 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 5 | +import cn.iocoder.yudao.module.system.enums.notice.NoticeTypeEnum; | ||
| 6 | import com.baomidou.mybatisplus.annotation.TableField; | 6 | import com.baomidou.mybatisplus.annotation.TableField; |
| 7 | import com.baomidou.mybatisplus.annotation.TableName; | 7 | import com.baomidou.mybatisplus.annotation.TableName; |
| 8 | import lombok.Data; | 8 | import lombok.Data; |
| @@ -16,7 +16,7 @@ import lombok.EqualsAndHashCode; | @@ -16,7 +16,7 @@ import lombok.EqualsAndHashCode; | ||
| 16 | @TableName("system_notice") | 16 | @TableName("system_notice") |
| 17 | @Data | 17 | @Data |
| 18 | @EqualsAndHashCode(callSuper = true) | 18 | @EqualsAndHashCode(callSuper = true) |
| 19 | -public class NoticeDO extends TenantBaseDO { | 19 | +public class NoticeDO extends BaseDO { |
| 20 | 20 | ||
| 21 | /** | 21 | /** |
| 22 | * 公告ID | 22 | * 公告ID |
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java
| 1 | package cn.iocoder.yudao.module.system.dal.dataobject.user; | 1 | package cn.iocoder.yudao.module.system.dal.dataobject.user; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.system.enums.common.SexEnum; | ||
| 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 3 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 5 | import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; | 4 | import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; |
| 6 | import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | 5 | import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; |
| 6 | +import cn.iocoder.yudao.module.system.enums.common.SexEnum; | ||
| 7 | import com.baomidou.mybatisplus.annotation.TableField; | 7 | import com.baomidou.mybatisplus.annotation.TableField; |
| 8 | import com.baomidou.mybatisplus.annotation.TableId; | 8 | import com.baomidou.mybatisplus.annotation.TableId; |
| 9 | import com.baomidou.mybatisplus.annotation.TableName; | 9 | import com.baomidou.mybatisplus.annotation.TableName; |
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/job/auth/UserSessionTimeoutJob.java
| @@ -19,12 +19,12 @@ import javax.annotation.Resource; | @@ -19,12 +19,12 @@ import javax.annotation.Resource; | ||
| 19 | public class UserSessionTimeoutJob implements JobHandler { | 19 | public class UserSessionTimeoutJob implements JobHandler { |
| 20 | 20 | ||
| 21 | @Resource | 21 | @Resource |
| 22 | - private UserSessionService sysUserSessionService; | 22 | + private UserSessionService userSessionService; |
| 23 | 23 | ||
| 24 | @Override | 24 | @Override |
| 25 | public String execute(String param) throws Exception { | 25 | public String execute(String param) throws Exception { |
| 26 | // 执行过期 | 26 | // 执行过期 |
| 27 | - Long timeoutCount = sysUserSessionService.clearSessionTimeout(); | 27 | + Long timeoutCount = userSessionService.clearSessionTimeout(); |
| 28 | // 返回结果,记录每次的超时数量 | 28 | // 返回结果,记录每次的超时数量 |
| 29 | return String.format("移除在线会话数量为 %s 个", timeoutCount); | 29 | return String.format("移除在线会话数量为 %s 个", timeoutCount); |
| 30 | } | 30 | } |
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java
| @@ -146,7 +146,7 @@ public class PermissionServiceImpl implements PermissionService { | @@ -146,7 +146,7 @@ public class PermissionServiceImpl implements PermissionService { | ||
| 146 | public List<MenuDO> getRoleMenusFromCache(Collection<Long> roleIds, Collection<Integer> menuTypes, | 146 | public List<MenuDO> getRoleMenusFromCache(Collection<Long> roleIds, Collection<Integer> menuTypes, |
| 147 | Collection<Integer> menusStatuses) { | 147 | Collection<Integer> menusStatuses) { |
| 148 | // 任一一个参数为空时,不返回任何菜单 | 148 | // 任一一个参数为空时,不返回任何菜单 |
| 149 | - if (CollectionUtils.isAnyEmpty(roleIds, menusStatuses, menusStatuses)) { | 149 | + if (CollectionUtils.isAnyEmpty(roleIds, menuTypes, menusStatuses)) { |
| 150 | return Collections.emptyList(); | 150 | return Collections.emptyList(); |
| 151 | } | 151 | } |
| 152 | // 判断角色是否包含管理员 | 152 | // 判断角色是否包含管理员 |
yudao-module-tool/yudao-module-tool-impl/pom.xml
| @@ -38,10 +38,6 @@ | @@ -38,10 +38,6 @@ | ||
| 38 | <groupId>cn.iocoder.boot</groupId> | 38 | <groupId>cn.iocoder.boot</groupId> |
| 39 | <artifactId>yudao-spring-boot-starter-biz-dict</artifactId> | 39 | <artifactId>yudao-spring-boot-starter-biz-dict</artifactId> |
| 40 | </dependency> | 40 | </dependency> |
| 41 | - <dependency> | ||
| 42 | - <groupId>cn.iocoder.boot</groupId> | ||
| 43 | - <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> | ||
| 44 | - </dependency> | ||
| 45 | 41 | ||
| 46 | <!-- Web 相关 --> | 42 | <!-- Web 相关 --> |
| 47 | <dependency> | 43 | <dependency> |
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/codegen/inner/CodegenBuilder.java
| @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.tool.service.codegen.inner; | @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.tool.service.codegen.inner; | ||
| 3 | import cn.hutool.core.map.MapUtil; | 3 | import cn.hutool.core.map.MapUtil; |
| 4 | import cn.hutool.core.util.ReflectUtil; | 4 | import cn.hutool.core.util.ReflectUtil; |
| 5 | import cn.hutool.core.util.StrUtil; | 5 | import cn.hutool.core.util.StrUtil; |
| 6 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | 6 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 7 | import cn.iocoder.yudao.module.tool.convert.codegen.CodegenConvert; | 7 | import cn.iocoder.yudao.module.tool.convert.codegen.CodegenConvert; |
| 8 | import cn.iocoder.yudao.module.tool.dal.dataobject.codegen.CodegenColumnDO; | 8 | import cn.iocoder.yudao.module.tool.dal.dataobject.codegen.CodegenColumnDO; |
| 9 | import cn.iocoder.yudao.module.tool.dal.dataobject.codegen.CodegenTableDO; | 9 | import cn.iocoder.yudao.module.tool.dal.dataobject.codegen.CodegenTableDO; |
| @@ -60,7 +60,7 @@ public class CodegenBuilder { | @@ -60,7 +60,7 @@ public class CodegenBuilder { | ||
| 60 | */ | 60 | */ |
| 61 | public static final String TENANT_ID_FIELD = "tenant_id"; | 61 | public static final String TENANT_ID_FIELD = "tenant_id"; |
| 62 | /** | 62 | /** |
| 63 | - * {@link TenantBaseDO} 的字段 | 63 | + * {@link cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO} 的字段 |
| 64 | */ | 64 | */ |
| 65 | public static final Set<String> BASE_DO_FIELDS = new HashSet<>(); | 65 | public static final Set<String> BASE_DO_FIELDS = new HashSet<>(); |
| 66 | /** | 66 | /** |
| @@ -96,7 +96,8 @@ public class CodegenBuilder { | @@ -96,7 +96,8 @@ public class CodegenBuilder { | ||
| 96 | .build(); | 96 | .build(); |
| 97 | 97 | ||
| 98 | static { | 98 | static { |
| 99 | - Arrays.stream(ReflectUtil.getFields(TenantBaseDO.class)).forEach(field -> BASE_DO_FIELDS.add(field.getName())); | 99 | + Arrays.stream(ReflectUtil.getFields(BaseDO.class)).forEach(field -> BASE_DO_FIELDS.add(field.getName())); |
| 100 | + BASE_DO_FIELDS.add(TENANT_ID_FIELD); | ||
| 100 | // 处理 OPERATION 相关的字段 | 101 | // 处理 OPERATION 相关的字段 |
| 101 | CREATE_OPERATION_EXCLUDE_COLUMN.addAll(BASE_DO_FIELDS); | 102 | CREATE_OPERATION_EXCLUDE_COLUMN.addAll(BASE_DO_FIELDS); |
| 102 | UPDATE_OPERATION_EXCLUDE_COLUMN.addAll(BASE_DO_FIELDS); | 103 | UPDATE_OPERATION_EXCLUDE_COLUMN.addAll(BASE_DO_FIELDS); |
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/codegen/inner/CodegenEngine.java
| 1 | package cn.iocoder.yudao.module.tool.service.codegen.inner; | 1 | package cn.iocoder.yudao.module.tool.service.codegen.inner; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.collection.ListUtil; | ||
| 4 | import cn.hutool.core.map.MapUtil; | 3 | import cn.hutool.core.map.MapUtil; |
| 5 | -import cn.hutool.core.util.ArrayUtil; | ||
| 6 | import cn.hutool.core.util.StrUtil; | 4 | import cn.hutool.core.util.StrUtil; |
| 7 | import cn.hutool.extra.template.TemplateConfig; | 5 | import cn.hutool.extra.template.TemplateConfig; |
| 8 | import cn.hutool.extra.template.TemplateEngine; | 6 | import cn.hutool.extra.template.TemplateEngine; |
| @@ -11,23 +9,21 @@ import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; | @@ -11,23 +9,21 @@ import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; | ||
| 11 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 9 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 12 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 10 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 13 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 11 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 14 | -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||
| 15 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | ||
| 16 | -import cn.iocoder.yudao.module.tool.enums.codegen.CodegenSceneEnum; | ||
| 17 | -import cn.iocoder.yudao.module.tool.framework.codegen.config.CodegenProperties; | 12 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 13 | +import cn.iocoder.yudao.framework.common.util.date.DateUtils; | ||
| 18 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | 14 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; |
| 19 | import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; | 15 | import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; |
| 20 | import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; | 16 | import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; |
| 21 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | 17 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| 22 | -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | ||
| 23 | -import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum; | ||
| 24 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 18 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 25 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | 19 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 26 | -import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; | 20 | +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 21 | +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | ||
| 22 | +import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum; | ||
| 27 | import cn.iocoder.yudao.module.tool.dal.dataobject.codegen.CodegenColumnDO; | 23 | import cn.iocoder.yudao.module.tool.dal.dataobject.codegen.CodegenColumnDO; |
| 28 | import cn.iocoder.yudao.module.tool.dal.dataobject.codegen.CodegenTableDO; | 24 | import cn.iocoder.yudao.module.tool.dal.dataobject.codegen.CodegenTableDO; |
| 29 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 30 | -import cn.iocoder.yudao.framework.common.util.date.DateUtils; | 25 | +import cn.iocoder.yudao.module.tool.enums.codegen.CodegenSceneEnum; |
| 26 | +import cn.iocoder.yudao.module.tool.framework.codegen.config.CodegenProperties; | ||
| 31 | import com.google.common.collect.Maps; | 27 | import com.google.common.collect.Maps; |
| 32 | import org.springframework.stereotype.Component; | 28 | import org.springframework.stereotype.Component; |
| 33 | 29 | ||
| @@ -115,7 +111,8 @@ public class CodegenEngine { | @@ -115,7 +111,8 @@ public class CodegenEngine { | ||
| 115 | private void initGlobalBindingMap() { | 111 | private void initGlobalBindingMap() { |
| 116 | // 全局配置 | 112 | // 全局配置 |
| 117 | globalBindingMap.put("basePackage", codegenProperties.getBasePackage()); | 113 | globalBindingMap.put("basePackage", codegenProperties.getBasePackage()); |
| 118 | - globalBindingMap.put("baseFrameworkPackage", codegenProperties.getBasePackage() + '.' + "framework"); // 用于后续获取测试类的 package 地址 | 114 | + globalBindingMap.put("baseFrameworkPackage", codegenProperties.getBasePackage() |
| 115 | + + '.' + "framework"); // 用于后续获取测试类的 package 地址 | ||
| 119 | // 全局 Java Bean | 116 | // 全局 Java Bean |
| 120 | globalBindingMap.put("CommonResultClassName", CommonResult.class.getName()); | 117 | globalBindingMap.put("CommonResultClassName", CommonResult.class.getName()); |
| 121 | globalBindingMap.put("PageResultClassName", PageResult.class.getName()); | 118 | globalBindingMap.put("PageResultClassName", PageResult.class.getName()); |
| @@ -123,6 +120,7 @@ public class CodegenEngine { | @@ -123,6 +120,7 @@ public class CodegenEngine { | ||
| 123 | globalBindingMap.put("PageParamClassName", PageParam.class.getName()); | 120 | globalBindingMap.put("PageParamClassName", PageParam.class.getName()); |
| 124 | globalBindingMap.put("DictFormatClassName", DictFormat.class.getName()); | 121 | globalBindingMap.put("DictFormatClassName", DictFormat.class.getName()); |
| 125 | // DO 类,独有字段 | 122 | // DO 类,独有字段 |
| 123 | + globalBindingMap.put("BaseDOClassName", BaseDO.class.getName()); | ||
| 126 | globalBindingMap.put("baseDOFields", CodegenBuilder.BASE_DO_FIELDS); | 124 | globalBindingMap.put("baseDOFields", CodegenBuilder.BASE_DO_FIELDS); |
| 127 | globalBindingMap.put("QueryWrapperClassName", LambdaQueryWrapperX.class.getName()); | 125 | globalBindingMap.put("QueryWrapperClassName", LambdaQueryWrapperX.class.getName()); |
| 128 | globalBindingMap.put("BaseMapperClassName", BaseMapperX.class.getName()); | 126 | globalBindingMap.put("BaseMapperClassName", BaseMapperX.class.getName()); |
| @@ -156,15 +154,6 @@ public class CodegenEngine { | @@ -156,15 +154,6 @@ public class CodegenEngine { | ||
| 156 | // permission 前缀 | 154 | // permission 前缀 |
| 157 | bindingMap.put("permissionPrefix", table.getModuleName() + ":" + simpleClassNameStrikeCase); | 155 | bindingMap.put("permissionPrefix", table.getModuleName() + ":" + simpleClassNameStrikeCase); |
| 158 | 156 | ||
| 159 | - // 如果多租户,则进行覆盖 DB 独有字段 | ||
| 160 | - if (CollectionUtils.findFirst(columns, column -> column.getColumnName().equals(CodegenBuilder.TENANT_ID_FIELD)) != null) { | ||
| 161 | - bindingMap.put("BaseDOClassName", TenantBaseDO.class.getName()); | ||
| 162 | - bindingMap.put("BaseDOClassName_simple", TenantBaseDO.class.getSimpleName()); | ||
| 163 | - } else { | ||
| 164 | - bindingMap.put("BaseDOClassName", BaseDO.class.getName()); | ||
| 165 | - bindingMap.put("BaseDOClassName_simple", BaseDO.class.getSimpleName()); | ||
| 166 | - } | ||
| 167 | - | ||
| 168 | // 执行生成 | 157 | // 执行生成 |
| 169 | final Map<String, String> result = Maps.newLinkedHashMapWithExpectedSize(TEMPLATES.size()); // 有序 | 158 | final Map<String, String> result = Maps.newLinkedHashMapWithExpectedSize(TEMPLATES.size()); // 有序 |
| 170 | TEMPLATES.forEach((vmPath, filePath) -> { | 159 | TEMPLATES.forEach((vmPath, filePath) -> { |
yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/dal/do.vm
| @@ -17,7 +17,7 @@ import ${BaseDOClassName}; | @@ -17,7 +17,7 @@ import ${BaseDOClassName}; | ||
| 17 | @Builder | 17 | @Builder |
| 18 | @NoArgsConstructor | 18 | @NoArgsConstructor |
| 19 | @AllArgsConstructor | 19 | @AllArgsConstructor |
| 20 | -public class ${table.className}DO extends ${BaseDOClassName_simple} { | 20 | +public class ${table.className}DO extends BaseDO { |
| 21 | 21 | ||
| 22 | #foreach ($column in $columns) | 22 | #foreach ($column in $columns) |
| 23 | #if (!${baseDOFields.contains(${column.javaField})})##排除 BaseDO 的字段 | 23 | #if (!${baseDOFields.contains(${column.javaField})})##排除 BaseDO 的字段 |
yudao-server/src/main/resources/application.yaml
| @@ -78,7 +78,9 @@ yudao: | @@ -78,7 +78,9 @@ yudao: | ||
| 78 | - cn.iocoder.yudao.module.system.enums.ErrorCodeConstants | 78 | - cn.iocoder.yudao.module.system.enums.ErrorCodeConstants |
| 79 | - cn.iocoder.yudao.module.tool.enums.ErrorCodeConstants | 79 | - cn.iocoder.yudao.module.tool.enums.ErrorCodeConstants |
| 80 | tenant: # 多租户相关配置项 | 80 | tenant: # 多租户相关配置项 |
| 81 | - tables: # 配置需要开启多租户的表;如果实体已经继承 TenantBaseDO 类,则无需重复配置 | 81 | + enable: true |
| 82 | + ignore-urls: /admin-api/system/captcha/get-image, /admin-api/infra/file/get/* | ||
| 83 | + ignore-tables: infra_config, infra_file, infra_job, infra_job_log, infra_job_log, system_tenant, system_dict_data, system_dict_type, system_error_code, system_menu, system_role, system_role_menu, system_sms_channel, tool_codegen_column, tool_codegen_table, tool_test_demo | ||
| 82 | sms-code: # 短信验证码相关的配置项 | 84 | sms-code: # 短信验证码相关的配置项 |
| 83 | expire-times: 10m | 85 | expire-times: 10m |
| 84 | send-frequency: 1m | 86 | send-frequency: 1m |
yudao-ui-admin/.env.development
yudao-ui-admin/src/utils/request.js
| @@ -4,6 +4,7 @@ import store from '@/store' | @@ -4,6 +4,7 @@ import store from '@/store' | ||
| 4 | import { getToken } from '@/utils/auth' | 4 | import { getToken } from '@/utils/auth' |
| 5 | import errorCode from '@/utils/errorCode' | 5 | import errorCode from '@/utils/errorCode' |
| 6 | import Cookies from "js-cookie"; | 6 | import Cookies from "js-cookie"; |
| 7 | +import {getTenantEnable} from "@/utils/ruoyi"; | ||
| 7 | 8 | ||
| 8 | // 是否显示重新登录 | 9 | // 是否显示重新登录 |
| 9 | let isReloginShow; | 10 | let isReloginShow; |
| @@ -24,9 +25,11 @@ service.interceptors.request.use(config => { | @@ -24,9 +25,11 @@ service.interceptors.request.use(config => { | ||
| 24 | config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 | 25 | config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 |
| 25 | } | 26 | } |
| 26 | // 设置租户 | 27 | // 设置租户 |
| 27 | - const tenantId = Cookies.get('tenantId'); | ||
| 28 | - if (tenantId) { | ||
| 29 | - config.headers['tenant-id'] = tenantId; | 28 | + if (getTenantEnable()) { |
| 29 | + const tenantId = Cookies.get('tenantId'); | ||
| 30 | + if (tenantId) { | ||
| 31 | + config.headers['tenant-id'] = tenantId; | ||
| 32 | + } | ||
| 30 | } | 33 | } |
| 31 | // get请求映射params参数 | 34 | // get请求映射params参数 |
| 32 | if (config.method === 'get' && config.params) { | 35 | if (config.method === 'get' && config.params) { |
yudao-ui-admin/src/utils/ruoyi.js
| @@ -170,3 +170,17 @@ export function getNowDateTime(timeStr) { | @@ -170,3 +170,17 @@ export function getNowDateTime(timeStr) { | ||
| 170 | let seconds = now.getSeconds().toString().padStart(2, "0") // 得到秒; | 170 | let seconds = now.getSeconds().toString().padStart(2, "0") // 得到秒; |
| 171 | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; | 171 | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; |
| 172 | } | 172 | } |
| 173 | + | ||
| 174 | +/** | ||
| 175 | + * 获得租户功能是否开启 | ||
| 176 | + */ | ||
| 177 | +export function getTenantEnable() { | ||
| 178 | + console.log("enable: " + process.env.VUE_APP_TENANT_ENABLE) | ||
| 179 | + if (process.env.VUE_APP_TENANT_ENABLE === "true") { | ||
| 180 | + return true; | ||
| 181 | + } | ||
| 182 | + if (process.env.VUE_APP_TENANT_ENABLE === "false") { | ||
| 183 | + return false; | ||
| 184 | + } | ||
| 185 | + return process.env.VUE_APP_TENANT_ENABLE || true; | ||
| 186 | +} |
yudao-ui-admin/src/views/login.vue
| @@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
| 2 | <div class="login"> | 2 | <div class="login"> |
| 3 | <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"> | 3 | <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"> |
| 4 | <h3 class="title">芋道后台管理系统</h3> | 4 | <h3 class="title">芋道后台管理系统</h3> |
| 5 | - <el-form-item prop="tenantName"> | 5 | + <el-form-item prop="tenantName" v-if="tenantEnable"> |
| 6 | <el-input v-model="loginForm.tenantName" type="text" auto-complete="off" placeholder='租户'> | 6 | <el-input v-model="loginForm.tenantName" type="text" auto-complete="off" placeholder='租户'> |
| 7 | <svg-icon slot="prefix" icon-class="tree" class="el-input__icon input-icon" /> | 7 | <svg-icon slot="prefix" icon-class="tree" class="el-input__icon input-icon" /> |
| 8 | </el-input> | 8 | </el-input> |
| @@ -54,7 +54,8 @@ import { getCodeImg,socialAuthRedirect } from "@/api/login"; | @@ -54,7 +54,8 @@ import { getCodeImg,socialAuthRedirect } from "@/api/login"; | ||
| 54 | import { getTenantIdByName } from "@/api/system/tenant"; | 54 | import { getTenantIdByName } from "@/api/system/tenant"; |
| 55 | import Cookies from "js-cookie"; | 55 | import Cookies from "js-cookie"; |
| 56 | import { encrypt, decrypt } from '@/utils/jsencrypt' | 56 | import { encrypt, decrypt } from '@/utils/jsencrypt' |
| 57 | -import {InfraApiErrorLogProcessStatusEnum, SystemUserSocialTypeEnum} from "@/utils/constants"; | 57 | +import {SystemUserSocialTypeEnum} from "@/utils/constants"; |
| 58 | +import { getTenantEnable } from "@/utils/ruoyi"; | ||
| 58 | 59 | ||
| 59 | export default { | 60 | export default { |
| 60 | name: "Login", | 61 | name: "Login", |
| @@ -62,6 +63,7 @@ export default { | @@ -62,6 +63,7 @@ export default { | ||
| 62 | return { | 63 | return { |
| 63 | codeUrl: "", | 64 | codeUrl: "", |
| 64 | captchaEnable: true, | 65 | captchaEnable: true, |
| 66 | + tenantEnable: true, | ||
| 65 | loginForm: { | 67 | loginForm: { |
| 66 | username: "admin", | 68 | username: "admin", |
| 67 | password: "admin123", | 69 | password: "admin123", |
| @@ -71,6 +73,13 @@ export default { | @@ -71,6 +73,13 @@ export default { | ||
| 71 | tenantName: "芋道源码", | 73 | tenantName: "芋道源码", |
| 72 | }, | 74 | }, |
| 73 | loginRules: { | 75 | loginRules: { |
| 76 | + username: [ | ||
| 77 | + { required: true, trigger: "blur", message: "用户名不能为空" } | ||
| 78 | + ], | ||
| 79 | + password: [ | ||
| 80 | + { required: true, trigger: "blur", message: "密码不能为空" } | ||
| 81 | + ], | ||
| 82 | + code: [{ required: true, trigger: "change", message: "验证码不能为空" }], | ||
| 74 | tenantName: [ | 83 | tenantName: [ |
| 75 | { required: true, trigger: "blur", message: "租户不能为空" }, | 84 | { required: true, trigger: "blur", message: "租户不能为空" }, |
| 76 | { | 85 | { |
| @@ -90,13 +99,6 @@ export default { | @@ -90,13 +99,6 @@ export default { | ||
| 90 | trigger: 'blur' | 99 | trigger: 'blur' |
| 91 | } | 100 | } |
| 92 | ], | 101 | ], |
| 93 | - username: [ | ||
| 94 | - { required: true, trigger: "blur", message: "用户名不能为空" } | ||
| 95 | - ], | ||
| 96 | - password: [ | ||
| 97 | - { required: true, trigger: "blur", message: "密码不能为空" } | ||
| 98 | - ], | ||
| 99 | - code: [{ required: true, trigger: "change", message: "验证码不能为空" }] | ||
| 100 | }, | 102 | }, |
| 101 | loading: false, | 103 | loading: false, |
| 102 | redirect: undefined, | 104 | redirect: undefined, |
| @@ -113,6 +115,8 @@ export default { | @@ -113,6 +115,8 @@ export default { | ||
| 113 | // } | 115 | // } |
| 114 | // }, | 116 | // }, |
| 115 | created() { | 117 | created() { |
| 118 | + // 租户开关 | ||
| 119 | + this.tenantEnable = getTenantEnable(); | ||
| 116 | // 重定向地址 | 120 | // 重定向地址 |
| 117 | this.redirect = this.$route.query.redirect; | 121 | this.redirect = this.$route.query.redirect; |
| 118 | this.getCode(); | 122 | this.getCode(); |