houzhongjian
2024-07-23 d9f9ba31913bb9f5053ad78109e8a3c1c00f1e6a
update framework
已修改42个文件
已添加7个文件
1751 ■■■■ 文件已修改
iailab-cloud/iailab-gateway/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-cloud/iailab-gateway/src/main/resources/application.yaml 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-cloud/iailab-monitor/pom.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-cloud/iailab-nacos/Dockerfile 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-cloud/iailab-nacos/src/main/resources/application.yaml 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-cloud/iailab-xxl-job/pom.xml 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-cloud/iailab-xxl-job/src/main/java/com/xxl/job/admin/XxlJobAdminApplication.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-cloud/iailab-xxl-job/src/main/resources/application.yaml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-cloud/iailab-xxl-job/src/main/resources/logback.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/config/IailabDataPermissionAutoConfiguration.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/config/MyBatisConfiguration.java 152 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/mapper/BaseMapperX.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/type/JsonLongSetTypeHandler.java 62 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/util/JdbcUtils.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-framework/iailab-common-mybatis/src/main/java/com/iailab/framework/mybatis/core/util/MyBatisUtils.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-framework/iailab-common-security/src/main/java/com/iailab/framework/security/config/IailabSecurityAutoConfiguration.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-framework/iailab-common/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-framework/iailab-common/src/main/java/com/iailab/framework/common/util/date/DateUtils.java 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-data/iailab-module-data-api/pom.xml 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-data/iailab-module-data-biz/pom.xml 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-data/pom.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-infra/iailab-module-infra-biz/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/dal/dataobject/file/FileConfigDO.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/framework/security/config/SecurityConfiguration.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/config/ConfigService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-infra/iailab-module-infra-biz/src/main/java/com/iailab/module/infra/service/config/ConfigServiceImpl.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-local.yaml 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-infra/iailab-module-infra-biz/src/main/resources/application.yaml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/mcs/entity/StModelResultEntity.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/permission/RoleApi.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/user/AdminUserApi.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/api/user/dto/AdminUserRespDTO.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-api/src/main/java/com/iailab/module/system/enums/oauth2/OAuth2GrantTypeEnum.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/pom.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/permission/RoleApiImpl.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/user/AdminUserApiImpl.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/auth/AuthController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/oauth2/OAuth2OpenController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/permission/RoleDO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/tenant/TenantPackageDO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/dal/dataobject/user/AdminUserDO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/MenuServiceImpl.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/RoleService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/service/permission/RoleServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/src/main/resources/application-local.yaml 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-system/iailab-module-system-biz/src/main/resources/application.yaml 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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>
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:
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>
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
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
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>
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) {
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
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>
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();
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)));
    }
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;
    }
}
//
//    @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;
//    }
//
//
//}
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);
    }
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);
//    }
//
//}
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());
        }
    }
}
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));
    }
}
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);
    }
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>
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();
    }
}
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>
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>
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>
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>
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);
        }
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();
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);
}
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;
    }
}
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 # 关闭演示模式
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 远程调用相关配置 ####################
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;
}
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);
}
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);
}
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;
}
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());
    }
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>
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);
    }
}
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());
    }
}
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));
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));
        }
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;
}
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;
}
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;
    /**
     * 用户邮箱
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
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);
    }
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);
}
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 生效问题
     *
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 分钟
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:
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>