Commit ba390c67f8502d7826f50dcb4201d5d31f9e13f8

Authored by YunaiV
2 parents 07d09992 a64df8e2

Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into feature/ai

Showing 23 changed files with 149 additions and 126 deletions
README.md
@@ -308,26 +308,26 @@ @@ -308,26 +308,26 @@
308 308
309 | 框架 | 说明 | 版本 | 学习指南 | 309 | 框架 | 说明 | 版本 | 学习指南 |
310 |---------------------------------------------------------------------------------------------|------------------|----------------|----------------------------------------------------------------| 310 |---------------------------------------------------------------------------------------------|------------------|----------------|----------------------------------------------------------------|
311 -| [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 3.4.5 | [文档](https://github.com/YunaiV/SpringBoot-Labs) | 311 +| [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 3.5.5 | [文档](https://github.com/YunaiV/SpringBoot-Labs) |
312 | [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 / 8.0+ | | 312 | [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 / 8.0+ | |
313 -| [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.23 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |  
314 -| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.7 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) | 313 +| [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.27 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
  314 +| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.12 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) |
315 | [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 4.3.1 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) | 315 | [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 4.3.1 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
316 | [Redis](https://redis.io/) | key-value 数据库 | 5.0 / 6.0 /7.0 | | 316 | [Redis](https://redis.io/) | key-value 数据库 | 5.0 / 6.0 /7.0 | |
317 -| [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.32.0 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) |  
318 -| [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 6.1.10 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) |  
319 -| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 6.3.1 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |  
320 -| [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 8.0.1 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) | 317 +| [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.35.0 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) |
  318 +| [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 6.2.9 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) |
  319 +| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 6.5.2 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |
  320 +| [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 8.0.2 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) |
321 | [Flowable](https://github.com/flowable/flowable-engine) | 工作流引擎 | 7.0.0 | [文档](https://doc.iocoder.cn/bpm/) | 321 | [Flowable](https://github.com/flowable/flowable-engine) | 工作流引擎 | 7.0.0 | [文档](https://doc.iocoder.cn/bpm/) |
322 -| [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) |  
323 -| [Springdoc](https://springdoc.org/) | Swagger 文档 | 2.3.0 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |  
324 -| [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 9.0.0 | [文档](http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao) |  
325 -| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 3.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) |  
326 -| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.17.1 | | 322 +| [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.5.0 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) |
  323 +| [Springdoc](https://springdoc.org/) | Swagger 文档 | 2.8.9 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |
  324 +| [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 9.5.0 | [文档](http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao) |
  325 +| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 3.5.2 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) |
  326 +| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.30.14 | |
327 | [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.6.3 | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) | 327 | [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.6.3 | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) |
328 -| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.18.34 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) |  
329 -| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.10.1 | - |  
330 -| [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 5.7.0 | - | 328 +| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.18.38 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) |
  329 +| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.12.2 | - |
  330 +| [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 5.17.0 | - |
331 331
332 ## 🐷 演示图 332 ## 🐷 演示图
333 333
@@ -37,12 +37,12 @@ @@ -37,12 +37,12 @@
37 <java.version>17</java.version> 37 <java.version>17</java.version>
38 <maven.compiler.source>${java.version}</maven.compiler.source> 38 <maven.compiler.source>${java.version}</maven.compiler.source>
39 <maven.compiler.target>${java.version}</maven.compiler.target> 39 <maven.compiler.target>${java.version}</maven.compiler.target>
40 - <maven-surefire-plugin.version>3.2.2</maven-surefire-plugin.version> 40 + <maven-surefire-plugin.version>3.5.3</maven-surefire-plugin.version>
41 <maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version> 41 <maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
42 - <flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version> 42 + <flatten-maven-plugin.version>1.7.2</flatten-maven-plugin.version>
43 <!-- maven-surefire-plugin 暂时无法通过 bom 的依赖读取(兼容老版本 IDEA 2024 及以前版本) --> 43 <!-- maven-surefire-plugin 暂时无法通过 bom 的依赖读取(兼容老版本 IDEA 2024 及以前版本) -->
44 <lombok.version>1.18.38</lombok.version> 44 <lombok.version>1.18.38</lombok.version>
45 - <spring.boot.version>3.5.4</spring.boot.version> 45 + <spring.boot.version>3.5.5</spring.boot.version>
46 <mapstruct.version>1.6.3</mapstruct.version> 46 <mapstruct.version>1.6.3</mapstruct.version>
47 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 47 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
48 </properties> 48 </properties>
yudao-dependencies/pom.xml
@@ -15,53 +15,54 @@ @@ -15,53 +15,54 @@
15 15
16 <properties> 16 <properties>
17 <revision>2025.08-SNAPSHOT</revision> 17 <revision>2025.08-SNAPSHOT</revision>
18 - <flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version> 18 + <flatten-maven-plugin.version>1.7.2</flatten-maven-plugin.version>
19 <!-- 统一依赖管理 --> 19 <!-- 统一依赖管理 -->
20 - <spring.boot.version>3.5.4</spring.boot.version> 20 + <spring.boot.version>3.5.5</spring.boot.version>
21 <!-- Web 相关 --> 21 <!-- Web 相关 -->
22 - <springdoc.version>2.8.9</springdoc.version> 22 + <springdoc.version>2.8.11</springdoc.version>
23 <knife4j.version>4.5.0</knife4j.version> 23 <knife4j.version>4.5.0</knife4j.version>
24 <!-- DB 相关 --> 24 <!-- DB 相关 -->
25 - <druid.version>1.2.24</druid.version> 25 + <druid.version>1.2.27</druid.version>
26 <mybatis.version>3.5.19</mybatis.version> 26 <mybatis.version>3.5.19</mybatis.version>
27 <mybatis-plus.version>3.5.12</mybatis-plus.version> 27 <mybatis-plus.version>3.5.12</mybatis-plus.version>
28 <mybatis-plus-join.version>1.5.4</mybatis-plus-join.version> 28 <mybatis-plus-join.version>1.5.4</mybatis-plus-join.version>
29 <dynamic-datasource.version>4.3.1</dynamic-datasource.version> 29 <dynamic-datasource.version>4.3.1</dynamic-datasource.version>
30 <easy-trans.version>3.0.6</easy-trans.version> 30 <easy-trans.version>3.0.6</easy-trans.version>
31 - <redisson.version>3.41.0</redisson.version> 31 + <redisson.version>3.51.0</redisson.version>
32 <dm8.jdbc.version>8.1.3.140</dm8.jdbc.version> 32 <dm8.jdbc.version>8.1.3.140</dm8.jdbc.version>
33 <kingbase.jdbc.version>8.6.0</kingbase.jdbc.version> 33 <kingbase.jdbc.version>8.6.0</kingbase.jdbc.version>
34 <opengauss.jdbc.version>5.1.0</opengauss.jdbc.version> 34 <opengauss.jdbc.version>5.1.0</opengauss.jdbc.version>
35 - <taos.version>3.3.3</taos.version> 35 + <taos.version>3.7.3</taos.version>
36 <!-- 消息队列 --> 36 <!-- 消息队列 -->
37 - <rocketmq-spring.version>2.3.2</rocketmq-spring.version> 37 + <rocketmq-spring.version>2.3.4</rocketmq-spring.version>
38 <!-- 服务保障相关 --> 38 <!-- 服务保障相关 -->
39 <lock4j.version>2.2.7</lock4j.version> 39 <lock4j.version>2.2.7</lock4j.version>
40 <!-- 监控相关 --> 40 <!-- 监控相关 -->
41 - <skywalking.version>9.0.0</skywalking.version> 41 + <skywalking.version>9.5.0</skywalking.version>
42 <spring-boot-admin.version>3.5.2</spring-boot-admin.version> 42 <spring-boot-admin.version>3.5.2</spring-boot-admin.version>
43 <opentracing.version>0.33.0</opentracing.version> 43 <opentracing.version>0.33.0</opentracing.version>
44 <!-- Test 测试相关 --> 44 <!-- Test 测试相关 -->
45 <podam.version>8.0.2.RELEASE</podam.version> 45 <podam.version>8.0.2.RELEASE</podam.version>
46 - <jedis-mock.version>1.1.8</jedis-mock.version> 46 + <jedis-mock.version>1.1.11</jedis-mock.version>
47 <mockito-inline.version>5.2.0</mockito-inline.version> 47 <mockito-inline.version>5.2.0</mockito-inline.version>
48 <!-- Bpm 工作流相关 --> 48 <!-- Bpm 工作流相关 -->
49 <flowable.version>7.0.1</flowable.version> 49 <flowable.version>7.0.1</flowable.version>
50 <!-- 工具类相关 --> 50 <!-- 工具类相关 -->
51 <anji-plus-captcha.version>1.4.0</anji-plus-captcha.version> 51 <anji-plus-captcha.version>1.4.0</anji-plus-captcha.version>
52 - <jsoup.version>1.18.3</jsoup.version> 52 + <jsoup.version>1.21.2</jsoup.version>
53 <lombok.version>1.18.38</lombok.version> 53 <lombok.version>1.18.38</lombok.version>
54 <mapstruct.version>1.6.3</mapstruct.version> 54 <mapstruct.version>1.6.3</mapstruct.version>
55 - <hutool-5.version>5.8.35</hutool-5.version>  
56 - <hutool-6.version>6.0.0-M19</hutool-6.version>  
57 - <fastexcel.version>1.2.0</fastexcel.version> 55 + <hutool-5.version>5.8.40</hutool-5.version>
  56 + <hutool-6.version>6.0.0-M22</hutool-6.version>
  57 + <fastexcel.version>1.3.0</fastexcel.version>
58 <velocity.version>2.4.1</velocity.version> 58 <velocity.version>2.4.1</velocity.version>
59 <fastjson.version>1.2.83</fastjson.version> 59 <fastjson.version>1.2.83</fastjson.version>
60 <guava.version>33.4.8-jre</guava.version> 60 <guava.version>33.4.8-jre</guava.version>
61 <transmittable-thread-local.version>2.14.5</transmittable-thread-local.version> 61 <transmittable-thread-local.version>2.14.5</transmittable-thread-local.version>
62 <commons-net.version>3.11.1</commons-net.version> 62 <commons-net.version>3.11.1</commons-net.version>
  63 + <commons-lang3.version>3.18.0</commons-lang3.version>
63 <jsch.version>0.1.55</jsch.version> 64 <jsch.version>0.1.55</jsch.version>
64 - <tika-core.version>3.1.0</tika-core.version> 65 + <tika-core.version>3.2.2</tika-core.version>
65 <ip2region.version>2.7.0</ip2region.version> 66 <ip2region.version>2.7.0</ip2region.version>
66 <bizlog-sdk.version>3.0.6</bizlog-sdk.version> 67 <bizlog-sdk.version>3.0.6</bizlog-sdk.version>
67 <netty.version>4.2.4.Final</netty.version> 68 <netty.version>4.2.4.Final</netty.version>
@@ -74,7 +75,7 @@ @@ -74,7 +75,7 @@
74 <justauth-starter.version>1.4.0</justauth-starter.version> 75 <justauth-starter.version>1.4.0</justauth-starter.version>
75 <jimureport.version>2.0.0</jimureport.version> 76 <jimureport.version>2.0.0</jimureport.version>
76 <jimubi.version>1.9.5</jimubi.version> 77 <jimubi.version>1.9.5</jimubi.version>
77 - <weixin-java.version>4.7.5.B</weixin-java.version> 78 + <weixin-java.version>4.7.7-20250808.182223</weixin-java.version>
78 </properties> 79 </properties>
79 80
80 <dependencyManagement> 81 <dependencyManagement>
@@ -524,7 +525,6 @@ @@ -524,7 +525,6 @@
524 <artifactId>commons-net</artifactId> <!-- 解决 ftp 连接 --> 525 <artifactId>commons-net</artifactId> <!-- 解决 ftp 连接 -->
525 <version>${commons-net.version}</version> 526 <version>${commons-net.version}</version>
526 </dependency> 527 </dependency>
527 -  
528 <dependency> 528 <dependency>
529 <groupId>com.jcraft</groupId> 529 <groupId>com.jcraft</groupId>
530 <artifactId>jsch</artifactId> <!-- 解决 sftp 连接 --> 530 <artifactId>jsch</artifactId> <!-- 解决 sftp 连接 -->
@@ -532,6 +532,12 @@ @@ -532,6 +532,12 @@
532 </dependency> 532 </dependency>
533 533
534 <dependency> 534 <dependency>
  535 + <groupId>org.apache.commons</groupId>
  536 + <artifactId>commons-lang3</artifactId>
  537 + <version>${commons-lang3.version}</version> <!-- 解决 CVE-2025-48924 漏洞 -->
  538 + </dependency>
  539 +
  540 + <dependency>
535 <groupId>com.anji-plus</groupId> 541 <groupId>com.anji-plus</groupId>
536 <artifactId>captcha-spring-boot-starter</artifactId> <!-- 验证码,一般用于登录使用 --> 542 <artifactId>captcha-spring-boot-starter</artifactId> <!-- 验证码,一般用于登录使用 -->
537 <version>${anji-plus-captcha.version}</version> 543 <version>${anji-plus-captcha.version}</version>
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java
@@ -75,7 +75,7 @@ public class TenantDatabaseInterceptor implements TenantLineHandler { @@ -75,7 +75,7 @@ public class TenantDatabaseInterceptor implements TenantLineHandler {
75 if (TenantBaseDO.class.isAssignableFrom(tableInfo.getEntityType())) { 75 if (TenantBaseDO.class.isAssignableFrom(tableInfo.getEntityType())) {
76 return false; 76 return false;
77 } 77 }
78 - // 如果添加了 @TenantIgnore 注解,显然也不忽略租户 78 + // 如果添加了 @TenantIgnore 注解,则忽略租户
79 TenantIgnore tenantIgnore = tableInfo.getEntityType().getAnnotation(TenantIgnore.class); 79 TenantIgnore tenantIgnore = tableInfo.getEntityType().getAnnotation(TenantIgnore.class);
80 return tenantIgnore != null; 80 return tenantIgnore != null;
81 } 81 }
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rabbitmq/TenantRabbitMQInitializer.java
@@ -13,11 +13,10 @@ public class TenantRabbitMQInitializer implements BeanPostProcessor { @@ -13,11 +13,10 @@ public class TenantRabbitMQInitializer implements BeanPostProcessor {
13 13
14 @Override 14 @Override
15 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 15 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
16 - if (bean instanceof RabbitTemplate) {  
17 - RabbitTemplate rabbitTemplate = (RabbitTemplate) bean; 16 + if (bean instanceof RabbitTemplate rabbitTemplate) {
18 rabbitTemplate.addBeforePublishPostProcessors(new TenantRabbitMQMessagePostProcessor()); 17 rabbitTemplate.addBeforePublishPostProcessors(new TenantRabbitMQMessagePostProcessor());
19 } 18 }
20 return bean; 19 return bean;
21 } 20 }
22 21
23 -}  
24 \ No newline at end of file 22 \ No newline at end of file
  23 +}
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rocketmq/TenantRocketMQInitializer.java
@@ -18,11 +18,9 @@ public class TenantRocketMQInitializer implements BeanPostProcessor { @@ -18,11 +18,9 @@ public class TenantRocketMQInitializer implements BeanPostProcessor {
18 18
19 @Override 19 @Override
20 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 20 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
21 - if (bean instanceof DefaultRocketMQListenerContainer) {  
22 - DefaultRocketMQListenerContainer container = (DefaultRocketMQListenerContainer) bean; 21 + if (bean instanceof DefaultRocketMQListenerContainer container) {
23 initTenantConsumer(container.getConsumer()); 22 initTenantConsumer(container.getConsumer());
24 - } else if (bean instanceof RocketMQTemplate) {  
25 - RocketMQTemplate template = (RocketMQTemplate) bean; 23 + } else if (bean instanceof RocketMQTemplate template) {
26 initTenantProducer(template.getProducer()); 24 initTenantProducer(template.getProducer());
27 } 25 }
28 return bean; 26 return bean;
@@ -50,4 +48,4 @@ public class TenantRocketMQInitializer implements BeanPostProcessor { @@ -50,4 +48,4 @@ public class TenantRocketMQInitializer implements BeanPostProcessor {
50 consumerImpl.registerConsumeMessageHook(new TenantRocketMQConsumeMessageHook()); 48 consumerImpl.registerConsumeMessageHook(new TenantRocketMQConsumeMessageHook());
51 } 49 }
52 50
53 -}  
54 \ No newline at end of file 51 \ No newline at end of file
  52 +}
yudao-framework/yudao-spring-boot-starter-job/src/main/java/cn/iocoder/yudao/framework/quartz/config/YudaoAsyncAutoConfiguration.java
@@ -23,15 +23,13 @@ public class YudaoAsyncAutoConfiguration { @@ -23,15 +23,13 @@ public class YudaoAsyncAutoConfiguration {
23 @Override 23 @Override
24 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 24 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
25 // 处理 ThreadPoolTaskExecutor 25 // 处理 ThreadPoolTaskExecutor
26 - if (bean instanceof ThreadPoolTaskExecutor) {  
27 - ThreadPoolTaskExecutor executor = (ThreadPoolTaskExecutor) bean; 26 + if (bean instanceof ThreadPoolTaskExecutor executor) {
28 executor.setTaskDecorator(TtlRunnable::get); 27 executor.setTaskDecorator(TtlRunnable::get);
29 return executor; 28 return executor;
30 } 29 }
31 // 处理 SimpleAsyncTaskExecutor 30 // 处理 SimpleAsyncTaskExecutor
32 // 参考 https://t.zsxq.com/CBoks 增加 31 // 参考 https://t.zsxq.com/CBoks 增加
33 - if (bean instanceof SimpleAsyncTaskExecutor) {  
34 - SimpleAsyncTaskExecutor executor = (SimpleAsyncTaskExecutor) bean; 32 + if (bean instanceof SimpleAsyncTaskExecutor executor) {
35 executor.setTaskDecorator(TtlRunnable::get); 33 executor.setTaskDecorator(TtlRunnable::get);
36 return executor; 34 return executor;
37 } 35 }
yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/config/YudaoTracerAutoConfiguration.java
1 package cn.iocoder.yudao.framework.tracer.config; 1 package cn.iocoder.yudao.framework.tracer.config;
2 2
3 import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; 3 import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
4 -import cn.iocoder.yudao.framework.tracer.core.aop.BizTraceAspect;  
5 import cn.iocoder.yudao.framework.tracer.core.filter.TraceFilter; 4 import cn.iocoder.yudao.framework.tracer.core.filter.TraceFilter;
6 -import io.opentracing.Tracer;  
7 -import io.opentracing.util.GlobalTracer;  
8 -import org.apache.skywalking.apm.toolkit.opentracing.SkywalkingTracer;  
9 import org.springframework.boot.autoconfigure.AutoConfiguration; 5 import org.springframework.boot.autoconfigure.AutoConfiguration;
10 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 6 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
11 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 7 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -20,32 +16,28 @@ import org.springframework.context.annotation.Bean; @@ -20,32 +16,28 @@ import org.springframework.context.annotation.Bean;
20 */ 16 */
21 @AutoConfiguration 17 @AutoConfiguration
22 @ConditionalOnClass(name = { 18 @ConditionalOnClass(name = {
23 - "org.apache.skywalking.apm.toolkit.opentracing.SkywalkingTracer",  
24 - "io.opentracing.Tracer", 19 + "org.apache.skywalking.apm.toolkit.opentracing.SkywalkingTracer", // 来自 apm-toolkit-opentracing.jar
  20 +// "io.opentracing.Tracer", // 来自 opentracing-api.jar
25 "jakarta.servlet.Filter" 21 "jakarta.servlet.Filter"
26 }) 22 })
27 @EnableConfigurationProperties(TracerProperties.class) 23 @EnableConfigurationProperties(TracerProperties.class)
28 @ConditionalOnProperty(prefix = "yudao.tracer", value = "enable", matchIfMissing = true) 24 @ConditionalOnProperty(prefix = "yudao.tracer", value = "enable", matchIfMissing = true)
29 public class YudaoTracerAutoConfiguration { 25 public class YudaoTracerAutoConfiguration {
30 26
31 - @Bean  
32 - public TracerProperties bizTracerProperties() {  
33 - return new TracerProperties();  
34 - }  
35 -  
36 - @Bean  
37 - public BizTraceAspect bizTracingAop() {  
38 - return new BizTraceAspect(tracer());  
39 - }  
40 -  
41 - @Bean  
42 - public Tracer tracer() {  
43 - // 创建 SkywalkingTracer 对象  
44 - SkywalkingTracer tracer = new SkywalkingTracer();  
45 - // 设置为 GlobalTracer 的追踪器  
46 - GlobalTracer.registerIfAbsent(tracer);  
47 - return tracer;  
48 - } 27 + // TODO @芋艿:skywalking 不兼容最新的 opentracing 版本。同时,opentracing 也停止了维护,尬住了!后续换 opentelemetry 即可!
  28 +// @Bean
  29 +// public BizTraceAspect bizTracingAop() {
  30 +// return new BizTraceAspect(tracer());
  31 +// }
  32 +//
  33 +// @Bean
  34 +// public Tracer tracer() {
  35 +// // 创建 SkywalkingTracer 对象
  36 +// SkywalkingTracer tracer = new SkywalkingTracer();
  37 +// // 设置为 GlobalTracer 的追踪器
  38 +// GlobalTracer.registerIfAbsent(tracer);
  39 +// return tracer;
  40 +// }
49 41
50 /** 42 /**
51 * 创建 TraceFilter 过滤器,响应 header 设置 traceId 43 * 创建 TraceFilter 过滤器,响应 header 设置 traceId
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/YudaoMybatisAutoConfiguration.java
@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.extension.incrementer.*; @@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.extension.incrementer.*;
10 import com.baomidou.mybatisplus.extension.parser.JsqlParserGlobal; 10 import com.baomidou.mybatisplus.extension.parser.JsqlParserGlobal;
11 import com.baomidou.mybatisplus.extension.parser.cache.JdkSerialCaffeineJsqlParseCache; 11 import com.baomidou.mybatisplus.extension.parser.cache.JdkSerialCaffeineJsqlParseCache;
12 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 12 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
  13 +import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
13 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 14 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
14 import org.apache.ibatis.annotations.Mapper; 15 import org.apache.ibatis.annotations.Mapper;
15 import org.mybatis.spring.annotation.MapperScan; 16 import org.mybatis.spring.annotation.MapperScan;
@@ -42,6 +43,7 @@ public class YudaoMybatisAutoConfiguration { @@ -42,6 +43,7 @@ public class YudaoMybatisAutoConfiguration {
42 public MybatisPlusInterceptor mybatisPlusInterceptor() { 43 public MybatisPlusInterceptor mybatisPlusInterceptor() {
43 MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); 44 MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
44 mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); // 分页插件 45 mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); // 分页插件
  46 + mybatisPlusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor()); // 拦截没有指定条件的 update 和 delete 语句
45 return mybatisPlusInterceptor; 47 return mybatisPlusInterceptor;
46 } 48 }
47 49
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/handler/DefaultDBFieldHandler.java
@@ -19,8 +19,7 @@ public class DefaultDBFieldHandler implements MetaObjectHandler { @@ -19,8 +19,7 @@ public class DefaultDBFieldHandler implements MetaObjectHandler {
19 19
20 @Override 20 @Override
21 public void insertFill(MetaObject metaObject) { 21 public void insertFill(MetaObject metaObject) {
22 - if (Objects.nonNull(metaObject) && metaObject.getOriginalObject() instanceof BaseDO) {  
23 - BaseDO baseDO = (BaseDO) metaObject.getOriginalObject(); 22 + if (Objects.nonNull(metaObject) && metaObject.getOriginalObject() instanceof BaseDO baseDO) {
24 23
25 LocalDateTime current = LocalDateTime.now(); 24 LocalDateTime current = LocalDateTime.now();
26 // 创建时间为空,则以当前时间为插入时间 25 // 创建时间为空,则以当前时间为插入时间
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/config/YudaoJacksonAutoConfiguration.java
1 package cn.iocoder.yudao.framework.jackson.config; 1 package cn.iocoder.yudao.framework.jackson.config;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 3 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
5 import cn.iocoder.yudao.framework.common.util.json.databind.NumberSerializer; 4 import cn.iocoder.yudao.framework.common.util.json.databind.NumberSerializer;
6 import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeDeserializer; 5 import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeDeserializer;
7 import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeSerializer; 6 import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeSerializer;
  7 +import com.fasterxml.jackson.databind.Module;
8 import com.fasterxml.jackson.databind.ObjectMapper; 8 import com.fasterxml.jackson.databind.ObjectMapper;
9 import com.fasterxml.jackson.databind.module.SimpleModule; 9 import com.fasterxml.jackson.databind.module.SimpleModule;
10 import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; 10 import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
@@ -13,39 +13,65 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; @@ -13,39 +13,65 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
13 import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; 13 import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
14 import lombok.extern.slf4j.Slf4j; 14 import lombok.extern.slf4j.Slf4j;
15 import org.springframework.boot.autoconfigure.AutoConfiguration; 15 import org.springframework.boot.autoconfigure.AutoConfiguration;
  16 +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
  17 +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
16 import org.springframework.context.annotation.Bean; 18 import org.springframework.context.annotation.Bean;
17 19
18 import java.time.LocalDate; 20 import java.time.LocalDate;
19 import java.time.LocalDateTime; 21 import java.time.LocalDateTime;
20 import java.time.LocalTime; 22 import java.time.LocalTime;
21 -import java.util.List;  
22 23
23 -@AutoConfiguration 24 +@AutoConfiguration(after = JacksonAutoConfiguration.class)
24 @Slf4j 25 @Slf4j
25 public class YudaoJacksonAutoConfiguration { 26 public class YudaoJacksonAutoConfiguration {
26 27
  28 + /**
  29 + * 从 Builder 源头定制(关键:使用 *ByType,避免 handledType 要求)
  30 + */
27 @Bean 31 @Bean
28 - @SuppressWarnings("InstantiationOfUtilityClass")  
29 - public JsonUtils jsonUtils(List<ObjectMapper> objectMappers) {  
30 - // 1.1 创建 SimpleModule 对象  
31 - SimpleModule simpleModule = new SimpleModule();  
32 - simpleModule  
33 - // 新增 Long 类型序列化规则,数值超过 2^53-1,在 JS 会出现精度丢失问题,因此 Long 自动序列化为字符串类型  
34 - .addSerializer(Long.class, NumberSerializer.INSTANCE)  
35 - .addSerializer(Long.TYPE, NumberSerializer.INSTANCE)  
36 - .addSerializer(LocalDate.class, LocalDateSerializer.INSTANCE)  
37 - .addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE)  
38 - .addSerializer(LocalTime.class, LocalTimeSerializer.INSTANCE)  
39 - .addDeserializer(LocalTime.class, LocalTimeDeserializer.INSTANCE)  
40 - // 新增 LocalDateTime 序列化、反序列化规则,使用 Long 时间戳  
41 - .addSerializer(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE)  
42 - .addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);  
43 - // 1.2 注册到 objectMapper  
44 - objectMappers.forEach(objectMapper -> objectMapper.registerModule(simpleModule)); 32 + public Jackson2ObjectMapperBuilderCustomizer ldtEpochMillisCustomizer() {
  33 + return builder -> builder
  34 + // Long -> Number
  35 + .serializerByType(Long.class, NumberSerializer.INSTANCE)
  36 + .serializerByType(Long.TYPE, NumberSerializer.INSTANCE)
  37 + // LocalDate / LocalTime
  38 + .serializerByType(LocalDate.class, LocalDateSerializer.INSTANCE)
  39 + .deserializerByType(LocalDate.class, LocalDateDeserializer.INSTANCE)
  40 + .serializerByType(LocalTime.class, LocalTimeSerializer.INSTANCE)
  41 + .deserializerByType(LocalTime.class, LocalTimeDeserializer.INSTANCE)
  42 + // LocalDateTime < - > EpochMillis
  43 + .serializerByType(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE)
  44 + .deserializerByType(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
  45 + }
45 46
46 - // 2. 设置 objectMapper 到 JsonUtils  
47 - JsonUtils.init(CollUtil.getFirst(objectMappers));  
48 - log.info("[init][初始化 JsonUtils 成功]"); 47 + /**
  48 + * 以 Bean 形式暴露 Module(Boot 会自动注册到所有 ObjectMapper)
  49 + */
  50 + @Bean
  51 + public Module timestampSupportModuleBean() {
  52 + SimpleModule m = new SimpleModule("TimestampSupportModule");
  53 + // Long -> Number,避免前端精度丢失
  54 + m.addSerializer(Long.class, NumberSerializer.INSTANCE);
  55 + m.addSerializer(Long.TYPE, NumberSerializer.INSTANCE);
  56 + // LocalDate / LocalTime
  57 + m.addSerializer(LocalDate.class, LocalDateSerializer.INSTANCE);
  58 + m.addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE);
  59 + m.addSerializer(LocalTime.class, LocalTimeSerializer.INSTANCE);
  60 + m.addDeserializer(LocalTime.class, LocalTimeDeserializer.INSTANCE);
  61 + // LocalDateTime < - > EpochMillis
  62 + m.addSerializer(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE);
  63 + m.addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
  64 + return m;
  65 + }
  66 +
  67 + /**
  68 + * 初始化全局 JsonUtils,直接使用主 ObjectMapper
  69 + */
  70 + @Bean
  71 + @SuppressWarnings("InstantiationOfUtilityClass")
  72 + public JsonUtils jsonUtils(ObjectMapper objectMapper) {
  73 + JsonUtils.init(objectMapper);
  74 + log.debug("[init][初始化 JsonUtils 成功]");
49 return new JsonUtils(); 75 return new JsonUtils();
50 } 76 }
51 77
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java
@@ -184,8 +184,7 @@ public class GlobalExceptionHandler { @@ -184,8 +184,7 @@ public class GlobalExceptionHandler {
184 @ExceptionHandler(HttpMessageNotReadableException.class) 184 @ExceptionHandler(HttpMessageNotReadableException.class)
185 public CommonResult<?> methodArgumentTypeInvalidFormatExceptionHandler(HttpMessageNotReadableException ex) { 185 public CommonResult<?> methodArgumentTypeInvalidFormatExceptionHandler(HttpMessageNotReadableException ex) {
186 log.warn("[methodArgumentTypeInvalidFormatExceptionHandler]", ex); 186 log.warn("[methodArgumentTypeInvalidFormatExceptionHandler]", ex);
187 - if (ex.getCause() instanceof InvalidFormatException) {  
188 - InvalidFormatException invalidFormatException = (InvalidFormatException) ex.getCause(); 187 + if (ex.getCause() instanceof InvalidFormatException invalidFormatException) {
189 return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数类型错误:%s", invalidFormatException.getValue())); 188 return CommonResult.error(BAD_REQUEST.getCode(), String.format("请求参数类型错误:%s", invalidFormatException.getValue()));
190 } 189 }
191 if (StrUtil.startWith(ex.getMessage(), "Required request body is missing")) { 190 if (StrUtil.startWith(ex.getMessage(), "Required request body is missing")) {
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/util/WebFrameworkUtils.java
@@ -146,10 +146,9 @@ public class WebFrameworkUtils { @@ -146,10 +146,9 @@ public class WebFrameworkUtils {
146 146
147 public static HttpServletRequest getRequest() { 147 public static HttpServletRequest getRequest() {
148 RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); 148 RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
149 - if (!(requestAttributes instanceof ServletRequestAttributes)) { 149 + if (!(requestAttributes instanceof ServletRequestAttributes servletRequestAttributes)) {
150 return null; 150 return null;
151 } 151 }
152 - ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;  
153 return servletRequestAttributes.getRequest(); 152 return servletRequestAttributes.getRequest();
154 } 153 }
155 154
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/api/event/BpmProcessInstanceStatusEvent.java
@@ -29,6 +29,11 @@ public class BpmProcessInstanceStatusEvent extends ApplicationEvent { @@ -29,6 +29,11 @@ public class BpmProcessInstanceStatusEvent extends ApplicationEvent {
29 @NotNull(message = "流程实例的状态不能为空") 29 @NotNull(message = "流程实例的状态不能为空")
30 private Integer status; 30 private Integer status;
31 /** 31 /**
  32 + * 流程实例结束的原因
  33 + */
  34 + private String reason;
  35 +
  36 + /**
32 * 流程实例对应的业务标识 37 * 流程实例对应的业务标识
33 * 例如说,请假 38 * 例如说,请假
34 */ 39 */
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
@@ -119,8 +119,9 @@ public interface BpmProcessInstanceConvert { @@ -119,8 +119,9 @@ public interface BpmProcessInstanceConvert {
119 @Mapping(source = "from.id", target = "to.id", ignore = true) 119 @Mapping(source = "from.id", target = "to.id", ignore = true)
120 void copyTo(BpmProcessDefinitionInfoDO from, @MappingTarget BpmProcessDefinitionRespVO to); 120 void copyTo(BpmProcessDefinitionInfoDO from, @MappingTarget BpmProcessDefinitionRespVO to);
121 121
122 - default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, ProcessInstance instance, Integer status) {  
123 - return new BpmProcessInstanceStatusEvent(source).setId(instance.getId()).setStatus(status) 122 + default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, ProcessInstance instance,
  123 + Integer status, String reason) {
  124 + return new BpmProcessInstanceStatusEvent(source).setId(instance.getId()).setStatus(status).setReason(reason)
124 .setProcessDefinitionKey(instance.getProcessDefinitionKey()).setBusinessKey(instance.getBusinessKey()); 125 .setProcessDefinitionKey(instance.getProcessDefinitionKey()).setBusinessKey(instance.getBusinessKey());
125 } 126 }
126 127
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
@@ -960,7 +960,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService @@ -960,7 +960,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
960 960
961 // 3. 发送流程实例的状态事件 961 // 3. 发送流程实例的状态事件
962 processInstanceEventPublisher.sendProcessInstanceResultEvent( 962 processInstanceEventPublisher.sendProcessInstanceResultEvent(
963 - BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceStatusEvent(this, instance, status)); 963 + BpmProcessInstanceConvert.INSTANCE.buildProcessInstanceStatusEvent(this, instance, status, reason));
964 964
965 // 4. 流程后置通知 965 // 4. 流程后置通知
966 if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) { 966 if (Objects.equals(status, BpmProcessInstanceStatusEnum.APPROVE.getStatus())) {
yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java
@@ -166,6 +166,10 @@ public class CouponServiceImpl implements CouponService { @@ -166,6 +166,10 @@ public class CouponServiceImpl implements CouponService {
166 public void invalidateCouponsByAdmin(List<Long> giveCouponIds, Long userId) { 166 public void invalidateCouponsByAdmin(List<Long> giveCouponIds, Long userId) {
167 // 循环收回 167 // 循环收回
168 for (Long couponId : giveCouponIds) { 168 for (Long couponId : giveCouponIds) {
  169 + // couponId 为空或 0 则跳过
  170 + if (null == couponId || couponId <= 0) {
  171 + continue;
  172 + }
169 try { 173 try {
170 getSelf().invalidateCoupon(couponId, userId); 174 getSelf().invalidateCoupon(couponId, userId);
171 } catch (Exception e) { 175 } catch (Exception e) {
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/framework/captcha/core/PictureWordCaptchaServiceImpl.java
@@ -8,8 +8,8 @@ import com.anji.captcha.service.impl.CaptchaServiceFactory; @@ -8,8 +8,8 @@ import com.anji.captcha.service.impl.CaptchaServiceFactory;
8 import com.anji.captcha.util.AESUtil; 8 import com.anji.captcha.util.AESUtil;
9 import com.anji.captcha.util.ImageUtils; 9 import com.anji.captcha.util.ImageUtils;
10 import com.anji.captcha.util.RandomUtils; 10 import com.anji.captcha.util.RandomUtils;
11 -import org.apache.commons.lang3.StringUtils;  
12 import cn.hutool.core.util.RandomUtil; 11 import cn.hutool.core.util.RandomUtil;
  12 +import org.apache.commons.lang3.Strings;
13 13
14 import java.awt.*; 14 import java.awt.*;
15 import java.awt.geom.AffineTransform; 15 import java.awt.geom.AffineTransform;
@@ -82,7 +82,7 @@ public class PictureWordCaptchaServiceImpl extends AbstractCaptchaService { @@ -82,7 +82,7 @@ public class PictureWordCaptchaServiceImpl extends AbstractCaptchaService {
82 82
83 // 用户输入的验证码(CaptchaVO 中 没有预留字段,暂时用 pointJson 无需加解密) 83 // 用户输入的验证码(CaptchaVO 中 没有预留字段,暂时用 pointJson 无需加解密)
84 String userCode = captchaVO.getPointJson(); 84 String userCode = captchaVO.getPointJson();
85 - if (!StringUtils.equalsIgnoreCase(code, userCode)) { 85 + if (!Strings.CI.equals(code, userCode)) {
86 afterValidateFail(captchaVO); 86 afterValidateFail(captchaVO);
87 return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_COORDINATE_ERROR); 87 return ResponseModel.errorMsg(RepCodeEnum.API_CAPTCHA_COORDINATE_ERROR);
88 } 88 }
@@ -209,4 +209,4 @@ public class PictureWordCaptchaServiceImpl extends AbstractCaptchaService { @@ -209,4 +209,4 @@ public class PictureWordCaptchaServiceImpl extends AbstractCaptchaService {
209 return RandomUtil.randomString(CHARACTERS, length); 209 return RandomUtil.randomString(CHARACTERS, length);
210 } 210 }
211 211
212 -}  
213 \ No newline at end of file 212 \ No newline at end of file
  213 +}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/framework/justauth/core/AuthRequestFactory.java
@@ -77,8 +77,8 @@ public class AuthRequestFactory { @@ -77,8 +77,8 @@ public class AuthRequestFactory {
77 extendList = extend.getConfig() 77 extendList = extend.getConfig()
78 .keySet() 78 .keySet()
79 .stream() 79 .stream()
80 - .filter(x -> names.contains(x.toUpperCase()))  
81 .map(String::toUpperCase) 80 .map(String::toUpperCase)
  81 + .filter(names::contains)
82 .collect(Collectors.toList()); 82 .collect(Collectors.toList());
83 } 83 }
84 84
@@ -318,4 +318,4 @@ public class AuthRequestFactory { @@ -318,4 +318,4 @@ public class AuthRequestFactory {
318 .proxy(new Proxy(Proxy.Type.valueOf(proxyConfig.getType()), new InetSocketAddress(proxyConfig.getHostname(), proxyConfig.getPort()))) 318 .proxy(new Proxy(Proxy.Type.valueOf(proxyConfig.getType()), new InetSocketAddress(proxyConfig.getHostname(), proxyConfig.getPort())))
319 .build()); 319 .build());
320 } 320 }
321 -}  
322 \ No newline at end of file 321 \ No newline at end of file
  322 +}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/AliyunSmsClient.java
@@ -114,12 +114,12 @@ public class AliyunSmsClient extends AbstractSmsClient { @@ -114,12 +114,12 @@ public class AliyunSmsClient extends AbstractSmsClient {
114 114
115 @VisibleForTesting 115 @VisibleForTesting
116 Integer convertSmsTemplateAuditStatus(Integer templateStatus) { 116 Integer convertSmsTemplateAuditStatus(Integer templateStatus) {
117 - switch (templateStatus) {  
118 - case 0: return SmsTemplateAuditStatusEnum.CHECKING.getStatus();  
119 - case 1: return SmsTemplateAuditStatusEnum.SUCCESS.getStatus();  
120 - case 2: return SmsTemplateAuditStatusEnum.FAIL.getStatus();  
121 - default: throw new IllegalArgumentException(String.format("未知审核状态(%d)", templateStatus));  
122 - } 117 + return switch (templateStatus) {
  118 + case 0 -> SmsTemplateAuditStatusEnum.CHECKING.getStatus();
  119 + case 1 -> SmsTemplateAuditStatusEnum.SUCCESS.getStatus();
  120 + case 2 -> SmsTemplateAuditStatusEnum.FAIL.getStatus();
  121 + default -> throw new IllegalArgumentException(String.format("未知审核状态(%d)", templateStatus));
  122 + };
123 } 123 }
124 124
125 /** 125 /**
@@ -153,8 +153,8 @@ public class AliyunSmsClient extends AbstractSmsClient { @@ -153,8 +153,8 @@ public class AliyunSmsClient extends AbstractSmsClient {
153 StringBuilder canonicalHeaders = new StringBuilder(); // 构造请求头,多个规范化消息头,按照消息头名称(小写)的字符代码顺序以升序排列后拼接在一起 153 StringBuilder canonicalHeaders = new StringBuilder(); // 构造请求头,多个规范化消息头,按照消息头名称(小写)的字符代码顺序以升序排列后拼接在一起
154 StringBuilder signedHeadersBuilder = new StringBuilder(); // 已签名消息头列表,多个请求头名称(小写)按首字母升序排列并以英文分号(;)分隔 154 StringBuilder signedHeadersBuilder = new StringBuilder(); // 已签名消息头列表,多个请求头名称(小写)按首字母升序排列并以英文分号(;)分隔
155 headers.entrySet().stream().filter(entry -> entry.getKey().toLowerCase().startsWith("x-acs-") 155 headers.entrySet().stream().filter(entry -> entry.getKey().toLowerCase().startsWith("x-acs-")
156 - || entry.getKey().equalsIgnoreCase("host")  
157 - || entry.getKey().equalsIgnoreCase("content-type")) 156 + || "host".equalsIgnoreCase(entry.getKey())
  157 + || "content-type".equalsIgnoreCase(entry.getKey()))
158 .sorted(Map.Entry.comparingByKey()).forEach(entry -> { 158 .sorted(Map.Entry.comparingByKey()).forEach(entry -> {
159 String lowerKey = entry.getKey().toLowerCase(); 159 String lowerKey = entry.getKey().toLowerCase();
160 canonicalHeaders.append(lowerKey).append(":").append(String.valueOf(entry.getValue()).trim()).append("\n"); 160 canonicalHeaders.append(lowerKey).append(":").append(String.valueOf(entry.getValue()).trim()).append("\n");
@@ -189,10 +189,10 @@ public class AliyunSmsClient extends AbstractSmsClient { @@ -189,10 +189,10 @@ public class AliyunSmsClient extends AbstractSmsClient {
189 @SneakyThrows 189 @SneakyThrows
190 private static String percentCode(String str) { 190 private static String percentCode(String str) {
191 Assert.notNull(str, "str 不能为空"); 191 Assert.notNull(str, "str 不能为空");
192 - return URLEncoder.encode(str, StandardCharsets.UTF_8.name()) 192 + return URLEncoder.encode(str, StandardCharsets.UTF_8)
193 .replace("+", "%20") // 加号 "+" 被替换为 "%20" 193 .replace("+", "%20") // 加号 "+" 被替换为 "%20"
194 .replace("*", "%2A") // 星号 "*" 被替换为 "%2A" 194 .replace("*", "%2A") // 星号 "*" 被替换为 "%2A"
195 .replace("%7E", "~"); // 波浪号 "%7E" 被替换为 "~" 195 .replace("%7E", "~"); // 波浪号 "%7E" 被替换为 "~"
196 } 196 }
197 197
198 -}  
199 \ No newline at end of file 198 \ No newline at end of file
  199 +}
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6 import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; 6 import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
7 import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; 7 import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
8 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; 8 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
  9 +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
9 import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO; 10 import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO;
10 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; 11 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
11 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; 12 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
@@ -97,6 +98,7 @@ public class AdminAuthServiceImpl implements AdminAuthService { @@ -97,6 +98,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
97 } 98 }
98 99
99 @Override 100 @Override
  101 + @DataPermission(enable = false)
100 public AuthLoginRespVO login(AuthLoginReqVO reqVO) { 102 public AuthLoginRespVO login(AuthLoginReqVO reqVO) {
101 // 校验验证码 103 // 校验验证码
102 validateCaptcha(reqVO); 104 validateCaptcha(reqVO);
yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2GrantServiceImplTest.java
@@ -16,7 +16,6 @@ import java.util.List; @@ -16,7 +16,6 @@ import java.util.List;
16 import static cn.hutool.core.util.RandomUtil.randomEle; 16 import static cn.hutool.core.util.RandomUtil.randomEle;
17 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; 17 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
18 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; 18 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
19 -import static java.util.Collections.emptyList;  
20 import static org.junit.jupiter.api.Assertions.*; 19 import static org.junit.jupiter.api.Assertions.*;
21 import static org.mockito.ArgumentMatchers.eq; 20 import static org.mockito.ArgumentMatchers.eq;
22 import static org.mockito.Mockito.when; 21 import static org.mockito.Mockito.when;
@@ -136,13 +135,6 @@ public class OAuth2GrantServiceImplTest extends BaseMockitoUnitTest { @@ -136,13 +135,6 @@ public class OAuth2GrantServiceImplTest extends BaseMockitoUnitTest {
136 } 135 }
137 136
138 @Test 137 @Test
139 - public void testGrantClientCredentials() {  
140 - assertThrows(UnsupportedOperationException.class,  
141 - () -> oauth2GrantService.grantClientCredentials(randomString(), emptyList()),  
142 - "暂时不支持 client_credentials 授权模式");  
143 - }  
144 -  
145 - @Test  
146 public void testRevokeToken_clientIdError() { 138 public void testRevokeToken_clientIdError() {
147 // 准备参数 139 // 准备参数
148 String clientId = randomString(); 140 String clientId = randomString();
yudao-module-system/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImplTest.java
@@ -236,6 +236,7 @@ public class OAuth2TokenServiceImplTest extends BaseDbAndRedisUnitTest { @@ -236,6 +236,7 @@ public class OAuth2TokenServiceImplTest extends BaseDbAndRedisUnitTest {
236 public void testCheckAccessToken_refreshToken() { 236 public void testCheckAccessToken_refreshToken() {
237 // mock 数据(访问令牌) 237 // mock 数据(访问令牌)
238 OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class) 238 OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class)
  239 + .setUserId(0L)
239 .setExpiresTime(LocalDateTime.now().plusDays(1)); 240 .setExpiresTime(LocalDateTime.now().plusDays(1));
240 oauth2RefreshTokenMapper.insert(refreshTokenDO); 241 oauth2RefreshTokenMapper.insert(refreshTokenDO);
241 // 准备参数 242 // 准备参数