From 874287a4c02d0a980d8b97c4a691b4f37ec5e812 Mon Sep 17 00:00:00 2001
From: houzhongjian <houzhongyi@126.com>
Date: 星期二, 03 十二月 2024 08:47:04 +0800
Subject: [PATCH] 1、security模块ExpressionUrlAuthorizationConfigurer改为AuthorizeHttpRequestsConfigurer 2、全局registry.antMatchers改为registry.requestMatchers 3、增加积木报表

---
 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/logger/ErrorLogCleanJob.java                                   |   80 ++--
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/permission/MenuMapper.java                            |    5 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java |   10 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/app/AppMapper.java                                    |    1 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/oauth2/OAuth2OpenController.java               |   54 ++
 pom.xml                                                                                                                                              |   49 ++
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/tenant/TenantPackageDO.java                      |   14 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java    |   12 
 iailab-module-report/iailab-module-report-biz/pom.xml                                                                                                |   19 +
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/auth/AuthController.java                       |    1 
 iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/IailabWebSecurityConfigurerAdapter.java                   |   33 -
 iailab-module-report/iailab-module-report-biz/src/main/resources/application-dev.yaml                                                                |   17 
 iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/AuthorizeRequestsCustomizer.java                          |    3 
 iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/ReportServerApplication.java                                    |   12 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuService.java                             |    8 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/framework/security/config/SecurityConfiguration.java               |   18 
 iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/framework/security/config/SecurityConfiguration.java            |   21 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackageSaveReqVO.java |   12 
 iailab-module-bpm/iailab-module-bpm-biz/src/main/java/com/iailab/module/bpm/framework/security/config/SecurityConfiguration.java                     |   14 
 iailab-module-infra/iailab-module-infra-biz/pom.xml                                                                                                  |    8 
 iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/framework/security/config/SecurityConfiguration.java                  |   16 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuServiceImpl.java                         |   77 ++++
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/job/demo/DemoJob.java                                           |   62 +-
 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/framework/security/config/SecurityConfiguration.java               |   26 
 iailab-framework/iailab-common-websocket/src/main/java/com/iailab/framework/websocket/core/security/WebSocketAuthorizeRequestsCustomizer.java        |    6 
 /dev/null                                                                                                                                            |  113 -------
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/framework/security/config/SecurityConfiguration.java            |   18 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/app/AppServiceImpl.java                                 |    1 
 iailab-module-report/iailab-module-report-biz/src/main/resources/application.yaml                                                                    |   39 +-
 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/logger/AccessLogCleanJob.java                                  |   80 ++--
 iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/framework/jmreport/core/service/JmReportTokenServiceImpl.java   |    7 
 iailab-cloud/iailab-gateway/src/main/resources/application.yaml                                                                                      |    5 
 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/demo/DemoJob.java                                              |   62 +-
 33 files changed, 507 insertions(+), 396 deletions(-)

diff --git a/iailab-cloud/iailab-gateway/src/main/resources/application.yaml b/iailab-cloud/iailab-gateway/src/main/resources/application.yaml
index 6428717..0923fc7 100644
--- a/iailab-cloud/iailab-gateway/src/main/resources/application.yaml
+++ b/iailab-cloud/iailab-gateway/src/main/resources/application.yaml
@@ -83,7 +83,7 @@
         - id: report-jimu # 路由的编号(积木报表)
           uri: grayLb://report-server
           predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
-            - Path=/jmreport/**
+            - Path=/jmreport/**, /drag/**
         ## statistics-server 服务
         - id: statistics-admin-api # 路由的编号
           uri: grayLb://statistics-server
@@ -155,6 +155,9 @@
       - name: model-server
         service-name: model-server
         url: /admin-api/model/v3/api-docs
+      - name: report-server
+        service-name: report-server
+        url: /admin-api/report/v3/api-docs
 --- #################### 平台相关配置 ####################
 
 iailab:
diff --git a/iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/AuthorizeRequestsCustomizer.java b/iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/AuthorizeRequestsCustomizer.java
index 2badc7c..063c85e 100644
--- a/iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/AuthorizeRequestsCustomizer.java
+++ b/iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/AuthorizeRequestsCustomizer.java
@@ -4,6 +4,7 @@
 import org.springframework.core.Ordered;
 import org.springframework.security.config.Customizer;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
 import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
 
 import javax.annotation.Resource;
@@ -15,7 +16,7 @@
  * @author iailab
  */
 public abstract class AuthorizeRequestsCustomizer
-        implements Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry>, Ordered {
+        implements Customizer<AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry>, Ordered {
 
     @Resource
     private WebProperties webProperties;
diff --git a/iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/IailabWebSecurityConfigurerAdapter.java b/iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/IailabWebSecurityConfigurerAdapter.java
index cfd671d..4813ecf 100644
--- a/iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/IailabWebSecurityConfigurerAdapter.java
+++ b/iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/IailabWebSecurityConfigurerAdapter.java
@@ -126,26 +126,23 @@
         // 设置每个请求的权限
         httpSecurity
                 // ①:全局共享规则
-                .authorizeRequests()
-                // 1.1 静态资源,可匿名访问
-                .antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll()
-                // 1.2 设置 @PermitAll 无需认证
-                .antMatchers(HttpMethod.GET, permitAllUrls.get(HttpMethod.GET).toArray(new String[0])).permitAll()
-                .antMatchers(HttpMethod.POST, permitAllUrls.get(HttpMethod.POST).toArray(new String[0])).permitAll()
-                .antMatchers(HttpMethod.PUT, permitAllUrls.get(HttpMethod.PUT).toArray(new String[0])).permitAll()
-                .antMatchers(HttpMethod.DELETE, permitAllUrls.get(HttpMethod.DELETE).toArray(new String[0])).permitAll()
-                // 1.3 基于 iailab.security.permit-all-urls 无需认证
-                .antMatchers(securityProperties.getPermitAllUrls().toArray(new String[0])).permitAll()
-                // 1.4 设置 App API 无需认证
-                .antMatchers(buildAppApi("/**")).permitAll()
-                // 1.5 验证码captcha 允许匿名访问
-                .antMatchers("/captcha/get", "/captcha/check").permitAll()
+                .authorizeHttpRequests(c -> c
+                        // 1.1 静态资源,可匿名访问
+                        .requestMatchers(HttpMethod.GET, "/*.html", "/*.html", "/*.css", "/*.js").permitAll()
+                        // 1.2 设置 @PermitAll 无需认证
+                        .requestMatchers(HttpMethod.GET, permitAllUrls.get(HttpMethod.GET).toArray(new String[0])).permitAll()
+                        .requestMatchers(HttpMethod.POST, permitAllUrls.get(HttpMethod.POST).toArray(new String[0])).permitAll()
+                        .requestMatchers(HttpMethod.PUT, permitAllUrls.get(HttpMethod.PUT).toArray(new String[0])).permitAll()
+                        .requestMatchers(HttpMethod.DELETE, permitAllUrls.get(HttpMethod.DELETE).toArray(new String[0])).permitAll()
+                        .requestMatchers(HttpMethod.HEAD, permitAllUrls.get(HttpMethod.HEAD).toArray(new String[0])).permitAll()
+                        .requestMatchers(HttpMethod.PATCH, permitAllUrls.get(HttpMethod.PATCH).toArray(new String[0])).permitAll()
+                        // 1.3 基于 yudao.security.permit-all-urls 无需认证
+                        .requestMatchers(securityProperties.getPermitAllUrls().toArray(new String[0])).permitAll()
+                )
                 // ②:每个项目的自定义规则
-                .and().authorizeRequests(registry -> // 下面,循环设置自定义规则
-                        authorizeRequestsCustomizers.forEach(customizer -> customizer.customize(registry)))
+                .authorizeHttpRequests(c -> authorizeRequestsCustomizers.forEach(customizer -> customizer.customize(c)))
                 // ③:兜底规则,必须认证
-                .authorizeRequests()
-                .anyRequest().authenticated();
+                .authorizeHttpRequests(c -> c.anyRequest().authenticated());
 
         // 添加 Token Filter
         httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
diff --git a/iailab-framework/iailab-common-websocket/src/main/java/com/iailab/framework/websocket/core/security/WebSocketAuthorizeRequestsCustomizer.java b/iailab-framework/iailab-common-websocket/src/main/java/com/iailab/framework/websocket/core/security/WebSocketAuthorizeRequestsCustomizer.java
index ccb979d..bd760f5 100644
--- a/iailab-framework/iailab-common-websocket/src/main/java/com/iailab/framework/websocket/core/security/WebSocketAuthorizeRequestsCustomizer.java
+++ b/iailab-framework/iailab-common-websocket/src/main/java/com/iailab/framework/websocket/core/security/WebSocketAuthorizeRequestsCustomizer.java
@@ -4,7 +4,7 @@
 import com.iailab.framework.websocket.config.WebSocketProperties;
 import lombok.RequiredArgsConstructor;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
+import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
 
 /**
  * WebSocket 的权限自定义
@@ -17,8 +17,8 @@
     private final WebSocketProperties webSocketProperties;
 
     @Override
-    public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
-        registry.antMatchers(webSocketProperties.getPath()).permitAll();
+    public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
+        registry.requestMatchers(webSocketProperties.getPath()).permitAll();
     }
 
 }
diff --git a/iailab-module-bpm/iailab-module-bpm-biz/src/main/java/com/iailab/module/bpm/framework/security/config/SecurityConfiguration.java b/iailab-module-bpm/iailab-module-bpm-biz/src/main/java/com/iailab/module/bpm/framework/security/config/SecurityConfiguration.java
index df13daa..730ffae 100644
--- a/iailab-module-bpm/iailab-module-bpm-biz/src/main/java/com/iailab/module/bpm/framework/security/config/SecurityConfiguration.java
+++ b/iailab-module-bpm/iailab-module-bpm-biz/src/main/java/com/iailab/module/bpm/framework/security/config/SecurityConfiguration.java
@@ -4,7 +4,7 @@
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
+import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
 
 /**
  * Bpm 模块的 Security 配置
@@ -17,16 +17,16 @@
         return new AuthorizeRequestsCustomizer() {
 
             @Override
-            public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
+            public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
                 // TODO iailab:这个每个项目都需要重复配置,得捉摸有没通用的方案
                 // Swagger 接口文档
-                registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据
-                        .antMatchers("/swagger-ui.html").permitAll(); // Swagger UI
+                registry.requestMatchers("/v3/api-docs/**").permitAll() // 元数据
+                        .requestMatchers("/swagger-ui.html").permitAll(); // Swagger UI
                 // Druid 监控
-                registry.antMatchers("/druid/**").anonymous();
+                registry.requestMatchers("/druid/**").anonymous();
                 // Spring Boot Actuator 的安全配置
-                registry.antMatchers("/actuator").anonymous()
-                        .antMatchers("/actuator/**").anonymous();
+                registry.requestMatchers("/actuator").anonymous()
+                        .requestMatchers("/actuator/**").anonymous();
             }
 
         };
diff --git a/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/framework/security/config/SecurityConfiguration.java b/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/framework/security/config/SecurityConfiguration.java
index 1a406c4..474a23e 100644
--- a/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/framework/security/config/SecurityConfiguration.java
+++ b/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/framework/security/config/SecurityConfiguration.java
@@ -5,7 +5,7 @@
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
+import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
 
 /**
  * System 模块的 Security 配置
@@ -18,18 +18,18 @@
         return new AuthorizeRequestsCustomizer() {
 
             @Override
-            public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
+            public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
                 // TODO iailab:这个每个项目都需要重复配置,得捉摸有没通用的方案
                 // Swagger 接口文档
-                registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据
-                        .antMatchers("/swagger-ui.html").permitAll(); // Swagger UI
+                registry.requestMatchers("/v3/api-docs/**").permitAll() // 元数据
+                        .requestMatchers("/swagger-ui.html").permitAll(); // Swagger UI
                 // Druid 监控
-                registry.antMatchers("/druid/**").anonymous();
+                registry.requestMatchers("/druid/**").anonymous();
                 // Spring Boot Actuator 的安全配置
-                registry.antMatchers("/actuator").anonymous()
-                        .antMatchers("/actuator/**").anonymous();
+                registry.requestMatchers("/actuator").anonymous()
+                        .requestMatchers("/actuator/**").anonymous();
                 // RPC 服务的安全配置
-                registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll();
+                registry.requestMatchers(ApiConstants.PREFIX + "/**").permitAll();
             }
 
         };
diff --git a/iailab-module-infra/iailab-module-infra-biz/pom.xml b/iailab-module-infra/iailab-module-infra-biz/pom.xml
index 0bd2a06..c15acd2 100644
--- a/iailab-module-infra/iailab-module-infra-biz/pom.xml
+++ b/iailab-module-infra/iailab-module-infra-biz/pom.xml
@@ -82,10 +82,10 @@
         </dependency>
 
         <!-- Job 定时任务相关 -->
-        <dependency>
-            <groupId>com.iailab</groupId>
-            <artifactId>iailab-common-job</artifactId>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.iailab</groupId>-->
+<!--            <artifactId>iailab-common-job</artifactId>-->
+<!--        </dependency>-->
 
         <!-- 消息队列相关 -->
 <!--        <dependency>-->
diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/framework/security/config/SecurityConfiguration.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/framework/security/config/SecurityConfiguration.java
index 4731bd7..efec207 100644
--- a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/framework/security/config/SecurityConfiguration.java
+++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/framework/security/config/SecurityConfiguration.java
@@ -6,7 +6,7 @@
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
+import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
 
 /**
  * Infra 模块的 Security 配置
@@ -22,26 +22,26 @@
         return new AuthorizeRequestsCustomizer() {
 
             @Override
-            public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
+            public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
                 // Swagger 接口文档
-                registry.antMatchers("/v3/api-docs/**").permitAll()
-                        .antMatchers("/webjars/**").permitAll()
-                        .antMatchers("/swagger-ui").permitAll()
-                        .antMatchers("/swagger-ui/**").permitAll();
+                registry.requestMatchers("/v3/api-docs/**").permitAll()
+                        .requestMatchers("/webjars/**").permitAll()
+                        .requestMatchers("/swagger-ui").permitAll()
+                        .requestMatchers("/swagger-ui/**").permitAll();
                 // Spring Boot Actuator 的安全配置
-                registry.antMatchers("/actuator").anonymous()
-                        .antMatchers("/actuator/**").anonymous();
+                registry.requestMatchers("/actuator").permitAll()
+                        .requestMatchers("/actuator/**").permitAll();
                 // Druid 监控
-                registry.antMatchers("/druid/**").anonymous();
+                registry.requestMatchers("/druid/**").permitAll();
                 // Spring Boot Admin Server 的安全配置
-                registry.antMatchers(adminSeverContextPath).anonymous()
-                        .antMatchers(adminSeverContextPath + "/**").anonymous();
+                registry.requestMatchers(adminSeverContextPath).permitAll()
+                        .requestMatchers(adminSeverContextPath + "/**").permitAll();
                 // 文件读取
-                registry.antMatchers(buildAdminApi("/infra/file/*/get/**")).permitAll();
+                registry.requestMatchers(buildAdminApi("/infra/file/*/get/**")).permitAll();
 
                 // TODO iailab:这个每个项目都需要重复配置,得捉摸有没通用的方案
                 // RPC 服务的安全配置
-                registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll();
+                registry.requestMatchers(ApiConstants.PREFIX + "/**").permitAll();
             }
 
         };
diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/demo/DemoJob.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/demo/DemoJob.java
index 940d2ba..ac02b86 100644
--- a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/demo/DemoJob.java
+++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/demo/DemoJob.java
@@ -1,31 +1,31 @@
-package com.iailab.module.infra.job.demo;
-
-import com.iailab.framework.tenant.core.job.TenantJob;
-import com.xxl.job.core.handler.annotation.XxlJob;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-
-import java.util.Date;
-import java.util.concurrent.atomic.AtomicInteger;
-
-@Component
-public class DemoJob {
-
-    private Logger logger = LoggerFactory.getLogger(getClass());
-
-    private final AtomicInteger counts = new AtomicInteger();
-
-    private static final Object lock = new Object();
-
-
-    @XxlJob("demoJob")
-//    @TenantJob
-    public void execute() {
-        synchronized (lock) {
-            logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet());
-            System.out.println(new Date() + ": 我是基础设施定时任务");
-        }
-    }
-
-}
+//package com.iailab.module.infra.job.demo;
+//
+//import com.iailab.framework.tenant.core.job.TenantJob;
+//import com.xxl.job.core.handler.annotation.XxlJob;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.stereotype.Component;
+//
+//import java.util.Date;
+//import java.util.concurrent.atomic.AtomicInteger;
+//
+//@Component
+//public class DemoJob {
+//
+//    private Logger logger = LoggerFactory.getLogger(getClass());
+//
+//    private final AtomicInteger counts = new AtomicInteger();
+//
+//    private static final Object lock = new Object();
+//
+//
+//    @XxlJob("demoJob")
+////    @TenantJob
+//    public void execute() {
+//        synchronized (lock) {
+//            logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet());
+//            System.out.println(new Date() + ": 我是基础设施定时任务");
+//        }
+//    }
+//
+//}
diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/logger/AccessLogCleanJob.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/logger/AccessLogCleanJob.java
index fcd231f..d3cd136 100644
--- a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/logger/AccessLogCleanJob.java
+++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/logger/AccessLogCleanJob.java
@@ -1,40 +1,40 @@
-package com.iailab.module.infra.job.logger;
-
-import com.iailab.framework.tenant.core.aop.TenantIgnore;
-import com.iailab.module.infra.service.logger.ApiAccessLogService;
-import com.xxl.job.core.handler.annotation.XxlJob;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.Resource;
-
-/**
- * 物理删除 N 天前的访问日志的 Job
- *
- * @author j-sentinel
- */
-@Component
-@Slf4j
-public class AccessLogCleanJob {
-
-    @Resource
-    private ApiAccessLogService apiAccessLogService;
-
-    /**
-     * 清理超过(14)天的日志
-     */
-    private static final Integer JOB_CLEAN_RETAIN_DAY = 14;
-
-    /**
-     * 每次删除间隔的条数,如果值太高可能会造成数据库的压力过大
-     */
-    private static final Integer DELETE_LIMIT = 100;
-
-    @XxlJob("accessLogCleanJob")
-    @TenantIgnore
-    public void execute() {
-        Integer count = apiAccessLogService.cleanAccessLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT);
-        log.info("[execute][定时执行清理访问日志数量 ({}) 个]", count);
-    }
-
-}
+//package com.iailab.module.infra.job.logger;
+//
+//import com.iailab.framework.tenant.core.aop.TenantIgnore;
+//import com.iailab.module.infra.service.logger.ApiAccessLogService;
+//import com.xxl.job.core.handler.annotation.XxlJob;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.stereotype.Component;
+//
+//import javax.annotation.Resource;
+//
+///**
+// * 物理删除 N 天前的访问日志的 Job
+// *
+// * @author j-sentinel
+// */
+//@Component
+//@Slf4j
+//public class AccessLogCleanJob {
+//
+//    @Resource
+//    private ApiAccessLogService apiAccessLogService;
+//
+//    /**
+//     * 清理超过(14)天的日志
+//     */
+//    private static final Integer JOB_CLEAN_RETAIN_DAY = 14;
+//
+//    /**
+//     * 每次删除间隔的条数,如果值太高可能会造成数据库的压力过大
+//     */
+//    private static final Integer DELETE_LIMIT = 100;
+//
+//    @XxlJob("accessLogCleanJob")
+//    @TenantIgnore
+//    public void execute() {
+//        Integer count = apiAccessLogService.cleanAccessLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT);
+//        log.info("[execute][定时执行清理访问日志数量 ({}) 个]", count);
+//    }
+//
+//}
diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/logger/ErrorLogCleanJob.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/logger/ErrorLogCleanJob.java
index c67acd3..bd07df5 100644
--- a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/logger/ErrorLogCleanJob.java
+++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/job/logger/ErrorLogCleanJob.java
@@ -1,40 +1,40 @@
-package com.iailab.module.infra.job.logger;
-
-import com.iailab.framework.tenant.core.aop.TenantIgnore;
-import com.iailab.module.infra.service.logger.ApiErrorLogService;
-import com.xxl.job.core.handler.annotation.XxlJob;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.Resource;
-
-/**
- * 物理删除 N 天前的错误日志的 Job
- *
- * @author j-sentinel
- */
-@Slf4j
-@Component
-public class ErrorLogCleanJob {
-
-    @Resource
-    private ApiErrorLogService apiErrorLogService;
-
-    /**
-     * 清理超过(14)天的日志
-     */
-    private static final Integer JOB_CLEAN_RETAIN_DAY = 14;
-
-    /**
-     * 每次删除间隔的条数,如果值太高可能会造成数据库的压力过大
-     */
-    private static final Integer DELETE_LIMIT = 100;
-
-    @XxlJob("errorLogCleanJob")
-    @TenantIgnore
-    public void execute() {
-        Integer count = apiErrorLogService.cleanErrorLog(JOB_CLEAN_RETAIN_DAY,DELETE_LIMIT);
-        log.info("[execute][定时执行清理错误日志数量 ({}) 个]", count);
-    }
-
-}
+//package com.iailab.module.infra.job.logger;
+//
+//import com.iailab.framework.tenant.core.aop.TenantIgnore;
+//import com.iailab.module.infra.service.logger.ApiErrorLogService;
+//import com.xxl.job.core.handler.annotation.XxlJob;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.stereotype.Component;
+//
+//import javax.annotation.Resource;
+//
+///**
+// * 物理删除 N 天前的错误日志的 Job
+// *
+// * @author j-sentinel
+// */
+//@Slf4j
+//@Component
+//public class ErrorLogCleanJob {
+//
+//    @Resource
+//    private ApiErrorLogService apiErrorLogService;
+//
+//    /**
+//     * 清理超过(14)天的日志
+//     */
+//    private static final Integer JOB_CLEAN_RETAIN_DAY = 14;
+//
+//    /**
+//     * 每次删除间隔的条数,如果值太高可能会造成数据库的压力过大
+//     */
+//    private static final Integer DELETE_LIMIT = 100;
+//
+//    @XxlJob("errorLogCleanJob")
+//    @TenantIgnore
+//    public void execute() {
+//        Integer count = apiErrorLogService.cleanErrorLog(JOB_CLEAN_RETAIN_DAY,DELETE_LIMIT);
+//        log.info("[execute][定时执行清理错误日志数量 ({}) 个]", count);
+//    }
+//
+//}
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/framework/security/config/SecurityConfiguration.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/framework/security/config/SecurityConfiguration.java
index 1be6188..231094f 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/framework/security/config/SecurityConfiguration.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/framework/security/config/SecurityConfiguration.java
@@ -5,7 +5,7 @@
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
+import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
 
 /**
  * System 模块的 Security 配置
@@ -18,20 +18,20 @@
         return new AuthorizeRequestsCustomizer() {
 
             @Override
-            public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
+            public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
                 // TODO iailab:这个每个项目都需要重复配置,得捉摸有没通用的方案
                 // Swagger 接口文档
-                registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据
-                        .antMatchers("/swagger-ui.html").permitAll(); // Swagger UI
+                registry.requestMatchers("/v3/api-docs/**").permitAll() // 元数据
+                        .requestMatchers("/swagger-ui.html").permitAll(); // Swagger UI
                 // Druid 监控
-                registry.antMatchers("/druid/**").anonymous();
+                registry.requestMatchers("/druid/**").anonymous();
                 // Spring Boot Actuator 的安全配置
-                registry.antMatchers("/actuator").anonymous()
-                        .antMatchers("/actuator/**").anonymous();
+                registry.requestMatchers("/actuator").anonymous()
+                        .requestMatchers("/actuator/**").anonymous();
 
-                registry.antMatchers("/admin-api/model/pre/item/upload-model").anonymous();
+                registry.requestMatchers("/admin-api/model/pre/item/upload-model").anonymous();
                 // RPC 服务的安全配置
-                registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll();
+                registry.requestMatchers(ApiConstants.PREFIX + "/**").permitAll();
             }
 
         };
diff --git a/iailab-module-report/iailab-module-report-biz/pom.xml b/iailab-module-report/iailab-module-report-biz/pom.xml
index 56c235f..f2d23c6 100644
--- a/iailab-module-report/iailab-module-report-biz/pom.xml
+++ b/iailab-module-report/iailab-module-report-biz/pom.xml
@@ -105,6 +105,25 @@
             <groupId>org.jeecgframework.jimureport</groupId>
             <artifactId>jimureport-spring-boot-starter</artifactId>
         </dependency>
+        <!-- 积木仪表盘-->
+        <dependency>
+            <groupId>org.jeecgframework.jimureport</groupId>
+            <artifactId>jimureport-dashboard-spring-boot-starter</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>autopoi-web</artifactId>
+                    <groupId>org.jeecgframework</groupId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.jeecgframework.jimureport</groupId>
+                    <artifactId>jimureport-spring-boot-starter</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.github.jsqlparser</groupId>
+                    <artifactId>jsqlparser</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
         <!-- 单独依赖升级版本,解决低版本validator失败问题 -->
         <dependency>
             <groupId>xerces</groupId>
diff --git a/iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/ReportServerApplication.java b/iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/ReportServerApplication.java
index aaa70d4..000e028 100644
--- a/iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/ReportServerApplication.java
+++ b/iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/ReportServerApplication.java
@@ -6,25 +6,13 @@
 /**
  * 项目的启动类
  *
- * 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
- * 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
- * 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
- *
  * @author iailab
  */
 @SpringBootApplication
 public class ReportServerApplication {
 
     public static void main(String[] args) {
-        // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
-        // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
-        // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
-
         SpringApplication.run(ReportServerApplication.class, args);
-
-        // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
-        // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
-        // 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
     }
 
 }
diff --git a/iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/framework/jmreport/core/service/JmReportTokenServiceImpl.java b/iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/framework/jmreport/core/service/JmReportTokenServiceImpl.java
index 878b9e4..deae3de 100644
--- a/iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/framework/jmreport/core/service/JmReportTokenServiceImpl.java
+++ b/iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/framework/jmreport/core/service/JmReportTokenServiceImpl.java
@@ -133,6 +133,13 @@
 
     @Override
     public String[] getRoles(String token) {
+        // 设置租户上下文。原因是:/jmreport/** 纯前端地址,不会走 buildLoginUserByToken 逻辑
+        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
+        if (loginUser == null) {
+            return null;
+        }
+        TenantContextHolder.setTenantId(loginUser.getTenantId());
+
         // 参见文档 https://help.jeecg.com/jimureport/prodSafe.html 文档
         // 适配:如果是本系统的管理员,则转换成 jimu 报表的管理员
         Long userId = SecurityFrameworkUtils.getLoginUserId();
diff --git a/iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/framework/security/config/SecurityConfiguration.java b/iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/framework/security/config/SecurityConfiguration.java
index 825057b..7878f92 100644
--- a/iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/framework/security/config/SecurityConfiguration.java
+++ b/iailab-module-report/iailab-module-report-biz/src/main/java/com/iailab/module/report/framework/security/config/SecurityConfiguration.java
@@ -4,7 +4,7 @@
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
+import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
 
 /**
  * Report 模块的 Security 配置
@@ -17,20 +17,23 @@
         return new AuthorizeRequestsCustomizer() {
 
             @Override
-            public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
+            public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
                 // Swagger 接口文档
-                registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据
-                        .antMatchers("/swagger-ui.html").permitAll(); // Swagger UI
+                registry.requestMatchers("/v3/api-docs/**").permitAll()
+                        .requestMatchers("/webjars/**").permitAll()
+                        .requestMatchers("/swagger-ui").permitAll()
+                        .requestMatchers("/swagger-ui/**").permitAll();
                 // Spring Boot Actuator 的安全配置
-                registry.antMatchers("/actuator").anonymous()
-                        .antMatchers("/actuator/**").anonymous();
+                registry.requestMatchers("/actuator").permitAll()
+                        .requestMatchers("/actuator/**").permitAll();
                 // Druid 监控
-                registry.antMatchers("/druid/**").anonymous();
+                registry.requestMatchers("/druid/**").permitAll();
                 // 积木报表
-                registry.antMatchers("/jmreport/**").permitAll();
+                registry.requestMatchers("/jmreport/**").permitAll();
+                // 积木仪表盘排除
+                registry.requestMatchers("/drag/**").permitAll();
             }
 
         };
     }
-
 }
diff --git a/iailab-module-report/iailab-module-report-biz/src/main/resources/application-dev.yaml b/iailab-module-report/iailab-module-report-biz/src/main/resources/application-dev.yaml
index 4557792..82226cf 100644
--- a/iailab-module-report/iailab-module-report-biz/src/main/resources/application-dev.yaml
+++ b/iailab-module-report/iailab-module-report-biz/src/main/resources/application-dev.yaml
@@ -39,12 +39,12 @@
       primary: master
       datasource:
         master:
-          url: jdbc:mysql://127.0.0.1:3306/iailab_plat_system?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
+          url: jdbc:mysql://172.16.8.100:3306/iailab_jmreport?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
           username: root
           password: 123456
         slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
           lazy: true # 开启懒加载,保证启动速度
-          url: jdbc:mysql://127.0.0.1:3306/iailab-plat?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
+          url: jdbc:mysql://127.0.0.1:3306/jimureport?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
           username: root
           password: 123456
 
@@ -54,12 +54,6 @@
     port: 6379 # 端口
     database: 1 # 数据库索引
     password: 123456 # 密码,建议生产环境开启
-
---- #################### MQ 消息队列相关配置 ####################
-
---- #################### 定时任务相关配置 ####################
-
---- #################### 服务保障相关配置 ####################
 
 # Lock4j 配置项
 lock4j:
@@ -89,9 +83,4 @@
 
 # 平台配置项,设置当前项目所有自定义的配置
 iailab:
-  xss:
-    enable: false
-    exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
-      - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
-      - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
-  demo: true # 开启演示模式
+  demo: false # 开启演示模式
diff --git a/iailab-module-report/iailab-module-report-biz/src/main/resources/application-local.yaml b/iailab-module-report/iailab-module-report-biz/src/main/resources/application-local.yaml
deleted file mode 100644
index 74194a9..0000000
--- a/iailab-module-report/iailab-module-report-biz/src/main/resources/application-local.yaml
+++ /dev/null
@@ -1,113 +0,0 @@
---- #################### 数据库相关配置 ####################
-spring:
-  # 数据源配置项
-  autoconfigure:
-    exclude:
-      - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
-      - de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration # 禁用 Spring Boot Admin 的 Client 的自动配置
-  datasource:
-    druid: # Druid 【监控】相关的全局配置
-      web-stat-filter:
-        enabled: true
-      stat-view-servlet:
-        enabled: true
-        allow: # 设置白名单,不填则允许所有访问
-        url-pattern: /druid/*
-        login-username: # 控制台管理用户名和密码
-        login-password:
-      filter:
-        stat:
-          enabled: true
-          log-slow-sql: true # 慢 SQL 记录
-          slow-sql-millis: 100
-          merge-sql: true
-        wall:
-          config:
-            multi-statement-allow: true
-    dynamic: # 多数据源配置
-      druid: # Druid 【连接池】相关的全局配置
-        initial-size: 1 # 初始连接数
-        min-idle: 1 # 最小连接池数量
-        max-active: 20 # 最大连接池数量
-        max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
-        time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
-        min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
-        max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
-        validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
-        test-while-idle: true
-        test-on-borrow: false
-        test-on-return: false
-      primary: master
-      datasource:
-        master:
-          url: jdbc:mysql://127.0.0.1:3306/iailab-plat?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
-          #          url: jdbc:mysql://127.0.0.1:3306/iailab-plat?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai # MySQL Connector/J 5.X 连接的示例
-          #          url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例
-          #          url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
-          #          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro # SQLServer 连接的示例
-          #          url: jdbc:dm://10.211.55.4:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
-          username: root
-          password: 123456
-        #          username: sa # SQL Server 连接的示例
-        #          password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W # SQL Server 连接的示例
-        #          username: SYSDBA # DM 连接的示例
-        #          password: SYSDBA # DM 连接的示例
-        slave: # 模拟从库,可根据自己需要修改
-          lazy: true # 开启懒加载,保证启动速度
-          url: jdbc:mysql://127.0.0.1:3306/iailab-plat?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
-          username: root
-          password: 123456
-
-  # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
-  redis:
-    host: 127.0.0.1 # 地址
-    port: 6379 # 端口
-    database: 0 # 数据库索引
-    password: 123456 # 密码,建议生产环境开启
-
---- #################### MQ 消息队列相关配置 ####################
-
---- #################### 定时任务相关配置 ####################
-
---- #################### 服务保障相关配置 ####################
-
-# Lock4j 配置项
-lock4j:
-  acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
-  expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
-
---- #################### 监控相关配置 ####################
-
-# Actuator 监控端点的配置项
-management:
-  endpoints:
-    web:
-      base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
-      exposure:
-        include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
-
-# Spring Boot Admin 配置项
-spring:
-  boot:
-    admin:
-      # Spring Boot Admin Client 客户端的相关配置
-      client:
-        instance:
-          service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
-
-# 日志文件配置
-logging:
-  level:
-    # 配置自己写的 MyBatis Mapper 打印日志
-    com.iailab.module.report.dal.mysql: debug
-
---- #################### 平台相关配置 ####################
-
-# 平台配置项,设置当前项目所有自定义的配置
-iailab:
-  env: # 多环境的配置项
-    tag: ${HOSTNAME}
-  security:
-    mock-enable: true
-  access-log: # 访问日志的配置项
-    enable: false
diff --git a/iailab-module-report/iailab-module-report-biz/src/main/resources/application.yaml b/iailab-module-report/iailab-module-report-biz/src/main/resources/application.yaml
index acac737..bcd7382 100644
--- a/iailab-module-report/iailab-module-report-biz/src/main/resources/application.yaml
+++ b/iailab-module-report/iailab-module-report-biz/src/main/resources/application.yaml
@@ -34,9 +34,6 @@
     multipart:
       max-file-size: 16MB # 单个文件大小
       max-request-size: 32MB # 设置总上传的文件大小
-  mvc:
-    pathmatch:
-      matching-strategy: ANT_PATH_MATCHER # 解决 SpringFox 与 SpringBoot 2.6.x 不兼容的问题,参见 SpringFoxHandlerProviderBeanPostProcessor 类
 
   # Jackson 配置项
   jackson:
@@ -68,7 +65,7 @@
     path: /v3/api-docs
   swagger-ui:
     enabled: true # 2.1 是否开启 Swagger 文档的官方 UI 界面
-    path: /swagger-ui.html
+    path: /swagger-ui
   default-flat-param-object: true # 参见 https://doc.xiaominfo.com/docs/faq/v4/knife4j-parameterobject-flat-param 文档
 
 knife4j:
@@ -106,18 +103,6 @@
 # VO 转换(数据翻译)相关
 easy-trans:
   is-enable-global: true # 启用全局翻译(拦截所有 SpringMVC ResponseBody 进行自动翻译 )。如果对于性能要求很高可关闭此配置,或通过 @IgnoreTrans 忽略某个接口
-  is-enable-cloud: false # 禁用 TransType.RPC 微服务模式
-
---- #################### RPC 远程调用相关配置 ####################
-
---- #################### MQ 消息队列相关配置 ####################
-
---- #################### 定时任务相关配置 ####################
-
-# 积木报表配置
-jeecg:
-  jmreport:
-    saas-mode: tenant
 
 --- #################### 平台相关配置 ####################
 
@@ -137,6 +122,24 @@
     description: 提供管理员管理的所有功能
     version: ${iailab.info.version}
   tenant: # 多租户相关配置项
-    enable: false
+    enable: true
 
-debug: false
+jeecg:
+  uploadType: local
+  path:
+    upload: D:/DLUT/IailabPlat
+  #大屏报表参数设置
+  jmreport:
+    #多租户模式,默认值为空(created:按照创建人隔离、tenant:按照租户隔离) (v1.6.2+ 新增)
+    saasMode: tenant
+    # 平台上线安全配置(v1.6.2+ 新增)
+    firewall:
+      # 数据源安全 (开启后,不允许使用平台数据源、SQL解析加签并且不允许查询数据库)
+      dataSourceSafe: false
+      # 低代码开发模式(dev:开发模式,prod:发布模式—关闭在线报表设计功能,分配角色admin、lowdeveloper可以放开限制)
+      lowCodeMode: dev
+
+minidao :
+  base-package: org.jeecg.modules.jmreport.desreport.dao*, org.jeecg.modules.drag.dao*
+
+debug: true
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/auth/AuthController.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/auth/AuthController.java
index 1c3eb85..7c3a9ef 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/auth/AuthController.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/auth/AuthController.java
@@ -136,6 +136,7 @@
         Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId));
         List<MenuDO> menuList = menuService.getMenuList(menuIds);
         menuList = menuService.filterDisableMenus(menuList);
+        menuList = menuService.filterMenus(menuList, "system");
 
         // 2. 拼接结果返回
         return success(AuthConvert.INSTANCE.convert(user, roles, menuList));
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/oauth2/OAuth2OpenController.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/oauth2/OAuth2OpenController.java
index 0b3b283..0868d9e 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/oauth2/OAuth2OpenController.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/oauth2/OAuth2OpenController.java
@@ -83,9 +83,43 @@
      *
      * 注意,默认需要传递 client_id + client_secret 参数
      */
+    @PostMapping("/fast/token")
+    @PermitAll
+    @Operation(summary = "脚手架获得访问令牌", description = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用")
+    @Parameters({
+            @Parameter(name = "grant_type", required = true, description = "授权类型", example = "code"),
+            @Parameter(name = "code", description = "授权范围", example = "userinfo.read"),
+            @Parameter(name = "redirect_uri", description = "重定向 URI", example = "https://www.iocoder.cn"),
+            @Parameter(name = "state", description = "状态", example = "1"),
+            @Parameter(name = "username", example = "tudou"),
+            @Parameter(name = "password", example = "cai"), // 多个使用空格分隔
+            @Parameter(name = "scope", example = "user_info"),
+            @Parameter(name = "refresh_token", example = "123424233"),
+    })
+    public CommonResult<OAuth2OpenAccessTokenRespVO> FastAccessToken(HttpServletRequest request,
+                                                                     @RequestParam("grant_type") String grantType,
+                                                                     @RequestParam(value = "code", required = false) String code, // 授权码模式
+                                                                     @RequestParam(value = "redirect_uri", required = false) String redirectUri, // 授权码模式
+                                                                     @RequestParam(value = "state", required = false) String state, // 授权码模式
+                                                                     @RequestParam(value = "username", required = false) String username, // 密码模式
+                                                                     @RequestParam(value = "password", required = false) String password, // 密码模式
+                                                                     @RequestParam(value = "scope", required = false) String scope, // 密码模式
+                                                                     @RequestParam(value = "refresh_token", required = false) String refreshToken) { // 刷新模式
+        OAuth2AccessTokenDO accessTokenDO = getAccessToken(request, grantType, code, redirectUri, state, username, password, scope, refreshToken);
+        Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查
+        return success(OAuth2OpenConvert.INSTANCE.convert(accessTokenDO));
+    }
+
+    /**
+     * 对应 Spring Security OAuth 的 TokenEndpoint 类的 postAccessToken 方法
+     *
+     * 外部平台专用授权方式
+     *
+     * 注意,默认需要传递 client_id + client_secret 参数
+     */
     @PostMapping("/token")
     @PermitAll
-    @Operation(summary = "获得访问令牌", description = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用")
+    @Operation(summary = "外部平台获得访问令牌", description = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用")
     @Parameters({
             @Parameter(name = "grant_type", required = true, description = "授权类型", example = "code"),
             @Parameter(name = "code", description = "授权码", example = "asdfasdfasdf"),
@@ -105,6 +139,17 @@
                                                    @RequestParam(value = "password", required = false) String password, // 密码模式
                                                    @RequestParam(value = "scope", required = false) String scope, // 密码模式
                                                    @RequestParam(value = "refresh_token", required = false) String refreshToken) { // 刷新模式
+        OAuth2AccessTokenDO accessTokenDO = getAccessToken(request, grantType, code, redirectUri, state, username, password, scope, refreshToken);
+        Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查
+        Map<String, Object> map = new HashMap<>();
+        map.put("access_token", accessTokenDO.getAccessToken());
+        map.put("refresh_token", accessTokenDO.getRefreshToken());
+        map.put("expires_time", LocalDateTimeUtil.toEpochMilli(accessTokenDO.getExpiresTime()) / 1000L);
+        map.put("client_id", accessTokenDO.getClientId());
+        return map;
+    }
+
+    private OAuth2AccessTokenDO getAccessToken(HttpServletRequest request, String grantType, String code, String redirectUri, String state, String username, String password, String scope, String refreshToken) {
         List<String> scopes = OAuth2Utils.buildScopes(scope);
         // 1.1 校验授权类型
         OAuth2GrantTypeEnum grantTypeEnum = OAuth2GrantTypeEnum.getByGrantType(grantType);
@@ -139,12 +184,7 @@
                 throw new IllegalArgumentException("未知授权类型:" + grantType);
         }
         Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查
-        Map<String, Object> map = new HashMap<>();
-        map.put("access_token", accessTokenDO.getAccessToken());
-        map.put("refresh_token", accessTokenDO.getRefreshToken());
-        map.put("expires_time", LocalDateTimeUtil.toEpochMilli(accessTokenDO.getExpiresTime()) / 1000L);
-        map.put("client_id", accessTokenDO.getClientId());
-        return map;
+        return accessTokenDO;
     }
 
     @DeleteMapping("/token")
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java
index 9c6d7af..910da0d 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java
@@ -8,6 +8,7 @@
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.time.LocalDateTime;
+import java.util.List;
 
 import static com.iailab.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
@@ -23,6 +24,15 @@
     @Schema(description = "状态", example = "1")
     private Integer status;
 
+    @Schema(description = "套餐图标", example = "http://localhost/xxx")
+    private String icon;
+
+    @Schema(description = "套餐标签", example = "模型管理")
+    private List<String> labels;
+
+    @Schema(description = "描述", example = "好")
+    private String description;
+
     @Schema(description = "备注", example = "好")
     private String remark;
 
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java
index 8f15cdd..c582b93 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java
@@ -3,7 +3,10 @@
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
+import java.util.List;
 import java.util.Set;
 
 @Schema(description = "管理后台 - 租户套餐 Response VO")
@@ -16,6 +19,15 @@
     @Schema(description = "套餐名", requiredMode = Schema.RequiredMode.REQUIRED, example = "VIP")
     private String name;
 
+    @Schema(description = "套餐图标", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://localhost/xxx")
+    private String icon;
+
+    @Schema(description = "套餐标签", example = "模型管理")
+    private List<String> labels;
+
+    @Schema(description = "描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "好")
+    private String description;
+
     @Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     private Integer status;
 
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackageSaveReqVO.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackageSaveReqVO.java
index ebdef5c..2691ed5 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackageSaveReqVO.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/tenant/vo/packages/TenantPackageSaveReqVO.java
@@ -7,6 +7,7 @@
 
 import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
+import java.util.List;
 import java.util.Set;
 
 @Schema(description = "管理后台 - 租户套餐创建/修改 Request VO")
@@ -20,6 +21,17 @@
     @NotEmpty(message = "套餐名不能为空")
     private String name;
 
+    @Schema(description = "套餐图标", example = "http://localhost/xxx")
+    @NotEmpty(message = "套餐图标不能为空")
+    private String icon;
+
+    @Schema(description = "套餐标签", example = "模型管理")
+    private List<String> labels;
+
+    @Schema(description = "描述", example = "好")
+    @NotNull(message = "描述不能为空")
+    private String description;
+
     @Schema(description = "状态,参见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     @NotNull(message = "状态不能为空")
     @InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}")
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/tenant/TenantPackageDO.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/tenant/TenantPackageDO.java
index 7cef0a1..d61b819 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/tenant/TenantPackageDO.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/tenant/TenantPackageDO.java
@@ -8,6 +8,7 @@
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.*;
 
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -40,6 +41,19 @@
      */
     private Integer status;
     /**
+     * 套餐图标
+     */
+    private String icon;
+    /**
+     * 套餐标签
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<String> labels;
+    /**
+     * 套餐介绍
+     */
+    private String description;
+    /**
      * 备注
      */
     private String remark;
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/app/AppMapper.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/app/AppMapper.java
index 9698925..e839fdf 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/app/AppMapper.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/app/AppMapper.java
@@ -20,6 +20,7 @@
         return selectPage(reqVO, new LambdaQueryWrapperX<AppDO>()
                 .likeIfPresent(AppDO::getAppCode, reqVO.getAppCode())
                 .likeIfPresent(AppDO::getAppName, reqVO.getAppName())
+                .orderByDesc(AppDO::getType)
                 .orderByDesc(AppDO::getId));
     }
 }
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/permission/MenuMapper.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/permission/MenuMapper.java
index 670d3ed..9ac64d7 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/permission/MenuMapper.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/mysql/permission/MenuMapper.java
@@ -26,11 +26,10 @@
                 .eqIfPresent(MenuDO::getStatus, reqVO.getStatus()));
     }
 
-    default List<MenuDO> selectAppMenuList(Long tenantId, MenuListReqVO reqVO) {
+    default List<MenuDO> selectAppMenuList(MenuListReqVO reqVO) {
         return selectList(new LambdaQueryWrapperX<MenuDO>()
                 .likeIfPresent(MenuDO::getName, reqVO.getName())
-                .eqIfPresent(MenuDO::getStatus, reqVO.getStatus())
-                .eq(MenuDO::getTenantId, tenantId));
+                .eqIfPresent(MenuDO::getStatus, reqVO.getStatus()));
     }
 
     default List<MenuDO> selectListByPermission(String permission) {
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/framework/security/config/SecurityConfiguration.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/framework/security/config/SecurityConfiguration.java
index cefacbf..a5b0a04 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/framework/security/config/SecurityConfiguration.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/framework/security/config/SecurityConfiguration.java
@@ -5,7 +5,7 @@
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
+import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
 
 /**
  * System 模块的 Security 配置
@@ -18,18 +18,20 @@
         return new AuthorizeRequestsCustomizer() {
 
             @Override
-            public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
+            public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
                 // TODO iailab:这个每个项目都需要重复配置,得捉摸有没通用的方案
                 // Swagger 接口文档
-                registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据
-                        .antMatchers("/swagger-ui.html").permitAll(); // Swagger UI
+                registry.requestMatchers("/v3/api-docs/**").permitAll()
+                        .requestMatchers("/webjars/**").permitAll()
+                        .requestMatchers("/swagger-ui").permitAll()
+                        .requestMatchers("/swagger-ui/**").permitAll();
                 // Druid 监控
-                registry.antMatchers("/druid/**").anonymous();
+                registry.requestMatchers("/druid/**").permitAll();
                 // Spring Boot Actuator 的安全配置
-                registry.antMatchers("/actuator").anonymous()
-                        .antMatchers("/actuator/**").anonymous();
+                registry.requestMatchers("/actuator").permitAll()
+                        .requestMatchers("/actuator/**").permitAll();
                 // RPC 服务的安全配置
-                registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll();
+                registry.requestMatchers(ApiConstants.PREFIX + "/**").permitAll();
             }
 
         };
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/job/demo/DemoJob.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/job/demo/DemoJob.java
index e3bb964..3be6681 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/job/demo/DemoJob.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/job/demo/DemoJob.java
@@ -1,31 +1,31 @@
-package com.iailab.module.system.job.demo;
-
-import com.iailab.framework.tenant.core.job.TenantJob;
-import com.xxl.job.core.handler.annotation.XxlJob;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-
-import java.util.Date;
-import java.util.concurrent.atomic.AtomicInteger;
-
-@Component
-public class DemoJob {
-
-    private Logger logger = LoggerFactory.getLogger(getClass());
-
-    private final AtomicInteger counts = new AtomicInteger();
-
-    private static final Object lock = new Object();
-
-
-    @XxlJob("demoJob")
-    @TenantJob
-    public void execute() {
-        synchronized (lock) {
-            logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet());
-            System.out.println(new Date() + ": 我是系统定时任务");
-        }
-    }
-
-}
+//package com.iailab.module.system.job.demo;
+//
+//import com.iailab.framework.tenant.core.job.TenantJob;
+//import com.xxl.job.core.handler.annotation.XxlJob;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.stereotype.Component;
+//
+//import java.util.Date;
+//import java.util.concurrent.atomic.AtomicInteger;
+//
+//@Component
+//public class DemoJob {
+//
+//    private Logger logger = LoggerFactory.getLogger(getClass());
+//
+//    private final AtomicInteger counts = new AtomicInteger();
+//
+//    private static final Object lock = new Object();
+//
+//
+//    @XxlJob("demoJob")
+//    @TenantJob
+//    public void execute() {
+//        synchronized (lock) {
+//            logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet());
+//            System.out.println(new Date() + ": 我是系统定时任务");
+//        }
+//    }
+//
+//}
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/app/AppServiceImpl.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/app/AppServiceImpl.java
index dd0be59..6d58734 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/app/AppServiceImpl.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/app/AppServiceImpl.java
@@ -194,6 +194,7 @@
         if(type == 1){
             menuDO.setCreator(loginUserNickname);
             menuDO.setCreateTime(app.getCreateTime());
+            menuDO.setIcon("fa-solid:border-none"); //默认icon
             menuMapper.insert(menuDO);
 //            //内置租户角色分配菜单
 //            assignRoleMenu(menuDO.getId(), app.getTenantId());
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuService.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuService.java
index e7ca3b7..9bb4b4c 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuService.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuService.java
@@ -71,6 +71,14 @@
     List<MenuDO> filterDisableMenus(List<MenuDO> list);
 
     /**
+     * 过滤掉业务菜单或系统菜单及其子菜单
+     *
+     * @param list 菜单列表
+     * @return 过滤后的菜单列表
+     */
+    List<MenuDO> filterMenus(List<MenuDO> list, String type);
+
+    /**
      * 筛选菜单列表
      *
      * @param reqVO 筛选条件请求 VO
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuServiceImpl.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuServiceImpl.java
index 1497663..ea51802 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuServiceImpl.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuServiceImpl.java
@@ -11,11 +11,14 @@
 import com.iailab.module.system.controller.admin.permission.vo.menu.MenuSaveVO;
 import com.iailab.module.system.controller.admin.tenant.vo.packages.TenantPackageSaveReqVO;
 import com.iailab.module.system.dal.dataobject.app.AppDO;
+import com.iailab.module.system.dal.dataobject.app.AppMenuDO;
 import com.iailab.module.system.dal.dataobject.permission.MenuDO;
 import com.iailab.module.system.dal.dataobject.permission.RoleDO;
 import com.iailab.module.system.dal.dataobject.permission.RoleMenuDO;
 import com.iailab.module.system.dal.dataobject.tenant.TenantDO;
 import com.iailab.module.system.dal.dataobject.tenant.TenantPackageDO;
+import com.iailab.module.system.dal.mysql.app.AppMapper;
+import com.iailab.module.system.dal.mysql.app.AppMenuMapper;
 import com.iailab.module.system.dal.mysql.permission.MenuMapper;
 import com.iailab.module.system.dal.mysql.permission.RoleMenuMapper;
 import com.iailab.module.system.dal.redis.RedisKeyConstants;
@@ -24,6 +27,7 @@
 import com.iailab.module.system.service.tenant.TenantPackageService;
 import com.iailab.module.system.service.tenant.TenantService;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.context.annotation.Lazy;
@@ -71,6 +75,10 @@
 
     @Resource
     private RoleMenuMapper roleMenuMapper;
+    @Autowired
+    private AppMapper appMapper;
+    @Autowired
+    private AppMenuMapper appMenuMapper;
 
     @Override
     @CacheEvict(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST, key = "#createReqVO.permission",
@@ -118,8 +126,10 @@
         //菜单归属租户和应用
         Long tenantId = getTenantId();
         AppDO appDO = appService.getAppByTenantId(tenantId);
-        updateObj.setTenantId(tenantId);
-        updateObj.setAppId(appDO.getId());
+        if(appDO.getTenantId() != 1) {
+            updateObj.setTenantId(tenantId);
+            updateObj.setAppId(appDO.getId());
+        }
         menuMapper.updateById(updateObj);
     }
 
@@ -186,6 +196,37 @@
         return enabledMenus;
     }
 
+    @Override
+    public List<MenuDO> filterMenus(List<MenuDO> menuList, String type) {
+        if (CollUtil.isEmpty(menuList)){
+            return Collections.emptyList();
+        }
+        Map<Long, MenuDO> menuMap = convertMap(menuList, MenuDO::getId);
+        LambdaQueryWrapper<AppDO> queryWrapper = new LambdaQueryWrapper<>();
+
+        //查询所有的系统应用菜单
+        if("system".equals(type)) {
+            queryWrapper.eq(AppDO::getType, 0);
+        } else if("app".equals(type)) {
+            queryWrapper.eq(AppDO::getType, 1);
+        }
+        List<AppDO> appDOS = appMapper.selectList(queryWrapper);
+        List<Long> appIds = appDOS.stream().map(AppDO::getId).collect(Collectors.toList());
+        List<MenuDO> menuDOS = menuMapper.selectList(new LambdaQueryWrapper<MenuDO>().in(MenuDO::getAppId, appIds));
+        List<Long> systemMenuIds = menuDOS.stream().map(MenuDO::getId).collect(Collectors.toList());
+
+        // 遍历 menu 菜单,查找不是禁用的菜单,添加到 系统菜单(应用菜单) 结果
+        List<MenuDO> systemMenus = new ArrayList<>();
+        Set<Long> appMenuCache = new HashSet<>(); // 存下递归搜索过被禁用的菜单,防止重复的搜索
+        for (MenuDO menu : menuList) {
+            if (isAppMenu(menu, menuMap, appMenuCache, systemMenuIds)) {
+                continue;
+            }
+            systemMenus.add(menu);
+        }
+        return systemMenus;
+    }
+
     private boolean isMenuDisabled(MenuDO node, Map<Long, MenuDO> menuMap, Set<Long> disabledMenuCache) {
         // 如果已经判定是禁用的节点,直接结束
         if (disabledMenuCache.contains(node.getId())) {
@@ -211,6 +252,31 @@
         return false;
     }
 
+    private boolean isAppMenu(MenuDO node, Map<Long, MenuDO> menuMap, Set<Long> menuCache, List<Long> systemMenuIds) {
+        // 如果已经判定是禁用的节点,直接结束
+        if (menuCache.contains(node.getId())) {
+            return true;
+        }
+
+        // 2. 遍历到 parentId 为根节点,则无需判断
+        Long parentId = node.getParentId();
+        if (ObjUtil.equal(parentId, ID_ROOT)) {
+            if (!systemMenuIds.contains(node.getId())) {
+                menuCache.add(node.getId());
+                return true;
+            }
+            return false;
+        }
+
+        // 3. 继续遍历 parent 节点
+        MenuDO parent = menuMap.get(parentId);
+        if (parent == null || isAppMenu(parent, menuMap, menuCache, systemMenuIds)) {
+            menuCache.add(node.getId());
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public List<MenuDO> getMenuList(MenuListReqVO reqVO) {
         return menuMapper.selectList(reqVO);
@@ -218,8 +284,13 @@
 
     @Override
     public List<MenuDO> getAppMenuList(Long tenantId, MenuListReqVO reqVO) {
-        List<MenuDO> menuDOS = menuMapper.selectAppMenuList(tenantId, reqVO);
+        List<MenuDO> menuDOS = menuMapper.selectAppMenuList(reqVO);
+        menuDOS = filterMenus(menuDOS, "app");
         Set<Long> menuDOIds = menuDOS.stream().map(MenuDO::getId).collect(Collectors.toSet());
+        TenantDO tenant = tenantService.getTenant(tenantId);
+        TenantPackageDO tenantPackage = tenantPackageService.getTenantPackage(tenant.getPackageId());
+        Set<Long> tenantMenuIds = tenantPackage.getMenuIds();
+        menuDOS = menuDOS.stream().filter(menuDO -> tenantMenuIds.contains(menuDO.getId())).collect(Collectors.toList());
         // 获得角色列表
         Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(getLoginUserId());
         List<RoleDO> roles = roleService.getRoleList(roleIds);
diff --git a/pom.xml b/pom.xml
index 32a18a9..2cb73e5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -33,6 +33,8 @@
         <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
         <flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version>
         <!-- 统一依赖管理 -->
+        <spring.framework.version>5.3.39</spring.framework.version>
+        <spring.security.version>5.8.14</spring.security.version>
         <spring.boot.version>2.7.18</spring.boot.version>
         <spring.cloud.version>2021.0.9</spring.cloud.version>
         <spring.cloud.alibaba.version>2021.0.6.1</spring.cloud.alibaba.version>
@@ -89,6 +91,7 @@
         <ip2region.version>2.7.0</ip2region.version>
         <bizlog-sdk.version>3.0.6</bizlog-sdk.version>
         <reflections.version>0.10.2</reflections.version>
+        <netty.version>4.1.113.Final</netty.version>
         <!-- 三方云服务相关 -->
         <okio.version>3.5.0</okio.version>
         <okhttp3.version>4.11.0</okhttp3.version>
@@ -98,7 +101,7 @@
         <aliyun-java-sdk-dysmsapi.version>2.2.1</aliyun-java-sdk-dysmsapi.version>
         <tencentcloud-sdk-java.version>3.1.880</tencentcloud-sdk-java.version>
         <justauth.version>1.0.8</justauth.version>
-        <jimureport.version>1.6.6</jimureport.version>
+        <jimureport.version>1.9.0</jimureport.version>
         <xercesImpl.version>2.12.2</xercesImpl.version>
         <weixin-java.version>4.6.0</weixin-java.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -119,7 +122,7 @@
                 <nacos.metadata.version>1.0.0</nacos.metadata.version>
                 <log.path>D:\DLUT\iailab-plat</log.path>
                 <logstash.address>127.0.0.1:4560</logstash.address>
-                <deploy.server>127.0.0.1</deploy.server>
+                <deploy.server>192.168.56.1</deploy.server>
             </properties>
             <activation>
                 <!-- 默认环境 -->
@@ -145,14 +148,17 @@
         <profile>
             <id>prod</id>
             <properties>
+                <!-- 环境标识,需要与配置文件的名称相对应 -->
                 <profiles.active>prod</profiles.active>
                 <nacos.server>127.0.0.1:8848</nacos.server>
                 <nacos.discovery.group>DEFAULT_GROUP</nacos.discovery.group>
                 <nacos.config.group>DEFAULT_GROUP</nacos.config.group>
-                <nacos.namespace>a7112341-c9e2-4177-bc5b-0d2e8cf0b3bb</nacos.namespace>
                 <nacos.username>nacos</nacos.username>
                 <nacos.password>nacos</nacos.password>
+                <nacos.metadata.version>1.0.0</nacos.metadata.version>
+                <log.path>D:\iailab\logs</log.path>
                 <logstash.address>127.0.0.1:4560</logstash.address>
+                <deploy.server>10.88.4.131</deploy.server>
             </properties>
         </profile>
     </profiles>
@@ -160,6 +166,27 @@
     <dependencyManagement>
         <dependencies>
             <!-- 统一依赖管理 -->
+            <dependency>
+                <groupId>io.netty</groupId>
+                <artifactId>netty-bom</artifactId>
+                <version>${netty.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework</groupId>
+                <artifactId>spring-framework-bom</artifactId> <!-- JDK8 版本独有:保证 Spring Framework 尽量高 -->
+                <version>${spring.framework.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.security</groupId>
+                <artifactId>spring-security-bom</artifactId> <!-- JDK8 版本独有:保证 Spring Security 尽量高 -->
+                <version>${spring.security.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
             <dependency>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-dependencies</artifactId>
@@ -746,6 +773,22 @@
                     </exclusion>
                 </exclusions>
             </dependency>
+            <!-- 积木仪表盘-->
+            <dependency>
+                <groupId>org.jeecgframework.jimureport</groupId>
+                <artifactId>jimureport-dashboard-spring-boot-starter</artifactId>
+                <version>${jimureport.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <artifactId>autopoi-web</artifactId>
+                        <groupId>org.jeecgframework</groupId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.jeecgframework.jimureport</groupId>
+                        <artifactId>jimureport-spring-boot-starter</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
             <dependency>
                 <groupId>xerces</groupId>
                 <artifactId>xercesImpl</artifactId>

--
Gitblit v1.9.3