Browse Source

售后:重构售后更新订单的逻辑

owen 1 year ago
parent
commit
bc07e1dbf4

+ 6 - 13
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java

@@ -85,7 +85,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
 
     @Override
     public TradeAfterSaleDO getAfterSale(Long userId, Long id) {
-         return tradeAfterSaleMapper.selectByIdAndUserId(id, userId);
+        return tradeAfterSaleMapper.selectByIdAndUserId(id, userId);
     }
 
     @Override
@@ -167,9 +167,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
         tradeAfterSaleMapper.insert(afterSale);
 
         // 更新交易订单项的售后状态
-        tradeOrderUpdateService.updateOrderItemAfterSaleStatus(orderItem.getId(),
-                TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(),
-                afterSale.getId(), null);
+        tradeOrderUpdateService.updateOrderItemWhenAfterSaleCreate(orderItem.getId(), afterSale.getId());
 
         // 记录售后日志
         createAfterSaleLog(orderItem.getUserId(), UserTypeEnum.MEMBER.getValue(),
@@ -219,8 +217,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
         // TODO 发送售后消息
 
         // 更新交易订单项的售后状态为【未申请】
-        tradeOrderUpdateService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(),
-                TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus());
+        tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId());
     }
 
     /**
@@ -313,8 +310,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
         // TODO 发送售后消息
 
         // 更新交易订单项的售后状态为【未申请】
-        tradeOrderUpdateService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(),
-                TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus());
+        tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId());
     }
 
     /**
@@ -360,9 +356,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
         // TODO 发送售后消息
 
         // 更新交易订单项的售后状态为【已完成】
-        tradeOrderUpdateService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(),
-                TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus(),
-                null, afterSale.getRefundPrice());
+        tradeOrderUpdateService.updateOrderItemWhenAfterSaleSuccess(afterSale.getOrderItemId(), afterSale.getRefundPrice());
     }
 
     private void createPayRefund(String userIp, TradeAfterSaleDO afterSale) {
@@ -403,8 +397,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
         // TODO 发送售后消息
 
         // 更新交易订单项的售后状态为【未申请】
-        tradeOrderUpdateService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(),
-                TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus());
+        tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId());
     }
 
     @Override

+ 20 - 17
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java

@@ -1,15 +1,17 @@
 package cn.iocoder.yudao.module.trade.service.order;
 
-import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderUpdateAddressReqVO;
-import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderUpdatePriceReqVO;
 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderRemarkReqVO;
+import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderUpdateAddressReqVO;
+import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderUpdatePriceReqVO;
 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO;
 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO;
 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO;
 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
 
+import javax.validation.constraints.NotNull;
+
 /**
  * 交易订单【写】Service 接口
  *
@@ -116,27 +118,28 @@ public interface TradeOrderUpdateService {
     // =================== Order Item ===================
 
     /**
-     * 更新交易订单项的售后状态
+     * 当售后申请后,更新交易订单项的售后状态
+     *
+     * @param id          交易订单项编号
+     * @param afterSaleId 售后单编号
+     */
+    void updateOrderItemWhenAfterSaleCreate(@NotNull Long id, @NotNull Long afterSaleId);
+
+
+    /**
+     * 当售后完成后,更新交易订单项的售后状态
      *
-     * @param id                 交易订单项编号
-     * @param oldAfterSaleStatus 当前售后状态;如果不符,更新后会抛出异常
-     * @param newAfterSaleStatus 目标售后状态
+     * @param id          交易订单项编号
+     * @param refundPrice 退款金额
      */
-    default void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus) {
-        updateOrderItemAfterSaleStatus(id, oldAfterSaleStatus, newAfterSaleStatus, null, null);
-    }
+    void updateOrderItemWhenAfterSaleSuccess(@NotNull Long id, @NotNull Integer refundPrice);
 
     /**
-     * 更新交易订单项的售后状态
+     * 当售后取消(用户取消、管理员驳回、管理员拒绝收货)后,更新交易订单项的售后状态
      *
-     * @param id                 交易订单项编号
-     * @param oldAfterSaleStatus 当前售后状态;如果不符,更新后会抛出异常
-     * @param newAfterSaleStatus 目标售后状态
-     * @param afterSaleId        售后单编号;当订单项发起售后时,必须传递该字段
-     * @param refundPrice        退款金额;当订单项退款成功时,必须传递该值
+     * @param id 交易订单项编号
      */
-    void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus,
-                                        Long afterSaleId, Integer refundPrice);
+    void updateOrderItemWhenAfterSaleCancel(@NotNull Long id);
 
     /**
      * 创建订单项的评论

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

@@ -508,7 +508,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         for (TradeOrderDO order : orders) {
             try {
                 getSelf().receiveOrderBySystem(order);
-                count ++;
+                count++;
             } catch (Throwable e) {
                 log.error("[autoReceiveOrder][order({}) 自动收货订单异常]", order.getId(), e);
             }
@@ -599,7 +599,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         for (TradeOrderDO order : orders) {
             try {
                 getSelf().cancelOrderBySystem(order);
-                count ++;
+                count++;
             } catch (Throwable e) {
                 log.error("[autoCancelOrder][order({}) 过期订单异常]", order.getId(), e);
             }
@@ -621,7 +621,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
     /**
      * 取消订单的核心实现
      *
-     * @param order 订单
+     * @param order      订单
      * @param cancelType 取消类型
      */
     private void cancelOrder0(TradeOrderDO order, TradeOrderCancelTypeEnum cancelType) {
@@ -770,69 +770,81 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 
     // =================== Order Item ===================
 
-    // TODO 疯狂:帮我重构下:
-    // 1. updateOrderItemAfterSaleStatus 拆分成三个方法:发起;同意;拒绝。原因是,职责更清晰,操作日志也更容易记录;
-
     @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus,
-                                               Long afterSaleId, Integer refundPrice) {
-        // 如果退款成功,则 refundPrice 非空
-        if (Objects.equals(newAfterSaleStatus, TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())
-                && refundPrice == null) {
-            throw new IllegalArgumentException(StrUtil.format("id({}) 退款成功,退款金额不能为空", id));
-        }
-        // 如果退款发起,则 afterSaleId 非空
-        if (Objects.equals(newAfterSaleStatus, TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus())
-                && afterSaleId == null) {
+    public void updateOrderItemWhenAfterSaleCreate(Long id, Long afterSaleId) {
+        if (afterSaleId == null) {
             throw new IllegalArgumentException(StrUtil.format("id({}) 退款发起,售后单编号不能为空", id));
         }
 
         // 更新订单项
-        int updateCount = tradeOrderItemMapper.updateAfterSaleStatus(id, oldAfterSaleStatus, newAfterSaleStatus, afterSaleId);
-        if (updateCount <= 0) {
-            throw exception(ORDER_ITEM_UPDATE_AFTER_SALE_STATUS_FAIL);
-        }
+        updateOrderItemAfterSaleStatus(id, TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(),
+                TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), afterSaleId);
+    }
 
-        // 如果有退款金额,则需要更新订单
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateOrderItemWhenAfterSaleSuccess(Long id, Integer refundPrice) {
         if (refundPrice == null) {
-            return;
+            throw new IllegalArgumentException(StrUtil.format("id({}) 退款成功,退款金额不能为空", id));
         }
-        // 计算总的退款金额
+
+        // 1. 更新订单项
+        updateOrderItemAfterSaleStatus(id, TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(),
+                TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus(), null);
+
+        // 2. 计算总的退款金额、退回积分
         TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(id);
         TradeOrderDO order = tradeOrderMapper.selectById(orderItem.getOrderId());
         Integer orderRefundPrice = order.getRefundPrice() + refundPrice;
-        // TODO @疯狂:809 到 817 改成:cancelOrderByAfterSale:相当于全部售后成功后,就是要取消胆子;
+        Integer orderRefundPoint = order.getRefundPoint() + orderItem.getUsePoint();
         if (isAllOrderItemAfterSaleSuccess(order.getId())) { // 如果都售后成功,则需要取消订单
-            tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId())
-                    .setRefundStatus(TradeOrderRefundStatusEnum.ALL.getStatus()).setRefundPrice(orderRefundPrice).setRefundPoint(order.getRefundPoint() + orderItem.getUsePoint())
-                    .setCancelType(TradeOrderCancelTypeEnum.AFTER_SALE_CLOSE.getType()).setCancelTime(LocalDateTime.now()));
-
-            // TODO 芋艿:记录订单日志
-
-            // TODO 芋艿:要不要退优惠劵
-
+            cancelOrderByAfterSale(order, orderRefundPrice, orderRefundPoint);
         } else { // 如果部分售后,则更新退款金额
             tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId())
-                    .setRefundStatus(TradeOrderRefundStatusEnum.PART.getStatus()).setRefundPrice(orderRefundPrice));
+                    .setRefundStatus(TradeOrderRefundStatusEnum.PART.getStatus())
+                    .setRefundPrice(orderRefundPrice).setRefundPoint(orderRefundPoint));
         }
 
         // TODO 芋艿:这块扣减规则,需要在考虑下
-        // 售后成功后,执行数据回滚逻辑
-        if (Objects.equals(newAfterSaleStatus, TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())) {
-            // 增加 SKU 库存
-            productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(Collections.singletonList(orderItem)));
-            // 扣减用户积分(赠送的)
-            reduceUserPoint(order.getUserId(), orderItem.getGivePoint(), MemberPointBizTypeEnum.AFTER_SALE_DEDUCT_GIVE, afterSaleId);
-            // 增加用户积分(返还抵扣)
-            addUserPoint(order.getUserId(), orderItem.getUsePoint(), MemberPointBizTypeEnum.AFTER_SALE_REFUND_USED, afterSaleId);
-            // 扣减用户经验
-            getSelf().reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, afterSaleId);
-            // 更新分佣记录为已失效
-            getSelf().cancelBrokerageAsync(order.getUserId(), id);
+        // 3.1 回滚数据:增加 SKU 库存
+        productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(Collections.singletonList(orderItem)));
+        // 3.2 回滚数据:扣减用户积分(赠送的)
+        reduceUserPoint(order.getUserId(), orderItem.getGivePoint(), MemberPointBizTypeEnum.AFTER_SALE_DEDUCT_GIVE, orderItem.getAfterSaleId());
+        // 3.3 回滚数据:增加用户积分(返还抵扣)
+        addUserPoint(order.getUserId(), orderItem.getUsePoint(), MemberPointBizTypeEnum.AFTER_SALE_REFUND_USED, orderItem.getAfterSaleId());
+        // 3.4 回滚数据:扣减用户经验
+        getSelf().reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, orderItem.getAfterSaleId());
+        // 3.5 回滚数据:更新分佣记录为已失效
+        getSelf().cancelBrokerageAsync(order.getUserId(), id);
+    }
+
+    @Override
+    public void updateOrderItemWhenAfterSaleCancel(Long id) {
+        // 更新订单项
+        updateOrderItemAfterSaleStatus(id, TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(),
+                TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null);
+    }
+
+    private void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus,
+                                                Long afterSaleId) {
+        // 更新订单项
+        int updateCount = tradeOrderItemMapper.updateAfterSaleStatus(id, oldAfterSaleStatus, newAfterSaleStatus, afterSaleId);
+        if (updateCount <= 0) {
+            throw exception(ORDER_ITEM_UPDATE_AFTER_SALE_STATUS_FAIL);
         }
     }
 
+    @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CANCEL)
+    private void cancelOrderByAfterSale(TradeOrderDO order, Integer orderRefundPrice, Integer refundPoint) {
+        // 1. 更新订单
+        tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId())
+                .setRefundStatus(TradeOrderRefundStatusEnum.ALL.getStatus())
+                .setRefundPrice(orderRefundPrice).setRefundPoint(refundPoint)
+                .setCancelType(TradeOrderCancelTypeEnum.AFTER_SALE_CLOSE.getType()).setCancelTime(LocalDateTime.now()));
+        // 2. 退还优惠券
+        couponApi.returnUsedCoupon(order.getCouponId());
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_COMMENT)