Commit 785fbeeb5bc09ba65e570f1e500a87719bbd42e0

Authored by YunaiV
1 parent 90fb2c62

code review:限时折扣活动

... ... @@ -13,14 +13,14 @@
13 13 <!-- Server 主项目 -->
14 14 <module>yudao-server</module>
15 15 <!-- 各种 module 拓展 -->
16   -<!-- <module>yudao-module-member</module>-->
  16 + <module>yudao-module-member</module>
17 17 <module>yudao-module-system</module>
18 18 <module>yudao-module-infra</module>
19 19 <!-- <module>yudao-module-bpm</module>-->
20 20 <!-- <module>yudao-module-report</module>-->
21 21 <!-- <module>yudao-module-mp</module>-->
22   -<!-- <module>yudao-module-pay</module>-->
23   -<!-- <module>yudao-module-mall</module>-->
  22 + <module>yudao-module-pay</module>
  23 + <module>yudao-module-mall</module>
24 24 <!-- 示例项目 -->
25 25 <module>yudao-example</module>
26 26 </modules>
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
... ... @@ -15,7 +15,6 @@ public interface ErrorCodeConstants {
15 15 ErrorCode DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_001_002, "限时折扣活动已关闭,不能修改");
16 16 ErrorCode DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1_013_001_003, "限时折扣活动未关闭,不能删除");
17 17 ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_001_004, "限时折扣活动已关闭,不能重复关闭");
18   - ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1_013_001_005, "限时折扣活动已结束,不能关闭");
19 18  
20 19 // ========== Banner 相关 1-013-002-000 ============
21 20 ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1_013_002_000, "Banner 不存在");
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java
... ... @@ -7,11 +7,8 @@ import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
7 7 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
8 8 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*;
9 9 import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert;
10   -import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
11 10 import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO;
12 11 import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
13   -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillActivityDO;
14   -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
15 12 import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService;
16 13 import io.swagger.v3.oas.annotations.Operation;
17 14 import io.swagger.v3.oas.annotations.Parameter;
... ... @@ -23,8 +20,6 @@ import org.springframework.web.bind.annotation.*;
23 20 import javax.annotation.Resource;
24 21 import javax.validation.Valid;
25 22 import java.util.List;
26   -import java.util.Set;
27   -import java.util.stream.Collectors;
28 23  
29 24 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
30 25 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
... ... @@ -94,7 +89,7 @@ public class DiscountActivityController {
94 89 public CommonResult<PageResult<DiscountActivityRespVO>> getDiscountActivityPage(@Valid DiscountActivityPageReqVO pageVO) {
95 90 PageResult<DiscountActivityDO> pageResult = discountActivityService.getDiscountActivityPage(pageVO);
96 91  
97   - if (CollUtil.isEmpty(pageResult.getList())) {
  92 + if (CollUtil.isEmpty(pageResult.getList())) { // TODO @zhangshuai:方法里的空行,目的是让代码分块,可以更清晰;所以上面这个空格可以不要,而下面判断之后的,空格,其实加下比较好;类似的还有 spuList、以及后面的 convert
98 93 return success(PageResult.empty(pageResult.getTotal()));
99 94 }
100 95 // 拼接数据
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java
... ... @@ -26,15 +26,16 @@ public class DiscountActivityRespVO extends DiscountActivityBaseVO {
26 26 private LocalDateTime createTime;
27 27  
28 28  
29   - @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
  29 + @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") // TODO @zhangshuai:属性和属性之间,最多空一行噢;
30 30 private Long spuId;
31 31  
32 32 @Schema(description = "限时折扣商品", requiredMode = Schema.RequiredMode.REQUIRED)
33 33 private List<DiscountActivityBaseVO.Product> products;
34 34  
35   -
36 35 // ========== 商品字段 ==========
37 36  
  37 + // TODO @zhangshuai:一个优惠活动,会关联多个商品,所以它不用返回 spuName 哈;
  38 + // TODO 最终界面展示字段就:编号、活动名称、参与商品数、活动状态、开始时间、结束时间、操作
38 39 @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 name 读取
39 40 example = "618大促")
40 41 private String spuName;
... ... @@ -45,5 +46,4 @@ public class DiscountActivityRespVO extends DiscountActivityBaseVO {
45 46 example = "50")
46 47 private Integer marketPrice;
47 48  
48   -
49 49 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java
... ... @@ -7,11 +7,8 @@ import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
7 7 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
8 8 import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO;
9 9 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*;
10   -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO;
11   -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO;
12 10 import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO;
13 11 import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
14   -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.SeckillProductDO;
15 12 import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
16 13 import org.mapstruct.Mapper;
17 14 import org.mapstruct.factory.Mappers;
... ... @@ -47,7 +44,7 @@ public interface DiscountActivityConvert {
47 44 List<ProductSpuRespDTO> spuList) {
48 45 PageResult<DiscountActivityRespVO> pageResult = convertPage(page);
49 46  
50   - // 拼接商品
  47 + // 拼接商品 TODO @zhangshuai:类似空行的问题,也可以看看
51 48 Map<Long, DiscountProductDO> discountActivityMap = CollectionUtils.convertMap(discountProductDOList, DiscountProductDO::getActivityId);
52 49 Map<Long, ProductSpuRespDTO> spuMap = CollectionUtils.convertMap(spuList, ProductSpuRespDTO::getId);
53 50 pageResult.getList().forEach(item -> {
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java
... ... @@ -34,7 +34,6 @@ public class DiscountProductDO extends BaseDO {
34 34 */
35 35 private Long activityId;
36 36  
37   -
38 37 /**
39 38 * 商品 SPU 编号
40 39 *
... ... @@ -67,7 +66,6 @@ public class DiscountProductDO extends BaseDO {
67 66 */
68 67 private Integer discountPrice;
69 68  
70   - // TODO 芋艿:这几个字段,要新增下;
71 69 /**
72 70 * 活动状态
73 71 *
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java
... ... @@ -28,6 +28,6 @@ public interface DiscountProductMapper extends BaseMapperX&lt;DiscountProductDO&gt; {
28 28 return selectList(DiscountProductDO::getActivityId, activityIds);
29 29 }
30 30  
31   -
  31 + // TODO @zhangshuai:逻辑里,尽量避免写 join 语句哈,你可以看看这个查询,有什么办法优化?目前的一个思路,是分 2 次查询,性能也是 ok 的
32 32 List<DiscountProductDO> getMatchDiscountProductList(@Param("skuIds") Collection<Long> skuIds);
33 33 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java
... ... @@ -36,6 +36,8 @@ public interface CombinationActivityService {
36 36 */
37 37 void updateCombinationActivity(@Valid CombinationActivityUpdateReqVO updateReqVO);
38 38  
  39 + // TODO @puhui999:这里少了一个关闭活动的接口;因为关闭的活动,才可以删除
  40 +
39 41 /**
40 42 * 删除拼团活动
41 43 *
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java
... ... @@ -43,7 +43,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
43 43  
44 44 @Override
45 45 public List<DiscountProductDO> getMatchDiscountProductList(Collection<Long> skuIds) {
46   - // 芋艿:开启、满足 skuId、日期内
  46 + // TODO @zhangshuai:这里是不是可以直接 return discountProductMapper.getMatchDiscountProductList(skuIds); 一般来说,如果 idea 报“黄色”的警告,尽量都处理下哈;原则是,一切警告,皆为异常(错误),这样可以写出更好的代码。
47 47 List<DiscountProductDO> matchDiscountProductList = discountProductMapper.getMatchDiscountProductList(skuIds);
48 48 return matchDiscountProductList;
49 49 }
... ... @@ -55,9 +55,11 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
55 55  
56 56 // 插入活动
57 57 DiscountActivityDO discountActivity = DiscountActivityConvert.INSTANCE.convert(createReqVO)
  58 + // TODO @zhangshuai:这里的调用去掉哈,强制就是开启的;
58 59 .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getEndTime()));
59 60 discountActivityMapper.insert(discountActivity);
60 61 // 插入商品
  62 + // TODO @zhangshuai:activityStatus 最好代码里,也做下设置噢。
61 63 List<DiscountProductDO> discountProducts = convertList(createReqVO.getProducts(),
62 64 product -> DiscountActivityConvert.INSTANCE.convert(product).setActivityId(discountActivity.getId()));
63 65 discountProductMapper.insertBatch(discountProducts);
... ... @@ -84,6 +86,8 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
84 86 }
85 87  
86 88 private void updateDiscountProduct(DiscountActivityUpdateReqVO updateReqVO) {
  89 + // TODO @zhangshuai:这里的逻辑,可以优化下哈;参考 CombinationActivityServiceImpl 的 updateCombinationProduct,主要是 CollectionUtils.diffList 的使用哈;
  90 + // 然后原先是使用 DiscountActivityConvert.INSTANCE.isEquals 对比,现在看看是不是简化就基于 skuId 对比就完事了;之前写的太精细,意义不大;
87 91 List<DiscountProductDO> dbDiscountProducts = discountProductMapper.selectListByActivityId(updateReqVO.getId());
88 92 // 计算要删除的记录
89 93 List<Long> deleteIds = convertList(dbDiscountProducts, DiscountProductDO::getId,
... ... @@ -102,7 +106,6 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
102 106 }
103 107 }
104 108  
105   - // 芋艿:校验逻辑简化,只查询时间冲突的活动,开启状态的。
106 109 /**
107 110 * 校验商品是否冲突
108 111 *
... ... @@ -114,13 +117,11 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
114 117 return;
115 118 }
116 119 // 查询商品参加的活动
117   -
  120 + // TODO @zhangshuai:下面 121 这个查询,是不是不用做呀;直接 convert 出 skuId 集合就 ok 啦;
118 121 List<DiscountProductDO> list = discountProductMapper.selectListByActivityId(id);
  122 + // TODO @zhangshuai:一般简单的 stream 方法,建议是使用 CollectionUtils,例如说这里是 convertList 对把。
119 123 List<Long> skuIds = list.stream().map(item -> item.getSkuId()).collect(Collectors.toList());
120 124 List<DiscountProductDO> matchDiscountProductList = getMatchDiscountProductList(skuIds);
121   -// getRewardProductListBySkuIds(
122   -// convertSet(products, DiscountActivityBaseVO.Product::getSkuId),
123   -// asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus()));
124 125 if (id != null) { // 排除自己这个活动
125 126 matchDiscountProductList.removeIf(product -> id.equals(product.getActivityId()));
126 127 }
... ... @@ -133,15 +134,12 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
133 134 @Override
134 135 public void closeDiscountActivity(Long id) {
135 136 // 校验存在
136   - DiscountActivityDO dbDiscountActivity = validateDiscountActivityExists(id);
137   - if (dbDiscountActivity.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { // 已关闭的活动,不能关闭噢
  137 + DiscountActivityDO activity = validateDiscountActivityExists(id);
  138 + if (activity.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { // 已关闭的活动,不能关闭噢
138 139 throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED);
139 140 }
140   - if (dbDiscountActivity.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { // 已关闭的活动,不能关闭噢
141   - throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END);
142   - }
143 141  
144   - // 更新为关闭。
  142 + // 更新
145 143 DiscountActivityDO updateObj = new DiscountActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus());
146 144 discountActivityMapper.updateById(updateObj);
147 145 }
... ... @@ -185,4 +183,5 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
185 183 public List<DiscountProductDO> getDiscountProductsByActivityId(Collection<Long> activityIds) {
186 184 return discountProductMapper.selectList("activity_id", activityIds);
187 185 }
  186 +
188 187 }
... ...
yudao-server/pom.xml
... ... @@ -37,11 +37,11 @@
37 37 </dependency>
38 38  
39 39 <!-- 会员中心。默认注释,保证编译速度 -->
40   -<!-- <dependency>-->
41   -<!-- <groupId>cn.iocoder.boot</groupId>-->
42   -<!-- <artifactId>yudao-module-member-biz</artifactId>-->
43   -<!-- <version>${revision}</version>-->
44   -<!-- </dependency>-->
  40 + <dependency>
  41 + <groupId>cn.iocoder.boot</groupId>
  42 + <artifactId>yudao-module-member-biz</artifactId>
  43 + <version>${revision}</version>
  44 + </dependency>
45 45  
46 46 <!-- 数据报表。默认注释,保证编译速度 -->
47 47 <!-- <dependency>-->
... ... @@ -56,40 +56,40 @@
56 56 <!-- <version>${revision}</version>-->
57 57 <!-- </dependency>-->
58 58 <!-- 支付服务。默认注释,保证编译速度 -->
59   -<!-- <dependency>-->
60   -<!-- <groupId>cn.iocoder.boot</groupId>-->
61   -<!-- <artifactId>yudao-module-pay-biz</artifactId>-->
62   -<!-- <version>${revision}</version>-->
63   -<!-- </dependency>-->
  59 + <dependency>
  60 + <groupId>cn.iocoder.boot</groupId>
  61 + <artifactId>yudao-module-pay-biz</artifactId>
  62 + <version>${revision}</version>
  63 + </dependency>
64 64  
65 65 <!-- 微信公众号模块。默认注释,保证编译速度 -->
66   -<!-- <dependency>-->
67   -<!-- <groupId>cn.iocoder.boot</groupId>-->
68   -<!-- <artifactId>yudao-module-mp-biz</artifactId>-->
69   -<!-- <version>${revision}</version>-->
70   -<!-- </dependency>-->
  66 + <dependency>
  67 + <groupId>cn.iocoder.boot</groupId>
  68 + <artifactId>yudao-module-mp-biz</artifactId>
  69 + <version>${revision}</version>
  70 + </dependency>
71 71  
72   - <!-- 商城相关模块。默认注释,保证编译速度 -->
73   -<!-- <dependency>-->
74   -<!-- <groupId>cn.iocoder.boot</groupId>-->
75   -<!-- <artifactId>yudao-module-promotion-biz</artifactId>-->
76   -<!-- <version>${revision}</version>-->
77   -<!-- </dependency>-->
78   -<!-- <dependency>-->
79   -<!-- <groupId>cn.iocoder.boot</groupId>-->
80   -<!-- <artifactId>yudao-module-product-biz</artifactId>-->
81   -<!-- <version>${revision}</version>-->
82   -<!-- </dependency>-->
83   -<!-- <dependency>-->
84   -<!-- <groupId>cn.iocoder.boot</groupId>-->
85   -<!-- <artifactId>yudao-module-trade-biz</artifactId>-->
86   -<!-- <version>${revision}</version>-->
87   -<!-- </dependency>-->
88   -<!-- <dependency>-->
89   -<!-- <groupId>cn.iocoder.boot</groupId>-->
90   -<!-- <artifactId>yudao-module-statistics-biz</artifactId>-->
91   -<!-- <version>${revision}</version>-->
92   -<!-- </dependency>-->
  72 +<!-- 商城相关模块。默认注释,保证编译速度-->
  73 + <dependency>
  74 + <groupId>cn.iocoder.boot</groupId>
  75 + <artifactId>yudao-module-promotion-biz</artifactId>
  76 + <version>${revision}</version>
  77 + </dependency>
  78 + <dependency>
  79 + <groupId>cn.iocoder.boot</groupId>
  80 + <artifactId>yudao-module-product-biz</artifactId>
  81 + <version>${revision}</version>
  82 + </dependency>
  83 + <dependency>
  84 + <groupId>cn.iocoder.boot</groupId>
  85 + <artifactId>yudao-module-trade-biz</artifactId>
  86 + <version>${revision}</version>
  87 + </dependency>
  88 + <dependency>
  89 + <groupId>cn.iocoder.boot</groupId>
  90 + <artifactId>yudao-module-statistics-biz</artifactId>
  91 + <version>${revision}</version>
  92 + </dependency>
93 93  
94 94 <!-- spring boot 配置所需依赖 -->
95 95 <dependency>
... ...