Browse Source

租户部分未完成

zhaopeiqing 8 months ago
parent
commit
fa9d0d6fa6
19 changed files with 503 additions and 42 deletions
  1. 1 0
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java
  2. 2 1
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleCodeEnum.java
  3. 5 5
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java
  4. 3 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuListReqVO.java
  5. 1 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java
  6. 21 21
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantSaveReqVO.java
  7. 36 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/tenant/UserTenantRelatePageReqVO.java
  8. 42 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/tenant/UserTenantRelateRespVO.java
  9. 37 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/tenant/UserTenantRelateSaveReqVO.java
  10. 3 3
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/tenant/TenantConvert.java
  11. 48 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/UserTenantRelateDO.java
  12. 13 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java
  13. 29 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/UserTenantRelateMapper.java
  14. 61 10
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java
  15. 8 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java
  16. 41 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
  17. 64 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/UserTenantRelateService.java
  18. 87 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/UserTenantRelateServiceImpl.java
  19. 1 0
      yudao-server/src/main/resources/application.yaml

+ 1 - 0
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java

@@ -44,6 +44,7 @@ public interface ErrorCodeConstants {
     ErrorCode USER_COUNT_MAX = new ErrorCode(1_002_003_008, "创建用户失败,原因:超过租户最大租户配额({})!");
     ErrorCode USER_PASSWORD_INCONSISTENT_FAILED = new ErrorCode(1_002_003_009, "新密码和确认密码不一致");
     ErrorCode USER_PASSWORD_SIMPLE_FAILED = new ErrorCode(1_002_003_010, "密码必须包含数字、大写字母、小写字母、特殊符号中的3种,且长度为9-30位");
+    ErrorCode USER_TENANT_RELATE_NOT_EXISTS = new ErrorCode(1_002_003_011, "用户租户关系不存在");
 
     // ========== 部门模块 1-002-004-000 ==========
     ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1_002_004_000, "已经存在该名字的部门");

+ 2 - 1
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleCodeEnum.java

@@ -13,7 +13,8 @@ public enum RoleCodeEnum {
 
     SUPER_ADMIN("super_admin", "超级管理员"),
     TENANT_ADMIN("tenant_admin", "租户管理员"),
-    CRM_ADMIN("crm_admin", "CRM 管理员"); // CRM 系统专用
+    CRM_ADMIN("crm_admin", "CRM 管理员"),
+    TENANT_SUPER_ADMIN("tenant_super_admin", "租户超级管理员"),; // CRM 系统专用
     ;
 
     /**

+ 5 - 5
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java

@@ -34,21 +34,21 @@ public class AuthLoginReqVO {
 
     // ========== 图片验证码相关 ==========
 
-    @Schema(description = "验证码,验证码开启时,需要传递", requiredMode = Schema.RequiredMode.REQUIRED,
-            example = "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==")
+//    @Schema(description = "验证码,验证码开启时,需要传递", requiredMode = Schema.RequiredMode.REQUIRED,
+//            example = "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==")
     @NotEmpty(message = "验证码不能为空", groups = CodeEnableGroup.class)
     private String captchaVerification;
 
     // ========== 绑定社交登录时,需要传递如下参数 ==========
 
-    @Schema(description = "社交平台的类型,参见 SocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
+//    @Schema(description = "社交平台的类型,参见 SocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
     @InEnum(SocialTypeEnum.class)
     private Integer socialType;
 
-    @Schema(description = "授权码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+//    @Schema(description = "授权码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private String socialCode;
 
-    @Schema(description = "state", requiredMode = Schema.RequiredMode.REQUIRED, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62")
+//    @Schema(description = "state", requiredMode = Schema.RequiredMode.REQUIRED, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62")
     private String socialState;
 
     /**

+ 3 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuListReqVO.java

@@ -13,4 +13,7 @@ public class MenuListReqVO {
     @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
     private Integer status;
 
+    @Schema(description = "租户编码", example = "1")
+    private Long tenantId;
+
 }

+ 1 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java

@@ -56,7 +56,7 @@ public class TenantController {
 
     @PostMapping("/create")
     @Operation(summary = "创建租户")
-    @PreAuthorize("@ss.hasPermission('system:tenant:create')")
+//    @PreAuthorize("@ss.hasPermission('system:tenant:create')")
     public CommonResult<Long> createTenant(@Valid @RequestBody TenantSaveReqVO createReqVO) {
         return success(tenantService.createTenant(createReqVO));
     }

+ 21 - 21
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantSaveReqVO.java

@@ -24,7 +24,7 @@ public class TenantSaveReqVO {
     private String name;
 
     @Schema(description = "联系人", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
-    @NotNull(message = "联系人不能为空")
+//    @NotNull(message = "联系人不能为空")
     private String contactName;
 
     @Schema(description = "联系手机", example = "15601691300")
@@ -37,34 +37,34 @@ public class TenantSaveReqVO {
     @Schema(description = "绑定域名", example = "https://www.iocoder.cn")
     private String website;
 
-    @Schema(description = "租户套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
-    @NotNull(message = "租户套餐编号不能为空")
-    private Long packageId;
+//    @Schema(description = "租户套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+//    @NotNull(message = "租户套餐编号不能为空")
+//    private Long packageId;
 
     @Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "过期时间不能为空")
+//    @NotNull(message = "过期时间不能为空")
     private LocalDateTime expireTime;
 
     @Schema(description = "账号数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
-    @NotNull(message = "账号数量不能为空")
+//    @NotNull(message = "账号数量不能为空")
     private Integer accountCount;
 
     // ========== 仅【创建】时,需要传递的字段 ==========
 
-    @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
-    @Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成")
-    @Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符")
-    private String username;
-
-    @Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
-    @Length(min = 4, max = 16, message = "密码长度为 4-16 位")
-    private String password;
-
-    @AssertTrue(message = "用户账号、密码不能为空")
-    @JsonIgnore
-    public boolean isUsernameValid() {
-        return id != null // 修改时,不需要传递
-                || (ObjectUtil.isAllNotEmpty(username, password)); // 新增时,必须都传递 username、password
-    }
+//    @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
+//    @Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成")
+//    @Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符")
+//    private String username;
+//
+//    @Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
+//    @Length(min = 4, max = 16, message = "密码长度为 4-16 位")
+//    private String password;
+//
+//    @AssertTrue(message = "用户账号、密码不能为空")
+//    @JsonIgnore
+//    public boolean isUsernameValid() {
+//        return id != null // 修改时,不需要传递
+//                || (ObjectUtil.isAllNotEmpty(username, password)); // 新增时,必须都传递 username、password
+//    }
 
 }

+ 36 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/tenant/UserTenantRelatePageReqVO.java

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.system.controller.admin.user.vo.tenant;
+
+import lombok.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 用户租户关系分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class UserTenantRelatePageReqVO extends PageParam {
+
+    @Schema(description = "用户ID", example = "29632")
+    private Long userId;
+
+    @Schema(description = "租户ID", example = "3553")
+    private Long tenantId;
+
+    @Schema(description = "用户在企业中的角色")
+    private String role;
+
+    @Schema(description = "当前生效")
+    private Boolean actived;
+
+    @Schema(description = "状态", example = "2")
+    private Integer status;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

+ 42 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/tenant/UserTenantRelateRespVO.java

@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.module.system.controller.admin.user.vo.tenant;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+import java.time.LocalDateTime;
+import com.alibaba.excel.annotation.*;
+
+@Schema(description = "管理后台 - 用户租户关系 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class UserTenantRelateRespVO {
+
+    @Schema(description = "关系ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "15794")
+    @ExcelProperty("关系ID")
+    private Long id;
+
+    @Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "29632")
+    @ExcelProperty("用户ID")
+    private Long userId;
+
+    @Schema(description = "租户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "3553")
+    @ExcelProperty("租户ID")
+    private Long tenantId;
+
+    @Schema(description = "用户在企业中的角色", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("用户在企业中的角色")
+    private String role;
+
+    @Schema(description = "当前生效", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("当前生效")
+    private Boolean actived;
+
+    @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+    @ExcelProperty("状态")
+    private Integer status;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 37 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/tenant/UserTenantRelateSaveReqVO.java

@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.system.controller.admin.user.vo.tenant;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+
+@Schema(description = "管理后台 - 用户租户关系新增/修改 Request VO")
+@Data
+public class UserTenantRelateSaveReqVO {
+
+    @Schema(description = "关系ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "15794")
+    private Long id;
+
+    @Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "29632")
+    @NotNull(message = "用户ID不能为空")
+    private Long userId;
+
+    @Schema(description = "租户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "3553")
+    @NotNull(message = "租户ID不能为空")
+    private Long tenantId;
+
+    @Schema(description = "用户在企业中的角色", requiredMode = Schema.RequiredMode.REQUIRED)
+//    @NotEmpty(message = "用户在企业中的角色不能为空")
+    private String role;
+
+    @Schema(description = "当前生效", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "当前生效不能为空")
+    private Boolean actived;
+
+    @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
+//    @NotNull(message = "状态不能为空")
+    private Integer status;
+
+}

+ 3 - 3
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/tenant/TenantConvert.java

@@ -17,9 +17,9 @@ public interface TenantConvert {
 
     default UserSaveReqVO convert02(TenantSaveReqVO bean) {
         UserSaveReqVO reqVO = new UserSaveReqVO();
-        reqVO.setUsername(bean.getUsername());
-        reqVO.setPassword(bean.getPassword());
-        reqVO.setNickname(bean.getContactName()).setMobile(bean.getContactMobile());
+//        reqVO.setUsername(bean.getUsername());
+//        reqVO.setPassword(bean.getPassword());
+//        reqVO.setNickname(bean.getContactName()).setMobile(bean.getContactMobile());
         return reqVO;
     }
 

+ 48 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/UserTenantRelateDO.java

@@ -0,0 +1,48 @@
+package cn.iocoder.yudao.module.system.dal.dataobject.user;
+
+import lombok.*;
+import com.baomidou.mybatisplus.annotation.*;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+
+/**
+ * 用户租户关系 DO
+ *
+ * @author 芋道源码
+ */
+@TableName("user_tenant_relate")
+@KeySequence("user_tenant_relate_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class UserTenantRelateDO extends BaseDO {
+
+    /**
+     * 关系ID
+     */
+    @TableId
+    private Long id;
+    /**
+     * 用户ID
+     */
+    private Long userId;
+    /**
+     * 租户ID
+     */
+    private Long tenantId;
+    /**
+     * 用户在企业中的角色
+     */
+    private String role;
+    /**
+     * 当前生效
+     */
+    private Boolean actived;
+    /**
+     * 状态
+     */
+    private Integer status;
+
+}

+ 13 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java

@@ -3,8 +3,12 @@ package cn.iocoder.yudao.module.system.dal.mysql.user;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
 import java.util.Collection;
@@ -47,4 +51,13 @@ public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {
         return selectList(AdminUserDO::getDeptId, deptIds);
     }
 
+    default AdminUserDO selectByIdSkipTenant(Long userId) {
+
+        return selectOne(new QueryWrapper<AdminUserDO>()
+                .eq("id", userId)
+                .eq("deleted", false));
+
+
+    }
+
 }

+ 29 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/UserTenantRelateMapper.java

@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.system.dal.mysql.user;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.tenant.UserTenantRelatePageReqVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.user.UserTenantRelateDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户租户关系 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface UserTenantRelateMapper extends BaseMapperX<UserTenantRelateDO> {
+
+    default PageResult<UserTenantRelateDO> selectPage(UserTenantRelatePageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<UserTenantRelateDO>()
+                .eqIfPresent(UserTenantRelateDO::getUserId, reqVO.getUserId())
+                .eqIfPresent(UserTenantRelateDO::getTenantId, reqVO.getTenantId())
+                .eqIfPresent(UserTenantRelateDO::getRole, reqVO.getRole())
+                .eqIfPresent(UserTenantRelateDO::getActived, reqVO.getActived())
+                .eqIfPresent(UserTenantRelateDO::getStatus, reqVO.getStatus())
+                .betweenIfPresent(UserTenantRelateDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(UserTenantRelateDO::getId));
+    }
+
+}

+ 61 - 10
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java

@@ -9,17 +9,23 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.security.core.LoginUser;
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
 import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
+import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleSaveReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.tenant.UserTenantRelateSaveReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
 import cn.iocoder.yudao.module.system.convert.tenant.TenantConvert;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
 import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper;
 import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum;
 import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
@@ -29,6 +35,7 @@ import cn.iocoder.yudao.module.system.service.permission.RoleService;
 import cn.iocoder.yudao.module.system.service.tenant.handler.TenantInfoHandler;
 import cn.iocoder.yudao.module.system.service.tenant.handler.TenantMenuHandler;
 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
+import cn.iocoder.yudao.module.system.service.user.UserTenantRelateService;
 import com.baomidou.dynamic.datasource.annotation.DSTransactional;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -40,8 +47,10 @@ import javax.annotation.Resource;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 import static java.util.Collections.singleton;
 
@@ -73,6 +82,9 @@ public class TenantServiceImpl implements TenantService {
     private MenuService menuService;
     @Resource
     private PermissionService permissionService;
+    @Resource
+    private UserTenantRelateService userTenantRelateService;
+
 
     @Override
     public List<Long> getTenantIdList() {
@@ -102,19 +114,35 @@ public class TenantServiceImpl implements TenantService {
         // 校验租户域名是否重复
         validTenantWebsiteDuplicate(createReqVO.getWebsite(), null);
         // 校验套餐被禁用
-        TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(createReqVO.getPackageId());
+//        TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(createReqVO.getPackageId());
 
         // 创建租户
         TenantDO tenant = BeanUtils.toBean(createReqVO, TenantDO.class);
         tenantMapper.insert(tenant);
+        // 获得用户信息
+        LoginUser user = SecurityFrameworkUtils.getLoginUser();
+        // 更新用户信息当前租户
+        userService.updateUserTenantId(user.getId(), tenant.getId());
+        // 3创建角色
+
+        // 4给角色授权所有菜单权限
+
+        // 5给角色授权所有数据权限
         // 创建租户的管理员
         TenantUtils.execute(tenant.getId(), () -> {
             // 创建角色
-            Long roleId = createRole(tenantPackage);
-            // 创建用户,并分配角色
-            Long userId = createUser(roleId, createReqVO);
+            Long roleId = createRole(0L);
+
+            // 1.1将这个用户所有租户关系设为不生效
+            userTenantRelateService.deactivateAllForUser(user.getId());
+            // 1.2插入用户租户关系
+            userTenantRelateService.createUserTenantRelate(new UserTenantRelateSaveReqVO().setUserId(user.getId()).setTenantId(tenant.getId()).setActived(true));
+
+
+            // 分配角色
+            permissionService.assignUserRole(user.getId(), singleton(roleId));
             // 修改租户的管理员
-            tenantMapper.updateById(new TenantDO().setId(tenant.getId()).setContactUserId(userId));
+            tenantMapper.updateById(new TenantDO().setId(tenant.getId()).setContactUserId(user.getId()));
         });
         return tenant.getId();
     }
@@ -138,6 +166,24 @@ public class TenantServiceImpl implements TenantService {
         return roleId;
     }
 
+    private Long createRole(Long tenantId) {
+        // 创建角色
+        RoleSaveReqVO reqVO = new RoleSaveReqVO();
+        reqVO.setName(RoleCodeEnum.TENANT_SUPER_ADMIN.getName()).setCode(RoleCodeEnum.TENANT_SUPER_ADMIN.getCode())
+                .setSort(0).setRemark("系统自动生成");
+        Long roleId = roleService.createRole(reqVO, RoleTypeEnum.CUSTOM.getType());
+        // 获取菜单Ids
+        List<MenuDO> menus = menuService.getMenuList(new MenuListReqVO().setTenantId(tenantId).setStatus(CommonStatusEnum.ENABLE.getStatus()));
+        Set<Long> menuIds = menus.stream()
+            .map(MenuDO::getId) // 映射每个MenuDO对象到它的id
+            .collect(Collectors.toSet()); // 收集到一个新的Set中
+        // 分配菜单权限
+        permissionService.assignRoleMenu(roleId, menuIds);
+        // 分配数据权限
+        permissionService.assignRoleDataScope(roleId, 1, null);
+        return roleId;
+    }
+
     @Override
     @DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换
     public void updateTenant(TenantSaveReqVO updateReqVO) {
@@ -148,15 +194,15 @@ public class TenantServiceImpl implements TenantService {
         // 校验租户域名是否重复
         validTenantWebsiteDuplicate(updateReqVO.getWebsite(), updateReqVO.getId());
         // 校验套餐被禁用
-        TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(updateReqVO.getPackageId());
+//        TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(updateReqVO.getPackageId());
 
         // 更新租户
         TenantDO updateObj = BeanUtils.toBean(updateReqVO, TenantDO.class);
         tenantMapper.updateById(updateObj);
         // 如果套餐发生变化,则修改其角色的权限
-        if (ObjectUtil.notEqual(tenant.getPackageId(), updateReqVO.getPackageId())) {
-            updateTenantRoleMenu(tenant.getId(), tenantPackage.getMenuIds());
-        }
+//        if (ObjectUtil.notEqual(tenant.getPackageId(), updateReqVO.getPackageId())) {
+//            updateTenantRoleMenu(tenant.getId(), tenantPackage.getMenuIds());
+//        }
     }
 
     private void validTenantNameDuplicate(String name, Long id) {
@@ -289,7 +335,12 @@ public class TenantServiceImpl implements TenantService {
         if (isSystemTenant(tenant)) { // 系统租户,菜单是全量的
             menuIds = CollectionUtils.convertSet(menuService.getMenuList(), MenuDO::getId);
         } else {
-            menuIds = tenantPackageService.getTenantPackage(tenant.getPackageId()).getMenuIds();
+//            menuIds = tenantPackageService.getTenantPackage(tenant.getPackageId()).getMenuIds();
+            // 获取菜单Ids
+            List<MenuDO> menus = menuService.getMenuList(new MenuListReqVO().setTenantId(0L).setStatus(CommonStatusEnum.ENABLE.getStatus()));
+            menuIds = menus.stream()
+                    .map(MenuDO::getId) // 映射每个MenuDO对象到它的id
+                    .collect(Collectors.toSet()); // 收集到一个新的Set中
         }
         // 执行处理器
         handler.handle(menuIds);

+ 8 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java

@@ -219,4 +219,12 @@ public interface AdminUserService {
      */
     boolean isPasswordMatch(String rawPassword, String encodedPassword);
 
+    /**
+     * 更新用户信息当前租户编码
+     *
+     * @param id     用户编号
+     * @param tenantId 当前租户编码
+     */
+    void updateUserTenantId(Long id, Long tenantId);
+
 }

+ 41 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java

@@ -11,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
 import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
+import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileResetPasswordReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
@@ -22,6 +23,7 @@ import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqV
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.user.UserTenantRelateDO;
 import cn.iocoder.yudao.module.system.dal.mysql.dept.UserPostMapper;
 import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
 import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
@@ -29,6 +31,8 @@ import cn.iocoder.yudao.module.system.service.dept.DeptService;
 import cn.iocoder.yudao.module.system.service.dept.PostService;
 import cn.iocoder.yudao.module.system.service.permission.PermissionService;
 import cn.iocoder.yudao.module.system.service.tenant.TenantService;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.github.yulichang.wrapper.interfaces.SelectWrapper;
 import com.google.common.annotations.VisibleForTesting;
 import com.mzt.logapi.context.LogRecordContext;
 import com.mzt.logapi.service.impl.DiffParseFunction;
@@ -382,13 +386,25 @@ public class AdminUserServiceImpl implements AdminUserService {
         if (id == null) {
             return null;
         }
-        AdminUserDO user = userMapper.selectById(id);
+        AdminUserDO user = userMapper.selectByIdSkipTenant(id);
         if (user == null) {
             throw exception(USER_NOT_EXISTS);
         }
         return user;
     }
 
+//    @VisibleForTesting
+//    AdminUserDO validateUserExists(Long id) {
+//        if (id == null) {
+//            return null;
+//        }
+//        AdminUserDO user = userMapper.validateUserExists(id);
+//        if (user == null) {
+//            throw exception(USER_NOT_EXISTS);
+//        }
+//        return user;
+//    }
+
     @VisibleForTesting
     void validateUsernameUnique(Long id, String username) {
         if (StrUtil.isBlank(username)) {
@@ -517,4 +533,28 @@ public class AdminUserServiceImpl implements AdminUserService {
         return passwordEncoder.encode(password);
     }
 
+    @Override
+    public void updateUserTenantId(Long id, Long tenantId) {
+        // 校验用户存在
+        validateUserExists(id);
+        // 更新状态
+        AdminUserDO updateObj = new AdminUserDO();
+        updateObj.setId(id);
+        updateObj.setTenantId(tenantId);
+        userMapper.updateById(updateObj);
+    }
+
+    /**
+     * 将该用户所有关系设为失效
+     *
+     * @param userId 用户ID
+     * @return 受影响的行数
+     */
+//    @Override
+//    public int deactivateAllForUser(Long userId) {
+//        SelectWrapper<UserTenantRelateDO> updateWrapper = new UpdateWrapper<>();
+//        updateWrapper.eq("user_id", userId).set("actived", false); // 注意:这里使用false而不是b'0',因为MyBatis-Plus会处理类型转换
+//        return userMapper.update(null, updateWrapper); // 第一个参数是null,因为我们不需要传递实体对象,只使用Wrapper来指定更新条件
+//    }
+
 }

+ 64 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/UserTenantRelateService.java

@@ -0,0 +1,64 @@
+package cn.iocoder.yudao.module.system.service.user;
+
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.tenant.UserTenantRelatePageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.tenant.UserTenantRelateSaveReqVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.user.UserTenantRelateDO;
+
+import javax.validation.Valid;
+
+/**
+ * 用户租户关系 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface UserTenantRelateService {
+
+    /**
+     * 创建用户租户关系
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createUserTenantRelate(@Valid UserTenantRelateSaveReqVO createReqVO);
+
+    /**
+     * 更新用户租户关系
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateUserTenantRelate(@Valid UserTenantRelateSaveReqVO updateReqVO);
+
+    /**
+     * 删除用户租户关系
+     *
+     * @param id 编号
+     */
+    void deleteUserTenantRelate(Long id);
+
+    /**
+     * 获得用户租户关系
+     *
+     * @param id 编号
+     * @return 用户租户关系
+     */
+    UserTenantRelateDO getUserTenantRelate(Long id);
+
+    /**
+     * 获得用户租户关系分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 用户租户关系分页
+     */
+    PageResult<UserTenantRelateDO> getUserTenantRelatePage(UserTenantRelatePageReqVO pageReqVO);
+
+    /**
+     * 将该用户所有关系设为失效
+     *
+     * @param userId
+     * @return
+     */
+    int deactivateAllForUser(Long userId);
+
+}

+ 87 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/UserTenantRelateServiceImpl.java

@@ -0,0 +1,87 @@
+package cn.iocoder.yudao.module.system.service.user;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.tenant.UserTenantRelatePageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.tenant.UserTenantRelateSaveReqVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.user.UserTenantRelateDO;
+import cn.iocoder.yudao.module.system.dal.mysql.user.UserTenantRelateMapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+
+
+import javax.annotation.Resource;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_TENANT_RELATE_NOT_EXISTS;
+
+/**
+ * 用户租户关系 Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Validated
+public class UserTenantRelateServiceImpl implements UserTenantRelateService {
+
+    @Resource
+    private UserTenantRelateMapper userTenantRelateMapper;
+
+    @Override
+    public Long createUserTenantRelate(UserTenantRelateSaveReqVO createReqVO) {
+        // 插入
+        UserTenantRelateDO userTenantRelate = BeanUtils.toBean(createReqVO, UserTenantRelateDO.class);
+        userTenantRelateMapper.insert(userTenantRelate);
+        // 返回
+        return userTenantRelate.getId();
+    }
+
+    @Override
+    public void updateUserTenantRelate(UserTenantRelateSaveReqVO updateReqVO) {
+        // 校验存在
+        validateUserTenantRelateExists(updateReqVO.getId());
+        // 更新
+        UserTenantRelateDO updateObj = BeanUtils.toBean(updateReqVO, UserTenantRelateDO.class);
+        userTenantRelateMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteUserTenantRelate(Long id) {
+        // 校验存在
+        validateUserTenantRelateExists(id);
+        // 删除
+        userTenantRelateMapper.deleteById(id);
+    }
+
+    private void validateUserTenantRelateExists(Long id) {
+        if (userTenantRelateMapper.selectById(id) == null) {
+            throw exception(USER_TENANT_RELATE_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public UserTenantRelateDO getUserTenantRelate(Long id) {
+        return userTenantRelateMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<UserTenantRelateDO> getUserTenantRelatePage(UserTenantRelatePageReqVO pageReqVO) {
+        return userTenantRelateMapper.selectPage(pageReqVO);
+    }
+
+    /**
+     * 将该用户所有关系设为失效
+     *
+     * @param userId 用户ID
+     * @return 受影响的行数
+     */
+    @Override
+    public int deactivateAllForUser(Long userId) {
+        UpdateWrapper<UserTenantRelateDO> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.eq("user_id", userId).set("actived", false); // 注意:这里使用false而不是b'0',因为MyBatis-Plus会处理类型转换
+        return userTenantRelateMapper.update(null, updateWrapper); // 第一个参数是null,因为我们不需要传递实体对象,只使用Wrapper来指定更新条件
+    }
+
+}

+ 1 - 0
yudao-server/src/main/resources/application.yaml

@@ -198,6 +198,7 @@ yudao:
       - /admin-api/system/auth/sms-register # 使用验证码注册,和租户无关
       - /admin-api/system/user/profile/reset-password # 使用验证码重置密码,和租户无关
       - /admin-api/system/auth/login # 使用账号登录,和租户无关
+      - /admin-api/system/tenant/create # 创建租户,不携带租户编号
     ignore-tables:
       - system_tenant
       - system_tenant_package