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,6 +43,10 @@ public interface BaseMapperX<T> extends BaseMapper<T> {
43 return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2)); 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 default Integer selectCount(String field, Object value) { 50 default Integer selectCount(String field, Object value) {
47 return selectCount(new QueryWrapper<T>().eq(field, value)).intValue(); 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,7 +40,8 @@ public interface ErrorCodeConstants {
40 ErrorCode USER_NOT_EXISTS = new ErrorCode(1002004003, "用户不存在"); 40 ErrorCode USER_NOT_EXISTS = new ErrorCode(1002004003, "用户不存在");
41 ErrorCode USER_IMPORT_LIST_IS_EMPTY = new ErrorCode(1002004004, "导入用户数据不能为空!"); 41 ErrorCode USER_IMPORT_LIST_IS_EMPTY = new ErrorCode(1002004004, "导入用户数据不能为空!");
42 ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1002004005, "用户密码校验失败"); 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 // ========== 部门模块 1002005000 ========== 46 // ========== 部门模块 1002005000 ==========
46 ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1002004001, "已经存在该名字的部门"); 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,6 +8,7 @@ import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantEx
8 import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO; 8 import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
9 import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantUpdateReqVO; 9 import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantUpdateReqVO;
10 import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO; 10 import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
  11 +import cn.iocoder.yudao.module.system.service.tenant.handler.TenantInfoHandler;
11 import cn.iocoder.yudao.module.system.service.tenant.handler.TenantMenuHandler; 12 import cn.iocoder.yudao.module.system.service.tenant.handler.TenantMenuHandler;
12 13
13 import javax.validation.Valid; 14 import javax.validation.Valid;
@@ -114,11 +115,18 @@ public interface TenantService extends TenantFrameworkService { @@ -114,11 +115,18 @@ public interface TenantService extends TenantFrameworkService {
114 List<TenantDO> getTenantListByPackageId(Long packageId); 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 * 其中,租户编号从 {@link TenantContextHolder} 上下文中获取 127 * 其中,租户编号从 {@link TenantContextHolder} 上下文中获取
119 * 128 *
120 * @param handler 处理器 129 * @param handler 处理器
121 */ 130 */
122 void handleTenantMenu(TenantMenuHandler handler); 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,9 +25,11 @@ import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
25 import cn.iocoder.yudao.module.system.mq.producer.tenant.TenantProducer; 25 import cn.iocoder.yudao.module.system.mq.producer.tenant.TenantProducer;
26 import cn.iocoder.yudao.module.system.service.permission.PermissionService; 26 import cn.iocoder.yudao.module.system.service.permission.PermissionService;
27 import cn.iocoder.yudao.module.system.service.permission.RoleService; 27 import cn.iocoder.yudao.module.system.service.permission.RoleService;
  28 +import cn.iocoder.yudao.module.system.service.tenant.handler.TenantInfoHandler;
28 import cn.iocoder.yudao.module.system.service.tenant.handler.TenantMenuHandler; 29 import cn.iocoder.yudao.module.system.service.tenant.handler.TenantMenuHandler;
29 import cn.iocoder.yudao.module.system.service.user.AdminUserService; 30 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
30 import lombok.extern.slf4j.Slf4j; 31 import lombok.extern.slf4j.Slf4j;
  32 +import org.springframework.context.annotation.Lazy;
31 import org.springframework.scheduling.annotation.Scheduled; 33 import org.springframework.scheduling.annotation.Scheduled;
32 import org.springframework.stereotype.Service; 34 import org.springframework.stereotype.Service;
33 import org.springframework.transaction.annotation.Transactional; 35 import org.springframework.transaction.annotation.Transactional;
@@ -79,6 +81,7 @@ public class TenantServiceImpl implements TenantService { @@ -79,6 +81,7 @@ public class TenantServiceImpl implements TenantService {
79 @Resource 81 @Resource
80 private TenantPackageService tenantPackageService; 82 private TenantPackageService tenantPackageService;
81 @Resource 83 @Resource
  84 + @Lazy // 延迟,避免循环依赖报错
82 private AdminUserService userService; 85 private AdminUserService userService;
83 @Resource 86 @Resource
84 private RoleService roleService; 87 private RoleService roleService;
@@ -299,6 +302,18 @@ public class TenantServiceImpl implements TenantService { @@ -299,6 +302,18 @@ public class TenantServiceImpl implements TenantService {
299 } 302 }
300 303
301 @Override 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 public void handleTenantMenu(TenantMenuHandler handler) { 317 public void handleTenantMenu(TenantMenuHandler handler) {
303 // 如果禁用,则不执行逻辑 318 // 如果禁用,则不执行逻辑
304 if (Boolean.FALSE.equals(tenantProperties.getEnable())) { 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,6 +18,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
18 import cn.iocoder.yudao.module.system.service.dept.DeptService; 18 import cn.iocoder.yudao.module.system.service.dept.DeptService;
19 import cn.iocoder.yudao.module.system.service.dept.PostService; 19 import cn.iocoder.yudao.module.system.service.dept.PostService;
20 import cn.iocoder.yudao.module.system.service.permission.PermissionService; 20 import cn.iocoder.yudao.module.system.service.permission.PermissionService;
  21 +import cn.iocoder.yudao.module.system.service.tenant.TenantService;
21 import com.google.common.annotations.VisibleForTesting; 22 import com.google.common.annotations.VisibleForTesting;
22 import lombok.extern.slf4j.Slf4j; 23 import lombok.extern.slf4j.Slf4j;
23 import org.springframework.beans.factory.annotation.Value; 24 import org.springframework.beans.factory.annotation.Value;
@@ -55,12 +56,21 @@ public class AdminUserServiceImpl implements AdminUserService { @@ -55,12 +56,21 @@ public class AdminUserServiceImpl implements AdminUserService {
55 private PermissionService permissionService; 56 private PermissionService permissionService;
56 @Resource 57 @Resource
57 private PasswordEncoder passwordEncoder; 58 private PasswordEncoder passwordEncoder;
  59 + @Resource
  60 + private TenantService tenantService;
58 61
59 @Resource 62 @Resource
60 private FileApi fileApi; 63 private FileApi fileApi;
61 64
62 @Override 65 @Override
63 public Long createUser(UserCreateReqVO reqVO) { 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 this.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), 75 this.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
66 reqVO.getDeptId(), reqVO.getPostIds()); 76 reqVO.getDeptId(), reqVO.getPostIds());