Browse Source

重构:将订单的分支流程,抽到 TradeOrderHandler 实现类中(补全各种排重逻辑)

YunaiV 1 year ago
parent
commit
b0179457ce

+ 1 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java

@@ -41,7 +41,7 @@ public interface SeckillProductMapper extends BaseMapperX<SeckillProductDO> {
         Assert.isTrue(count > 0);
         return update(null, new LambdaUpdateWrapper<SeckillProductDO>()
                 .eq(SeckillProductDO::getId, id)
-                .gt(SeckillProductDO::getStock, count)
+                .ge(SeckillProductDO::getStock, count)
                 .setSql("stock = stock - " + count));
     }
 

+ 18 - 5
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBargainOrderHandler.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.trade.service.order.handler;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
 import cn.iocoder.yudao.module.promotion.api.bargain.BargainActivityApi;
 import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi;
@@ -50,16 +51,28 @@ public class TradeBargainOrderHandler implements TradeOrderHandler {
     }
 
     @Override
-    public void cancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
-        if (TradeOrderTypeEnum.isBargain(order.getType())) {
+    public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
+        if (!TradeOrderTypeEnum.isBargain(order.getType())) {
             return;
         }
         // 明确校验一下
         Assert.isTrue(orderItems.size() == 1, "砍价时,只允许选择一个商品");
 
-        // 恢复砍价活动的库存
-        bargainActivityApi.updateBargainActivityStock(order.getBargainActivityId(),
-                orderItems.get(0).getCount());
+        // 售后的订单项,已经在 afterCancelOrderItem 回滚库存,所以这里不需要重复回滚
+        orderItems = filterOrderItemListByNoneAfterSale(orderItems);
+        if (CollUtil.isEmpty(orderItems)) {
+            return;
+        }
+        afterCancelOrderItem(order, orderItems.get(0));
+    }
+
+    @Override
+    public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) {
+        if (!TradeOrderTypeEnum.isBargain(order.getType())) {
+            return;
+        }
+        // 恢复(增加)砍价活动的库存
+        bargainActivityApi.updateBargainActivityStock(order.getBargainActivityId(), orderItem.getCount());
     }
 
 }

+ 8 - 10
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationOrderHandler.java

@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.service.order.handler;
 
 import cn.hutool.core.lang.Assert;
 import cn.iocoder.yudao.framework.common.core.KeyValue;
-import cn.iocoder.yudao.framework.common.core.KeyValue;
 import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
@@ -17,11 +16,9 @@ import org.springframework.stereotype.Component;
 import javax.annotation.Resource;
 import java.util.List;
 
-import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS;
-
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_CREATE_FAIL_EXIST_UNPAID;
+import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS;
 
 /**
  * 拼团订单的 {@link TradeOrderHandler} 实现类
@@ -50,11 +47,11 @@ public class TradeCombinationOrderHandler implements TradeOrderHandler {
         }
         Assert.isTrue(orderItems.size() == 1, "拼团时,只允许选择一个商品");
 
-        // 校验是否满足拼团活动相关限制
+        // 1. 校验是否满足拼团活动相关限制
         TradeOrderItemDO item = orderItems.get(0);
         combinationRecordApi.validateCombinationRecord(order.getUserId(), order.getCombinationActivityId(),
                 order.getCombinationHeadId(), item.getSkuId(), item.getCount());
-        // 校验该用户是否存在未支付的拼团活动订单;就是还没支付的时候,重复下单了;需要校验下;不然的话,一个拼团可以下多个单子了;
+        // 2. 校验该用户是否存在未支付的拼团活动订单;就是还没支付的时候,重复下单了;需要校验下;不然的话,一个拼团可以下多个单子了;
         TradeOrderDO activityOrder = orderQueryService.getActivityOrderByUserIdAndActivityIdAndStatus(
                 order.getUserId(), order.getCombinationActivityId(), TradeOrderStatusEnum.UNPAID.getStatus());
         if (activityOrder != null) {
@@ -65,17 +62,18 @@ public class TradeCombinationOrderHandler implements TradeOrderHandler {
     @Override
     public void afterPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
         // 1.如果不是拼团订单则结束
-        if (TradeOrderTypeEnum.isCombination(order.getType())) {
+        if (!TradeOrderTypeEnum.isCombination(order.getType())) {
             return;
         }
         Assert.isTrue(orderItems.size() == 1, "拼团时,只允许选择一个商品");
 
-        // 2.获取商品信息
+        // 2. 创建拼团记录
         TradeOrderItemDO item = orderItems.get(0);
-        // 2.1.创建拼团记录
         KeyValue<Long, Long> recordIdAndHeadId = combinationRecordApi.createCombinationRecord(
                 TradeOrderConvert.INSTANCE.convert(order, item));
-        // 3.更新拼团相关信息到订单
+
+        // 3. 更新拼团相关信息到订单
+        // TODO 芋艿,只需要更新 record
         orderUpdateService.updateOrderCombinationInfo(order.getId(), order.getCombinationActivityId(),
                 recordIdAndHeadId.getKey(), recordIdAndHeadId.getValue());
     }

+ 13 - 13
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeMemberPointOrderHandler.java

@@ -45,8 +45,8 @@ public class TradeMemberPointOrderHandler implements TradeOrderHandler {
                 order.getId());
 
         // 增加用户经验
-        memberLevelApi.addExperience(order.getUserId(), order.getPayPrice(), MemberExperienceBizTypeEnum.ORDER.getType(),
-                String.valueOf(order.getId()));
+        memberLevelApi.addExperience(order.getUserId(), order.getPayPrice(),
+                MemberExperienceBizTypeEnum.ORDER_GIVE.getType(), String.valueOf(order.getId()));
     }
 
     @Override
@@ -59,36 +59,36 @@ public class TradeMemberPointOrderHandler implements TradeOrderHandler {
 
         // 增加(回滚)用户积分(订单抵扣)
         Integer usePoint = getSumValue(orderItems, TradeOrderItemDO::getUsePoint, Integer::sum);
-        addPoint(order.getUserId(), usePoint, MemberPointBizTypeEnum.ORDER_CANCEL,
+        addPoint(order.getUserId(), usePoint, MemberPointBizTypeEnum.ORDER_USE_CANCEL,
                 order.getId());
+
         // 如下的返还,需要经过支持,也就是经历 afterPayOrder 流程
         if (!order.getPayStatus()) {
             return;
         }
         // 扣减(回滚)积分(订单赠送)
         Integer givePoint = getSumValue(orderItems, TradeOrderItemDO::getGivePoint, Integer::sum);
-        reducePoint(order.getUserId(), givePoint, MemberPointBizTypeEnum.ORDER_CANCEL,
+        reducePoint(order.getUserId(), givePoint, MemberPointBizTypeEnum.ORDER_GIVE_CANCEL,
                 order.getId());
         // 扣减(回滚)用户经验
         int payPrice = order.getPayPrice() - order.getRefundPrice();
-        // TODO @疯狂:这里的 bizId 和 afterCancelOrderItem 不一致了,有什么建议的处理方案?
-        memberLevelApi.addExperience(order.getUserId(), -payPrice, MemberExperienceBizTypeEnum.REFUND.getType(),
-                String.valueOf(order.getId()));
+        memberLevelApi.addExperience(order.getUserId(), payPrice,
+                MemberExperienceBizTypeEnum.ORDER_GIVE_CANCEL.getType(), String.valueOf(order.getId()));
     }
 
     @Override
     public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) {
         // 扣减(回滚)积分(订单赠送)
-        reducePoint(order.getUserId(), orderItem.getGivePoint(), MemberPointBizTypeEnum.AFTER_SALE_DEDUCT_GIVE,
-                orderItem.getAfterSaleId());
+        reducePoint(order.getUserId(), orderItem.getGivePoint(), MemberPointBizTypeEnum.ORDER_GIVE_CANCEL_ITEM,
+                orderItem.getId());
         // 增加(回滚)积分(订单抵扣)
-        addPoint(order.getUserId(), orderItem.getUsePoint(), MemberPointBizTypeEnum.AFTER_SALE_REFUND_USED,
-                orderItem.getAfterSaleId());
+        addPoint(order.getUserId(), orderItem.getUsePoint(), MemberPointBizTypeEnum.ORDER_USE_CANCEL_ITEM,
+                orderItem.getId());
 
         // 扣减(回滚)用户经验
         AfterSaleDO afterSale = afterSaleService.getAfterSale(orderItem.getAfterSaleId());
-        memberLevelApi.addExperience(order.getUserId(), -afterSale.getRefundPrice(), MemberExperienceBizTypeEnum.REFUND.getType(),
-                String.valueOf(orderItem.getAfterSaleId()));
+        memberLevelApi.reduceExperience(order.getUserId(), afterSale.getRefundPrice(),
+                MemberExperienceBizTypeEnum.ORDER_GIVE_CANCEL_ITEM.getType(), String.valueOf(orderItem.getId()));
     }
 
     /**

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

@@ -1,6 +1,6 @@
 package cn.iocoder.yudao.module.trade.service.order.handler;
 
-import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 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.TradeOrderItemAfterSaleStatusEnum;
@@ -71,8 +71,8 @@ public interface TradeOrderHandler {
      * @return 过滤后的订单项列表
      */
     default List<TradeOrderItemDO> filterOrderItemListByNoneAfterSale(List<TradeOrderItemDO> orderItems) {
-        CollUtil.filterNew(orderItems, item -> !TradeOrderItemAfterSaleStatusEnum.isNone(item.getAfterSaleStatus()));
-        return orderItems;
+        return CollectionUtils.filterList(orderItems,
+                item -> TradeOrderItemAfterSaleStatusEnum.isNone(item.getAfterSaleStatus()));
     }
 
 }

+ 17 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeSeckillOrderHandler.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.trade.service.order.handler;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
 import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
@@ -35,16 +36,29 @@ public class TradeSeckillOrderHandler implements TradeOrderHandler {
     }
 
     @Override
-    public void cancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
-        if (TradeOrderTypeEnum.isSeckill(order.getType())) {
+    public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
+        if (!TradeOrderTypeEnum.isSeckill(order.getType())) {
             return;
         }
         // 明确校验一下
         Assert.isTrue(orderItems.size() == 1, "秒杀时,只允许选择一个商品");
 
+        // 售后的订单项,已经在 afterCancelOrderItem 回滚库存,所以这里不需要重复回滚
+        orderItems = filterOrderItemListByNoneAfterSale(orderItems);
+        if (CollUtil.isEmpty(orderItems)) {
+            return;
+        }
+        afterCancelOrderItem(order, orderItems.get(0));
+    }
+
+    @Override
+    public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) {
+        if (!TradeOrderTypeEnum.isSeckill(order.getType())) {
+            return;
+        }
         // 恢复秒杀活动的库存
         seckillActivityApi.updateSeckillStockIncr(order.getSeckillActivityId(),
-                orderItems.get(0).getSkuId(), orderItems.get(0).getCount());
+                orderItem.getSkuId(), orderItem.getCount());
     }
 
 }

+ 10 - 1
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApi.java

@@ -18,7 +18,6 @@ public interface MemberLevelApi {
      */
     MemberLevelRespDTO getMemberLevel(Long id);
 
-    // TODO 芋艿:后续增加一个减少接口;
     /**
      * 增加会员经验
      *
@@ -29,4 +28,14 @@ public interface MemberLevelApi {
      */
     void addExperience(Long userId, Integer experience, Integer bizType, String bizId);
 
+    /**
+     * 扣减会员经验
+     *
+     * @param userId     会员ID
+     * @param experience 经验
+     * @param bizType    业务类型 {@link MemberExperienceBizTypeEnum}
+     * @param bizId      业务编号
+     */
+    void reduceExperience(Long userId, Integer experience, Integer bizType, String bizId);
+
 }

+ 3 - 2
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberExperienceBizTypeEnum.java

@@ -20,10 +20,11 @@ public enum MemberExperienceBizTypeEnum {
      */
     ADMIN(0, "管理员调整", "管理员调整获得 {} 经验", true),
     INVITE_REGISTER(1, "邀新奖励", "邀请好友获得 {} 经验", true),
-    ORDER(2, "下单奖励", "下单获得 {} 经验", true),
-    REFUND(3, "退单扣除", "退单获得 {} 经验", false),
     SIGN_IN(4, "签到奖励", "签到获得 {} 经验", true),
     LOTTERY(5, "抽奖奖励", "抽奖获得 {} 经验", true),
+    ORDER_GIVE(11, "下单奖励", "下单获得 {} 经验", true),
+    ORDER_GIVE_CANCEL(12, "下单奖励(整单取消)", "取消订单获得 {} 经验", false), // ORDER_GIVE 的取消
+    ORDER_GIVE_CANCEL_ITEM(13, "下单奖励(单个退款)", "退款订单获得 {} 经验", false), // ORDER_GIVE 的取消
     ;
 
     /**

+ 8 - 5
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java

@@ -18,11 +18,14 @@ public enum MemberPointBizTypeEnum implements IntArrayValuable {
 
     SIGN(1, "签到", "签到获得 {} 积分", true),
     ADMIN(2, "管理员修改", "管理员修改 {} 积分", true),
-    ORDER_GIVE(10, "订单奖励", "下单获得 {} 积分", true), // 支付订单时,赠送积分
-    ORDER_CANCEL(11, "订单取消", "订单取消,退还 {} 积分", true), // 取消订单时,退回积分
-    ORDER_USE(12, "订单使用", "下单使用 {} 积分", false), // 下单时,扣减积分
-    AFTER_SALE_REFUND_USED(13, "订单退款", "订单退款,退还 {} 积分", true), // 售后订单成功时,退回积分(对应 ORDER_USE 操作)
-    AFTER_SALE_DEDUCT_GIVE(14, "订单退款", "订单退款,扣除赠送的 {} 积分", false), // 售后订单成功时,扣减积分(对应 ORDER_GIVE 操作)
+
+    ORDER_USE(11, "订单积分抵扣", "下单使用 {} 积分", false), // 下单时,扣减积分
+    ORDER_USE_CANCEL(12, "订单积分抵扣(整单取消)", "订单取消,退还 {} 积分", true), // ORDER_USE 的取消
+    ORDER_USE_CANCEL_ITEM(13, "订单积分抵扣(单个退款)", "订单退款,退还 {} 积分", true), // ORDER_USE 的取消
+
+    ORDER_GIVE(21, "订单积分奖励", "下单获得 {} 积分", true), // 支付订单时,赠送积分
+    ORDER_GIVE_CANCEL(22, "订单积分奖励(整单取消)", "订单取消,退还 {} 积分", false), // ORDER_GIVE 的取消
+    ORDER_GIVE_CANCEL_ITEM(23, "订单积分奖励(单个退款)", "订单退款,扣除赠送的 {} 积分", false) // ORDER_GIVE 的取消
     ;
 
     /**

+ 5 - 0
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApiImpl.java

@@ -38,4 +38,9 @@ public class MemberLevelApiImpl implements MemberLevelApi {
         memberLevelService.addExperience(userId, experience, bizTypeEnum, bizId);
     }
 
+    @Override
+    public void reduceExperience(Long userId, Integer experience, Integer bizType, String bizId) {
+        addExperience(userId, -experience, bizType, bizId);
+    }
+
 }