Explorar o código

trade:1、重构 order handler 的参数;2、增加砍价商品的价格计算

YunaiV hai 1 ano
pai
achega
8dbabb9efc
Modificáronse 35 ficheiros con 365 adicións e 423 borrados
  1. 13 0
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApi.java
  2. 1 0
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/dto/BargainRecordCreateReqDTO.java
  3. 25 0
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/dto/BargainValidateJoinRespDTO.java
  4. 2 1
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java
  5. 3 0
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
  6. 39 0
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/bargain/BargainRecordStatusEnum.java
  7. 2 2
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java
  8. 12 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java
  9. 7 5
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainRecordDO.java
  10. 5 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainRecordMapper.java
  11. 13 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java
  12. 58 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java
  13. 1 9
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java
  14. 0 12
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java
  15. 3 4
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java
  16. 3 38
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
  17. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderLogConvert.java
  18. 13 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
  19. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java
  20. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderLogService.java
  21. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderLogServiceImpl.java
  22. 34 46
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
  23. 0 87
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/TradeAfterOrderCreateReqBO.java
  24. 0 43
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/TradeAfterPayOrderReqBO.java
  25. 0 94
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/TradeBeforeOrderCreateReqBO.java
  26. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/TradeOrderLogCreateReqBO.java
  27. 7 12
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBargainHandler.java
  28. 33 39
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java
  29. 12 9
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeOrderHandler.java
  30. 7 12
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeSeckillHandler.java
  31. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java
  32. 5 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java
  33. 55 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeBargainActivityPriceCalculator.java
  34. 4 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java
  35. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeSeckillActivityPriceCalculator.java

+ 13 - 0
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApi.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.promotion.api.bargain;
 
 import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainRecordCreateReqDTO;
+import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO;
 
 import javax.validation.Valid;
 
@@ -20,4 +21,16 @@ public interface BargainRecordApi {
      */
     void createBargainRecord(@Valid BargainRecordCreateReqDTO reqDTO);
 
+    /**
+     * 【下单前】校验是否参与砍价活动
+     * <p>
+     * 如果校验失败,则抛出业务异常
+     *
+     * @param userId          用户编号
+     * @param bargainRecordId 砍价活动编号
+     * @param skuId           SKU 编号
+     * @return 砍价信息
+     */
+    BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId);
+
 }

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

@@ -51,6 +51,7 @@ public class BargainRecordCreateReqDTO {
     @NotNull(message = "商品原价不能为空")
     private Integer price;
 
+    // TODO @puhui999:创建时,这个参数不应该传递哈;
     /**
      * 开团状态:进行中 砍价成功 砍价失败
      */

+ 25 - 0
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/dto/BargainValidateJoinRespDTO.java

@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.promotion.api.bargain.dto;
+
+import lombok.Data;
+
+/**
+ * 校验参与砍价 Response DTO
+ */
+@Data
+public class BargainValidateJoinRespDTO {
+
+    /**
+     * 砍价活动编号
+     */
+    private Long activityId;
+    /**
+     * 砍价活动名称
+     */
+    private String name;
+
+    /**
+     * 砍价金额
+     */
+    private Integer bargainPrice;
+
+}

+ 2 - 1
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java

@@ -19,13 +19,14 @@ public interface SeckillActivityApi {
     void updateSeckillStock(Long id, Long skuId, Integer count);
 
     /**
-     * 校验是否参与秒杀商品
+     * 【下单前】校验是否参与秒杀活动
      *
      * 如果校验失败,则抛出业务异常
      *
      * @param activityId 活动编号
      * @param skuId SKU 编号
      * @param count 数量
+     * @return 秒杀信息
      */
     SeckillValidateJoinRespDTO validateJoinSeckill(Long activityId, Long skuId, Integer count);
 

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

@@ -97,5 +97,8 @@ public interface ErrorCodeConstants {
     ErrorCode BARGAIN_RECORD_EXISTS = new ErrorCode(1_013_013_001, "砍价失败,已参与过该砍价");
     ErrorCode BARGAIN_RECORD_HEAD_NOT_EXISTS = new ErrorCode(1_013_013_002, "砍价失败,父砍价不存在");
     ErrorCode BARGAIN_RECORD_USER_FULL = new ErrorCode(1_013_013_003, "砍价失败,砍价人数已满");
+    ErrorCode BARGAIN_JOIN_RECORD_NOT_IN_PROGRESS = new ErrorCode(1_013_013_004, "砍价失败,砍价记录不在进行中");
+    ErrorCode BARGAIN_JOIN_FAILED_ACTIVITY_TIME_END = new ErrorCode(1_013_013_005, "砍价失败,活动已经结束");
+    ErrorCode BARGAIN_JOIN_ACTIVITY_STATUS_CLOSED = new ErrorCode(1_013_013_006, "砍价失败,原因:砍价活动已关闭");
 
 }

+ 39 - 0
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/bargain/BargainRecordStatusEnum.java

@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.promotion.enums.bargain;
+
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * 砍价记录的状态枚举
+ *
+ * @author 芋道源码
+ */
+@AllArgsConstructor
+@Getter
+public enum BargainRecordStatusEnum implements IntArrayValuable {
+
+    IN_PROGRESS(1, "砍价中"),
+    SUCCESS(2, "砍价成功"),
+    FAILED(3, "砍价失败"),
+    ;
+
+    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BargainRecordStatusEnum::getStatus).toArray();
+
+    /**
+     * 值
+     */
+    private final Integer status;
+    /**
+     * 名字
+     */
+    private final String name;
+
+    @Override
+    public int[] array() {
+        return ARRAYS;
+    }
+
+}

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

@@ -16,8 +16,8 @@ import java.util.Arrays;
 public enum PromotionTypeEnum implements IntArrayValuable {
 
     SECKILL_ACTIVITY(1, "秒杀活动"),
-    BARGAIN_ACTIVITY(2, "拼团活动"),
-    COMBINATION_ACTIVITY(3, "砍价活动"),
+    BARGAIN_ACTIVITY(2, "砍价活动"),
+    COMBINATION_ACTIVITY(3, "拼团活动"),
 
     DISCOUNT_ACTIVITY(4, "限时折扣"),
     REWARD_ACTIVITY(5, "满减送"),

+ 12 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java

@@ -1,19 +1,30 @@
 package cn.iocoder.yudao.module.promotion.api.bargain;
 
 import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainRecordCreateReqDTO;
+import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO;
+import cn.iocoder.yudao.module.promotion.service.bargain.BargainRecordService;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
+
 /**
- * 砍价活动 API 实现类 TODO @puhui999
+ * 砍价活动 API 实现类
  *
  * @author HUIHUI
  */
 @Service
 public class BargainRecordApiImpl implements BargainRecordApi {
 
+    @Resource
+    private BargainRecordService bargainRecordService;
+
     @Override
     public void createBargainRecord(BargainRecordCreateReqDTO reqDTO) {
+    }
 
+    @Override
+    public BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId) {
+        return bargainRecordService.validateJoinBargain(userId, bargainRecordId, skuId);
     }
 
 }

+ 7 - 5
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainRecordDO.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.promotion.dal.dataobject.bargain;
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.promotion.enums.bargain.BargainRecordStatusEnum;
 import com.baomidou.mybatisplus.annotation.KeySequence;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -43,7 +44,6 @@ public class BargainRecordDO extends BaseDO {
      * 商品 SPU 编号
      */
     private Long spuId;
-
     /**
      * 商品 SKU 编号
      */
@@ -53,19 +53,19 @@ public class BargainRecordDO extends BaseDO {
      * 砍价底价,单位分
      */
     private Integer bargainPrice;
-
     /**
      * 商品原价,单位分
      */
     private Integer price;
-
     /**
      * 应付金额,单位分
      */
     private Integer payPrice;
 
     /**
-     * 状态1 - 砍价中;2- 砍价成功;3 - 砍价失败
+     * 砍价状态
+     *
+     * 枚举 {@link BargainRecordStatusEnum}
      */
     private Integer status;
 
@@ -81,7 +81,9 @@ public class BargainRecordDO extends BaseDO {
 
     /**
      * 过期时间
+     *
+     * 到达该时间时,其他用户无法帮助砍价,但是还是允许下单
      */
-    private Data expireTime;
+    private LocalDateTime expireTime;
 
 }

+ 5 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainRecordMapper.java

@@ -12,4 +12,9 @@ import org.apache.ibatis.annotations.Mapper;
 @Mapper
 public interface BargainRecordMapper extends BaseMapperX<BargainRecordDO> {
 
+    default BargainRecordDO selectByIdAndUserId(Long id, Long userId) {
+        return selectOne(BargainRecordDO::getId, id,
+                BargainRecordDO::getUserId, userId);
+    }
+
 }

+ 13 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java

@@ -1,6 +1,8 @@
 package cn.iocoder.yudao.module.promotion.service.bargain;
 
 
+import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO;
+
 /**
  * 砍价记录 service 接口
  *
@@ -8,6 +10,16 @@ package cn.iocoder.yudao.module.promotion.service.bargain;
  */
 public interface BargainRecordService {
 
-//    TODO
+    /**
+     * 【下单前】校验是否参与砍价活动
+     * <p>
+     * 如果校验失败,则抛出业务异常
+     *
+     * @param userId          用户编号
+     * @param bargainRecordId 砍价活动编号
+     * @param skuId           SKU 编号
+     * @return 砍价信息
+     */
+    BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId);
 
 }

+ 58 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java

@@ -1,8 +1,24 @@
 package cn.iocoder.yudao.module.promotion.service.bargain;
 
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.ObjUtil;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
+import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO;
+import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainRecordMapper;
+import cn.iocoder.yudao.module.promotion.enums.bargain.BargainRecordStatusEnum;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
+import javax.annotation.Resource;
+
+import java.util.Objects;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
+
 /**
  * 砍价记录 Service 实现类
  *
@@ -11,4 +27,46 @@ import org.springframework.validation.annotation.Validated;
 @Service
 @Validated
 public class BargainRecordServiceImpl implements BargainRecordService {
+
+    @Resource
+    private BargainActivityService bargainActivityService;
+
+    @Resource
+    private BargainRecordMapper bargainRecordMapper;
+
+    // TODO puhui999:create 时,需要校验下限购数量;
+
+    @Override
+    public BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId) {
+        // 1.1 拼团记录不存在
+        BargainRecordDO record = bargainRecordMapper.selectByIdAndUserId(bargainRecordId, userId);
+        if (record == null) {
+            throw exception(BARGAIN_RECORD_NOT_EXISTS);
+        }
+        // 1.2 拼团记录未在进行中
+        if (ObjUtil.notEqual(record.getStatus(), BargainRecordStatusEnum.IN_PROGRESS)) {
+            throw exception(BARGAIN_JOIN_RECORD_NOT_IN_PROGRESS);
+        }
+
+        // 2.1 砍价活动不存在
+        BargainActivityDO activity = bargainActivityService.getBargainActivity(record.getActivityId());
+        if (activity == null) {
+            throw exception(BARGAIN_ACTIVITY_NOT_EXISTS);
+        }
+        if (ObjUtil.notEqual(activity.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
+            throw exception(BARGAIN_JOIN_ACTIVITY_STATUS_CLOSED);
+        }
+        Assert.isTrue(Objects.equals(skuId, activity.getSkuId()), "砍价商品不匹配"); // 防御性校验
+        // 2.2 活动已过期
+        if (LocalDateTimeUtils.isBetween(activity.getStartTime(), activity.getEndTime())) {
+            throw exception(BARGAIN_JOIN_FAILED_ACTIVITY_TIME_END);
+        }
+        // 2.3 库存不足
+        if (activity.getStock() <= 0) {
+            throw exception(BARGAIN_ACTIVITY_UPDATE_STOCK_FAIL);
+        }
+        return new BargainValidateJoinRespDTO().setActivityId(activity.getId()).setName(activity.getName())
+                .setBargainPrice(record.getPayPrice());
+    }
+
 }

+ 1 - 9
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java

@@ -107,15 +107,6 @@ public interface SeckillActivityService {
      */
     PageResult<SeckillActivityDO> getSeckillActivityAppPageByConfigId(AppSeckillActivityPageReqVO pageReqVO);
 
-    /**
-     * 获取秒杀活动商品信息
-     *
-     * @param id     活动编号
-     * @param skuIds sku 编号
-     * @return 秒杀活动商品信息列表
-     */
-    List<SeckillProductDO> getSeckillActivityProductList(Long id, Collection<Long> skuIds);
-
     /**
      * 校验是否参与秒杀商品
      *
@@ -124,6 +115,7 @@ public interface SeckillActivityService {
      * @param activityId 活动编号
      * @param skuId SKU 编号
      * @param count 数量
+     * @return 秒杀信息
      */
     SeckillValidateJoinRespDTO validateJoinSeckill(Long activityId, Long skuId, Integer count);
 

+ 0 - 12
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java

@@ -278,18 +278,6 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
         return seckillActivityMapper.selectPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus());
     }
 
-    @Override
-    public List<SeckillProductDO> getSeckillActivityProductList(Long id, Collection<Long> skuIds) {
-
-        // 2、校验活动商品是否存在
-        List<SeckillProductDO> productList = filterList(seckillProductMapper.selectListByActivityId(id),
-                item -> skuIds.contains(item.getSkuId()));
-        if (CollectionUtil.isEmpty(productList)) {
-            throw exception(SKU_NOT_EXISTS);
-        }
-        return productList;
-    }
-
     @Override
     public SeckillValidateJoinRespDTO validateJoinSeckill(Long activityId, Long skuId, Integer count) {
         // 1.1 校验秒杀活动是否存在

+ 3 - 4
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java

@@ -60,15 +60,14 @@ public class AppTradeOrderSettlementReqVO {
     private Long combinationHeadId;
 
     // ========== 砍价活动相关字段 ==========
-    // TODO @puhui999:是不是砍价记录的编号哈?
-    @Schema(description = "砍价活动编号", example = "123")
-    private Long bargainActivityId;
+    @Schema(description = "砍价记录编号", example = "123")
+    private Long bargainRecordId;
 
     @AssertTrue(message = "活动商品每次只能购买一种规格")
     @JsonIgnore
     public boolean isValidActivityItems() {
         // 校验是否是活动订单
-        if (ObjUtil.isAllEmpty(seckillActivityId, combinationActivityId, combinationHeadId)) {
+        if (ObjUtil.isAllEmpty(seckillActivityId, combinationActivityId, combinationHeadId, bargainRecordId)) {
             return true;
         }
         // 校验订单项是否超出

+ 3 - 38
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java

@@ -16,7 +16,6 @@ import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDeta
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
-import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
 import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
 import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
 import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
@@ -34,8 +33,6 @@ import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEn
 import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO;
 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
 import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
-import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterOrderCreateReqBO;
-import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
 import org.mapstruct.Mapper;
@@ -94,19 +91,19 @@ public interface TradeOrderConvert {
         return new ProductSkuUpdateStockReqDTO(items);
     }
 
-    default ProductSkuUpdateStockReqDTO convertNegative(List<AppTradeOrderSettlementReqVO.Item> list) {
+    default ProductSkuUpdateStockReqDTO convertNegative(List<TradeOrderItemDO> list) {
         List<ProductSkuUpdateStockReqDTO.Item> items = CollectionUtils.convertList(list, item ->
                 new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(-item.getCount()));
         return new ProductSkuUpdateStockReqDTO(items);
     }
 
     default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
-                                         TradePriceCalculateRespBO calculateRespBO, TradeOrderProperties orderProperties) {
+                                         TradeOrderProperties orderProperties) {
         PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO()
                 .setAppId(orderProperties.getAppId()).setUserIp(order.getUserIp());
         // 商户相关字段
         createReqDTO.setMerchantOrderId(String.valueOf(order.getId()));
-        String subject = calculateRespBO.getItems().get(0).getSpuName();
+        String subject = orderItems.get(0).getSpuName();
         subject = StrUtils.maxLength(subject, PayOrderCreateReqDTO.SUBJECT_MAX_LENGTH); // 避免超过 32 位
         createReqDTO.setSubject(subject);
         createReqDTO.setBody(subject); // TODO 芋艿:临时写死
@@ -263,36 +260,4 @@ public interface TradeOrderConvert {
         return bo;
     }
 
-    @Mappings({
-            @Mapping(target = "userId", source = "userId"),
-            @Mapping(target = "orderType", source = "calculateRespBO.type"),
-            @Mapping(target = "items", source = "createReqVO.items"),
-    })
-    TradeBeforeOrderCreateReqBO convert(Long userId, AppTradeOrderCreateReqVO createReqVO, TradePriceCalculateRespBO calculateRespBO);
-
-
-    List<TradeAfterOrderCreateReqBO.Item> convertList(List<TradeOrderItemDO> orderItems);
-
-
-    @Mappings({
-            @Mapping(target = "userId", source = "userId"),
-            @Mapping(target = "orderId", source = "tradeOrderDO.id"),
-            @Mapping(target = "payPrice", source = "tradeOrderDO.payPrice"),
-            @Mapping(target = "items", source = "orderItems"),
-    })
-    TradeAfterOrderCreateReqBO convert(Long userId, AppTradeOrderCreateReqVO createReqVO,
-                                       TradeOrderDO tradeOrderDO, List<TradeOrderItemDO> orderItems);
-
-    @Mappings({
-            @Mapping(target = "activityId", source = "combinationActivityId"),
-            @Mapping(target = "spuId", expression = "java(reqBO.getItems().get(0).getSpuId())"),
-            @Mapping(target = "skuId", expression = "java(reqBO.getItems().get(0).getSkuId())"),// TODO 艿艿看看这里
-            @Mapping(target = "count", expression = "java(reqBO.getItems().get(0).getCount())"),
-            @Mapping(target = "orderId", source = "orderId"),
-            @Mapping(target = "userId", source = "userId"),
-            @Mapping(target = "headId", source = "combinationHeadId"),
-            @Mapping(target = "combinationPrice", source = "payPrice")
-    })
-    CombinationRecordCreateReqDTO convert(TradeAfterOrderCreateReqBO reqBO);
-
 }

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderLogConvert.java

@@ -1,7 +1,7 @@
 package cn.iocoder.yudao.module.trade.convert.order;
 
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
-import cn.iocoder.yudao.module.trade.service.order.bo.logger.TradeOrderLogCreateReqBO;
+import cn.iocoder.yudao.module.trade.service.order.bo.TradeOrderLogCreateReqBO;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
 

+ 13 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java

@@ -295,4 +295,17 @@ public class TradeOrderDO extends BaseDO {
      */
     private Long seckillActivityId;
 
+    /**
+     * 砍价活动编号
+     *
+     * 关联 BargainActivityDO 的 id 字段
+     */
+    private Long bargainActivityId;
+    /**
+     * 砍价记录编号
+     *
+     * 关联 BargainRecordDO 的 id 字段
+     */
+    private Long bargainRecordId;
+
 }

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java

@@ -7,7 +7,7 @@ import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
 import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog;
 import cn.iocoder.yudao.module.trade.service.order.TradeOrderLogService;
-import cn.iocoder.yudao.module.trade.service.order.bo.logger.TradeOrderLogCreateReqBO;
+import cn.iocoder.yudao.module.trade.service.order.bo.TradeOrderLogCreateReqBO;
 import lombok.extern.slf4j.Slf4j;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.annotation.AfterReturning;

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

@@ -1,7 +1,7 @@
 package cn.iocoder.yudao.module.trade.service.order;
 
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
-import cn.iocoder.yudao.module.trade.service.order.bo.logger.TradeOrderLogCreateReqBO;
+import cn.iocoder.yudao.module.trade.service.order.bo.TradeOrderLogCreateReqBO;
 import org.springframework.scheduling.annotation.Async;
 
 import java.util.List;

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

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.trade.service.order;
 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderLogConvert;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderLogMapper;
-import cn.iocoder.yudao.module.trade.service.order.bo.logger.TradeOrderLogCreateReqBO;
+import cn.iocoder.yudao.module.trade.service.order.bo.TradeOrderLogCreateReqBO;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;

+ 34 - 46
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java

@@ -27,7 +27,6 @@ import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
 import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
-import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi;
 import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
 import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
 import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
@@ -61,7 +60,6 @@ import cn.iocoder.yudao.module.trade.service.cart.CartService;
 import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
 import cn.iocoder.yudao.module.trade.service.message.TradeMessageService;
 import cn.iocoder.yudao.module.trade.service.message.bo.TradeOrderMessageWhenDeliveryOrderReqBO;
-import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterPayOrderReqBO;
 import cn.iocoder.yudao.module.trade.service.order.handler.TradeOrderHandler;
 import cn.iocoder.yudao.module.trade.service.price.TradePriceService;
 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
@@ -128,8 +126,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
     @Resource
     private CombinationRecordApi combinationRecordApi;
     @Resource
-    private BargainRecordApi bargainRecordApi;
-    @Resource
     private MemberUserApi memberUserApi;
     @Resource
     private MemberLevelApi memberLevelApi;
@@ -195,24 +191,27 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
     @Transactional(rollbackFor = Exception.class)
     @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CREATE)
     public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) {
-        // 0. 价格计算
+        // 1.1 价格计算
         TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, createReqVO);
+        // 1.2 构建订单
+        TradeOrderDO order = buildTradeOrder(userId, userIp, createReqVO, calculateRespBO);
+        List<TradeOrderItemDO> orderItems = buildTradeOrderItems(order, calculateRespBO);
 
-        // 1. 订单创建前的逻辑
-        beforeCreateTradeOrder(userId, createReqVO, calculateRespBO);
+        // 2. 订单创建前的逻辑
+        beforeCreateTradeOrder(order, orderItems);
 
-        // 2.1 插入 TradeOrderDO 订单
-        TradeOrderDO order = createTradeOrder(userId, userIp, createReqVO, calculateRespBO);
-        // 2.2 插入 TradeOrderItemDO 订单项
-        List<TradeOrderItemDO> orderItems = createTradeOrderItems(order, calculateRespBO);
+        // 3. 保存订单
+        tradeOrderMapper.insert(order);
+        orderItems.forEach(orderItem -> orderItem.setOrderId(order.getId()));
+        tradeOrderItemMapper.insertBatch(orderItems);
 
-        // 3. 订单创建后的逻辑
-        afterCreateTradeOrder(userId, createReqVO, order, orderItems, calculateRespBO);
+        // 4. 订单创建后的逻辑
+        afterCreateTradeOrder(order, orderItems, createReqVO);
         return order;
     }
 
-    private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO,
-                                          TradePriceCalculateRespBO calculateRespBO) {
+    private TradeOrderDO buildTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO,
+                                         TradePriceCalculateRespBO calculateRespBO) {
         TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO);
         order.setType(calculateRespBO.getType());
         order.setNo(tradeNoRedisDAO.generate(TradeNoRedisDAO.TRADE_ORDER_NO_PREFIX));
@@ -235,33 +234,27 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
             order.setPickUpVerifyCode(RandomUtil.randomNumbers(8)); // 随机一个核销码,长度为 8 位
         }
         // TODO @疯狂:是不是可以在这里设置下推广人哈;
-        tradeOrderMapper.insert(order);
         return order;
     }
 
-    private List<TradeOrderItemDO> createTradeOrderItems(TradeOrderDO tradeOrderDO,
-                                                         TradePriceCalculateRespBO calculateRespBO) {
-        List<TradeOrderItemDO> orderItems = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO);
-        tradeOrderItemMapper.insertBatch(orderItems);
-        return orderItems;
+    private List<TradeOrderItemDO> buildTradeOrderItems(TradeOrderDO tradeOrderDO,
+                                                        TradePriceCalculateRespBO calculateRespBO) {
+        return TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO);
     }
 
     /**
      * 订单创建前,执行前置逻辑
      *
-     * @param userId          用户编号
-     * @param createReqVO     创建订单请求
-     * @param calculateRespBO 订单价格计算结果
+     * @param order 订单
+     * @param orderItems 订单项
      */
-    private void beforeCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
-                                        TradePriceCalculateRespBO calculateRespBO) {
+    private void beforeCreateTradeOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
         // 1. 执行订单创建前置处理器
         // TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等
-        tradeOrderHandlers.forEach(handler ->
-                handler.beforeOrderCreate(TradeOrderConvert.INSTANCE.convert(userId, createReqVO, calculateRespBO)));
+        tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(order, orderItems));
 
         // 2. 下单时扣减商品库存
-        productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(createReqVO.getItems()));
+        productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems));
     }
 
     /**
@@ -269,22 +262,19 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
      * <p>
      * 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等
      *
-     * @param userId          用户编号
+     * @param order           订单
+     * @param orderItems      订单项
      * @param createReqVO     创建订单请求
-     * @param order           交易订单
-     * @param calculateRespBO 订单价格计算结果
      */
-    private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
-                                       TradeOrderDO order, List<TradeOrderItemDO> orderItems,
-                                       TradePriceCalculateRespBO calculateRespBO) {
+    private void afterCreateTradeOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
+                                       AppTradeOrderCreateReqVO createReqVO) {
         // 1. 执行订单创建后置处理器
-        tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(
-                TradeOrderConvert.INSTANCE.convert(userId, createReqVO, order, orderItems)));
+        tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(order, orderItems));
 
         // 2. 有使用优惠券时更新
         // 不在前置扣减的原因,是因为优惠劵要记录使用的订单号
-        if (createReqVO.getCouponId() != null) {
-            couponApi.useCoupon(new CouponUseReqDTO().setId(createReqVO.getCouponId()).setUserId(userId)
+        if (order.getCouponId() != null) {
+            couponApi.useCoupon(new CouponUseReqDTO().setId(order.getCouponId()).setUserId(order.getUserId())
                     .setOrderId(order.getId()));
         }
 
@@ -295,11 +285,11 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         // 4. 删除购物车商品
         Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId);
         if (CollUtil.isNotEmpty(cartIds)) {
-            cartService.deleteCart(userId, cartIds);
+            cartService.deleteCart(order.getUserId(), cartIds);
         }
 
         // 5. 生成预支付
-        createPayOrder(order, orderItems, calculateRespBO);
+        createPayOrder(order, orderItems);
 
         // 6. 插入订单日志
         TradeOrderLogUtils.setOrderInfo(order.getId(), null, order.getStatus());
@@ -313,11 +303,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来!
     }
 
-    private void createPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
-                                TradePriceCalculateRespBO calculateRespBO) {
+    private void createPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
         // 创建支付单,用于后续的支付
         PayOrderCreateReqDTO payOrderCreateReqDTO = TradeOrderConvert.INSTANCE.convert(
-                order, orderItems, calculateRespBO, tradeOrderProperties);
+                order, orderItems, tradeOrderProperties);
         Long payOrderId = payOrderApi.createOrder(payOrderCreateReqDTO);
 
         // 更新到交易单上
@@ -343,8 +332,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         }
 
         // 3、订单支付成功后
-        tradeOrderHandlers.forEach(tradeOrderHandler -> tradeOrderHandler.afterPayOrder(new TradeAfterPayOrderReqBO()
-                .setOrderId(order.getId()).setOrderType(order.getType()).setUserId(order.getUserId()).setPayTime(LocalDateTime.now())));
+        tradeOrderHandlers.forEach(handler -> handler.afterPayOrder(order));
 
         // 4.1 增加用户积分(赠送)
         addUserPoint(order.getUserId(), order.getGivePoint(), MemberPointBizTypeEnum.ORDER_GIVE, order.getId());

+ 0 - 87
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/TradeAfterOrderCreateReqBO.java

@@ -1,87 +0,0 @@
-package cn.iocoder.yudao.module.trade.service.order.bo;
-
-import lombok.Data;
-
-import javax.validation.Valid;
-import javax.validation.constraints.NotNull;
-import java.util.List;
-
-// TODO 芋艿:在想想这些参数的定义
-/**
- * 订单创建之后 Request BO
- *
- * @author HUIHUI
- */
-@Data
-public class TradeAfterOrderCreateReqBO {
-
-    // ========== 拼团活动相关字段 ==========
-
-    /**
-     * 拼团活动编号
-     */
-    private Long combinationActivityId;
-
-    /**
-     * 拼团团长编号
-     */
-    private Long combinationHeadId;
-
-    /**
-     * 订单编号
-     */
-    @NotNull(message = "订单编号不能为空")
-    private Long orderId;
-
-    /**
-     * 用户编号
-     */
-    @NotNull(message = "用户编号不能为空")
-    private Long userId;
-
-    /**
-     * 支付金额
-     */
-    @NotNull(message = "支付金额不能为空")
-    private Integer payPrice;
-
-    // ========== 购买商品相关字段 ==========
-
-    /**
-     * 订单购买的商品信息
-     */
-    private List<Item> items;
-
-    /**
-     * 订单商品信息
-     * 记录购买商品的简要核心信息
-     *
-     * @author HUIHUI
-     */
-    @Data
-    @Valid
-    public static class Item {
-
-        /**
-         * SPU 编号
-         */
-        @NotNull(message = "SPU 编号不能为空")
-        private Long spuId;
-
-        /**
-         * 商品 SKU 编号
-         *
-         * 关联 ProductSkuDO 的 id 编号
-         */
-        @NotNull(message = "SKU 编号活动商品不能为空")
-        private Long skuId;
-
-        /**
-         * 购买的商品数量
-         */
-        @NotNull(message = "购买数量不能为空")
-        private Integer count;
-
-    }
-
-}

+ 0 - 43
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/TradeAfterPayOrderReqBO.java

@@ -1,43 +0,0 @@
-package cn.iocoder.yudao.module.trade.service.order.bo;
-
-import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-/**
- * 订单支付后 Request BO
- *
- * @author HUIHUI
- */
-@Data
-public class TradeAfterPayOrderReqBO {
-
-    /**
-     * 订单编号
-     */
-    @Schema(description = "订单编号", example = "6")
-    private Long orderId;
-
-    /**
-     * 订单类型
-     *
-     * 枚举 {@link TradeOrderTypeEnum}
-     */
-    @Schema(description = "订单类型", example = "3")
-    private Integer orderType;
-
-    /**
-     * 用户编号
-     */
-    @Schema(description = "用户编号", example = "11")
-    private Long userId;
-
-    /**
-     * 订单支付时间
-     */
-    @Schema(description = "订单支付时间", example = "2023-08-15 10:00:00")
-    private LocalDateTime payTime;
-
-}

+ 0 - 94
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/TradeBeforeOrderCreateReqBO.java

@@ -1,94 +0,0 @@
-package cn.iocoder.yudao.module.trade.service.order.bo;
-
-import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
-import lombok.Data;
-
-import javax.validation.Valid;
-import javax.validation.constraints.NotNull;
-import java.util.List;
-// TODO 芋艿:在想想这些参数的定义
-
-/**
- * 订单创建之前 Request BO
- *
- * @author HUIHUI
- */
-@Data
-public class TradeBeforeOrderCreateReqBO {
-
-    /**
-     * 订单类型
-     *
-     * 枚举 {@link TradeOrderTypeEnum}
-     */
-    @NotNull(message = "订单类型不能为空")
-    private Integer orderType;
-
-    /**
-     * 用户编号
-     *
-     * 关联 MemberUserDO 的 id 编号
-     */
-    @NotNull(message = "用户编号不能为空")
-    private Long userId;
-
-    // ========== 秒杀活动相关字段 ==========
-
-    /**
-     * 秒杀活动编号
-     */
-    private Long seckillActivityId;
-
-    // ========== 拼团活动相关字段 ==========
-
-    /**
-     * 拼团活动编号
-     */
-    private Long combinationActivityId;
-
-    /**
-     * 拼团团长编号
-     */
-    private Long combinationHeadId;
-
-    // ========== 砍价活动相关字段 ==========
-
-    /**
-     * 砍价活动编号
-     */
-    private Long bargainActivityId;
-
-    // ========== 购买商品相关字段 ==========
-
-    /**
-     * 订单购买的商品信息
-     */
-    private List<Item> items;
-
-    /**
-     * 订单商品信息
-     * 记录购买商品的简要核心信息
-     *
-     * @author HUIHUI
-     */
-    @Data
-    @Valid
-    public static class Item {
-
-        /**
-         * 商品 SKU 编号
-         *
-         * 关联 ProductSkuDO 的 id 编号
-         */
-        @NotNull(message = "SKU 编号活动商品不能为空")
-        private Long skuId;
-
-        /**
-         * 购买的商品数量
-         */
-        @NotNull(message = "购买数量不能为空")
-        private Integer count;
-
-    }
-
-}

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/logger/TradeOrderLogCreateReqBO.java → yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/TradeOrderLogCreateReqBO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.trade.service.order.bo.logger;
+package cn.iocoder.yudao.module.trade.service.order.bo;
 
 import lombok.Data;
 

+ 7 - 12
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBargainHandler.java

@@ -2,11 +2,13 @@ package cn.iocoder.yudao.module.trade.service.order.handler;
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.module.promotion.api.bargain.BargainActivityApi;
+import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
-import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
+import java.util.List;
 
 /**
  * 砍价订单 handler 实现类
@@ -19,21 +21,14 @@ public class TradeBargainHandler implements TradeOrderHandler {
     @Resource
     private BargainActivityApi bargainActivityApi;
 
-    // TODO @puhui999:先临时写在这里;在价格计算时,如果是秒杀商品,需要校验如下条件:
-    // 1. 商品存在、库存充足、单次限购;
-    // 2. 活动进行中、时间段符合
-
     @Override
-    public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
-        // 如果是砍价订单
-        if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), reqBO.getOrderType())) {
+    public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
+        if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), order.getType())) {
             return;
         }
-
-        // 获取商品信息
-        TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
         // 扣减砍价活动的库存
-        bargainActivityApi.updateBargainActivityStock(reqBO.getBargainActivityId(), item.getCount());
+        bargainActivityApi.updateBargainActivityStock(order.getBargainActivityId(),
+                orderItems.get(0).getCount());
     }
 
 }

+ 33 - 39
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java

@@ -1,12 +1,6 @@
 package cn.iocoder.yudao.module.trade.service.order.handler;
 
-import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
-import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
-import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
-import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterOrderCreateReqBO;
-import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterPayOrderReqBO;
-import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
@@ -22,38 +16,38 @@ public class TradeCombinationHandler implements TradeOrderHandler {
     @Resource
     private CombinationRecordApi combinationRecordApi;
 
-    @Override
-    public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
-        // 如果不是拼团订单则结束
-        if (ObjectUtil.notEqual(TradeOrderTypeEnum.COMBINATION.getType(), reqBO.getOrderType())) {
-            return;
-        }
-
-        // 获取商品信息
-        TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
-        // 校验是否满足拼团活动相关限制
-        combinationRecordApi.validateCombinationRecord(reqBO.getCombinationActivityId(), reqBO.getUserId(), item.getSkuId(), item.getCount());
-    }
-
-    @Override
-    public void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO) {
-        if (reqBO.getCombinationActivityId() == null) {
-            return;
-        }
-
-        // 创建砍价记录
-        combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(reqBO));
-    }
-
-    @Override
-    public void afterPayOrder(TradeAfterPayOrderReqBO reqBO) {
-        // 如果不是拼团订单则结束
-        if (ObjectUtil.notEqual(TradeOrderTypeEnum.COMBINATION.getType(), reqBO.getOrderType())) {
-            return;
-        }
-
-        // 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录
-        combinationRecordApi.updateRecordStatusToInProgress(reqBO.getUserId(), reqBO.getOrderId(), reqBO.getPayTime());
-    }
+//    @Override
+//    public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
+//        // 如果不是拼团订单则结束
+//        if (ObjectUtil.notEqual(TradeOrderTypeEnum.COMBINATION.getType(), reqBO.getOrderType())) {
+//            return;
+//        }
+//
+//        // 获取商品信息
+//        TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
+//        // 校验是否满足拼团活动相关限制
+//        combinationRecordApi.validateCombinationRecord(reqBO.getCombinationActivityId(), reqBO.getUserId(), item.getSkuId(), item.getCount());
+//    }
+
+//    @Override
+//    public void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO) {
+//        if (reqBO.getCombinationActivityId() == null) {
+//            return;
+//        }
+//
+//        // 创建砍价记录
+//        combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(reqBO));
+//    }
+
+//    @Override
+//    public void afterPayOrder(TradeAfterPayOrderReqBO reqBO) {
+//        // 如果不是拼团订单则结束
+//        if (ObjectUtil.notEqual(TradeOrderTypeEnum.COMBINATION.getType(), reqBO.getOrderType())) {
+//            return;
+//        }
+//
+//        // 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录
+//        combinationRecordApi.updateRecordStatusToInProgress(reqBO.getUserId(), reqBO.getOrderId(), reqBO.getPayTime());
+//    }
 
 }

+ 12 - 9
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeOrderHandler.java

@@ -1,8 +1,9 @@
 package cn.iocoder.yudao.module.trade.service.order.handler;
 
-import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterOrderCreateReqBO;
-import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterPayOrderReqBO;
-import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
+
+import java.util.List;
 
 /**
  * 订单活动特殊逻辑处理器 handler 接口
@@ -15,23 +16,25 @@ public interface TradeOrderHandler {
     /**
      * 订单创建前
      *
-     * @param reqBO 请求
+     * @param order 订单
+     * @param orderItems 订单项
      */
-    default void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {}
+    default void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {}
 
     /**
      * 订单创建后
      *
-     * @param reqBO 请求
+     * @param order 订单
+     * @param orderItems 订单项
      */
-    default void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO) {}
+    default void afterOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {}
 
     /**
      * 支付订单后
      *
-     * @param reqBO 请求
+     * @param order 订单
      */
-    default void afterPayOrder(TradeAfterPayOrderReqBO reqBO) {}
+    default void afterPayOrder(TradeOrderDO order) {}
 
     /**
      * 订单取消

+ 7 - 12
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeSeckillHandler.java

@@ -2,11 +2,13 @@ package cn.iocoder.yudao.module.trade.service.order.handler;
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi;
+import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
+import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
-import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
+import java.util.List;
 
 /**
  * 秒杀订单 handler 实现类
@@ -19,21 +21,14 @@ public class TradeSeckillHandler implements TradeOrderHandler {
     @Resource
     private SeckillActivityApi seckillActivityApi;
 
-    // TODO @puhui999:先临时写在这里;在价格计算时,如果是秒杀商品,需要校验如下条件:
-    // 1. 商品存在、库存充足、单次限购;
-    // 2. 活动进行中、时间段符合
-
     @Override
-    public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) {
-        // 如果是秒杀订单:额外扣减秒杀的库存;
-        if (ObjectUtil.notEqual(TradeOrderTypeEnum.SECKILL.getType(), reqBO.getOrderType())) {
+    public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
+        if (ObjectUtil.notEqual(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) {
             return;
         }
-
-        // 获取商品信息
-        TradeBeforeOrderCreateReqBO.Item item = reqBO.getItems().get(0);
         // 扣减秒杀活动的库存
-        seckillActivityApi.updateSeckillStock(reqBO.getSeckillActivityId(), item.getSkuId(), item.getCount());
+        seckillActivityApi.updateSeckillStock(order.getSeckillActivityId(),
+                orderItems.get(0).getSkuId(), orderItems.get(0).getCount());
     }
 
 }

+ 2 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java

@@ -81,9 +81,9 @@ public class TradePriceCalculateReqBO {
 
     // ========== 砍价活动相关字段 ==========
     /**
-     * 砍价活动编号
+     * 砍价记录编号
      */
-    private Long bargainActivityId;
+    private Long bargainRecordId;
 
     /**
      * 商品 SKU

+ 5 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java

@@ -58,6 +58,11 @@ public class TradePriceCalculateRespBO {
      */
     private Integer givePoint;
 
+    /**
+     * 砍价活动编号
+     */
+    private Long bargainActivityId;
+
     /**
      * 订单价格
      */

+ 55 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeBargainActivityPriceCalculator.java

@@ -0,0 +1,55 @@
+package cn.iocoder.yudao.module.trade.service.price.calculator;
+
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi;
+import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO;
+import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
+import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
+import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+// TODO huihui:单测需要补充
+/**
+ * 砍价活动的 {@link TradePriceCalculator} 实现类
+ *
+ * @author 芋道源码
+ */
+@Component
+@Order(TradePriceCalculator.ORDER_BARGAIN_ACTIVITY)
+public class TradeBargainActivityPriceCalculator implements TradePriceCalculator {
+
+    @Resource
+    private BargainRecordApi bargainRecordApi;
+
+    @Override
+    public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
+        // 1. 判断订单类型和是否具有拼团记录编号
+        if (param.getBargainRecordId() != null) {
+            return;
+        }
+        Assert.isTrue(param.getItems().size() == 1, "砍价时,只允许选择一个商品");
+        Assert.isTrue(param.getItems().get(0).getCount() == 1, "砍价时,只允许选择一个商品");
+        // 2. 校验是否可以参与砍价
+        TradePriceCalculateRespBO.OrderItem orderItem = result.getItems().get(0);
+        BargainValidateJoinRespDTO bargainActivity = bargainRecordApi.validateJoinBargain(
+                param.getUserId(), param.getBargainRecordId(), orderItem.getSkuId());
+
+        // 3.1 记录优惠明细
+        Integer discountPrice = orderItem.getPayPrice() - bargainActivity.getBargainPrice() * orderItem.getCount();
+        TradePriceCalculatorHelper.addPromotion(result, orderItem,
+                param.getSeckillActivityId(), bargainActivity.getName(), PromotionTypeEnum.BARGAIN_ACTIVITY.getType(),
+                StrUtil.format("砍价活动:省 {} 元", TradePriceCalculatorHelper.formatPrice(discountPrice)),
+                discountPrice);
+        // 3.2 更新 SKU 优惠金额
+        orderItem.setDiscountPrice(orderItem.getDiscountPrice() + discountPrice);
+        TradePriceCalculatorHelper.recountPayPrice(orderItem);
+        TradePriceCalculatorHelper.recountAllPrice(result);
+        // 4. 特殊:设置对应的砍价活动编号
+        result.setBargainActivityId(bargainActivity.getActivityId());
+    }
+
+}

+ 4 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java

@@ -14,6 +14,10 @@ import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
 public interface TradePriceCalculator {
 
     int ORDER_MEMBER_LEVEL = 5;
+
+    int ORDER_SECKILL_ACTIVITY = 8;
+    int ORDER_BARGAIN_ACTIVITY = 8;
+
     int ORDER_DISCOUNT_ACTIVITY = 10;
     int ORDER_REWARD_ACTIVITY = 20;
     int ORDER_COUPON = 30;

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

@@ -23,7 +23,7 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCU
  * @author HUIHUI
  */
 @Component
-@Order(TradePriceCalculator.ORDER_DISCOUNT_ACTIVITY)
+@Order(TradePriceCalculator.ORDER_SECKILL_ACTIVITY)
 public class TradeSeckillActivityPriceCalculator implements TradePriceCalculator {
 
     @Resource