Commit bc07e1dbf43941b51655ad8287d129a66c03d19c

Authored by owen
1 parent 74ef98f8

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

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
85 85  
86 86 @Override
87 87 public TradeAfterSaleDO getAfterSale(Long userId, Long id) {
88   - return tradeAfterSaleMapper.selectByIdAndUserId(id, userId);
  88 + return tradeAfterSaleMapper.selectByIdAndUserId(id, userId);
89 89 }
90 90  
91 91 @Override
... ... @@ -167,9 +167,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
167 167 tradeAfterSaleMapper.insert(afterSale);
168 168  
169 169 // 更新交易订单项的售后状态
170   - tradeOrderUpdateService.updateOrderItemAfterSaleStatus(orderItem.getId(),
171   - TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(),
172   - afterSale.getId(), null);
  170 + tradeOrderUpdateService.updateOrderItemWhenAfterSaleCreate(orderItem.getId(), afterSale.getId());
173 171  
174 172 // 记录售后日志
175 173 createAfterSaleLog(orderItem.getUserId(), UserTypeEnum.MEMBER.getValue(),
... ... @@ -219,8 +217,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
219 217 // TODO 发送售后消息
220 218  
221 219 // 更新交易订单项的售后状态为【未申请】
222   - tradeOrderUpdateService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(),
223   - TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus());
  220 + tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId());
224 221 }
225 222  
226 223 /**
... ... @@ -313,8 +310,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
313 310 // TODO 发送售后消息
314 311  
315 312 // 更新交易订单项的售后状态为【未申请】
316   - tradeOrderUpdateService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(),
317   - TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus());
  313 + tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId());
318 314 }
319 315  
320 316 /**
... ... @@ -360,9 +356,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
360 356 // TODO 发送售后消息
361 357  
362 358 // 更新交易订单项的售后状态为【已完成】
363   - tradeOrderUpdateService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(),
364   - TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus(),
365   - null, afterSale.getRefundPrice());
  359 + tradeOrderUpdateService.updateOrderItemWhenAfterSaleSuccess(afterSale.getOrderItemId(), afterSale.getRefundPrice());
366 360 }
367 361  
368 362 private void createPayRefund(String userIp, TradeAfterSaleDO afterSale) {
... ... @@ -403,8 +397,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
403 397 // TODO 发送售后消息
404 398  
405 399 // 更新交易订单项的售后状态为【未申请】
406   - tradeOrderUpdateService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(),
407   - TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus());
  400 + tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId());
408 401 }
409 402  
410 403 @Override
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java
1 1 package cn.iocoder.yudao.module.trade.service.order;
2 2  
3   -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderUpdateAddressReqVO;
4   -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderUpdatePriceReqVO;
5 3 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
6 4 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderRemarkReqVO;
  5 +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderUpdateAddressReqVO;
  6 +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderUpdatePriceReqVO;
7 7 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO;
8 8 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO;
9 9 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO;
10 10 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
11 11 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
12 12  
  13 +import javax.validation.constraints.NotNull;
  14 +
13 15 /**
14 16 * 交易订单【写】Service 接口
15 17 *
... ... @@ -116,27 +118,28 @@ public interface TradeOrderUpdateService {
116 118 // =================== Order Item ===================
117 119  
118 120 /**
119   - * 更新交易订单项的售后状态
  121 + * 当售后申请后,更新交易订单项的售后状态
  122 + *
  123 + * @param id 交易订单项编号
  124 + * @param afterSaleId 售后单编号
  125 + */
  126 + void updateOrderItemWhenAfterSaleCreate(@NotNull Long id, @NotNull Long afterSaleId);
  127 +
  128 +
  129 + /**
  130 + * 当售后完成后,更新交易订单项的售后状态
120 131 *
121   - * @param id 交易订单项编号
122   - * @param oldAfterSaleStatus 当前售后状态;如果不符,更新后会抛出异常
123   - * @param newAfterSaleStatus 目标售后状态
  132 + * @param id 交易订单项编号
  133 + * @param refundPrice 退款金额
124 134 */
125   - default void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus) {
126   - updateOrderItemAfterSaleStatus(id, oldAfterSaleStatus, newAfterSaleStatus, null, null);
127   - }
  135 + void updateOrderItemWhenAfterSaleSuccess(@NotNull Long id, @NotNull Integer refundPrice);
128 136  
129 137 /**
130   - * 更新交易订单项的售后状态
  138 + * 当售后取消(用户取消、管理员驳回、管理员拒绝收货)后,更新交易订单项的售后状态
131 139 *
132   - * @param id 交易订单项编号
133   - * @param oldAfterSaleStatus 当前售后状态;如果不符,更新后会抛出异常
134   - * @param newAfterSaleStatus 目标售后状态
135   - * @param afterSaleId 售后单编号;当订单项发起售后时,必须传递该字段
136   - * @param refundPrice 退款金额;当订单项退款成功时,必须传递该值
  140 + * @param id 交易订单项编号
137 141 */
138   - void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus,
139   - Long afterSaleId, Integer refundPrice);
  142 + void updateOrderItemWhenAfterSaleCancel(@NotNull Long id);
140 143  
141 144 /**
142 145 * 创建订单项的评论
... ...
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 {
508 508 for (TradeOrderDO order : orders) {
509 509 try {
510 510 getSelf().receiveOrderBySystem(order);
511   - count ++;
  511 + count++;
512 512 } catch (Throwable e) {
513 513 log.error("[autoReceiveOrder][order({}) 自动收货订单异常]", order.getId(), e);
514 514 }
... ... @@ -599,7 +599,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
599 599 for (TradeOrderDO order : orders) {
600 600 try {
601 601 getSelf().cancelOrderBySystem(order);
602   - count ++;
  602 + count++;
603 603 } catch (Throwable e) {
604 604 log.error("[autoCancelOrder][order({}) 过期订单异常]", order.getId(), e);
605 605 }
... ... @@ -621,7 +621,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
621 621 /**
622 622 * 取消订单的核心实现
623 623 *
624   - * @param order 订单
  624 + * @param order 订单
625 625 * @param cancelType 取消类型
626 626 */
627 627 private void cancelOrder0(TradeOrderDO order, TradeOrderCancelTypeEnum cancelType) {
... ... @@ -770,69 +770,81 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
770 770  
771 771 // =================== Order Item ===================
772 772  
773   - // TODO 疯狂:帮我重构下:
774   - // 1. updateOrderItemAfterSaleStatus 拆分成三个方法:发起;同意;拒绝。原因是,职责更清晰,操作日志也更容易记录;
775   -
776 773 @Override
777   - @Transactional(rollbackFor = Exception.class)
778   - public void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus,
779   - Long afterSaleId, Integer refundPrice) {
780   - // 如果退款成功,则 refundPrice 非空
781   - if (Objects.equals(newAfterSaleStatus, TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())
782   - && refundPrice == null) {
783   - throw new IllegalArgumentException(StrUtil.format("id({}) 退款成功,退款金额不能为空", id));
784   - }
785   - // 如果退款发起,则 afterSaleId 非空
786   - if (Objects.equals(newAfterSaleStatus, TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus())
787   - && afterSaleId == null) {
  774 + public void updateOrderItemWhenAfterSaleCreate(Long id, Long afterSaleId) {
  775 + if (afterSaleId == null) {
788 776 throw new IllegalArgumentException(StrUtil.format("id({}) 退款发起,售后单编号不能为空", id));
789 777 }
790 778  
791 779 // 更新订单项
792   - int updateCount = tradeOrderItemMapper.updateAfterSaleStatus(id, oldAfterSaleStatus, newAfterSaleStatus, afterSaleId);
793   - if (updateCount <= 0) {
794   - throw exception(ORDER_ITEM_UPDATE_AFTER_SALE_STATUS_FAIL);
795   - }
  780 + updateOrderItemAfterSaleStatus(id, TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(),
  781 + TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), afterSaleId);
  782 + }
796 783  
797   - // 如果有退款金额,则需要更新订单
  784 + @Override
  785 + @Transactional(rollbackFor = Exception.class)
  786 + public void updateOrderItemWhenAfterSaleSuccess(Long id, Integer refundPrice) {
798 787 if (refundPrice == null) {
799   - return;
  788 + throw new IllegalArgumentException(StrUtil.format("id({}) 退款成功,退款金额不能为空", id));
800 789 }
801   - // 计算总的退款金额
  790 +
  791 + // 1. 更新订单项
  792 + updateOrderItemAfterSaleStatus(id, TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(),
  793 + TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus(), null);
  794 +
  795 + // 2. 计算总的退款金额、退回积分
802 796 TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(id);
803 797 TradeOrderDO order = tradeOrderMapper.selectById(orderItem.getOrderId());
804 798 Integer orderRefundPrice = order.getRefundPrice() + refundPrice;
805   - // TODO @疯狂:809 到 817 改成:cancelOrderByAfterSale:相当于全部售后成功后,就是要取消胆子;
  799 + Integer orderRefundPoint = order.getRefundPoint() + orderItem.getUsePoint();
806 800 if (isAllOrderItemAfterSaleSuccess(order.getId())) { // 如果都售后成功,则需要取消订单
807   - tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId())
808   - .setRefundStatus(TradeOrderRefundStatusEnum.ALL.getStatus()).setRefundPrice(orderRefundPrice).setRefundPoint(order.getRefundPoint() + orderItem.getUsePoint())
809   - .setCancelType(TradeOrderCancelTypeEnum.AFTER_SALE_CLOSE.getType()).setCancelTime(LocalDateTime.now()));
810   -
811   - // TODO 芋艿:记录订单日志
812   -
813   - // TODO 芋艿:要不要退优惠劵
814   -
  801 + cancelOrderByAfterSale(order, orderRefundPrice, orderRefundPoint);
815 802 } else { // 如果部分售后,则更新退款金额
816 803 tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId())
817   - .setRefundStatus(TradeOrderRefundStatusEnum.PART.getStatus()).setRefundPrice(orderRefundPrice));
  804 + .setRefundStatus(TradeOrderRefundStatusEnum.PART.getStatus())
  805 + .setRefundPrice(orderRefundPrice).setRefundPoint(orderRefundPoint));
818 806 }
819 807  
820 808 // TODO 芋艿:这块扣减规则,需要在考虑下
821   - // 售后成功后,执行数据回滚逻辑
822   - if (Objects.equals(newAfterSaleStatus, TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())) {
823   - // 增加 SKU 库存
824   - productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(Collections.singletonList(orderItem)));
825   - // 扣减用户积分(赠送的)
826   - reduceUserPoint(order.getUserId(), orderItem.getGivePoint(), MemberPointBizTypeEnum.AFTER_SALE_DEDUCT_GIVE, afterSaleId);
827   - // 增加用户积分(返还抵扣)
828   - addUserPoint(order.getUserId(), orderItem.getUsePoint(), MemberPointBizTypeEnum.AFTER_SALE_REFUND_USED, afterSaleId);
829   - // 扣减用户经验
830   - getSelf().reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, afterSaleId);
831   - // 更新分佣记录为已失效
832   - getSelf().cancelBrokerageAsync(order.getUserId(), id);
  809 + // 3.1 回滚数据:增加 SKU 库存
  810 + productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(Collections.singletonList(orderItem)));
  811 + // 3.2 回滚数据:扣减用户积分(赠送的)
  812 + reduceUserPoint(order.getUserId(), orderItem.getGivePoint(), MemberPointBizTypeEnum.AFTER_SALE_DEDUCT_GIVE, orderItem.getAfterSaleId());
  813 + // 3.3 回滚数据:增加用户积分(返还抵扣)
  814 + addUserPoint(order.getUserId(), orderItem.getUsePoint(), MemberPointBizTypeEnum.AFTER_SALE_REFUND_USED, orderItem.getAfterSaleId());
  815 + // 3.4 回滚数据:扣减用户经验
  816 + getSelf().reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, orderItem.getAfterSaleId());
  817 + // 3.5 回滚数据:更新分佣记录为已失效
  818 + getSelf().cancelBrokerageAsync(order.getUserId(), id);
  819 + }
  820 +
  821 + @Override
  822 + public void updateOrderItemWhenAfterSaleCancel(Long id) {
  823 + // 更新订单项
  824 + updateOrderItemAfterSaleStatus(id, TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(),
  825 + TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null);
  826 + }
  827 +
  828 + private void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus,
  829 + Long afterSaleId) {
  830 + // 更新订单项
  831 + int updateCount = tradeOrderItemMapper.updateAfterSaleStatus(id, oldAfterSaleStatus, newAfterSaleStatus, afterSaleId);
  832 + if (updateCount <= 0) {
  833 + throw exception(ORDER_ITEM_UPDATE_AFTER_SALE_STATUS_FAIL);
833 834 }
834 835 }
835 836  
  837 + @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CANCEL)
  838 + private void cancelOrderByAfterSale(TradeOrderDO order, Integer orderRefundPrice, Integer refundPoint) {
  839 + // 1. 更新订单
  840 + tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId())
  841 + .setRefundStatus(TradeOrderRefundStatusEnum.ALL.getStatus())
  842 + .setRefundPrice(orderRefundPrice).setRefundPoint(refundPoint)
  843 + .setCancelType(TradeOrderCancelTypeEnum.AFTER_SALE_CLOSE.getType()).setCancelTime(LocalDateTime.now()));
  844 + // 2. 退还优惠券
  845 + couponApi.returnUsedCoupon(order.getCouponId());
  846 + }
  847 +
836 848 @Override
837 849 @Transactional(rollbackFor = Exception.class)
838 850 @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_COMMENT)
... ...