Browse Source

多租户:登录界面,根据 host 域名获取对应的租户编号

YunaiV 1 year ago
parent
commit
feba904fd8

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

@@ -104,6 +104,7 @@ public interface ErrorCodeConstants {
     ErrorCode TENANT_EXPIRE = new ErrorCode(1_002_015_002, "名字为【{}】的租户已过期");
     ErrorCode TENANT_CAN_NOT_UPDATE_SYSTEM = new ErrorCode(1_002_015_003, "系统租户不能进行修改、删除等操作!");
     ErrorCode TENANT_NAME_DUPLICATE = new ErrorCode(1_002_015_004, "名字为【{}】的租户已存在");
+    ErrorCode TENANT_WEBSITE_DUPLICATE = new ErrorCode(1_002_015_005, "域名为【{}】的租户已存在");
 
     // ========== 租户套餐 1-002-016-000 ==========
     ErrorCode TENANT_PACKAGE_NOT_EXISTS = new ErrorCode(1_002_016_000, "租户套餐不存在");

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

@@ -37,8 +37,17 @@ public class TenantController {
     @Operation(summary = "使用租户名,获得租户编号", description = "登录界面,根据用户的租户名,获得租户编号")
     @Parameter(name = "name", description = "租户名", required = true, example = "1024")
     public CommonResult<Long> getTenantIdByName(@RequestParam("name") String name) {
-        TenantDO tenantDO = tenantService.getTenantByName(name);
-        return success(tenantDO != null ? tenantDO.getId() : null);
+        TenantDO tenant = tenantService.getTenantByName(name);
+        return success(tenant != null ? tenant.getId() : null);
+    }
+
+    @GetMapping("/get-by-website")
+    @PermitAll
+    @Operation(summary = "使用域名,获得租户信息", description = "登录界面,根据用户的域名,获得租户信息")
+    @Parameter(name = "website", description = "域名", required = true, example = "www.iocoder.cn")
+    public CommonResult<TenantSimpleRespVO> getTenantByWebsite(@RequestParam("website") String website) {
+        TenantDO tenant = tenantService.getTenantByWebsite(website);
+        return success(TenantConvert.INSTANCE.convert03(tenant));
     }
 
     @PostMapping("/create")
@@ -94,5 +103,4 @@ public class TenantController {
         ExcelUtils.write(response, "租户.xls", "数据", TenantExcelVO.class, datas);
     }
 
-
 }

+ 20 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantSimpleRespVO.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@Schema(description = "管理后台 - 租户精简 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class TenantSimpleRespVO extends TenantBaseVO {
+
+    @Schema(description = "租户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    private Long id;
+
+    @Schema(description = "租户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
+    private String name;
+
+}

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

@@ -1,10 +1,7 @@
 package cn.iocoder.yudao.module.system.convert.tenant;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantCreateReqVO;
-import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantExcelVO;
-import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantRespVO;
-import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantUpdateReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.*;
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserCreateReqVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
 import org.mapstruct.Mapper;
@@ -28,6 +25,8 @@ public interface TenantConvert {
 
     TenantRespVO convert(TenantDO bean);
 
+    TenantSimpleRespVO convert03(TenantDO bean);
+
     List<TenantRespVO> convertList(List<TenantDO> list);
 
     PageResult<TenantRespVO> convertPage(PageResult<TenantDO> page);

+ 4 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/tenant/TenantMapper.java

@@ -42,6 +42,10 @@ public interface TenantMapper extends BaseMapperX<TenantDO> {
         return selectOne(TenantDO::getName, name);
     }
 
+    default TenantDO selectByWebsite(String website) {
+        return selectOne(TenantDO::getWebsite, website);
+    }
+
     default Long selectCountByPackageId(Long packageId) {
         return selectCount(TenantDO::getPackageId, packageId);
     }

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

@@ -78,11 +78,19 @@ public interface TenantService {
     /**
      * 获得名字对应的租户
      *
-     * @param name 户名
+     * @param name 户名
      * @return 租户
      */
     TenantDO getTenantByName(String name);
 
+    /**
+     * 获得域名对应的租户
+     *
+     * @param website 域名
+     * @return 租户
+     */
+    TenantDO getTenantByWebsite(String website);
+
     /**
      * 获得使用指定套餐的租户数量
      *
@@ -128,4 +136,5 @@ public interface TenantService {
      * @param id 租户编号
      */
     void validTenant(Long id);
+
 }

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

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.service.tenant;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
@@ -99,6 +100,8 @@ public class TenantServiceImpl implements TenantService {
     public Long createTenant(TenantCreateReqVO createReqVO) {
         // 校验租户名称是否重复
         validTenantNameDuplicate(createReqVO.getName(), null);
+        // 校验租户域名是否重复
+        validTenantWebsiteDuplicate(createReqVO.getWebsite(), null);
         // 校验套餐被禁用
         TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(createReqVO.getPackageId());
 
@@ -143,6 +146,8 @@ public class TenantServiceImpl implements TenantService {
         TenantDO tenant = validateUpdateTenant(updateReqVO.getId());
         // 校验租户名称是否重复
         validTenantNameDuplicate(updateReqVO.getName(), updateReqVO.getId());
+        // 校验租户域名是否重复
+        validTenantWebsiteDuplicate(updateReqVO.getWebsite(), updateReqVO.getId());
         // 校验套餐被禁用
         TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(updateReqVO.getPackageId());
 
@@ -169,6 +174,23 @@ public class TenantServiceImpl implements TenantService {
         }
     }
 
+    private void validTenantWebsiteDuplicate(String website, Long id) {
+        if (StrUtil.isEmpty(website)) {
+            return;
+        }
+        TenantDO tenant = tenantMapper.selectByWebsite(website);
+        if (tenant == null) {
+            return;
+        }
+        // 如果 id 为空,说明不用比较是否为相同名字的租户
+        if (id == null) {
+            throw exception(TENANT_WEBSITE_DUPLICATE, website);
+        }
+        if (!tenant.getId().equals(id)) {
+            throw exception(TENANT_WEBSITE_DUPLICATE, website);
+        }
+    }
+
     @Override
     @DSTransactional
     public void updateTenantRoleMenu(Long tenantId, Set<Long> menuIds) {
@@ -234,6 +256,11 @@ public class TenantServiceImpl implements TenantService {
         return tenantMapper.selectByName(name);
     }
 
+    @Override
+    public TenantDO getTenantByWebsite(String website) {
+        return tenantMapper.selectByWebsite(website);
+    }
+
     @Override
     public Long getTenantCountByPackageId(Long packageId) {
         return tenantMapper.selectCountByPackageId(packageId);

+ 6 - 6
yudao-server/src/main/resources/application-local.yaml

@@ -49,18 +49,18 @@ spring:
       datasource:
         master:
           name: ruoyi-vue-pro
-          # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
+          url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
           #          url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
           #          url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.master.name} # PostgreSQL 连接的示例
           #          url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
           #          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.master.name} # SQLServer 连接的示例
-          url: jdbc:dm://10.211.55.4:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
-#          username: root
-#          password: 123456
+#          url: jdbc:dm://10.211.55.4:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
+          username: root
+          password: 123456
         #          username: sa
         #          password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
-          username: SYSDBA # DM 连接的示例
-          password: SYSDBA # DM 连接的示例
+#          username: SYSDBA # DM 连接的示例
+#          password: SYSDBA # DM 连接的示例
         slave: # 模拟从库,可根据自己需要修改
           name: ruoyi-vue-pro
           lazy: true # 开启懒加载,保证启动速度

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

@@ -175,6 +175,7 @@ yudao:
     enable: true
     ignore-urls:
       - /admin-api/system/tenant/get-id-by-name # 基于名字获取租户,不许带租户编号
+      - /admin-api/system/tenant/get-by-website # 基于域名获取租户,不许带租户编号
       - /admin-api/system/captcha/get # 获取图片验证码,和租户无关
       - /admin-api/system/captcha/check # 校验图片验证码,和租户无关
       - /admin-api/infra/file/*/get/** # 获取图片,和租户无关