Yue 10 месяцев назад
Родитель
Сommit
547a81acd5
43 измененных файлов с 1490 добавлено и 1075 удалено
  1. 1 1
      SERVER/VberAdminPlusV3/.script/sql/admin.sql
  2. 9 3
      SERVER/VberAdminPlusV3/pom.xml
  3. 1 1
      SERVER/VberAdminPlusV3/vber-admin/src/main/java/com/vber/web/service/SysRegisterService.java
  4. 17 0
      SERVER/VberAdminPlusV3/vber-common/vber-common-core/src/main/java/com/vber/common/core/utils/TreeBuildUtils.java
  5. 66 42
      SERVER/VberAdminPlusV3/vber-common/vber-common-excel/src/main/java/com/vber/common/excel/core/ExcelDownHandler.java
  6. 4 0
      SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/pom.xml
  7. 51 0
      SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/src/main/java/com/vber/common/mybatis/aspect/DataPermissionAspect.java
  8. 10 1
      SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/src/main/java/com/vber/common/mybatis/config/MybatisPlusConfig.java
  9. 3 0
      SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/src/main/java/com/vber/common/mybatis/core/page/PageQuery.java
  10. 27 106
      SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/src/main/java/com/vber/common/mybatis/handler/PlusDataPermissionHandler.java
  11. 29 0
      SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/src/main/java/com/vber/common/mybatis/helper/DataPermissionHelper.java
  12. 4 6
      SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/src/main/java/com/vber/common/mybatis/interceptor/PlusDataPermissionInterceptor.java
  13. 2 116
      SERVER/VberAdminPlusV3/vber-common/vber-common-oss/src/main/java/com/vber/common/oss/core/OssClient.java
  14. 3 7
      SERVER/VberAdminPlusV3/vber-common/vber-common-oss/src/main/java/com/vber/common/oss/enumd/AccessPolicyType.java
  15. 0 35
      SERVER/VberAdminPlusV3/vber-common/vber-common-oss/src/main/java/com/vber/common/oss/enumd/PolicyType.java
  16. 6 0
      SERVER/VberAdminPlusV3/vber-common/vber-common-ratelimiter/src/main/java/com/vber/common/ratelimiter/annotation/RateLimiter.java
  17. 2 1
      SERVER/VberAdminPlusV3/vber-common/vber-common-ratelimiter/src/main/java/com/vber/common/ratelimiter/aspectj/RateLimiterAspect.java
  18. 41 3
      SERVER/VberAdminPlusV3/vber-common/vber-common-redis/src/main/java/com/vber/common/redis/utils/RedisUtils.java
  19. 1 1
      SERVER/VberAdminPlusV3/vber-common/vber-common-sms/src/main/java/com/vber/common/sms/core/dao/PlusSmsDao.java
  20. 3 1
      SERVER/VberAdminPlusV3/vber-common/vber-common-sse/src/main/java/com/vber/common/sse/core/SseEmitterManager.java
  21. 2 4
      SERVER/VberAdminPlusV3/vber-common/vber-common-tenant/src/main/java/com/vber/common/tenant/config/TenantConfig.java
  22. 12 4
      SERVER/VberAdminPlusV3/vber-common/vber-common-tenant/src/main/java/com/vber/common/tenant/handle/TenantKeyPrefixHandler.java
  23. 1 1
      SERVER/VberAdminPlusV3/vber-common/vber-common-translation/src/main/java/com/vber/common/translation/core/handler/TranslationHandler.java
  24. 3 2
      SERVER/VberAdminPlusV3/vber-modules/vber-generator/src/main/java/com/vber/generator/service/GenTableServiceImpl.java
  25. 1 2
      SERVER/VberAdminPlusV3/vber-modules/vber-generator/src/main/java/com/vber/generator/util/GenUtils.java
  26. 12 9
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/controller/system/SysUserController.java
  27. 6 0
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/mapper/SysDictDataMapper.java
  28. 19 0
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/mapper/SysOrgMapper.java
  29. 8 1
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/mapper/SysPostMapper.java
  30. 13 0
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/mapper/SysRoleMapper.java
  31. 24 4
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/mapper/SysUserMapper.java
  32. 6 0
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/mapper/SysUserRoleMapper.java
  33. 1 0
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/ISysRoleService.java
  34. 1 3
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/impl/SysDataScopeServiceImpl.java
  35. 22 10
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/impl/SysOrgServiceImpl.java
  36. 2 6
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/impl/SysPostServiceImpl.java
  37. 36 5
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/impl/SysRoleServiceImpl.java
  38. 1 3
      SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/impl/SysUserServiceImpl.java
  39. 2 0
      UI/VAP_V3.VUE/.env.development
  40. 3 1
      UI/VAP_V3.VUE/.env.production
  41. 1032 695
      UI/VAP_V3.VUE/pnpm-lock.yaml
  42. 3 1
      UI/VAP_V3.VUE/src/core/utils/sse.ts
  43. 0 0
      UI/VAP_V3.VUE/src/views/system/log/operLog.vue

+ 1 - 1
SERVER/VberAdminPlusV3/.script/sql/admin.sql

@@ -422,7 +422,7 @@ CREATE TABLE sys_social
 (
     id                 BIGINT       NOT NULL AUTO_INCREMENT COMMENT '主键',
     user_id            BIGINT       NOT NULL COMMENT '用户ID',
-    tenant_id          VARCHAR(20)  DEFAULT NULL COMMENT '租户id',
+    tenant_id          VARCHAR(20)  DEFAULT "000000" COMMENT '租户id',
     auth_id            VARCHAR(255) NOT NULL COMMENT '平台+平台唯一id',
     source             VARCHAR(255) NOT NULL COMMENT '用户来源',
     open_id            VARCHAR(255) DEFAULT NULL COMMENT '平台编号唯一id',

+ 9 - 3
SERVER/VberAdminPlusV3/pom.xml

@@ -22,10 +22,10 @@
         <java.version>17</java.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-        <spring-boot.version>3.2.11</spring-boot.version>
-        <spring-boot-admin.version>3.2.3</spring-boot-admin.version>
+        <spring-boot.version>3.3.5</spring-boot.version>
+        <spring-boot-admin.version>3.3.4</spring-boot-admin.version>
         <mybatis.version>3.5.16</mybatis.version>
-        <mybatis-plus.version>3.5.8</mybatis-plus.version>
+        <mybatis-plus.version>3.5.9</mybatis-plus.version>
         <dynamic-ds.version>4.3.1</dynamic-ds.version>
         <shardingsphere.version>5.5.0</shardingsphere.version>
         <springdoc.version>2.6.0</springdoc.version>
@@ -210,6 +210,12 @@
                 <version>${mybatis-plus.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>mybatis-plus-jsqlparser</artifactId>
+                <version>${mybatis-plus.version}</version>
+            </dependency>
+
             <dependency>
                 <groupId>com.baomidou</groupId>
                 <artifactId>mybatis-plus-annotation</artifactId>

+ 1 - 1
SERVER/VberAdminPlusV3/vber-admin/src/main/java/com/vber/web/service/SysRegisterService.java

@@ -96,7 +96,7 @@ public class SysRegisterService {
      * @param message  消息内容
      */
     private void recordLogininfor(String tenantId, String username, String message) {
-        SysLoginService.buildLoginEvent(tenantId, username, Constants.REGISTER, message);
+        SysLoginService.buildLoginEvent(tenantId, username, Constants.LOGIN_FAIL, message);
     }
 
 

+ 17 - 0
SERVER/VberAdminPlusV3/vber-common/vber-common-core/src/main/java/com/vber/common/core/utils/TreeBuildUtils.java

@@ -43,6 +43,23 @@ public class TreeBuildUtils extends TreeUtil {
         return TreeUtil.build(list, k, DEFAULT_CONFIG, nodeParser);
     }
 
+    /**
+     * 构建树形结构
+     *
+     * @param <T>        输入节点的类型
+     * @param <K>        节点ID的类型
+     * @param parentId   顶级节点
+     * @param list       节点列表,其中包含了要构建树形结构的所有节点
+     * @param nodeParser 解析器,用于将输入节点转换为树节点
+     * @return 构建好的树形结构列表
+     */
+    public static <T, K> List<Tree<K>> build(List<T> list, K parentId, NodeParser<T, K> nodeParser) {
+        if (CollUtil.isEmpty(list)) {
+            return CollUtil.newArrayList();
+        }
+        return TreeUtil.build(list, parentId, DEFAULT_CONFIG, nodeParser);
+    }
+
     /**
      * 获取节点列表中所有节点的叶子节点
      *

+ 66 - 42
SERVER/VberAdminPlusV3/vber-common/vber-common-excel/src/main/java/com/vber/common/excel/core/ExcelDownHandler.java

@@ -139,8 +139,8 @@ public class ExcelDownHandler implements SheetWriteHandler {
             } else if (everyOptions.getOptions().size() > 10) {
                 // 当一级选项参数个数大于10,使用额外表的形式
                 dropDownWithSheet(helper, workbook, sheet, everyOptions.getIndex(), everyOptions.getOptions());
-            } else if (everyOptions.getOptions().size() != 0) {
-                // 当一级选项个数不为空,使用默认形式
+            } else {
+                // 否则使用默认形式
                 dropDownWithSimple(helper, sheet, everyOptions.getIndex(), everyOptions.getOptions());
             }
         });
@@ -171,10 +171,25 @@ public class ExcelDownHandler implements SheetWriteHandler {
         Sheet linkedOptionsDataSheet = workbook.createSheet(WorkbookUtil.createSafeSheetName(linkedOptionsSheetName));
         // 将下拉表隐藏
         workbook.setSheetHidden(workbook.getSheetIndex(linkedOptionsDataSheet), true);
-        // 完善横向的一级选项数据
+        // 选项数据
         List<String> firstOptions = options.getOptions();
         Map<String, List<String>> secoundOptionsMap = options.getNextOptions();
 
+        // 采用按行填充数据的方式,避免EasyExcel出现数据无法写入的问题
+        // Attempting to write a row in the range that is already written to disk
+
+        // 使用ArrayList记载数据,防止乱序
+        List<String> columnNames = new ArrayList<>();
+        // 写入第一行,即第一级的数据
+        Row firstRow = linkedOptionsDataSheet.createRow(0);
+        for (int columnIndex = 0; columnIndex < firstOptions.size(); columnIndex++) {
+            String columnName = firstOptions.get(columnIndex);
+            firstRow.createCell(columnIndex)
+                    .setCellValue(columnName);
+            columnNames.add(columnName);
+        }
+
+
         // 创建名称管理器
         Name name = workbook.createName();
         // 设置名称管理器的别名
@@ -190,28 +205,12 @@ public class ExcelDownHandler implements SheetWriteHandler {
         // 设置数据校验为序列模式,引用的是名称管理器中的别名
         this.markOptionsToSheet(helper, sheet, options.getIndex(), helper.createFormulaListConstraint(linkedOptionsSheetName));
 
-        for (int columIndex = 0; columIndex < firstOptions.size(); columIndex++) {
-            // 先提取主表中一级下拉的列名
+        // 创建二级选项的名称管理器
+        for (int columIndex = 0; columIndex < columnNames.size(); columIndex++) {
+            // 列名
             String firstOptionsColumnName = getExcelColumnName(columIndex);
-            // 一次循环是每一个一级选项
-            int finalI = columIndex;
-            // 本次循环的一级选项值
-            String thisFirstOptionsValue = firstOptions.get(columIndex);
-            // 创建第一行的数据
-            Optional.ofNullable(linkedOptionsDataSheet.getRow(0))
-                    // 如果不存在则创建第一行
-                    .orElseGet(() -> linkedOptionsDataSheet.createRow(finalI))
-                    // 第一行当前列
-                    .createCell(columIndex)
-                    // 设置值为当前一级选项值
-                    .setCellValue(thisFirstOptionsValue);
-
-            // 第二行开始,设置第二级别选项参数
-            List<String> secondOptions = secoundOptionsMap.get(thisFirstOptionsValue);
-            if (CollUtil.isEmpty(secondOptions)) {
-                // 必须保证至少有一个关联选项,否则将导致Excel解析错误
-                secondOptions = Collections.singletonList("暂无_0");
-            }
+            // 对应的一级值
+            String thisFirstOptionsValue = columnNames.get(columIndex);
 
             // 以该一级选项值创建子名称管理器
             Name sonName = workbook.createName();
@@ -222,7 +221,9 @@ public class ExcelDownHandler implements SheetWriteHandler {
                     linkedOptionsSheetName,
                     firstOptionsColumnName,
                     firstOptionsColumnName,
-                    secondOptions.size() + 1
+                    // 二级选项存在则设置为(选项个数+1)行,否则设置为2行
+                    Math.max(Optional.ofNullable(secoundOptionsMap.get(thisFirstOptionsValue))
+                            .orElseGet(ArrayList::new).size(), 1) + 1
             );
             // 设置名称管理器的引用位置
             sonName.setRefersToFormula(sonFunction);
@@ -235,25 +236,48 @@ public class ExcelDownHandler implements SheetWriteHandler {
                 // 二级只能主表每一行的每一列添加二级校验
                 markLinkedOptionsToSheet(helper, sheet, i, options.getNextIndex(), helper.createFormulaListConstraint(secondOptionsFunction));
             }
-
-            for (int rowIndex = 0; rowIndex < secondOptions.size(); rowIndex++) {
-                // 从第二行开始填充二级选项
-                int finalRowIndex = rowIndex + 1;
-                int finalColumIndex = columIndex;
-
-                Row row = Optional.ofNullable(linkedOptionsDataSheet.getRow(finalRowIndex))
-                        // 没有则创建
-                        .orElseGet(() -> linkedOptionsDataSheet.createRow(finalRowIndex));
-                Optional
-                        // 在本级一级选项所在的列
-                        .ofNullable(row.getCell(finalColumIndex))
-                        // 不存在则创建
-                        .orElseGet(() -> row.createCell(finalColumIndex))
-                        // 设置二级选项值
-                        .setCellValue(secondOptions.get(rowIndex));
+        }
+        // 将二级数据处理为按行区分
+        Map<Integer, List<String>> columnValueMap = new HashMap<>();
+        int currentRow = 1;
+        while (currentRow >= 0) {
+            boolean flag = false;
+            List<String> rowData = new ArrayList<>();
+            for (String columnName : columnNames) {
+                List<String> data = secoundOptionsMap.get(columnName);
+                if (CollUtil.isEmpty(data)) {
+                    // 添加空字符串填充位置
+                    rowData.add(" ");
+                    continue;
+                }
+                // 取第一个
+                String str = data.get(0);
+                rowData.add(str);
+                // 通过移除的方式避免重复
+                data.remove(0);
+                // 设置可以继续
+                flag = true;
+            }
+            columnValueMap.put(currentRow, rowData);
+            // 可以继续,则增加行数,否则置为负数跳出循环
+            if (flag) {
+                currentRow++;
+            } else {
+                currentRow = -1;
             }
         }
-
+        // 填充第二级选项数据
+        columnValueMap.forEach((rowIndex, rowValues) -> {
+            Row row = linkedOptionsDataSheet.createRow(rowIndex);
+            for (int columnIndex = 0; columnIndex < rowValues.size(); columnIndex++) {
+                String rowValue = rowValues.get(columnIndex);
+                // 填充位置的部分不渲染
+                if (StrUtil.isNotBlank(rowValue)) {
+                    row.createCell(columnIndex)
+                            .setCellValue(rowValue);
+                }
+            }
+        });
         currentLinkedOptionsSheetIndex++;
     }
 

+ 4 - 0
SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/pom.xml

@@ -48,6 +48,10 @@
             </exclusions>
         </dependency>
 
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-jsqlparser</artifactId>
+        </dependency>
 
         <!-- sql性能分析插件 -->
         <dependency>

+ 51 - 0
SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/src/main/java/com/vber/common/mybatis/aspect/DataPermissionAspect.java

@@ -0,0 +1,51 @@
+package com.vber.common.mybatis.aspect;
+
+
+import com.vber.common.mybatis.annotation.DataPermission;
+import com.vber.common.mybatis.helper.DataPermissionHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+
+/**
+ * 数据权限处理
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@Aspect
+public class DataPermissionAspect {
+
+    /**
+     * 处理请求前执行
+     */
+    @Before(value = "@annotation(dataPermission)")
+    public void doBefore(JoinPoint joinPoint, DataPermission dataPermission) {
+        DataPermissionHelper.setPermission(dataPermission);
+    }
+
+    /**
+     * 处理完请求后执行
+     *
+     * @param joinPoint 切点
+     */
+    @AfterReturning(pointcut = "@annotation(dataPermission)")
+    public void doAfterReturning(JoinPoint joinPoint, DataPermission dataPermission) {
+        DataPermissionHelper.removePermission();
+    }
+
+    /**
+     * 拦截异常操作
+     *
+     * @param joinPoint 切点
+     * @param e         异常
+     */
+    @AfterThrowing(value = "@annotation(dataPermission)", throwing = "e")
+    public void doAfterThrowing(JoinPoint joinPoint, DataPermission dataPermission, Exception e) {
+        DataPermissionHelper.removePermission();
+    }
+
+}

+ 10 - 1
SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/src/main/java/com/vber/common/mybatis/config/MybatisPlusConfig.java

@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerIntercept
 import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
 import com.vber.common.core.factory.YmlPropertySourceFactory;
 import com.vber.common.core.utils.SpringUtils;
+import com.vber.common.mybatis.aspect.DataPermissionAspect;
 import com.vber.common.mybatis.handler.InjectionMetaObjectHandler;
 import com.vber.common.mybatis.handler.MybatisExceptionHandler;
 import com.vber.common.mybatis.interceptor.PlusDataPermissionInterceptor;
@@ -51,7 +52,15 @@ public class MybatisPlusConfig {
      * 数据权限拦截器
      */
     public PlusDataPermissionInterceptor dataPermissionInterceptor() {
-        return new PlusDataPermissionInterceptor(SpringUtils.getProperty("mybatis-plus.mapperPackage"));
+        return new PlusDataPermissionInterceptor();
+    }
+
+    /**
+     * 数据权限切面处理器
+     */
+    @Bean
+    public DataPermissionAspect dataPermissionAspect() {
+        return new DataPermissionAspect();
     }
 
     /**

+ 3 - 0
SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/src/main/java/com/vber/common/mybatis/core/page/PageQuery.java

@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.metadata.OrderItem;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.vber.common.core.exception.ServiceException;
 import com.vber.common.core.utils.StringUtils;
 import com.vber.common.core.utils.sql.SqlUtil;
@@ -114,6 +115,8 @@ public class PageQuery implements Serializable {
         return list;
     }
 
+
+    @JsonIgnore
     public Integer getFirstNum() {
         return (pageNum - 1) * pageSize;
     }

+ 27 - 106
SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/src/main/java/com/vber/common/mybatis/handler/PlusDataPermissionHandler.java

@@ -52,10 +52,6 @@ import java.util.function.Function;
 @Slf4j
 public class PlusDataPermissionHandler {
 
-    /**
-     * 方法或类(名称) 与 注解的映射关系缓存
-     */
-    private final Map<String, DataPermission> dataPermissionCacheMap = new ConcurrentHashMap<>();
 
     /**
      * spel 解析器
@@ -68,14 +64,6 @@ public class PlusDataPermissionHandler {
     private final BeanResolver beanResolver = new BeanFactoryResolver(SpringUtils.getBeanFactory());
 
 
-    /**
-     * 构造方法,扫描指定包下的 Mapper 类并初始化缓存
-     *
-     * @param mapperPackage Mapper 类所在的包路径
-     */
-    public PlusDataPermissionHandler(String mapperPackage) {
-        scanMapperClasses(mapperPackage);
-    }
 
 
     /**
@@ -87,24 +75,24 @@ public class PlusDataPermissionHandler {
      * @return 数据过滤条件的 SQL 片段
      */
     public Expression getSqlSegment(Expression where, String mappedStatementId, boolean isSelect) {
-        // 获取数据权限配置
-        DataPermission dataPermission = getDataPermission(mappedStatementId);
-        // 获取当前登录用户信息
-        LoginUser currentUser = DataPermissionHelper.getVariable("user");
-        if (ObjectUtil.isNull(currentUser)) {
-            currentUser = LoginHelper.getLoginUser();
-            DataPermissionHelper.setVariable("user", currentUser);
-        }
-        // 如果是超级管理员或租户管理员,则不过滤数据
-        if (LoginHelper.isSuperAdmin() || LoginHelper.isTenantAdmin()) {
-            return where;
-        }
-        // 构造数据过滤条件的 SQL 片段
-        String dataFilterSql = buildDataFilter(dataPermission, isSelect);
-        if (StringUtils.isBlank(dataFilterSql)) {
-            return where;
-        }
         try {
+            // 获取数据权限配置
+            DataPermission dataPermission = DataPermissionHelper.getPermission();
+            // 获取当前登录用户信息
+            LoginUser currentUser = DataPermissionHelper.getVariable("user");
+            if (ObjectUtil.isNull(currentUser)) {
+                currentUser = LoginHelper.getLoginUser();
+                DataPermissionHelper.setVariable("user", currentUser);
+            }
+            // 如果是超级管理员或租户管理员,则不过滤数据
+            if (LoginHelper.isSuperAdmin() || LoginHelper.isTenantAdmin()) {
+                return where;
+            }
+            // 构造数据过滤条件的 SQL 片段
+            String dataFilterSql = buildDataFilter(dataPermission, isSelect);
+            if (StringUtils.isBlank(dataFilterSql)) {
+                return where;
+            }
             Expression expression = CCJSqlParserUtil.parseExpression(dataFilterSql);
             // 数据权限使用单独的括号 防止与其他条件冲突
             ParenthesedExpressionList<Expression> parenthesis = new ParenthesedExpressionList<>(expression);
@@ -115,6 +103,8 @@ public class PlusDataPermissionHandler {
             }
         } catch (JSQLParserException e) {
             throw new ServiceException("数据权限解析异常 => " + e.getMessage());
+        } finally {
+            DataPermissionHelper.removePermission();
         }
     }
 
@@ -163,6 +153,7 @@ public class PlusDataPermissionHandler {
                 if (StringUtils.isNotBlank(dataColumn.permission()) &&
                         CollUtil.contains(user.getMenuPermission(), dataColumn.permission())
                 ) {
+                    conditions.add(joinStr + " 1 = 1 ");
                     isSuccess = true;
                     continue;
                 }
@@ -171,8 +162,12 @@ public class PlusDataPermissionHandler {
                     context.setVariable(dataColumn.key()[i], dataColumn.value()[i]);
                 }
 
+
+                // 忽略数据权限 防止spel表达式内有其他sql查询导致死循环调用
+                String sql = DataPermissionHelper.ignore(() ->
+                        parser.parseExpression(type.getSqlTemplate(), parserContext).getValue(context, String.class)
+                );
                 // 解析sql模板并填充
-                String sql = parser.parseExpression(type.getSqlTemplate(), parserContext).getValue(context, String.class);
                 conditions.add(joinStr + sql);
                 isSuccess = true;
             }
@@ -189,89 +184,15 @@ public class PlusDataPermissionHandler {
         return "";
     }
 
-    /**
-     * 扫描指定包下的 Mapper 类,并查找其中带有特定注解的方法或类
-     *
-     * @param mapperPackage Mapper 类所在的包路径
-     */
-    private void scanMapperClasses(String mapperPackage) {
-        // 创建资源解析器和元数据读取工厂
-        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
-        CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
-        // 将 Mapper 包路径按分隔符拆分为数组
-        String[] packagePatternArray = StringUtils.splitPreserveAllTokens(mapperPackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
-        String classpath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX;
-        try {
-            for (String packagePattern : packagePatternArray) {
-                // 将包路径转换为资源路径
-                String path = ClassUtils.convertClassNameToResourcePath(packagePattern);
-                // 获取指定路径下的所有 .class 文件资源
-                Resource[] resources = resolver.getResources(classpath + path + "/*.class");
-                for (Resource resource : resources) {
-                    // 获取资源的类元数据
-                    ClassMetadata classMetadata = factory.getMetadataReader(resource).getClassMetadata();
-                    // 获取资源对应的类对象
-                    Class<?> clazz = Resources.classForName(classMetadata.getClassName());
-                    // 查找类中的特定注解
-                    findAnnotation(clazz);
-                }
-            }
-        } catch (Exception e) {
-            log.error("初始化数据安全缓存时出错:{}", e.getMessage());
-        }
-    }
 
-    /**
-     * 在指定的类中查找特定的注解 DataPermission,并将带有这个注解的方法或类存储到 dataPermissionCacheMap 中
-     *
-     * @param clazz 要查找的类
-     */
-    private void findAnnotation(Class<?> clazz) {
-        DataPermission dataPermission;
-        // 获取方法注解
-        for (Method method : clazz.getMethods()) {
-            if (method.isDefault() || method.isVarArgs()) {
-                continue;
-            }
-            String mappedStatementId = clazz.getName() + "." + method.getName();
-            if (AnnotationUtil.hasAnnotation(method, DataPermission.class)) {
-                dataPermission = AnnotationUtil.getAnnotation(method, DataPermission.class);
-                dataPermissionCacheMap.put(mappedStatementId, dataPermission);
-            }
-        }
-        // 获取类注解
-        if (AnnotationUtil.hasAnnotation(clazz, DataPermission.class)) {
-            dataPermission = AnnotationUtil.getAnnotation(clazz, DataPermission.class);
-            dataPermissionCacheMap.put(clazz.getName(), dataPermission);
-        }
-    }
 
-    /**
-     * 根据映射语句 ID 或类名获取对应的 DataPermission 注解对象
-     *
-     * @param mapperId 映射语句 ID
-     * @return DataPermission 注解对象,如果不存在则返回 null
-     */
-    public DataPermission getDataPermission(String mapperId) {
-        // 检查缓存中是否包含映射语句 ID 对应的 DataPermission 注解对象
-        if (dataPermissionCacheMap.containsKey(mapperId)) {
-            return dataPermissionCacheMap.get(mapperId);
-        }
-        // 如果缓存中不包含映射语句 ID 对应的 DataPermission 注解对象,则尝试使用类名作为键查找
-        String clazzName = mapperId.substring(0, mapperId.lastIndexOf("."));
-        if (dataPermissionCacheMap.containsKey(clazzName)) {
-            return dataPermissionCacheMap.get(clazzName);
-        }
-        return null;
-    }
 
     /**
      * 检查给定的映射语句 ID 是否有效,即是否能够找到对应的 DataPermission 注解对象
      *
-     * @param mapperId 映射语句 ID
      * @return 如果找到对应的 DataPermission 注解对象,则返回 false;否则返回 true
      */
-    public boolean invalid(String mapperId) {
-        return getDataPermission(mapperId) == null;
+    public boolean invalid() {
+        return DataPermissionHelper.getPermission() == null;
     }
 }

+ 29 - 0
SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/src/main/java/com/vber/common/mybatis/helper/DataPermissionHelper.java

@@ -7,6 +7,7 @@ import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy;
 import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
 import com.vber.common.core.utils.reflect.ReflectUtils;
+import com.vber.common.mybatis.annotation.DataPermission;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 
@@ -28,6 +29,34 @@ public class DataPermissionHelper {
 
     private static final ThreadLocal<Stack<Integer>> REENTRANT_IGNORE = ThreadLocal.withInitial(Stack::new);
 
+    private static final ThreadLocal<DataPermission> PERMISSION_CACHE = new ThreadLocal<>();
+
+    /**
+     * 获取当前执行mapper权限注解
+     *
+     * @return 返回当前执行mapper权限注解
+     */
+    public static DataPermission getPermission() {
+        return PERMISSION_CACHE.get();
+    }
+
+    /**
+     * 设置当前执行mapper权限注解
+     *
+     * @param dataPermission   数据权限注解
+     */
+    public static void setPermission(DataPermission dataPermission) {
+        PERMISSION_CACHE.set(dataPermission);
+    }
+
+    /**
+     * 删除当前执行mapper权限注解
+     */
+    public static void removePermission() {
+        PERMISSION_CACHE.remove();
+    }
+
+
     /**
      * 从上下文中获取指定键的变量值,并将其转换为指定的类型
      *

+ 4 - 6
SERVER/VberAdminPlusV3/vber-common/vber-common-mybatis/src/main/java/com/vber/common/mybatis/interceptor/PlusDataPermissionInterceptor.java

@@ -38,11 +38,9 @@ public class PlusDataPermissionInterceptor extends BaseMultiTableInnerIntercepto
 
     /**
      * 构造函数,初始化 PlusDataPermissionHandler 实例
-     *
-     * @param mapperPackage 扫描的映射器包
      */
-    public PlusDataPermissionInterceptor(String mapperPackage) {
-        this.dataPermissionHandler = new PlusDataPermissionHandler(mapperPackage);
+    public PlusDataPermissionInterceptor() {
+        this.dataPermissionHandler = new PlusDataPermissionHandler();
     }
 
     /**
@@ -63,7 +61,7 @@ public class PlusDataPermissionInterceptor extends BaseMultiTableInnerIntercepto
             return;
         }
         // 检查是否缺少有效的数据权限注解
-        if (dataPermissionHandler.invalid(ms.getId())) {
+        if (dataPermissionHandler.invalid()) {
             return;
         }
         // 解析 sql 分配对应方法
@@ -91,7 +89,7 @@ public class PlusDataPermissionInterceptor extends BaseMultiTableInnerIntercepto
                 return;
             }
             // 检查是否缺少有效的数据权限注解
-            if (dataPermissionHandler.invalid(ms.getId())) {
+            if (dataPermissionHandler.invalid()) {
                 return;
             }
             PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql();

+ 2 - 116
SERVER/VberAdminPlusV3/vber-common/vber-common-oss/src/main/java/com/vber/common/oss/core/OssClient.java

@@ -10,7 +10,6 @@ import com.vber.common.core.utils.file.FileUtils;
 import com.vber.common.oss.constant.OssConstant;
 import com.vber.common.oss.entity.UploadResult;
 import com.vber.common.oss.enumd.AccessPolicyType;
-import com.vber.common.oss.enumd.PolicyType;
 import com.vber.common.oss.exception.OssException;
 import com.vber.common.oss.file.VbFile;
 import com.vber.common.oss.properties.OssProperties;
@@ -27,7 +26,6 @@ import software.amazon.awssdk.services.s3.S3Configuration;
 import software.amazon.awssdk.services.s3.crt.S3CrtHttpConfiguration;
 import software.amazon.awssdk.services.s3.model.GetObjectResponse;
 import software.amazon.awssdk.services.s3.model.NoSuchBucketException;
-import software.amazon.awssdk.services.s3.model.S3Exception;
 import software.amazon.awssdk.services.s3.presigner.S3Presigner;
 import software.amazon.awssdk.transfer.s3.S3TransferManager;
 import software.amazon.awssdk.transfer.s3.model.*;
@@ -88,9 +86,8 @@ public class OssClient {
                 StaticCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
                         AwsBasicCredentials.create(properties.getAccessKey(), properties.getSecretKey()));
                 //MinIO 使用 HTTPS 限制使用域名访问,站点填域名。需要启用路径样式访问
-//                boolean isStyle = !StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE);
-                boolean isStyle = true;
-                //创建AWS基于 CRT 的 S3 客户端
+                boolean isStyle = !StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE);
+                // 创建AWS基于 CRT 的 S3 客户端
                 client = S3AsyncClient.crtBuilder()
                         .credentialsProvider(credentialsProvider)
                         .endpointOverride(URI.create(getEndpoint()))
@@ -118,7 +115,6 @@ public class OssClient {
                         .serviceConfiguration(config)
                         .build();
 
-                createBucket();
             }
         } catch (Exception e) {
             if (e instanceof OssException) {
@@ -131,43 +127,6 @@ public class OssClient {
         this.presigner = presigner;
     }
 
-    /**
-     * 同步创建存储桶
-     * 如果存储桶不存在,会进行创建;如果存储桶存在,不执行任何操作
-     *
-     * @throws OssException 当创建存储桶时发生异常时抛出
-     */
-    public void createBucket() {
-        String bucketName = properties.getBucketName();
-        try {
-            // 尝试获取存储桶的信息
-            client.headBucket(
-                            x -> x.bucket(bucketName)
-                                    .build())
-                    .join();
-        } catch (Exception ex) {
-            if (ex.getCause() instanceof NoSuchBucketException) {
-                try {
-                    // 存储桶不存在,尝试创建存储桶
-                    client.createBucket(
-                                    x -> x.bucket(bucketName))
-                            .join();
-
-                    // 设置存储桶的访问策略(Bucket Policy)
-                    client.putBucketPolicy(
-                                    x -> x.bucket(bucketName)
-                                            .policy(getPolicy(bucketName, getAccessPolicy().getPolicyType())))
-                            .join();
-                } catch (S3Exception e) {
-                    // 存储桶创建或策略设置失败
-                    throw new OssException("创建Bucket失败, 请核对配置信息:[" + e.getMessage() + "]");
-                }
-            } else {
-                throw new OssException("判断Bucket是否存在失败,请核对配置信息:[" + ex.getMessage() + "]");
-            }
-        }
-    }
-
     /**
      * 上传文件到 Amazon S3,并返回上传结果
      *
@@ -714,79 +673,6 @@ public class OssClient {
     }
 
 
-    /**
-     * 生成 AWS S3 存储桶访问策略
-     *
-     * @param bucketName 存储桶
-     * @param policyType 桶策略类型
-     * @return 符合 AWS S3 存储桶访问策略格式的字符串
-     */
-    private static String getPolicy(String bucketName, PolicyType policyType) {
-        String policy = switch (policyType) {
-            case WRITE -> """
-                    {
-                      "Version": "2012-10-17",
-                      "Statement": []
-                    }
-                    """;
-            case READ_WRITE -> """
-                    {
-                      "Version": "2012-10-17",
-                      "Statement": [
-                        {
-                          "Effect": "Allow",
-                          "Principal": "*",
-                          "Action": [
-                            "s3:GetBucketLocation",
-                            "s3:ListBucket",
-                            "s3:ListBucketMultipartUploads"
-                          ],
-                          "Resource": "arn:aws:s3:::bucketName"
-                        },
-                        {
-                          "Effect": "Allow",
-                          "Principal": "*",
-                          "Action": [
-                            "s3:AbortMultipartUpload",
-                            "s3:DeleteObject",
-                            "s3:GetObject",
-                            "s3:ListMultipartUploadParts",
-                            "s3:PutObject"
-                          ],
-                          "Resource": "arn:aws:s3:::bucketName/*"
-                        }
-                      ]
-                    }
-                    """;
-            case READ -> """
-                    {
-                      "Version": "2012-10-17",
-                      "Statement": [
-                        {
-                          "Effect": "Allow",
-                          "Principal": "*",
-                          "Action": ["s3:GetBucketLocation"],
-                          "Resource": "arn:aws:s3:::bucketName"
-                        },
-                        {
-                          "Effect": "Deny",
-                          "Principal": "*",
-                          "Action": ["s3:ListBucket"],
-                          "Resource": "arn:aws:s3:::bucketName"
-                        },
-                        {
-                          "Effect": "Allow",
-                          "Principal": "*",
-                          "Action": "s3:GetObject",
-                          "Resource": "arn:aws:s3:::bucketName/*"
-                        }
-                      ]
-                    }
-                    """;
-        };
-        return policy.replaceAll("bucketName", bucketName);
-    }
-
 
     public boolean isLocal() {
         return LOCAL_ACCESS_KEY.equals(configKey);

+ 3 - 7
SERVER/VberAdminPlusV3/vber-common/vber-common-oss/src/main/java/com/vber/common/oss/enumd/AccessPolicyType.java

@@ -17,17 +17,17 @@ public enum AccessPolicyType {
     /**
      * private
      */
-    PRIVATE("0", BucketCannedACL.PRIVATE, ObjectCannedACL.PRIVATE, PolicyType.WRITE),
+    PRIVATE("0", BucketCannedACL.PRIVATE, ObjectCannedACL.PRIVATE),
 
     /**
      * public
      */
-    PUBLIC("1", BucketCannedACL.PUBLIC_READ_WRITE, ObjectCannedACL.PUBLIC_READ_WRITE, PolicyType.READ_WRITE),
+    PUBLIC("1", BucketCannedACL.PUBLIC_READ_WRITE, ObjectCannedACL.PUBLIC_READ_WRITE),
 
     /**
      * custom
      */
-    CUSTOM("2", BucketCannedACL.PUBLIC_READ, ObjectCannedACL.PUBLIC_READ, PolicyType.READ);
+    CUSTOM("2", BucketCannedACL.PUBLIC_READ, ObjectCannedACL.PUBLIC_READ);
 
     /**
      * 桶 权限类型(数据库值)
@@ -44,10 +44,6 @@ public enum AccessPolicyType {
      */
     private final ObjectCannedACL objectCannedACL;
 
-    /**
-     * 桶策略类型
-     */
-    private final PolicyType policyType;
 
     public static AccessPolicyType getByType(String type) {
         for (AccessPolicyType value : values()) {

+ 0 - 35
SERVER/VberAdminPlusV3/vber-common/vber-common-oss/src/main/java/com/vber/common/oss/enumd/PolicyType.java

@@ -1,35 +0,0 @@
-package com.vber.common.oss.enumd;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * minio策略配置
- *
- * @author Iwb
- */
-@Getter
-@AllArgsConstructor
-public enum PolicyType {
-
-    /**
-     * 只读
-     */
-    READ("read-only"),
-
-    /**
-     * 只写
-     */
-    WRITE("write-only"),
-
-    /**
-     * 读写
-     */
-    READ_WRITE("read-write");
-
-    /**
-     * 类型
-     */
-    private final String type;
-
-}

+ 6 - 0
SERVER/VberAdminPlusV3/vber-common/vber-common-ratelimiter/src/main/java/com/vber/common/ratelimiter/annotation/RateLimiter.java

@@ -38,4 +38,10 @@ public @interface RateLimiter {
      * 提示消息 支持国际化 格式为 {code}
      */
     String message() default "{rate.limiter.message}";
+
+    /**
+     * 限流策略超时时间 默认一天(策略存活时间 会清除已存在的策略数据)
+     */
+    int timeout() default 86400;
+
 }

+ 2 - 1
SERVER/VberAdminPlusV3/vber-common/vber-common-ratelimiter/src/main/java/com/vber/common/ratelimiter/aspectj/RateLimiterAspect.java

@@ -54,13 +54,14 @@ public class RateLimiterAspect {
     public void doBefore(JoinPoint point, RateLimiter rateLimiter) {
         int time = rateLimiter.time();
         int count = rateLimiter.count();
+        int timeout = rateLimiter.timeout();
         try {
             String combineKey = getCombineKey(rateLimiter, point);
             RateType rateType = RateType.OVERALL;
             if (rateLimiter.limitType() == LimitType.CLUSTER) {
                 rateType = RateType.PER_CLIENT;
             }
-            long number = RedisUtils.rateLimiter(combineKey, rateType, count, time);
+            long number = RedisUtils.rateLimiter(combineKey, rateType, count, time, timeout);
             if (number == -1) {
                 String message = rateLimiter.message();
                 if (StringUtils.startsWith(message, "{") && StringUtils.endsWith(message, "}")) {

+ 41 - 3
SERVER/VberAdminPlusV3/vber-common/vber-common-redis/src/main/java/com/vber/common/redis/utils/RedisUtils.java

@@ -4,6 +4,7 @@ import com.vber.common.core.utils.SpringUtils;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.redisson.api.*;
+import org.redisson.api.options.KeysScanOptions;
 
 import java.time.Duration;
 import java.util.Collection;
@@ -36,8 +37,22 @@ public class RedisUtils {
      * @return -1 表示失败
      */
     public static long rateLimiter(String key, RateType rateType, int rate, int rateInterval) {
+        return rateLimiter(key, rateType, rate, rateInterval, 0);
+    }
+
+    /**
+     * 限流
+     *
+     * @param key          限流key
+     * @param rateType     限流类型
+     * @param rate         速率
+     * @param rateInterval 速率间隔
+     * @param timeout      超时时间
+     * @return -1 表示失败
+     */
+    public static long rateLimiter(String key, RateType rateType, int rate, int rateInterval, int timeout) {
         RRateLimiter rateLimiter = CLIENT.getRateLimiter(key);
-        rateLimiter.trySetRate(rateType, rate, rateInterval, RateIntervalUnit.SECONDS);
+        rateLimiter.trySetRate(rateType, rate, Duration.ofSeconds(rateInterval), Duration.ofSeconds(timeout));
         if (rateLimiter.tryAcquire()) {
             return rateLimiter.availablePermits();
         } else {
@@ -519,12 +534,35 @@ public class RedisUtils {
     /**
      * 获得缓存的基本对象列表(全局匹配忽略租户 自行拼接租户id)
      *
+     * <P>
+     * limit-设置扫描的限制数量(默认为0,查询全部)
+     * pattern-设置键的匹配模式(默认为null)
+     * chunkSize-设置每次扫描的块大小(默认为0,本方法设置为1000)
+     * type-设置键的类型(默认为null,查询全部类型)
+     * </P>
+     *  @see KeysScanOptions
+     *
      * @param pattern 字符串前缀
      * @return 对象列表
      */
     public static Collection<String> keys(final String pattern) {
-        Stream<String> stream = CLIENT.getKeys().getKeysStreamByPattern(pattern);
-        return stream.collect(Collectors.toList());
+        return  keys(KeysScanOptions.defaults().pattern(pattern).chunkSize(1000));
+    }
+
+    /**
+     * 通过扫描参数获取缓存的基本对象列表
+     * @param keysScanOptions 扫描参数
+     * <P>
+     * limit-设置扫描的限制数量(默认为0,查询全部)
+     * pattern-设置键的匹配模式(默认为null)
+     * chunkSize-设置每次扫描的块大小(默认为0)
+     * type-设置键的类型(默认为null,查询全部类型)
+     * </P>
+     * @see KeysScanOptions
+     */
+    public static Collection<String> keys(final KeysScanOptions keysScanOptions) {
+        Stream<String> keysStream = CLIENT.getKeys().getKeysStream(keysScanOptions);
+        return keysStream.collect(Collectors.toList());
     }
 
     /**

+ 1 - 1
SERVER/VberAdminPlusV3/vber-common/vber-common-sms/src/main/java/com/vber/common/sms/core/dao/PlusSmsDao.java

@@ -66,7 +66,7 @@ public class PlusSmsDao implements SmsDao {
      */
     @Override
     public void clean() {
-        RedisUtils.deleteObject(GlobalConstants.GLOBAL_REDIS_KEY + "sms:");
+        RedisUtils.deleteKeys(GlobalConstants.GLOBAL_REDIS_KEY + "sms:*");
     }
 
 }

+ 3 - 1
SERVER/VberAdminPlusV3/vber-common/vber-common-sse/src/main/java/com/vber/common/sse/core/SseEmitterManager.java

@@ -67,7 +67,9 @@ public class SseEmitterManager {
         Map<String, SseEmitter> emitters = USER_TOKEN_EMITTERS.get(userId);
         if (emitters != null) {
             try {
-                emitters.get(token).send(SseEmitter.event().comment("disconnected"));
+                SseEmitter sseEmitter = emitters.get(token);
+                sseEmitter.send(SseEmitter.event().comment("disconnected"));
+                sseEmitter.complete();
             } catch (Exception ignore) {
             }
             emitters.remove(token);

+ 2 - 4
SERVER/VberAdminPlusV3/vber-common/vber-common-tenant/src/main/java/com/vber/common/tenant/config/TenantConfig.java

@@ -16,7 +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.ConditionalOnBean;
+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;
@@ -33,9 +33,7 @@ import org.springframework.context.annotation.Primary;
 @ConditionalOnProperty(value = "tenant.enable", havingValue = "true")
 public class TenantConfig {
 
-
-    @ConditionalOnBean(MybatisPlusConfig.class)
-    @AutoConfiguration(after = {MybatisPlusConfig.class})
+    @AutoConfiguration
     static class MybatisPlusConfiguration {
 
         /**

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

@@ -27,8 +27,12 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
         if (StringUtils.isBlank(name)) {
             return null;
         }
-        if (InterceptorIgnoreHelper.willIgnoreTenantLine("")) {
-            return super.map(name);
+        try {
+            if (InterceptorIgnoreHelper.willIgnoreTenantLine("")) {
+                return super.map(name);
+            }
+        } catch (NoClassDefFoundError ignore) {
+            // 有些服务不需要mp导致类不存在 忽略即可
         }
         if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
             return super.map(name);
@@ -54,8 +58,12 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
         if (StringUtils.isBlank(unmap)) {
             return null;
         }
-        if (InterceptorIgnoreHelper.willIgnoreTenantLine("")) {
-            return super.map(name);
+        try {
+            if (InterceptorIgnoreHelper.willIgnoreTenantLine("")) {
+                return super.unmap(name);
+            }
+        } catch (NoClassDefFoundError ignore) {
+            // 有些服务不需要mp导致类不存在 忽略即可
         }
         if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
             return super.unmap(name);

+ 1 - 1
SERVER/VberAdminPlusV3/vber-common/vber-common-translation/src/main/java/com/vber/common/translation/core/handler/TranslationHandler.java

@@ -39,7 +39,7 @@ public class TranslationHandler extends JsonSerializer<Object> implements Contex
         if (ObjectUtil.isNotNull(trans)) {
             // 如果映射字段不为空 则取映射字段的值
             if (StringUtils.isNotBlank(translation.mapper())) {
-                value = ReflectUtils.invokeGetter(gen.getCurrentValue(), translation.mapper());
+                value = ReflectUtils.invokeGetter(gen.currentValue(), translation.mapper());
             }
             // 如果为 null 直接写出
             if (ObjectUtil.isNull(value)) {

+ 3 - 2
SERVER/VberAdminPlusV3/vber-modules/vber-generator/src/main/java/com/vber/generator/service/GenTableServiceImpl.java

@@ -148,7 +148,8 @@ public class GenTableServiceImpl implements IGenTableService {
                 .like(StringUtils.isNotBlank(genTable.getTableName()), "lower(table_name)", StringUtils.lowerCase(genTable.getTableName()))
                 .like(StringUtils.isNotBlank(genTable.getTableComment()), "lower(table_comment)", StringUtils.lowerCase(genTable.getTableComment()))
                 .between(StringUtils.isNotEmpty(params.get("beginTime")) && StringUtils.isNotEmpty(params.get("endTime")),
-                        "create_time", params.get("beginTime"), params.get("endTime"));
+                        "create_time", params.get("beginTime"), params.get("endTime"))
+                .orderByAsc("table_id");
         return wrapper;
     }
 
@@ -314,7 +315,7 @@ public class GenTableServiceImpl implements IGenTableService {
         try {
             for (GenTable table : tableList) {
                 String tableName = table.getTableName();
-                GenUtils.initTable(table, operId);
+                GenUtils.initTable(table);
                 table.setDataName(dataName);
                 int row = baseMapper.insert(table);
                 if (row > 0) {

+ 1 - 2
SERVER/VberAdminPlusV3/vber-modules/vber-generator/src/main/java/com/vber/generator/util/GenUtils.java

@@ -22,14 +22,13 @@ public class GenUtils {
     /**
      * 初始化表信息
      */
-    public static void initTable(GenTable genTable, Long operId) {
+    public static void initTable(GenTable genTable) {
         genTable.setClassName(convertClassName(genTable.getTableName()));
         genTable.setPackageName(GenConfig.getPackageName());
         genTable.setModuleName(getModuleName(GenConfig.getPackageName()));
         genTable.setBusinessName(getBusinessName(genTable.getTableName()));
         genTable.setFunctionName(replaceText(genTable.getTableComment()));
         genTable.setFunctionAuthor(GenConfig.getAuthor());
-        genTable.setCreateBy(operId);
     }
 
     /**

+ 12 - 9
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/controller/system/SysUserController.java

@@ -136,21 +136,24 @@ public class SysUserController extends BaseController {
     @SaCheckPermission("system:user:query")
     @GetMapping(value = {"/", "/{userId}"})
     public R<SysUserInfoVo> getInfo(@PathVariable(value = "userId", required = false) Long userId) {
-        userService.checkUserDataScope(userId);
         SysUserInfoVo userInfoVo = new SysUserInfoVo();
-        SysRoleBo roleBo = new SysRoleBo();
-        roleBo.setStatus(UserConstants.ROLE_NORMAL);
-        SysPostBo postBo = new SysPostBo();
-        postBo.setStatus(UserConstants.POST_NORMAL);
-        List<SysRoleVo> roles = roleService.selectRoleList(roleBo);
-        userInfoVo.setRoles(LoginHelper.isSuperAdmin(userId) || LoginHelper.isSuperSystem(userId) ? roles : StreamUtils.filter(roles, r -> !r.isSuperAdmin()));
-        userInfoVo.setPosts(postService.selectPostList(postBo));
         if (ObjectUtil.isNotNull(userId)) {
+            userService.checkUserDataScope(userId);
             SysUserVo sysUser = userService.selectUserById(userId);
             userInfoVo.setUser(sysUser);
             userInfoVo.setRoleIds(StreamUtils.toList(sysUser.getRoles(), SysRoleVo::getRoleId));
-            userInfoVo.setPostIds(postService.selectPostListByUserId(userId));
+            Long orgId = sysUser.getOrgId();
+            if (ObjectUtil.isNotNull(orgId)) {
+                SysPostBo postBo = new SysPostBo();
+                postBo.setOrgId(orgId);
+                userInfoVo.setPosts(postService.selectPostList(postBo));
+                userInfoVo.setPostIds(postService.selectPostListByUserId(userId));
+            }
         }
+        SysRoleBo roleBo = new SysRoleBo();
+        roleBo.setStatus(UserConstants.ROLE_NORMAL);
+        List<SysRoleVo> roles = roleService.selectRoleList(roleBo);
+        userInfoVo.setRoles(LoginHelper.isSuperAdmin(userId) || LoginHelper.isSuperSystem(userId) ? roles : StreamUtils.filter(roles, r -> !r.isSuperAdmin()));
         return R.ok(userInfoVo);
     }
 

+ 6 - 0
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/mapper/SysDictDataMapper.java

@@ -16,6 +16,12 @@ import java.util.List;
 @Repository
 public interface SysDictDataMapper extends BaseMapperPlus<SysDictData, SysDictDataVo> {
 
+    /**
+     * 根据字典类型查询字典数据列表
+     *
+     * @param dictType 字典类型
+     * @return 符合条件的字典数据列表
+     */
     default List<SysDictDataVo> selectDictDataByType(String dictType) {
         return selectVoList(
                 new LambdaQueryWrapper<SysDictData>()

+ 19 - 0
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/mapper/SysOrgMapper.java

@@ -1,10 +1,12 @@
 package com.vber.system.mapper;
 
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Constants;
 import com.vber.common.mybatis.annotation.DataColumn;
 import com.vber.common.mybatis.annotation.DataPermission;
 import com.vber.common.mybatis.core.mapper.BaseMapperPlus;
+import com.vber.common.mybatis.helper.DataBaseHelper;
 import com.vber.system.domain.SysOrg;
 import com.vber.system.domain.vo.SysOrgVo;
 import org.apache.ibatis.annotations.Param;
@@ -31,11 +33,28 @@ public interface SysOrgMapper extends BaseMapperPlus<SysOrg, SysOrgVo> {
     })
     List<SysOrgVo> selectOrgList(@Param(Constants.WRAPPER) Wrapper<SysOrg> queryWrapper);
 
+    /**
+     * 统计指定组织机构ID的组织机构数量
+     *
+     * @param orgId 组织机构ID
+     * @return 该组织机构ID的组织机构数量
+     */
     @DataPermission({
             @DataColumn(key = "orgName", value = "org_id")
     })
     long countOrgById(Long orgId);
 
+    /**
+     * 根据父组织机构ID查询其所有子组织机构的列表
+     *
+     * @param parentId 父组织机构ID
+     * @return 包含子组织机构的列表
+     */
+    default List<SysOrg> selectListByParentId(Long parentId) {
+        return this.selectList(new LambdaQueryWrapper<SysOrg>()
+                .select(SysOrg::getOrgId)
+                .apply(DataBaseHelper.findInSet(parentId, "ancestors")));
+    }
     /**
      * 根据角色ID查询组织机构树信息
      *

+ 8 - 1
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/mapper/SysPostMapper.java

@@ -21,8 +21,15 @@ import java.util.List;
 @Repository
 public interface SysPostMapper extends BaseMapperPlus<SysPost, SysPostVo> {
 
+    /**
+     * 分页查询岗位列表
+     *
+     * @param page         分页对象
+     * @param queryWrapper 查询条件
+     * @return 包含岗位信息的分页结果
+     */
     @DataPermission({
-            @DataColumn(key = "deptName", value = "dept_id"),
+            @DataColumn(key = "orgName", value = "org_id"),
             @DataColumn(key = "userName", value = "create_by")
     })
     Page<SysPostVo> selectPagePostList(@Param("page") Page<SysPostVo> page, @Param(Constants.WRAPPER) Wrapper<SysPost> queryWrapper);

+ 13 - 0
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/mapper/SysRoleMapper.java

@@ -21,6 +21,13 @@ import java.util.List;
 @Repository
 public interface SysRoleMapper extends BaseMapperPlus<SysRole, SysRoleVo> {
 
+    /**
+     * 分页查询角色列表
+     *
+     * @param page         分页对象
+     * @param queryWrapper 查询条件
+     * @return 包含角色信息的分页结果
+     */
     @DataPermission({
             @DataColumn(key = "orgName", value = "d.org_id"),
             @DataColumn(key = "userName", value = "r.create_by")
@@ -39,6 +46,12 @@ public interface SysRoleMapper extends BaseMapperPlus<SysRole, SysRoleVo> {
     })
     List<SysRoleVo> selectRoleList(@Param(Constants.WRAPPER) Wrapper<SysRole> queryWrapper);
 
+    /**
+     * 根据角色ID查询角色信息
+     *
+     * @param roleId 角色ID
+     * @return 对应的角色信息
+     */
     @DataPermission({
             @DataColumn(key = "orgName", value = "d.org_id"),
             @DataColumn(key = "userName", value = "r.create_by")

+ 24 - 4
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/mapper/SysUserMapper.java

@@ -22,6 +22,13 @@ import java.util.List;
 @Repository
 public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
 
+    /**
+     * 分页查询用户列表,并进行数据权限控制
+     *
+     * @param page         分页参数
+     * @param queryWrapper 查询条件
+     * @return 分页的用户信息
+     */
     @DataPermission({
             @DataColumn(key = "orgName", value = "u.org_id"),
             @DataColumn(key = "userName", value = "u.user_id")
@@ -29,10 +36,10 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
     Page<SysUserVo> selectPageUserList(@Param("page") Page<SysUser> page, @Param(Constants.WRAPPER) Wrapper<SysUser> queryWrapper);
 
     /**
-     * 根据条件分页查询用户列表
+     * 查询用户列表,并进行数据权限控制
      *
      * @param queryWrapper 查询条件
-     * @return 用户信息集合信息
+     * @return 用户信息集合
      */
     @DataPermission({
             @DataColumn(key = "orgName", value = "org_id"),
@@ -78,10 +85,10 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
 
 
     /**
-     * 通过用户ID查询用户
+     * 根据用户ID统计用户数量
      *
      * @param userId 用户ID
-     * @return 用户对象信息
+     * @return 用户数量
      */
     @DataPermission({
             @DataColumn(key = "orgName", value = "org_id"),
@@ -89,6 +96,13 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
     })
     long countUserById(Long userId);
 
+    /**
+     * 根据条件更新用户数据
+     *
+     * @param user          要更新的用户实体
+     * @param updateWrapper 更新条件封装器
+     * @return 更新操作影响的行数
+     */
     @Override
     @DataPermission({
             @DataColumn(key = "orgName", value = "org_id"),
@@ -96,6 +110,12 @@ public interface SysUserMapper extends BaseMapperPlus<SysUser, SysUserVo> {
     })
     int update(@Param(Constants.ENTITY) SysUser user, @Param(Constants.WRAPPER) Wrapper<SysUser> updateWrapper);
 
+    /**
+     * 根据用户ID更新用户数据
+     *
+     * @param user 要更新的用户实体
+     * @return 更新操作影响的行数
+     */
     @Override
     @DataPermission({
             @DataColumn(key = "orgName", value = "org_id"),

+ 6 - 0
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/mapper/SysUserRoleMapper.java

@@ -14,6 +14,12 @@ import java.util.List;
 @Repository
 public interface SysUserRoleMapper extends BaseMapperPlus<SysUserRole, SysUserRole> {
 
+    /**
+     * 根据角色ID查询关联的用户ID列表
+     *
+     * @param roleId 角色ID
+     * @return 关联到指定角色的用户ID列表
+     */
     List<Long> selectUserIdsByRoleId(Long roleId);
 
 }

+ 1 - 0
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/ISysRoleService.java

@@ -198,4 +198,5 @@ public interface ISysRoleService {
     int insertAuthUsers(Long roleId, Long[] userIds);
 
     void cleanOnlineUserByRole(Long roleId);
+    void cleanOnlineUser(List<Long> userIds);
 }

+ 1 - 3
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/impl/SysDataScopeServiceImpl.java

@@ -63,9 +63,7 @@ public class SysDataScopeServiceImpl implements ISysDataScopeService {
         if (ObjectUtil.isNull(orgId)) {
             return "-1";
         }
-        List<SysOrg> orgList = orgMapper.selectList(new LambdaQueryWrapper<SysOrg>()
-                .select(SysOrg::getOrgId)
-                .apply(DataBaseHelper.findInSet(orgId, "ancestors")));
+        List<SysOrg> orgList = orgMapper.selectListByParentId(orgId);
         List<Long> ids = StreamUtils.toList(orgList, SysOrg::getOrgId);
         ids.add(orgId);
         if (CollUtil.isNotEmpty(ids)) {

+ 22 - 10
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/impl/SysOrgServiceImpl.java

@@ -11,10 +11,7 @@ import com.vber.common.core.constant.CacheNames;
 import com.vber.common.core.constant.UserConstants;
 import com.vber.common.core.exception.ServiceException;
 import com.vber.common.core.service.OrgService;
-import com.vber.common.core.utils.MapstructUtils;
-import com.vber.common.core.utils.SpringUtils;
-import com.vber.common.core.utils.StringUtils;
-import com.vber.common.core.utils.TreeBuildUtils;
+import com.vber.common.core.utils.*;
 import com.vber.common.mybatis.helper.DataBaseHelper;
 import com.vber.common.redis.utils.CacheUtils;
 import com.vber.common.satoken.utils.LoginHelper;
@@ -102,11 +99,23 @@ public class SysOrgServiceImpl implements ISysOrgService, OrgService {
         if (CollUtil.isEmpty(orgs)) {
             return CollUtil.newArrayList();
         }
-        return TreeBuildUtils.build(orgs, (org, tree) ->
-                tree.setId(org.getOrgId())
-                        .setParentId(org.getParentId())
-                        .setName(org.getOrgName())
-                        .setWeight(org.getOrderNum()));
+
+        // 获取当前列表中每一个节点的parentId,然后在列表中查找是否有id与其parentId对应,若无对应,则表明此时节点列表中,该节点在当前列表中属于顶级节点
+        List<Tree<Long>> treeList = CollUtil.newArrayList();
+        for (SysOrgVo d : orgs) {
+            Long parentId = d.getParentId();
+            SysOrgVo sysOrgVo = StreamUtils.findFirst(orgs, it -> it.getOrgId().longValue() == parentId);
+            if (ObjectUtil.isNull(sysOrgVo)) {
+                List<Tree<Long>> trees = TreeBuildUtils.build(orgs, parentId, (dept, tree) ->
+                        tree.setId(dept.getOrgId())
+                                .setParentId(dept.getParentId())
+                                .setName(dept.getOrgName())
+                                .setWeight(dept.getOrderNum()));
+                Tree<Long> tree = trees.stream().filter(it -> it.getId().longValue() == d.getOrgId()).findFirst().get();
+                treeList.add(tree);
+            }
+        }
+        return treeList;
     }
 
     /**
@@ -265,11 +274,14 @@ public class SysOrgServiceImpl implements ISysOrgService, OrgService {
     public int updateOrg(SysOrgBo bo) {
         SysOrg org = MapstructUtils.convert(bo, SysOrg.class);
         SysOrg oldOrg = baseMapper.selectById(org.getOrgId());
+        if (ObjectUtil.isNull(oldOrg)) {
+            throw new ServiceException("组织机构不存在,无法修改");
+        }
         if (!oldOrg.getParentId().equals(org.getParentId())) {
             // 如果是新父组织机构 则校验是否具有新父组织机构权限 避免越权
             this.checkOrgDataScope(org.getParentId());
             SysOrg newParentOrg = baseMapper.selectById(org.getParentId());
-            if (ObjectUtil.isNotNull(newParentOrg) && ObjectUtil.isNotNull(oldOrg)) {
+            if (ObjectUtil.isNotNull(newParentOrg)) {
                 String newAncestors = newParentOrg.getAncestors() + StringUtils.SEPARATOR + newParentOrg.getOrgId();
                 String oldAncestors = oldOrg.getAncestors();
                 org.setAncestors(newAncestors);

+ 2 - 6
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/impl/SysPostServiceImpl.java

@@ -72,12 +72,8 @@ public class SysPostServiceImpl implements ISysPostService {
         } else if (ObjectUtil.isNotNull(bo.getBelongOrgId())) {
             //组织机构树搜索
             wrapper.and(x -> {
-                List<Long> orgIds = orgMapper.selectList(new LambdaQueryWrapper<SysOrg>()
-                                .select(SysOrg::getOrgId)
-                                .apply(DataBaseHelper.findInSet(bo.getBelongOrgId(), "ancestors")))
-                        .stream()
-                        .map(SysOrg::getOrgId)
-                        .collect(Collectors.toList());
+                List<SysOrg> deptList = orgMapper.selectListByParentId(bo.getBelongOrgId());
+                List<Long> orgIds = StreamUtils.toList(deptList, SysOrg::getOrgId);
                 orgIds.add(bo.getBelongOrgId());
                 x.in(SysPost::getOrgId, orgIds);
             });

+ 36 - 5
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/impl/SysRoleServiceImpl.java

@@ -435,7 +435,7 @@ public class SysRoleServiceImpl implements ISysRoleService {
                 .eq(SysUserRole::getRoleId, userRole.getRoleId())
                 .eq(SysUserRole::getUserId, userRole.getUserId()));
         if (rows > 0) {
-            cleanOnlineUserByRole(userRole.getRoleId());
+            cleanOnlineUser(List.of(userRole.getUserId()));
         }
         return rows;
     }
@@ -449,11 +449,12 @@ public class SysRoleServiceImpl implements ISysRoleService {
      */
     @Override
     public int deleteAuthUsers(Long roleId, Long[] userIds) {
+        List<Long> ids = List.of(userIds);
         int rows = userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
                 .eq(SysUserRole::getRoleId, roleId)
-                .in(SysUserRole::getUserId, Arrays.asList(userIds)));
+                .in(SysUserRole::getUserId, ids));
         if (rows > 0) {
-            cleanOnlineUserByRole(roleId);
+            cleanOnlineUser(ids);
         }
         return rows;
     }
@@ -469,7 +470,8 @@ public class SysRoleServiceImpl implements ISysRoleService {
     public int insertAuthUsers(Long roleId, Long[] userIds) {
         // 新增用户与角色管理
         int rows = 1;
-        List<SysUserRole> list = StreamUtils.toList(List.of(userIds), userId -> {
+        List<Long> ids = List.of(userIds);
+        List<SysUserRole> list = StreamUtils.toList(ids, userId -> {
             SysUserRole ur = new SysUserRole();
             ur.setUserId(userId);
             ur.setRoleId(roleId);
@@ -479,7 +481,7 @@ public class SysRoleServiceImpl implements ISysRoleService {
             rows = userRoleMapper.insertBatch(list) ? list.size() : 0;
         }
         if (rows > 0) {
-            cleanOnlineUserByRole(roleId);
+            cleanOnlineUser(ids);
         }
         return rows;
     }
@@ -503,6 +505,9 @@ public class SysRoleServiceImpl implements ISysRoleService {
                 return;
             }
             LoginUser loginUser = LoginHelper.getLoginUser(token);
+            if (ObjectUtil.isNull(loginUser) || CollUtil.isEmpty(loginUser.getRoles())) {
+                return;
+            }
             if (loginUser.getRoles().stream().anyMatch(r -> r.getRoleId().equals(roleId))) {
                 try {
                     StpUtil.logoutByTokenValue(token);
@@ -511,4 +516,30 @@ public class SysRoleServiceImpl implements ISysRoleService {
             }
         });
     }
+
+    @Override
+    public void cleanOnlineUser(List<Long> userIds) {
+        List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
+        if (CollUtil.isEmpty(keys)) {
+            return;
+        }
+        // 角色关联的在线用户量过大会导致redis阻塞卡顿 谨慎操作
+        keys.parallelStream().forEach(key -> {
+            String token = StringUtils.substringAfterLast(key, ":");
+            // 如果已经过期则跳过
+            if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) {
+                return;
+            }
+            LoginUser loginUser = LoginHelper.getLoginUser(token);
+            if (ObjectUtil.isNull(loginUser)) {
+                return;
+            }
+            if (userIds.contains(loginUser.getUserId())) {
+                try {
+                    StpUtil.logoutByTokenValue(token);
+                } catch (NotLoginException ignored) {
+                }
+            }
+        });
+    }
 }

+ 1 - 3
SERVER/VberAdminPlusV3/vber-modules/vber-system/src/main/java/com/vber/system/service/impl/SysUserServiceImpl.java

@@ -97,9 +97,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
                 .between(StringUtils.isNotEmpty(params.get("beginTime")) && StringUtils.isNotEmpty(params.get("endTime")),
                         "u.create_time", params.get("beginTime"), params.get("endTime"))
                 .and(ObjectUtil.isNotNull(user.getOrgId()), w -> {
-                    List<SysOrg> orgList = orgMapper.selectList(new LambdaQueryWrapper<SysOrg>()
-                            .select(SysOrg::getOrgId)
-                            .apply(DataBaseHelper.findInSet(user.getOrgId(), "ancestors")));
+                    List<SysOrg> orgList = orgMapper.selectListByParentId(user.getOrgId());
                     List<Long> ids = StreamUtils.toList(orgList, SysOrg::getOrgId);
                     ids.add(user.getOrgId());
                     w.in("u.org_id", ids);

+ 2 - 0
UI/VAP_V3.VUE/.env.development

@@ -31,3 +31,5 @@ VITE_APP_RSA_PRIVATE_KEY = 'MIIBOgIBAAJBAMbhuE0LLYvbgKxsxnDlv2YRLHNMjiGy3YI2PRvd
 VITE_APP_CLIENT_ID = '9579f8780cf24ae2959d03d11482b18a'
 # websocket 开关 默认使用sse推送
 VITE_APP_WEBSOCKET = false
+# sse 开关
+VITE_APP_SSE = true

+ 3 - 1
UI/VAP_V3.VUE/.env.production

@@ -31,4 +31,6 @@ VITE_APP_RSA_PRIVATE_KEY = 'MIIBOgIBAAJBAMbhuE0LLYvbgKxsxnDlv2YRLHNMjiGy3YI2PRvd
 VITE_APP_CLIENT_ID = '9579f8780cf24ae2959d03d11482b18a'
 
 # websocket 开关 默认使用sse推送
-VITE_APP_WEBSOCKET = false
+VITE_APP_WEBSOCKET = false
+# sse 开关
+VITE_APP_SSE = true

Разница между файлами не показана из-за своего большого размера
+ 1032 - 695
UI/VAP_V3.VUE/pnpm-lock.yaml


+ 3 - 1
UI/VAP_V3.VUE/src/core/utils/sse.ts

@@ -4,9 +4,11 @@ import appStore from "@s"
 
 // 初始化
 export const initSSE = (url: any) => {
-	if (import.meta.env.VITE_APP_WEBSOCKET === "true") {
+	if (import.meta.env.VITE_APP_WEBSOCKET === "true"||import.meta.env.VITE_APP_SSE === 'false') {
 		return
 	}
+
+
 	url =
 		url + "?Authorization=Bearer " + getToken() + "&ClientId=" + import.meta.env.VITE_APP_CLIENT_ID
 	const { data, error } = useEventSource(url, [], {

+ 0 - 0
UI/VAP_V3.VUE/src/views/system/log/operlog.vue → UI/VAP_V3.VUE/src/views/system/log/operLog.vue


Некоторые файлы не были показаны из-за большого количества измененных файлов