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,7 +85,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
85 85
86 @Override 86 @Override
87 public TradeAfterSaleDO getAfterSale(Long userId, Long id) { 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 @Override 91 @Override
@@ -167,9 +167,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa @@ -167,9 +167,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
167 tradeAfterSaleMapper.insert(afterSale); 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 createAfterSaleLog(orderItem.getUserId(), UserTypeEnum.MEMBER.getValue(), 173 createAfterSaleLog(orderItem.getUserId(), UserTypeEnum.MEMBER.getValue(),
@@ -219,8 +217,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa @@ -219,8 +217,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
219 // TODO 发送售后消息 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,8 +310,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
313 // TODO 发送售后消息 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,9 +356,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
360 // TODO 发送售后消息 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 private void createPayRefund(String userIp, TradeAfterSaleDO afterSale) { 362 private void createPayRefund(String userIp, TradeAfterSaleDO afterSale) {
@@ -403,8 +397,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa @@ -403,8 +397,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
403 // TODO 发送售后消息 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 @Override 403 @Override
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java
1 package cn.iocoder.yudao.module.trade.service.order; 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 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; 3 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
6 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderRemarkReqVO; 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 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; 7 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO;
8 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO; 8 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO;
9 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO; 9 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO;
10 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; 10 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
11 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 11 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
12 12
  13 +import javax.validation.constraints.NotNull;
  14 +
13 /** 15 /**
14 * 交易订单【写】Service 接口 16 * 交易订单【写】Service 接口
15 * 17 *
@@ -116,27 +118,28 @@ public interface TradeOrderUpdateService { @@ -116,27 +118,28 @@ public interface TradeOrderUpdateService {
116 // =================== Order Item =================== 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,7 +508,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
508 for (TradeOrderDO order : orders) { 508 for (TradeOrderDO order : orders) {
509 try { 509 try {
510 getSelf().receiveOrderBySystem(order); 510 getSelf().receiveOrderBySystem(order);
511 - count ++; 511 + count++;
512 } catch (Throwable e) { 512 } catch (Throwable e) {
513 log.error("[autoReceiveOrder][order({}) 自动收货订单异常]", order.getId(), e); 513 log.error("[autoReceiveOrder][order({}) 自动收货订单异常]", order.getId(), e);
514 } 514 }
@@ -599,7 +599,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -599,7 +599,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
599 for (TradeOrderDO order : orders) { 599 for (TradeOrderDO order : orders) {
600 try { 600 try {
601 getSelf().cancelOrderBySystem(order); 601 getSelf().cancelOrderBySystem(order);
602 - count ++; 602 + count++;
603 } catch (Throwable e) { 603 } catch (Throwable e) {
604 log.error("[autoCancelOrder][order({}) 过期订单异常]", order.getId(), e); 604 log.error("[autoCancelOrder][order({}) 过期订单异常]", order.getId(), e);
605 } 605 }
@@ -621,7 +621,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -621,7 +621,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
621 /** 621 /**
622 * 取消订单的核心实现 622 * 取消订单的核心实现
623 * 623 *
624 - * @param order 订单 624 + * @param order 订单
625 * @param cancelType 取消类型 625 * @param cancelType 取消类型
626 */ 626 */
627 private void cancelOrder0(TradeOrderDO order, TradeOrderCancelTypeEnum cancelType) { 627 private void cancelOrder0(TradeOrderDO order, TradeOrderCancelTypeEnum cancelType) {
@@ -770,69 +770,81 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -770,69 +770,81 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
770 770
771 // =================== Order Item =================== 771 // =================== Order Item ===================
772 772
773 - // TODO 疯狂:帮我重构下:  
774 - // 1. updateOrderItemAfterSaleStatus 拆分成三个方法:发起;同意;拒绝。原因是,职责更清晰,操作日志也更容易记录;  
775 -  
776 @Override 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 throw new IllegalArgumentException(StrUtil.format("id({}) 退款发起,售后单编号不能为空", id)); 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 if (refundPrice == null) { 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 TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(id); 796 TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(id);
803 TradeOrderDO order = tradeOrderMapper.selectById(orderItem.getOrderId()); 797 TradeOrderDO order = tradeOrderMapper.selectById(orderItem.getOrderId());
804 Integer orderRefundPrice = order.getRefundPrice() + refundPrice; 798 Integer orderRefundPrice = order.getRefundPrice() + refundPrice;
805 - // TODO @疯狂:809 到 817 改成:cancelOrderByAfterSale:相当于全部售后成功后,就是要取消胆子; 799 + Integer orderRefundPoint = order.getRefundPoint() + orderItem.getUsePoint();
806 if (isAllOrderItemAfterSaleSuccess(order.getId())) { // 如果都售后成功,则需要取消订单 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 } else { // 如果部分售后,则更新退款金额 802 } else { // 如果部分售后,则更新退款金额
816 tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()) 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 // TODO 芋艿:这块扣减规则,需要在考虑下 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 @Override 848 @Override
837 @Transactional(rollbackFor = Exception.class) 849 @Transactional(rollbackFor = Exception.class)
838 @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_COMMENT) 850 @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_COMMENT)