Commit 848fcdf329d2df1e9b5f0028e6b359c370b10e75
1 parent
d10b4595
租户创建人数的限制
Showing
6 changed files
with
61 additions
and
2 deletions
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
| ... | ... | @@ -43,6 +43,10 @@ public interface BaseMapperX<T> extends BaseMapper<T> { |
| 43 | 43 | return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2)); |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | + default Long selectCount() { | |
| 47 | + return selectCount(new QueryWrapper<T>()); | |
| 48 | + } | |
| 49 | + | |
| 46 | 50 | default Integer selectCount(String field, Object value) { |
| 47 | 51 | return selectCount(new QueryWrapper<T>().eq(field, value)).intValue(); |
| 48 | 52 | } | ... | ... |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java
| ... | ... | @@ -40,7 +40,8 @@ public interface ErrorCodeConstants { |
| 40 | 40 | ErrorCode USER_NOT_EXISTS = new ErrorCode(1002004003, "用户不存在"); |
| 41 | 41 | ErrorCode USER_IMPORT_LIST_IS_EMPTY = new ErrorCode(1002004004, "导入用户数据不能为空!"); |
| 42 | 42 | ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1002004005, "用户密码校验失败"); |
| 43 | - ErrorCode USER_IS_DISABLE = new ErrorCode(1002003004, "名字为【{}】的用户已被禁用"); | |
| 43 | + ErrorCode USER_IS_DISABLE = new ErrorCode(1002004006, "名字为【{}】的用户已被禁用"); | |
| 44 | + ErrorCode USER_COUNT_MAX = new ErrorCode(1002004007, "创建用户失败,原因:超过租户最大租户配额({})!"); | |
| 44 | 45 | |
| 45 | 46 | // ========== 部门模块 1002005000 ========== |
| 46 | 47 | ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1002004001, "已经存在该名字的部门"); | ... | ... |
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantService.java
| ... | ... | @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantEx |
| 8 | 8 | import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO; |
| 9 | 9 | import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantUpdateReqVO; |
| 10 | 10 | import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO; |
| 11 | +import cn.iocoder.yudao.module.system.service.tenant.handler.TenantInfoHandler; | |
| 11 | 12 | import cn.iocoder.yudao.module.system.service.tenant.handler.TenantMenuHandler; |
| 12 | 13 | |
| 13 | 14 | import javax.validation.Valid; |
| ... | ... | @@ -114,11 +115,18 @@ public interface TenantService extends TenantFrameworkService { |
| 114 | 115 | List<TenantDO> getTenantListByPackageId(Long packageId); |
| 115 | 116 | |
| 116 | 117 | /** |
| 118 | + * 进行租户的信息处理逻辑 | |
| 119 | + * 其中,租户编号从 {@link TenantContextHolder} 上下文中获取 | |
| 120 | + * | |
| 121 | + * @param handler 处理器 | |
| 122 | + */ | |
| 123 | + void handleTenantInfo(TenantInfoHandler handler); | |
| 124 | + | |
| 125 | + /** | |
| 117 | 126 | * 进行租户的菜单处理逻辑 |
| 118 | 127 | * 其中,租户编号从 {@link TenantContextHolder} 上下文中获取 |
| 119 | 128 | * |
| 120 | 129 | * @param handler 处理器 |
| 121 | 130 | */ |
| 122 | 131 | void handleTenantMenu(TenantMenuHandler handler); |
| 123 | - | |
| 124 | 132 | } | ... | ... |
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java
| ... | ... | @@ -25,9 +25,11 @@ import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum; |
| 25 | 25 | import cn.iocoder.yudao.module.system.mq.producer.tenant.TenantProducer; |
| 26 | 26 | import cn.iocoder.yudao.module.system.service.permission.PermissionService; |
| 27 | 27 | import cn.iocoder.yudao.module.system.service.permission.RoleService; |
| 28 | +import cn.iocoder.yudao.module.system.service.tenant.handler.TenantInfoHandler; | |
| 28 | 29 | import cn.iocoder.yudao.module.system.service.tenant.handler.TenantMenuHandler; |
| 29 | 30 | import cn.iocoder.yudao.module.system.service.user.AdminUserService; |
| 30 | 31 | import lombok.extern.slf4j.Slf4j; |
| 32 | +import org.springframework.context.annotation.Lazy; | |
| 31 | 33 | import org.springframework.scheduling.annotation.Scheduled; |
| 32 | 34 | import org.springframework.stereotype.Service; |
| 33 | 35 | import org.springframework.transaction.annotation.Transactional; |
| ... | ... | @@ -79,6 +81,7 @@ public class TenantServiceImpl implements TenantService { |
| 79 | 81 | @Resource |
| 80 | 82 | private TenantPackageService tenantPackageService; |
| 81 | 83 | @Resource |
| 84 | + @Lazy // 延迟,避免循环依赖报错 | |
| 82 | 85 | private AdminUserService userService; |
| 83 | 86 | @Resource |
| 84 | 87 | private RoleService roleService; |
| ... | ... | @@ -299,6 +302,18 @@ public class TenantServiceImpl implements TenantService { |
| 299 | 302 | } |
| 300 | 303 | |
| 301 | 304 | @Override |
| 305 | + public void handleTenantInfo(TenantInfoHandler handler) { | |
| 306 | + // 如果禁用,则不执行逻辑 | |
| 307 | + if (Boolean.FALSE.equals(tenantProperties.getEnable())) { | |
| 308 | + return; | |
| 309 | + } | |
| 310 | + // 获得租户 | |
| 311 | + TenantDO tenant = getTenant(TenantContextHolder.getRequiredTenantId()); | |
| 312 | + // 执行处理器 | |
| 313 | + handler.handle(tenant); | |
| 314 | + } | |
| 315 | + | |
| 316 | + @Override | |
| 302 | 317 | public void handleTenantMenu(TenantMenuHandler handler) { |
| 303 | 318 | // 如果禁用,则不执行逻辑 |
| 304 | 319 | if (Boolean.FALSE.equals(tenantProperties.getEnable())) { | ... | ... |
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/tenant/handler/TenantInfoHandler.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.system.service.tenant.handler; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * 租户信息处理 | |
| 7 | + * 目的:尽量减少租户逻辑耦合到系统中 | |
| 8 | + * | |
| 9 | + * @author 芋道源码 | |
| 10 | + */ | |
| 11 | +public interface TenantInfoHandler { | |
| 12 | + | |
| 13 | + /** | |
| 14 | + * 基于传入的租户信息,进行相关逻辑的执行 | |
| 15 | + * 例如说,创建用户时,超过最大账户配额 | |
| 16 | + * | |
| 17 | + * @param tenant 租户信息 | |
| 18 | + */ | |
| 19 | + void handle(TenantDO tenant); | |
| 20 | + | |
| 21 | +} | ... | ... |
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
| ... | ... | @@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper; |
| 18 | 18 | import cn.iocoder.yudao.module.system.service.dept.DeptService; |
| 19 | 19 | import cn.iocoder.yudao.module.system.service.dept.PostService; |
| 20 | 20 | import cn.iocoder.yudao.module.system.service.permission.PermissionService; |
| 21 | +import cn.iocoder.yudao.module.system.service.tenant.TenantService; | |
| 21 | 22 | import com.google.common.annotations.VisibleForTesting; |
| 22 | 23 | import lombok.extern.slf4j.Slf4j; |
| 23 | 24 | import org.springframework.beans.factory.annotation.Value; |
| ... | ... | @@ -55,12 +56,21 @@ public class AdminUserServiceImpl implements AdminUserService { |
| 55 | 56 | private PermissionService permissionService; |
| 56 | 57 | @Resource |
| 57 | 58 | private PasswordEncoder passwordEncoder; |
| 59 | + @Resource | |
| 60 | + private TenantService tenantService; | |
| 58 | 61 | |
| 59 | 62 | @Resource |
| 60 | 63 | private FileApi fileApi; |
| 61 | 64 | |
| 62 | 65 | @Override |
| 63 | 66 | public Long createUser(UserCreateReqVO reqVO) { |
| 67 | + // 校验账户配合 | |
| 68 | + tenantService.handleTenantInfo(tenant -> { | |
| 69 | + long count = userMapper.selectCount(); | |
| 70 | + if (count >= tenant.getAccountCount()) { | |
| 71 | + throw exception(USER_COUNT_MAX, tenant.getAccountCount()); | |
| 72 | + } | |
| 73 | + }); | |
| 64 | 74 | // 校验正确性 |
| 65 | 75 | this.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), |
| 66 | 76 | reqVO.getDeptId(), reqVO.getPostIds()); | ... | ... |