From d9f9ba31913bb9f5053ad78109e8a3c1c00f1e6a Mon Sep 17 00:00:00 2001
From: houzhongjian <houzhongyi@126.com>
Date: 星期二, 23 七月 2024 09:58:30 +0800
Subject: [PATCH] update framework

---
 iailab-cloud/iailab-xxl-job/src/main/resources/logback.xml                                                                                             |    2 
 iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-local.yaml                                                                  |  164 +++++
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/oauth2/OAuth2OpenController.java                 |    2 
 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/file/FileConfigDO.java                                |   14 
 iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/config/IailabDataPermissionAutoConfiguration.java |   15 
 iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/type/JsonLongSetTypeHandler.java                                |   62 +-
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/permission/RoleDO.java                             |    4 
 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/config/ConfigServiceImpl.java                                |   19 
 iailab-cloud/iailab-nacos/src/main/resources/application.yaml                                                                                          |   82 ++
 iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/util/date/DateUtils.java                                                      |  138 ++++
 iailab-cloud/iailab-xxl-job/src/main/resources/application.yaml                                                                                        |   29 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuService.java                               |   11 
 iailab-cloud/iailab-gateway/pom.xml                                                                                                                    |    6 
 iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/permission/RoleApi.java                                       |   12 
 iailab-cloud/iailab-nacos/Dockerfile                                                                                                                   |   20 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/mcs/entity/StModelResultEntity.java                                        |   42 +
 iailab-cloud/iailab-gateway/src/main/resources/application.yaml                                                                                        |   40 +
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/RoleServiceImpl.java                           |   11 
 iailab-module-infra/iailab-module-infra-biz/src/main/resources/application.yaml                                                                        |   19 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/permission/RoleApiImpl.java                                   |   16 
 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/config/ConfigService.java                                    |    8 
 iailab-cloud/iailab-monitor/pom.xml                                                                                                                    |   11 
 iailab-module-data/pom.xml                                                                                                                             |   25 
 iailab-module-data/iailab-module-data-biz/pom.xml                                                                                                      |  188 ++++++
 iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java        |    1 
 iailab-module-data/iailab-module-data-api/pom.xml                                                                                                      |   48 +
 pom.xml                                                                                                                                                |   73 +
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/tenant/TenantPackageDO.java                        |    4 
 iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/config/MyBatisConfiguration.java                                     |  152 ++--
 iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/mapper/BaseMapperX.java                                         |    2 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/RoleService.java                               |    9 
 iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/oauth2/OAuth2GrantTypeEnum.java                             |    2 
 iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/user/AdminUserApi.java                                        |    6 
 iailab-framework/iailab-common/pom.xml                                                                                                                 |    5 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/auth/AuthController.java                         |    3 
 iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/IailabSecurityAutoConfiguration.java                        |   14 
 iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/user/dto/AdminUserRespDTO.java                                |    7 
 iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/util/JdbcUtils.java                                             |   25 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/user/AdminUserApiImpl.java                                    |   19 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/user/AdminUserDO.java                              |    4 
 iailab-cloud/iailab-xxl-job/src/main/java/com/xxl/job/admin/XxlJobAdminApplication.java                                                                |    2 
 iailab-module-infra/iailab-module-infra-biz/pom.xml                                                                                                    |    6 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuServiceImpl.java                           |   58 +
 iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/framework/security/config/SecurityConfiguration.java                 |    6 
 iailab-cloud/iailab-xxl-job/pom.xml                                                                                                                    |  103 ++-
 iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/util/MyBatisUtils.java                                          |   24 
 iailab-module-system/iailab-module-system-biz/pom.xml                                                                                                  |    8 
 iailab-module-system/iailab-module-system-biz/src/main/resources/application-local.yaml                                                                |  210 +++++++
 iailab-module-system/iailab-module-system-biz/src/main/resources/application.yaml                                                                      |   20 
 49 files changed, 1,514 insertions(+), 237 deletions(-)

diff --git a/iailab-cloud/iailab-gateway/pom.xml b/iailab-cloud/iailab-gateway/pom.xml
index 222fdd6..c5642d5 100644
--- a/iailab-cloud/iailab-gateway/pom.xml
+++ b/iailab-cloud/iailab-gateway/pom.xml
@@ -20,12 +20,6 @@
     </properties>
 
     <dependencies>
-        <!-- Spring Cloud 基础 -->
-        <dependency>
-            <groupId>org.springframework.cloud</groupId>
-            <artifactId>spring-cloud-starter-bootstrap</artifactId>
-        </dependency>
-
         <!-- 业务组件 -->
         <dependency>
             <groupId>com.iailab</groupId>
diff --git a/iailab-cloud/iailab-gateway/src/main/resources/application.yaml b/iailab-cloud/iailab-gateway/src/main/resources/application.yaml
index 59def29..28a5cb6 100644
--- a/iailab-cloud/iailab-gateway/src/main/resources/application.yaml
+++ b/iailab-cloud/iailab-gateway/src/main/resources/application.yaml
@@ -1,6 +1,17 @@
 spring:
+  application:
+    name: gateway-server
+
+  profiles:
+    active: local
+
   main:
     allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。
+
+  config:
+    import:
+      - optional:classpath:application-${spring.profiles.active}.yaml # 加载【本地】配置
+      - optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml # 加载【Nacos】的配置
 
   cloud:
     # Spring Cloud Gateway 配置项,对应 GatewayProperties 类
@@ -74,8 +85,29 @@
           uri: grayLb://iailab-monitor
           predicates:
             - Path=/iailab-monitor/**
+        ## data-server 服务
+        - id: data-admin-api # 路由的编号
+          uri: grayLb://data-server
+          predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
+            - Path=/admin-api/data/**
+          filters:
+            - RewritePath=/admin-api/data/v3/api-docs, /v3/api-docs
+        ## model-server 服务
+        - id: model-admin-api # 路由的编号
+          uri: grayLb://model-server
+          predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
+            - Path=/admin-api/model/**
+          filters:
+            - RewritePath=/admin-api/model/v3/api-docs, /v3/api-docs
       x-forwarded:
-        prefix-enabled: false # 避免 Swagger 重复带上额外的 /admin-api/system 前缀
+        prefix-enabled: true # 避免 Swagger 重复带上额外的 /admin-api/system 前缀
+
+server:
+  port: 48080
+
+logging:
+  file:
+    name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
 
 knife4j:
   # 聚合 Swagger 文档,参考 https://doc.xiaominfo.com/docs/action/springcloud-gateway 文档
@@ -91,6 +123,12 @@
       - name: bpm-server
         service-name: bpm-server
         url: /admin-api/bpm/v3/api-docs
+      - name: data-server
+        service-name: data-server
+        url: /admin-api/data/v3/api-docs
+      - name: model-server
+        service-name: model-server
+        url: /admin-api/model/v3/api-docs
 --- #################### 平台相关配置 ####################
 
 iailab:
diff --git a/iailab-cloud/iailab-monitor/pom.xml b/iailab-cloud/iailab-monitor/pom.xml
index dda7ccc..f4e17a7 100644
--- a/iailab-cloud/iailab-monitor/pom.xml
+++ b/iailab-cloud/iailab-monitor/pom.xml
@@ -63,10 +63,21 @@
     </dependencies>
 
     <build>
+        <!-- 设置构建的 jar 包名 -->
+        <finalName>${project.artifactId}</finalName>
         <plugins>
+            <!-- 打包 -->
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring.boot.version}</version> <!-- 如果 spring.boot.version 版本修改,则这里也要跟着修改 -->
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
+                        </goals>
+                    </execution>
+                </executions>
             </plugin>
         </plugins>
     </build>
diff --git a/iailab-cloud/iailab-nacos/Dockerfile b/iailab-cloud/iailab-nacos/Dockerfile
index 630b9bb..09f01cf 100644
--- a/iailab-cloud/iailab-nacos/Dockerfile
+++ b/iailab-cloud/iailab-nacos/Dockerfile
@@ -1,17 +1,9 @@
-#FROM findepi/graalvm:java17-native
-FROM openjdk:17.0.2-oraclelinux8
-
-MAINTAINER Lion Li
-
-RUN mkdir -p /ruoyi/nacos
-
-WORKDIR /ruoyi/nacos
-
+FROM eclipse-temurin:8-jre
+RUN mkdir -p /sda2/iailab/iailab-platform/nacos
+WORKDIR /sda2/iailab/iailab-platform/nacos
 EXPOSE 8848
-
 ENV TZ=Asia/Shanghai LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="-Xms512m -Xmx1024m"
+## 将后端项目的 Jar 文件,复制到镜像中
+COPY ./iailab-nacos.jar nacos-server.jar
 
-ADD ./target/ruoyi-nacos.jar ./app.jar
-
-ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom ${JAVA_OPTS} -jar app.jar
-
+CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar iailab-nacos.jar
diff --git a/iailab-cloud/iailab-nacos/src/main/resources/application.yaml b/iailab-cloud/iailab-nacos/src/main/resources/application.yaml
new file mode 100644
index 0000000..89c04a6
--- /dev/null
+++ b/iailab-cloud/iailab-nacos/src/main/resources/application.yaml
@@ -0,0 +1,82 @@
+db:
+  num: 1
+  url:
+    '0': jdbc:mysql://172.16.8.100:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
+  password:
+    '0': 123456
+  user:
+    '0': root
+management:
+  endpoints:
+    web:
+      exposure:
+        include: '*'
+  metrics:
+    export:
+      elastic:
+        enabled: false
+      influx:
+        enabled: false
+nacos:
+  config:
+    push:
+      maxRetryTime: 50
+  core:
+    auth:
+      caching:
+        enabled: true
+      enable:
+        userAgentAuthWhite: false
+      enabled: true
+      plugin:
+        nacos:
+          token:
+            cache:
+              enable: false
+            expire:
+              seconds: 18000
+            secret:
+              key: SecretKey012345678901234567890123456789012345678901234567890123456789
+      server:
+        identity:
+          key: serverIdentity
+          value: security
+      system:
+        type: nacos
+  istio:
+    mcp:
+      server:
+        enabled: false
+  naming:
+    empty-service:
+      auto-clean: true
+      clean:
+        initial-delay-ms: 50000
+        period-time-ms: 30000
+  plugin:
+    datasource:
+      log:
+        enabled: true
+  security:
+    ignore:
+      urls: /,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-ui/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**
+server:
+  error:
+    include-message: ALWAYS
+  port: 8848
+  servlet:
+    contextPath: /nacos
+spring:
+  application:
+    name: iailab-nacos
+  boot:
+    admin:
+      client:
+        instance:
+          service-host-type: IP
+        password: 123456
+        url: http://127.0.0.1:9100
+        username: iailab
+  sql:
+    init:
+      platform: mysql
\ No newline at end of file
diff --git a/iailab-cloud/iailab-xxl-job/pom.xml b/iailab-cloud/iailab-xxl-job/pom.xml
index 366e751..326b2a2 100644
--- a/iailab-cloud/iailab-xxl-job/pom.xml
+++ b/iailab-cloud/iailab-xxl-job/pom.xml
@@ -50,11 +50,6 @@
 	</licenses>
 
 	<dependencies>
-		<!-- Spring Cloud 基础 -->
-		<dependency>
-			<groupId>org.springframework.cloud</groupId>
-			<artifactId>spring-cloud-starter-bootstrap</artifactId>
-		</dependency>
 		<!-- starter-web:spring-webmvc + autoconfigure + logback + yaml + tomcat -->
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
@@ -125,57 +120,79 @@
 	</dependencies>
 
 	<build>
+		<finalName>${project.artifactId}</finalName>
 		<plugins>
-			<!-- Source -->
 			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-source-plugin</artifactId>
-				<version>${maven-source-plugin.version}</version>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+				<version>${spring-boot.version}</version>
 				<executions>
 					<execution>
-						<phase>package</phase>
 						<goals>
-							<goal>jar-no-fork</goal>
+							<goal>repackage</goal>
 						</goals>
 					</execution>
 				</executions>
-			</plugin>
-			<!-- Javadoc -->
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-javadoc-plugin</artifactId>
-				<version>${maven-javadoc-plugin.version}</version>
-				<executions>
-					<execution>
-						<phase>package</phase>
-						<goals>
-							<goal>jar</goal>
-						</goals>
-						<configuration>
-							<doclint>none</doclint>
-						</configuration>
-					</execution>
-				</executions>
-			</plugin>
-			<!-- GPG -->
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-gpg-plugin</artifactId>
-				<version>${maven-gpg-plugin.version}</version>
 				<configuration>
-					<useAgent>false</useAgent>
+					<!-- 作用:项目打成jar的同时将本地jar包也引入进去 -->
+					<includeSystemScope>true</includeSystemScope>
 				</configuration>
-<!--				<executions>-->
-<!--					<execution>-->
-<!--						<phase>verify</phase>-->
-<!--						<goals>-->
-<!--							<goal>sign</goal>-->
-<!--						</goals>-->
-<!--					</execution>-->
-<!--				</executions>-->
 			</plugin>
 		</plugins>
 	</build>
 
+<!--	<build>-->
+<!--		<plugins>-->
+<!--			&lt;!&ndash; Source &ndash;&gt;-->
+<!--			<plugin>-->
+<!--				<groupId>org.apache.maven.plugins</groupId>-->
+<!--				<artifactId>maven-source-plugin</artifactId>-->
+<!--				<version>${maven-source-plugin.version}</version>-->
+<!--				<executions>-->
+<!--					<execution>-->
+<!--						<phase>package</phase>-->
+<!--						<goals>-->
+<!--							<goal>jar-no-fork</goal>-->
+<!--						</goals>-->
+<!--					</execution>-->
+<!--				</executions>-->
+<!--			</plugin>-->
+<!--			&lt;!&ndash; Javadoc &ndash;&gt;-->
+<!--			<plugin>-->
+<!--				<groupId>org.apache.maven.plugins</groupId>-->
+<!--				<artifactId>maven-javadoc-plugin</artifactId>-->
+<!--				<version>${maven-javadoc-plugin.version}</version>-->
+<!--				<executions>-->
+<!--					<execution>-->
+<!--						<phase>package</phase>-->
+<!--						<goals>-->
+<!--							<goal>jar</goal>-->
+<!--						</goals>-->
+<!--						<configuration>-->
+<!--							<doclint>none</doclint>-->
+<!--						</configuration>-->
+<!--					</execution>-->
+<!--				</executions>-->
+<!--			</plugin>-->
+<!--			&lt;!&ndash; GPG &ndash;&gt;-->
+<!--			<plugin>-->
+<!--				<groupId>org.apache.maven.plugins</groupId>-->
+<!--				<artifactId>maven-gpg-plugin</artifactId>-->
+<!--				<version>${maven-gpg-plugin.version}</version>-->
+<!--				<configuration>-->
+<!--					<useAgent>false</useAgent>-->
+<!--				</configuration>-->
+<!--&lt;!&ndash;				<executions>&ndash;&gt;-->
+<!--&lt;!&ndash;					<execution>&ndash;&gt;-->
+<!--&lt;!&ndash;						<phase>verify</phase>&ndash;&gt;-->
+<!--&lt;!&ndash;						<goals>&ndash;&gt;-->
+<!--&lt;!&ndash;							<goal>sign</goal>&ndash;&gt;-->
+<!--&lt;!&ndash;						</goals>&ndash;&gt;-->
+<!--&lt;!&ndash;					</execution>&ndash;&gt;-->
+<!--&lt;!&ndash;				</executions>&ndash;&gt;-->
+<!--			</plugin>-->
+<!--		</plugins>-->
+<!--	</build>-->
+
 
 </project>
\ No newline at end of file
diff --git a/iailab-cloud/iailab-xxl-job/src/main/java/com/xxl/job/admin/XxlJobAdminApplication.java b/iailab-cloud/iailab-xxl-job/src/main/java/com/xxl/job/admin/XxlJobAdminApplication.java
index fce10a8..af1877a 100644
--- a/iailab-cloud/iailab-xxl-job/src/main/java/com/xxl/job/admin/XxlJobAdminApplication.java
+++ b/iailab-cloud/iailab-xxl-job/src/main/java/com/xxl/job/admin/XxlJobAdminApplication.java
@@ -2,11 +2,13 @@
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 
 /**
  * @author xuxueli 2018-10-28 00:38:13
  */
 @SpringBootApplication
+@EnableDiscoveryClient
 public class XxlJobAdminApplication {
 
 	public static void main(String[] args) {
diff --git a/iailab-cloud/iailab-xxl-job/src/main/resources/application.yaml b/iailab-cloud/iailab-xxl-job/src/main/resources/application.yaml
index f453523..115d06d 100644
--- a/iailab-cloud/iailab-xxl-job/src/main/resources/application.yaml
+++ b/iailab-cloud/iailab-xxl-job/src/main/resources/application.yaml
@@ -1,4 +1,26 @@
+server:
+  port: 9090
+  servlet:
+    context-path: /xxl-job-admin
+
+logging:
+  file:
+    name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
+
 spring:
+  application:
+    name: xxl-job-server
+  profiles:
+    # 环境配置
+#    active: @profiles.active@
+    active: local
+    # Spring Boot Admin 配置项
+    boot:
+      admin:
+        # Spring Boot Admin Client 客户端的相关配置
+        client:
+          instance:
+            service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
   mvc:
     servlet:
       load-on-startup: 0
@@ -14,7 +36,7 @@
       number_format: 0.
       new_builtin_class_resolver: safer
   datasource:
-    url: jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
+    url: jdbc:mysql://172.16.8.100:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
     username: root
     password: 123456
     driver-class-name: com.mysql.cj.jdbc.Driver
@@ -60,6 +82,11 @@
 
 # 服务端点检查
 management:
+  server:
+    base-path: /actuator
+  health:
+    mail:
+      enabled: false
   trace:
     http:
       enabled: true
diff --git a/iailab-cloud/iailab-xxl-job/src/main/resources/logback.xml b/iailab-cloud/iailab-xxl-job/src/main/resources/logback.xml
index d4b08c2..4206db9 100644
--- a/iailab-cloud/iailab-xxl-job/src/main/resources/logback.xml
+++ b/iailab-cloud/iailab-xxl-job/src/main/resources/logback.xml
@@ -2,7 +2,7 @@
 <configuration debug="false" scan="true" scanPeriod="1 seconds">
 
     <contextName>logback</contextName>
-    <property name="log.path" value="/data/applogs/xxl-job/xxl-job-admin.log"/>
+    <property name="log.path" value="/sda2/data/applogs/xxl-job/xxl-job-admin.log"/>
 
     <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
         <encoder>
diff --git a/iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/config/IailabDataPermissionAutoConfiguration.java b/iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/config/IailabDataPermissionAutoConfiguration.java
index d2c481d..7428e3c 100644
--- a/iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/config/IailabDataPermissionAutoConfiguration.java
+++ b/iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/config/IailabDataPermissionAutoConfiguration.java
@@ -1,7 +1,8 @@
 package com.iailab.framework.datapermission.config;
 
+import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
 import com.iailab.framework.datapermission.core.aop.DataPermissionAnnotationAdvisor;
-import com.iailab.framework.datapermission.core.db.DataPermissionDatabaseInterceptor;
+import com.iailab.framework.datapermission.core.db.DataPermissionRuleHandler;
 import com.iailab.framework.datapermission.core.rule.DataPermissionRule;
 import com.iailab.framework.datapermission.core.rule.DataPermissionRuleFactory;
 import com.iailab.framework.datapermission.core.rule.DataPermissionRuleFactoryImpl;
@@ -26,16 +27,18 @@
     }
 
     @Bean
-    public DataPermissionDatabaseInterceptor dataPermissionDatabaseInterceptor(MybatisPlusInterceptor interceptor,
-                                                                               DataPermissionRuleFactory ruleFactory) {
-        // 创建 DataPermissionDatabaseInterceptor 拦截器
-        DataPermissionDatabaseInterceptor inner = new DataPermissionDatabaseInterceptor(ruleFactory);
+    public DataPermissionRuleHandler dataPermissionRuleHandler(MybatisPlusInterceptor interceptor,
+                                                               DataPermissionRuleFactory ruleFactory) {
+        // 创建 DataPermissionInterceptor 拦截器
+        DataPermissionRuleHandler handler = new DataPermissionRuleHandler(ruleFactory);
+        DataPermissionInterceptor inner = new DataPermissionInterceptor(handler);
         // 添加到 interceptor 中
         // 需要加在首个,主要是为了在分页插件前面。这个是 MyBatis Plus 的规定
         MyBatisUtils.addInterceptor(interceptor, inner, 0);
-        return inner;
+        return handler;
     }
 
+
     @Bean
     public DataPermissionAnnotationAdvisor dataPermissionAnnotationAdvisor() {
         return new DataPermissionAnnotationAdvisor();
diff --git a/iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java b/iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java
index 87f2d01..a69106c 100644
--- a/iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java
+++ b/iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java
@@ -156,6 +156,7 @@
         }
         // 拼接条件
         return new InExpression(MyBatisUtils.buildColumn(tableName, tableAlias, columnName),
+//                new Parenthesis(new ExpressionList<>(CollectionUtils.convertList(deptIds, LongValue::new))));
                 new ExpressionList(CollectionUtils.convertList(deptIds, LongValue::new)));
     }
 
diff --git a/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/config/MyBatisConfiguration.java b/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/config/MyBatisConfiguration.java
index 5a00cb6..e841574 100644
--- a/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/config/MyBatisConfiguration.java
+++ b/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/config/MyBatisConfiguration.java
@@ -1,72 +1,84 @@
-package com.iailab.framework.mybatis.config;
-
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import com.iailab.framework.mybatis.core.handler.MybatisHandler;
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.apache.ibatis.type.JdbcType;
-import org.mybatis.spring.SqlSessionFactoryBean;
-import org.mybatis.spring.SqlSessionTemplate;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.boot.jdbc.DataSourceBuilder;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
-import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
-import org.springframework.jdbc.datasource.DataSourceTransactionManager;
-
-
-/**
- * @author houzhongjian
- * @Title: MyBatisConfiguration
- * @ProjectName design-parent
- * @Description: 解决独立启动某个服务时报错问题 No typehandler found for property sqlSessionTemplate
- * @date 2024/7/2 16:35
- */
-@Configuration
-public class MyBatisConfiguration {
-
-    //  配置mapper的扫描,找到所有的mapper.xml映射文件
-    @Value("${iailab.info.base-package}")
-    private String mapperLocations;
-
-
-//    @Bean(name = "dataSource")
-//    @ConfigurationProperties(prefix = "spring.datasource.test1")
+//package com.iailab.framework.mybatis.config;
+//
+//import com.alibaba.fastjson.JSONArray;
+//import com.alibaba.fastjson.JSONObject;
+//import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+//import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
+//import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
+//import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+//import com.iailab.framework.mybatis.core.handler.MybatisHandler;
+//import com.iailab.framework.mybatis.interceptor.DataFilterInterceptor;
+//import org.apache.ibatis.session.SqlSessionFactory;
+//import org.apache.ibatis.type.JdbcType;
+//import org.mybatis.spring.SqlSessionFactoryBean;
+//import org.mybatis.spring.SqlSessionTemplate;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.boot.jdbc.DataSourceBuilder;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.context.annotation.Primary;
+//import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+//import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+//
+//
+///**
+// * @author houzhongjian
+// * @Title: MyBatisConfiguration
+// * @ProjectName design-parent
+// * @Description: 解决独立启动某个服务时报错问题 No typehandler found for property sqlSessionTemplate
+// * @date 2024/7/2 16:35
+// */
+//@Configuration
+//public class MyBatisConfiguration {
+//
+//    //  配置mapper的扫描,找到所有的mapper.xml映射文件
+////    @Value("${iailab.info.base-package}")
+//    @Value("${mybatis-plus.mapper-locations}")
+//    private String mapperLocations;
+//
+//    @Bean
 //    @Primary
-//    public DataSource dataSource() {
-//        return DataSourceBuilder.create().build();
+//    public SqlSessionFactory sqlSessionFactory() throws Exception {
+//        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
+//        sqlSessionFactoryBean.setDataSource(DataSourceBuilder.create().build());
+//        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
+//        sqlSessionFactoryBean.setConfiguration(buildConfiguration());
+//        return sqlSessionFactoryBean.getObject();
 //    }
-
-    @Bean
-    @Primary
-    public SqlSessionFactory sqlSessionFactory() throws Exception {
-        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
-        sqlSessionFactoryBean.setDataSource(DataSourceBuilder.create().build());
-        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
-        sqlSessionFactoryBean.setConfiguration(buildConfiguration());
-        return sqlSessionFactoryBean.getObject();
-    }
-
-    @Bean
-    @Primary
-    public SqlSessionTemplate sqlSessionTemplate() throws Exception {
-        return  new SqlSessionTemplate(sqlSessionFactory());
-    }
-
-    @Bean
-    @Primary
-    public DataSourceTransactionManager transactionManager() {
-        return new DataSourceTransactionManager(DataSourceBuilder.create().build());
-    }
-
-    private org.apache.ibatis.session.Configuration buildConfiguration() {
-        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
-        configuration.getTypeHandlerRegistry().register(JSONObject.class, JdbcType.VARCHAR, MybatisHandler.class);
-        configuration.getTypeHandlerRegistry().register(JSONArray.class, JdbcType.VARCHAR, MybatisHandler.class);
-        return configuration;
-    }
-
-
-}
\ No newline at end of file
+//
+//    @Bean
+//    @Primary
+//    public SqlSessionTemplate sqlSessionTemplate() throws Exception {
+//        return  new SqlSessionTemplate(sqlSessionFactory());
+//    }
+//
+//    @Bean
+//    @Primary
+//    public DataSourceTransactionManager transactionManager() {
+//        return new DataSourceTransactionManager(DataSourceBuilder.create().build());
+//    }
+//
+//    private org.apache.ibatis.session.Configuration buildConfiguration() {
+//        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
+//        configuration.getTypeHandlerRegistry().register(JSONObject.class, JdbcType.VARCHAR, MybatisHandler.class);
+//        configuration.getTypeHandlerRegistry().register(JSONArray.class, JdbcType.VARCHAR, MybatisHandler.class);
+//        return configuration;
+//    }
+//
+//    @Bean
+//    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+//        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
+//        // 数据权限
+//        mybatisPlusInterceptor.addInnerInterceptor(new DataFilterInterceptor());
+//        // 分页插件
+//        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
+//        // 乐观锁
+//        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
+//        // 防止全表更新与删除
+//        mybatisPlusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
+//
+//        return mybatisPlusInterceptor;
+//    }
+//
+//
+//}
\ No newline at end of file
diff --git a/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/mapper/BaseMapperX.java b/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/mapper/BaseMapperX.java
index a141b97..0924bf0 100644
--- a/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/mapper/BaseMapperX.java
+++ b/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/mapper/BaseMapperX.java
@@ -185,7 +185,7 @@
         return Db.updateBatchById(entities, size);
     }
 
-    default Boolean insertOrUpdate(T entity) {
+    default boolean insertOrUpdate(T entity) {
         return  Db.saveOrUpdate(entity);
     }
 
diff --git a/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/type/JsonLongSetTypeHandler.java b/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/type/JsonLongSetTypeHandler.java
index b7e130f..cce6ac8 100644
--- a/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/type/JsonLongSetTypeHandler.java
+++ b/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/type/JsonLongSetTypeHandler.java
@@ -1,31 +1,31 @@
-package com.iailab.framework.mybatis.core.type;
-
-import com.iailab.framework.common.util.json.JsonUtils;
-import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
-import com.fasterxml.jackson.core.type.TypeReference;
-
-import java.util.Set;
-
-/**
- * 参考 {@link com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler} 实现
- * 在我们将字符串反序列化为 Set 并且泛型为 Long 时,如果每个元素的数值太小,会被处理成 Integer 类型,导致可能存在隐性的 BUG。
- *
- * 例如说哦,SysUserDO 的 postIds 属性
- *
- * @author iailab
- */
-public class JsonLongSetTypeHandler extends AbstractJsonTypeHandler<Object> {
-
-    private static final TypeReference<Set<Long>> TYPE_REFERENCE = new TypeReference<Set<Long>>(){};
-
-    @Override
-    protected Object parse(String json) {
-        return JsonUtils.parseObject(json, TYPE_REFERENCE);
-    }
-
-    @Override
-    protected String toJson(Object obj) {
-        return JsonUtils.toJsonString(obj);
-    }
-
-}
+//package com.iailab.framework.mybatis.core.type;
+//
+//import com.iailab.framework.common.util.json.JsonUtils;
+//import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
+//import com.fasterxml.jackson.core.type.TypeReference;
+//
+//import java.util.Set;
+//
+///**
+// * 参考 {@link com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler} 实现
+// * 在我们将字符串反序列化为 Set 并且泛型为 Long 时,如果每个元素的数值太小,会被处理成 Integer 类型,导致可能存在隐性的 BUG。
+// *
+// * 例如说哦,SysUserDO 的 postIds 属性
+// *
+// * @author iailab
+// */
+//public class JsonLongSetTypeHandler extends AbstractJsonTypeHandler<Object> {
+//
+//    private static final TypeReference<Set<Long>> TYPE_REFERENCE = new TypeReference<Set<Long>>(){};
+//
+//    @Override
+//    protected Object parse(String json) {
+//        return JsonUtils.parseObject(json, TYPE_REFERENCE);
+//    }
+//
+//    @Override
+//    protected String toJson(Object obj) {
+//        return JsonUtils.toJsonString(obj);
+//    }
+//
+//}
diff --git a/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/util/JdbcUtils.java b/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/util/JdbcUtils.java
index 75f491d..6c12b4e 100644
--- a/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/util/JdbcUtils.java
+++ b/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/util/JdbcUtils.java
@@ -1,14 +1,19 @@
 package com.iailab.framework.mybatis.core.util;
 
+import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
 import com.baomidou.mybatisplus.annotation.DbType;
+import com.iailab.framework.common.util.spring.SpringUtils;
+import com.iailab.framework.mybatis.core.enums.DbTypeEnum;
 
+import javax.sql.DataSource;
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.sql.SQLException;
 
 /**
  * JDBC 工具类
  *
- * @author iailab
+ * @author 芋道源码
  */
 public class JdbcUtils {
 
@@ -35,8 +40,22 @@
      * @return DB 类型
      */
     public static DbType getDbType(String url) {
-        String name = com.alibaba.druid.util.JdbcUtils.getDbType(url, null);
-        return DbType.getDbType(name);
+        return com.baomidou.mybatisplus.extension.toolkit.JdbcUtils.getDbType(url);
+    }
+
+    /**
+     * 通过当前数据库连接获得对应的 DB 类型
+     *
+     * @return DB 类型
+     */
+    public static DbType getDbType() {
+        DynamicRoutingDataSource dynamicRoutingDataSource = SpringUtils.getBean(DynamicRoutingDataSource.class);
+        DataSource dataSource = dynamicRoutingDataSource.determineDataSource();
+        try (Connection conn = dataSource.getConnection()) {
+            return DbTypeEnum.find(conn.getMetaData().getDatabaseProductName());
+        } catch (SQLException e) {
+            throw new IllegalArgumentException(e.getMessage());
+        }
     }
 
 }
diff --git a/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/util/MyBatisUtils.java b/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/util/MyBatisUtils.java
index 2a9dc12..a8d8411 100644
--- a/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/util/MyBatisUtils.java
+++ b/iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/util/MyBatisUtils.java
@@ -1,13 +1,16 @@
 package com.iailab.framework.mybatis.core.util;
 
 import cn.hutool.core.collection.CollectionUtil;
-import com.iailab.framework.common.pojo.PageParam;
-import com.iailab.framework.common.pojo.SortingField;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.annotation.DbType;
 import com.baomidou.mybatisplus.core.metadata.OrderItem;
 import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.iailab.framework.common.pojo.PageParam;
+import com.iailab.framework.common.pojo.SortingField;
+import com.iailab.framework.mybatis.core.enums.DbTypeEnum;
 import net.sf.jsqlparser.expression.Alias;
 import net.sf.jsqlparser.schema.Column;
 import net.sf.jsqlparser.schema.Table;
@@ -56,7 +59,7 @@
 
     /**
      * 获得 Table 对应的表名
-     *
+     * <p>
      * 兼容 MySQL 转义表名 `t_xxx`
      *
      * @param table 表
@@ -85,4 +88,19 @@
         return new Column(tableName + StringPool.DOT + column);
     }
 
+    /**
+     * 跨数据库的 find_in_set 实现
+     *
+     * @param column 字段名称
+     * @param value  查询值(不带单引号)
+     * @return sql
+     */
+    public static String findInSet(String column, Object value) {
+        // 这里不用SqlConstants.DB_TYPE,因为它是使用 primary 数据源的 url 推断出来的类型
+        DbType dbType = JdbcUtils.getDbType();
+        return DbTypeEnum.getFindInSetTemplate(dbType)
+                .replace("#{column}", column)
+                .replace("#{value}", StrUtil.toString(value));
+    }
+
 }
diff --git a/iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/IailabSecurityAutoConfiguration.java b/iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/IailabSecurityAutoConfiguration.java
index 46c63a3..4ab66ee 100644
--- a/iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/IailabSecurityAutoConfiguration.java
+++ b/iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/IailabSecurityAutoConfiguration.java
@@ -1,5 +1,6 @@
 package com.iailab.framework.security.config;
 
+import cn.hutool.extra.spring.SpringUtil;
 import com.iailab.framework.security.core.aop.PreAuthenticatedAspect;
 import com.iailab.framework.security.core.context.TransmittableThreadLocalSecurityContextHolderStrategy;
 import com.iailab.framework.security.core.filter.TokenAuthenticationFilter;
@@ -10,6 +11,7 @@
 import com.iailab.framework.web.core.handler.GlobalExceptionHandler;
 import com.iailab.module.system.api.oauth2.OAuth2TokenApi;
 import com.iailab.module.system.api.permission.PermissionApi;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
 import org.springframework.boot.autoconfigure.AutoConfiguration;
 import org.springframework.boot.autoconfigure.AutoConfigureOrder;
@@ -80,11 +82,23 @@
     @Bean
     public TokenAuthenticationFilter authenticationTokenFilter(GlobalExceptionHandler globalExceptionHandler,
                                                                OAuth2TokenApi oauth2TokenApi) {
+        try {
+            OAuth2TokenApi oAuth2TokenApi = SpringUtil.getBean("aAuth2TokenApiImpl", OAuth2TokenApi.class);
+            if (oAuth2TokenApi != null) {
+                oauth2TokenApi = oAuth2TokenApi;
+            }
+        } catch (Exception ignored) {}
         return new TokenAuthenticationFilter(securityProperties, globalExceptionHandler, oauth2TokenApi);
     }
 
     @Bean("ss") // 使用 Spring Security 的缩写,方便使用
     public SecurityFrameworkService securityFrameworkService(PermissionApi permissionApi) {
+        try {
+            PermissionApi permissionApiImpl = SpringUtil.getBean("permissionApiImpl", PermissionApi.class);
+            if (permissionApiImpl != null) {
+                permissionApi = permissionApiImpl;
+            }
+        } catch (Exception ignored) {}
         return new SecurityFrameworkServiceImpl(permissionApi);
     }
 
diff --git a/iailab-framework/iailab-common/pom.xml b/iailab-framework/iailab-common/pom.xml
index 688884c..85ebbed 100644
--- a/iailab-framework/iailab-common/pom.xml
+++ b/iailab-framework/iailab-common/pom.xml
@@ -129,6 +129,11 @@
         </dependency>
 
         <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+        </dependency>
+
+        <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>transmittable-thread-local</artifactId>
         </dependency>
diff --git a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/util/date/DateUtils.java b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/util/date/DateUtils.java
index e17ef7d..dc63f08 100644
--- a/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/util/date/DateUtils.java
+++ b/iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/util/date/DateUtils.java
@@ -1,10 +1,15 @@
 package com.iailab.framework.common.util.date;
 
 import cn.hutool.core.date.LocalDateTimeUtil;
+import org.joda.time.DateTime;
 
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.time.*;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.List;
 
 /**
  * 时间工具类
@@ -26,6 +31,44 @@
     public static final String FORMAT_YEAR_MONTH_DAY = "yyyy-MM-dd";
 
     public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";
+
+    /**
+     * 日期格式化 日期格式为:yyyy-MM-dd
+     * @param date  日期
+     * @return  返回yyyy-MM-dd格式日期
+     */
+    public static String format(Date date) {
+        return format(date, FORMAT_YEAR_MONTH_DAY);
+    }
+
+    /**
+     * 日期格式化 日期格式为:yyyy-MM-dd
+     * @param date  日期
+     * @param pattern  格式,如:DateUtils.DATE_TIME_PATTERN
+     * @return  返回yyyy-MM-dd格式日期
+     */
+    public static String format(Date date, String pattern) {
+        if(date != null){
+            SimpleDateFormat df = new SimpleDateFormat(pattern);
+            return df.format(date);
+        }
+        return null;
+    }
+
+    /**
+     * 日期解析
+     * @param date  日期
+     * @param pattern  格式,如:DateUtils.DATE_TIME_PATTERN
+     * @return  返回Date
+     */
+    public static Date parse(String date, String pattern) {
+        try {
+            return new SimpleDateFormat(pattern).parse(date);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
 
     /**
      * 将 LocalDateTime 转换成 Date
@@ -146,4 +189,99 @@
         return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now().minusDays(1));
     }
 
+    public static List<String> getTimeScale(Date startDate, Date endDate, int seconds) {
+        List<String> days = new ArrayList<String>();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(startDate);
+        while (calendar.getTime().compareTo(endDate) <= 0) {
+            days.add(DateUtils.format(calendar.getTime(), FORMAT_YEAR_MONTH_DAY));
+            calendar.add(Calendar.SECOND, seconds);
+        }
+        return days;
+    }
+
+    /**
+     * 对日期的【秒】进行加/减
+     *
+     * @param date 日期
+     * @param seconds 秒数,负数为减
+     * @return 加/减几秒后的日期
+     */
+    public static Date addDateSeconds(Date date, int seconds) {
+        DateTime dateTime = new DateTime(date);
+        return dateTime.plusSeconds(seconds).toDate();
+    }
+
+    /**
+     * 对日期的【分钟】进行加/减
+     *
+     * @param date 日期
+     * @param minutes 分钟数,负数为减
+     * @return 加/减几分钟后的日期
+     */
+    public static Date addDateMinutes(Date date, int minutes) {
+        DateTime dateTime = new DateTime(date);
+        return dateTime.plusMinutes(minutes).toDate();
+    }
+
+    /**
+     * 对日期的【小时】进行加/减
+     *
+     * @param date 日期
+     * @param hours 小时数,负数为减
+     * @return 加/减几小时后的日期
+     */
+    public static Date addDateHours(Date date, int hours) {
+        DateTime dateTime = new DateTime(date);
+        return dateTime.plusHours(hours).toDate();
+    }
+
+    /**
+     * 对日期的【天】进行加/减
+     *
+     * @param date 日期
+     * @param days 天数,负数为减
+     * @return 加/减几天后的日期
+     */
+    public static Date addDateDays(Date date, int days) {
+        DateTime dateTime = new DateTime(date);
+        return dateTime.plusDays(days).toDate();
+    }
+
+    /**
+     * 对日期的【周】进行加/减
+     *
+     * @param date 日期
+     * @param weeks 周数,负数为减
+     * @return 加/减几周后的日期
+     */
+    public static Date addDateWeeks(Date date, int weeks) {
+        DateTime dateTime = new DateTime(date);
+        return dateTime.plusWeeks(weeks).toDate();
+    }
+
+    /**
+     * 对日期的【月】进行加/减
+     *
+     * @param date 日期
+     * @param months 月数,负数为减
+     * @return 加/减几月后的日期
+     */
+    public static Date addDateMonths(Date date, int months) {
+        DateTime dateTime = new DateTime(date);
+        return dateTime.plusMonths(months).toDate();
+    }
+
+    /**
+     * 对日期的【年】进行加/减
+     *
+     * @param date 日期
+     * @param years 年数,负数为减
+     * @return 加/减几年后的日期
+     */
+    public static Date addDateYears(Date date, int years) {
+        DateTime dateTime = new DateTime(date);
+        return dateTime.plusYears(years).toDate();
+    }
+
 }
diff --git a/iailab-module-data/iailab-module-data-api/pom.xml b/iailab-module-data/iailab-module-data-api/pom.xml
new file mode 100644
index 0000000..66fd6b5
--- /dev/null
+++ b/iailab-module-data/iailab-module-data-api/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.iailab</groupId>
+        <artifactId>iailab-module-data</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <version>${revision}</version>
+
+    <artifactId>iailab-module-data-api</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-common</artifactId>
+        </dependency>
+
+        <!-- Web 相关 -->
+        <dependency>
+            <groupId>org.springdoc</groupId>
+            <artifactId>springdoc-openapi-ui</artifactId>
+        </dependency>
+
+        <!-- 参数校验 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <!-- RPC 远程调用相关 -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/iailab-module-data/iailab-module-data-biz/pom.xml b/iailab-module-data/iailab-module-data-biz/pom.xml
new file mode 100644
index 0000000..7af3b45
--- /dev/null
+++ b/iailab-module-data/iailab-module-data-biz/pom.xml
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.iailab</groupId>
+        <artifactId>iailab-module-data</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <artifactId>iailab-module-data-biz</artifactId>
+    <name>${project.artifactId}</name>
+    <packaging>jar</packaging>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-common-env</artifactId>
+        </dependency>
+        <!-- 消息队列相关 -->
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-common-mq</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-common-mybatis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-common-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-common-excel</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-common-security</artifactId>
+        </dependency>
+        <!-- RPC 远程调用相关 -->
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-common-rpc</artifactId>
+        </dependency>
+        <!-- 监控相关 -->
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-common-monitor</artifactId>
+        </dependency>
+        <!-- Job 定时任务相关 -->
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-common-job</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-common-biz-data-permission</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-module-data-api</artifactId>
+            <version>${revision}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-module-model-api</artifactId>
+            <version>${revision}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-module-infra-api</artifactId>
+            <version>${revision}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.iailab</groupId>
+            <artifactId>iailab-module-system-api</artifactId>
+            <version>${revision}</version>
+        </dependency>
+
+        <!-- nacos 客户端 -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+        <!-- nacos 配置中心 -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.quartz-scheduler</groupId>
+            <artifactId>quartz</artifactId>
+            <version>2.3.2</version>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>cn.afterturn</groupId>-->
+<!--            <artifactId>easypoi-base</artifactId>-->
+<!--            <version>${easypoi.version}</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>cn.afterturn</groupId>-->
+<!--            <artifactId>easypoi-web</artifactId>-->
+<!--            <version>${easypoi.version}</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>cn.afterturn</groupId>-->
+<!--            <artifactId>easypoi-annotation</artifactId>-->
+<!--            <version>${easypoi.version}</version>-->
+<!--        </dependency>-->
+
+        <!-- 引用POI -->
+<!--        <dependency>-->
+<!--            <groupId>org.apache.poi</groupId>-->
+<!--            <artifactId>poi</artifactId>-->
+<!--            <version>4.1.1</version>-->
+<!--        </dependency>-->
+
+<!--        <dependency>-->
+<!--            <groupId>org.jetbrains</groupId>-->
+<!--            <artifactId>annotations</artifactId>-->
+<!--            <version>17.0.0</version>-->
+<!--            <scope>compile</scope>-->
+<!--        </dependency>-->
+
+        <!-- ModBus TCP -->
+        <dependency>
+            <groupId>com.infiniteautomation</groupId>
+            <artifactId>modbus4j</artifactId>
+            <version>3.0.4</version>
+        </dependency>
+
+        <!-- OPC UA -->
+        <dependency>
+            <groupId>org.eclipse.milo</groupId>
+            <artifactId>sdk-client</artifactId>
+            <version>0.6.9</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.milo</groupId>
+            <artifactId>sdk-server</artifactId>
+            <version>0.6.9</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>31.0.1-jre</version>
+        </dependency>
+
+        <!-- influxdb -->
+        <dependency>
+            <groupId>com.influxdb</groupId>
+            <artifactId>influxdb-client-java</artifactId>
+            <version>6.8.0</version>
+        </dependency>
+
+<!--        &lt;!&ndash; websocket &ndash;&gt;-->
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-starter-websocket</artifactId>-->
+<!--        </dependency>-->
+
+    </dependencies>
+
+    <build>
+        <!-- 设置构建的 jar 包名 -->
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <!-- 打包 -->
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring.boot.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>
\ No newline at end of file
diff --git a/iailab-module-data/pom.xml b/iailab-module-data/pom.xml
new file mode 100644
index 0000000..72f4f29
--- /dev/null
+++ b/iailab-module-data/pom.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.iailab</groupId>
+        <artifactId>iailab-platform</artifactId>
+        <version>${revision}</version>
+    </parent>
+
+    <artifactId>iailab-module-data</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>iailab-module-data-biz</module>
+        <module>iailab-module-data-api</module>
+    </modules>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+</project>
\ No newline at end of file
diff --git a/iailab-module-infra/iailab-module-infra-biz/pom.xml b/iailab-module-infra/iailab-module-infra-biz/pom.xml
index 8c1416d..e9608d9 100644
--- a/iailab-module-infra/iailab-module-infra-biz/pom.xml
+++ b/iailab-module-infra/iailab-module-infra-biz/pom.xml
@@ -19,12 +19,6 @@
     </description>
 
     <dependencies>
-        <!-- Spring Cloud 基础 -->
-        <dependency>
-            <groupId>org.springframework.cloud</groupId>
-            <artifactId>spring-cloud-starter-bootstrap</artifactId>
-        </dependency>
-
         <!-- 依赖服务 -->
         <dependency>
             <groupId>com.iailab</groupId>
diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/file/FileConfigDO.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/file/FileConfigDO.java
index e18a2b8..719279e 100644
--- a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/file/FileConfigDO.java
+++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/file/FileConfigDO.java
@@ -17,6 +17,8 @@
 import com.fasterxml.jackson.core.type.TypeReference;
 import lombok.*;
 
+import java.lang.reflect.Field;
+
 /**
  * 文件配置表
  *
@@ -65,8 +67,16 @@
 
     public static class FileClientConfigTypeHandler extends AbstractJsonTypeHandler<Object> {
 
+        public FileClientConfigTypeHandler(Class<?> type) {
+            super(type);
+        }
+
+        public FileClientConfigTypeHandler(Class<?> type, Field field) {
+            super(type, field);
+        }
+
         @Override
-        protected Object parse(String json) {
+        public Object parse(String json) {
             FileClientConfig config = JsonUtils.parseObjectQuietly(json, new TypeReference<FileClientConfig>() {});
             if (config != null) {
                 return config;
@@ -92,7 +102,7 @@
         }
 
         @Override
-        protected String toJson(Object obj) {
+        public String toJson(Object obj) {
             return JsonUtils.toJsonString(obj);
         }
 
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 9069e30..4731bd7 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
@@ -24,8 +24,10 @@
             @Override
             public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
                 // Swagger 接口文档
-                registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据
-                        .antMatchers("/swagger-ui.html").permitAll(); // Swagger UI
+                registry.antMatchers("/v3/api-docs/**").permitAll()
+                        .antMatchers("/webjars/**").permitAll()
+                        .antMatchers("/swagger-ui").permitAll()
+                        .antMatchers("/swagger-ui/**").permitAll();
                 // Spring Boot Actuator 的安全配置
                 registry.antMatchers("/actuator").anonymous()
                         .antMatchers("/actuator/**").anonymous();
diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/config/ConfigService.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/config/ConfigService.java
index ce85e00..b9a7a3f 100644
--- a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/config/ConfigService.java
+++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/config/ConfigService.java
@@ -60,4 +60,12 @@
      */
     PageResult<ConfigDO> getConfigPage(@Valid ConfigPageReqVO reqVO);
 
+    /**
+     * 根据参数编码,获取参数的value值
+     *
+     * @param configCode  参数编码
+     */
+    String getValue(String configCode);
+
+
 }
diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/config/ConfigServiceImpl.java b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/config/ConfigServiceImpl.java
index 6689caa..53400e7 100644
--- a/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/config/ConfigServiceImpl.java
+++ b/iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/config/ConfigServiceImpl.java
@@ -9,10 +9,15 @@
 import com.iailab.module.infra.enums.config.ConfigTypeEnum;
 import com.google.common.annotations.VisibleForTesting;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
 
 import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static com.iailab.module.infra.enums.ErrorCodeConstants.*;
@@ -27,6 +32,9 @@
 
     @Resource
     private ConfigMapper configMapper;
+
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
 
     @Override
     public Long createConfig(ConfigSaveReqVO createReqVO) {
@@ -106,4 +114,15 @@
         }
     }
 
+    @Override
+    public String getValue(String configCode) {
+        String paramValue = stringRedisTemplate.opsForValue().get(configCode);
+        if(paramValue == null){
+            ConfigDO configDO = configMapper.selectByKey(configCode);
+            paramValue = configDO.getValue();
+            stringRedisTemplate.opsForValue().set(configCode, paramValue);
+        }
+        return paramValue;
+    }
+
 }
diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-local.yaml b/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-local.yaml
new file mode 100644
index 0000000..861fa2e
--- /dev/null
+++ b/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-local.yaml
@@ -0,0 +1,164 @@
+--- #################### 注册中心 + 配置中心相关配置 ####################
+
+spring:
+  cloud:
+    nacos:
+      server-addr: @nacos.server@ # Nacos 服务器地址
+      username: @nacos.username@
+      password: @nacos.password@
+      discovery: # 【配置中心】配置项
+        namespace: @nacos.namespace@ # 命名空间。这里使用 dev 开发环境
+        group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
+        metadata:
+          version: @nacos.metadata.version@ # 服务实例的版本号,可用于灰度发布
+      config: # 【注册中心】配置项
+        namespace: @nacos.namespace@ # 命名空间。这里使用 dev 开发环境
+        group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
+
+--- #################### 数据库相关配置 ####################
+spring:
+
+  # 数据源配置项
+  autoconfigure:
+    exclude:
+      - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
+      - de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration # 禁用 Spring Boot Admin 的 Server 的自动配置
+      - de.codecentric.boot.admin.server.cloud.config.AdminServerDiscoveryAutoConfiguration # 禁用 Spring Boot Admin 的 Server 的自动配置
+      - de.codecentric.boot.admin.server.ui.config.AdminServerUiAutoConfiguration # 禁用 Spring Boot Admin 的 Server UI 的自动配置
+      - 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-platform?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
+          #          url: jdbc:mysql://127.0.0.1:3306/iailab-platform?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-platform?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 消息队列相关配置 ####################
+
+# rocketmq 配置项,对应 RocketMQProperties 配置类
+rocketmq:
+  name-server: 127.0.0.1:9876 # RocketMQ Namesrv
+
+spring:
+  # RabbitMQ 配置项,对应 RabbitProperties 配置类
+  rabbitmq:
+    host: 127.0.0.1 # RabbitMQ 服务的地址
+    port: 5672 # RabbitMQ 服务的端口
+    username: guest # RabbitMQ 服务的账号
+    password: guest # RabbitMQ 服务的密码
+  # Kafka 配置项,对应 KafkaProperties 配置类
+  kafka:
+    bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
+
+--- #################### 定时任务相关配置 ####################
+xxl:
+  job:
+    enabled: false # 是否开启调度中心,默认为 true 开启
+    admin:
+      addresses: http://127.0.0.1:9090/xxl-job-admin # 调度中心部署跟地址
+
+--- #################### 服务保障相关配置 ####################
+
+# 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]
+      # Spring Boot Admin Server 服务端的相关配置
+      context-path: /admin # 配置 Spring
+
+# 日志文件配置
+logging:
+  level:
+    # 配置自己写的 MyBatis Mapper 打印日志
+    com.iailab.module.infra.dal.mysql: debug
+    com.iailab.module.infra.dal.mysql.logger.ApiErrorLogMapper: INFO # 配置 ApiErrorLogMapper 的日志级别为 info,避免和 GlobalExceptionHandler 重复打印
+    com.iailab.module.infra.dal.mysql.file.FileConfigMapper: INFO # 配置 FileConfigMapper 的日志级别为 info
+
+--- #################### 平台相关配置 ####################
+
+# 平台配置项,设置当前项目所有自定义的配置
+iailab:
+  env: # 多环境的配置项
+    tag: ${HOSTNAME}
+  security:
+    mock-enable: true
+  xss:
+    enable: false
+    exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
+      - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
+      - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
+  access-log: # 访问日志的配置项
+    enable: false
+  demo: false # 关闭演示模式
diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application.yaml b/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application.yaml
index 1e56de7..a1b0c23 100644
--- a/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application.yaml
+++ b/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application.yaml
@@ -1,7 +1,18 @@
 spring:
+  application:
+    name: infra-server
+
+  profiles:
+    active: local
+
   main:
     allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。
     allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务
+
+  config:
+    import:
+      - optional:classpath:application-${spring.profiles.active}.yaml # 加载【本地】配置
+      - optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml # 加载【Nacos】的配置
 
   # Servlet 配置
   servlet:
@@ -26,6 +37,13 @@
     type: REDIS
     redis:
       time-to-live: 1h # 设置过期时间为 1 小时
+
+server:
+  port: 48082
+
+logging:
+  file:
+    name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
 
 --- #################### 接口文档配置 ####################
 
@@ -73,7 +91,6 @@
 # VO 转换(数据翻译)相关
 easy-trans:
   is-enable-global: true # 启用全局翻译(拦截所有 SpringMVC ResponseBody 进行自动翻译 )。如果对于性能要求很高可关闭此配置,或通过 @IgnoreTrans 忽略某个接口
-  is-enable-cloud: false # 禁用 TransType.RPC 微服务模式
 
 --- #################### RPC 远程调用相关配置 ####################
 
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/mcs/entity/StModelResultEntity.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/mcs/entity/StModelResultEntity.java
new file mode 100644
index 0000000..32a2cd4
--- /dev/null
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/mcs/entity/StModelResultEntity.java
@@ -0,0 +1,42 @@
+package com.iailab.module.mcs.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 模型返回信息表
+ *
+ * @author lirm ${email}
+ * @since 1.0.0 2023-06-21
+ */
+@Data
+@TableName("t_st_model_result")
+public class StModelResultEntity {
+
+    /**
+     * id
+     */
+	private String id;
+    /**
+     * 模型ID
+     */
+	private String modelId;
+    /**
+     * 行号
+     */
+	private Integer lineIndex;
+    /**
+     * 输出key
+     */
+	private String resultKey;
+    /**
+     * 输出值
+     */
+	private String resultValue;
+    /**
+     * 输出时间
+     */
+	private Date resultTime;
+}
\ No newline at end of file
diff --git a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/permission/RoleApi.java b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/permission/RoleApi.java
index 0c13f44..e1fec28 100644
--- a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/permission/RoleApi.java
+++ b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/permission/RoleApi.java
@@ -1,17 +1,20 @@
 package com.iailab.module.system.api.permission;
 
 import com.iailab.framework.common.pojo.CommonResult;
+import com.iailab.module.system.api.permission.dto.RoleDTO;
 import com.iailab.module.system.enums.ApiConstants;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.Operation;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 
 import java.util.Collection;
 
-@FeignClient(name = ApiConstants.NAME) // TODO iailab:fallbackFactory =
+@FeignClient(name = ApiConstants.NAME)
 @Tag(name = "RPC 服务 - 角色")
 public interface RoleApi {
 
@@ -22,4 +25,11 @@
     @Parameter(name = "ids", description = "角色编号数组", example = "1,2", required = true)
     CommonResult<Boolean> validRoleList(@RequestParam("ids") Collection<Long> ids);
 
+    @Operation(summary = "Feign接口-保存或者修改角色")
+    @PostMapping("/api/feign/roles/save")
+    void saveRoleInfo(@RequestBody RoleDTO roleDTO);
+
+    @Operation(summary = "Feign接口-根据角色名称查询角色")
+    @GetMapping("/api/feign/roles/getRoleByName")
+    RoleDTO getRoleByName(@RequestParam("name") String name);
 }
\ No newline at end of file
diff --git a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/user/AdminUserApi.java b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/user/AdminUserApi.java
index 2f632ff..6f4b4d6 100644
--- a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/user/AdminUserApi.java
+++ b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/user/AdminUserApi.java
@@ -11,6 +11,8 @@
 import io.swagger.v3.oas.annotations.Operation;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 
 import java.util.*;
@@ -86,4 +88,8 @@
         return getUser(Convert.toLong(id)).getCheckedData();
     }
 
+    @Operation(summary = "Feign接口-保存或者修改用户")
+    @PostMapping("/api/feign/users/saveOrUpdate")
+    void saveOrUpdateUserInfo(@RequestBody AdminUserRespDTO userRespDTO);
+
 }
diff --git a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/user/dto/AdminUserRespDTO.java b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/user/dto/AdminUserRespDTO.java
index fcc5984..e031950 100644
--- a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/user/dto/AdminUserRespDTO.java
+++ b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/user/dto/AdminUserRespDTO.java
@@ -4,6 +4,7 @@
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import java.util.List;
 import java.util.Set;
 
 @Schema(description = "RPC 服务 - Admin 用户 Response DTO")
@@ -12,6 +13,9 @@
 
     @Schema(description = "用户 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private Long id;
+
+    @Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "admin")
+    private String username;
 
     @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小王")
     private String nickname;
@@ -28,4 +32,7 @@
     @Schema(description = "手机号码", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
     private String mobile;
 
+    @Schema(description = "角色ID列表")
+    private Set<Long> roleIdList;
+
 }
diff --git a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/oauth2/OAuth2GrantTypeEnum.java b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/oauth2/OAuth2GrantTypeEnum.java
index 8c0163d..efe9541 100644
--- a/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/oauth2/OAuth2GrantTypeEnum.java
+++ b/iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/oauth2/OAuth2GrantTypeEnum.java
@@ -22,7 +22,7 @@
 
     private final String grantType;
 
-    public static OAuth2GrantTypeEnum getByGranType(String grantType) {
+    public static OAuth2GrantTypeEnum getByGrantType(String grantType) {
         return ArrayUtil.firstMatch(o -> o.getGrantType().equals(grantType), values());
     }
 
diff --git a/iailab-module-system/iailab-module-system-biz/pom.xml b/iailab-module-system/iailab-module-system-biz/pom.xml
index 2f59f0e..54eec59 100644
--- a/iailab-module-system/iailab-module-system-biz/pom.xml
+++ b/iailab-module-system/iailab-module-system-biz/pom.xml
@@ -19,10 +19,10 @@
 
     <dependencies>
         <!-- Spring Cloud 基础 -->
-        <dependency>
-            <groupId>org.springframework.cloud</groupId>
-            <artifactId>spring-cloud-starter-bootstrap</artifactId>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.cloud</groupId>-->
+<!--            <artifactId>spring-cloud-starter-bootstrap</artifactId>-->
+<!--        </dependency>-->
 
         <dependency>
             <groupId>com.iailab</groupId>
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/permission/RoleApiImpl.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/permission/RoleApiImpl.java
index 59cdd9f..2afb85f 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/permission/RoleApiImpl.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/permission/RoleApiImpl.java
@@ -1,6 +1,9 @@
 package com.iailab.module.system.api.permission;
 
 import com.iailab.framework.common.pojo.CommonResult;
+import com.iailab.framework.common.util.object.ConvertUtils;
+import com.iailab.module.system.api.permission.dto.RoleDTO;
+import com.iailab.module.system.dal.dataobject.permission.RoleDO;
 import com.iailab.module.system.service.permission.RoleService;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.RestController;
@@ -22,4 +25,17 @@
         roleService.validateRoleList(ids);
         return success(true);
     }
+
+    @Override
+    public void saveRoleInfo(RoleDTO roleDTO) {
+        RoleDO entity = ConvertUtils.sourceToTarget(roleDTO, RoleDO.class);
+        if (roleService.getRoleByName(entity.getName()) == null) {
+            roleService.insert(entity);
+        }
+    }
+
+    @Override
+    public RoleDTO getRoleByName(String name) {
+        return ConvertUtils.sourceToTarget(roleService.getRoleByName(name),RoleDTO.class);
+    }
 }
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/user/AdminUserApiImpl.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/user/AdminUserApiImpl.java
index 02428bc..e951bd2 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/user/AdminUserApiImpl.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/user/AdminUserApiImpl.java
@@ -4,10 +4,13 @@
 import cn.hutool.core.util.ObjUtil;
 import com.iailab.framework.common.pojo.CommonResult;
 import com.iailab.framework.common.util.object.BeanUtils;
+import com.iailab.framework.common.util.object.ConvertUtils;
 import com.iailab.module.system.api.user.dto.AdminUserRespDTO;
+import com.iailab.module.system.controller.admin.user.vo.user.UserSaveReqVO;
 import com.iailab.module.system.dal.dataobject.dept.DeptDO;
 import com.iailab.module.system.dal.dataobject.user.AdminUserDO;
 import com.iailab.module.system.service.dept.DeptService;
+import com.iailab.module.system.service.permission.PermissionService;
 import com.iailab.module.system.service.user.AdminUserService;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.RestController;
@@ -27,6 +30,8 @@
     private AdminUserService userService;
     @Resource
     private DeptService deptService;
+    @Resource
+    private PermissionService permissionService;
 
     @Override
     public CommonResult<AdminUserRespDTO> getUser(Long id) {
@@ -86,4 +91,18 @@
         return success(true);
     }
 
+    @Override
+    public void saveOrUpdateUserInfo(AdminUserRespDTO userRespDTO) {
+        AdminUserDO entity = ConvertUtils.sourceToTarget(userRespDTO, AdminUserDO.class);
+        AdminUserDO dto = userService.getUserByUsername(entity.getUsername());
+        UserSaveReqVO bean = BeanUtils.toBean(dto, UserSaveReqVO.class);
+        if (dto != null) {
+            bean.setId(dto.getId());
+            userService.updateUser(bean);
+        } else {
+            userService.createUser(bean);
+        }
+        permissionService.assignUserRole(entity.getId(), userRespDTO.getRoleIdList());
+    }
+
 }
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 52fb0bd..9aa2241 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
@@ -39,6 +39,7 @@
 import static com.iailab.framework.common.util.collection.CollectionUtils.convertSet;
 import static com.iailab.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
+
 @Tag(name = "管理后台 - 认证")
 @RestController
 @RequestMapping("/system/auth")
@@ -109,7 +110,7 @@
         // 1.3 获得菜单列表
         Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId));
         List<MenuDO> menuList = menuService.getMenuList(menuIds);
-        menuList.removeIf(menu -> !CommonStatusEnum.ENABLE.getStatus().equals(menu.getStatus())); // 移除禁用的菜单
+        menuList = menuService.filterDisableMenus(menuList);
 
         // 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 f8e8704..44791bf 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
@@ -105,7 +105,7 @@
                                                                      @RequestParam(value = "refresh_token", required = false) String refreshToken) { // 刷新模式
         List<String> scopes = OAuth2Utils.buildScopes(scope);
         // 1.1 校验授权类型
-        OAuth2GrantTypeEnum grantTypeEnum = OAuth2GrantTypeEnum.getByGranType(grantType);
+        OAuth2GrantTypeEnum grantTypeEnum = OAuth2GrantTypeEnum.getByGrantType(grantType);
         if (grantTypeEnum == null) {
             throw exception0(BAD_REQUEST.getCode(), StrUtil.format("未知授权类型({})", grantType));
         }
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/permission/RoleDO.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/permission/RoleDO.java
index bbd872e..1dbb0fd 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/permission/RoleDO.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/permission/RoleDO.java
@@ -1,7 +1,7 @@
 package com.iailab.module.system.dal.dataobject.permission;
 
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
 import com.iailab.framework.common.enums.CommonStatusEnum;
-import com.iailab.framework.mybatis.core.type.JsonLongSetTypeHandler;
 import com.iailab.module.system.enums.permission.DataScopeEnum;
 import com.iailab.framework.tenant.core.db.TenantBaseDO;
 import com.iailab.module.system.enums.permission.RoleTypeEnum;
@@ -72,7 +72,7 @@
      *
      * 适用于 {@link #dataScope} 的值为 {@link DataScopeEnum#DEPT_CUSTOM} 时
      */
-    @TableField(typeHandler = JsonLongSetTypeHandler.class)
+    @TableField(typeHandler = JacksonTypeHandler.class)
     private Set<Long> dataScopeDeptIds;
 
 }
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 67c3e28..7cef0a1 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
@@ -1,8 +1,8 @@
 package com.iailab.module.system.dal.dataobject.tenant;
 
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
 import com.iailab.framework.common.enums.CommonStatusEnum;
 import com.iailab.framework.mybatis.core.dataobject.BaseDO;
-import com.iailab.framework.mybatis.core.type.JsonLongSetTypeHandler;
 import com.baomidou.mybatisplus.annotation.KeySequence;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -46,7 +46,7 @@
     /**
      * 关联的菜单编号
      */
-    @TableField(typeHandler = JsonLongSetTypeHandler.class)
+    @TableField(typeHandler = JacksonTypeHandler.class)
     private Set<Long> menuIds;
 
 }
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/user/AdminUserDO.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/user/AdminUserDO.java
index a9badf5..d561fca 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/user/AdminUserDO.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/user/AdminUserDO.java
@@ -1,7 +1,7 @@
 package com.iailab.module.system.dal.dataobject.user;
 
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
 import com.iailab.framework.common.enums.CommonStatusEnum;
-import com.iailab.framework.mybatis.core.type.JsonLongSetTypeHandler;
 import com.iailab.framework.tenant.core.db.TenantBaseDO;
 import com.iailab.module.system.enums.common.SexEnum;
 import com.baomidou.mybatisplus.annotation.KeySequence;
@@ -58,7 +58,7 @@
     /**
      * 岗位编号数组
      */
-    @TableField(typeHandler = JsonLongSetTypeHandler.class)
+    @TableField(typeHandler = JacksonTypeHandler.class)
     private Set<Long> postIds;
     /**
      * 用户邮箱
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 98b40a5..a1ea09e 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
@@ -1,5 +1,6 @@
 package com.iailab.module.system.service.permission;
 
+
 import com.iailab.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
 import com.iailab.module.system.controller.admin.permission.vo.menu.MenuSaveVO;
 import com.iailab.module.system.dal.dataobject.permission.MenuDO;
@@ -10,7 +11,7 @@
 /**
  * 菜单 Service 接口
  *
- * @author iailab
+ * @author 芋道源码
  */
 public interface MenuService {
 
@@ -53,6 +54,14 @@
     List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO);
 
     /**
+     * 过滤掉关闭的菜单及其子菜单
+     *
+     * @param list 菜单列表
+     * @return 过滤后的菜单列表
+     */
+    List<MenuDO> filterDisableMenus(List<MenuDO> list);
+
+    /**
      * 筛选菜单列表
      *
      * @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 125fb04..9c90502 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
@@ -1,6 +1,10 @@
 package com.iailab.module.system.service.permission;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjUtil;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+import com.iailab.framework.common.enums.CommonStatusEnum;
 import com.iailab.framework.common.util.object.BeanUtils;
 import com.iailab.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
 import com.iailab.module.system.controller.admin.permission.vo.menu.MenuSaveVO;
@@ -9,8 +13,6 @@
 import com.iailab.module.system.dal.redis.RedisKeyConstants;
 import com.iailab.module.system.enums.permission.MenuTypeEnum;
 import com.iailab.module.system.service.tenant.TenantService;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.Cacheable;
@@ -19,18 +21,19 @@
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
 
 import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static com.iailab.framework.common.util.collection.CollectionUtils.convertList;
+import static com.iailab.framework.common.util.collection.CollectionUtils.convertMap;
 import static com.iailab.module.system.dal.dataobject.permission.MenuDO.ID_ROOT;
 import static com.iailab.module.system.enums.ErrorCodeConstants.*;
+
 
 /**
  * 菜单 Service 实现
  *
- * @author iailab
+ * @author 芋道源码
  */
 @Service
 @Slf4j
@@ -106,6 +109,7 @@
 
     @Override
     public List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO) {
+        // 查询所有菜单,并过滤掉关闭的节点
         List<MenuDO> menus = getMenuList(reqVO);
         // 开启多租户的情况下,需要过滤掉未开通的菜单
         tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId())));
@@ -113,6 +117,50 @@
     }
 
     @Override
+    public List<MenuDO> filterDisableMenus(List<MenuDO> menuList) {
+        if (CollUtil.isEmpty(menuList)){
+            return Collections.emptyList();
+        }
+        Map<Long, MenuDO> menuMap = convertMap(menuList, MenuDO::getId);
+
+        // 遍历 menu 菜单,查找不是禁用的菜单,添加到 enabledMenus 结果
+        List<MenuDO> enabledMenus = new ArrayList<>();
+        Set<Long> disabledMenuCache = new HashSet<>(); // 存下递归搜索过被禁用的菜单,防止重复的搜索
+        for (MenuDO menu : menuList) {
+            if (isMenuDisabled(menu, menuMap, disabledMenuCache)) {
+                continue;
+            }
+            enabledMenus.add(menu);
+        }
+        return enabledMenus;
+    }
+
+    private boolean isMenuDisabled(MenuDO node, Map<Long, MenuDO> menuMap, Set<Long> disabledMenuCache) {
+        // 如果已经判定是禁用的节点,直接结束
+        if (disabledMenuCache.contains(node.getId())) {
+            return true;
+        }
+
+        // 1. 遍历到 parentId 为根节点,则无需判断
+        Long parentId = node.getParentId();
+        if (ObjUtil.equal(parentId, ID_ROOT)) {
+            if (CommonStatusEnum.isDisable(node.getStatus())) {
+                disabledMenuCache.add(node.getId());
+                return true;
+            }
+            return false;
+        }
+
+        // 2. 继续遍历 parent 节点
+        MenuDO parent = menuMap.get(parentId);
+        if (parent == null || isMenuDisabled(parent, menuMap, disabledMenuCache)) {
+            disabledMenuCache.add(node.getId());
+            return true;
+        }
+        return false;
+    }
+
+    @Override
     public List<MenuDO> getMenuList(MenuListReqVO reqVO) {
         return menuMapper.selectList(reqVO);
     }
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/RoleService.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/RoleService.java
index 3010453..ebeb949 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/RoleService.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/RoleService.java
@@ -121,4 +121,13 @@
      */
     void validateRoleList(Collection<Long> ids);
 
+    /**
+     * 根据角色名获得角色
+     *
+     * @param name 角色编号
+     * @return 角色
+     */
+    RoleDO getRoleByName(String name);
+
+    void insert(RoleDO role);
 }
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/RoleServiceImpl.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/RoleServiceImpl.java
index e512895..b4ae471 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/RoleServiceImpl.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/RoleServiceImpl.java
@@ -8,6 +8,7 @@
 import com.iailab.framework.common.pojo.PageResult;
 import com.iailab.framework.common.util.collection.CollectionUtils;
 import com.iailab.framework.common.util.object.BeanUtils;
+import com.iailab.framework.mybatis.core.query.LambdaQueryWrapperX;
 import com.iailab.module.system.controller.admin.permission.vo.role.RolePageReqVO;
 import com.iailab.module.system.controller.admin.permission.vo.role.RoleSaveReqVO;
 import com.iailab.module.system.dal.dataobject.permission.RoleDO;
@@ -249,6 +250,16 @@
         });
     }
 
+    @Override
+    public RoleDO getRoleByName(String name) {
+        return roleMapper.selectOne(new LambdaQueryWrapperX<RoleDO>().eq(RoleDO::getName, name));
+    }
+
+    @Override
+    public void insert(RoleDO role) {
+        roleMapper.insert(role);
+    }
+
     /**
      * 获得自身的代理对象,解决 AOP 生效问题
      *
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/resources/application-local.yaml b/iailab-module-system/iailab-module-system-biz/src/main/resources/application-local.yaml
new file mode 100644
index 0000000..d24f9d6
--- /dev/null
+++ b/iailab-module-system/iailab-module-system-biz/src/main/resources/application-local.yaml
@@ -0,0 +1,210 @@
+--- #################### 注册中心 + 配置中心相关配置 ####################
+spring:
+  cloud:
+    nacos:
+      server-addr: 127.0.0.1:8848 # Nacos 服务器地址
+      username: nacos
+      password: nacos
+      discovery: # 【配置中心】配置项
+        namespace: a7112341-c9e2-4177-bc5b-0d2e8cf0b3bb
+        group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
+        metadata:
+          version: 1.0.0 # 服务实例的版本号,可用于灰度发布
+      config: # 【注册中心】配置项
+        namespace: a7112341-c9e2-4177-bc5b-0d2e8cf0b3bb
+        group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
+
+--- #################### 数据库相关配置 ####################
+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-platform?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
+          #          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?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/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
+          username: root
+          password: 123456
+
+  # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
+  redis:
+    host: 172.16.8.100 # 地址
+    port: 6379 # 端口
+    database: 0 # 数据库索引
+    password: 123456 # 密码,建议生产环境开启
+
+--- #################### MQ 消息队列相关配置 ####################
+
+# rocketmq 配置项,对应 RocketMQProperties 配置类
+rocketmq:
+  name-server: 127.0.0.1:9876 # RocketMQ Namesrv
+
+spring:
+  # RabbitMQ 配置项,对应 RabbitProperties 配置类
+  rabbitmq:
+    host: 127.0.0.1 # RabbitMQ 服务的地址
+    port: 5672 # RabbitMQ 服务的端口
+    username: guest # RabbitMQ 服务的账号
+    password: guest # RabbitMQ 服务的密码
+  # Kafka 配置项,对应 KafkaProperties 配置类
+  kafka:
+    bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
+
+--- #################### 定时任务相关配置 ####################
+
+xxl:
+  job:
+    enabled: true # 是否开启调度中心,默认为 true 开启
+    admin:
+      addresses: http://127.0.0.1:9090/xxl-job-admin # 调度中心部署跟地址
+
+--- #################### 服务保障相关配置 ####################
+
+# 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.system.dal.mysql: debug
+    com.iailab.module.system.dal.mysql.sensitiveword.SensitiveWordMapper: INFO # 配置 SensitiveWordMapper 的日志级别为 info
+    com.iailab.module.system.dal.mysql.sms.SmsChannelMapper: INFO # 配置 SmsChannelMapper 的日志级别为 info
+    #org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿:先禁用,Spring Boot 3.X 存在部分错误的 WARN 提示
+
+--- #################### 微信公众号、小程序相关配置 ####################
+wx:
+  mp: # 公众号配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
+    #    app-id: wx041349c6f39b268b
+    #    secret: 5abee519483bc9f8cb37ce280e814bd0
+    app-id: wx5b23ba7a5589ecbb # 测试号
+    secret: 2a7b3b20c537e52e74afd395eb85f61f
+    # 存储配置,解决 AccessToken 的跨节点的共享
+    config-storage:
+      type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
+      key-prefix: wx # Redis Key 的前缀
+      http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
+  miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
+    #    appid: wx62056c0d5e8db250
+    #    secret: 333ae72f41552af1e998fe1f54e1584a
+    appid: wx63c280fe3248a3e7 # wenhualian的接口测试号
+    secret: 6f270509224a7ae1296bbf1c8cb97aed
+    config-storage:
+      type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
+      key-prefix: wa # Redis Key 的前缀
+      http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
+
+--- #################### 平台相关配置 ####################
+
+# 平台配置项,设置当前项目所有自定义的配置
+iailab:
+  env: # 多环境的配置项
+    tag: ${HOSTNAME}
+  captcha:
+    enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试
+  security:
+    mock-enable: true
+  xss:
+    enable: false
+    exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
+      - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
+      - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
+  access-log: # 访问日志的配置项
+    enable: false
+  demo: false # 关闭演示模式
+
+justauth:
+  enabled: true
+  type:
+    DINGTALK: # 钉钉
+      client-id: dingvrnreaje3yqvzhxg
+      client-secret: i8E6iZyDvZj51JIb0tYsYfVQYOks9Cq1lgryEjFRqC79P3iJcrxEwT6Qk2QvLrLI
+      ignore-check-redirect-uri: true
+    WECHAT_ENTERPRISE: # 企业微信
+      client-id: wwd411c69a39ad2e54
+      client-secret: 1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw
+      agent-id: 1000004
+      ignore-check-redirect-uri: true
+    # noinspection SpringBootApplicationYaml
+    WECHAT_MINI_APP: # 微信小程序
+      client-id: ${wx.miniapp.appid}
+      client-secret: ${wx.miniapp.secret}
+      ignore-check-redirect-uri: true
+      ignore-check-state: true # 微信小程序,不会使用到 state,所以不进行校验
+    WECHAT_MP: # 微信公众号
+      client-id: ${wx.mp.app-id}
+      client-secret: ${wx.mp.secret}
+      ignore-check-redirect-uri: true
+  cache:
+    type: REDIS
+    prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE::
+    timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/resources/application.yaml b/iailab-module-system/iailab-module-system-biz/src/main/resources/application.yaml
index 3d9776b..deb9212 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/resources/application.yaml
+++ b/iailab-module-system/iailab-module-system-biz/src/main/resources/application.yaml
@@ -1,7 +1,18 @@
 spring:
+  application:
+    name: system-server
+
+  profiles:
+    active: local
+
   main:
     allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。
     allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务
+
+  config:
+    import:
+      - optional:classpath:application-${spring.profiles.active}.yaml # 加载【本地】配置
+      - optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml # 加载【Nacos】的配置
 
   # Servlet 配置
   servlet:
@@ -26,6 +37,13 @@
     type: REDIS
     redis:
       time-to-live: 1h # 设置过期时间为 1 小时
+
+server:
+  port: 48081
+
+logging:
+  file:
+    name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
 
 --- #################### 接口文档配置 ####################
 
@@ -146,7 +164,7 @@
     version: ${iailab.info.version}
     base-package: ${iailab.info.base-package}
   captcha:
-    enable: true # 验证码的开关,默认为 true;
+    enable: false # 验证码的开关,默认为 true;
   tenant: # 多租户相关配置项
     enable: true
     ignore-urls:
diff --git a/pom.xml b/pom.xml
index 8089c92..d0a380e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,15 +8,15 @@
     <version>${revision}</version>
     <packaging>pom</packaging>
     <modules>
-<!--        <module>iailab-server</module>-->
-<!--        <module>iailab-dependencies</module>-->
         <module>iailab-framework</module>
+        <module>iailab-cloud</module>
         <!--  各种 module 拓展 -->
         <module>iailab-module-system</module>
         <module>iailab-module-infra</module>
         <module>iailab-module-bpm</module>
         <module>iailab-module-report</module>
-        <module>iailab-cloud</module>
+        <module>iailab-module-data</module>
+        <module>iailab-module-model</module>
     </modules>
 
     <name>${project.artifactId}</name>
@@ -34,28 +34,29 @@
         <flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version>
         <!-- 统一依赖管理 -->
         <spring.boot.version>2.7.18</spring.boot.version>
-        <spring.cloud.version>2021.0.5</spring.cloud.version>
-        <spring.cloud.alibaba.version>2021.0.5.0</spring.cloud.alibaba.version>
+        <spring.cloud.version>2021.0.9</spring.cloud.version>
+        <spring.cloud.alibaba.version>2021.0.6.1</spring.cloud.alibaba.version>
         <!-- Web 相关 -->
         <servlet.versoin>2.5</servlet.versoin>
-        <springdoc.version>1.6.15</springdoc.version>
-        <knife4j.version>4.3.0</knife4j.version>
+        <springdoc.version>1.7.0</springdoc.version>
+        <knife4j.version>4.5.0</knife4j.version>
         <!-- DB 相关 -->
-        <druid.version>1.2.21</druid.version>
-        <mybatis-plus.version>3.5.5</mybatis-plus.version>
-        <mybatis-plus-generator.version>3.5.5</mybatis-plus-generator.version>
-        <dynamic-datasource.version>4.3.0</dynamic-datasource.version>
-        <mybatis-plus-join.version>1.4.10</mybatis-plus-join.version>
-        <easy-trans.version>2.2.11</easy-trans.version>
-        <redisson.version>3.18.0</redisson.version> <!-- Spring Boot 2.X 最多使用 3.18.0 版本,否则会报 Tuple NoClassDefFoundError -->
+        <druid.version>1.2.23</druid.version>
+        <mybatis.version>3.5.16</mybatis.version>
+        <mybatis-plus.version>3.5.7</mybatis-plus.version>
+        <mybatis-plus-generator.version>3.5.7</mybatis-plus-generator.version>
+        <dynamic-datasource.version>4.3.1</dynamic-datasource.version>
+        <mybatis-plus-join.version>1.4.13</mybatis-plus-join.version>
+        <easy-trans.version>3.0.5</easy-trans.version>
+        <redisson.version>3.32.0</redisson.version> <!-- Spring Boot 2.X 最多使用 3.18.0 版本,否则会报 Tuple NoClassDefFoundError -->
         <dm8.jdbc.version>8.1.3.62</dm8.jdbc.version>
         <!-- 消息队列 -->
-        <rocketmq-spring.version>2.2.3</rocketmq-spring.version>
+        <rocketmq-spring.version>2.3.0</rocketmq-spring.version>
         <!-- RPC 相关 -->
         <!-- Config 配置中心相关 -->
         <apollo.version>1.9.2</apollo.version>
         <!-- Job 定时任务相关 -->
-        <xxl-job.version>2.3.1</xxl-job.version>
+        <xxl-job.version>2.4.0</xxl-job.version>
         <!-- 服务保障相关 -->
         <lock4j.version>2.2.7</lock4j.version>
         <!-- 监控相关 -->
@@ -70,20 +71,21 @@
         <flowable.version>6.8.0</flowable.version>
         <!-- 工具类相关 -->
         <captcha-plus.version>1.0.8</captcha-plus.version>
-        <jsoup.version>1.17.2</jsoup.version>
-        <lombok.version>1.18.30</lombok.version>
+        <jsoup.version>1.18.1</jsoup.version>
+        <lombok.version>1.18.34</lombok.version>
         <mapstruct.version>1.5.5.Final</mapstruct.version>
-        <hutool.version>5.8.25</hutool.version>
-        <easyexcel.verion>3.3.3</easyexcel.verion>
+        <hutool.version>5.8.29</hutool.version>
+        <joda.time.version>2.10.14</joda.time.version>
+        <easyexcel.verion>3.3.4</easyexcel.verion>
         <velocity.version>2.3</velocity.version>
-        <screw.version>1.0.5</screw.version>
+<!--        <screw.version>1.0.5</screw.version>-->
         <fastjson.version>1.2.83</fastjson.version>
-        <guava.version>33.0.0-jre</guava.version>
-        <guice.version>5.1.0</guice.version>
+        <guava.version>33.2.1-jre</guava.version>
+<!--        <guice.version>5.1.0</guice.version>-->
         <transmittable-thread-local.version>2.14.5</transmittable-thread-local.version>
-        <commons-net.version>3.10.0</commons-net.version>
+        <commons-net.version>3.11.1</commons-net.version>
         <jsch.version>0.1.55</jsch.version>
-        <tika-core.version>2.9.1</tika-core.version>
+        <tika-core.version>2.9.2</tika-core.version>
         <ip2region.version>2.7.0</ip2region.version>
         <bizlog-sdk.version>3.0.6</bizlog-sdk.version>
         <reflections.version>0.10.2</reflections.version>
@@ -121,6 +123,21 @@
                 <!-- 默认环境 -->
                 <activeByDefault>true</activeByDefault>
             </activation>
+        </profile>
+        <profile>
+            <id>test</id>
+            <properties>
+                <!-- 环境标识,需要与配置文件的名称相对应 -->
+                <profiles.active>test</profiles.active>
+                <nacos.server>172.16.8.100:8848</nacos.server>
+                <nacos.discovery.group>DEFAULT_GROUP</nacos.discovery.group>
+                <nacos.config.group>DEFAULT_GROUP</nacos.config.group>
+                <nacos.username>nacos</nacos.username>
+                <nacos.password>nacos</nacos.password>
+                <nacos.namespace>a7112341-c9e2-4177-bc5b-0d2e8cf0b3bb</nacos.namespace>
+                <nacos.metadata.version>1.0.0</nacos.metadata.version>
+                <logstash.address>127.0.0.1:4560</logstash.address>
+            </properties>
         </profile>
         <profile>
             <id>prod</id>
@@ -532,6 +549,12 @@
             </dependency>
 
             <dependency>
+                <groupId>joda-time</groupId>
+                <artifactId>joda-time</artifactId>
+                <version>${joda.time.version}</version>
+            </dependency>
+
+            <dependency>
                 <groupId>com.alibaba</groupId>
                 <artifactId>easyexcel</artifactId>
                 <version>${easyexcel.verion}</version>

--
Gitblit v1.9.3