mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 22:57:17 +08:00 
			
		
		
		
	refactor(tenant): 优化租户相关代码
This commit is contained in:
		| @@ -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; | ||||
|     } | ||||
|   | ||||
| @@ -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; | ||||
| 
 | ||||
| @@ -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<TenantService, TenantResp, TenantDetailResp, TenantQuery, TenantReq> { | ||||
|  | ||||
|     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, "新密码解密失败"); | ||||
|   | ||||
| @@ -49,7 +49,7 @@ public class TenantDO extends BaseDO { | ||||
|     private String code; | ||||
|  | ||||
|     /** | ||||
|      * 域名 | ||||
|      * 绑定域名 | ||||
|      */ | ||||
|     private String domain; | ||||
|  | ||||
|   | ||||
| @@ -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<Long> menuIds = new ArrayList<>(); | ||||
|     @NotEmpty(message = "关联菜单不能为空") | ||||
|     private List<Long> menuIds; | ||||
| } | ||||
| @@ -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; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -30,4 +30,12 @@ import top.continew.starter.data.service.IService; | ||||
|  * @author 小熊 | ||||
|  * @since 2024/11/26 11:25 | ||||
|  */ | ||||
| public interface PackageService extends BaseService<PackageResp, PackageDetailResp, PackageQuery, PackageReq>, IService<PackageDO> {} | ||||
| public interface PackageService extends BaseService<PackageResp, PackageDetailResp, PackageQuery, PackageReq>, IService<PackageDO> { | ||||
|  | ||||
|     /** | ||||
|      * 检查套餐状态 | ||||
|      * | ||||
|      * @param id ID | ||||
|      */ | ||||
|     void checkStatus(Long id); | ||||
| } | ||||
| @@ -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<TenantResp, TenantDetailResp, TenantQuery, TenantReq>, IService<TenantDO> { | ||||
|  | ||||
|     /** | ||||
|      * 根据绑定域名查询 | ||||
|      * | ||||
|      * @param domain 绑定域名 | ||||
|      * @return 租户信息 | ||||
|      */ | ||||
|     TenantDO getByDomain(String domain); | ||||
|  | ||||
|     /** | ||||
|      * 根据编码查询 | ||||
|      * | ||||
|      * @param code 编码 | ||||
|      * @return 租户信息 | ||||
|      */ | ||||
|     TenantDO getByCode(String code); | ||||
|  | ||||
|     /** | ||||
|      * 检查租户状态 | ||||
|      * | ||||
| @@ -44,7 +59,18 @@ public interface TenantService extends BaseService<TenantResp, TenantDetailResp, | ||||
|     void checkStatus(Long id); | ||||
|  | ||||
|     /** | ||||
|      * 获取所有可用的租户列表 | ||||
|      * 更新租户菜单 | ||||
|      * | ||||
|      * @param newMenuIds 新菜单 ID 列表 | ||||
|      * @param packageId  套餐 ID | ||||
|      */ | ||||
|     List<TenantAvailableResp> getAvailableList(); | ||||
|     void updateTenantMenu(List<Long> newMenuIds, Long packageId); | ||||
|  | ||||
|     /** | ||||
|      * 根据套餐 ID 查询数量 | ||||
|      * | ||||
|      * @param packageIds 套餐 ID 列表 | ||||
|      * @return 租户数量 | ||||
|      */ | ||||
|     Long countByPackageIds(List<Long> packageIds); | ||||
| } | ||||
| @@ -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<PackageMapper, PackageDO, PackageResp, PackageDetailResp, PackageQuery, PackageReq> 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<PackageMapper, PackageDO | ||||
|             return; | ||||
|         } | ||||
|         // 更新租户菜单 | ||||
|         List<Long> tenantIdList = tenantMapper.lambdaQuery() | ||||
|             .select(TenantDO::getId) | ||||
|             .eq(TenantDO::getPackageId, id) | ||||
|             .list() | ||||
|             .stream() | ||||
|             .map(TenantDO::getId) | ||||
|             .toList(); | ||||
|         if (CollUtil.isEmpty(tenantIdList)) { | ||||
|             return; | ||||
|         } | ||||
|         List<Long> oldMenuIds = packageMenuService.listMenuIdsByPackageId(id); | ||||
|         List<Long> newMenuIds = req.getMenuIds(); | ||||
|         // 如果有删除的菜单则绑定了套餐的租户对应的菜单也会删除 | ||||
|         List<Long> deleteMenuIds = new ArrayList<>(oldMenuIds); | ||||
|         deleteMenuIds.removeAll(newMenuIds); | ||||
|         if (CollUtil.isNotEmpty(deleteMenuIds)) { | ||||
|             List<MenuDO> deleteMenus = menuService.listByIds(deleteMenuIds); | ||||
|             tenantIdList.forEach(tenantId -> SpringUtil.getBean(TenantHandler.class) | ||||
|                 .execute(tenantId, () -> menuService.deleteTenantMenus(deleteMenus))); | ||||
|         } | ||||
|         // 如果有新增的菜单则绑定了套餐的租户对应的菜单也会新增 | ||||
|         List<Long> addMenuIds = new ArrayList<>(newMenuIds); | ||||
|         addMenuIds.removeAll(oldMenuIds); | ||||
|         if (CollUtil.isNotEmpty(addMenuIds)) { | ||||
|             List<MenuDO> 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<Long> 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(), "租户套餐已被禁用"); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -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<TenantMapper, TenantDO, TenantResp, TenantDetailResp, TenantQuery, TenantReq> 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<Long> 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<TenantMapper, TenantDO, T | ||||
|     @Override | ||||
|     public void beforeUpdate(TenantReq req, Long id) { | ||||
|         this.checkNameRepeat(req.getName(), id); | ||||
|         this.checkDomainRepeat(req.getDomain(), id); | ||||
|         TenantDO tenant = super.getById(id); | ||||
|         // 变更套餐 | ||||
|         if (!tenant.getPackageId().equals(req.getPackageId())) { | ||||
|             packageService.checkStatus(req.getPackageId()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -114,30 +119,63 @@ public class TenantServiceImpl extends BaseServiceImpl<TenantMapper, TenantDO, T | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void checkStatus(Long id) { | ||||
|         TenantDO tenant = this.getById(id); | ||||
|         if (!tenantProperties.isEnabled() || id.equals(tenantProperties.getSuperTenantId())) { | ||||
|             return; | ||||
|         } | ||||
|         CheckUtils.throwIfNotEqual(DisEnableStatusEnum.ENABLE, tenant.getStatus(), "此租户已被禁用"); | ||||
|         CheckUtils.throwIf(tenant.getExpireTime() != null && tenant.getExpireTime() | ||||
|             .isBefore(LocalDateTime.now()), "此租户已过期"); | ||||
|         // 检查套餐 | ||||
|         PackageDO tenantPackage = packageService.getById(tenant.getPackageId()); | ||||
|         CheckUtils.throwIfNotEqual(DisEnableStatusEnum.ENABLE, tenantPackage.getStatus(), "此租户套餐已被禁用"); | ||||
|     public TenantDO getByDomain(String domain) { | ||||
|         return baseMapper.lambdaQuery().eq(TenantDO::getDomain, domain).oneOpt().orElse(null); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<TenantAvailableResp> getAvailableList() { | ||||
|         List<TenantDO> 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<Long> newMenuIds, Long packageId) { | ||||
|         List<Long> tenantIdList = this.listIdByPackageId(packageId); | ||||
|         if (CollUtil.isEmpty(tenantIdList)) { | ||||
|             return; | ||||
|         } | ||||
|         List<Long> oldMenuIds = packageMenuService.listMenuIdsByPackageId(packageId); | ||||
|         // 如果有删除的菜单则绑定了套餐的租户对应的菜单也会删除 | ||||
|         List<Long> deleteMenuIds = new ArrayList<>(oldMenuIds); | ||||
|         deleteMenuIds.removeAll(newMenuIds); | ||||
|         if (CollUtil.isNotEmpty(deleteMenuIds)) { | ||||
|             List<MenuDO> deleteMenus = menuService.listByIds(deleteMenuIds); | ||||
|             tenantIdList.forEach(tenantId ->  SpringUtil.getBean(TenantHandler.class).execute(tenantId, () -> menuService | ||||
|                 .deleteTenantMenus(deleteMenus))); | ||||
|         } | ||||
|         // 如果有新增的菜单则绑定了套餐的租户对应的菜单也会新增 | ||||
|         List<Long> addMenuIds = new ArrayList<>(newMenuIds); | ||||
|         addMenuIds.removeAll(oldMenuIds); | ||||
|         if (CollUtil.isNotEmpty(addMenuIds)) { | ||||
|             List<MenuDO> 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<Long> packageIds) { | ||||
|         return baseMapper.lambdaQuery().in(TenantDO::getPackageId, packageIds).count(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 名称是否存在 | ||||
|      * 检查名称是否重复 | ||||
|      * | ||||
|      * @param name 名称 | ||||
|      * @param id   ID | ||||
| @@ -149,6 +187,19 @@ public class TenantServiceImpl extends BaseServiceImpl<TenantMapper, TenantDO, T | ||||
|             .exists(), "名称为 [{}] 的租户已存在", name); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 检查绑定域名是否重复 | ||||
|      * | ||||
|      * @param domain 绑定域名 | ||||
|      * @param id     ID | ||||
|      */ | ||||
|     private void checkDomainRepeat(String domain, Long id) { | ||||
|         CheckUtils.throwIf(baseMapper.lambdaQuery() | ||||
|             .eq(TenantDO::getDomain, domain) | ||||
|             .ne(id != null, TenantDO::getId, id) | ||||
|             .exists(), "绑定域名为 [{}] 的租户已存在", domain); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 生成租户编码 | ||||
|      * | ||||
| @@ -161,4 +212,20 @@ public class TenantServiceImpl extends BaseServiceImpl<TenantMapper, TenantDO, T | ||||
|         } while (baseMapper.lambdaQuery().eq(TenantDO::getCode, code).exists()); | ||||
|         return code; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 根据套餐 ID 查询租户 ID 列表 | ||||
|      * | ||||
|      * @param id 套餐 ID | ||||
|      * @return 租户 ID 列表 | ||||
|      */ | ||||
|     private List<Long> listIdByPackageId(Long id) { | ||||
|         return baseMapper.lambdaQuery() | ||||
|             .select(TenantDO::getId) | ||||
|             .eq(TenantDO::getPackageId, id) | ||||
|             .list() | ||||
|             .stream() | ||||
|             .map(TenantDO::getId) | ||||
|             .toList(); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user