Răsfoiți Sursa

review 拼团、秒杀活动的实现

YunaiV 1 an în urmă
părinte
comite
b84f7825c5
46 a modificat fișierele cu 197 adăugiri și 147 ștergeri
  1. 1 0
      yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
  2. 2 4
      yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
  3. 1 1
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java
  4. 4 2
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java
  5. 22 19
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java
  6. 4 3
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
  7. 1 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java
  8. 1 1
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java
  9. 2 2
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApi.java
  10. 1 0
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordReqDTO.java
  11. 2 2
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
  12. 3 2
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/combination/CombinationRecordStatusEnum.java
  13. 1 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java
  14. 10 8
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationActivityController.java
  15. 3 2
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityBaseVO.java
  16. 1 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityExcelVO.java
  17. 1 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityExportReqVO.java
  18. 1 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityRespVO.java
  19. 1 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductExcelVO.java
  20. 1 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductExportReqVO.java
  21. 16 6
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
  22. 1 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java
  23. 5 2
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/combinationactivity/CombinationActivityDO.java
  24. 6 4
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/combinationactivity/CombinationRecordDO.java
  25. 0 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/package-info.java
  26. 2 2
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java
  27. 1 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillconfig/SeckillConfigDO.java
  28. 1 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationActivityMapper.java
  29. 5 3
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationRecordMapper.java
  30. 0 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/package-info.java
  31. 0 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillconfig/SeckillConfigMapper.java
  32. 3 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java
  33. 14 9
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java
  34. 21 15
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java
  35. 1 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigServiceImpl.java
  36. 1 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java
  37. 1 0
      yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImplTest.java
  38. 8 16
      yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql
  39. 3 1
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
  40. 3 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java
  41. 8 4
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
  42. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDeliveryDO.java
  43. 1 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderDeliveryMapper.java
  44. 1 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java
  45. 30 27
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
  46. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java

+ 1 - 0
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java

@@ -70,6 +70,7 @@ public class LocalDateTimeUtils {
      * @param endTime2   校验所需的结束时间
      * @return 是否重叠
      */
+    // TODO @puhui999:LocalDateTimeUtil.isOverlap() 是不是可以满足呀?
     public static boolean checkTimeOverlap(LocalTime startTime1, LocalTime endTime1, LocalTime startTime2, LocalTime endTime2) {
         // 判断时间是否重叠
         // 开始时间在已配置时段的结束时间之前 且 结束时间在已配置时段的开始时间之后 []

+ 2 - 4
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java

@@ -45,10 +45,8 @@ public interface ErrorCodeConstants {
     ErrorCode SKU_STOCK_NOT_ENOUGH = new ErrorCode(1008006004, "商品 SKU 库存不足");
 
     // ========== 商品 评价 1008007000 ==========
-    ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1008007000, "商品 评价 不存在");
-    ErrorCode ORDER_SKU_COMMENT_EXISTS = new ErrorCode(1008007001, "订单 商品评价 已存在");
-    ErrorCode COMMENT_ERROR_OPT = new ErrorCode(1008007002, "商品评价非法操作");
-    ErrorCode COMMENT_ADDITIONAL_EXISTS  = new ErrorCode(1008007003, "商品追加评价已存在");
+    ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1008007000, "商品评价不存在");
+    ErrorCode COMMENT_ORDER_EXISTS = new ErrorCode(1008007001, "订单的商品评价已存在");
 
     // ========== 商品 收藏 1008008000 ==========
     ErrorCode FAVORITE_EXISTS = new ErrorCode(1008008000, "该商品已经被收藏");

+ 1 - 1
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java

@@ -10,7 +10,7 @@ import java.time.LocalDateTime;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
-@Schema(description = "管理后台 - 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的")
+@Schema(description = "管理后台 - 商品 SPU 导出 Request VO,参数和 ProductSpuPageReqVO 是一致的")
 @Data
 @NoArgsConstructor
 @AllArgsConstructor

+ 4 - 2
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java

@@ -51,14 +51,16 @@ public class AppProductCommentController {
             @Parameter(name = "spuId", description = "商品 SPU 编号", required = true, example = "1024"),
             @Parameter(name = "count", description = "数量", required = true, example = "10")
     })
-    public CommonResult<List<AppProductCommentRespVO>> getCommentList(@RequestParam("spuId") Long spuId,
-                                                                      @RequestParam(value = "count", defaultValue = "10") Integer count) {
+    public CommonResult<List<AppProductCommentRespVO>> getCommentList(
+            @RequestParam("spuId") Long spuId,
+            @RequestParam(value = "count", defaultValue = "10") Integer count) {
         return success(productCommentService.getCommentList(spuId, count));
     }
 
     @GetMapping("/page")
     @Operation(summary = "获得商品评价分页")
     public CommonResult<PageResult<AppProductCommentRespVO>> getCommentPage(@Valid AppCommentPageReqVO pageVO) {
+        // TODO @puhui999:写到 convert 里,可以更简洁哈。
         PageResult<ProductCommentDO> commentDOPage = productCommentService.getCommentPage(pageVO, Boolean.TRUE);
         Set<Long> skuIds = CollectionUtils.convertSet(commentDOPage.getList(), ProductCommentDO::getSkuId);
         List<ProductSkuDO> skuList = productSkuService.getSkuList(skuIds);

+ 22 - 19
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.convert.comment;
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO;
@@ -34,37 +35,33 @@ public interface ProductCommentConvert {
 
     ProductCommentRespVO convert(ProductCommentDO bean);
 
+    @Mapping(target = "scores", expression = "java(calculateOverallScore(goodCount, mediocreCount, negativeCount))")
+    AppCommentStatisticsRespVO convert(Long goodCount, Long mediocreCount, Long negativeCount);
     @Named("calculateOverallScore")
     default double calculateOverallScore(long goodCount, long mediocreCount, long negativeCount) {
         return (goodCount * 5 + mediocreCount * 3 + negativeCount) / (double) (goodCount + mediocreCount + negativeCount);
     }
-
-    @Mapping(target = "scores", expression = "java(calculateOverallScore(goodCount, mediocreCount, negativeCount))")
-    AppCommentStatisticsRespVO convert(Long goodCount, Long mediocreCount, Long negativeCount);
-
+    
     List<ProductCommentRespVO> convertList(List<ProductCommentDO> list);
 
-    List<AppProductPropertyValueDetailRespVO> convertList01(List<ProductSkuDO.Property> properties);
-
     PageResult<ProductCommentRespVO> convertPage(PageResult<ProductCommentDO> page);
 
     PageResult<AppProductCommentRespVO> convertPage01(PageResult<ProductCommentDO> pageResult);
 
-    default PageResult<AppProductCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult, Map<Long, ProductSkuDO> skuDOMap) {
+    default PageResult<AppProductCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult,
+                                                              Map<Long, ProductSkuDO> skuMap) {
         PageResult<AppProductCommentRespVO> page = convertPage01(pageResult);
         page.getList().forEach(item -> {
             // 判断用户是否选择匿名
             if (ObjectUtil.equal(item.getAnonymous(), true)) {
                 item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS);
             }
-            ProductSkuDO productSkuDO = skuDOMap.get(item.getSkuId());
-            if (productSkuDO != null) {
-                List<AppProductPropertyValueDetailRespVO> skuProperties = ProductCommentConvert.INSTANCE.convertList01(productSkuDO.getProperties());
-                item.setSkuProperties(skuProperties);
-            }
+            MapUtils.findAndThen(skuMap, item.getSkuId(),
+                    sku -> item.setSkuProperties(convertList01(sku.getProperties())));
         });
         return page;
     }
+    List<AppProductPropertyValueDetailRespVO> convertList01(List<ProductSkuDO.Property> properties);
 
     /**
      * 计算综合评分
@@ -83,14 +80,19 @@ public interface ProductCommentConvert {
 
     ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO);
 
-    @Mapping(target = "scores", expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))")
+    @Mapping(target = "scores",
+            expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))")
     default ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO, ProductSpuDO spuDO, MemberUserRespDTO user) {
         ProductCommentDO commentDO = convert(createReqDTO);
-        commentDO.setUserId(user.getId());
-        commentDO.setUserNickname(user.getNickname());
-        commentDO.setUserAvatar(user.getAvatar());
-        commentDO.setSpuId(spuDO.getId());
-        commentDO.setSpuName(spuDO.getName());
+        if (user != null) {
+            commentDO.setUserId(user.getId());
+            commentDO.setUserNickname(user.getNickname());
+            commentDO.setUserAvatar(user.getAvatar());
+        }
+        if (spuDO != null) {
+            commentDO.setSpuId(spuDO.getId());
+            commentDO.setSpuName(spuDO.getName());
+        }
         return commentDO;
     }
 
@@ -98,7 +100,8 @@ public interface ProductCommentConvert {
     @Mapping(target = "orderId", constant = "0L")
     @Mapping(target = "orderItemId", constant = "0L")
     @Mapping(target = "anonymous", expression = "java(Boolean.FALSE)")
-    @Mapping(target = "scores", expression = "java(convertScores(createReq.getDescriptionScores(), createReq.getBenefitScores()))")
+    @Mapping(target = "scores",
+            expression = "java(convertScores(createReq.getDescriptionScores(), createReq.getBenefitScores()))")
     ProductCommentDO convert(ProductCommentCreateReqVO createReq);
 
     List<AppProductCommentRespVO> convertList02(List<ProductCommentDO> list);

+ 4 - 3
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java

@@ -1,7 +1,6 @@
 package cn.iocoder.yudao.module.product.convert.spu;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
@@ -22,6 +21,7 @@ import java.util.List;
 import java.util.Map;
 
 import static cn.hutool.core.util.ObjectUtil.defaultIfNull;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
 
 /**
  * 商品 SPU Convert
@@ -110,8 +110,9 @@ public interface ProductSpuConvert {
     }
 
     default List<ProductSpuDetailRespVO> convertForSpuDetailRespListVO(List<ProductSpuDO> spus, List<ProductSkuDO> skus) {
-        ArrayList<ProductSpuDetailRespVO> vos = new ArrayList<>();
-        Map<Long, List<ProductSkuDO>> skuMultiMap = CollectionUtils.convertMultiMap(skus, ProductSkuDO::getSpuId);
+        List<ProductSpuDetailRespVO> vos = new ArrayList<>(spus.size());
+        Map<Long, List<ProductSkuDO>> skuMultiMap = convertMultiMap(skus, ProductSkuDO::getSpuId);
+        // TODO @puhui999:可以直接使用 CollUtils.convertList
         spus.forEach(spu -> {
             ProductSpuDetailRespVO detailRespVO = convert03(spu);
             detailRespVO.setSkus(ProductSkuConvert.INSTANCE.convertList(skuMultiMap.get(spu.getId())));

+ 1 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java

@@ -26,6 +26,7 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
     }
 
     static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) {
+        // TODO @puhui999:是不是不用 apply 拉?直接用 mybatis 的方法就好啦
         // 构建好评查询语句:好评计算 总评 >= 4
         if (ObjectUtil.equal(type, AppCommentPageReqVO.GOOD_COMMENT)) {
             queryWrapper.apply("scores >= 4");

+ 1 - 1
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java

@@ -112,7 +112,7 @@ public class ProductCommentServiceImpl implements ProductCommentService {
         // 判断当前订单的当前商品用户是否评价过
         ProductCommentDO exist = productCommentMapper.selectByUserIdAndOrderItemIdAndSpuId(userId, orderItemId, skuId);
         if (null != exist) {
-            throw exception(ORDER_SKU_COMMENT_EXISTS);
+            throw exception(COMMENT_ORDER_EXISTS);
         }
     }
 

+ 2 - 2
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApi.java

@@ -4,6 +4,8 @@ import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRe
 
 import javax.validation.Valid;
 
+// TODO @puhui999:CombinationRecordApi 分成活动、记录哈
+// TODO @芋艿:后面也再撸撸这几个接口
 /**
  * 拼团活动 API 接口
  *
@@ -26,7 +28,6 @@ public interface CombinationApi {
      */
     boolean validateRecordStatusIsSuccess(Long userId, Long orderId);
 
-
     /**
      * 更新开团记录状态
      *
@@ -42,7 +43,6 @@ public interface CombinationApi {
      * @param userId  用户编号
      * @param orderId 订单编号
      * @param status  状态值
-     * @return
      */
     void updateRecordStatusAndStartTime(Long userId, Long orderId, Integer status);
 

+ 1 - 0
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordReqDTO.java

@@ -5,6 +5,7 @@ import lombok.Data;
 import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
 
+// TODO @puhui999:CombinationRecordCreateReqDTO,这样更容易知道是创建噢
 /**
  * 拼团记录 Request DTO
  *

+ 2 - 2
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java

@@ -42,8 +42,7 @@ public interface ErrorCodeConstants {
     ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013006004, "满减送活动已关闭,不能重复关闭");
     ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1013006005, "满减送活动已结束,不能关闭");
 
-    // ========== Price 相关 1013007000 ============
-    ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1013007000, "支付价格计算异常,原因:价格小于等于 0");
+    // ========== TODO 空着 1013007000 ============
 
     // ========== 秒杀活动 1013008000 ==========
     ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1013008000, "秒杀活动不存在");
@@ -66,4 +65,5 @@ public interface ErrorCodeConstants {
     ErrorCode COMBINATION_ACTIVITY_STATUS_DISABLE = new ErrorCode(1013010002, "拼团活动已关闭不能修改");
     ErrorCode COMBINATION_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013010003, "拼团活动未关闭或未结束,不能删除");
     ErrorCode COMBINATION_RECORD_NOT_EXISTS = new ErrorCode(1013010004, "拼团不存在");
+
 }

+ 3 - 2
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/combination/CombinationRecordStatusEnum.java

@@ -14,8 +14,9 @@ import java.util.Arrays;
 @AllArgsConstructor
 @Getter
 public enum CombinationRecordStatusEnum implements IntArrayValuable {
-    NOT_PAY(0, "未付款"),
-    ONGOING(1, "进行中"),
+
+    WAITING(0, "未付款"),
+    IN_PROGRESS(1, "进行中"),
     SUCCESS(2, "拼团成功"),
     FAILED(3, "拼团失败");
 

+ 1 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java

@@ -14,6 +14,7 @@ import java.time.LocalDateTime;
  */
 @Service
 public class CombinationApiImpl implements CombinationApi {
+
     @Resource
     private CombinationActivityService activityService;
 

+ 10 - 8
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationActivityController.java

@@ -1,6 +1,5 @@
 package cn.iocoder.yudao.module.promotion.controller.admin.combination;
 
-import cn.hutool.core.collection.CollectionUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
@@ -28,6 +27,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 
+import static cn.hutool.core.collection.CollectionUtil.newArrayList;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
 
@@ -71,9 +71,9 @@ public class CombinationActivityController {
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
     @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')")
     public CommonResult<CombinationActivityRespVO> getCombinationActivity(@RequestParam("id") Long id) {
-        CombinationActivityDO combinationActivity = combinationActivityService.getCombinationActivity(id);
-        List<CombinationProductDO> productDOs = combinationActivityService.getProductsByActivityIds(CollectionUtil.newArrayList(id));
-        return success(CombinationActivityConvert.INSTANCE.convert(combinationActivity, productDOs));
+        CombinationActivityDO activity = combinationActivityService.getCombinationActivity(id);
+        List<CombinationProductDO> products = combinationActivityService.getProductsByActivityIds(newArrayList(id));
+        return success(CombinationActivityConvert.INSTANCE.convert(activity, products));
     }
 
     @GetMapping("/list")
@@ -88,13 +88,15 @@ public class CombinationActivityController {
     @GetMapping("/page")
     @Operation(summary = "获得拼团活动分页")
     @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')")
-    public CommonResult<PageResult<CombinationActivityRespVO>> getCombinationActivityPage(@Valid CombinationActivityPageReqVO pageVO) {
+    public CommonResult<PageResult<CombinationActivityRespVO>> getCombinationActivityPage(
+            @Valid CombinationActivityPageReqVO pageVO) {
         PageResult<CombinationActivityDO> pageResult = combinationActivityService.getCombinationActivityPage(pageVO);
+        // TODO @puhui999:可以不一定 aIds,直接批量查询结果出来;下面也是类似;
         Set<Long> aIds = CollectionUtils.convertSet(pageResult.getList(), CombinationActivityDO::getId);
-        List<CombinationProductDO> productDOs = combinationActivityService.getProductsByActivityIds(aIds);
+        List<CombinationProductDO> products = combinationActivityService.getProductsByActivityIds(aIds);
         Set<Long> spuIds = CollectionUtils.convertSet(pageResult.getList(), CombinationActivityDO::getSpuId);
-        List<ProductSpuRespDTO> spuList = spuApi.getSpuList(spuIds);
-        return success(CombinationActivityConvert.INSTANCE.convertPage(pageResult, productDOs, spuList));
+        List<ProductSpuRespDTO> spus = spuApi.getSpuList(spuIds);
+        return success(CombinationActivityConvert.INSTANCE.convertPage(pageResult, products, spus));
     }
 
     @GetMapping("/export-excel")

+ 3 - 2
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityBaseVO.java

@@ -20,7 +20,7 @@ public class CombinationActivityBaseVO {
     @NotNull(message = "拼团名称不能为空")
     private String name;
 
-    @Schema(description = "商品 SPU 编号关联 ProductSpuDO 的 id", example = "[1,2,3]")
+    @Schema(description = "商品 SPU 编号关联 ProductSpuDO 的 id", example = "[1,2,3]")
     @NotNull(message = "拼团商品不能为空")
     private Long spuId;
 
@@ -32,6 +32,7 @@ public class CombinationActivityBaseVO {
     @NotNull(message = "单次限购数量不能为空")
     private Integer singleLimitCount;
 
+    // TODO @puhui999:是不是弄成 2 个字段会好点哈。开始、结束
     @Schema(description = "活动时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
     @NotNull(message = "活动时间不能为空")
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@@ -42,7 +43,7 @@ public class CombinationActivityBaseVO {
     private Integer userSize;
 
     @Schema(description = "限制时长(小时)", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "限制时长(小时)不能为空")
+    @NotNull(message = "限制时长不能为空")
     private Integer limitDuration;
 
 }

+ 1 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityExcelVO.java

@@ -7,7 +7,7 @@ import lombok.Data;
 
 import java.time.LocalDateTime;
 
-
+// TODO @puhui999:如无必要,导出都可以删除哈
 /**
  * 拼团活动 Excel VO
  *

+ 1 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityExportReqVO.java

@@ -8,6 +8,7 @@ import java.time.LocalDateTime;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
+// TODO @puhui999:如无必要,导出都可以删除哈
 @Schema(description = "管理后台 - 拼团活动 Excel 导出 Request VO,参数和 CombinationActivityPageReqVO 是一致的")
 @Data
 public class CombinationActivityExportReqVO {

+ 1 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityRespVO.java

@@ -45,7 +45,7 @@ public class CombinationActivityRespVO extends CombinationActivityBaseVO {
     @NotNull(message = "虚拟成团不能为空")
     private Integer virtualGroup;
 
-    @Schema(description = "活动状态:0开启 1关闭", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
+    @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
     @NotNull(message = "活动状态不能为空")
     private Integer status;
 

+ 1 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductExcelVO.java

@@ -5,6 +5,7 @@ import lombok.Data;
 
 import java.time.LocalDateTime;
 
+// TODO @puhui999:可以考虑删除 excel 导出哈
 /**
  * 拼团商品 Excel VO
  *

+ 1 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductExportReqVO.java

@@ -8,6 +8,7 @@ import java.time.LocalDateTime;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
+// TODO @puhui999:可以考虑删除 excel 导出哈
 @Schema(description = "管理后台 - 拼团商品 Excel 导出 Request VO,参数和 CombinationProductPageReqVO 是一致的")
 @Data
 public class CombinationProductExportReqVO {

+ 16 - 6
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java

@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.promotion.convert.combination;
 
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordReqDTO;
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
@@ -26,6 +25,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
+
 /**
  * 拼团活动 Convert
  *
@@ -74,13 +75,17 @@ public interface CombinationActivityConvert {
 
     PageResult<CombinationActivityRespVO> convertPage(PageResult<CombinationActivityDO> page);
 
-    default PageResult<CombinationActivityRespVO> convertPage(PageResult<CombinationActivityDO> page, List<CombinationProductDO> productDOList, List<ProductSpuRespDTO> spuList) {
-        Map<Long, ProductSpuRespDTO> spuMap = CollectionUtils.convertMap(spuList, ProductSpuRespDTO::getId, c -> c);
+    default PageResult<CombinationActivityRespVO> convertPage(PageResult<CombinationActivityDO> page,
+                                                              List<CombinationProductDO> productList,
+                                                              List<ProductSpuRespDTO> spuList) {
+        // TODO @puhui999:c -> c 可以去掉哈
+        Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId, c -> c);
         PageResult<CombinationActivityRespVO> pageResult = convertPage(page);
         pageResult.getList().forEach(item -> {
+            // TODO @puhui999:最好 MapUtils.findAndThen,万一没找到呢,啊哈哈。
             item.setSpuName(spuMap.get(item.getSpuId()).getName());
             item.setPicUrl(spuMap.get(item.getSpuId()).getPicUrl());
-            item.setProducts(convertList2(productDOList));
+            item.setProducts(convertList2(productList));
         });
         return pageResult;
     }
@@ -111,12 +116,17 @@ public interface CombinationActivityConvert {
         return list;
     }
 
-    default List<CombinationProductDO> convertList1(CombinationActivityDO activityDO, List<CombinationProductUpdateReqVO> vos, List<CombinationProductDO> productDOs) {
-        Map<Long, Long> longMap = CollectionUtils.convertMap(productDOs, CombinationProductDO::getSkuId, CombinationProductDO::getId);
+    // TODO @puhui999:这个方法的参数,调整成 productDOs、vos、activityDO;因为 productDOs 是主角;
+    // 然后,这个方法,感觉不是为了 convert,而是为了补全;
+    default List<CombinationProductDO> convertList1(CombinationActivityDO activityDO,
+                                                    List<CombinationProductUpdateReqVO> vos,
+                                                    List<CombinationProductDO> productDOs) {
+        Map<Long, Long> longMap = convertMap(productDOs, CombinationProductDO::getSkuId, CombinationProductDO::getId);
         List<CombinationProductDO> list = new ArrayList<>();
         vos.forEach(sku -> {
             CombinationProductDO productDO = convert(activityDO, sku);
             productDO.setId(longMap.get(sku.getSkuId()));
+            // TODO @puhui999:是是不是用 activityDO 的状态;
             productDO.setActivityStatus(CommonStatusEnum.ENABLE.getStatus());
             list.add(productDO);
         });

+ 1 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java

@@ -84,6 +84,7 @@ public interface SeckillActivityConvert {
         return list;
     }
 
+    // TODO @puhui999:同拼团那个 convert 想通的情况哈。
     default List<SeckillProductDO> convertList1(SeckillActivityDO activityDO, List<SeckillProductUpdateReqVO> vos, List<SeckillProductDO> productDOs) {
         Map<Long, Long> longMap = CollectionUtils.convertMap(productDOs, SeckillProductDO::getSkuId, SeckillProductDO::getId);
         List<SeckillProductDO> list = new ArrayList<>();

+ 5 - 2
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/combinationactivity/CombinationActivityDO.java

@@ -9,6 +9,7 @@ import lombok.*;
 
 import java.time.LocalDateTime;
 
+// TODO @puhui999:是不是应该在 combination 哈?
 /**
  * 拼团活动 DO
  *
@@ -34,7 +35,9 @@ public class CombinationActivityDO extends BaseDO {
      */
     private String name;
     /**
-     * 商品 SPU 编号关联 ProductSpuDO 的 id
+     * 商品 SPU 编号
+     *
+     * 关联 ProductSpuDO 的 id
      */
     private Long spuId;
     /**
@@ -75,7 +78,7 @@ public class CombinationActivityDO extends BaseDO {
     private Integer virtualGroup;
     /**
      * 活动状态:0开启 1关闭
-     * <p>
+     *
      * 枚举 {@link CommonStatusEnum}
      */
     private Integer status;

+ 6 - 4
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/combinationactivity/CombinationRecordDO.java

@@ -31,11 +31,11 @@ public class CombinationRecordDO extends BaseDO {
      */
     private Long activityId;
     /**
-     * spu 编号
+     * SPU 编号
      */
     private Long spuId;
     /**
-     * sku 编号
+     * SKU 编号
      */
     private Long skuId;
     /**
@@ -48,7 +48,7 @@ public class CombinationRecordDO extends BaseDO {
     private Long orderId;
     /**
      * 团长编号
-     * <p>
+     *
      * 关联 {@link CombinationRecordDO#getUserId()}
      */
     private Long headId;
@@ -84,7 +84,8 @@ public class CombinationRecordDO extends BaseDO {
     private Boolean virtualGroup;
     /**
      * 过期时间,单位:小时
-     * 关联关联 {@link CombinationActivityDO#getLimitDuration()}
+     *
+     * 关联 {@link CombinationActivityDO#getLimitDuration()}
      */
     private Integer expireTime;
     /**
@@ -97,6 +98,7 @@ public class CombinationRecordDO extends BaseDO {
     private LocalDateTime endTime;
     /**
      * 开团需要人数
+     *
      * 关联 {@link CombinationActivityDO#getUserSize()}
      */
     private Integer userSize;

+ 0 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/package-info.java

@@ -1 +0,0 @@
-package cn.iocoder.yudao.module.promotion.dal.dataobject.combination;

+ 2 - 2
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java

@@ -47,11 +47,11 @@ public class SeckillProductDO extends BaseDO {
     @TableField(typeHandler = LongListTypeHandler.class)
     private List<Long> configIds;
     /**
-     * 商品 spu_id
+     * 商品 SPU 编号
      */
     private Long spuId;
     /**
-     * 商品 sku_id
+     * 商品 SKU 编号
      */
     private Long skuId;
     /**

+ 1 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillconfig/SeckillConfigDO.java

@@ -50,7 +50,7 @@ public class SeckillConfigDO extends BaseDO {
     private List<String> sliderPicUrls;
     /**
      * 状态
-     * <p>
+     *
      * 枚举 {@link CommonStatusEnum 对应的类}
      */
     private Integer status;

+ 1 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationActivityMapper.java

@@ -10,6 +10,7 @@ import org.apache.ibatis.annotations.Mapper;
 
 import java.util.List;
 
+// TODO @puhui999:是不是应该在 combination 哈?
 /**
  * 拼团活动 Mapper
  *

+ 5 - 3
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationRecordMapper.java

@@ -16,16 +16,18 @@ import java.util.List;
 public interface CombinationRecordMapper extends BaseMapperX<CombinationRecordDO> {
 
     default CombinationRecordDO selectRecord(Long userId, Long orderId) {
-        return selectOne(CombinationRecordDO::getUserId, userId, CombinationRecordDO::getOrderId, orderId);
+        return selectOne(CombinationRecordDO::getUserId, userId,
+                CombinationRecordDO::getOrderId, orderId);
     }
 
     default List<CombinationRecordDO> selectListByHeadIdAndStatus(Long headId, Integer status) {
-        return selectList(new LambdaQueryWrapperX<CombinationRecordDO>().eq(CombinationRecordDO::getHeadId, headId)
+        return selectList(new LambdaQueryWrapperX<CombinationRecordDO>()
+                .eq(CombinationRecordDO::getHeadId, headId)
                 .eq(CombinationRecordDO::getStatus, status));
     }
 
     default List<CombinationRecordDO> selectListByStatus(Integer status) {
-        return selectList(new LambdaQueryWrapperX<CombinationRecordDO>().eq(CombinationRecordDO::getStatus, status));
+        return selectList(CombinationRecordDO::getStatus, status);
     }
 
 }

+ 0 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/package-info.java

@@ -1 +0,0 @@
-package cn.iocoder.yudao.module.promotion.dal.mysql.combination;

+ 0 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillconfig/SeckillConfigMapper.java

@@ -23,5 +23,4 @@ public interface SeckillConfigMapper extends BaseMapperX<SeckillConfigDO> {
         return selectList(SeckillConfigDO::getStatus, status);
     }
 
-
 }

+ 3 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java

@@ -83,6 +83,7 @@ public interface CombinationActivityService {
      */
     List<CombinationProductDO> getProductsByActivityIds(Collection<Long> ids);
 
+    // TODO @puhui999:拆一个 CombinationRecordService 里,方法名可以简洁成 updateRecordStatusByOrderId;service 方法可以稍微简单一点,如果是 update 方法
     /**
      * 更新拼团状态
      *
@@ -99,10 +100,10 @@ public interface CombinationActivityService {
      * @param orderId   订单编号
      * @param status    状态
      * @param startTime 开始时间
-     * @return
      */
     void updateRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, Integer status, LocalDateTime startTime);
 
+    // TODO @puhui999:拆一个 CombinationRecordService 里
     /**
      * 创建拼团记录
      *
@@ -118,4 +119,5 @@ public interface CombinationActivityService {
      * @return 拼团状态
      */
     boolean validateRecordStatusIsSuccess(Long userId, Long orderId);
+
 }

+ 14 - 9
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java

@@ -254,28 +254,33 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
     @Override
     public void createRecord(CombinationRecordReqDTO reqDTO) {
         // 校验拼团活动
-        CombinationActivityDO activityDO = validateCombinationActivityExists(reqDTO.getActivityId());
+        CombinationActivityDO activity = validateCombinationActivityExists(reqDTO.getActivityId());
+        // TODO @puhui999:需要校验下,它当前是不是已经参加了该拼团;
+        // TODO @puhui999: 父拼团是否存在,是否已经满了
 
-        CombinationRecordDO recordDO = CombinationActivityConvert.INSTANCE.convert(reqDTO);
-        recordDO.setVirtualGroup(false);
-        recordDO.setExpireTime(activityDO.getLimitDuration());
-        recordDO.setUserSize(activityDO.getUserSize());
-        recordMapper.insert(recordDO);
+        CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO);
+        record.setVirtualGroup(false);
+        // TODO @puhui999:过期时间,应该是 Date 哈;
+        record.setExpireTime(activity.getLimitDuration());
+        record.setUserSize(activity.getUserSize());
+        recordMapper.insert(record);
     }
 
     @Override
     public boolean validateRecordStatusIsSuccess(Long userId, Long orderId) {
-        CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId);
-        return ObjectUtil.equal(recordDO.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus());
+        CombinationRecordDO record = validateCombinationRecord(userId, orderId);
+        // TODO @puhui999:可以搞个 getRecrod 方法,然后业务通过 CombinationRecordStatusEnum.isSuccess 方法校验
+        return ObjectUtil.equal(record.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus());
     }
 
+    // TODO @puhui999:status 传入进来搞哈;
     /**
      * APP 端获取开团记录
      *
      * @return 开团记录
      */
     public List<CombinationRecordDO> getRecordList() {
-        return recordMapper.selectListByStatus(CombinationRecordStatusEnum.ONGOING.getStatus());
+        return recordMapper.selectListByStatus(CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
     }
 
 }

+ 21 - 15
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java

@@ -60,9 +60,10 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
     public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) {
         // 校验商品秒秒杀时段是否冲突
         validateProductSpuSeckillConflict(createReqVO.getConfigIds(), createReqVO.getSpuId(), null);
-        // 获取所选 spu下的所有 sku
+        // 获取所选 spu 下的所有 sku
         List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollUtil.newArrayList(createReqVO.getSpuId()));
         // 校验商品 sku 是否存在
+        // TODO @puhui999:直接校验 sku 数量,是不是就完事啦,不需要校验的特别严谨哈;
         validateProductSkuExistence(skus, createReqVO.getProducts(), SeckillProductCreateReqVO::getSkuId);
 
         // 插入秒杀活动
@@ -71,6 +72,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
                 .setTotalStock(CollectionUtils.getSumValue(createReqVO.getProducts(), SeckillProductCreateReqVO::getStock, Integer::sum));
         seckillActivityMapper.insert(activity);
         // 插入商品
+        // TODO @puhui999:products 要注意复数哈
         List<SeckillProductDO> product = SeckillActivityConvert.INSTANCE.convertList(activity, createReqVO.getProducts());
         seckillProductMapper.insertBatch(product);
         return activity.getId();
@@ -97,6 +99,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
         }
         List<SeckillActivityDO> activityDOs2 = CollectionUtils.convertList(activityDOs, c -> c, s -> {
             // 判断秒杀时段是否有交集
+            // TODO @puhui999:是不是 containsAny 就是有交集呀
             List<Long> configIdsClone = CollUtil.newArrayList(s.getConfigIds());
             configIdsClone.retainAll(configIds);
             return CollUtil.isNotEmpty(configIdsClone);
@@ -134,29 +137,32 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
     /**
      * 更新秒杀商品
      *
-     * @param updateObj DO
+     * @param updateObj 更新的活动
      * @param products  商品配置
      */
+    // TODO @puhui999:我在想,我们是不是可以封装一个 CollUtil 的方法,传入两个数组,判断出哪些是新增、哪些是修改、哪些是删除;
+    // 例如说,products 先转化成 SeckillProductDO;然后,基于一个 func(key1, key2) 做比对;
+    // 如果可以跑通,所有涉及到这种逻辑的,都可以服用哈。
     private void updateSeckillProduct(SeckillActivityDO updateObj, List<SeckillProductUpdateReqVO> products) {
-        List<SeckillProductDO> seckillProductDOs = seckillProductMapper.selectListByActivityId(updateObj.getId());
         // 数据库中的活动商品
-        Set<Long> convertSet = CollectionUtils.convertSet(seckillProductDOs, SeckillProductDO::getSkuId);
-        // 前端传过来的活动商品
-        Set<Long> convertSet1 = CollectionUtils.convertSet(products, SeckillProductUpdateReqVO::getSkuId);
-        // 删除后台存在的前端不存在的商品
-        List<Long> d = CollectionUtils.filterList(convertSet, item -> !convertSet1.contains(item));
+        List<SeckillProductDO> seckillProductDOs = seckillProductMapper.selectListByActivityId(updateObj.getId());
+        Set<Long> dbSkuIds = CollectionUtils.convertSet(seckillProductDOs, SeckillProductDO::getSkuId);
+        // 1. 删除后台存在的前端不存在的商品
+        // TODO @puhui999:delete 应该是 id,不是 skuId 哈
+        Set<Long> voSkuIds = CollectionUtils.convertSet(products, SeckillProductUpdateReqVO::getSkuId);
+        List<Long> d = CollectionUtils.filterList(dbSkuIds, item -> !voSkuIds.contains(item));
         if (CollUtil.isNotEmpty(d)) {
             seckillProductMapper.deleteBatchIds(d);
         }
-        // 前端存在的后端不存在的商品
-        List<Long> c = CollectionUtils.filterList(convertSet1, item -> !convertSet.contains(item));
+        // 2. 前端存在的后端不存在的商品
+        List<Long> c = CollectionUtils.filterList(voSkuIds, item -> !dbSkuIds.contains(item));
         if (CollUtil.isNotEmpty(c)) {
             List<SeckillProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> c.contains(item.getSkuId()));
             List<SeckillProductDO> productDOs = SeckillActivityConvert.INSTANCE.convertList(updateObj, vos);
             seckillProductMapper.insertBatch(productDOs);
         }
-        // 更新已存在的商品
-        List<Long> u = CollectionUtils.filterList(convertSet1, convertSet::contains);
+        // 3. 更新已存在的商品
+        List<Long> u = CollectionUtils.filterList(voSkuIds, dbSkuIds::contains);
         if (CollUtil.isNotEmpty(u)) {
             List<SeckillProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> u.contains(item.getSkuId()));
             List<SeckillProductDO> productDOs = SeckillActivityConvert.INSTANCE.convertList1(updateObj, vos, seckillProductDOs);
@@ -165,12 +171,12 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
     }
 
     @Override
-    @Transactional(rollbackFor = Exception.class)
+    @Transactional(rollbackFor = Exception.class) // TODO @puhui999:这个不用加事务哈
     public void closeSeckillActivity(Long id) {
         // TODO 待验证没使用过
         // 校验存在
-        SeckillActivityDO seckillActivity = validateSeckillActivityExists(id);
-        if (CommonStatusEnum.DISABLE.getStatus().equals(seckillActivity.getStatus())) {
+        SeckillActivityDO activity = validateSeckillActivityExists(id);
+        if (CommonStatusEnum.DISABLE.getStatus().equals(activity.getStatus())) {
             throw exception(SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED);
         }
 

+ 1 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigServiceImpl.java

@@ -151,6 +151,7 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
         return seckillConfigMapper.selectPage(pageVO);
     }
 
+    // TODO @puhui999:改成传入 enable 状态哈。一个通用的 getSeckillConfigList 方法
     @Override
     public List<SeckillConfigDO> getListAllSimple() {
         return seckillConfigMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());

+ 1 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java

@@ -31,6 +31,7 @@ public class PromotionUtils {
         return LocalDateTimeUtils.beforeNow(endTime) ? CommonStatusEnum.DISABLE.getStatus() : CommonStatusEnum.ENABLE.getStatus();
     }
 
+    // TODO @puhui999:写个注释哈。
     public static <T> void validateProductSkuExistence(List<ProductSkuRespDTO> skus, List<T> products, Function<T, Long> func) {
         // 校验 sku 个数是否一致
         Set<Long> skuIdsSet = CollectionUtils.convertSet(products, func);

+ 1 - 0
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImplTest.java

@@ -24,6 +24,7 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_ACTIVITY_NOT_EXISTS;
 import static org.junit.jupiter.api.Assertions.*;
 
+// TODO 芋艿:等完成后,在补全单测
 /**
  * {@link CombinationActivityServiceImpl} 的单元测试类
  *

+ 8 - 16
yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql

@@ -1,16 +1,8 @@
-DELETE
-FROM "market_activity";
-DELETE
-FROM "promotion_coupon_template";
-DELETE
-FROM "promotion_coupon";
-DELETE
-FROM "promotion_reward_activity";
-DELETE
-FROM "promotion_discount_activity";
-DELETE
-FROM "promotion_discount_product";
-DELETE
-FROM "promotion_seckill_config";
-DELETE
-FROM "promotion_combination_activity";
+DELETE FROM "market_activity";
+DELETE FROM "promotion_coupon_template";
+DELETE FROM "promotion_coupon";
+DELETE FROM "promotion_reward_activity";
+DELETE FROM "promotion_discount_activity";
+DELETE FROM "promotion_discount_product";
+DELETE FROM "promotion_seckill_config";
+DELETE FROM "promotion_combination_activity";

+ 3 - 1
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java

@@ -70,7 +70,9 @@ public interface ErrorCodeConstants {
     ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011006000, "自提门店不存在");
 
     // ==========  物流 PICK_UP 模块 1011007000 ==========
+    // TODO @puhui999:这几个错误码,应该属于订单哈
     ErrorCode ORDER_DELIVERY_FAILED_ITEMS_NOT_EMPTY = new ErrorCode(1011007000, "订单发货失败,请选择发货商品");
     ErrorCode ORDER_DELIVERY_FAILED_ITEM_NOT_EXISTS = new ErrorCode(1011007001, "订单发货失败,所选发货商品不存在");
-    ErrorCode ORDER_DELIVERY_FAILED_ITEM_ALREADY_DELIVERY = new ErrorCode(1011007001, "订单发货失败,所选商品已发货");
+    ErrorCode ORDER_DELIVERY_FAILED_ITEM_ALREADY_DELIVERY = new ErrorCode(1011007002, "订单发货失败,所选商品已发货");
+
 }

+ 3 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java

@@ -21,13 +21,15 @@ public class TradeOrderDeliveryReqVO {
     @NotNull(message = "发货类型不能为空")
     private Integer type;
 
+    // TODO @puhui999:还是要校验下
+
     @Schema(description = "发货物流公司编号", example = "1")
     private Long logisticsId;
 
     @Schema(description = "发货物流单号", example = "SF123456789")
     private String logisticsNo;
 
-    // TODO 订单项商品单独发货
+    // TODO 订单项商品单独发货;不做单独发
 
     @Schema(description = "发货订单项", example = "[1,2,3]")
     @NotNull(message = "发货订单项不能为空")

+ 8 - 4
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java

@@ -108,13 +108,17 @@ public class AppTradeOrderController {
         // 全部
         orderCount.put("allCount", tradeOrderService.getOrderCount(getLoginUserId(), null, null));
         // 待付款(未支付)
-        orderCount.put("unpaidCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.UNPAID.getStatus(), null));
+        orderCount.put("unpaidCount", tradeOrderService.getOrderCount(getLoginUserId(),
+                TradeOrderStatusEnum.UNPAID.getStatus(), null));
         // 待发货
-        orderCount.put("undeliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.UNDELIVERED.getStatus(), null));
+        orderCount.put("undeliveredCount", tradeOrderService.getOrderCount(getLoginUserId(),
+                TradeOrderStatusEnum.UNDELIVERED.getStatus(), null));
         // 待收货
-        orderCount.put("deliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.DELIVERED.getStatus(), null));
+        orderCount.put("deliveredCount", tradeOrderService.getOrderCount(getLoginUserId(),
+                TradeOrderStatusEnum.DELIVERED.getStatus(), null));
         // 待评价
-        orderCount.put("uncommentedCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.COMPLETED.getStatus(), false));
+        orderCount.put("uncommentedCount", tradeOrderService.getOrderCount(getLoginUserId(),
+                TradeOrderStatusEnum.COMPLETED.getStatus(), false));
         return success(orderCount);
     }
 

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDeliveryDO.java

@@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.*;
 
-
+// TODO @puhui999:
 /**
  * 交易订单发货记录 DO
  *

+ 1 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderDeliveryMapper.java

@@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.Mapper;
 
 import java.util.List;
 
+// TODO @puhui999:应该去掉啦
 /**
  * 交易订单发货记录 Mapper
  *

+ 1 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java

@@ -180,8 +180,7 @@ public interface TradeOrderService {
     TradeOrderDO getOrderByIdAndUserId(Long orderId, Long loginUserId);
 
     /**
-     * 创建订单项评论
-     * 创建交易订单项的评价
+     * 创建订单项的评论
      *
      * @param createReqVO 创建请求
      * @return 得到评价 id

+ 30 - 27
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java

@@ -178,7 +178,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
             MemberUserRespDTO user = memberUserApi.getUser(userId);
             // TODO 拼团一次应该只能选择一种规格的商品
             combinationApi.createRecord(TradeOrderConvert.INSTANCE.convert(order, orderItems.get(0), createReqVO, user)
-                    .setStatus(CombinationRecordStatusEnum.NOT_PAY.getStatus()));
+                    .setStatus(CombinationRecordStatusEnum.WAITING.getStatus()));
         }
         // TODO 秒杀扣减库存是下单就扣除还是等待订单支付成功再扣除
         if (ObjectUtil.equal(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) {
@@ -204,23 +204,6 @@ public class TradeOrderServiceImpl implements TradeOrderService {
         return address;
     }
 
-    /**
-     * 校验活动返回订单类型
-     *
-     * @param createReqVO 请求参数
-     * @return 订单类型
-     */
-    private Integer validateActivity(AppTradeOrderCreateReqVO createReqVO) {
-        if (createReqVO.getSeckillActivityId() != null) {
-            return TradeOrderTypeEnum.SECKILL.getType();
-        }
-        if (createReqVO.getCombinationActivityId() != null) {
-            return TradeOrderTypeEnum.COMBINATION.getType();
-        }
-        // TODO 砍价敬请期待
-        return TradeOrderTypeEnum.NORMAL.getType();
-    }
-
     private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO,
                                           TradePriceCalculateRespBO calculateRespBO) {
         // 用户选择物流配送的时候才需要填写收货地址
@@ -246,6 +229,23 @@ public class TradeOrderServiceImpl implements TradeOrderService {
         return order;
     }
 
+    /**
+     * 校验活动,并返回订单类型
+     *
+     * @param createReqVO 请求参数
+     * @return 订单类型
+     */
+    private Integer validateActivity(AppTradeOrderCreateReqVO createReqVO) {
+        if (createReqVO.getSeckillActivityId() != null) {
+            return TradeOrderTypeEnum.SECKILL.getType();
+        }
+        if (createReqVO.getCombinationActivityId() != null) {
+            return TradeOrderTypeEnum.COMBINATION.getType();
+        }
+        // TODO 砍价敬请期待
+        return TradeOrderTypeEnum.NORMAL.getType();
+    }
+
     private List<TradeOrderItemDO> createTradeOrderItems(TradeOrderDO tradeOrderDO, TradePriceCalculateRespBO calculateRespBO) {
         List<TradeOrderItemDO> orderItems = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO);
         tradeOrderItemMapper.insertBatch(orderItems);
@@ -314,7 +314,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
         // 1、拼团活动
         if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
             // 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录
-            combinationApi.updateRecordStatusAndStartTime(order.getUserId(), order.getId(), CombinationRecordStatusEnum.ONGOING.getStatus());
+            combinationApi.updateRecordStatusAndStartTime(order.getUserId(), order.getId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
         }
         // TODO 芋艿:发送订单变化的消息
 
@@ -422,6 +422,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
         orderDeliveryMapper.insertBatch(deliveryDOs);
         // TODO 芋艿:发送订单变化的消息
 
+        // TODO @puhui999:可以抽个 message 包,里面是 Order 所有的 message;类似工作流的
         // 发送站内信
         // 1、构造消息
         Map<String, Object> msgMap = new HashMap<>();
@@ -684,24 +685,26 @@ public class TradeOrderServiceImpl implements TradeOrderService {
     @Override
     public Long createOrderItemComment(AppTradeOrderItemCommentCreateReqVO createReqVO) {
         Long loginUserId = getLoginUserId();
-        // 先通过订单项 ID 查询订单项是否存在
-        TradeOrderItemDO orderItemDO = getOrderItemByIdAndUserId(createReqVO.getOrderItemId(), loginUserId);
-        if (orderItemDO == null) {
+        // 先通过订单项 ID查询订单项是否存在
+        TradeOrderItemDO orderItem = getOrderItemByIdAndUserId(createReqVO.getOrderItemId(), loginUserId);
+        if (orderItem == null) {
             throw exception(ORDER_ITEM_NOT_FOUND);
         }
         // 校验订单
-        TradeOrderDO orderDO = getOrderByIdAndUserId(orderItemDO.getOrderId(), loginUserId);
-        if (orderDO == null) {
+        TradeOrderDO order = getOrderByIdAndUserId(orderItem.getOrderId(), loginUserId);
+        if (order == null) {
             throw exception(ORDER_NOT_FOUND);
         }
-        if (ObjectUtil.notEqual(orderDO.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus())) {
+        if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus())) {
             throw exception(ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED);
         }
-        if (ObjectUtil.notEqual(orderDO.getCommentStatus(), Boolean.FALSE)) {
+        if (ObjectUtil.notEqual(order.getCommentStatus(), Boolean.FALSE)) {
             throw exception(ORDER_COMMENT_STATUS_NOT_FALSE);
         }
+        // TODO @puhui999:是不是评论完,要更新 status、commentStatus;另外,是不是上面 order 可以不校验,直接只判断 orderItem 就够;
+        // 对于 order 来说,就是评论完,把 order 更新完合理的 status 等字段。
 
-        ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItemDO);
+        ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItem);
         return productCommentApi.createComment(productCommentCreateReqDTO);
     }
 

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java

@@ -21,7 +21,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
-import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL;
+import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL;
 
 /**
  * 价格计算 Service 实现类