Commit 848fcdf329d2df1e9b5f0028e6b359c370b10e75

Authored by YunaiV
1 parent d10b4595

租户创建人数的限制

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());
... ...