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 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 56 public static LocalDateTime[] buildBetweenTime(int year1, int mouth1, int day1,
47 57 int year2, int mouth2, int day2) {
48 58 return new LocalDateTime[]{buildTime(year1, mouth1, day1), buildTime(year2, mouth2, day2)};
... ... @@ -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 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 59 * 商品体积,单位:m^3 平米
60 60 */
61 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 1 package cn.iocoder.yudao.module.product.api.spu.dto;
2 2  
3   -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
4 3 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
5 4 import lombok.Data;
6 5  
... ... @@ -32,6 +31,12 @@ public class ProductSpuRespDTO {
32 31 */
33 32 private String keyword;
34 33 /**
  34 + * 单位
  35 + *
  36 + * 对应 product_unit 数据字典
  37 + */
  38 + private Integer unit;
  39 + /**
35 40 * 商品简介
36 41 */
37 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 51 private Double volume;
52 52  
53 53 @Schema(description = "一级分销的佣金,单位:分", example = "199")
54   - private Integer firstBrokerageRecord;
  54 + private Integer firstBrokeragePrice;
55 55  
56 56 @Schema(description = "二级分销的佣金,单位:分", example = "19")
57   - private Integer secondBrokerageRecord;
  57 + private Integer secondBrokeragePrice;
58 58  
59 59 @Schema(description = "属性数组")
60 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 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 92 o.setMarketPrice(generaInt());
93 93 o.setStock(generaInt());
94 94 o.setWarnStock(10);
95   - o.setFirstBrokerageRecord(generaInt());
96   - o.setSecondBrokerageRecord(generaInt());
  95 + o.setFirstBrokeragePrice(generaInt());
  96 + o.setSecondBrokeragePrice(generaInt());
97 97 // 限制分数为两位数
98 98 o.setWeight(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP));
99 99 o.setVolume(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP));
... ... @@ -143,8 +143,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
143 143 o.setMarketPrice(generaInt());
144 144 o.setStock(generaInt());
145 145 o.setWarnStock(10);
146   - o.setFirstBrokerageRecord(generaInt());
147   - o.setSecondBrokerageRecord(generaInt());
  146 + o.setFirstBrokeragePrice(generaInt());
  147 + o.setSecondBrokeragePrice(generaInt());
148 148 // 限制分数为两位数
149 149 o.setWeight(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP));
150 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 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 4 * 拼团活动 Api 接口
8 5 *
9 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 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2  
3 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 5 import javax.validation.Valid;
7 6 import java.time.LocalDateTime;
8   -import java.util.List;
9 7  
10 8 // TODO @芋艿:后面也再撸撸这几个接口
11 9  
... ... @@ -33,26 +31,7 @@ public interface CombinationRecordApi {
33 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 36 * @param userId 用户编号
58 37 * @param orderId 订单编号
... ... @@ -60,7 +39,7 @@ public interface CombinationRecordApi {
60 39 void updateRecordStatusToSuccess(Long userId, Long orderId);
61 40  
62 41 /**
63   - * 更新拼团状态为失败
  42 + * 更新拼团状态为 失败
64 43 *
65 44 * @param userId 用户编号
66 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 13 @Data
14 14 public class CombinationRecordCreateReqDTO {
15 15  
16   - // TODO @puhui999:注释还是要的哈
17   -
  16 + /**
  17 + * 拼团活动编号
  18 + */
18 19 @NotNull(message = "拼团活动编号不能为空")
19 20 private Long activityId;
20   -
  21 + /**
  22 + * spu 编号
  23 + */
21 24 @NotNull(message = "spu 编号不能为空")
22 25 private Long spuId;
23   -
  26 + /**
  27 + * sku 编号
  28 + */
24 29 @NotNull(message = "sku 编号不能为空")
25 30 private Long skuId;
26   -
  31 + /**
  32 + * 订单编号
  33 + */
27 34 @NotNull(message = "订单编号不能为空")
28 35 private Long orderId;
29   -
  36 + /**
  37 + * 用户编号
  38 + */
30 39 @NotNull(message = "用户编号不能为空")
31 40 private Long userId;
32   -
  41 + /**
  42 + * 团长编号
  43 + */
33 44 @NotNull(message = "团长编号不能为空")
34 45 private Long headId;
35   -
  46 + /**
  47 + * 拼团商品单价
  48 + */
36 49 @NotNull(message = "拼团商品单价不能为空")
37 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 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 4 * 秒杀活动 API 接口
7 5 *
... ... @@ -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 56 ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除");
57 57 ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭");
58 58 ErrorCode SECKILL_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1013008006, "秒杀失败,原因秒杀库存不足");
  59 + ErrorCode SECKILL_ACTIVITY_FAIL_STATUS_CLOSED = new ErrorCode(1013008007, "秒杀活动已关闭");
59 60  
60 61 // ========== 秒杀时段 1013009000 ==========
61 62 ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1013009000, "秒杀时段不存在");
... ...
yudao-module-mall/yudao-module-promotion-biz/pom.xml
... ... @@ -77,6 +77,10 @@
77 77 <groupId>cn.iocoder.boot</groupId>
78 78 <artifactId>yudao-spring-boot-starter-excel</artifactId>
79 79 </dependency>
  80 + <dependency>
  81 + <groupId>cn.iocoder.boot</groupId>
  82 + <artifactId>yudao-spring-boot-starter-biz-dict</artifactId>
  83 + </dependency>
80 84 </dependencies>
81 85  
82 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 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2  
3   -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO;
4 3 import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService;
5 4 import org.springframework.stereotype.Service;
6   -import org.springframework.validation.annotation.Validated;
7 5  
8 6 import javax.annotation.Resource;
9 7  
... ... @@ -13,15 +11,14 @@ import javax.annotation.Resource;
13 11 * @author HUIHUI
14 12 */
15 13 @Service
16   -@Validated
17   -public class CombinationApiImpl implements CombinationApi {
  14 +public class CombinationActivityApiImpl implements CombinationActivityApi {
18 15  
19 16 @Resource
20 17 private CombinationActivityService activityService;
21 18  
22 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 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2  
3 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 4 import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
7 5 import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
8 6 import org.springframework.stereotype.Service;
9 7  
10 8 import javax.annotation.Resource;
11 9 import java.time.LocalDateTime;
12   -import java.util.List;
13 10  
14 11 /**
15 12 * 拼团活动 API 实现类
... ... @@ -33,16 +30,6 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
33 30 }
34 31  
35 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 33 public void updateRecordStatusToSuccess(Long userId, Long orderId) {
47 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 1 package cn.iocoder.yudao.module.promotion.api.seckill;
2 2  
3   -import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;
4 3 import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService;
5 4 import org.springframework.stereotype.Service;
6 5  
... ... @@ -18,8 +17,8 @@ public class SeckillActivityApiImpl implements SeckillActivityApi {
18 17 private SeckillActivityService activityService;
19 18  
20 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 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 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 9 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO;
7 10 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO;
8 11 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO;
... ... @@ -19,6 +22,7 @@ import org.springframework.web.bind.annotation.*;
19 22  
20 23 import javax.annotation.Resource;
21 24 import javax.validation.Valid;
  25 +import java.util.List;
22 26  
23 27 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
24 28  
... ... @@ -30,6 +34,8 @@ public class BargainActivityController {
30 34  
31 35 @Resource
32 36 private BargainActivityService activityService;
  37 + @Resource
  38 + private ProductSpuApi spuApi;
33 39  
34 40 @PostMapping("/create")
35 41 @Operation(summary = "创建砍价活动")
... ... @@ -73,7 +79,8 @@ public class BargainActivityController {
73 79 if (CollUtil.isEmpty(pageResult.getList())) {
74 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 1 package cn.iocoder.yudao.module.promotion.controller.app.bargain;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 5 import cn.iocoder.yudao.framework.common.pojo.PageParam;
5 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 10 import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityDetailRespVO;
8 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 15 import io.swagger.v3.oas.annotations.Operation;
  16 +import io.swagger.v3.oas.annotations.Parameter;
10 17 import io.swagger.v3.oas.annotations.tags.Tag;
11 18 import org.springframework.validation.annotation.Validated;
12 19 import org.springframework.web.bind.annotation.GetMapping;
... ... @@ -14,8 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
14 21 import org.springframework.web.bind.annotation.RequestParam;
15 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 25 import java.util.List;
20 26  
21 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 31 @RequestMapping("/promotion/bargain-activity")
26 32 @Validated
27 33 public class AppBargainActivityController {
  34 + @Resource
  35 + private BargainActivityService bargainActivityService;
  36 + @Resource
  37 + private ProductSpuApi spuApi;
28 38  
29 39 @GetMapping("/page")
30   - @Operation(summary = "获得砍价活动活动") // TODO 芋艿:只查询进行中,且在时间范围内的
31   - // TODO 芋艿:缺少 swagger 注解
  40 + @Operation(summary = "获得砍价活动分页")
32 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 51 @GetMapping("/list")
62 52 @Operation(summary = "获得砍价活动列表", description = "用于小程序首页")
63   - // TODO 芋艿:增加 Spring Cache
64   - // TODO 芋艿:缺少 swagger 注解
  53 + @Parameter(name = "count", description = "需要展示的数量", example = "6")
65 54 public CommonResult<List<AppBargainActivityRespVO>> getBargainActivityList(
66 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 66 @GetMapping("/get-detail")
90 67 @Operation(summary = "获得砍价活动详情")
91   - // TODO 芋艿:缺少 swagger 注解
  68 + @Parameter(name = "id", description = "活动编号", example = "1")
92 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 45 @Schema(description = "商品单位", required = true, example = "个") // 从 SPU 的 unit 读取,然后转换
46 46 private String unitName;
47 47  
48   - @Schema(description = "砍价最低金额,单位:分", required = true, example = "100") // 从砍价商品里取最低价
  48 + @Schema(description = "砍价最低金额,单位:分", required = true, example = "100")
49 49 private Integer bargainPrice;
50 50  
51 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 36 @Schema(description = "商品市场价,单位:分", required = true, example = "50") // 从 SPU 的 marketPrice 读取
37 37 private Integer marketPrice;
38 38  
39   - @Schema(description = "砍价最低金额,单位:分", required = true, example = "100") // 从砍价商品里取最低价
  39 + @Schema(description = "砍价最低金额,单位:分", required = true, example = "100")
40 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 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 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 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 10 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO;
6 11 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO;
7 12 import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO;
8 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 20 import io.swagger.v3.oas.annotations.Operation;
11 21 import io.swagger.v3.oas.annotations.Parameter;
12 22 import io.swagger.v3.oas.annotations.tags.Tag;
  23 +import org.springframework.context.annotation.Lazy;
13 24 import org.springframework.validation.annotation.Validated;
14 25 import org.springframework.web.bind.annotation.GetMapping;
15 26 import org.springframework.web.bind.annotation.RequestMapping;
16 27 import org.springframework.web.bind.annotation.RequestParam;
17 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 32 import java.util.List;
22 33  
  34 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
23 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 41 @Tag(name = "用户 App - 秒杀活动")
26 42 @RestController
27 43 @RequestMapping("/promotion/seckill-activity")
28 44 @Validated
29 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 55 @GetMapping("/get-now")
32 56 @Operation(summary = "获得当前秒杀活动") // 提供给首页使用
33 57 // TODO 芋艿:需要增加 spring cache
34 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 76 @GetMapping("/page")
60 77 @Operation(summary = "获得秒杀活动分页")
61   - // TODO @芋艿:分页参数
62 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 86 @GetMapping("/get-detail")
91 87 @Operation(summary = "获得秒杀活动明细")
92 88 @Parameter(name = "id", description = "活动编号", required = true, example = "1024")
93 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 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 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 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 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 10 import io.swagger.v3.oas.annotations.Operation;
6 11 import io.swagger.v3.oas.annotations.tags.Tag;
7 12 import org.springframework.validation.annotation.Validated;
... ... @@ -9,7 +14,8 @@ import org.springframework.web.bind.annotation.GetMapping;
9 14 import org.springframework.web.bind.annotation.RequestMapping;
10 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 19 import java.util.List;
14 20  
15 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 25 @RequestMapping("/promotion/seckill-config")
20 26 @Validated
21 27 public class AppSeckillConfigController {
  28 + @Resource
  29 + private SeckillConfigService configService;
22 30  
23 31 @GetMapping("/list")
24 32 @Operation(summary = "获得秒杀时间段列表")
25 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 19 @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
20 20 private Integer status;
21 21  
22   - // TODO @芋艿:开始时间、结束时间,要和场次结合起来;就是要算到当前场次,是几点哈;
  22 + // TODO @芋艿:开始时间、结束时间,要和场次结合起来;就是要算到当前场次,是几点哈;
23 23  
24 24 @Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
25 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 31 private Integer totalStock;
32 32  
33 33 @Schema(description = "秒杀金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
34   - // 从秒杀商品里取最低价
35 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 1 package cn.iocoder.yudao.module.promotion.convert.bargain;
2 2  
3 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 8 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityBaseVO;
5 9 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO;
6 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 13 import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
8 14 import org.mapstruct.Mapper;
9 15 import org.mapstruct.factory.Mappers;
10 16  
11 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 24 * 拼团活动 Convert
... ... @@ -30,4 +40,60 @@ public interface BargainActivityConvert {
30 40  
31 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 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 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 8 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
7 9 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
8 10 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
... ... @@ -92,6 +94,19 @@ public interface CombinationActivityConvert {
92 94  
93 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 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 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 5 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  6 +import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
6 7 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  8 +import cn.iocoder.yudao.module.product.enums.DictTypeConstants;
7 9 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
8 10 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityDetailRespVO;
9 11 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO;
10 12 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
11 13 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
12 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 19 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
14 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 22 import org.mapstruct.Mapper;
16 23 import org.mapstruct.Mapping;
17 24 import org.mapstruct.Mappings;
... ... @@ -20,6 +27,10 @@ import org.mapstruct.factory.Mappers;
20 27 import java.util.List;
21 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 35 * 秒杀活动 Convert
25 36 *
... ... @@ -79,4 +90,50 @@ public interface SeckillActivityConvert {
79 90  
80 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 5 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigRespVO;
6 6 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigSimpleRespVO;
7 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 9 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
9 10 import org.mapstruct.Mapper;
10 11 import org.mapstruct.factory.Mappers;
... ... @@ -33,4 +34,7 @@ public interface SeckillConfigConvert {
33 34  
34 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 87 */
88 88 private Integer singleLimitCount;
89 89 /**
90   - * 秒杀库存
  90 + * 秒杀库存(剩余库存秒杀时扣减)
91 91 */
92 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 1 package cn.iocoder.yudao.module.promotion.dal.mysql.bargain;
2 2  
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
3 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 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 9 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
9 10 import org.apache.ibatis.annotations.Mapper;
10 11  
  12 +import java.time.LocalDateTime;
11 13 import java.util.List;
12 14  
13 15 /**
... ... @@ -39,8 +41,15 @@ public interface BargainActivityMapper extends BaseMapperX&lt;BargainActivityDO&gt; {
39 41 default int updateActivityStock(Long id, int count) {
40 42 return update(null, new LambdaUpdateWrapper<BargainActivityDO>()
41 43 .eq(BargainActivityDO::getId, id)
42   - .gt(BargainActivityDO::getStock, 0) // TODO @puhui999:不是 > 0,是要大于 count 哈
  44 + .gt(BargainActivityDO::getStock, count)
43 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 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
7 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 9 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
9 10 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
10 11 import org.apache.ibatis.annotations.Mapper;
... ... @@ -24,7 +25,7 @@ public interface SeckillActivityMapper extends BaseMapperX&lt;SeckillActivityDO&gt; {
24 25 .likeIfPresent(SeckillActivityDO::getName, reqVO.getName())
25 26 .eqIfPresent(SeckillActivityDO::getStatus, reqVO.getStatus())
26 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 29 .orderByDesc(SeckillActivityDO::getId));
29 30 }
30 31  
... ... @@ -48,4 +49,10 @@ public interface SeckillActivityMapper extends BaseMapperX&lt;SeckillActivityDO&gt; {
48 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 34 default int updateActivityStock(Long id, int count) {
35 35 return update(null, new LambdaUpdateWrapper<SeckillProductDO>()
36 36 .eq(SeckillProductDO::getId, id)
37   - .gt(SeckillProductDO::getStock, 0) // TODO @puhui999:不是 > 0,是要大于 count 哈
  37 + .gt(SeckillProductDO::getStock, count)
38 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 1 package cn.iocoder.yudao.module.promotion.service.bargain;
2 2  
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
3 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 5 import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO;
5 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 8 import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
8 9  
9 10 import javax.validation.Valid;
  11 +import java.util.List;
10 12  
11 13 /**
12 14 * 砍价活动 Service 接口
... ... @@ -61,4 +63,19 @@ public interface BargainActivityService {
61 63 */
62 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 2  
3 3 import cn.hutool.core.util.ObjectUtil;
4 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
5 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 7 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
7 8 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
... ... @@ -16,6 +17,7 @@ import org.springframework.transaction.annotation.Transactional;
16 17 import org.springframework.validation.annotation.Validated;
17 18  
18 19 import javax.annotation.Resource;
  20 +import java.time.LocalDateTime;
19 21 import java.util.List;
20 22  
21 23 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
... ... @@ -113,9 +115,9 @@ public class BargainActivityServiceImpl implements BargainActivityService {
113 115 // 校验存在
114 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 123 bargainActivityMapper.deleteById(id);
... ... @@ -139,4 +141,20 @@ public class BargainActivityServiceImpl implements BargainActivityService {
139 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 1 package cn.iocoder.yudao.module.promotion.service.combination;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO;
5 4 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
6 5 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
7 6 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
... ... @@ -74,10 +73,13 @@ public interface CombinationActivityService {
74 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 9 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
10 10 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
11 11 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
12   -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO;
13 12 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
14 13 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
15 14 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
... ... @@ -34,7 +33,6 @@ import java.util.Map;
34 33  
35 34 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
36 35 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
37   -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
38 36 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
39 37 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
40 38 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
... ... @@ -88,7 +86,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
88 86 /**
89 87 * 校验拼团商品参与的活动是否存在冲突
90 88 *
91   - * @param spuId 商品 SPU 编号
  89 + * @param spuId 商品 SPU 编号
92 90 * @param activityId 拼团活动编号
93 91 */
94 92 private void validateProductConflict(Long spuId, Long activityId) {
... ... @@ -107,7 +105,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
107 105 /**
108 106 * 校验拼团商品是否都存在
109 107 *
110   - * @param spuId 商品 SPU 编号
  108 + * @param spuId 商品 SPU 编号
111 109 * @param products 拼团商品
112 110 */
113 111 private void validateProductExists(Long spuId, List<CombinationProductBaseVO> products) {
... ... @@ -152,7 +150,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
152 150 * 更新拼团商品
153 151 *
154 152 * @param activity 拼团活动
155   - * @param products 该活动的最新商品配置
  153 + * @param products 该活动的最新商品配置
156 154 */
157 155 private void updateCombinationProduct(CombinationActivityDO activity, List<CombinationProductBaseVO> products) {
158 156 // 第一步,对比新老数据,获得添加、修改、删除的列表
... ... @@ -217,35 +215,34 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
217 215 }
218 216  
219 217 @Override
220   - public void validateCombination(CombinationActivityUpdateStockReqDTO reqDTO) {
  218 + public void validateCombination(Long activityId, Long userId, Long skuId, Integer count) {
221 219 // 1.1 校验拼团活动是否存在
222   - CombinationActivityDO activity = validateCombinationActivityExists(reqDTO.getActivityId());
  220 + CombinationActivityDO activity = validateCombinationActivityExists(activityId);
223 221 // 1.2 校验活动是否开启
224 222 if (ObjectUtil.equal(activity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
225 223 throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE);
226 224 }
227 225 // 1.3 校验是否超出单次限购数量
228   - if (activity.getSingleLimitCount() < reqDTO.getCount()) {
  226 + if (activity.getSingleLimitCount() < count) {
229 227 throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED);
230 228 }
231 229  
232 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 57 */
58 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 129 }
130 130  
131 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 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 138 @Override
... ... @@ -154,20 +145,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
154 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 149 * APP 端获取开团记录
173 150 *
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java
1 1 package cn.iocoder.yudao.module.promotion.service.seckill;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;
5 4 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
6 5 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
7 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 8 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
9 9 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
10 10  
... ... @@ -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 89 */
88 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 3 import cn.hutool.core.util.ObjectUtil;
4 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 7 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
7 8 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
8 9 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
9 10 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
10   -import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;
11 11 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
12 12 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
13 13 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
14 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 16 import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
16 17 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
17 18 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
... ... @@ -147,32 +148,32 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
147 148  
148 149 @Override
149 150 @Transactional(rollbackFor = Exception.class)
150   - public void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO) {
  151 + public void updateSeckillStock(Long activityId, Long skuId, Integer count) {
151 152 // 1、校验秒杀活动是否存在
152   - SeckillActivityDO seckillActivity = getSeckillActivity(updateStockReqDTO.getActivityId());
  153 + SeckillActivityDO seckillActivity = getSeckillActivity(activityId);
153 154 // 1.1、校验库存是否充足
154   - if (seckillActivity.getTotalStock() < updateStockReqDTO.getCount()) {
  155 + if (seckillActivity.getTotalStock() < count) {
155 156 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
156 157 }
157 158  
158 159 // 2、获取活动商品
159   - List<SeckillProductDO> products = getSeckillProductListByActivityId(updateStockReqDTO.getActivityId());
  160 + List<SeckillProductDO> products = getSeckillProductListByActivityId(activityId);
160 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 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 165 if (isSufficient) {
165 166 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
166 167 }
167 168  
168 169 // 3、更新活动商品库存
169   - int updateCount = seckillProductMapper.updateActivityStock(product.getId(), updateStockReqDTO.getItem().getCount());
  170 + int updateCount = seckillProductMapper.updateActivityStock(product.getId(), count);
170 171 if (updateCount == 0) {
171 172 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
172 173 }
173 174  
174 175 // 4、更新活动库存
175   - updateCount = seckillActivityMapper.updateActivityStock(seckillActivity.getId(), updateStockReqDTO.getCount());
  176 + updateCount = seckillActivityMapper.updateActivityStock(seckillActivity.getId(), count);
176 177 if (updateCount == 0) {
177 178 throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
178 179 }
... ... @@ -265,4 +266,15 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
265 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 14 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
15 15 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
16 16 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
17   -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO;
18 17 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
19   -import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;
20 18 import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
21 19 import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
22 20 import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
... ... @@ -279,15 +277,9 @@ public interface TradeOrderConvert {
279 277 return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId())
280 278 .setBasePrice(item.getPayPrice() * item.getCount())
281 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 283 TradeBeforeOrderCreateReqBO convert(AppTradeOrderCreateReqVO createReqVO);
292 284  
293 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 184 @Transactional(rollbackFor = Exception.class)
185 185 public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) {
186 186 // 1、执行订单创建前置处理器
187   - // TODO @puhui999:最好也抽个 beforeOrderCreate 方法;
  187 + // TODO @puhui999:最好也抽个 beforeOrderCreate 方法;不要 BO 各自处理参数岂不美哉?
188 188 TradeBeforeOrderCreateReqBO beforeOrderCreateReqBO = TradeOrderConvert.INSTANCE.convert(createReqVO);
189 189 beforeOrderCreateReqBO.setOrderType(validateActivity(createReqVO));
  190 + beforeOrderCreateReqBO.setUserId(userId);
190 191 beforeOrderCreateReqBO.setCount(getSumValue(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCount, Integer::sum));
191 192 // TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等
192 193 tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(beforeOrderCreateReqBO));
... ... @@ -730,7 +731,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
730 731 }
731 732  
732 733 // TODO 活动相关库存回滚需要活动 id,活动 id 怎么获取?app 端能否传过来
733   - tradeOrderHandlers.forEach(handler -> handler.rollbackStock());
  734 + tradeOrderHandlers.forEach(handler -> handler.rollback());
734 735  
735 736 // 2.回滚库存
736 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 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
5 5  
6   -import javax.validation.Valid;
7 6 import javax.validation.constraints.NotNull;
8 7  
9 8 // TODO 芋艿:在想想这些参数的定义
... ... @@ -34,25 +33,16 @@ public class TradeBeforeOrderCreateReqBO {
34 33 @Schema(description = "砍价活动编号", example = "123")
35 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 22  
23 23 @Override
24 24 public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
25   - // 如果是秒杀订单
  25 + // 如果是砍价订单
26 26 if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), reqBO.getOrderType())) {
27 27 return;
28 28 }
... ... @@ -37,7 +37,7 @@ public class TradeBargainHandler implements TradeOrderHandler {
37 37 }
38 38  
39 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 1 package cn.iocoder.yudao.module.trade.service.order.handler;
2 2  
3 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 5 import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
6 6 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
7 7 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
... ... @@ -20,7 +20,7 @@ import javax.annotation.Resource;
20 20 public class TradeCombinationHandler implements TradeOrderHandler {
21 21  
22 22 @Resource
23   - private CombinationApi combinationApi;
  23 + private CombinationActivityApi combinationActivityApi;
24 24 @Resource
25 25 private CombinationRecordApi combinationRecordApi;
26 26  
... ... @@ -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 38 @Override
... ... @@ -42,7 +42,7 @@ public class TradeCombinationHandler implements TradeOrderHandler {
42 42 }
43 43  
44 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 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 2  
3 3 import cn.hutool.core.util.ObjectUtil;
4 4 import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi;
5   -import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
6 5 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
7 6 import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterOrderCreateReqBO;
8 7 import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
... ... @@ -28,7 +27,7 @@ public class TradeSeckillHandler implements TradeOrderHandler {
28 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 33 @Override
... ... @@ -37,7 +36,7 @@ public class TradeSeckillHandler implements TradeOrderHandler {
37 36 }
38 37  
39 38 @Override
40   - public void rollbackStock() {
  39 + public void rollback() {
41 40  
42 41 }
43 42  
... ...