Browse Source

trade:完善砍价的下单流程

YunaiV 1 year atrás
parent
commit
aec8e853e4
11 changed files with 89 additions and 21 deletions
  1. 10 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/enums/ErrorCodeConstants.java
  3. 4 4
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java
  4. 8 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java
  5. 14 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainRecordMapper.java
  6. 2 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java
  7. 1 10
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java
  8. 10 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java
  9. 20 5
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java
  10. 15 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBargainHandler.java
  11. 4 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeBargainActivityPriceCalculator.java

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

@@ -21,4 +21,14 @@ public interface BargainRecordApi {
      */
     BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId);
 
+    /**
+     * 更新砍价记录的订单编号
+     *
+     * 在砍价成功后,用户发起订单后,会记录该订单编号
+     *
+     * @param id     砍价记录编号
+     * @param orderId 订单编号
+     */
+    void updateBargainRecordOrderId(Long id, Long orderId);
+
 }

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

@@ -99,6 +99,7 @@ public interface ErrorCodeConstants {
     ErrorCode BARGAIN_RECORD_CREATE_FAIL_EXISTS = new ErrorCode(1_013_013_001, "参与失败,您已经参与当前砍价活动");
     ErrorCode BARGAIN_RECORD_CREATE_FAIL_LIMIT = new ErrorCode(1_013_013_002, "参与失败,您已达到当前砍价活动的参与上限");
     ErrorCode BARGAIN_JOIN_RECORD_NOT_SUCCESS = new ErrorCode(1_013_013_004, "下单失败,砍价未成功");
+    ErrorCode BARGAIN_JOIN_RECORD_ALREADY_ORDER = new ErrorCode(1_013_013_005, "下单失败,该砍价已经下单");
 
     // ========== 砍价助力 1-013-014-000 ==========
     ErrorCode BARGAIN_HELP_CREATE_FAIL_RECORD_NOT_IN_PROCESS = new ErrorCode(1_013_014_000, "助力失败,砍价记录不处于进行中");

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

@@ -1,6 +1,5 @@
 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;
@@ -19,12 +18,13 @@ public class BargainRecordApiImpl implements BargainRecordApi {
     private BargainRecordService bargainRecordService;
 
     @Override
-    public void createBargainRecord(BargainRecordCreateReqDTO reqDTO) {
+    public BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId) {
+        return bargainRecordService.validateJoinBargain(userId, bargainRecordId, skuId);
     }
 
     @Override
-    public BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId) {
-        return bargainRecordService.validateJoinBargain(userId, bargainRecordId, skuId);
+    public void updateBargainRecordOrderId(Long id, Long orderId) {
+        bargainRecordService.updateBargainRecordOrderId(id, orderId);
     }
 
 }

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

@@ -39,6 +39,14 @@ public interface BargainActivityMapper extends BaseMapperX<BargainActivityDO> {
      * @return 影响的行数
      */
     default int updateStock(Long id, int count) {
+        // 情况一:增加库存
+        if (count > 0) {
+            return update(null, new LambdaUpdateWrapper<BargainActivityDO>()
+                    .eq(BargainActivityDO::getId, id)
+                    .setSql("stock = stock + " + count));
+        }
+        // 情况二:扣减库存
+        count = -count; // 取正
         return update(null, new LambdaUpdateWrapper<BargainActivityDO>()
                 .eq(BargainActivityDO::getId, id)
                 .ge(BargainActivityDO::getStock, count)

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

@@ -93,4 +93,18 @@ public interface BargainRecordMapper extends BaseMapperX<BargainRecordDO> {
                 .last("LIMIT " + count));
     }
 
+    /**
+     * 更新砍价的订单编号,前提是 orderId 原本是空的
+     *
+     * @param id 砍价记录编号
+     * @param orderId 订单编号
+     * @return 更新数量
+     */
+    default int updateOrderIdById(Long id, Long orderId) {
+        return update(new BargainRecordDO().setOrderId(orderId),
+                new LambdaQueryWrapper<>(BargainRecordDO.class)
+                        .eq(BargainRecordDO::getId, id)
+                        .isNull(BargainRecordDO::getOrderId));
+    }
+
 }

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

@@ -36,6 +36,8 @@ public interface BargainActivityService {
     /**
      * 更新砍价活动库存
      *
+     * 如果更新失败(库存不足),则抛出业务异常
+     *
      * @param id    砍价活动编号
      * @param count 购买数量
      */

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

@@ -83,16 +83,7 @@ public class BargainActivityServiceImpl implements BargainActivityService {
 
     @Override
     public void updateBargainActivityStock(Long id, Integer count) {
-        // 查询砍价活动
-        BargainActivityDO activity = getBargainActivity(id);
-        if (activity == null) {
-            throw exception(BARGAIN_ACTIVITY_NOT_EXISTS);
-        }
-        if (count > activity.getStock()) {
-            throw exception(BARGAIN_ACTIVITY_STOCK_NOT_ENOUGH);
-        }
-
-        // 更新砍价库存
+        // 更新库存。如果更新失败,则抛出异常
         int updateCount = bargainActivityMapper.updateStock(id, count);
         if (updateCount == 0) {
             throw exception(BARGAIN_ACTIVITY_STOCK_NOT_ENOUGH);

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

@@ -56,6 +56,16 @@ public interface BargainRecordService {
     BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId);
 
     /**
+     * 更新砍价记录的订单编号
+     *
+     * 在砍价成功后,用户发起订单后,会记录该订单编号
+     *
+     * @param id     砍价记录编号
+     * @param orderId 订单编号
+     */
+    void updateBargainRecordOrderId(Long id, Long orderId);
+
+    /**
      * 获得砍价记录
      *
      * @param id 砍价记录编号

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

@@ -13,6 +13,7 @@ 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.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Nullable;
@@ -42,7 +43,7 @@ public class BargainRecordServiceImpl implements BargainRecordService {
 
     @Override
     public Long createBargainRecord(Long userId, AppBargainRecordCreateReqVO reqVO) {
-        // 1. 校验砍价活动
+        // 1. 校验砍价活动(包括库存)
         BargainActivityDO activity = bargainActivityService.validateBargainActivityCanJoin(reqVO.getActivityId());
 
         // 2.1 校验当前是否已经有参与中的砍价活动
@@ -77,17 +78,21 @@ public class BargainRecordServiceImpl implements BargainRecordService {
 
     @Override
     public BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId) {
-        // 1.1 拼团记录不存在
+        // 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)) {
+        // 1.2 砍价记录未在进行中
+        if (ObjUtil.notEqual(record.getStatus(), BargainRecordStatusEnum.SUCCESS.getStatus())) {
             throw exception(BARGAIN_JOIN_RECORD_NOT_SUCCESS);
         }
+        // 1.3 砍价记录已经下单
+        if (record.getOrderId() != null) {
+            throw exception(BARGAIN_JOIN_RECORD_ALREADY_ORDER);
+        }
 
-        // 2. 校验砍价活动
+        // 2.1 校验砍价活动(包括库存)
         BargainActivityDO activity = bargainActivityService.validateBargainActivityCanJoin(record.getActivityId());
         Assert.isTrue(Objects.equals(skuId, activity.getSkuId()), "砍价商品不匹配"); // 防御性校验
         return new BargainValidateJoinRespDTO().setActivityId(activity.getId()).setName(activity.getName())
@@ -95,6 +100,16 @@ public class BargainRecordServiceImpl implements BargainRecordService {
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateBargainRecordOrderId(Long id, Long orderId) {
+        // 更新失败,说明已经下单
+        int updateCount = bargainRecordMapper.updateOrderIdById(id, orderId);
+        if (updateCount == 0) {
+            throw exception(BARGAIN_JOIN_RECORD_ALREADY_ORDER);
+        }
+    }
+
+    @Override
     public BargainRecordDO getBargainRecord(Long id) {
         return bargainRecordMapper.selectById(id);
     }

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

@@ -2,6 +2,7 @@ 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.promotion.api.bargain.BargainRecordApi;
 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;
@@ -20,6 +21,8 @@ public class TradeBargainHandler implements TradeOrderHandler {
 
     @Resource
     private BargainActivityApi bargainActivityApi;
+    @Resource
+    private BargainRecordApi bargainRecordApi;
 
     @Override
     public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
@@ -28,7 +31,18 @@ public class TradeBargainHandler implements TradeOrderHandler {
         }
         // 扣减砍价活动的库存
         bargainActivityApi.updateBargainActivityStock(order.getBargainActivityId(),
-                orderItems.get(0).getCount());
+                -orderItems.get(0).getCount());
+    }
+
+    @Override
+    public void afterOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
+        if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), order.getType())) {
+            return;
+        }
+        // 记录砍价记录对应的订单编号
+        bargainRecordApi.updateBargainRecordOrderId(order.getBargainRecordId(), order.getId());
     }
 
+    // TODO 芋艿:取消订单时,需要增加库存
+
 }

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

@@ -1,10 +1,12 @@
 package cn.iocoder.yudao.module.trade.service.price.calculator;
 
 import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.ObjectUtil;
 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.enums.order.TradeOrderTypeEnum;
 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;
@@ -28,7 +30,7 @@ public class TradeBargainActivityPriceCalculator implements TradePriceCalculator
     @Override
     public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
         // 1. 判断订单类型和是否具有拼团记录编号
-        if (param.getBargainRecordId() != null) {
+        if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.BARGAIN.getType())) {
             return;
         }
         Assert.isTrue(param.getItems().size() == 1, "砍价时,只允许选择一个商品");
@@ -40,6 +42,7 @@ public class TradeBargainActivityPriceCalculator implements TradePriceCalculator
 
         // 3.1 记录优惠明细
         Integer discountPrice = orderItem.getPayPrice() - bargainActivity.getBargainPrice() * orderItem.getCount();
+        // TODO 芋艿:极端情况,优惠金额为负数,需要处理
         TradePriceCalculatorHelper.addPromotion(result, orderItem,
                 param.getSeckillActivityId(), bargainActivity.getName(), PromotionTypeEnum.BARGAIN_ACTIVITY.getType(),
                 StrUtil.format("砍价活动:省 {} 元", TradePriceCalculatorHelper.formatPrice(discountPrice)),