Revert "1. 统一包名修改"

This commit is contained in:
chenbowen
2025-09-22 03:05:14 +08:00
parent 30e8a5a704
commit 9a311fc3f6
5602 changed files with 85186 additions and 84972 deletions

View File

Before

Width:  |  Height:  |  Size: 201 KiB

After

Width:  |  Height:  |  Size: 201 KiB

View File

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2021 cloud-cloud
Copyright (c) 2021 yudao-cloud
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

View File

@@ -3,7 +3,7 @@
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">
<parent>
<groupId>com.zt.plat</groupId>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>dsc-base</artifactId>
<version>${revision}</version>
</parent>
@@ -16,35 +16,35 @@
<dependencies>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-module-system-api</artifactId>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-system-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-module-infra-api</artifactId>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-infra-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-module-base-server</artifactId>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-base-server</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-module-contract-order-server</artifactId>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-contract-order-server</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-module-erp-server</artifactId>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-erp-server</artifactId>
<version>${revision}</version>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-web</artifactId>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-web</artifactId>
</dependency>
<dependency>
@@ -55,8 +55,8 @@
<!-- 服务保障相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-protection</artifactId>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-protection</artifactId>
</dependency>
<!-- Registry 注册中心相关 -->
@@ -73,9 +73,9 @@
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-rpc</artifactId>
<!-- 目的:cloud-server 单体启动,禁用 openfeign -->
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-rpc</artifactId>
<!-- 目的:yudao-server 单体启动,禁用 openfeign -->
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>

View File

@@ -0,0 +1,20 @@
package cn.iocoder.yudao.base;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Base 服务器的启动类
*
* @author ZT
*/
@SuppressWarnings("SpringComponentScan") // 忽略 IDEA 无法识别 ${yudao.info.base-package}
@SpringBootApplication(scanBasePackages = {"${yudao.info.base-package}.base", "${yudao.info.base-package}.module"},
excludeName = {})
public class BaseServerApplication {
public static void main(String[] args) {
SpringApplication.run(BaseServerApplication.class, args);
}
}

View File

@@ -1,4 +1,4 @@
package com.zt.plat.base.controller.base;
package cn.iocoder.yudao.base.controller.base;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -6,9 +6,9 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.zt.plat.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import static com.zt.plat.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
/**
* base 控制器

View File

@@ -1,20 +0,0 @@
package com.zt.plat.base;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Base 服务器的启动类
*
* @author ZT
*/
@SuppressWarnings("SpringComponentScan") // 忽略 IDEA 无法识别 ${cloud.info.base-package}
@SpringBootApplication(scanBasePackages = {"${cloud.info.base-package}.base", "${cloud.info.base-package}.module"},
excludeName = {})
public class BaseServerApplication {
public static void main(String[] args) {
SpringApplication.run(BaseServerApplication.class, args);
}
}

View File

@@ -78,7 +78,7 @@ management:
logging:
level:
# 配置自己写的 MyBatis Mapper 打印日志
com.zt.plat.module.base.dal.mysql: debug
cn.iocoder.yudao.module.base.dal.mysql: debug
org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR
mybatis-plus:
@@ -87,7 +87,7 @@ mybatis-plus:
# 芋道配置项,设置当前项目所有自定义的配置
cloud:
yudao:
env: # 多环境的配置项
tag: ${HOSTNAME}
security:

View File

@@ -83,7 +83,7 @@ mybatis-plus:
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
banner: false # 关闭控制台的 Banner 打印
type-aliases-package: com.zt.plat.module.*.dal.dataobject
type-aliases-package: cn.iocoder.yudao.module.*.dal.dataobject
encryptor:
password: XDV71a+xqStEA3WH # 加解密的秘钥,可使用 https://www.imaegoo.com/2020/aes-key-generator/ 网站生成
@@ -101,13 +101,13 @@ xxl:
logpath: ${user.home}/logs/xxl-job/${spring.application.name} # 执行器运行日志文件存储磁盘路径
accessToken: default_token # 执行器通讯TOKEN
cloud:
yudao:
info:
version: 1.0.0
base-package: com.zt.plat
base-package: cn.iocoder.yudao
web:
admin-ui:
url: http://dashboard.cloud.iocoder.cn # Admin 管理后台 UI 的地址
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
xss:
enable: false
exclude-urls: # 如下两个 url仅仅是为了演示去掉配置也没关系
@@ -116,7 +116,7 @@ cloud:
swagger:
title: 管理后台
description: 提供管理员管理的所有功能
version: ${cloud.info.version}
version: ${yudao.info.version}
tenant: # 多租户相关配置项
enable: true

View File

@@ -1,734 +0,0 @@
<?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>
<distributionManagement>
<repository>
<id>ZT</id>
<name>中铜 ZStack 私服</name>
<url>http://172.16.46.63:30708/repository/test/</url>
</repository>
<!-- <snapshotRepository>-->
<!-- <id>ZT</id>-->
<!-- <name>中铜 ZStack 私服</name>-->
<!-- <url>https://your-nexus.example.com/repository/maven-snapshots/</url>-->
<!-- </snapshotRepository>-->
</distributionManagement>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-dependencies</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<description>基础 bom 文件,管理整个项目的依赖版本</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<properties>
<revision>3.0.34</revision>
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
<!-- 统一依赖管理 -->
<spring.boot.version>3.4.5</spring.boot.version>
<spring.cloud.version>2024.0.1</spring.cloud.version>
<spring.cloud.alibaba.version>2023.0.3.2</spring.cloud.alibaba.version>
<!-- Web 相关 -->
<springdoc.version>2.8.3</springdoc.version>
<knife4j.version>4.6.0</knife4j.version>
<!-- DB 相关 -->
<druid.version>1.2.24</druid.version>
<mybatis.version>3.5.19</mybatis.version>
<mybatis-plus.version>3.5.10.1</mybatis-plus.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.6</easy-trans.version>
<redisson.version>3.41.0</redisson.version>
<dm8.jdbc.version>8.1.3.140</dm8.jdbc.version>
<kingbase.jdbc.version>8.6.0</kingbase.jdbc.version>
<opengauss.jdbc.version>5.1.0</opengauss.jdbc.version>
<taos.version>3.3.3</taos.version>
<!-- 消息队列 -->
<rocketmq-spring.version>2.3.2</rocketmq-spring.version>
<!-- RPC 相关 -->
<!-- Config 配置中心相关 -->
<!-- Job 定时任务相关 -->
<xxl-job.version>2.4.0</xxl-job.version>
<!-- 服务保障相关 -->
<lock4j.version>2.2.7</lock4j.version>
<!-- 监控相关 -->
<skywalking.version>9.0.0</skywalking.version>
<spring-boot-admin.version>3.4.5</spring-boot-admin.version>
<opentracing.version>0.33.0</opentracing.version>
<!-- Test 测试相关 -->
<podam.version>8.0.2.RELEASE</podam.version>
<jedis-mock.version>1.1.4</jedis-mock.version>
<mockito-inline.version>5.2.0</mockito-inline.version>
<!-- Bpm 工作流相关 -->
<flowable.version>7.0.1</flowable.version>
<!-- 工具类相关 -->
<anji-plus-captcha.version>1.4.0</anji-plus-captcha.version>
<jsoup.version>1.18.1</jsoup.version>
<lombok.version>1.18.36</lombok.version>
<mapstruct.version>1.6.3</mapstruct.version>
<hutool-5.version>5.8.35</hutool-5.version>
<hutool-6.version>6.0.0-M19</hutool-6.version>
<easyexcel.version>4.0.3</easyexcel.version>
<velocity.version>2.4.1</velocity.version>
<fastjson.version>1.2.83</fastjson.version>
<guava.version>33.4.8-jre</guava.version>
<transmittable-thread-local.version>2.14.5</transmittable-thread-local.version>
<commons-net.version>3.11.1</commons-net.version>
<jsch.version>0.1.55</jsch.version>
<tika-core.version>3.1.0</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>
<netty.version>4.1.116.Final</netty.version>
<mqtt.version>1.2.5</mqtt.version>
<pf4j-spring.version>0.9.0</pf4j-spring.version>
<vertx.version>4.5.13</vertx.version>
<!-- 三方云服务相关 -->
<commons-io.version>2.17.0</commons-io.version>
<commons-compress.version>1.27.1</commons-compress.version>
<awssdk.version>2.30.14</awssdk.version>
<justauth.version>1.16.7</justauth.version>
<justauth-starter.version>1.4.0</justauth-starter.version>
<jimureport.version>1.9.4</jimureport.version>
<weixin-java.version>4.7.5.B</weixin-java.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 统一依赖管理 -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-bom</artifactId>
<version>${netty.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>io.github.mouzt</groupId>
<artifactId>bizlog-sdk</artifactId>
<version>${bizlog-sdk.version}</version>
<exclusions>
<exclusion> <!-- 排除掉springboot依赖使用项目的 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-biz-tenant</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-biz-data-permission</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-biz-ip</artifactId>
<version>${revision}</version>
</dependency>
<!-- Spring 核心 -->
<dependency>
<!-- 用于生成自定义的 Spring @ConfigurationProperties 配置类的说明文件 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-env</artifactId>
<version>${revision}</version>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-web</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-security</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-websocket</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.xingfudeshi</groupId> <!-- TODO 芋艿https://github.com/xiaoymin/knife4j/issues/874 -->
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
<version>${springdoc.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId> <!-- 接口文档 UIknife4j【网关专属】 -->
<artifactId>knife4j-gateway-spring-boot-starter</artifactId>
<version>4.5.0</version> <!-- TODO 芋艿:等 4.5.0 => 4.6.0 -->
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-mybatis</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<!-- 注意:必须声明,避免 flowable 和 mybatis-plus 引入的 mybatis 版本不一致!!! -->
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId> <!-- 代码生成器,使用它解析表结构 -->
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId> <!-- 多数据源 -->
<version>${dynamic-datasource.version}</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-boot-starter</artifactId> <!-- MyBatis 联表查询 -->
<version>${mybatis-plus-join.version}</version>
</dependency>
<dependency>
<groupId>com.fhs-opensource</groupId> <!-- VO 数据翻译 -->
<artifactId>easy-trans-spring-boot-starter</artifactId>
<version>${easy-trans.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fhs-opensource</groupId>
<artifactId>easy-trans-mybatis-plus-extend</artifactId>
<version>${easy-trans.version}</version>
</dependency>
<dependency>
<groupId>com.fhs-opensource</groupId>
<artifactId>easy-trans-anno</artifactId>
<version>${easy-trans.version}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-redis</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>${redisson.version}</version>
</dependency>
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmJdbcDriver18</artifactId>
<version>${dm8.jdbc.version}</version>
</dependency>
<dependency>
<groupId>org.opengauss</groupId>
<artifactId>opengauss-jdbc</artifactId>
<version>${opengauss.jdbc.version}</version>
</dependency>
<dependency>
<groupId>cn.com.kingbase</groupId>
<artifactId>kingbase8</artifactId>
<version>${kingbase.jdbc.version}</version>
</dependency>
<dependency>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>${taos.version}</version>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-rpc</artifactId>
<version>${revision}</version>
</dependency>
<!-- Registry 注册中心相关 -->
<!-- Config 配置中心相关 -->
<!-- Job 定时任务相关 -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${xxl-job.version}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-job</artifactId>
<version>${revision}</version>
</dependency>
<!-- 消息队列相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-mq</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>${rocketmq-spring.version}</version>
</dependency>
<!-- 服务保障相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-protection</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>lock4j-redisson-spring-boot-starter</artifactId>
<version>${lock4j.version}</version>
<exclusions>
<exclusion>
<artifactId>redisson-spring-boot-starter</artifactId>
<groupId>org.redisson</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-monitor</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>${skywalking.version}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>${skywalking.version}</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-opentracing</artifactId>
<version>${skywalking.version}</version>
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <artifactId>opentracing-api</artifactId>-->
<!-- <groupId>io.opentracing</groupId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <artifactId>opentracing-util</artifactId>-->
<!-- <groupId>io.opentracing</groupId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
</dependency>
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-api</artifactId>
<version>${opentracing.version}</version>
</dependency>
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-util</artifactId>
<version>${opentracing.version}</version>
</dependency>
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-noop</artifactId>
<version>${opentracing.version}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId> <!-- 实现 Spring Boot Admin Server 服务端 -->
<version>${spring-boot-admin.version}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId> <!-- 实现 Spring Boot Admin Server 服务端 -->
<version>${spring-boot-admin.version}</version>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-test</artifactId>
<version>${revision}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>${mockito-inline.version}</version> <!-- 支持 Mockito 的 final 类与 static 方法的 mock -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.version}</version>
<exclusions>
<exclusion>
<artifactId>asm</artifactId>
<groupId>org.ow2.asm</groupId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.fppt</groupId> <!-- 单元测试,我们采用内嵌的 Redis 数据库 -->
<artifactId>jedis-mock</artifactId>
<version>${jedis-mock.version}</version>
</dependency>
<dependency>
<groupId>uk.co.jemos.podam</groupId> <!-- 单元测试,随机生成 POJO 类 -->
<artifactId>podam</artifactId>
<version>${podam.version}</version>
</dependency>
<!-- 工作流相关 -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-process</artifactId>
<version>${flowable.version}</version>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-actuator</artifactId>
<version>${flowable.version}</version>
</dependency>
<!-- 工作流相关结束 -->
<!-- 工具类相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-common</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-excel</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool-5.version}</version>
</dependency>
<dependency>
<groupId>org.dromara.hutool</groupId>
<artifactId>hutool-extra</artifactId>
<version>${hutool-6.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>${easyexcel.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>${commons-compress.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId> <!-- 文件类型的识别 -->
<version>${tika-core.version}</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId> <!-- 解决 ThreadLocal 父子线程的传值问题 -->
<version>${transmittable-thread-local.version}</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId> <!-- 解决 ftp 连接 -->
<version>${commons-net.version}</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId> <!-- 解决 sftp 连接 -->
<version>${jsch.version}</version>
</dependency>
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>captcha-spring-boot-starter</artifactId> <!-- 验证码,一般用于登录使用 -->
<version>${anji-plus-captcha.version}</version>
</dependency>
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>${ip2region.version}</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${jsoup.version}</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>${reflections.version}</version>
</dependency>
<!-- 三方云服务相关 -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>${awssdk.version}</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
<version>${weixin-java.version}</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-mp-spring-boot-starter</artifactId>
<version>${weixin-java.version}</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-miniapp-spring-boot-starter</artifactId>
<version>${weixin-java.version}</version>
</dependency>
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
<version>${justauth.version}</version>
</dependency>
<dependency>
<groupId>com.xkcoding.justauth</groupId>
<artifactId>justauth-spring-boot-starter</artifactId>
<version>${justauth-starter.version}</version>
</dependency>
<!-- 积木报表-->
<dependency>
<groupId>org.jeecgframework.jimureport</groupId>
<artifactId>jimureport-spring-boot3-starter-fastjson2</artifactId>
<version>${jimureport.version}</version>
</dependency>
<dependency>
<groupId>org.jeecgframework.jimureport</groupId>
<artifactId>jimubi-spring-boot3-starter</artifactId>
<version>${jimureport.version}</version>
<exclusions>
<exclusion>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- PF4J -->
<dependency>
<groupId>org.pf4j</groupId>
<artifactId>pf4j-spring</artifactId>
<version>${pf4j-spring.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Vert.x -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-mqtt</artifactId>
<version>${vertx.version}</version>
</dependency>
<!-- MQTT -->
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>${mqtt.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!-- 统一 revision 版本 -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>${flatten-maven-plugin.version}</version>
<configuration>
<flattenMode>bom</flattenMode>
<updatePomFile>true</updatePomFile>
</configuration>
<executions>
<execution>
<goals>
<goal>flatten</goal>
</goals>
<id>flatten</id>
<phase>process-resources</phase>
</execution>
<execution>
<goals>
<goal>clean</goal>
</goals>
<id>flatten.clean</id>
<phase>clean</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,156 +0,0 @@
<?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">
<parent>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-framework</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-common</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>定义基础 pojo 类、枚举、工具类等等</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies>
<!-- Spring 核心 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<dependency>
<!-- 用于生成自定义的 Spring @ConfigurationProperties 配置类的说明文件 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
<scope>provided</scope> <!-- 设置为 provided主要是 PageParam 使用到 -->
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId>
<scope>provided</scope> <!-- 设置为 provided主要是 api 包使用到 -->
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<scope>provided</scope> <!-- 设置为 provided主要是 PageParam 使用到 -->
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
</dependency>
<dependency>
<groupId>com.fhs-opensource</groupId> <!-- VO 数据翻译 -->
<artifactId>easy-trans-anno</artifactId> <!-- 默认引入的原因,方便 xxx-module-api 包使用 -->
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -1,4 +0,0 @@
/**
* 针对 infra 模块的 api 包
*/
package com.zt.plat.framework.common.biz.infra;

View File

@@ -1,4 +0,0 @@
/**
* 特殊:用于 framework 下starter 需要调用 biz 业务模块的接口定义!
*/
package com.zt.plat.framework.common.biz;

View File

@@ -1,4 +0,0 @@
/**
* 针对 system 模块的 api 包
*/
package com.zt.plat.framework.common.biz.system;

View File

@@ -1,39 +0,0 @@
package com.zt.plat.framework.common.enums;
import cn.hutool.core.util.ArrayUtil;
import com.zt.plat.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 全局用户类型枚举
*/
@AllArgsConstructor
@Getter
public enum UserTypeEnum implements ArrayValuable<Integer> {
MEMBER(1, "会员"), // 面向 c 端,普通用户
ADMIN(2, "管理员"); // 面向 b 端,管理后台
public static final Integer[] ARRAYS = Arrays.stream(values()).map(UserTypeEnum::getValue).toArray(Integer[]::new);
/**
* 类型
*/
private final Integer value;
/**
* 类型名
*/
private final String name;
public static UserTypeEnum valueOf(Integer value) {
return ArrayUtil.firstMatch(userType -> userType.getValue().equals(value), UserTypeEnum.values());
}
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -1,32 +0,0 @@
package com.zt.plat.framework.common.exception;
import com.zt.plat.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.zt.plat.framework.common.exception.enums.ServiceErrorCodeRange;
import lombok.Data;
/**
* 错误码对象
*
* 全局错误码,占用 [0, 999], 参见 {@link GlobalErrorCodeConstants}
* 业务异常错误码,占用 [1 000 000 000, +∞),参见 {@link ServiceErrorCodeRange}
*
* TODO 错误码设计成对象的原因,为未来的 i18 国际化做准备
*/
@Data
public class ErrorCode {
/**
* 错误码
*/
private final Integer code;
/**
* 错误提示
*/
private final String msg;
public ErrorCode(Integer code, String message) {
this.code = code;
this.msg = message;
}
}

View File

@@ -1,6 +0,0 @@
/**
* 基础的通用类,和框架无关
*
* 例如说CommonResult 为通用返回
*/
package com.zt.plat.framework.common;

View File

@@ -1,7 +0,0 @@
/**
* 对于工具类的选择,优先查找 Hutool 中有没对应的方法
* 如果没有,则自己封装对应的工具类,以 Utils 结尾,用于区分
*
* ps如果担心 Hutool 存在坑的问题,可以阅读 Hutool 的实现源码,以确保可靠性。并且,可以补充相关的单元测试。
*/
package com.zt.plat.framework.common.util;

View File

@@ -1,4 +0,0 @@
/**
* 使用 Hibernate Validator 实现参数校验
*/
package com.zt.plat.framework.common.validation;

View File

@@ -1 +0,0 @@
<http://www.iocoder.cn/Spring-Boot/Validation/?cloud>

View File

@@ -1,54 +0,0 @@
<?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.zt.plat</groupId>
<artifactId>cloud-framework</artifactId>
<version>${revision}</version>
</parent>
<artifactId>cloud-spring-boot-starter-biz-business</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-module-system-api</artifactId>
<version>${revision}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-security</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-common</artifactId>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-biz-data-permission</artifactId>
<version>${revision}</version>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-module-infra-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-rpc</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,33 +0,0 @@
package com.zt.plat.framework.business.config;
import com.zt.plat.framework.business.filter.FileUploadFilter;
import com.zt.plat.framework.business.interceptor.BusinessHeaderInterceptor;
import com.zt.plat.framework.business.interceptor.FileUploadHeaderInterceptor;
import com.zt.plat.framework.web.config.CloudWebAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author chenbowen
*/
@AutoConfiguration(after = CloudWebAutoConfiguration.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class CloudBusinessAutoConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 只拦截增删改和 set 相关的 url
registry.addInterceptor(new BusinessHeaderInterceptor())
.addPathPatterns("/**/add**", "/**/create**", "/**/update**", "/**/edit**", "/**/set**");
registry.addInterceptor(new FileUploadHeaderInterceptor())
.addPathPatterns("/**/add**", "/**/create**", "/**/update**", "/**/edit**", "/**/set**");
}
@Bean
public FilterRegistrationBean<FileUploadFilter> businessHeaderFilter() {
return new FilterRegistrationBean<>(new FileUploadFilter());
}
}

View File

@@ -1,28 +0,0 @@
package com.zt.plat.framework.business.controller;
import com.zt.plat.framework.business.annotation.FileUploadController;
import com.zt.plat.framework.business.vo.FileUploadInfoVO;
import com.zt.plat.framework.common.pojo.CommonResult;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.web.bind.annotation.GetMapping;
import static com.zt.plat.framework.common.pojo.CommonResult.success;
/**
* @author chenbowen
*/
public abstract class AbstractFileUploadController {
protected static String FILE_UPLOAD_SOURCE = "";
@GetMapping("/upload-info")
@Operation(summary = "获取文件上传 source 配置值")
public CommonResult<FileUploadInfoVO> getFileUploadSource() {
FileUploadInfoVO vo = new FileUploadInfoVO();
vo.setSource(FILE_UPLOAD_SOURCE);
return success(vo);
}
protected static void setFileUploadInfo(FileUploadController annotation) {
FILE_UPLOAD_SOURCE = annotation.source();
}
}

View File

@@ -1,28 +0,0 @@
package com.zt.plat.framework.business.framework;
import com.zt.plat.framework.datapermission.core.rule.company.CompanyDataPermissionRuleCustomizer;
import com.zt.plat.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author chenbowen
*/
@Configuration(proxyBeanMethods = false)
public class BusinessDataPermissionConfiguration {
@Bean
public CompanyDataPermissionRuleCustomizer sysCompanyDataPermissionRuleCustomizer() {
return rule -> {
// companyId
rule.addCompanyColumn("demo_contract", "company_id");
};
}
@Bean
public DeptDataPermissionRuleCustomizer businessDeptDataPermissionRuleCustomizer() {
return rule -> {
// dept
rule.addDeptColumn("demo_contract", "dept_id");
};
}
}

View File

@@ -1,13 +0,0 @@
package com.zt.plat.framework.business.framework.rpc;
import com.zt.plat.module.infra.api.businessfile.BusinessFileApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author chenbowen
*/
@AutoConfiguration
@EnableFeignClients(clients = BusinessFileApi.class)
public class CloudBusinessRpcAutoConfiguration {
}

View File

@@ -1,3 +0,0 @@
com.zt.plat.framework.business.config.CloudBusinessAutoConfiguration
com.zt.plat.framework.business.framework.BusinessDataPermissionConfiguration
com.zt.plat.framework.business.framework.rpc.CloudBusinessRpcAutoConfiguration

View File

@@ -1,56 +0,0 @@
<?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">
<parent>
<artifactId>cloud-framework</artifactId>
<groupId>com.zt.plat</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-spring-boot-starter-biz-data-permission</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>数据权限</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-common</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-security</artifactId>
<optional>true</optional> <!-- 可选,如果使用 DeptDataPermissionRule 必须提供 -->
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-mybatis</artifactId>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-rpc</artifactId>
<optional>true</optional>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-biz-tenant</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,54 +0,0 @@
package com.zt.plat.framework.datapermission.config;
import cn.hutool.extra.spring.SpringUtil;
import com.zt.plat.framework.common.biz.system.permission.PermissionCommonApi;
import com.zt.plat.framework.datapermission.core.rule.company.CompanyDataPermissionRule;
import com.zt.plat.framework.datapermission.core.rule.company.CompanyDataPermissionRuleCustomizer;
import com.zt.plat.framework.datapermission.core.rule.dept.DeptDataPermissionRule;
import com.zt.plat.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
import com.zt.plat.framework.security.core.LoginUser;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import java.util.List;
/**
* 基于部门的数据权限 AutoConfiguration
*
* @author ZT
*/
@AutoConfiguration
@ConditionalOnClass(LoginUser.class)
@ConditionalOnBean(value = {CompanyDataPermissionRuleCustomizer.class, DeptDataPermissionRuleCustomizer.class})
public class CloudBusinessDataPermissionAutoConfiguration {
@Bean
public CompanyDataPermissionRule companyDataPermissionRule(List<CompanyDataPermissionRuleCustomizer> customizers) {
// 创建 CompanyDataPermissionRule 对象
CompanyDataPermissionRule rule = new CompanyDataPermissionRule();
// 补全表配置
customizers.forEach(customizer -> customizer.customize(rule));
return rule;
}
@Bean
public DeptDataPermissionRule deptBusinessDataPermissionRule(PermissionCommonApi permissionApi, List<DeptDataPermissionRuleCustomizer> customizers) {
// Cloud 专属逻辑:优先使用本地的 PermissionApi 实现类,而不是 Feign 调用
// 原因:在创建租户时,租户还没创建好,导致 Feign 调用获取数据权限时,报“租户不存在”的错误
try {
PermissionCommonApi permissionApiImpl = SpringUtil.getBean("permissionApiImpl", PermissionCommonApi.class);
if (permissionApiImpl != null) {
permissionApi = permissionApiImpl;
}
} catch (Exception ignored) {}
// 创建 DeptDataPermissionRule 对象
DeptDataPermissionRule rule = new DeptDataPermissionRule(permissionApi);
// 补全表配置
customizers.forEach(customizer -> customizer.customize(rule));
return rule;
}
}

View File

@@ -1,46 +0,0 @@
package com.zt.plat.framework.datapermission.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
import com.zt.plat.framework.datapermission.core.aop.DataPermissionAnnotationAdvisor;
import com.zt.plat.framework.datapermission.core.db.DataPermissionRuleHandler;
import com.zt.plat.framework.datapermission.core.rule.DataPermissionRule;
import com.zt.plat.framework.datapermission.core.rule.DataPermissionRuleFactory;
import com.zt.plat.framework.datapermission.core.rule.DataPermissionRuleFactoryImpl;
import com.zt.plat.framework.mybatis.core.util.MyBatisUtils;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import java.util.List;
/**
* 数据权限的自动配置类
*
* @author ZT
*/
@AutoConfiguration
public class CloudDataPermissionAutoConfiguration {
@Bean
public DataPermissionRuleFactory dataPermissionRuleFactory(List<DataPermissionRule> rules) {
return new DataPermissionRuleFactoryImpl(rules);
}
@Bean
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 handler;
}
@Bean
public DataPermissionAnnotationAdvisor dataPermissionAnnotationAdvisor() {
return new DataPermissionAnnotationAdvisor();
}
}

View File

@@ -1,34 +0,0 @@
package com.zt.plat.framework.datapermission.config;
import com.zt.plat.framework.datapermission.core.rpc.DataPermissionRequestInterceptor;
import com.zt.plat.framework.datapermission.core.rpc.DataPermissionRpcWebFilter;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import static com.zt.plat.framework.common.enums.WebFilterOrderEnum.TENANT_CONTEXT_FILTER;
/**
* 数据权限针对 RPC 的自动配置类
*
* @author ZT
*/
@AutoConfiguration
@ConditionalOnClass(name = "feign.RequestInterceptor")
public class CloudDataPermissionRpcAutoConfiguration {
@Bean
public DataPermissionRequestInterceptor dataPermissionRequestInterceptor() {
return new DataPermissionRequestInterceptor();
}
@Bean
public FilterRegistrationBean<DataPermissionRpcWebFilter> dataPermissionRpcFilter() {
FilterRegistrationBean<DataPermissionRpcWebFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new DataPermissionRpcWebFilter());
registrationBean.setOrder(TENANT_CONTEXT_FILTER - 1); // 顺序没有绝对的要求,在租户 Filter 前面稳妥点
return registrationBean;
}
}

View File

@@ -1,43 +0,0 @@
package com.zt.plat.framework.datapermission.config;
import cn.hutool.extra.spring.SpringUtil;
import com.zt.plat.framework.common.biz.system.permission.PermissionCommonApi;
import com.zt.plat.framework.datapermission.core.rule.dept.DeptDataPermissionRule;
import com.zt.plat.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
import com.zt.plat.framework.security.core.LoginUser;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import java.util.List;
/**
* 基于部门的数据权限 AutoConfiguration
*
* @author ZT
*/
@AutoConfiguration
@ConditionalOnClass(LoginUser.class)
@ConditionalOnBean(value = {PermissionCommonApi.class, DeptDataPermissionRuleCustomizer.class})
public class CloudDeptDataPermissionAutoConfiguration {
@Bean
public DeptDataPermissionRule deptDataPermissionRule(PermissionCommonApi permissionApi, List<DeptDataPermissionRuleCustomizer> customizers) {
// Cloud 专属逻辑:优先使用本地的 PermissionApi 实现类,而不是 Feign 调用
// 原因:在创建租户时,租户还没创建好,导致 Feign 调用获取数据权限时,报“租户不存在”的错误
try {
PermissionCommonApi permissionApiImpl = SpringUtil.getBean("permissionApiImpl", PermissionCommonApi.class);
if (permissionApiImpl != null) {
permissionApi = permissionApiImpl;
}
} catch (Exception ignored) {}
// 创建 DeptDataPermissionRule 对象
DeptDataPermissionRule rule = new DeptDataPermissionRule(permissionApi);
// 补全表配置
customizers.forEach(customizer -> customizer.customize(rule));
return rule;
}
}

View File

@@ -1,21 +0,0 @@
package com.zt.plat.framework.datapermission.core.rule.company;
import com.zt.plat.framework.datapermission.core.rule.dept.DeptDataPermissionRule;
/**
* {@link DeptDataPermissionRule} 的自定义配置接口
*
* @author ZT
*/
@FunctionalInterface
public interface CompanyDataPermissionRuleCustomizer {
/**
* 自定义该权限规则
* 1. 调用 {@link CompanyDataPermissionRule#addCompanyColumn(Class, String)} 方法,配置基于 dept_id 的过滤规则
*
* @param rule 权限规则
*/
void customize(CompanyDataPermissionRule rule);
}

View File

@@ -1,6 +0,0 @@
/**
* 基于部门的数据权限规则
*
* @author ZT
*/
package com.zt.plat.framework.datapermission.core.rule.dept;

View File

@@ -1,4 +0,0 @@
/**
* 基于 JSqlParser 解析 SQL增加数据权限的 WHERE 条件
*/
package com.zt.plat.framework.datapermission;

View File

@@ -1,4 +0,0 @@
com.zt.plat.framework.datapermission.config.CloudDataPermissionAutoConfiguration
com.zt.plat.framework.datapermission.config.CloudDeptDataPermissionAutoConfiguration
com.zt.plat.framework.datapermission.config.CloudBusinessDataPermissionAutoConfiguration
com.zt.plat.framework.datapermission.config.CloudDataPermissionRpcAutoConfiguration

View File

@@ -1,15 +0,0 @@
package com.zt.plat.framework.datapermission.core.util;
import com.zt.plat.framework.datapermission.core.aop.DataPermissionContextHolder;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
public class DataPermissionUtilsTest {
@Test
public void testExecuteIgnore() {
DataPermissionUtils.executeIgnore(() -> assertFalse(DataPermissionContextHolder.get().enable()));
}
}

View File

@@ -1,54 +0,0 @@
<?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">
<parent>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-framework</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-spring-boot-starter-biz-ip</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>IP 拓展,支持如下功能:
1. IP 功能:查询 IP 对应的城市信息
基于 https://gitee.com/lionsoul/ip2region 实现
2. 城市功能:查询城市编码对应的城市信息
基于 https://github.com/modood/Administrative-divisions-of-China 实现
</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-common</artifactId>
</dependency>
<!-- IP地址检索 -->
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -1,11 +0,0 @@
/**
* IP 拓展,支持如下功能:
*
* 1. IP 功能:查询 IP 对应的城市信息
* 基于 https://gitee.com/lionsoul/ip2region 实现
* 2. 城市功能:查询城市编码对应的城市信息
* 基于 https://github.com/modood/Administrative-divisions-of-China 实现
*
* @author ZT
*/
package com.zt.plat.framework.ip;

View File

@@ -1,92 +0,0 @@
<?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">
<parent>
<artifactId>cloud-framework</artifactId>
<groupId>com.zt.plat</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-spring-boot-starter-biz-tenant</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>多租户</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-common</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-security</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-mybatis</artifactId>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-redis</artifactId>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-rpc</artifactId>
<optional>true</optional>
</dependency>
<!-- Job 定时任务相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-job</artifactId>
<optional>true</optional>
</dependency>
<!-- 消息队列相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-mq</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<optional>true</optional>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,234 +0,0 @@
package com.zt.plat.framework.tenant.config;
import cn.hutool.extra.spring.SpringUtil;
import com.zt.plat.framework.common.biz.system.tenant.TenantCommonApi;
import com.zt.plat.framework.common.enums.WebFilterOrderEnum;
import com.zt.plat.framework.mybatis.core.util.MyBatisUtils;
import com.zt.plat.framework.redis.config.CloudCacheProperties;
import com.zt.plat.framework.security.core.service.SecurityFrameworkService;
import com.zt.plat.framework.tenant.core.aop.TenantIgnore;
import com.zt.plat.framework.tenant.core.aop.TenantIgnoreAspect;
import com.zt.plat.framework.tenant.core.db.TenantDatabaseInterceptor;
import com.zt.plat.framework.tenant.core.job.TenantJobAspect;
import com.zt.plat.framework.tenant.core.mq.rabbitmq.TenantRabbitMQInitializer;
import com.zt.plat.framework.tenant.core.mq.redis.TenantRedisMessageInterceptor;
import com.zt.plat.framework.tenant.core.mq.rocketmq.TenantRocketMQInitializer;
import com.zt.plat.framework.tenant.core.redis.TenantRedisCacheManager;
import com.zt.plat.framework.tenant.core.security.TenantSecurityWebFilter;
import com.zt.plat.framework.tenant.core.service.TenantFrameworkService;
import com.zt.plat.framework.tenant.core.service.TenantFrameworkServiceImpl;
import com.zt.plat.framework.tenant.core.web.CompanyVisitContextInterceptor;
import com.zt.plat.framework.tenant.core.web.TenantContextWebFilter;
import com.zt.plat.framework.tenant.core.web.TenantVisitContextInterceptor;
import com.zt.plat.framework.web.config.WebProperties;
import com.zt.plat.framework.web.core.handler.GlobalExceptionHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import jakarta.annotation.Resource;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.BatchStrategies;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.util.pattern.PathPattern;
import java.util.Map;
import java.util.Objects;
import static com.zt.plat.framework.common.util.collection.CollectionUtils.convertList;
@AutoConfiguration
@ConditionalOnProperty(prefix = "cloud.tenant", value = "enable", matchIfMissing = true) // 允许使用 cloud.tenant.enable=false 禁用多租户
@EnableConfigurationProperties(TenantProperties.class)
public class CloudTenantAutoConfiguration {
@Resource
private ApplicationContext applicationContext;
@Bean
public TenantFrameworkService tenantFrameworkService(TenantCommonApi tenantApi) {
// 参见 https://gitee.com/zhijiantianya/cloud-cloud/issues/IC6YZF
try {
TenantCommonApi tenantApiImpl = SpringUtil.getBean("tenantApiImpl", TenantCommonApi.class);
if (tenantApiImpl != null) {
tenantApi = tenantApiImpl;
}
} catch (Exception ignored) {}
return new TenantFrameworkServiceImpl(tenantApi);
}
// ========== AOP ==========
@Bean
public TenantIgnoreAspect tenantIgnoreAspect() {
return new TenantIgnoreAspect();
}
// ========== DB ==========
@Bean
public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantProperties properties,
MybatisPlusInterceptor interceptor) {
TenantLineInnerInterceptor inner = new TenantLineInnerInterceptor(new TenantDatabaseInterceptor(properties));
// 添加到 interceptor 中
// 需要加在首个,主要是为了在分页插件前面。这个是 MyBatis Plus 的规定
MyBatisUtils.addInterceptor(interceptor, inner, 0);
return inner;
}
// ========== WEB ==========
@Bean
public FilterRegistrationBean<TenantContextWebFilter> tenantContextWebFilter(TenantProperties tenantProperties) {
FilterRegistrationBean<TenantContextWebFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new TenantContextWebFilter());
registrationBean.setOrder(WebFilterOrderEnum.TENANT_CONTEXT_FILTER);
addIgnoreUrls(tenantProperties);
return registrationBean;
}
/**
* 如果 Controller 接口上,有 {@link TenantIgnore} 注解,那么添加到忽略的 URL 中
*
* @param tenantProperties 租户配置
*/
private void addIgnoreUrls(TenantProperties tenantProperties) {
// 获得接口对应的 HandlerMethod 集合
RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping)
applicationContext.getBean("requestMappingHandlerMapping");
Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods();
// 获得有 @TenantIgnore 注解的接口
for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethodMap.entrySet()) {
HandlerMethod handlerMethod = entry.getValue();
if (!handlerMethod.hasMethodAnnotation(TenantIgnore.class)) {
continue;
}
// 添加到忽略的 URL 中
if (entry.getKey().getPatternsCondition() != null) {
tenantProperties.getIgnoreUrls().addAll(entry.getKey().getPatternsCondition().getPatterns());
}
if (entry.getKey().getPathPatternsCondition() != null) {
tenantProperties.getIgnoreUrls().addAll(
convertList(entry.getKey().getPathPatternsCondition().getPatterns(), PathPattern::getPatternString));
}
}
}
@Bean
public TenantVisitContextInterceptor tenantVisitContextInterceptor(TenantProperties tenantProperties,
SecurityFrameworkService securityFrameworkService) {
return new TenantVisitContextInterceptor(tenantProperties, securityFrameworkService);
}
@Bean
public CompanyVisitContextInterceptor deptVisitContextInterceptor(SecurityFrameworkService securityFrameworkService) {
return new CompanyVisitContextInterceptor();
}
@Bean
public WebMvcConfigurer tenantWebMvcConfigurer(TenantProperties tenantProperties,
TenantVisitContextInterceptor tenantVisitContextInterceptor) {
return new WebMvcConfigurer() {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(tenantVisitContextInterceptor)
.excludePathPatterns(tenantProperties.getIgnoreVisitUrls().toArray(new String[0]));
}
};
}
@Bean
public WebMvcConfigurer deptWebMvcConfigurer(TenantProperties tenantProperties, CompanyVisitContextInterceptor companyVisitContextInterceptor) {
return new WebMvcConfigurer() {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(companyVisitContextInterceptor)
.excludePathPatterns(tenantProperties.getIgnoreVisitUrls().toArray(new String[0]));
}
};
}
// ========== Security ==========
@Bean
public FilterRegistrationBean<TenantSecurityWebFilter> tenantSecurityWebFilter(TenantProperties tenantProperties,
WebProperties webProperties,
GlobalExceptionHandler globalExceptionHandler,
TenantFrameworkService tenantFrameworkService) {
FilterRegistrationBean<TenantSecurityWebFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new TenantSecurityWebFilter(tenantProperties, webProperties,
globalExceptionHandler, tenantFrameworkService));
registrationBean.setOrder(WebFilterOrderEnum.TENANT_SECURITY_FILTER);
return registrationBean;
}
// ========== Job ==========
@Bean
@ConditionalOnClass(name = "com.xxl.job.core.handler.annotation.XxlJob")
public TenantJobAspect tenantJobAspect(TenantFrameworkService tenantFrameworkService) {
return new TenantJobAspect(tenantFrameworkService);
}
// ========== MQ ==========
/**
* 多租户 Redis 消息队列的配置类
*
* 为什么要单独一个配置类呢?如果直接把 TenantRedisMessageInterceptor Bean 的初始化放外面,会报 RedisMessageInterceptor 类不存在的错误
*/
@Configuration
@ConditionalOnClass(name = "com.zt.plat.framework.mq.redis.core.RedisMQTemplate")
public static class TenantRedisMQAutoConfiguration {
@Bean
public TenantRedisMessageInterceptor tenantRedisMessageInterceptor() {
return new TenantRedisMessageInterceptor();
}
}
@Bean
@ConditionalOnClass(name = "org.springframework.amqp.rabbit.core.RabbitTemplate")
public TenantRabbitMQInitializer tenantRabbitMQInitializer() {
return new TenantRabbitMQInitializer();
}
@Bean
@ConditionalOnClass(name = "org.apache.rocketmq.spring.core.RocketMQTemplate")
public TenantRocketMQInitializer tenantRocketMQInitializer() {
return new TenantRocketMQInitializer();
}
// ========== Redis ==========
@Bean
@Primary // 引入租户时tenantRedisCacheManager 为主 Bean
public RedisCacheManager tenantRedisCacheManager(RedisTemplate<String, Object> redisTemplate,
RedisCacheConfiguration redisCacheConfiguration,
CloudCacheProperties cloudCacheProperties,
TenantProperties tenantProperties) {
// 创建 RedisCacheWriter 对象
RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
BatchStrategies.scan(cloudCacheProperties.getRedisScanBatchSize()));
// 创建 TenantRedisCacheManager 对象
return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration, tenantProperties.getIgnoreCaches());
}
}

View File

@@ -1,20 +0,0 @@
package com.zt.plat.framework.tenant.config;
import com.zt.plat.framework.tenant.core.rpc.TenantRequestInterceptor;
import com.zt.plat.framework.common.biz.system.tenant.TenantCommonApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
@AutoConfiguration
@ConditionalOnProperty(prefix = "cloud.tenant", value = "enable", matchIfMissing = true) // 允许使用 cloud.tenant.enable=false 禁用多租户
@EnableFeignClients(clients = TenantCommonApi.class) // 主要是引入相关的 API 服务
public class CloudTenantRpcAutoConfiguration {
@Bean
public TenantRequestInterceptor tenantRequestInterceptor() {
return new TenantRequestInterceptor();
}
}

View File

@@ -1,21 +0,0 @@
package com.zt.plat.framework.tenant.core.db;
import com.zt.plat.framework.mybatis.core.dataobject.BaseDO;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 拓展多租户的 BaseDO 基类
*
* @author ZT
*/
@Data
@EqualsAndHashCode(callSuper = true)
public abstract class TenantBaseDO extends BaseDO {
/**
* 多租户编号
*/
private Long tenantId;
}

View File

@@ -1,24 +0,0 @@
package com.zt.plat.framework.tenant.core.rpc;
import com.zt.plat.framework.tenant.core.context.TenantContextHolder;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import static com.zt.plat.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID;
/**
* Tenant 的 RequestInterceptor 实现类Feign 请求时,将 {@link TenantContextHolder} 设置到 header 中,继续透传给被调用的服务
*
* @author ZT
*/
public class TenantRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
Long tenantId = TenantContextHolder.getTenantId();
if (tenantId != null) {
requestTemplate.header(HEADER_TENANT_ID, String.valueOf(tenantId));
}
}
}

View File

@@ -1,17 +0,0 @@
/**
* 多租户,支持如下层面:
* 1. DB基于 MyBatis Plus 多租户的功能实现。
* 2. Redis通过在 Redis Key 上拼接租户编号的方式,进行隔离。
* 3. Web请求 HTTP API 时,解析 Header 的 tenant-id 租户编号,添加到租户上下文。
* 4. Security校验当前登陆的用户是否越权访问其它租户的数据。
* 5. Job在 JobHandler 执行任务时,会按照每个租户,都独立并行执行一次。
* 6. MQ在 Producer 发送消息时Header 带上 tenant-id 租户编号;在 Consumer 消费消息时,将 Header 的 tenant-id 租户编号,添加到租户上下文。
* 7. Async异步需要保证 ThreadLocal 的传递性,通过使用阿里开源的 TransmittableThreadLocal 实现。相关的改造点,可见:
* 1Spring Async
* {@link com.zt.plat.framework.quartz.config.CloudAsyncAutoConfiguration#threadPoolTaskExecutorBeanPostProcessor()}
* 2Spring Security
* TransmittableThreadLocalSecurityContextHolderStrategy
* 和 CloudSecurityAutoConfiguration#securityContextHolderMethodInvokingFactoryBean() 方法
*
*/
package com.zt.plat.framework.tenant;

View File

@@ -1,2 +0,0 @@
org.springframework.boot.env.EnvironmentPostProcessor=\
com.zt.plat.framework.tenant.core.mq.kafka.TenantKafkaEnvironmentPostProcessor

View File

@@ -1,2 +0,0 @@
com.zt.plat.framework.tenant.config.CloudTenantRpcAutoConfiguration
com.zt.plat.framework.tenant.config.CloudTenantAutoConfiguration

View File

@@ -1,66 +0,0 @@
<?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">
<parent>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-framework</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-spring-boot-starter-env</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
开发环境拓展,实现类似阿里的特性环境的能力
1. https://segmentfault.com/a/1190000018022987
</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-common</artifactId>
</dependency>
<!-- Spring 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
<!-- RPC 相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
</dependency>
<!-- Registry 注册中心相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,46 +0,0 @@
package com.zt.plat.framework.env.config;
import com.zt.plat.framework.env.core.fegin.EnvLoadBalancerClientFactory;
import com.zt.plat.framework.env.core.fegin.EnvRequestInterceptor;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientSpecification;
import org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import java.util.Collections;
import java.util.List;
/**
* 多环境的 RPC 组件的自动配置
*
* @author ZT
*/
@AutoConfiguration
@EnableConfigurationProperties(EnvProperties.class)
public class CloudEnvRpcAutoConfiguration {
// ========== Feign 相关 ==========
/**
* 创建 {@link EnvLoadBalancerClientFactory} Bean
*
* 参考 {@link LoadBalancerAutoConfiguration#loadBalancerClientFactory(LoadBalancerClientsProperties)} 方法
*/
@Bean
public LoadBalancerClientFactory loadBalancerClientFactory(LoadBalancerClientsProperties properties,
ObjectProvider<List<LoadBalancerClientSpecification>> configurations) {
EnvLoadBalancerClientFactory clientFactory = new EnvLoadBalancerClientFactory(properties);
clientFactory.setConfigurations(configurations.getIfAvailable(Collections::emptyList));
return clientFactory;
}
@Bean
public EnvRequestInterceptor envRequestInterceptor() {
return new EnvRequestInterceptor();
}
}

View File

@@ -1,32 +0,0 @@
package com.zt.plat.framework.env.config;
import com.zt.plat.framework.common.enums.WebFilterOrderEnum;
import com.zt.plat.framework.env.core.web.EnvWebFilter;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
/**
* 多环境的 Web 组件的自动配置
*
* @author ZT
*/
@AutoConfiguration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@EnableConfigurationProperties(EnvProperties.class)
public class CloudEnvWebAutoConfiguration {
/**
* 创建 {@link EnvWebFilter} Bean
*/
@Bean
public FilterRegistrationBean<EnvWebFilter> envWebFilterFilter() {
EnvWebFilter filter = new EnvWebFilter();
FilterRegistrationBean<EnvWebFilter> bean = new FilterRegistrationBean<>(filter);
bean.setOrder(WebFilterOrderEnum.ENV_TAG_FILTER);
return bean;
}
}

View File

@@ -1,22 +0,0 @@
package com.zt.plat.framework.env.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 环境配置
*
* @author ZT
*/
@ConfigurationProperties(prefix = "cloud.env")
@Data
public class EnvProperties {
public static final String TAG_KEY = "cloud.env.tag";
/**
* 环境标签
*/
private String tag;
}

View File

@@ -1 +0,0 @@
package com.zt.plat.framework.env.core;

View File

@@ -1,56 +0,0 @@
package com.zt.plat.framework.env.core.util;
import com.zt.plat.framework.env.config.EnvProperties;
import feign.RequestTemplate;
import jakarta.servlet.http.HttpServletRequest;
import lombok.SneakyThrows;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.core.env.Environment;
import java.net.InetAddress;
import java.util.Objects;
/**
* 环境 Utils
*
* @author ZT
*/
public class EnvUtils {
private static final String HEADER_TAG = "tag";
public static final String HOST_NAME_VALUE = "${HOSTNAME}";
public static String getTag(HttpServletRequest request) {
String tag = request.getHeader(HEADER_TAG);
// 如果请求的是 "${HOSTNAME}",则解析成对应的本地主机名
// 目的:特殊逻辑,解决 IDEA Rest Client 不支持环境变量的读取,所以就服务器来做
return Objects.equals(tag, HOST_NAME_VALUE) ? getHostName() : tag;
}
public static String getTag(ServiceInstance instance) {
return instance.getMetadata().get(HEADER_TAG);
}
public static String getTag(Environment environment) {
String tag = environment.getProperty(EnvProperties.TAG_KEY);
// 如果请求的是 "${HOSTNAME}",则解析成对应的本地主机名
// 目的:特殊逻辑,解决 IDEA Rest Client 不支持环境变量的读取,所以就服务器来做
return Objects.equals(tag, HOST_NAME_VALUE) ? getHostName() : tag;
}
public static void setTag(RequestTemplate requestTemplate, String tag) {
requestTemplate.header(HEADER_TAG, tag);
}
/**
* 获得 hostname 主机名
*
* @return 主机名
*/
@SneakyThrows
public static String getHostName() {
return InetAddress.getLocalHost().getHostName();
}
}

View File

@@ -1,7 +0,0 @@
/**
* 开发环境拓展,实现类似阿里的特性环境的能力
* 1. https://segmentfault.com/a/1190000018022987
*
* @author ZT
*/
package com.zt.plat.framework.env;

View File

@@ -1,2 +0,0 @@
org.springframework.boot.env.EnvironmentPostProcessor=\
com.zt.plat.framework.env.config.EnvEnvironmentPostProcessor

View File

@@ -1,2 +0,0 @@
com.zt.plat.framework.env.config.CloudEnvWebAutoConfiguration
com.zt.plat.framework.env.config.CloudEnvRpcAutoConfiguration

View File

@@ -1,80 +0,0 @@
<?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">
<parent>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-framework</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-spring-boot-starter-excel</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>Excel 拓展</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-common</artifactId>
</dependency>
<!-- Spring 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-rpc</artifactId>
<optional>true</optional>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有 ExcelUtils 使用 -->
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有 ExcelUtils 使用 -->
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId> <!-- 解决 https://github.com/alibaba/easyexcel/issues/3954 问题 -->
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-biz-ip</artifactId>
<optional>true</optional> <!-- 设置为 optional只有在 AreaConvert 的时候使用 -->
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -1,18 +0,0 @@
package com.zt.plat.framework.dict.config;
import com.zt.plat.framework.common.biz.system.dict.DictDataCommonApi;
import com.zt.plat.framework.dict.core.DictFrameworkUtils;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
@AutoConfiguration
public class CloudDictAutoConfiguration {
@Bean
@SuppressWarnings("InstantiationOfUtilityClass")
public DictFrameworkUtils dictUtils(DictDataCommonApi dictDataApi) {
DictFrameworkUtils.init(dictDataApi);
return new DictFrameworkUtils();
}
}

View File

@@ -1,15 +0,0 @@
package com.zt.plat.framework.dict.config;
import com.zt.plat.framework.common.biz.system.dict.DictDataCommonApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* 字典用到 Feign 的配置项
*
* @author ZT
*/
@AutoConfiguration
@EnableFeignClients(clients = DictDataCommonApi.class) // 主要是引入相关的 API 服务
public class CloudDictRpcAutoConfiguration {
}

View File

@@ -1,6 +0,0 @@
/**
* 字典数据模块,提供 {@link com.zt.plat.framework.dict.core.DictFrameworkUtils} 工具类
*
* 通过将字典缓存在内存中,保证性能
*/
package com.zt.plat.framework.dict;

View File

@@ -1,4 +0,0 @@
/**
* 基于 EasyExcel 实现 Excel 相关的操作
*/
package com.zt.plat.framework.excel;

View File

@@ -1,2 +0,0 @@
com.zt.plat.framework.dict.config.CloudDictRpcAutoConfiguration
com.zt.plat.framework.dict.config.CloudDictAutoConfiguration

View File

@@ -1,50 +0,0 @@
<?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">
<parent>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-framework</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-spring-boot-starter-job</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>任务拓展,基于 XXL-Job 实现</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-common</artifactId>
</dependency>
<!-- Spring 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<optional>true</optional>
</dependency>
<!-- Job 相关 -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,36 +0,0 @@
package com.zt.plat.framework.quartz.config;
import com.alibaba.ttl.TtlRunnable;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
* 异步任务 Configuration
*/
@AutoConfiguration
@EnableAsync
public class CloudAsyncAutoConfiguration {
@Bean
public BeanPostProcessor threadPoolTaskExecutorBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof ThreadPoolTaskExecutor)) {
return bean;
}
// 修改提交的任务,接入 TransmittableThreadLocal
ThreadPoolTaskExecutor executor = (ThreadPoolTaskExecutor) bean;
executor.setTaskDecorator(TtlRunnable::get);
return executor;
}
};
}
}

View File

@@ -1,47 +0,0 @@
package com.zt.plat.framework.quartz.config;
import com.xxl.job.core.executor.XxlJobExecutor;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* XXL-Job 自动配置类
*
* @author ZT
*/
@AutoConfiguration
@ConditionalOnClass(XxlJobSpringExecutor.class)
@ConditionalOnProperty(prefix = "xxl.job", name = "enabled", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties({XxlJobProperties.class})
@EnableScheduling // 开启 Spring 自带的定时任务
@Slf4j
public class CloudXxlJobAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public XxlJobExecutor xxlJobExecutor(XxlJobProperties properties) {
log.info("[xxlJobExecutor][初始化 XXL-Job 执行器的配置]");
XxlJobProperties.AdminProperties admin = properties.getAdmin();
XxlJobProperties.ExecutorProperties executor = properties.getExecutor();
// 初始化执行器
XxlJobExecutor xxlJobExecutor = new XxlJobSpringExecutor();
xxlJobExecutor.setIp(executor.getIp());
xxlJobExecutor.setPort(executor.getPort());
xxlJobExecutor.setAppname(executor.getAppName());
xxlJobExecutor.setLogPath(executor.getLogPath());
xxlJobExecutor.setLogRetentionDays(executor.getLogRetentionDays());
xxlJobExecutor.setAdminAddresses(admin.getAddresses());
xxlJobExecutor.setAccessToken(properties.getAccessToken());
return xxlJobExecutor;
}
}

View File

@@ -1,5 +0,0 @@
/**
* 1. 定时任务,基于 XXL-Job 实现。
* 2. 异步任务,采用 Spring Async 异步执行。
*/
package com.zt.plat.framework.quartz;

View File

@@ -1,2 +0,0 @@
com.zt.plat.framework.quartz.config.CloudXxlJobAutoConfiguration
com.zt.plat.framework.quartz.config.CloudAsyncAutoConfiguration

View File

@@ -1 +0,0 @@
<http://www.iocoder.cn/Spring-Boot/Job/?cloud>

View File

@@ -1 +0,0 @@
<http://www.iocoder.cn/Spring-Boot/Async-Job/?cloud>

View File

@@ -1,73 +0,0 @@
<?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">
<parent>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-framework</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-spring-boot-starter-monitor</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>服务监控,提供链路追踪、日志服务、指标收集等等功能</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-common</artifactId>
</dependency>
<!-- Spring 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有 TraceFilter 使用 -->
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有 TraceFilter 使用 -->
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-util</artifactId>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-opentracing</artifactId>
</dependency>
<!-- Micrometer 对 Prometheus 的支持 -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId> <!-- 实现 Spring Boot Admin Server 服务端 -->
</dependency>
</dependencies>
</project>

View File

@@ -1,27 +0,0 @@
package com.zt.plat.framework.tracer.config;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
/**
* Metrics 配置类
*
* @author ZT
*/
@AutoConfiguration
@ConditionalOnClass({MeterRegistryCustomizer.class})
@ConditionalOnProperty(prefix = "cloud.metrics", value = "enable", matchIfMissing = true) // 允许使用 cloud.metrics.enable=false 禁用 Metrics
public class CloudMetricsAutoConfiguration {
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags(
@Value("${spring.application.name}") String applicationName) {
return registry -> registry.config().commonTags("application", applicationName);
}
}

View File

@@ -1,55 +0,0 @@
package com.zt.plat.framework.tracer.config;
import com.zt.plat.framework.common.enums.WebFilterOrderEnum;
import com.zt.plat.framework.tracer.core.aop.BizTraceAspect;
import com.zt.plat.framework.tracer.core.filter.TraceFilter;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
/**
* Tracer 配置类
*
* @author mashu
*/
@AutoConfiguration
@ConditionalOnClass(value = {BizTraceAspect.class}, name = "jakarta.servlet.Filter")
@EnableConfigurationProperties(TracerProperties.class)
@ConditionalOnProperty(prefix = "cloud.tracer", value = "enable", matchIfMissing = true)
public class CloudTracerAutoConfiguration {
// TODO @芋艿:重要。目前 opentracing 版本存在冲突,要么保证 skywalking要么保证阿里云短信 sdk
// @Bean
// public TracerProperties bizTracerProperties() {
// return new TracerProperties();
// }
//
// @Bean
// public BizTraceAspect bizTracingAop() {
// return new BizTraceAspect(tracer());
// }
//
// @Bean
// public Tracer tracer() {
// // 创建 SkywalkingTracer 对象
// SkywalkingTracer tracer = new SkywalkingTracer();
// // 设置为 GlobalTracer 的追踪器
// GlobalTracer.register(tracer);
// return tracer;
// }
/**
* 创建 TraceFilter 过滤器,响应 header 设置 traceId
*/
@Bean
public FilterRegistrationBean<TraceFilter> traceFilter() {
FilterRegistrationBean<TraceFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new TraceFilter());
registrationBean.setOrder(WebFilterOrderEnum.TRACE_FILTER);
return registrationBean;
}
}

View File

@@ -1,14 +0,0 @@
package com.zt.plat.framework.tracer.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* BizTracer配置类
*
* @author 麻薯
*/
@ConfigurationProperties("cloud.tracer")
@Data
public class TracerProperties {
}

View File

@@ -1,6 +0,0 @@
/**
* 使用 SkyWalking 组件,作为链路追踪、日志中心。
*
* @author ZT
*/
package com.zt.plat.framework.tracer;

View File

@@ -1,2 +0,0 @@
com.zt.plat.framework.tracer.config.CloudTracerAutoConfiguration
com.zt.plat.framework.tracer.config.CloudMetricsAutoConfiguration

View File

@@ -1 +0,0 @@
<https://www.iocoder.cn/Spring-Boot/Admin/?cloud>

View File

@@ -1 +0,0 @@
<https://www.iocoder.cn/Spring-Boot/Actuator/?cloud>

View File

@@ -1 +0,0 @@
<http://www.iocoder.cn/Spring-Boot/SkyWalking/?cloud>

View File

@@ -1,43 +0,0 @@
<?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">
<parent>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-framework</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-spring-boot-starter-mq</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>消息队列,支持 Redis、RocketMQ、RabbitMQ、Kafka 四种</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies>
<!-- DB 相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-redis</artifactId>
</dependency>
<!-- 消息队列相关 -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<!-- <optional>true</optional>-->
</dependency>
</dependencies>
</project>

View File

@@ -1,4 +0,0 @@
/**
* 消息队列,支持 Redis、RocketMQ、RabbitMQ、Kafka 四种
*/
package com.zt.plat.framework.mq;

View File

@@ -1,28 +0,0 @@
package com.zt.plat.framework.mq.rabbitmq.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
/**
* RabbitMQ 消息队列配置类
*
* @author ZT
*/
@AutoConfiguration
@Slf4j
@ConditionalOnClass(name = "org.springframework.amqp.rabbit.core.RabbitTemplate")
public class CloudRabbitMQAutoConfiguration {
/**
* Jackson2JsonMessageConverter Bean使用 jackson 序列化消息
*/
@Bean
public MessageConverter createMessageConverter() {
return new Jackson2JsonMessageConverter();
}
}

View File

@@ -1,4 +0,0 @@
/**
* 占位符,无特殊逻辑
*/
package com.zt.plat.framework.mq.rabbitmq.core;

View File

@@ -1,4 +0,0 @@
/**
* 消息队列,基于 RabbitMQ 提供
*/
package com.zt.plat.framework.mq.rabbitmq;

View File

@@ -1,163 +0,0 @@
package com.zt.plat.framework.mq.redis.config;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.system.SystemUtil;
import com.zt.plat.framework.common.enums.DocumentEnum;
import com.zt.plat.framework.mq.redis.core.RedisMQTemplate;
import com.zt.plat.framework.mq.redis.core.job.RedisPendingMessageResendJob;
import com.zt.plat.framework.mq.redis.core.job.RedisStreamMessageCleanupJob;
import com.zt.plat.framework.mq.redis.core.pubsub.AbstractRedisChannelMessageListener;
import com.zt.plat.framework.mq.redis.core.stream.AbstractRedisStreamMessageListener;
import com.zt.plat.framework.redis.config.CloudRedisAutoConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.connection.stream.Consumer;
import org.springframework.data.redis.connection.stream.ObjectRecord;
import org.springframework.data.redis.connection.stream.ReadOffset;
import org.springframework.data.redis.connection.stream.StreamOffset;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.stream.StreamMessageListenerContainer;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.util.List;
import java.util.Properties;
/**
* Redis 消息队列 Consumer 配置类
*
* @author ZT
*/
@Slf4j
@EnableScheduling // 启用定时任务,用于 RedisPendingMessageResendJob 重发消息
@AutoConfiguration(after = CloudRedisAutoConfiguration.class)
public class CloudRedisMQConsumerAutoConfiguration {
/**
* 创建 Redis Pub/Sub 广播消费的容器
*/
@Bean
@ConditionalOnBean(AbstractRedisChannelMessageListener.class) // 只有 AbstractChannelMessageListener 存在的时候,才需要注册 Redis pubsub 监听
public RedisMessageListenerContainer redisMessageListenerContainer(
RedisMQTemplate redisMQTemplate, List<AbstractRedisChannelMessageListener<?>> listeners) {
// 创建 RedisMessageListenerContainer 对象
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
// 设置 RedisConnection 工厂。
container.setConnectionFactory(redisMQTemplate.getRedisTemplate().getRequiredConnectionFactory());
// 添加监听器
listeners.forEach(listener -> {
listener.setRedisMQTemplate(redisMQTemplate);
container.addMessageListener(listener, new ChannelTopic(listener.getChannel()));
log.info("[redisMessageListenerContainer][注册 Channel({}) 对应的监听器({})]",
listener.getChannel(), listener.getClass().getName());
});
return container;
}
/**
* 创建 Redis Stream 重新消费的任务
*/
@Bean
@ConditionalOnBean(AbstractRedisStreamMessageListener.class) // 只有 AbstractStreamMessageListener 存在的时候,才需要注册 Redis pubsub 监听
public RedisPendingMessageResendJob redisPendingMessageResendJob(List<AbstractRedisStreamMessageListener<?>> listeners,
RedisMQTemplate redisTemplate,
@Value("${spring.application.name}") String groupName,
RedissonClient redissonClient) {
return new RedisPendingMessageResendJob(listeners, redisTemplate, groupName, redissonClient);
}
/**
* 创建 Redis Stream 消息清理任务
*/
@Bean
@ConditionalOnBean(AbstractRedisStreamMessageListener.class)
public RedisStreamMessageCleanupJob redisStreamMessageCleanupJob(List<AbstractRedisStreamMessageListener<?>> listeners,
RedisMQTemplate redisTemplate,
RedissonClient redissonClient) {
return new RedisStreamMessageCleanupJob(listeners, redisTemplate, redissonClient);
}
/**
* 创建 Redis Stream 集群消费的容器
*
* 基础知识:<a href="https://www.geek-book.com/src/docs/redis/redis/redis.io/commands/xreadgroup.html">Redis Stream 的 xreadgroup 命令</a>
*/
@Bean(initMethod = "start", destroyMethod = "stop")
@ConditionalOnBean(AbstractRedisStreamMessageListener.class) // 只有 AbstractStreamMessageListener 存在的时候,才需要注册 Redis pubsub 监听
public StreamMessageListenerContainer<String, ObjectRecord<String, String>> redisStreamMessageListenerContainer(
RedisMQTemplate redisMQTemplate, List<AbstractRedisStreamMessageListener<?>> listeners) {
RedisTemplate<String, ?> redisTemplate = redisMQTemplate.getRedisTemplate();
checkRedisVersion(redisTemplate);
// 第一步,创建 StreamMessageListenerContainer 容器
// 创建 options 配置
StreamMessageListenerContainer.StreamMessageListenerContainerOptions<String, ObjectRecord<String, String>> containerOptions =
StreamMessageListenerContainer.StreamMessageListenerContainerOptions.builder()
.batchSize(10) // 一次性最多拉取多少条消息
.targetType(String.class) // 目标类型。统一使用 String通过自己封装的 AbstractStreamMessageListener 去反序列化
.build();
// 创建 container 对象
StreamMessageListenerContainer<String, ObjectRecord<String, String>> container =
StreamMessageListenerContainer.create(redisMQTemplate.getRedisTemplate().getRequiredConnectionFactory(), containerOptions);
// 第二步,注册监听器,消费对应的 Stream 主题
String consumerName = buildConsumerName();
listeners.parallelStream().forEach(listener -> {
log.info("[redisStreamMessageListenerContainer][开始注册 StreamKey({}) 对应的监听器({})]",
listener.getStreamKey(), listener.getClass().getName());
// 创建 listener 对应的消费者分组
try {
redisTemplate.opsForStream().createGroup(listener.getStreamKey(), listener.getGroup());
} catch (Exception ignore) {
}
// 设置 listener 对应的 redisTemplate
listener.setRedisMQTemplate(redisMQTemplate);
// 创建 Consumer 对象
Consumer consumer = Consumer.from(listener.getGroup(), consumerName);
// 设置 Consumer 消费进度,以最小消费进度为准
StreamOffset<String> streamOffset = StreamOffset.create(listener.getStreamKey(), ReadOffset.lastConsumed());
// 设置 Consumer 监听
StreamMessageListenerContainer.StreamReadRequestBuilder<String> builder = StreamMessageListenerContainer.StreamReadRequest
.builder(streamOffset).consumer(consumer)
.autoAcknowledge(false) // 不自动 ack
.cancelOnError(throwable -> false); // 默认配置,发生异常就取消消费,显然不符合预期;因此,我们设置为 false
container.register(builder.build(), listener);
log.info("[redisStreamMessageListenerContainer][完成注册 StreamKey({}) 对应的监听器({})]",
listener.getStreamKey(), listener.getClass().getName());
});
return container;
}
/**
* 构建消费者名字,使用本地 IP + 进程编号的方式。
* 参考自 RocketMQ clientId 的实现
*
* @return 消费者名字
*/
private static String buildConsumerName() {
return String.format("%s@%d", SystemUtil.getHostInfo().getAddress(), SystemUtil.getCurrentPID());
}
/**
* 校验 Redis 版本号,是否满足最低的版本号要求!
*/
private static void checkRedisVersion(RedisTemplate<String, ?> redisTemplate) {
// 获得 Redis 版本
Properties info = redisTemplate.execute((RedisCallback<Properties>) RedisServerCommands::info);
String version = MapUtil.getStr(info, "redis_version");
// 校验最低版本必须大于等于 5.0.0
int majorVersion = Integer.parseInt(StrUtil.subBefore(version, '.', false));
if (majorVersion < 5) {
throw new IllegalStateException(StrUtil.format("您当前的 Redis 版本为 {},小于最低要求的 5.0.0 版本!" +
"请参考 {} 文档进行安装。", version, DocumentEnum.REDIS_INSTALL.getUrl()));
}
}
}

View File

@@ -1,31 +0,0 @@
package com.zt.plat.framework.mq.redis.config;
import com.zt.plat.framework.mq.redis.core.RedisMQTemplate;
import com.zt.plat.framework.mq.redis.core.interceptor.RedisMessageInterceptor;
import com.zt.plat.framework.redis.config.CloudRedisAutoConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.List;
/**
* Redis 消息队列 Producer 配置类
*
* @author ZT
*/
@Slf4j
@AutoConfiguration(after = CloudRedisAutoConfiguration.class)
public class CloudRedisMQProducerAutoConfiguration {
@Bean
public RedisMQTemplate redisMQTemplate(StringRedisTemplate redisTemplate,
List<RedisMessageInterceptor> interceptors) {
RedisMQTemplate redisMQTemplate = new RedisMQTemplate(redisTemplate);
// 添加拦截器
interceptors.forEach(redisMQTemplate::addInterceptor);
return redisMQTemplate;
}
}

View File

@@ -1,6 +0,0 @@
/**
* 消息队列,基于 Redis 提供:
* 1. 基于 Pub/Sub 实现广播消费
* 2. 基于 Stream 实现集群消费
*/
package com.zt.plat.framework.mq.redis;

View File

@@ -1,3 +0,0 @@
com.zt.plat.framework.mq.redis.config.CloudRedisMQProducerAutoConfiguration
com.zt.plat.framework.mq.redis.config.CloudRedisMQConsumerAutoConfiguration
com.zt.plat.framework.mq.rabbitmq.config.CloudRabbitMQAutoConfiguration

View File

@@ -1 +0,0 @@
<http://www.iocoder.cn/Spring-Boot/RocketMQ/?cloud>

View File

@@ -1 +0,0 @@
<http://www.iocoder.cn/Spring-Boot/Kafka/?cloud>

View File

@@ -1 +0,0 @@
<http://www.iocoder.cn/Spring-Boot/RabbitMQ/?cloud>

View File

@@ -1 +0,0 @@
<http://www.iocoder.cn/Spring-Boot/RocketMQ/?cloud>

View File

@@ -1,112 +0,0 @@
<?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">
<parent>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-framework</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-spring-boot-starter-mybatis</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>数据库连接池、多数据源、事务、MyBatis 拓展</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-common</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-web</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有 OncePerRequestFilter 使用到 -->
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmJdbcDriver18</artifactId>
</dependency>
<dependency>
<groupId>cn.com.kingbase</groupId>
<artifactId>kingbase8</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.opengauss</groupId>
<artifactId>opengauss-jdbc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId> <!-- 多数据源 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-boot-starter</artifactId> <!-- MyBatis 联表查询 -->
</dependency>
<dependency>
<groupId>com.fhs-opensource</groupId> <!-- VO 数据翻译 -->
<artifactId>easy-trans-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.fhs-opensource</groupId>
<artifactId>easy-trans-mybatis-plus-extend</artifactId>
</dependency>
<dependency>
<groupId>com.zt.plat</groupId>
<artifactId>cloud-spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,43 +0,0 @@
package com.zt.plat.framework.datasource.config;
import com.alibaba.druid.spring.boot3.autoconfigure.properties.DruidStatProperties;
import com.zt.plat.framework.common.biz.system.sequence.SequenceCommonApi;
import com.zt.plat.framework.datasource.core.filter.DruidAdRemoveFilter;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* 数据库配置类
*
* @author ZT
*/
@AutoConfiguration
@EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理
@EnableConfigurationProperties(DruidStatProperties.class)
@EnableFeignClients(clients = SequenceCommonApi.class)
public class CloudDataSourceAutoConfiguration {
/**
* 创建 DruidAdRemoveFilter 过滤器,过滤 common.js 的广告
*/
@Bean
@ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true")
public FilterRegistrationBean<DruidAdRemoveFilter> druidAdRemoveFilterFilter(DruidStatProperties properties) {
// 获取 druid web 监控页面的参数
DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
// 提取 common.js 的配置路径
String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
// 创建 DruidAdRemoveFilter Bean
FilterRegistrationBean<DruidAdRemoveFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new DruidAdRemoveFilter());
registrationBean.addUrlPatterns(commonJsPattern);
return registrationBean;
}
}

View File

@@ -1,5 +0,0 @@
/**
* 数据库连接池,采用 Druid
* 多数据源,采用爆米花
*/
package com.zt.plat.framework.datasource;

View File

@@ -1,76 +0,0 @@
package com.zt.plat.framework.mybatis.config;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
import com.baomidou.mybatisplus.extension.incrementer.*;
import com.baomidou.mybatisplus.extension.parser.JsqlParserGlobal;
import com.baomidou.mybatisplus.extension.parser.cache.JdkSerialCaffeineJsqlParseCache;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.zt.plat.framework.mybatis.core.handler.DefaultDBFieldHandler;
import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.concurrent.TimeUnit;
/**
* MyBaits 配置类
*
* @author ZT
*/
@AutoConfiguration(before = MybatisPlusAutoConfiguration.class) // 目的:先于 MyBatis Plus 自动配置,避免 @MapperScan 可能扫描不到 Mapper 打印 warn 日志
@MapperScan(value = "${cloud.info.base-package}", annotationClass = Mapper.class,
lazyInitialization = "${mybatis.lazy-initialization:false}") // Mapper 懒加载,目前仅用于单元测试
public class CloudMybatisAutoConfiguration {
static {
// 动态 SQL 智能优化支持本地缓存加速解析,更完善的租户复杂 XML 动态 SQL 支持,静态注入缓存
JsqlParserGlobal.setJsqlParseCache(new JdkSerialCaffeineJsqlParseCache(
(cache) -> cache.maximumSize(1024)
.expireAfterWrite(5, TimeUnit.SECONDS))
);
}
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); // 分页插件
return mybatisPlusInterceptor;
}
@Bean
public MetaObjectHandler defaultMetaObjectHandler() {
return new DefaultDBFieldHandler(); // 自动填充参数类
}
@Bean
@ConditionalOnProperty(prefix = "mybatis-plus.global-config.db-config", name = "id-type", havingValue = "INPUT")
public IKeyGenerator keyGenerator(ConfigurableEnvironment environment) {
DbType dbType = IdTypeEnvironmentPostProcessor.getDbType(environment);
if (dbType != null) {
switch (dbType) {
case POSTGRE_SQL:
return new PostgreKeyGenerator();
case ORACLE:
case ORACLE_12C:
return new OracleKeyGenerator();
case H2:
return new H2KeyGenerator();
case KINGBASE_ES:
return new KingbaseKeyGenerator();
case DM:
return new DmKeyGenerator();
}
}
// 找不到合适的 IKeyGenerator 实现类
throw new IllegalArgumentException(StrUtil.format("DbType{} 找不到合适的 IKeyGenerator 实现类", dbType));
}
}

View File

@@ -1,4 +0,0 @@
/**
* 使用 MyBatis Plus 提升使用 MyBatis 的开发效率
*/
package com.zt.plat.framework.mybatis;

View File

@@ -1,18 +0,0 @@
package com.zt.plat.framework.translate.config;
import com.zt.plat.framework.translate.core.TranslateUtils;
import com.fhs.trans.service.impl.TransService;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
@AutoConfiguration
public class CloudTranslateAutoConfiguration {
@Bean
@SuppressWarnings({"InstantiationOfUtilityClass", "SpringJavaInjectionPointsAutowiringInspection"})
public TranslateUtils translateUtils(TransService transService) {
TranslateUtils.init(transService);
return new TranslateUtils();
}
}

View File

@@ -1,4 +0,0 @@
/**
* 使用 Easy-Trans 提升使用 VO 数据翻译的开发效率
*/
package com.zt.plat.framework.translate;

View File

@@ -1,2 +0,0 @@
org.springframework.boot.env.EnvironmentPostProcessor=\
com.zt.plat.framework.mybatis.config.IdTypeEnvironmentPostProcessor

View File

@@ -1,3 +0,0 @@
com.zt.plat.framework.datasource.config.CloudDataSourceAutoConfiguration
com.zt.plat.framework.mybatis.config.CloudMybatisAutoConfiguration
com.zt.plat.framework.translate.config.CloudTranslateAutoConfiguration

View File

@@ -1 +0,0 @@
<http://www.iocoder.cn/Spring-Boot/MyBatis/?cloud>

Some files were not shown because too many files have changed in this diff Show More