package cn.iocoder.yudao.module.trade.service.aftersale; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundRespDTO; import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleDisagreeReqVO; import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO; import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.AfterSaleRefuseReqVO; import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSaleDeliveryReqVO; import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppAfterSalePageReqVO; import cn.iocoder.yudao.module.trade.convert.aftersale.AfterSaleConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; 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.dal.mysql.aftersale.AfterSaleMapper; import cn.iocoder.yudao.module.trade.dal.redis.no.TradeNoRedisDAO; import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleOperateTypeEnum; import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleStatusEnum; import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleTypeEnum; import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleWayEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; import cn.iocoder.yudao.module.trade.framework.aftersale.core.annotations.AfterSaleLog; import cn.iocoder.yudao.module.trade.framework.aftersale.core.utils.AfterSaleLogUtils; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; /** * 售后订单 Service 实现类 * * @author 芋道源码 */ @Slf4j @Service @Validated public class AfterSaleServiceImpl implements AfterSaleService { @Resource @Lazy // 延迟加载,避免循环依赖 private TradeOrderUpdateService tradeOrderUpdateService; @Resource private TradeOrderQueryService tradeOrderQueryService; @Resource private DeliveryExpressService deliveryExpressService; @Resource private AfterSaleMapper tradeAfterSaleMapper; @Resource private TradeNoRedisDAO tradeNoRedisDAO; @Resource private PayRefundApi payRefundApi; @Resource private CombinationRecordApi combinationRecordApi; @Resource private TradeOrderProperties tradeOrderProperties; @Override public PageResult getAfterSalePage(AfterSalePageReqVO pageReqVO) { return tradeAfterSaleMapper.selectPage(pageReqVO); } @Override public PageResult getAfterSalePage(Long userId, AppAfterSalePageReqVO pageReqVO) { return tradeAfterSaleMapper.selectPage(userId, pageReqVO); } @Override public AfterSaleDO getAfterSale(Long userId, Long id) { return tradeAfterSaleMapper.selectByIdAndUserId(id, userId); } @Override public AfterSaleDO getAfterSale(Long id) { return tradeAfterSaleMapper.selectById(id); } @Override @Transactional(rollbackFor = Exception.class) @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.MEMBER_CREATE) public Long createAfterSale(Long userId, AppAfterSaleCreateReqVO createReqVO) { // 第一步,前置校验 TradeOrderItemDO tradeOrderItem = validateOrderItemApplicable(userId, createReqVO); // 第二步,存储售后订单 AfterSaleDO afterSale = createAfterSale(createReqVO, tradeOrderItem); return afterSale.getId(); } /** * 校验交易订单项是否可以申请售后 * * @param userId 用户编号 * @param createReqVO 售后创建信息 * @return 交易订单项 */ private TradeOrderItemDO validateOrderItemApplicable(Long userId, AppAfterSaleCreateReqVO createReqVO) { // 校验订单项存在 TradeOrderItemDO orderItem = tradeOrderQueryService.getOrderItem(userId, createReqVO.getOrderItemId()); if (orderItem == null) { throw exception(ORDER_ITEM_NOT_FOUND); } // 已申请售后,不允许再发起售后申请 if (!TradeOrderItemAfterSaleStatusEnum.isNone(orderItem.getAfterSaleStatus())) { throw exception(AFTER_SALE_CREATE_FAIL_ORDER_ITEM_APPLIED); } // 申请的退款金额,不能超过商品的价格 if (createReqVO.getRefundPrice() > orderItem.getPayPrice()) { throw exception(AFTER_SALE_CREATE_FAIL_REFUND_PRICE_ERROR); } // 校验订单存在 TradeOrderDO order = tradeOrderQueryService.getOrder(userId, orderItem.getOrderId()); if (order == null) { throw exception(ORDER_NOT_FOUND); } // TODO 芋艿:超过一定时间,不允许售后 // 已取消,无法发起售后 if (TradeOrderStatusEnum.isCanceled(order.getStatus())) { throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_CANCELED); } // 未支付,无法发起售后 if (!TradeOrderStatusEnum.havePaid(order.getStatus())) { throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_PAID); } // 如果是【退货退款】的情况,需要额外校验是否发货 if (createReqVO.getWay().equals(AfterSaleWayEnum.RETURN_AND_REFUND.getWay()) && !TradeOrderStatusEnum.haveDelivered(order.getStatus())) { throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED); } // 如果是拼团订单,则进行中不允许售后 if (TradeOrderTypeEnum.isCombination(order.getType())) { CombinationRecordRespDTO combinationRecord = combinationRecordApi.getCombinationRecordByOrderId( order.getUserId(), order.getId()); if (combinationRecord != null && CombinationRecordStatusEnum.isInProgress(combinationRecord.getStatus())) { throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_COMBINATION_IN_PROGRESS); } } return orderItem; } private AfterSaleDO createAfterSale(AppAfterSaleCreateReqVO createReqVO, TradeOrderItemDO orderItem) { // 创建售后单 AfterSaleDO afterSale = AfterSaleConvert.INSTANCE.convert(createReqVO, orderItem); afterSale.setNo(tradeNoRedisDAO.generate(TradeNoRedisDAO.AFTER_SALE_NO_PREFIX)); afterSale.setStatus(AfterSaleStatusEnum.APPLY.getStatus()); // 标记是售中还是售后 TradeOrderDO order = tradeOrderQueryService.getOrder(orderItem.getUserId(), orderItem.getOrderId()); afterSale.setOrderNo(order.getNo()); // 记录 orderNo 订单流水,方便后续检索 afterSale.setType(TradeOrderStatusEnum.isCompleted(order.getStatus()) ? AfterSaleTypeEnum.AFTER_SALE.getType() : AfterSaleTypeEnum.IN_SALE.getType()); tradeAfterSaleMapper.insert(afterSale); // 更新交易订单项的售后状态 tradeOrderUpdateService.updateOrderItemWhenAfterSaleCreate(orderItem.getId(), afterSale.getId()); // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), null, AfterSaleStatusEnum.APPLY.getStatus()); return afterSale; } @Override @Transactional(rollbackFor = Exception.class) @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_AGREE_APPLY) public void agreeAfterSale(Long userId, Long id) { // 校验售后单存在,并状态未审批 AfterSaleDO afterSale = validateAfterSaleAuditable(id); // 更新售后单的状态 // 情况一:退款:标记为 WAIT_REFUND 状态。后续等退款发起成功后,在标记为 COMPLETE 状态 // 情况二:退货退款:需要等用户退货后,才能发起退款 Integer newStatus = afterSale.getWay().equals(AfterSaleWayEnum.REFUND.getWay()) ? AfterSaleStatusEnum.WAIT_REFUND.getStatus() : AfterSaleStatusEnum.SELLER_AGREE.getStatus(); updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.APPLY.getStatus(), new AfterSaleDO() .setStatus(newStatus).setAuditUserId(userId).setAuditTime(LocalDateTime.now())); // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), newStatus); } @Override @Transactional(rollbackFor = Exception.class) @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_DISAGREE_APPLY) public void disagreeAfterSale(Long userId, AfterSaleDisagreeReqVO auditReqVO) { // 校验售后单存在,并状态未审批 AfterSaleDO afterSale = validateAfterSaleAuditable(auditReqVO.getId()); // 更新售后单的状态 Integer newStatus = AfterSaleStatusEnum.SELLER_DISAGREE.getStatus(); updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.APPLY.getStatus(), new AfterSaleDO() .setStatus(newStatus).setAuditUserId(userId).setAuditTime(LocalDateTime.now()) .setAuditReason(auditReqVO.getAuditReason())); // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), newStatus); // 更新交易订单项的售后状态为【未申请】 tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId()); } /** * 校验售后单是否可审批(同意售后、拒绝售后) * * @param id 售后编号 * @return 售后单 */ private AfterSaleDO validateAfterSaleAuditable(Long id) { AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); if (afterSale == null) { throw exception(AFTER_SALE_NOT_FOUND); } if (ObjectUtil.notEqual(afterSale.getStatus(), AfterSaleStatusEnum.APPLY.getStatus())) { throw exception(AFTER_SALE_AUDIT_FAIL_STATUS_NOT_APPLY); } return afterSale; } private void updateAfterSaleStatus(Long id, Integer status, AfterSaleDO updateObj) { int updateCount = tradeAfterSaleMapper.updateByIdAndStatus(id, status, updateObj); if (updateCount == 0) { throw exception(AFTER_SALE_UPDATE_STATUS_FAIL); } } @Override @Transactional(rollbackFor = Exception.class) @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.MEMBER_DELIVERY) public void deliveryAfterSale(Long userId, AppAfterSaleDeliveryReqVO deliveryReqVO) { // 校验售后单存在,并状态未退货 AfterSaleDO afterSale = tradeAfterSaleMapper.selectByIdAndUserId(deliveryReqVO.getId(), userId); if (afterSale == null) { throw exception(AFTER_SALE_NOT_FOUND); } if (ObjectUtil.notEqual(afterSale.getStatus(), AfterSaleStatusEnum.SELLER_AGREE.getStatus())) { throw exception(AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_AGREE); } DeliveryExpressDO express = deliveryExpressService.validateDeliveryExpress(deliveryReqVO.getLogisticsId()); // 更新售后单的物流信息 updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.SELLER_AGREE.getStatus(), new AfterSaleDO() .setStatus(AfterSaleStatusEnum.BUYER_DELIVERY.getStatus()) .setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo()) .setDeliveryTime(LocalDateTime.now())); // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), AfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), MapUtil.builder().put("deliveryName", express.getName()) .put("logisticsNo", deliveryReqVO.getLogisticsNo()).build()); } @Override @Transactional(rollbackFor = Exception.class) @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_AGREE_RECEIVE) public void receiveAfterSale(Long userId, Long id) { // 校验售后单存在,并状态为已退货 AfterSaleDO afterSale = validateAfterSaleReceivable(id); // 更新售后单的状态 updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), new AfterSaleDO() .setStatus(AfterSaleStatusEnum.WAIT_REFUND.getStatus()).setReceiveTime(LocalDateTime.now())); // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), AfterSaleStatusEnum.WAIT_REFUND.getStatus()); } @Override @Transactional(rollbackFor = Exception.class) @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_DISAGREE_RECEIVE) public void refuseAfterSale(Long userId, AfterSaleRefuseReqVO refuseReqVO) { // 校验售后单存在,并状态为已退货 AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(refuseReqVO.getId()); if (afterSale == null) { throw exception(AFTER_SALE_NOT_FOUND); } if (ObjectUtil.notEqual(afterSale.getStatus(), AfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) { throw exception(AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY); } // 更新售后单的状态 updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), new AfterSaleDO() .setStatus(AfterSaleStatusEnum.SELLER_REFUSE.getStatus()).setReceiveTime(LocalDateTime.now()) .setReceiveReason(refuseReqVO.getRefuseMemo())); // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), AfterSaleStatusEnum.SELLER_REFUSE.getStatus(), MapUtil.of("reason", refuseReqVO.getRefuseMemo())); // 更新交易订单项的售后状态为【未申请】 tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId()); } /** * 校验售后单是否可收货,即处于买家已发货 * * @param id 售后编号 * @return 售后单 */ private AfterSaleDO validateAfterSaleReceivable(Long id) { AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); if (afterSale == null) { throw exception(AFTER_SALE_NOT_FOUND); } if (ObjectUtil.notEqual(afterSale.getStatus(), AfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) { throw exception(AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY); } return afterSale; } @Override @Transactional(rollbackFor = Exception.class) @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_REFUND) public void refundAfterSale(Long userId, String userIp, Long id) { // 校验售后单的状态,并状态待退款 AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); if (afterSale == null) { throw exception(AFTER_SALE_NOT_FOUND); } if (ObjectUtil.notEqual(afterSale.getStatus(), AfterSaleStatusEnum.WAIT_REFUND.getStatus())) { throw exception(AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND); } Integer newStatus; if (ObjUtil.equals(afterSale.getRefundPrice(), 0)) { // 特殊:退款为 0 的订单,直接标记为完成(积分商城)。关联案例:https://t.zsxq.com/AQEvL updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.WAIT_REFUND.getStatus(), new AfterSaleDO() .setStatus(AfterSaleStatusEnum.COMPLETE.getStatus()).setRefundTime(LocalDateTime.now())); newStatus = AfterSaleStatusEnum.COMPLETE.getStatus(); } else { // 发起退款单。注意,需要在事务提交后,再进行发起,避免重复发起 createPayRefund(userIp, afterSale); newStatus = afterSale.getStatus(); // 特殊:这里状态不变,而是最终 updateAfterSaleRefunded 处理!!! } // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), newStatus); } private void createPayRefund(String userIp, AfterSaleDO afterSale) { // 创建退款单 PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties) .setUserId(afterSale.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) .setReason(StrUtil.format("退款【{}】", afterSale.getSpuName())); Long payRefundId = payRefundApi.createRefund(createReqDTO); // 更新售后单的退款单号 tradeAfterSaleMapper.updateById(new AfterSaleDO().setId(afterSale.getId()).setPayRefundId(payRefundId)); } @Override @Transactional(rollbackFor = Exception.class) @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.SYSTEM_REFUND_SUCCESS) public void updateAfterSaleRefunded(Long id, Long orderId, Long payRefundId) { // 1. 校验售后单的状态,并状态待退款 AfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); if (afterSale == null) { throw exception(AFTER_SALE_NOT_FOUND); } if (ObjectUtil.notEqual(afterSale.getStatus(), AfterSaleStatusEnum.WAIT_REFUND.getStatus())) { throw exception(AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND); } // 2. 校验退款单 PayRefundRespDTO payRefund = validatePayRefund(afterSale, payRefundId); // 3. 处理退款结果 if (PayRefundStatusEnum.isSuccess(payRefund.getStatus())) { // 【情况一:退款成功】 updateAfterSaleStatus(afterSale.getId(), AfterSaleStatusEnum.WAIT_REFUND.getStatus(), new AfterSaleDO() .setStatus(AfterSaleStatusEnum.COMPLETE.getStatus()).setRefundTime(LocalDateTime.now())); // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), AfterSaleStatusEnum.COMPLETE.getStatus()); // 更新交易订单项的售后状态为【已完成】 tradeOrderUpdateService.updateOrderItemWhenAfterSaleSuccess(afterSale.getOrderItemId(), afterSale.getRefundPrice()); // 【情况二:退款失败】 } else if (PayRefundStatusEnum.isFailure(payRefund.getStatus())) { // 记录售后日志 AfterSaleLogUtils.setAfterSaleOperateType(AfterSaleOperateTypeEnum.SYSTEM_REFUND_FAIL); AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), afterSale.getStatus()); } } /** * 校验退款单的合法性 * * @param afterSale 售后单 * @param payRefundId 退款单编号 * @return 退款单 */ private PayRefundRespDTO validatePayRefund(AfterSaleDO afterSale, Long payRefundId) { // 1. 校验退款单是否存在 PayRefundRespDTO payRefund = payRefundApi.getRefund(payRefundId); if (payRefund == null) { log.error("[validatePayRefund][afterSale({}) payRefund({}) 不存在,请进行处理!]", afterSale.getId(), payRefundId); throw exception(AFTER_SALE_REFUND_FAIL_REFUND_NOT_FOUND); } // 2.1 校验退款单无退款结果(成功、失败) if (!PayRefundStatusEnum.isSuccess(payRefund.getStatus()) && !PayRefundStatusEnum.isFailure(payRefund.getStatus())) { log.error("[validatePayRefund][afterSale({}) payRefund({}) 无退款结果,请进行处理!payRefund 数据是:{}]", afterSale.getId(), payRefundId, toJsonString(payRefund)); throw exception(AFTER_SALE_REFUND_FAIL_REFUND_NOT_SUCCESS_OR_FAILURE); } // 2.2 校验退款金额一致 if (ObjectUtil.notEqual(payRefund.getRefundPrice(), afterSale.getRefundPrice())) { log.error("[validatePayRefund][afterSale({}) payRefund({}) 退款金额不匹配,请进行处理!afterSale 数据是:{},payRefund 数据是:{}]", afterSale.getId(), payRefundId, toJsonString(afterSale), toJsonString(payRefund)); throw exception(AFTER_SALE_REFUND_FAIL_REFUND_PRICE_NOT_MATCH); } // 2.3 校验退款订单匹配(二次) if (ObjectUtil.notEqual(payRefund.getMerchantRefundId(), afterSale.getId().toString())) { log.error("[validatePayRefund][afterSale({}) 退款单不匹配({}),请进行处理!payRefund 数据是:{}]", afterSale.getId(), payRefundId, toJsonString(payRefund)); throw exception(AFTER_SALE_REFUND_FAIL_REFUND_ORDER_ID_ERROR); } return payRefund; } @Override @Transactional(rollbackFor = Exception.class) @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.MEMBER_CANCEL) public void cancelAfterSale(Long userId, Long id) { // 校验售后单的状态,并状态待退款 AfterSaleDO afterSale = tradeAfterSaleMapper.selectByIdAndUserId(id, userId); if (afterSale == null) { throw exception(AFTER_SALE_NOT_FOUND); } if (!ObjectUtils.equalsAny(afterSale.getStatus(), AfterSaleStatusEnum.APPLY.getStatus(), AfterSaleStatusEnum.SELLER_AGREE.getStatus(), AfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) { throw exception(AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE_OR_BUYER_DELIVERY); } // 更新售后单的状态为【已取消】 updateAfterSaleStatus(afterSale.getId(), afterSale.getStatus(), new AfterSaleDO() .setStatus(AfterSaleStatusEnum.BUYER_CANCEL.getStatus())); // 记录售后日志 AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), AfterSaleStatusEnum.BUYER_CANCEL.getStatus()); // 更新交易订单项的售后状态为【未申请】 tradeOrderUpdateService.updateOrderItemWhenAfterSaleCancel(afterSale.getOrderItemId()); } @Override public Long getApplyingAfterSaleCount(Long userId) { return tradeAfterSaleMapper.selectCountByUserIdAndStatus(userId, AfterSaleStatusEnum.APPLYING_STATUSES); } }