Commit 787de1be94f21d945d55c2de28ad4c0db6692fdb
Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into feature/mall_product
# Conflicts: # sql/mysql/mall.sql # sql/mysql/ruoyi-vue-pro.sql # yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateReqVO.java # yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserService.java
Showing
189 changed files
with
1533 additions
and
2012 deletions
README.md
| @@ -256,7 +256,7 @@ _鍓嶇鍩轰簬 crmeb uniapp 缁忚繃鎺堟潈閲嶆瀯锛屼紭鍖栦唬鐮佸疄鐜帮紝鎺ュ叆鑺嬮 | @@ -256,7 +256,7 @@ _鍓嶇鍩轰簬 crmeb uniapp 缁忚繃鎺堟潈閲嶆瀯锛屼紭鍖栦唬鐮佸疄鐜帮紝鎺ュ叆鑺嬮 | ||
| 256 | 256 | ||
| 257 | | 妗嗘灦 | 璇存槑 | 鐗堟湰 | 瀛︿範鎸囧崡 | | 257 | | 妗嗘灦 | 璇存槑 | 鐗堟湰 | 瀛︿範鎸囧崡 | |
| 258 | |---------------------------------------------------------------------------------------------|------------------|----------------|----------------------------------------------------------------| | 258 | |---------------------------------------------------------------------------------------------|------------------|----------------|----------------------------------------------------------------| |
| 259 | -| [Spring Boot](https://spring.io/projects/spring-boot) | 搴旂敤寮鍙戞鏋 | 2.7.16 | [鏂囨。](https://github.com/YunaiV/SpringBoot-Labs) | | 259 | +| [Spring Boot](https://spring.io/projects/spring-boot) | 搴旂敤寮鍙戞鏋 | 2.7.17 | [鏂囨。](https://github.com/YunaiV/SpringBoot-Labs) | |
| 260 | | [MySQL](https://www.mysql.com/cn/) | 鏁版嵁搴撴湇鍔″櫒 | 5.7 / 8.0+ | | | 260 | | [MySQL](https://www.mysql.com/cn/) | 鏁版嵁搴撴湇鍔″櫒 | 5.7 / 8.0+ | | |
| 261 | | [Druid](https://github.com/alibaba/druid) | JDBC 杩炴帴姹犮佺洃鎺х粍浠 | 1.2.19 | [鏂囨。](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) | | 261 | | [Druid](https://github.com/alibaba/druid) | JDBC 杩炴帴姹犮佺洃鎺х粍浠 | 1.2.19 | [鏂囨。](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) | |
| 262 | | [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 澧炲己宸ュ叿鍖 | 3.5.3.2 | [鏂囨。](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) | | 262 | | [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 澧炲己宸ュ叿鍖 | 3.5.3.2 | [鏂囨。](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) | |
pom.xml
| @@ -13,16 +13,16 @@ | @@ -13,16 +13,16 @@ | ||
| 13 | <!-- Server 主项目 --> | 13 | <!-- Server 主项目 --> |
| 14 | <module>yudao-server</module> | 14 | <module>yudao-server</module> |
| 15 | <!-- 各种 module 拓展 --> | 15 | <!-- 各种 module 拓展 --> |
| 16 | - <module>yudao-module-member</module> | ||
| 17 | <module>yudao-module-system</module> | 16 | <module>yudao-module-system</module> |
| 18 | <module>yudao-module-infra</module> | 17 | <module>yudao-module-infra</module> |
| 19 | - <!-- <module>yudao-module-bpm</module>--> | 18 | +<!-- <module>yudao-module-member</module>--> |
| 19 | +<!-- <module>yudao-module-bpm</module>--> | ||
| 20 | <!-- <module>yudao-module-report</module>--> | 20 | <!-- <module>yudao-module-report</module>--> |
| 21 | <!-- <module>yudao-module-mp</module>--> | 21 | <!-- <module>yudao-module-mp</module>--> |
| 22 | - <module>yudao-module-pay</module> | ||
| 23 | - <module>yudao-module-mall</module> | 22 | +<!-- <module>yudao-module-pay</module>--> |
| 23 | +<!-- <module>yudao-module-mall</module>--> | ||
| 24 | <!-- 示例项目 --> | 24 | <!-- 示例项目 --> |
| 25 | - <module>yudao-example</module> | 25 | +<!-- <module>yudao-example</module>--> |
| 26 | </modules> | 26 | </modules> |
| 27 | 27 | ||
| 28 | <name>${project.artifactId}</name> | 28 | <name>${project.artifactId}</name> |
| @@ -30,7 +30,7 @@ | @@ -30,7 +30,7 @@ | ||
| 30 | <url>https://github.com/YunaiV/ruoyi-vue-pro</url> | 30 | <url>https://github.com/YunaiV/ruoyi-vue-pro</url> |
| 31 | 31 | ||
| 32 | <properties> | 32 | <properties> |
| 33 | - <revision>1.8.2-snapshot</revision> | 33 | + <revision>1.8.3-snapshot</revision> |
| 34 | <!-- Maven 相关 --> | 34 | <!-- Maven 相关 --> |
| 35 | <java.version>1.8</java.version> | 35 | <java.version>1.8</java.version> |
| 36 | <maven.compiler.source>${java.version}</maven.compiler.source> | 36 | <maven.compiler.source>${java.version}</maven.compiler.source> |
| @@ -40,7 +40,7 @@ | @@ -40,7 +40,7 @@ | ||
| 40 | <flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version> | 40 | <flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version> |
| 41 | <!-- 看看咋放到 bom 里 --> | 41 | <!-- 看看咋放到 bom 里 --> |
| 42 | <lombok.version>1.18.30</lombok.version> | 42 | <lombok.version>1.18.30</lombok.version> |
| 43 | - <spring.boot.version>2.7.16</spring.boot.version> | 43 | + <spring.boot.version>2.7.17</spring.boot.version> |
| 44 | <mapstruct.version>1.5.5.Final</mapstruct.version> | 44 | <mapstruct.version>1.5.5.Final</mapstruct.version> |
| 45 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | 45 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| 46 | </properties> | 46 | </properties> |
yudao-dependencies/pom.xml
| @@ -14,28 +14,30 @@ | @@ -14,28 +14,30 @@ | ||
| 14 | <url>https://github.com/YunaiV/ruoyi-vue-pro</url> | 14 | <url>https://github.com/YunaiV/ruoyi-vue-pro</url> |
| 15 | 15 | ||
| 16 | <properties> | 16 | <properties> |
| 17 | - <revision>1.8.2-snapshot</revision> | 17 | + <revision>1.8.3-snapshot</revision> |
| 18 | <flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version> | 18 | <flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version> |
| 19 | <!-- 统一依赖管理 --> | 19 | <!-- 统一依赖管理 --> |
| 20 | - <spring.boot.version>2.7.16</spring.boot.version> | 20 | + <spring.boot.version>2.7.17</spring.boot.version> |
| 21 | <!-- Web 相关 --> | 21 | <!-- Web 相关 --> |
| 22 | <springdoc.version>1.6.15</springdoc.version> | 22 | <springdoc.version>1.6.15</springdoc.version> |
| 23 | <knife4j.version>4.3.0</knife4j.version> | 23 | <knife4j.version>4.3.0</knife4j.version> |
| 24 | <servlet.versoin>2.5</servlet.versoin> | 24 | <servlet.versoin>2.5</servlet.versoin> |
| 25 | <!-- DB 相关 --> | 25 | <!-- DB 相关 --> |
| 26 | - <druid.version>1.2.19</druid.version> | ||
| 27 | - <mybatis-plus.version>3.5.3.2</mybatis-plus.version> | ||
| 28 | - <mybatis-plus-generator.version>3.5.3.2</mybatis-plus-generator.version> | 26 | + <druid.version>1.2.20</druid.version> |
| 27 | + <mybatis-plus.version>3.5.4</mybatis-plus.version> | ||
| 28 | + <mybatis-plus-generator.version>3.5.4</mybatis-plus-generator.version> | ||
| 29 | <dynamic-datasource.version>3.6.1</dynamic-datasource.version> | 29 | <dynamic-datasource.version>3.6.1</dynamic-datasource.version> |
| 30 | - <mybatis-plus-join.version>1.4.6</mybatis-plus-join.version> | 30 | + <mybatis-plus-join.version>1.4.7</mybatis-plus-join.version> |
| 31 | <redisson.version>3.18.0</redisson.version> | 31 | <redisson.version>3.18.0</redisson.version> |
| 32 | - <dm8.jdbc.version>8.1.2.141</dm8.jdbc.version> | 32 | + <dm8.jdbc.version>8.1.3.62</dm8.jdbc.version> |
| 33 | + <!-- 消息队列 --> | ||
| 34 | + <rocketmq-spring.version>2.2.3</rocketmq-spring.version> | ||
| 33 | <!-- 服务保障相关 --> | 35 | <!-- 服务保障相关 --> |
| 34 | - <lock4j.version>2.2.3</lock4j.version> | 36 | + <lock4j.version>2.2.5</lock4j.version> |
| 35 | <resilience4j.version>1.7.1</resilience4j.version> | 37 | <resilience4j.version>1.7.1</resilience4j.version> |
| 36 | <!-- 监控相关 --> | 38 | <!-- 监控相关 --> |
| 37 | <skywalking.version>8.12.0</skywalking.version> | 39 | <skywalking.version>8.12.0</skywalking.version> |
| 38 | - <spring-boot-admin.version>2.7.10</spring-boot-admin.version> | 40 | + <spring-boot-admin.version>2.7.11</spring-boot-admin.version> |
| 39 | <opentracing.version>0.33.0</opentracing.version> | 41 | <opentracing.version>0.33.0</opentracing.version> |
| 40 | <!-- Test 测试相关 --> | 42 | <!-- Test 测试相关 --> |
| 41 | <podam.version>7.2.11.RELEASE</podam.version> | 43 | <podam.version>7.2.11.RELEASE</podam.version> |
| @@ -44,8 +46,8 @@ | @@ -44,8 +46,8 @@ | ||
| 44 | <!-- Bpm 工作流相关 --> | 46 | <!-- Bpm 工作流相关 --> |
| 45 | <flowable.version>6.8.0</flowable.version> | 47 | <flowable.version>6.8.0</flowable.version> |
| 46 | <!-- 工具类相关 --> | 48 | <!-- 工具类相关 --> |
| 47 | - <captcha-plus.version>1.0.8</captcha-plus.version> | ||
| 48 | - <jsoup.version>1.16.1</jsoup.version> | 49 | + <captcha-plus.version>1.0.10</captcha-plus.version> |
| 50 | + <jsoup.version>1.16.2</jsoup.version> | ||
| 49 | <lombok.version>1.18.30</lombok.version> | 51 | <lombok.version>1.18.30</lombok.version> |
| 50 | <mapstruct.version>1.5.5.Final</mapstruct.version> | 52 | <mapstruct.version>1.5.5.Final</mapstruct.version> |
| 51 | <hutool.version>5.8.22</hutool.version> | 53 | <hutool.version>5.8.22</hutool.version> |
| @@ -53,10 +55,10 @@ | @@ -53,10 +55,10 @@ | ||
| 53 | <velocity.version>2.3</velocity.version> | 55 | <velocity.version>2.3</velocity.version> |
| 54 | <screw.version>1.0.5</screw.version> | 56 | <screw.version>1.0.5</screw.version> |
| 55 | <fastjson.version>1.2.83</fastjson.version> | 57 | <fastjson.version>1.2.83</fastjson.version> |
| 56 | - <guava.version>32.1.2-jre</guava.version> | 58 | + <guava.version>32.1.3-jre</guava.version> |
| 57 | <guice.version>5.1.0</guice.version> | 59 | <guice.version>5.1.0</guice.version> |
| 58 | <transmittable-thread-local.version>2.14.2</transmittable-thread-local.version> | 60 | <transmittable-thread-local.version>2.14.2</transmittable-thread-local.version> |
| 59 | - <commons-net.version>3.9.0</commons-net.version> | 61 | + <commons-net.version>3.10.0</commons-net.version> |
| 60 | <jsch.version>0.1.55</jsch.version> | 62 | <jsch.version>0.1.55</jsch.version> |
| 61 | <tika-core.version>2.7.0</tika-core.version> | 63 | <tika-core.version>2.7.0</tika-core.version> |
| 62 | <ip2region.version>2.7.0</ip2region.version> | 64 | <ip2region.version>2.7.0</ip2region.version> |
| @@ -67,8 +69,8 @@ | @@ -67,8 +69,8 @@ | ||
| 67 | <minio.version>8.5.6</minio.version> | 69 | <minio.version>8.5.6</minio.version> |
| 68 | <aliyun-java-sdk-core.version>4.6.4</aliyun-java-sdk-core.version> | 70 | <aliyun-java-sdk-core.version>4.6.4</aliyun-java-sdk-core.version> |
| 69 | <aliyun-java-sdk-dysmsapi.version>2.2.1</aliyun-java-sdk-dysmsapi.version> | 71 | <aliyun-java-sdk-dysmsapi.version>2.2.1</aliyun-java-sdk-dysmsapi.version> |
| 70 | - <tencentcloud-sdk-java.version>3.1.853</tencentcloud-sdk-java.version> | ||
| 71 | - <justauth.version>1.0.5</justauth.version> | 72 | + <tencentcloud-sdk-java.version>3.1.880</tencentcloud-sdk-java.version> |
| 73 | + <justauth.version>1.0.7</justauth.version> | ||
| 72 | <jimureport.version>1.6.1</jimureport.version> | 74 | <jimureport.version>1.6.1</jimureport.version> |
| 73 | <xercesImpl.version>2.12.2</xercesImpl.version> | 75 | <xercesImpl.version>2.12.2</xercesImpl.version> |
| 74 | <weixin-java.version>4.5.0</weixin-java.version> | 76 | <weixin-java.version>4.5.0</weixin-java.version> |
| @@ -98,11 +100,6 @@ | @@ -98,11 +100,6 @@ | ||
| 98 | </dependency> | 100 | </dependency> |
| 99 | <dependency> | 101 | <dependency> |
| 100 | <groupId>cn.iocoder.boot</groupId> | 102 | <groupId>cn.iocoder.boot</groupId> |
| 101 | - <artifactId>yudao-spring-boot-starter-biz-trade</artifactId> | ||
| 102 | - <version>${revision}</version> | ||
| 103 | - </dependency> | ||
| 104 | - <dependency> | ||
| 105 | - <groupId>cn.iocoder.boot</groupId> | ||
| 106 | <artifactId>yudao-spring-boot-starter-biz-dict</artifactId> | 103 | <artifactId>yudao-spring-boot-starter-biz-dict</artifactId> |
| 107 | <version>${revision}</version> | 104 | <version>${revision}</version> |
| 108 | </dependency> | 105 | </dependency> |
| @@ -260,6 +257,12 @@ | @@ -260,6 +257,12 @@ | ||
| 260 | <version>${revision}</version> | 257 | <version>${revision}</version> |
| 261 | </dependency> | 258 | </dependency> |
| 262 | 259 | ||
| 260 | + <dependency> | ||
| 261 | + <groupId>org.apache.rocketmq</groupId> | ||
| 262 | + <artifactId>rocketmq-spring-boot-starter</artifactId> | ||
| 263 | + <version>${rocketmq-spring.version}</version> | ||
| 264 | + </dependency> | ||
| 265 | + | ||
| 263 | <!-- 服务保障相关 --> | 266 | <!-- 服务保障相关 --> |
| 264 | <dependency> | 267 | <dependency> |
| 265 | <groupId>cn.iocoder.boot</groupId> | 268 | <groupId>cn.iocoder.boot</groupId> |
yudao-example/yudao-sso-demo-by-code/pom.xml
| @@ -21,7 +21,7 @@ | @@ -21,7 +21,7 @@ | ||
| 21 | <maven.compiler.target>8</maven.compiler.target> | 21 | <maven.compiler.target>8</maven.compiler.target> |
| 22 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | 22 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| 23 | <!-- 统一依赖管理 --> | 23 | <!-- 统一依赖管理 --> |
| 24 | - <spring.boot.version>2.7.16</spring.boot.version> | 24 | + <spring.boot.version>2.7.17</spring.boot.version> |
| 25 | </properties> | 25 | </properties> |
| 26 | 26 | ||
| 27 | <dependencyManagement> | 27 | <dependencyManagement> |
yudao-example/yudao-sso-demo-by-password/pom.xml
| @@ -21,7 +21,7 @@ | @@ -21,7 +21,7 @@ | ||
| 21 | <maven.compiler.target>8</maven.compiler.target> | 21 | <maven.compiler.target>8</maven.compiler.target> |
| 22 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | 22 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| 23 | <!-- 统一依赖管理 --> | 23 | <!-- 统一依赖管理 --> |
| 24 | - <spring.boot.version>2.7.16</spring.boot.version> | 24 | + <spring.boot.version>2.7.17</spring.boot.version> |
| 25 | </properties> | 25 | </properties> |
| 26 | 26 | ||
| 27 | <dependencyManagement> | 27 | <dependencyManagement> |
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/core/KeyValue.java
| @@ -4,6 +4,8 @@ import lombok.AllArgsConstructor; | @@ -4,6 +4,8 @@ import lombok.AllArgsConstructor; | ||
| 4 | import lombok.Data; | 4 | import lombok.Data; |
| 5 | import lombok.NoArgsConstructor; | 5 | import lombok.NoArgsConstructor; |
| 6 | 6 | ||
| 7 | +import java.io.Serializable; | ||
| 8 | + | ||
| 7 | /** | 9 | /** |
| 8 | * Key Value 的键值对 | 10 | * Key Value 的键值对 |
| 9 | * | 11 | * |
| @@ -12,7 +14,7 @@ import lombok.NoArgsConstructor; | @@ -12,7 +14,7 @@ import lombok.NoArgsConstructor; | ||
| 12 | @Data | 14 | @Data |
| 13 | @NoArgsConstructor | 15 | @NoArgsConstructor |
| 14 | @AllArgsConstructor | 16 | @AllArgsConstructor |
| 15 | -public class KeyValue<K, V> { | 17 | +public class KeyValue<K, V> implements Serializable { |
| 16 | 18 | ||
| 17 | private K key; | 19 | private K key; |
| 18 | private V value; | 20 | private V value; |
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
| @@ -8,6 +8,7 @@ import com.google.common.collect.ImmutableMap; | @@ -8,6 +8,7 @@ import com.google.common.collect.ImmutableMap; | ||
| 8 | import java.util.*; | 8 | import java.util.*; |
| 9 | import java.util.function.*; | 9 | import java.util.function.*; |
| 10 | import java.util.stream.Collectors; | 10 | import java.util.stream.Collectors; |
| 11 | +import java.util.stream.Stream; | ||
| 11 | 12 | ||
| 12 | import static java.util.Arrays.asList; | 13 | import static java.util.Arrays.asList; |
| 13 | 14 | ||
| @@ -271,4 +272,20 @@ public class CollectionUtils { | @@ -271,4 +272,20 @@ public class CollectionUtils { | ||
| 271 | return deptId == null ? Collections.emptyList() : Collections.singleton(deptId); | 272 | return deptId == null ? Collections.emptyList() : Collections.singleton(deptId); |
| 272 | } | 273 | } |
| 273 | 274 | ||
| 275 | + public static <T, U> List<U> convertListByFlatMap(Collection<T> from, | ||
| 276 | + Function<T, ? extends Stream<? extends U>> func) { | ||
| 277 | + if (CollUtil.isEmpty(from)) { | ||
| 278 | + return new ArrayList<>(); | ||
| 279 | + } | ||
| 280 | + return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toList()); | ||
| 281 | + } | ||
| 282 | + | ||
| 283 | + public static <T, U> Set<U> convertSetByFlatMap(Collection<T> from, | ||
| 284 | + Function<T, ? extends Stream<? extends U>> func) { | ||
| 285 | + if (CollUtil.isEmpty(from)) { | ||
| 286 | + return new HashSet<>(); | ||
| 287 | + } | ||
| 288 | + return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet()); | ||
| 289 | + } | ||
| 290 | + | ||
| 274 | } | 291 | } |
yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/config/YudaoErrorCodeConfiguration.java renamed to yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/config/YudaoErrorCodeAutoConfiguration.java
| @@ -21,7 +21,7 @@ import org.springframework.scheduling.annotation.EnableScheduling; | @@ -21,7 +21,7 @@ import org.springframework.scheduling.annotation.EnableScheduling; | ||
| 21 | @ConditionalOnProperty(prefix = "yudao.error-code", value = "enable", matchIfMissing = true) // 允许使用 yudao.error-code.enable=false 禁用访问日志 | 21 | @ConditionalOnProperty(prefix = "yudao.error-code", value = "enable", matchIfMissing = true) // 允许使用 yudao.error-code.enable=false 禁用访问日志 |
| 22 | @EnableConfigurationProperties(ErrorCodeProperties.class) | 22 | @EnableConfigurationProperties(ErrorCodeProperties.class) |
| 23 | @EnableScheduling // 开启调度任务的功能,因为 ErrorCodeRemoteLoader 通过定时刷新错误码 | 23 | @EnableScheduling // 开启调度任务的功能,因为 ErrorCodeRemoteLoader 通过定时刷新错误码 |
| 24 | -public class YudaoErrorCodeConfiguration { | 24 | +public class YudaoErrorCodeAutoConfiguration { |
| 25 | 25 | ||
| 26 | @Bean | 26 | @Bean |
| 27 | public ErrorCodeAutoGenerator errorCodeAutoGenerator(@Value("${spring.application.name}") String applicationName, | 27 | public ErrorCodeAutoGenerator errorCodeAutoGenerator(@Value("${spring.application.name}") String applicationName, |
yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
yudao-framework/yudao-spring-boot-starter-biz-tenant/pom.xml
| @@ -48,6 +48,22 @@ | @@ -48,6 +48,22 @@ | ||
| 48 | <dependency> | 48 | <dependency> |
| 49 | <groupId>cn.iocoder.boot</groupId> | 49 | <groupId>cn.iocoder.boot</groupId> |
| 50 | <artifactId>yudao-spring-boot-starter-mq</artifactId> | 50 | <artifactId>yudao-spring-boot-starter-mq</artifactId> |
| 51 | + <optional>true</optional> | ||
| 52 | + </dependency> | ||
| 53 | + <dependency> | ||
| 54 | + <groupId>org.springframework.kafka</groupId> | ||
| 55 | + <artifactId>spring-kafka</artifactId> | ||
| 56 | + <optional>true</optional> | ||
| 57 | + </dependency> | ||
| 58 | + <dependency> | ||
| 59 | + <groupId>org.springframework.amqp</groupId> | ||
| 60 | + <artifactId>spring-rabbit</artifactId> | ||
| 61 | + <optional>true</optional> | ||
| 62 | + </dependency> | ||
| 63 | + <dependency> | ||
| 64 | + <groupId>org.apache.rocketmq</groupId> | ||
| 65 | + <artifactId>rocketmq-spring-boot-starter</artifactId> | ||
| 66 | + <optional>true</optional> | ||
| 51 | </dependency> | 67 | </dependency> |
| 52 | 68 | ||
| 53 | <!-- Test 测试相关 --> | 69 | <!-- Test 测试相关 --> |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
| @@ -6,7 +6,9 @@ import cn.iocoder.yudao.framework.redis.config.YudaoCacheProperties; | @@ -6,7 +6,9 @@ import cn.iocoder.yudao.framework.redis.config.YudaoCacheProperties; | ||
| 6 | import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnoreAspect; | 6 | import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnoreAspect; |
| 7 | import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor; | 7 | import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor; |
| 8 | import cn.iocoder.yudao.framework.tenant.core.job.TenantJobAspect; | 8 | import cn.iocoder.yudao.framework.tenant.core.job.TenantJobAspect; |
| 9 | -import cn.iocoder.yudao.framework.tenant.core.mq.TenantRedisMessageInterceptor; | 9 | +import cn.iocoder.yudao.framework.tenant.core.mq.rabbitmq.TenantRabbitMQInitializer; |
| 10 | +import cn.iocoder.yudao.framework.tenant.core.mq.redis.TenantRedisMessageInterceptor; | ||
| 11 | +import cn.iocoder.yudao.framework.tenant.core.mq.rocketmq.TenantRocketMQInitializer; | ||
| 10 | import cn.iocoder.yudao.framework.tenant.core.redis.TenantRedisCacheManager; | 12 | import cn.iocoder.yudao.framework.tenant.core.redis.TenantRedisCacheManager; |
| 11 | import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter; | 13 | import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter; |
| 12 | import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService; | 14 | import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService; |
| @@ -18,6 +20,7 @@ import cn.iocoder.yudao.module.system.api.tenant.TenantApi; | @@ -18,6 +20,7 @@ import cn.iocoder.yudao.module.system.api.tenant.TenantApi; | ||
| 18 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; | 20 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
| 19 | import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; | 21 | import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; |
| 20 | import org.springframework.boot.autoconfigure.AutoConfiguration; | 22 | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| 23 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | ||
| 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | 24 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| 22 | import org.springframework.boot.context.properties.EnableConfigurationProperties; | 25 | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| 23 | import org.springframework.boot.web.servlet.FilterRegistrationBean; | 26 | import org.springframework.boot.web.servlet.FilterRegistrationBean; |
| @@ -92,6 +95,18 @@ public class YudaoTenantAutoConfiguration { | @@ -92,6 +95,18 @@ public class YudaoTenantAutoConfiguration { | ||
| 92 | return new TenantRedisMessageInterceptor(); | 95 | return new TenantRedisMessageInterceptor(); |
| 93 | } | 96 | } |
| 94 | 97 | ||
| 98 | + @Bean | ||
| 99 | + @ConditionalOnClass(name = "org.springframework.amqp.rabbit.core.RabbitTemplate") | ||
| 100 | + public TenantRabbitMQInitializer tenantRabbitMQInitializer() { | ||
| 101 | + return new TenantRabbitMQInitializer(); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + @Bean | ||
| 105 | + @ConditionalOnClass(name = "org.apache.rocketmq.spring.core.RocketMQTemplate") | ||
| 106 | + public TenantRocketMQInitializer tenantRocketMQInitializer() { | ||
| 107 | + return new TenantRocketMQInitializer(); | ||
| 108 | + } | ||
| 109 | + | ||
| 95 | // ========== Job ========== | 110 | // ========== Job ========== |
| 96 | 111 | ||
| 97 | @Bean | 112 | @Bean |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/kafka/TenantKafkaEnvironmentPostProcessor.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.tenant.core.mq.kafka; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.util.StrUtil; | ||
| 4 | +import lombok.extern.slf4j.Slf4j; | ||
| 5 | +import org.springframework.boot.SpringApplication; | ||
| 6 | +import org.springframework.boot.env.EnvironmentPostProcessor; | ||
| 7 | +import org.springframework.core.env.ConfigurableEnvironment; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * 多租户的 Kafka 的 {@link EnvironmentPostProcessor} 实现类 | ||
| 11 | + * | ||
| 12 | + * Kafka Producer 发送消息时,增加 {@link TenantKafkaProducerInterceptor} 拦截器 | ||
| 13 | + * | ||
| 14 | + * @author 芋道源码 | ||
| 15 | + */ | ||
| 16 | +@Slf4j | ||
| 17 | +public class TenantKafkaEnvironmentPostProcessor implements EnvironmentPostProcessor { | ||
| 18 | + | ||
| 19 | + private static final String PROPERTY_KEY_INTERCEPTOR_CLASSES = "spring.kafka.producer.properties.interceptor.classes"; | ||
| 20 | + | ||
| 21 | + @Override | ||
| 22 | + public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { | ||
| 23 | + // 添加 TenantKafkaProducerInterceptor 拦截器 | ||
| 24 | + try { | ||
| 25 | + String value = environment.getProperty(PROPERTY_KEY_INTERCEPTOR_CLASSES); | ||
| 26 | + if (StrUtil.isEmpty(value)) { | ||
| 27 | + value = TenantKafkaProducerInterceptor.class.getName(); | ||
| 28 | + } else { | ||
| 29 | + value += "," + TenantKafkaProducerInterceptor.class.getName(); | ||
| 30 | + } | ||
| 31 | + environment.getSystemProperties().put(PROPERTY_KEY_INTERCEPTOR_CLASSES, value); | ||
| 32 | + } catch (NoClassDefFoundError ignore) { | ||
| 33 | + // 如果触发 NoClassDefFoundError 异常,说明 TenantKafkaProducerInterceptor 类不存在,即没引入 kafka-spring 依赖 | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | +} |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/kafka/TenantKafkaProducerInterceptor.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.tenant.core.mq.kafka; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.util.ReflectUtil; | ||
| 4 | +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | ||
| 5 | +import org.apache.kafka.clients.producer.ProducerInterceptor; | ||
| 6 | +import org.apache.kafka.clients.producer.ProducerRecord; | ||
| 7 | +import org.apache.kafka.clients.producer.RecordMetadata; | ||
| 8 | +import org.apache.kafka.common.header.Headers; | ||
| 9 | +import org.springframework.messaging.handler.invocation.InvocableHandlerMethod; | ||
| 10 | + | ||
| 11 | +import java.util.Map; | ||
| 12 | + | ||
| 13 | +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * Kafka 消息队列的多租户 {@link ProducerInterceptor} 实现类 | ||
| 17 | + * | ||
| 18 | + * 1. Producer 发送消息时,将 {@link TenantContextHolder} 租户编号,添加到消息的 Header 中 | ||
| 19 | + * 2. Consumer 消费消息时,将消息的 Header 的租户编号,添加到 {@link TenantContextHolder} 中,通过 {@link InvocableHandlerMethod} 实现 | ||
| 20 | + * | ||
| 21 | + * @author 芋道源码 | ||
| 22 | + */ | ||
| 23 | +public class TenantKafkaProducerInterceptor implements ProducerInterceptor<Object, Object> { | ||
| 24 | + | ||
| 25 | + @Override | ||
| 26 | + public ProducerRecord<Object, Object> onSend(ProducerRecord<Object, Object> record) { | ||
| 27 | + Long tenantId = TenantContextHolder.getTenantId(); | ||
| 28 | + if (tenantId != null) { | ||
| 29 | + Headers headers = (Headers) ReflectUtil.getFieldValue(record, "headers"); // private 属性,没有 get 方法,智能反射 | ||
| 30 | + headers.add(HEADER_TENANT_ID, tenantId.toString().getBytes()); | ||
| 31 | + } | ||
| 32 | + return record; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + @Override | ||
| 36 | + public void onAcknowledgement(RecordMetadata metadata, Exception exception) { | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + @Override | ||
| 40 | + public void close() { | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + @Override | ||
| 44 | + public void configure(Map<String, ?> configs) { | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | +} |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rabbitmq/TenantRabbitMQInitializer.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.tenant.core.mq.rabbitmq; | ||
| 2 | + | ||
| 3 | +import org.springframework.amqp.rabbit.core.RabbitTemplate; | ||
| 4 | +import org.springframework.beans.BeansException; | ||
| 5 | +import org.springframework.beans.factory.config.BeanPostProcessor; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 多租户的 RabbitMQ 初始化器 | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +public class TenantRabbitMQInitializer implements BeanPostProcessor { | ||
| 13 | + | ||
| 14 | + @Override | ||
| 15 | + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { | ||
| 16 | + if (bean instanceof RabbitTemplate) { | ||
| 17 | + RabbitTemplate rabbitTemplate = (RabbitTemplate) bean; | ||
| 18 | + rabbitTemplate.addBeforePublishPostProcessors(new TenantRabbitMQMessagePostProcessor()); | ||
| 19 | + } | ||
| 20 | + return bean; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | +} | ||
| 0 | \ No newline at end of file | 24 | \ No newline at end of file |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rabbitmq/TenantRabbitMQMessagePostProcessor.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.tenant.core.mq.rabbitmq; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | ||
| 4 | +import org.apache.kafka.clients.producer.ProducerInterceptor; | ||
| 5 | +import org.springframework.amqp.AmqpException; | ||
| 6 | +import org.springframework.amqp.core.Message; | ||
| 7 | +import org.springframework.amqp.core.MessagePostProcessor; | ||
| 8 | +import org.springframework.messaging.handler.invocation.InvocableHandlerMethod; | ||
| 9 | + | ||
| 10 | +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * RabbitMQ 消息队列的多租户 {@link ProducerInterceptor} 实现类 | ||
| 14 | + * | ||
| 15 | + * 1. Producer 发送消息时,将 {@link TenantContextHolder} 租户编号,添加到消息的 Header 中 | ||
| 16 | + * 2. Consumer 消费消息时,将消息的 Header 的租户编号,添加到 {@link TenantContextHolder} 中,通过 {@link InvocableHandlerMethod} 实现 | ||
| 17 | + * | ||
| 18 | + * @author 芋道源码 | ||
| 19 | + */ | ||
| 20 | +public class TenantRabbitMQMessagePostProcessor implements MessagePostProcessor { | ||
| 21 | + | ||
| 22 | + @Override | ||
| 23 | + public Message postProcessMessage(Message message) throws AmqpException { | ||
| 24 | + Long tenantId = TenantContextHolder.getTenantId(); | ||
| 25 | + if (tenantId != null) { | ||
| 26 | + message.getMessageProperties().getHeaders().put(HEADER_TENANT_ID, tenantId); | ||
| 27 | + } | ||
| 28 | + return message; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | +} |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/TenantRedisMessageInterceptor.java renamed to yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/redis/TenantRedisMessageInterceptor.java
| 1 | -package cn.iocoder.yudao.framework.tenant.core.mq; | 1 | +package cn.iocoder.yudao.framework.tenant.core.mq.redis; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.StrUtil; | 3 | import cn.hutool.core.util.StrUtil; |
| 4 | -import cn.iocoder.yudao.framework.mq.core.interceptor.RedisMessageInterceptor; | ||
| 5 | -import cn.iocoder.yudao.framework.mq.core.message.AbstractRedisMessage; | 4 | +import cn.iocoder.yudao.framework.mq.redis.core.interceptor.RedisMessageInterceptor; |
| 5 | +import cn.iocoder.yudao.framework.mq.redis.core.message.AbstractRedisMessage; | ||
| 6 | import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | 6 | import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; |
| 7 | 7 | ||
| 8 | import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; | 8 | import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rocketmq/TenantRocketMQConsumeMessageHook.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.tenant.core.mq.rocketmq; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.lang.Assert; | ||
| 4 | +import cn.hutool.core.util.StrUtil; | ||
| 5 | +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | ||
| 6 | +import org.apache.rocketmq.client.hook.ConsumeMessageContext; | ||
| 7 | +import org.apache.rocketmq.client.hook.ConsumeMessageHook; | ||
| 8 | +import org.apache.rocketmq.common.message.MessageExt; | ||
| 9 | +import org.springframework.messaging.handler.invocation.InvocableHandlerMethod; | ||
| 10 | + | ||
| 11 | +import java.util.List; | ||
| 12 | + | ||
| 13 | +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * RocketMQ 消息队列的多租户 {@link ConsumeMessageHook} 实现类 | ||
| 17 | + * | ||
| 18 | + * Consumer 消费消息时,将消息的 Header 的租户编号,添加到 {@link TenantContextHolder} 中,通过 {@link InvocableHandlerMethod} 实现 | ||
| 19 | + * | ||
| 20 | + * @author 芋道源码 | ||
| 21 | + */ | ||
| 22 | +public class TenantRocketMQConsumeMessageHook implements ConsumeMessageHook { | ||
| 23 | + | ||
| 24 | + @Override | ||
| 25 | + public String hookName() { | ||
| 26 | + return getClass().getSimpleName(); | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + @Override | ||
| 30 | + public void consumeMessageBefore(ConsumeMessageContext context) { | ||
| 31 | + // 校验,消息必须是单条,不然设置租户可能不正确 | ||
| 32 | + List<MessageExt> messages = context.getMsgList(); | ||
| 33 | + Assert.isTrue(messages.size() == 1, "消息条数({})不正确", messages.size()); | ||
| 34 | + // 设置租户编号 | ||
| 35 | + String tenantId = messages.get(0).getUserProperty(HEADER_TENANT_ID); | ||
| 36 | + if (StrUtil.isNotEmpty(tenantId)) { | ||
| 37 | + TenantContextHolder.setTenantId(Long.parseLong(tenantId)); | ||
| 38 | + } | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + @Override | ||
| 42 | + public void consumeMessageAfter(ConsumeMessageContext context) { | ||
| 43 | + TenantContextHolder.clear(); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | +} |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rocketmq/TenantRocketMQInitializer.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.tenant.core.mq.rocketmq; | ||
| 2 | + | ||
| 3 | +import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; | ||
| 4 | +import org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl; | ||
| 5 | +import org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl; | ||
| 6 | +import org.apache.rocketmq.client.producer.DefaultMQProducer; | ||
| 7 | +import org.apache.rocketmq.spring.core.RocketMQTemplate; | ||
| 8 | +import org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer; | ||
| 9 | +import org.springframework.beans.BeansException; | ||
| 10 | +import org.springframework.beans.factory.config.BeanPostProcessor; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * 多租户的 RocketMQ 初始化器 | ||
| 14 | + * | ||
| 15 | + * @author 芋道源码 | ||
| 16 | + */ | ||
| 17 | +public class TenantRocketMQInitializer implements BeanPostProcessor { | ||
| 18 | + | ||
| 19 | + @Override | ||
| 20 | + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { | ||
| 21 | + if (bean instanceof DefaultRocketMQListenerContainer) { | ||
| 22 | + DefaultRocketMQListenerContainer container = (DefaultRocketMQListenerContainer) bean; | ||
| 23 | + initTenantConsumer(container.getConsumer()); | ||
| 24 | + } else if (bean instanceof RocketMQTemplate) { | ||
| 25 | + RocketMQTemplate template = (RocketMQTemplate) bean; | ||
| 26 | + initTenantProducer(template.getProducer()); | ||
| 27 | + } | ||
| 28 | + return bean; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + private void initTenantProducer(DefaultMQProducer producer) { | ||
| 32 | + if (producer == null) { | ||
| 33 | + return; | ||
| 34 | + } | ||
| 35 | + DefaultMQProducerImpl producerImpl = producer.getDefaultMQProducerImpl(); | ||
| 36 | + if (producerImpl == null) { | ||
| 37 | + return; | ||
| 38 | + } | ||
| 39 | + producerImpl.registerSendMessageHook(new TenantRocketMQSendMessageHook()); | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + private void initTenantConsumer(DefaultMQPushConsumer consumer) { | ||
| 43 | + if (consumer == null) { | ||
| 44 | + return; | ||
| 45 | + } | ||
| 46 | + DefaultMQPushConsumerImpl consumerImpl = consumer.getDefaultMQPushConsumerImpl(); | ||
| 47 | + if (consumerImpl == null) { | ||
| 48 | + return; | ||
| 49 | + } | ||
| 50 | + consumerImpl.registerConsumeMessageHook(new TenantRocketMQConsumeMessageHook()); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | +} | ||
| 0 | \ No newline at end of file | 54 | \ No newline at end of file |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/mq/rocketmq/TenantRocketMQSendMessageHook.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.tenant.core.mq.rocketmq; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | ||
| 4 | +import org.apache.rocketmq.client.hook.SendMessageContext; | ||
| 5 | +import org.apache.rocketmq.client.hook.SendMessageHook; | ||
| 6 | + | ||
| 7 | +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * RocketMQ 消息队列的多租户 {@link SendMessageHook} 实现类 | ||
| 11 | + * | ||
| 12 | + * Producer 发送消息时,将 {@link TenantContextHolder} 租户编号,添加到消息的 Header 中 | ||
| 13 | + * | ||
| 14 | + * @author 芋道源码 | ||
| 15 | + */ | ||
| 16 | +public class TenantRocketMQSendMessageHook implements SendMessageHook { | ||
| 17 | + | ||
| 18 | + @Override | ||
| 19 | + public String hookName() { | ||
| 20 | + return getClass().getSimpleName(); | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + @Override | ||
| 24 | + public void sendMessageBefore(SendMessageContext sendMessageContext) { | ||
| 25 | + Long tenantId = TenantContextHolder.getTenantId(); | ||
| 26 | + if (tenantId == null) { | ||
| 27 | + return; | ||
| 28 | + } | ||
| 29 | + sendMessageContext.getMessage().putUserProperty(HEADER_TENANT_ID, tenantId.toString()); | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + @Override | ||
| 33 | + public void sendMessageAfter(SendMessageContext sendMessageContext) { | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | +} |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright 2002-2021 the original author or authors. | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * https://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.springframework.messaging.handler.invocation; | ||
| 18 | + | ||
| 19 | +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | ||
| 20 | +import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; | ||
| 21 | +import org.springframework.core.DefaultParameterNameDiscoverer; | ||
| 22 | +import org.springframework.core.MethodParameter; | ||
| 23 | +import org.springframework.core.ParameterNameDiscoverer; | ||
| 24 | +import org.springframework.core.ResolvableType; | ||
| 25 | +import org.springframework.lang.Nullable; | ||
| 26 | +import org.springframework.messaging.Message; | ||
| 27 | +import org.springframework.messaging.handler.HandlerMethod; | ||
| 28 | +import org.springframework.util.ObjectUtils; | ||
| 29 | + | ||
| 30 | +import java.lang.reflect.InvocationTargetException; | ||
| 31 | +import java.lang.reflect.Method; | ||
| 32 | +import java.lang.reflect.Type; | ||
| 33 | +import java.util.Arrays; | ||
| 34 | + | ||
| 35 | +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; | ||
| 36 | + | ||
| 37 | +/** | ||
| 38 | + * Extension of {@link HandlerMethod} that invokes the underlying method with | ||
| 39 | + * argument values resolved from the current HTTP request through a list of | ||
| 40 | + * {@link HandlerMethodArgumentResolver}. | ||
| 41 | + * | ||
| 42 | + * 针对 rabbitmq-spring 和 kafka-spring,不存在合适的拓展点,可以实现 Consumer 消费前,读取 Header 中的 tenant-id 设置到 {@link TenantContextHolder} 中 | ||
| 43 | + * TODO 芋艿:持续跟进,看看有没新的拓展点 | ||
| 44 | + * | ||
| 45 | + * @author Rossen Stoyanchev | ||
| 46 | + * @author Juergen Hoeller | ||
| 47 | + * @since 4.0 | ||
| 48 | + */ | ||
| 49 | +public class InvocableHandlerMethod extends HandlerMethod { | ||
| 50 | + | ||
| 51 | + private static final Object[] EMPTY_ARGS = new Object[0]; | ||
| 52 | + | ||
| 53 | + private HandlerMethodArgumentResolverComposite resolvers = new HandlerMethodArgumentResolverComposite(); | ||
| 54 | + | ||
| 55 | + private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer(); | ||
| 56 | + | ||
| 57 | + /** | ||
| 58 | + * Create an instance from a {@code HandlerMethod}. | ||
| 59 | + */ | ||
| 60 | + public InvocableHandlerMethod(HandlerMethod handlerMethod) { | ||
| 61 | + super(handlerMethod); | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + /** | ||
| 65 | + * Create an instance from a bean instance and a method. | ||
| 66 | + */ | ||
| 67 | + public InvocableHandlerMethod(Object bean, Method method) { | ||
| 68 | + super(bean, method); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * Construct a new handler method with the given bean instance, method name and parameters. | ||
| 73 | + * @param bean the object bean | ||
| 74 | + * @param methodName the method name | ||
| 75 | + * @param parameterTypes the method parameter types | ||
| 76 | + * @throws NoSuchMethodException when the method cannot be found | ||
| 77 | + */ | ||
| 78 | + public InvocableHandlerMethod(Object bean, String methodName, Class<?>... parameterTypes) | ||
| 79 | + throws NoSuchMethodException { | ||
| 80 | + | ||
| 81 | + super(bean, methodName, parameterTypes); | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + /** | ||
| 85 | + * Set {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers} to use for resolving method argument values. | ||
| 86 | + */ | ||
| 87 | + public void setMessageMethodArgumentResolvers(HandlerMethodArgumentResolverComposite argumentResolvers) { | ||
| 88 | + this.resolvers = argumentResolvers; | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + /** | ||
| 92 | + * Set the ParameterNameDiscoverer for resolving parameter names when needed | ||
| 93 | + * (e.g. default request attribute name). | ||
| 94 | + * <p>Default is a {@link DefaultParameterNameDiscoverer}. | ||
| 95 | + */ | ||
| 96 | + public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) { | ||
| 97 | + this.parameterNameDiscoverer = parameterNameDiscoverer; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + /** | ||
| 101 | + * Invoke the method after resolving its argument values in the context of the given message. | ||
| 102 | + * <p>Argument values are commonly resolved through | ||
| 103 | + * {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolvers}. | ||
| 104 | + * The {@code providedArgs} parameter however may supply argument values to be used directly, | ||
| 105 | + * i.e. without argument resolution. | ||
| 106 | + * <p>Delegates to {@link #getMethodArgumentValues} and calls {@link #doInvoke} with the | ||
| 107 | + * resolved arguments. | ||
| 108 | + * @param message the current message being processed | ||
| 109 | + * @param providedArgs "given" arguments matched by type, not resolved | ||
| 110 | + * @return the raw value returned by the invoked method | ||
| 111 | + * @throws Exception raised if no suitable argument resolver can be found, | ||
| 112 | + * or if the method raised an exception | ||
| 113 | + * @see #getMethodArgumentValues | ||
| 114 | + * @see #doInvoke | ||
| 115 | + */ | ||
| 116 | + @Nullable | ||
| 117 | + public Object invoke(Message<?> message, Object... providedArgs) throws Exception { | ||
| 118 | + Object[] args = getMethodArgumentValues(message, providedArgs); | ||
| 119 | + if (logger.isTraceEnabled()) { | ||
| 120 | + logger.trace("Arguments: " + Arrays.toString(args)); | ||
| 121 | + } | ||
| 122 | + // 注意:如下是本类的改动点!!! | ||
| 123 | + // 情况一:无租户编号的情况 | ||
| 124 | + Long tenantId= parseTenantId(message); | ||
| 125 | + if (tenantId == null) { | ||
| 126 | + return doInvoke(args); | ||
| 127 | + } | ||
| 128 | + // 情况二:有租户的情况下 | ||
| 129 | + return TenantUtils.execute(tenantId, () -> doInvoke(args)); | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + private Long parseTenantId(Message<?> message) { | ||
| 133 | + Object tenantId = message.getHeaders().get(HEADER_TENANT_ID); | ||
| 134 | + if (tenantId == null) { | ||
| 135 | + return null; | ||
| 136 | + } | ||
| 137 | + if (tenantId instanceof Long) { | ||
| 138 | + return (Long) tenantId; | ||
| 139 | + } | ||
| 140 | + if (tenantId instanceof Number) { | ||
| 141 | + return ((Number) tenantId).longValue(); | ||
| 142 | + } | ||
| 143 | + if (tenantId instanceof String) { | ||
| 144 | + return Long.parseLong((String) tenantId); | ||
| 145 | + } | ||
| 146 | + if (tenantId instanceof byte[]) { | ||
| 147 | + return Long.parseLong(new String((byte[]) tenantId)); | ||
| 148 | + } | ||
| 149 | + throw new IllegalArgumentException("未知的数据类型:" + tenantId); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + /** | ||
| 153 | + * Get the method argument values for the current message, checking the provided | ||
| 154 | + * argument values and falling back to the configured argument resolvers. | ||
| 155 | + * <p>The resulting array will be passed into {@link #doInvoke}. | ||
| 156 | + * @since 5.1.2 | ||
| 157 | + */ | ||
| 158 | + protected Object[] getMethodArgumentValues(Message<?> message, Object... providedArgs) throws Exception { | ||
| 159 | + MethodParameter[] parameters = getMethodParameters(); | ||
| 160 | + if (ObjectUtils.isEmpty(parameters)) { | ||
| 161 | + return EMPTY_ARGS; | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + Object[] args = new Object[parameters.length]; | ||
| 165 | + for (int i = 0; i < parameters.length; i++) { | ||
| 166 | + MethodParameter parameter = parameters[i]; | ||
| 167 | + parameter.initParameterNameDiscovery(this.parameterNameDiscoverer); | ||
| 168 | + args[i] = findProvidedArgument(parameter, providedArgs); | ||
| 169 | + if (args[i] != null) { | ||
| 170 | + continue; | ||
| 171 | + } | ||
| 172 | + if (!this.resolvers.supportsParameter(parameter)) { | ||
| 173 | + throw new MethodArgumentResolutionException( | ||
| 174 | + message, parameter, formatArgumentError(parameter, "No suitable resolver")); | ||
| 175 | + } | ||
| 176 | + try { | ||
| 177 | + args[i] = this.resolvers.resolveArgument(parameter, message); | ||
| 178 | + } | ||
| 179 | + catch (Exception ex) { | ||
| 180 | + // Leave stack trace for later, exception may actually be resolved and handled... | ||
| 181 | + if (logger.isDebugEnabled()) { | ||
| 182 | + String exMsg = ex.getMessage(); | ||
| 183 | + if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) { | ||
| 184 | + logger.debug(formatArgumentError(parameter, exMsg)); | ||
| 185 | + } | ||
| 186 | + } | ||
| 187 | + throw ex; | ||
| 188 | + } | ||
| 189 | + } | ||
| 190 | + return args; | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + /** | ||
| 194 | + * Invoke the handler method with the given argument values. | ||
| 195 | + */ | ||
| 196 | + @Nullable | ||
| 197 | + protected Object doInvoke(Object... args) throws Exception { | ||
| 198 | + try { | ||
| 199 | + return getBridgedMethod().invoke(getBean(), args); | ||
| 200 | + } | ||
| 201 | + catch (IllegalArgumentException ex) { | ||
| 202 | + assertTargetBean(getBridgedMethod(), getBean(), args); | ||
| 203 | + String text = (ex.getMessage() != null ? ex.getMessage() : "Illegal argument"); | ||
| 204 | + throw new IllegalStateException(formatInvokeError(text, args), ex); | ||
| 205 | + } | ||
| 206 | + catch (InvocationTargetException ex) { | ||
| 207 | + // Unwrap for HandlerExceptionResolvers ... | ||
| 208 | + Throwable targetException = ex.getTargetException(); | ||
| 209 | + if (targetException instanceof RuntimeException) { | ||
| 210 | + throw (RuntimeException) targetException; | ||
| 211 | + } | ||
| 212 | + else if (targetException instanceof Error) { | ||
| 213 | + throw (Error) targetException; | ||
| 214 | + } | ||
| 215 | + else if (targetException instanceof Exception) { | ||
| 216 | + throw (Exception) targetException; | ||
| 217 | + } | ||
| 218 | + else { | ||
| 219 | + throw new IllegalStateException(formatInvokeError("Invocation failure", args), targetException); | ||
| 220 | + } | ||
| 221 | + } | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + MethodParameter getAsyncReturnValueType(@Nullable Object returnValue) { | ||
| 225 | + return new AsyncResultMethodParameter(returnValue); | ||
| 226 | + } | ||
| 227 | + | ||
| 228 | + private class AsyncResultMethodParameter extends HandlerMethodParameter { | ||
| 229 | + | ||
| 230 | + @Nullable | ||
| 231 | + private final Object returnValue; | ||
| 232 | + | ||
| 233 | + private final ResolvableType returnType; | ||
| 234 | + | ||
| 235 | + public AsyncResultMethodParameter(@Nullable Object returnValue) { | ||
| 236 | + super(-1); | ||
| 237 | + this.returnValue = returnValue; | ||
| 238 | + this.returnType = ResolvableType.forType(super.getGenericParameterType()).getGeneric(); | ||
| 239 | + } | ||
| 240 | + | ||
| 241 | + protected AsyncResultMethodParameter(AsyncResultMethodParameter original) { | ||
| 242 | + super(original); | ||
| 243 | + this.returnValue = original.returnValue; | ||
| 244 | + this.returnType = original.returnType; | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | + @Override | ||
| 248 | + public Class<?> getParameterType() { | ||
| 249 | + if (this.returnValue != null) { | ||
| 250 | + return this.returnValue.getClass(); | ||
| 251 | + } | ||
| 252 | + if (!ResolvableType.NONE.equals(this.returnType)) { | ||
| 253 | + return this.returnType.toClass(); | ||
| 254 | + } | ||
| 255 | + return super.getParameterType(); | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + @Override | ||
| 259 | + public Type getGenericParameterType() { | ||
| 260 | + return this.returnType.getType(); | ||
| 261 | + } | ||
| 262 | + | ||
| 263 | + @Override | ||
| 264 | + public AsyncResultMethodParameter clone() { | ||
| 265 | + return new AsyncResultMethodParameter(this); | ||
| 266 | + } | ||
| 267 | + } | ||
| 268 | + | ||
| 269 | +} |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/resources/META-INF/spring.factories
0 → 100644
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/test/java/cn/iocoder/yudao/framework/tenant/core/job/TestJob.java deleted
| 1 | -package cn.iocoder.yudao.framework.tenant.core.job; | ||
| 2 | - | ||
| 3 | -import cn.hutool.core.collection.CollUtil; | ||
| 4 | -import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; | ||
| 5 | -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | ||
| 6 | -import org.springframework.stereotype.Component; | ||
| 7 | - | ||
| 8 | -import java.util.List; | ||
| 9 | -import java.util.concurrent.CopyOnWriteArrayList; | ||
| 10 | - | ||
| 11 | -@Component | ||
| 12 | -public class TestJob implements JobHandler { | ||
| 13 | - | ||
| 14 | - private final List<Long> tenantIds = new CopyOnWriteArrayList<>(); | ||
| 15 | - | ||
| 16 | - @Override | ||
| 17 | - @TenantJob // 标记多租户 | ||
| 18 | - public String execute(String param) throws Exception { | ||
| 19 | - tenantIds.add(TenantContextHolder.getTenantId()); | ||
| 20 | - return "success"; | ||
| 21 | - } | ||
| 22 | - | ||
| 23 | - public List<Long> getTenantIds() { | ||
| 24 | - CollUtil.sort(tenantIds, Long::compareTo); | ||
| 25 | - return tenantIds; | ||
| 26 | - } | ||
| 27 | - | ||
| 28 | -} |
yudao-framework/yudao-spring-boot-starter-mq/pom.xml
| @@ -12,7 +12,7 @@ | @@ -12,7 +12,7 @@ | ||
| 12 | <packaging>jar</packaging> | 12 | <packaging>jar</packaging> |
| 13 | 13 | ||
| 14 | <name>${project.artifactId}</name> | 14 | <name>${project.artifactId}</name> |
| 15 | - <description>消息队列,基于 Redis Pub/Sub 实现广播消费,基于 Stream 实现集群消费</description> | 15 | + <description>消息队列,支持 Redis、RocketMQ、RabbitMQ、Kafka 四种</description> |
| 16 | <url>https://github.com/YunaiV/ruoyi-vue-pro</url> | 16 | <url>https://github.com/YunaiV/ruoyi-vue-pro</url> |
| 17 | 17 | ||
| 18 | <dependencies> | 18 | <dependencies> |
| @@ -21,6 +21,23 @@ | @@ -21,6 +21,23 @@ | ||
| 21 | <groupId>cn.iocoder.boot</groupId> | 21 | <groupId>cn.iocoder.boot</groupId> |
| 22 | <artifactId>yudao-spring-boot-starter-redis</artifactId> | 22 | <artifactId>yudao-spring-boot-starter-redis</artifactId> |
| 23 | </dependency> | 23 | </dependency> |
| 24 | + | ||
| 25 | + <!-- 消息队列相关 --> | ||
| 26 | + <dependency> | ||
| 27 | + <groupId>org.springframework.kafka</groupId> | ||
| 28 | + <artifactId>spring-kafka</artifactId> | ||
| 29 | + <optional>true</optional> | ||
| 30 | + </dependency> | ||
| 31 | + <dependency> | ||
| 32 | + <groupId>org.springframework.amqp</groupId> | ||
| 33 | + <artifactId>spring-rabbit</artifactId> | ||
| 34 | + <optional>true</optional> | ||
| 35 | + </dependency> | ||
| 36 | + <dependency> | ||
| 37 | + <groupId>org.apache.rocketmq</groupId> | ||
| 38 | + <artifactId>rocketmq-spring-boot-starter</artifactId> | ||
| 39 | + <optional>true</optional> | ||
| 40 | + </dependency> | ||
| 24 | </dependencies> | 41 | </dependencies> |
| 25 | 42 | ||
| 26 | -</project> | 43 | -</project> |
| 44 | +</project> | ||
| 27 | \ No newline at end of file | 45 | \ No newline at end of file |
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/package-info.java
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/rabbitmq/config/YudaoRabbitMQAutoConfiguration.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.mq.rabbitmq.config; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.util.ReflectUtil; | ||
| 4 | +import lombok.extern.slf4j.Slf4j; | ||
| 5 | +import org.springframework.amqp.utils.SerializationUtils; | ||
| 6 | +import org.springframework.boot.autoconfigure.AutoConfiguration; | ||
| 7 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | ||
| 8 | + | ||
| 9 | +import java.lang.reflect.Field; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * RabbitMQ 消息队列配置类 | ||
| 13 | + * | ||
| 14 | + * @author 芋道源码 | ||
| 15 | + */ | ||
| 16 | +@AutoConfiguration | ||
| 17 | +@Slf4j | ||
| 18 | +@ConditionalOnClass(name = "org.springframework.amqp.rabbit.core.RabbitTemplate") | ||
| 19 | +public class YudaoRabbitMQAutoConfiguration { | ||
| 20 | + | ||
| 21 | + static { | ||
| 22 | + // 强制设置 SerializationUtils 的 TRUST_ALL 为 true,避免 RabbitMQ Consumer 反序列化消息报错 | ||
| 23 | + // 为什么不通过设置 spring.amqp.deserialization.trust.all 呢?因为可能在 SerializationUtils static 初始化后 | ||
| 24 | + Field trustAllField = ReflectUtil.getField(SerializationUtils.class, "TRUST_ALL"); | ||
| 25 | + ReflectUtil.removeFinalModify(trustAllField); | ||
| 26 | + ReflectUtil.setFieldValue(SerializationUtils.class, trustAllField, true); | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | +} |
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/rabbitmq/core/package-info.java
0 → 100644
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/rabbitmq/package-info.java
0 → 100644
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/config/YudaoMQAutoConfiguration.java renamed to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/config/YudaoRedisMQAutoConfiguration.java
| 1 | -package cn.iocoder.yudao.framework.mq.config; | 1 | +package cn.iocoder.yudao.framework.mq.redis.config; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.map.MapUtil; | 3 | import cn.hutool.core.map.MapUtil; |
| 4 | import cn.hutool.core.util.StrUtil; | 4 | import cn.hutool.core.util.StrUtil; |
| 5 | import cn.hutool.system.SystemUtil; | 5 | import cn.hutool.system.SystemUtil; |
| 6 | import cn.iocoder.yudao.framework.common.enums.DocumentEnum; | 6 | import cn.iocoder.yudao.framework.common.enums.DocumentEnum; |
| 7 | -import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; | ||
| 8 | -import cn.iocoder.yudao.framework.mq.core.interceptor.RedisMessageInterceptor; | ||
| 9 | -import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener; | ||
| 10 | -import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; | ||
| 11 | -import cn.iocoder.yudao.framework.mq.job.RedisPendingMessageResendJob; | 7 | +import cn.iocoder.yudao.framework.mq.redis.core.RedisMQTemplate; |
| 8 | +import cn.iocoder.yudao.framework.mq.redis.core.interceptor.RedisMessageInterceptor; | ||
| 9 | +import cn.iocoder.yudao.framework.mq.redis.core.job.RedisPendingMessageResendJob; | ||
| 10 | +import cn.iocoder.yudao.framework.mq.redis.core.pubsub.AbstractRedisChannelMessageListener; | ||
| 11 | +import cn.iocoder.yudao.framework.mq.redis.core.stream.AbstractRedisStreamMessageListener; | ||
| 12 | import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; | 12 | import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; |
| 13 | import lombok.extern.slf4j.Slf4j; | 13 | import lombok.extern.slf4j.Slf4j; |
| 14 | import org.redisson.api.RedissonClient; | 14 | import org.redisson.api.RedissonClient; |
| 15 | import org.springframework.beans.factory.annotation.Value; | 15 | import org.springframework.beans.factory.annotation.Value; |
| 16 | import org.springframework.boot.autoconfigure.AutoConfiguration; | 16 | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| 17 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; | 17 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; |
| 18 | -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
| 19 | import org.springframework.context.annotation.Bean; | 18 | import org.springframework.context.annotation.Bean; |
| 20 | import org.springframework.data.redis.connection.RedisServerCommands; | 19 | import org.springframework.data.redis.connection.RedisServerCommands; |
| 21 | import org.springframework.data.redis.connection.stream.Consumer; | 20 | import org.springframework.data.redis.connection.stream.Consumer; |
| @@ -27,7 +26,6 @@ import org.springframework.data.redis.core.RedisTemplate; | @@ -27,7 +26,6 @@ import org.springframework.data.redis.core.RedisTemplate; | ||
| 27 | import org.springframework.data.redis.core.StringRedisTemplate; | 26 | import org.springframework.data.redis.core.StringRedisTemplate; |
| 28 | import org.springframework.data.redis.listener.ChannelTopic; | 27 | import org.springframework.data.redis.listener.ChannelTopic; |
| 29 | import org.springframework.data.redis.listener.RedisMessageListenerContainer; | 28 | import org.springframework.data.redis.listener.RedisMessageListenerContainer; |
| 30 | -import org.springframework.data.redis.stream.DefaultStreamMessageListenerContainerX; | ||
| 31 | import org.springframework.data.redis.stream.StreamMessageListenerContainer; | 29 | import org.springframework.data.redis.stream.StreamMessageListenerContainer; |
| 32 | import org.springframework.scheduling.annotation.EnableScheduling; | 30 | import org.springframework.scheduling.annotation.EnableScheduling; |
| 33 | 31 | ||
| @@ -42,7 +40,7 @@ import java.util.Properties; | @@ -42,7 +40,7 @@ import java.util.Properties; | ||
| 42 | @Slf4j | 40 | @Slf4j |
| 43 | @EnableScheduling // 启用定时任务,用于 RedisPendingMessageResendJob 重发消息 | 41 | @EnableScheduling // 启用定时任务,用于 RedisPendingMessageResendJob 重发消息 |
| 44 | @AutoConfiguration(after = YudaoRedisAutoConfiguration.class) | 42 | @AutoConfiguration(after = YudaoRedisAutoConfiguration.class) |
| 45 | -public class YudaoMQAutoConfiguration { | 43 | +public class YudaoRedisMQAutoConfiguration { |
| 46 | 44 | ||
| 47 | @Bean | 45 | @Bean |
| 48 | public RedisMQTemplate redisMQTemplate(StringRedisTemplate redisTemplate, | 46 | public RedisMQTemplate redisMQTemplate(StringRedisTemplate redisTemplate, |
| @@ -59,10 +57,9 @@ public class YudaoMQAutoConfiguration { | @@ -59,10 +57,9 @@ public class YudaoMQAutoConfiguration { | ||
| 59 | * 创建 Redis Pub/Sub 广播消费的容器 | 57 | * 创建 Redis Pub/Sub 广播消费的容器 |
| 60 | */ | 58 | */ |
| 61 | @Bean(initMethod = "start", destroyMethod = "stop") | 59 | @Bean(initMethod = "start", destroyMethod = "stop") |
| 62 | - @ConditionalOnBean(AbstractChannelMessageListener.class) // 只有 AbstractChannelMessageListener 存在的时候,才需要注册 Redis pubsub 监听 | ||
| 63 | - @ConditionalOnProperty(prefix = "yudao.mq.redis.pubsub", value = "enable", matchIfMissing = true) // 允许使用 yudao.mq.redis.pubsub.enable=false 禁用多租户 | 60 | + @ConditionalOnBean(AbstractRedisChannelMessageListener.class) // 只有 AbstractChannelMessageListener 存在的时候,才需要注册 Redis pubsub 监听 |
| 64 | public RedisMessageListenerContainer redisMessageListenerContainer( | 61 | public RedisMessageListenerContainer redisMessageListenerContainer( |
| 65 | - RedisMQTemplate redisMQTemplate, List<AbstractChannelMessageListener<?>> listeners) { | 62 | + RedisMQTemplate redisMQTemplate, List<AbstractRedisChannelMessageListener<?>> listeners) { |
| 66 | // 创建 RedisMessageListenerContainer 对象 | 63 | // 创建 RedisMessageListenerContainer 对象 |
| 67 | RedisMessageListenerContainer container = new RedisMessageListenerContainer(); | 64 | RedisMessageListenerContainer container = new RedisMessageListenerContainer(); |
| 68 | // 设置 RedisConnection 工厂。 | 65 | // 设置 RedisConnection 工厂。 |
| @@ -81,9 +78,8 @@ public class YudaoMQAutoConfiguration { | @@ -81,9 +78,8 @@ public class YudaoMQAutoConfiguration { | ||
| 81 | * 创建 Redis Stream 重新消费的任务 | 78 | * 创建 Redis Stream 重新消费的任务 |
| 82 | */ | 79 | */ |
| 83 | @Bean | 80 | @Bean |
| 84 | - @ConditionalOnBean(AbstractStreamMessageListener.class) // 只有 AbstractStreamMessageListener 存在的时候,才需要注册 Redis pubsub 监听 | ||
| 85 | - @ConditionalOnProperty(prefix = "yudao.mq.redis.stream", value = "enable", matchIfMissing = true) // 允许使用 yudao.mq.redis.stream.enable=false 禁用多租户 | ||
| 86 | - public RedisPendingMessageResendJob redisPendingMessageResendJob(List<AbstractStreamMessageListener<?>> listeners, | 81 | + @ConditionalOnBean(AbstractRedisStreamMessageListener.class) // 只有 AbstractStreamMessageListener 存在的时候,才需要注册 Redis pubsub 监听 |
| 82 | + public RedisPendingMessageResendJob redisPendingMessageResendJob(List<AbstractRedisStreamMessageListener<?>> listeners, | ||
| 87 | RedisMQTemplate redisTemplate, | 83 | RedisMQTemplate redisTemplate, |
| 88 | @Value("${spring.application.name}") String groupName, | 84 | @Value("${spring.application.name}") String groupName, |
| 89 | RedissonClient redissonClient) { | 85 | RedissonClient redissonClient) { |
| @@ -92,14 +88,13 @@ public class YudaoMQAutoConfiguration { | @@ -92,14 +88,13 @@ public class YudaoMQAutoConfiguration { | ||
| 92 | 88 | ||
| 93 | /** | 89 | /** |
| 94 | * 创建 Redis Stream 集群消费的容器 | 90 | * 创建 Redis Stream 集群消费的容器 |
| 95 | - * <p> | ||
| 96 | - * Redis Stream 的 xreadgroup 命令:https://www.geek-book.com/src/docs/redis/redis/redis.io/commands/xreadgroup.html | 91 | + * |
| 92 | + * 基础知识:<a href="https://www.geek-book.com/src/docs/redis/redis/redis.io/commands/xreadgroup.html">Redis Stream 的 xreadgroup 命令</a> | ||
| 97 | */ | 93 | */ |
| 98 | @Bean(initMethod = "start", destroyMethod = "stop") | 94 | @Bean(initMethod = "start", destroyMethod = "stop") |
| 99 | - @ConditionalOnBean(AbstractStreamMessageListener.class) // 只有 AbstractStreamMessageListener 存在的时候,才需要注册 Redis pubsub 监听 | ||
| 100 | - @ConditionalOnProperty(prefix = "yudao.mq.redis.stream", value = "enable", matchIfMissing = true) // 允许使用 yudao.mq.redis.stream.enable=false 禁用多租户 | 95 | + @ConditionalOnBean(AbstractRedisStreamMessageListener.class) // 只有 AbstractStreamMessageListener 存在的时候,才需要注册 Redis pubsub 监听 |
| 101 | public StreamMessageListenerContainer<String, ObjectRecord<String, String>> redisStreamMessageListenerContainer( | 96 | public StreamMessageListenerContainer<String, ObjectRecord<String, String>> redisStreamMessageListenerContainer( |
| 102 | - RedisMQTemplate redisMQTemplate, List<AbstractStreamMessageListener<?>> listeners) { | 97 | + RedisMQTemplate redisMQTemplate, List<AbstractRedisStreamMessageListener<?>> listeners) { |
| 103 | RedisTemplate<String, ?> redisTemplate = redisMQTemplate.getRedisTemplate(); | 98 | RedisTemplate<String, ?> redisTemplate = redisMQTemplate.getRedisTemplate(); |
| 104 | checkRedisVersion(redisTemplate); | 99 | checkRedisVersion(redisTemplate); |
| 105 | // 第一步,创建 StreamMessageListenerContainer 容器 | 100 | // 第一步,创建 StreamMessageListenerContainer 容器 |
| @@ -111,8 +106,7 @@ public class YudaoMQAutoConfiguration { | @@ -111,8 +106,7 @@ public class YudaoMQAutoConfiguration { | ||
| 111 | .build(); | 106 | .build(); |
| 112 | // 创建 container 对象 | 107 | // 创建 container 对象 |
| 113 | StreamMessageListenerContainer<String, ObjectRecord<String, String>> container = | 108 | StreamMessageListenerContainer<String, ObjectRecord<String, String>> container = |
| 114 | -// StreamMessageListenerContainer.create(redisTemplate.getRequiredConnectionFactory(), containerOptions); | ||
| 115 | - DefaultStreamMessageListenerContainerX.create(redisMQTemplate.getRedisTemplate().getRequiredConnectionFactory(), containerOptions); | 109 | + StreamMessageListenerContainer.create(redisMQTemplate.getRedisTemplate().getRequiredConnectionFactory(), containerOptions); |
| 116 | 110 | ||
| 117 | // 第二步,注册监听器,消费对应的 Stream 主题 | 111 | // 第二步,注册监听器,消费对应的 Stream 主题 |
| 118 | String consumerName = buildConsumerName(); | 112 | String consumerName = buildConsumerName(); |
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/RedisMQTemplate.java renamed to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/RedisMQTemplate.java
| 1 | -package cn.iocoder.yudao.framework.mq.core; | 1 | +package cn.iocoder.yudao.framework.mq.redis.core; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 3 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 4 | -import cn.iocoder.yudao.framework.mq.core.interceptor.RedisMessageInterceptor; | ||
| 5 | -import cn.iocoder.yudao.framework.mq.core.message.AbstractRedisMessage; | ||
| 6 | -import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessage; | ||
| 7 | -import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage; | 4 | +import cn.iocoder.yudao.framework.mq.redis.core.interceptor.RedisMessageInterceptor; |
| 5 | +import cn.iocoder.yudao.framework.mq.redis.core.message.AbstractRedisMessage; | ||
| 6 | +import cn.iocoder.yudao.framework.mq.redis.core.pubsub.AbstractRedisChannelMessage; | ||
| 7 | +import cn.iocoder.yudao.framework.mq.redis.core.stream.AbstractRedisStreamMessage; | ||
| 8 | import lombok.AllArgsConstructor; | 8 | import lombok.AllArgsConstructor; |
| 9 | import lombok.Getter; | 9 | import lombok.Getter; |
| 10 | import org.springframework.data.redis.connection.stream.RecordId; | 10 | import org.springframework.data.redis.connection.stream.RecordId; |
| @@ -35,7 +35,7 @@ public class RedisMQTemplate { | @@ -35,7 +35,7 @@ public class RedisMQTemplate { | ||
| 35 | * | 35 | * |
| 36 | * @param message 消息 | 36 | * @param message 消息 |
| 37 | */ | 37 | */ |
| 38 | - public <T extends AbstractChannelMessage> void send(T message) { | 38 | + public <T extends AbstractRedisChannelMessage> void send(T message) { |
| 39 | try { | 39 | try { |
| 40 | sendMessageBefore(message); | 40 | sendMessageBefore(message); |
| 41 | // 发送消息 | 41 | // 发送消息 |
| @@ -51,7 +51,7 @@ public class RedisMQTemplate { | @@ -51,7 +51,7 @@ public class RedisMQTemplate { | ||
| 51 | * @param message 消息 | 51 | * @param message 消息 |
| 52 | * @return 消息记录的编号对象 | 52 | * @return 消息记录的编号对象 |
| 53 | */ | 53 | */ |
| 54 | - public <T extends AbstractStreamMessage> RecordId send(T message) { | 54 | + public <T extends AbstractRedisStreamMessage> RecordId send(T message) { |
| 55 | try { | 55 | try { |
| 56 | sendMessageBefore(message); | 56 | sendMessageBefore(message); |
| 57 | // 发送消息 | 57 | // 发送消息 |
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/interceptor/RedisMessageInterceptor.java renamed to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/interceptor/RedisMessageInterceptor.java
| 1 | -package cn.iocoder.yudao.framework.mq.core.interceptor; | 1 | +package cn.iocoder.yudao.framework.mq.redis.core.interceptor; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.mq.core.message.AbstractRedisMessage; | 3 | +import cn.iocoder.yudao.framework.mq.redis.core.message.AbstractRedisMessage; |
| 4 | 4 | ||
| 5 | /** | 5 | /** |
| 6 | * {@link AbstractRedisMessage} 消息拦截器 | 6 | * {@link AbstractRedisMessage} 消息拦截器 |
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/job/RedisPendingMessageResendJob.java renamed to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/job/RedisPendingMessageResendJob.java
| 1 | -package cn.iocoder.yudao.framework.mq.job; | 1 | +package cn.iocoder.yudao.framework.mq.redis.core.job; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | -import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; | ||
| 5 | -import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; | 4 | +import cn.iocoder.yudao.framework.mq.redis.core.RedisMQTemplate; |
| 5 | +import cn.iocoder.yudao.framework.mq.redis.core.stream.AbstractRedisStreamMessageListener; | ||
| 6 | import lombok.AllArgsConstructor; | 6 | import lombok.AllArgsConstructor; |
| 7 | import lombok.extern.slf4j.Slf4j; | 7 | import lombok.extern.slf4j.Slf4j; |
| 8 | import org.redisson.api.RLock; | 8 | import org.redisson.api.RLock; |
| @@ -33,7 +33,7 @@ public class RedisPendingMessageResendJob { | @@ -33,7 +33,7 @@ public class RedisPendingMessageResendJob { | ||
| 33 | */ | 33 | */ |
| 34 | private static final int EXPIRE_TIME = 5 * 60; | 34 | private static final int EXPIRE_TIME = 5 * 60; |
| 35 | 35 | ||
| 36 | - private final List<AbstractStreamMessageListener<?>> listeners; | 36 | + private final List<AbstractRedisStreamMessageListener<?>> listeners; |
| 37 | private final RedisMQTemplate redisTemplate; | 37 | private final RedisMQTemplate redisTemplate; |
| 38 | private final String groupName; | 38 | private final String groupName; |
| 39 | private final RedissonClient redissonClient; | 39 | private final RedissonClient redissonClient; |
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/message/AbstractRedisMessage.java renamed to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/message/AbstractRedisMessage.java
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/pubsub/AbstractChannelMessage.java renamed to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/pubsub/AbstractRedisChannelMessage.java
| 1 | -package cn.iocoder.yudao.framework.mq.core.pubsub; | 1 | +package cn.iocoder.yudao.framework.mq.redis.core.pubsub; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.mq.core.message.AbstractRedisMessage; | 3 | +import cn.iocoder.yudao.framework.mq.redis.core.message.AbstractRedisMessage; |
| 4 | import com.fasterxml.jackson.annotation.JsonIgnore; | 4 | import com.fasterxml.jackson.annotation.JsonIgnore; |
| 5 | 5 | ||
| 6 | /** | 6 | /** |
| @@ -8,14 +8,16 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | @@ -8,14 +8,16 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | ||
| 8 | * | 8 | * |
| 9 | * @author 芋道源码 | 9 | * @author 芋道源码 |
| 10 | */ | 10 | */ |
| 11 | -public abstract class AbstractChannelMessage extends AbstractRedisMessage { | 11 | +public abstract class AbstractRedisChannelMessage extends AbstractRedisMessage { |
| 12 | 12 | ||
| 13 | /** | 13 | /** |
| 14 | - * 获得 Redis Channel | 14 | + * 获得 Redis Channel,默认使用类名 |
| 15 | * | 15 | * |
| 16 | * @return Channel | 16 | * @return Channel |
| 17 | */ | 17 | */ |
| 18 | @JsonIgnore // 避免序列化。原因是,Redis 发布 Channel 消息的时候,已经会指定。 | 18 | @JsonIgnore // 避免序列化。原因是,Redis 发布 Channel 消息的时候,已经会指定。 |
| 19 | - public abstract String getChannel(); | 19 | + public String getChannel() { |
| 20 | + return getClass().getSimpleName(); | ||
| 21 | + } | ||
| 20 | 22 | ||
| 21 | } | 23 | } |
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/pubsub/AbstractChannelMessageListener.java renamed to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/pubsub/AbstractRedisChannelMessageListener.java
| 1 | -package cn.iocoder.yudao.framework.mq.core.pubsub; | 1 | +package cn.iocoder.yudao.framework.mq.redis.core.pubsub; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.TypeUtil; | 3 | import cn.hutool.core.util.TypeUtil; |
| 4 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 4 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 5 | -import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; | ||
| 6 | -import cn.iocoder.yudao.framework.mq.core.interceptor.RedisMessageInterceptor; | ||
| 7 | -import cn.iocoder.yudao.framework.mq.core.message.AbstractRedisMessage; | 5 | +import cn.iocoder.yudao.framework.mq.redis.core.RedisMQTemplate; |
| 6 | +import cn.iocoder.yudao.framework.mq.redis.core.interceptor.RedisMessageInterceptor; | ||
| 7 | +import cn.iocoder.yudao.framework.mq.redis.core.message.AbstractRedisMessage; | ||
| 8 | import lombok.Setter; | 8 | import lombok.Setter; |
| 9 | import lombok.SneakyThrows; | 9 | import lombok.SneakyThrows; |
| 10 | import org.springframework.data.redis.connection.Message; | 10 | import org.springframework.data.redis.connection.Message; |
| @@ -20,7 +20,7 @@ import java.util.List; | @@ -20,7 +20,7 @@ import java.util.List; | ||
| 20 | * | 20 | * |
| 21 | * @author 芋道源码 | 21 | * @author 芋道源码 |
| 22 | */ | 22 | */ |
| 23 | -public abstract class AbstractChannelMessageListener<T extends AbstractChannelMessage> implements MessageListener { | 23 | +public abstract class AbstractRedisChannelMessageListener<T extends AbstractRedisChannelMessage> implements MessageListener { |
| 24 | 24 | ||
| 25 | /** | 25 | /** |
| 26 | * 消息类型 | 26 | * 消息类型 |
| @@ -37,7 +37,7 @@ public abstract class AbstractChannelMessageListener<T extends AbstractChannelMe | @@ -37,7 +37,7 @@ public abstract class AbstractChannelMessageListener<T extends AbstractChannelMe | ||
| 37 | private RedisMQTemplate redisMQTemplate; | 37 | private RedisMQTemplate redisMQTemplate; |
| 38 | 38 | ||
| 39 | @SneakyThrows | 39 | @SneakyThrows |
| 40 | - protected AbstractChannelMessageListener() { | 40 | + protected AbstractRedisChannelMessageListener() { |
| 41 | this.messageType = getMessageClass(); | 41 | this.messageType = getMessageClass(); |
| 42 | this.channel = messageType.getDeclaredConstructor().newInstance().getChannel(); | 42 | this.channel = messageType.getDeclaredConstructor().newInstance().getChannel(); |
| 43 | } | 43 | } |
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/stream/AbstractStreamMessage.java renamed to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/stream/AbstractRedisStreamMessage.java
| 1 | -package cn.iocoder.yudao.framework.mq.core.stream; | 1 | +package cn.iocoder.yudao.framework.mq.redis.core.stream; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.mq.core.message.AbstractRedisMessage; | 3 | +import cn.iocoder.yudao.framework.mq.redis.core.message.AbstractRedisMessage; |
| 4 | import com.fasterxml.jackson.annotation.JsonIgnore; | 4 | import com.fasterxml.jackson.annotation.JsonIgnore; |
| 5 | 5 | ||
| 6 | /** | 6 | /** |
| @@ -8,14 +8,16 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | @@ -8,14 +8,16 @@ import com.fasterxml.jackson.annotation.JsonIgnore; | ||
| 8 | * | 8 | * |
| 9 | * @author 芋道源码 | 9 | * @author 芋道源码 |
| 10 | */ | 10 | */ |
| 11 | -public abstract class AbstractStreamMessage extends AbstractRedisMessage { | 11 | +public abstract class AbstractRedisStreamMessage extends AbstractRedisMessage { |
| 12 | 12 | ||
| 13 | /** | 13 | /** |
| 14 | - * 获得 Redis Stream Key | 14 | + * 获得 Redis Stream Key,默认使用类名 |
| 15 | * | 15 | * |
| 16 | * @return Channel | 16 | * @return Channel |
| 17 | */ | 17 | */ |
| 18 | @JsonIgnore // 避免序列化 | 18 | @JsonIgnore // 避免序列化 |
| 19 | - public abstract String getStreamKey(); | 19 | + public String getStreamKey() { |
| 20 | + return getClass().getSimpleName(); | ||
| 21 | + } | ||
| 20 | 22 | ||
| 21 | } | 23 | } |
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/core/stream/AbstractStreamMessageListener.java renamed to yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/core/stream/AbstractRedisStreamMessageListener.java
| 1 | -package cn.iocoder.yudao.framework.mq.core.stream; | 1 | +package cn.iocoder.yudao.framework.mq.redis.core.stream; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.TypeUtil; | 3 | import cn.hutool.core.util.TypeUtil; |
| 4 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 4 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 5 | -import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; | ||
| 6 | -import cn.iocoder.yudao.framework.mq.core.interceptor.RedisMessageInterceptor; | ||
| 7 | -import cn.iocoder.yudao.framework.mq.core.message.AbstractRedisMessage; | 5 | +import cn.iocoder.yudao.framework.mq.redis.core.RedisMQTemplate; |
| 6 | +import cn.iocoder.yudao.framework.mq.redis.core.interceptor.RedisMessageInterceptor; | ||
| 7 | +import cn.iocoder.yudao.framework.mq.redis.core.message.AbstractRedisMessage; | ||
| 8 | import lombok.Getter; | 8 | import lombok.Getter; |
| 9 | import lombok.Setter; | 9 | import lombok.Setter; |
| 10 | import lombok.SneakyThrows; | 10 | import lombok.SneakyThrows; |
| @@ -22,7 +22,7 @@ import java.util.List; | @@ -22,7 +22,7 @@ import java.util.List; | ||
| 22 | * | 22 | * |
| 23 | * @author 芋道源码 | 23 | * @author 芋道源码 |
| 24 | */ | 24 | */ |
| 25 | -public abstract class AbstractStreamMessageListener<T extends AbstractStreamMessage> | 25 | +public abstract class AbstractRedisStreamMessageListener<T extends AbstractRedisStreamMessage> |
| 26 | implements StreamListener<String, ObjectRecord<String, String>> { | 26 | implements StreamListener<String, ObjectRecord<String, String>> { |
| 27 | 27 | ||
| 28 | /** | 28 | /** |
| @@ -48,7 +48,7 @@ public abstract class AbstractStreamMessageListener<T extends AbstractStreamMess | @@ -48,7 +48,7 @@ public abstract class AbstractStreamMessageListener<T extends AbstractStreamMess | ||
| 48 | private RedisMQTemplate redisMQTemplate; | 48 | private RedisMQTemplate redisMQTemplate; |
| 49 | 49 | ||
| 50 | @SneakyThrows | 50 | @SneakyThrows |
| 51 | - protected AbstractStreamMessageListener() { | 51 | + protected AbstractRedisStreamMessageListener() { |
| 52 | this.messageType = getMessageClass(); | 52 | this.messageType = getMessageClass(); |
| 53 | this.streamKey = messageType.getDeclaredConstructor().newInstance().getStreamKey(); | 53 | this.streamKey = messageType.getDeclaredConstructor().newInstance().getStreamKey(); |
| 54 | } | 54 | } |
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/cn/iocoder/yudao/framework/mq/redis/package-info.java
0 → 100644
yudao-framework/yudao-spring-boot-starter-mq/src/main/java/org/springframework/data/redis/stream/DefaultStreamMessageListenerContainerX.java deleted
| 1 | -package org.springframework.data.redis.stream; | ||
| 2 | - | ||
| 3 | -import cn.hutool.core.util.ReflectUtil; | ||
| 4 | -import org.springframework.data.redis.connection.RedisConnectionFactory; | ||
| 5 | -import org.springframework.data.redis.connection.stream.ByteRecord; | ||
| 6 | -import org.springframework.data.redis.connection.stream.ReadOffset; | ||
| 7 | -import org.springframework.data.redis.connection.stream.Record; | ||
| 8 | -import org.springframework.util.Assert; | ||
| 9 | - | ||
| 10 | -import java.util.Collections; | ||
| 11 | -import java.util.List; | ||
| 12 | -import java.util.function.Function; | ||
| 13 | - | ||
| 14 | -/** | ||
| 15 | - * 拓展 DefaultStreamMessageListenerContainer 实现,解决 Spring Data Redis + Redisson 结合使用时,Redisson 在 Stream 获得不到数据时,返回 null 而不是空 List,导致 NPE 异常。 | ||
| 16 | - * 对应 issue:https://github.com/spring-projects/spring-data-redis/issues/2147 和 https://github.com/redisson/redisson/issues/4006 | ||
| 17 | - * 目前看下来 Spring Data Redis 不肯加 null 判断,Redisson 暂时也没改返回 null 到空 List 的打算,所以暂时只能自己改,哽咽! | ||
| 18 | - * | ||
| 19 | - * @author 芋道源码 | ||
| 20 | - */ | ||
| 21 | -public class DefaultStreamMessageListenerContainerX<K, V extends Record<K, ?>> extends DefaultStreamMessageListenerContainer<K, V> { | ||
| 22 | - | ||
| 23 | - /** | ||
| 24 | - * 参考 {@link StreamMessageListenerContainer#create(RedisConnectionFactory, StreamMessageListenerContainerOptions)} 的实现 | ||
| 25 | - */ | ||
| 26 | - public static <K, V extends Record<K, ?>> StreamMessageListenerContainer<K, V> create(RedisConnectionFactory connectionFactory, StreamMessageListenerContainer.StreamMessageListenerContainerOptions<K, V> options) { | ||
| 27 | - Assert.notNull(connectionFactory, "RedisConnectionFactory must not be null!"); | ||
| 28 | - Assert.notNull(options, "StreamMessageListenerContainerOptions must not be null!"); | ||
| 29 | - return new DefaultStreamMessageListenerContainerX<>(connectionFactory, options); | ||
| 30 | - } | ||
| 31 | - | ||
| 32 | - public DefaultStreamMessageListenerContainerX(RedisConnectionFactory connectionFactory, StreamMessageListenerContainerOptions<K, V> containerOptions) { | ||
| 33 | - super(connectionFactory, containerOptions); | ||
| 34 | - } | ||
| 35 | - | ||
| 36 | - /** | ||
| 37 | - * 参考 {@link DefaultStreamMessageListenerContainer#register(StreamReadRequest, StreamListener)} 的实现 | ||
| 38 | - */ | ||
| 39 | - @Override | ||
| 40 | - public Subscription register(StreamReadRequest<K> streamRequest, StreamListener<K, V> listener) { | ||
| 41 | - return this.doRegisterX(getReadTaskX(streamRequest, listener)); | ||
| 42 | - } | ||
| 43 | - | ||
| 44 | - @SuppressWarnings("unchecked") | ||
| 45 | - private StreamPollTask<K, V> getReadTaskX(StreamReadRequest<K> streamRequest, StreamListener<K, V> listener) { | ||
| 46 | - StreamPollTask<K, V> task = ReflectUtil.invoke(this, "getReadTask", streamRequest, listener); | ||
| 47 | - // 修改 readFunction 方法 | ||
| 48 | - Function<ReadOffset, List<ByteRecord>> readFunction = (Function<ReadOffset, List<ByteRecord>>) ReflectUtil.getFieldValue(task, "readFunction"); | ||
| 49 | - ReflectUtil.setFieldValue(task, "readFunction", (Function<ReadOffset, List<ByteRecord>>) readOffset -> { | ||
| 50 | - List<ByteRecord> records = readFunction.apply(readOffset); | ||
| 51 | - //【重点】保证 records 不是空,避免 NPE 的问题!!! | ||
| 52 | - return records != null ? records : Collections.emptyList(); | ||
| 53 | - }); | ||
| 54 | - return task; | ||
| 55 | - } | ||
| 56 | - | ||
| 57 | - private Subscription doRegisterX(Task task) { | ||
| 58 | - return ReflectUtil.invoke(this, "doRegister", task); | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | -} | ||
| 62 | - |
yudao-framework/yudao-spring-boot-starter-mq/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
| 1 | -cn.iocoder.yudao.framework.mq.config.YudaoMQAutoConfiguration | ||
| 2 | \ No newline at end of file | 1 | \ No newline at end of file |
| 2 | +cn.iocoder.yudao.framework.mq.redis.config.YudaoRedisMQAutoConfiguration | ||
| 3 | +cn.iocoder.yudao.framework.mq.rabbitmq.config.YudaoRabbitMQAutoConfiguration | ||
| 3 | \ No newline at end of file | 4 | \ No newline at end of file |
yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 事件机制 Event 入门》.md
0 → 100644
| 1 | +<http://www.iocoder.cn/Spring-Boot/RocketMQ/?yudao> |
yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 Kafka 入门》.md
0 → 100644
| 1 | +<http://www.iocoder.cn/Spring-Boot/Kafka/?yudao> |
yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 RabbitMQ 入门》.md
0 → 100644
| 1 | +<http://www.iocoder.cn/Spring-Boot/RabbitMQ/?yudao> |
yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 RocketMQ 入门》.md
0 → 100644
| 1 | +<http://www.iocoder.cn/Spring-Boot/RocketMQ/?yudao> |
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/service/ApiAccessLog.java
| @@ -5,7 +5,6 @@ import lombok.Data; | @@ -5,7 +5,6 @@ import lombok.Data; | ||
| 5 | import javax.validation.constraints.NotNull; | 5 | import javax.validation.constraints.NotNull; |
| 6 | import java.time.LocalDateTime; | 6 | import java.time.LocalDateTime; |
| 7 | 7 | ||
| 8 | -// TODO @小吉祥:搞个 job,清理 14 天外的访问日志; | ||
| 9 | /** | 8 | /** |
| 10 | * API 访问日志 | 9 | * API 访问日志 |
| 11 | * | 10 | * |
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/service/ApiErrorLog.java
| @@ -5,7 +5,6 @@ import lombok.Data; | @@ -5,7 +5,6 @@ import lombok.Data; | ||
| 5 | import javax.validation.constraints.NotNull; | 5 | import javax.validation.constraints.NotNull; |
| 6 | import java.time.LocalDateTime; | 6 | import java.time.LocalDateTime; |
| 7 | 7 | ||
| 8 | -// TODO @小吉祥:搞个 job,清理 14 天外的异常日志; | ||
| 9 | /** | 8 | /** |
| 10 | * API 错误日志 | 9 | * API 错误日志 |
| 11 | * | 10 | * |
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmCommentTypeEnum.java
| @@ -20,16 +20,16 @@ public enum BpmCommentTypeEnum { | @@ -20,16 +20,16 @@ public enum BpmCommentTypeEnum { | ||
| 20 | ; | 20 | ; |
| 21 | 21 | ||
| 22 | /** | 22 | /** |
| 23 | - * 结果 | 23 | + * 操作类型 |
| 24 | */ | 24 | */ |
| 25 | private final Integer type; | 25 | private final Integer type; |
| 26 | /** | 26 | /** |
| 27 | - * 描述 | 27 | + * 操作名字 |
| 28 | */ | 28 | */ |
| 29 | - private final String desc; | 29 | + private final String name; |
| 30 | /** | 30 | /** |
| 31 | - * 模板信息 | 31 | + * 操作描述 |
| 32 | */ | 32 | */ |
| 33 | - private final String templateComment; | 33 | + private final String comment; |
| 34 | 34 | ||
| 35 | } | 35 | } |
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java
| @@ -30,13 +30,13 @@ public enum BpmProcessInstanceResultEnum { | @@ -30,13 +30,13 @@ public enum BpmProcessInstanceResultEnum { | ||
| 30 | * 相当于是 通过 APPROVE 的特殊状态 | 30 | * 相当于是 通过 APPROVE 的特殊状态 |
| 31 | * 例如:A审批, A 后加签了 B,并且审批通过了任务,但是 B 还未审批,则当前任务状态为“待后加签任务完成” | 31 | * 例如:A审批, A 后加签了 B,并且审批通过了任务,但是 B 还未审批,则当前任务状态为“待后加签任务完成” |
| 32 | */ | 32 | */ |
| 33 | - ADD_SIGN_AFTER(7, "待后加签任务完成"), | 33 | + SIGN_AFTER(7, "待后加签任务完成"), |
| 34 | /** | 34 | /** |
| 35 | * 【加签】源任务未审批,但是向前加签了,所以源任务状态变为“待前加签任务完成” | 35 | * 【加签】源任务未审批,但是向前加签了,所以源任务状态变为“待前加签任务完成” |
| 36 | * 相当于是 处理中 PROCESS 的特殊状态 | 36 | * 相当于是 处理中 PROCESS 的特殊状态 |
| 37 | * 例如:A 审批, A 前加签了 B,B 还未审核 | 37 | * 例如:A 审批, A 前加签了 B,B 还未审核 |
| 38 | */ | 38 | */ |
| 39 | - ADD_SIGN_BEFORE(8, "待前加签任务完成"), | 39 | + SIGN_BEFORE(8, "待前加签任务完成"), |
| 40 | /** | 40 | /** |
| 41 | * 【加签】后加签任务被创建时的初始状态 | 41 | * 【加签】后加签任务被创建时的初始状态 |
| 42 | * 相当于是 处理中 PROCESS 的特殊状态 | 42 | * 相当于是 处理中 PROCESS 的特殊状态 |
| @@ -71,7 +71,7 @@ public enum BpmProcessInstanceResultEnum { | @@ -71,7 +71,7 @@ public enum BpmProcessInstanceResultEnum { | ||
| 71 | public static boolean isEndResult(Integer result) { | 71 | public static boolean isEndResult(Integer result) { |
| 72 | return ObjectUtils.equalsAny(result, APPROVE.getResult(), REJECT.getResult(), | 72 | return ObjectUtils.equalsAny(result, APPROVE.getResult(), REJECT.getResult(), |
| 73 | CANCEL.getResult(), BACK.getResult(), | 73 | CANCEL.getResult(), BACK.getResult(), |
| 74 | - ADD_SIGN_AFTER.getResult()); | 74 | + SIGN_AFTER.getResult()); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | } | 77 | } |
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmTaskAddSignTypeEnum.java
| @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.bpm.enums.task; | @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.bpm.enums.task; | ||
| 3 | import lombok.AllArgsConstructor; | 3 | import lombok.AllArgsConstructor; |
| 4 | import lombok.Getter; | 4 | import lombok.Getter; |
| 5 | 5 | ||
| 6 | - | ||
| 7 | /** | 6 | /** |
| 8 | * 流程任务 -- 加签类型枚举类型 | 7 | * 流程任务 -- 加签类型枚举类型 |
| 9 | */ | 8 | */ |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
| @@ -74,7 +74,7 @@ public class BpmTaskController { | @@ -74,7 +74,7 @@ public class BpmTaskController { | ||
| 74 | return success(true); | 74 | return success(true); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | - @GetMapping("/get-return-list") | 77 | + @GetMapping("/return-list") |
| 78 | @Operation(summary = "获取所有可回退的节点", description = "用于【流程详情】的【回退】按钮") | 78 | @Operation(summary = "获取所有可回退的节点", description = "用于【流程详情】的【回退】按钮") |
| 79 | @Parameter(name = "taskId", description = "当前任务ID", required = true) | 79 | @Parameter(name = "taskId", description = "当前任务ID", required = true) |
| 80 | @PreAuthorize("@ss.hasPermission('bpm:task:update')") | 80 | @PreAuthorize("@ss.hasPermission('bpm:task:update')") |
| @@ -98,27 +98,28 @@ public class BpmTaskController { | @@ -98,27 +98,28 @@ public class BpmTaskController { | ||
| 98 | return success(true); | 98 | return success(true); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | - @PutMapping("/add-sign") | 101 | + @PutMapping("/create-sign") |
| 102 | @Operation(summary = "加签", description = "before 前加签,after 后加签") | 102 | @Operation(summary = "加签", description = "before 前加签,after 后加签") |
| 103 | @PreAuthorize("@ss.hasPermission('bpm:task:update')") | 103 | @PreAuthorize("@ss.hasPermission('bpm:task:update')") |
| 104 | - public CommonResult<Boolean> addSignTask(@Valid @RequestBody BpmTaskAddSignReqVO reqVO) { | ||
| 105 | - taskService.addSignTask(getLoginUserId(), reqVO); | 104 | + public CommonResult<Boolean> createSignTask(@Valid @RequestBody BpmTaskAddSignReqVO reqVO) { |
| 105 | + taskService.createSignTask(getLoginUserId(), reqVO); | ||
| 106 | return success(true); | 106 | return success(true); |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | - @PutMapping("/sub-sign") | 109 | + @DeleteMapping("/delete-sign") |
| 110 | @Operation(summary = "减签") | 110 | @Operation(summary = "减签") |
| 111 | @PreAuthorize("@ss.hasPermission('bpm:task:update')") | 111 | @PreAuthorize("@ss.hasPermission('bpm:task:update')") |
| 112 | - public CommonResult<Boolean> subSignTask(@Valid @RequestBody BpmTaskSubSignReqVO reqVO) { | ||
| 113 | - taskService.subSignTask(getLoginUserId(), reqVO); | 112 | + public CommonResult<Boolean> deleteSignTask(@Valid @RequestBody BpmTaskSubSignReqVO reqVO) { |
| 113 | + taskService.deleteSignTask(getLoginUserId(), reqVO); | ||
| 114 | return success(true); | 114 | return success(true); |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | - @GetMapping("/get-children-task-list") | 117 | + @GetMapping("children-list") |
| 118 | @Operation(summary = "获取能被减签的任务") | 118 | @Operation(summary = "获取能被减签的任务") |
| 119 | + @Parameter(name = "parentId", description = "父级任务 ID", required = true) | ||
| 119 | @PreAuthorize("@ss.hasPermission('bpm:task:update')") | 120 | @PreAuthorize("@ss.hasPermission('bpm:task:update')") |
| 120 | - public CommonResult<List<BpmTaskSubSignRespVO>> getChildrenTaskList(@RequestParam("taskId") String taskId) { | ||
| 121 | - return success(taskService.getChildrenTaskList(taskId)); | 121 | + public CommonResult<List<BpmTaskSubSignRespVO>> getChildrenTaskList(@RequestParam("parentId") String parentId) { |
| 122 | + return success(taskService.getChildrenTaskList(parentId)); | ||
| 122 | } | 123 | } |
| 123 | 124 | ||
| 124 | } | 125 | } |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskAddSignReqVO.java
| @@ -6,6 +6,7 @@ import lombok.Data; | @@ -6,6 +6,7 @@ import lombok.Data; | ||
| 6 | import javax.validation.constraints.NotEmpty; | 6 | import javax.validation.constraints.NotEmpty; |
| 7 | import java.util.Set; | 7 | import java.util.Set; |
| 8 | 8 | ||
| 9 | +// TODO @海洋:类名,应该是 create 哈 | ||
| 9 | @Schema(description = "管理后台 - 加签流程任务的 Request VO") | 10 | @Schema(description = "管理后台 - 加签流程任务的 Request VO") |
| 10 | @Data | 11 | @Data |
| 11 | public class BpmTaskAddSignReqVO { | 12 | public class BpmTaskAddSignReqVO { |
| @@ -26,4 +27,4 @@ public class BpmTaskAddSignReqVO { | @@ -26,4 +27,4 @@ public class BpmTaskAddSignReqVO { | ||
| 26 | @NotEmpty(message = "加签原因不能为空") | 27 | @NotEmpty(message = "加签原因不能为空") |
| 27 | private String reason; | 28 | private String reason; |
| 28 | 29 | ||
| 29 | -} | ||
| 30 | \ No newline at end of file | 30 | \ No newline at end of file |
| 31 | +} |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskSubSignReqVO.java
| @@ -5,6 +5,7 @@ import lombok.Data; | @@ -5,6 +5,7 @@ import lombok.Data; | ||
| 5 | 5 | ||
| 6 | import javax.validation.constraints.NotEmpty; | 6 | import javax.validation.constraints.NotEmpty; |
| 7 | 7 | ||
| 8 | +// TODO @海洋:类名,应该是 delete 哈 | ||
| 8 | @Schema(description = "管理后台 - 减签流程任务的 Request VO") | 9 | @Schema(description = "管理后台 - 减签流程任务的 Request VO") |
| 9 | @Data | 10 | @Data |
| 10 | public class BpmTaskSubSignReqVO { | 11 | public class BpmTaskSubSignReqVO { |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
| 1 | package cn.iocoder.yudao.module.bpm.convert.task; | 1 | package cn.iocoder.yudao.module.bpm.convert.task; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.hutool.core.date.LocalDateTimeUtil; | 3 | import cn.hutool.core.date.LocalDateTimeUtil; |
| 4 | +import cn.hutool.core.util.ObjectUtil; | ||
| 5 | import cn.hutool.core.util.StrUtil; | 5 | import cn.hutool.core.util.StrUtil; |
| 6 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 6 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 7 | +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | ||
| 7 | import cn.iocoder.yudao.framework.common.util.date.DateUtils; | 8 | import cn.iocoder.yudao.framework.common.util.date.DateUtils; |
| 8 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | 9 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; |
| 9 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; | 10 | import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; |
| @@ -25,6 +26,9 @@ import java.util.Date; | @@ -25,6 +26,9 @@ import java.util.Date; | ||
| 25 | import java.util.List; | 26 | import java.util.List; |
| 26 | import java.util.Map; | 27 | import java.util.Map; |
| 27 | 28 | ||
| 29 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap; | ||
| 30 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; | ||
| 31 | + | ||
| 28 | /** | 32 | /** |
| 29 | * Bpm 任务 Convert | 33 | * Bpm 任务 Convert |
| 30 | * | 34 | * |
| @@ -167,32 +171,31 @@ public interface BpmTaskConvert { | @@ -167,32 +171,31 @@ public interface BpmTaskConvert { | ||
| 167 | default List<BpmTaskSubSignRespVO> convertList(List<BpmTaskExtDO> bpmTaskExtDOList, | 171 | default List<BpmTaskSubSignRespVO> convertList(List<BpmTaskExtDO> bpmTaskExtDOList, |
| 168 | Map<Long, AdminUserRespDTO> userMap, | 172 | Map<Long, AdminUserRespDTO> userMap, |
| 169 | Map<String, Task> idTaskMap){ | 173 | Map<String, Task> idTaskMap){ |
| 170 | - return CollectionUtils.convertList(bpmTaskExtDOList, task->{ | ||
| 171 | - BpmTaskSubSignRespVO bpmTaskSubSignRespVO = new BpmTaskSubSignRespVO(); | ||
| 172 | - bpmTaskSubSignRespVO.setName(task.getName()); | ||
| 173 | - bpmTaskSubSignRespVO.setId(task.getTaskId()); | ||
| 174 | - Task sourceTask = idTaskMap.get(task.getTaskId()); | 174 | + return CollectionUtils.convertList(bpmTaskExtDOList, task -> { |
| 175 | + BpmTaskSubSignRespVO bpmTaskSubSignRespVO = new BpmTaskSubSignRespVO() | ||
| 176 | + .setId(task.getTaskId()).setName(task.getName()); | ||
| 175 | // 后加签任务不会直接设置 assignee ,所以不存在 assignee 的情况,则去取 owner | 177 | // 后加签任务不会直接设置 assignee ,所以不存在 assignee 的情况,则去取 owner |
| 176 | - String assignee = StrUtil.isNotEmpty(sourceTask.getAssignee()) ? sourceTask.getAssignee() : sourceTask.getOwner(); | ||
| 177 | - AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(assignee)); | ||
| 178 | - if (assignUser != null) { | ||
| 179 | - bpmTaskSubSignRespVO.setAssigneeUser(convert3(assignUser)); | ||
| 180 | - } | 178 | + Task sourceTask = idTaskMap.get(task.getTaskId()); |
| 179 | + String assignee = ObjectUtil.defaultIfBlank(sourceTask.getOwner(),sourceTask.getAssignee()); | ||
| 180 | + MapUtils.findAndThen(userMap,NumberUtils.parseLong(assignee), | ||
| 181 | + assignUser-> bpmTaskSubSignRespVO.setAssigneeUser(convert3(assignUser))); | ||
| 181 | return bpmTaskSubSignRespVO; | 182 | return bpmTaskSubSignRespVO; |
| 182 | }); | 183 | }); |
| 183 | } | 184 | } |
| 184 | 185 | ||
| 185 | /** | 186 | /** |
| 186 | * 转换任务为父子级 | 187 | * 转换任务为父子级 |
| 188 | + * | ||
| 187 | * @param sourceList 原始数据 | 189 | * @param sourceList 原始数据 |
| 188 | * @return 转换后的父子级数组 | 190 | * @return 转换后的父子级数组 |
| 189 | */ | 191 | */ |
| 190 | - default List<BpmTaskRespVO> convertChildrenList(List<BpmTaskRespVO> sourceList){ | ||
| 191 | - List<BpmTaskRespVO> childrenTaskList = CollectionUtils.filterList(sourceList, r -> StrUtil.isNotEmpty(r.getParentTaskId())); | ||
| 192 | - Map<String, List<BpmTaskRespVO>> parentChildrenTaskListMap = CollectionUtils.convertMultiMap(childrenTaskList, BpmTaskRespVO::getParentTaskId); | 192 | + default List<BpmTaskRespVO> convertChildrenList(List<BpmTaskRespVO> sourceList) { |
| 193 | + List<BpmTaskRespVO> childrenTaskList = filterList(sourceList, r -> StrUtil.isNotEmpty(r.getParentTaskId())); | ||
| 194 | + Map<String, List<BpmTaskRespVO>> parentChildrenTaskListMap = convertMultiMap(childrenTaskList, BpmTaskRespVO::getParentTaskId); | ||
| 193 | for (BpmTaskRespVO bpmTaskRespVO : sourceList) { | 195 | for (BpmTaskRespVO bpmTaskRespVO : sourceList) { |
| 194 | bpmTaskRespVO.setChildren(parentChildrenTaskListMap.get(bpmTaskRespVO.getId())); | 196 | bpmTaskRespVO.setChildren(parentChildrenTaskListMap.get(bpmTaskRespVO.getId())); |
| 195 | } | 197 | } |
| 196 | - return CollectionUtils.filterList(sourceList, r -> StrUtil.isEmpty(r.getParentTaskId())); | 198 | + return filterList(sourceList, r -> StrUtil.isEmpty(r.getParentTaskId())); |
| 197 | } | 199 | } |
| 200 | + | ||
| 198 | } | 201 | } |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java
| @@ -21,13 +21,13 @@ public interface BpmTaskExtMapper extends BaseMapperX<BpmTaskExtDO> { | @@ -21,13 +21,13 @@ public interface BpmTaskExtMapper extends BaseMapperX<BpmTaskExtDO> { | ||
| 21 | return selectList(BpmTaskExtDO::getTaskId, taskIds); | 21 | return selectList(BpmTaskExtDO::getTaskId, taskIds); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | + // TODO @海:BpmProcessInstanceResultEnum.CAN_SUB_SIGN_STATUS_LIST) 应该作为条件,mapper 不要有业务 | ||
| 24 | default List<BpmTaskExtDO> selectProcessListByTaskIds(Collection<String> taskIds) { | 25 | default List<BpmTaskExtDO> selectProcessListByTaskIds(Collection<String> taskIds) { |
| 25 | return selectList(new LambdaQueryWrapperX<BpmTaskExtDO>() | 26 | return selectList(new LambdaQueryWrapperX<BpmTaskExtDO>() |
| 26 | .in(BpmTaskExtDO::getTaskId, taskIds) | 27 | .in(BpmTaskExtDO::getTaskId, taskIds) |
| 27 | .in(BpmTaskExtDO::getResult, BpmProcessInstanceResultEnum.CAN_SUB_SIGN_STATUS_LIST)); | 28 | .in(BpmTaskExtDO::getResult, BpmProcessInstanceResultEnum.CAN_SUB_SIGN_STATUS_LIST)); |
| 28 | } | 29 | } |
| 29 | 30 | ||
| 30 | - | ||
| 31 | default BpmTaskExtDO selectByTaskId(String taskId) { | 31 | default BpmTaskExtDO selectByTaskId(String taskId) { |
| 32 | return selectOne(BpmTaskExtDO::getTaskId, taskId); | 32 | return selectOne(BpmTaskExtDO::getTaskId, taskId); |
| 33 | } | 33 | } |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmSecurityConfiguration.java deleted
| 1 | -package cn.iocoder.yudao.module.bpm.framework.bpm.config; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer; | ||
| 4 | -import org.springframework.context.annotation.Bean; | ||
| 5 | -import org.springframework.context.annotation.Configuration; | ||
| 6 | -import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
| 7 | -import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; | ||
| 8 | - | ||
| 9 | -/** | ||
| 10 | - * @author kemengkai | ||
| 11 | - * @create 2022-05-07 08:15 | ||
| 12 | - */ | ||
| 13 | -@Configuration("bpmSecurityConfiguration") | ||
| 14 | -public class BpmSecurityConfiguration { | ||
| 15 | - | ||
| 16 | - @Bean("bpmAuthorizeRequestsCustomizer") | ||
| 17 | - public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() { | ||
| 18 | - return new AuthorizeRequestsCustomizer() { | ||
| 19 | - | ||
| 20 | - @Override | ||
| 21 | - public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) { | ||
| 22 | - // 任务回退接口 | ||
| 23 | - registry.antMatchers(buildAdminApi("/bpm/task/back")).permitAll(); | ||
| 24 | - } | ||
| 25 | - | ||
| 26 | - }; | ||
| 27 | - } | ||
| 28 | -} |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
| @@ -288,5 +288,4 @@ public class BpmModelServiceImpl implements BpmModelService { | @@ -288,5 +288,4 @@ public class BpmModelServiceImpl implements BpmModelService { | ||
| 288 | processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode()); | 288 | processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode()); |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | - | ||
| 292 | } | 291 | } |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
| @@ -163,7 +163,7 @@ public interface BpmTaskService { | @@ -163,7 +163,7 @@ public interface BpmTaskService { | ||
| 163 | * @param userId 被加签的用户和任务 ID,加签类型 | 163 | * @param userId 被加签的用户和任务 ID,加签类型 |
| 164 | * @param reqVO 当前用户 ID | 164 | * @param reqVO 当前用户 ID |
| 165 | */ | 165 | */ |
| 166 | - void addSignTask(Long userId, BpmTaskAddSignReqVO reqVO); | 166 | + void createSignTask(Long userId, BpmTaskAddSignReqVO reqVO); |
| 167 | 167 | ||
| 168 | /** | 168 | /** |
| 169 | * 任务减签名 | 169 | * 任务减签名 |
| @@ -171,14 +171,14 @@ public interface BpmTaskService { | @@ -171,14 +171,14 @@ public interface BpmTaskService { | ||
| 171 | * @param userId 当前用户ID | 171 | * @param userId 当前用户ID |
| 172 | * @param reqVO 被减签的任务 ID,理由 | 172 | * @param reqVO 被减签的任务 ID,理由 |
| 173 | */ | 173 | */ |
| 174 | - void subSignTask(Long userId, BpmTaskSubSignReqVO reqVO); | 174 | + void deleteSignTask(Long userId, BpmTaskSubSignReqVO reqVO); |
| 175 | 175 | ||
| 176 | /** | 176 | /** |
| 177 | * 获取指定任务的子任务和审批人信息 | 177 | * 获取指定任务的子任务和审批人信息 |
| 178 | * | 178 | * |
| 179 | - * @param taskId 指定任务ID | 179 | + * @param parentId 指定任务ID |
| 180 | * @return 子任务列表 | 180 | * @return 子任务列表 |
| 181 | */ | 181 | */ |
| 182 | - List<BpmTaskSubSignRespVO> getChildrenTaskList(String taskId); | 182 | + List<BpmTaskSubSignRespVO> getChildrenTaskList(String parentId); |
| 183 | 183 | ||
| 184 | } | 184 | } |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
| @@ -53,7 +53,6 @@ import javax.annotation.Resource; | @@ -53,7 +53,6 @@ import javax.annotation.Resource; | ||
| 53 | import javax.validation.Valid; | 53 | import javax.validation.Valid; |
| 54 | import java.time.LocalDateTime; | 54 | import java.time.LocalDateTime; |
| 55 | import java.util.*; | 55 | import java.util.*; |
| 56 | -import java.util.stream.Collectors; | ||
| 57 | import java.util.stream.Stream; | 56 | import java.util.stream.Stream; |
| 58 | 57 | ||
| 59 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 58 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| @@ -240,10 +239,11 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -240,10 +239,11 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 240 | handleParentTask(task); | 239 | handleParentTask(task); |
| 241 | } | 240 | } |
| 242 | 241 | ||
| 242 | + | ||
| 243 | /** | 243 | /** |
| 244 | * 审批通过存在“后加签”的任务。 | 244 | * 审批通过存在“后加签”的任务。 |
| 245 | * <p> | 245 | * <p> |
| 246 | - * 注意:该任务不能马上完成,需要一个中间状态(ADD_SIGN_AFTER),并激活剩余所有子任务(PROCESS)为可审批处理 | 246 | + * 注意:该任务不能马上完成,需要一个中间状态(SIGN_AFTER),并激活剩余所有子任务(PROCESS)为可审批处理 |
| 247 | * | 247 | * |
| 248 | * @param task 当前任务 | 248 | * @param task 当前任务 |
| 249 | * @param reqVO 前端请求参数 | 249 | * @param reqVO 前端请求参数 |
| @@ -251,7 +251,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -251,7 +251,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 251 | private void approveAfterSignTask(Task task, BpmTaskApproveReqVO reqVO) { | 251 | private void approveAfterSignTask(Task task, BpmTaskApproveReqVO reqVO) { |
| 252 | // 1. 有向后加签,则该任务状态临时设置为 ADD_SIGN_AFTER 状态 | 252 | // 1. 有向后加签,则该任务状态临时设置为 ADD_SIGN_AFTER 状态 |
| 253 | taskExtMapper.updateByTaskId( | 253 | taskExtMapper.updateByTaskId( |
| 254 | - new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.ADD_SIGN_AFTER.getResult()) | 254 | + new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.SIGN_AFTER.getResult()) |
| 255 | .setReason(reqVO.getReason()).setEndTime(LocalDateTime.now())); | 255 | .setReason(reqVO.getReason()).setEndTime(LocalDateTime.now())); |
| 256 | 256 | ||
| 257 | // 2. 激活子任务 | 257 | // 2. 激活子任务 |
| @@ -265,7 +265,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -265,7 +265,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | /** | 267 | /** |
| 268 | - * 处理当前任务的父任务 | 268 | + * 处理当前任务的父任务,主要处理“加签”的情况 |
| 269 | * | 269 | * |
| 270 | * @param task 当前任务 | 270 | * @param task 当前任务 |
| 271 | */ | 271 | */ |
| @@ -274,76 +274,79 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -274,76 +274,79 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 274 | if (StrUtil.isBlank(parentTaskId)) { | 274 | if (StrUtil.isBlank(parentTaskId)) { |
| 275 | return; | 275 | return; |
| 276 | } | 276 | } |
| 277 | - if (StrUtil.isNotBlank(parentTaskId)) { | ||
| 278 | - // 1. 判断当前任务的父任务是否还有子任务 | ||
| 279 | - Long childrenTaskCount = getChildrenTaskCount(parentTaskId); | ||
| 280 | - if (childrenTaskCount > 0) { | ||
| 281 | - return; | ||
| 282 | - } | ||
| 283 | - // 2. 获取父任务 | ||
| 284 | - Task parentTask = validateTaskExist(parentTaskId); | ||
| 285 | - | ||
| 286 | - // 3. 情况一:处理向前加签 | ||
| 287 | - String scopeType = parentTask.getScopeType(); | ||
| 288 | - if (BpmTaskAddSignTypeEnum.BEFORE.getType().equals(scopeType)) { | ||
| 289 | - // 3.1 如果是向前加签的任务,则调用 resolveTask 指派父任务,将 owner 重新赋值给父任务的 assignee | ||
| 290 | - taskService.resolveTask(parentTaskId); | ||
| 291 | - // 3.2 更新任务拓展表为处理中 | ||
| 292 | - taskExtMapper.updateByTaskId( | ||
| 293 | - new BpmTaskExtDO().setTaskId(parentTask.getId()).setResult(BpmProcessInstanceResultEnum.PROCESS.getResult())); | ||
| 294 | - } else if (BpmTaskAddSignTypeEnum.AFTER.getType().equals(scopeType)) { | ||
| 295 | - // 3. 情况二:处理向后加签 | ||
| 296 | - handleAfterSign(parentTask); | ||
| 297 | - } | 277 | + // 1. 判断当前任务的父任务是否还有子任务 |
| 278 | + Long childrenTaskCount = getChildrenTaskCount(parentTaskId); | ||
| 279 | + if (childrenTaskCount > 0) { | ||
| 280 | + return; | ||
| 281 | + } | ||
| 282 | + // 2. 获取父任务 | ||
| 283 | + Task parentTask = validateTaskExist(parentTaskId); | ||
| 298 | 284 | ||
| 299 | - // 4. 子任务已处理完成,清空 scopeType 字段,修改 parentTask 信息,方便后续可以继续向前后向后加签 | ||
| 300 | - // 再查询一次的原因是避免报错:Task was updated by another transaction concurrently | ||
| 301 | - // 因为前面处理后可能会导致 parentTask rev 字段被修改,需要重新获取最新的 | ||
| 302 | - parentTask = getTask(parentTaskId); | ||
| 303 | - if (parentTask == null) { | ||
| 304 | - // 为空的情况是:已经通过 handleAfterSign 方法将任务完成了,所以 ru_task 表会查不到数据 | ||
| 305 | - return; | ||
| 306 | - } | ||
| 307 | - clearTaskScopeTypeAndSave(parentTask); | 285 | + // 3. 处理加签情况 |
| 286 | + String scopeType = parentTask.getScopeType(); | ||
| 287 | + if(!validateSignType(scopeType)){ | ||
| 288 | + return; | ||
| 308 | } | 289 | } |
| 290 | + // 3.1 情况一:处理向前加签 | ||
| 291 | + if (BpmTaskAddSignTypeEnum.BEFORE.getType().equals(scopeType)) { | ||
| 292 | + // 3.1.1 如果是向前加签的任务,则调用 resolveTask 指派父任务,将 owner 重新赋值给父任务的 assignee,这样它就可以被审批 | ||
| 293 | + taskService.resolveTask(parentTaskId); | ||
| 294 | + // 3.1.2 更新任务拓展表为处理中 | ||
| 295 | + taskExtMapper.updateByTaskId( | ||
| 296 | + new BpmTaskExtDO().setTaskId(parentTask.getId()).setResult(BpmProcessInstanceResultEnum.PROCESS.getResult())); | ||
| 297 | + } else if (BpmTaskAddSignTypeEnum.AFTER.getType().equals(scopeType)) { | ||
| 298 | + // 3.2 情况二:处理向后加签 | ||
| 299 | + handleParentTaskForAfterSign(parentTask); | ||
| 300 | + } | ||
| 301 | + | ||
| 302 | + // 4. 子任务已处理完成,清空 scopeType 字段,修改 parentTask 信息,方便后续可以继续向前后向后加签 | ||
| 303 | + // 再查询一次的原因是避免报错:Task was updated by another transaction concurrently | ||
| 304 | + // 因为前面处理后可能会导致 parentTask rev 字段被修改,需要重新获取最新的 | ||
| 305 | + parentTask = getTask(parentTaskId); | ||
| 306 | + if (parentTask == null) { | ||
| 307 | + // 为空的情况是:已经通过 handleAfterSign 方法将任务完成了,所以 ru_task 表会查不到数据 | ||
| 308 | + return; | ||
| 309 | + } | ||
| 310 | + clearTaskScopeTypeAndSave(parentTask); | ||
| 309 | } | 311 | } |
| 310 | 312 | ||
| 313 | + | ||
| 311 | /** | 314 | /** |
| 312 | * 处理后加签任务 | 315 | * 处理后加签任务 |
| 313 | * | 316 | * |
| 314 | * @param parentTask 当前审批任务的父任务 | 317 | * @param parentTask 当前审批任务的父任务 |
| 315 | */ | 318 | */ |
| 316 | - private void handleAfterSign(Task parentTask) { | 319 | + // TODO @海:这个逻辑,怎么感觉可以是 parentTask 的 parent,再去调用 handleParentTask 方法;可以微信聊下; |
| 320 | + private void handleParentTaskForAfterSign(Task parentTask) { | ||
| 317 | String parentTaskId = parentTask.getId(); | 321 | String parentTaskId = parentTask.getId(); |
| 318 | - //1. 更新 parentTask 的任务拓展表为通过,并调用 complete 完成自己 | 322 | + // 1. 更新 parentTask 的任务拓展表为通过,并调用 complete 完成自己 |
| 319 | BpmTaskExtDO currentTaskExt = taskExtMapper.selectByTaskId(parentTask.getId()); | 323 | BpmTaskExtDO currentTaskExt = taskExtMapper.selectByTaskId(parentTask.getId()); |
| 320 | - BpmTaskExtDO currentTaskUpdateEntity = new BpmTaskExtDO().setTaskId(parentTask.getId()) | 324 | + BpmTaskExtDO currentTaskExtUpdateObj = new BpmTaskExtDO().setTaskId(parentTask.getId()) |
| 321 | .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); | 325 | .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()); |
| 322 | if (currentTaskExt.getEndTime() == null) { | 326 | if (currentTaskExt.getEndTime() == null) { |
| 323 | // 1.1 有这个判断是因为,以前没设置过结束时间,才去设置 | 327 | // 1.1 有这个判断是因为,以前没设置过结束时间,才去设置 |
| 324 | - currentTaskUpdateEntity.setEndTime(LocalDateTime.now()); | 328 | + currentTaskExtUpdateObj.setEndTime(LocalDateTime.now()); |
| 325 | } | 329 | } |
| 326 | - // 1.2 完成自己 | ||
| 327 | - taskExtMapper.updateByTaskId(currentTaskUpdateEntity); | 330 | + taskExtMapper.updateByTaskId(currentTaskExtUpdateObj); |
| 331 | + // 1.2 完成自己(因为它已经没有子任务,所以也可以完成) | ||
| 328 | taskService.complete(parentTaskId); | 332 | taskService.complete(parentTaskId); |
| 329 | 333 | ||
| 330 | // 2. 如果有父级,递归查询上级任务是否都已经完成 | 334 | // 2. 如果有父级,递归查询上级任务是否都已经完成 |
| 331 | if (StrUtil.isEmpty(parentTask.getParentTaskId())) { | 335 | if (StrUtil.isEmpty(parentTask.getParentTaskId())) { |
| 332 | return; | 336 | return; |
| 333 | } | 337 | } |
| 334 | - // TODO @海:这块待讨论,脑子略乱;感觉 handleAfterSign 的后半段,和 handleParentTask 有点重叠??? | ||
| 335 | // 2.1 判断整条链路的任务是否完成 | 338 | // 2.1 判断整条链路的任务是否完成 |
| 336 | // 例如从 A 任务加签了一个 B 任务,B 任务又加签了一个 C 任务,C 任务加签了 D 任务 | 339 | // 例如从 A 任务加签了一个 B 任务,B 任务又加签了一个 C 任务,C 任务加签了 D 任务 |
| 337 | // 此时,D 任务完成,要一直往上找到祖先任务 A调用 complete 方法完成 A 任务 | 340 | // 此时,D 任务完成,要一直往上找到祖先任务 A调用 complete 方法完成 A 任务 |
| 338 | boolean allChildrenTaskFinish = true; | 341 | boolean allChildrenTaskFinish = true; |
| 339 | while (StrUtil.isNotBlank(parentTask.getParentTaskId())) { | 342 | while (StrUtil.isNotBlank(parentTask.getParentTaskId())) { |
| 340 | parentTask = validateTaskExist(parentTask.getParentTaskId()); | 343 | parentTask = validateTaskExist(parentTask.getParentTaskId()); |
| 341 | - BpmTaskExtDO bpmTaskExtDO = taskExtMapper.selectByTaskId(parentTask.getId()); | ||
| 342 | - if (bpmTaskExtDO == null) { | 344 | + BpmTaskExtDO parentTaskExt = taskExtMapper.selectByTaskId(parentTask.getId()); |
| 345 | + if (parentTaskExt == null) { | ||
| 343 | break; | 346 | break; |
| 344 | } | 347 | } |
| 345 | - boolean currentTaskFinish = BpmProcessInstanceResultEnum.isEndResult(bpmTaskExtDO.getResult()); | ||
| 346 | - // 2.2 如果 allChildrenTaskFinish 已经被赋值为 false ,则不会再赋值为 true,因为整个链路没有完成 | 348 | + boolean currentTaskFinish = BpmProcessInstanceResultEnum.isEndResult(parentTaskExt.getResult()); |
| 349 | + // 2.2 如果 allChildrenTaskFinish 已经被赋值为 false,则不会再赋值为 true,因为整个链路没有完成 | ||
| 347 | if (allChildrenTaskFinish) { | 350 | if (allChildrenTaskFinish) { |
| 348 | allChildrenTaskFinish = currentTaskFinish; | 351 | allChildrenTaskFinish = currentTaskFinish; |
| 349 | } | 352 | } |
| @@ -354,19 +357,19 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -354,19 +357,19 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 354 | 357 | ||
| 355 | // 3 处理非完成状态的任务 | 358 | // 3 处理非完成状态的任务 |
| 356 | // 3.1 判断当前任务的父任务是否还有子任务 | 359 | // 3.1 判断当前任务的父任务是否还有子任务 |
| 357 | - Long childrenTaskCount = getChildrenTaskCount(bpmTaskExtDO.getTaskId()); | 360 | + Long childrenTaskCount = getChildrenTaskCount(parentTaskExt.getTaskId()); |
| 358 | if (childrenTaskCount > 0) { | 361 | if (childrenTaskCount > 0) { |
| 359 | continue; | 362 | continue; |
| 360 | } | 363 | } |
| 361 | // 3.2 没有子任务,判断当前任务状态是否为 ADD_SIGN_BEFORE 待前加签任务完成 | 364 | // 3.2 没有子任务,判断当前任务状态是否为 ADD_SIGN_BEFORE 待前加签任务完成 |
| 362 | - if (BpmProcessInstanceResultEnum.ADD_SIGN_BEFORE.getResult().equals(bpmTaskExtDO.getResult())) { | 365 | + if (BpmProcessInstanceResultEnum.SIGN_BEFORE.getResult().equals(parentTaskExt.getResult())) { |
| 363 | // 3.3 需要修改该任务状态为处理中 | 366 | // 3.3 需要修改该任务状态为处理中 |
| 364 | - taskService.resolveTask(bpmTaskExtDO.getTaskId()); | ||
| 365 | - bpmTaskExtDO.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); | ||
| 366 | - taskExtMapper.updateByTaskId(bpmTaskExtDO); | 367 | + taskService.resolveTask(parentTaskExt.getTaskId()); |
| 368 | + parentTaskExt.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()); | ||
| 369 | + taskExtMapper.updateByTaskId(parentTaskExt); | ||
| 367 | } | 370 | } |
| 368 | // 3.4 清空 scopeType 字段,用于任务没有子任务时使用该方法,方便任务可以再次被不同的方式加签 | 371 | // 3.4 清空 scopeType 字段,用于任务没有子任务时使用该方法,方便任务可以再次被不同的方式加签 |
| 369 | - parentTask = validateTaskExist(bpmTaskExtDO.getTaskId()); | 372 | + parentTask = validateTaskExist(parentTaskExt.getTaskId()); |
| 370 | clearTaskScopeTypeAndSave(parentTask); | 373 | clearTaskScopeTypeAndSave(parentTask); |
| 371 | } | 374 | } |
| 372 | 375 | ||
| @@ -387,7 +390,6 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -387,7 +390,6 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 387 | taskService.saveTask(task); | 390 | taskService.saveTask(task); |
| 388 | } | 391 | } |
| 389 | 392 | ||
| 390 | - | ||
| 391 | /** | 393 | /** |
| 392 | * 获取子任务个数 | 394 | * 获取子任务个数 |
| 393 | * | 395 | * |
| @@ -709,7 +711,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -709,7 +711,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 709 | 711 | ||
| 710 | @Override | 712 | @Override |
| 711 | @Transactional(rollbackFor = Exception.class) | 713 | @Transactional(rollbackFor = Exception.class) |
| 712 | - public void addSignTask(Long userId, BpmTaskAddSignReqVO reqVO) { | 714 | + public void createSignTask(Long userId, BpmTaskAddSignReqVO reqVO) { |
| 713 | // 1. 获取和校验任务 | 715 | // 1. 获取和校验任务 |
| 714 | TaskEntityImpl taskEntity = validateAddSign(userId, reqVO); | 716 | TaskEntityImpl taskEntity = validateAddSign(userId, reqVO); |
| 715 | List<AdminUserRespDTO> userList = adminUserApi.getUserList(reqVO.getUserIdList()); | 717 | List<AdminUserRespDTO> userList = adminUserApi.getUserList(reqVO.getUserIdList()); |
| @@ -728,7 +730,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -728,7 +730,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 728 | // 2.3 更新扩展表状态 | 730 | // 2.3 更新扩展表状态 |
| 729 | taskExtMapper.updateByTaskId( | 731 | taskExtMapper.updateByTaskId( |
| 730 | new BpmTaskExtDO().setTaskId(taskEntity.getId()) | 732 | new BpmTaskExtDO().setTaskId(taskEntity.getId()) |
| 731 | - .setResult(BpmProcessInstanceResultEnum.ADD_SIGN_BEFORE.getResult()) | 733 | + .setResult(BpmProcessInstanceResultEnum.SIGN_BEFORE.getResult()) |
| 732 | .setReason(reqVO.getReason())); | 734 | .setReason(reqVO.getReason())); |
| 733 | } | 735 | } |
| 734 | // 2.4 记录加签方式,完成任务时需要用到判断 | 736 | // 2.4 记录加签方式,完成任务时需要用到判断 |
| @@ -737,12 +739,12 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -737,12 +739,12 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 737 | taskService.saveTask(taskEntity); | 739 | taskService.saveTask(taskEntity); |
| 738 | 740 | ||
| 739 | // 3. 创建加签任务 | 741 | // 3. 创建加签任务 |
| 740 | - createAddSignChildrenTasks(convertList(reqVO.getUserIdList(), String::valueOf), taskEntity); | 742 | + createSignTask(convertList(reqVO.getUserIdList(), String::valueOf), taskEntity); |
| 741 | 743 | ||
| 742 | // 4. 记录加签 comment,拼接结果为: [当前用户]向前加签/向后加签给了[多个用户],理由为:reason | 744 | // 4. 记录加签 comment,拼接结果为: [当前用户]向前加签/向后加签给了[多个用户],理由为:reason |
| 743 | AdminUserRespDTO currentUser = adminUserApi.getUser(userId); | 745 | AdminUserRespDTO currentUser = adminUserApi.getUser(userId); |
| 744 | - String comment = StrUtil.format(BpmCommentTypeEnum.ADD_SIGN.getTemplateComment(), currentUser.getNickname(), BpmTaskAddSignTypeEnum.formatDesc(reqVO.getType()), | ||
| 745 | - String.join(",", convertList(userList, AdminUserRespDTO::getNickname)), reqVO.getReason()); | 746 | + String comment = StrUtil.format(BpmCommentTypeEnum.ADD_SIGN.getComment(), currentUser.getNickname(), |
| 747 | + BpmTaskAddSignTypeEnum.formatDesc(reqVO.getType()), String.join(",", convertList(userList, AdminUserRespDTO::getNickname)), reqVO.getReason()); | ||
| 746 | taskService.addComment(reqVO.getId(), taskEntity.getProcessInstanceId(), | 748 | taskService.addComment(reqVO.getId(), taskEntity.getProcessInstanceId(), |
| 747 | BpmCommentTypeEnum.ADD_SIGN.getType().toString(), comment); | 749 | BpmCommentTypeEnum.ADD_SIGN.getType().toString(), comment); |
| 748 | } | 750 | } |
| @@ -786,7 +788,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -786,7 +788,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 786 | * @param addSingUserIdList 被加签的用户 ID | 788 | * @param addSingUserIdList 被加签的用户 ID |
| 787 | * @param taskEntity 被加签的任务 | 789 | * @param taskEntity 被加签的任务 |
| 788 | */ | 790 | */ |
| 789 | - private void createAddSignChildrenTasks(List<String> addSingUserIdList, TaskEntityImpl taskEntity) { | 791 | + private void createSignTask(List<String> addSingUserIdList, TaskEntityImpl taskEntity) { |
| 790 | if (CollUtil.isEmpty(addSingUserIdList)) { | 792 | if (CollUtil.isEmpty(addSingUserIdList)) { |
| 791 | return; | 793 | return; |
| 792 | } | 794 | } |
| @@ -795,23 +797,22 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -795,23 +797,22 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 795 | if (StrUtil.isBlank(addSignId)) { | 797 | if (StrUtil.isBlank(addSignId)) { |
| 796 | continue; | 798 | continue; |
| 797 | } | 799 | } |
| 798 | - createChildrenTask(taskEntity, addSignId); | 800 | + createSignTask(taskEntity, addSignId); |
| 799 | } | 801 | } |
| 800 | } | 802 | } |
| 801 | 803 | ||
| 802 | /** | 804 | /** |
| 803 | - * 创建子任务 | 805 | + * 创建加签子任务 |
| 804 | * | 806 | * |
| 805 | * @param parentTask 父任务 | 807 | * @param parentTask 父任务 |
| 806 | * @param assignee 子任务的执行人 | 808 | * @param assignee 子任务的执行人 |
| 807 | - * @return | ||
| 808 | */ | 809 | */ |
| 809 | - private void createChildrenTask(TaskEntityImpl parentTask, String assignee) { | 810 | + private void createSignTask(TaskEntityImpl parentTask, String assignee) { |
| 810 | // 1. 生成子任务 | 811 | // 1. 生成子任务 |
| 811 | TaskEntityImpl task = (TaskEntityImpl) taskService.newTask(IdUtil.fastSimpleUUID()); | 812 | TaskEntityImpl task = (TaskEntityImpl) taskService.newTask(IdUtil.fastSimpleUUID()); |
| 812 | task = BpmTaskConvert.INSTANCE.convert(task, parentTask); | 813 | task = BpmTaskConvert.INSTANCE.convert(task, parentTask); |
| 813 | if (BpmTaskAddSignTypeEnum.BEFORE.getType().equals(parentTask.getScopeType())) { | 814 | if (BpmTaskAddSignTypeEnum.BEFORE.getType().equals(parentTask.getScopeType())) { |
| 814 | - // 2.1 前加签,才设置审批人,否则设置 owner | 815 | + // 2.1 前加签,设置审批人 |
| 815 | task.setAssignee(assignee); | 816 | task.setAssignee(assignee); |
| 816 | } else { | 817 | } else { |
| 817 | // 2.2.1 设置 owner 不设置 assignee 是因为不能同时审批,需要等父任务完成 | 818 | // 2.2.1 设置 owner 不设置 assignee 是因为不能同时审批,需要等父任务完成 |
| @@ -825,9 +826,10 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -825,9 +826,10 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 825 | 826 | ||
| 826 | @Override | 827 | @Override |
| 827 | @Transactional(rollbackFor = Exception.class) | 828 | @Transactional(rollbackFor = Exception.class) |
| 828 | - public void subSignTask(Long userId, BpmTaskSubSignReqVO reqVO) { | 829 | + public void deleteSignTask(Long userId, BpmTaskSubSignReqVO reqVO) { |
| 830 | + // 1.1 校验 task 可以被减签 | ||
| 829 | Task task = validateSubSign(reqVO.getId()); | 831 | Task task = validateSubSign(reqVO.getId()); |
| 830 | - AdminUserRespDTO user = adminUserApi.getUser(userId); | 832 | + // 1.2 校验取消人存在 |
| 831 | AdminUserRespDTO cancelUser = null; | 833 | AdminUserRespDTO cancelUser = null; |
| 832 | if (StrUtil.isNotBlank(task.getAssignee())) { | 834 | if (StrUtil.isNotBlank(task.getAssignee())) { |
| 833 | cancelUser = adminUserApi.getUser(NumberUtils.parseLong(task.getAssignee())); | 835 | cancelUser = adminUserApi.getUser(NumberUtils.parseLong(task.getAssignee())); |
| @@ -836,20 +838,24 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -836,20 +838,24 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 836 | cancelUser = adminUserApi.getUser(NumberUtils.parseLong(task.getOwner())); | 838 | cancelUser = adminUserApi.getUser(NumberUtils.parseLong(task.getOwner())); |
| 837 | } | 839 | } |
| 838 | Assert.notNull(cancelUser, "任务中没有所有者和审批人,数据错误"); | 840 | Assert.notNull(cancelUser, "任务中没有所有者和审批人,数据错误"); |
| 839 | - //1. 获取所有需要删除的任务 ID ,包含当前任务和所有子任务 | 841 | + |
| 842 | + // 2. 删除任务和对应子任务 | ||
| 843 | + // 2.1 获取所有需要删除的任务 ID ,包含当前任务和所有子任务 | ||
| 840 | List<String> allTaskIdList = getAllChildTaskIds(task.getId()); | 844 | List<String> allTaskIdList = getAllChildTaskIds(task.getId()); |
| 841 | - //2. 删除任务和所有子任务 | 845 | + // 2.2 删除任务和所有子任务 |
| 842 | taskService.deleteTasks(allTaskIdList); | 846 | taskService.deleteTasks(allTaskIdList); |
| 843 | - //3. 修改扩展表状态为取消 | 847 | + // 2.3 修改扩展表状态为取消 |
| 848 | + AdminUserRespDTO user = adminUserApi.getUser(userId); | ||
| 844 | taskExtMapper.updateBatchByTaskIdList(allTaskIdList, new BpmTaskExtDO().setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()) | 849 | taskExtMapper.updateBatchByTaskIdList(allTaskIdList, new BpmTaskExtDO().setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()) |
| 845 | .setReason(StrUtil.format("由于{}操作[减签],任务被取消", user.getNickname()))); | 850 | .setReason(StrUtil.format("由于{}操作[减签],任务被取消", user.getNickname()))); |
| 846 | - //4.记录日志到父任务中 先记录日志是因为,通过 handleParentTask 方法之后,任务可能被完成了,并且不存在了,会报异常,所以先记录 | ||
| 847 | - String comment = StrUtil.format(BpmCommentTypeEnum.SUB_SIGN.getTemplateComment(), user.getNickname(), cancelUser.getNickname()); | 851 | + |
| 852 | + // 3. 记录日志到父任务中。先记录日志是因为,通过 handleParentTask 方法之后,任务可能被完成了,并且不存在了,会报异常,所以先记录 | ||
| 853 | + String comment = StrUtil.format(BpmCommentTypeEnum.SUB_SIGN.getComment(), user.getNickname(), cancelUser.getNickname()); | ||
| 848 | taskService.addComment(task.getParentTaskId(), task.getProcessInstanceId(), | 854 | taskService.addComment(task.getParentTaskId(), task.getProcessInstanceId(), |
| 849 | BpmCommentTypeEnum.SUB_SIGN.getType().toString(), comment); | 855 | BpmCommentTypeEnum.SUB_SIGN.getType().toString(), comment); |
| 850 | - //5. 处理当前任务的父任务 | ||
| 851 | - this.handleParentTask(task); | ||
| 852 | 856 | ||
| 857 | + // 4. 处理当前任务的父任务 | ||
| 858 | + handleParentTask(task); | ||
| 853 | } | 859 | } |
| 854 | 860 | ||
| 855 | /** | 861 | /** |
| @@ -860,14 +866,29 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -860,14 +866,29 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 860 | */ | 866 | */ |
| 861 | private Task validateSubSign(String id) { | 867 | private Task validateSubSign(String id) { |
| 862 | Task task = validateTaskExist(id); | 868 | Task task = validateTaskExist(id); |
| 863 | - //必须有parentId | ||
| 864 | - if (StrUtil.isEmpty(task.getParentTaskId())) { | 869 | + |
| 870 | + // 必须有 scopeType | ||
| 871 | + String scopeType = task.getScopeType(); | ||
| 872 | + if (StrUtil.isEmpty(scopeType)) { | ||
| 873 | + throw exception(TASK_SUB_SIGN_NO_PARENT); | ||
| 874 | + } | ||
| 875 | + // 并且值为 向前和向后加签 | ||
| 876 | + if (!validateSignType(scopeType)) { | ||
| 865 | throw exception(TASK_SUB_SIGN_NO_PARENT); | 877 | throw exception(TASK_SUB_SIGN_NO_PARENT); |
| 866 | } | 878 | } |
| 867 | return task; | 879 | return task; |
| 868 | } | 880 | } |
| 869 | 881 | ||
| 870 | /** | 882 | /** |
| 883 | + * 判断当前类型是否为加签 | ||
| 884 | + * @param scopeType 任务的 scopeType | ||
| 885 | + * @return 当前 scopeType 为加签则返回 true | ||
| 886 | + */ | ||
| 887 | + private boolean validateSignType(String scopeType){ | ||
| 888 | + return StrUtil.equalsAny(scopeType,BpmTaskAddSignTypeEnum.BEFORE.getType(),scopeType, BpmTaskAddSignTypeEnum.AFTER.getType()); | ||
| 889 | + } | ||
| 890 | + | ||
| 891 | + /** | ||
| 871 | * 获取所有要被取消的删除的任务 ID 集合 | 892 | * 获取所有要被取消的删除的任务 ID 集合 |
| 872 | * | 893 | * |
| 873 | * @param parentTaskId 父级任务ID | 894 | * @param parentTaskId 父级任务ID |
| @@ -875,25 +896,40 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -875,25 +896,40 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 875 | */ | 896 | */ |
| 876 | public List<String> getAllChildTaskIds(String parentTaskId) { | 897 | public List<String> getAllChildTaskIds(String parentTaskId) { |
| 877 | List<String> allChildTaskIds = new ArrayList<>(); | 898 | List<String> allChildTaskIds = new ArrayList<>(); |
| 878 | - //1. 先将自己放入 | ||
| 879 | - allChildTaskIds.add(parentTaskId); | ||
| 880 | - //2. 递归获取子级 | ||
| 881 | - recursiveGetChildTaskIds(parentTaskId, allChildTaskIds); | 899 | + // 1. 递归获取子级 |
| 900 | + Stack<String> stack = new Stack<>(); | ||
| 901 | + // 1.1 将根任务ID入栈 | ||
| 902 | + stack.push(parentTaskId); | ||
| 903 | + //控制遍历的次数不超过 Byte.MAX_VALUE,避免脏数据造成死循环 | ||
| 904 | + int count = 0; | ||
| 905 | + // TODO @海:< 的前后空格,要注意哈; | ||
| 906 | + while (!stack.isEmpty() && count<Byte.MAX_VALUE) { | ||
| 907 | + // 1.2 弹出栈顶任务ID | ||
| 908 | + String taskId = stack.pop(); | ||
| 909 | + // 1.3 将任务ID添加到结果集合中 | ||
| 910 | + allChildTaskIds.add(taskId); | ||
| 911 | + // 1.4 获取该任务的子任务列表 | ||
| 912 | + // TODO @海:有个更高效的写法;一次性去 in 一层;不然每个节点,都去查询一次 db, 太浪费了;每次 in,最终就是 O(h) 查询,而不是 O(n) 查询; | ||
| 913 | + List<String> childrenTaskIdList = getChildrenTaskIdList(taskId); | ||
| 914 | + if (CollUtil.isNotEmpty(childrenTaskIdList)) { | ||
| 915 | + for (String childTaskId : childrenTaskIdList) { | ||
| 916 | + // 1.5 将子任务ID入栈,以便后续处理 | ||
| 917 | + stack.push(childTaskId); | ||
| 918 | + } | ||
| 919 | + } | ||
| 920 | + count++; | ||
| 921 | + } | ||
| 882 | return allChildTaskIds; | 922 | return allChildTaskIds; |
| 883 | } | 923 | } |
| 884 | 924 | ||
| 885 | /** | 925 | /** |
| 886 | - * 递归处理子级任务 | 926 | + * 获取指定父级任务的所有子任务 ID 集合 |
| 887 | * | 927 | * |
| 888 | - * @param taskId 当前任务ID | ||
| 889 | - * @param taskIds 结果 | 928 | + * @param parentTaskId 父任务 ID |
| 929 | + * @return 所有子任务的 ID 集合 | ||
| 890 | */ | 930 | */ |
| 891 | - private void recursiveGetChildTaskIds(String taskId, List<String> taskIds) { | ||
| 892 | - List<String> childrenTaskIdList = getChildrenTaskIdList(taskId); | ||
| 893 | - for (String childTaskId : childrenTaskIdList) { | ||
| 894 | - taskIds.add(childTaskId); // 将子任务的ID添加到集合中 | ||
| 895 | - recursiveGetChildTaskIds(childTaskId, taskIds); // 递归获取子任务的子任务 | ||
| 896 | - } | 931 | + private List<String> getChildrenTaskIdList(String parentTaskId) { |
| 932 | + return convertList(getChildrenTaskList0(parentTaskId), Task::getId); | ||
| 897 | } | 933 | } |
| 898 | 934 | ||
| 899 | /** | 935 | /** |
| @@ -902,33 +938,32 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -902,33 +938,32 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 902 | * @param parentTaskId 父任务 ID | 938 | * @param parentTaskId 父任务 ID |
| 903 | * @return 所有子任务的 ID 集合 | 939 | * @return 所有子任务的 ID 集合 |
| 904 | */ | 940 | */ |
| 905 | - private List<String> getChildrenTaskIdList(String parentTaskId) { | 941 | + private List<Task> getChildrenTaskList0(String parentTaskId) { |
| 906 | String tableName = managementService.getTableName(TaskEntity.class); | 942 | String tableName = managementService.getTableName(TaskEntity.class); |
| 907 | - String sql = "select ID_ from " + tableName + " where PARENT_TASK_ID_=#{parentTaskId}"; | ||
| 908 | - List<Task> childrenTaskList = taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).list(); | ||
| 909 | - return convertList(childrenTaskList, Task::getId); | 943 | + // taskService.createTaskQuery() 没有 parentId 参数,所以写 sql 查询 |
| 944 | + String sql = "select ID_,OWNER_,ASSIGNEE_ from " + tableName + " where PARENT_TASK_ID_=#{parentTaskId}"; | ||
| 945 | + return taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).list(); | ||
| 910 | } | 946 | } |
| 911 | 947 | ||
| 948 | + | ||
| 912 | @Override | 949 | @Override |
| 913 | - public List<BpmTaskSubSignRespVO> getChildrenTaskList(String taskId) { | ||
| 914 | - List<String> childrenTaskIdList = getChildrenTaskIdList(taskId); | ||
| 915 | - if (CollUtil.isEmpty(childrenTaskIdList)) { | 950 | + public List<BpmTaskSubSignRespVO> getChildrenTaskList(String parentId) { |
| 951 | + // 1. 只查询进行中的任务 后加签的任务,可能不存在 assignee,所以还需要查询 owner | ||
| 952 | + List<Task> taskList = getChildrenTaskList0(parentId); | ||
| 953 | + if (CollUtil.isEmpty(taskList)) { | ||
| 916 | return Collections.emptyList(); | 954 | return Collections.emptyList(); |
| 917 | } | 955 | } |
| 918 | - //1. 只查询进行中的任务 | ||
| 919 | - List<BpmTaskExtDO> bpmTaskExtDOList = taskExtMapper.selectProcessListByTaskIds(childrenTaskIdList); | ||
| 920 | - //2. 后加签的任务,可能不存在 assignee,所以还需要查询 owner | ||
| 921 | - List<Task> taskList = taskService.createTaskQuery().taskIds(childrenTaskIdList).list(); | ||
| 922 | - Map<String, Task> idTaskMap = convertMap(taskList, TaskInfo::getId); | ||
| 923 | - //3. 将 owner 和 assignee 统一到一个集合中 | ||
| 924 | - List<Long> userIds = taskList.stream() | ||
| 925 | - .flatMap(control -> | ||
| 926 | - Stream.of(control.getAssignee(), control.getOwner()) | ||
| 927 | - .filter(Objects::nonNull)) | ||
| 928 | - .distinct() | ||
| 929 | - .map(NumberUtils::parseLong) | ||
| 930 | - .collect(Collectors.toList()); | 956 | + List<String> childrenTaskIdList = convertList(taskList, Task::getId); |
| 957 | + | ||
| 958 | + // 2.1 将 owner 和 assignee 统一到一个集合中 | ||
| 959 | + List<Long> userIds = convertListByFlatMap(taskList, control -> | ||
| 960 | + Stream.of(NumberUtils.parseLong(control.getAssignee()), NumberUtils.parseLong(control.getOwner())) | ||
| 961 | + .filter(Objects::nonNull)); | ||
| 962 | + // 2.2 组装数据 | ||
| 931 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds); | 963 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds); |
| 932 | - return BpmTaskConvert.INSTANCE.convertList(bpmTaskExtDOList, userMap, idTaskMap); | 964 | + List<BpmTaskExtDO> taskExtList = taskExtMapper.selectProcessListByTaskIds(childrenTaskIdList); |
| 965 | + Map<String, Task> idTaskMap = convertMap(taskList, TaskInfo::getId); | ||
| 966 | + return BpmTaskConvert.INSTANCE.convertList(taskExtList, userMap, idTaskMap); | ||
| 933 | } | 967 | } |
| 968 | + | ||
| 934 | } | 969 | } |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DatabaseDocController.java
| @@ -147,7 +147,7 @@ public class DatabaseDocController { | @@ -147,7 +147,7 @@ public class DatabaseDocController { | ||
| 147 | */ | 147 | */ |
| 148 | private static ProcessConfig buildProcessConfig() { | 148 | private static ProcessConfig buildProcessConfig() { |
| 149 | return ProcessConfig.builder() | 149 | return ProcessConfig.builder() |
| 150 | - .ignoreTablePrefix(Arrays.asList("QRTZ_", "ACT_")) // 忽略表前缀 | 150 | + .ignoreTablePrefix(Arrays.asList("QRTZ_", "ACT_", "FLW_")) // 忽略表前缀 |
| 151 | .build(); | 151 | .build(); |
| 152 | } | 152 | } |
| 153 | 153 |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/security/config/SecurityConfiguration.java
| @@ -29,8 +29,6 @@ public class SecurityConfiguration { | @@ -29,8 +29,6 @@ public class SecurityConfiguration { | ||
| 29 | .antMatchers("/swagger-resources/**").anonymous() | 29 | .antMatchers("/swagger-resources/**").anonymous() |
| 30 | .antMatchers("/webjars/**").anonymous() | 30 | .antMatchers("/webjars/**").anonymous() |
| 31 | .antMatchers("/*/api-docs").anonymous(); | 31 | .antMatchers("/*/api-docs").anonymous(); |
| 32 | - // 积木报表 | ||
| 33 | - registry.antMatchers("/jmreport/**").permitAll(); | ||
| 34 | // Spring Boot Actuator 的安全配置 | 32 | // Spring Boot Actuator 的安全配置 |
| 35 | registry.antMatchers("/actuator").anonymous() | 33 | registry.antMatchers("/actuator").anonymous() |
| 36 | .antMatchers("/actuator/**").anonymous(); | 34 | .antMatchers("/actuator/**").anonymous(); |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/JobLogCleanJob.java renamed to yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/job/JobLogCleanJob.java
| 1 | -package cn.iocoder.yudao.module.infra.job.logger; | 1 | +package cn.iocoder.yudao.module.infra.job.job; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; | 3 | import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; |
| 4 | import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; | 4 | import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; |
| @@ -33,7 +33,7 @@ public class JobLogCleanJob implements JobHandler { | @@ -33,7 +33,7 @@ public class JobLogCleanJob implements JobHandler { | ||
| 33 | @TenantIgnore | 33 | @TenantIgnore |
| 34 | public String execute(String param) { | 34 | public String execute(String param) { |
| 35 | Integer count = jobLogService.cleanJobLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT); | 35 | Integer count = jobLogService.cleanJobLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT); |
| 36 | - log.info("[count][定时执行清理定时任务日志数量 ({}) 个]", count); | 36 | + log.info("[execute][定时执行清理定时任务日志数量 ({}) 个]", count); |
| 37 | return String.format("定时执行清理定时任务日志数量 %s 个", count); | 37 | return String.format("定时执行清理定时任务日志数量 %s 个", count); |
| 38 | } | 38 | } |
| 39 | 39 |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/job/AccessLogCleanJob.java renamed to yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/AccessLogCleanJob.java
| 1 | -package cn.iocoder.yudao.module.infra.job.job; | 1 | +package cn.iocoder.yudao.module.infra.job.logger; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; | 3 | import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; |
| 4 | import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; | 4 | import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; |
| @@ -34,7 +34,7 @@ public class AccessLogCleanJob implements JobHandler { | @@ -34,7 +34,7 @@ public class AccessLogCleanJob implements JobHandler { | ||
| 34 | @TenantIgnore | 34 | @TenantIgnore |
| 35 | public String execute(String param) { | 35 | public String execute(String param) { |
| 36 | Integer count = apiAccessLogService.cleanAccessLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT); | 36 | Integer count = apiAccessLogService.cleanAccessLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT); |
| 37 | - log.info("[count][定时执行清理访问日志数量 ({}) 个]", count); | 37 | + log.info("[execute][定时执行清理访问日志数量 ({}) 个]", count); |
| 38 | return String.format("定时执行清理错误日志数量 %s 个", count); | 38 | return String.format("定时执行清理错误日志数量 %s 个", count); |
| 39 | } | 39 | } |
| 40 | 40 |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/job/ErrorLogCleanJob.java renamed to yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/ErrorLogCleanJob.java
| 1 | -package cn.iocoder.yudao.module.infra.job.job; | 1 | +package cn.iocoder.yudao.module.infra.job.logger; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; | 3 | import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; |
| 4 | import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; | 4 | import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; |
| @@ -34,7 +34,7 @@ public class ErrorLogCleanJob implements JobHandler { | @@ -34,7 +34,7 @@ public class ErrorLogCleanJob implements JobHandler { | ||
| 34 | @TenantIgnore | 34 | @TenantIgnore |
| 35 | public String execute(String param) { | 35 | public String execute(String param) { |
| 36 | Integer count = apiErrorLogService.cleanErrorLog(JOB_CLEAN_RETAIN_DAY,DELETE_LIMIT); | 36 | Integer count = apiErrorLogService.cleanErrorLog(JOB_CLEAN_RETAIN_DAY,DELETE_LIMIT); |
| 37 | - log.info("[count][定时执行清理错误日志数量 ({}) 个]", count); | 37 | + log.info("[execute][定时执行清理错误日志数量 ({}) 个]", count); |
| 38 | return String.format("定时执行清理错误日志数量 %s 个", count); | 38 | return String.format("定时执行清理错误日志数量 %s 个", count); |
| 39 | } | 39 | } |
| 40 | 40 |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImpl.java
| @@ -58,9 +58,9 @@ public class FileConfigServiceImpl implements FileConfigService { | @@ -58,9 +58,9 @@ public class FileConfigServiceImpl implements FileConfigService { | ||
| 58 | FileConfigDO config = Objects.equals(CACHE_MASTER_ID, id) ? | 58 | FileConfigDO config = Objects.equals(CACHE_MASTER_ID, id) ? |
| 59 | fileConfigMapper.selectByMaster() : fileConfigMapper.selectById(id); | 59 | fileConfigMapper.selectByMaster() : fileConfigMapper.selectById(id); |
| 60 | if (config != null) { | 60 | if (config != null) { |
| 61 | - fileClientFactory.createOrUpdateFileClient(id, config.getStorage(), config.getConfig()); | 61 | + fileClientFactory.createOrUpdateFileClient(config.getId(), config.getStorage(), config.getConfig()); |
| 62 | } | 62 | } |
| 63 | - return fileClientFactory.getFileClient(id); | 63 | + return fileClientFactory.getFileClient(null == config ? id : config.getId()); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | }); | 66 | }); |
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben/api/api.ts.vm
| @@ -28,5 +28,5 @@ export function delete${simpleClassName}(id: number) { | @@ -28,5 +28,5 @@ export function delete${simpleClassName}(id: number) { | ||
| 28 | 28 | ||
| 29 | // 导出${table.classComment} Excel | 29 | // 导出${table.classComment} Excel |
| 30 | export function export${simpleClassName}(params) { | 30 | export function export${simpleClassName}(params) { |
| 31 | - return defHttp.download({ url: '${baseURL}/export-excel', params }, '${table.classComment}.xls') | 31 | + return defHttp.download({ url: '${baseURL}/export-excel', params }, '${table.classComment}.xls') |
| 32 | } | 32 | } |
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben/views/data.ts.vm
| 1 | -import type { BasicColumn, FormSchema } from '@/components/Table' | ||
| 2 | -import { useRender } from '@/components/Table' | ||
| 3 | -import { DICT_TYPE, getDictOptions } from '@/utils/dict' | 1 | +import type {BasicColumn, FormSchema} from '@/components/Table' |
| 2 | +import {useRender} from '@/components/Table' | ||
| 3 | +import {DICT_TYPE, getDictOptions} from '@/utils/dict' | ||
| 4 | 4 | ||
| 5 | export const columns: BasicColumn[] = [ | 5 | export const columns: BasicColumn[] = [ |
| 6 | #foreach($column in $columns) | 6 | #foreach($column in $columns) |
| @@ -50,7 +50,7 @@ export const searchFormSchema: FormSchema[] = [ | @@ -50,7 +50,7 @@ export const searchFormSchema: FormSchema[] = [ | ||
| 50 | field: '${javaField}', | 50 | field: '${javaField}', |
| 51 | #if ($column.htmlType == "input") | 51 | #if ($column.htmlType == "input") |
| 52 | component: 'Input', | 52 | component: 'Input', |
| 53 | - #elseif ($column.htmlType == "select" || $column.htmlType == "radio") | 53 | + #elseif ($column.htmlType == "select") |
| 54 | component: 'Select', | 54 | component: 'Select', |
| 55 | componentProps: { | 55 | componentProps: { |
| 56 | #if ("" != $dictType)## 设置了 dictType 数据字典的情况 | 56 | #if ("" != $dictType)## 设置了 dictType 数据字典的情况 |
| @@ -59,6 +59,15 @@ export const searchFormSchema: FormSchema[] = [ | @@ -59,6 +59,15 @@ export const searchFormSchema: FormSchema[] = [ | ||
| 59 | options: [], | 59 | options: [], |
| 60 | #end | 60 | #end |
| 61 | }, | 61 | }, |
| 62 | + #elseif ($column.htmlType == "radio") | ||
| 63 | + component: 'Radio', | ||
| 64 | + componentProps: { | ||
| 65 | + #if ("" != $dictType)## 设置了 dictType 数据字典的情况 | ||
| 66 | + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase()), | ||
| 67 | + #else## 未设置 dictType 数据字典的情况 | ||
| 68 | + options: [], | ||
| 69 | + #end | ||
| 70 | + }, | ||
| 62 | #elseif($column.htmlType == "datetime") | 71 | #elseif($column.htmlType == "datetime") |
| 63 | component: 'RangePicker', | 72 | component: 'RangePicker', |
| 64 | #end | 73 | #end |
| @@ -181,7 +190,8 @@ export const updateFormSchema: FormSchema[] = [ | @@ -181,7 +190,8 @@ export const updateFormSchema: FormSchema[] = [ | ||
| 181 | fileType: 'file', | 190 | fileType: 'file', |
| 182 | maxCount: 1, | 191 | maxCount: 1, |
| 183 | }, | 192 | }, |
| 184 | - #elseif($column.htmlType == "editor")## 文本编辑器component: 'Editor', | 193 | + #elseif($column.htmlType == "editor")## 文本编辑器 |
| 194 | + component: 'Editor', | ||
| 185 | #elseif($column.htmlType == "select")## 下拉框 | 195 | #elseif($column.htmlType == "select")## 下拉框 |
| 186 | component: 'Select', | 196 | component: 'Select', |
| 187 | componentProps: { | 197 | componentProps: { |
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben/views/index.vue.vm
| 1 | <script lang="ts" setup> | 1 | <script lang="ts" setup> |
| 2 | -import ${ simpleClassName }Modal from './${simpleClassName}Modal.vue' | 2 | +import ${simpleClassName}Modal from './${simpleClassName}Modal.vue' |
| 3 | import { columns, searchFormSchema } from './${classNameVar}.data' | 3 | import { columns, searchFormSchema } from './${classNameVar}.data' |
| 4 | import { useI18n } from '@/hooks/web/useI18n' | 4 | import { useI18n } from '@/hooks/web/useI18n' |
| 5 | import { useMessage } from '@/hooks/web/useMessage' | 5 | import { useMessage } from '@/hooks/web/useMessage' |
| 6 | import { useModal } from '@/components/Modal' | 6 | import { useModal } from '@/components/Modal' |
| 7 | -import { IconEnum } from '@/enums/appEnum' | ||
| 8 | -import { BasicTable, useTable, TableAction } from '@/components/Table' | ||
| 9 | -import { delete${ simpleClassName }, export${ simpleClassName }, get${ simpleClassName } Page } from '@/api/${table.moduleName}/${classNameVar}' | 7 | +import { useTable } from '@/components/Table' |
| 8 | +import { delete${simpleClassName}, export${simpleClassName}, get${simpleClassName}Page } from '@/api/${table.moduleName}/${classNameVar}' | ||
| 10 | 9 | ||
| 11 | defineOptions({ name: '${table.className}' }) | 10 | defineOptions({ name: '${table.className}' }) |
| 12 | 11 | ||
| @@ -16,7 +15,7 @@ const [registerModal, { openModal }] = useModal() | @@ -16,7 +15,7 @@ const [registerModal, { openModal }] = useModal() | ||
| 16 | 15 | ||
| 17 | const [registerTable, { getForm, reload }] = useTable({ | 16 | const [registerTable, { getForm, reload }] = useTable({ |
| 18 | title: '${table.classComment}列表', | 17 | title: '${table.classComment}列表', |
| 19 | - api: get${ simpleClassName }Page, | 18 | + api: get${simpleClassName}Page, |
| 20 | columns, | 19 | columns, |
| 21 | formConfig: { labelWidth: 120, schemas: searchFormSchema }, | 20 | formConfig: { labelWidth: 120, schemas: searchFormSchema }, |
| 22 | useSearchForm: true, | 21 | useSearchForm: true, |
| @@ -43,14 +42,14 @@ async function handleExport() { | @@ -43,14 +42,14 @@ async function handleExport() { | ||
| 43 | iconType: 'warning', | 42 | iconType: 'warning', |
| 44 | content: t('common.exportMessage'), | 43 | content: t('common.exportMessage'), |
| 45 | async onOk() { | 44 | async onOk() { |
| 46 | - await export${ simpleClassName } (getForm().getFieldsValue()) | 45 | + await export${simpleClassName}(getForm().getFieldsValue()) |
| 47 | createMessage.success(t('common.exportSuccessText')) | 46 | createMessage.success(t('common.exportSuccessText')) |
| 48 | }, | 47 | }, |
| 49 | }) | 48 | }) |
| 50 | } | 49 | } |
| 51 | 50 | ||
| 52 | async function handleDelete(record: Recordable) { | 51 | async function handleDelete(record: Recordable) { |
| 53 | - await delete${ simpleClassName } (record.id) | 52 | + await delete${simpleClassName}(record.id) |
| 54 | createMessage.success(t('common.delSuccessText')) | 53 | createMessage.success(t('common.delSuccessText')) |
| 55 | reload() | 54 | reload() |
| 56 | } | 55 | } |
| @@ -62,7 +61,7 @@ async function handleDelete(record: Recordable) { | @@ -62,7 +61,7 @@ async function handleDelete(record: Recordable) { | ||
| 62 | <a-button type="primary" v-auth="['${permissionPrefix}:create']" :preIcon="IconEnum.ADD" @click="handleCreate"> | 61 | <a-button type="primary" v-auth="['${permissionPrefix}:create']" :preIcon="IconEnum.ADD" @click="handleCreate"> |
| 63 | {{ t('action.create') }} | 62 | {{ t('action.create') }} |
| 64 | </a-button> | 63 | </a-button> |
| 65 | - <a-button type="warning" v-auth="['${permissionPrefix}:export']" :preIcon="IconEnum.EXPORT" @click="handleExport"> | 64 | + <a-button v-auth="['${permissionPrefix}:export']" :preIcon="IconEnum.EXPORT" @click="handleExport"> |
| 66 | {{ t('action.export') }} | 65 | {{ t('action.export') }} |
| 67 | </a-button> | 66 | </a-button> |
| 68 | </template> | 67 | </template> |
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java
| @@ -258,12 +258,12 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest { | @@ -258,12 +258,12 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest { | ||
| 258 | Long id = fileConfig.getId(); | 258 | Long id = fileConfig.getId(); |
| 259 | // mock 获得 Client | 259 | // mock 获得 Client |
| 260 | FileClient fileClient = new LocalFileClient(id, new LocalFileClientConfig()); | 260 | FileClient fileClient = new LocalFileClient(id, new LocalFileClientConfig()); |
| 261 | - when(fileClientFactory.getFileClient(eq(0L))).thenReturn(fileClient); | 261 | + when(fileClientFactory.getFileClient(eq(fileConfig.getId()))).thenReturn(fileClient); |
| 262 | 262 | ||
| 263 | // 调用,并断言 | 263 | // 调用,并断言 |
| 264 | assertSame(fileClient, fileConfigService.getMasterFileClient()); | 264 | assertSame(fileClient, fileConfigService.getMasterFileClient()); |
| 265 | // 断言缓存 | 265 | // 断言缓存 |
| 266 | - verify(fileClientFactory).createOrUpdateFileClient(eq(0L), eq(fileConfig.getStorage()), | 266 | + verify(fileClientFactory).createOrUpdateFileClient(eq(fileConfig.getId()), eq(fileConfig.getStorage()), |
| 267 | eq(fileConfig.getConfig())); | 267 | eq(fileConfig.getConfig())); |
| 268 | } | 268 | } |
| 269 | 269 |
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/dto/ProductCommentCreateReqDTO.java
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.api.comment.dto; | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.api.comment.dto; | ||
| 2 | 2 | ||
| 3 | import lombok.Data; | 3 | import lombok.Data; |
| 4 | 4 | ||
| 5 | +import javax.validation.constraints.NotNull; | ||
| 5 | import java.util.List; | 6 | import java.util.List; |
| 6 | 7 | ||
| 7 | /** | 8 | /** |
| @@ -15,6 +16,7 @@ public class ProductCommentCreateReqDTO { | @@ -15,6 +16,7 @@ public class ProductCommentCreateReqDTO { | ||
| 15 | /** | 16 | /** |
| 16 | * 商品 SKU 编号 | 17 | * 商品 SKU 编号 |
| 17 | */ | 18 | */ |
| 19 | + @NotNull(message = "商品 SKU 编号不能为空") | ||
| 18 | private Long skuId; | 20 | private Long skuId; |
| 19 | /** | 21 | /** |
| 20 | * 订单编号 | 22 | * 订单编号 |
| @@ -26,20 +28,19 @@ public class ProductCommentCreateReqDTO { | @@ -26,20 +28,19 @@ public class ProductCommentCreateReqDTO { | ||
| 26 | private Long orderItemId; | 28 | private Long orderItemId; |
| 27 | 29 | ||
| 28 | /** | 30 | /** |
| 29 | - * 评分星级 1-5 分 | ||
| 30 | - */ | ||
| 31 | - private Integer scores; | ||
| 32 | - /** | ||
| 33 | * 描述星级 1-5 分 | 31 | * 描述星级 1-5 分 |
| 34 | */ | 32 | */ |
| 33 | + @NotNull(message = "描述星级不能为空") | ||
| 35 | private Integer descriptionScores; | 34 | private Integer descriptionScores; |
| 36 | /** | 35 | /** |
| 37 | * 服务星级 1-5 分 | 36 | * 服务星级 1-5 分 |
| 38 | */ | 37 | */ |
| 38 | + @NotNull(message = "服务星级不能为空") | ||
| 39 | private Integer benefitScores; | 39 | private Integer benefitScores; |
| 40 | /** | 40 | /** |
| 41 | * 评论内容 | 41 | * 评论内容 |
| 42 | */ | 42 | */ |
| 43 | + @NotNull(message = "评论内容不能为空") | ||
| 43 | private String content; | 44 | private String content; |
| 44 | /** | 45 | /** |
| 45 | * 评论图片地址数组,以逗号分隔最多上传 9 张 | 46 | * 评论图片地址数组,以逗号分隔最多上传 9 张 |
| @@ -49,11 +50,12 @@ public class ProductCommentCreateReqDTO { | @@ -49,11 +50,12 @@ public class ProductCommentCreateReqDTO { | ||
| 49 | /** | 50 | /** |
| 50 | * 是否匿名 | 51 | * 是否匿名 |
| 51 | */ | 52 | */ |
| 53 | + @NotNull(message = "是否匿名不能为空") | ||
| 52 | private Boolean anonymous; | 54 | private Boolean anonymous; |
| 53 | /** | 55 | /** |
| 54 | * 评价人 | 56 | * 评价人 |
| 55 | */ | 57 | */ |
| 58 | + @NotNull(message = "评价人不能为空") | ||
| 56 | private Long userId; | 59 | private Long userId; |
| 57 | 60 | ||
| 58 | - | ||
| 59 | } | 61 | } |
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApi.java deleted
| 1 | -package cn.iocoder.yudao.module.product.api.property; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; | ||
| 4 | - | ||
| 5 | -import java.util.Collection; | ||
| 6 | -import java.util.List; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * 商品属性值 API 接口 | ||
| 10 | - * | ||
| 11 | - * @author 芋道源码 | ||
| 12 | - */ | ||
| 13 | -public interface ProductPropertyValueApi { | ||
| 14 | - | ||
| 15 | - /** | ||
| 16 | - * 根据编号数组,获得属性值列表 | ||
| 17 | - * | ||
| 18 | - * @param ids 编号数组 | ||
| 19 | - * @return 属性值明细列表 | ||
| 20 | - */ | ||
| 21 | - List<ProductPropertyValueDetailRespDTO> getPropertyValueDetailList(Collection<Long> ids); | ||
| 22 | - | ||
| 23 | -} |
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java
| @@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.product.api.spu.dto; | @@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.product.api.spu.dto; | ||
| 3 | import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; | 3 | import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; |
| 4 | import lombok.Data; | 4 | import lombok.Data; |
| 5 | 5 | ||
| 6 | -import java.util.List; | ||
| 7 | - | ||
| 8 | // TODO @LeeYan9: ProductSpuRespDTO | 6 | // TODO @LeeYan9: ProductSpuRespDTO |
| 9 | /** | 7 | /** |
| 10 | * 商品 SPU 信息 Response DTO | 8 | * 商品 SPU 信息 Response DTO |
| @@ -27,55 +25,22 @@ public class ProductSpuRespDTO { | @@ -27,55 +25,22 @@ public class ProductSpuRespDTO { | ||
| 27 | */ | 25 | */ |
| 28 | private String name; | 26 | private String name; |
| 29 | /** | 27 | /** |
| 30 | - * 关键字 | ||
| 31 | - */ | ||
| 32 | - private String keyword; | ||
| 33 | - /** | ||
| 34 | * 单位 | 28 | * 单位 |
| 35 | * | 29 | * |
| 36 | * 对应 product_unit 数据字典 | 30 | * 对应 product_unit 数据字典 |
| 37 | */ | 31 | */ |
| 38 | private Integer unit; | 32 | private Integer unit; |
| 39 | - /** | ||
| 40 | - * 商品简介 | ||
| 41 | - */ | ||
| 42 | - private String introduction; | ||
| 43 | - /** | ||
| 44 | - * 商品详情 | ||
| 45 | - */ | ||
| 46 | - private String description; | ||
| 47 | - // TODO @芋艿:是不是要删除 | ||
| 48 | - /** | ||
| 49 | - * 商品条码(一维码) | ||
| 50 | - */ | ||
| 51 | - private String barCode; | ||
| 52 | 33 | ||
| 53 | /** | 34 | /** |
| 54 | * 商品分类编号 | 35 | * 商品分类编号 |
| 55 | */ | 36 | */ |
| 56 | private Long categoryId; | 37 | private Long categoryId; |
| 57 | /** | 38 | /** |
| 58 | - * 商品品牌编号 | ||
| 59 | - */ | ||
| 60 | - private Long brandId; | ||
| 61 | - /** | ||
| 62 | * 商品封面图 | 39 | * 商品封面图 |
| 63 | */ | 40 | */ |
| 64 | private String picUrl; | 41 | private String picUrl; |
| 65 | - /** | ||
| 66 | - * 商品轮播图 | ||
| 67 | - */ | ||
| 68 | - private List<String> sliderPicUrls; | ||
| 69 | - /** | ||
| 70 | - * 商品视频 | ||
| 71 | - */ | ||
| 72 | - private String videoUrl; | ||
| 73 | 42 | ||
| 74 | /** | 43 | /** |
| 75 | - * 排序字段 | ||
| 76 | - */ | ||
| 77 | - private Integer sort; | ||
| 78 | - /** | ||
| 79 | * 商品状态 | 44 | * 商品状态 |
| 80 | * <p> | 45 | * <p> |
| 81 | * 枚举 {@link ProductSpuStatusEnum} | 46 | * 枚举 {@link ProductSpuStatusEnum} |
| @@ -124,22 +89,6 @@ public class ProductSpuRespDTO { | @@ -124,22 +89,6 @@ public class ProductSpuRespDTO { | ||
| 124 | */ | 89 | */ |
| 125 | private Integer giveIntegral; | 90 | private Integer giveIntegral; |
| 126 | 91 | ||
| 127 | - // ========== 统计相关字段 ========= | ||
| 128 | - | ||
| 129 | - /** | ||
| 130 | - * 商品销量 | ||
| 131 | - */ | ||
| 132 | - private Integer salesCount; | ||
| 133 | - /** | ||
| 134 | - * 虚拟销量 | ||
| 135 | - */ | ||
| 136 | - private Integer virtualSalesCount; | ||
| 137 | - /** | ||
| 138 | - * 商品点击量 | ||
| 139 | - */ | ||
| 140 | - private Integer clickCount; | ||
| 141 | - | ||
| 142 | - | ||
| 143 | // ========== 分销相关字段 ========= | 92 | // ========== 分销相关字段 ========= |
| 144 | 93 | ||
| 145 | /** | 94 | /** |
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/group/ProductGroupStyleEnum.java deleted
| 1 | -package cn.iocoder.yudao.module.product.enums.group; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | ||
| 4 | -import lombok.AllArgsConstructor; | ||
| 5 | -import lombok.Getter; | ||
| 6 | - | ||
| 7 | -import java.util.Arrays; | ||
| 8 | - | ||
| 9 | -/** | ||
| 10 | - * 商品分组的样式枚举 | ||
| 11 | - * | ||
| 12 | - * @author 芋道源码 | ||
| 13 | - */ | ||
| 14 | -@Getter | ||
| 15 | -@AllArgsConstructor | ||
| 16 | -public enum ProductGroupStyleEnum implements IntArrayValuable { | ||
| 17 | - | ||
| 18 | - ONE(1, "每列一个"), | ||
| 19 | - TWO(2, "每列两个"), | ||
| 20 | - THREE(2, "每列三个"),; | ||
| 21 | - | ||
| 22 | - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductGroupStyleEnum::getStyle).toArray(); | ||
| 23 | - | ||
| 24 | - /** | ||
| 25 | - * 列表样式 | ||
| 26 | - */ | ||
| 27 | - private final Integer style; | ||
| 28 | - /** | ||
| 29 | - * 状态名 | ||
| 30 | - */ | ||
| 31 | - private final String name; | ||
| 32 | - | ||
| 33 | - @Override | ||
| 34 | - public int[] array() { | ||
| 35 | - return ARRAYS; | ||
| 36 | - } | ||
| 37 | - | ||
| 38 | -} |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.product.api.property; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; | ||
| 4 | -import cn.iocoder.yudao.module.product.convert.property.ProductPropertyValueConvert; | ||
| 5 | -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; | ||
| 6 | -import org.springframework.stereotype.Service; | ||
| 7 | -import org.springframework.validation.annotation.Validated; | ||
| 8 | - | ||
| 9 | -import javax.annotation.Resource; | ||
| 10 | -import java.util.Collection; | ||
| 11 | -import java.util.List; | ||
| 12 | - | ||
| 13 | -/** | ||
| 14 | - * 商品属性值 API 实现类 | ||
| 15 | - * | ||
| 16 | - * @author 芋道源码 | ||
| 17 | - */ | ||
| 18 | -@Service | ||
| 19 | -@Validated | ||
| 20 | -public class ProductPropertyValueApiImpl implements ProductPropertyValueApi { | ||
| 21 | - | ||
| 22 | - @Resource | ||
| 23 | - private ProductPropertyValueService productPropertyValueService; | ||
| 24 | - | ||
| 25 | - @Override | ||
| 26 | - public List<ProductPropertyValueDetailRespDTO> getPropertyValueDetailList(Collection<Long> ids) { | ||
| 27 | - return ProductPropertyValueConvert.INSTANCE.convertList02( | ||
| 28 | - productPropertyValueService.getPropertyValueDetailList(ids)); | ||
| 29 | - } | ||
| 30 | - | ||
| 31 | -} |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java
| 1 | package cn.iocoder.yudao.module.product.api.sku; | 1 | package cn.iocoder.yudao.module.product.api.sku; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | 3 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 5 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; | 4 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; |
| 6 | import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; | 5 | import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; |
| @@ -11,7 +10,6 @@ import org.springframework.validation.annotation.Validated; | @@ -11,7 +10,6 @@ import org.springframework.validation.annotation.Validated; | ||
| 11 | 10 | ||
| 12 | import javax.annotation.Resource; | 11 | import javax.annotation.Resource; |
| 13 | import java.util.Collection; | 12 | import java.util.Collection; |
| 14 | -import java.util.Collections; | ||
| 15 | import java.util.List; | 13 | import java.util.List; |
| 16 | 14 | ||
| 17 | /** | 15 | /** |
| @@ -35,18 +33,12 @@ public class ProductSkuApiImpl implements ProductSkuApi { | @@ -35,18 +33,12 @@ public class ProductSkuApiImpl implements ProductSkuApi { | ||
| 35 | 33 | ||
| 36 | @Override | 34 | @Override |
| 37 | public List<ProductSkuRespDTO> getSkuList(Collection<Long> ids) { | 35 | public List<ProductSkuRespDTO> getSkuList(Collection<Long> ids) { |
| 38 | - if (CollUtil.isEmpty(ids)) { | ||
| 39 | - return Collections.emptyList(); | ||
| 40 | - } | ||
| 41 | List<ProductSkuDO> skus = productSkuService.getSkuList(ids); | 36 | List<ProductSkuDO> skus = productSkuService.getSkuList(ids); |
| 42 | return ProductSkuConvert.INSTANCE.convertList04(skus); | 37 | return ProductSkuConvert.INSTANCE.convertList04(skus); |
| 43 | } | 38 | } |
| 44 | 39 | ||
| 45 | @Override | 40 | @Override |
| 46 | public List<ProductSkuRespDTO> getSkuListBySpuId(Collection<Long> spuIds) { | 41 | public List<ProductSkuRespDTO> getSkuListBySpuId(Collection<Long> spuIds) { |
| 47 | - if (CollUtil.isEmpty(spuIds)) { | ||
| 48 | - return Collections.emptyList(); | ||
| 49 | - } | ||
| 50 | List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spuIds); | 42 | List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spuIds); |
| 51 | return ProductSkuConvert.INSTANCE.convertList04(skus); | 43 | return ProductSkuConvert.INSTANCE.convertList04(skus); |
| 52 | } | 44 | } |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java
| @@ -27,9 +27,6 @@ public class ProductSpuApiImpl implements ProductSpuApi { | @@ -27,9 +27,6 @@ public class ProductSpuApiImpl implements ProductSpuApi { | ||
| 27 | 27 | ||
| 28 | @Override | 28 | @Override |
| 29 | public List<ProductSpuRespDTO> getSpuList(Collection<Long> ids) { | 29 | public List<ProductSpuRespDTO> getSpuList(Collection<Long> ids) { |
| 30 | - if (CollectionUtil.isEmpty(ids)) { | ||
| 31 | - return Collections.emptyList(); | ||
| 32 | - } | ||
| 33 | return ProductSpuConvert.INSTANCE.convertList2(spuService.getSpuList(ids)); | 30 | return ProductSpuConvert.INSTANCE.convertList2(spuService.getSpuList(ids)); |
| 34 | } | 31 | } |
| 35 | 32 |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyValueConvert.java
| 1 | package cn.iocoder.yudao.module.product.convert.property; | 1 | package cn.iocoder.yudao.module.product.convert.property; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 5 | -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | ||
| 6 | -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; | ||
| 7 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; | 4 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; |
| 8 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; | 5 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; |
| 9 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; | 6 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; |
| 10 | -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; | ||
| 11 | import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; | 7 | import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; |
| 12 | -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; | ||
| 13 | import org.mapstruct.Mapper; | 8 | import org.mapstruct.Mapper; |
| 14 | import org.mapstruct.factory.Mappers; | 9 | import org.mapstruct.factory.Mappers; |
| 15 | 10 | ||
| 16 | import java.util.List; | 11 | import java.util.List; |
| 17 | -import java.util.Map; | ||
| 18 | - | ||
| 19 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | ||
| 20 | 12 | ||
| 21 | /** | 13 | /** |
| 22 | * 属性值 Convert | 14 | * 属性值 Convert |
| @@ -38,18 +30,4 @@ public interface ProductPropertyValueConvert { | @@ -38,18 +30,4 @@ public interface ProductPropertyValueConvert { | ||
| 38 | 30 | ||
| 39 | PageResult<ProductPropertyValueRespVO> convertPage(PageResult<ProductPropertyValueDO> page); | 31 | PageResult<ProductPropertyValueRespVO> convertPage(PageResult<ProductPropertyValueDO> page); |
| 40 | 32 | ||
| 41 | - default List<ProductPropertyValueDetailRespBO> convertList(List<ProductPropertyValueDO> values, List<ProductPropertyDO> keys) { | ||
| 42 | - Map<Long, ProductPropertyDO> keyMap = convertMap(keys, ProductPropertyDO::getId); | ||
| 43 | - return CollectionUtils.convertList(values, value -> { | ||
| 44 | - ProductPropertyValueDetailRespBO valueDetail = new ProductPropertyValueDetailRespBO() | ||
| 45 | - .setValueId(value.getId()).setValueName(value.getName()); | ||
| 46 | - // 设置属性项 | ||
| 47 | - MapUtils.findAndThen(keyMap, value.getPropertyId(), | ||
| 48 | - key -> valueDetail.setPropertyId(key.getId()).setPropertyName(key.getName())); | ||
| 49 | - return valueDetail; | ||
| 50 | - }); | ||
| 51 | - } | ||
| 52 | - | ||
| 53 | - List<ProductPropertyValueDetailRespDTO> convertList02(List<ProductPropertyValueDetailRespBO> list); | ||
| 54 | - | ||
| 55 | } | 33 | } |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java
| @@ -5,7 +5,6 @@ import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.Produc | @@ -5,7 +5,6 @@ import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.Produc | ||
| 5 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; | 5 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; |
| 6 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; | 6 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; |
| 7 | import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; | 7 | import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; |
| 8 | -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; | ||
| 9 | 8 | ||
| 10 | import java.util.Collection; | 9 | import java.util.Collection; |
| 11 | import java.util.List; | 10 | import java.util.List; |
| @@ -57,14 +56,6 @@ public interface ProductPropertyValueService { | @@ -57,14 +56,6 @@ public interface ProductPropertyValueService { | ||
| 57 | List<ProductPropertyValueDO> getPropertyValueListByPropertyId(Collection<Long> propertyIds); | 56 | List<ProductPropertyValueDO> getPropertyValueListByPropertyId(Collection<Long> propertyIds); |
| 58 | 57 | ||
| 59 | /** | 58 | /** |
| 60 | - * 根据编号数组,获得属性值列表 | ||
| 61 | - * | ||
| 62 | - * @param ids 编号数组 | ||
| 63 | - * @return 属性值明细列表 | ||
| 64 | - */ | ||
| 65 | - List<ProductPropertyValueDetailRespBO> getPropertyValueDetailList(Collection<Long> ids); | ||
| 66 | - | ||
| 67 | - /** | ||
| 68 | * 根据属性项编号,活的属性值数量 | 59 | * 根据属性项编号,活的属性值数量 |
| 69 | * | 60 | * |
| 70 | * @param propertyId 属性项编号数 | 61 | * @param propertyId 属性项编号数 |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java
| 1 | package cn.iocoder.yudao.module.product.service.property; | 1 | package cn.iocoder.yudao.module.product.service.property; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; | 4 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; |
| 6 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; | 5 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; |
| 7 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; | 6 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; |
| 8 | import cn.iocoder.yudao.module.product.convert.property.ProductPropertyValueConvert; | 7 | import cn.iocoder.yudao.module.product.convert.property.ProductPropertyValueConvert; |
| 9 | -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; | ||
| 10 | import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; | 8 | import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; |
| 11 | import cn.iocoder.yudao.module.product.dal.mysql.property.ProductPropertyValueMapper; | 9 | import cn.iocoder.yudao.module.product.dal.mysql.property.ProductPropertyValueMapper; |
| 12 | -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; | ||
| 13 | import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; | 10 | import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; |
| 14 | import org.springframework.context.annotation.Lazy; | 11 | import org.springframework.context.annotation.Lazy; |
| 15 | import org.springframework.stereotype.Service; | 12 | import org.springframework.stereotype.Service; |
| @@ -17,11 +14,9 @@ import org.springframework.validation.annotation.Validated; | @@ -17,11 +14,9 @@ import org.springframework.validation.annotation.Validated; | ||
| 17 | 14 | ||
| 18 | import javax.annotation.Resource; | 15 | import javax.annotation.Resource; |
| 19 | import java.util.Collection; | 16 | import java.util.Collection; |
| 20 | -import java.util.Collections; | ||
| 21 | import java.util.List; | 17 | import java.util.List; |
| 22 | 18 | ||
| 23 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 19 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 24 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | ||
| 25 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_EXISTS; | 20 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_EXISTS; |
| 26 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_NOT_EXISTS; | 21 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_NOT_EXISTS; |
| 27 | 22 | ||
| @@ -100,23 +95,6 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ | @@ -100,23 +95,6 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ | ||
| 100 | } | 95 | } |
| 101 | 96 | ||
| 102 | @Override | 97 | @Override |
| 103 | - public List<ProductPropertyValueDetailRespBO> getPropertyValueDetailList(Collection<Long> ids) { | ||
| 104 | - // 获得属性值列表 | ||
| 105 | - if (CollUtil.isEmpty(ids)) { | ||
| 106 | - return Collections.emptyList(); | ||
| 107 | - } | ||
| 108 | - List<ProductPropertyValueDO> values = productPropertyValueMapper.selectBatchIds(ids); | ||
| 109 | - if (CollUtil.isEmpty(values)) { | ||
| 110 | - return Collections.emptyList(); | ||
| 111 | - } | ||
| 112 | - // 获得属性项列表 | ||
| 113 | - List<ProductPropertyDO> keys = productPropertyService.getPropertyList( | ||
| 114 | - convertSet(values, ProductPropertyValueDO::getPropertyId)); | ||
| 115 | - // 组装明细 | ||
| 116 | - return ProductPropertyValueConvert.INSTANCE.convertList(values, keys); | ||
| 117 | - } | ||
| 118 | - | ||
| 119 | - @Override | ||
| 120 | public Integer getPropertyValueCountByPropertyId(Long propertyId) { | 98 | public Integer getPropertyValueCountByPropertyId(Long propertyId) { |
| 121 | return productPropertyValueMapper.selectCountByPropertyId(propertyId); | 99 | return productPropertyValueMapper.selectCountByPropertyId(propertyId); |
| 122 | } | 100 | } |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/bo/ProductPropertyValueDetailRespBO.java deleted
| 1 | -package cn.iocoder.yudao.module.product.service.property.bo; | ||
| 2 | - | ||
| 3 | -import lombok.Data; | ||
| 4 | - | ||
| 5 | -/** | ||
| 6 | - * 商品属性项的明细 Response BO | ||
| 7 | - * | ||
| 8 | - * @author 芋道源码 | ||
| 9 | - */ | ||
| 10 | -@Data | ||
| 11 | -public class ProductPropertyValueDetailRespBO { | ||
| 12 | - | ||
| 13 | - /** | ||
| 14 | - * 属性的编号 | ||
| 15 | - */ | ||
| 16 | - private Long propertyId; | ||
| 17 | - | ||
| 18 | - /** | ||
| 19 | - * 属性的名称 | ||
| 20 | - */ | ||
| 21 | - private String propertyName; | ||
| 22 | - | ||
| 23 | - /** | ||
| 24 | - * 属性值的编号 | ||
| 25 | - */ | ||
| 26 | - private Long valueId; | ||
| 27 | - | ||
| 28 | - /** | ||
| 29 | - * 属性值的名称 | ||
| 30 | - */ | ||
| 31 | - private String valueName; | ||
| 32 | - | ||
| 33 | -} |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
| @@ -153,6 +153,9 @@ public class ProductSkuServiceImpl implements ProductSkuService { | @@ -153,6 +153,9 @@ public class ProductSkuServiceImpl implements ProductSkuService { | ||
| 153 | 153 | ||
| 154 | @Override | 154 | @Override |
| 155 | public List<ProductSkuDO> getSkuListBySpuId(Collection<Long> spuIds) { | 155 | public List<ProductSkuDO> getSkuListBySpuId(Collection<Long> spuIds) { |
| 156 | + if (CollUtil.isEmpty(spuIds)) { | ||
| 157 | + return Collections.emptyList(); | ||
| 158 | + } | ||
| 156 | return productSkuMapper.selectListBySpuId(spuIds); | 159 | return productSkuMapper.selectListBySpuId(spuIds); |
| 157 | } | 160 | } |
| 158 | 161 |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
| @@ -188,6 +188,9 @@ public class ProductSpuServiceImpl implements ProductSpuService { | @@ -188,6 +188,9 @@ public class ProductSpuServiceImpl implements ProductSpuService { | ||
| 188 | 188 | ||
| 189 | @Override | 189 | @Override |
| 190 | public List<ProductSpuDO> getSpuList(Collection<Long> ids) { | 190 | public List<ProductSpuDO> getSpuList(Collection<Long> ids) { |
| 191 | + if (CollUtil.isEmpty(ids)) { | ||
| 192 | + return Collections.emptyList(); | ||
| 193 | + } | ||
| 191 | return productSpuMapper.selectBatchIds(ids); | 194 | return productSpuMapper.selectBatchIds(ids); |
| 192 | } | 195 | } |
| 193 | 196 |
yudao-module-mall/yudao-module-promotion-api/pom.xml
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationActivityApi.java deleted
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java
| @@ -42,14 +42,6 @@ public interface CombinationRecordApi { | @@ -42,14 +42,6 @@ public interface CombinationRecordApi { | ||
| 42 | boolean isCombinationRecordSuccess(Long userId, Long orderId); | 42 | boolean isCombinationRecordSuccess(Long userId, Long orderId); |
| 43 | 43 | ||
| 44 | /** | 44 | /** |
| 45 | - * 更新拼团状态为【失败】 | ||
| 46 | - * | ||
| 47 | - * @param userId 用户编号 | ||
| 48 | - * @param orderId 订单编号 | ||
| 49 | - */ | ||
| 50 | - void updateRecordStatusToFailed(Long userId, Long orderId); | ||
| 51 | - | ||
| 52 | - /** | ||
| 53 | * 【下单前】校验是否满足拼团活动条件 | 45 | * 【下单前】校验是否满足拼团活动条件 |
| 54 | * | 46 | * |
| 55 | * 如果校验失败,则抛出业务异常 | 47 | * 如果校验失败,则抛出业务异常 |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.api.price; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; | ||
| 4 | -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; | ||
| 5 | - | ||
| 6 | -/** | ||
| 7 | - * 价格 API 接口 | ||
| 8 | - * | ||
| 9 | - * @author 芋道源码 | ||
| 10 | - */ | ||
| 11 | -public interface PriceApi { | ||
| 12 | - | ||
| 13 | - /** | ||
| 14 | - * 计算商品的价格 | ||
| 15 | - * | ||
| 16 | - * @param calculateReqDTO 价格请求 | ||
| 17 | - * @return 价格相应 | ||
| 18 | - */ | ||
| 19 | - PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO); | ||
| 20 | - | ||
| 21 | -} |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/CouponMeetRespDTO.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.api.price.dto; | ||
| 2 | - | ||
| 3 | -import lombok.Data; | ||
| 4 | - | ||
| 5 | -/** | ||
| 6 | - * 优惠劵的匹配信息 Response DTO | ||
| 7 | - * | ||
| 8 | - * why 放在 price 包下?主要获取的时候,需要涉及到较多的价格计算逻辑,放在 price 可以更好的复用逻辑 | ||
| 9 | - * | ||
| 10 | - * @author 芋道源码 | ||
| 11 | - */ | ||
| 12 | -@Data | ||
| 13 | -public class CouponMeetRespDTO { | ||
| 14 | - | ||
| 15 | - /** | ||
| 16 | - * 优惠劵编号 | ||
| 17 | - */ | ||
| 18 | - private Long id; | ||
| 19 | - | ||
| 20 | - // ========== 非优惠劵的基本信息字段 ========== | ||
| 21 | - /** | ||
| 22 | - * 是否匹配 | ||
| 23 | - */ | ||
| 24 | - private Boolean meet; | ||
| 25 | - /** | ||
| 26 | - * 不匹配的提示,即 {@link #meet} = true 才有值 | ||
| 27 | - * | ||
| 28 | - * 例如说: | ||
| 29 | - * 1. 所结算商品没有符合条件的商品 | ||
| 30 | - * 2. 差 XXX 元可用优惠劵 | ||
| 31 | - * 3. 优惠劵未到使用时间 | ||
| 32 | - */ | ||
| 33 | - private String meetTip; | ||
| 34 | - | ||
| 35 | -} |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.api.price.dto; | ||
| 2 | - | ||
| 3 | -import lombok.Data; | ||
| 4 | - | ||
| 5 | -import javax.validation.constraints.Min; | ||
| 6 | -import javax.validation.constraints.NotNull; | ||
| 7 | -import java.util.List; | ||
| 8 | - | ||
| 9 | -/** | ||
| 10 | - * 价格计算 Request DTO | ||
| 11 | - * | ||
| 12 | - * @author 芋道源码 | ||
| 13 | - */ | ||
| 14 | -@Data | ||
| 15 | -@Deprecated | ||
| 16 | -public class PriceCalculateReqDTO { | ||
| 17 | - | ||
| 18 | - /** | ||
| 19 | - * 用户编号 | ||
| 20 | - * | ||
| 21 | - * 对应 MemberUserDO 的 id 编号 | ||
| 22 | - */ | ||
| 23 | - private Long userId; | ||
| 24 | - | ||
| 25 | - /** | ||
| 26 | - * 优惠劵编号 | ||
| 27 | - */ | ||
| 28 | - private Long couponId; | ||
| 29 | - | ||
| 30 | - /** | ||
| 31 | - * 收货地址编号 | ||
| 32 | - */ | ||
| 33 | - private Long addressId; | ||
| 34 | - | ||
| 35 | - /** | ||
| 36 | - * 商品 SKU 数组 | ||
| 37 | - */ | ||
| 38 | - @NotNull(message = "商品数组不能为空") | ||
| 39 | - private List<Item> items; | ||
| 40 | - | ||
| 41 | - /** | ||
| 42 | - * 商品 SKU | ||
| 43 | - */ | ||
| 44 | - @Data | ||
| 45 | - public static class Item { | ||
| 46 | - | ||
| 47 | - /** | ||
| 48 | - * SKU 编号 | ||
| 49 | - */ | ||
| 50 | - @NotNull(message = "商品 SKU 编号不能为空") | ||
| 51 | - private Long skuId; | ||
| 52 | - | ||
| 53 | - /** | ||
| 54 | - * SKU 数量 | ||
| 55 | - */ | ||
| 56 | - @NotNull(message = "商品 SKU 数量不能为空") | ||
| 57 | - @Min(value = 0L, message = "商品 SKU 数量必须大于等于 0") // 可传递 0 数量,用于购物车未选中的情况 | ||
| 58 | - private Integer count; | ||
| 59 | - | ||
| 60 | - } | ||
| 61 | - | ||
| 62 | -} |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.api.price.dto; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; | ||
| 4 | -import lombok.Data; | ||
| 5 | - | ||
| 6 | -import java.util.List; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * 价格计算 Response DTO | ||
| 10 | - * | ||
| 11 | - * 整体设计,参考 taobao 的技术文档: | ||
| 12 | - * 1. <a href="https://developer.alibaba.com/docs/doc.htm?treeId=1&articleId=1029&docType=1">订单管理</a> | ||
| 13 | - * 2. <a href="https://open.taobao.com/docV3.htm?docId=108471&docType=1">常用订单金额说明</a> | ||
| 14 | - * | ||
| 15 | - * 举个例子:<a href="https://img.alicdn.com/top/i1/LB1mALAi4HI8KJjy1zbXXaxdpXa">订单图</a> | ||
| 16 | - * 输入: | ||
| 17 | - * 1. 订单实付: trade.payment = 198.00;订单邮费:5 元; | ||
| 18 | - * 2. 商品级优惠 圣诞价: 省 29.00 元 和 圣诞价:省 150.00 元; 订单级优惠,圣诞 2:省 5.00 元; | ||
| 19 | - * 分摊: | ||
| 20 | - * 1. 商品 1:原价 108 元,优惠 29 元,子订单实付 79 元,分摊主订单优惠 1.99 元; | ||
| 21 | - * 2. 商品 2:原价 269 元,优惠 150 元,子订单实付 119 元,分摊主订单优惠 3.01 元; | ||
| 22 | - * | ||
| 23 | - * @author 芋道源码 | ||
| 24 | - */ | ||
| 25 | -@Data | ||
| 26 | -@Deprecated | ||
| 27 | -public class PriceCalculateRespDTO { | ||
| 28 | - | ||
| 29 | - /** | ||
| 30 | - * 订单 | ||
| 31 | - */ | ||
| 32 | - private Order order; | ||
| 33 | - | ||
| 34 | - /** | ||
| 35 | - * 营销活动数组 | ||
| 36 | - * | ||
| 37 | - * 只对应 {@link Order#items} 商品匹配的活动 | ||
| 38 | - */ | ||
| 39 | - private List<Promotion> promotions; | ||
| 40 | - | ||
| 41 | - // TODO @芋艿:需要改造下,主要是价格字段 | ||
| 42 | - /** | ||
| 43 | - * 订单 | ||
| 44 | - */ | ||
| 45 | - @Data | ||
| 46 | - public static class Order { | ||
| 47 | - | ||
| 48 | - /** | ||
| 49 | - * 商品原价(总),单位:分 | ||
| 50 | - * | ||
| 51 | - * 基于 {@link OrderItem#getOriginalPrice()} 求和 | ||
| 52 | - * | ||
| 53 | - * 对应 taobao 的 trade.total_fee 字段 | ||
| 54 | - */ | ||
| 55 | - private Integer totalPrice; | ||
| 56 | - /** | ||
| 57 | - * 订单优惠(总),单位:分 | ||
| 58 | - * | ||
| 59 | - * 订单级优惠:对主订单的优惠,常见如:订单满 200 元减 10 元;订单满 80 包邮。 | ||
| 60 | - * | ||
| 61 | - * 对应 taobao 的 order.discount_fee 字段 | ||
| 62 | - */ | ||
| 63 | - private Integer discountPrice; | ||
| 64 | - /** | ||
| 65 | - * 优惠劵减免金额(总),单位:分 | ||
| 66 | - * | ||
| 67 | - * 对应 taobao 的 trade.coupon_fee 字段 | ||
| 68 | - */ | ||
| 69 | - private Integer couponPrice; | ||
| 70 | - /** | ||
| 71 | - * 积分减免金额(总),单位:分 | ||
| 72 | - * | ||
| 73 | - * 对应 taobao 的 trade.point_fee 字段 | ||
| 74 | - */ | ||
| 75 | - private Integer pointPrice; | ||
| 76 | - /** | ||
| 77 | - * 运费金额,单位:分 | ||
| 78 | - */ | ||
| 79 | - private Integer deliveryPrice; | ||
| 80 | - /** | ||
| 81 | - * 最终购买金额(总),单位:分 | ||
| 82 | - * | ||
| 83 | - * = {@link OrderItem#getPayPrice()} 求和 | ||
| 84 | - * - {@link #couponPrice} | ||
| 85 | - * - {@link #pointPrice} | ||
| 86 | - * + {@link #deliveryPrice} | ||
| 87 | - * - {@link #discountPrice} | ||
| 88 | - */ | ||
| 89 | - private Integer payPrice; | ||
| 90 | - /** | ||
| 91 | - * 商品 SKU 数组 | ||
| 92 | - */ | ||
| 93 | - private List<OrderItem> items; | ||
| 94 | - | ||
| 95 | - // ========== 营销基本信息 ========== | ||
| 96 | - /** | ||
| 97 | - * 优惠劵编号 | ||
| 98 | - */ | ||
| 99 | - private Long couponId; | ||
| 100 | - | ||
| 101 | - } | ||
| 102 | - | ||
| 103 | - /** | ||
| 104 | - * 订单商品 SKU | ||
| 105 | - */ | ||
| 106 | - @Data | ||
| 107 | - public static class OrderItem { | ||
| 108 | - | ||
| 109 | - /** | ||
| 110 | - * SPU 编号 | ||
| 111 | - */ | ||
| 112 | - private Long spuId; | ||
| 113 | - /** | ||
| 114 | - * SKU 编号 | ||
| 115 | - */ | ||
| 116 | - private Long skuId; | ||
| 117 | - /** | ||
| 118 | - * 购买数量 | ||
| 119 | - */ | ||
| 120 | - private Integer count; | ||
| 121 | - | ||
| 122 | - /** | ||
| 123 | - * 商品原价(总),单位:分 | ||
| 124 | - * | ||
| 125 | - * = {@link #originalUnitPrice} * {@link #getCount()} | ||
| 126 | - */ | ||
| 127 | - private Integer originalPrice; | ||
| 128 | - /** | ||
| 129 | - * 商品原价(单),单位:分 | ||
| 130 | - * | ||
| 131 | - * 对应 ProductSkuDO 的 price 字段 | ||
| 132 | - * 对应 taobao 的 order.price 字段 | ||
| 133 | - */ | ||
| 134 | - private Integer originalUnitPrice; | ||
| 135 | - /** | ||
| 136 | - * 商品优惠(总),单位:分 | ||
| 137 | - * | ||
| 138 | - * 商品级优惠:对单个商品的,常见如:商品原价的 8 折;商品原价的减 50 元 | ||
| 139 | - * | ||
| 140 | - * 对应 taobao 的 order.discount_fee 字段 | ||
| 141 | - */ | ||
| 142 | - private Integer discountPrice; | ||
| 143 | - /** | ||
| 144 | - * 子订单实付金额,不算主订单分摊金额,单位:分 | ||
| 145 | - * | ||
| 146 | - * = {@link #originalPrice} | ||
| 147 | - * - {@link #discountPrice} | ||
| 148 | - * | ||
| 149 | - * 对应 taobao 的 order.payment 字段 | ||
| 150 | - */ | ||
| 151 | - private Integer payPrice; | ||
| 152 | - | ||
| 153 | - /** | ||
| 154 | - * 子订单分摊金额(总),单位:分 | ||
| 155 | - * 需要分摊 {@link Order#discountPrice}、{@link Order#couponPrice}、{@link Order#pointPrice} | ||
| 156 | - * | ||
| 157 | - * 对应 taobao 的 order.part_mjz_discount 字段 | ||
| 158 | - * 淘宝说明:子订单分摊优惠基础逻辑:一般正常优惠券和满减优惠按照子订单的金额进行分摊,特殊情况如果优惠券是指定商品使用的,只会分摊到对应商品子订单上不分摊。 | ||
| 159 | - */ | ||
| 160 | - private Integer orderPartPrice; | ||
| 161 | - /** | ||
| 162 | - * 分摊后子订单实付金额(总),单位:分 | ||
| 163 | - * | ||
| 164 | - * = {@link #payPrice} | ||
| 165 | - * - {@link #orderPartPrice} | ||
| 166 | - * | ||
| 167 | - * 对应 taobao 的 divide_order_fee 字段 | ||
| 168 | - */ | ||
| 169 | - private Integer orderDividePrice; | ||
| 170 | - | ||
| 171 | - } | ||
| 172 | - | ||
| 173 | - /** | ||
| 174 | - * 营销明细 | ||
| 175 | - */ | ||
| 176 | - @Data | ||
| 177 | - @Deprecated | ||
| 178 | - public static class Promotion { | ||
| 179 | - | ||
| 180 | - /** | ||
| 181 | - * 营销编号 | ||
| 182 | - * | ||
| 183 | - * 例如说:营销活动的编号、优惠劵的编号 | ||
| 184 | - */ | ||
| 185 | - private Long id; | ||
| 186 | - /** | ||
| 187 | - * 营销名字 | ||
| 188 | - */ | ||
| 189 | - private String name; | ||
| 190 | - /** | ||
| 191 | - * 营销类型 | ||
| 192 | - * | ||
| 193 | - * 枚举 {@link PromotionTypeEnum} | ||
| 194 | - */ | ||
| 195 | - private Integer type; | ||
| 196 | - /** | ||
| 197 | - * 营销级别 | ||
| 198 | - * | ||
| 199 | - * 枚举 @link PromotionLevelEnum} TODO PromotionLevelEnum 没有这个枚举类 | ||
| 200 | - */ | ||
| 201 | - private Integer level; | ||
| 202 | - /** | ||
| 203 | - * 计算时的原价(总),单位:分 | ||
| 204 | - */ | ||
| 205 | - private Integer totalPrice; | ||
| 206 | - /** | ||
| 207 | - * 计算时的优惠(总),单位:分 | ||
| 208 | - */ | ||
| 209 | - private Integer discountPrice; | ||
| 210 | - /** | ||
| 211 | - * 匹配的商品 SKU 数组 | ||
| 212 | - */ | ||
| 213 | - private List<PromotionItem> items; | ||
| 214 | - | ||
| 215 | - // ========== 匹配情况 ========== | ||
| 216 | - | ||
| 217 | - /** | ||
| 218 | - * 是否满足优惠条件 | ||
| 219 | - */ | ||
| 220 | - private Boolean match; | ||
| 221 | - /** | ||
| 222 | - * 满足条件的提示 | ||
| 223 | - * | ||
| 224 | - * 如果 {@link #match} = true 满足,则提示“圣诞价:省 150.00 元” | ||
| 225 | - * 如果 {@link #match} = false 不满足,则提示“购满 85 元,可减 40 元” | ||
| 226 | - */ | ||
| 227 | - private String description; | ||
| 228 | - | ||
| 229 | - } | ||
| 230 | - | ||
| 231 | - /** | ||
| 232 | - * 营销匹配的商品 SKU | ||
| 233 | - */ | ||
| 234 | - @Data | ||
| 235 | - public static class PromotionItem { | ||
| 236 | - | ||
| 237 | - /** | ||
| 238 | - * 商品 SKU 编号 | ||
| 239 | - */ | ||
| 240 | - private Long skuId; | ||
| 241 | - /** | ||
| 242 | - * 计算时的原价(总),单位:分 | ||
| 243 | - */ | ||
| 244 | - private Integer originalPrice; | ||
| 245 | - /** | ||
| 246 | - * 计算时的优惠(总),单位:分 | ||
| 247 | - */ | ||
| 248 | - private Integer discountPrice; | ||
| 249 | - | ||
| 250 | - } | ||
| 251 | - | ||
| 252 | -} |
yudao-module-mall/yudao-module-promotion-biz/pom.xml
| @@ -14,8 +14,8 @@ | @@ -14,8 +14,8 @@ | ||
| 14 | <name>${project.artifactId}</name> | 14 | <name>${project.artifactId}</name> |
| 15 | 15 | ||
| 16 | <description> | 16 | <description> |
| 17 | - market模块,主要实现营销相关功能 | ||
| 18 | - 例如:营销活动、banner广告、优惠券、优惠码等功能。 | 17 | + promotion 模块,主要实现营销相关功能 |
| 18 | + 例如:营销活动、banner 广告、优惠券、优惠码等功能。 | ||
| 19 | </description> | 19 | </description> |
| 20 | 20 | ||
| 21 | <dependencies> | 21 | <dependencies> |
| @@ -49,10 +49,6 @@ | @@ -49,10 +49,6 @@ | ||
| 49 | <groupId>cn.iocoder.boot</groupId> | 49 | <groupId>cn.iocoder.boot</groupId> |
| 50 | <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> | 50 | <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> |
| 51 | </dependency> | 51 | </dependency> |
| 52 | - <dependency> | ||
| 53 | - <groupId>cn.iocoder.boot</groupId> | ||
| 54 | - <artifactId>yudao-spring-boot-starter-biz-weixin</artifactId> | ||
| 55 | - </dependency> | ||
| 56 | 52 | ||
| 57 | <!-- Web 相关 --> | 53 | <!-- Web 相关 --> |
| 58 | <dependency> | 54 | <dependency> |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApiImpl.java
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.api.bargain; | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.api.bargain; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService; | 3 | import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService; |
| 4 | import org.springframework.stereotype.Service; | 4 | import org.springframework.stereotype.Service; |
| 5 | +import org.springframework.validation.annotation.Validated; | ||
| 5 | 6 | ||
| 6 | import javax.annotation.Resource; | 7 | import javax.annotation.Resource; |
| 7 | 8 | ||
| @@ -11,6 +12,7 @@ import javax.annotation.Resource; | @@ -11,6 +12,7 @@ import javax.annotation.Resource; | ||
| 11 | * @author HUIHUI | 12 | * @author HUIHUI |
| 12 | */ | 13 | */ |
| 13 | @Service | 14 | @Service |
| 15 | +@Validated | ||
| 14 | public class BargainActivityApiImpl implements BargainActivityApi { | 16 | public class BargainActivityApiImpl implements BargainActivityApi { |
| 15 | 17 | ||
| 16 | @Resource | 18 | @Resource |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.api.bargain; | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.api.bargain; | ||
| 3 | import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO; | 3 | import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO; |
| 4 | import cn.iocoder.yudao.module.promotion.service.bargain.BargainRecordService; | 4 | import cn.iocoder.yudao.module.promotion.service.bargain.BargainRecordService; |
| 5 | import org.springframework.stereotype.Service; | 5 | import org.springframework.stereotype.Service; |
| 6 | +import org.springframework.validation.annotation.Validated; | ||
| 6 | 7 | ||
| 7 | import javax.annotation.Resource; | 8 | import javax.annotation.Resource; |
| 8 | 9 | ||
| @@ -12,6 +13,7 @@ import javax.annotation.Resource; | @@ -12,6 +13,7 @@ import javax.annotation.Resource; | ||
| 12 | * @author HUIHUI | 13 | * @author HUIHUI |
| 13 | */ | 14 | */ |
| 14 | @Service | 15 | @Service |
| 16 | +@Validated | ||
| 15 | public class BargainRecordApiImpl implements BargainRecordApi { | 17 | public class BargainRecordApiImpl implements BargainRecordApi { |
| 16 | 18 | ||
| 17 | @Resource | 19 | @Resource |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationActivityApiImpl.java deleted
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java
| @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationR | @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationR | ||
| 8 | import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; | 8 | import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; |
| 9 | import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; | 9 | import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; |
| 10 | import org.springframework.stereotype.Service; | 10 | import org.springframework.stereotype.Service; |
| 11 | +import org.springframework.validation.annotation.Validated; | ||
| 11 | 12 | ||
| 12 | import javax.annotation.Resource; | 13 | import javax.annotation.Resource; |
| 13 | 14 | ||
| @@ -20,6 +21,7 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINA | @@ -20,6 +21,7 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINA | ||
| 20 | * @author HUIHUI | 21 | * @author HUIHUI |
| 21 | */ | 22 | */ |
| 22 | @Service | 23 | @Service |
| 24 | +@Validated | ||
| 23 | public class CombinationRecordApiImpl implements CombinationRecordApi { | 25 | public class CombinationRecordApiImpl implements CombinationRecordApi { |
| 24 | 26 | ||
| 25 | @Resource | 27 | @Resource |
| @@ -45,11 +47,6 @@ public class CombinationRecordApiImpl implements CombinationRecordApi { | @@ -45,11 +47,6 @@ public class CombinationRecordApiImpl implements CombinationRecordApi { | ||
| 45 | } | 47 | } |
| 46 | 48 | ||
| 47 | @Override | 49 | @Override |
| 48 | - public void updateRecordStatusToFailed(Long userId, Long orderId) { | ||
| 49 | - recordService.updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordStatusEnum.FAILED.getStatus(), userId, orderId); | ||
| 50 | - } | ||
| 51 | - | ||
| 52 | - @Override | ||
| 53 | public CombinationValidateJoinRespDTO validateJoinCombination(Long userId, Long activityId, Long headId, Long skuId, Integer count) { | 50 | public CombinationValidateJoinRespDTO validateJoinCombination(Long userId, Long activityId, Long headId, Long skuId, Integer count) { |
| 54 | return recordService.validateJoinCombination(userId, activityId, headId, skuId, count); | 51 | return recordService.validateJoinCombination(userId, activityId, headId, skuId, count); |
| 55 | } | 52 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java
| @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert; | @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert; | ||
| 8 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; | 8 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; |
| 9 | import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; | 9 | import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; |
| 10 | import org.springframework.stereotype.Service; | 10 | import org.springframework.stereotype.Service; |
| 11 | +import org.springframework.validation.annotation.Validated; | ||
| 11 | 12 | ||
| 12 | import javax.annotation.Resource; | 13 | import javax.annotation.Resource; |
| 13 | 14 | ||
| @@ -17,6 +18,7 @@ import javax.annotation.Resource; | @@ -17,6 +18,7 @@ import javax.annotation.Resource; | ||
| 17 | * @author 芋道源码 | 18 | * @author 芋道源码 |
| 18 | */ | 19 | */ |
| 19 | @Service | 20 | @Service |
| 21 | +@Validated | ||
| 20 | public class CouponApiImpl implements CouponApi { | 22 | public class CouponApiImpl implements CouponApi { |
| 21 | 23 | ||
| 22 | @Resource | 24 | @Resource |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApiImpl.java
| @@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO | @@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO | ||
| 4 | import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert; | 4 | import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert; |
| 5 | import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; | 5 | import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; |
| 6 | import org.springframework.stereotype.Service; | 6 | import org.springframework.stereotype.Service; |
| 7 | +import org.springframework.validation.annotation.Validated; | ||
| 7 | 8 | ||
| 8 | import javax.annotation.Resource; | 9 | import javax.annotation.Resource; |
| 9 | import java.util.Collection; | 10 | import java.util.Collection; |
| @@ -15,6 +16,7 @@ import java.util.List; | @@ -15,6 +16,7 @@ import java.util.List; | ||
| 15 | * @author 芋道源码 | 16 | * @author 芋道源码 |
| 16 | */ | 17 | */ |
| 17 | @Service | 18 | @Service |
| 19 | +@Validated | ||
| 18 | public class DiscountActivityApiImpl implements DiscountActivityApi { | 20 | public class DiscountActivityApiImpl implements DiscountActivityApi { |
| 19 | 21 | ||
| 20 | @Resource | 22 | @Resource |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.api.price; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; | ||
| 4 | -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; | ||
| 5 | -import cn.iocoder.yudao.module.promotion.service.price.PriceService; | ||
| 6 | -import org.springframework.stereotype.Service; | ||
| 7 | - | ||
| 8 | -import javax.annotation.Resource; | ||
| 9 | - | ||
| 10 | -/** | ||
| 11 | - * 价格 API 实现类 | ||
| 12 | - * | ||
| 13 | - * @author 芋道源码 | ||
| 14 | - */ | ||
| 15 | -@Service | ||
| 16 | -public class PriceApiImpl implements PriceApi { | ||
| 17 | - | ||
| 18 | - @Resource | ||
| 19 | - private PriceService priceService; | ||
| 20 | - | ||
| 21 | - @Override | ||
| 22 | - public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) { | ||
| 23 | - //return priceService.calculatePrice(calculateReqDTO); TODO 没有 calculatePrice 这个方法 | ||
| 24 | - | ||
| 25 | - return null; | ||
| 26 | - } | ||
| 27 | - | ||
| 28 | -} |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApiImpl.java
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.api.reward; | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.api.reward; | ||
| 3 | import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO; | 3 | import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO; |
| 4 | import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; | 4 | import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; |
| 5 | import org.springframework.stereotype.Service; | 5 | import org.springframework.stereotype.Service; |
| 6 | +import org.springframework.validation.annotation.Validated; | ||
| 6 | 7 | ||
| 7 | import javax.annotation.Resource; | 8 | import javax.annotation.Resource; |
| 8 | import java.util.Collection; | 9 | import java.util.Collection; |
| @@ -14,6 +15,7 @@ import java.util.List; | @@ -14,6 +15,7 @@ import java.util.List; | ||
| 14 | * @author 芋道源码 | 15 | * @author 芋道源码 |
| 15 | */ | 16 | */ |
| 16 | @Service | 17 | @Service |
| 18 | +@Validated | ||
| 17 | public class RewardActivityApiImpl implements RewardActivityApi { | 19 | public class RewardActivityApiImpl implements RewardActivityApi { |
| 18 | 20 | ||
| 19 | @Resource | 21 | @Resource |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.api.seckill; | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.api.seckill; | ||
| 3 | import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillValidateJoinRespDTO; | 3 | import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillValidateJoinRespDTO; |
| 4 | import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService; | 4 | import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService; |
| 5 | import org.springframework.stereotype.Service; | 5 | import org.springframework.stereotype.Service; |
| 6 | +import org.springframework.validation.annotation.Validated; | ||
| 6 | 7 | ||
| 7 | import javax.annotation.Resource; | 8 | import javax.annotation.Resource; |
| 8 | 9 | ||
| @@ -12,6 +13,7 @@ import javax.annotation.Resource; | @@ -12,6 +13,7 @@ import javax.annotation.Resource; | ||
| 12 | * @author HUIHUI | 13 | * @author HUIHUI |
| 13 | */ | 14 | */ |
| 14 | @Service | 15 | @Service |
| 16 | +@Validated | ||
| 15 | public class SeckillActivityApiImpl implements SeckillActivityApi { | 17 | public class SeckillActivityApiImpl implements SeckillActivityApi { |
| 16 | 18 | ||
| 17 | @Resource | 19 | @Resource |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java
| @@ -4,6 +4,8 @@ import io.swagger.v3.oas.annotations.media.Schema; | @@ -4,6 +4,8 @@ import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | import lombok.Data; | 4 | import lombok.Data; |
| 5 | import lombok.ToString; | 5 | import lombok.ToString; |
| 6 | 6 | ||
| 7 | +import java.time.LocalDateTime; | ||
| 8 | + | ||
| 7 | @Schema(description = "管理后台 - Banner Response VO") | 9 | @Schema(description = "管理后台 - Banner Response VO") |
| 8 | @Data | 10 | @Data |
| 9 | @ToString(callSuper = true) | 11 | @ToString(callSuper = true) |
| @@ -12,4 +14,7 @@ public class BannerRespVO extends BannerBaseVO { | @@ -12,4 +14,7 @@ public class BannerRespVO extends BannerBaseVO { | ||
| 12 | @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED) | 14 | @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED) |
| 13 | private Long id; | 15 | private Long id; |
| 14 | 16 | ||
| 17 | + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-07-01 23:59:59") | ||
| 18 | + private LocalDateTime createTime; | ||
| 19 | + | ||
| 15 | } | 20 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java
| @@ -96,13 +96,13 @@ public class AppCouponTemplateController { | @@ -96,13 +96,13 @@ public class AppCouponTemplateController { | ||
| 96 | */ | 96 | */ |
| 97 | private Long getProductScopeValue(Integer productScope, Long spuId) { | 97 | private Long getProductScopeValue(Integer productScope, Long spuId) { |
| 98 | // 通用券:没有商品范围 | 98 | // 通用券:没有商品范围 |
| 99 | - if (productScope == null || ObjectUtils.equalsAny(productScope, PromotionProductScopeEnum.ALL.getScope(), null)) { | 99 | + if (ObjectUtils.equalsAny(productScope, PromotionProductScopeEnum.ALL.getScope(), null)) { |
| 100 | return null; | 100 | return null; |
| 101 | } | 101 | } |
| 102 | // 品类券:查询商品的品类编号 | 102 | // 品类券:查询商品的品类编号 |
| 103 | if (Objects.equals(productScope, PromotionProductScopeEnum.CATEGORY.getScope()) && spuId != null) { | 103 | if (Objects.equals(productScope, PromotionProductScopeEnum.CATEGORY.getScope()) && spuId != null) { |
| 104 | - return Optional.ofNullable(productSpuApi.getSpu(spuId)) | ||
| 105 | - .map(ProductSpuRespDTO::getCategoryId).orElse(null); | 104 | + ProductSpuRespDTO spu = productSpuApi.getSpu(spuId); |
| 105 | + return spu != null ? spu.getCategoryId() : null; | ||
| 106 | } | 106 | } |
| 107 | // 商品卷:直接返回 | 107 | // 商品卷:直接返回 |
| 108 | return spuId; | 108 | return spuId; |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.convert.price; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 4 | -import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; | ||
| 5 | -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; | ||
| 6 | -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; | ||
| 7 | -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | ||
| 8 | -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; | ||
| 9 | -import org.mapstruct.Mapper; | ||
| 10 | -import org.mapstruct.factory.Mappers; | ||
| 11 | - | ||
| 12 | -import java.util.ArrayList; | ||
| 13 | -import java.util.List; | ||
| 14 | -import java.util.Map; | ||
| 15 | - | ||
| 16 | -@Mapper | ||
| 17 | -public interface PriceConvert { | ||
| 18 | - | ||
| 19 | - PriceConvert INSTANCE = Mappers.getMapper(PriceConvert.class); | ||
| 20 | - | ||
| 21 | - default PriceCalculateRespDTO convert(PriceCalculateReqDTO calculateReqDTO, List<ProductSkuRespDTO> skuList) { | ||
| 22 | - // 创建 PriceCalculateRespDTO 对象 | ||
| 23 | - PriceCalculateRespDTO priceCalculate = new PriceCalculateRespDTO(); | ||
| 24 | - // 创建它的 Order 属性 | ||
| 25 | - PriceCalculateRespDTO.Order order = new PriceCalculateRespDTO.Order().setTotalPrice(0).setDiscountPrice(0) | ||
| 26 | - .setCouponPrice(0).setPointPrice(0).setDeliveryPrice(0).setPayPrice(0) | ||
| 27 | - .setItems(new ArrayList<>()).setCouponId(calculateReqDTO.getCouponId()); | ||
| 28 | - priceCalculate.setOrder(order).setPromotions(new ArrayList<>()); | ||
| 29 | - // 创建它的 OrderItem 属性 | ||
| 30 | - Map<Long, Integer> skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(), | ||
| 31 | - PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount); | ||
| 32 | - skuList.forEach(sku -> { | ||
| 33 | - Integer count = skuIdCountMap.get(sku.getId()); | ||
| 34 | - PriceCalculateRespDTO.OrderItem orderItem = new PriceCalculateRespDTO.OrderItem() | ||
| 35 | - .setSpuId(sku.getSpuId()).setSkuId(sku.getId()).setCount(count) | ||
| 36 | - .setOriginalUnitPrice(sku.getPrice()).setOriginalPrice(sku.getPrice() * count) | ||
| 37 | - .setDiscountPrice(0).setOrderPartPrice(0); | ||
| 38 | - orderItem.setPayPrice(orderItem.getOriginalPrice()).setOrderDividePrice(orderItem.getOriginalPrice()); | ||
| 39 | - priceCalculate.getOrder().getItems().add(orderItem); | ||
| 40 | - // 补充价格信息到 Order 中 | ||
| 41 | - order.setTotalPrice(order.getTotalPrice() + orderItem.getOriginalPrice()) | ||
| 42 | - .setPayPrice(order.getTotalPrice()); | ||
| 43 | - }); | ||
| 44 | - return priceCalculate; | ||
| 45 | - } | ||
| 46 | - | ||
| 47 | - CouponMeetRespDTO convert(CouponDO coupon); | ||
| 48 | - | ||
| 49 | -} |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/UserCreateConsumer.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/coupon/CouponTakeByRegisterConsumer.java
| 1 | package cn.iocoder.yudao.module.promotion.mq.consumer.coupon; | 1 | package cn.iocoder.yudao.module.promotion.mq.consumer.coupon; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; | ||
| 4 | -import cn.iocoder.yudao.module.promotion.mq.message.coupon.UserCreateMessage; | 3 | +import cn.iocoder.yudao.module.member.message.user.MemberUserCreateMessage; |
| 5 | import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; | 4 | import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; |
| 6 | import lombok.extern.slf4j.Slf4j; | 5 | import lombok.extern.slf4j.Slf4j; |
| 6 | +import org.springframework.context.event.EventListener; | ||
| 7 | +import org.springframework.scheduling.annotation.Async; | ||
| 7 | import org.springframework.stereotype.Component; | 8 | import org.springframework.stereotype.Component; |
| 8 | 9 | ||
| 9 | import javax.annotation.Resource; | 10 | import javax.annotation.Resource; |
| 10 | 11 | ||
| 11 | /** | 12 | /** |
| 12 | - * 针对 {@link UserCreateMessage} 的消费者 | 13 | + * 用户注册时,发送优惠劵的消费者,基 {@link MemberUserCreateMessage} 消息 |
| 13 | * | 14 | * |
| 14 | * @author owen | 15 | * @author owen |
| 15 | */ | 16 | */ |
| 16 | @Component | 17 | @Component |
| 17 | @Slf4j | 18 | @Slf4j |
| 18 | -public class UserCreateConsumer extends AbstractStreamMessageListener<UserCreateMessage> { | 19 | +public class CouponTakeByRegisterConsumer { |
| 19 | 20 | ||
| 20 | @Resource | 21 | @Resource |
| 21 | private CouponService couponService; | 22 | private CouponService couponService; |
| 22 | 23 | ||
| 23 | - @Override | ||
| 24 | - public void onMessage(UserCreateMessage message) { | 24 | + @EventListener |
| 25 | + @Async // Spring Event 默认在 Producer 发送的线程,通过 @Async 实现异步 | ||
| 26 | + public void onMessage(MemberUserCreateMessage message) { | ||
| 25 | log.info("[onMessage][消息内容({})]", message); | 27 | log.info("[onMessage][消息内容({})]", message); |
| 26 | couponService.takeCouponByRegister(message.getUserId()); | 28 | couponService.takeCouponByRegister(message.getUserId()); |
| 27 | } | 29 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/consumer/package-info.java
0 → 100644
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/message/package-info.java
0 → 100644
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/producer/package-info.java
0 → 100644
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java
| @@ -108,8 +108,8 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic | @@ -108,8 +108,8 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic | ||
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | // 2. 校验商品 sku 都存在 | 110 | // 2. 校验商品 sku 都存在 |
| 111 | - Map<Long, ProductSkuRespDTO> skuMap = convertMap(productSkuApi.getSkuListBySpuId(singletonList(spuId)), | ||
| 112 | - ProductSkuRespDTO::getId); | 111 | + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(singletonList(spuId)); |
| 112 | + Map<Long, ProductSkuRespDTO> skuMap = convertMap(skus, ProductSkuRespDTO::getId); | ||
| 113 | products.forEach(product -> { | 113 | products.forEach(product -> { |
| 114 | if (!skuMap.containsKey(product.getSkuId())) { | 114 | if (!skuMap.containsKey(product.getSkuId())) { |
| 115 | throw exception(SKU_NOT_EXISTS); | 115 | throw exception(SKU_NOT_EXISTS); |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java
| @@ -22,15 +22,6 @@ import java.util.Map; | @@ -22,15 +22,6 @@ import java.util.Map; | ||
| 22 | public interface CombinationRecordService { | 22 | public interface CombinationRecordService { |
| 23 | 23 | ||
| 24 | /** | 24 | /** |
| 25 | - * 更新拼团状态 | ||
| 26 | - * | ||
| 27 | - * @param status 状态 | ||
| 28 | - * @param userId 用户编号 | ||
| 29 | - * @param orderId 订单编号 | ||
| 30 | - */ | ||
| 31 | - void updateCombinationRecordStatusByUserIdAndOrderId(Integer status, Long userId, Long orderId); | ||
| 32 | - | ||
| 33 | - /** | ||
| 34 | * 【下单前】校验是否满足拼团活动条件 | 25 | * 【下单前】校验是否满足拼团活动条件 |
| 35 | * | 26 | * |
| 36 | * 如果校验失败,则抛出业务异常 | 27 | * 如果校验失败,则抛出业务异常 |
| @@ -63,15 +54,6 @@ public interface CombinationRecordService { | @@ -63,15 +54,6 @@ public interface CombinationRecordService { | ||
| 63 | CombinationRecordDO getCombinationRecord(Long userId, Long orderId); | 54 | CombinationRecordDO getCombinationRecord(Long userId, Long orderId); |
| 64 | 55 | ||
| 65 | /** | 56 | /** |
| 66 | - * 获取拼团记录 | ||
| 67 | - * | ||
| 68 | - * @param userId 用户 id | ||
| 69 | - * @param activityId 活动 id | ||
| 70 | - * @return 拼团记录列表 | ||
| 71 | - */ | ||
| 72 | - List<CombinationRecordDO> getCombinationRecordListByUserIdAndActivityId(Long userId, Long activityId); | ||
| 73 | - | ||
| 74 | - /** | ||
| 75 | * 【下单前】校验是否满足拼团活动条件 | 57 | * 【下单前】校验是否满足拼团活动条件 |
| 76 | * | 58 | * |
| 77 | * 如果校验失败,则抛出业务异常 | 59 | * 如果校验失败,则抛出业务异常 |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
| @@ -24,6 +24,7 @@ import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationRecord | @@ -24,6 +24,7 @@ import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationRecord | ||
| 24 | import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; | 24 | import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; |
| 25 | import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi; | 25 | import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi; |
| 26 | import lombok.extern.slf4j.Slf4j; | 26 | import lombok.extern.slf4j.Slf4j; |
| 27 | +import org.springframework.context.annotation.Lazy; | ||
| 27 | import org.springframework.stereotype.Service; | 28 | import org.springframework.stereotype.Service; |
| 28 | import org.springframework.transaction.annotation.Transactional; | 29 | import org.springframework.transaction.annotation.Transactional; |
| 29 | import org.springframework.validation.annotation.Validated; | 30 | import org.springframework.validation.annotation.Validated; |
| @@ -64,27 +65,9 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { | @@ -64,27 +65,9 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { | ||
| 64 | private ProductSkuApi productSkuApi; | 65 | private ProductSkuApi productSkuApi; |
| 65 | 66 | ||
| 66 | @Resource | 67 | @Resource |
| 68 | + @Lazy | ||
| 67 | private TradeOrderApi tradeOrderApi; | 69 | private TradeOrderApi tradeOrderApi; |
| 68 | 70 | ||
| 69 | - @Override | ||
| 70 | - @Transactional(rollbackFor = Exception.class) | ||
| 71 | - public void updateCombinationRecordStatusByUserIdAndOrderId(Integer status, Long userId, Long orderId) { | ||
| 72 | - // 校验拼团是否存在 | ||
| 73 | - CombinationRecordDO record = validateCombinationRecord(userId, orderId); | ||
| 74 | - | ||
| 75 | - // 更新状态 | ||
| 76 | - combinationRecordMapper.updateById(new CombinationRecordDO().setId(record.getId()).setStatus(status)); | ||
| 77 | - } | ||
| 78 | - | ||
| 79 | - private CombinationRecordDO validateCombinationRecord(Long userId, Long orderId) { | ||
| 80 | - // 校验拼团是否存在 | ||
| 81 | - CombinationRecordDO recordDO = combinationRecordMapper.selectByUserIdAndOrderId(userId, orderId); | ||
| 82 | - if (recordDO == null) { | ||
| 83 | - throw exception(COMBINATION_RECORD_NOT_EXISTS); | ||
| 84 | - } | ||
| 85 | - return recordDO; | ||
| 86 | - } | ||
| 87 | - | ||
| 88 | // TODO @芋艿:在详细预览下; | 71 | // TODO @芋艿:在详细预览下; |
| 89 | @Override | 72 | @Override |
| 90 | public KeyValue<CombinationActivityDO, CombinationProductDO> validateCombinationRecord( | 73 | public KeyValue<CombinationActivityDO, CombinationProductDO> validateCombinationRecord( |
| @@ -230,11 +213,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { | @@ -230,11 +213,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { | ||
| 230 | } | 213 | } |
| 231 | 214 | ||
| 232 | @Override | 215 | @Override |
| 233 | - public List<CombinationRecordDO> getCombinationRecordListByUserIdAndActivityId(Long userId, Long activityId) { | ||
| 234 | - return combinationRecordMapper.selectListByUserIdAndActivityId(userId, activityId); | ||
| 235 | - } | ||
| 236 | - | ||
| 237 | - @Override | ||
| 238 | public CombinationValidateJoinRespDTO validateJoinCombination(Long userId, Long activityId, Long headId, | 216 | public CombinationValidateJoinRespDTO validateJoinCombination(Long userId, Long activityId, Long headId, |
| 239 | Long skuId, Integer count) { | 217 | Long skuId, Integer count) { |
| 240 | KeyValue<CombinationActivityDO, CombinationProductDO> keyValue = validateCombinationRecord(userId, activityId, | 218 | KeyValue<CombinationActivityDO, CombinationProductDO> keyValue = validateCombinationRecord(userId, activityId, |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java
| @@ -7,7 +7,6 @@ import cn.hutool.core.util.ObjectUtil; | @@ -7,7 +7,6 @@ import cn.hutool.core.util.ObjectUtil; | ||
| 7 | import cn.hutool.core.util.StrUtil; | 7 | import cn.hutool.core.util.StrUtil; |
| 8 | import cn.hutool.extra.spring.SpringUtil; | 8 | import cn.hutool.extra.spring.SpringUtil; |
| 9 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 9 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 10 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 11 | import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; | 10 | import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; |
| 12 | import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | 11 | import cn.iocoder.yudao.module.member.api.user.MemberUserApi; |
| 13 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | 12 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; |
| @@ -80,12 +79,11 @@ public class CouponServiceImpl implements CouponService { | @@ -80,12 +79,11 @@ public class CouponServiceImpl implements CouponService { | ||
| 80 | public PageResult<CouponDO> getCouponPage(CouponPageReqVO pageReqVO) { | 79 | public PageResult<CouponDO> getCouponPage(CouponPageReqVO pageReqVO) { |
| 81 | // 获得用户编号 | 80 | // 获得用户编号 |
| 82 | if (StrUtil.isNotEmpty(pageReqVO.getNickname())) { | 81 | if (StrUtil.isNotEmpty(pageReqVO.getNickname())) { |
| 83 | - Set<Long> userIds = CollectionUtils.convertSet(memberUserApi.getUserListByNickname(pageReqVO.getNickname()), | ||
| 84 | - MemberUserRespDTO::getId); | ||
| 85 | - if (CollUtil.isEmpty(userIds)) { | 82 | + List<MemberUserRespDTO> users = memberUserApi.getUserListByNickname(pageReqVO.getNickname()); |
| 83 | + if (CollUtil.isEmpty(users)) { | ||
| 86 | return PageResult.empty(); | 84 | return PageResult.empty(); |
| 87 | } | 85 | } |
| 88 | - pageReqVO.setUserIds(userIds); | 86 | + pageReqVO.setUserIds(convertSet(users, MemberUserRespDTO::getId)); |
| 89 | } | 87 | } |
| 90 | // 分页查询 | 88 | // 分页查询 |
| 91 | return couponMapper.selectPage(pageReqVO); | 89 | return couponMapper.selectPage(pageReqVO); |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.service.price; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; | ||
| 4 | -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; | ||
| 5 | - | ||
| 6 | -import java.util.List; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * 价格计算 Service 接口 | ||
| 10 | - * | ||
| 11 | - * @author 芋道源码 | ||
| 12 | - */ | ||
| 13 | -public interface PriceService { | ||
| 14 | - | ||
| 15 | - /** | ||
| 16 | - * 获得优惠劵的匹配信息列表 | ||
| 17 | - * | ||
| 18 | - * @param calculateReqDTO 价格请求 | ||
| 19 | - * @return 价格响应 | ||
| 20 | - */ | ||
| 21 | - List<CouponMeetRespDTO> getMeetCouponList(PriceCalculateReqDTO calculateReqDTO); | ||
| 22 | - | ||
| 23 | -} |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.service.price; | ||
| 2 | - | ||
| 3 | -import cn.hutool.core.collection.CollUtil; | ||
| 4 | -import cn.iocoder.yudao.framework.common.exception.ServiceException; | ||
| 5 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 6 | -import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; | ||
| 7 | -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; | ||
| 8 | -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; | ||
| 9 | -import cn.iocoder.yudao.module.promotion.convert.price.PriceConvert; | ||
| 10 | -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; | ||
| 11 | -import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; | ||
| 12 | -import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; | ||
| 13 | -import lombok.extern.slf4j.Slf4j; | ||
| 14 | -import org.springframework.stereotype.Service; | ||
| 15 | -import org.springframework.validation.annotation.Validated; | ||
| 16 | - | ||
| 17 | -import javax.annotation.Resource; | ||
| 18 | -import java.util.Collections; | ||
| 19 | -import java.util.List; | ||
| 20 | - | ||
| 21 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; | ||
| 22 | -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_VALID_TIME_NOT_NOW; | ||
| 23 | - | ||
| 24 | -/** | ||
| 25 | - * 价格计算 Service 实现类 | ||
| 26 | - * | ||
| 27 | - * 优惠计算顺序:min(限时折扣, 会员折扣) > 满减送 > 优惠券。 | ||
| 28 | - * 参考文档: | ||
| 29 | - * 1. <a href="https://help.youzan.com/displaylist/detail_4_4-1-60384">有赞文档:限时折扣、满减送、优惠券哪个优先计算?</a> | ||
| 30 | - * | ||
| 31 | - * TODO 芋艿:进一步完善 | ||
| 32 | - * 1. 限时折扣:指定金额、减免金额、折扣 | ||
| 33 | - * 2. 满减送:循环、折扣 | ||
| 34 | - * 3. 优惠劵:待定 | ||
| 35 | - * | ||
| 36 | - * @author 芋道源码 | ||
| 37 | - */ | ||
| 38 | -@Service | ||
| 39 | -@Validated | ||
| 40 | -@Slf4j | ||
| 41 | -public class PriceServiceImpl implements PriceService { | ||
| 42 | - | ||
| 43 | - @Resource | ||
| 44 | - private CouponService couponService; | ||
| 45 | - | ||
| 46 | - @Override | ||
| 47 | - public List<CouponMeetRespDTO> getMeetCouponList(PriceCalculateReqDTO calculateReqDTO) { | ||
| 48 | - // 先计算一轮价格 | ||
| 49 | -// PriceCalculateRespDTO priceCalculate = calculatePrice(calculateReqDTO); | ||
| 50 | - PriceCalculateRespDTO priceCalculate = null; | ||
| 51 | - | ||
| 52 | - // 获得用户的待使用优惠劵 | ||
| 53 | - List<CouponDO> couponList = couponService.getCouponList(calculateReqDTO.getUserId(), CouponStatusEnum.UNUSED.getStatus()); | ||
| 54 | - if (CollUtil.isEmpty(couponList)) { | ||
| 55 | - return Collections.emptyList(); | ||
| 56 | - } | ||
| 57 | - | ||
| 58 | - // 获得优惠劵的匹配信息 | ||
| 59 | - return CollectionUtils.convertList(couponList, coupon -> { | ||
| 60 | - CouponMeetRespDTO couponMeetRespDTO = PriceConvert.INSTANCE.convert(coupon); | ||
| 61 | - try { | ||
| 62 | - // 校验优惠劵 | ||
| 63 | - couponService.validCoupon(coupon); | ||
| 64 | - | ||
| 65 | - // 获得匹配的商品 SKU 数组 | ||
| 66 | - // TODO 芋艿:后续处理 | ||
| 67 | -// List<PriceCalculateRespDTO.OrderItem> orderItems = getMatchCouponOrderItems(priceCalculate, coupon); | ||
| 68 | - List<PriceCalculateRespDTO.OrderItem> orderItems = null; | ||
| 69 | - if (CollUtil.isEmpty(orderItems)) { | ||
| 70 | - return couponMeetRespDTO.setMeet(false).setMeetTip("所结算商品没有符合条件的商品"); | ||
| 71 | - } | ||
| 72 | - | ||
| 73 | - // 计算是否满足优惠劵的使用金额 | ||
| 74 | - Integer originPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); | ||
| 75 | - assert originPrice != null; | ||
| 76 | - if (originPrice < coupon.getUsePrice()) { | ||
| 77 | - return couponMeetRespDTO.setMeet(false) | ||
| 78 | -// .setMeetTip(String.format("差 %s 元可用优惠劵", formatPrice(coupon.getUsePrice() - originPrice))); | ||
| 79 | - .setMeetTip("所结算的商品中未满足使用的金额"); | ||
| 80 | - } | ||
| 81 | - } catch (ServiceException serviceException) { | ||
| 82 | - couponMeetRespDTO.setMeet(false); | ||
| 83 | - if (serviceException.getCode().equals(COUPON_VALID_TIME_NOT_NOW.getCode())) { | ||
| 84 | - couponMeetRespDTO.setMeetTip("优惠劵未到使用时间"); | ||
| 85 | - } else { | ||
| 86 | - log.error("[getMeetCouponList][calculateReqDTO({}) 获得优惠劵匹配信息异常]", calculateReqDTO, serviceException); | ||
| 87 | - couponMeetRespDTO.setMeetTip("优惠劵不满足使用条件"); | ||
| 88 | - } | ||
| 89 | - return couponMeetRespDTO; | ||
| 90 | - } | ||
| 91 | - // 满足 | ||
| 92 | - return couponMeetRespDTO.setMeet(true); | ||
| 93 | - }); | ||
| 94 | - } | ||
| 95 | - | ||
| 96 | -} |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java
| @@ -123,8 +123,8 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | @@ -123,8 +123,8 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | ||
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | // 2. 校验商品 sku 都存在 | 125 | // 2. 校验商品 sku 都存在 |
| 126 | - Map<Long, ProductSkuRespDTO> skuMap = convertMap(productSkuApi.getSkuListBySpuId(singletonList(spuId)), | ||
| 127 | - ProductSkuRespDTO::getId); | 126 | + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(singletonList(spuId)); |
| 127 | + Map<Long, ProductSkuRespDTO> skuMap = convertMap(skus, ProductSkuRespDTO::getId); | ||
| 128 | products.forEach(product -> { | 128 | products.forEach(product -> { |
| 129 | if (!skuMap.containsKey(product.getSkuId())) { | 129 | if (!skuMap.containsKey(product.getSkuId())) { |
| 130 | throw exception(SKU_NOT_EXISTS); | 130 | throw exception(SKU_NOT_EXISTS); |
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java
| @@ -138,7 +138,7 @@ public class DiscountActivityServiceImplTest extends BaseDbUnitTest { | @@ -138,7 +138,7 @@ public class DiscountActivityServiceImplTest extends BaseDbUnitTest { | ||
| 138 | Long id = dbDiscountActivity.getId(); | 138 | Long id = dbDiscountActivity.getId(); |
| 139 | 139 | ||
| 140 | // 调用 | 140 | // 调用 |
| 141 | - discountActivityService.closeRewardActivity(id); | 141 | + discountActivityService.closeDiscountActivity(id); |
| 142 | // 校验状态 | 142 | // 校验状态 |
| 143 | DiscountActivityDO discountActivity = discountActivityMapper.selectById(id); | 143 | DiscountActivityDO discountActivity = discountActivityMapper.selectById(id); |
| 144 | assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.CLOSE.getStatus()); | 144 | assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.CLOSE.getStatus()); |
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.service.price; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.exception.ServiceException; | ||
| 4 | -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; | ||
| 5 | -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | ||
| 6 | -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | ||
| 7 | -import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; | ||
| 8 | -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; | ||
| 9 | -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; | ||
| 10 | -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; | ||
| 11 | -import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; | ||
| 12 | -import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; | ||
| 13 | -import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; | ||
| 14 | -import org.junit.jupiter.api.Test; | ||
| 15 | -import org.mockito.InjectMocks; | ||
| 16 | -import org.mockito.Mock; | ||
| 17 | - | ||
| 18 | -import java.util.List; | ||
| 19 | - | ||
| 20 | -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; | ||
| 21 | -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | ||
| 22 | -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | ||
| 23 | -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_VALID_TIME_NOT_NOW; | ||
| 24 | -import static java.util.Arrays.asList; | ||
| 25 | -import static java.util.Collections.singletonList; | ||
| 26 | -import static org.junit.jupiter.api.Assertions.*; | ||
| 27 | -import static org.mockito.ArgumentMatchers.eq; | ||
| 28 | -import static org.mockito.Mockito.doThrow; | ||
| 29 | -import static org.mockito.Mockito.when; | ||
| 30 | - | ||
| 31 | -/** | ||
| 32 | - * {@link PriceServiceImpl} 的单元测试 | ||
| 33 | - * | ||
| 34 | - * @author 芋道源码 | ||
| 35 | - */ | ||
| 36 | -public class PriceServiceTest extends BaseMockitoUnitTest { | ||
| 37 | - | ||
| 38 | - @InjectMocks | ||
| 39 | - private PriceServiceImpl priceService; | ||
| 40 | - | ||
| 41 | - @Mock | ||
| 42 | - private RewardActivityService rewardActivityService; | ||
| 43 | - @Mock | ||
| 44 | - private CouponService couponService; | ||
| 45 | - @Mock | ||
| 46 | - private ProductSkuApi productSkuApi; | ||
| 47 | - | ||
| 48 | - /** | ||
| 49 | - * 测试满减送活动,不匹配的情况 | ||
| 50 | - */ | ||
| 51 | - @Test | ||
| 52 | - public void testCalculatePrice_rewardActivityNotMeet() { | ||
| 53 | - | ||
| 54 | - } | ||
| 55 | - | ||
| 56 | - @Test | ||
| 57 | - public void testGetMeetCouponList() { | ||
| 58 | - // 准备参数 | ||
| 59 | - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1024L) | ||
| 60 | - .setItems(singletonList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2))); | ||
| 61 | - // mock 方法(商品 SKU 信息) | ||
| 62 | - ProductSkuRespDTO productSku = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); | ||
| 63 | - when(productSkuApi.getSkuList(eq(asSet(10L)))).thenReturn(singletonList(productSku)); | ||
| 64 | - // mock 方法(情况一:优惠劵未到使用时间) | ||
| 65 | - CouponDO coupon01 = randomPojo(CouponDO.class); | ||
| 66 | - doThrow(new ServiceException(COUPON_VALID_TIME_NOT_NOW)).when(couponService).validCoupon(coupon01); | ||
| 67 | - // mock 方法(情况二:所结算商品没有符合条件的商品) | ||
| 68 | - CouponDO coupon02 = randomPojo(CouponDO.class); | ||
| 69 | - // mock 方法(情况三:使用金额不足) | ||
| 70 | - CouponDO coupon03 = randomPojo(CouponDO.class, o -> o.setProductScope(PromotionProductScopeEnum.ALL.getScope()) | ||
| 71 | - .setUsePrice(300)); | ||
| 72 | - // mock 方法(情况五:满足条件) | ||
| 73 | - CouponDO coupon04 = randomPojo(CouponDO.class, o -> o.setProductScope(PromotionProductScopeEnum.ALL.getScope()) | ||
| 74 | - .setUsePrice(190)); | ||
| 75 | - // mock 方法(获得用户的待使用优惠劵) | ||
| 76 | - when(couponService.getCouponList(eq(1024L), eq(CouponStatusEnum.UNUSED.getStatus()))) | ||
| 77 | - .thenReturn(asList(coupon01, coupon02, coupon03, coupon04)); | ||
| 78 | - // 调用 | ||
| 79 | - List<CouponMeetRespDTO> list = priceService.getMeetCouponList(calculateReqDTO); | ||
| 80 | - // 断言 | ||
| 81 | - assertEquals(list.size(), 4); | ||
| 82 | - // 断言情况一:优惠劵未到使用时间 | ||
| 83 | - CouponMeetRespDTO couponMeetRespDTO01 = list.get(0); | ||
| 84 | - assertPojoEquals(couponMeetRespDTO01, coupon01); | ||
| 85 | - assertFalse(couponMeetRespDTO01.getMeet()); | ||
| 86 | - assertEquals(couponMeetRespDTO01.getMeetTip(), "优惠劵未到使用时间"); | ||
| 87 | - // 断言情况二:所结算商品没有符合条件的商品 | ||
| 88 | - CouponMeetRespDTO couponMeetRespDTO02 = list.get(1); | ||
| 89 | - assertPojoEquals(couponMeetRespDTO02, coupon02); | ||
| 90 | - assertFalse(couponMeetRespDTO02.getMeet()); | ||
| 91 | - assertEquals(couponMeetRespDTO02.getMeetTip(), "所结算商品没有符合条件的商品"); | ||
| 92 | - // 断言情况三:差 %s 元可用优惠劵 | ||
| 93 | - CouponMeetRespDTO couponMeetRespDTO03 = list.get(2); | ||
| 94 | - assertPojoEquals(couponMeetRespDTO03, coupon03); | ||
| 95 | - assertFalse(couponMeetRespDTO03.getMeet()); | ||
| 96 | - assertEquals(couponMeetRespDTO03.getMeetTip(), "所结算的商品中未满足使用的金额"); | ||
| 97 | - // 断言情况四:满足条件 | ||
| 98 | - CouponMeetRespDTO couponMeetRespDTO04 = list.get(3); | ||
| 99 | - assertPojoEquals(couponMeetRespDTO04, coupon04); | ||
| 100 | - assertTrue(couponMeetRespDTO04.getMeet()); | ||
| 101 | - assertNull(couponMeetRespDTO04.getMeetTip()); | ||
| 102 | - } | ||
| 103 | - | ||
| 104 | -} |
yudao-module-mall/yudao-module-statistics-biz/pom.xml
| @@ -58,7 +58,6 @@ | @@ -58,7 +58,6 @@ | ||
| 58 | <groupId>cn.iocoder.boot</groupId> | 58 | <groupId>cn.iocoder.boot</groupId> |
| 59 | <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> | 59 | <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> |
| 60 | </dependency> | 60 | </dependency> |
| 61 | - | ||
| 62 | <dependency> | 61 | <dependency> |
| 63 | <groupId>cn.iocoder.boot</groupId> | 62 | <groupId>cn.iocoder.boot</groupId> |
| 64 | <artifactId>yudao-spring-boot-starter-biz-ip</artifactId> | 63 | <artifactId>yudao-spring-boot-starter-biz-ip</artifactId> |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/dataobject/member/MemberStatisticsDO.java
| 1 | package cn.iocoder.yudao.module.statistics.dal.dataobject.member; | 1 | package cn.iocoder.yudao.module.statistics.dal.dataobject.member; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | import com.baomidou.mybatisplus.annotation.KeySequence; | 4 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 5 | import com.baomidou.mybatisplus.annotation.TableId; | 5 | import com.baomidou.mybatisplus.annotation.TableId; |
| 6 | import com.baomidou.mybatisplus.annotation.TableName; | 6 | import com.baomidou.mybatisplus.annotation.TableName; |
| @@ -23,7 +23,7 @@ import java.time.LocalDateTime; | @@ -23,7 +23,7 @@ import java.time.LocalDateTime; | ||
| 23 | @Builder | 23 | @Builder |
| 24 | @NoArgsConstructor | 24 | @NoArgsConstructor |
| 25 | @AllArgsConstructor | 25 | @AllArgsConstructor |
| 26 | -public class MemberStatisticsDO extends TenantBaseDO { | 26 | +public class MemberStatisticsDO extends BaseDO { |
| 27 | 27 | ||
| 28 | /** | 28 | /** |
| 29 | * 编号,主键自增 | 29 | * 编号,主键自增 |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/dataobject/trade/TradeStatisticsDO.java
| 1 | package cn.iocoder.yudao.module.statistics.dal.dataobject.trade; | 1 | package cn.iocoder.yudao.module.statistics.dal.dataobject.trade; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | import com.baomidou.mybatisplus.annotation.KeySequence; | 4 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 5 | import com.baomidou.mybatisplus.annotation.TableId; | 5 | import com.baomidou.mybatisplus.annotation.TableId; |
| 6 | import com.baomidou.mybatisplus.annotation.TableName; | 6 | import com.baomidou.mybatisplus.annotation.TableName; |
| @@ -23,7 +23,7 @@ import java.time.LocalDateTime; | @@ -23,7 +23,7 @@ import java.time.LocalDateTime; | ||
| 23 | @Builder | 23 | @Builder |
| 24 | @NoArgsConstructor | 24 | @NoArgsConstructor |
| 25 | @AllArgsConstructor | 25 | @AllArgsConstructor |
| 26 | -public class TradeStatisticsDO extends TenantBaseDO { | 26 | +public class TradeStatisticsDO extends BaseDO { |
| 27 | 27 | ||
| 28 | /** | 28 | /** |
| 29 | * 编号,主键自增 | 29 | * 编号,主键自增 |
yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/pay/PayWalletStatisticsServiceImpl.java
| 1 | package cn.iocoder.yudao.module.statistics.service.pay; | 1 | package cn.iocoder.yudao.module.statistics.service.pay; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | 3 | +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; |
| 4 | import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | 4 | import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; |
| 5 | import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; | 5 | import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; |
| 6 | import cn.iocoder.yudao.module.statistics.dal.mysql.pay.PayWalletStatisticsMapper; | 6 | import cn.iocoder.yudao.module.statistics.dal.mysql.pay.PayWalletStatisticsMapper; |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageUserController.java
| @@ -77,6 +77,7 @@ public class BrokerageUserController { | @@ -77,6 +77,7 @@ public class BrokerageUserController { | ||
| 77 | @PreAuthorize("@ss.hasPermission('trade:brokerage-user:query')") | 77 | @PreAuthorize("@ss.hasPermission('trade:brokerage-user:query')") |
| 78 | public CommonResult<BrokerageUserRespVO> getBrokerageUser(@RequestParam("id") Long id) { | 78 | public CommonResult<BrokerageUserRespVO> getBrokerageUser(@RequestParam("id") Long id) { |
| 79 | BrokerageUserDO brokerageUser = brokerageUserService.getBrokerageUser(id); | 79 | BrokerageUserDO brokerageUser = brokerageUserService.getBrokerageUser(id); |
| 80 | + // TODO @疯狂:是不是搞成一个统一的 convert? | ||
| 80 | BrokerageUserRespVO respVO = BrokerageUserConvert.INSTANCE.convert(brokerageUser); | 81 | BrokerageUserRespVO respVO = BrokerageUserConvert.INSTANCE.convert(brokerageUser); |
| 81 | return success(BrokerageUserConvert.INSTANCE.copyTo(memberUserApi.getUser(id), respVO)); | 82 | return success(BrokerageUserConvert.INSTANCE.copyTo(memberUserApi.getUser(id), respVO)); |
| 82 | } | 83 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
| @@ -7,7 +7,7 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | @@ -7,7 +7,7 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 7 | import cn.iocoder.yudao.framework.common.util.string.StrUtils; | 7 | import cn.iocoder.yudao.framework.common.util.string.StrUtils; |
| 8 | import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | 8 | import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; |
| 9 | import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; | 9 | import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; |
| 10 | -import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; | 10 | +import cn.iocoder.yudao.module.member.api.address.dto.MemberAddressRespDTO; |
| 11 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | 11 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; |
| 12 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; | 12 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; |
| 13 | import cn.iocoder.yudao.module.pay.enums.DictTypeConstants; | 13 | import cn.iocoder.yudao.module.pay.enums.DictTypeConstants; |
| @@ -241,7 +241,7 @@ public interface TradeOrderConvert { | @@ -241,7 +241,7 @@ public interface TradeOrderConvert { | ||
| 241 | return reqBO; | 241 | return reqBO; |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | - default AppTradeOrderSettlementRespVO convert(TradePriceCalculateRespBO calculate, AddressRespDTO address) { | 244 | + default AppTradeOrderSettlementRespVO convert(TradePriceCalculateRespBO calculate, MemberAddressRespDTO address) { |
| 245 | AppTradeOrderSettlementRespVO respVO = convert0(calculate, address); | 245 | AppTradeOrderSettlementRespVO respVO = convert0(calculate, address); |
| 246 | if (address != null) { | 246 | if (address != null) { |
| 247 | respVO.getAddress().setAreaName(AreaUtils.format(address.getAreaId())); | 247 | respVO.getAddress().setAreaName(AreaUtils.format(address.getAreaId())); |
| @@ -249,7 +249,7 @@ public interface TradeOrderConvert { | @@ -249,7 +249,7 @@ public interface TradeOrderConvert { | ||
| 249 | return respVO; | 249 | return respVO; |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | - AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, AddressRespDTO address); | 252 | + AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, MemberAddressRespDTO address); |
| 253 | 253 | ||
| 254 | List<AppOrderExpressTrackRespDTO> convertList02(List<ExpressTrackRespDTO> list); | 254 | List<AppOrderExpressTrackRespDTO> convertList02(List<ExpressTrackRespDTO> list); |
| 255 | 255 |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java
| @@ -232,7 +232,8 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | @@ -232,7 +232,8 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | ||
| 232 | return PageResult.empty(); | 232 | return PageResult.empty(); |
| 233 | } | 233 | } |
| 234 | // 1.2 根据昵称过滤下级用户 | 234 | // 1.2 根据昵称过滤下级用户 |
| 235 | - Map<Long, MemberUserRespDTO> userMap = convertMapByFilter(memberUserApi.getUserList(childIds), | 235 | + List<MemberUserRespDTO> users = memberUserApi.getUserList(childIds); |
| 236 | + Map<Long, MemberUserRespDTO> userMap = convertMapByFilter(users, | ||
| 236 | user -> StrUtil.contains(user.getNickname(), pageReqVO.getNickname()), | 237 | user -> StrUtil.contains(user.getNickname(), pageReqVO.getNickname()), |
| 237 | MemberUserRespDTO::getId); | 238 | MemberUserRespDTO::getId); |
| 238 | if (CollUtil.isEmpty(userMap)) { | 239 | if (CollUtil.isEmpty(userMap)) { |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
| @@ -11,8 +11,8 @@ import cn.iocoder.yudao.framework.common.core.KeyValue; | @@ -11,8 +11,8 @@ import cn.iocoder.yudao.framework.common.core.KeyValue; | ||
| 11 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | 11 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |
| 12 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 12 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 13 | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; | 13 | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; |
| 14 | -import cn.iocoder.yudao.module.member.api.address.AddressApi; | ||
| 15 | -import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; | 14 | +import cn.iocoder.yudao.module.member.api.address.MemberAddressApi; |
| 15 | +import cn.iocoder.yudao.module.member.api.address.dto.MemberAddressRespDTO; | ||
| 16 | import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; | 16 | import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; |
| 17 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; | 17 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; |
| 18 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; | 18 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; |
| @@ -98,7 +98,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | @@ -98,7 +98,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 98 | @Resource | 98 | @Resource |
| 99 | private PayOrderApi payOrderApi; | 99 | private PayOrderApi payOrderApi; |
| 100 | @Resource | 100 | @Resource |
| 101 | - private AddressApi addressApi; | 101 | + private MemberAddressApi addressApi; |
| 102 | @Resource | 102 | @Resource |
| 103 | private ProductCommentApi productCommentApi; | 103 | private ProductCommentApi productCommentApi; |
| 104 | 104 | ||
| @@ -110,7 +110,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | @@ -110,7 +110,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 110 | @Override | 110 | @Override |
| 111 | public AppTradeOrderSettlementRespVO settlementOrder(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) { | 111 | public AppTradeOrderSettlementRespVO settlementOrder(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) { |
| 112 | // 1. 获得收货地址 | 112 | // 1. 获得收货地址 |
| 113 | - AddressRespDTO address = getAddress(userId, settlementReqVO.getAddressId()); | 113 | + MemberAddressRespDTO address = getAddress(userId, settlementReqVO.getAddressId()); |
| 114 | if (address != null) { | 114 | if (address != null) { |
| 115 | settlementReqVO.setAddressId(address.getId()); | 115 | settlementReqVO.setAddressId(address.getId()); |
| 116 | } | 116 | } |
| @@ -129,7 +129,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | @@ -129,7 +129,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 129 | * @param addressId 地址编号 | 129 | * @param addressId 地址编号 |
| 130 | * @return 地址 | 130 | * @return 地址 |
| 131 | */ | 131 | */ |
| 132 | - private AddressRespDTO getAddress(Long userId, Long addressId) { | 132 | + private MemberAddressRespDTO getAddress(Long userId, Long addressId) { |
| 133 | if (addressId != null) { | 133 | if (addressId != null) { |
| 134 | return addressApi.getAddress(addressId, userId); | 134 | return addressApi.getAddress(addressId, userId); |
| 135 | } | 135 | } |
| @@ -193,7 +193,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | @@ -193,7 +193,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 193 | // 物流信息 | 193 | // 物流信息 |
| 194 | order.setDeliveryType(createReqVO.getDeliveryType()); | 194 | order.setDeliveryType(createReqVO.getDeliveryType()); |
| 195 | if (Objects.equals(createReqVO.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getType())) { | 195 | if (Objects.equals(createReqVO.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getType())) { |
| 196 | - AddressRespDTO address = addressApi.getAddress(createReqVO.getAddressId(), userId); | 196 | + MemberAddressRespDTO address = addressApi.getAddress(createReqVO.getAddressId(), userId); |
| 197 | Assert.notNull(address, "地址({}) 不能为空", createReqVO.getAddressId()); // 价格计算时,已经计算 | 197 | Assert.notNull(address, "地址({}) 不能为空", createReqVO.getAddressId()); // 价格计算时,已经计算 |
| 198 | order.setReceiverName(address.getName()).setReceiverMobile(address.getMobile()) | 198 | order.setReceiverName(address.getName()).setReceiverMobile(address.getMobile()) |
| 199 | .setReceiverAreaId(address.getAreaId()).setReceiverDetailAddress(address.getDetailAddress()); | 199 | .setReceiverAreaId(address.getAreaId()).setReceiverDetailAddress(address.getDetailAddress()); |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java
| @@ -4,8 +4,8 @@ import cn.hutool.core.collection.CollUtil; | @@ -4,8 +4,8 @@ import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.hutool.core.lang.Assert; | 4 | import cn.hutool.core.lang.Assert; |
| 5 | import cn.hutool.core.util.StrUtil; | 5 | import cn.hutool.core.util.StrUtil; |
| 6 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 6 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 7 | -import cn.iocoder.yudao.module.member.api.address.AddressApi; | ||
| 8 | -import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; | 7 | +import cn.iocoder.yudao.module.member.api.address.MemberAddressApi; |
| 8 | +import cn.iocoder.yudao.module.member.api.address.dto.MemberAddressRespDTO; | ||
| 9 | import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO; | 9 | import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO; |
| 10 | import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; | 10 | import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; |
| 11 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; | 11 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; |
| @@ -41,7 +41,7 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; | @@ -41,7 +41,7 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; | ||
| 41 | public class TradeDeliveryPriceCalculator implements TradePriceCalculator { | 41 | public class TradeDeliveryPriceCalculator implements TradePriceCalculator { |
| 42 | 42 | ||
| 43 | @Resource | 43 | @Resource |
| 44 | - private AddressApi addressApi; | 44 | + private MemberAddressApi addressApi; |
| 45 | 45 | ||
| 46 | @Resource | 46 | @Resource |
| 47 | private DeliveryPickUpStoreService deliveryPickUpStoreService; | 47 | private DeliveryPickUpStoreService deliveryPickUpStoreService; |
| @@ -81,7 +81,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { | @@ -81,7 +81,7 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { | ||
| 81 | // 价格计算时,如果为空就不算~最终下单,会校验该字段不允许空 | 81 | // 价格计算时,如果为空就不算~最终下单,会校验该字段不允许空 |
| 82 | return; | 82 | return; |
| 83 | } | 83 | } |
| 84 | - AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId()); | 84 | + MemberAddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId()); |
| 85 | Assert.notNull(address, "收件人({})的地址,不能为空", param.getUserId()); | 85 | Assert.notNull(address, "收件人({})的地址,不能为空", param.getUserId()); |
| 86 | 86 | ||
| 87 | // 情况一:全局包邮 | 87 | // 情况一:全局包邮 |
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceTest.java
| 1 | package cn.iocoder.yudao.module.trade.service.order; | 1 | package cn.iocoder.yudao.module.trade.service.order; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.common.enums.TerminalEnum; | ||
| 4 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | 3 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| 5 | -import cn.iocoder.yudao.module.member.api.address.AddressApi; | ||
| 6 | -import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; | 4 | +import cn.iocoder.yudao.module.member.api.address.MemberAddressApi; |
| 7 | import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | 5 | import cn.iocoder.yudao.module.member.api.user.MemberUserApi; |
| 8 | import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; | 6 | import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; |
| 9 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; | 7 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; |
| 10 | import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | 8 | import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; |
| 11 | -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; | ||
| 12 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | 9 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; |
| 13 | -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | ||
| 14 | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | 10 | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; |
| 15 | -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | ||
| 16 | -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; | ||
| 17 | import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; | 11 | import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; |
| 18 | -import cn.iocoder.yudao.module.promotion.api.price.PriceApi; | ||
| 19 | -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; | ||
| 20 | import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; | 12 | import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; |
| 21 | -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; | ||
| 22 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; | 13 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; |
| 23 | -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; | ||
| 24 | import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; | 14 | import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; |
| 25 | import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; | 15 | import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; |
| 26 | -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; | ||
| 27 | -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderRefundStatusEnum; | ||
| 28 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; | 16 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; |
| 29 | -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | ||
| 30 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderConfig; | 17 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderConfig; |
| 31 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; | 18 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; |
| 32 | import org.junit.jupiter.api.BeforeEach; | 19 | import org.junit.jupiter.api.BeforeEach; |
| @@ -36,17 +23,11 @@ import org.springframework.context.annotation.Import; | @@ -36,17 +23,11 @@ import org.springframework.context.annotation.Import; | ||
| 36 | 23 | ||
| 37 | import javax.annotation.Resource; | 24 | import javax.annotation.Resource; |
| 38 | import java.time.Duration; | 25 | import java.time.Duration; |
| 39 | -import java.util.Arrays; | ||
| 40 | -import java.util.List; | ||
| 41 | 26 | ||
| 42 | -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; | ||
| 43 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | 27 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; |
| 44 | import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | 28 | import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; |
| 45 | -import static java.util.Collections.singletonList; | ||
| 46 | import static org.junit.jupiter.api.Assertions.*; | 29 | import static org.junit.jupiter.api.Assertions.*; |
| 47 | -import static org.mockito.ArgumentMatchers.argThat; | ||
| 48 | import static org.mockito.ArgumentMatchers.eq; | 30 | import static org.mockito.ArgumentMatchers.eq; |
| 49 | -import static org.mockito.Mockito.verify; | ||
| 50 | import static org.mockito.Mockito.when; | 31 | import static org.mockito.Mockito.when; |
| 51 | 32 | ||
| 52 | /** | 33 | /** |
| @@ -72,12 +53,12 @@ public class TradeOrderUpdateServiceTest extends BaseDbUnitTest { | @@ -72,12 +53,12 @@ public class TradeOrderUpdateServiceTest extends BaseDbUnitTest { | ||
| 72 | private ProductSpuApi productSpuApi; | 53 | private ProductSpuApi productSpuApi; |
| 73 | @MockBean | 54 | @MockBean |
| 74 | private ProductSkuApi productSkuApi; | 55 | private ProductSkuApi productSkuApi; |
| 75 | - @MockBean | ||
| 76 | - private PriceApi priceApi; | 56 | +// @MockBean |
| 57 | +// private PriceApi priceApi; | ||
| 77 | @MockBean | 58 | @MockBean |
| 78 | private PayOrderApi payOrderApi; | 59 | private PayOrderApi payOrderApi; |
| 79 | @MockBean | 60 | @MockBean |
| 80 | - private AddressApi addressApi; | 61 | + private MemberAddressApi addressApi; |
| 81 | @MockBean | 62 | @MockBean |
| 82 | private CouponApi couponApi; | 63 | private CouponApi couponApi; |
| 83 | 64 | ||
| @@ -90,159 +71,159 @@ public class TradeOrderUpdateServiceTest extends BaseDbUnitTest { | @@ -90,159 +71,159 @@ public class TradeOrderUpdateServiceTest extends BaseDbUnitTest { | ||
| 90 | when(tradeOrderProperties.getPayExpireTime()).thenReturn(Duration.ofDays(1)); | 71 | when(tradeOrderProperties.getPayExpireTime()).thenReturn(Duration.ofDays(1)); |
| 91 | } | 72 | } |
| 92 | 73 | ||
| 93 | - @Test | ||
| 94 | - public void testCreateTradeOrder_success() { | ||
| 95 | - // 准备参数 | ||
| 96 | - Long userId = 100L; | ||
| 97 | - String userIp = "127.0.0.1"; | ||
| 98 | -// AppTradeOrderCreateReqVO reqVO = new AppTradeOrderCreateReqVO() | ||
| 99 | -// .setAddressId(10L).setCouponId(101L).setRemark("我是备注").setFromCart(true) | ||
| 100 | -// .setItems(Arrays.asList(new AppTradeOrderCreateReqVO.Item().setSkuId(1L).setCount(3), | ||
| 101 | -// new AppTradeOrderCreateReqVO.Item().setSkuId(2L).setCount(4))); | ||
| 102 | - AppTradeOrderCreateReqVO reqVO = null; | ||
| 103 | - // TODO 芋艿:重新高下 | ||
| 104 | - // mock 方法(商品 SKU 检查) | ||
| 105 | - ProductSkuRespDTO sku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(1L).setSpuId(11L) | ||
| 106 | - .setPrice(50).setStock(100) | ||
| 107 | - .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(111L).setValueId(222L)))); | ||
| 108 | - ProductSkuRespDTO sku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(2L).setSpuId(21L) | ||
| 109 | - .setPrice(20).setStock(50)) | ||
| 110 | - .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(333L).setValueId(444L))); | ||
| 111 | - when(productSkuApi.getSkuList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(sku01, sku02)); | ||
| 112 | - // mock 方法(商品 SPU 检查) | ||
| 113 | - ProductSpuRespDTO spu01 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(11L) | ||
| 114 | - .setStatus(ProductSpuStatusEnum.ENABLE.getStatus()).setName("商品 1")); | ||
| 115 | - ProductSpuRespDTO spu02 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(21L) | ||
| 116 | - .setStatus(ProductSpuStatusEnum.ENABLE.getStatus())); | ||
| 117 | - when(productSpuApi.getSpuList(eq(asSet(11L, 21L)))).thenReturn(Arrays.asList(spu01, spu02)); | ||
| 118 | - // mock 方法(用户收件地址的校验) | ||
| 119 | - AddressRespDTO addressRespDTO = new AddressRespDTO().setId(10L).setUserId(userId).setName("芋艿") | ||
| 120 | - .setMobile("15601691300").setAreaId(3306).setDetailAddress("土豆村"); | ||
| 121 | - when(addressApi.getAddress(eq(10L), eq(userId))).thenReturn(addressRespDTO); | ||
| 122 | - // mock 方法(价格计算) | ||
| 123 | - PriceCalculateRespDTO.OrderItem priceOrderItem01 = new PriceCalculateRespDTO.OrderItem() | ||
| 124 | - .setSpuId(11L).setSkuId(1L).setCount(3).setOriginalPrice(150).setOriginalUnitPrice(50) | ||
| 125 | - .setDiscountPrice(20).setPayPrice(130).setOrderPartPrice(7).setOrderDividePrice(35); | ||
| 126 | - PriceCalculateRespDTO.OrderItem priceOrderItem02 = new PriceCalculateRespDTO.OrderItem() | ||
| 127 | - .setSpuId(21L).setSkuId(2L).setCount(4).setOriginalPrice(80).setOriginalUnitPrice(20) | ||
| 128 | - .setDiscountPrice(40).setPayPrice(40).setOrderPartPrice(15).setOrderDividePrice(25); | ||
| 129 | - PriceCalculateRespDTO.Order priceOrder = new PriceCalculateRespDTO.Order() | ||
| 130 | - .setTotalPrice(230).setDiscountPrice(0).setCouponPrice(30) | ||
| 131 | - .setPointPrice(10).setDeliveryPrice(20).setPayPrice(80).setCouponId(101L).setCouponPrice(30) | ||
| 132 | - .setItems(Arrays.asList(priceOrderItem01, priceOrderItem02)); | ||
| 133 | - when(priceApi.calculatePrice(argThat(priceCalculateReqDTO -> { | ||
| 134 | - assertEquals(priceCalculateReqDTO.getUserId(), 100L); | ||
| 135 | - assertEquals(priceCalculateReqDTO.getCouponId(), 101L); | ||
| 136 | - assertEquals(priceCalculateReqDTO.getItems().get(0).getSkuId(), 1L); | ||
| 137 | - assertEquals(priceCalculateReqDTO.getItems().get(0).getCount(), 3); | ||
| 138 | - assertEquals(priceCalculateReqDTO.getItems().get(1).getSkuId(), 2L); | ||
| 139 | - assertEquals(priceCalculateReqDTO.getItems().get(1).getCount(), 4); | ||
| 140 | - return true; | ||
| 141 | - }))).thenReturn(new PriceCalculateRespDTO().setOrder(priceOrder)); | ||
| 142 | - // mock 方法(创建支付单) | ||
| 143 | - when(payOrderApi.createOrder(argThat(createReqDTO -> { | ||
| 144 | - assertEquals(createReqDTO.getAppId(), 888L); | ||
| 145 | - assertEquals(createReqDTO.getUserIp(), userIp); | ||
| 146 | - assertNotNull(createReqDTO.getMerchantOrderId()); // 由于 tradeOrderId 后生成,只能校验非空 | ||
| 147 | - assertEquals(createReqDTO.getSubject(), "商品 1 等多件"); | ||
| 148 | - assertNull(createReqDTO.getBody()); | ||
| 149 | - assertEquals(createReqDTO.getPrice(), 80); | ||
| 150 | - assertNotNull(createReqDTO.getExpireTime()); | ||
| 151 | - return true; | ||
| 152 | - }))).thenReturn(1000L); | ||
| 153 | - | ||
| 154 | - // 调用方法 | ||
| 155 | - TradeOrderDO order = tradeOrderUpdateService.createOrder(userId, userIp, reqVO, null); | ||
| 156 | - // 断言 TradeOrderDO 订单 | ||
| 157 | - List<TradeOrderDO> tradeOrderDOs = tradeOrderMapper.selectList(); | ||
| 158 | - assertEquals(tradeOrderDOs.size(), 1); | ||
| 159 | - TradeOrderDO tradeOrderDO = tradeOrderDOs.get(0); | ||
| 160 | - assertEquals(tradeOrderDO.getId(), order.getId()); | ||
| 161 | - assertNotNull(tradeOrderDO.getNo()); | ||
| 162 | - assertEquals(tradeOrderDO.getType(), TradeOrderTypeEnum.NORMAL.getType()); | ||
| 163 | - assertEquals(tradeOrderDO.getTerminal(), TerminalEnum.H5.getTerminal()); | ||
| 164 | - assertEquals(tradeOrderDO.getUserId(), userId); | ||
| 165 | - assertEquals(tradeOrderDO.getUserIp(), userIp); | ||
| 166 | - assertEquals(tradeOrderDO.getStatus(), TradeOrderStatusEnum.UNPAID.getStatus()); | ||
| 167 | - assertEquals(tradeOrderDO.getProductCount(), 7); | ||
| 168 | - assertNull(tradeOrderDO.getFinishTime()); | ||
| 169 | - assertNull(tradeOrderDO.getCancelTime()); | ||
| 170 | - assertNull(tradeOrderDO.getCancelType()); | ||
| 171 | - assertEquals(tradeOrderDO.getUserRemark(), "我是备注"); | ||
| 172 | - assertNull(tradeOrderDO.getRemark()); | ||
| 173 | - assertFalse(tradeOrderDO.getPayStatus()); | ||
| 174 | - assertNull(tradeOrderDO.getPayTime()); | ||
| 175 | - assertEquals(tradeOrderDO.getTotalPrice(), 230); | ||
| 176 | - assertEquals(tradeOrderDO.getDiscountPrice(), 0); | ||
| 177 | - assertEquals(tradeOrderDO.getAdjustPrice(), 0); | ||
| 178 | - assertEquals(tradeOrderDO.getPayPrice(), 80); | ||
| 179 | - assertEquals(tradeOrderDO.getPayOrderId(), 1000L); | ||
| 180 | - assertNull(tradeOrderDO.getPayChannelCode()); | ||
| 181 | - assertNull(tradeOrderDO.getLogisticsId()); | ||
| 182 | - assertNull(tradeOrderDO.getDeliveryTime()); | ||
| 183 | - assertNull(tradeOrderDO.getReceiveTime()); | ||
| 184 | - assertEquals(tradeOrderDO.getReceiverName(), "芋艿"); | ||
| 185 | - assertEquals(tradeOrderDO.getReceiverMobile(), "15601691300"); | ||
| 186 | - assertEquals(tradeOrderDO.getReceiverAreaId(), 3306); | ||
| 187 | - assertEquals(tradeOrderDO.getReceiverDetailAddress(), "土豆村"); | ||
| 188 | - assertEquals(tradeOrderDO.getRefundStatus(), TradeOrderRefundStatusEnum.NONE.getStatus()); | ||
| 189 | - assertEquals(tradeOrderDO.getRefundPrice(), 0); | ||
| 190 | - assertEquals(tradeOrderDO.getCouponPrice(), 30); | ||
| 191 | - assertEquals(tradeOrderDO.getPointPrice(), 10); | ||
| 192 | - // 断言 TradeOrderItemDO 订单(第 1 个) | ||
| 193 | - List<TradeOrderItemDO> tradeOrderItemDOs = tradeOrderItemMapper.selectList(); | ||
| 194 | - assertEquals(tradeOrderItemDOs.size(), 2); | ||
| 195 | - TradeOrderItemDO tradeOrderItemDO01 = tradeOrderItemDOs.get(0); | ||
| 196 | - assertNotNull(tradeOrderItemDO01.getId()); | ||
| 197 | - assertEquals(tradeOrderItemDO01.getUserId(), userId); | ||
| 198 | - assertEquals(tradeOrderItemDO01.getOrderId(), order.getId()); | ||
| 199 | - assertEquals(tradeOrderItemDO01.getSpuId(), 11L); | ||
| 200 | - assertEquals(tradeOrderItemDO01.getSkuId(), 1L); | ||
| 201 | - assertEquals(tradeOrderItemDO01.getProperties().size(), 1); | ||
| 202 | - assertEquals(tradeOrderItemDO01.getProperties().get(0).getPropertyId(), 111L); | ||
| 203 | - assertEquals(tradeOrderItemDO01.getProperties().get(0).getValueId(), 222L); | ||
| 204 | - //assertEquals(tradeOrderItemDO01.getSpuName(), sku01.getSpuName()); TODO 找不到spuName | ||
| 205 | - assertEquals(tradeOrderItemDO01.getPicUrl(), sku01.getPicUrl()); | ||
| 206 | - assertEquals(tradeOrderItemDO01.getCount(), 3); | ||
| 207 | -// assertEquals(tradeOrderItemDO01.getOriginalPrice(), 150); | ||
| 208 | - assertEquals(tradeOrderItemDO01.getPrice(), 50); | ||
| 209 | - assertEquals(tradeOrderItemDO01.getDiscountPrice(), 20); | ||
| 210 | - assertEquals(tradeOrderItemDO01.getPayPrice(), 130); | ||
| 211 | - assertEquals(tradeOrderItemDO01.getAfterSaleStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); | ||
| 212 | - // 断言 TradeOrderItemDO 订单(第 2 个) | ||
| 213 | - TradeOrderItemDO tradeOrderItemDO02 = tradeOrderItemDOs.get(1); | ||
| 214 | - assertNotNull(tradeOrderItemDO02.getId()); | ||
| 215 | - assertEquals(tradeOrderItemDO02.getUserId(), userId); | ||
| 216 | - assertEquals(tradeOrderItemDO02.getOrderId(), order.getId()); | ||
| 217 | - assertEquals(tradeOrderItemDO02.getSpuId(), 21L); | ||
| 218 | - assertEquals(tradeOrderItemDO02.getSkuId(), 2L); | ||
| 219 | - assertEquals(tradeOrderItemDO02.getProperties().size(), 1); | ||
| 220 | - assertEquals(tradeOrderItemDO02.getProperties().get(0).getPropertyId(), 333L); | ||
| 221 | - assertEquals(tradeOrderItemDO02.getProperties().get(0).getValueId(), 444L); | ||
| 222 | - //assertEquals(tradeOrderItemDO02.getSpuName(), sku02.getSpuName()); TODO 找不到spuName | ||
| 223 | - assertEquals(tradeOrderItemDO02.getPicUrl(), sku02.getPicUrl()); | ||
| 224 | - assertEquals(tradeOrderItemDO02.getCount(), 4); | ||
| 225 | -// assertEquals(tradeOrderItemDO02.getOriginalPrice(), 80); | ||
| 226 | - assertEquals(tradeOrderItemDO02.getPrice(), 20); | ||
| 227 | - assertEquals(tradeOrderItemDO02.getDiscountPrice(), 40); | ||
| 228 | - assertEquals(tradeOrderItemDO02.getPayPrice(), 40); | ||
| 229 | - assertEquals(tradeOrderItemDO02.getAfterSaleStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); | ||
| 230 | - // 校验调用 | ||
| 231 | - verify(productSkuApi).updateSkuStock(argThat(updateStockReqDTO -> { | ||
| 232 | - assertEquals(updateStockReqDTO.getItems().size(), 2); | ||
| 233 | - assertEquals(updateStockReqDTO.getItems().get(0).getId(), 1L); | ||
| 234 | - assertEquals(updateStockReqDTO.getItems().get(0).getIncrCount(), 3); | ||
| 235 | - assertEquals(updateStockReqDTO.getItems().get(1).getId(), 2L); | ||
| 236 | - assertEquals(updateStockReqDTO.getItems().get(1).getIncrCount(), 4); | ||
| 237 | - return true; | ||
| 238 | - })); | ||
| 239 | - verify(couponApi).useCoupon(argThat(reqDTO -> { | ||
| 240 | - assertEquals(reqDTO.getId(), reqVO.getCouponId()); | ||
| 241 | - assertEquals(reqDTO.getUserId(), userId); | ||
| 242 | - assertEquals(reqDTO.getOrderId(), order.getId()); | ||
| 243 | - return true; | ||
| 244 | - })); | ||
| 245 | - } | 74 | +// @Test |
| 75 | +// public void testCreateTradeOrder_success() { | ||
| 76 | +// // 准备参数 | ||
| 77 | +// Long userId = 100L; | ||
| 78 | +// String userIp = "127.0.0.1"; | ||
| 79 | +//// AppTradeOrderCreateReqVO reqVO = new AppTradeOrderCreateReqVO() | ||
| 80 | +//// .setAddressId(10L).setCouponId(101L).setRemark("我是备注").setFromCart(true) | ||
| 81 | +//// .setItems(Arrays.asList(new AppTradeOrderCreateReqVO.Item().setSkuId(1L).setCount(3), | ||
| 82 | +//// new AppTradeOrderCreateReqVO.Item().setSkuId(2L).setCount(4))); | ||
| 83 | +// AppTradeOrderCreateReqVO reqVO = null; | ||
| 84 | +// // TODO 芋艿:重新高下 | ||
| 85 | +// // mock 方法(商品 SKU 检查) | ||
| 86 | +// ProductSkuRespDTO sku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(1L).setSpuId(11L) | ||
| 87 | +// .setPrice(50).setStock(100) | ||
| 88 | +// .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(111L).setValueId(222L)))); | ||
| 89 | +// ProductSkuRespDTO sku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(2L).setSpuId(21L) | ||
| 90 | +// .setPrice(20).setStock(50)) | ||
| 91 | +// .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(333L).setValueId(444L))); | ||
| 92 | +// when(productSkuApi.getSkuList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(sku01, sku02)); | ||
| 93 | +// // mock 方法(商品 SPU 检查) | ||
| 94 | +// ProductSpuRespDTO spu01 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(11L) | ||
| 95 | +// .setStatus(ProductSpuStatusEnum.ENABLE.getStatus()).setName("商品 1")); | ||
| 96 | +// ProductSpuRespDTO spu02 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(21L) | ||
| 97 | +// .setStatus(ProductSpuStatusEnum.ENABLE.getStatus())); | ||
| 98 | +// when(productSpuApi.getSpuList(eq(asSet(11L, 21L)))).thenReturn(Arrays.asList(spu01, spu02)); | ||
| 99 | +// // mock 方法(用户收件地址的校验) | ||
| 100 | +// MemberAddressRespDTO addressRespDTO = new MemberAddressRespDTO().setId(10L).setUserId(userId).setName("芋艿") | ||
| 101 | +// .setMobile("15601691300").setAreaId(3306).setDetailAddress("土豆村"); | ||
| 102 | +// when(addressApi.getAddress(eq(10L), eq(userId))).thenReturn(addressRespDTO); | ||
| 103 | +// // mock 方法(价格计算) | ||
| 104 | +// PriceCalculateRespDTO.OrderItem priceOrderItem01 = new PriceCalculateRespDTO.OrderItem() | ||
| 105 | +// .setSpuId(11L).setSkuId(1L).setCount(3).setOriginalPrice(150).setOriginalUnitPrice(50) | ||
| 106 | +// .setDiscountPrice(20).setPayPrice(130).setOrderPartPrice(7).setOrderDividePrice(35); | ||
| 107 | +// PriceCalculateRespDTO.OrderItem priceOrderItem02 = new PriceCalculateRespDTO.OrderItem() | ||
| 108 | +// .setSpuId(21L).setSkuId(2L).setCount(4).setOriginalPrice(80).setOriginalUnitPrice(20) | ||
| 109 | +// .setDiscountPrice(40).setPayPrice(40).setOrderPartPrice(15).setOrderDividePrice(25); | ||
| 110 | +// PriceCalculateRespDTO.Order priceOrder = new PriceCalculateRespDTO.Order() | ||
| 111 | +// .setTotalPrice(230).setDiscountPrice(0).setCouponPrice(30) | ||
| 112 | +// .setPointPrice(10).setDeliveryPrice(20).setPayPrice(80).setCouponId(101L).setCouponPrice(30) | ||
| 113 | +// .setItems(Arrays.asList(priceOrderItem01, priceOrderItem02)); | ||
| 114 | +// when(priceApi.calculatePrice(argThat(priceCalculateReqDTO -> { | ||
| 115 | +// assertEquals(priceCalculateReqDTO.getUserId(), 100L); | ||
| 116 | +// assertEquals(priceCalculateReqDTO.getCouponId(), 101L); | ||
| 117 | +// assertEquals(priceCalculateReqDTO.getItems().get(0).getSkuId(), 1L); | ||
| 118 | +// assertEquals(priceCalculateReqDTO.getItems().get(0).getCount(), 3); | ||
| 119 | +// assertEquals(priceCalculateReqDTO.getItems().get(1).getSkuId(), 2L); | ||
| 120 | +// assertEquals(priceCalculateReqDTO.getItems().get(1).getCount(), 4); | ||
| 121 | +// return true; | ||
| 122 | +// }))).thenReturn(new PriceCalculateRespDTO().setOrder(priceOrder)); | ||
| 123 | +// // mock 方法(创建支付单) | ||
| 124 | +// when(payOrderApi.createOrder(argThat(createReqDTO -> { | ||
| 125 | +// assertEquals(createReqDTO.getAppId(), 888L); | ||
| 126 | +// assertEquals(createReqDTO.getUserIp(), userIp); | ||
| 127 | +// assertNotNull(createReqDTO.getMerchantOrderId()); // 由于 tradeOrderId 后生成,只能校验非空 | ||
| 128 | +// assertEquals(createReqDTO.getSubject(), "商品 1 等多件"); | ||
| 129 | +// assertNull(createReqDTO.getBody()); | ||
| 130 | +// assertEquals(createReqDTO.getPrice(), 80); | ||
| 131 | +// assertNotNull(createReqDTO.getExpireTime()); | ||
| 132 | +// return true; | ||
| 133 | +// }))).thenReturn(1000L); | ||
| 134 | +// | ||
| 135 | +// // 调用方法 | ||
| 136 | +// TradeOrderDO order = tradeOrderUpdateService.createOrder(userId, userIp, reqVO, null); | ||
| 137 | +// // 断言 TradeOrderDO 订单 | ||
| 138 | +// List<TradeOrderDO> tradeOrderDOs = tradeOrderMapper.selectList(); | ||
| 139 | +// assertEquals(tradeOrderDOs.size(), 1); | ||
| 140 | +// TradeOrderDO tradeOrderDO = tradeOrderDOs.get(0); | ||
| 141 | +// assertEquals(tradeOrderDO.getId(), order.getId()); | ||
| 142 | +// assertNotNull(tradeOrderDO.getNo()); | ||
| 143 | +// assertEquals(tradeOrderDO.getType(), TradeOrderTypeEnum.NORMAL.getType()); | ||
| 144 | +// assertEquals(tradeOrderDO.getTerminal(), TerminalEnum.H5.getTerminal()); | ||
| 145 | +// assertEquals(tradeOrderDO.getUserId(), userId); | ||
| 146 | +// assertEquals(tradeOrderDO.getUserIp(), userIp); | ||
| 147 | +// assertEquals(tradeOrderDO.getStatus(), TradeOrderStatusEnum.UNPAID.getStatus()); | ||
| 148 | +// assertEquals(tradeOrderDO.getProductCount(), 7); | ||
| 149 | +// assertNull(tradeOrderDO.getFinishTime()); | ||
| 150 | +// assertNull(tradeOrderDO.getCancelTime()); | ||
| 151 | +// assertNull(tradeOrderDO.getCancelType()); | ||
| 152 | +// assertEquals(tradeOrderDO.getUserRemark(), "我是备注"); | ||
| 153 | +// assertNull(tradeOrderDO.getRemark()); | ||
| 154 | +// assertFalse(tradeOrderDO.getPayStatus()); | ||
| 155 | +// assertNull(tradeOrderDO.getPayTime()); | ||
| 156 | +// assertEquals(tradeOrderDO.getTotalPrice(), 230); | ||
| 157 | +// assertEquals(tradeOrderDO.getDiscountPrice(), 0); | ||
| 158 | +// assertEquals(tradeOrderDO.getAdjustPrice(), 0); | ||
| 159 | +// assertEquals(tradeOrderDO.getPayPrice(), 80); | ||
| 160 | +// assertEquals(tradeOrderDO.getPayOrderId(), 1000L); | ||
| 161 | +// assertNull(tradeOrderDO.getPayChannelCode()); | ||
| 162 | +// assertNull(tradeOrderDO.getLogisticsId()); | ||
| 163 | +// assertNull(tradeOrderDO.getDeliveryTime()); | ||
| 164 | +// assertNull(tradeOrderDO.getReceiveTime()); | ||
| 165 | +// assertEquals(tradeOrderDO.getReceiverName(), "芋艿"); | ||
| 166 | +// assertEquals(tradeOrderDO.getReceiverMobile(), "15601691300"); | ||
| 167 | +// assertEquals(tradeOrderDO.getReceiverAreaId(), 3306); | ||
| 168 | +// assertEquals(tradeOrderDO.getReceiverDetailAddress(), "土豆村"); | ||
| 169 | +// assertEquals(tradeOrderDO.getRefundStatus(), TradeOrderRefundStatusEnum.NONE.getStatus()); | ||
| 170 | +// assertEquals(tradeOrderDO.getRefundPrice(), 0); | ||
| 171 | +// assertEquals(tradeOrderDO.getCouponPrice(), 30); | ||
| 172 | +// assertEquals(tradeOrderDO.getPointPrice(), 10); | ||
| 173 | +// // 断言 TradeOrderItemDO 订单(第 1 个) | ||
| 174 | +// List<TradeOrderItemDO> tradeOrderItemDOs = tradeOrderItemMapper.selectList(); | ||
| 175 | +// assertEquals(tradeOrderItemDOs.size(), 2); | ||
| 176 | +// TradeOrderItemDO tradeOrderItemDO01 = tradeOrderItemDOs.get(0); | ||
| 177 | +// assertNotNull(tradeOrderItemDO01.getId()); | ||
| 178 | +// assertEquals(tradeOrderItemDO01.getUserId(), userId); | ||
| 179 | +// assertEquals(tradeOrderItemDO01.getOrderId(), order.getId()); | ||
| 180 | +// assertEquals(tradeOrderItemDO01.getSpuId(), 11L); | ||
| 181 | +// assertEquals(tradeOrderItemDO01.getSkuId(), 1L); | ||
| 182 | +// assertEquals(tradeOrderItemDO01.getProperties().size(), 1); | ||
| 183 | +// assertEquals(tradeOrderItemDO01.getProperties().get(0).getPropertyId(), 111L); | ||
| 184 | +// assertEquals(tradeOrderItemDO01.getProperties().get(0).getValueId(), 222L); | ||
| 185 | +// //assertEquals(tradeOrderItemDO01.getSpuName(), sku01.getSpuName()); TODO 找不到spuName | ||
| 186 | +// assertEquals(tradeOrderItemDO01.getPicUrl(), sku01.getPicUrl()); | ||
| 187 | +// assertEquals(tradeOrderItemDO01.getCount(), 3); | ||
| 188 | +//// assertEquals(tradeOrderItemDO01.getOriginalPrice(), 150); | ||
| 189 | +// assertEquals(tradeOrderItemDO01.getPrice(), 50); | ||
| 190 | +// assertEquals(tradeOrderItemDO01.getDiscountPrice(), 20); | ||
| 191 | +// assertEquals(tradeOrderItemDO01.getPayPrice(), 130); | ||
| 192 | +// assertEquals(tradeOrderItemDO01.getAfterSaleStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); | ||
| 193 | +// // 断言 TradeOrderItemDO 订单(第 2 个) | ||
| 194 | +// TradeOrderItemDO tradeOrderItemDO02 = tradeOrderItemDOs.get(1); | ||
| 195 | +// assertNotNull(tradeOrderItemDO02.getId()); | ||
| 196 | +// assertEquals(tradeOrderItemDO02.getUserId(), userId); | ||
| 197 | +// assertEquals(tradeOrderItemDO02.getOrderId(), order.getId()); | ||
| 198 | +// assertEquals(tradeOrderItemDO02.getSpuId(), 21L); | ||
| 199 | +// assertEquals(tradeOrderItemDO02.getSkuId(), 2L); | ||
| 200 | +// assertEquals(tradeOrderItemDO02.getProperties().size(), 1); | ||
| 201 | +// assertEquals(tradeOrderItemDO02.getProperties().get(0).getPropertyId(), 333L); | ||
| 202 | +// assertEquals(tradeOrderItemDO02.getProperties().get(0).getValueId(), 444L); | ||
| 203 | +// //assertEquals(tradeOrderItemDO02.getSpuName(), sku02.getSpuName()); TODO 找不到spuName | ||
| 204 | +// assertEquals(tradeOrderItemDO02.getPicUrl(), sku02.getPicUrl()); | ||
| 205 | +// assertEquals(tradeOrderItemDO02.getCount(), 4); | ||
| 206 | +//// assertEquals(tradeOrderItemDO02.getOriginalPrice(), 80); | ||
| 207 | +// assertEquals(tradeOrderItemDO02.getPrice(), 20); | ||
| 208 | +// assertEquals(tradeOrderItemDO02.getDiscountPrice(), 40); | ||
| 209 | +// assertEquals(tradeOrderItemDO02.getPayPrice(), 40); | ||
| 210 | +// assertEquals(tradeOrderItemDO02.getAfterSaleStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); | ||
| 211 | +// // 校验调用 | ||
| 212 | +// verify(productSkuApi).updateSkuStock(argThat(updateStockReqDTO -> { | ||
| 213 | +// assertEquals(updateStockReqDTO.getItems().size(), 2); | ||
| 214 | +// assertEquals(updateStockReqDTO.getItems().get(0).getId(), 1L); | ||
| 215 | +// assertEquals(updateStockReqDTO.getItems().get(0).getIncrCount(), 3); | ||
| 216 | +// assertEquals(updateStockReqDTO.getItems().get(1).getId(), 2L); | ||
| 217 | +// assertEquals(updateStockReqDTO.getItems().get(1).getIncrCount(), 4); | ||
| 218 | +// return true; | ||
| 219 | +// })); | ||
| 220 | +// verify(couponApi).useCoupon(argThat(reqDTO -> { | ||
| 221 | +// assertEquals(reqDTO.getId(), reqVO.getCouponId()); | ||
| 222 | +// assertEquals(reqDTO.getUserId(), userId); | ||
| 223 | +// assertEquals(reqDTO.getOrderId(), order.getId()); | ||
| 224 | +// return true; | ||
| 225 | +// })); | ||
| 226 | +// } | ||
| 246 | 227 | ||
| 247 | @Test | 228 | @Test |
| 248 | public void testUpdateOrderPaid() { | 229 | public void testUpdateOrderPaid() { |
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java
| @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; | @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.map.MapUtil; | 3 | import cn.hutool.core.map.MapUtil; |
| 4 | import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; | 4 | import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; |
| 5 | -import cn.iocoder.yudao.module.member.api.address.AddressApi; | ||
| 6 | -import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; | 5 | +import cn.iocoder.yudao.module.member.api.address.MemberAddressApi; |
| 6 | +import cn.iocoder.yudao.module.member.api.address.dto.MemberAddressRespDTO; | ||
| 7 | import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO; | 7 | import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO; |
| 8 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; | 8 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; |
| 9 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; | 9 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; |
| @@ -38,7 +38,7 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { | @@ -38,7 +38,7 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { | ||
| 38 | private TradeDeliveryPriceCalculator calculator; | 38 | private TradeDeliveryPriceCalculator calculator; |
| 39 | 39 | ||
| 40 | @Mock | 40 | @Mock |
| 41 | - private AddressApi addressApi; | 41 | + private MemberAddressApi addressApi; |
| 42 | 42 | ||
| 43 | @Mock | 43 | @Mock |
| 44 | private DeliveryExpressTemplateService deliveryExpressTemplateService; | 44 | private DeliveryExpressTemplateService deliveryExpressTemplateService; |
| @@ -80,7 +80,7 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { | @@ -80,7 +80,7 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { | ||
| 80 | TradePriceCalculatorHelper.recountAllPrice(resultBO); | 80 | TradePriceCalculatorHelper.recountAllPrice(resultBO); |
| 81 | 81 | ||
| 82 | // 准备收件地址数据 | 82 | // 准备收件地址数据 |
| 83 | - AddressRespDTO addressResp = randomPojo(AddressRespDTO.class, item -> item.setAreaId(10)); | 83 | + MemberAddressRespDTO addressResp = randomPojo(MemberAddressRespDTO.class, item -> item.setAreaId(10)); |
| 84 | when(addressApi.getAddress(eq(10L), eq(1L))).thenReturn(addressResp); | 84 | when(addressApi.getAddress(eq(10L), eq(1L))).thenReturn(addressResp); |
| 85 | 85 | ||
| 86 | // 准备运费模板费用配置数据 | 86 | // 准备运费模板费用配置数据 |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApi.java renamed to yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/MemberAddressApi.java
| 1 | package cn.iocoder.yudao.module.member.api.address; | 1 | package cn.iocoder.yudao.module.member.api.address; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; | 3 | +import cn.iocoder.yudao.module.member.api.address.dto.MemberAddressRespDTO; |
| 4 | 4 | ||
| 5 | /** | 5 | /** |
| 6 | * 用户收件地址 API 接口 | 6 | * 用户收件地址 API 接口 |
| 7 | * | 7 | * |
| 8 | * @author 芋道源码 | 8 | * @author 芋道源码 |
| 9 | */ | 9 | */ |
| 10 | -public interface AddressApi { | 10 | +public interface MemberAddressApi { |
| 11 | 11 | ||
| 12 | /** | 12 | /** |
| 13 | * 获得用户收件地址 | 13 | * 获得用户收件地址 |
| @@ -16,7 +16,7 @@ public interface AddressApi { | @@ -16,7 +16,7 @@ public interface AddressApi { | ||
| 16 | * @param userId 用户编号 | 16 | * @param userId 用户编号 |
| 17 | * @return 用户收件地址 | 17 | * @return 用户收件地址 |
| 18 | */ | 18 | */ |
| 19 | - AddressRespDTO getAddress(Long id, Long userId); | 19 | + MemberAddressRespDTO getAddress(Long id, Long userId); |
| 20 | 20 | ||
| 21 | /** | 21 | /** |
| 22 | * 获得用户默认收件地址 | 22 | * 获得用户默认收件地址 |
| @@ -24,6 +24,6 @@ public interface AddressApi { | @@ -24,6 +24,6 @@ public interface AddressApi { | ||
| 24 | * @param userId 用户编号 | 24 | * @param userId 用户编号 |
| 25 | * @return 用户收件地址 | 25 | * @return 用户收件地址 |
| 26 | */ | 26 | */ |
| 27 | - AddressRespDTO getDefaultAddress(Long userId); | 27 | + MemberAddressRespDTO getDefaultAddress(Long userId); |
| 28 | 28 | ||
| 29 | } | 29 | } |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/dto/AddressRespDTO.java renamed to yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/address/dto/MemberAddressRespDTO.java
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java
| @@ -38,7 +38,8 @@ public interface MemberUserApi { | @@ -38,7 +38,8 @@ public interface MemberUserApi { | ||
| 38 | * @return 会员用户 Map | 38 | * @return 会员用户 Map |
| 39 | */ | 39 | */ |
| 40 | default Map<Long, MemberUserRespDTO> getUserMap(Collection<Long> ids) { | 40 | default Map<Long, MemberUserRespDTO> getUserMap(Collection<Long> ids) { |
| 41 | - return convertMap(getUserList(ids), MemberUserRespDTO::getId); | 41 | + List<MemberUserRespDTO> list = getUserList(ids); |
| 42 | + return convertMap(list, MemberUserRespDTO::getId); | ||
| 42 | } | 43 | } |
| 43 | 44 | ||
| 44 | /** | 45 | /** |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/message/package-info.java
0 → 100644
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/mq/message/coupon/UserCreateMessage.java renamed to yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/message/user/MemberUserCreateMessage.java
| 1 | -package cn.iocoder.yudao.module.promotion.mq.message.coupon; | 1 | +package cn.iocoder.yudao.module.member.message.user; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage; | ||
| 4 | import lombok.Data; | 3 | import lombok.Data; |
| 5 | -import lombok.EqualsAndHashCode; | ||
| 6 | 4 | ||
| 7 | import javax.validation.constraints.NotNull; | 5 | import javax.validation.constraints.NotNull; |
| 8 | 6 | ||
| @@ -12,8 +10,7 @@ import javax.validation.constraints.NotNull; | @@ -12,8 +10,7 @@ import javax.validation.constraints.NotNull; | ||
| 12 | * @author owen | 10 | * @author owen |
| 13 | */ | 11 | */ |
| 14 | @Data | 12 | @Data |
| 15 | -@EqualsAndHashCode(callSuper = true) | ||
| 16 | -public class UserCreateMessage extends AbstractStreamMessage { | 13 | +public class MemberUserCreateMessage { |
| 17 | 14 | ||
| 18 | /** | 15 | /** |
| 19 | * 用户编号 | 16 | * 用户编号 |
| @@ -21,9 +18,4 @@ public class UserCreateMessage extends AbstractStreamMessage { | @@ -21,9 +18,4 @@ public class UserCreateMessage extends AbstractStreamMessage { | ||
| 21 | @NotNull(message = "用户编号不能为空") | 18 | @NotNull(message = "用户编号不能为空") |
| 22 | private Long userId; | 19 | private Long userId; |
| 23 | 20 | ||
| 24 | - @Override | ||
| 25 | - public String getStreamKey() { | ||
| 26 | - return "member.create.send"; | ||
| 27 | - } | ||
| 28 | - | ||
| 29 | } | 21 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/address/AddressApiImpl.java renamed to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/address/MemberAddressApiImpl.java
| 1 | package cn.iocoder.yudao.module.member.api.address; | 1 | package cn.iocoder.yudao.module.member.api.address; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; | 3 | +import cn.iocoder.yudao.module.member.api.address.dto.MemberAddressRespDTO; |
| 4 | import cn.iocoder.yudao.module.member.convert.address.AddressConvert; | 4 | import cn.iocoder.yudao.module.member.convert.address.AddressConvert; |
| 5 | import cn.iocoder.yudao.module.member.service.address.AddressService; | 5 | import cn.iocoder.yudao.module.member.service.address.AddressService; |
| 6 | import org.springframework.stereotype.Service; | 6 | import org.springframework.stereotype.Service; |
| @@ -15,18 +15,18 @@ import javax.annotation.Resource; | @@ -15,18 +15,18 @@ import javax.annotation.Resource; | ||
| 15 | */ | 15 | */ |
| 16 | @Service | 16 | @Service |
| 17 | @Validated | 17 | @Validated |
| 18 | -public class AddressApiImpl implements AddressApi { | 18 | +public class MemberAddressApiImpl implements MemberAddressApi { |
| 19 | 19 | ||
| 20 | @Resource | 20 | @Resource |
| 21 | private AddressService addressService; | 21 | private AddressService addressService; |
| 22 | 22 | ||
| 23 | @Override | 23 | @Override |
| 24 | - public AddressRespDTO getAddress(Long id, Long userId) { | 24 | + public MemberAddressRespDTO getAddress(Long id, Long userId) { |
| 25 | return AddressConvert.INSTANCE.convert02(addressService.getAddress(userId, id)); | 25 | return AddressConvert.INSTANCE.convert02(addressService.getAddress(userId, id)); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | @Override | 28 | @Override |
| 29 | - public AddressRespDTO getDefaultAddress(Long userId) { | 29 | + public MemberAddressRespDTO getDefaultAddress(Long userId) { |
| 30 | return AddressConvert.INSTANCE.convert02(addressService.getDefaultUserAddress(userId)); | 30 | return AddressConvert.INSTANCE.convert02(addressService.getDefaultUserAddress(userId)); |
| 31 | } | 31 | } |
| 32 | 32 |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/point/MemberPointRecordController.java
| @@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.member.controller.admin.point; | @@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.member.controller.admin.point; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | -import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | ||
| 6 | -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||
| 7 | import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordPageReqVO; | 5 | import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordPageReqVO; |
| 8 | import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordRespVO; | 6 | import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordRespVO; |
| 9 | import cn.iocoder.yudao.module.member.convert.point.MemberPointRecordConvert; | 7 | import cn.iocoder.yudao.module.member.convert.point.MemberPointRecordConvert; |
| 10 | import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO; | 8 | import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO; |
| 9 | +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; | ||
| 11 | import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService; | 10 | import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService; |
| 11 | +import cn.iocoder.yudao.module.member.service.user.MemberUserService; | ||
| 12 | import io.swagger.v3.oas.annotations.Operation; | 12 | import io.swagger.v3.oas.annotations.Operation; |
| 13 | import io.swagger.v3.oas.annotations.tags.Tag; | 13 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 14 | import org.springframework.security.access.prepost.PreAuthorize; | 14 | import org.springframework.security.access.prepost.PreAuthorize; |
| @@ -35,7 +35,7 @@ public class MemberPointRecordController { | @@ -35,7 +35,7 @@ public class MemberPointRecordController { | ||
| 35 | private MemberPointRecordService pointRecordService; | 35 | private MemberPointRecordService pointRecordService; |
| 36 | 36 | ||
| 37 | @Resource | 37 | @Resource |
| 38 | - private MemberUserApi memberUserApi; | 38 | + private MemberUserService memberUserService; |
| 39 | 39 | ||
| 40 | @GetMapping("/page") | 40 | @GetMapping("/page") |
| 41 | @Operation(summary = "获得用户积分记录分页") | 41 | @Operation(summary = "获得用户积分记录分页") |
| @@ -48,7 +48,7 @@ public class MemberPointRecordController { | @@ -48,7 +48,7 @@ public class MemberPointRecordController { | ||
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | // 拼接结果返回 | 50 | // 拼接结果返回 |
| 51 | - List<MemberUserRespDTO> users = memberUserApi.getUserList( | 51 | + List<MemberUserDO> users = memberUserService.getUserList( |
| 52 | convertSet(pageResult.getList(), MemberPointRecordDO::getUserId)); | 52 | convertSet(pageResult.getList(), MemberPointRecordDO::getUserId)); |
| 53 | return success(MemberPointRecordConvert.INSTANCE.convertPage(pageResult, users)); | 53 | return success(MemberPointRecordConvert.INSTANCE.convertPage(pageResult, users)); |
| 54 | } | 54 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/signin/MemberSignInRecordController.java
| @@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.member.controller.admin.signin; | @@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.member.controller.admin.signin; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | -import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | ||
| 6 | -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||
| 7 | import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordPageReqVO; | 5 | import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordPageReqVO; |
| 8 | import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordRespVO; | 6 | import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordRespVO; |
| 9 | import cn.iocoder.yudao.module.member.convert.signin.MemberSignInRecordConvert; | 7 | import cn.iocoder.yudao.module.member.convert.signin.MemberSignInRecordConvert; |
| 10 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; | 8 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; |
| 9 | +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; | ||
| 11 | import cn.iocoder.yudao.module.member.service.signin.MemberSignInRecordService; | 10 | import cn.iocoder.yudao.module.member.service.signin.MemberSignInRecordService; |
| 11 | +import cn.iocoder.yudao.module.member.service.user.MemberUserService; | ||
| 12 | import io.swagger.v3.oas.annotations.Operation; | 12 | import io.swagger.v3.oas.annotations.Operation; |
| 13 | import io.swagger.v3.oas.annotations.tags.Tag; | 13 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 14 | import org.springframework.security.access.prepost.PreAuthorize; | 14 | import org.springframework.security.access.prepost.PreAuthorize; |
| @@ -35,7 +35,7 @@ public class MemberSignInRecordController { | @@ -35,7 +35,7 @@ public class MemberSignInRecordController { | ||
| 35 | private MemberSignInRecordService signInRecordService; | 35 | private MemberSignInRecordService signInRecordService; |
| 36 | 36 | ||
| 37 | @Resource | 37 | @Resource |
| 38 | - private MemberUserApi memberUserApi; | 38 | + private MemberUserService memberUserService; |
| 39 | 39 | ||
| 40 | @GetMapping("/page") | 40 | @GetMapping("/page") |
| 41 | @Operation(summary = "获得签到记录分页") | 41 | @Operation(summary = "获得签到记录分页") |
| @@ -48,7 +48,7 @@ public class MemberSignInRecordController { | @@ -48,7 +48,7 @@ public class MemberSignInRecordController { | ||
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | // 拼接结果返回 | 50 | // 拼接结果返回 |
| 51 | - List<MemberUserRespDTO> users = memberUserApi.getUserList( | 51 | + List<MemberUserDO> users = memberUserService.getUserList( |
| 52 | convertSet(pageResult.getList(), MemberSignInRecordDO::getUserId)); | 52 | convertSet(pageResult.getList(), MemberSignInRecordDO::getUserId)); |
| 53 | return success(MemberSignInRecordConvert.INSTANCE.convertPage(pageResult, users)); | 53 | return success(MemberSignInRecordConvert.INSTANCE.convertPage(pageResult, users)); |
| 54 | } | 54 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http
| @@ -4,7 +4,7 @@ Content-Type: application/json | @@ -4,7 +4,7 @@ Content-Type: application/json | ||
| 4 | tenant-id: {{appTenentId}} | 4 | tenant-id: {{appTenentId}} |
| 5 | 5 | ||
| 6 | { | 6 | { |
| 7 | - "mobile": "15601691300", | 7 | + "mobile": "15601691388", |
| 8 | "password": "admin123" | 8 | "password": "admin123" |
| 9 | } | 9 | } |
| 10 | 10 | ||
| @@ -14,7 +14,7 @@ Content-Type: application/json | @@ -14,7 +14,7 @@ Content-Type: application/json | ||
| 14 | tenant-id: {{appTenentId}} | 14 | tenant-id: {{appTenentId}} |
| 15 | 15 | ||
| 16 | { | 16 | { |
| 17 | - "mobile": "15601691399", | 17 | + "mobile": "15601691388", |
| 18 | "scene": 1 | 18 | "scene": 1 |
| 19 | } | 19 | } |
| 20 | 20 | ||
| @@ -22,9 +22,10 @@ tenant-id: {{appTenentId}} | @@ -22,9 +22,10 @@ tenant-id: {{appTenentId}} | ||
| 22 | POST {{appApi}}/member/auth/sms-login | 22 | POST {{appApi}}/member/auth/sms-login |
| 23 | Content-Type: application/json | 23 | Content-Type: application/json |
| 24 | tenant-id: {{appTenentId}} | 24 | tenant-id: {{appTenentId}} |
| 25 | +terminal: 30 | ||
| 25 | 26 | ||
| 26 | { | 27 | { |
| 27 | - "mobile": "15601691301", | 28 | + "mobile": "15601691388", |
| 28 | "code": 9999 | 29 | "code": 9999 |
| 29 | } | 30 | } |
| 30 | 31 |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/address/AddressConvert.java
| 1 | package cn.iocoder.yudao.module.member.convert.address; | 1 | package cn.iocoder.yudao.module.member.convert.address; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; | 3 | import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; |
| 4 | -import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; | 4 | +import cn.iocoder.yudao.module.member.api.address.dto.MemberAddressRespDTO; |
| 5 | import cn.iocoder.yudao.module.member.controller.admin.address.vo.AddressRespVO; | 5 | import cn.iocoder.yudao.module.member.controller.admin.address.vo.AddressRespVO; |
| 6 | import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO; | 6 | import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO; |
| 7 | import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressRespVO; | 7 | import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressRespVO; |
| @@ -33,7 +33,7 @@ public interface AddressConvert { | @@ -33,7 +33,7 @@ public interface AddressConvert { | ||
| 33 | 33 | ||
| 34 | List<AppAddressRespVO> convertList(List<MemberAddressDO> list); | 34 | List<AppAddressRespVO> convertList(List<MemberAddressDO> list); |
| 35 | 35 | ||
| 36 | - AddressRespDTO convert02(MemberAddressDO bean); | 36 | + MemberAddressRespDTO convert02(MemberAddressDO bean); |
| 37 | 37 | ||
| 38 | @Named("convertAreaIdToAreaName") | 38 | @Named("convertAreaIdToAreaName") |
| 39 | default String convertAreaIdToAreaName(Integer areaId) { | 39 | default String convertAreaIdToAreaName(Integer areaId) { |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/point/MemberPointRecordConvert.java
| @@ -2,10 +2,10 @@ package cn.iocoder.yudao.module.member.convert.point; | @@ -2,10 +2,10 @@ package cn.iocoder.yudao.module.member.convert.point; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | 4 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| 5 | -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||
| 6 | import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordRespVO; | 5 | import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordRespVO; |
| 7 | import cn.iocoder.yudao.module.member.controller.app.point.vo.AppMemberPointRecordRespVO; | 6 | import cn.iocoder.yudao.module.member.controller.app.point.vo.AppMemberPointRecordRespVO; |
| 8 | import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO; | 7 | import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO; |
| 8 | +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; | ||
| 9 | import org.mapstruct.Mapper; | 9 | import org.mapstruct.Mapper; |
| 10 | import org.mapstruct.factory.Mappers; | 10 | import org.mapstruct.factory.Mappers; |
| 11 | 11 | ||
| @@ -24,10 +24,10 @@ public interface MemberPointRecordConvert { | @@ -24,10 +24,10 @@ public interface MemberPointRecordConvert { | ||
| 24 | 24 | ||
| 25 | MemberPointRecordConvert INSTANCE = Mappers.getMapper(MemberPointRecordConvert.class); | 25 | MemberPointRecordConvert INSTANCE = Mappers.getMapper(MemberPointRecordConvert.class); |
| 26 | 26 | ||
| 27 | - default PageResult<MemberPointRecordRespVO> convertPage(PageResult<MemberPointRecordDO> pageResult, List<MemberUserRespDTO> users) { | 27 | + default PageResult<MemberPointRecordRespVO> convertPage(PageResult<MemberPointRecordDO> pageResult, List<MemberUserDO> users) { |
| 28 | PageResult<MemberPointRecordRespVO> voPageResult = convertPage(pageResult); | 28 | PageResult<MemberPointRecordRespVO> voPageResult = convertPage(pageResult); |
| 29 | // user 拼接 | 29 | // user 拼接 |
| 30 | - Map<Long, MemberUserRespDTO> userMap = convertMap(users, MemberUserRespDTO::getId); | 30 | + Map<Long, MemberUserDO> userMap = convertMap(users, MemberUserDO::getId); |
| 31 | voPageResult.getList().forEach(record -> MapUtils.findAndThen(userMap, record.getUserId(), | 31 | voPageResult.getList().forEach(record -> MapUtils.findAndThen(userMap, record.getUserId(), |
| 32 | memberUserRespDTO -> record.setNickname(memberUserRespDTO.getNickname()))); | 32 | memberUserRespDTO -> record.setNickname(memberUserRespDTO.getNickname()))); |
| 33 | return voPageResult; | 33 | return voPageResult; |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/signin/MemberSignInRecordConvert.java
| @@ -4,11 +4,11 @@ import cn.hutool.core.collection.CollUtil; | @@ -4,11 +4,11 @@ import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.hutool.core.util.ObjUtil; | 4 | import cn.hutool.core.util.ObjUtil; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | 6 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| 7 | -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||
| 8 | import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordRespVO; | 7 | import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordRespVO; |
| 9 | import cn.iocoder.yudao.module.member.controller.app.signin.vo.record.AppMemberSignInRecordRespVO; | 8 | import cn.iocoder.yudao.module.member.controller.app.signin.vo.record.AppMemberSignInRecordRespVO; |
| 10 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInConfigDO; | 9 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInConfigDO; |
| 11 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; | 10 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; |
| 11 | +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; | ||
| 12 | import org.mapstruct.Mapper; | 12 | import org.mapstruct.Mapper; |
| 13 | import org.mapstruct.factory.Mappers; | 13 | import org.mapstruct.factory.Mappers; |
| 14 | 14 | ||
| @@ -28,10 +28,10 @@ public interface MemberSignInRecordConvert { | @@ -28,10 +28,10 @@ public interface MemberSignInRecordConvert { | ||
| 28 | 28 | ||
| 29 | MemberSignInRecordConvert INSTANCE = Mappers.getMapper(MemberSignInRecordConvert.class); | 29 | MemberSignInRecordConvert INSTANCE = Mappers.getMapper(MemberSignInRecordConvert.class); |
| 30 | 30 | ||
| 31 | - default PageResult<MemberSignInRecordRespVO> convertPage(PageResult<MemberSignInRecordDO> pageResult, List<MemberUserRespDTO> users) { | 31 | + default PageResult<MemberSignInRecordRespVO> convertPage(PageResult<MemberSignInRecordDO> pageResult, List<MemberUserDO> users) { |
| 32 | PageResult<MemberSignInRecordRespVO> voPageResult = convertPage(pageResult); | 32 | PageResult<MemberSignInRecordRespVO> voPageResult = convertPage(pageResult); |
| 33 | // user 拼接 | 33 | // user 拼接 |
| 34 | - Map<Long, MemberUserRespDTO> userMap = convertMap(users, MemberUserRespDTO::getId); | 34 | + Map<Long, MemberUserDO> userMap = convertMap(users, MemberUserDO::getId); |
| 35 | voPageResult.getList().forEach(record -> MapUtils.findAndThen(userMap, record.getUserId(), | 35 | voPageResult.getList().forEach(record -> MapUtils.findAndThen(userMap, record.getUserId(), |
| 36 | memberUserRespDTO -> record.setNickname(memberUserRespDTO.getNickname()))); | 36 | memberUserRespDTO -> record.setNickname(memberUserRespDTO.getNickname()))); |
| 37 | return voPageResult; | 37 | return voPageResult; |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/consumer/package-info.java
0 → 100644
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/message/package-info.java
0 → 100644
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/message/user/UserCreateMessage.java deleted
| 1 | -package cn.iocoder.yudao.module.member.mq.message.user; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage; | ||
| 4 | -import lombok.Data; | ||
| 5 | -import lombok.EqualsAndHashCode; | ||
| 6 | - | ||
| 7 | -import javax.validation.constraints.NotNull; | ||
| 8 | - | ||
| 9 | -/** | ||
| 10 | - * 会员用户创建消息 | ||
| 11 | - * | ||
| 12 | - * @author owen | ||
| 13 | - */ | ||
| 14 | -@Data | ||
| 15 | -@EqualsAndHashCode(callSuper = true) | ||
| 16 | -public class UserCreateMessage extends AbstractStreamMessage { | ||
| 17 | - | ||
| 18 | - /** | ||
| 19 | - * 用户编号 | ||
| 20 | - */ | ||
| 21 | - @NotNull(message = "用户编号不能为空") | ||
| 22 | - private Long userId; | ||
| 23 | - | ||
| 24 | - @Override | ||
| 25 | - public String getStreamKey() { | ||
| 26 | - return "member.create.send"; | ||
| 27 | - } | ||
| 28 | - | ||
| 29 | -} |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/package-info.java
0 → 100644
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/UserCreateProducer.java renamed to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/mq/producer/user/MemberUserProducer.java
| 1 | package cn.iocoder.yudao.module.member.mq.producer.user; | 1 | package cn.iocoder.yudao.module.member.mq.producer.user; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; | ||
| 4 | -import cn.iocoder.yudao.module.member.mq.message.user.UserCreateMessage; | 3 | +import cn.iocoder.yudao.module.member.message.user.MemberUserCreateMessage; |
| 5 | import lombok.extern.slf4j.Slf4j; | 4 | import lombok.extern.slf4j.Slf4j; |
| 5 | +import org.springframework.context.ApplicationContext; | ||
| 6 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
| 7 | 7 | ||
| 8 | import javax.annotation.Resource; | 8 | import javax.annotation.Resource; |
| 9 | 9 | ||
| 10 | /** | 10 | /** |
| 11 | - * 会员用户创建 Producer | 11 | + * 会员用户 Producer |
| 12 | * | 12 | * |
| 13 | * @author owen | 13 | * @author owen |
| 14 | */ | 14 | */ |
| 15 | @Slf4j | 15 | @Slf4j |
| 16 | @Component | 16 | @Component |
| 17 | -public class UserCreateProducer { | 17 | +public class MemberUserProducer { |
| 18 | 18 | ||
| 19 | @Resource | 19 | @Resource |
| 20 | - private RedisMQTemplate redisMQTemplate; | 20 | + private ApplicationContext applicationContext; |
| 21 | 21 | ||
| 22 | /** | 22 | /** |
| 23 | - * 发送 {@link UserCreateMessage} 消息 | 23 | + * 发送 {@link MemberUserCreateMessage} 消息 |
| 24 | * | 24 | * |
| 25 | * @param userId 用户编号 | 25 | * @param userId 用户编号 |
| 26 | */ | 26 | */ |
| 27 | public void sendUserCreateMessage(Long userId) { | 27 | public void sendUserCreateMessage(Long userId) { |
| 28 | - redisMQTemplate.send(new UserCreateMessage().setUserId(userId)); | 28 | + applicationContext.publishEvent(new MemberUserCreateMessage().setUserId(userId)); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | } | 31 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java
| @@ -7,18 +7,18 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; | @@ -7,18 +7,18 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 7 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 7 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 8 | import cn.iocoder.yudao.framework.common.util.date.DateUtils; | 8 | import cn.iocoder.yudao.framework.common.util.date.DateUtils; |
| 9 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | 9 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; |
| 10 | -import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | ||
| 11 | -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||
| 12 | import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordPageReqVO; | 10 | import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordPageReqVO; |
| 13 | import cn.iocoder.yudao.module.member.controller.app.signin.vo.record.AppMemberSignInRecordSummaryRespVO; | 11 | import cn.iocoder.yudao.module.member.controller.app.signin.vo.record.AppMemberSignInRecordSummaryRespVO; |
| 14 | import cn.iocoder.yudao.module.member.convert.signin.MemberSignInRecordConvert; | 12 | import cn.iocoder.yudao.module.member.convert.signin.MemberSignInRecordConvert; |
| 15 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInConfigDO; | 13 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInConfigDO; |
| 16 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; | 14 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; |
| 15 | +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; | ||
| 17 | import cn.iocoder.yudao.module.member.dal.mysql.signin.MemberSignInRecordMapper; | 16 | import cn.iocoder.yudao.module.member.dal.mysql.signin.MemberSignInRecordMapper; |
| 18 | import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; | 17 | import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; |
| 19 | import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; | 18 | import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; |
| 20 | import cn.iocoder.yudao.module.member.service.level.MemberLevelService; | 19 | import cn.iocoder.yudao.module.member.service.level.MemberLevelService; |
| 21 | import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService; | 20 | import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService; |
| 21 | +import cn.iocoder.yudao.module.member.service.user.MemberUserService; | ||
| 22 | import org.apache.commons.lang3.StringUtils; | 22 | import org.apache.commons.lang3.StringUtils; |
| 23 | import org.springframework.stereotype.Service; | 23 | import org.springframework.stereotype.Service; |
| 24 | import org.springframework.transaction.annotation.Transactional; | 24 | import org.springframework.transaction.annotation.Transactional; |
| @@ -53,7 +53,7 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService | @@ -53,7 +53,7 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService | ||
| 53 | private MemberLevelService memberLevelService; | 53 | private MemberLevelService memberLevelService; |
| 54 | 54 | ||
| 55 | @Resource | 55 | @Resource |
| 56 | - private MemberUserApi memberUserApi; | 56 | + private MemberUserService memberUserService; |
| 57 | 57 | ||
| 58 | @Override | 58 | @Override |
| 59 | public AppMemberSignInRecordSummaryRespVO getSignInRecordSummary(Long userId) { | 59 | public AppMemberSignInRecordSummaryRespVO getSignInRecordSummary(Long userId) { |
| @@ -126,12 +126,12 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService | @@ -126,12 +126,12 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService | ||
| 126 | // 根据用户昵称查询出用户ids | 126 | // 根据用户昵称查询出用户ids |
| 127 | Set<Long> userIds = null; | 127 | Set<Long> userIds = null; |
| 128 | if (StringUtils.isNotBlank(pageReqVO.getNickname())) { | 128 | if (StringUtils.isNotBlank(pageReqVO.getNickname())) { |
| 129 | - List<MemberUserRespDTO> users = memberUserApi.getUserListByNickname(pageReqVO.getNickname()); | 129 | + List<MemberUserDO> users = memberUserService.getUserListByNickname(pageReqVO.getNickname()); |
| 130 | // 如果查询用户结果为空直接返回无需继续查询 | 130 | // 如果查询用户结果为空直接返回无需继续查询 |
| 131 | if (CollUtil.isEmpty(users)) { | 131 | if (CollUtil.isEmpty(users)) { |
| 132 | return PageResult.empty(); | 132 | return PageResult.empty(); |
| 133 | } | 133 | } |
| 134 | - userIds = convertSet(users, MemberUserRespDTO::getId); | 134 | + userIds = convertSet(users, MemberUserDO::getId); |
| 135 | } | 135 | } |
| 136 | // 分页查询 | 136 | // 分页查询 |
| 137 | return signInRecordMapper.selectPage(pageReqVO, userIds); | 137 | return signInRecordMapper.selectPage(pageReqVO, userIds); |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java
| @@ -7,7 +7,6 @@ import cn.hutool.core.util.ObjectUtil; | @@ -7,7 +7,6 @@ import cn.hutool.core.util.ObjectUtil; | ||
| 7 | import cn.hutool.core.util.StrUtil; | 7 | import cn.hutool.core.util.StrUtil; |
| 8 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 8 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 9 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 9 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 10 | -import cn.iocoder.yudao.module.infra.api.file.FileApi; | ||
| 11 | import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO; | 10 | import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO; |
| 12 | import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO; | 11 | import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO; |
| 13 | import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserResetPasswordReqVO; | 12 | import cn.iocoder.yudao.module.member.controller.app.user.vo.AppMemberUserResetPasswordReqVO; |
| @@ -18,7 +17,7 @@ import cn.iocoder.yudao.module.member.convert.auth.AuthConvert; | @@ -18,7 +17,7 @@ import cn.iocoder.yudao.module.member.convert.auth.AuthConvert; | ||
| 18 | import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert; | 17 | import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert; |
| 19 | import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; | 18 | import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; |
| 20 | import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; | 19 | import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; |
| 21 | -import cn.iocoder.yudao.module.member.mq.producer.user.UserCreateProducer; | 20 | +import cn.iocoder.yudao.module.member.mq.producer.user.MemberUserProducer; |
| 22 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; | 21 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; |
| 23 | import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; | 22 | import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; |
| 24 | import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; | 23 | import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; |
| @@ -29,7 +28,6 @@ import org.springframework.stereotype.Service; | @@ -29,7 +28,6 @@ import org.springframework.stereotype.Service; | ||
| 29 | import org.springframework.transaction.annotation.Transactional; | 28 | import org.springframework.transaction.annotation.Transactional; |
| 30 | import org.springframework.transaction.support.TransactionSynchronization; | 29 | import org.springframework.transaction.support.TransactionSynchronization; |
| 31 | import org.springframework.transaction.support.TransactionSynchronizationManager; | 30 | import org.springframework.transaction.support.TransactionSynchronizationManager; |
| 32 | -import org.springframework.transaction.support.TransactionTemplate; | ||
| 33 | 31 | ||
| 34 | import javax.annotation.Resource; | 32 | import javax.annotation.Resource; |
| 35 | import javax.validation.Valid; | 33 | import javax.validation.Valid; |
| @@ -55,18 +53,13 @@ public class MemberUserServiceImpl implements MemberUserService { | @@ -55,18 +53,13 @@ public class MemberUserServiceImpl implements MemberUserService { | ||
| 55 | private MemberUserMapper memberUserMapper; | 53 | private MemberUserMapper memberUserMapper; |
| 56 | 54 | ||
| 57 | @Resource | 55 | @Resource |
| 58 | - private FileApi fileApi; | ||
| 59 | - @Resource | ||
| 60 | private SmsCodeApi smsCodeApi; | 56 | private SmsCodeApi smsCodeApi; |
| 61 | 57 | ||
| 62 | @Resource | 58 | @Resource |
| 63 | private PasswordEncoder passwordEncoder; | 59 | private PasswordEncoder passwordEncoder; |
| 64 | 60 | ||
| 65 | @Resource | 61 | @Resource |
| 66 | - private UserCreateProducer registerCouponProducer; | ||
| 67 | - | ||
| 68 | - @Resource | ||
| 69 | - private TransactionTemplate transactionTemplate; | 62 | + private MemberUserProducer memberUserProducer; |
| 70 | 63 | ||
| 71 | @Override | 64 | @Override |
| 72 | public MemberUserDO getUserByMobile(String mobile) { | 65 | public MemberUserDO getUserByMobile(String mobile) { |
| @@ -107,7 +100,7 @@ public class MemberUserServiceImpl implements MemberUserService { | @@ -107,7 +100,7 @@ public class MemberUserServiceImpl implements MemberUserService { | ||
| 107 | 100 | ||
| 108 | @Override | 101 | @Override |
| 109 | public void afterCommit() { | 102 | public void afterCommit() { |
| 110 | - registerCouponProducer.sendUserCreateMessage(user.getId()); | 103 | + memberUserProducer.sendUserCreateMessage(user.getId()); |
| 111 | } | 104 | } |
| 112 | 105 | ||
| 113 | }); | 106 | }); |
yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java renamed to yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/MemberAddressServiceImplTest.java
| @@ -24,7 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; | @@ -24,7 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; | ||
| 24 | * @author 芋道源码 | 24 | * @author 芋道源码 |
| 25 | */ | 25 | */ |
| 26 | @Import(AddressServiceImpl.class) | 26 | @Import(AddressServiceImpl.class) |
| 27 | -public class AddressServiceImplTest extends BaseDbUnitTest { | 27 | +public class MemberAddressServiceImplTest extends BaseDbUnitTest { |
| 28 | 28 | ||
| 29 | @Resource | 29 | @Resource |
| 30 | private AddressServiceImpl addressService; | 30 | private AddressServiceImpl addressService; |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/PayWalletBizTypeEnum.java renamed to yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/wallet/PayWalletBizTypeEnum.java
| 1 | -package cn.iocoder.yudao.module.pay.enums.member; | 1 | +package cn.iocoder.yudao.module.pay.enums.wallet; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | 3 | import cn.iocoder.yudao.framework.common.core.IntArrayValuable; |
| 4 | import lombok.AllArgsConstructor; | 4 | import lombok.AllArgsConstructor; |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/package-info.java deleted
| 1 | -package cn.iocoder.yudao.module.pay; |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletController.java
| @@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollectionUtil; | @@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollectionUtil; | ||
| 4 | import cn.hutool.core.util.StrUtil; | 4 | import cn.hutool.core.util.StrUtil; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 8 | import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | 7 | import cn.iocoder.yudao.module.member.api.user.MemberUserApi; |
| 9 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | 8 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; |
| 10 | import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletPageReqVO; | 9 | import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletPageReqVO; |
| @@ -26,12 +25,10 @@ import javax.annotation.Resource; | @@ -26,12 +25,10 @@ import javax.annotation.Resource; | ||
| 26 | import javax.validation.Valid; | 25 | import javax.validation.Valid; |
| 27 | import java.util.List; | 26 | import java.util.List; |
| 28 | import java.util.Map; | 27 | import java.util.Map; |
| 29 | -import java.util.Set; | ||
| 30 | 28 | ||
| 31 | import static cn.iocoder.yudao.framework.common.enums.UserTypeEnum.MEMBER; | 29 | import static cn.iocoder.yudao.framework.common.enums.UserTypeEnum.MEMBER; |
| 32 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 30 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 33 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | ||
| 34 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | 31 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| 35 | 32 | ||
| 36 | @Tag(name = "管理后台 - 用户钱包") | 33 | @Tag(name = "管理后台 - 用户钱包") |
| 37 | @RestController | 34 | @RestController |
| @@ -50,6 +47,7 @@ public class PayWalletController { | @@ -50,6 +47,7 @@ public class PayWalletController { | ||
| 50 | @Operation(summary = "获得用户钱包明细") | 47 | @Operation(summary = "获得用户钱包明细") |
| 51 | public CommonResult<PayWalletRespVO> getWallet(PayWalletUserReqVO reqVO) { | 48 | public CommonResult<PayWalletRespVO> getWallet(PayWalletUserReqVO reqVO) { |
| 52 | PayWalletDO wallet = payWalletService.getOrCreateWallet(reqVO.getUserId(), MEMBER.getValue()); | 49 | PayWalletDO wallet = payWalletService.getOrCreateWallet(reqVO.getUserId(), MEMBER.getValue()); |
| 50 | + // TODO jason:如果为空,返回给前端只要 null 就可以了 | ||
| 53 | MemberUserRespDTO memberUser = memberUserApi.getUser(reqVO.getUserId()); | 51 | MemberUserRespDTO memberUser = memberUserApi.getUser(reqVO.getUserId()); |
| 54 | String nickname = memberUser == null ? "" : memberUser.getNickname(); | 52 | String nickname = memberUser == null ? "" : memberUser.getNickname(); |
| 55 | String avatar = memberUser == null ? "" : memberUser.getAvatar(); | 53 | String avatar = memberUser == null ? "" : memberUser.getAvatar(); |
| @@ -61,9 +59,8 @@ public class PayWalletController { | @@ -61,9 +59,8 @@ public class PayWalletController { | ||
| 61 | @PreAuthorize("@ss.hasPermission('pay:wallet:query')") | 59 | @PreAuthorize("@ss.hasPermission('pay:wallet:query')") |
| 62 | public CommonResult<PageResult<PayWalletRespVO>> getWalletPage(@Valid PayWalletPageReqVO pageVO) { | 60 | public CommonResult<PageResult<PayWalletRespVO>> getWalletPage(@Valid PayWalletPageReqVO pageVO) { |
| 63 | if (StrUtil.isNotEmpty(pageVO.getNickname())) { | 61 | if (StrUtil.isNotEmpty(pageVO.getNickname())) { |
| 64 | - Set<Long> userIds = CollectionUtils.convertSet(memberUserApi.getUserListByNickname(pageVO.getNickname()), | ||
| 65 | - MemberUserRespDTO::getId); | ||
| 66 | - pageVO.setUserIds(userIds); | 62 | + List<MemberUserRespDTO> users = memberUserApi.getUserListByNickname(pageVO.getNickname()); |
| 63 | + pageVO.setUserIds(convertSet(users, MemberUserRespDTO::getId)); | ||
| 67 | } | 64 | } |
| 68 | // TODO @jason:管理员也可以先查询下。。 | 65 | // TODO @jason:管理员也可以先查询下。。 |
| 69 | // 暂时支持查询 userType 会员类型。管理员类型还不知道使用场景 | 66 | // 暂时支持查询 userType 会员类型。管理员类型还不知道使用场景 |
| @@ -71,8 +68,8 @@ public class PayWalletController { | @@ -71,8 +68,8 @@ public class PayWalletController { | ||
| 71 | if (CollectionUtil.isEmpty(pageResult.getList())) { | 68 | if (CollectionUtil.isEmpty(pageResult.getList())) { |
| 72 | return success(new PageResult<>(pageResult.getTotal())); | 69 | return success(new PageResult<>(pageResult.getTotal())); |
| 73 | } | 70 | } |
| 74 | - List<Long> userIds = convertList(pageResult.getList(), PayWalletDO::getUserId); | ||
| 75 | - Map<Long, MemberUserRespDTO> userMap = convertMap(memberUserApi.getUserList(userIds),MemberUserRespDTO::getId); | 71 | + List<MemberUserRespDTO> users = memberUserApi.getUserList(convertList(pageResult.getList(), PayWalletDO::getUserId)); |
| 72 | + Map<Long, MemberUserRespDTO> userMap = convertMap(users, MemberUserRespDTO::getId); | ||
| 76 | return success(PayWalletConvert.INSTANCE.convertPage(pageResult, userMap)); | 73 | return success(PayWalletConvert.INSTANCE.convertPage(pageResult, userMap)); |
| 77 | } | 74 | } |
| 78 | 75 |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletTransactionDO.java
| 1 | package cn.iocoder.yudao.module.pay.dal.dataobject.wallet; | 1 | package cn.iocoder.yudao.module.pay.dal.dataobject.wallet; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | -import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | 4 | +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; |
| 5 | import com.baomidou.mybatisplus.annotation.KeySequence; | 5 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 6 | import com.baomidou.mybatisplus.annotation.TableId; | 6 | import com.baomidou.mybatisplus.annotation.TableId; |
| 7 | import com.baomidou.mybatisplus.annotation.TableName; | 7 | import com.baomidou.mybatisplus.annotation.TableName; |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java
| @@ -17,7 +17,7 @@ import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum; | @@ -17,7 +17,7 @@ import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum; | ||
| 17 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; | 17 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; |
| 18 | import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; | 18 | import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; |
| 19 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; | 19 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; |
| 20 | -import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | 20 | +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; |
| 21 | import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | 21 | import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; |
| 22 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; | 22 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; |
| 23 | import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; | 23 | import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
| @@ -421,6 +421,7 @@ public class PayOrderServiceImpl implements PayOrderService { | @@ -421,6 +421,7 @@ public class PayOrderServiceImpl implements PayOrderService { | ||
| 421 | return; | 421 | return; |
| 422 | } | 422 | } |
| 423 | 423 | ||
| 424 | + // TODO 芋艿:应该 new 出来更新 | ||
| 424 | order.setPrice(payPrice); | 425 | order.setPrice(payPrice); |
| 425 | orderMapper.updateById(order); | 426 | orderMapper.updateById(order); |
| 426 | } | 427 | } |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java
| @@ -11,7 +11,7 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; | @@ -11,7 +11,7 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; | ||
| 11 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO; | 11 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargeDO; |
| 12 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargePackageDO; | 12 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletRechargePackageDO; |
| 13 | import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletRechargeMapper; | 13 | import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletRechargeMapper; |
| 14 | -import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | 14 | +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; |
| 15 | import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | 15 | import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; |
| 16 | import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; | 16 | import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; |
| 17 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; | 17 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; |
| @@ -64,6 +64,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { | @@ -64,6 +64,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { | ||
| 64 | @Transactional(rollbackFor = Exception.class) | 64 | @Transactional(rollbackFor = Exception.class) |
| 65 | public PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, String userIp, | 65 | public PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, String userIp, |
| 66 | AppPayWalletRechargeCreateReqVO reqVO) { | 66 | AppPayWalletRechargeCreateReqVO reqVO) { |
| 67 | + | ||
| 67 | // 1.1 计算充值金额 | 68 | // 1.1 计算充值金额 |
| 68 | int payPrice; | 69 | int payPrice; |
| 69 | int bonusPrice = 0; | 70 | int bonusPrice = 0; |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java
| @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletPageReqVO; | 4 | import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletPageReqVO; |
| 5 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; | 5 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; |
| 6 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; | 6 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; |
| 7 | -import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | 7 | +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; |
| 8 | 8 | ||
| 9 | /** | 9 | /** |
| 10 | * 钱包 Service 接口 | 10 | * 钱包 Service 接口 |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java
| @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; | @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; | ||
| 8 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; | 8 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; |
| 9 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; | 9 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; |
| 10 | import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletMapper; | 10 | import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletMapper; |
| 11 | -import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | 11 | +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; |
| 12 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; | 12 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; |
| 13 | import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; | 13 | import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; |
| 14 | import cn.iocoder.yudao.module.pay.service.wallet.bo.WalletTransactionCreateReqBO; | 14 | import cn.iocoder.yudao.module.pay.service.wallet.bo.WalletTransactionCreateReqBO; |
| @@ -22,8 +22,8 @@ import java.time.LocalDateTime; | @@ -22,8 +22,8 @@ import java.time.LocalDateTime; | ||
| 22 | 22 | ||
| 23 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 23 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 24 | import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; | 24 | import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; |
| 25 | -import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYMENT; | ||
| 26 | -import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYMENT_REFUND; | 25 | +import static cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum.PAYMENT; |
| 26 | +import static cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum.PAYMENT_REFUND; | ||
| 27 | 27 | ||
| 28 | /** | 28 | /** |
| 29 | * 钱包 Service 实现类 | 29 | * 钱包 Service 实现类 |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java
| @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.transaction.PayWalletTransactionPageReqVO; | 4 | import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.transaction.PayWalletTransactionPageReqVO; |
| 5 | import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO; | 5 | import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO; |
| 6 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; | 6 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; |
| 7 | -import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | 7 | +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; |
| 8 | import cn.iocoder.yudao.module.pay.service.wallet.bo.WalletTransactionCreateReqBO; | 8 | import cn.iocoder.yudao.module.pay.service.wallet.bo.WalletTransactionCreateReqBO; |
| 9 | 9 | ||
| 10 | import javax.validation.Valid; | 10 | import javax.validation.Valid; |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java
| @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; | @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; | ||
| 8 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; | 8 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; |
| 9 | import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletTransactionMapper; | 9 | import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletTransactionMapper; |
| 10 | import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; | 10 | import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; |
| 11 | -import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | 11 | +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; |
| 12 | import cn.iocoder.yudao.module.pay.service.wallet.bo.WalletTransactionCreateReqBO; | 12 | import cn.iocoder.yudao.module.pay.service.wallet.bo.WalletTransactionCreateReqBO; |
| 13 | import lombok.extern.slf4j.Slf4j; | 13 | import lombok.extern.slf4j.Slf4j; |
| 14 | import org.springframework.stereotype.Service; | 14 | import org.springframework.stereotype.Service; |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/bo/WalletTransactionCreateReqBO.java
| 1 | package cn.iocoder.yudao.module.pay.service.wallet.bo; | 1 | package cn.iocoder.yudao.module.pay.service.wallet.bo; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; | 3 | import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 4 | -import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | 4 | +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; |
| 5 | import lombok.Data; | 5 | import lombok.Data; |
| 6 | 6 | ||
| 7 | import javax.validation.constraints.NotEmpty; | 7 | import javax.validation.constraints.NotEmpty; |
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java
| @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.pay.service.order; | @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.pay.service.order; | ||
| 3 | import cn.hutool.extra.spring.SpringUtil; | 3 | import cn.hutool.extra.spring.SpringUtil; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClient; | 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClient; |
| 6 | -import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; | ||
| 7 | import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; | 6 | import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; |
| 8 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; | 7 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; |
| 9 | import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; | 8 | import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; |
| @@ -68,8 +67,6 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -68,8 +67,6 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 68 | private PayOrderExtensionMapper orderExtensionMapper; | 67 | private PayOrderExtensionMapper orderExtensionMapper; |
| 69 | 68 | ||
| 70 | @MockBean | 69 | @MockBean |
| 71 | - private PayClientFactory payClientFactory; | ||
| 72 | - @MockBean | ||
| 73 | private PayProperties properties; | 70 | private PayProperties properties; |
| 74 | @MockBean | 71 | @MockBean |
| 75 | private PayAppService appService; | 72 | private PayAppService appService; |
| @@ -351,7 +348,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -351,7 +348,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 351 | .thenReturn(channel); | 348 | .thenReturn(channel); |
| 352 | // mock 方法(client) | 349 | // mock 方法(client) |
| 353 | PayClient client = mock(PayClient.class); | 350 | PayClient client = mock(PayClient.class); |
| 354 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 351 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 355 | // mock 方法() | 352 | // mock 方法() |
| 356 | PayOrderRespDTO unifiedOrderResp = randomPojo(PayOrderRespDTO.class, o -> | 353 | PayOrderRespDTO unifiedOrderResp = randomPojo(PayOrderRespDTO.class, o -> |
| 357 | o.setChannelErrorCode("001").setChannelErrorMsg("模拟异常")); | 354 | o.setChannelErrorCode("001").setChannelErrorMsg("模拟异常")); |
| @@ -405,7 +402,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -405,7 +402,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 405 | .thenReturn(channel); | 402 | .thenReturn(channel); |
| 406 | // mock 方法(client) | 403 | // mock 方法(client) |
| 407 | PayClient client = mock(PayClient.class); | 404 | PayClient client = mock(PayClient.class); |
| 408 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 405 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 409 | // mock 方法(支付渠道的调用) | 406 | // mock 方法(支付渠道的调用) |
| 410 | PayOrderRespDTO unifiedOrderResp = randomPojo(PayOrderRespDTO.class, o -> o.setChannelErrorCode(null).setChannelErrorMsg(null) | 407 | PayOrderRespDTO unifiedOrderResp = randomPojo(PayOrderRespDTO.class, o -> o.setChannelErrorCode(null).setChannelErrorMsg(null) |
| 411 | .setDisplayMode(PayOrderDisplayModeEnum.URL.getMode()).setDisplayContent("tudou")); | 408 | .setDisplayMode(PayOrderDisplayModeEnum.URL.getMode()).setDisplayContent("tudou")); |
| @@ -463,7 +460,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -463,7 +460,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 463 | orderExtensionMapper.insert(orderExtension); | 460 | orderExtensionMapper.insert(orderExtension); |
| 464 | // mock 方法(PayClient 已支付) | 461 | // mock 方法(PayClient 已支付) |
| 465 | PayClient client = mock(PayClient.class); | 462 | PayClient client = mock(PayClient.class); |
| 466 | - when(payClientFactory.getPayClient(eq(orderExtension.getChannelId()))).thenReturn(client); | 463 | + when(channelService.getPayClient(eq(orderExtension.getChannelId()))).thenReturn(client); |
| 467 | when(client.getOrder(eq(orderExtension.getNo()))).thenReturn(randomPojo(PayOrderRespDTO.class, | 464 | when(client.getOrder(eq(orderExtension.getNo()))).thenReturn(randomPojo(PayOrderRespDTO.class, |
| 468 | o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()))); | 465 | o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()))); |
| 469 | 466 | ||
| @@ -482,7 +479,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -482,7 +479,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 482 | orderExtensionMapper.insert(orderExtension); | 479 | orderExtensionMapper.insert(orderExtension); |
| 483 | // mock 方法(PayClient 已支付) | 480 | // mock 方法(PayClient 已支付) |
| 484 | PayClient client = mock(PayClient.class); | 481 | PayClient client = mock(PayClient.class); |
| 485 | - when(payClientFactory.getPayClient(eq(orderExtension.getChannelId()))).thenReturn(client); | 482 | + when(channelService.getPayClient(eq(orderExtension.getChannelId()))).thenReturn(client); |
| 486 | when(client.getOrder(eq(orderExtension.getNo()))).thenReturn(randomPojo(PayOrderRespDTO.class, | 483 | when(client.getOrder(eq(orderExtension.getNo()))).thenReturn(randomPojo(PayOrderRespDTO.class, |
| 487 | o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus()))); | 484 | o -> o.setStatus(PayOrderStatusEnum.WAITING.getStatus()))); |
| 488 | 485 | ||
| @@ -639,7 +636,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -639,7 +636,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 639 | orderExtensionMapper.insert(orderExtension); | 636 | orderExtensionMapper.insert(orderExtension); |
| 640 | // 准备参数 | 637 | // 准备参数 |
| 641 | PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L) | 638 | PayChannelDO channel = randomPojo(PayChannelDO.class, o -> o.setId(10L) |
| 642 | - .setFeeRate(0.1D)); | 639 | + .setFeeRate(10D)); |
| 643 | PayOrderRespDTO notify = randomPojo(PayOrderRespDTO.class, | 640 | PayOrderRespDTO notify = randomPojo(PayOrderRespDTO.class, |
| 644 | o -> o.setStatus(PayOrderStatusRespEnum.SUCCESS.getStatus()) | 641 | o -> o.setStatus(PayOrderStatusRespEnum.SUCCESS.getStatus()) |
| 645 | .setOutTradeNo("P110")); | 642 | .setOutTradeNo("P110")); |
| @@ -656,7 +653,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -656,7 +653,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 656 | .setChannelId(10L).setChannelCode(channel.getCode()) | 653 | .setChannelId(10L).setChannelCode(channel.getCode()) |
| 657 | .setSuccessTime(notify.getSuccessTime()).setExtensionId(orderExtension.getId()).setNo(orderExtension.getNo()) | 654 | .setSuccessTime(notify.getSuccessTime()).setExtensionId(orderExtension.getId()).setNo(orderExtension.getNo()) |
| 658 | .setChannelOrderNo(notify.getChannelOrderNo()).setChannelUserId(notify.getChannelUserId()) | 655 | .setChannelOrderNo(notify.getChannelOrderNo()).setChannelUserId(notify.getChannelUserId()) |
| 659 | - .setChannelFeeRate(0.1D).setChannelFeePrice(1); | 656 | + .setChannelFeeRate(10D).setChannelFeePrice(1); |
| 660 | assertPojoEquals(order, orderMapper.selectOne(null), | 657 | assertPojoEquals(order, orderMapper.selectOne(null), |
| 661 | "updateTime", "updater"); | 658 | "updateTime", "updater"); |
| 662 | // 断言,调用 | 659 | // 断言,调用 |
| @@ -874,7 +871,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -874,7 +871,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 874 | orderExtensionMapper.insert(orderExtension); | 871 | orderExtensionMapper.insert(orderExtension); |
| 875 | // mock 方法(PayClient) | 872 | // mock 方法(PayClient) |
| 876 | PayClient client = mock(PayClient.class); | 873 | PayClient client = mock(PayClient.class); |
| 877 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 874 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 878 | // mock 方法(PayClient 异常) | 875 | // mock 方法(PayClient 异常) |
| 879 | when(client.getOrder(any())).thenThrow(new RuntimeException()); | 876 | when(client.getOrder(any())).thenThrow(new RuntimeException()); |
| 880 | 877 | ||
| @@ -901,7 +898,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -901,7 +898,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 901 | orderExtensionMapper.insert(orderExtension); | 898 | orderExtensionMapper.insert(orderExtension); |
| 902 | // mock 方法(PayClient) | 899 | // mock 方法(PayClient) |
| 903 | PayClient client = mock(PayClient.class); | 900 | PayClient client = mock(PayClient.class); |
| 904 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 901 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 905 | // mock 方法(PayClient 成功返回) | 902 | // mock 方法(PayClient 成功返回) |
| 906 | PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, | 903 | PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, |
| 907 | o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus())); | 904 | o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus())); |
| @@ -935,7 +932,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -935,7 +932,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 935 | orderExtensionMapper.insert(orderExtension); | 932 | orderExtensionMapper.insert(orderExtension); |
| 936 | // mock 方法(PayClient) | 933 | // mock 方法(PayClient) |
| 937 | PayClient client = mock(PayClient.class); | 934 | PayClient client = mock(PayClient.class); |
| 938 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 935 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 939 | // mock 方法(PayClient 成功返回) | 936 | // mock 方法(PayClient 成功返回) |
| 940 | PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, | 937 | PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, |
| 941 | o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus())); | 938 | o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus())); |
| @@ -966,7 +963,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -966,7 +963,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 966 | orderExtensionMapper.insert(orderExtension); | 963 | orderExtensionMapper.insert(orderExtension); |
| 967 | // mock 方法(PayClient) | 964 | // mock 方法(PayClient) |
| 968 | PayClient client = mock(PayClient.class); | 965 | PayClient client = mock(PayClient.class); |
| 969 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 966 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 970 | 967 | ||
| 971 | // 调用 | 968 | // 调用 |
| 972 | int count = orderService.expireOrder(); | 969 | int count = orderService.expireOrder(); |
| @@ -1013,7 +1010,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -1013,7 +1010,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 1013 | orderExtensionMapper.insert(orderExtension); | 1010 | orderExtensionMapper.insert(orderExtension); |
| 1014 | // mock 方法(PayClient) | 1011 | // mock 方法(PayClient) |
| 1015 | PayClient client = mock(PayClient.class); | 1012 | PayClient client = mock(PayClient.class); |
| 1016 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 1013 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 1017 | // mock 方法(PayClient 退款返回) | 1014 | // mock 方法(PayClient 退款返回) |
| 1018 | PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, | 1015 | PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, |
| 1019 | o -> o.setStatus(PayOrderStatusEnum.REFUND.getStatus())); | 1016 | o -> o.setStatus(PayOrderStatusEnum.REFUND.getStatus())); |
| @@ -1047,7 +1044,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -1047,7 +1044,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 1047 | orderExtensionMapper.insert(orderExtension); | 1044 | orderExtensionMapper.insert(orderExtension); |
| 1048 | // mock 方法(PayClient) | 1045 | // mock 方法(PayClient) |
| 1049 | PayClient client = mock(PayClient.class); | 1046 | PayClient client = mock(PayClient.class); |
| 1050 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 1047 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 1051 | // mock 方法(PayClient 成功返回) | 1048 | // mock 方法(PayClient 成功返回) |
| 1052 | PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, | 1049 | PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, |
| 1053 | o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus())); | 1050 | o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus())); |
| @@ -1081,7 +1078,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | @@ -1081,7 +1078,7 @@ public class PayOrderServiceTest extends BaseDbAndRedisUnitTest { | ||
| 1081 | orderExtensionMapper.insert(orderExtension); | 1078 | orderExtensionMapper.insert(orderExtension); |
| 1082 | // mock 方法(PayClient) | 1079 | // mock 方法(PayClient) |
| 1083 | PayClient client = mock(PayClient.class); | 1080 | PayClient client = mock(PayClient.class); |
| 1084 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 1081 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 1085 | // mock 方法(PayClient 关闭返回) | 1082 | // mock 方法(PayClient 关闭返回) |
| 1086 | PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, | 1083 | PayOrderRespDTO respDTO = randomPojo(PayOrderRespDTO.class, |
| 1087 | o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus())); | 1084 | o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus())); |
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java
| @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.pay.service.refund; | @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.pay.service.refund; | ||
| 3 | import cn.hutool.extra.spring.SpringUtil; | 3 | import cn.hutool.extra.spring.SpringUtil; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClient; | 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClient; |
| 6 | -import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; | ||
| 7 | import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; | 6 | import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; |
| 8 | import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; | 7 | import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; |
| 9 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; | 8 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; |
| @@ -67,8 +66,6 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { | @@ -67,8 +66,6 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { | ||
| 67 | @MockBean | 66 | @MockBean |
| 68 | private PayProperties payProperties; | 67 | private PayProperties payProperties; |
| 69 | @MockBean | 68 | @MockBean |
| 70 | - private PayClientFactory payClientFactory; | ||
| 71 | - @MockBean | ||
| 72 | private PayOrderService orderService; | 69 | private PayOrderService orderService; |
| 73 | @MockBean | 70 | @MockBean |
| 74 | private PayAppService appService; | 71 | private PayAppService appService; |
| @@ -335,7 +332,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { | @@ -335,7 +332,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { | ||
| 335 | when(channelService.validPayChannel(eq(1L))).thenReturn(channel); | 332 | when(channelService.validPayChannel(eq(1L))).thenReturn(channel); |
| 336 | // mock 方法(client) | 333 | // mock 方法(client) |
| 337 | PayClient client = mock(PayClient.class); | 334 | PayClient client = mock(PayClient.class); |
| 338 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 335 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 339 | // mock 数据(refund 已存在) | 336 | // mock 数据(refund 已存在) |
| 340 | PayRefundDO refund = randomPojo(PayRefundDO.class, o -> | 337 | PayRefundDO refund = randomPojo(PayRefundDO.class, o -> |
| 341 | o.setAppId(1L).setMerchantRefundId("200")); | 338 | o.setAppId(1L).setMerchantRefundId("200")); |
| @@ -367,7 +364,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { | @@ -367,7 +364,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { | ||
| 367 | when(channelService.validPayChannel(eq(10L))).thenReturn(channel); | 364 | when(channelService.validPayChannel(eq(10L))).thenReturn(channel); |
| 368 | // mock 方法(client) | 365 | // mock 方法(client) |
| 369 | PayClient client = mock(PayClient.class); | 366 | PayClient client = mock(PayClient.class); |
| 370 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 367 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 371 | // mock 方法(client 调用发生异常) | 368 | // mock 方法(client 调用发生异常) |
| 372 | when(client.unifiedRefund(any(PayRefundUnifiedReqDTO.class))).thenThrow(new RuntimeException()); | 369 | when(client.unifiedRefund(any(PayRefundUnifiedReqDTO.class))).thenThrow(new RuntimeException()); |
| 373 | 370 | ||
| @@ -411,7 +408,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { | @@ -411,7 +408,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { | ||
| 411 | when(channelService.validPayChannel(eq(10L))).thenReturn(channel); | 408 | when(channelService.validPayChannel(eq(10L))).thenReturn(channel); |
| 412 | // mock 方法(client) | 409 | // mock 方法(client) |
| 413 | PayClient client = mock(PayClient.class); | 410 | PayClient client = mock(PayClient.class); |
| 414 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 411 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 415 | // mock 方法(client 成功) | 412 | // mock 方法(client 成功) |
| 416 | PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class); | 413 | PayRefundRespDTO refundRespDTO = randomPojo(PayRefundRespDTO.class); |
| 417 | when(client.unifiedRefund(argThat(unifiedReqDTO -> { | 414 | when(client.unifiedRefund(argThat(unifiedReqDTO -> { |
| @@ -668,7 +665,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { | @@ -668,7 +665,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { | ||
| 668 | refundMapper.insert(refund); | 665 | refundMapper.insert(refund); |
| 669 | // mock 方法(client) | 666 | // mock 方法(client) |
| 670 | PayClient client = mock(PayClient.class); | 667 | PayClient client = mock(PayClient.class); |
| 671 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 668 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 672 | // mock 方法(client 返回指定状态) | 669 | // mock 方法(client 返回指定状态) |
| 673 | PayRefundRespDTO respDTO = randomPojo(PayRefundRespDTO.class, o -> o.setStatus(status)); | 670 | PayRefundRespDTO respDTO = randomPojo(PayRefundRespDTO.class, o -> o.setStatus(status)); |
| 674 | when(client.getRefund(eq("P110"), eq("R220"))).thenReturn(respDTO); | 671 | when(client.getRefund(eq("P110"), eq("R220"))).thenReturn(respDTO); |
| @@ -690,7 +687,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { | @@ -690,7 +687,7 @@ public class PayRefundServiceTest extends BaseDbAndRedisUnitTest { | ||
| 690 | refundMapper.insert(refund); | 687 | refundMapper.insert(refund); |
| 691 | // mock 方法(client) | 688 | // mock 方法(client) |
| 692 | PayClient client = mock(PayClient.class); | 689 | PayClient client = mock(PayClient.class); |
| 693 | - when(payClientFactory.getPayClient(eq(10L))).thenReturn(client); | 690 | + when(channelService.getPayClient(eq(10L))).thenReturn(client); |
| 694 | // mock 方法(client 抛出异常) | 691 | // mock 方法(client 抛出异常) |
| 695 | when(client.getRefund(eq("P110"), eq("R220"))).thenThrow(new RuntimeException()); | 692 | when(client.getRefund(eq("P110"), eq("R220"))).thenThrow(new RuntimeException()); |
| 696 | 693 |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java
| @@ -14,12 +14,12 @@ public interface SocialClientApi { | @@ -14,12 +14,12 @@ public interface SocialClientApi { | ||
| 14 | /** | 14 | /** |
| 15 | * 获得社交平台的授权 URL | 15 | * 获得社交平台的授权 URL |
| 16 | * | 16 | * |
| 17 | - * @param type 社交平台的类型 {@link SocialTypeEnum} | 17 | + * @param socialType 社交平台的类型 {@link SocialTypeEnum} |
| 18 | * @param userType 用户类型 | 18 | * @param userType 用户类型 |
| 19 | * @param redirectUri 重定向 URL | 19 | * @param redirectUri 重定向 URL |
| 20 | * @return 社交平台的授权 URL | 20 | * @return 社交平台的授权 URL |
| 21 | */ | 21 | */ |
| 22 | - String getAuthorizeUrl(Integer type, Integer userType, String redirectUri); | 22 | + String getAuthorizeUrl(Integer socialType, Integer userType, String redirectUri); |
| 23 | 23 | ||
| 24 | /** | 24 | /** |
| 25 | * 创建微信公众号 JS SDK 初始化所需的签名 | 25 | * 创建微信公众号 JS SDK 初始化所需的签名 |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApi.java
| @@ -35,12 +35,12 @@ public interface SocialUserApi { | @@ -35,12 +35,12 @@ public interface SocialUserApi { | ||
| 35 | * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 | 35 | * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 |
| 36 | * | 36 | * |
| 37 | * @param userType 用户类型 | 37 | * @param userType 用户类型 |
| 38 | - * @param type 社交平台的类型 | 38 | + * @param socialType 社交平台的类型 |
| 39 | * @param code 授权码 | 39 | * @param code 授权码 |
| 40 | * @param state state | 40 | * @param state state |
| 41 | * @return 社交用户 | 41 | * @return 社交用户 |
| 42 | */ | 42 | */ |
| 43 | - SocialUserRespDTO getSocialUser(Integer userType, Integer type, | 43 | + SocialUserRespDTO getSocialUser(Integer userType, Integer socialType, |
| 44 | String code, String state); | 44 | String code, String state); |
| 45 | 45 | ||
| 46 | } | 46 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java
| @@ -24,8 +24,8 @@ public class SocialClientApiImpl implements SocialClientApi { | @@ -24,8 +24,8 @@ public class SocialClientApiImpl implements SocialClientApi { | ||
| 24 | private SocialClientService socialClientService; | 24 | private SocialClientService socialClientService; |
| 25 | 25 | ||
| 26 | @Override | 26 | @Override |
| 27 | - public String getAuthorizeUrl(Integer type, Integer userType, String redirectUri) { | ||
| 28 | - return socialClientService.getAuthorizeUrl(type, userType, redirectUri); | 27 | + public String getAuthorizeUrl(Integer socialType, Integer userType, String redirectUri) { |
| 28 | + return socialClientService.getAuthorizeUrl(socialType, userType, redirectUri); | ||
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | @Override | 31 | @Override |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApiImpl.java
| @@ -33,8 +33,8 @@ public class SocialUserApiImpl implements SocialUserApi { | @@ -33,8 +33,8 @@ public class SocialUserApiImpl implements SocialUserApi { | ||
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | @Override | 35 | @Override |
| 36 | - public SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state) { | ||
| 37 | - return socialUserService.getSocialUser(userType, type, code, state); | 36 | + public SocialUserRespDTO getSocialUser(Integer userType, Integer socialType, String code, String state) { |
| 37 | + return socialUserService.getSocialUser(userType, socialType, code, state); | ||
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | } | 40 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
| @@ -148,7 +148,8 @@ public class AuthController { | @@ -148,7 +148,8 @@ public class AuthController { | ||
| 148 | }) | 148 | }) |
| 149 | public CommonResult<String> socialLogin(@RequestParam("type") Integer type, | 149 | public CommonResult<String> socialLogin(@RequestParam("type") Integer type, |
| 150 | @RequestParam("redirectUri") String redirectUri) { | 150 | @RequestParam("redirectUri") String redirectUri) { |
| 151 | - return success(socialClientService.getAuthorizeUrl(type, UserTypeEnum.ADMIN.getValue(), redirectUri)); | 151 | + return success(socialClientService.getAuthorizeUrl( |
| 152 | + type, UserTypeEnum.ADMIN.getValue(), redirectUri)); | ||
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | @PostMapping("/social-login") | 155 | @PostMapping("/social-login") |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsTemplateController.http
| @@ -6,9 +6,9 @@ tenant-id: {{adminTenentId}} | @@ -6,9 +6,9 @@ tenant-id: {{adminTenentId}} | ||
| 6 | 6 | ||
| 7 | { | 7 | { |
| 8 | "templateCode": "test_01", | 8 | "templateCode": "test_01", |
| 9 | - "mobile": "156016913900", | ||
| 10 | - "params": { | ||
| 11 | - "key01": "value01", | ||
| 12 | - "key02": "value02" | 9 | + "mobile": "15601691390", |
| 10 | + "templateParams": { | ||
| 11 | + "operation": "value01", | ||
| 12 | + "code": "value02" | ||
| 13 | } | 13 | } |
| 14 | } | 14 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/dict/DictDataConvert.java
| @@ -31,5 +31,4 @@ public interface DictDataConvert { | @@ -31,5 +31,4 @@ public interface DictDataConvert { | ||
| 31 | 31 | ||
| 32 | List<AppDictDataRespVO> convertList03(List<DictDataDO> list); | 32 | List<AppDictDataRespVO> convertList03(List<DictDataDO> list); |
| 33 | 33 | ||
| 34 | - List<DictDataRespDTO> convertList04(List<DictDataDO> list); | ||
| 35 | } | 34 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/mail/MailSendConsumer.java
| 1 | package cn.iocoder.yudao.module.system.mq.consumer.mail; | 1 | package cn.iocoder.yudao.module.system.mq.consumer.mail; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; | ||
| 4 | import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage; | 3 | import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage; |
| 5 | -import cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage; | ||
| 6 | import cn.iocoder.yudao.module.system.service.mail.MailSendService; | 4 | import cn.iocoder.yudao.module.system.service.mail.MailSendService; |
| 7 | import lombok.extern.slf4j.Slf4j; | 5 | import lombok.extern.slf4j.Slf4j; |
| 6 | +import org.springframework.context.event.EventListener; | ||
| 7 | +import org.springframework.scheduling.annotation.Async; | ||
| 8 | import org.springframework.stereotype.Component; | 8 | import org.springframework.stereotype.Component; |
| 9 | 9 | ||
| 10 | import javax.annotation.Resource; | 10 | import javax.annotation.Resource; |
| @@ -16,12 +16,13 @@ import javax.annotation.Resource; | @@ -16,12 +16,13 @@ import javax.annotation.Resource; | ||
| 16 | */ | 16 | */ |
| 17 | @Component | 17 | @Component |
| 18 | @Slf4j | 18 | @Slf4j |
| 19 | -public class MailSendConsumer extends AbstractStreamMessageListener<MailSendMessage> { | 19 | +public class MailSendConsumer { |
| 20 | 20 | ||
| 21 | @Resource | 21 | @Resource |
| 22 | private MailSendService mailSendService; | 22 | private MailSendService mailSendService; |
| 23 | 23 | ||
| 24 | - @Override | 24 | + @EventListener |
| 25 | + @Async // Spring Event 默认在 Producer 发送的线程,通过 @Async 实现异步 | ||
| 25 | public void onMessage(MailSendMessage message) { | 26 | public void onMessage(MailSendMessage message) { |
| 26 | log.info("[onMessage][消息内容({})]", message); | 27 | log.info("[onMessage][消息内容({})]", message); |
| 27 | mailSendService.doSendMail(message); | 28 | mailSendService.doSendMail(message); |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/sms/SmsSendConsumer.java
| @@ -2,8 +2,9 @@ package cn.iocoder.yudao.module.system.mq.consumer.sms; | @@ -2,8 +2,9 @@ package cn.iocoder.yudao.module.system.mq.consumer.sms; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage; | 3 | import cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage; |
| 4 | import cn.iocoder.yudao.module.system.service.sms.SmsSendService; | 4 | import cn.iocoder.yudao.module.system.service.sms.SmsSendService; |
| 5 | -import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener; | ||
| 6 | import lombok.extern.slf4j.Slf4j; | 5 | import lombok.extern.slf4j.Slf4j; |
| 6 | +import org.springframework.context.event.EventListener; | ||
| 7 | +import org.springframework.scheduling.annotation.Async; | ||
| 7 | import org.springframework.stereotype.Component; | 8 | import org.springframework.stereotype.Component; |
| 8 | 9 | ||
| 9 | import javax.annotation.Resource; | 10 | import javax.annotation.Resource; |
| @@ -15,12 +16,13 @@ import javax.annotation.Resource; | @@ -15,12 +16,13 @@ import javax.annotation.Resource; | ||
| 15 | */ | 16 | */ |
| 16 | @Component | 17 | @Component |
| 17 | @Slf4j | 18 | @Slf4j |
| 18 | -public class SmsSendConsumer extends AbstractStreamMessageListener<SmsSendMessage> { | 19 | +public class SmsSendConsumer { |
| 19 | 20 | ||
| 20 | @Resource | 21 | @Resource |
| 21 | private SmsSendService smsSendService; | 22 | private SmsSendService smsSendService; |
| 22 | 23 | ||
| 23 | - @Override | 24 | + @EventListener |
| 25 | + @Async // Spring Event 默认在 Producer 发送的线程,通过 @Async 实现异步 | ||
| 24 | public void onMessage(SmsSendMessage message) { | 26 | public void onMessage(SmsSendMessage message) { |
| 25 | log.info("[onMessage][消息内容({})]", message); | 27 | log.info("[onMessage][消息内容({})]", message); |
| 26 | smsSendService.doSendSms(message); | 28 | smsSendService.doSendSms(message); |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/mail/MailSendMessage.java
| 1 | package cn.iocoder.yudao.module.system.mq.message.mail; | 1 | package cn.iocoder.yudao.module.system.mq.message.mail; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage; | ||
| 4 | import lombok.Data; | 3 | import lombok.Data; |
| 5 | -import lombok.EqualsAndHashCode; | ||
| 6 | 4 | ||
| 7 | import javax.validation.constraints.NotEmpty; | 5 | import javax.validation.constraints.NotEmpty; |
| 8 | import javax.validation.constraints.NotNull; | 6 | import javax.validation.constraints.NotNull; |
| @@ -13,8 +11,7 @@ import javax.validation.constraints.NotNull; | @@ -13,8 +11,7 @@ import javax.validation.constraints.NotNull; | ||
| 13 | * @author 芋道源码 | 11 | * @author 芋道源码 |
| 14 | */ | 12 | */ |
| 15 | @Data | 13 | @Data |
| 16 | -@EqualsAndHashCode(callSuper = true) | ||
| 17 | -public class MailSendMessage extends AbstractStreamMessage { | 14 | +public class MailSendMessage { |
| 18 | 15 | ||
| 19 | /** | 16 | /** |
| 20 | * 邮件日志编号 | 17 | * 邮件日志编号 |
| @@ -47,9 +44,4 @@ public class MailSendMessage extends AbstractStreamMessage { | @@ -47,9 +44,4 @@ public class MailSendMessage extends AbstractStreamMessage { | ||
| 47 | @NotEmpty(message = "邮件内容不能为空") | 44 | @NotEmpty(message = "邮件内容不能为空") |
| 48 | private String content; | 45 | private String content; |
| 49 | 46 | ||
| 50 | - @Override | ||
| 51 | - public String getStreamKey() { | ||
| 52 | - return "system.mail.send"; | ||
| 53 | - } | ||
| 54 | - | ||
| 55 | } | 47 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/sms/SmsSendMessage.java
| 1 | package cn.iocoder.yudao.module.system.mq.message.sms; | 1 | package cn.iocoder.yudao.module.system.mq.message.sms; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.core.KeyValue; | 3 | import cn.iocoder.yudao.framework.common.core.KeyValue; |
| 4 | -import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage; | ||
| 5 | import lombok.Data; | 4 | import lombok.Data; |
| 6 | -import lombok.EqualsAndHashCode; | ||
| 7 | 5 | ||
| 8 | import javax.validation.constraints.NotNull; | 6 | import javax.validation.constraints.NotNull; |
| 9 | import java.util.List; | 7 | import java.util.List; |
| @@ -14,8 +12,7 @@ import java.util.List; | @@ -14,8 +12,7 @@ import java.util.List; | ||
| 14 | * @author 芋道源码 | 12 | * @author 芋道源码 |
| 15 | */ | 13 | */ |
| 16 | @Data | 14 | @Data |
| 17 | -@EqualsAndHashCode(callSuper = true) | ||
| 18 | -public class SmsSendMessage extends AbstractStreamMessage { | 15 | +public class SmsSendMessage { |
| 19 | 16 | ||
| 20 | /** | 17 | /** |
| 21 | * 短信日志编号 | 18 | * 短信日志编号 |
| @@ -42,9 +39,4 @@ public class SmsSendMessage extends AbstractStreamMessage { | @@ -42,9 +39,4 @@ public class SmsSendMessage extends AbstractStreamMessage { | ||
| 42 | */ | 39 | */ |
| 43 | private List<KeyValue<String, Object>> templateParams; | 40 | private List<KeyValue<String, Object>> templateParams; |
| 44 | 41 | ||
| 45 | - @Override | ||
| 46 | - public String getStreamKey() { | ||
| 47 | - return "system.sms.send"; | ||
| 48 | - } | ||
| 49 | - | ||
| 50 | } | 42 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java
| 1 | package cn.iocoder.yudao.module.system.mq.producer.mail; | 1 | package cn.iocoder.yudao.module.system.mq.producer.mail; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; | ||
| 4 | import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage; | 3 | import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage; |
| 5 | import lombok.extern.slf4j.Slf4j; | 4 | import lombok.extern.slf4j.Slf4j; |
| 5 | +import org.springframework.context.ApplicationContext; | ||
| 6 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
| 7 | 7 | ||
| 8 | import javax.annotation.Resource; | 8 | import javax.annotation.Resource; |
| @@ -18,7 +18,7 @@ import javax.annotation.Resource; | @@ -18,7 +18,7 @@ import javax.annotation.Resource; | ||
| 18 | public class MailProducer { | 18 | public class MailProducer { |
| 19 | 19 | ||
| 20 | @Resource | 20 | @Resource |
| 21 | - private RedisMQTemplate redisMQTemplate; | 21 | + private ApplicationContext applicationContext; |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | * 发送 {@link MailSendMessage} 消息 | 24 | * 发送 {@link MailSendMessage} 消息 |
| @@ -35,7 +35,7 @@ public class MailProducer { | @@ -35,7 +35,7 @@ public class MailProducer { | ||
| 35 | MailSendMessage message = new MailSendMessage() | 35 | MailSendMessage message = new MailSendMessage() |
| 36 | .setLogId(sendLogId).setMail(mail).setAccountId(accountId) | 36 | .setLogId(sendLogId).setMail(mail).setAccountId(accountId) |
| 37 | .setNickname(nickname).setTitle(title).setContent(content); | 37 | .setNickname(nickname).setTitle(title).setContent(content); |
| 38 | - redisMQTemplate.send(message); | 38 | + applicationContext.publishEvent(message); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | } | 41 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/producer/sms/SmsProducer.java
| 1 | package cn.iocoder.yudao.module.system.mq.producer.sms; | 1 | package cn.iocoder.yudao.module.system.mq.producer.sms; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.core.KeyValue; | 3 | import cn.iocoder.yudao.framework.common.core.KeyValue; |
| 4 | -import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; | ||
| 5 | import cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage; | 4 | import cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage; |
| 6 | import lombok.extern.slf4j.Slf4j; | 5 | import lombok.extern.slf4j.Slf4j; |
| 6 | +import org.springframework.context.ApplicationContext; | ||
| 7 | import org.springframework.stereotype.Component; | 7 | import org.springframework.stereotype.Component; |
| 8 | 8 | ||
| 9 | import javax.annotation.Resource; | 9 | import javax.annotation.Resource; |
| @@ -20,7 +20,7 @@ import java.util.List; | @@ -20,7 +20,7 @@ import java.util.List; | ||
| 20 | public class SmsProducer { | 20 | public class SmsProducer { |
| 21 | 21 | ||
| 22 | @Resource | 22 | @Resource |
| 23 | - private RedisMQTemplate redisMQTemplate; | 23 | + private ApplicationContext applicationContext; |
| 24 | 24 | ||
| 25 | /** | 25 | /** |
| 26 | * 发送 {@link SmsSendMessage} 消息 | 26 | * 发送 {@link SmsSendMessage} 消息 |
| @@ -35,7 +35,7 @@ public class SmsProducer { | @@ -35,7 +35,7 @@ public class SmsProducer { | ||
| 35 | Long channelId, String apiTemplateId, List<KeyValue<String, Object>> templateParams) { | 35 | Long channelId, String apiTemplateId, List<KeyValue<String, Object>> templateParams) { |
| 36 | SmsSendMessage message = new SmsSendMessage().setLogId(logId).setMobile(mobile); | 36 | SmsSendMessage message = new SmsSendMessage().setLogId(logId).setMobile(mobile); |
| 37 | message.setChannelId(channelId).setApiTemplateId(apiTemplateId).setTemplateParams(templateParams); | 37 | message.setChannelId(channelId).setApiTemplateId(apiTemplateId).setTemplateParams(templateParams); |
| 38 | - redisMQTemplate.send(message); | 38 | + applicationContext.publishEvent(message); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | } | 41 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordService.java
| @@ -91,8 +91,8 @@ public interface SensitiveWordService { | @@ -91,8 +91,8 @@ public interface SensitiveWordService { | ||
| 91 | * 判断文本是否包含敏感词 | 91 | * 判断文本是否包含敏感词 |
| 92 | * | 92 | * |
| 93 | * @param text 文本 | 93 | * @param text 文本 |
| 94 | - * @param tags 表述数组 | ||
| 95 | - * @return 是否包含 | 94 | + * @param tags 标签数组 |
| 95 | + * @return 是否包含敏感词 | ||
| 96 | */ | 96 | */ |
| 97 | boolean isTextValid(String text, List<String> tags); | 97 | boolean isTextValid(String text, List<String> tags); |
| 98 | 98 |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java
| @@ -258,6 +258,7 @@ public class SensitiveWordServiceImpl implements SensitiveWordService { | @@ -258,6 +258,7 @@ public class SensitiveWordServiceImpl implements SensitiveWordService { | ||
| 258 | if (trie == null) { | 258 | if (trie == null) { |
| 259 | continue; | 259 | continue; |
| 260 | } | 260 | } |
| 261 | + // 如果有一个标签不合法,则返回 false 不合法 | ||
| 261 | if (!trie.isValid(text)) { | 262 | if (!trie.isValid(text)) { |
| 262 | return false; | 263 | return false; |
| 263 | } | 264 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java
| @@ -5,7 +5,6 @@ import cn.hutool.core.util.StrUtil; | @@ -5,7 +5,6 @@ import cn.hutool.core.util.StrUtil; | ||
| 5 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 5 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | import cn.iocoder.yudao.framework.sms.core.client.SmsClient; | 7 | import cn.iocoder.yudao.framework.sms.core.client.SmsClient; |
| 8 | -import cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory; | ||
| 9 | import cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult; | 8 | import cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult; |
| 10 | import cn.iocoder.yudao.framework.sms.core.client.dto.SmsTemplateRespDTO; | 9 | import cn.iocoder.yudao.framework.sms.core.client.dto.SmsTemplateRespDTO; |
| 11 | import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateCreateReqVO; | 10 | import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateCreateReqVO; |
| @@ -53,9 +52,6 @@ public class SmsTemplateServiceImpl implements SmsTemplateService { | @@ -53,9 +52,6 @@ public class SmsTemplateServiceImpl implements SmsTemplateService { | ||
| 53 | @Resource | 52 | @Resource |
| 54 | private SmsChannelService smsChannelService; | 53 | private SmsChannelService smsChannelService; |
| 55 | 54 | ||
| 56 | - @Resource | ||
| 57 | - private SmsClientFactory smsClientFactory; | ||
| 58 | - | ||
| 59 | @Override | 55 | @Override |
| 60 | public Long createSmsTemplate(SmsTemplateCreateReqVO createReqVO) { | 56 | public Long createSmsTemplate(SmsTemplateCreateReqVO createReqVO) { |
| 61 | // 校验短信渠道 | 57 | // 校验短信渠道 |
| @@ -173,7 +169,7 @@ public class SmsTemplateServiceImpl implements SmsTemplateService { | @@ -173,7 +169,7 @@ public class SmsTemplateServiceImpl implements SmsTemplateService { | ||
| 173 | @VisibleForTesting | 169 | @VisibleForTesting |
| 174 | void validateApiTemplate(Long channelId, String apiTemplateId) { | 170 | void validateApiTemplate(Long channelId, String apiTemplateId) { |
| 175 | // 获得短信模板 | 171 | // 获得短信模板 |
| 176 | - SmsClient smsClient = smsClientFactory.getSmsClient(channelId); | 172 | + SmsClient smsClient = smsChannelService.getSmsClient(channelId); |
| 177 | Assert.notNull(smsClient, String.format("短信客户端(%d) 不存在", channelId)); | 173 | Assert.notNull(smsClient, String.format("短信客户端(%d) 不存在", channelId)); |
| 178 | SmsCommonResult<SmsTemplateRespDTO> templateResult = smsClient.getSmsTemplate(apiTemplateId); | 174 | SmsCommonResult<SmsTemplateRespDTO> templateResult = smsClient.getSmsTemplate(apiTemplateId); |
| 179 | // 校验短信模板是否正确 | 175 | // 校验短信模板是否正确 |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserService.java
| @@ -38,12 +38,12 @@ public interface SocialUserService { | @@ -38,12 +38,12 @@ public interface SocialUserService { | ||
| 38 | /** | 38 | /** |
| 39 | * 取消绑定社交用户 | 39 | * 取消绑定社交用户 |
| 40 | * | 40 | * |
| 41 | - * @param userId 用户编号 | 41 | + * @param userId 用户编号 |
| 42 | * @param userType 全局用户类型 | 42 | * @param userType 全局用户类型 |
| 43 | - * @param type 社交平台的类型 {@link SocialTypeEnum} | ||
| 44 | - * @param openid 社交平台的 openid | 43 | + * @param socialType 社交平台的类型 {@link SocialTypeEnum} |
| 44 | + * @param openid 社交平台的 openid | ||
| 45 | */ | 45 | */ |
| 46 | - void unbindSocialUser(Long userId, Integer userType, Integer type, String openid); | 46 | + void unbindSocialUser(Long userId, Integer userType, Integer socialType, String openid); |
| 47 | 47 | ||
| 48 | /** | 48 | /** |
| 49 | * 获得社交用户 | 49 | * 获得社交用户 |
| @@ -51,12 +51,12 @@ public interface SocialUserService { | @@ -51,12 +51,12 @@ public interface SocialUserService { | ||
| 51 | * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 | 51 | * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 |
| 52 | * | 52 | * |
| 53 | * @param userType 用户类型 | 53 | * @param userType 用户类型 |
| 54 | - * @param type 社交平台的类型 | ||
| 55 | - * @param code 授权码 | ||
| 56 | - * @param state state | 54 | + * @param socialType 社交平台的类型 |
| 55 | + * @param code 授权码 | ||
| 56 | + * @param state state | ||
| 57 | * @return 社交用户 | 57 | * @return 社交用户 |
| 58 | */ | 58 | */ |
| 59 | - SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state); | 59 | + SocialUserRespDTO getSocialUser(Integer userType, Integer socialType, String code, String state); |
| 60 | 60 | ||
| 61 | // ==================== 社交用户 CRUD ==================== | 61 | // ==================== 社交用户 CRUD ==================== |
| 62 | 62 |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java
| @@ -84,9 +84,9 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -84,9 +84,9 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | @Override | 86 | @Override |
| 87 | - public void unbindSocialUser(Long userId, Integer userType, Integer type, String openid) { | 87 | + public void unbindSocialUser(Long userId, Integer userType, Integer socialType, String openid) { |
| 88 | // 获得 openid 对应的 SocialUserDO 社交用户 | 88 | // 获得 openid 对应的 SocialUserDO 社交用户 |
| 89 | - SocialUserDO socialUser = socialUserMapper.selectByTypeAndOpenid(type, openid); | 89 | + SocialUserDO socialUser = socialUserMapper.selectByTypeAndOpenid(socialType, openid); |
| 90 | if (socialUser == null) { | 90 | if (socialUser == null) { |
| 91 | throw exception(SOCIAL_USER_NOT_FOUND); | 91 | throw exception(SOCIAL_USER_NOT_FOUND); |
| 92 | } | 92 | } |
| @@ -96,9 +96,9 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -96,9 +96,9 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | @Override | 98 | @Override |
| 99 | - public SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state) { | 99 | + public SocialUserRespDTO getSocialUser(Integer userType, Integer socialType, String code, String state) { |
| 100 | // 获得社交用户 | 100 | // 获得社交用户 |
| 101 | - SocialUserDO socialUser = authSocialUser(type, userType, code, state); | 101 | + SocialUserDO socialUser = authSocialUser(socialType, userType, code, state); |
| 102 | Assert.notNull(socialUser, "社交用户不能为空"); | 102 | Assert.notNull(socialUser, "社交用户不能为空"); |
| 103 | 103 | ||
| 104 | // 如果未绑定的社交用户,则无法自动登录,进行报错 | 104 | // 如果未绑定的社交用户,则无法自动登录,进行报错 |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/collection/SimpleTrie.java
| @@ -30,9 +30,10 @@ public class SimpleTrie { | @@ -30,9 +30,10 @@ public class SimpleTrie { | ||
| 30 | * @param strs 字符串数组 | 30 | * @param strs 字符串数组 |
| 31 | */ | 31 | */ |
| 32 | public SimpleTrie(Collection<String> strs) { | 32 | public SimpleTrie(Collection<String> strs) { |
| 33 | - children = new HashMap<>(); | 33 | + // 排序,优先使用较短的前缀 |
| 34 | + strs = CollUtil.sort(strs, String::compareTo); | ||
| 34 | // 构建树 | 35 | // 构建树 |
| 35 | - CollUtil.sort(strs, String::compareTo); // 排序,优先使用较短的前缀 | 36 | + children = new HashMap<>(); |
| 36 | for (String str : strs) { | 37 | for (String str : strs) { |
| 37 | Map<Character, Object> child = children; | 38 | Map<Character, Object> child = children; |
| 38 | // 遍历每个字符 | 39 | // 遍历每个字符 |
| @@ -56,11 +57,11 @@ public class SimpleTrie { | @@ -56,11 +57,11 @@ public class SimpleTrie { | ||
| 56 | * 验证文本是否合法,即不包含敏感词 | 57 | * 验证文本是否合法,即不包含敏感词 |
| 57 | * | 58 | * |
| 58 | * @param text 文本 | 59 | * @param text 文本 |
| 59 | - * @return 是否 ok | 60 | + * @return 是否 true-合法 false-不合法 |
| 60 | */ | 61 | */ |
| 61 | public boolean isValid(String text) { | 62 | public boolean isValid(String text) { |
| 62 | // 遍历 text,使用每一个 [i, n) 段的字符串,使用 children 前缀树匹配,是否包含敏感词 | 63 | // 遍历 text,使用每一个 [i, n) 段的字符串,使用 children 前缀树匹配,是否包含敏感词 |
| 63 | - for (int i = 0; i < text.length() - 1; i++) { | 64 | + for (int i = 0; i < text.length(); i++) { |
| 64 | Map<Character, Object> child = (Map<Character, Object>) children.get(text.charAt(i)); | 65 | Map<Character, Object> child = (Map<Character, Object>) children.get(text.charAt(i)); |
| 65 | if (child == null) { | 66 | if (child == null) { |
| 66 | continue; | 67 | continue; |
| @@ -74,14 +75,17 @@ public class SimpleTrie { | @@ -74,14 +75,17 @@ public class SimpleTrie { | ||
| 74 | } | 75 | } |
| 75 | 76 | ||
| 76 | /** | 77 | /** |
| 77 | - * 验证文本从指定位置开始,是否包含某个敏感词 | 78 | + * 验证文本从指定位置开始,是否不包含某个敏感词 |
| 78 | * | 79 | * |
| 79 | * @param text 文本 | 80 | * @param text 文本 |
| 80 | * @param index 开始位置 | 81 | * @param index 开始位置 |
| 81 | * @param child 节点(当前遍历到的) | 82 | * @param child 节点(当前遍历到的) |
| 82 | - * @return 是否包含 | 83 | + * @return 是否不包含 true-不包含 false-包含 |
| 83 | */ | 84 | */ |
| 84 | private boolean recursion(String text, int index, Map<Character, Object> child) { | 85 | private boolean recursion(String text, int index, Map<Character, Object> child) { |
| 86 | + if (child.containsKey(CHARACTER_END)) { | ||
| 87 | + return false; | ||
| 88 | + } | ||
| 85 | if (index == text.length()) { | 89 | if (index == text.length()) { |
| 86 | return true; | 90 | return true; |
| 87 | } | 91 | } |
| @@ -99,7 +103,7 @@ public class SimpleTrie { | @@ -99,7 +103,7 @@ public class SimpleTrie { | ||
| 99 | */ | 103 | */ |
| 100 | public List<String> validate(String text) { | 104 | public List<String> validate(String text) { |
| 101 | Set<String> results = new HashSet<>(); | 105 | Set<String> results = new HashSet<>(); |
| 102 | - for (int i = 0; i < text.length() - 1; i++) { | 106 | + for (int i = 0; i < text.length(); i++) { |
| 103 | Character c = text.charAt(i); | 107 | Character c = text.charAt(i); |
| 104 | Map<Character, Object> child = (Map<Character, Object>) children.get(c); | 108 | Map<Character, Object> child = (Map<Character, Object>) children.get(c); |
| 105 | if (child == null) { | 109 | if (child == null) { |
| @@ -127,6 +131,9 @@ public class SimpleTrie { | @@ -127,6 +131,9 @@ public class SimpleTrie { | ||
| 127 | */ | 131 | */ |
| 128 | @SuppressWarnings("unchecked") | 132 | @SuppressWarnings("unchecked") |
| 129 | private static boolean recursionWithResult(String text, int index, Map<Character, Object> child, StringBuilder result) { | 133 | private static boolean recursionWithResult(String text, int index, Map<Character, Object> child, StringBuilder result) { |
| 134 | + if (child.containsKey(CHARACTER_END)) { | ||
| 135 | + return false; | ||
| 136 | + } | ||
| 130 | if (index == text.length()) { | 137 | if (index == text.length()) { |
| 131 | return true; | 138 | return true; |
| 132 | } | 139 | } |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java
| @@ -56,20 +56,28 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { | @@ -56,20 +56,28 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { | ||
| 56 | SensitiveWordDO wordDO2 = randomPojo(SensitiveWordDO.class, o -> o.setName("笨蛋") | 56 | SensitiveWordDO wordDO2 = randomPojo(SensitiveWordDO.class, o -> o.setName("笨蛋") |
| 57 | .setTags(singletonList("蔬菜")).setStatus(CommonStatusEnum.ENABLE.getStatus())); | 57 | .setTags(singletonList("蔬菜")).setStatus(CommonStatusEnum.ENABLE.getStatus())); |
| 58 | sensitiveWordMapper.insert(wordDO2); | 58 | sensitiveWordMapper.insert(wordDO2); |
| 59 | + SensitiveWordDO wordDO3 = randomPojo(SensitiveWordDO.class, o -> o.setName("白") | ||
| 60 | + .setTags(singletonList("测试")).setStatus(CommonStatusEnum.ENABLE.getStatus())); | ||
| 61 | + sensitiveWordMapper.insert(wordDO3); | ||
| 62 | + SensitiveWordDO wordDO4 = randomPojo(SensitiveWordDO.class, o -> o.setName("白痴") | ||
| 63 | + .setTags(singletonList("测试")).setStatus(CommonStatusEnum.ENABLE.getStatus())); | ||
| 64 | + sensitiveWordMapper.insert(wordDO4); | ||
| 59 | 65 | ||
| 60 | // 调用 | 66 | // 调用 |
| 61 | sensitiveWordService.initLocalCache(); | 67 | sensitiveWordService.initLocalCache(); |
| 62 | // 断言 sensitiveWordTagsCache 缓存 | 68 | // 断言 sensitiveWordTagsCache 缓存 |
| 63 | - assertEquals(SetUtils.asSet("论坛", "蔬菜"), sensitiveWordService.getSensitiveWordTagSet()); | 69 | + assertEquals(SetUtils.asSet("论坛", "蔬菜", "测试"), sensitiveWordService.getSensitiveWordTagSet()); |
| 64 | // 断言 sensitiveWordCache | 70 | // 断言 sensitiveWordCache |
| 65 | - assertEquals(2, sensitiveWordService.getSensitiveWordCache().size()); | 71 | + assertEquals(4, sensitiveWordService.getSensitiveWordCache().size()); |
| 66 | assertPojoEquals(wordDO1, sensitiveWordService.getSensitiveWordCache().get(0)); | 72 | assertPojoEquals(wordDO1, sensitiveWordService.getSensitiveWordCache().get(0)); |
| 67 | assertPojoEquals(wordDO2, sensitiveWordService.getSensitiveWordCache().get(1)); | 73 | assertPojoEquals(wordDO2, sensitiveWordService.getSensitiveWordCache().get(1)); |
| 74 | + assertPojoEquals(wordDO3, sensitiveWordService.getSensitiveWordCache().get(2)); | ||
| 68 | // 断言 tagSensitiveWordTries 缓存 | 75 | // 断言 tagSensitiveWordTries 缓存 |
| 69 | assertNotNull(sensitiveWordService.getDefaultSensitiveWordTrie()); | 76 | assertNotNull(sensitiveWordService.getDefaultSensitiveWordTrie()); |
| 70 | - assertEquals(2, sensitiveWordService.getTagSensitiveWordTries().size()); | 77 | + assertEquals(3, sensitiveWordService.getTagSensitiveWordTries().size()); |
| 71 | assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("论坛")); | 78 | assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("论坛")); |
| 72 | assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("蔬菜")); | 79 | assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("蔬菜")); |
| 80 | + assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("测试")); | ||
| 73 | } | 81 | } |
| 74 | 82 | ||
| 75 | @Test | 83 | @Test |
| @@ -231,11 +239,17 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { | @@ -231,11 +239,17 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { | ||
| 231 | testInitLocalCache(); | 239 | testInitLocalCache(); |
| 232 | // 准备参数 | 240 | // 准备参数 |
| 233 | String text = "你是傻瓜,你是笨蛋"; | 241 | String text = "你是傻瓜,你是笨蛋"; |
| 234 | - | ||
| 235 | // 调用 | 242 | // 调用 |
| 236 | List<String> result = sensitiveWordService.validateText(text, null); | 243 | List<String> result = sensitiveWordService.validateText(text, null); |
| 237 | // 断言 | 244 | // 断言 |
| 238 | assertEquals(Arrays.asList("傻瓜", "笨蛋"), result); | 245 | assertEquals(Arrays.asList("傻瓜", "笨蛋"), result); |
| 246 | + | ||
| 247 | + // 准备参数 | ||
| 248 | + String text2 = "你是傻瓜,你是笨蛋,你是白"; | ||
| 249 | + // 调用 | ||
| 250 | + List<String> result2 = sensitiveWordService.validateText(text2, null); | ||
| 251 | + // 断言 | ||
| 252 | + assertEquals(Arrays.asList("傻瓜", "笨蛋","白"), result2); | ||
| 239 | } | 253 | } |
| 240 | 254 | ||
| 241 | @Test | 255 | @Test |
| @@ -243,11 +257,18 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { | @@ -243,11 +257,18 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { | ||
| 243 | testInitLocalCache(); | 257 | testInitLocalCache(); |
| 244 | // 准备参数 | 258 | // 准备参数 |
| 245 | String text = "你是傻瓜,你是笨蛋"; | 259 | String text = "你是傻瓜,你是笨蛋"; |
| 246 | - | ||
| 247 | // 调用 | 260 | // 调用 |
| 248 | List<String> result = sensitiveWordService.validateText(text, singletonList("论坛")); | 261 | List<String> result = sensitiveWordService.validateText(text, singletonList("论坛")); |
| 249 | // 断言 | 262 | // 断言 |
| 250 | assertEquals(singletonList("傻瓜"), result); | 263 | assertEquals(singletonList("傻瓜"), result); |
| 264 | + | ||
| 265 | + | ||
| 266 | + // 准备参数 | ||
| 267 | + String text2 = "你是白"; | ||
| 268 | + // 调用 | ||
| 269 | + List<String> result2 = sensitiveWordService.validateText(text2, singletonList("测试")); | ||
| 270 | + // 断言 | ||
| 271 | + assertEquals(singletonList("白"), result2); | ||
| 251 | } | 272 | } |
| 252 | 273 | ||
| 253 | @Test | 274 | @Test |
| @@ -255,9 +276,13 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { | @@ -255,9 +276,13 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { | ||
| 255 | testInitLocalCache(); | 276 | testInitLocalCache(); |
| 256 | // 准备参数 | 277 | // 准备参数 |
| 257 | String text = "你是傻瓜,你是笨蛋"; | 278 | String text = "你是傻瓜,你是笨蛋"; |
| 258 | - | ||
| 259 | // 调用,断言 | 279 | // 调用,断言 |
| 260 | assertFalse(sensitiveWordService.isTextValid(text, null)); | 280 | assertFalse(sensitiveWordService.isTextValid(text, null)); |
| 281 | + | ||
| 282 | + // 准备参数 | ||
| 283 | + String text2 = "你是白"; | ||
| 284 | + // 调用,断言 | ||
| 285 | + assertFalse(sensitiveWordService.isTextValid(text2, null)); | ||
| 261 | } | 286 | } |
| 262 | 287 | ||
| 263 | @Test | 288 | @Test |
| @@ -265,9 +290,13 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { | @@ -265,9 +290,13 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { | ||
| 265 | testInitLocalCache(); | 290 | testInitLocalCache(); |
| 266 | // 准备参数 | 291 | // 准备参数 |
| 267 | String text = "你是傻瓜,你是笨蛋"; | 292 | String text = "你是傻瓜,你是笨蛋"; |
| 268 | - | ||
| 269 | // 调用,断言 | 293 | // 调用,断言 |
| 270 | assertFalse(sensitiveWordService.isTextValid(text, singletonList("论坛"))); | 294 | assertFalse(sensitiveWordService.isTextValid(text, singletonList("论坛"))); |
| 295 | + | ||
| 296 | + // 准备参数 | ||
| 297 | + String text2 = "你是白"; | ||
| 298 | + // 调用,断言 | ||
| 299 | + assertFalse(sensitiveWordService.isTextValid(text2, singletonList("测试"))); | ||
| 271 | } | 300 | } |
| 272 | 301 | ||
| 273 | } | 302 | } |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImplTest.java
| @@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 6 | import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; | 6 | import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; |
| 7 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | 7 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; |
| 8 | import cn.iocoder.yudao.framework.sms.core.client.SmsClient; | 8 | import cn.iocoder.yudao.framework.sms.core.client.SmsClient; |
| 9 | -import cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory; | ||
| 10 | import cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult; | 9 | import cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult; |
| 11 | import cn.iocoder.yudao.framework.sms.core.client.dto.SmsTemplateRespDTO; | 10 | import cn.iocoder.yudao.framework.sms.core.client.dto.SmsTemplateRespDTO; |
| 12 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | 11 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| @@ -36,7 +35,7 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; | @@ -36,7 +35,7 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; | ||
| 36 | import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; | 35 | import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; |
| 37 | import static org.junit.jupiter.api.Assertions.*; | 36 | import static org.junit.jupiter.api.Assertions.*; |
| 38 | import static org.mockito.ArgumentMatchers.eq; | 37 | import static org.mockito.ArgumentMatchers.eq; |
| 39 | -import static org.mockito.Mockito.*; | 38 | +import static org.mockito.Mockito.when; |
| 40 | 39 | ||
| 41 | @Import(SmsTemplateServiceImpl.class) | 40 | @Import(SmsTemplateServiceImpl.class) |
| 42 | public class SmsTemplateServiceImplTest extends BaseDbUnitTest { | 41 | public class SmsTemplateServiceImplTest extends BaseDbUnitTest { |
| @@ -50,8 +49,6 @@ public class SmsTemplateServiceImplTest extends BaseDbUnitTest { | @@ -50,8 +49,6 @@ public class SmsTemplateServiceImplTest extends BaseDbUnitTest { | ||
| 50 | @MockBean | 49 | @MockBean |
| 51 | private SmsChannelService smsChannelService; | 50 | private SmsChannelService smsChannelService; |
| 52 | @MockBean | 51 | @MockBean |
| 53 | - private SmsClientFactory smsClientFactory; | ||
| 54 | - @MockBean | ||
| 55 | private SmsClient smsClient; | 52 | private SmsClient smsClient; |
| 56 | 53 | ||
| 57 | @Test | 54 | @Test |
| @@ -82,7 +79,7 @@ public class SmsTemplateServiceImplTest extends BaseDbUnitTest { | @@ -82,7 +79,7 @@ public class SmsTemplateServiceImplTest extends BaseDbUnitTest { | ||
| 82 | }); | 79 | }); |
| 83 | when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO); | 80 | when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO); |
| 84 | // mock 获得 API 短信模板成功 | 81 | // mock 获得 API 短信模板成功 |
| 85 | - when(smsClientFactory.getSmsClient(eq(reqVO.getChannelId()))).thenReturn(smsClient); | 82 | + when(smsChannelService.getSmsClient(eq(reqVO.getChannelId()))).thenReturn(smsClient); |
| 86 | when(smsClient.getSmsTemplate(eq(reqVO.getApiTemplateId()))).thenReturn(randomPojo(SmsCommonResult.class, SmsTemplateRespDTO.class, | 83 | when(smsClient.getSmsTemplate(eq(reqVO.getApiTemplateId()))).thenReturn(randomPojo(SmsCommonResult.class, SmsTemplateRespDTO.class, |
| 87 | o -> o.setCode(GlobalErrorCodeConstants.SUCCESS.getCode()))); | 84 | o -> o.setCode(GlobalErrorCodeConstants.SUCCESS.getCode()))); |
| 88 | 85 | ||
| @@ -117,7 +114,7 @@ public class SmsTemplateServiceImplTest extends BaseDbUnitTest { | @@ -117,7 +114,7 @@ public class SmsTemplateServiceImplTest extends BaseDbUnitTest { | ||
| 117 | }); | 114 | }); |
| 118 | when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO); | 115 | when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO); |
| 119 | // mock 获得 API 短信模板成功 | 116 | // mock 获得 API 短信模板成功 |
| 120 | - when(smsClientFactory.getSmsClient(eq(reqVO.getChannelId()))).thenReturn(smsClient); | 117 | + when(smsChannelService.getSmsClient(eq(reqVO.getChannelId()))).thenReturn(smsClient); |
| 121 | when(smsClient.getSmsTemplate(eq(reqVO.getApiTemplateId()))).thenReturn(randomPojo(SmsCommonResult.class, SmsTemplateRespDTO.class, | 118 | when(smsClient.getSmsTemplate(eq(reqVO.getApiTemplateId()))).thenReturn(randomPojo(SmsCommonResult.class, SmsTemplateRespDTO.class, |
| 122 | o -> o.setCode(GlobalErrorCodeConstants.SUCCESS.getCode()))); | 119 | o -> o.setCode(GlobalErrorCodeConstants.SUCCESS.getCode()))); |
| 123 | 120 |
yudao-server/pom.xml
| @@ -37,11 +37,11 @@ | @@ -37,11 +37,11 @@ | ||
| 37 | </dependency> | 37 | </dependency> |
| 38 | 38 | ||
| 39 | <!-- 会员中心。默认注释,保证编译速度 --> | 39 | <!-- 会员中心。默认注释,保证编译速度 --> |
| 40 | - <dependency> | ||
| 41 | - <groupId>cn.iocoder.boot</groupId> | ||
| 42 | - <artifactId>yudao-module-member-biz</artifactId> | ||
| 43 | - <version>${revision}</version> | ||
| 44 | - </dependency> | 40 | +<!-- <dependency>--> |
| 41 | +<!-- <groupId>cn.iocoder.boot</groupId>--> | ||
| 42 | +<!-- <artifactId>yudao-module-member-biz</artifactId>--> | ||
| 43 | +<!-- <version>${revision}</version>--> | ||
| 44 | +<!-- </dependency>--> | ||
| 45 | 45 | ||
| 46 | <!-- 数据报表。默认注释,保证编译速度 --> | 46 | <!-- 数据报表。默认注释,保证编译速度 --> |
| 47 | <!-- <dependency>--> | 47 | <!-- <dependency>--> |
| @@ -56,40 +56,40 @@ | @@ -56,40 +56,40 @@ | ||
| 56 | <!-- <version>${revision}</version>--> | 56 | <!-- <version>${revision}</version>--> |
| 57 | <!-- </dependency>--> | 57 | <!-- </dependency>--> |
| 58 | <!-- 支付服务。默认注释,保证编译速度 --> | 58 | <!-- 支付服务。默认注释,保证编译速度 --> |
| 59 | - <dependency> | ||
| 60 | - <groupId>cn.iocoder.boot</groupId> | ||
| 61 | - <artifactId>yudao-module-pay-biz</artifactId> | ||
| 62 | - <version>${revision}</version> | ||
| 63 | - </dependency> | 59 | +<!-- <dependency>--> |
| 60 | +<!-- <groupId>cn.iocoder.boot</groupId>--> | ||
| 61 | +<!-- <artifactId>yudao-module-pay-biz</artifactId>--> | ||
| 62 | +<!-- <version>${revision}</version>--> | ||
| 63 | +<!-- </dependency>--> | ||
| 64 | 64 | ||
| 65 | <!-- 微信公众号模块。默认注释,保证编译速度 --> | 65 | <!-- 微信公众号模块。默认注释,保证编译速度 --> |
| 66 | - <dependency> | ||
| 67 | - <groupId>cn.iocoder.boot</groupId> | ||
| 68 | - <artifactId>yudao-module-mp-biz</artifactId> | ||
| 69 | - <version>${revision}</version> | ||
| 70 | - </dependency> | 66 | +<!-- <dependency>--> |
| 67 | +<!-- <groupId>cn.iocoder.boot</groupId>--> | ||
| 68 | +<!-- <artifactId>yudao-module-mp-biz</artifactId>--> | ||
| 69 | +<!-- <version>${revision}</version>--> | ||
| 70 | +<!-- </dependency>--> | ||
| 71 | 71 | ||
| 72 | <!-- 商城相关模块。默认注释,保证编译速度--> | 72 | <!-- 商城相关模块。默认注释,保证编译速度--> |
| 73 | - <dependency> | ||
| 74 | - <groupId>cn.iocoder.boot</groupId> | ||
| 75 | - <artifactId>yudao-module-promotion-biz</artifactId> | ||
| 76 | - <version>${revision}</version> | ||
| 77 | - </dependency> | ||
| 78 | - <dependency> | ||
| 79 | - <groupId>cn.iocoder.boot</groupId> | ||
| 80 | - <artifactId>yudao-module-product-biz</artifactId> | ||
| 81 | - <version>${revision}</version> | ||
| 82 | - </dependency> | ||
| 83 | - <dependency> | ||
| 84 | - <groupId>cn.iocoder.boot</groupId> | ||
| 85 | - <artifactId>yudao-module-trade-biz</artifactId> | ||
| 86 | - <version>${revision}</version> | ||
| 87 | - </dependency> | ||
| 88 | - <dependency> | ||
| 89 | - <groupId>cn.iocoder.boot</groupId> | ||
| 90 | - <artifactId>yudao-module-statistics-biz</artifactId> | ||
| 91 | - <version>${revision}</version> | ||
| 92 | - </dependency> | 73 | +<!-- <dependency>--> |
| 74 | +<!-- <groupId>cn.iocoder.boot</groupId>--> | ||
| 75 | +<!-- <artifactId>yudao-module-promotion-biz</artifactId>--> | ||
| 76 | +<!-- <version>${revision}</version>--> | ||
| 77 | +<!-- </dependency>--> | ||
| 78 | +<!-- <dependency>--> | ||
| 79 | +<!-- <groupId>cn.iocoder.boot</groupId>--> | ||
| 80 | +<!-- <artifactId>yudao-module-product-biz</artifactId>--> | ||
| 81 | +<!-- <version>${revision}</version>--> | ||
| 82 | +<!-- </dependency>--> | ||
| 83 | +<!-- <dependency>--> | ||
| 84 | +<!-- <groupId>cn.iocoder.boot</groupId>--> | ||
| 85 | +<!-- <artifactId>yudao-module-trade-biz</artifactId>--> | ||
| 86 | +<!-- <version>${revision}</version>--> | ||
| 87 | +<!-- </dependency>--> | ||
| 88 | +<!-- <dependency>--> | ||
| 89 | +<!-- <groupId>cn.iocoder.boot</groupId>--> | ||
| 90 | +<!-- <artifactId>yudao-module-statistics-biz</artifactId>--> | ||
| 91 | +<!-- <version>${revision}</version>--> | ||
| 92 | +<!-- </dependency>--> | ||
| 93 | 93 | ||
| 94 | <!-- spring boot 配置所需依赖 --> | 94 | <!-- spring boot 配置所需依赖 --> |
| 95 | <dependency> | 95 | <dependency> |
yudao-server/src/main/resources/application-dev.yaml
| @@ -94,6 +94,23 @@ spring: | @@ -94,6 +94,23 @@ spring: | ||
| 94 | jdbc: # 使用 JDBC 的 JobStore 的时候,JDBC 的配置 | 94 | jdbc: # 使用 JDBC 的 JobStore 的时候,JDBC 的配置 |
| 95 | initialize-schema: NEVER # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never ,我们手动创建表结构。 | 95 | initialize-schema: NEVER # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never ,我们手动创建表结构。 |
| 96 | 96 | ||
| 97 | +--- #################### 消息队列相关 #################### | ||
| 98 | + | ||
| 99 | +# rocketmq 配置项,对应 RocketMQProperties 配置类 | ||
| 100 | +rocketmq: | ||
| 101 | + name-server: 127.0.0.1:9876 # RocketMQ Namesrv | ||
| 102 | + | ||
| 103 | +spring: | ||
| 104 | + # RabbitMQ 配置项,对应 RabbitProperties 配置类 | ||
| 105 | + rabbitmq: | ||
| 106 | + host: 127.0.0.1 # RabbitMQ 服务的地址 | ||
| 107 | + port: 5672 # RabbitMQ 服务的端口 | ||
| 108 | + username: guest # RabbitMQ 服务的账号 | ||
| 109 | + password: guest # RabbitMQ 服务的密码 | ||
| 110 | + # Kafka 配置项,对应 KafkaProperties 配置类 | ||
| 111 | + kafka: | ||
| 112 | + bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 | ||
| 113 | + | ||
| 97 | --- #################### 服务保障相关配置 #################### | 114 | --- #################### 服务保障相关配置 #################### |
| 98 | 115 | ||
| 99 | # Lock4j 配置项 | 116 | # Lock4j 配置项 |
yudao-server/src/main/resources/application-local.yaml
| @@ -109,6 +109,23 @@ spring: | @@ -109,6 +109,23 @@ spring: | ||
| 109 | jdbc: # 使用 JDBC 的 JobStore 的时候,JDBC 的配置 | 109 | jdbc: # 使用 JDBC 的 JobStore 的时候,JDBC 的配置 |
| 110 | initialize-schema: NEVER # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never ,我们手动创建表结构。 | 110 | initialize-schema: NEVER # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never ,我们手动创建表结构。 |
| 111 | 111 | ||
| 112 | +--- #################### 消息队列相关 #################### | ||
| 113 | + | ||
| 114 | +# rocketmq 配置项,对应 RocketMQProperties 配置类 | ||
| 115 | +rocketmq: | ||
| 116 | + name-server: 127.0.0.1:9876 # RocketMQ Namesrv | ||
| 117 | + | ||
| 118 | +spring: | ||
| 119 | + # RabbitMQ 配置项,对应 RabbitProperties 配置类 | ||
| 120 | + rabbitmq: | ||
| 121 | + host: 127.0.0.1 # RabbitMQ 服务的地址 | ||
| 122 | + port: 5672 # RabbitMQ 服务的端口 | ||
| 123 | + username: guest # RabbitMQ 服务的账号 | ||
| 124 | + password: guest # RabbitMQ 服务的密码 | ||
| 125 | + # Kafka 配置项,对应 KafkaProperties 配置类 | ||
| 126 | + kafka: | ||
| 127 | + bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 | ||
| 128 | + | ||
| 112 | --- #################### 服务保障相关配置 #################### | 129 | --- #################### 服务保障相关配置 #################### |
| 113 | 130 | ||
| 114 | # Lock4j 配置项 | 131 | # Lock4j 配置项 |
yudao-server/src/main/resources/application.yaml
| @@ -106,6 +106,32 @@ aj: | @@ -106,6 +106,32 @@ aj: | ||
| 106 | req-check-minute-limit: 60 # check 接口一分钟内请求数限制 | 106 | req-check-minute-limit: 60 # check 接口一分钟内请求数限制 |
| 107 | req-verify-minute-limit: 60 # verify 接口一分钟内请求数限制 | 107 | req-verify-minute-limit: 60 # verify 接口一分钟内请求数限制 |
| 108 | 108 | ||
| 109 | +--- #################### 消息队列相关 #################### | ||
| 110 | + | ||
| 111 | +# rocketmq 配置项,对应 RocketMQProperties 配置类 | ||
| 112 | +rocketmq: | ||
| 113 | + # Producer 配置项 | ||
| 114 | + producer: | ||
| 115 | + group: ${spring.application.name}_PRODUCER # 生产者分组 | ||
| 116 | + | ||
| 117 | +spring: | ||
| 118 | + # Kafka 配置项,对应 KafkaProperties 配置类 | ||
| 119 | + kafka: | ||
| 120 | + # Kafka Producer 配置项 | ||
| 121 | + producer: | ||
| 122 | + acks: 1 # 0-不应答。1-leader 应答。all-所有 leader 和 follower 应答。 | ||
| 123 | + retries: 3 # 发送失败时,重试发送的次数 | ||
| 124 | + value-serializer: org.springframework.kafka.support.serializer.JsonSerializer # 消息的 value 的序列化 | ||
| 125 | + # Kafka Consumer 配置项 | ||
| 126 | + consumer: | ||
| 127 | + auto-offset-reset: earliest # 设置消费者分组最初的消费进度为 earliest 。可参考博客 https://blog.csdn.net/lishuangzhe7047/article/details/74530417 理解 | ||
| 128 | + value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer | ||
| 129 | + properties: | ||
| 130 | + spring.json.trusted.packages: '*' | ||
| 131 | + # Kafka Consumer Listener 监听器配置 | ||
| 132 | + listener: | ||
| 133 | + missing-topics-fatal: false # 消费监听接口监听的主题不存在时,默认会报错。所以通过设置为 false ,解决报错 | ||
| 134 | + | ||
| 109 | --- #################### 芋道相关配置 #################### | 135 | --- #################### 芋道相关配置 #################### |
| 110 | 136 | ||
| 111 | yudao: | 137 | yudao: |
| @@ -145,12 +171,6 @@ yudao: | @@ -145,12 +171,6 @@ yudao: | ||
| 145 | - cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants | 171 | - cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants |
| 146 | - cn.iocoder.yudao.module.system.enums.ErrorCodeConstants | 172 | - cn.iocoder.yudao.module.system.enums.ErrorCodeConstants |
| 147 | - cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants | 173 | - cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants |
| 148 | - mq: | ||
| 149 | - redis: | ||
| 150 | - pubsub: | ||
| 151 | - enable: false # 是否开启 Redis pubsub 广播消费,默认为 true。这里设置成 false,可以按需开启 | ||
| 152 | - stream: | ||
| 153 | - enable: false # 是否开启 Redis stream 集群消费,默认为 true。这里设置成 false,可以按需开启 | ||
| 154 | tenant: # 多租户相关配置项 | 174 | tenant: # 多租户相关配置项 |
| 155 | enable: true | 175 | enable: true |
| 156 | ignore-urls: | 176 | ignore-urls: |
yudao-server/src/main/resources/static/MP_verify_DKOvVzFP7vPwwHx2.txt deleted
yudao-server/src/main/resources/static/READMD.md deleted
| 1 | -## 微信公众号 | ||
| 2 | - | ||
| 3 | -参考文章:https://www.yuque.com/docs/share/0e2966dd-89f8-4b69-980d-b876168725df | ||
| 4 | - | ||
| 5 | -① 访问 social-login.html 选择【微信公众号】 | ||
| 6 | - | ||
| 7 | -② 微信公众号授权完成后,跳转回 social-login2.html,输入手机号 + 密码,进行绑定 | ||
| 8 | - | ||
| 9 | -## 微信小程序 | ||
| 10 | - | ||
| 11 | -参考文章:https://www.yuque.com/docs/share/88e3d30a-6830-45fc-8c25-dae485aef3aa | ||
| 12 | - | ||
| 13 | -① 暂时使用 mini-program-test 项目 |
yudao-server/src/main/resources/static/pay_wx_pub.html deleted
| 1 | -<!DOCTYPE html> | ||
| 2 | -<html> | ||
| 3 | -<head> | ||
| 4 | - <meta charset="UTF-8"> | ||
| 5 | - <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/> | ||
| 6 | - <title>支付测试页</title> | ||
| 7 | - <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script> | ||
| 8 | - <script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> | ||
| 9 | -</head> | ||
| 10 | -<body> | ||
| 11 | -<div>点击如下按钮,发起支付的测试</div> | ||
| 12 | -<div> | ||
| 13 | - <button id="wx_pub">微信公众号</button> | ||
| 14 | -</div> | ||
| 15 | -</body> | ||
| 16 | -<script> | ||
| 17 | - let shopOrderId = undefined; | ||
| 18 | - let payOrderId = undefined; | ||
| 19 | - let server = 'http://127.0.0.1:48080'; | ||
| 20 | - // let server = 'http://niubi.natapp1.cc'; | ||
| 21 | - // TODO openid | ||
| 22 | - let openid = "ockUAwIZ-0OeMZl9ogcZ4ILrGba0"; | ||
| 23 | - $(function() { | ||
| 24 | - // 获得 JsapiTicket | ||
| 25 | - // 参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文档 | ||
| 26 | - $.ajax({ | ||
| 27 | - url: server + "/app-api/wx/mp/create-jsapi-signature?url=" + document.location.href, | ||
| 28 | - method: 'POST', | ||
| 29 | - headers: { | ||
| 30 | - 'tenant-id': 1 | ||
| 31 | - }, | ||
| 32 | - success: function( result ) { | ||
| 33 | - if (result.code !== 0) { | ||
| 34 | - alert('获取 JsapiTicket 失败,原因:' + result.msg) | ||
| 35 | - return; | ||
| 36 | - } | ||
| 37 | - var jsapiTicket = result.data; | ||
| 38 | - jsapiTicket.jsApiList = ['chooseWXPay']; | ||
| 39 | - jsapiTicket.debug = false; | ||
| 40 | - | ||
| 41 | - // 初始化 JS | ||
| 42 | - wx.config(jsapiTicket); | ||
| 43 | - } | ||
| 44 | - }); | ||
| 45 | - | ||
| 46 | - // 自动发起商城订单编号 | ||
| 47 | - $.ajax({ | ||
| 48 | - url: server + "/app-api/shop/order/create", | ||
| 49 | - method: 'POST', | ||
| 50 | - success: function( result ) { | ||
| 51 | - if (result.code !== 0) { | ||
| 52 | - alert('创建商城订单失败,原因:' + result.msg) | ||
| 53 | - return; | ||
| 54 | - } | ||
| 55 | - shopOrderId = result.data.id; | ||
| 56 | - payOrderId = result.data.payOrderId; | ||
| 57 | - console.log("商城订单:" + shopOrderId) | ||
| 58 | - console.log("支付订单:" + payOrderId) | ||
| 59 | - } | ||
| 60 | - }) | ||
| 61 | - }) | ||
| 62 | - | ||
| 63 | - // 微信公众号 | ||
| 64 | - $( "#wx_pub").on( "click", function() { | ||
| 65 | - if (typeof WeixinJSBridge == "undefined") { | ||
| 66 | - // if (document.addEventListener) { | ||
| 67 | - // document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false); | ||
| 68 | - // } else if (document.attachEvent) { | ||
| 69 | - // document.attachEvent('WeixinJSBridgeReady', onBridgeReady); | ||
| 70 | - // document.attachEvent('onWeixinJSBridgeReady', onBridgeReady); | ||
| 71 | - // } | ||
| 72 | - alert('微信支付,只支持在微信客户端中使用!'); | ||
| 73 | - return; | ||
| 74 | - } | ||
| 75 | - if (navigator.userAgent.indexOf('wechatdevtools') >= 0) { | ||
| 76 | - alert('微信支付,无法在微信开发者工具中使用!请使用微信客户端!'); | ||
| 77 | - return; | ||
| 78 | - } | ||
| 79 | - | ||
| 80 | - // 提交支付 | ||
| 81 | - // 参考 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6 文档 | ||
| 82 | - // 参考 https://segmentfault.com/a/1190000020704650 文档 | ||
| 83 | - $.ajax({ | ||
| 84 | - url: server + "/app-api/pay/order/submit", | ||
| 85 | - method: 'POST', | ||
| 86 | - dataType: "json", | ||
| 87 | - contentType: "application/json", | ||
| 88 | - data: JSON.stringify({ | ||
| 89 | - "id": payOrderId, | ||
| 90 | - "channelCode": 'wx_pub', | ||
| 91 | - "channelExtras": { | ||
| 92 | - "openid": openid | ||
| 93 | - } | ||
| 94 | - }), | ||
| 95 | - success: function( result ) { | ||
| 96 | - if (result.code !== 0) { | ||
| 97 | - alert('提交支付订单失败,原因:' + result.msg) | ||
| 98 | - return; | ||
| 99 | - } | ||
| 100 | - alert('点击确定,开始微信支付'); | ||
| 101 | - // 开始调用微信支付 | ||
| 102 | - let data = result.data.invokeResponse; | ||
| 103 | - wx.chooseWXPay({ | ||
| 104 | - timestamp: data.timeStamp, | ||
| 105 | - nonceStr: data.nonceStr, | ||
| 106 | - package: data.packageValue, | ||
| 107 | - signType: data.signType, | ||
| 108 | - paySign: data.paySign, | ||
| 109 | - success: function (res) { | ||
| 110 | - alert(JSON.stringify(res)); | ||
| 111 | - }, | ||
| 112 | - error: function(e) { | ||
| 113 | - alert(JSON.stringify(e)); | ||
| 114 | - } | ||
| 115 | - }); | ||
| 116 | - } | ||
| 117 | - }) | ||
| 118 | - }); | ||
| 119 | -</script> | ||
| 120 | -</html> |
yudao-ui-admin/package.json