mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	售后:重构售后更新订单的逻辑
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
| @@ -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 oldAfterSaleStatus 当前售后状态;如果不符,更新后会抛出异常 | ||||
|      * @param newAfterSaleStatus 目标售后状态 | ||||
|      * @param id          交易订单项编号 | ||||
|      * @param afterSaleId 售后单编号 | ||||
|      */ | ||||
|     default void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus) { | ||||
|         updateOrderItemAfterSaleStatus(id, oldAfterSaleStatus, newAfterSaleStatus, null, null); | ||||
|     } | ||||
|     void updateOrderItemWhenAfterSaleCreate(@NotNull Long id, @NotNull Long afterSaleId); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 更新交易订单项的售后状态 | ||||
|      * 当售后完成后,更新交易订单项的售后状态 | ||||
|      * | ||||
|      * @param id                 交易订单项编号 | ||||
|      * @param oldAfterSaleStatus 当前售后状态;如果不符,更新后会抛出异常 | ||||
|      * @param newAfterSaleStatus 目标售后状态 | ||||
|      * @param afterSaleId        售后单编号;当订单项发起售后时,必须传递该字段 | ||||
|      * @param refundPrice        退款金额;当订单项退款成功时,必须传递该值 | ||||
|      * @param id          交易订单项编号 | ||||
|      * @param refundPrice 退款金额 | ||||
|      */ | ||||
|     void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus, | ||||
|                                         Long afterSaleId, Integer refundPrice); | ||||
|     void updateOrderItemWhenAfterSaleSuccess(@NotNull Long id, @NotNull Integer refundPrice); | ||||
|  | ||||
|     /** | ||||
|      * 当售后取消(用户取消、管理员驳回、管理员拒绝收货)后,更新交易订单项的售后状态 | ||||
|      * | ||||
|      * @param id 交易订单项编号 | ||||
|      */ | ||||
|     void updateOrderItemWhenAfterSaleCancel(@NotNull Long id); | ||||
|  | ||||
|     /** | ||||
|      * 创建订单项的评论 | ||||
|   | ||||
| @@ -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,67 +770,79 @@ 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)); | ||||
|         } | ||||
|  | ||||
|         // 更新订单项 | ||||
|         updateOrderItemAfterSaleStatus(id, TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), | ||||
|                 TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), afterSaleId); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void updateOrderItemWhenAfterSaleSuccess(Long id, Integer refundPrice) { | ||||
|         if (refundPrice == null) { | ||||
|             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; | ||||
|         Integer orderRefundPoint = order.getRefundPoint() + orderItem.getUsePoint(); | ||||
|         if (isAllOrderItemAfterSaleSuccess(order.getId())) { // 如果都售后成功,则需要取消订单 | ||||
|             cancelOrderByAfterSale(order, orderRefundPrice, orderRefundPoint); | ||||
|         } else { // 如果部分售后,则更新退款金额 | ||||
|             tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()) | ||||
|                     .setRefundStatus(TradeOrderRefundStatusEnum.PART.getStatus()) | ||||
|                     .setRefundPrice(orderRefundPrice).setRefundPoint(orderRefundPoint)); | ||||
|         } | ||||
|  | ||||
|         // TODO 芋艿:这块扣减规则,需要在考虑下 | ||||
|         // 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); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|         // 如果有退款金额,则需要更新订单 | ||||
|         if (refundPrice == null) { | ||||
|             return; | ||||
|         } | ||||
|         // 计算总的退款金额 | ||||
|         TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(id); | ||||
|         TradeOrderDO order = tradeOrderMapper.selectById(orderItem.getOrderId()); | ||||
|         Integer orderRefundPrice = order.getRefundPrice() + refundPrice; | ||||
|         // TODO @疯狂:809 到 817 改成:cancelOrderByAfterSale:相当于全部售后成功后,就是要取消胆子; | ||||
|         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 芋艿:要不要退优惠劵 | ||||
|  | ||||
|         } else { // 如果部分售后,则更新退款金额 | ||||
|             tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()) | ||||
|                     .setRefundStatus(TradeOrderRefundStatusEnum.PART.getStatus()).setRefundPrice(orderRefundPrice)); | ||||
|         } | ||||
|  | ||||
|         // 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); | ||||
|         } | ||||
|     @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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 owen
					owen