Commit 2278ad46529846df8740c875c68558d6abc91ae1

Authored by YunaiV
2 parents 962f2bbf 04a391cd

Merge branch 'feature/mall_product' of https://gitee.com/puhui999/ruoyi-vue-pro …

…into feature/mall_product

 Conflicts:
	yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
Showing 48 changed files with 515 additions and 452 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
@@ -43,6 +43,16 @@ public class LocalDateTimeUtils { @@ -43,6 +43,16 @@ public class LocalDateTimeUtils {
43 return LocalDateTime.of(year, mouth, day, 0, 0, 0); 43 return LocalDateTime.of(year, mouth, day, 0, 0, 0);
44 } 44 }
45 45
  46 + /**
  47 + * 创建指定时间
  48 + *
  49 + * @param timeStr 时间字符串
  50 + * @return 指定时间
  51 + */
  52 + public static LocalDateTime buildTime(String timeStr) {
  53 + return LocalDateTime.of(LocalDate.now(), LocalTime.parse(timeStr));
  54 + }
  55 +
46 public static LocalDateTime[] buildBetweenTime(int year1, int mouth1, int day1, 56 public static LocalDateTime[] buildBetweenTime(int year1, int mouth1, int day1,
47 int year2, int mouth2, int day2) { 57 int year2, int mouth2, int day2) {
48 return new LocalDateTime[]{buildTime(year1, mouth1, day1), buildTime(year2, mouth2, day2)}; 58 return new LocalDateTime[]{buildTime(year1, mouth1, day1), buildTime(year2, mouth2, day2)};
@@ -63,6 +73,22 @@ public class LocalDateTimeUtils { @@ -63,6 +73,22 @@ public class LocalDateTimeUtils {
63 } 73 }
64 74
65 /** 75 /**
  76 + * 判断当前时间是否在该时间范围内
  77 + *
  78 + * @param startTime 开始时间
  79 + * @param endTime 结束时间
  80 + * @return 是否
  81 + */
  82 + public static boolean isBetween(String startTime, String endTime) {
  83 + if (startTime == null || endTime == null) {
  84 + return false;
  85 + }
  86 + LocalDate nowDate = LocalDate.now();
  87 + return LocalDateTimeUtil.isIn(LocalDateTime.now(), LocalDateTime.of(nowDate, LocalTime.parse(startTime)),
  88 + LocalDateTime.of(nowDate, LocalTime.parse(endTime)));
  89 + }
  90 +
  91 + /**
66 * 判断时间段是否重叠 92 * 判断时间段是否重叠
67 * 93 *
68 * @param startTime1 开始 time1 94 * @param startTime1 开始 time1
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java
@@ -59,14 +59,13 @@ public class ProductSkuRespDTO { @@ -59,14 +59,13 @@ public class ProductSkuRespDTO {
59 * 商品体积,单位:m^3 平米 59 * 商品体积,单位:m^3 平米
60 */ 60 */
61 private Double volume; 61 private Double volume;
62 - // TODO @puhui999:firstBrokeragePrice ;尴尬,我当时打错了;secondBrokeragePrice  
63 /** 62 /**
64 * 一级分销的佣金,单位:分 63 * 一级分销的佣金,单位:分
65 */ 64 */
66 - private Integer firstBrokerageRecord; 65 + private Integer firstBrokeragePrice;
67 /** 66 /**
68 * 二级分销的佣金,单位:分 67 * 二级分销的佣金,单位:分
69 */ 68 */
70 - private Integer secondBrokerageRecord; 69 + private Integer secondBrokeragePrice;
71 70
72 } 71 }
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java
1 package cn.iocoder.yudao.module.product.api.spu.dto; 1 package cn.iocoder.yudao.module.product.api.spu.dto;
2 2
3 -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;  
4 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; 3 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
5 import lombok.Data; 4 import lombok.Data;
6 5
@@ -32,6 +31,12 @@ public class ProductSpuRespDTO { @@ -32,6 +31,12 @@ public class ProductSpuRespDTO {
32 */ 31 */
33 private String keyword; 32 private String keyword;
34 /** 33 /**
  34 + * 单位
  35 + *
  36 + * 对应 product_unit 数据字典
  37 + */
  38 + private Integer unit;
  39 + /**
35 * 商品简介 40 * 商品简介
36 */ 41 */
37 private String introduction; 42 private String introduction;
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java
@@ -51,10 +51,10 @@ public class ProductSkuBaseVO { @@ -51,10 +51,10 @@ public class ProductSkuBaseVO {
51 private Double volume; 51 private Double volume;
52 52
53 @Schema(description = "一级分销的佣金,单位:分", example = "199") 53 @Schema(description = "一级分销的佣金,单位:分", example = "199")
54 - private Integer firstBrokerageRecord; 54 + private Integer firstBrokeragePrice;
55 55
56 @Schema(description = "二级分销的佣金,单位:分", example = "19") 56 @Schema(description = "二级分销的佣金,单位:分", example = "19")
57 - private Integer secondBrokerageRecord; 57 + private Integer secondBrokeragePrice;
58 58
59 @Schema(description = "属性数组") 59 @Schema(description = "属性数组")
60 private List<Property> properties; 60 private List<Property> properties;
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java
@@ -81,11 +81,11 @@ public class ProductSkuDO extends BaseDO { @@ -81,11 +81,11 @@ public class ProductSkuDO extends BaseDO {
81 /** 81 /**
82 * 一级分销的佣金,单位:分 82 * 一级分销的佣金,单位:分
83 */ 83 */
84 - private Integer firstBrokerageRecord; 84 + private Integer firstBrokeragePrice;
85 /** 85 /**
86 * 二级分销的佣金,单位:分 86 * 二级分销的佣金,单位:分
87 */ 87 */
88 - private Integer secondBrokerageRecord; 88 + private Integer secondBrokeragePrice;
89 89
90 // ========== 营销相关字段 ========= 90 // ========== 营销相关字段 =========
91 91
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java
@@ -92,8 +92,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @@ -92,8 +92,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
92 o.setMarketPrice(generaInt()); 92 o.setMarketPrice(generaInt());
93 o.setStock(generaInt()); 93 o.setStock(generaInt());
94 o.setWarnStock(10); 94 o.setWarnStock(10);
95 - o.setFirstBrokerageRecord(generaInt());  
96 - o.setSecondBrokerageRecord(generaInt()); 95 + o.setFirstBrokeragePrice(generaInt());
  96 + o.setSecondBrokeragePrice(generaInt());
97 // 限制分数为两位数 97 // 限制分数为两位数
98 o.setWeight(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); 98 o.setWeight(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP));
99 o.setVolume(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); 99 o.setVolume(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP));
@@ -143,8 +143,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @@ -143,8 +143,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
143 o.setMarketPrice(generaInt()); 143 o.setMarketPrice(generaInt());
144 o.setStock(generaInt()); 144 o.setStock(generaInt());
145 o.setWarnStock(10); 145 o.setWarnStock(10);
146 - o.setFirstBrokerageRecord(generaInt());  
147 - o.setSecondBrokerageRecord(generaInt()); 146 + o.setFirstBrokeragePrice(generaInt());
  147 + o.setSecondBrokeragePrice(generaInt());
148 // 限制分数为两位数 148 // 限制分数为两位数
149 o.setWeight(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); 149 o.setWeight(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP));
150 o.setVolume(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); 150 o.setVolume(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP));
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApi.java renamed to yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationActivityApi.java
1 package cn.iocoder.yudao.module.promotion.api.combination; 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2
3 -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO;  
4 -  
5 -// TODO @puhui999:是不是改成 CombinationActivityApi  
6 /** 3 /**
7 * 拼团活动 Api 接口 4 * 拼团活动 Api 接口
8 * 5 *
9 * @author HUIHUI 6 * @author HUIHUI
10 */ 7 */
11 -public interface CombinationApi { 8 +public interface CombinationActivityApi {
12 9
13 /** 10 /**
14 - * 更新活动库存 11 + * 校验是否满足拼团条件
15 * 12 *
16 - * @param reqDTO 请求 13 + * @param activityId 活动编号
  14 + * @param userId 用户编号
  15 + * @param skuId sku 编号
  16 + * @param count 数量
17 */ 17 */
18 - // TODO @puhui999:应该是更新哇?还是校验哈;  
19 - void validateCombination(CombinationActivityUpdateStockReqDTO reqDTO); 18 + void validateCombination(Long activityId, Long userId, Long skuId, Integer count);
20 19
21 } 20 }
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java
1 package cn.iocoder.yudao.module.promotion.api.combination; 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2
3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; 3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
4 -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;  
5 4
6 import javax.validation.Valid; 5 import javax.validation.Valid;
7 import java.time.LocalDateTime; 6 import java.time.LocalDateTime;
8 -import java.util.List;  
9 7
10 // TODO @芋艿:后面也再撸撸这几个接口 8 // TODO @芋艿:后面也再撸撸这几个接口
11 9
@@ -33,26 +31,7 @@ public interface CombinationRecordApi { @@ -33,26 +31,7 @@ public interface CombinationRecordApi {
33 boolean isCombinationRecordSuccess(Long userId, Long orderId); 31 boolean isCombinationRecordSuccess(Long userId, Long orderId);
34 32
35 /** 33 /**
36 - * 获取拼团记录  
37 - *  
38 - * @param userId 用户编号  
39 - * @param activityId 活动编号  
40 - * @return 拼团记录列表  
41 - */  
42 - List<CombinationRecordRespDTO> getRecordListByUserIdAndActivityId(Long userId, Long activityId);  
43 -  
44 - /**  
45 - * 验证组合限制数  
46 - * 校验是否满足限购要求  
47 - *  
48 - * @param count 本次购买数量  
49 - * @param sumCount 已购买数量合计  
50 - * @param activityId 活动编号  
51 - */  
52 - void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount);  
53 -  
54 - /**  
55 - * 更新拼团状态为成功 34 + * 更新拼团状态为 成功
56 * 35 *
57 * @param userId 用户编号 36 * @param userId 用户编号
58 * @param orderId 订单编号 37 * @param orderId 订单编号
@@ -60,7 +39,7 @@ public interface CombinationRecordApi { @@ -60,7 +39,7 @@ public interface CombinationRecordApi {
60 void updateRecordStatusToSuccess(Long userId, Long orderId); 39 void updateRecordStatusToSuccess(Long userId, Long orderId);
61 40
62 /** 41 /**
63 - * 更新拼团状态为失败 42 + * 更新拼团状态为 失败
64 * 43 *
65 * @param userId 用户编号 44 * @param userId 用户编号
66 * @param orderId 订单编号 45 * @param orderId 订单编号
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationActivityUpdateStockReqDTO.java deleted
1 -package cn.iocoder.yudao.module.promotion.api.combination.dto;  
2 -  
3 -import lombok.Data;  
4 -  
5 -import javax.validation.Valid;  
6 -import javax.validation.constraints.NotNull;  
7 -  
8 -/**  
9 - * 拼团活动更新活动库存 Request DTO  
10 - *  
11 - * @author HUIHUI  
12 - */  
13 -@Data  
14 -public class CombinationActivityUpdateStockReqDTO {  
15 -  
16 - // TODO @puhui999:是不是一个 activityId、count、skuId 参数就完事啦。  
17 -  
18 - @NotNull(message = "活动编号不能为空")  
19 - private Long activityId;  
20 -  
21 - @NotNull(message = "购买数量不能为空")  
22 - private Integer count;  
23 -  
24 - @NotNull(message = "活动商品不能为空")  
25 - private Item item;  
26 -  
27 - @Data  
28 - @Valid  
29 - public static class Item {  
30 -  
31 - @NotNull(message = "SPU 编号不能为空")  
32 - private Long spuId;  
33 -  
34 - @NotNull(message = "SKU 编号活动商品不能为空")  
35 - private Long skuId;  
36 -  
37 - @NotNull(message = "购买数量不能为空")  
38 - private Integer count;  
39 -  
40 - }  
41 -  
42 -}  
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordCreateReqDTO.java
@@ -13,26 +13,39 @@ import javax.validation.constraints.NotNull; @@ -13,26 +13,39 @@ import javax.validation.constraints.NotNull;
13 @Data 13 @Data
14 public class CombinationRecordCreateReqDTO { 14 public class CombinationRecordCreateReqDTO {
15 15
16 - // TODO @puhui999:注释还是要的哈  
17 - 16 + /**
  17 + * 拼团活动编号
  18 + */
18 @NotNull(message = "拼团活动编号不能为空") 19 @NotNull(message = "拼团活动编号不能为空")
19 private Long activityId; 20 private Long activityId;
20 - 21 + /**
  22 + * spu 编号
  23 + */
21 @NotNull(message = "spu 编号不能为空") 24 @NotNull(message = "spu 编号不能为空")
22 private Long spuId; 25 private Long spuId;
23 - 26 + /**
  27 + * sku 编号
  28 + */
24 @NotNull(message = "sku 编号不能为空") 29 @NotNull(message = "sku 编号不能为空")
25 private Long skuId; 30 private Long skuId;
26 - 31 + /**
  32 + * 订单编号
  33 + */
27 @NotNull(message = "订单编号不能为空") 34 @NotNull(message = "订单编号不能为空")
28 private Long orderId; 35 private Long orderId;
29 - 36 + /**
  37 + * 用户编号
  38 + */
30 @NotNull(message = "用户编号不能为空") 39 @NotNull(message = "用户编号不能为空")
31 private Long userId; 40 private Long userId;
32 - 41 + /**
  42 + * 团长编号
  43 + */
33 @NotNull(message = "团长编号不能为空") 44 @NotNull(message = "团长编号不能为空")
34 private Long headId; 45 private Long headId;
35 - 46 + /**
  47 + * 拼团商品单价
  48 + */
36 @NotNull(message = "拼团商品单价不能为空") 49 @NotNull(message = "拼团商品单价不能为空")
37 private Integer combinationPrice; 50 private Integer combinationPrice;
38 51
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java
1 package cn.iocoder.yudao.module.promotion.api.seckill; 1 package cn.iocoder.yudao.module.promotion.api.seckill;
2 2
3 -import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;  
4 -  
5 /** 3 /**
6 * 秒杀活动 API 接口 4 * 秒杀活动 API 接口
7 * 5 *
@@ -12,8 +10,10 @@ public interface SeckillActivityApi { @@ -12,8 +10,10 @@ public interface SeckillActivityApi {
12 /** 10 /**
13 * 更新秒杀库存 11 * 更新秒杀库存
14 * 12 *
15 - * @param updateStockReqDTO 请求 13 + * @param activityId 活动编号
  14 + * @param skuId sku 编号
  15 + * @param count 数量
16 */ 16 */
17 - void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO); 17 + void updateSeckillStock(Long activityId, Long skuId, Integer count);
18 18
19 } 19 }
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/dto/SeckillActivityUpdateStockReqDTO.java deleted
1 -package cn.iocoder.yudao.module.promotion.api.seckill.dto;  
2 -  
3 -import lombok.Data;  
4 -  
5 -import javax.validation.Valid;  
6 -import javax.validation.constraints.NotNull;  
7 -  
8 -/**  
9 - * 更新秒杀库存 request DTO  
10 - *  
11 - * @author HUIHUI  
12 - */  
13 -@Data  
14 -public class SeckillActivityUpdateStockReqDTO {  
15 -  
16 - // TODO @puhui999:可以不用 dto,直接 activityId、skuId、count 即可  
17 -  
18 - @NotNull(message = "活动编号不能为空")  
19 - private Long activityId;  
20 -  
21 - @NotNull(message = "购买数量不能为空")  
22 - private Integer count;  
23 -  
24 - @NotNull(message = "活动商品不能为空")  
25 - private Item item;  
26 -  
27 - @Data  
28 - @Valid  
29 - public static class Item {  
30 -  
31 - @NotNull(message = "SPU 编号不能为空")  
32 - private Long spuId;  
33 -  
34 - @NotNull(message = "SKU 编号活动商品不能为空")  
35 - private Long skuId;  
36 -  
37 - @NotNull(message = "购买数量不能为空")  
38 - private Integer count;  
39 -  
40 - }  
41 -  
42 -}  
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
@@ -56,6 +56,7 @@ public interface ErrorCodeConstants { @@ -56,6 +56,7 @@ public interface ErrorCodeConstants {
56 ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除"); 56 ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除");
57 ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭"); 57 ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭");
58 ErrorCode SECKILL_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1013008006, "秒杀失败,原因秒杀库存不足"); 58 ErrorCode SECKILL_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1013008006, "秒杀失败,原因秒杀库存不足");
  59 + ErrorCode SECKILL_ACTIVITY_FAIL_STATUS_CLOSED = new ErrorCode(1013008007, "秒杀活动已关闭");
59 60
60 // ========== 秒杀时段 1013009000 ========== 61 // ========== 秒杀时段 1013009000 ==========
61 ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1013009000, "秒杀时段不存在"); 62 ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1013009000, "秒杀时段不存在");
yudao-module-mall/yudao-module-promotion-biz/pom.xml
@@ -77,6 +77,10 @@ @@ -77,6 +77,10 @@
77 <groupId>cn.iocoder.boot</groupId> 77 <groupId>cn.iocoder.boot</groupId>
78 <artifactId>yudao-spring-boot-starter-excel</artifactId> 78 <artifactId>yudao-spring-boot-starter-excel</artifactId>
79 </dependency> 79 </dependency>
  80 + <dependency>
  81 + <groupId>cn.iocoder.boot</groupId>
  82 + <artifactId>yudao-spring-boot-starter-biz-dict</artifactId>
  83 + </dependency>
80 </dependencies> 84 </dependencies>
81 85
82 </project> 86 </project>
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationActivityApiImpl.java
1 package cn.iocoder.yudao.module.promotion.api.combination; 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2
3 -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO;  
4 import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService; 3 import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService;
5 import org.springframework.stereotype.Service; 4 import org.springframework.stereotype.Service;
6 -import org.springframework.validation.annotation.Validated;  
7 5
8 import javax.annotation.Resource; 6 import javax.annotation.Resource;
9 7
@@ -13,15 +11,14 @@ import javax.annotation.Resource; @@ -13,15 +11,14 @@ import javax.annotation.Resource;
13 * @author HUIHUI 11 * @author HUIHUI
14 */ 12 */
15 @Service 13 @Service
16 -@Validated  
17 -public class CombinationApiImpl implements CombinationApi { 14 +public class CombinationActivityApiImpl implements CombinationActivityApi {
18 15
19 @Resource 16 @Resource
20 private CombinationActivityService activityService; 17 private CombinationActivityService activityService;
21 18
22 @Override 19 @Override
23 - public void validateCombination(CombinationActivityUpdateStockReqDTO reqDTO) {  
24 - activityService.validateCombination(reqDTO); 20 + public void validateCombination(Long activityId, Long userId, Long skuId, Integer count) {
  21 + activityService.validateCombination(activityId, userId, skuId, count);
25 } 22 }
26 23
27 } 24 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java
1 package cn.iocoder.yudao.module.promotion.api.combination; 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2
3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; 3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
4 -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;  
5 -import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;  
6 import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; 4 import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
7 import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; 5 import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
8 import org.springframework.stereotype.Service; 6 import org.springframework.stereotype.Service;
9 7
10 import javax.annotation.Resource; 8 import javax.annotation.Resource;
11 import java.time.LocalDateTime; 9 import java.time.LocalDateTime;
12 -import java.util.List;  
13 10
14 /** 11 /**
15 * 拼团活动 API 实现类 12 * 拼团活动 API 实现类
@@ -33,16 +30,6 @@ public class CombinationRecordApiImpl implements CombinationRecordApi { @@ -33,16 +30,6 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
33 } 30 }
34 31
35 @Override 32 @Override
36 - public List<CombinationRecordRespDTO> getRecordListByUserIdAndActivityId(Long userId, Long activityId) {  
37 - return CombinationActivityConvert.INSTANCE.convert(recordService.getRecordListByUserIdAndActivityId(userId, activityId));  
38 - }  
39 -  
40 - @Override  
41 - public void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount) {  
42 - recordService.validateCombinationLimitCount(activityId, count, sumCount);  
43 - }  
44 -  
45 - @Override  
46 public void updateRecordStatusToSuccess(Long userId, Long orderId) { 33 public void updateRecordStatusToSuccess(Long userId, Long orderId) {
47 recordService.updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordStatusEnum.SUCCESS.getStatus(), userId, orderId); 34 recordService.updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordStatusEnum.SUCCESS.getStatus(), userId, orderId);
48 } 35 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java
1 package cn.iocoder.yudao.module.promotion.api.seckill; 1 package cn.iocoder.yudao.module.promotion.api.seckill;
2 2
3 -import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;  
4 import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService; 3 import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService;
5 import org.springframework.stereotype.Service; 4 import org.springframework.stereotype.Service;
6 5
@@ -18,8 +17,8 @@ public class SeckillActivityApiImpl implements SeckillActivityApi { @@ -18,8 +17,8 @@ public class SeckillActivityApiImpl implements SeckillActivityApi {
18 private SeckillActivityService activityService; 17 private SeckillActivityService activityService;
19 18
20 @Override 19 @Override
21 - public void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO) {  
22 - activityService.updateSeckillStock(updateStockReqDTO); 20 + public void updateSeckillStock(Long activityId, Long skuId, Integer count) {
  21 + activityService.updateSeckillStock(activityId, skuId, count);
23 } 22 }
24 23
25 } 24 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainActivityController.java
@@ -3,6 +3,9 @@ package cn.iocoder.yudao.module.promotion.controller.admin.bargain; @@ -3,6 +3,9 @@ package cn.iocoder.yudao.module.promotion.controller.admin.bargain;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
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.CollectionUtils;
  7 +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
  8 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
6 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO; 9 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO;
7 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO; 10 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO;
8 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO; 11 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO;
@@ -19,6 +22,7 @@ import org.springframework.web.bind.annotation.*; @@ -19,6 +22,7 @@ import org.springframework.web.bind.annotation.*;
19 22
20 import javax.annotation.Resource; 23 import javax.annotation.Resource;
21 import javax.validation.Valid; 24 import javax.validation.Valid;
  25 +import java.util.List;
22 26
23 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 27 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
24 28
@@ -30,6 +34,8 @@ public class BargainActivityController { @@ -30,6 +34,8 @@ public class BargainActivityController {
30 34
31 @Resource 35 @Resource
32 private BargainActivityService activityService; 36 private BargainActivityService activityService;
  37 + @Resource
  38 + private ProductSpuApi spuApi;
33 39
34 @PostMapping("/create") 40 @PostMapping("/create")
35 @Operation(summary = "创建砍价活动") 41 @Operation(summary = "创建砍价活动")
@@ -73,7 +79,8 @@ public class BargainActivityController { @@ -73,7 +79,8 @@ public class BargainActivityController {
73 if (CollUtil.isEmpty(pageResult.getList())) { 79 if (CollUtil.isEmpty(pageResult.getList())) {
74 return success(PageResult.empty(pageResult.getTotal())); 80 return success(PageResult.empty(pageResult.getTotal()));
75 } 81 }
76 - return success(BargainActivityConvert.INSTANCE.convertPage(activityService.getBargainActivityPage(pageVO))); 82 + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(CollectionUtils.convertList(pageResult.getList(), BargainActivityDO::getSpuId));
  83 + return success(BargainActivityConvert.INSTANCE.convertPage(pageResult, spuList));
77 } 84 }
78 85
79 } 86 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/AppBargainActivityController.java
1 package cn.iocoder.yudao.module.promotion.controller.app.bargain; 1 package cn.iocoder.yudao.module.promotion.controller.app.bargain;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageParam; 5 import cn.iocoder.yudao.framework.common.pojo.PageParam;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 -import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; 7 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  8 +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
  9 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
7 import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityDetailRespVO; 10 import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityDetailRespVO;
8 import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityRespVO; 11 import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityRespVO;
  12 +import cn.iocoder.yudao.module.promotion.convert.bargain.BargainActivityConvert;
  13 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
  14 +import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService;
9 import io.swagger.v3.oas.annotations.Operation; 15 import io.swagger.v3.oas.annotations.Operation;
  16 +import io.swagger.v3.oas.annotations.Parameter;
10 import io.swagger.v3.oas.annotations.tags.Tag; 17 import io.swagger.v3.oas.annotations.tags.Tag;
11 import org.springframework.validation.annotation.Validated; 18 import org.springframework.validation.annotation.Validated;
12 import org.springframework.web.bind.annotation.GetMapping; 19 import org.springframework.web.bind.annotation.GetMapping;
@@ -14,8 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping; @@ -14,8 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
14 import org.springframework.web.bind.annotation.RequestParam; 21 import org.springframework.web.bind.annotation.RequestParam;
15 import org.springframework.web.bind.annotation.RestController; 22 import org.springframework.web.bind.annotation.RestController;
16 23
17 -import java.time.Duration;  
18 -import java.util.ArrayList; 24 +import javax.annotation.Resource;
19 import java.util.List; 25 import java.util.List;
20 26
21 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 27 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -25,86 +31,49 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -25,86 +31,49 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
25 @RequestMapping("/promotion/bargain-activity") 31 @RequestMapping("/promotion/bargain-activity")
26 @Validated 32 @Validated
27 public class AppBargainActivityController { 33 public class AppBargainActivityController {
  34 + @Resource
  35 + private BargainActivityService bargainActivityService;
  36 + @Resource
  37 + private ProductSpuApi spuApi;
28 38
29 @GetMapping("/page") 39 @GetMapping("/page")
30 - @Operation(summary = "获得砍价活动活动") // TODO 芋艿:只查询进行中,且在时间范围内的  
31 - // TODO 芋艿:缺少 swagger 注解 40 + @Operation(summary = "获得砍价活动分页")
32 public CommonResult<PageResult<AppBargainActivityRespVO>> getBargainActivityPage(PageParam pageReqVO) { 41 public CommonResult<PageResult<AppBargainActivityRespVO>> getBargainActivityPage(PageParam pageReqVO) {
33 - List<AppBargainActivityRespVO> activityList = new ArrayList<>();  
34 - AppBargainActivityRespVO activity1 = new AppBargainActivityRespVO();  
35 - activity1.setId(1L);  
36 - activity1.setName("618 大砍价");  
37 - activity1.setSpuId(2048L);  
38 - activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");  
39 - activity1.setMarketPrice(50);  
40 - activity1.setBargainPrice(100);  
41 - activity1.setStartTime(LocalDateTimeUtils.addTime(Duration.ofDays(-2)));  
42 - activity1.setEndTime(LocalDateTimeUtils.addTime(Duration.ofDays(1)));  
43 - activity1.setStock(10);  
44 - activityList.add(activity1); 42 + PageResult<BargainActivityDO> result = bargainActivityService.getBargainActivityAppPage(pageReqVO);
  43 + if (CollUtil.isEmpty(result.getList())) {
  44 + return success(PageResult.empty(result.getTotal()));
  45 + }
45 46
46 - AppBargainActivityRespVO activity2 = new AppBargainActivityRespVO();  
47 - activity2.setId(2L);  
48 - activity2.setName("双十一砍价");  
49 - activity2.setSpuId(4096L);  
50 - activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg");  
51 - activity2.setMarketPrice(100);  
52 - activity2.setBargainPrice(200);  
53 - activity2.setStartTime(LocalDateTimeUtils.addTime(Duration.ofDays(-2)));  
54 - activity2.setEndTime(LocalDateTimeUtils.addTime(Duration.ofDays(1)));  
55 - activity2.setStock(0);  
56 - activityList.add(activity2);  
57 -  
58 - return success(new PageResult<>(activityList, 10L)); 47 + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(CollectionUtils.convertList(result.getList(), BargainActivityDO::getSpuId));
  48 + return success(BargainActivityConvert.INSTANCE.convertAppPage(result, spuList));
59 } 49 }
60 50
61 @GetMapping("/list") 51 @GetMapping("/list")
62 @Operation(summary = "获得砍价活动列表", description = "用于小程序首页") 52 @Operation(summary = "获得砍价活动列表", description = "用于小程序首页")
63 - // TODO 芋艿:增加 Spring Cache  
64 - // TODO 芋艿:缺少 swagger 注解 53 + @Parameter(name = "count", description = "需要展示的数量", example = "6")
65 public CommonResult<List<AppBargainActivityRespVO>> getBargainActivityList( 54 public CommonResult<List<AppBargainActivityRespVO>> getBargainActivityList(
66 @RequestParam(name = "count", defaultValue = "6") Integer count) { 55 @RequestParam(name = "count", defaultValue = "6") Integer count) {
67 - List<AppBargainActivityRespVO> activityList = new ArrayList<>();  
68 - AppBargainActivityRespVO activity1 = new AppBargainActivityRespVO();  
69 - activity1.setId(1L);  
70 - activity1.setName("618 大砍价");  
71 - activity1.setSpuId(2048L);  
72 - activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");  
73 - activity1.setMarketPrice(50);  
74 - activity1.setBargainPrice(100);  
75 - activityList.add(activity1);  
76 -  
77 - AppBargainActivityRespVO activity2 = new AppBargainActivityRespVO();  
78 - activity2.setId(2L);  
79 - activity2.setName("双十一砍价");  
80 - activity2.setSpuId(4096L);  
81 - activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg");  
82 - activity2.setMarketPrice(100);  
83 - activity2.setBargainPrice(200);  
84 - activityList.add(activity2); 56 + List<BargainActivityDO> list = bargainActivityService.getBargainActivityAppList(count);
  57 + if (CollUtil.isEmpty(list)) {
  58 + return success(BargainActivityConvert.INSTANCE.convertAppList(list));
  59 + }
85 60
86 - return success(activityList); 61 + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(CollectionUtils.convertList(list, BargainActivityDO::getSpuId));
  62 + // TODO 芋艿:增加 Spring Cache
  63 + return success(BargainActivityConvert.INSTANCE.convertAppList(list, spuList));
87 } 64 }
88 65
89 @GetMapping("/get-detail") 66 @GetMapping("/get-detail")
90 @Operation(summary = "获得砍价活动详情") 67 @Operation(summary = "获得砍价活动详情")
91 - // TODO 芋艿:缺少 swagger 注解 68 + @Parameter(name = "id", description = "活动编号", example = "1")
92 public CommonResult<AppBargainActivityDetailRespVO> getBargainActivityDetail(@RequestParam("id") Long id) { 69 public CommonResult<AppBargainActivityDetailRespVO> getBargainActivityDetail(@RequestParam("id") Long id) {
93 - AppBargainActivityDetailRespVO activity = new AppBargainActivityDetailRespVO();  
94 - activity.setId(2L);  
95 - activity.setName("618 大砍价");  
96 - activity.setSpuId(2048L);  
97 - activity.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");  
98 - activity.setMarketPrice(50);  
99 - activity.setBargainPrice(100);  
100 - activity.setStock(10);  
101 - activity.setUnitName("件");  
102 - activity.setPrice(40);  
103 - activity.setStartTime(LocalDateTimeUtils.addTime(Duration.ofDays(-2)));  
104 - activity.setEndTime(LocalDateTimeUtils.addTime(Duration.ofDays(-10)));  
105 - activity.setDescription("我吃西红柿");  
106 - activity.setSuccessCount(10);  
107 - return success(activity); 70 + BargainActivityDO activity = bargainActivityService.getBargainActivity(id);
  71 + if (activity == null) {
  72 + return success(null);
  73 + }
  74 +
  75 + ProductSpuRespDTO spu = spuApi.getSpu(activity.getSpuId());
  76 + return success(BargainActivityConvert.INSTANCE.convert1(activity, spu));
108 } 77 }
109 78
110 } 79 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/vo/activity/AppBargainActivityDetailRespVO.java
@@ -45,7 +45,7 @@ public class AppBargainActivityDetailRespVO { @@ -45,7 +45,7 @@ public class AppBargainActivityDetailRespVO {
45 @Schema(description = "商品单位", required = true, example = "个") // 从 SPU 的 unit 读取,然后转换 45 @Schema(description = "商品单位", required = true, example = "个") // 从 SPU 的 unit 读取,然后转换
46 private String unitName; 46 private String unitName;
47 47
48 - @Schema(description = "砍价最低金额,单位:分", required = true, example = "100") // 从砍价商品里取最低价 48 + @Schema(description = "砍价最低金额,单位:分", required = true, example = "100")
49 private Integer bargainPrice; 49 private Integer bargainPrice;
50 50
51 @Schema(description = "砍价成功数量", required = true, example = "100") 51 @Schema(description = "砍价成功数量", required = true, example = "100")
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/vo/activity/AppBargainActivityRespVO.java
@@ -36,7 +36,7 @@ public class AppBargainActivityRespVO { @@ -36,7 +36,7 @@ public class AppBargainActivityRespVO {
36 @Schema(description = "商品市场价,单位:分", required = true, example = "50") // 从 SPU 的 marketPrice 读取 36 @Schema(description = "商品市场价,单位:分", required = true, example = "50") // 从 SPU 的 marketPrice 读取
37 private Integer marketPrice; 37 private Integer marketPrice;
38 38
39 - @Schema(description = "砍价最低金额,单位:分", required = true, example = "100") // 从砍价商品里取最低价 39 + @Schema(description = "砍价最低金额,单位:分", required = true, example = "100")
40 private Integer bargainPrice; 40 private Integer bargainPrice;
41 41
42 } 42 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java
1 package cn.iocoder.yudao.module.promotion.controller.app.seckill; 1 package cn.iocoder.yudao.module.promotion.controller.app.seckill;
2 2
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 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.product.api.spu.ProductSpuApi;
  9 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
5 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO; 10 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO;
6 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO; 11 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO;
7 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO; 12 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
8 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO; 13 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO;
9 -import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO; 14 +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
  15 +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
  16 +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
  17 +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
  18 +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService;
  19 +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService;
10 import io.swagger.v3.oas.annotations.Operation; 20 import io.swagger.v3.oas.annotations.Operation;
11 import io.swagger.v3.oas.annotations.Parameter; 21 import io.swagger.v3.oas.annotations.Parameter;
12 import io.swagger.v3.oas.annotations.tags.Tag; 22 import io.swagger.v3.oas.annotations.tags.Tag;
  23 +import org.springframework.context.annotation.Lazy;
13 import org.springframework.validation.annotation.Validated; 24 import org.springframework.validation.annotation.Validated;
14 import org.springframework.web.bind.annotation.GetMapping; 25 import org.springframework.web.bind.annotation.GetMapping;
15 import org.springframework.web.bind.annotation.RequestMapping; 26 import org.springframework.web.bind.annotation.RequestMapping;
16 import org.springframework.web.bind.annotation.RequestParam; 27 import org.springframework.web.bind.annotation.RequestParam;
17 import org.springframework.web.bind.annotation.RestController; 28 import org.springframework.web.bind.annotation.RestController;
18 29
19 -import java.time.LocalDateTime;  
20 -import java.util.ArrayList; 30 +import javax.annotation.Resource;
  31 +import java.util.Arrays;
21 import java.util.List; 32 import java.util.List;
22 33
  34 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
23 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 35 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  36 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
  37 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.findFirst;
  38 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.isBetween;
  39 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_ACTIVITY_FAIL_STATUS_CLOSED;
24 40
25 @Tag(name = "用户 App - 秒杀活动") 41 @Tag(name = "用户 App - 秒杀活动")
26 @RestController 42 @RestController
27 @RequestMapping("/promotion/seckill-activity") 43 @RequestMapping("/promotion/seckill-activity")
28 @Validated 44 @Validated
29 public class AppSeckillActivityController { 45 public class AppSeckillActivityController {
  46 + @Resource
  47 + private SeckillActivityService activityService;
  48 + @Resource
  49 + @Lazy
  50 + private SeckillConfigService configService;
  51 +
  52 + @Resource
  53 + private ProductSpuApi spuApi;
30 54
31 @GetMapping("/get-now") 55 @GetMapping("/get-now")
32 @Operation(summary = "获得当前秒杀活动") // 提供给首页使用 56 @Operation(summary = "获得当前秒杀活动") // 提供给首页使用
33 // TODO 芋艿:需要增加 spring cache 57 // TODO 芋艿:需要增加 spring cache
34 public CommonResult<AppSeckillActivityNowRespVO> getNowSeckillActivity() { 58 public CommonResult<AppSeckillActivityNowRespVO> getNowSeckillActivity() {
35 - AppSeckillActivityNowRespVO respVO = new AppSeckillActivityNowRespVO();  
36 - respVO.setConfig(new AppSeckillConfigRespVO().setId(10L).setStartTime("01:00").setEndTime("09:59"));  
37 - List<AppSeckillActivityRespVO> activityList = new ArrayList<>();  
38 - AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO();  
39 - activity1.setId(1L);  
40 - activity1.setName("618 大秒杀");  
41 - activity1.setSpuId(2048L);  
42 - activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");  
43 - activity1.setMarketPrice(50);  
44 - activity1.setSeckillPrice(100);  
45 - activityList.add(activity1); 59 + // 1、获取当前时间处在哪个秒杀阶段
  60 + List<SeckillConfigDO> configList = configService.getSeckillConfigList();
  61 + SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(),
  62 + CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime()));
  63 + // 1、1 时段不存在直接返回 null
  64 + if (filteredConfig == null) {
  65 + return success(null);
  66 + }
46 67
47 - AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO();  
48 - activity2.setId(2L);  
49 - activity2.setName("双十一大秒杀");  
50 - activity2.setSpuId(4096L);  
51 - activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg");  
52 - activity2.setMarketPrice(100);  
53 - activity2.setSeckillPrice(200);  
54 - activityList.add(activity2);  
55 - respVO.setActivities(activityList);  
56 - return success(respVO); 68 + // 2、查询满足当前阶段的活动
  69 + List<SeckillActivityDO> activityList = activityService.getSeckillActivityListByConfigIds(Arrays.asList(filteredConfig.getId()));
  70 + List<SeckillActivityDO> filteredList = filterList(activityList, item -> ObjectUtil.equal(item.getStatus(), CommonStatusEnum.ENABLE.getStatus()));
  71 + // 2、1 获取 spu 信息
  72 + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(CollectionUtils.convertList(filteredList, SeckillActivityDO::getSpuId));
  73 + return success(SeckillActivityConvert.INSTANCE.convert(filteredConfig, filteredList, spuList));
57 } 74 }
58 75
59 @GetMapping("/page") 76 @GetMapping("/page")
60 @Operation(summary = "获得秒杀活动分页") 77 @Operation(summary = "获得秒杀活动分页")
61 - // TODO @芋艿:分页参数  
62 public CommonResult<PageResult<AppSeckillActivityRespVO>> getSeckillActivityPage(AppSeckillActivityPageReqVO pageReqVO) { 78 public CommonResult<PageResult<AppSeckillActivityRespVO>> getSeckillActivityPage(AppSeckillActivityPageReqVO pageReqVO) {
63 - List<AppSeckillActivityRespVO> activityList = new ArrayList<>();  
64 - AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO();  
65 - activity1.setId(1L);  
66 - activity1.setName("618 大秒杀");  
67 - activity1.setSpuId(2048L);  
68 - activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");  
69 - activity1.setMarketPrice(50);  
70 - activity1.setSeckillPrice(100);  
71 - activity1.setUnitName("个");  
72 - activity1.setStock(1);  
73 - activity1.setTotalStock(2);  
74 - activityList.add(activity1);  
75 -  
76 - AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO();  
77 - activity2.setId(2L);  
78 - activity2.setName("双十一大秒杀");  
79 - activity2.setSpuId(4096L);  
80 - activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg");  
81 - activity2.setMarketPrice(100);  
82 - activity2.setSeckillPrice(200);  
83 - activity2.setUnitName("套");  
84 - activity2.setStock(2);  
85 - activity2.setTotalStock(3);  
86 - activityList.add(activity2);  
87 - return success(new PageResult<>(activityList, 100L)); 79 + // 1、查询满足当前阶段的活动
  80 + PageResult<SeckillActivityDO> pageResult = activityService.getSeckillActivityAppPageByConfigId(pageReqVO);
  81 + // 1、1 获取 spu 信息
  82 + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(CollectionUtils.convertList(pageResult.getList(), SeckillActivityDO::getSpuId));
  83 + return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult, spuList));
88 } 84 }
89 85
90 @GetMapping("/get-detail") 86 @GetMapping("/get-detail")
91 @Operation(summary = "获得秒杀活动明细") 87 @Operation(summary = "获得秒杀活动明细")
92 @Parameter(name = "id", description = "活动编号", required = true, example = "1024") 88 @Parameter(name = "id", description = "活动编号", required = true, example = "1024")
93 public CommonResult<AppSeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) { 89 public CommonResult<AppSeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) {
  90 + // 1、获取当前时间处在哪个秒杀阶段
  91 + List<SeckillConfigDO> configList = configService.getSeckillConfigList();
  92 + SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(),
  93 + CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime()));
  94 + // 1、1 时段不存在直接返回 null
  95 + if (filteredConfig == null) {
  96 + return success(null);
  97 + }
  98 +
  99 + // 2、获取活动
  100 + SeckillActivityDO seckillActivity = activityService.getSeckillActivity(id);
  101 + if (seckillActivity == null) {
  102 + return success(null);
  103 + }
94 // TODO 芋艿:如果禁用的时候,需要抛出异常; 104 // TODO 芋艿:如果禁用的时候,需要抛出异常;
95 - AppSeckillActivityDetailRespVO obj = new AppSeckillActivityDetailRespVO();  
96 - // 设置其属性的值  
97 - obj.setId(id);  
98 - obj.setName("晚九点限时秒杀");  
99 - obj.setStatus(1);  
100 - obj.setStartTime(LocalDateTime.of(2023, 6, 16, 0, 0, 0));  
101 - obj.setEndTime(LocalDateTime.of(2023, 6, 20, 23, 59, 0));  
102 - obj.setSpuId(633L);  
103 - obj.setSingleLimitCount(2);  
104 - obj.setTotalLimitCount(3);  
105 - obj.setStock(100);  
106 - obj.setTotalStock(200); 105 + if (ObjectUtil.equal(seckillActivity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
  106 + throw exception(SECKILL_ACTIVITY_FAIL_STATUS_CLOSED);
  107 + }
107 108
108 - // 创建一个Product对象的列表  
109 - List<AppSeckillActivityDetailRespVO.Product> productList = new ArrayList<>();  
110 - // 创建三个新的Product对象并设置其属性的值  
111 - AppSeckillActivityDetailRespVO.Product product1 = new AppSeckillActivityDetailRespVO.Product();  
112 - product1.setSkuId(1L);  
113 - product1.setSeckillPrice(100);  
114 - product1.setStock(50);  
115 - // 将第一个Product对象添加到列表中  
116 - productList.add(product1);  
117 - // 创建第二个Product对象并设置其属性的值  
118 - AppSeckillActivityDetailRespVO.Product product2 = new AppSeckillActivityDetailRespVO.Product();  
119 - product2.setSkuId(2L);  
120 - product2.setSeckillPrice(200);  
121 - product2.setStock(100);  
122 - // 将第二个Product对象添加到列表中  
123 - productList.add(product2);  
124 - // 创建第三个Product对象并设置其属性的值  
125 - AppSeckillActivityDetailRespVO.Product product3 = new AppSeckillActivityDetailRespVO.Product();  
126 - product3.setSkuId(3L);  
127 - product3.setSeckillPrice(300);  
128 - product3.setStock(150);  
129 - // 将第三个Product对象添加到列表中  
130 - productList.add(product3);  
131 - // 将Product列表设置为对象的属性值  
132 - obj.setProducts(productList);  
133 - return success(obj); 109 + // 3、获取活动商品
  110 + List<SeckillProductDO> products = activityService.getSeckillProductListByActivityId(seckillActivity.getId());
  111 + return success(SeckillActivityConvert.INSTANCE.convert3(seckillActivity, products, filteredConfig));
134 } 112 }
135 113
136 } 114 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillConfigController.java
1 package cn.iocoder.yudao.module.promotion.controller.app.seckill; 1 package cn.iocoder.yudao.module.promotion.controller.app.seckill;
2 2
  3 +import cn.hutool.core.collection.CollectionUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO; 6 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
  7 +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert;
  8 +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
  9 +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService;
5 import io.swagger.v3.oas.annotations.Operation; 10 import io.swagger.v3.oas.annotations.Operation;
6 import io.swagger.v3.oas.annotations.tags.Tag; 11 import io.swagger.v3.oas.annotations.tags.Tag;
7 import org.springframework.validation.annotation.Validated; 12 import org.springframework.validation.annotation.Validated;
@@ -9,7 +14,8 @@ import org.springframework.web.bind.annotation.GetMapping; @@ -9,7 +14,8 @@ import org.springframework.web.bind.annotation.GetMapping;
9 import org.springframework.web.bind.annotation.RequestMapping; 14 import org.springframework.web.bind.annotation.RequestMapping;
10 import org.springframework.web.bind.annotation.RestController; 15 import org.springframework.web.bind.annotation.RestController;
11 16
12 -import java.util.Arrays; 17 +import javax.annotation.Resource;
  18 +import java.util.Collections;
13 import java.util.List; 19 import java.util.List;
14 20
15 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 21 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -19,18 +25,26 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -19,18 +25,26 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
19 @RequestMapping("/promotion/seckill-config") 25 @RequestMapping("/promotion/seckill-config")
20 @Validated 26 @Validated
21 public class AppSeckillConfigController { 27 public class AppSeckillConfigController {
  28 + @Resource
  29 + private SeckillConfigService configService;
22 30
23 @GetMapping("/list") 31 @GetMapping("/list")
24 @Operation(summary = "获得秒杀时间段列表") 32 @Operation(summary = "获得秒杀时间段列表")
25 public CommonResult<List<AppSeckillConfigRespVO>> getSeckillConfigList() { 33 public CommonResult<List<AppSeckillConfigRespVO>> getSeckillConfigList() {
26 - return success(Arrays.asList(  
27 - new AppSeckillConfigRespVO().setId(1L).setStartTime("00:00").setEndTime("09:59")  
28 - .setSliderPicUrls(Arrays.asList("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg",  
29 - "https://static.iocoder.cn/mall/132.jpeg")),  
30 - new AppSeckillConfigRespVO().setId(2L).setStartTime("10:00").setEndTime("12:59"),  
31 - new AppSeckillConfigRespVO().setId(2L).setStartTime("13:00").setEndTime("22:59"),  
32 - new AppSeckillConfigRespVO().setId(2L).setStartTime("23:00").setEndTime("23:59")  
33 - )); 34 + List<SeckillConfigDO> list = configService.getSeckillConfigListByStatus(CommonStatusEnum.ENABLE.getStatus());
  35 + if (CollectionUtil.isEmpty(list)) {
  36 + return success(Collections.emptyList());
  37 + }
  38 +
  39 + return success(SeckillConfigConvert.INSTANCE.convertList2(list));
  40 + //return success(Arrays.asList(
  41 + // new AppSeckillConfigRespVO().setId(1L).setStartTime("00:00").setEndTime("09:59")
  42 + // .setSliderPicUrls(Arrays.asList("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg",
  43 + // "https://static.iocoder.cn/mall/132.jpeg")),
  44 + // new AppSeckillConfigRespVO().setId(2L).setStartTime("10:00").setEndTime("12:59"),
  45 + // new AppSeckillConfigRespVO().setId(2L).setStartTime("13:00").setEndTime("22:59"),
  46 + // new AppSeckillConfigRespVO().setId(2L).setStartTime("23:00").setEndTime("23:59")
  47 + //));
34 } 48 }
35 49
36 } 50 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityDetailRespVO.java
@@ -19,7 +19,7 @@ public class AppSeckillActivityDetailRespVO { @@ -19,7 +19,7 @@ public class AppSeckillActivityDetailRespVO {
19 @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 19 @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
20 private Integer status; 20 private Integer status;
21 21
22 - // TODO @芋艿:开始时间、结束时间,要和场次结合起来;就是要算到当前场次,是几点哈; 22 + // TODO @芋艿:开始时间、结束时间,要和场次结合起来;就是要算到当前场次,是几点哈;
23 23
24 @Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED) 24 @Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
25 private LocalDateTime startTime; 25 private LocalDateTime startTime;
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityRespVO.java
@@ -31,7 +31,6 @@ public class AppSeckillActivityRespVO { @@ -31,7 +31,6 @@ public class AppSeckillActivityRespVO {
31 private Integer totalStock; 31 private Integer totalStock;
32 32
33 @Schema(description = "秒杀金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") 33 @Schema(description = "秒杀金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
34 - // 从秒杀商品里取最低价  
35 private Integer seckillPrice; 34 private Integer seckillPrice;
36 35
37 } 36 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/bargain/BargainActivityConvert.java
1 package cn.iocoder.yudao.module.promotion.convert.bargain; 1 package cn.iocoder.yudao.module.promotion.convert.bargain;
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.dict.core.util.DictFrameworkUtils;
  6 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  7 +import cn.iocoder.yudao.module.product.enums.DictTypeConstants;
4 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityBaseVO; 8 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityBaseVO;
5 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO; 9 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO;
6 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO; 10 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO;
  11 +import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityDetailRespVO;
  12 +import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityRespVO;
7 import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO; 13 import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
8 import org.mapstruct.Mapper; 14 import org.mapstruct.Mapper;
9 import org.mapstruct.factory.Mappers; 15 import org.mapstruct.factory.Mappers;
10 16
11 import java.util.List; 17 import java.util.List;
  18 +import java.util.Map;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  21 +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
12 22
13 /** 23 /**
14 * 拼团活动 Convert 24 * 拼团活动 Convert
@@ -30,4 +40,60 @@ public interface BargainActivityConvert { @@ -30,4 +40,60 @@ public interface BargainActivityConvert {
30 40
31 PageResult<BargainActivityRespVO> convertPage(PageResult<BargainActivityDO> page); 41 PageResult<BargainActivityRespVO> convertPage(PageResult<BargainActivityDO> page);
32 42
  43 + default PageResult<BargainActivityRespVO> convertPage(PageResult<BargainActivityDO> page, List<ProductSpuRespDTO> spuList) {
  44 + PageResult<BargainActivityRespVO> result = convertPage(page);
  45 + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
  46 + List<BargainActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> {
  47 + findAndThen(spuMap, item.getSpuId(), spu -> {
  48 + item.setPicUrl(spu.getPicUrl());
  49 + item.setSpuName(spu.getName());
  50 + });
  51 + return item;
  52 + });
  53 + result.setList(list);
  54 + return result;
  55 + }
  56 +
  57 + AppBargainActivityDetailRespVO convert1(BargainActivityDO bean);
  58 +
  59 + default AppBargainActivityDetailRespVO convert1(BargainActivityDO bean, ProductSpuRespDTO spu) {
  60 + AppBargainActivityDetailRespVO detail = convert1(bean);
  61 + if (spu != null) {
  62 + detail.setPicUrl(spu.getPicUrl());
  63 + detail.setMarketPrice(spu.getMarketPrice());
  64 + detail.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit()));
  65 + }
  66 + return detail;
  67 + }
  68 +
  69 + PageResult<AppBargainActivityRespVO> convertAppPage(PageResult<BargainActivityDO> page);
  70 +
  71 + default PageResult<AppBargainActivityRespVO> convertAppPage(PageResult<BargainActivityDO> page, List<ProductSpuRespDTO> spuList) {
  72 + PageResult<AppBargainActivityRespVO> result = convertAppPage(page);
  73 + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
  74 + List<AppBargainActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> {
  75 + findAndThen(spuMap, item.getSpuId(), spu -> {
  76 + item.setPicUrl(spu.getPicUrl());
  77 + item.setMarketPrice(spu.getMarketPrice());
  78 + });
  79 + return item;
  80 + });
  81 + result.setList(list);
  82 + return result;
  83 + }
  84 +
  85 + List<AppBargainActivityRespVO> convertAppList(List<BargainActivityDO> list);
  86 +
  87 + default List<AppBargainActivityRespVO> convertAppList(List<BargainActivityDO> list, List<ProductSpuRespDTO> spuList) {
  88 + List<AppBargainActivityRespVO> activityList = convertAppList(list);
  89 + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
  90 + return CollectionUtils.convertList(activityList, item -> {
  91 + findAndThen(spuMap, item.getSpuId(), spu -> {
  92 + item.setPicUrl(spu.getPicUrl());
  93 + item.setMarketPrice(spu.getMarketPrice());
  94 + });
  95 + return item;
  96 + });
  97 + }
  98 +
33 } 99 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.promotion.convert.combination; @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.promotion.convert.combination;
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; 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  6 +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
  7 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
6 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; 8 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
7 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; 9 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
8 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; 10 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
@@ -92,6 +94,19 @@ public interface CombinationActivityConvert { @@ -92,6 +94,19 @@ public interface CombinationActivityConvert {
92 94
93 CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO); 95 CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO);
94 96
  97 + default CombinationRecordDO convert1(CombinationRecordCreateReqDTO reqDTO, CombinationActivityDO activity, MemberUserRespDTO user,
  98 + ProductSpuRespDTO spu, ProductSkuRespDTO sku) {
  99 + CombinationRecordDO record = convert(reqDTO);
  100 + record.setVirtualGroup(false);
  101 + record.setExpireTime(record.getStartTime().plusHours(activity.getLimitDuration()));
  102 + record.setUserSize(activity.getUserSize());
  103 + record.setNickname(user.getNickname());
  104 + record.setAvatar(user.getAvatar());
  105 + record.setSpuName(spu.getName());
  106 + record.setPicUrl(sku.getPicUrl());
  107 + return record;
  108 + }
  109 +
95 List<CombinationRecordRespDTO> convert(List<CombinationRecordDO> bean); 110 List<CombinationRecordRespDTO> convert(List<CombinationRecordDO> bean);
96 111
97 } 112 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java
@@ -3,15 +3,22 @@ package cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity; @@ -3,15 +3,22 @@ package cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity;
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; 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  6 +import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
6 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; 7 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  8 +import cn.iocoder.yudao.module.product.enums.DictTypeConstants;
7 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; 9 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
8 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityDetailRespVO; 10 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityDetailRespVO;
9 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO; 11 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO;
10 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; 12 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
11 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO; 13 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
12 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO; 14 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO;
  15 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO;
  16 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO;
  17 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO;
  18 +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert;
13 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; 19 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
14 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; 20 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
  21 +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
15 import org.mapstruct.Mapper; 22 import org.mapstruct.Mapper;
16 import org.mapstruct.Mapping; 23 import org.mapstruct.Mapping;
17 import org.mapstruct.Mappings; 24 import org.mapstruct.Mappings;
@@ -20,6 +27,10 @@ import org.mapstruct.factory.Mappers; @@ -20,6 +27,10 @@ import org.mapstruct.factory.Mappers;
20 import java.util.List; 27 import java.util.List;
21 import java.util.Map; 28 import java.util.Map;
22 29
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
  32 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
  33 +
23 /** 34 /**
24 * 秒杀活动 Convert 35 * 秒杀活动 Convert
25 * 36 *
@@ -79,4 +90,50 @@ public interface SeckillActivityConvert { @@ -79,4 +90,50 @@ public interface SeckillActivityConvert {
79 90
80 List<SeckillProductRespVO> convertList2(List<SeckillProductDO> list); 91 List<SeckillProductRespVO> convertList2(List<SeckillProductDO> list);
81 92
  93 + List<AppSeckillActivityRespVO> convertList3(List<SeckillActivityDO> activityList);
  94 +
  95 + default AppSeckillActivityNowRespVO convert(SeckillConfigDO filteredConfig, List<SeckillActivityDO> activityList, List<ProductSpuRespDTO> spuList) {
  96 + AppSeckillActivityNowRespVO respVO = new AppSeckillActivityNowRespVO();
  97 + respVO.setConfig(SeckillConfigConvert.INSTANCE.convert1(filteredConfig));
  98 + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
  99 + respVO.setActivities(CollectionUtils.convertList(convertList3(activityList), item -> {
  100 + findAndThen(spuMap, item.getSpuId(), spu -> {
  101 + item.setPicUrl(spu.getPicUrl());
  102 + item.setMarketPrice(spu.getMarketPrice());
  103 + item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit()));
  104 + });
  105 + return item;
  106 + }));
  107 + return respVO;
  108 + }
  109 +
  110 + PageResult<AppSeckillActivityRespVO> convertPage1(PageResult<SeckillActivityDO> pageResult);
  111 +
  112 + default PageResult<AppSeckillActivityRespVO> convertPage(PageResult<SeckillActivityDO> pageResult, List<ProductSpuRespDTO> spuList) {
  113 + PageResult<AppSeckillActivityRespVO> result = convertPage1(pageResult);
  114 + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
  115 + List<AppSeckillActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> {
  116 + findAndThen(spuMap, item.getSpuId(), spu -> {
  117 + item.setPicUrl(spu.getPicUrl());
  118 + item.setMarketPrice(spu.getMarketPrice());
  119 + item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit()));
  120 + });
  121 + return item;
  122 + });
  123 + result.setList(list);
  124 + return result;
  125 + }
  126 +
  127 + AppSeckillActivityDetailRespVO convert2(SeckillActivityDO seckillActivity);
  128 +
  129 + List<AppSeckillActivityDetailRespVO.Product> convertList1(List<SeckillProductDO> products);
  130 +
  131 + default AppSeckillActivityDetailRespVO convert3(SeckillActivityDO seckillActivity, List<SeckillProductDO> products, SeckillConfigDO filteredConfig) {
  132 + AppSeckillActivityDetailRespVO respVO = convert2(seckillActivity);
  133 + respVO.setProducts(convertList1(products));
  134 + respVO.setStartTime(buildTime(filteredConfig.getStartTime()));
  135 + respVO.setEndTime(buildTime(filteredConfig.getEndTime()));
  136 + return respVO;
  137 + }
  138 +
82 } 139 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillconfig/SeckillConfigConvert.java
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.Seck @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.Seck
5 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigRespVO; 5 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigRespVO;
6 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigSimpleRespVO; 6 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigSimpleRespVO;
7 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO; 7 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
  8 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
8 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; 9 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
9 import org.mapstruct.Mapper; 10 import org.mapstruct.Mapper;
10 import org.mapstruct.factory.Mappers; 11 import org.mapstruct.factory.Mappers;
@@ -33,4 +34,7 @@ public interface SeckillConfigConvert { @@ -33,4 +34,7 @@ public interface SeckillConfigConvert {
33 34
34 PageResult<SeckillConfigRespVO> convertPage(PageResult<SeckillConfigDO> page); 35 PageResult<SeckillConfigRespVO> convertPage(PageResult<SeckillConfigDO> page);
35 36
  37 + List<AppSeckillConfigRespVO> convertList2(List<SeckillConfigDO> list);
  38 +
  39 + AppSeckillConfigRespVO convert1(SeckillConfigDO filteredConfig);
36 } 40 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java
@@ -87,7 +87,7 @@ public class SeckillActivityDO extends BaseDO { @@ -87,7 +87,7 @@ public class SeckillActivityDO extends BaseDO {
87 */ 87 */
88 private Integer singleLimitCount; 88 private Integer singleLimitCount;
89 /** 89 /**
90 - * 秒杀库存 90 + * 秒杀库存(剩余库存秒杀时扣减)
91 */ 91 */
92 private Integer stock; 92 private Integer stock;
93 /** 93 /**
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java
1 package cn.iocoder.yudao.module.promotion.dal.mysql.bargain; 1 package cn.iocoder.yudao.module.promotion.dal.mysql.bargain;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
@@ -8,6 +9,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityD @@ -8,6 +9,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityD
8 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 9 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
9 import org.apache.ibatis.annotations.Mapper; 10 import org.apache.ibatis.annotations.Mapper;
10 11
  12 +import java.time.LocalDateTime;
11 import java.util.List; 13 import java.util.List;
12 14
13 /** 15 /**
@@ -39,8 +41,15 @@ public interface BargainActivityMapper extends BaseMapperX&lt;BargainActivityDO&gt; { @@ -39,8 +41,15 @@ public interface BargainActivityMapper extends BaseMapperX&lt;BargainActivityDO&gt; {
39 default int updateActivityStock(Long id, int count) { 41 default int updateActivityStock(Long id, int count) {
40 return update(null, new LambdaUpdateWrapper<BargainActivityDO>() 42 return update(null, new LambdaUpdateWrapper<BargainActivityDO>()
41 .eq(BargainActivityDO::getId, id) 43 .eq(BargainActivityDO::getId, id)
42 - .gt(BargainActivityDO::getStock, 0) // TODO @puhui999:不是 > 0,是要大于 count 哈 44 + .gt(BargainActivityDO::getStock, count)
43 .setSql("stock = stock - " + count)); 45 .setSql("stock = stock - " + count));
44 } 46 }
45 47
  48 + default PageResult<BargainActivityDO> selectAppPage(PageParam pageReqVO, Integer status, LocalDateTime now) {
  49 + return selectPage(pageReqVO, new LambdaQueryWrapperX<BargainActivityDO>()
  50 + .eq(BargainActivityDO::getStatus, status)
  51 + .le(BargainActivityDO::getStartTime, now)
  52 + .ge(BargainActivityDO::getEndTime, now));
  53 + }
  54 +
46 } 55 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
7 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; 7 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
  8 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
8 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; 9 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
9 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 10 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
10 import org.apache.ibatis.annotations.Mapper; 11 import org.apache.ibatis.annotations.Mapper;
@@ -24,7 +25,7 @@ public interface SeckillActivityMapper extends BaseMapperX&lt;SeckillActivityDO&gt; { @@ -24,7 +25,7 @@ public interface SeckillActivityMapper extends BaseMapperX&lt;SeckillActivityDO&gt; {
24 .likeIfPresent(SeckillActivityDO::getName, reqVO.getName()) 25 .likeIfPresent(SeckillActivityDO::getName, reqVO.getName())
25 .eqIfPresent(SeckillActivityDO::getStatus, reqVO.getStatus()) 26 .eqIfPresent(SeckillActivityDO::getStatus, reqVO.getStatus())
26 .betweenIfPresent(SeckillActivityDO::getCreateTime, reqVO.getCreateTime()) 27 .betweenIfPresent(SeckillActivityDO::getCreateTime, reqVO.getCreateTime())
27 - .apply(ObjectUtil.isNotNull(reqVO.getConfigId()), "FIND_IN_SET(" + reqVO.getConfigId() + ",time_ids) > 0") 28 + .apply(ObjectUtil.isNotNull(reqVO.getConfigId()), "FIND_IN_SET(" + reqVO.getConfigId() + ", config_ids) > 0")
28 .orderByDesc(SeckillActivityDO::getId)); 29 .orderByDesc(SeckillActivityDO::getId));
29 } 30 }
30 31
@@ -48,4 +49,10 @@ public interface SeckillActivityMapper extends BaseMapperX&lt;SeckillActivityDO&gt; { @@ -48,4 +49,10 @@ public interface SeckillActivityMapper extends BaseMapperX&lt;SeckillActivityDO&gt; {
48 .setSql("totalStock = totalStock - " + count)); 49 .setSql("totalStock = totalStock - " + count));
49 } 50 }
50 51
  52 + default PageResult<SeckillActivityDO> selectPage(AppSeckillActivityPageReqVO pageReqVO, Integer status) {
  53 + return selectPage(pageReqVO, new LambdaQueryWrapperX<SeckillActivityDO>()
  54 + .eqIfPresent(SeckillActivityDO::getStatus, status)
  55 + .apply(ObjectUtil.isNotNull(pageReqVO.getConfigId()), "FIND_IN_SET(" + pageReqVO.getConfigId() + ",config_ids) > 0"));
  56 + }
  57 +
51 } 58 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java
@@ -34,7 +34,7 @@ public interface SeckillProductMapper extends BaseMapperX&lt;SeckillProductDO&gt; { @@ -34,7 +34,7 @@ public interface SeckillProductMapper extends BaseMapperX&lt;SeckillProductDO&gt; {
34 default int updateActivityStock(Long id, int count) { 34 default int updateActivityStock(Long id, int count) {
35 return update(null, new LambdaUpdateWrapper<SeckillProductDO>() 35 return update(null, new LambdaUpdateWrapper<SeckillProductDO>()
36 .eq(SeckillProductDO::getId, id) 36 .eq(SeckillProductDO::getId, id)
37 - .gt(SeckillProductDO::getStock, 0) // TODO @puhui999:不是 > 0,是要大于 count 哈 37 + .gt(SeckillProductDO::getStock, count)
38 .setSql("stock = stock - " + count)); 38 .setSql("stock = stock - " + count));
39 } 39 }
40 40
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java
1 package cn.iocoder.yudao.module.promotion.service.bargain; 1 package cn.iocoder.yudao.module.promotion.service.bargain;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO; 5 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO;
5 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO; 6 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO;
@@ -7,6 +8,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActi @@ -7,6 +8,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActi
7 import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO; 8 import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
8 9
9 import javax.validation.Valid; 10 import javax.validation.Valid;
  11 +import java.util.List;
10 12
11 /** 13 /**
12 * 砍价活动 Service 接口 14 * 砍价活动 Service 接口
@@ -61,4 +63,19 @@ public interface BargainActivityService { @@ -61,4 +63,19 @@ public interface BargainActivityService {
61 */ 63 */
62 PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO); 64 PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO);
63 65
  66 + /**
  67 + * 获取 APP 端活动分页数据
  68 + *
  69 + * @param pageReqVO 分页请求
  70 + * @return 砍价活动分页
  71 + */
  72 + PageResult<BargainActivityDO> getBargainActivityAppPage(PageParam pageReqVO);
  73 +
  74 + /**
  75 + * 获取 APP 端活动展示数据
  76 + *
  77 + * @param count 需要的数量
  78 + * @return
  79 + */
  80 + List<BargainActivityDO> getBargainActivityAppList(Integer count);
64 } 81 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.service.bargain; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.service.bargain;
2 2
3 import cn.hutool.core.util.ObjectUtil; 3 import cn.hutool.core.util.ObjectUtil;
4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; 7 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
7 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; 8 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
@@ -16,6 +17,7 @@ import org.springframework.transaction.annotation.Transactional; @@ -16,6 +17,7 @@ import org.springframework.transaction.annotation.Transactional;
16 import org.springframework.validation.annotation.Validated; 17 import org.springframework.validation.annotation.Validated;
17 18
18 import javax.annotation.Resource; 19 import javax.annotation.Resource;
  20 +import java.time.LocalDateTime;
19 import java.util.List; 21 import java.util.List;
20 22
21 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 23 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -113,9 +115,9 @@ public class BargainActivityServiceImpl implements BargainActivityService { @@ -113,9 +115,9 @@ public class BargainActivityServiceImpl implements BargainActivityService {
113 // 校验存在 115 // 校验存在
114 BargainActivityDO activityDO = validateBargainActivityExists(id); 116 BargainActivityDO activityDO = validateBargainActivityExists(id);
115 // 校验状态 117 // 校验状态
116 - if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {  
117 - throw exception(BARGAIN_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);  
118 - } 118 + //if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
  119 + // throw exception(BARGAIN_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
  120 + //}
119 121
120 // 删除 122 // 删除
121 bargainActivityMapper.deleteById(id); 123 bargainActivityMapper.deleteById(id);
@@ -139,4 +141,20 @@ public class BargainActivityServiceImpl implements BargainActivityService { @@ -139,4 +141,20 @@ public class BargainActivityServiceImpl implements BargainActivityService {
139 return bargainActivityMapper.selectPage(pageReqVO); 141 return bargainActivityMapper.selectPage(pageReqVO);
140 } 142 }
141 143
  144 + @Override
  145 + public PageResult<BargainActivityDO> getBargainActivityAppPage(PageParam pageReqVO) {
  146 + // 只查询进行中,且在时间范围内的
  147 + return bargainActivityMapper.selectAppPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now());
  148 +
  149 + }
  150 +
  151 + @Override
  152 + public List<BargainActivityDO> getBargainActivityAppList(Integer count) {
  153 + if (count == null) {
  154 + count = 6;
  155 + }
  156 + PageResult<BargainActivityDO> result = bargainActivityMapper.selectAppPage(new PageParam().setPageSize(count), CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now());
  157 + return result.getList();
  158 + }
  159 +
142 } 160 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java
1 package cn.iocoder.yudao.module.promotion.service.combination; 1 package cn.iocoder.yudao.module.promotion.service.combination;
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.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO;  
5 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO; 4 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
6 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO; 5 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
7 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO; 6 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
@@ -74,10 +73,13 @@ public interface CombinationActivityService { @@ -74,10 +73,13 @@ public interface CombinationActivityService {
74 List<CombinationProductDO> getCombinationProductsByActivityIds(Collection<Long> activityIds); 73 List<CombinationProductDO> getCombinationProductsByActivityIds(Collection<Long> activityIds);
75 74
76 /** 75 /**
77 - * 更新拼图活动库存 76 + * 校验是否满足拼团条件
78 * 77 *
79 - * @param reqDTO 请求 78 + * @param activityId 活动编号
  79 + * @param userId 用户编号
  80 + * @param skuId sku 编号
  81 + * @param count 数量
80 */ 82 */
81 - void validateCombination(CombinationActivityUpdateStockReqDTO reqDTO); 83 + void validateCombination(Long activityId, Long userId, Long skuId, Integer count);
82 84
83 } 85 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java
@@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
9 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; 9 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
10 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; 10 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
11 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; 11 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
12 -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO;  
13 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO; 12 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
14 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO; 13 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
15 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO; 14 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
@@ -34,7 +33,6 @@ import java.util.Map; @@ -34,7 +33,6 @@ import java.util.Map;
34 33
35 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 34 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
36 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; 35 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
37 -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;  
38 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; 36 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
39 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; 37 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
40 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; 38 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
@@ -88,7 +86,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic @@ -88,7 +86,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
88 /** 86 /**
89 * 校验拼团商品参与的活动是否存在冲突 87 * 校验拼团商品参与的活动是否存在冲突
90 * 88 *
91 - * @param spuId 商品 SPU 编号 89 + * @param spuId 商品 SPU 编号
92 * @param activityId 拼团活动编号 90 * @param activityId 拼团活动编号
93 */ 91 */
94 private void validateProductConflict(Long spuId, Long activityId) { 92 private void validateProductConflict(Long spuId, Long activityId) {
@@ -107,7 +105,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic @@ -107,7 +105,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
107 /** 105 /**
108 * 校验拼团商品是否都存在 106 * 校验拼团商品是否都存在
109 * 107 *
110 - * @param spuId 商品 SPU 编号 108 + * @param spuId 商品 SPU 编号
111 * @param products 拼团商品 109 * @param products 拼团商品
112 */ 110 */
113 private void validateProductExists(Long spuId, List<CombinationProductBaseVO> products) { 111 private void validateProductExists(Long spuId, List<CombinationProductBaseVO> products) {
@@ -152,7 +150,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic @@ -152,7 +150,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
152 * 更新拼团商品 150 * 更新拼团商品
153 * 151 *
154 * @param activity 拼团活动 152 * @param activity 拼团活动
155 - * @param products 该活动的最新商品配置 153 + * @param products 该活动的最新商品配置
156 */ 154 */
157 private void updateCombinationProduct(CombinationActivityDO activity, List<CombinationProductBaseVO> products) { 155 private void updateCombinationProduct(CombinationActivityDO activity, List<CombinationProductBaseVO> products) {
158 // 第一步,对比新老数据,获得添加、修改、删除的列表 156 // 第一步,对比新老数据,获得添加、修改、删除的列表
@@ -217,35 +215,34 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic @@ -217,35 +215,34 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
217 } 215 }
218 216
219 @Override 217 @Override
220 - public void validateCombination(CombinationActivityUpdateStockReqDTO reqDTO) { 218 + public void validateCombination(Long activityId, Long userId, Long skuId, Integer count) {
221 // 1.1 校验拼团活动是否存在 219 // 1.1 校验拼团活动是否存在
222 - CombinationActivityDO activity = validateCombinationActivityExists(reqDTO.getActivityId()); 220 + CombinationActivityDO activity = validateCombinationActivityExists(activityId);
223 // 1.2 校验活动是否开启 221 // 1.2 校验活动是否开启
224 if (ObjectUtil.equal(activity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) { 222 if (ObjectUtil.equal(activity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
225 throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE); 223 throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE);
226 } 224 }
227 // 1.3 校验是否超出单次限购数量 225 // 1.3 校验是否超出单次限购数量
228 - if (activity.getSingleLimitCount() < reqDTO.getCount()) { 226 + if (activity.getSingleLimitCount() < count) {
229 throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED); 227 throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED);
230 } 228 }
231 229
232 // 2. 校验是否超出总限购数量 230 // 2. 校验是否超出总限购数量
233 - // TODO @puhui999:userId 应该接口传递哈;要保证 service 无状态  
234 - List<CombinationRecordDO> recordList = combinationRecordService.getRecordListByUserIdAndActivityId(  
235 - getLoginUserId(), reqDTO.getActivityId());  
236 - // TODO @puhui999:最好 if true return;减少括号层数  
237 - if (CollUtil.isNotEmpty(recordList)) {  
238 - // 过滤出拼团成功的  
239 - // TODO @puhui999:count 要不存一个在 record 里?  
240 - List<Long> skuIds = convertList(recordList, CombinationRecordDO::getSkuId,  
241 - item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus()));  
242 - Integer countSum = tradeOrderApi.getOrderItemCountSumByOrderIdAndSkuId(convertList(recordList,  
243 - CombinationRecordDO::getOrderId,  
244 - item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())), skuIds);  
245 - if (activity.getTotalLimitCount() < countSum) {  
246 - throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED);  
247 - } 231 + List<CombinationRecordDO> recordList = combinationRecordService.getRecordListByUserIdAndActivityId(userId, activityId);
  232 + if (CollUtil.isEmpty(recordList)) {
  233 + return;
  234 + }
  235 + // 过滤出拼团成功的
  236 + // TODO @puhui999:count 要不存一个在 record 里?
  237 + List<Long> skuIds = convertList(recordList, CombinationRecordDO::getSkuId,
  238 + item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus()));
  239 + Integer countSum = tradeOrderApi.getOrderItemCountSumByOrderIdAndSkuId(convertList(recordList,
  240 + CombinationRecordDO::getOrderId,
  241 + item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())), skuIds);
  242 + if (activity.getTotalLimitCount() < countSum) {
  243 + throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED);
248 } 244 }
  245 +
249 } 246 }
250 247
251 } 248 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java
@@ -57,14 +57,4 @@ public interface CombinationRecordService { @@ -57,14 +57,4 @@ public interface CombinationRecordService {
57 */ 57 */
58 List<CombinationRecordDO> getRecordListByUserIdAndActivityId(Long userId, Long activityId); 58 List<CombinationRecordDO> getRecordListByUserIdAndActivityId(Long userId, Long activityId);
59 59
60 - /**  
61 - * 验证组合限制数  
62 - * 校验是否满足限购要求  
63 - *  
64 - * @param count 本次购买数量  
65 - * @param sumCount 已购买数量合计  
66 - * @param activityId 活动编号  
67 - */  
68 - void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount);  
69 -  
70 } 60 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
@@ -129,19 +129,10 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { @@ -129,19 +129,10 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
129 } 129 }
130 130
131 // 2. 创建拼团记录 131 // 2. 创建拼团记录
132 - // TODO @puhui999:可以把 user、spu、sku 一起放 convert 里哈;  
133 - CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO);  
134 - record.setVirtualGroup(false);  
135 - record.setExpireTime(record.getStartTime().plusHours(activity.getLimitDuration()));  
136 - record.setUserSize(activity.getUserSize());  
137 MemberUserRespDTO user = memberUserApi.getUser(reqDTO.getUserId()); 132 MemberUserRespDTO user = memberUserApi.getUser(reqDTO.getUserId());
138 - record.setNickname(user.getNickname());  
139 - record.setAvatar(user.getAvatar());  
140 - ProductSpuRespDTO spu = productSpuApi.getSpu(record.getSpuId());  
141 - record.setSpuName(spu.getName());  
142 - ProductSkuRespDTO sku = productSkuApi.getSku(record.getSkuId());  
143 - record.setPicUrl(sku.getPicUrl());  
144 - recordMapper.insert(record); 133 + ProductSpuRespDTO spu = productSpuApi.getSpu(reqDTO.getSpuId());
  134 + ProductSkuRespDTO sku = productSkuApi.getSku(reqDTO.getSkuId());
  135 + recordMapper.insert(CombinationActivityConvert.INSTANCE.convert1(reqDTO, activity, user, spu, sku));
145 } 136 }
146 137
147 @Override 138 @Override
@@ -154,20 +145,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { @@ -154,20 +145,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
154 return recordMapper.selectListByUserIdAndActivityId(userId, activityId); 145 return recordMapper.selectListByUserIdAndActivityId(userId, activityId);
155 } 146 }
156 147
157 - @Override  
158 - public void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount) {  
159 - // 1.1 校验拼团活动  
160 - CombinationActivityDO activity = combinationActivityService.validateCombinationActivityExists(activityId);  
161 - // 校验是否达到限购总限购标准  
162 - if ((sumCount + count) > activity.getTotalLimitCount()) {  
163 - throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED);  
164 - }  
165 - // 单次购买是否达到限购标准  
166 - if (count > activity.getSingleLimitCount()) {  
167 - throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED);  
168 - }  
169 - }  
170 -  
171 /** 148 /**
172 * APP 端获取开团记录 149 * APP 端获取开团记录
173 * 150 *
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java
1 package cn.iocoder.yudao.module.promotion.service.seckill; 1 package cn.iocoder.yudao.module.promotion.service.seckill;
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.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;  
5 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; 4 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
6 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; 5 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
7 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; 6 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
8 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; 8 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
9 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; 9 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
10 10
@@ -37,9 +37,11 @@ public interface SeckillActivityService { @@ -37,9 +37,11 @@ public interface SeckillActivityService {
37 /** 37 /**
38 * 更新秒杀库存 38 * 更新秒杀库存
39 * 39 *
40 - * @param updateStockReqDTO 更新信息 40 + * @param activityId 活动编号
  41 + * @param skuId sku 编号
  42 + * @param count 数量
41 */ 43 */
42 - void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO); 44 + void updateSeckillStock(Long activityId, Long skuId, Integer count);
43 45
44 /** 46 /**
45 * 关闭秒杀活动 47 * 关闭秒杀活动
@@ -87,4 +89,20 @@ public interface SeckillActivityService { @@ -87,4 +89,20 @@ public interface SeckillActivityService {
87 */ 89 */
88 List<SeckillProductDO> getSeckillProductListByActivityId(Collection<Long> activityIds); 90 List<SeckillProductDO> getSeckillProductListByActivityId(Collection<Long> activityIds);
89 91
  92 + /**
  93 + * 通过活动时段获取秒杀活动
  94 + *
  95 + * @param ids 时段配置编号
  96 + * @return 秒杀活动列表
  97 + */
  98 + List<SeckillActivityDO> getSeckillActivityListByConfigIds(Collection<Long> ids);
  99 +
  100 + /**
  101 + * 通过活动时段获取秒杀活动
  102 + *
  103 + * @param pageReqVO 请求
  104 + * @return 秒杀活动列表
  105 + */
  106 + PageResult<SeckillActivityDO> getSeckillActivityAppPageByConfigId(AppSeckillActivityPageReqVO pageReqVO);
  107 +
90 } 108 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java
@@ -3,15 +3,16 @@ package cn.iocoder.yudao.module.promotion.service.seckill; @@ -3,15 +3,16 @@ package cn.iocoder.yudao.module.promotion.service.seckill;
3 import cn.hutool.core.util.ObjectUtil; 3 import cn.hutool.core.util.ObjectUtil;
4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
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.CollectionUtils;
6 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; 7 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
7 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; 8 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
8 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; 9 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
9 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; 10 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
10 -import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;  
11 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; 11 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
12 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; 12 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
13 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; 13 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
14 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO; 14 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
  15 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
15 import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert; 16 import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
16 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; 17 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
17 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; 18 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
@@ -147,32 +148,32 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -147,32 +148,32 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
147 148
148 @Override 149 @Override
149 @Transactional(rollbackFor = Exception.class) 150 @Transactional(rollbackFor = Exception.class)
150 - public void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO) { 151 + public void updateSeckillStock(Long activityId, Long skuId, Integer count) {
151 // 1、校验秒杀活动是否存在 152 // 1、校验秒杀活动是否存在
152 - SeckillActivityDO seckillActivity = getSeckillActivity(updateStockReqDTO.getActivityId()); 153 + SeckillActivityDO seckillActivity = getSeckillActivity(activityId);
153 // 1.1、校验库存是否充足 154 // 1.1、校验库存是否充足
154 - if (seckillActivity.getTotalStock() < updateStockReqDTO.getCount()) { 155 + if (seckillActivity.getTotalStock() < count) {
155 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); 156 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
156 } 157 }
157 158
158 // 2、获取活动商品 159 // 2、获取活动商品
159 - List<SeckillProductDO> products = getSeckillProductListByActivityId(updateStockReqDTO.getActivityId()); 160 + List<SeckillProductDO> products = getSeckillProductListByActivityId(activityId);
160 // 2.1、过滤出购买的商品 161 // 2.1、过滤出购买的商品
161 - SeckillProductDO product = findFirst(products, item -> ObjectUtil.equal(updateStockReqDTO.getItem().getSkuId(), item.getSkuId())); 162 + SeckillProductDO product = findFirst(products, item -> ObjectUtil.equal(skuId, item.getSkuId()));
162 // 2.2、检查活动商品库存是否充足 163 // 2.2、检查活动商品库存是否充足
163 - boolean isSufficient = product == null || (product.getStock() == 0 || (product.getStock() < updateStockReqDTO.getItem().getCount()) || (product.getStock() - updateStockReqDTO.getItem().getCount()) < 0); 164 + boolean isSufficient = product == null || (product.getStock() == 0 || (product.getStock() < count) || (product.getStock() - count) < 0);
164 if (isSufficient) { 165 if (isSufficient) {
165 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); 166 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
166 } 167 }
167 168
168 // 3、更新活动商品库存 169 // 3、更新活动商品库存
169 - int updateCount = seckillProductMapper.updateActivityStock(product.getId(), updateStockReqDTO.getItem().getCount()); 170 + int updateCount = seckillProductMapper.updateActivityStock(product.getId(), count);
170 if (updateCount == 0) { 171 if (updateCount == 0) {
171 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); 172 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
172 } 173 }
173 174
174 // 4、更新活动库存 175 // 4、更新活动库存
175 - updateCount = seckillActivityMapper.updateActivityStock(seckillActivity.getId(), updateStockReqDTO.getCount()); 176 + updateCount = seckillActivityMapper.updateActivityStock(seckillActivity.getId(), count);
176 if (updateCount == 0) { 177 if (updateCount == 0) {
177 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); 178 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
178 } 179 }
@@ -265,4 +266,15 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -265,4 +266,15 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
265 return seckillProductMapper.selectListByActivityId(activityIds); 266 return seckillProductMapper.selectListByActivityId(activityIds);
266 } 267 }
267 268
  269 + @Override
  270 + public List<SeckillActivityDO> getSeckillActivityListByConfigIds(Collection<Long> ids) {
  271 + return CollectionUtils.filterList(seckillActivityMapper.selectList(),
  272 + item -> CollectionUtils.anyMatch(item.getConfigIds(), ids::contains));
  273 + }
  274 +
  275 + @Override
  276 + public PageResult<SeckillActivityDO> getSeckillActivityAppPageByConfigId(AppSeckillActivityPageReqVO pageReqVO) {
  277 + return seckillActivityMapper.selectPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus());
  278 + }
  279 +
268 } 280 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
@@ -14,9 +14,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDT @@ -14,9 +14,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDT
14 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; 14 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
15 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; 15 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
16 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; 16 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
17 -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO;  
18 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; 17 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
19 -import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;  
20 import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; 18 import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
21 import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; 19 import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
22 import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; 20 import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
@@ -279,15 +277,9 @@ public interface TradeOrderConvert { @@ -279,15 +277,9 @@ public interface TradeOrderConvert {
279 return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId()) 277 return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId())
280 .setBasePrice(item.getPayPrice() * item.getCount()) 278 .setBasePrice(item.getPayPrice() * item.getCount())
281 .setTitle(StrUtil.format("{}成功购买{}", user.getNickname(), item.getSpuName())) 279 .setTitle(StrUtil.format("{}成功购买{}", user.getNickname(), item.getSpuName()))
282 - .setFirstFixedPrice(sku.getFirstBrokerageRecord()).setSecondFixedPrice(sku.getSecondBrokerageRecord()); 280 + .setFirstFixedPrice(sku.getFirstBrokeragePrice()).setSecondFixedPrice(sku.getSecondBrokeragePrice());
283 } 281 }
284 282
285 - @Mapping(target = "activityId", source = "reqBO.seckillActivityId")  
286 - SeckillActivityUpdateStockReqDTO convert(TradeBeforeOrderCreateReqBO reqBO);  
287 -  
288 - @Mapping(target = "activityId", source = "reqBO.combinationActivityId")  
289 - CombinationActivityUpdateStockReqDTO convert1(TradeBeforeOrderCreateReqBO reqBO);  
290 -  
291 TradeBeforeOrderCreateReqBO convert(AppTradeOrderCreateReqVO createReqVO); 283 TradeBeforeOrderCreateReqBO convert(AppTradeOrderCreateReqVO createReqVO);
292 284
293 @Mappings({ 285 @Mappings({
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
@@ -184,9 +184,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -184,9 +184,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
184 @Transactional(rollbackFor = Exception.class) 184 @Transactional(rollbackFor = Exception.class)
185 public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) { 185 public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) {
186 // 1、执行订单创建前置处理器 186 // 1、执行订单创建前置处理器
187 - // TODO @puhui999:最好也抽个 beforeOrderCreate 方法; 187 + // TODO @puhui999:最好也抽个 beforeOrderCreate 方法;不要 BO 各自处理参数岂不美哉?
188 TradeBeforeOrderCreateReqBO beforeOrderCreateReqBO = TradeOrderConvert.INSTANCE.convert(createReqVO); 188 TradeBeforeOrderCreateReqBO beforeOrderCreateReqBO = TradeOrderConvert.INSTANCE.convert(createReqVO);
189 beforeOrderCreateReqBO.setOrderType(validateActivity(createReqVO)); 189 beforeOrderCreateReqBO.setOrderType(validateActivity(createReqVO));
  190 + beforeOrderCreateReqBO.setUserId(userId);
190 beforeOrderCreateReqBO.setCount(getSumValue(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCount, Integer::sum)); 191 beforeOrderCreateReqBO.setCount(getSumValue(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCount, Integer::sum));
191 // TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等 192 // TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等
192 tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(beforeOrderCreateReqBO)); 193 tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(beforeOrderCreateReqBO));
@@ -730,7 +731,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -730,7 +731,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
730 } 731 }
731 732
732 // TODO 活动相关库存回滚需要活动 id,活动 id 怎么获取?app 端能否传过来 733 // TODO 活动相关库存回滚需要活动 id,活动 id 怎么获取?app 端能否传过来
733 - tradeOrderHandlers.forEach(handler -> handler.rollbackStock()); 734 + tradeOrderHandlers.forEach(handler -> handler.rollback());
734 735
735 // 2.回滚库存 736 // 2.回滚库存
736 List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id); 737 List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id);
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/TradeBeforeOrderCreateReqBO.java
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.service.order.bo; @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.service.order.bo;
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 -import javax.validation.Valid;  
7 import javax.validation.constraints.NotNull; 6 import javax.validation.constraints.NotNull;
8 7
9 // TODO 芋艿:在想想这些参数的定义 8 // TODO 芋艿:在想想这些参数的定义
@@ -34,25 +33,16 @@ public class TradeBeforeOrderCreateReqBO { @@ -34,25 +33,16 @@ public class TradeBeforeOrderCreateReqBO {
34 @Schema(description = "砍价活动编号", example = "123") 33 @Schema(description = "砍价活动编号", example = "123")
35 private Long bargainActivityId; 34 private Long bargainActivityId;
36 35
37 - @NotNull(message = "购买数量不能为空")  
38 - private Integer count;  
39 -  
40 - @NotNull(message = "活动商品不能为空")  
41 - private Item item;  
42 -  
43 - @Data  
44 - @Valid  
45 - public static class Item { 36 + @NotNull(message = "SPU 编号不能为空")
  37 + private Long spuId;
46 38
47 - @NotNull(message = "SPU 编号不能为空")  
48 - private Long spuId; 39 + @NotNull(message = "SKU 编号活动商品不能为空")
  40 + private Long skuId;
49 41
50 - @NotNull(message = "SKU 编号活动商品不能为空")  
51 - private Long skuId; 42 + @NotNull(message = "用户编号不能为空")
  43 + private Long userId;
52 44
53 - @NotNull(message = "购买数量不能为空")  
54 - private Integer count;  
55 -  
56 - } 45 + @NotNull(message = "购买数量不能为空")
  46 + private Integer count;
57 47
58 } 48 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBargainHandler.java
@@ -22,7 +22,7 @@ public class TradeBargainHandler implements TradeOrderHandler { @@ -22,7 +22,7 @@ public class TradeBargainHandler implements TradeOrderHandler {
22 22
23 @Override 23 @Override
24 public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) { 24 public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
25 - // 如果是秒杀订单 25 + // 如果是砍价订单
26 if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), reqBO.getOrderType())) { 26 if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), reqBO.getOrderType())) {
27 return; 27 return;
28 } 28 }
@@ -37,7 +37,7 @@ public class TradeBargainHandler implements TradeOrderHandler { @@ -37,7 +37,7 @@ public class TradeBargainHandler implements TradeOrderHandler {
37 } 37 }
38 38
39 @Override 39 @Override
40 - public void rollbackStock() { 40 + public void rollback() {
41 41
42 } 42 }
43 43
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java
1 package cn.iocoder.yudao.module.trade.service.order.handler; 1 package cn.iocoder.yudao.module.trade.service.order.handler;
2 2
3 import cn.hutool.core.util.ObjectUtil; 3 import cn.hutool.core.util.ObjectUtil;
4 -import cn.iocoder.yudao.module.promotion.api.combination.CombinationApi; 4 +import cn.iocoder.yudao.module.promotion.api.combination.CombinationActivityApi;
5 import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; 5 import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
6 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; 6 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
7 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; 7 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
@@ -20,7 +20,7 @@ import javax.annotation.Resource; @@ -20,7 +20,7 @@ import javax.annotation.Resource;
20 public class TradeCombinationHandler implements TradeOrderHandler { 20 public class TradeCombinationHandler implements TradeOrderHandler {
21 21
22 @Resource 22 @Resource
23 - private CombinationApi combinationApi; 23 + private CombinationActivityApi combinationActivityApi;
24 @Resource 24 @Resource
25 private CombinationRecordApi combinationRecordApi; 25 private CombinationRecordApi combinationRecordApi;
26 26
@@ -32,7 +32,7 @@ public class TradeCombinationHandler implements TradeOrderHandler { @@ -32,7 +32,7 @@ public class TradeCombinationHandler implements TradeOrderHandler {
32 } 32 }
33 33
34 // 校验是否满足拼团活动相关限制 34 // 校验是否满足拼团活动相关限制
35 - combinationApi.validateCombination(TradeOrderConvert.INSTANCE.convert1(reqBO)); 35 + combinationActivityApi.validateCombination(reqBO.getCombinationActivityId(), reqBO.getUserId(), reqBO.getSkuId(), reqBO.getCount());
36 } 36 }
37 37
38 @Override 38 @Override
@@ -42,7 +42,7 @@ public class TradeCombinationHandler implements TradeOrderHandler { @@ -42,7 +42,7 @@ public class TradeCombinationHandler implements TradeOrderHandler {
42 } 42 }
43 43
44 @Override 44 @Override
45 - public void rollbackStock() { 45 + public void rollback() {
46 46
47 } 47 }
48 48
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeOrderHandler.java
@@ -25,8 +25,8 @@ public interface TradeOrderHandler { @@ -25,8 +25,8 @@ public interface TradeOrderHandler {
25 void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO); 25 void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO);
26 26
27 /** 27 /**
28 - * 回滚活动相关库存 28 + * 回滚
29 */ 29 */
30 - void rollbackStock(); 30 + void rollback();
31 31
32 } 32 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeSeckillHandler.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.service.order.handler; @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.service.order.handler;
2 2
3 import cn.hutool.core.util.ObjectUtil; 3 import cn.hutool.core.util.ObjectUtil;
4 import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi; 4 import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi;
5 -import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;  
6 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; 5 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
7 import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterOrderCreateReqBO; 6 import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterOrderCreateReqBO;
8 import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO; 7 import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
@@ -28,7 +27,7 @@ public class TradeSeckillHandler implements TradeOrderHandler { @@ -28,7 +27,7 @@ public class TradeSeckillHandler implements TradeOrderHandler {
28 return; 27 return;
29 } 28 }
30 29
31 - seckillActivityApi.updateSeckillStock(TradeOrderConvert.INSTANCE.convert(reqBO)); 30 + seckillActivityApi.updateSeckillStock(reqBO.getSeckillActivityId(), reqBO.getSkuId(), reqBO.getCount());
32 } 31 }
33 32
34 @Override 33 @Override
@@ -37,7 +36,7 @@ public class TradeSeckillHandler implements TradeOrderHandler { @@ -37,7 +36,7 @@ public class TradeSeckillHandler implements TradeOrderHandler {
37 } 36 }
38 37
39 @Override 38 @Override
40 - public void rollbackStock() { 39 + public void rollback() {
41 40
42 } 41 }
43 42