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