Explorar o código

feat:新增多级租户逻辑,以及对应列表、审批节点后对应操作列、多级租户登录逻辑
前端:多级租户页面,租户登录逻辑重写

韩帛霖 hai 1 ano
pai
achega
8ddbd27530
Modificáronse 26 ficheiros con 1208 adicións e 495 borrados
  1. 4 0
      zkqy-admin/pom.xml
  2. 14 22
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/LoginPageConfigurationController.java
  3. 13 24
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysDictDataController.java
  4. 30 3
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysLoginController.java
  5. 37 22
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysTenantController.java
  6. 91 36
      zkqy-common/src/main/java/com/zkqy/common/core/domain/entity/SysTenant.java
  7. 9 14
      zkqy-framework/src/main/java/com/zkqy/framework/config/SecurityConfig.java
  8. 1 0
      zkqy-framework/src/main/java/com/zkqy/framework/web/service/UserDetailsServiceImpl.java
  9. 4 0
      zkqy-process-execution/src/main/java/com/zkqy/execution/produce/dispersed/runbpm/PreExecutionToolClass.java
  10. 6 1
      zkqy-system/src/main/java/com/zkqy/system/mapper/SysDictDataMapper.java
  11. 34 10
      zkqy-system/src/main/java/com/zkqy/system/mapper/SysTenantMapper.java
  12. 27 16
      zkqy-system/src/main/java/com/zkqy/system/mapper/SysUserMapper.java
  13. 7 1
      zkqy-system/src/main/java/com/zkqy/system/service/ISysDictTypeService.java
  14. 35 12
      zkqy-system/src/main/java/com/zkqy/system/service/ISysTenantService.java
  15. 17 0
      zkqy-system/src/main/java/com/zkqy/system/service/impl/SysDictTypeServiceImpl.java
  16. 124 73
      zkqy-system/src/main/java/com/zkqy/system/service/impl/SysTenantServiceImpl.java
  17. 2 1
      zkqy-system/src/main/java/com/zkqy/system/service/impl/SysUserServiceImpl.java
  18. 223 172
      zkqy-system/src/main/resources/mapper/system/SysDictDataMapper.xml
  19. 81 25
      zkqy-system/src/main/resources/mapper/system/SysTenantMapper.xml
  20. 6 2
      zkqy-system/src/main/resources/mapper/system/SysUserMapper.xml
  21. 14 1
      zkqy-ui/src/api/login.js
  22. 17 0
      zkqy-ui/src/api/system/tenant.js
  23. 1 1
      zkqy-ui/src/permission.js
  24. 30 26
      zkqy-ui/src/router/index.js
  25. 79 33
      zkqy-ui/src/views/login.vue
  26. 302 0
      zkqy-ui/src/views/system/tenant/tenantIndex.vue

+ 4 - 0
zkqy-admin/pom.xml

@@ -79,6 +79,10 @@
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
 
     </dependencies>
 

+ 14 - 22
zkqy-admin/src/main/java/com/zkqy/web/controller/system/LoginPageConfigurationController.java

@@ -27,19 +27,17 @@ import java.util.List;
 @RestController
 @RequestMapping("/system/configuration")
 @Api(value = "/system/configuration", description = "登录页面配置信息-接口")
-public class LoginPageConfigurationController extends BaseController
-{
+public class LoginPageConfigurationController extends BaseController {
     @Autowired
     private ILoginPageConfigurationService loginPageConfigurationService;
 
-/**
- * 查询登录页面配置信息列表
- */
-@PreAuthorize("@ss.hasPermi('system:configuration:list')")
-@GetMapping("/list")
-@ApiOperation(value = "查询登录页面配置信息列表")
-    public TableDataInfo list(LoginPageConfiguration loginPageConfiguration)
-    {
+    /**
+     * 查询登录页面配置信息列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:configuration:list')")
+    @GetMapping("/list")
+    @ApiOperation(value = "查询登录页面配置信息列表")
+    public TableDataInfo list(LoginPageConfiguration loginPageConfiguration) {
         startPage();
         List<LoginPageConfiguration> list = loginPageConfigurationService.selectLoginPageConfigurationList(loginPageConfiguration);
         return getDataTable(list);
@@ -52,8 +50,7 @@ public class LoginPageConfigurationController extends BaseController
     @Log(title = "登录页面配置信息", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
     @ApiOperation(value = "导出登录页面配置信息列表")
-    public void export(HttpServletResponse response, LoginPageConfiguration loginPageConfiguration)
-    {
+    public void export(HttpServletResponse response, LoginPageConfiguration loginPageConfiguration) {
         List<LoginPageConfiguration> list = loginPageConfigurationService.selectLoginPageConfigurationList(loginPageConfiguration);
         ExcelUtil<LoginPageConfiguration> util = new ExcelUtil<LoginPageConfiguration>(LoginPageConfiguration.class);
         util.exportExcel(response, list, "登录页面配置信息数据");
@@ -65,8 +62,7 @@ public class LoginPageConfigurationController extends BaseController
     @PreAuthorize("@ss.hasPermi('system:configuration:query')")
     @GetMapping(value = "/{tenantId}")
     @ApiOperation(value = "获取登录页面配置信息详细信息")
-    public AjaxResult getInfo(@PathVariable("tenantId") Long tenantId)
-    {
+    public AjaxResult getInfo(@PathVariable("tenantId") Long tenantId) {
         return success(loginPageConfigurationService.selectLoginPageConfigurationByTenantId(tenantId));
     }
 
@@ -75,8 +71,7 @@ public class LoginPageConfigurationController extends BaseController
      */
     @Anonymous
     @GetMapping("/queryLoginPageConfigurationInfo/{loginPageNumber}")
-    public AjaxResult queryLoginPageConfigurationInfo(@PathVariable("loginPageNumber") String loginPageNumber){
-        System.err.println(loginPageNumber);
+    public AjaxResult queryLoginPageConfigurationInfo(@PathVariable("loginPageNumber") String loginPageNumber) {
         return success(loginPageConfigurationService.selectLoginPageConfigurationByLoginPageNumber(loginPageNumber));
     }
 
@@ -87,8 +82,7 @@ public class LoginPageConfigurationController extends BaseController
     @Log(title = "登录页面配置信息", businessType = BusinessType.INSERT)
     @PostMapping
     @ApiOperation(value = "新增登录页面配置信息")
-    public AjaxResult add(@RequestBody LoginPageConfiguration loginPageConfiguration)
-    {
+    public AjaxResult add(@RequestBody LoginPageConfiguration loginPageConfiguration) {
         return toAjax(loginPageConfigurationService.insertLoginPageConfiguration(loginPageConfiguration));
     }
 
@@ -99,8 +93,7 @@ public class LoginPageConfigurationController extends BaseController
     @Log(title = "登录页面配置信息", businessType = BusinessType.UPDATE)
     @PutMapping
     @ApiOperation(value = "修改登录页面配置信息")
-    public AjaxResult edit(@RequestBody LoginPageConfiguration loginPageConfiguration)
-    {
+    public AjaxResult edit(@RequestBody LoginPageConfiguration loginPageConfiguration) {
         return toAjax(loginPageConfigurationService.updateLoginPageConfiguration(loginPageConfiguration));
     }
 
@@ -111,8 +104,7 @@ public class LoginPageConfigurationController extends BaseController
     @Log(title = "登录页面配置信息", businessType = BusinessType.DELETE)
     @DeleteMapping("/{ids}")
     @ApiOperation(value = "删除登录页面配置信息")
-    public AjaxResult remove(@PathVariable Long[] ids)
-    {
+    public AjaxResult remove(@PathVariable Long[] ids) {
         return toAjax(loginPageConfigurationService.deleteLoginPageConfigurationByIds(ids));
     }
 }

+ 13 - 24
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysDictDataController.java

@@ -29,23 +29,21 @@ import com.zkqy.system.service.ISysDictTypeService;
 
 /**
  * 数据字典信息
- * 
+ *
  * @author ruoyi
  */
 @RestController
 @RequestMapping("/system/dict/data")
-public class SysDictDataController extends BaseController
-{
+public class SysDictDataController extends BaseController {
     @Autowired
     private ISysDictDataService dictDataService;
 
     @Autowired
     private ISysDictTypeService dictTypeService;
 
-//    @PreAuthorize("@ss.hasPermi('system:dict:list')")
+    //    @PreAuthorize("@ss.hasPermi('system:dict:list')")
     @GetMapping("/list")
-    public TableDataInfo list(SysDictData dictData)
-    {
+    public TableDataInfo list(SysDictData dictData) {
         startPage();
         List<SysDictData> list = dictDataService.selectDictDataList(dictData);
         return getDataTable(list);
@@ -54,8 +52,7 @@ public class SysDictDataController extends BaseController
     @Log(title = "字典数据", businessType = BusinessType.EXPORT)
     @PreAuthorize("@ss.hasPermi('system:dict:export')")
     @PostMapping("/export")
-    public void export(HttpServletResponse response, SysDictData dictData)
-    {
+    public void export(HttpServletResponse response, SysDictData dictData) {
         List<SysDictData> list = dictDataService.selectDictDataList(dictData);
         ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class);
         util.exportExcel(response, list, "字典数据");
@@ -66,8 +63,7 @@ public class SysDictDataController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('system:dict:query')")
     @GetMapping(value = "/{dictCode}")
-    public AjaxResult getInfo(@PathVariable Long dictCode)
-    {
+    public AjaxResult getInfo(@PathVariable Long dictCode) {
         return success(dictDataService.selectDictDataById(dictCode));
     }
 
@@ -78,8 +74,7 @@ public class SysDictDataController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('system:dict:query')")
     @GetMapping(value = "/getDictLabel/{dictLabel}")
-    public AjaxResult getInfoByDictLabel(@PathVariable String dictLabel)
-    {
+    public AjaxResult getInfoByDictLabel(@PathVariable String dictLabel) {
         return success(dictDataService.selectDictDataByDictLabel(dictLabel));
     }
 
@@ -87,13 +82,10 @@ public class SysDictDataController extends BaseController
     /**
      * 根据字典类型查询字典数据信息
      */
-    @Anonymous
     @GetMapping(value = "/type/{dictType}")
-    public AjaxResult dictType(@PathVariable String dictType)
-    {
-        List<SysDictData> data = dictTypeService.selectDictDataByTypeAll(dictType);
-        if (StringUtils.isNull(data))
-        {
+    public AjaxResult dictType(@PathVariable String dictType) {
+        List<SysDictData> data = dictTypeService.selectDictDataByTypeAllTenant(dictType);
+        if (StringUtils.isNull(data)) {
             data = new ArrayList<>();
         }
         return success(data);
@@ -105,8 +97,7 @@ public class SysDictDataController extends BaseController
     @PreAuthorize("@ss.hasPermi('system:dict:add')")
     @Log(title = "字典数据", businessType = BusinessType.INSERT)
     @PostMapping
-    public AjaxResult add(@Validated @RequestBody SysDictData dict)
-    {
+    public AjaxResult add(@Validated @RequestBody SysDictData dict) {
         dict.setCreateBy(getUsername());
         return toAjax(dictDataService.insertDictData(dict));
     }
@@ -117,8 +108,7 @@ public class SysDictDataController extends BaseController
     @PreAuthorize("@ss.hasPermi('system:dict:edit')")
     @Log(title = "字典数据", businessType = BusinessType.UPDATE)
     @PutMapping
-    public AjaxResult edit(@Validated @RequestBody SysDictData dict)
-    {
+    public AjaxResult edit(@Validated @RequestBody SysDictData dict) {
         dict.setUpdateBy(getUsername());
         return toAjax(dictDataService.updateDictData(dict));
     }
@@ -129,8 +119,7 @@ public class SysDictDataController extends BaseController
     @PreAuthorize("@ss.hasPermi('system:dict:remove')")
     @Log(title = "字典类型", businessType = BusinessType.DELETE)
     @DeleteMapping("/{dictCodes}")
-    public AjaxResult remove(@PathVariable Long[] dictCodes)
-    {
+    public AjaxResult remove(@PathVariable Long[] dictCodes) {
         dictDataService.deleteDictDataByIds(dictCodes);
         return success();
     }

+ 30 - 3
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysLoginController.java

@@ -6,7 +6,11 @@ import java.util.Set;
 import com.zkqy.common.core.domain.entity.DataSource;
 import com.zkqy.common.core.domain.entity.SysTenant;
 import com.zkqy.framework.web.service.TokenService;
+import com.zkqy.system.domain.LoginPageConfiguration;
 import com.zkqy.system.service.IDataSourceService;
+import com.zkqy.system.service.ILoginPageConfigurationService;
+import com.zkqy.system.service.ISysTenantService;
+import com.zkqy.system.service.impl.LoginPageConfigurationServiceImpl;
 import com.zkqy.system.service.impl.SysTenantServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -53,6 +57,13 @@ public class SysLoginController {
     @Resource
     private TokenService tokenService;
 
+    @Resource
+    private ISysTenantService iSysTenantService;
+
+
+    @Autowired //登录页面配置信息
+    private ILoginPageConfigurationService loginPageConfigurationService;
+
     //@Resource
     //private IDataSourceService dataSourceService;
 
@@ -96,7 +107,7 @@ public class SysLoginController {
         }
         // 生成令牌
         String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
-                loginBody.getUuid(),true);
+                loginBody.getUuid(), true);
         if (tokenService.getLoginUserIsAdminByToken(token)) {
             return AjaxResult.error("用户不存在!");
         }
@@ -109,6 +120,22 @@ public class SysLoginController {
         return ajax;
     }
 
+    /**
+     * 验证租户i是否存在有效
+     *
+     * @param tenantCode 租户编号
+     * @return
+     */
+    @GetMapping("/isTenantExist")
+    public AjaxResult isTenantExist(String tenantCode) {
+        SysTenant sysTenantInfo = iSysTenantService.selectSysTenantByTenantCode(tenantCode);
+        if (sysTenantInfo != null) {
+            sysTenantInfo.setLoginPageConfiguration(loginPageConfigurationService.selectLoginPageConfigurationByLoginPageNumber(tenantCode));
+            return AjaxResult.success(sysTenantInfo);
+        }
+        return AjaxResult.error("租户不存在");
+    }
+
 
     /**
      * 登录方法
@@ -126,7 +153,7 @@ public class SysLoginController {
         }
         // 生成令牌
         String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
-                loginBody.getUuid(),false);
+                loginBody.getUuid(), false);
         if (tokenService.getLoginUserIsAdminByToken(token)) {
             return AjaxResult.error("用户不存在!");
         }
@@ -159,7 +186,7 @@ public class SysLoginController {
         }
         // 生成令牌
         String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
-                loginBody.getUuid(),true);
+                loginBody.getUuid(), true);
         //检查租户过期时间
         String checkTenantExpirationTimeMsg = loginService.checkTenantExpirationTime(loginBody.getUsername());
         if (!checkTenantExpirationTimeMsg.isEmpty()) {

+ 37 - 22
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysTenantController.java

@@ -25,14 +25,13 @@ import com.zkqy.common.core.page.TableDataInfo;
 
 /**
  * 租户信息Controller
- * 
- * @author ruoyi
+ *
+ * @author zkqy
  * @date 2023-06-03
  */
 @RestController
 @RequestMapping("/system/tenant")
-public class SysTenantController extends BaseController
-{
+public class SysTenantController extends BaseController {
     @Autowired
     private ISysTenantService sysTenantService;
 
@@ -41,21 +40,29 @@ public class SysTenantController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('system:tenant:list')")
     @GetMapping("/list")
-    public TableDataInfo list(SysTenant sysTenant)
-    {
+    public TableDataInfo list(SysTenant sysTenant) {
         startPage();
         List<SysTenant> list = sysTenantService.selectSysTenantList(sysTenant);
         return getDataTable(list);
     }
 
+    /**
+     * 查询所有租户信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:tenant:list')")
+    @GetMapping("/getTenantAllList")
+    public TableDataInfo getTenantAllList(SysTenant sysTenant) {
+        List<SysTenant> list = sysTenantService.selectSysTenantAllList(sysTenant);
+        return getDataTable(list);
+    }
+
     /**
      * 导出租户信息列表
      */
     @PreAuthorize("@ss.hasPermi('system:tenant:export')")
     @Log(title = "租户信息", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
-    public void export(HttpServletResponse response, SysTenant sysTenant)
-    {
+    public void export(HttpServletResponse response, SysTenant sysTenant) {
         List<SysTenant> list = sysTenantService.selectSysTenantList(sysTenant);
         ExcelUtil<SysTenant> util = new ExcelUtil<SysTenant>(SysTenant.class);
         util.exportExcel(response, list, "租户信息数据");
@@ -66,19 +73,29 @@ public class SysTenantController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('system:tenant:query')")
     @GetMapping(value = "/{tenantId}")
-    public AjaxResult getInfo(@PathVariable("tenantId") Long tenantId)
-    {
+    public AjaxResult getInfo(@PathVariable("tenantId") Long tenantId) {
         return success(sysTenantService.selectSysTenantByTenantId(tenantId));
     }
 
+    /**
+     * 获取当前租户下的子租户
+     *
+     * @param tenantId
+     * @return
+     */
+    @PreAuthorize("@ss.hasPermi('system:tenant:query')")
+    @GetMapping(value = "/getTenantChildrenInfo/{tenantId}")
+    public AjaxResult getTenantChildrenInfo(@PathVariable("tenantId") Long tenantId) {
+        return success(sysTenantService.selectSysTenantChildrenInfoByTenantId(tenantId));
+    }
+
     /**
      * 新增租户信息
      */
     @PreAuthorize("@ss.hasPermi('system:tenant:add')")
     @Log(title = "租户信息", businessType = BusinessType.INSERT)
     @PostMapping
-    public AjaxResult add(@RequestBody SysTenant sysTenant)
-    {
+    public AjaxResult add(@RequestBody SysTenant sysTenant) {
         return toAjax(sysTenantService.insertSysTenant(sysTenant));
     }
 
@@ -88,8 +105,7 @@ public class SysTenantController extends BaseController
     @PreAuthorize("@ss.hasPermi('system:tenant:edit')")
     @Log(title = "租户信息", businessType = BusinessType.UPDATE)
     @PutMapping
-    public AjaxResult edit(@RequestBody SysTenant sysTenant)
-    {
+    public AjaxResult edit(@RequestBody SysTenant sysTenant) {
         return toAjax(sysTenantService.updateSysTenant(sysTenant));
     }
 
@@ -98,9 +114,8 @@ public class SysTenantController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('system:tenant:remove')")
     @Log(title = "租户信息", businessType = BusinessType.DELETE)
-	@DeleteMapping("/{tenantIds}")
-    public AjaxResult remove(@PathVariable Long[] tenantIds)
-    {
+    @DeleteMapping("/{tenantIds}")
+    public AjaxResult remove(@PathVariable Long[] tenantIds) {
         return toAjax(sysTenantService.deleteSysTenantByTenantIds(tenantIds));
     }
 
@@ -109,7 +124,7 @@ public class SysTenantController extends BaseController
      */
     @Anonymous
     @GetMapping("/initTenantMenuData/{tenantId}")
-    public AjaxResult initTenantMenuData(@PathVariable Long tenantId){
+    public AjaxResult initTenantMenuData(@PathVariable Long tenantId) {
         return sysTenantService.initTenantMenuData(tenantId);
     }
 
@@ -117,16 +132,16 @@ public class SysTenantController extends BaseController
      * 生成激活码方法
      */
     @GetMapping("/crateTenantCode/{tenantId}/{tenantExpirationTime}")
-    public AjaxResult crateTenantCode(@PathVariable String tenantId,@PathVariable String tenantExpirationTime) throws Exception {
-        return sysTenantService.crateTenantCode(tenantId,tenantExpirationTime);
+    public AjaxResult crateTenantCode(@PathVariable String tenantId, @PathVariable String tenantExpirationTime) throws Exception {
+        return sysTenantService.crateTenantCode(tenantId, tenantExpirationTime);
     }
 
     /**
      * 激活租户
      */
     @GetMapping("/activationOperation/{tenantId}/{activationCode}")
-    public AjaxResult activationOperation(@PathVariable String tenantId,@PathVariable String activationCode) throws Exception {
-        return sysTenantService.activationOperation(tenantId,activationCode);
+    public AjaxResult activationOperation(@PathVariable String tenantId, @PathVariable String activationCode) throws Exception {
+        return sysTenantService.activationOperation(tenantId, activationCode);
     }
 
 }

+ 91 - 36
zkqy-common/src/main/java/com/zkqy/common/core/domain/entity/SysTenant.java

@@ -2,56 +2,131 @@ package com.zkqy.common.core.domain.entity;
 
 import com.zkqy.common.annotation.Excel;
 import com.zkqy.common.core.domain.BaseEntity;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
 
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.Size;
 
 /**
  * 部门表 sys_tenant
- * 
- * @author ruoyi
+ *
+ * @author zkqy
  */
-public class SysTenant extends BaseEntity
-{
+public class SysTenant extends BaseEntity {
     private static final long serialVersionUID = 1L;
 
-    /** 租户ID */
+    /**
+     * 租户ID
+     */
     private Long tenantId;
 
-    /** 租户名称 */
+    /**
+     * 租户名称
+     */
     @Excel(name = "租户名称")
     private String tenantName;
 
-    /** 租户编号(公司统一信用代码) */
+    /**
+     * 租户编号(公司统一信用代码)
+     */
     @Excel(name = "租户编号", readConverterExp = "公司统一信用代码")
     private String tenantCode;
 
-    /** 负责人 */
+    /**
+     * 负责人
+     */
     @Excel(name = "负责人")
     private String owner;
 
-    /** 联系方式 */
+    /**
+     * 联系方式
+     */
     @Excel(name = "联系方式")
     private String contactInfo;
 
-    /** 地址 */
+    /**
+     * 地址
+     */
     @Excel(name = "地址")
     private String address;
 
-    /** 删除标志(0代表存在 1代表删除) */
+    /**
+     * 删除标志(0代表存在 1代表删除)
+     */
     @Excel(name = "是否删除(0:未删除,1已删除)")
     private String isDel;
 
-    /** 数据源id */
+    /**
+     * 数据源id
+     */
     private Long datasourceId;
 
     private DataSource dataSource;
 
-    /** 租户的到期时间 */
+    /**
+     * 租户的到期时间
+     */
     private String tenantExpirationTime;
 
+    /**
+     * 租户父级id
+     */
+    private String tenantParentId;
+    /**
+     * 租户客户端访问地址
+     */
+
+    private String tenantClientLoginUrl;
+    /**
+     * 租户工具端访问地址
+     */
+    private String tenantToolLoginUrl;
+    /**
+     * 租户等级
+     */
+    private String tenantGrade;
+
+    private Object loginPageConfiguration;
+
+    public Object getLoginPageConfiguration() {
+        return loginPageConfiguration;
+    }
+
+    public void setLoginPageConfiguration(Object loginPageConfiguration) {
+        this.loginPageConfiguration = loginPageConfiguration;
+    }
+
+    public String getTenantParentId() {
+        return tenantParentId;
+    }
+
+    public void setTenantParentId(String tenantParentId) {
+        this.tenantParentId = tenantParentId;
+    }
+
+    public String getTenantClientLoginUrl() {
+        return tenantClientLoginUrl;
+    }
+
+    public void setTenantClientLoginUrl(String tenantClientLoginUrl) {
+        this.tenantClientLoginUrl = tenantClientLoginUrl;
+    }
+
+    public String getTenantToolLoginUrl() {
+        return tenantToolLoginUrl;
+    }
+
+    public void setTenantToolLoginUrl(String tenantToolLoginUrl) {
+        this.tenantToolLoginUrl = tenantToolLoginUrl;
+    }
+
+    public String getTenantGrade() {
+        return tenantGrade;
+    }
+
+    public void setTenantGrade(String tenantGrade) {
+        this.tenantGrade = tenantGrade;
+    }
+
     public String getTenantExpirationTime() {
         return tenantExpirationTime;
     }
@@ -73,6 +148,7 @@ public class SysTenant extends BaseEntity
     public String getTenantName() {
         return tenantName;
     }
+
     public void setTenantName(String tenantName) {
         this.tenantName = tenantName;
     }
@@ -135,26 +211,5 @@ public class SysTenant extends BaseEntity
         this.dataSource = dataSource;
     }
 
-    @Override
-    public String toString() {
-        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
-            .append("tenantId", getTenantId())
-            .append("tenantName", getTenantName())
-            .append("tenantCode", getTenantCode())
-            .append("owner", getOwner())
-            .append("contactInfo", getContactInfo())
-            .append("address", getAddress())
-            .append("isDel", getIsDel())
-            .append("createBy", getCreateBy())
-            .append("createTime", getCreateTime())
-            .append("updateBy", getUpdateBy())
-            .append("updateTime", getUpdateTime())
-            .append("datasourceId",getTenantId())
-            .append("dataSource",getDataSource())
-            .toString();
-    }
-
-
-
 
 }

+ 9 - 14
zkqy-framework/src/main/java/com/zkqy/framework/config/SecurityConfig.java

@@ -22,18 +22,17 @@ import com.zkqy.framework.security.handle.LogoutSuccessHandlerImpl;
 
 /**
  * spring security配置
- * 
+ *
  * @author ruoyi
  */
 @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
-public class SecurityConfig extends WebSecurityConfigurerAdapter
-{
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
     /**
      * 自定义用户认证逻辑
      */
     @Autowired
     private UserDetailsService userDetailsService;
-    
+
     /**
      * 认证失败处理类
      */
@@ -51,7 +50,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      */
     @Autowired
     private JwtAuthenticationTokenFilter authenticationTokenFilter;
-    
+
     /**
      * 跨域过滤器
      */
@@ -72,8 +71,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      */
     @Bean
     @Override
-    public AuthenticationManager authenticationManagerBean() throws Exception
-    {
+    public AuthenticationManager authenticationManagerBean() throws Exception {
         return super.authenticationManagerBean();
     }
 
@@ -93,8 +91,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      * authenticated       |   用户登录后可访问
      */
     @Override
-    protected void configure(HttpSecurity httpSecurity) throws Exception
-    {
+    protected void configure(HttpSecurity httpSecurity) throws Exception {
         // 注解标记允许匿名访问的url
         ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();
         permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
@@ -111,7 +108,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 // 过滤请求
                 .authorizeRequests()
                 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
-                .antMatchers("/login", "/register", "/captchaImage","/uniappLogin").permitAll()
+                .antMatchers("/login", "/register", "/captchaImage", "/uniappLogin", "/isTenantExist").permitAll()
                 // 静态资源,可匿名访问
                 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                 .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
@@ -132,8 +129,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      * 强散列哈希加密实现
      */
     @Bean
-    public BCryptPasswordEncoder bCryptPasswordEncoder()
-    {
+    public BCryptPasswordEncoder bCryptPasswordEncoder() {
         return new BCryptPasswordEncoder();
     }
 
@@ -141,8 +137,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      * 身份认证接口
      */
     @Override
-    protected void configure(AuthenticationManagerBuilder auth) throws Exception
-    {
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
         auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
     }
 }

+ 1 - 0
zkqy-framework/src/main/java/com/zkqy/framework/web/service/UserDetailsServiceImpl.java

@@ -58,6 +58,7 @@ public class UserDetailsServiceImpl implements UserDetailsService
         return createLoginUser(user);
     }
 
+
     public UserDetails createLoginUser(SysUser user)
     {
         return new LoginUser(user.getUserId(), user.getDeptId(), user.getTenantId(), user, permissionService.getMenuPermission(user));

+ 4 - 0
zkqy-process-execution/src/main/java/com/zkqy/execution/produce/dispersed/runbpm/PreExecutionToolClass.java

@@ -182,6 +182,9 @@ public class PreExecutionToolClass<R> {
         intoProduction.setTaskProcessKey(runBpmExecuteProcess.getTaskKey());
         // 执行新增方法
         runBpmExecuteProcessMapper.insertBpmExecuteProcess(runBpmExecuteProcess);
+        // 新增计划表中绑定任务key编码
+
+
         /**3️⃣3️⃣3️⃣ 插入所有预执行节点*/
         List<BpmExecuteNode> runBpmExecuteNodeList = new ArrayList<>();
         bpmProcessConfigurationList.forEach(item -> {
@@ -199,6 +202,7 @@ public class PreExecutionToolClass<R> {
             bpmExecuteNode.setTaskNodeState("0");  // 状态默认未执行
             bpmExecuteNode.setTaskPriority("1");   // 任务优先级 设计是从排产操作时选中的任务优先级
             bpmExecuteNode.setTaskNodeExecuteType(item.getNodeExecuteType());  // 当前节点上是手动执行还是自动执行 true || false
+            bpmExecuteNode.setTask3(item.getSpare3());  // 审批节点后操作列
             runBpmExecuteNodeList.add(bpmExecuteNode);
         });
         runBpmExecuteNodeMapper.insertBpmExecuteNodeList(runBpmExecuteNodeList);

+ 6 - 1
zkqy-system/src/main/java/com/zkqy/system/mapper/SysDictDataMapper.java

@@ -48,7 +48,12 @@ public interface SysDictDataMapper
      * @param dictType
      * @return
      */
-    public List<SysDictData> selectDictDataByTypeAll(String dictType);
+    public List<SysDictData> selectDictDataByTypeAll(String dictType);    /**
+     * 菜单用的是所有的字典数据
+     * @param dictType
+     * @return
+     */
+    public List<SysDictData> selectDictDataByTypeAllTenant(String dictType);
 
     /**
      * 根据字典类型和字典键值查询字典数据信息

+ 34 - 10
zkqy-system/src/main/java/com/zkqy/system/mapper/SysTenantMapper.java

@@ -1,27 +1,51 @@
 package com.zkqy.system.mapper;
 
 import java.util.List;
+
 import com.zkqy.common.core.domain.entity.SysTenant;
 
 /**
  * 租户信息Mapper接口
- * 
- * @author ruoyi
+ *
+ * @author zkqy
  * @date 2023-06-03
  */
-public interface SysTenantMapper 
-{
+public interface SysTenantMapper {
     /**
      * 查询租户信息
-     * 
+     *
      * @param tenantId 租户信息主键
      * @return 租户信息
      */
     public SysTenant selectSysTenantByTenantId(Long tenantId);
 
+    /**
+     * 查询租户信息
+     *
+     * @param tenantCode 租户信息编码
+     * @return 租户信息
+     */
+    public SysTenant selectSysTenantByTenantCode(String tenantCode);
+
+    /**
+     * 查询租户信息
+     *
+     * @param tenantId 租户信息主键
+     * @return 租户信息
+     */
+    public List<SysTenant> selectSysTenantChildrenInfoByTenantId(Long tenantId);
+
+    /**
+     * 查询所有租户信息
+     *
+     * @param sysTenant 租户信息
+     * @return 租户信息集合
+     */
+    public List<SysTenant> selectSysTenantAllList(SysTenant sysTenant);
+
     /**
      * 查询租户信息列表
-     * 
+     *
      * @param sysTenant 租户信息
      * @return 租户信息集合
      */
@@ -29,7 +53,7 @@ public interface SysTenantMapper
 
     /**
      * 新增租户信息
-     * 
+     *
      * @param sysTenant 租户信息
      * @return 结果
      */
@@ -37,7 +61,7 @@ public interface SysTenantMapper
 
     /**
      * 修改租户信息
-     * 
+     *
      * @param sysTenant 租户信息
      * @return 结果
      */
@@ -45,7 +69,7 @@ public interface SysTenantMapper
 
     /**
      * 删除租户信息
-     * 
+     *
      * @param tenantId 租户信息主键
      * @return 结果
      */
@@ -53,7 +77,7 @@ public interface SysTenantMapper
 
     /**
      * 批量删除租户信息
-     * 
+     *
      * @param tenantIds 需要删除的数据主键集合
      * @return 结果
      */

+ 27 - 16
zkqy-system/src/main/java/com/zkqy/system/mapper/SysUserMapper.java

@@ -4,18 +4,18 @@ import java.util.List;
 
 import org.apache.ibatis.annotations.Param;
 import com.zkqy.common.core.domain.entity.SysUser;
+import org.springframework.security.core.parameters.P;
 
 /**
  * 用户表 数据层
- * 
+ *
  * @author ruoyi
  */
-public interface SysUserMapper
-{
+public interface SysUserMapper {
 
     /**
      * 根据条件分页查询用户列表
-     * 
+     *
      * @param sysUser 用户信息
      * @return 用户信息集合信息
      */
@@ -23,7 +23,7 @@ public interface SysUserMapper
 
     /**
      * 根据条件分页查询已配用户角色列表
-     * 
+     *
      * @param user 用户信息
      * @return 用户信息集合信息
      */
@@ -31,7 +31,7 @@ public interface SysUserMapper
 
     /**
      * 根据条件分页查询未分配用户角色列表
-     * 
+     *
      * @param user 用户信息
      * @return 用户信息集合信息
      */
@@ -39,15 +39,24 @@ public interface SysUserMapper
 
     /**
      * 通过用户名查询用户
-     * 
+     *
      * @param userName 用户名
      * @return 用户对象信息
      */
     public SysUser selectUserByUserName(String userName);
 
+    /**
+     * 通过租户信息查询用户
+     *
+     * @param tenantId 租户id
+     * @param userName 用户名
+     * @return 用户对象信息
+     */
+    public SysUser selectUserByTenantInfo(@Param("tenantId") String tenantId, @Param("userName") String userName);
+
     /**
      * 通过用户ID查询用户
-     * 
+     *
      * @param userId 用户ID
      * @return 用户对象信息
      */
@@ -55,7 +64,7 @@ public interface SysUserMapper
 
     /**
      * 新增用户信息
-     * 
+     *
      * @param user 用户信息
      * @return 结果
      */
@@ -63,7 +72,7 @@ public interface SysUserMapper
 
     /**
      * 修改用户信息
-     * 
+     *
      * @param user 用户信息
      * @return 结果
      */
@@ -71,16 +80,16 @@ public interface SysUserMapper
 
     /**
      * 修改用户头像
-     * 
+     *
      * @param userName 用户名
-     * @param avatar 头像地址
+     * @param avatar   头像地址
      * @return 结果
      */
     public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar);
 
     /**
      * 重置用户密码
-     * 
+     *
      * @param userName 用户名
      * @param password 密码
      * @return 结果
@@ -89,7 +98,7 @@ public interface SysUserMapper
 
     /**
      * 通过用户ID删除用户
-     * 
+     *
      * @param userId 用户ID
      * @return 结果
      */
@@ -97,7 +106,7 @@ public interface SysUserMapper
 
     /**
      * 批量删除用户信息
-     * 
+     *
      * @param userIds 需要删除的用户ID
      * @return 结果
      */
@@ -105,7 +114,7 @@ public interface SysUserMapper
 
     /**
      * 校验用户名称是否唯一
-     * 
+     *
      * @param userName 用户名称
      * @return 结果
      */
@@ -139,6 +148,7 @@ public interface SysUserMapper
 
     /**
      * 查询这组用户中是否存在真实用户
+     *
      * @param userIds
      * @return
      */
@@ -146,6 +156,7 @@ public interface SysUserMapper
 
     /**
      * 根据账号查询当前库中存在多少相同账号
+     *
      * @param userName 账号
      * @return
      */

+ 7 - 1
zkqy-system/src/main/java/com/zkqy/system/service/ISysDictTypeService.java

@@ -40,7 +40,13 @@ public interface ISysDictTypeService
      * @param dictType 字典类型
      * @return 字典数据集合信息
      */
-    public List<SysDictData> selectDictDataByTypeAll(String dictType);
+    public List<SysDictData> selectDictDataByTypeAll(String dictType);    /**
+     * 根据字典类型查询字典数据
+     *
+     * @param dictType 字典类型
+     * @return 字典数据集合信息
+     */
+    public List<SysDictData> selectDictDataByTypeAllTenant(String dictType);
 
 
     /**

+ 35 - 12
zkqy-system/src/main/java/com/zkqy/system/service/ISysTenantService.java

@@ -7,31 +7,54 @@ import com.zkqy.common.core.domain.entity.SysTenant;
 
 /**
  * 租户信息Service接口
- * 
- * @author ruoyi
+ *
+ * @author zkqy
  * @date 2023-06-03
  */
-public interface ISysTenantService 
-{
+public interface ISysTenantService {
     /**
      * 查询租户信息
-     * 
+     *
      * @param tenantId 租户信息主键
      * @return 租户信息
      */
     public SysTenant selectSysTenantByTenantId(Long tenantId);
 
+    /**
+     * 查询租户信息
+     *
+     * @param tenantCode 租户信息编码
+     * @return 租户信息
+     */
+    public SysTenant selectSysTenantByTenantCode(String tenantCode);
+
+    /**
+     * 查询租户信息
+     *
+     * @param tenantId 租户信息主键
+     * @return 租户信息
+     */
+    public List<SysTenant> selectSysTenantChildrenInfoByTenantId(Long tenantId);
+
     /**
      * 查询租户信息列表
-     * 
+     *
      * @param sysTenant 租户信息
      * @return 租户信息集合
      */
     public List<SysTenant> selectSysTenantList(SysTenant sysTenant);
 
+    /**
+     * 查询所有租户信息
+     *
+     * @param sysTenant 租户信息
+     * @return 租户信息集合
+     */
+    public List<SysTenant> selectSysTenantAllList(SysTenant sysTenant);
+
     /**
      * 新增租户信息
-     * 
+     *
      * @param sysTenant 租户信息
      * @return 结果
      */
@@ -39,7 +62,7 @@ public interface ISysTenantService
 
     /**
      * 修改租户信息
-     * 
+     *
      * @param sysTenant 租户信息
      * @return 结果
      */
@@ -47,7 +70,7 @@ public interface ISysTenantService
 
     /**
      * 批量删除租户信息
-     * 
+     *
      * @param tenantIds 需要删除的租户信息主键集合
      * @return 结果
      */
@@ -55,7 +78,7 @@ public interface ISysTenantService
 
     /**
      * 删除租户信息信息
-     * 
+     *
      * @param tenantId 租户信息主键
      * @return 结果
      */
@@ -70,10 +93,10 @@ public interface ISysTenantService
     /**
      * 创建租户激活码
      */
-    AjaxResult crateTenantCode( String tenantId,String tenantExpirationTime) throws Exception;
+    AjaxResult crateTenantCode(String tenantId, String tenantExpirationTime) throws Exception;
 
     /**
      * 激活租户
      */
-    AjaxResult activationOperation( String tenantId,String activationCode) throws Exception;
+    AjaxResult activationOperation(String tenantId, String activationCode) throws Exception;
 }

+ 17 - 0
zkqy-system/src/main/java/com/zkqy/system/service/impl/SysDictTypeServiceImpl.java

@@ -1,5 +1,6 @@
 package com.zkqy.system.service.impl;
 
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
@@ -103,6 +104,22 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
         return null;
     }
 
+    @Override
+    public List<SysDictData> selectDictDataByTypeAllTenant(String dictType) {
+        List<SysDictData> dictDatas = DictUtils.getDictCache(dictType);
+        if (StringUtils.isNotEmpty(dictDatas))
+        {
+            return dictDatas;
+        }
+        dictDatas = dictDataMapper.selectDictDataByTypeAllTenant(dictType);
+        if (StringUtils.isNotEmpty(dictDatas))
+        {
+            DictUtils.setDictCache(dictType, dictDatas);
+            return dictDatas;
+        }
+        return null;
+    }
+
     /**
      * 根据字典类型ID查询信息
      * 

+ 124 - 73
zkqy-system/src/main/java/com/zkqy/system/service/impl/SysTenantServiceImpl.java

@@ -2,6 +2,7 @@ package com.zkqy.system.service.impl;
 
 import java.io.File;
 import java.io.IOException;
+import java.time.Duration;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
 import java.time.temporal.ChronoUnit;
@@ -13,6 +14,8 @@ import cn.hutool.core.date.LocalDateTimeUtil;
 import cn.hutool.core.util.CharsetUtil;
 import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
 import cn.hutool.crypto.symmetric.SymmetricCrypto;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.zkqy.common.core.domain.AjaxResult;
 import com.zkqy.common.core.domain.entity.SysMenu;
@@ -24,6 +27,7 @@ import com.zkqy.common.utils.ip.IpUtils;
 import com.zkqy.system.domain.SysActivationCodeLog;
 import com.zkqy.system.domain.SysTenantMenu;
 import com.zkqy.system.mapper.*;
+import com.zkqy.system.service.ILoginPageConfigurationService;
 import com.zkqy.system.service.ISysUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.StringRedisTemplate;
@@ -34,22 +38,18 @@ import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 租户信息Service业务层处理
- * 
- * @author ruoyi
+ *
+ * @author zkqy
  * @date 2023-06-03
  */
 @Service
-public class SysTenantServiceImpl implements ISysTenantService 
-{
+public class SysTenantServiceImpl implements ISysTenantService {
     @Autowired
     private SysTenantMapper sysTenantMapper;
 
     @Autowired
     private SysTenantMenuMapper sysTenantMenuMapper;
 
-    @Autowired
-    private  StringRedisTemplate stringRedisTemplate;
-
     @Autowired
     private SysMenuMapper sysMenuMapper;
 
@@ -59,71 +59,115 @@ public class SysTenantServiceImpl implements ISysTenantService
     @Autowired
     private SysUserMapper sysUserMapper;
 
+    @Autowired
+    private StringRedisTemplate stringRedisTemplate;
+
     @Autowired
     private SysActivationCodeLogMapper sysActivationCodeLogMapper;
 
+
     /**
      * 查询租户信息
-     * 
+     *
      * @param tenantId 租户信息主键
      * @return 租户信息
      */
     @Override
-    public SysTenant selectSysTenantByTenantId(Long tenantId)
-    {
+    public SysTenant selectSysTenantByTenantId(Long tenantId) {
         return sysTenantMapper.selectSysTenantByTenantId(tenantId);
     }
 
+    @Override
+    public SysTenant selectSysTenantByTenantCode(String tenantCode) {
+        return sysTenantMapper.selectSysTenantByTenantCode(tenantCode);
+    }
+
+    @Override
+    public List<SysTenant> selectSysTenantChildrenInfoByTenantId(Long tenantId) {
+        return sysTenantMapper.selectSysTenantChildrenInfoByTenantId(tenantId);
+    }
+
     /**
      * 查询租户信息列表
-     * 
+     *
      * @param sysTenant 租户信息
      * @return 租户信息
      */
     @Override
-    public List<SysTenant> selectSysTenantList(SysTenant sysTenant)
-    {
-        return sysTenantMapper.selectSysTenantList(sysTenant);
+    public List<SysTenant> selectSysTenantList(SysTenant sysTenant) {
+        SymmetricCrypto symmetricCrypto = new SymmetricCrypto(SymmetricAlgorithm.DES, "sgEsnN6QWq8W7j5H01020304".getBytes());
+        List<SysTenant> sysTenants = sysTenantMapper.selectSysTenantList(sysTenant);
+        sysTenants.stream().forEach(item -> {
+            if (item.getTenantExpirationTime() != null) {
+                String decryptStr = symmetricCrypto.decryptStr(item.getTenantExpirationTime(), CharsetUtil.CHARSET_UTF_8);
+                LocalDateTime localDateTime = DateUtils.toLocalDateTime(decryptStr.toString(), "yyyy-MM-dd HH:mm:ss");
+                LocalDateTime start = LocalDateTimeUtil.parse(LocalDateTime.now().toString());
+                LocalDateTime end = LocalDateTimeUtil.parse(localDateTime.toString());
+                Duration between = LocalDateTimeUtil.between(start, end);
+                Long l = between.toDays();
+                if (l < 0) {
+                    //String endDay = l.toString().replace("-", "").toString();
+                    //item.setTenantExpirationTime("已到期"+endDay+"天");
+                    item.setTenantExpirationTime("已到期");
+                } else if (l == 0) {
+                    //计算两个日期相差的小时数
+                    Long totalMinutes = LocalDateTimeUtil.between(start, end, ChronoUnit.MINUTES);
+                    //分钟转时间
+                    int totalMinutesInt = Integer.parseInt(totalMinutes.toString());
+                    int hours = (totalMinutesInt / 60);
+                    int remainingMinutes = totalMinutesInt % 60;
+                    item.setTenantExpirationTime(0 + "天" + hours + "小时" + remainingMinutes + "分钟");
+                } else {
+                    item.setTenantExpirationTime(l.toString());
+                }
+            } else {
+                item.setTenantExpirationTime("未激活");
+            }
+        });
+        //return sysTenantMapper.selectSysTenantList(sysTenant);
+        return sysTenants;
+    }
+
+    @Override
+    public List<SysTenant> selectSysTenantAllList(SysTenant sysTenant) {
+        return sysTenantMapper.selectSysTenantAllList(sysTenant);
     }
 
     /**
      * 新增租户信息
-     * 
+     *
      * @param sysTenant 租户信息
      * @return 结果
      */
     @Override
-    public int insertSysTenant(SysTenant sysTenant)
-    {
+    public int insertSysTenant(SysTenant sysTenant) {
         sysTenant.setCreateTime(DateUtils.getNowDate());
         return sysTenantMapper.insertSysTenant(sysTenant);
     }
 
     /**
      * 修改租户信息
-     * 
+     *
      * @param sysTenant 租户信息
      * @return 结果
      */
     @Override
-    public int updateSysTenant(SysTenant sysTenant)
-    {
+    public int updateSysTenant(SysTenant sysTenant) {
         return sysTenantMapper.updateSysTenant(sysTenant);
     }
 
     /**
      * 批量删除租户信息
-     * 
+     *
      * @param tenantIds 需要删除的租户信息主键
      * @return 结果
      */
     @Override
     @Transactional
-    public int deleteSysTenantByTenantIds(Long[] tenantIds)
-    {
+    public int deleteSysTenantByTenantIds(Long[] tenantIds) {
         //查询删除用户信息编号
         Long[] userIds = sysUserMapper.selectUserIdByTenantIds(tenantIds);
-        if(userIds.length > 0) {
+        if (userIds.length > 0) {
             //删除用户
             userService.deleteUserByIds(userIds);
         }
@@ -133,41 +177,21 @@ public class SysTenantServiceImpl implements ISysTenantService
 
     /**
      * 删除租户信息信息
-     * 
+     *
      * @param tenantId 租户信息主键
      * @return 结果
      */
     @Override
-    public int deleteSysTenantByTenantId(Long tenantId)
-    {
+    public int deleteSysTenantByTenantId(Long tenantId) {
         return sysTenantMapper.deleteSysTenantByTenantId(tenantId);
     }
 
     @Override
     @Transactional
     public AjaxResult initTenantMenuData(Long tenantId) {
-        List<SysMenu> list = new ArrayList<>();
-        ObjectMapper objectMapper = new ObjectMapper();
-        try {
-            //获取租户默认菜单信息
-            List<SysMenu> menus = objectMapper.readValue(new File("ruoyi-system/src/main/resources/sql/initialize_sys_tenant_menu.json"), objectMapper.getTypeFactory().constructCollectionType(List.class, SysMenu.class));
-
-            //筛选出根节点
-            list = menus.stream().filter(menu -> 0L == menu.getParentId()).peek(
-                    //设置子节点信息
-                    menu -> menu.setChildren(getChildrenList(menu, menus))
-            ).collect(Collectors.toList());
-
-            //循环遍历数据新增
-            for (int i = 0; i < list.size(); i++){
-                printTree(list.get(i),0L,tenantId);
-            }
-
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return AjaxResult.success(list);
+        return null;
     }
+
     //获取子节点信息
     private List<SysMenu> getChildrenList(SysMenu root, List<SysMenu> menus) {
         List<SysMenu> list = menus.stream().filter(menu ->
@@ -179,8 +203,9 @@ public class SysTenantServiceImpl implements ISysTenantService
         }).collect(Collectors.toList());
         return list;
     }
+
     //新增菜单
-    public void printTree(SysMenu root,Long parentId,Long tenantId) {
+    public void printTree(SysMenu root, Long parentId, Long tenantId) {
         if (root == null) {
             return;
         }
@@ -194,18 +219,19 @@ public class SysTenantServiceImpl implements ISysTenantService
         sysTenantMenu.setMenuId(root.getMenuId());
         sysTenantMenuMapper.insertSysTenantMenu(sysTenantMenu);
         for (SysMenu child : root.getChildren()) {  // 遍历子节点
-            printTree(child,root.getMenuId(),tenantId);  // 递归调用
+            printTree(child, root.getMenuId(), tenantId);  // 递归调用
         }
     }
 
     /**
      * 生成激活码
+     *
      * @param tenantId
      * @param tenantExpirationTime
      * @return
      */
     @Override
-    public AjaxResult crateTenantCode(String tenantId,String tenantExpirationTime) throws Exception {
+    public AjaxResult crateTenantCode(String tenantId, String tenantExpirationTime) throws Exception {
         //加密器
         SymmetricCrypto des = new SymmetricCrypto(SymmetricAlgorithm.DES, "sgEsnN6QWq8W7j5H01020304".getBytes());
         //激活码生成时间
@@ -215,16 +241,19 @@ public class SysTenantServiceImpl implements ISysTenantService
         LocalDateTime offset = LocalDateTimeUtil.offset(now, 1, ChronoUnit.DAYS);
         String offsetStr = DateUtils.toLocalDateTimeStr(offset);
         //激活码生成时间+租户id+激活码有效期+激活多长时间
-        String dataStr=nowStr+"_"+tenantId+"_"+offsetStr+"_"+tenantExpirationTime;
+        String dataStr = nowStr + "_" + tenantId + "_" + offsetStr + "_" + tenantExpirationTime;
         //加密信息
         String encryptHex = des.encryptHex(dataStr);
         //生成激活码操作
         activationCodeLog("生成激活码");
+        //生成了就往
+        stringRedisTemplate.opsForSet().add("activeCode", encryptHex);
         return AjaxResult.success(encryptHex);
     }
 
     /**
      * 激活码激活操作
+     *
      * @param tenantId
      * @param activationCode
      * @return
@@ -232,9 +261,15 @@ public class SysTenantServiceImpl implements ISysTenantService
      */
     @Override
     public AjaxResult activationOperation(String tenantId, String activationCode) throws Exception {
-        String activeCode="active:code:"+activationCode;//魔法值后期抽出来
+        //是否是一个假的
+        Boolean activeCode1 = stringRedisTemplate.opsForSet().isMember("activeCode", activationCode);
+        if (activeCode1 == false) {
+            return AjaxResult.error("请输入系统生成的激活码!!!");
+        }
+        //是否使用过
+        String activeCode = "active:code:" + activationCode;//魔法值后期抽出来
         String strCode = stringRedisTemplate.opsForValue().get(activeCode);
-        if(StringUtils.isNotEmpty(strCode)){
+        if (StringUtils.isNotEmpty(strCode)) {
             return AjaxResult.error("当前激活码已经被使用过了不能重复使用");
         }
         //激活码生成时间+租户id+激活码有效期+激活多长时间
@@ -242,42 +277,42 @@ public class SysTenantServiceImpl implements ISysTenantService
         String decryptStr = symmetricCrypto.decryptStr(activationCode, CharsetUtil.CHARSET_UTF_8);
         String[] contentString = decryptStr.split("_");
         //判断激活码是否失效
-        String expirationDateStr=contentString[2];
-        LocalDateTime expirationDate = DateUtils.toLocalDateTime(expirationDateStr,"yyyy-MM-dd HH:mm:ss");
+        String expirationDateStr = contentString[2];
+        LocalDateTime expirationDate = DateUtils.toLocalDateTime(expirationDateStr, "yyyy-MM-dd HH:mm:ss");
         long expirationDateSecond = expirationDate.toEpochSecond(ZoneOffset.ofHours(8));
         long nowSecond = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8));
-        if(expirationDateSecond-nowSecond<0){
+        if (expirationDateSecond - nowSecond < 0) {
             return AjaxResult.error("此激活码已经过期,不能在继续使用");
         }
-        if(!tenantId.equals(contentString[1])){
+        if (!tenantId.equals(contentString[1])) {
             return AjaxResult.error("当前激活码不能在当前租户使用");
         }
         //先查询、这个用户有没有被激活过
         SysTenant sysTenant = sysTenantMapper.selectSysTenantByTenantId(Long.valueOf(tenantId));
-        SysTenant sysTenantOne=new SysTenant();
+        SysTenant sysTenantOne = new SysTenant();
         sysTenantOne.setTenantId(Long.valueOf(tenantId));
         //判断有没有有被激活过、有时间代表激活过
-        if(StringUtils.isNotEmpty(sysTenant.getTenantExpirationTime())){
+        if (StringUtils.isNotEmpty(sysTenant.getTenantExpirationTime())) {
             //解密
             String LastActiveTime = symmetricCrypto.decryptStr(sysTenant.getTenantExpirationTime(), CharsetUtil.CHARSET_UTF_8);
             LocalDateTime localDateTime = DateUtils.toLocalDateTime(LastActiveTime, "yyyy-MM-dd HH:mm:ss");
             //当前日期时间戳
-            long  nowTimeSecond =LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8));
+            long nowTimeSecond = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8));
             //原来的过期时间
-            long  oldTimeSecond = localDateTime.toEpochSecond(ZoneOffset.ofHours(8));
+            long oldTimeSecond = localDateTime.toEpochSecond(ZoneOffset.ofHours(8));
             //老的过期时间跟当前时间比较 如果小于0证明已经过期好久了
-            if(oldTimeSecond-nowTimeSecond<0){
+            if (oldTimeSecond - nowTimeSecond < 0) {
                 //新续期的时间从当前时间进行续期操作
                 renewalTime(symmetricCrypto, contentString, sysTenantOne);
-            }else {
+            } else {
                 //老的时间快过期了还没过期(旧到期时间+新到期时间(续期操作))
                 LocalDateTime newActiveDateTime = LocalDateTimeUtil.offset(localDateTime, Long.parseLong(contentString[3]), ChronoUnit.DAYS);
                 //加密
-                String newActiveDateTimeStr= symmetricCrypto.encryptHex(DateUtils.toLocalDateTimeStr(newActiveDateTime));
+                String newActiveDateTimeStr = symmetricCrypto.encryptHex(DateUtils.toLocalDateTimeStr(newActiveDateTime));
                 //更新到期时间
                 sysTenantOne.setTenantExpirationTime(newActiveDateTimeStr);
             }
-        }else {
+        } else {
             //新续期的时间从当前时间进行续期操作
             renewalTime(symmetricCrypto, contentString, sysTenantOne);
         }
@@ -286,12 +321,13 @@ public class SysTenantServiceImpl implements ISysTenantService
         //保存验证码操作日志
         activationCodeLog("使用激活码");
         //24小时之后就删除了我们保存的验证码信息
-        stringRedisTemplate.opsForValue().set(activeCode,activationCode,24, TimeUnit.HOURS);
+        stringRedisTemplate.opsForValue().set(activeCode, activationCode, 24, TimeUnit.HOURS);
         return AjaxResult.success();
     }
 
     /**
      * 从当前时间往后续期租户时间
+     *
      * @param symmetricCrypto
      * @param contentString
      * @param sysTenantOne
@@ -302,18 +338,19 @@ public class SysTenantServiceImpl implements ISysTenantService
         //设置到期时间
         LocalDateTime activeDateTime = LocalDateTimeUtil.offset(localDateTime, Long.parseLong(contentString[3]), ChronoUnit.DAYS);
         //加密到期时间
-        String newActiveDateTimeStr= symmetricCrypto.encryptHex(DateUtils.toLocalDateTimeStr(activeDateTime));
+        String newActiveDateTimeStr = symmetricCrypto.encryptHex(DateUtils.toLocalDateTimeStr(activeDateTime));
         sysTenantOne.setTenantExpirationTime(newActiveDateTimeStr);
     }
 
     /**
      * 保存激活码操作日志
+     *
      * @param msg
      */
     private void activationCodeLog(String msg) {
         //保存生成激活码日志
         SysUser user = SecurityUtils.getLoginUser().getUser();
-        SysActivationCodeLog activationCodeLog=new SysActivationCodeLog();
+        SysActivationCodeLog activationCodeLog = new SysActivationCodeLog();
         //生成时间
         activationCodeLog.setGenerationTime(new Date());
         //ip
@@ -330,11 +367,25 @@ public class SysTenantServiceImpl implements ISysTenantService
     public static void main(String[] args) {
         //校验充值天数是否正确
         SymmetricCrypto symmetricCrypto = new SymmetricCrypto(SymmetricAlgorithm.DES, "sgEsnN6QWq8W7j5H01020304".getBytes());
-        String a = symmetricCrypto.decryptStr("facb3dad9a590c24584416fd0e9690e6ad8116cefdd53d5f");
+        String a = symmetricCrypto.decryptStr("2d034a7f7f6cc999b23b15c29e1e278c594a628aed13e40a");
+        System.out.println(a);
+        long between = LocalDateTimeUtil.between(LocalDateTime.now(), DateUtils.toLocalDateTime(a, "yyyy-MM-dd HH:mm:ss"), ChronoUnit.DAYS);
+        System.out.println(between);
+        if (between == 0) {
+            //计算两个日期相差的小时数
+            Long totalMinutes = LocalDateTimeUtil.between(LocalDateTime.now(), DateUtils.toLocalDateTime(a, "yyyy-MM-dd HH:mm:ss"), ChronoUnit.MINUTES);
+            //分钟转时间
+            int totalMinutesInt = Integer.parseInt(totalMinutes.toString());
+            int hours = (totalMinutesInt / 60);
+            int remainingMinutes = totalMinutesInt % 60;
+            System.out.println(hours + "小时" + remainingMinutes + "分钟后就过期了");
+        }
+
         //判断如果用户过期了
-        LocalDateTime activeDateTime = LocalDateTimeUtil.offset(LocalDateTime.now(), -100, ChronoUnit.DAYS);
-        String activeDateTimeStr = DateUtils.toLocalDateTimeStr(activeDateTime);
-        String newActiveDateTimeStr= symmetricCrypto.encryptHex(activeDateTimeStr);
+        //LocalDateTime activeDateTime = LocalDateTimeUtil.offset(LocalDateTime.now(), -100, ChronoUnit.DAYS);
+        //String activeDateTimeStr = DateUtils.toLocalDateTimeStr(activeDateTime);
+        //String newActiveDateTimeStr= symmetricCrypto.encryptHex(activeDateTimeStr);
+        //System.out.println(newActiveDateTimeStr);
     }
 
 }

+ 2 - 1
zkqy-system/src/main/java/com/zkqy/system/service/impl/SysUserServiceImpl.java

@@ -112,7 +112,8 @@ public class SysUserServiceImpl implements ISysUserService {
      */
     @Override
     public SysUser selectUserByUserName(String userName) {
-        return userMapper.selectUserByUserName(userName);
+        String info[] = userName.split("¥¥¥");
+        return userMapper.selectUserByTenantInfo(info[0], info[1]);
     }
 
     /**

+ 223 - 172
zkqy-system/src/main/resources/mapper/system/SysDictDataMapper.xml

@@ -1,178 +1,229 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper
-PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.zkqy.system.mapper.SysDictDataMapper">
-	<resultMap type="com.zkqy.common.core.domain.entity.SysDictData" id="SysDictDataResult">
-		<id     property="dictCode"   column="dict_code"   />
-		<result property="dictSort"   column="dict_sort"   />
-		<result property="dictLabel"  column="dict_label"  />
-		<result property="dictValue"  column="dict_value"  />
-		<result property="dictType"   column="dict_type"   />
-		<result property="cssClass"   column="css_class"   />
-		<result property="listClass"  column="list_class"  />
-		<result property="isDefault"  column="is_default"  />
-		<result property="status"     column="status"      />
-		<result property="createBy"   column="create_by"   />
-		<result property="createTime" column="create_time" />
-		<result property="updateBy"   column="update_by"   />
-		<result property="updateTime" column="update_time" />
-	</resultMap>
-	
-	<sql id="selectDictDataVo">
-        select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark 
-		from   {DBNAME}.sys_dict_data
+    <resultMap type="com.zkqy.common.core.domain.entity.SysDictData" id="SysDictDataResult">
+        <id property="dictCode" column="dict_code"/>
+        <result property="dictSort" column="dict_sort"/>
+        <result property="dictLabel" column="dict_label"/>
+        <result property="dictValue" column="dict_value"/>
+        <result property="dictType" column="dict_type"/>
+        <result property="cssClass" column="css_class"/>
+        <result property="listClass" column="list_class"/>
+        <result property="isDefault" column="is_default"/>
+        <result property="status" column="status"/>
+        <result property="createBy" column="create_by"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="updateTime" column="update_time"/>
+    </resultMap>
+
+    <sql id="selectDictDataVo">
+        select dict_code,
+               dict_sort,
+               dict_label,
+               dict_value,
+               dict_type,
+               css_class,
+               list_class,
+               is_default,
+               status,
+               create_by,
+               create_time,
+               remark
+        from {DBNAME}.sys_dict_data
+    </sql>
+
+    <sql id="selectDictDataVoTwo">
+        select dict_code,
+               dict_sort,
+               dict_label,
+               dict_value,
+               dict_type,
+               css_class,
+               list_class,
+               is_default,
+               status,
+               create_by,
+               create_time,
+               remark
+        from sys_dict_data
+    </sql>
+    <sql id="selectDictDataVoSan">
+        select dict_value
+        from sys_dict_data
+    </sql>
+    <sql id="selectDictDataVoBpm">
+        select dict_code,
+               dict_sort,
+               dict_label,
+               dict_value,
+               dict_type,
+               css_class,
+               list_class,
+               is_default,
+               status,
+               create_by,
+               create_time,
+               remark
+        from {DBNAME}.sys_dict_data
     </sql>
 
-	<sql id="selectDictDataVoTwo">
-		select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark
-		from   sys_dict_data
-	</sql>
-	<sql id="selectDictDataVoSan">
-		select dict_value
-		from  sys_dict_data
-	</sql>
-	<sql id="selectDictDataVoBpm">
-		select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark
-		from {DBNAME}.sys_dict_data
-	</sql>
-
-	<select id="selectDictDataList" parameterType="com.zkqy.common.core.domain.entity.SysDictData" resultMap="SysDictDataResult">
-	    <include refid="selectDictDataVo"/>
-		<where>
-		    <if test="dictType != null and dictType != ''">
-				AND dict_type = #{dictType}
-			</if>
-			<if test="dictLabel != null and dictLabel != ''">
-				AND dict_label like concat('%', #{dictLabel}, '%')
-			</if>
-			<if test="status != null and status != ''">
-				AND status = #{status}
-			</if>
-		</where>
-		order by dict_sort asc
-	</select>
-
-	<select id="selectDictDataListTwo" parameterType="com.zkqy.common.core.domain.entity.SysDictData" resultMap="SysDictDataResult">
-		<include refid="selectDictDataVoTwo"/>
-		<where>
-			<if test="dictType != null and dictType != ''">
-				AND dict_type = #{dictType}
-			</if>
-			<if test="dictLabel != null and dictLabel != ''">
-				AND dict_label like concat('%', #{dictLabel}, '%')
-			</if>
-			<if test="status != null and status != ''">
-				AND status = #{status}
-			</if>
-		</where>
-		order by dict_sort asc
-	</select>
-	<select id="selectDictDataListBpm" parameterType="com.zkqy.common.core.domain.entity.SysDictData" resultMap="SysDictDataResult">
-		<include refid="selectDictDataVoBpm"/>
-		<where>
-			<if test="dictType != null and dictType != ''">
-				AND dict_type = #{dictType}
-			</if>
-			<if test="dictLabel != null and dictLabel != ''">
-				AND dict_label like concat('%', #{dictLabel}, '%')
-			</if>
-			<if test="status != null and status != ''">
-				AND status = #{status}
-			</if>
-		</where>
-		order by dict_sort asc
-	</select>
-
-	<select id="selectDictDataByType" parameterType="com.zkqy.common.core.domain.entity.SysDictData" resultMap="SysDictDataResult">
-		<include refid="selectDictDataVo"/>
-		where status = '0' and dict_type = #{dictType} order by dict_sort asc
-	</select>
-
-	<select id="selectDictDataByTypeAll" parameterType="com.zkqy.common.core.domain.entity.SysDictData" resultMap="SysDictDataResult">
-		<include refid="selectDictDataVoTwo"/>
-		where status = '0' and dict_type = #{dictType} order by dict_sort asc
-	</select>
-	
-	<select id="selectDictLabel" resultType="String">
-		select dict_label from {DBNAME}.sys_dict_data
-		where dict_type = #{dictType} and dict_value = #{dictValue}
-	</select>
-	
-	<select id="selectDictDataById" parameterType="Long" resultMap="SysDictDataResult">
-		<include refid="selectDictDataVo"/>
-		where dict_code = #{dictCode}
-	</select>
-	
-	<select id="countDictDataByType" resultType="Integer">
-	    select count(1) from {DBNAME}.sys_dict_data where dict_type=#{dictType}
-	</select>
-
-	<select id="selectDictDataByDictLabel" parameterType="string" resultType="string">
-		select dict_value
-		from  {DBNAME}.sys_dict_data
-		where dict_label = #{dictLabel}
-	</select>
-
-	<delete id="deleteDictDataById" parameterType="Long">
- 		delete from {DBNAME}.sys_dict_data where dict_code = #{dictCode}
- 	</delete>
- 	
- 	<delete id="deleteDictDataByIds" parameterType="Long">
- 		delete from {DBNAME}.sys_dict_data where dict_code in
- 		<foreach collection="array" item="dictCode" open="(" separator="," close=")">
- 			#{dictCode}
-        </foreach> 
- 	</delete>
-	
-	<update id="updateDictData" parameterType="com.zkqy.common.core.domain.entity.SysDictData">
- 		update {DBNAME}.sys_dict_data
- 		<set>
- 			<if test="dictSort != null">dict_sort = #{dictSort},</if>
- 			<if test="dictLabel != null and dictLabel != ''">dict_label = #{dictLabel},</if>
- 			<if test="dictValue != null and dictValue != ''">dict_value = #{dictValue},</if>
- 			<if test="dictType != null and dictType != ''">dict_type = #{dictType},</if>
- 			<if test="cssClass != null">css_class = #{cssClass},</if>
- 			<if test="listClass != null">list_class = #{listClass},</if>
- 			<if test="isDefault != null and isDefault != ''">is_default = #{isDefault},</if>
- 			<if test="status != null">status = #{status},</if>
- 			<if test="remark != null">remark = #{remark},</if>
- 			<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
- 			update_time = sysdate()
- 		</set>
- 		where dict_code = #{dictCode}
-	</update>
-	
-	<update id="updateDictDataType" parameterType="String">
- 		update {DBNAME}.sys_dict_data set dict_type = #{newDictType} where dict_type = #{oldDictType}
-	</update>
- 	
- 	<insert id="insertDictData" parameterType="com.zkqy.common.core.domain.entity.SysDictData">
- 		insert into {DBNAME}.sys_dict_data(
- 			<if test="dictSort != null">dict_sort,</if>
- 			<if test="dictLabel != null and dictLabel != ''">dict_label,</if>
- 			<if test="dictValue != null and dictValue != ''">dict_value,</if>
- 			<if test="dictType != null and dictType != ''">dict_type,</if>
- 			<if test="cssClass != null and cssClass != ''">css_class,</if>
- 			<if test="listClass != null and listClass != ''">list_class,</if>
- 			<if test="isDefault != null and isDefault != ''">is_default,</if>
- 			<if test="status != null">status,</if>
- 			<if test="remark != null and remark != ''">remark,</if>
- 			<if test="createBy != null and createBy != ''">create_by,</if>
- 			create_time
- 		)values(
- 		    <if test="dictSort != null">#{dictSort},</if>
- 		    <if test="dictLabel != null and dictLabel != ''">#{dictLabel},</if>
- 			<if test="dictValue != null and dictValue != ''">#{dictValue},</if>
- 			<if test="dictType != null and dictType != ''">#{dictType},</if>
- 			<if test="cssClass != null and cssClass != ''">#{cssClass},</if>
- 			<if test="listClass != null and listClass != ''">#{listClass},</if>
- 			<if test="isDefault != null and isDefault != ''">#{isDefault},</if>
- 			<if test="status != null">#{status},</if>
- 			<if test="remark != null and remark != ''">#{remark},</if>
- 			<if test="createBy != null and createBy != ''">#{createBy},</if>
- 			sysdate()
- 		)
-	</insert>
-	
+    <select id="selectDictDataList" parameterType="com.zkqy.common.core.domain.entity.SysDictData"
+            resultMap="SysDictDataResult">
+        <include refid="selectDictDataVo"/>
+        <where>
+            <if test="dictType != null and dictType != ''">
+                AND dict_type = #{dictType}
+            </if>
+            <if test="dictLabel != null and dictLabel != ''">
+                AND dict_label like concat('%', #{dictLabel}, '%')
+            </if>
+            <if test="status != null and status != ''">
+                AND status = #{status}
+            </if>
+        </where>
+        order by dict_sort asc
+    </select>
+
+    <select id="selectDictDataListTwo" parameterType="com.zkqy.common.core.domain.entity.SysDictData"
+            resultMap="SysDictDataResult">
+        <include refid="selectDictDataVoTwo"/>
+        <where>
+            <if test="dictType != null and dictType != ''">
+                AND dict_type = #{dictType}
+            </if>
+            <if test="dictLabel != null and dictLabel != ''">
+                AND dict_label like concat('%', #{dictLabel}, '%')
+            </if>
+            <if test="status != null and status != ''">
+                AND status = #{status}
+            </if>
+        </where>
+        order by dict_sort asc
+    </select>
+    <select id="selectDictDataListBpm" parameterType="com.zkqy.common.core.domain.entity.SysDictData"
+            resultMap="SysDictDataResult">
+        <include refid="selectDictDataVoBpm"/>
+        <where>
+            <if test="dictType != null and dictType != ''">
+                AND dict_type = #{dictType}
+            </if>
+            <if test="dictLabel != null and dictLabel != ''">
+                AND dict_label like concat('%', #{dictLabel}, '%')
+            </if>
+            <if test="status != null and status != ''">
+                AND status = #{status}
+            </if>
+        </where>
+        order by dict_sort asc
+    </select>
+
+    <select id="selectDictDataByType" parameterType="com.zkqy.common.core.domain.entity.SysDictData"
+            resultMap="SysDictDataResult">
+        <include refid="selectDictDataVo"/>
+        where status = '0' and dict_type = #{dictType} order by dict_sort asc
+    </select>
+
+    <select id="selectDictDataByTypeAll" parameterType="com.zkqy.common.core.domain.entity.SysDictData"
+            resultMap="SysDictDataResult">
+        <include refid="selectDictDataVoTwo"/>
+        where status = '0' and dict_type = #{dictType} order by dict_sort asc
+    </select>
+    <select id="selectDictDataByTypeAllTenant" parameterType="com.zkqy.common.core.domain.entity.SysDictData"
+            resultMap="SysDictDataResult">
+        <include refid="selectDictDataVo"/>
+        where status = '0' and dict_type = #{dictType} order by dict_sort asc
+    </select>
+
+    <select id="selectDictLabel" resultType="String">
+        select dict_label
+        from {DBNAME}.sys_dict_data
+        where dict_type = #{dictType}
+          and dict_value = #{dictValue}
+    </select>
+
+    <select id="selectDictDataById" parameterType="Long" resultMap="SysDictDataResult">
+        <include refid="selectDictDataVo"/>
+        where dict_code = #{dictCode}
+    </select>
+
+    <select id="countDictDataByType" resultType="Integer">
+        select count(1)
+        from {DBNAME}.sys_dict_data
+        where dict_type=#{dictType}
+    </select>
+
+    <select id="selectDictDataByDictLabel" parameterType="string" resultType="string">
+        select dict_value
+        from {DBNAME}.sys_dict_data
+        where dict_label = #{dictLabel}
+    </select>
+
+    <delete id="deleteDictDataById" parameterType="Long">
+        delete
+        from {DBNAME}.sys_dict_data
+        where dict_code = #{dictCode}
+    </delete>
+
+    <delete id="deleteDictDataByIds" parameterType="Long">
+        delete from {DBNAME}.sys_dict_data where dict_code in
+        <foreach collection="array" item="dictCode" open="(" separator="," close=")">
+            #{dictCode}
+        </foreach>
+    </delete>
+
+    <update id="updateDictData" parameterType="com.zkqy.common.core.domain.entity.SysDictData">
+        update {DBNAME}.sys_dict_data
+        <set>
+            <if test="dictSort != null">dict_sort = #{dictSort},</if>
+            <if test="dictLabel != null and dictLabel != ''">dict_label = #{dictLabel},</if>
+            <if test="dictValue != null and dictValue != ''">dict_value = #{dictValue},</if>
+            <if test="dictType != null and dictType != ''">dict_type = #{dictType},</if>
+            <if test="cssClass != null">css_class = #{cssClass},</if>
+            <if test="listClass != null">list_class = #{listClass},</if>
+            <if test="isDefault != null and isDefault != ''">is_default = #{isDefault},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
+            update_time = sysdate()
+        </set>
+        where dict_code = #{dictCode}
+    </update>
+
+    <update id="updateDictDataType" parameterType="String">
+        update {DBNAME}.sys_dict_data
+        set dict_type = #{newDictType}
+        where dict_type = #{oldDictType}
+    </update>
+
+    <insert id="insertDictData" parameterType="com.zkqy.common.core.domain.entity.SysDictData">
+        insert into {DBNAME}.sys_dict_data(
+        <if test="dictSort != null">dict_sort,</if>
+        <if test="dictLabel != null and dictLabel != ''">dict_label,</if>
+        <if test="dictValue != null and dictValue != ''">dict_value,</if>
+        <if test="dictType != null and dictType != ''">dict_type,</if>
+        <if test="cssClass != null and cssClass != ''">css_class,</if>
+        <if test="listClass != null and listClass != ''">list_class,</if>
+        <if test="isDefault != null and isDefault != ''">is_default,</if>
+        <if test="status != null">status,</if>
+        <if test="remark != null and remark != ''">remark,</if>
+        <if test="createBy != null and createBy != ''">create_by,</if>
+        create_time
+        )values(
+        <if test="dictSort != null">#{dictSort},</if>
+        <if test="dictLabel != null and dictLabel != ''">#{dictLabel},</if>
+        <if test="dictValue != null and dictValue != ''">#{dictValue},</if>
+        <if test="dictType != null and dictType != ''">#{dictType},</if>
+        <if test="cssClass != null and cssClass != ''">#{cssClass},</if>
+        <if test="listClass != null and listClass != ''">#{listClass},</if>
+        <if test="isDefault != null and isDefault != ''">#{isDefault},</if>
+        <if test="status != null">#{status},</if>
+        <if test="remark != null and remark != ''">#{remark},</if>
+        <if test="createBy != null and createBy != ''">#{createBy},</if>
+        sysdate()
+        )
+    </insert>
+
 </mapper> 

+ 81 - 25
zkqy-system/src/main/resources/mapper/system/SysTenantMapper.xml

@@ -1,43 +1,85 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper
-PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.zkqy.system.mapper.SysTenantMapper">
-    
+
     <resultMap type="SysTenant" id="SysTenantResult">
-        <result property="tenantId"    column="tenant_id"    />
-        <result property="tenantName"    column="tenant_name"    />
-        <result property="tenantCode"    column="tenant_code"    />
-        <result property="owner"    column="owner"    />
-        <result property="contactInfo"    column="contact_info"    />
-        <result property="address"    column="address"    />
-        <result property="createBy"    column="create_by"    />
-        <result property="createTime"    column="create_time"    />
-        <result property="isDel"    column="is_del"    />
+        <result property="tenantId" column="tenant_id"/>
+        <result property="tenantName" column="tenant_name"/>
+        <result property="tenantCode" column="tenant_code"/>
+        <result property="owner" column="owner"/>
+        <result property="contactInfo" column="contact_info"/>
+        <result property="address" column="address"/>
+        <result property="createBy" column="create_by"/>
+        <result property="createTime" column="create_time"/>
+        <result property="isDel" column="is_del"/>
         <result property="datasourceId" column="datasource_id"/>
         <result property="tenantExpirationTime" column="tenant_expiration_time"/>
+        <result property="tenantParentId" column="tenant_parent_id"/>
+        <result property="tenantToolLoginUrl" column="tenant_tool_login_url"/>
+        <result property="tenantClientLoginUrl" column="tenant_client_login_url"/>
+        <result property="tenantGrade" column="tenant_grade"/>
+
     </resultMap>
 
     <sql id="selectSysTenantVo">
-        select tenant_id, tenant_name, tenant_code, owner, contact_info, address, create_by, create_time, is_del,datasource_id,tenant_expiration_time from sys_tenant where is_del = '0'
+        select tenant_id,
+               tenant_name,
+               tenant_code,
+               owner,
+               contact_info,
+               address,
+               create_by,
+               create_time,
+               is_del,
+               datasource_id,
+               tenant_expiration_time,
+               tenant_parent_id,
+               tenant_tool_login_url,
+               tenant_client_login_url,
+               tenant_grade
+        from sys_tenant
+        where is_del = '0'
     </sql>
 
     <select id="selectSysTenantList" parameterType="SysTenant" resultMap="SysTenantResult">
         <include refid="selectSysTenantVo"/>
-            <if test="tenantName != null  and tenantName != ''"> and tenant_name like concat('%', #{tenantName}, '%')</if>
-            <if test="tenantCode != null  and tenantCode != ''"> and tenant_code = #{tenantCode}</if>
-            <if test="owner != null  and owner != ''"> and owner = #{owner}</if>
-            <if test="contactInfo != null  and contactInfo != ''"> and contact_info = #{contactInfo}</if>
-            <if test="address != null  and address != ''"> and address = #{address}</if>
-            <if test="isDel != null  and isDel != ''"> and is_del = #{isDel}</if>
-             order by tenant_id desc
+        and tenant_parent_id = 0
+        <if test="tenantName != null  and tenantName != ''">and tenant_name like concat('%', #{tenantName}, '%')</if>
+        <if test="tenantCode != null  and tenantCode != ''">and tenant_code = #{tenantCode}</if>
+        <if test="owner != null  and owner != ''">and owner = #{owner}</if>
+        <if test="contactInfo != null  and contactInfo != ''">and contact_info = #{contactInfo}</if>
+        <if test="address != null  and address != ''">and address = #{address}</if>
+        <if test="isDel != null  and isDel != ''">and is_del = #{isDel}</if>
+        order by tenant_id desc
+    </select>
+    <select id="selectSysTenantAllList" parameterType="SysTenant" resultMap="SysTenantResult">
+        <include refid="selectSysTenantVo"/>
+        <if test="tenantParentId != null  and tenantParentId != ''">and tenant_parent_id = #{tenantParentId}</if>
+        <if test="tenantName != null  and tenantName != ''">and tenant_name like concat('%', #{tenantName}, '%')</if>
+        <if test="tenantCode != null  and tenantCode != ''">and tenant_code = #{tenantCode}</if>
+        <if test="owner != null  and owner != ''">and owner = #{owner}</if>
+        <if test="contactInfo != null  and contactInfo != ''">and contact_info = #{contactInfo}</if>
+        <if test="address != null  and address != ''">and address = #{address}</if>
+        <if test="isDel != null  and isDel != ''">and is_del = #{isDel}</if>
+        order by tenant_id desc
     </select>
-    
+
     <select id="selectSysTenantByTenantId" parameterType="Long" resultMap="SysTenantResult">
         <include refid="selectSysTenantVo"/>
         and tenant_id = #{tenantId}
     </select>
-        
+    <select id="selectSysTenantByTenantCode" parameterType="string" resultMap="SysTenantResult">
+        <include refid="selectSysTenantVo"/>
+        and tenant_code = #{tenantCode}
+    </select>
+
+    <select id="selectSysTenantChildrenInfoByTenantId" parameterType="Long" resultMap="SysTenantResult">
+        <include refid="selectSysTenantVo"/>
+        and tenant_parent_id = #{tenantId}
+    </select>
+
     <insert id="insertSysTenant" parameterType="SysTenant" useGeneratedKeys="true" keyProperty="tenantId">
         insert into sys_tenant
         <trim prefix="(" suffix=")" suffixOverrides=",">
@@ -49,8 +91,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createBy != null and createBy != ''">create_by,</if>
             <if test="createTime != null">create_time,</if>
             <if test="datasourceId != null">datasource_id,</if>
+            <if test="tenantParentId != null">tenant_parent_id,</if>
+            <if test="tenantClientLoginUrl !=null">tenant_client_login_url</if>
+            <if test="tenantToolLoginUrl !=null">tenant_tool_login_url</if>
+            <if test="tenantGrade != null">tenant_grade,</if>
             is_del
-         </trim>
+        </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="tenantName != null and tenantName != ''">#{tenantName},</if>
             <if test="tenantCode != null and tenantCode != ''">#{tenantCode},</if>
@@ -60,8 +106,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createBy != null and createBy != ''">#{createBy},</if>
             <if test="createTime != null">#{createTime},</if>
             <if test="datasourceId != null">#{datasourceId},</if>
+            <if test="tenantParentId != null">#{tenantParentId},</if>
+            <if test="tenantClientLoginUrl !=null">tenant_client_login_url = #{tenantClientLoginUrl},</if>
+            <if test="tenantToolLoginUrl !=null">tenant_tool_login_url = #{tenantToolLoginUrl},</if>
+            <if test="tenantGrade != null">tenant_grade = #{tenantGrade},</if>
             '0'
-         </trim>
+        </trim>
     </insert>
 
     <update id="updateSysTenant" parameterType="SysTenant">
@@ -76,12 +126,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createTime != null">create_time = #{createTime},</if>
             <if test="datasourceId != null">datasource_id = #{datasourceId},</if>
             <if test="tenantExpirationTime != null">tenant_expiration_time = #{tenantExpirationTime},</if>
+            <if test="tenantParentId != null">tenant_parent_id = #{tenantParentId},</if>
+            <if test="tenantToolLoginUrl !=null">tenant_tool_login_url = #{tenantToolLoginUrl},</if>
+            <if test="tenantClientLoginUrl !=null">tenant_client_login_url = #{tenantClientLoginUrl},</if>
+            <if test="tenantGrade != null">tenant_grade = #{tenantGrade},</if>
         </trim>
         where tenant_id = #{tenantId}
     </update>
 
     <update id="deleteSysTenantByTenantId" parameterType="Long">
-        update sys_tenant set is_del = '2' where tenant_id = #{tenantId}
+        update sys_tenant
+        set is_del = '2'
+        where tenant_id = #{tenantId}
     </update>
 
     <update id="deleteSysTenantByTenantIds" parameterType="String">

+ 6 - 2
zkqy-system/src/main/resources/mapper/system/SysUserMapper.xml

@@ -203,10 +203,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 	</select>
 	
 	<select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">
-	    <include refid="selectUserVo"/>
+		<include refid="selectUserVo"/>
 		where u.user_name = #{userName} and u.del_flag = '0'
 	</select>
-	
+	<select id="selectUserByTenantInfo" parameterType="String" resultMap="SysUserResult">
+		<include refid="selectUserVo"/>
+		where u.tenant_id = #{tenantId} and u.user_name = #{userName} and u.del_flag = '0'
+	</select>
+
 	<select id="selectUserById" parameterType="Long" resultMap="SysUserResult">
 		<include refid="selectUserVo"/>
 		where u.user_id = #{userId}

+ 14 - 1
zkqy-ui/src/api/login.js

@@ -18,6 +18,18 @@ export function login(username, password, code, uuid) {
   })
 }
 
+// 验证租户是否存在
+export function isTenantExist(tenantCode) {
+  return request({
+    url: '/isTenantExist',
+    headers: {
+      isToken: false
+    },
+    method: 'get',
+    params: tenantCode
+  })
+}
+
 // 注册方法
 export function register(data) {
   return request({
@@ -56,4 +68,5 @@ export function getCodeImg() {
     method: 'get',
     timeout: 20000
   })
-}
+}
+

+ 17 - 0
zkqy-ui/src/api/system/tenant.js

@@ -8,6 +8,14 @@ export function listTenant(query) {
     params: query
   })
 }
+// 查询所有租户信息列表
+export function getTenantAllList(query) {
+  return request({
+    url: '/system/tenant/getTenantAllList',
+    method: 'get',
+    params: query
+  })
+}
 
 // 查询租户信息详细
 export function getTenant(tenantId) {
@@ -17,6 +25,14 @@ export function getTenant(tenantId) {
   })
 }
 
+// 查询当前租户下所有子租户信息
+export function getTenantChildrenInfo(tenantId) {
+  return request({
+    url: '/system/tenant/getTenantChildrenInfo/' + tenantId,
+    method: 'get'
+  })
+}
+
 // 新增租户信息
 export function addTenant(data) {
   return request({
@@ -84,6 +100,7 @@ export function createTenantCode(data) {
     method: 'get',
   })
 }
+
 // 激活码激活租户
 export function activationOperation(data) {
   return request({

+ 1 - 1
zkqy-ui/src/permission.js

@@ -8,7 +8,7 @@ import { isRelogin } from '@/utils/request'
 
 NProgress.configure({ showSpinner: false })
 
-const whiteList = ['/login', '/register']
+const whiteList = ['/login', '/register','/404']
 
 router.beforeEach((to, from, next) => {
   NProgress.start()

+ 30 - 26
zkqy-ui/src/router/index.js

@@ -20,12 +20,12 @@ import Layout from '@/layout'
  * roles: ['admin', 'common']       // 访问路由的角色权限
  * permissions: ['a:a:a', 'b:b:b']  // 访问路由的菜单权限
  * meta : {
-    noCache: true                   // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
-    title: 'title'                  // 设置该路由在侧边栏和面包屑中展示的名字
-    icon: 'svg-name'                // 设置该路由的图标,对应路径src/assets/icons/svg
-    breadcrumb: false               // 如果设置为false,则不会在breadcrumb面包屑中显示
-    activeMenu: '/system/user'      // 当路由设置了该属性,则会高亮相对应的侧边栏。
-  }
+ noCache: true                   // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
+ title: 'title'                  // 设置该路由在侧边栏和面包屑中展示的名字
+ icon: 'svg-name'                // 设置该路由的图标,对应路径src/assets/icons/svg
+ breadcrumb: false               // 如果设置为false,则不会在breadcrumb面包屑中显示
+ activeMenu: '/system/user'      // 当路由设置了该属性,则会高亮相对应的侧边栏。
+ }
  */
 
 // 公共路由
@@ -33,7 +33,7 @@ export const constantRoutes = [
   // {
   //   path: '/data',
   //   component: data,
-  //   hidden: true, 
+  //   hidden: true,
   //   children: [
   //     {
   //       path: 'data',
@@ -134,14 +134,18 @@ export const constantRoutes = [
   {
     path: '/login',
     component: () => {
-      var url = new URL(window.location.href);
-      var params = new URLSearchParams(url.search);
-      let temp = params.get('tenantId')
-      if (temp) {
-        return import('@/views/login')
-      } else {
-        return import('@/views/error/404')
-      }
+      return import('@/views/login')
+
+
+      // var url = new URL(window.location.href);
+      // var params = new URLSearchParams(url.search);
+      // let temp = params.get('tenantId')
+      // if (temp) {
+      //   return import('@/views/login')
+      // } else {
+      //   // return import('@/views/error/404')
+      //   return import('@/views/login')
+      // }
 
     },
     hidden: true
@@ -170,7 +174,7 @@ export const constantRoutes = [
         path: 'index',
         component: () => import('@/views/index'),
         name: 'Index',
-        meta: { title: '首页', icon: 'dashboard', affix: true }
+        meta: {title: '首页', icon: 'dashboard', affix: true}
       }
     ]
   },
@@ -184,7 +188,7 @@ export const constantRoutes = [
         path: 'profile',
         component: () => import('@/views/system/user/profile/index'),
         name: 'Profile',
-        meta: { title: '个人中心', icon: 'user' }
+        meta: {title: '个人中心', icon: 'user'}
       }
     ]
   },
@@ -203,7 +207,7 @@ export const dynamicRoutes = [
         path: 'role/:userId(\\d+)',
         component: () => import('@/views/system/data/index'),
         name: 'AuthRole',
-        meta: { title: '数据源配置', activeMenu: '/system/data' }
+        meta: {title: '数据源配置', activeMenu: '/system/data'}
       }
     ]
   },
@@ -217,7 +221,7 @@ export const dynamicRoutes = [
         path: 'role/:userId(\\d+)',
         component: () => import('@/views/system/user/authRole'),
         name: 'AuthRole',
-        meta: { title: '分配角色', activeMenu: '/system/user' }
+        meta: {title: '分配角色', activeMenu: '/system/user'}
       }
     ]
   },
@@ -231,7 +235,7 @@ export const dynamicRoutes = [
         path: 'fromModel/:index',
         component: () => import('@/views/system/fromModel/index'),
         name: 'fromModel',
-        meta: { title: '表单建模', activeMenu: '/system/fromModel/index' }
+        meta: {title: '表单建模', activeMenu: '/system/fromModel/index'}
       },
       // {
       //   path: '/fromModel/:index',
@@ -252,7 +256,7 @@ export const dynamicRoutes = [
         path: 'user/:roleId(\\d+)',
         component: () => import('@/views/system/role/authUser'),
         name: 'AuthUser',
-        meta: { title: '分配用户', activeMenu: '/system/role' }
+        meta: {title: '分配用户', activeMenu: '/system/role'}
       }
     ]
   },
@@ -266,7 +270,7 @@ export const dynamicRoutes = [
         path: 'index/:dictId(\\d+)',
         component: () => import('@/views/system/dict/data'),
         name: 'Data',
-        meta: { title: '字典数据', activeMenu: '/system/dict' }
+        meta: {title: '字典数据', activeMenu: '/system/dict'}
       }
     ]
   },
@@ -281,7 +285,7 @@ export const dynamicRoutes = [
         path: 'index/:dictId(\\d+)',
         component: () => import('@/views/system/tenant/dict/data'),
         name: 'TenantData',
-        meta: { title: '字典数据', activeMenu: '/system/tenant/dict' }
+        meta: {title: '字典数据', activeMenu: '/system/tenant/dict'}
       }
     ]
   },
@@ -296,7 +300,7 @@ export const dynamicRoutes = [
         path: 'index/:jobId(\\d+)',
         component: () => import('@/views/monitor/job/log'),
         name: 'JobLog',
-        meta: { title: '调度日志', activeMenu: '/monitor/job' }
+        meta: {title: '调度日志', activeMenu: '/monitor/job'}
       }
     ]
   },
@@ -310,7 +314,7 @@ export const dynamicRoutes = [
         path: 'index/:tableId(\\d+)',
         component: () => import('@/views/tool/gen/editTable'),
         name: 'GenEdit',
-        meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
+        meta: {title: '修改生成配置', activeMenu: '/tool/gen'}
       }
     ]
   }
@@ -331,6 +335,6 @@ Router.prototype.replace = function push(location) {
 
 export default new Router({
   mode: 'history', // 去掉url中的#
-  scrollBehavior: () => ({ y: 0 }),
+  scrollBehavior: () => ({y: 0}),
   routes: constantRoutes
 })

+ 79 - 33
zkqy-ui/src/views/login.vue

@@ -16,7 +16,8 @@
           <div class="grid-content bg-purple-dark title">
             工业应用操作系统
             <!-- 智能制造平台 -->
-          </div></el-col
+          </div>
+        </el-col
         >
       </el-row>
       <el-row class="rowww">
@@ -59,7 +60,7 @@
           </el-col>
           <el-col :span="4" :offset="1">
             <div class="login-code">
-              <img :src="codeUrl" @click="getCode" class="login-code-img" />
+              <img :src="codeUrl" @click="getCode" class="login-code-img"/>
             </div>
           </el-col>
         </el-row>
@@ -70,7 +71,8 @@
           <img :src="codeUrl" @click="getCode" class="login-code-img" />
         </div> -->
         <el-checkbox v-model="loginForm.rememberMe" class="aaa"
-          >在这个设备上记住我</el-checkbox
+        >在这个设备上记住我
+        </el-checkbox
         >
       </el-row>
 
@@ -79,7 +81,8 @@
           class="logg"
           :loading="loading"
           @click.native.prevent="handleLogin"
-          >登录</el-col
+        >登录
+        </el-col
         >
       </el-row>
     </el-form>
@@ -101,7 +104,7 @@
           placeholder="账号"
           show-password
         >
-          
+
         </el-input>
       </el-form-item>
       <el-form-item prop="password">
@@ -114,7 +117,7 @@
           @keyup.enter.native="handleLogin"
           show-password
         >
-         
+
         </el-input>
       </el-form-item>
 
@@ -156,7 +159,7 @@
         </div>
       </el-form-item>
     </el-form>
-  
+
     <div class="el-login-footer">
       <span>Copyright © 2018-2023 zkqy.vip All Rights Reserved.</span>
     </div> -->
@@ -164,11 +167,11 @@
 </template>
 
 <script>
-import { getCodeImg } from "@/api/login";
-import { changeDatasource } from "@/api/dataEngine";
+import {getCodeImg, isTenantExist} from "@/api/login";
+import {changeDatasource} from "@/api/dataEngine";
 import Cookies from "js-cookie";
-import { encrypt, decrypt } from "@/utils/jsencrypt";
-import { getLoginPageConfigurationInfo } from "@/api/system/configuration";
+import {encrypt, decrypt} from "@/utils/jsencrypt";
+import {getLoginPageConfigurationInfo} from "@/api/system/configuration";
 
 export default {
   name: "Login",
@@ -177,7 +180,9 @@ export default {
       // 页面配置信息
       config: {},
       codeUrl: "",
+      tenantId: "",
       loginForm: {
+        tenantCode: "", //租户编号
         username: "",
         password: "",
         // username: "admin",
@@ -188,12 +193,12 @@ export default {
       },
       loginRules: {
         username: [
-          { required: true, trigger: "blur", message: "请输入您的账号" },
+          {required: true, trigger: "blur", message: "请输入您的账号"},
         ],
         password: [
-          { required: true, trigger: "blur", message: "请输入您的密码" },
+          {required: true, trigger: "blur", message: "请输入您的密码"},
         ],
-        code: [{ required: true, trigger: "blur", message: "请输入验证码" }],
+        code: [{required: true, trigger: "blur", message: "请输入验证码"}],
       },
       loading: true,
       // 验证码开关
@@ -214,11 +219,37 @@ export default {
     },
   },
   created() {
-    this.getCode();
-    this.getCookie();
-    this.getConfig();
+    this.validateTenantId()
   },
   methods: {
+    // 校验url
+    validateTenantId() {
+      let tenantCode = this.$route.query['tenantCode']
+      console.log(tenantCode)
+      if (tenantCode != null) {
+        // 得到tenantId 查询裤中是否存在该租户
+        isTenantExist({tenantCode: tenantCode}).then(res => {
+          if (res.data?.tenantId) { // 判断当前编号是否存在库中
+            this.tenantId = res.data.tenantId
+            // 得到租户的信息
+            this.config = res.data.loginPageConfiguration
+            // 如果当前租户没有配置登录页面则不可访问
+            if (this.config == null && this.config == undefined) {
+              // this.$router.push({path: "/404"})
+            } else {
+              this.getCode();
+              this.getCookie();
+            }
+          } else {
+            // 当前访问链接中的租户编号不存在
+            this.$router.push({path: "/404"})
+          }
+        })
+      } else {
+        console.log('跳转')
+        this.$router.push({path: "/404"})
+      }
+    },
     setConfig() {
       let {
         loginPageTitle,
@@ -301,7 +332,8 @@ export default {
         this.$message.error("获取页面信息失败,请检查tenantId");
       }
     },
-    forgetEvent() {},
+    forgetEvent() {
+    },
     getCode() {
       getCodeImg().then((res) => {
         this.captchaEnabled =
@@ -328,7 +360,7 @@ export default {
         if (valid) {
           this.loading = true;
           if (this.loginForm.rememberMe) {
-            Cookies.set("username", this.loginForm.username, { expires: 30 });
+            Cookies.set("username", this.loginForm.username, {expires: 30});
             Cookies.set("password", encrypt(this.loginForm.password), {
               expires: 30,
             });
@@ -340,18 +372,18 @@ export default {
             Cookies.remove("password");
             Cookies.remove("rememberMe");
           }
-          this.$store
-            .dispatch("Login", this.loginForm)
-            .then(() => {
-              changeDatasource(); //切换数据源
-              this.$router.push({ path: this.redirect || "/" }).catch(() => {});
-            })
-            .catch(() => {
-              this.loading = false;
-              if (this.captchaEnabled) {
-                this.getCode();
-              }
+          console.log(this.loginForm)
+          this.loginForm.username = this.tenantId + '¥¥¥' + this.loginForm.username;
+          this.$store.dispatch("Login", this.loginForm).then(() => {
+            changeDatasource(); //切换数据源
+            this.$router.push({path: this.redirect || "/"}).catch(() => {
             });
+          }).catch(() => {
+            this.loading = false;
+            if (this.captchaEnabled) {
+              this.getCode();
+            }
+          });
         }
       });
     },
@@ -364,8 +396,10 @@ export default {
   height: 54px;
   line-height: 54px;
 }
+
 .login {
   position: relative;
+
   .page-description {
     position: absolute;
     left: 10%;
@@ -373,6 +407,7 @@ export default {
     transform: translateY(-100%);
     display: flex;
     flex-direction: column;
+
     .description {
       display: block;
       font-size: 38px;
@@ -387,6 +422,7 @@ export default {
       -webkit-line-clamp: 2;
       text-overflow: ellipsis;
     }
+
     .sub-description {
       font-size: 20px;
       color: #fff;
@@ -394,6 +430,7 @@ export default {
     }
   }
 }
+
 .logg {
   margin-top: 42px;
   margin-left: 196px;
@@ -404,9 +441,9 @@ export default {
   opacity: 1;
   border-radius: 27px;
   background: linear-gradient(
-    135deg,
-    rgba(79, 138, 255, 1) 0%,
-    rgba(75, 94, 255, 1) 100%
+      135deg,
+      rgba(79, 138, 255, 1) 0%,
+      rgba(75, 94, 255, 1) 100%
   );
   box-shadow: 0px 4px 16px rgba(179, 192, 231, 1);
   color: #fff;
@@ -414,6 +451,7 @@ export default {
   font-weight: 500;
   cursor: pointer;
 }
+
 .aaa {
   width: 248px;
   height: 24px;
@@ -426,22 +464,26 @@ export default {
   vertical-align: top;
   margin-top: 16px;
 }
+
 .bottomtext {
   margin-top: -5px !important;
   margin-left: 58px !important;
 }
+
 .rowww {
   width: 522px;
   height: 80px;
   margin-top: 25px;
   margin-left: 55px;
 }
+
 .roww {
   width: 522px;
   height: 80px;
   margin-top: 16px;
   margin-left: 55px;
 }
+
 .ppp {
   width: 522px;
   height: 24px;
@@ -455,6 +497,7 @@ export default {
   text-align: left;
   vertical-align: top;
 }
+
 .el-input__inner {
   width: 522px;
   /* height: 54px  !important; */
@@ -467,6 +510,7 @@ export default {
   border: 1px solid rgba(218, 224, 242, 1);
   margin-top: 2px;
 }
+
 .inputt input {
   width: 100%;
 }
@@ -482,6 +526,7 @@ export default {
   opacity: 1;
   background-size: cover;
 }
+
 .login {
   display: flex;
   justify-content: center;
@@ -526,6 +571,7 @@ export default {
   height: 54px;
   opacity: 1;
 }
+
 .el-col-18 {
   width: 66%;
 }

+ 302 - 0
zkqy-ui/src/views/system/tenant/tenantIndex.vue

@@ -0,0 +1,302 @@
+<template>
+  <div class="app-container">
+    <el-form
+      :model="queryParams"
+      ref="queryForm"
+      size="small"
+      :inline="true"
+      v-show="showSearch"
+      label-width="68px"
+    >
+      <el-form-item label="租户名称" prop="tenantName">
+        <el-input
+          v-model="queryParams.tenantName"
+          placeholder="请输入租户名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="租户编号" prop="tenantCode">
+        <el-input
+          v-model="queryParams.tenantCode"
+          placeholder="请输入租户编号"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="负责人" prop="owner">
+        <el-input
+          v-model="queryParams.owner"
+          placeholder="请输入负责人"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="联系方式" prop="contactInfo">
+        <el-input
+          v-model="queryParams.contactInfo"
+          placeholder="请输入联系方式"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="地址" prop="address">
+        <el-input
+          v-model="queryParams.address"
+          placeholder="请输入地址"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button
+          type="primary"
+          icon="el-icon-search"
+          size="mini"
+          @click="handleQuery"
+        >搜索
+        </el-button
+        >
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
+        >重置
+        </el-button
+        >
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+
+      <el-col :span="1.5">
+        <el-button
+          v-if="selection.length == 0"
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['system:tenant:export']"
+        >导出
+        </el-button>
+        <ExcelDownLoad
+          v-else
+          :headerList="headerList"
+          :fieldList="selection"
+          :excelTitle="excelTitle"
+        ></ExcelDownLoad>
+      </el-col>
+      <right-toolbar
+        :showSearch.sync="showSearch"
+        @queryTable="getList"
+      ></right-toolbar>
+    </el-row>
+
+    <el-table
+      v-loading="loading"
+      :data="tenantList"
+      style="width: 100%"
+      row-key="tenantId"
+      border
+      lazy
+      :load="load"
+      :tree-props="{children: 'children', hasChildren:'hasChildren' }"
+
+      @cell-dblclick="copyText"
+    >
+      <el-table-column label="租户ID" align="center" prop="tenantId"/>
+      <el-table-column label="租户名称" align="center" prop="tenantName"/>
+      <el-table-column label="租户编号" align="center" prop="tenantCode"/>
+      <el-table-column label="负责人" align="center" prop="owner"/>
+      <el-table-column label="联系方式" align="center" prop="contactInfo"/>
+      <el-table-column label="地址" align="center" prop="address"/>
+      <el-table-column label="租户父级ID" align="center" prop="tenantParentId"/>
+      <el-table-column label="客户端访问地址" align="center" prop="tenantClientLoginUrl"/>
+      <el-table-column label="工具端访问地址" align="center" prop="tenantToolLoginUrl"/>
+      <el-table-column label="租户等级" align="center" prop="tenantGrade"/>
+      <el-table-column label="到期天数" align="center" prop="tenantExpirationTime"/>
+    </el-table>
+
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </div>
+</template>
+
+<script>
+import {
+  listTenant,
+  getTenantAllList,
+  selectAllUser,
+  getTenantChildrenInfo
+} from '@/api/system/tenant'
+import {mapState} from "vuex";
+import ExcelDownLoad from '@/components/ExcelDownLoad/index.vue'
+
+export default {
+  name: 'Tenant',
+  dicts: [
+    'datasource_type',
+    'sqlserver_connection_information',
+    'mysql_connection_information',
+    'dm_connection_information',
+    'orcale_connection_information',
+    'system_login_url'
+  ],
+  components: {
+    ExcelDownLoad
+  },
+  data() {
+    return {
+
+      // 前端导出数据
+      selection: [],
+      headerList: {
+        租户名称: 'tenantName',
+        租户编号: 'tenantCode',
+        负责人: 'owner',
+        联系方式: 'contactInfo',
+        地址: 'address',
+        是否删除: 'isDel'
+      },
+      excelTitle: 'tenant',
+      // 弹窗的加载提示
+      dialogLoading: false,
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 租户信息表格数据
+      tenantList: [],
+      // 弹出层标题
+      title: '',
+      // 是否显示弹出层
+      open: false,
+      // 所有用户信息
+      allUser: [],
+      // 查询参数
+      queryParams: {
+        tenantParentId: 0,
+        pageNum: 1,
+        pageSize: 10,
+        tenantName: null,
+        tenantCode: null,
+        owner: null,
+        contactInfo: null,
+        address: null
+      },
+    }
+  },
+  computed: {
+    ...mapState({
+      userInfo: state => state
+    })
+  },
+  created() {
+
+    this.getList()
+    this.selectAllUser()
+  },
+  methods: {
+    copyText(row, column, cell, event) {
+      // 双击复制
+      const textToCopy = event.target.innerText;
+      navigator.clipboard.writeText(textToCopy).then(() => {
+        this.$message({message: '复制成功', type: 'success'}); // 提示
+      }).catch((error) => {
+        console.error('复制失败:', error);
+
+      });
+    },
+    load(tree, treeNode, resolve) {
+      console.log(tree, treeNode, resolve)
+      // 根据当前租户id查询子租户
+      getTenantChildrenInfo(tree.tenantId).then(res => {
+        if (res.data != null) {
+          resolve(res.data)
+        } else {
+          resolve({})
+        }
+      })
+    },
+
+
+    buildTree(data, parentId = null) {
+      const children = data.filter(item => item.tenantParentId === parentId)
+      return children.map(child => ({
+        value: child.tenantId,
+        label: child.tenantName,
+        children: this.buildTree(data, child.tenantId) // 将 child.tenant_id 作为下一层的 parentId
+      }))
+    },
+
+    // 获取所用用户名,作校验用
+    async selectAllUser() {
+      let res = await selectAllUser()
+      if (res.code == 200) {
+        this.allUser = res.data
+      } else {
+        console.log(res.msg)
+      }
+    },
+    // 重置login配置表单数据
+    resetloginForm() {
+      this.loginForm = {
+        loginPageNumber: '',
+        loginPageTitle: '',
+        loginPageDescription: '',
+        loginPageLogo: '',
+        loginPageBackgroundImage: '',
+        windowTitle: '',
+        windowLogo: '',
+        tenantId: ''
+      }
+    },
+
+    /** 查询租户信息列表 */
+    getList() {
+      this.loading = true
+      this.currentPage = this.queryParams.pageNum
+      this.queryParams.tenantParentId = this.userInfo.user.tenant.tenantId
+      getTenantAllList(this.queryParams).then((response) => {
+        this.tenantList = response.rows
+        this.tenantList.forEach(item => {
+          item['hasChildren'] = true
+        })
+        this.total = response.total
+        this.loading = false
+      })
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1
+      this.getList()
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm('queryForm')
+      this.handleQuery()
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download(
+        'system/tenant/export',
+        {
+          ...this.queryParams
+        },
+        `tenant_${new Date().getTime()}.xlsx`
+      )
+    },
+  }
+}
+</script>