diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleOperateTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleOperateTypeEnum.java index da41c2b93..db870c637 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleOperateTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/AfterSaleOperateTypeEnum.java @@ -1,28 +1,35 @@ package cn.iocoder.yudao.module.trade.enums.aftersale; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + /** * 售后操作类型的枚举 * * @author 陈賝 * @since 2023/6/13 13:53 */ -// TODO @chenchen:可以 lombok 简化构造方法,和 get 方法 +@RequiredArgsConstructor +@Getter public enum AfterSaleOperateTypeEnum { - /** - * 用户申请 - */ - APPLY("用户申请"), + MEMBER_CREATE(10, "会员申请退款"), + ADMIN_AGREE_APPLY(11, "商家同意退款"), + ADMIN_DISAGREE_APPLY(12, "商家拒绝退款"), + MEMBER_DELIVERY(20, "会员填写退货物流信息,快递公司:{deliveryName},快递单号:{logisticsNo}"), + ADMIN_AGREE_RECEIVE(21, "商家收货"), + ADMIN_DISAGREE_RECEIVE(22, "商家拒绝收货,原因:{reason}"), + ADMIN_REFUND(30, "商家退款"), + MEMBER_CANCEL(40, "会员取消退款"), ; - private final String description; - - AfterSaleOperateTypeEnum(String description) { - this.description = description; - } - - public String description() { - return description; - } + /** + * 操作类型 + */ + private final Integer type; + /** + * 操作描述 + */ + private final String content; } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderOperateTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderOperateTypeEnum.java index bd66aa726..616bd2d79 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderOperateTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderOperateTypeEnum.java @@ -29,11 +29,11 @@ public enum TradeOrderOperateTypeEnum { ; /** - * 类型 + * 操作类型 */ private final Integer type; /** - * 类型 + * 操作描述 */ private final String content; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java index ef3e75c7d..62e18f5a6 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java @@ -71,7 +71,7 @@ public class AppTradeAfterSaleController { @PostMapping(value = "/create") @Operation(summary = "申请售后") - @AfterSaleLog(id = "#info.data", content = "'申请售后:售后编号['+#info.data+'],订单编号['+#createReqVO.orderItemId+'], '", operateType = AfterSaleOperateTypeEnum.APPLY) + @AfterSaleLog(id = "#info.data", content = "'申请售后:售后编号['+#info.data+'],订单编号['+#createReqVO.orderItemId+'], '", operateType = AfterSaleOperateTypeEnum.MEMBER_CREATE) public CommonResult createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) { AfterSaleLogUtils.setBeforeStatus(0); AfterSaleLogUtils.setAfterStatus(TradeAfterSaleStatusEnum.APPLY.getStatus()); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/annotations/AfterSaleLog.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/annotations/AfterSaleLog.java index ebfdd7522..59c116909 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/annotations/AfterSaleLog.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/annotations/AfterSaleLog.java @@ -21,7 +21,8 @@ public @interface AfterSaleLog { /** * 售后 ID */ - String id(); + @Deprecated + String id() default ""; /** * 操作类型 @@ -31,6 +32,7 @@ public @interface AfterSaleLog { /** * 日志内容 */ + @Deprecated String content() default ""; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/aop/AfterSaleLogAspect.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/aop/AfterSaleLogAspect.java index f554d9a15..f341d2d35 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/aop/AfterSaleLogAspect.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/aop/AfterSaleLogAspect.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.aop; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.util.spring.SpringExpressionUtils; -import cn.iocoder.yudao.framework.operatelog.core.service.OperateLog; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.annotations.AfterSaleLog; import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogCreateReqDTO; @@ -96,7 +95,7 @@ public class AfterSaleLogAspect { String id = MapUtil.getStr(spelMap, afterSaleLogPoint.id()); result.put(ID, id); // 操作类型 - String operateType = afterSaleLogPoint.operateType().description(); + String operateType = afterSaleLogPoint.operateType().getContent(); result.put(OPERATE_TYPE, operateType); // 日志内容 String content = MapUtil.getStr(spelMap, afterSaleLogPoint.content()); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/util/AfterSaleLogUtils.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/util/AfterSaleLogUtils.java index 3f8327dc0..44f829daf 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/util/AfterSaleLogUtils.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/aftersalelog/core/util/AfterSaleLogUtils.java @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.util; import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.aop.AfterSaleLogAspect; +import java.util.Map; + /** * 操作日志工具类 * 目前主要的作用,是提供给业务代码,记录操作明细和拓展字段 @@ -19,4 +21,13 @@ public class AfterSaleLogUtils { AfterSaleLogAspect.setAfterStatus(status); } + public static void setAfterSaleInfo(Long id, Integer beforeStatus, Integer afterStatus) { + setAfterSaleInfo(id, beforeStatus, afterStatus, null); + } + + public static void setAfterSaleInfo(Long id, Integer beforeStatus, Integer afterStatus, + Map exts) { + // TODO 待实现 + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java index a41b73ec3..ed1e87c94 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.trade.service.aftersale; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.RandomUtil; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; @@ -17,18 +17,23 @@ import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSa import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert; import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO; +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.TradeAfterSaleLogMapper; import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.TradeAfterSaleMapper; +import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleOperateTypeEnum; import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum; import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum; import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; +import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.annotations.AfterSaleLog; import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogCreateReqDTO; import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service.AfterSaleLogService; +import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.util.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 lombok.extern.slf4j.Slf4j; @@ -61,6 +66,8 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa private TradeOrderUpdateService tradeOrderUpdateService; @Resource private TradeOrderQueryService tradeOrderQueryService; + @Resource + private DeliveryExpressService deliveryExpressService; @Resource private TradeAfterSaleMapper tradeAfterSaleMapper; @@ -93,10 +100,9 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa return tradeAfterSaleMapper.selectById(id); } - // TODO 芋艿:拼团失败,要不要发起售后的方式退款?还是走取消逻辑? - @Override @Transactional(rollbackFor = Exception.class) + @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.MEMBER_CREATE) public Long createAfterSale(Long userId, AppTradeAfterSaleCreateReqVO createReqVO) { // 第一步,前置校验 TradeOrderItemDO tradeOrderItem = validateOrderItemApplicable(userId, createReqVO); @@ -163,15 +169,14 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa afterSale.setOrderNo(order.getNo()); // 记录 orderNo 订单流水,方便后续检索 afterSale.setType(TradeOrderStatusEnum.isCompleted(order.getStatus()) ? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType()); - // TODO 退还积分 tradeAfterSaleMapper.insert(afterSale); // 更新交易订单项的售后状态 tradeOrderUpdateService.updateOrderItemWhenAfterSaleCreate(orderItem.getId(), afterSale.getId()); // 记录售后日志 - createAfterSaleLog(orderItem.getUserId(), UserTypeEnum.MEMBER.getValue(), - afterSale, null, afterSale.getStatus()); + AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), null, + TradeAfterSaleStatusEnum.APPLY.getStatus()); // TODO 发送售后消息 return afterSale; @@ -179,6 +184,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa @Override @Transactional(rollbackFor = Exception.class) + @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_AGREE_APPLY) public void agreeAfterSale(Long userId, Long id) { // 校验售后单存在,并状态未审批 TradeAfterSaleDO afterSale = validateAfterSaleAuditable(id); @@ -192,14 +198,14 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa .setStatus(newStatus).setAuditUserId(userId).setAuditTime(LocalDateTime.now())); // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), - afterSale, afterSale.getStatus(), newStatus); + AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), newStatus); // TODO 发送售后消息 } @Override @Transactional(rollbackFor = Exception.class) + @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_DISAGREE_APPLY) public void disagreeAfterSale(Long userId, TradeAfterSaleDisagreeReqVO auditReqVO) { // 校验售后单存在,并状态未审批 TradeAfterSaleDO afterSale = validateAfterSaleAuditable(auditReqVO.getId()); @@ -211,8 +217,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa .setAuditReason(auditReqVO.getAuditReason())); // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), - afterSale, afterSale.getStatus(), newStatus); + AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), newStatus); // TODO 发送售后消息 @@ -246,6 +251,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa @Override @Transactional(rollbackFor = Exception.class) + @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.MEMBER_DELIVERY) public void deliveryAfterSale(Long userId, AppTradeAfterSaleDeliveryReqVO deliveryReqVO) { // 校验售后单存在,并状态未退货 TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(deliveryReqVO.getId()); @@ -255,6 +261,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus())) { throw exception(AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_AGREE); } + DeliveryExpressDO express = deliveryExpressService.validateDeliveryExpress(deliveryReqVO.getLogisticsId()); // 更新售后单的物流信息 updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus(), new TradeAfterSaleDO() @@ -263,14 +270,17 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa .setDeliveryTime(LocalDateTime.now())); // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.MEMBER.getValue(), - afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus()); + AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), + TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), + MapUtil.builder().put("expressName", express.getName()) + .put("logisticsNo", deliveryReqVO.getLogisticsNo()).build()); // TODO 发送售后消息 } @Override @Transactional(rollbackFor = Exception.class) + @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_AGREE_RECEIVE) public void receiveAfterSale(Long userId, Long id) { // 校验售后单存在,并状态为已退货 TradeAfterSaleDO afterSale = validateAfterSaleReceivable(id); @@ -280,14 +290,15 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa .setStatus(TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus()).setReceiveTime(LocalDateTime.now())); // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), - afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus()); + AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), + TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus()); // TODO 发送售后消息 } @Override @Transactional(rollbackFor = Exception.class) + @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_DISAGREE_RECEIVE) public void refuseAfterSale(Long userId, TradeAfterSaleRefuseReqVO refuseReqVO) { // 校验售后单存在,并状态为已退货 TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(refuseReqVO.getId()); @@ -304,8 +315,9 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa .setReceiveReason(refuseReqVO.getRefuseMemo())); // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), - afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus()); + AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), + TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus(), + MapUtil.of("reason", refuseReqVO.getRefuseMemo())); // TODO 发送售后消息 @@ -332,6 +344,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa @Override @Transactional(rollbackFor = Exception.class) + @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.ADMIN_REFUND) public void refundAfterSale(Long userId, String userIp, Long id) { // 校验售后单的状态,并状态待退款 TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); @@ -350,8 +363,8 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa .setStatus(TradeAfterSaleStatusEnum.COMPLETE.getStatus()).setRefundTime(LocalDateTime.now())); // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), - afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.COMPLETE.getStatus()); + AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), + TradeAfterSaleStatusEnum.COMPLETE.getStatus()); // TODO 发送售后消息 @@ -374,6 +387,8 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa } @Override + @Transactional(rollbackFor = Exception.class) + @AfterSaleLog(operateType = AfterSaleOperateTypeEnum.MEMBER_CANCEL) public void cancelAfterSale(Long userId, Long id) { // 校验售后单的状态,并状态待退款 TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); @@ -391,8 +406,8 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa .setStatus(TradeAfterSaleStatusEnum.BUYER_CANCEL.getStatus())); // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.MEMBER.getValue(), - afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_CANCEL.getStatus()); + AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), afterSale.getStatus(), + TradeAfterSaleStatusEnum.BUYER_CANCEL.getStatus()); // TODO 发送售后消息