From 79311ecc71f0c6beabe0e5f84e1423ce745a5f09 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 20 Feb 2022 00:33:12 +0800 Subject: [PATCH] =?UTF-8?q?*=20=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91?= =?UTF-8?q?=E5=90=8E=E7=AB=AF=20`yudao.tenant.enable`=20=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E9=A1=B9=EF=BC=8C=E5=89=8D=E7=AB=AF=20`VUE=5FAPP=5FTENANT=5FEN?= =?UTF-8?q?ABLE`=20=E9=85=8D=E7=BD=AE=E9=A1=B9=EF=BC=8C=E7=94=A8=E4=BA=8E?= =?UTF-8?q?=E5=BC=80=E5=85=B3=E7=A7=9F=E6=88=B7=E5=8A=9F=E8=83=BD=20*=20?= =?UTF-8?q?=E3=80=90=E4=BC=98=E5=8C=96=E3=80=91=E8=B0=83=E6=95=B4=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E6=89=80=E6=9C=89=E8=A1=A8=E5=BC=80=E5=90=AF=E5=A4=9A?= =?UTF-8?q?=E7=A7=9F=E6=88=B7=E7=9A=84=E7=89=B9=E6=80=A7=EF=BC=8C=E5=8F=AF?= =?UTF-8?q?=E9=80=9A=E8=BF=87=20`yudao.tenant.ignore-tables`=20=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E9=A1=B9=E8=BF=9B=E8=A1=8C=E5=BF=BD=E7=95=A5=EF=BC=8C?= =?UTF-8?q?=E6=9B=BF=E4=BB=A3=E5=8E=9F=E6=9C=AC=E9=BB=98=E8=AE=A4=E4=B8=8D?= =?UTF-8?q?=E5=BC=80=E5=90=AF=E7=9A=84=E7=AD=96=E7=95=A5=20*=20=E3=80=90?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E3=80=91=E9=80=9A=E8=BF=87=20`yudao.tenant.i?= =?UTF-8?q?gnore-urls`=20=E9=85=8D=E7=BD=AE=E5=BF=BD=E7=95=A5=E5=A4=9A?= =?UTF-8?q?=E7=A7=9F=E6=88=B7=E7=9A=84=E8=AF=B7=E6=B1=82=EF=BC=8C=E4=BE=8B?= =?UTF-8?q?=E5=A6=82=E8=AF=B4=20=EF=BC=8C=E4=BE=8B=E5=A6=82=E8=AF=B4?= =?UTF-8?q?=E7=9F=AD=E4=BF=A1=E5=9B=9E=E8=B0=83=E3=80=81=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=9B=9E=E8=B0=83=E7=AD=89=20Open=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/enums/WebFilterOrderEnum.java | 2 +- .../tenant/config/TenantProperties.java | 34 +++++---- .../YudaoTenantDatabaseAutoConfiguration.java | 3 + .../YudaoTenantJobAutoConfiguration.java | 3 + .../YudaoTenantMQAutoConfiguration.java | 3 + .../YudaoTenantSecurityAutoConfiguration.java | 11 ++- .../YudaoTenantWebAutoConfiguration.java | 3 + .../core/context/TenantContextHolder.java | 2 +- .../core/db/TenantDatabaseInterceptor.java | 10 +-- .../security/TenantSecurityWebFilter.java | 70 +++++++++++++++---- .../config/YudaoSwaggerAutoConfiguration.java | 11 +-- .../web/core/filter/ApiRequestFilter.java | 27 +++++++ .../yudao-module-infra-impl/pom.xml | 10 +-- .../controller/admin/file/FileController.java | 2 - .../infra/dal/dataobject/file/FileDO.java | 4 +- .../dal/dataobject/logger/ApiAccessLogDO.java | 4 +- .../dal/dataobject/logger/ApiErrorLogDO.java | 4 +- .../api/logger/dto/LoginLogCreateReqDTO.java | 3 +- .../yudao-module-system-impl/pom.xml | 10 ++- .../dal/dataobject/auth/UserSessionDO.java | 4 +- .../system/dal/dataobject/dept/DeptDO.java | 6 +- .../system/dal/dataobject/dept/PostDO.java | 4 +- .../dal/dataobject/logger/OperateLogDO.java | 4 +- .../dal/dataobject/notice/NoticeDO.java | 6 +- .../dal/dataobject/user/AdminUserDO.java | 2 +- .../job/auth/UserSessionTimeoutJob.java | 4 +- .../permission/PermissionServiceImpl.java | 2 +- .../yudao-module-tool-impl/pom.xml | 4 -- .../service/codegen/inner/CodegenBuilder.java | 7 +- .../service/codegen/inner/CodegenEngine.java | 31 +++----- .../src/main/resources/codegen/java/dal/do.vm | 2 +- .../src/main/resources/application.yaml | 4 +- yudao-ui-admin/.env.development | 3 + yudao-ui-admin/src/utils/request.js | 9 ++- yudao-ui-admin/src/utils/ruoyi.js | 14 ++++ yudao-ui-admin/src/views/login.vue | 22 +++--- 36 files changed, 221 insertions(+), 123 deletions(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/ApiRequestFilter.java diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java index 6cfbba177..d00cb780e 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java +++ b/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; /** * Web 过滤器顺序的枚举类,保证过滤器按照符合我们的预期 * - * 考虑到每个 starter 都需要用到该工具类,所以放到 common 模块下的 util 包下 + * 考虑到每个 starter 都需要用到该工具类,所以放到 common 模块下的 util 包下 * * @author 芋道源码 */ diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/TenantProperties.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/TenantProperties.java index c092682ec..a23ccd341 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/TenantProperties.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/TenantProperties.java @@ -14,22 +14,28 @@ import java.util.Set; @Data public class TenantProperties { -// /** -// * 租户是否开启 -// */ -// private static final Boolean ENABLE_DEFAULT = true; -// -// /** -// * 是否开启 -// */ -// private Boolean enable = ENABLE_DEFAULT; + /** + * 租户是否开启 + */ + private static final Boolean ENABLE_DEFAULT = true; /** - * 需要多租户的表 - * - * 由于多租户并不作为 yudao 项目的重点功能,更多是扩展性的功能,所以采用正向配置需要多租户的表。 - * 如果需要,你可以改成 ignoreTables 来取消部分不需要的表 + * 是否开启 */ - private Set tables; + private Boolean enable = ENABLE_DEFAULT; + + /** + * 需要忽略多租户的请求 + * + * 默认情况下,每个请求需要带上 tenant-id 的请求头。但是,部分请求是无需带上的,例如说短信回调、支付回调等 Open API! + */ + private Set ignoreUrls; + + /** + * 需要忽略多租户的表 + * + * 即默认所有表都开启多租户的功能,所以记得添加对应的 tenant_id 字段哟 + */ + private Set ignoreTables; } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantDatabaseAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantDatabaseAutoConfiguration.java index 1c7d8a7b3..97b174ef7 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantDatabaseAutoConfiguration.java +++ b/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; 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; @@ -14,6 +15,8 @@ import org.springframework.context.annotation.Configuration; * @author 芋道源码 */ @Configuration +// 允许使用 yudao.tenant.enable=false 禁用多租户 +@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) @EnableConfigurationProperties(TenantProperties.class) public class YudaoTenantDatabaseAutoConfiguration { diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantJobAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantJobAutoConfiguration.java index 89b58f86e..2baced9d5 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantJobAutoConfiguration.java +++ b/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; 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; @@ -16,6 +17,8 @@ import org.springframework.context.annotation.Configuration; * @author 芋道源码 */ @Configuration +// 允许使用 yudao.tenant.enable=false 禁用多租户 +@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) public class YudaoTenantJobAutoConfiguration { @Bean diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantMQAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantMQAutoConfiguration.java index 6a465b91e..30274fdcf 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantMQAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantMQAutoConfiguration.java @@ -1,6 +1,7 @@ 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; @@ -10,6 +11,8 @@ import org.springframework.context.annotation.Configuration; * @author 芋道源码 */ @Configuration +// 允许使用 yudao.tenant.enable=false 禁用多租户 +@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) public class YudaoTenantMQAutoConfiguration { @Bean diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantSecurityAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantSecurityAutoConfiguration.java index b5dbd0000..dc4bae5d0 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantSecurityAutoConfiguration.java +++ b/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; import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter; +import cn.iocoder.yudao.framework.web.config.WebProperties; +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; @@ -12,12 +15,16 @@ import org.springframework.context.annotation.Configuration; * @author 芋道源码 */ @Configuration +// 允许使用 yudao.tenant.enable=false 禁用多租户 +@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) +@EnableConfigurationProperties(TenantProperties.class) public class YudaoTenantSecurityAutoConfiguration { @Bean - public FilterRegistrationBean tenantSecurityWebFilter() { + public FilterRegistrationBean tenantSecurityWebFilter(TenantProperties tenantProperties, + WebProperties webProperties) { FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); - registrationBean.setFilter(new TenantSecurityWebFilter()); + registrationBean.setFilter(new TenantSecurityWebFilter(tenantProperties, webProperties)); registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER); return registrationBean; } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantWebAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantWebAutoConfiguration.java index c2830a79a..6e5154db4 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantWebAutoConfiguration.java +++ b/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; 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; @@ -12,6 +13,8 @@ import org.springframework.context.annotation.Configuration; * @author 芋道源码 */ @Configuration +// 允许使用 yudao.tenant.enable=false 禁用多租户 +@ConditionalOnProperty(prefix = "yudao.tenant", value = "enable", matchIfMissing = true) public class YudaoTenantWebAutoConfiguration { @Bean diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java index 74de19205..d986b44fb 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java @@ -33,7 +33,7 @@ public class TenantContextHolder { public static Long getRequiredTenantId() { Long tenantId = getTenantId(); if (tenantId == null) { - throw new NullPointerException("TenantContextHolder 不存在租户编号"); + throw new NullPointerException("TenantContextHolder 不存在租户编号"); // TODO 芋艿:增加文档链接 } return tenantId; } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java index 283bd4497..de2e1a7ef 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java @@ -3,8 +3,6 @@ package cn.iocoder.yudao.framework.tenant.core.db; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.tenant.config.TenantProperties; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import com.baomidou.mybatisplus.core.metadata.TableInfo; -import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; import lombok.AllArgsConstructor; import net.sf.jsqlparser.expression.Expression; @@ -27,13 +25,7 @@ public class TenantDatabaseInterceptor implements TenantLineHandler { @Override public boolean ignoreTable(String tableName) { - // 如果实体类继承 TenantBaseDO 类,则是多租户表,不进行忽略 - TableInfo tableInfo = TableInfoHelper.getTableInfo(tableName); - if (tableInfo != null && TenantBaseDO.class.isAssignableFrom(tableInfo.getEntityType())) { - return false; - } - // 不包含,说明要过滤 - return !CollUtil.contains(properties.getTables(), tableName); + return CollUtil.contains(properties.getIgnoreTables(), tableName); } } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java index 00d51beaf..87285c412 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/security/TenantSecurityWebFilter.java @@ -1,13 +1,17 @@ package cn.iocoder.yudao.framework.tenant.core.security; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.framework.tenant.config.TenantProperties; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +import cn.iocoder.yudao.framework.web.config.WebProperties; +import cn.iocoder.yudao.framework.web.core.filter.ApiRequestFilter; import lombok.extern.slf4j.Slf4j; -import org.springframework.web.filter.OncePerRequestFilter; +import org.springframework.util.AntPathMatcher; import javax.servlet.FilterChain; import javax.servlet.ServletException; @@ -18,34 +22,72 @@ import java.util.Objects; /** * 多租户 Security Web 过滤器 - * 校验用户访问的租户,是否是其所在的租户,避免越权问题 + * 1. 如果是登陆的用户,校验是否有权限访问该租户,避免越权问题。 + * 2. 如果请求未带租户的编号,检查是否是忽略的 URL,否则也不允许访问。 + * + * 校验用户访问的租户,是否是其所在的租户, * * @author 芋道源码 */ @Slf4j -public class TenantSecurityWebFilter extends OncePerRequestFilter { +public class TenantSecurityWebFilter extends ApiRequestFilter { + + private final TenantProperties tenantProperties; + private final AntPathMatcher pathMatcher; + + public TenantSecurityWebFilter(TenantProperties tenantProperties, + WebProperties webProperties) { + super(webProperties); + this.tenantProperties = tenantProperties; + this.pathMatcher = new AntPathMatcher(); + } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { + Long tenantId = TenantContextHolder.getTenantId(); + // 1. 登陆的用户,校验是否有权限访问该租户,避免越权问题。 LoginUser user = SecurityFrameworkUtils.getLoginUser(); - assert user != null; // shouldNotFilter 已经校验 - // 校验租户是否匹配。 - if (!Objects.equals(user.getTenantId(), TenantContextHolder.getTenantId())) { - log.error("[doFilterInternal][租户({}) User({}/{}) 越权访问租户({}) URL({}/{})]", - user.getTenantId(), user.getId(), user.getUserType(), - TenantContextHolder.getTenantId(), request.getRequestURI(), request.getMethod()); - ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.FORBIDDEN.getCode(), - "您无权访问该租户的数据")); + if (user != null) { + // 如果获取不到租户编号,则尝试使用登陆用户的租户编号 + if (tenantId == null) { + tenantId = user.getTenantId(); + TenantContextHolder.setTenantId(tenantId); + // 如果传递了租户编号,则进行比对租户编号,避免越权问题 + } else if (!Objects.equals(user.getTenantId(), TenantContextHolder.getTenantId())) { + log.error("[doFilterInternal][租户({}) User({}/{}) 越权访问租户({}) URL({}/{})]", + user.getTenantId(), user.getId(), user.getUserType(), + TenantContextHolder.getTenantId(), request.getRequestURI(), request.getMethod()); + ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.FORBIDDEN.getCode(), + "您无权访问该租户的数据")); + return; + } + } + + // 2. 如果请求未带租户的编号,检查是否是忽略的 URL,否则也不允许访问。 + if (tenantId == null && !isIgnoreUrl(request)) { + log.error("[doFilterInternal][URL({}/{}) 未传递租户编号]", request.getRequestURI(), request.getMethod()); + ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), + "租户的请求未传递,请进行排查")); return; } + // 继续过滤 chain.doFilter(request, response); } - @Override - protected boolean shouldNotFilter(HttpServletRequest request) { - return SecurityFrameworkUtils.getLoginUser() == null; + private boolean isIgnoreUrl(HttpServletRequest request) { + // 快速匹配,保证性能 + if (CollUtil.contains(tenantProperties.getIgnoreUrls(), request.getRequestURI())) { + return true; + } + // 逐个 Ant 路径匹配 + for (String url : tenantProperties.getIgnoreUrls()) { + if (pathMatcher.match(url, request.getRequestURI())) { + return true; + } + } + return false; } } diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java index 3a8e79fd6..8766d0458 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java +++ b/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 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; -import springfox.documentation.RequestHandler; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.ApiKey; -import springfox.documentation.service.AuthorizationScope; -import springfox.documentation.service.Contact; -import springfox.documentation.service.SecurityReference; -import springfox.documentation.service.SecurityScheme; +import springfox.documentation.service.*; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.Docket; @@ -24,7 +18,6 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; import java.util.Collections; import java.util.List; -import java.util.function.Predicate; import static springfox.documentation.builders.RequestHandlerSelectors.basePackage; @@ -37,8 +30,8 @@ import static springfox.documentation.builders.RequestHandlerSelectors.basePacka @EnableSwagger2 @EnableKnife4j @ConditionalOnClass({Docket.class, ApiInfoBuilder.class}) -@ConditionalOnProperty(prefix = "yudao.swagger", value = "enable", matchIfMissing = true) // 允许使用 swagger.enable=false 禁用 Swagger +@ConditionalOnProperty(prefix = "yudao.swagger", value = "enable", matchIfMissing = true) @EnableConfigurationProperties(SwaggerProperties.class) public class YudaoSwaggerAutoConfiguration { diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/ApiRequestFilter.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/ApiRequestFilter.java new file mode 100644 index 000000000..8e78a3b72 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/ApiRequestFilter.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.framework.web.core.filter; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.web.config.WebProperties; +import lombok.RequiredArgsConstructor; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.http.HttpServletRequest; + +/** + * 过滤 /admin-api、/app-api 等 API 请求的过滤器 + * + * @author 芋道源码 + */ +@RequiredArgsConstructor +public abstract class ApiRequestFilter extends OncePerRequestFilter { + + protected final WebProperties webProperties; + + @Override + protected boolean shouldNotFilter(HttpServletRequest request) { + // 只过滤 API 请求的地址 + return !StrUtil.startWithAny(request.getRequestURI(), webProperties.getAdminApi().getPrefix(), + webProperties.getAppApi().getPrefix()); + } + +} diff --git a/yudao-module-infra/yudao-module-infra-impl/pom.xml b/yudao-module-infra/yudao-module-infra-impl/pom.xml index 3bcb7458a..97bb1a8c8 100644 --- a/yudao-module-infra/yudao-module-infra-impl/pom.xml +++ b/yudao-module-infra/yudao-module-infra-impl/pom.xml @@ -39,10 +39,6 @@ cn.iocoder.boot yudao-spring-boot-starter-biz-operatelog - - cn.iocoder.boot - yudao-spring-boot-starter-biz-tenant - @@ -67,6 +63,12 @@ yudao-spring-boot-starter-config + + + cn.iocoder.boot + yudao-spring-boot-starter-job + + cn.iocoder.boot diff --git a/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java b/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java index 32789f1af..48c7e146c 100644 --- a/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java +++ b/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; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.module.infra.controller.admin.file.vo.FilePageReqVO; import cn.iocoder.yudao.module.infra.controller.admin.file.vo.FileRespVO; import cn.iocoder.yudao.module.infra.convert.file.FileConvert; @@ -62,7 +61,6 @@ public class FileController { @ApiOperation("下载文件") @ApiImplicitParam(name = "path", value = "文件附件", required = true, dataTypeClass = MultipartFile.class) public void getFile(HttpServletResponse response, @PathVariable("path") String path) throws IOException { - TenantContextHolder.setNullTenantId(); FileDO file = fileService.getFile(path); if (file == null) { log.warn("[getFile][path({}) 文件不存在]", path); diff --git a/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/file/FileDO.java b/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/file/FileDO.java index 47eb2403e..7ed2c5522 100644 --- a/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/file/FileDO.java +++ b/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/file/FileDO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.file; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; @@ -21,7 +21,7 @@ import java.io.InputStream; @Builder @NoArgsConstructor @AllArgsConstructor -public class FileDO extends TenantBaseDO { +public class FileDO extends BaseDO { /** * 文件路径 diff --git a/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/logger/ApiAccessLogDO.java b/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/logger/ApiAccessLogDO.java index 2ad8a326d..20b9b1d09 100644 --- a/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/logger/ApiAccessLogDO.java +++ b/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; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; @@ -21,7 +21,7 @@ import java.util.Date; @Builder @NoArgsConstructor @AllArgsConstructor -public class ApiAccessLogDO extends TenantBaseDO { +public class ApiAccessLogDO extends BaseDO { /** * 编号 diff --git a/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/logger/ApiErrorLogDO.java b/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/logger/ApiErrorLogDO.java index 1ed7df412..03bb38b0f 100644 --- a/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/logger/ApiErrorLogDO.java +++ b/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/logger/ApiErrorLogDO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.logger; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.infra.enums.logger.ApiErrorLogProcessStatusEnum; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -21,7 +21,7 @@ import java.util.Date; @Builder @NoArgsConstructor @AllArgsConstructor -public class ApiErrorLogDO extends TenantBaseDO { +public class ApiErrorLogDO extends BaseDO { /** * 编号 diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/LoginLogCreateReqDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/LoginLogCreateReqDTO.java index d3ae4fb4f..b4aeb3046 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/LoginLogCreateReqDTO.java +++ b/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 { private String userIp; /** * 浏览器 UserAgent + * + * 允许空,原因:Job 过期登出时,是无法传递 UserAgent 的 */ - @NotEmpty(message = "浏览器 UserAgent 不能为空") private String userAgent; } diff --git a/yudao-module-system/yudao-module-system-impl/pom.xml b/yudao-module-system/yudao-module-system-impl/pom.xml index 6484acd5b..b297830b5 100644 --- a/yudao-module-system/yudao-module-system-impl/pom.xml +++ b/yudao-module-system/yudao-module-system-impl/pom.xml @@ -53,11 +53,11 @@ cn.iocoder.boot - yudao-spring-boot-starter-biz-tenant + yudao-spring-boot-starter-biz-social cn.iocoder.boot - yudao-spring-boot-starter-biz-social + yudao-spring-boot-starter-biz-tenant @@ -77,6 +77,12 @@ yudao-spring-boot-starter-redis + + + cn.iocoder.boot + yudao-spring-boot-starter-job + + cn.iocoder.boot diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/auth/UserSessionDO.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/auth/UserSessionDO.java index 01885004e..afa426aec 100644 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/auth/UserSessionDO.java +++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/auth/UserSessionDO.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.system.dal.dataobject.auth; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.security.core.LoginUser; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -25,7 +25,7 @@ import java.util.Date; @Data @Builder @EqualsAndHashCode(callSuper = true) -public class UserSessionDO extends TenantBaseDO { +public class UserSessionDO extends BaseDO { /** * 会话编号, 即 sessionId diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java index 557a1f36f..15810cfd4 100644 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java +++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.system.dal.dataobject.dept; -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -17,7 +17,7 @@ import lombok.EqualsAndHashCode; @TableName("system_dept") @Data @EqualsAndHashCode(callSuper = true) -public class DeptDO extends TenantBaseDO { +public class DeptDO extends BaseDO { /** * 部门ID diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/PostDO.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/PostDO.java index ba9074d03..3b41e0ed1 100644 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/PostDO.java +++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/PostDO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.system.dal.dataobject.dept; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -15,7 +15,7 @@ import lombok.EqualsAndHashCode; @TableName("system_post") @Data @EqualsAndHashCode(callSuper = true) -public class PostDO extends TenantBaseDO { +public class PostDO extends BaseDO { /** * 岗位序号 diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogDO.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogDO.java index c76ec5f7b..1f7f2cc96 100644 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogDO.java +++ b/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; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -22,7 +22,7 @@ import java.util.Map; @TableName(value = "system_operate_log", autoResultMap = true) @Data @EqualsAndHashCode(callSuper = true) -public class OperateLogDO extends TenantBaseDO { +public class OperateLogDO extends BaseDO { /** * {@link #javaMethodArgs} 的最大长度 diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/notice/NoticeDO.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/notice/NoticeDO.java index 20860b835..21eb24cb4 100644 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/notice/NoticeDO.java +++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/notice/NoticeDO.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.system.dal.dataobject.notice; -import cn.iocoder.yudao.module.system.enums.notice.NoticeTypeEnum; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.system.enums.notice.NoticeTypeEnum; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -16,7 +16,7 @@ import lombok.EqualsAndHashCode; @TableName("system_notice") @Data @EqualsAndHashCode(callSuper = true) -public class NoticeDO extends TenantBaseDO { +public class NoticeDO extends BaseDO { /** * 公告ID diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java index 870ad30fc..cafe7deda 100644 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java +++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java @@ -1,9 +1,9 @@ package cn.iocoder.yudao.module.system.dal.dataobject.user; -import cn.iocoder.yudao.module.system.enums.common.SexEnum; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.module.system.enums.common.SexEnum; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/job/auth/UserSessionTimeoutJob.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/job/auth/UserSessionTimeoutJob.java index d1a061d3e..04b58b89f 100644 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/job/auth/UserSessionTimeoutJob.java +++ b/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; public class UserSessionTimeoutJob implements JobHandler { @Resource - private UserSessionService sysUserSessionService; + private UserSessionService userSessionService; @Override public String execute(String param) throws Exception { // 执行过期 - Long timeoutCount = sysUserSessionService.clearSessionTimeout(); + Long timeoutCount = userSessionService.clearSessionTimeout(); // 返回结果,记录每次的超时数量 return String.format("移除在线会话数量为 %s 个", timeoutCount); } diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java index 12e3fbcde..ba873cb66 100644 --- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java +++ b/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 { public List getRoleMenusFromCache(Collection roleIds, Collection menuTypes, Collection menusStatuses) { // 任一一个参数为空时,不返回任何菜单 - if (CollectionUtils.isAnyEmpty(roleIds, menusStatuses, menusStatuses)) { + if (CollectionUtils.isAnyEmpty(roleIds, menuTypes, menusStatuses)) { return Collections.emptyList(); } // 判断角色是否包含管理员 diff --git a/yudao-module-tool/yudao-module-tool-impl/pom.xml b/yudao-module-tool/yudao-module-tool-impl/pom.xml index 2c969dd0a..0f28e2f70 100644 --- a/yudao-module-tool/yudao-module-tool-impl/pom.xml +++ b/yudao-module-tool/yudao-module-tool-impl/pom.xml @@ -38,10 +38,6 @@ cn.iocoder.boot yudao-spring-boot-starter-biz-dict - - cn.iocoder.boot - yudao-spring-boot-starter-biz-tenant - diff --git a/yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/codegen/inner/CodegenBuilder.java b/yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/codegen/inner/CodegenBuilder.java index 4914b3d22..cbced2559 100644 --- a/yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/codegen/inner/CodegenBuilder.java +++ b/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; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.tool.convert.codegen.CodegenConvert; import cn.iocoder.yudao.module.tool.dal.dataobject.codegen.CodegenColumnDO; import cn.iocoder.yudao.module.tool.dal.dataobject.codegen.CodegenTableDO; @@ -60,7 +60,7 @@ public class CodegenBuilder { */ public static final String TENANT_ID_FIELD = "tenant_id"; /** - * {@link TenantBaseDO} 的字段 + * {@link cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO} 的字段 */ public static final Set BASE_DO_FIELDS = new HashSet<>(); /** @@ -96,7 +96,8 @@ public class CodegenBuilder { .build(); static { - Arrays.stream(ReflectUtil.getFields(TenantBaseDO.class)).forEach(field -> BASE_DO_FIELDS.add(field.getName())); + Arrays.stream(ReflectUtil.getFields(BaseDO.class)).forEach(field -> BASE_DO_FIELDS.add(field.getName())); + BASE_DO_FIELDS.add(TENANT_ID_FIELD); // 处理 OPERATION 相关的字段 CREATE_OPERATION_EXCLUDE_COLUMN.addAll(BASE_DO_FIELDS); UPDATE_OPERATION_EXCLUDE_COLUMN.addAll(BASE_DO_FIELDS); diff --git a/yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/codegen/inner/CodegenEngine.java b/yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/codegen/inner/CodegenEngine.java index d1c330475..80bd1d36f 100644 --- a/yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/codegen/inner/CodegenEngine.java +++ b/yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/codegen/inner/CodegenEngine.java @@ -1,8 +1,6 @@ package cn.iocoder.yudao.module.tool.service.codegen.inner; -import cn.hutool.core.collection.ListUtil; import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.template.TemplateConfig; import cn.hutool.extra.template.TemplateEngine; @@ -11,23 +9,21 @@ import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; -import cn.iocoder.yudao.module.tool.enums.codegen.CodegenSceneEnum; -import cn.iocoder.yudao.module.tool.framework.codegen.config.CodegenProperties; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 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.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum; import cn.iocoder.yudao.module.tool.dal.dataobject.codegen.CodegenColumnDO; import cn.iocoder.yudao.module.tool.dal.dataobject.codegen.CodegenTableDO; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.date.DateUtils; +import cn.iocoder.yudao.module.tool.enums.codegen.CodegenSceneEnum; +import cn.iocoder.yudao.module.tool.framework.codegen.config.CodegenProperties; import com.google.common.collect.Maps; import org.springframework.stereotype.Component; @@ -115,7 +111,8 @@ public class CodegenEngine { private void initGlobalBindingMap() { // 全局配置 globalBindingMap.put("basePackage", codegenProperties.getBasePackage()); - globalBindingMap.put("baseFrameworkPackage", codegenProperties.getBasePackage() + '.' + "framework"); // 用于后续获取测试类的 package 地址 + globalBindingMap.put("baseFrameworkPackage", codegenProperties.getBasePackage() + + '.' + "framework"); // 用于后续获取测试类的 package 地址 // 全局 Java Bean globalBindingMap.put("CommonResultClassName", CommonResult.class.getName()); globalBindingMap.put("PageResultClassName", PageResult.class.getName()); @@ -123,6 +120,7 @@ public class CodegenEngine { globalBindingMap.put("PageParamClassName", PageParam.class.getName()); globalBindingMap.put("DictFormatClassName", DictFormat.class.getName()); // DO 类,独有字段 + globalBindingMap.put("BaseDOClassName", BaseDO.class.getName()); globalBindingMap.put("baseDOFields", CodegenBuilder.BASE_DO_FIELDS); globalBindingMap.put("QueryWrapperClassName", LambdaQueryWrapperX.class.getName()); globalBindingMap.put("BaseMapperClassName", BaseMapperX.class.getName()); @@ -156,15 +154,6 @@ public class CodegenEngine { // permission 前缀 bindingMap.put("permissionPrefix", table.getModuleName() + ":" + simpleClassNameStrikeCase); - // 如果多租户,则进行覆盖 DB 独有字段 - if (CollectionUtils.findFirst(columns, column -> column.getColumnName().equals(CodegenBuilder.TENANT_ID_FIELD)) != null) { - bindingMap.put("BaseDOClassName", TenantBaseDO.class.getName()); - bindingMap.put("BaseDOClassName_simple", TenantBaseDO.class.getSimpleName()); - } else { - bindingMap.put("BaseDOClassName", BaseDO.class.getName()); - bindingMap.put("BaseDOClassName_simple", BaseDO.class.getSimpleName()); - } - // 执行生成 final Map result = Maps.newLinkedHashMapWithExpectedSize(TEMPLATES.size()); // 有序 TEMPLATES.forEach((vmPath, filePath) -> { diff --git a/yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/dal/do.vm b/yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/dal/do.vm index ffad97a28..687a09010 100644 --- a/yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/dal/do.vm +++ b/yudao-module-tool/yudao-module-tool-impl/src/main/resources/codegen/java/dal/do.vm @@ -17,7 +17,7 @@ import ${BaseDOClassName}; @Builder @NoArgsConstructor @AllArgsConstructor -public class ${table.className}DO extends ${BaseDOClassName_simple} { +public class ${table.className}DO extends BaseDO { #foreach ($column in $columns) #if (!${baseDOFields.contains(${column.javaField})})##排除 BaseDO 的字段 diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 825ac44e4..dbd325da9 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -78,7 +78,9 @@ yudao: - cn.iocoder.yudao.module.system.enums.ErrorCodeConstants - cn.iocoder.yudao.module.tool.enums.ErrorCodeConstants tenant: # 多租户相关配置项 - tables: # 配置需要开启多租户的表;如果实体已经继承 TenantBaseDO 类,则无需重复配置 + enable: true + ignore-urls: /admin-api/system/captcha/get-image, /admin-api/infra/file/get/* + 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 sms-code: # 短信验证码相关的配置项 expire-times: 10m send-frequency: 1m diff --git a/yudao-ui-admin/.env.development b/yudao-ui-admin/.env.development index 170c93cdc..7f6246a9e 100644 --- a/yudao-ui-admin/.env.development +++ b/yudao-ui-admin/.env.development @@ -10,3 +10,6 @@ VUE_APP_BASE_API = '/dev-api' # 路由懒加载 VUE_CLI_BABEL_TRANSPILE_MODULES = true + +# 多租户的开关 +VUE_APP_TENANT_ENABLE = true diff --git a/yudao-ui-admin/src/utils/request.js b/yudao-ui-admin/src/utils/request.js index 76b1df1d1..bd7d5b7e4 100644 --- a/yudao-ui-admin/src/utils/request.js +++ b/yudao-ui-admin/src/utils/request.js @@ -4,6 +4,7 @@ import store from '@/store' import { getToken } from '@/utils/auth' import errorCode from '@/utils/errorCode' import Cookies from "js-cookie"; +import {getTenantEnable} from "@/utils/ruoyi"; // 是否显示重新登录 let isReloginShow; @@ -24,9 +25,11 @@ service.interceptors.request.use(config => { config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 } // 设置租户 - const tenantId = Cookies.get('tenantId'); - if (tenantId) { - config.headers['tenant-id'] = tenantId; + if (getTenantEnable()) { + const tenantId = Cookies.get('tenantId'); + if (tenantId) { + config.headers['tenant-id'] = tenantId; + } } // get请求映射params参数 if (config.method === 'get' && config.params) { diff --git a/yudao-ui-admin/src/utils/ruoyi.js b/yudao-ui-admin/src/utils/ruoyi.js index e96763e7a..3dd996cee 100644 --- a/yudao-ui-admin/src/utils/ruoyi.js +++ b/yudao-ui-admin/src/utils/ruoyi.js @@ -170,3 +170,17 @@ export function getNowDateTime(timeStr) { let seconds = now.getSeconds().toString().padStart(2, "0") // 得到秒; return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; } + +/** + * 获得租户功能是否开启 + */ +export function getTenantEnable() { + console.log("enable: " + process.env.VUE_APP_TENANT_ENABLE) + if (process.env.VUE_APP_TENANT_ENABLE === "true") { + return true; + } + if (process.env.VUE_APP_TENANT_ENABLE === "false") { + return false; + } + return process.env.VUE_APP_TENANT_ENABLE || true; +} diff --git a/yudao-ui-admin/src/views/login.vue b/yudao-ui-admin/src/views/login.vue index b1497a402..1031d9dc3 100644 --- a/yudao-ui-admin/src/views/login.vue +++ b/yudao-ui-admin/src/views/login.vue @@ -2,7 +2,7 @@