From 7e9a950694ce78f11b0f2ffb8fe69617502c361e Mon Sep 17 00:00:00 2001 From: Charles7c Date: Thu, 17 Jul 2025 22:15:13 +0800 Subject: [PATCH] =?UTF-8?q?refactor(tenant):=20=E4=BC=98=E5=8C=96=E7=A7=9F?= =?UTF-8?q?=E6=88=B7=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../base/model/entity/TenantBaseDO.java | 43 ++++++ .../config/TenantExtensionProperties.java | 10 ++ .../admin/common/constant/RegexConstants.java | 14 +- .../tenant/config/DefaultTenantProvider.java | 37 ++++-- ...nController.java => CommonController.java} | 4 +- .../tenant/controller/TenantController.java | 21 +-- .../admin/tenant/model/entity/TenantDO.java | 2 +- .../admin/tenant/model/req/PackageReq.java | 5 +- .../admin/tenant/model/req/TenantReq.java | 7 +- .../admin/tenant/model/resp/TenantResp.java | 6 +- .../admin/tenant/service/PackageService.java | 10 +- .../admin/tenant/service/TenantService.java | 32 ++++- .../service/impl/PackageServiceImpl.java | 57 +++----- .../service/impl/TenantServiceImpl.java | 125 ++++++++++++++---- .../satoken/SaExtensionInterceptor.java | 31 ++++- .../controller/common/CaptchaController.java | 2 + .../controller/common/CommonController.java | 2 + .../admin/job/DemoEnvironmentJob.java | 2 + .../continew/admin/job/NoticePublishJob.java | 3 + .../src/main/resources/config/application.yml | 35 ++--- .../changelog/mysql/plugin/plugin_tenant.sql | 2 +- .../postgresql/plugin/plugin_tenant.sql | 3 +- .../service/impl/OnlineUserServiceImpl.java | 8 +- .../system/model/entity/user/UserDO.java | 10 +- .../admin/system/model/query/MenuQuery.java | 2 +- .../system/service/impl/DeptServiceImpl.java | 5 +- .../system/service/impl/FileServiceImpl.java | 2 + .../service/impl/SmsConfigServiceImpl.java | 2 +- .../service/impl/StorageServiceImpl.java | 2 +- 29 files changed, 333 insertions(+), 151 deletions(-) create mode 100644 continew-common/src/main/java/top/continew/admin/common/base/model/entity/TenantBaseDO.java rename continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/{TenantCommonController.java => CommonController.java} (96%) diff --git a/continew-common/src/main/java/top/continew/admin/common/base/model/entity/TenantBaseDO.java b/continew-common/src/main/java/top/continew/admin/common/base/model/entity/TenantBaseDO.java new file mode 100644 index 00000000..15a68891 --- /dev/null +++ b/continew-common/src/main/java/top/continew/admin/common/base/model/entity/TenantBaseDO.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.continew.admin.common.base.model.entity; + +import lombok.Data; + +import java.io.Serial; + +/** + * 租户实体类基类 + * + *

+ * 通用字段:ID、创建人、创建时间、修改人、修改时间、租户 ID + *

+ * + * @author Charles7c + * @since 2025/7/17 20:20 + */ +@Data +public class TenantBaseDO extends BaseDO { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 租户 ID + */ + private Long tenantId; +} diff --git a/continew-common/src/main/java/top/continew/admin/common/config/TenantExtensionProperties.java b/continew-common/src/main/java/top/continew/admin/common/config/TenantExtensionProperties.java index 4903da0e..02543017 100644 --- a/continew-common/src/main/java/top/continew/admin/common/config/TenantExtensionProperties.java +++ b/continew-common/src/main/java/top/continew/admin/common/config/TenantExtensionProperties.java @@ -35,6 +35,16 @@ import java.util.List; @ConfigurationProperties(prefix = PropertiesConstants.TENANT) public class TenantExtensionProperties { + /** + * 是否启用 + */ + private boolean enabled; + + /** + * 请求头中租户编码键名 + */ + private String tenantCodeHeader; + /** * 忽略菜单 ID(租户不能使用的菜单) */ diff --git a/continew-common/src/main/java/top/continew/admin/common/constant/RegexConstants.java b/continew-common/src/main/java/top/continew/admin/common/constant/RegexConstants.java index 82bb04e1..4037298e 100644 --- a/continew-common/src/main/java/top/continew/admin/common/constant/RegexConstants.java +++ b/continew-common/src/main/java/top/continew/admin/common/constant/RegexConstants.java @@ -60,10 +60,22 @@ public class RegexConstants { public static final String PACKAGE_NAME = "^(?:[a-zA-Z_][a-zA-Z0-9_]*\\.)*[a-zA-Z_][a-zA-Z0-9_]*$"; /** - * HTTP 域名 URL 正则 + * HTTP 域名 URL 正则(非 IP 地址) */ public static final String HTTP_DOMAIN_URL = "^(https?:\\/\\/)([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}(\\/[^\\s]*)?$"; + /** + * HTTP HOST 正则 + *

+ * 域名、IPV4、IPV6 + *

+ */ + public static final String HTTP_HOST = """ + ^((?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}| + (?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)| + (?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}| + """; + private RegexConstants() { } } diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/DefaultTenantProvider.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/DefaultTenantProvider.java index 1df20979..6c8fc21b 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/DefaultTenantProvider.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/config/DefaultTenantProvider.java @@ -17,13 +17,17 @@ package top.continew.admin.tenant.config; import cn.hutool.core.util.StrUtil; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import top.continew.admin.common.config.TenantExtensionProperties; +import top.continew.admin.tenant.model.entity.TenantDO; import top.continew.admin.tenant.service.TenantService; +import top.continew.starter.core.util.ServletUtils; +import top.continew.starter.core.util.validation.CheckUtils; import top.continew.starter.extension.tenant.autoconfigure.TenantProperties; import top.continew.starter.extension.tenant.config.TenantProvider; import top.continew.starter.extension.tenant.context.TenantContext; -import top.continew.starter.extension.tenant.enums.TenantIsolationLevel; /** * 默认租户提供者 @@ -37,21 +41,38 @@ import top.continew.starter.extension.tenant.enums.TenantIsolationLevel; public class DefaultTenantProvider implements TenantProvider { private final TenantProperties tenantProperties; + private final TenantExtensionProperties tenantExtensionProperties; private final TenantService tenantService; @Override public TenantContext getByTenantId(String tenantIdAsString, boolean verify) { TenantContext context = new TenantContext(); - context.setIsolationLevel(TenantIsolationLevel.LINE); - // 超级租户 Long superTenantId = tenantProperties.getSuperTenantId(); - if (StrUtil.isBlank(tenantIdAsString) || superTenantId.toString().equals(tenantIdAsString)) { - context.setTenantId(superTenantId); + context.setTenantId(superTenantId); + // 超级租户 + if (superTenantId.toString().equals(tenantIdAsString)) { return context; } - // 获取租户信息 - Long tenantId = Long.valueOf(tenantIdAsString); - tenantService.checkStatus(tenantId); + Long tenantId; + // 未指定租户 + if (StrUtil.isBlank(tenantIdAsString)) { + // 检查是否指定了租户编码(登录相关接口) + HttpServletRequest request = ServletUtils.getRequest(); + String tenantCode = request.getHeader(tenantExtensionProperties.getTenantCodeHeader()); + if (StrUtil.isBlank(tenantCode)) { + return context; + } + TenantDO tenant = tenantService.getByCode(tenantCode); + CheckUtils.throwIfNull(tenant, "编码为 [%s] 的租户不存在".formatted(tenantCode)); + tenantId = tenant.getId(); + } else { + // 指定租户 + tenantId = Long.parseLong(tenantIdAsString); + } + // 检查租户状态 + if (verify) { + tenantService.checkStatus(tenantId); + } context.setTenantId(tenantId); return context; } diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/TenantCommonController.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/CommonController.java similarity index 96% rename from continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/TenantCommonController.java rename to continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/CommonController.java index 4d0f2ef7..aa04103d 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/TenantCommonController.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/CommonController.java @@ -40,10 +40,10 @@ import java.util.List; @Tag(name = "公共 API") @Log(ignore = true) @Validated -@RestController @RequiredArgsConstructor +@RestController("tenantCommonController") @RequestMapping("/tenant/common") -public class TenantCommonController { +public class CommonController { private final PackageService packageService; diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/TenantController.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/TenantController.java index c3e4f20a..7093dbb6 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/TenantController.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/controller/TenantController.java @@ -17,13 +17,15 @@ package top.continew.admin.tenant.controller; import cn.dev33.satoken.annotation.SaCheckPermission; -import cn.dev33.satoken.annotation.SaIgnore; import cn.hutool.extra.spring.SpringUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; import top.continew.admin.common.base.controller.BaseController; import top.continew.admin.common.util.SecureUtils; import top.continew.admin.system.model.entity.user.UserDO; @@ -33,7 +35,6 @@ import top.continew.admin.tenant.model.entity.TenantDO; import top.continew.admin.tenant.model.query.TenantQuery; import top.continew.admin.tenant.model.req.TenantAdminUserPwdUpdateReq; import top.continew.admin.tenant.model.req.TenantReq; -import top.continew.admin.tenant.model.resp.TenantCommonResp; import top.continew.admin.tenant.model.resp.TenantDetailResp; import top.continew.admin.tenant.model.resp.TenantResp; import top.continew.admin.tenant.service.TenantService; @@ -42,7 +43,6 @@ import top.continew.starter.core.util.validation.ValidationUtils; import top.continew.starter.extension.crud.annotation.CrudRequestMapping; import top.continew.starter.extension.crud.enums.Api; import top.continew.starter.extension.tenant.TenantHandler; -import top.continew.starter.extension.tenant.autoconfigure.TenantProperties; /** * 租户管理 API @@ -57,26 +57,15 @@ import top.continew.starter.extension.tenant.autoconfigure.TenantProperties; @CrudRequestMapping(value = "/tenant/management", api = {Api.PAGE, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE}) public class TenantController extends BaseController { - private final TenantProperties tenantProperties; private final UserService userService; - @SaIgnore - @GetMapping("/common") - @Operation(summary = "租户通用信息查询", description = "租户通用信息查询") - public TenantCommonResp common() { - TenantCommonResp commonResp = new TenantCommonResp(); - commonResp.setIsEnabled(tenantProperties.isEnabled()); - commonResp.setAvailableList(baseService.getAvailableList()); - return commonResp; - } - @Operation(summary = "修改租户管理员密码", description = "修改租户管理员密码") @SaCheckPermission("tenant:management:updateAdminUserPwd") @PutMapping("/{id}/admin/pwd") public void updateAdminUserPwd(@Valid @RequestBody TenantAdminUserPwdUpdateReq req, @PathVariable Long id) { TenantDO tenant = baseService.getById(id); String encryptPassword = req.getPassword(); - SpringUtil.getBean(TenantHandler.class).execute(tenant.getId(), () -> { + SpringUtil.getBean(TenantHandler.class).execute(id, () -> { UserDO user = userService.getById(tenant.getAdminUser()); String password = ExceptionUtils.exToNull(() -> SecureUtils.decryptByRsaPrivateKey(encryptPassword)); ValidationUtils.throwIfNull(password, "新密码解密失败"); diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/entity/TenantDO.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/entity/TenantDO.java index e01edac9..d36a542a 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/entity/TenantDO.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/entity/TenantDO.java @@ -49,7 +49,7 @@ public class TenantDO extends BaseDO { private String code; /** - * 域名 + * 绑定域名 */ private String domain; diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/req/PackageReq.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/req/PackageReq.java index 9cb16efa..064b2d24 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/req/PackageReq.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/req/PackageReq.java @@ -18,13 +18,13 @@ package top.continew.admin.tenant.model.req; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; import lombok.Data; import org.hibernate.validator.constraints.Length; import top.continew.admin.common.enums.DisEnableStatusEnum; import java.io.Serial; import java.io.Serializable; -import java.util.ArrayList; import java.util.List; /** @@ -78,5 +78,6 @@ public class PackageReq implements Serializable { * 关联的菜单 ID 列表 */ @Schema(description = "关联的菜单 ID 列表", example = "[1000, 1010, 1011]") - private List menuIds = new ArrayList<>(); + @NotEmpty(message = "关联菜单不能为空") + private List menuIds; } \ No newline at end of file diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/req/TenantReq.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/req/TenantReq.java index c2851218..18efcc64 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/req/TenantReq.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/req/TenantReq.java @@ -54,10 +54,11 @@ public class TenantReq implements Serializable { private String name; /** - * 域名 + * 绑定域名 */ - @Schema(description = "域名", example = "https://T0sL6RWv0vFh.continew.top/") - @Length(max = 255, message = "域名长度不能超过 {max} 个字符") + @Schema(description = "绑定域名", example = "https://T0sL6RWv0vFh.continew.top/") + @Length(max = 255, message = "绑定域名长度不能超过 {max} 个字符") + @Pattern(regexp = RegexConstants.HTTP_HOST, message = "绑定域名格式不正确") private String domain; /** diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/resp/TenantResp.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/resp/TenantResp.java index e167fa81..1d8c4bec 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/resp/TenantResp.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/model/resp/TenantResp.java @@ -61,10 +61,10 @@ public class TenantResp extends BaseDetailResp { private String code; /** - * 域名 + * 绑定域名 */ - @Schema(description = "域名", example = "https://T0sL6RWv0vFh.continew.top/") - @ExcelProperty(value = "域名", order = 4) + @Schema(description = "绑定域名", example = "https://T0sL6RWv0vFh.continew.top/") + @ExcelProperty(value = "绑定域名", order = 4) private String domain; /** diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/PackageService.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/PackageService.java index 91fa9c46..ffb2f0fc 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/PackageService.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/PackageService.java @@ -30,4 +30,12 @@ import top.continew.starter.data.service.IService; * @author 小熊 * @since 2024/11/26 11:25 */ -public interface PackageService extends BaseService, IService {} \ No newline at end of file +public interface PackageService extends BaseService, IService { + + /** + * 检查套餐状态 + * + * @param id ID + */ + void checkStatus(Long id); +} \ No newline at end of file diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/TenantService.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/TenantService.java index 4fa6b062..e4e69a6a 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/TenantService.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/TenantService.java @@ -20,7 +20,6 @@ import top.continew.admin.common.base.service.BaseService; import top.continew.admin.tenant.model.entity.TenantDO; import top.continew.admin.tenant.model.query.TenantQuery; import top.continew.admin.tenant.model.req.TenantReq; -import top.continew.admin.tenant.model.resp.TenantAvailableResp; import top.continew.admin.tenant.model.resp.TenantDetailResp; import top.continew.admin.tenant.model.resp.TenantResp; import top.continew.starter.data.service.IService; @@ -36,6 +35,22 @@ import java.util.List; */ public interface TenantService extends BaseService, IService { + /** + * 根据绑定域名查询 + * + * @param domain 绑定域名 + * @return 租户信息 + */ + TenantDO getByDomain(String domain); + + /** + * 根据编码查询 + * + * @param code 编码 + * @return 租户信息 + */ + TenantDO getByCode(String code); + /** * 检查租户状态 * @@ -44,7 +59,18 @@ public interface TenantService extends BaseService getAvailableList(); + void updateTenantMenu(List newMenuIds, Long packageId); + + /** + * 根据套餐 ID 查询数量 + * + * @param packageIds 套餐 ID 列表 + * @return 租户数量 + */ + Long countByPackageIds(List packageIds); } \ No newline at end of file diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/impl/PackageServiceImpl.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/impl/PackageServiceImpl.java index 1d7d50cf..1607c056 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/impl/PackageServiceImpl.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/impl/PackageServiceImpl.java @@ -16,27 +16,23 @@ package top.continew.admin.tenant.service.impl; -import cn.hutool.core.collection.CollUtil; -import cn.hutool.extra.spring.SpringUtil; +import jakarta.annotation.Resource; import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import top.continew.admin.common.base.service.BaseServiceImpl; -import top.continew.admin.system.model.entity.MenuDO; -import top.continew.admin.system.service.MenuService; +import top.continew.admin.common.enums.DisEnableStatusEnum; import top.continew.admin.tenant.mapper.PackageMapper; -import top.continew.admin.tenant.mapper.TenantMapper; import top.continew.admin.tenant.model.entity.PackageDO; -import top.continew.admin.tenant.model.entity.TenantDO; import top.continew.admin.tenant.model.query.PackageQuery; import top.continew.admin.tenant.model.req.PackageReq; import top.continew.admin.tenant.model.resp.PackageDetailResp; import top.continew.admin.tenant.model.resp.PackageResp; import top.continew.admin.tenant.service.PackageMenuService; import top.continew.admin.tenant.service.PackageService; +import top.continew.admin.tenant.service.TenantService; import top.continew.starter.core.util.validation.CheckUtils; -import top.continew.starter.extension.tenant.TenantHandler; -import java.util.ArrayList; import java.util.List; /** @@ -51,8 +47,9 @@ import java.util.List; public class PackageServiceImpl extends BaseServiceImpl implements PackageService { private final PackageMenuService packageMenuService; - private final MenuService menuService; - private final TenantMapper tenantMapper; + @Lazy + @Resource + private TenantService tenantService; @Override public Long create(PackageReq req) { @@ -75,42 +72,18 @@ public class PackageServiceImpl extends BaseServiceImpl tenantIdList = tenantMapper.lambdaQuery() - .select(TenantDO::getId) - .eq(TenantDO::getPackageId, id) - .list() - .stream() - .map(TenantDO::getId) - .toList(); - if (CollUtil.isEmpty(tenantIdList)) { - return; - } - List oldMenuIds = packageMenuService.listMenuIdsByPackageId(id); - List newMenuIds = req.getMenuIds(); - // 如果有删除的菜单则绑定了套餐的租户对应的菜单也会删除 - List deleteMenuIds = new ArrayList<>(oldMenuIds); - deleteMenuIds.removeAll(newMenuIds); - if (CollUtil.isNotEmpty(deleteMenuIds)) { - List deleteMenus = menuService.listByIds(deleteMenuIds); - tenantIdList.forEach(tenantId -> SpringUtil.getBean(TenantHandler.class) - .execute(tenantId, () -> menuService.deleteTenantMenus(deleteMenus))); - } - // 如果有新增的菜单则绑定了套餐的租户对应的菜单也会新增 - List addMenuIds = new ArrayList<>(newMenuIds); - addMenuIds.removeAll(oldMenuIds); - if (CollUtil.isNotEmpty(addMenuIds)) { - List addMenus = menuService.listByIds(addMenuIds); - for (MenuDO addMenu : addMenus) { - MenuDO parentMenu = addMenu.getParentId() != 0 ? menuService.getById(addMenu.getParentId()) : null; - tenantIdList.forEach(tenantId -> SpringUtil.getBean(TenantHandler.class) - .execute(tenantId, () -> menuService.addTenantMenu(addMenu, parentMenu))); - } - } + tenantService.updateTenantMenu(req.getMenuIds(), id); } @Override public void beforeDelete(List ids) { - CheckUtils.throwIf(tenantMapper.lambdaQuery().in(TenantDO::getPackageId, ids).exists(), "所选套餐存在关联租户,不允许删除"); + CheckUtils.throwIf(tenantService.countByPackageIds(ids) > 0, "所选套餐存在关联租户,不允许删除"); + } + + @Override + public void checkStatus(Long id) { + PackageDO entity = this.getById(id); + CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, entity.getStatus(), "租户套餐已被禁用"); } /** diff --git a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/impl/TenantServiceImpl.java b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/impl/TenantServiceImpl.java index 5b3b182a..a58e9f9b 100644 --- a/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/impl/TenantServiceImpl.java +++ b/continew-plugin/continew-plugin-tenant/src/main/java/top/continew/admin/tenant/service/impl/TenantServiceImpl.java @@ -16,25 +16,23 @@ package top.continew.admin.tenant.service.impl; -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.date.DateUtil; +import cn.hutool.core.collection.CollUtil; import cn.hutool.extra.spring.SpringUtil; import com.alicp.jetcache.anno.Cached; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import me.ahoo.cosid.provider.IdGeneratorProvider; import org.springframework.stereotype.Service; import top.continew.admin.common.base.service.BaseServiceImpl; import top.continew.admin.common.enums.DisEnableStatusEnum; +import top.continew.admin.system.model.entity.MenuDO; +import top.continew.admin.system.service.MenuService; import top.continew.admin.tenant.constant.TenantCacheConstants; import top.continew.admin.tenant.constant.TenantConstants; import top.continew.admin.tenant.handler.TenantDataHandler; import top.continew.admin.tenant.mapper.TenantMapper; -import top.continew.admin.tenant.model.entity.PackageDO; import top.continew.admin.tenant.model.entity.TenantDO; import top.continew.admin.tenant.model.query.TenantQuery; import top.continew.admin.tenant.model.req.TenantReq; -import top.continew.admin.tenant.model.resp.TenantAvailableResp; import top.continew.admin.tenant.model.resp.TenantDetailResp; import top.continew.admin.tenant.model.resp.TenantResp; import top.continew.admin.tenant.service.PackageMenuService; @@ -42,12 +40,12 @@ import top.continew.admin.tenant.service.PackageService; import top.continew.admin.tenant.service.TenantService; import top.continew.starter.cache.redisson.util.RedisUtils; import top.continew.starter.core.util.validation.CheckUtils; -import top.continew.starter.extension.crud.model.entity.BaseIdDO; import top.continew.starter.extension.tenant.TenantHandler; import top.continew.starter.extension.tenant.autoconfigure.TenantProperties; import java.io.Serializable; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; /** @@ -62,17 +60,18 @@ import java.util.List; public class TenantServiceImpl extends BaseServiceImpl implements TenantService { private final TenantProperties tenantProperties; - private final IdGeneratorProvider idGeneratorProvider; - private final PackageMenuService packageMenuService; private final PackageService packageService; + private final IdGeneratorProvider idGeneratorProvider; private final TenantDataHandler tenantDataHandler; + private final PackageMenuService packageMenuService; + private final MenuService menuService; @Override public Long create(TenantReq req) { this.checkNameRepeat(req.getName(), null); - // 检查租户套餐 - List menuIds = packageMenuService.listMenuIdsByPackageId(req.getPackageId()); - CheckUtils.throwIfEmpty(menuIds, "所选套餐无可用菜单"); + this.checkDomainRepeat(req.getDomain(), null); + // 检查套餐 + packageService.checkStatus(req.getPackageId()); // 生成租户编码 req.setCode(this.generateCode()); // 新增信息 @@ -86,6 +85,12 @@ public class TenantServiceImpl extends BaseServiceImpl getAvailableList() { - List tenantList = baseMapper.selectList(Wrappers.lambdaQuery(TenantDO.class) - .select(TenantDO::getName, BaseIdDO::getId, TenantDO::getDomain) - .eq(TenantDO::getStatus, DisEnableStatusEnum.ENABLE) - .and(t -> t.isNull(TenantDO::getExpireTime).or().ge(TenantDO::getExpireTime, DateUtil.date()))); - return BeanUtil.copyToList(tenantList, TenantAvailableResp.class); + public TenantDO getByCode(String code) { + return baseMapper.lambdaQuery().eq(TenantDO::getCode, code).oneOpt().orElse(null); + } + + @Override + public void checkStatus(Long id) { + TenantDO tenant = this.getById(id); + if (id.equals(tenantProperties.getSuperTenantId())) { + return; + } + CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, tenant.getStatus(), "租户已被禁用"); + CheckUtils.throwIf(tenant.getExpireTime() != null && tenant.getExpireTime() + .isBefore(LocalDateTime.now()), "租户已过期"); + // 检查套餐 + packageService.checkStatus(tenant.getPackageId()); + } + + @Override + public void updateTenantMenu(List newMenuIds, Long packageId) { + List tenantIdList = this.listIdByPackageId(packageId); + if (CollUtil.isEmpty(tenantIdList)) { + return; + } + List oldMenuIds = packageMenuService.listMenuIdsByPackageId(packageId); + // 如果有删除的菜单则绑定了套餐的租户对应的菜单也会删除 + List deleteMenuIds = new ArrayList<>(oldMenuIds); + deleteMenuIds.removeAll(newMenuIds); + if (CollUtil.isNotEmpty(deleteMenuIds)) { + List deleteMenus = menuService.listByIds(deleteMenuIds); + tenantIdList.forEach(tenantId -> SpringUtil.getBean(TenantHandler.class).execute(tenantId, () -> menuService + .deleteTenantMenus(deleteMenus))); + } + // 如果有新增的菜单则绑定了套餐的租户对应的菜单也会新增 + List addMenuIds = new ArrayList<>(newMenuIds); + addMenuIds.removeAll(oldMenuIds); + if (CollUtil.isNotEmpty(addMenuIds)) { + List addMenus = menuService.listByIds(addMenuIds); + for (MenuDO addMenu : addMenus) { + MenuDO parentMenu = addMenu.getParentId() != 0 ? menuService.getById(addMenu.getParentId()) : null; + tenantIdList.forEach(tenantId -> SpringUtil.getBean(TenantHandler.class).execute(tenantId, () -> menuService + .addTenantMenu(addMenu, parentMenu))); + } + } + } + + @Override + public Long countByPackageIds(List packageIds) { + return baseMapper.lambdaQuery().in(TenantDO::getPackageId, packageIds).count(); } /** - * 名称是否存在 + * 检查名称是否重复 * * @param name 名称 * @param id ID @@ -149,6 +187,19 @@ public class TenantServiceImpl extends BaseServiceImpl listIdByPackageId(Long id) { + return baseMapper.lambdaQuery() + .select(TenantDO::getId) + .eq(TenantDO::getPackageId, id) + .list() + .stream() + .map(TenantDO::getId) + .toList(); + } } \ No newline at end of file diff --git a/continew-server/src/main/java/top/continew/admin/config/satoken/SaExtensionInterceptor.java b/continew-server/src/main/java/top/continew/admin/config/satoken/SaExtensionInterceptor.java index a7297c79..60846b34 100644 --- a/continew-server/src/main/java/top/continew/admin/config/satoken/SaExtensionInterceptor.java +++ b/continew-server/src/main/java/top/continew/admin/config/satoken/SaExtensionInterceptor.java @@ -19,10 +19,18 @@ package top.continew.admin.config.satoken; import cn.dev33.satoken.fun.SaParamFunction; import cn.dev33.satoken.interceptor.SaInterceptor; import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.extra.servlet.JakartaServletUtil; +import cn.hutool.json.JSONUtil; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.lang.Nullable; +import top.continew.admin.common.context.UserContext; import top.continew.admin.common.context.UserContextHolder; +import top.continew.starter.extension.tenant.context.TenantContextHolder; +import top.continew.starter.web.model.R; /** * Sa-Token 扩展拦截器 @@ -30,6 +38,7 @@ import top.continew.admin.common.context.UserContextHolder; * @author Charles7c * @since 2024/10/10 20:25 */ +@Slf4j public class SaExtensionInterceptor extends SaInterceptor { public SaExtensionInterceptor(SaParamFunction auth) { @@ -41,11 +50,24 @@ public class SaExtensionInterceptor extends SaInterceptor { HttpServletResponse response, Object handler) throws Exception { boolean flag = super.preHandle(request, response, handler); - if (flag && StpUtil.isLogin()) { - UserContextHolder.getContext(); - UserContextHolder.getExtraContext(); + if (!flag || !StpUtil.isLogin()) { + return flag; } - return flag; + // 设置上下文 + UserContext userContext = UserContextHolder.getContext(); + if (userContext == null) { + return true; + } + // 检查用户租户权限 + Long userTenantId = userContext.getTenantId(); + Long tenantId = TenantContextHolder.getTenantId(); + if (!userTenantId.equals(tenantId)) { + JakartaServletUtil.write(response, JSONUtil.toJsonStr(R.fail(String.valueOf(HttpStatus.FORBIDDEN + .value()), "您当前没有访问该租户的权限")), MediaType.APPLICATION_JSON_VALUE); + return false; + } + UserContextHolder.getExtraContext(); + return true; } @Override @@ -53,6 +75,7 @@ public class SaExtensionInterceptor extends SaInterceptor { HttpServletResponse response, Object handler, @Nullable Exception e) throws Exception { + // 清除上下文 try { super.afterCompletion(request, response, handler, e); } finally { diff --git a/continew-server/src/main/java/top/continew/admin/controller/common/CaptchaController.java b/continew-server/src/main/java/top/continew/admin/controller/common/CaptchaController.java index 95de8826..610bab74 100644 --- a/continew-server/src/main/java/top/continew/admin/controller/common/CaptchaController.java +++ b/continew-server/src/main/java/top/continew/admin/controller/common/CaptchaController.java @@ -57,6 +57,7 @@ import top.continew.starter.core.autoconfigure.application.ApplicationProperties import top.continew.starter.core.util.TemplateUtils; import top.continew.starter.core.util.validation.CheckUtils; import top.continew.starter.core.util.validation.ValidationUtils; +import top.continew.starter.extension.tenant.annotation.TenantIgnore; import top.continew.starter.log.annotation.Log; import top.continew.starter.messaging.mail.util.MailUtils; import top.continew.starter.ratelimiter.annotation.RateLimiter; @@ -78,6 +79,7 @@ import java.util.concurrent.TimeUnit; * @since 2022/12/11 14:00 */ @Tag(name = "验证码 API") +@TenantIgnore @SaIgnore @Validated @RestController diff --git a/continew-server/src/main/java/top/continew/admin/controller/common/CommonController.java b/continew-server/src/main/java/top/continew/admin/controller/common/CommonController.java index 2e5ccba8..e1f39905 100644 --- a/continew-server/src/main/java/top/continew/admin/controller/common/CommonController.java +++ b/continew-server/src/main/java/top/continew/admin/controller/common/CommonController.java @@ -38,6 +38,7 @@ import top.continew.admin.system.service.*; import top.continew.starter.core.util.validation.ValidationUtils; import top.continew.starter.extension.crud.model.query.SortQuery; import top.continew.starter.extension.crud.model.resp.LabelValueResp; +import top.continew.starter.extension.tenant.annotation.TenantIgnore; import top.continew.starter.log.annotation.Log; import java.io.IOException; @@ -111,6 +112,7 @@ public class CommonController { return dictItemService.listByDictCode(code); } + @TenantIgnore @SaIgnore @Operation(summary = "查询系统配置参数", description = "查询系统配置参数") @GetMapping("/dict/option/site") diff --git a/continew-server/src/main/java/top/continew/admin/job/DemoEnvironmentJob.java b/continew-server/src/main/java/top/continew/admin/job/DemoEnvironmentJob.java index 2e10ac8a..ec49f77c 100644 --- a/continew-server/src/main/java/top/continew/admin/job/DemoEnvironmentJob.java +++ b/continew-server/src/main/java/top/continew/admin/job/DemoEnvironmentJob.java @@ -35,6 +35,7 @@ import top.continew.admin.system.model.entity.user.UserDO; import top.continew.admin.system.model.entity.user.UserSocialDO; import top.continew.starter.cache.redisson.util.RedisUtils; import top.continew.starter.core.constant.StringConstants; +import top.continew.starter.extension.tenant.annotation.TenantIgnore; import java.util.List; import java.util.function.BooleanSupplier; @@ -78,6 +79,7 @@ public class DemoEnvironmentJob { /** * 重置演示环境数据 */ + @TenantIgnore @JobExecutor(name = "ResetEnvironmentData") @Transactional(rollbackFor = Exception.class) public void resetEnvironmentData() { diff --git a/continew-server/src/main/java/top/continew/admin/job/NoticePublishJob.java b/continew-server/src/main/java/top/continew/admin/job/NoticePublishJob.java index a1b2bbd1..5db17f26 100644 --- a/continew-server/src/main/java/top/continew/admin/job/NoticePublishJob.java +++ b/continew-server/src/main/java/top/continew/admin/job/NoticePublishJob.java @@ -33,6 +33,7 @@ import top.continew.admin.system.mapper.NoticeMapper; import top.continew.admin.system.model.entity.NoticeDO; import top.continew.admin.system.service.NoticeService; import top.continew.starter.core.constant.PropertiesConstants; +import top.continew.starter.extension.tenant.annotation.TenantIgnore; import java.time.LocalDateTime; import java.util.List; @@ -55,6 +56,7 @@ public class NoticePublishJob { @ConditionalOnProperty(prefix = "snail-job", name = PropertiesConstants.ENABLED, havingValue = "false") public static class Scheduler { + @TenantIgnore @Scheduled(cron = "0 * * * * ?") @Transactional(rollbackFor = Exception.class) public void publishNoticeWithSchedule() { @@ -71,6 +73,7 @@ public class NoticePublishJob { @ConditionalOnEnabledScheduleJob public static class ScheduleJob { + @TenantIgnore @JobExecutor(name = "NoticePublishJob") @Transactional(rollbackFor = Exception.class) public void publishNoticeWithScheduleJob() { diff --git a/continew-server/src/main/resources/config/application.yml b/continew-server/src/main/resources/config/application.yml index d736cf79..9910f7f0 100644 --- a/continew-server/src/main/resources/config/application.yml +++ b/continew-server/src/main/resources/config/application.yml @@ -175,7 +175,7 @@ logging: --- ### 链路追踪配置 continew-starter.trace: enabled: true - trace-id-name: traceId + trace-id-name: X-Trace-Id ## TLog 配置 tlog: enable-invoke-time-print: false @@ -202,24 +202,27 @@ continew-starter.tenant: enabled: true # 隔离级别(默认:LINE,行级) isolation-level: LINE - # 超级/默认租户 ID + # 超级/默认租户 ID:超管用户所在租户(默认:0) super-tenant-id: 0 + # 请求头中租户 ID 键名 + tenant-id-header: X-Tenant-Id + # 请求头中租户编码键名 + tenant-code-header: X-Tenant-Code # 忽略表(忽略拼接租户条件) ignore-tables: - - gen_config # 代码生成 - - gen_field_config + - tenant # 租户表 + - tenant_package # 租户套餐表 + - tenant_package_menu # 租户套餐与菜单关联表 + - gen_config # 代码生成配置表 + - gen_field_config # 代码生成字段配置表 - sys_dict # 字典表 - - sys_dict_item - - sys_option # 参数 - - sys_storage # 存储配置 - - tenant # 租户 - - tenant_package - - tenant_package_menu - - tenant_datasource - - sys_client # 客户端管理 - - sys_sms_config - - sys_sms_log - - sys_app # 应用 + - sys_dict_item # 字典项表 + - sys_option # 参数表 + - sys_storage # 存储表 + - sys_sms_config # 短信配置表 + - sys_sms_log # 短信日志表 + - sys_client # 客户端表 + - sys_app # 应用表 # 忽略菜单 ID(租户不能使用的菜单) ignore-menus: - 1130 # 字典管理 @@ -229,7 +232,7 @@ continew-starter.tenant: - 3000 # 租户管理 - 7000 # 能力开放 - 8000 # 任务调度 - - 9000 # 代码生成 + - 9000 # 开发工具 --- ### 限流器配置 continew-starter: diff --git a/continew-server/src/main/resources/db/changelog/mysql/plugin/plugin_tenant.sql b/continew-server/src/main/resources/db/changelog/mysql/plugin/plugin_tenant.sql index 54e08d79..0f421992 100644 --- a/continew-server/src/main/resources/db/changelog/mysql/plugin/plugin_tenant.sql +++ b/continew-server/src/main/resources/db/changelog/mysql/plugin/plugin_tenant.sql @@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS `tenant` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', `name` varchar(30) NOT NULL COMMENT '名称', `code` varchar(30) NOT NULL COMMENT '编码', - `domain` varchar(255) DEFAULT NULL COMMENT '域名', + `domain` varchar(255) DEFAULT NULL COMMENT '绑定域名', `expire_time` datetime DEFAULT NULL COMMENT '过期时间', `description` varchar(200) DEFAULT NULL COMMENT '描述', `status` tinyint(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态(1:启用;2:禁用)', diff --git a/continew-server/src/main/resources/db/changelog/postgresql/plugin/plugin_tenant.sql b/continew-server/src/main/resources/db/changelog/postgresql/plugin/plugin_tenant.sql index 7163915d..93ca2157 100644 --- a/continew-server/src/main/resources/db/changelog/postgresql/plugin/plugin_tenant.sql +++ b/continew-server/src/main/resources/db/changelog/postgresql/plugin/plugin_tenant.sql @@ -22,13 +22,12 @@ CREATE TABLE IF NOT EXISTS "tenant" ( CREATE UNIQUE INDEX "uk_tenant_code" ON "tenant" ("code"); CREATE INDEX "idx_tenant_admin_user" ON "tenant" ("admin_user"); CREATE INDEX "idx_tenant_package_id" ON "tenant" ("package_id"); -CREATE INDEX "idx_tenant_datasource_id" ON "tenant" ("datasource_id"); CREATE INDEX "idx_tenant_create_user" ON "tenant" ("create_user"); CREATE INDEX "idx_tenant_update_user" ON "tenant" ("update_user"); COMMENT ON COLUMN "tenant"."id" IS 'ID'; COMMENT ON COLUMN "tenant"."name" IS '名称'; COMMENT ON COLUMN "tenant"."code" IS '编码'; -COMMENT ON COLUMN "tenant"."domain" IS '域名'; +COMMENT ON COLUMN "tenant"."domain" IS '绑定域名'; COMMENT ON COLUMN "tenant"."expire_time" IS '过期时间'; COMMENT ON COLUMN "tenant"."description" IS '描述'; COMMENT ON COLUMN "tenant"."status" IS '状态(1:启用;2:禁用)'; diff --git a/continew-system/src/main/java/top/continew/admin/auth/service/impl/OnlineUserServiceImpl.java b/continew-system/src/main/java/top/continew/admin/auth/service/impl/OnlineUserServiceImpl.java index 097b41f3..5b1e9c2d 100644 --- a/continew-system/src/main/java/top/continew/admin/auth/service/impl/OnlineUserServiceImpl.java +++ b/continew-system/src/main/java/top/continew/admin/auth/service/impl/OnlineUserServiceImpl.java @@ -29,13 +29,13 @@ import org.springframework.stereotype.Service; import top.continew.admin.auth.model.query.OnlineUserQuery; import top.continew.admin.auth.model.resp.OnlineUserResp; import top.continew.admin.auth.service.OnlineUserService; +import top.continew.admin.common.config.TenantExtensionProperties; import top.continew.admin.common.context.UserContext; import top.continew.admin.common.context.UserContextHolder; import top.continew.admin.common.context.UserExtraContext; import top.continew.starter.core.constant.StringConstants; import top.continew.starter.extension.crud.model.query.PageQuery; import top.continew.starter.extension.crud.model.resp.PageResp; -import top.continew.starter.extension.tenant.autoconfigure.TenantProperties; import top.continew.starter.extension.tenant.context.TenantContextHolder; import java.time.LocalDateTime; @@ -52,7 +52,7 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class OnlineUserServiceImpl implements OnlineUserService { - private final TenantProperties tenantProperties; + private final TenantExtensionProperties tenantExtensionProperties; @Override @AutoOperate(type = OnlineUserResp.class, on = "list") @@ -92,8 +92,8 @@ public class OnlineUserServiceImpl implements OnlineUserService { .isMatchClientId(query.getClientId(), userContext)) { continue; } - //租户数据过滤 - if (tenantProperties.isEnabled()) { + // 只显示本租户数据 + if (tenantExtensionProperties.isEnabled()) { if (!TenantContextHolder.getTenantId().equals(userContext.getTenantId())) { continue; } diff --git a/continew-system/src/main/java/top/continew/admin/system/model/entity/user/UserDO.java b/continew-system/src/main/java/top/continew/admin/system/model/entity/user/UserDO.java index 92ccb92f..1b3ab65f 100644 --- a/continew-system/src/main/java/top/continew/admin/system/model/entity/user/UserDO.java +++ b/continew-system/src/main/java/top/continew/admin/system/model/entity/user/UserDO.java @@ -20,11 +20,11 @@ import com.baomidou.mybatisplus.annotation.FieldStrategy; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +import top.continew.admin.common.base.model.entity.TenantBaseDO; import top.continew.admin.common.config.mybatis.BCryptEncryptor; import top.continew.admin.common.enums.DisEnableStatusEnum; import top.continew.admin.common.enums.GenderEnum; import top.continew.starter.extension.crud.annotation.DictModel; -import top.continew.admin.common.base.model.entity.BaseDO; import top.continew.starter.security.crypto.annotation.FieldEncrypt; import java.io.Serial; @@ -39,7 +39,7 @@ import java.time.LocalDateTime; @Data @DictModel(labelKey = "nickname", extraKeys = {"username"}) @TableName("sys_user") -public class UserDO extends BaseDO { +public class UserDO extends TenantBaseDO { @Serial private static final long serialVersionUID = 1L; @@ -108,10 +108,4 @@ public class UserDO extends BaseDO { * 部门 ID */ private Long deptId; - - /** - * 租户 ID - */ - @TableField(select = false) - private Long tenantId; } diff --git a/continew-system/src/main/java/top/continew/admin/system/model/query/MenuQuery.java b/continew-system/src/main/java/top/continew/admin/system/model/query/MenuQuery.java index 9fa4f8f8..5f6eb169 100644 --- a/continew-system/src/main/java/top/continew/admin/system/model/query/MenuQuery.java +++ b/continew-system/src/main/java/top/continew/admin/system/model/query/MenuQuery.java @@ -62,6 +62,6 @@ public class MenuQuery implements Serializable { * 排除的菜单 ID 列表 */ @Schema(hidden = true, description = "菜单 ID 列表", example = "[9000]") - @Query(columns = "id", type = QueryType.NOT_IN) + @Query(columns = {"id", "parent_id"}, type = QueryType.NOT_IN) private List excludeMenuIdList; } diff --git a/continew-system/src/main/java/top/continew/admin/system/service/impl/DeptServiceImpl.java b/continew-system/src/main/java/top/continew/admin/system/service/impl/DeptServiceImpl.java index 52a8b503..145ac97b 100644 --- a/continew-system/src/main/java/top/continew/admin/system/service/impl/DeptServiceImpl.java +++ b/continew-system/src/main/java/top/continew/admin/system/service/impl/DeptServiceImpl.java @@ -21,6 +21,7 @@ import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import jakarta.annotation.Resource; import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import top.continew.admin.common.base.service.BaseServiceImpl; import top.continew.admin.common.enums.DisEnableStatusEnum; @@ -53,10 +54,10 @@ import java.util.Optional; public class DeptServiceImpl extends BaseServiceImpl implements DeptService { private final RoleDeptService roleDeptService; + private final DataSource dataSource; + @Lazy @Resource private UserService userService; - @Resource - private DataSource dataSource; @Override public void beforeCreate(DeptReq req) { diff --git a/continew-system/src/main/java/top/continew/admin/system/service/impl/FileServiceImpl.java b/continew-system/src/main/java/top/continew/admin/system/service/impl/FileServiceImpl.java index a586ee91..aa284ee3 100644 --- a/continew-system/src/main/java/top/continew/admin/system/service/impl/FileServiceImpl.java +++ b/continew-system/src/main/java/top/continew/admin/system/service/impl/FileServiceImpl.java @@ -28,6 +28,7 @@ import org.dromara.x.file.storage.core.FileInfo; import org.dromara.x.file.storage.core.FileStorageService; import org.dromara.x.file.storage.core.ProgressListener; import org.dromara.x.file.storage.core.upload.UploadPretreatment; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import top.continew.admin.common.base.service.BaseServiceImpl; @@ -64,6 +65,7 @@ import java.util.stream.Collectors; public class FileServiceImpl extends BaseServiceImpl implements FileService { private final FileStorageService fileStorageService; + @Lazy @Resource private StorageService storageService; diff --git a/continew-system/src/main/java/top/continew/admin/system/service/impl/SmsConfigServiceImpl.java b/continew-system/src/main/java/top/continew/admin/system/service/impl/SmsConfigServiceImpl.java index b29e51e2..dfe6c6c0 100644 --- a/continew-system/src/main/java/top/continew/admin/system/service/impl/SmsConfigServiceImpl.java +++ b/continew-system/src/main/java/top/continew/admin/system/service/impl/SmsConfigServiceImpl.java @@ -73,7 +73,7 @@ public class SmsConfigServiceImpl extends BaseServiceImpl