Переглянути джерело

Add 增加 同步租户参数配置功能,其他代码优化

Yue 6 місяців тому
батько
коміт
670d01bafc
15 змінених файлів з 134 додано та 22 видалено
  1. 1 1
      SERVER/VberAdminPlusV3/vber-admin/src/main/resources/application-dev.yml
  2. 2 2
      SERVER/VberAdminPlusV3/vber-common/vber-common-core/src/main/java/com/vber/common/json/validate/JsonPatternValidator.java
  3. 16 12
      SERVER/VberAdminPlusV3/vber-common/vber-common-tenant/src/main/java/com/vber/common/tenant/config/TenantConfig.java
  4. 5 0
      SERVER/VberAdminPlusV3/vber-common/vber-common-tenant/src/main/java/com/vber/common/tenant/core/TenantSaTokenDao.java
  5. 2 2
      SERVER/VberAdminPlusV3/vber-common/vber-common-tenant/src/main/java/com/vber/common/tenant/handle/TenantKeyPrefixHandler.java
  6. 2 1
      SERVER/VberAdminPlusV3/vber-common/vber-common-tenant/src/main/java/com/vber/common/tenant/manager/TenantSpringCacheManager.java
  7. 1 1
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/controller/system/SysPostController.java
  8. 15 0
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/controller/system/SysTenantController.java
  9. 5 0
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/ISysTenantService.java
  10. 56 0
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/impl/SysTenantServiceImpl.java
  11. 5 0
      UI/VAP_V3.VUE/src/api/system/_post.ts
  12. 5 0
      UI/VAP_V3.VUE/src/api/system/_tenant.ts
  13. 1 1
      UI/VAP_V3.VUE/src/views/account/login.vue
  14. 1 1
      UI/VAP_V3.VUE/src/views/system/post/index.vue
  15. 17 1
      UI/VAP_V3.VUE/src/views/system/tenant/index.vue

+ 1 - 1
SERVER/VberAdminPlusV3/vber-admin/src/main/resources/application-dev.yml

@@ -74,7 +74,7 @@ spring.data:
 
 redisson:
   # redis key前缀
-  keyPrefix: vber
+  keyPrefix: vber_dev
   # 线程池数量
   threads: 4
   # Netty线程池数量

+ 2 - 2
SERVER/VberAdminPlusV3/vber-common/vber-common-core/src/main/java/com/vber/common/json/validate/JsonPatternValidator.java

@@ -1,9 +1,9 @@
 package com.vber.common.json.validate;
 
+import com.vber.common.core.utils.StringUtils;
+import com.vber.common.json.utils.JsonUtils;
 import jakarta.validation.ConstraintValidator;
 import jakarta.validation.ConstraintValidatorContext;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.json.utils.JsonUtils;
 
 /**
  * JSON 格式校验器

+ 16 - 12
SERVER/VberAdminPlusV3/vber-common/vber-common-tenant/src/main/java/com/vber/common/tenant/config/TenantConfig.java

@@ -16,6 +16,7 @@ import org.redisson.config.ClusterServersConfig;
 import org.redisson.config.SingleServerConfig;
 import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
 import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.cache.CacheManager;
@@ -32,6 +33,21 @@ import org.springframework.context.annotation.Primary;
 @ConditionalOnProperty(value = "tenant.enable", havingValue = "true")
 public class TenantConfig {
 
+
+    @ConditionalOnClass(TenantLineInnerInterceptor.class)
+    @AutoConfiguration
+    static class MybatisPlusConfiguration {
+
+        /**
+         * 多租户插件
+         */
+        @Bean
+        public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantProperties tenantProperties) {
+            return new TenantLineInnerInterceptor(new PlusTenantLineHandler(tenantProperties));
+        }
+
+    }
+
     @Bean
     public RedissonAutoConfigurationCustomizer tenantRedissonCustomizer(RedissonProperties redissonProperties) {
         return config -> {
@@ -69,17 +85,5 @@ public class TenantConfig {
         return new TenantSaTokenDao();
     }
 
-    @AutoConfiguration
-    static class MybatisPlusConfiguration {
-
-        /**
-         * 多租户插件
-         */
-        @Bean
-        public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantProperties tenantProperties) {
-            return new TenantLineInnerInterceptor(new PlusTenantLineHandler(tenantProperties));
-        }
-
-    }
 
 }

+ 5 - 0
SERVER/VberAdminPlusV3/vber-common/vber-common-tenant/src/main/java/com/vber/common/tenant/core/TenantSaTokenDao.java

@@ -81,6 +81,11 @@ public class TenantSaTokenDao extends PlusSaTokenDao {
         return super.getObject(GlobalConstants.GLOBAL_REDIS_KEY + key);
     }
 
+    @Override
+    public <T> T getObject(String key, Class<T> classType) {
+        return super.getObject(GlobalConstants.GLOBAL_REDIS_KEY + key, classType);
+    }
+
     /**
      * 写入Object,并设定存活时间 (单位: 秒)
      */

+ 2 - 2
SERVER/VberAdminPlusV3/vber-common/vber-common-tenant/src/main/java/com/vber/common/tenant/handle/TenantKeyPrefixHandler.java

@@ -39,7 +39,7 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
         }
         String tenantId = TenantHelper.getTenantId();
         if (StringUtils.isBlank(tenantId)) {
-            log.error("无法获取有效的租户id -> Null");
+            log.error("无法获取有效的租户id [TenantKeyPrefixHandler] -> Null");
             return super.map(name);
         }
         if (StringUtils.startsWith(name, tenantId)) {
@@ -70,7 +70,7 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
         }
         String tenantId = TenantHelper.getTenantId();
         if (StringUtils.isBlank(tenantId)) {
-            log.error("无法获取有效的租户ID -> Null");
+            log.error("无法获取有效的租户ID [TenantKeyPrefixHandler] --> Null");
             return unmap;
         }
         if (StringUtils.startsWith(unmap, tenantId)) {

+ 2 - 1
SERVER/VberAdminPlusV3/vber-common/vber-common-tenant/src/main/java/com/vber/common/tenant/manager/TenantSpringCacheManager.java

@@ -29,7 +29,8 @@ public class TenantSpringCacheManager extends PlusSpringCacheManager {
         }
         String tenantId = TenantHelper.getTenantId();
         if (StringUtils.isBlank(tenantId)) {
-            log.error("无法获取有效的租户id -> Null");
+            log.error("无法获取有效的租户id [TenantSpringCacheManager] -> Null");
+            return super.getCache(name);
         }
         if (StringUtils.startsWith(name, tenantId)) {
             // 如果存在则直接返回

+ 1 - 1
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/controller/system/SysPostController.java

@@ -141,7 +141,7 @@ public class SysPostController extends BaseController {
      */
     @SaCheckPermission("system:post:list")
     @GetMapping("/orgTree")
-    public R<List<Tree<Long>>> deptTree(SysOrgBo org) {
+    public R<List<Tree<Long>>> orgTree(SysOrgBo org) {
         return R.ok(orgService.selectOrgTreeList(org));
     }
 

+ 15 - 0
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/controller/system/SysTenantController.java

@@ -193,4 +193,19 @@ public class SysTenantController extends BaseController {
         return R.ok("同步租户字典成功");
     }
 
+    /**
+     * 同步租户参数配置
+     */
+    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
+    @Log(title = "租户管理", businessType = BusinessType.INSERT)
+    @Lock4j
+    @GetMapping("/syncTenantConfig")
+    public R<Void> syncTenantConfig() {
+        if (!TenantHelper.isEnable()) {
+            return R.fail("当前未开启租户模式");
+        }
+        tenantService.syncTenantConfig();
+        return R.ok("同步租户参数配置成功");
+    }
+
 }

+ 5 - 0
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/ISysTenantService.java

@@ -84,4 +84,9 @@ public interface ISysTenantService {
      * 同步租户字典
      */
     void syncTenantDict();
+
+    /**
+     * 同步租户参数配置
+     */
+    void syncTenantConfig();
 }

+ 56 - 0
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/impl/SysTenantServiceImpl.java

@@ -487,4 +487,60 @@ public class SysTenantServiceImpl implements ISysTenantService {
         }
     }
 
+
+    /**
+     * 同步租户参数配置
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void syncTenantConfig() {
+        // 查询超管 所有参数配置
+        List<SysConfig> configList = TenantHelper.ignore(() -> configMapper.selectList());
+
+        // 所有租户参数配置
+        Map<String, List<SysConfig>> configMap = StreamUtils.groupByKey(configList, TenantEntity::getTenantId);
+
+        // 默认租户字典类型列表
+        List<SysConfig> defaultConfigList = configMap.get(TenantConstants.DEFAULT_TENANT_ID);
+
+        // 获取所有租户编号
+        List<String> tenantIds = baseMapper.selectObjs(
+                new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId)
+                        .eq(SysTenant::getStatus, SystemConstants.NORMAL), x -> {
+                    return Convert.toStr(x);
+                });
+        // 待入库的字典类型和字典数据
+        List<SysConfig> saveConfigList = new ArrayList<>();
+        // 待同步的租户编号(用于清除对于租户的字典缓存)
+        Set<String> syncTenantIds = new HashSet<>();
+        // 循环所有租户,处理需要同步的数据
+        for (String tenantId : tenantIds) {
+            // 排除默认租户
+            if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
+                continue;
+            }
+            // 根据默认租户的字典类型进行数据同步
+            for (SysConfig config : defaultConfigList) {
+                // 获取当前租户的字典类型列表
+                List<String> typeList = StreamUtils.toList(configMap.get(tenantId), SysConfig::getConfigKey);
+                if (!typeList.contains(config.getConfigKey())) {
+                    SysConfig type = BeanUtil.toBean(config, SysConfig.class);
+                    type.setConfigId(null);
+                    type.setTenantId(tenantId);
+                    type.setCreateTime(null);
+                    type.setUpdateTime(null);
+                    syncTenantIds.add(tenantId);
+                    saveConfigList.add(type);
+                }
+            }
+        }
+        TenantHelper.ignore(() -> {
+            if (CollUtil.isNotEmpty(saveConfigList)) {
+                configMapper.insertBatch(saveConfigList);
+            }
+        });
+        for (String tenantId : syncTenantIds) {
+            TenantHelper.dynamic(tenantId, () -> CacheUtils.clear(CacheNames.SYS_CONFIG));
+        }
+    }
 }

+ 5 - 0
UI/VAP_V3.VUE/src/api/system/_post.ts

@@ -51,6 +51,11 @@ class postApi {
 			}
 		})
 	}
+	orgTreeSelect = () => {
+		return Rs.get({
+			url: "/system/post/orgTree"
+		})
+	}
 }
 
 export default postApi

+ 5 - 0
UI/VAP_V3.VUE/src/api/system/_tenant.ts

@@ -85,6 +85,11 @@ class tenantApi {
 			url: "/system/tenant/syncTenantDict"
 		})
 	}
+	syncTenantConfig = () => {
+		return Rs.get({
+			url: "/system/tenant/syncTenantConfig"
+		})
+	}
 
 	// 动态切换租户
 	dynamicTenant = (tenantId: string | number) => {

+ 1 - 1
UI/VAP_V3.VUE/src/views/account/login.vue

@@ -189,7 +189,7 @@ watch(
 						:label="item.companyName"
 						:value="item.tenantId"></el-option>
 					<template #prefix>
-						<span class="el-input__icon input-icon"><VbIcon icon-name="home" class="fs-3" /></span>
+						<span class="el-input__icon"><VbIcon icon-name="home" class="fs-3" /></span>
 					</template>
 				</el-select>
 			</el-form-item>

+ 1 - 1
UI/VAP_V3.VUE/src/views/system/post/index.vue

@@ -225,7 +225,7 @@ function onOrgChange(data: any) {
 }
 function getOrgTreeSelect() {
 	return new Promise((resolve, reject) => {
-		apis.system.userApi.selectOrgTreeSelect().then((res: any) => {
+		apis.system.postApi.orgTreeSelect().then((res: any) => {
 			orgOptions.value = res.data
 			resolve({ data: res.data })
 		})

+ 17 - 1
UI/VAP_V3.VUE/src/views/system/tenant/index.vue

@@ -25,7 +25,7 @@ const opts = reactive({
 		},
 		{ field: "status", name: "租户状态", visible: true, isSort: false, width: 100 },
 		{ field: "actions", name: `操作`, width: 150 }
-	],
+	] as any[],
 	queryParams: {
 		companyName: undefined,
 		licenseNumber: undefined,
@@ -109,6 +109,16 @@ const opts = reactive({
 			btnClass: "btn btn-light-warning",
 			permission: "no_auth",
 			clickFun: handleSyncTenantDict
+		},
+		{
+			key: "handleSyncTenantConfig",
+			show: appStore.authStore.user.roles.includes("super_admin"),
+			name: "同步租户配置",
+			iconType: "class",
+			icon: "me-1 bi bi-arrow-repeat",
+			btnClass: "btn btn-light-warning",
+			permission: "no_auth",
+			clickFun: handleSyncTenantConfig
 		}
 	] as any,
 	tableListFun: apis.system.tenantApi.list,
@@ -351,6 +361,12 @@ function handleSyncTenantDict() {
 	})
 }
 
+function handleSyncTenantConfig() {
+	apis.system.tenantApi.syncTenantConfig().then(() => {
+		message.msgSuccess("同步成功")
+	})
+}
+
 /** 提交按钮 */
 function submitForm() {
 	apis.system.tenantApi.addOrUpdate(form.value).then(() => {