浏览代码

trade:补全售后日志的记录

YunaiV 1 年之前
父节点
当前提交
3c643f814c

+ 21 - 14
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;
 
 }

+ 2 - 2
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;
 

+ 1 - 1
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<Long> createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) {
         AfterSaleLogUtils.setBeforeStatus(0);
         AfterSaleLogUtils.setAfterStatus(TradeAfterSaleStatusEnum.APPLY.getStatus());

+ 3 - 1
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 "";
 
 }

+ 1 - 2
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());

+ 11 - 0
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<String, Object> exts) {
+        // TODO 待实现
+    }
+
 }

+ 35 - 20
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.<String, Object>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 发送售后消息