ソースを参照

!514 mall交易日志封装
* 交易日志封装
* 交易日志封装
* 交易日志模块

陈賝 1 年間 前
コミット
59e16795be
20 ファイル変更470 行追加51 行削除
  1. 1 0
      yudao-framework/pom.xml
  2. 81 0
      yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spel/SpelUtil.java
  3. 1 1
      yudao-framework/yudao-spring-boot-starter-biz-operatelog/pom.xml
  4. 54 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/pom.xml
  5. 17 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/config/YudaoAfterSaleLogAutoConfiguration.java
  6. 34 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/annotations/AfterSaleLog.java
  7. 87 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/aop/AfterSaleLogAspect.java
  8. 42 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/dto/TradeAfterSaleLogDTO.java
  9. 27 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/enums/AfterSaleStatusEnum.java
  10. 1 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/package-info.java
  11. 16 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/service/AfterSaleLogService.java
  12. 1 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/package-info.java
  13. 1 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  14. 32 17
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java
  15. 5 0
      yudao-module-mall/yudao-module-trade-biz/pom.xml
  16. 18 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java
  17. 8 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java
  18. 2 22
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java
  19. 39 9
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java
  20. 3 2
      yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java

+ 1 - 0
yudao-framework/pom.xml

@@ -31,6 +31,7 @@
         <module>yudao-spring-boot-starter-biz-sms</module>
 
         <module>yudao-spring-boot-starter-biz-pay</module>
+        <module>yudao-spring-boot-starter-biz-trade</module>
         <module>yudao-spring-boot-starter-biz-weixin</module>
         <module>yudao-spring-boot-starter-biz-social</module>
         <module>yudao-spring-boot-starter-biz-tenant</module>

+ 81 - 0
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spel/SpelUtil.java

@@ -0,0 +1,81 @@
+package cn.iocoder.yudao.framework.common.util.spel;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.core.DefaultParameterNameDiscoverer;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+
+/**
+ * SpelUtil
+ *
+ * @author Chopper
+ * @version v1.0
+ * 2021-01-11 10:45
+ */
+public class SpelUtil {
+
+
+    /**
+     * spel表达式解析器
+     */
+    private static SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
+    /**
+     * 参数名发现器
+     */
+    private static DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
+
+    /**
+     * 转换 jspl参数
+     *
+     * @param joinPoint
+     * @param spel
+     * @return
+     */
+    public static String compileParams(JoinPoint joinPoint, String spel) { //Spel表达式解析日志信息
+        //获得方法参数名数组
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+
+        String[] parameterNames = parameterNameDiscoverer.getParameterNames(signature.getMethod());
+        if (parameterNames != null && parameterNames.length > 0) {
+            EvaluationContext context = new StandardEvaluationContext();
+
+            //获取方法参数值
+            Object[] args = joinPoint.getArgs();
+            for (int i = 0; i < args.length; i++) {
+                //替换spel里的变量值为实际值, 比如 #user -->  user对象
+                context.setVariable(parameterNames[i], args[i]);
+            }
+            return spelExpressionParser.parseExpression(spel).getValue(context).toString();
+        }
+        return "";
+    }
+
+    /**
+     * 转换 jspl参数
+     *
+     * @param joinPoint
+     * @param spel
+     * @return
+     */
+    public static String compileParams(JoinPoint joinPoint, Object rvt, String spel) { //Spel表达式解析日志信息
+        //获得方法参数名数组
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+
+        String[] parameterNames = parameterNameDiscoverer.getParameterNames(signature.getMethod());
+        if (parameterNames != null && parameterNames.length > 0) {
+            EvaluationContext context = new StandardEvaluationContext();
+
+            //获取方法参数值
+            Object[] args = joinPoint.getArgs();
+            for (int i = 0; i < args.length; i++) {
+                //替换spel里的变量值为实际值, 比如 #user -->  user对象
+                context.setVariable(parameterNames[i], args[i]);
+            }
+            context.setVariable("rvt", rvt);
+            return spelExpressionParser.parseExpression(spel).getValue(context).toString();
+        }
+        return "";
+    }
+}

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-operatelog/pom.xml

@@ -37,7 +37,7 @@
         <!-- 业务组件 -->
         <dependency>
             <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行操作日志的记录 -->
+            <artifactId>yudao-module-system-api</artifactId>
             <version>${revision}</version>
         </dependency>
 

+ 54 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/pom.xml

@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>cn.iocoder.boot</groupId>
+        <artifactId>yudao-framework</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>yudao-spring-boot-starter-biz-trade</artifactId>
+    <packaging>jar</packaging>
+
+    <name>${project.artifactId}</name>
+    <description>交易模块</description>
+    <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
+
+    <dependencies>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-common</artifactId>
+        </dependency>
+
+        <!-- Spring 核心 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+
+        <!-- Web 相关 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-web</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- 业务组件 -->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行操作日志的记录 -->
+            <version>${revision}</version>
+        </dependency>
+
+        <!-- 工具类相关 -->
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-security</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 17 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/config/YudaoAfterSaleLogAutoConfiguration.java

@@ -0,0 +1,17 @@
+package cn.iocoder.yudao.framework.trade.config;
+
+import cn.iocoder.yudao.framework.trade.core.annotations.AfterSaleLog;
+import cn.iocoder.yudao.framework.trade.core.aop.AfterSaleLogAspect;
+import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.Bean;
+
+@AutoConfiguration
+public class YudaoAfterSaleLogAutoConfiguration {
+
+    @Bean
+    public AfterSaleLogAspect afterSaleLogAspect() {
+        return new AfterSaleLogAspect();
+    }
+
+}

+ 34 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/annotations/AfterSaleLog.java

@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.framework.trade.core.annotations;
+
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.stereotype.Component;
+
+import java.lang.annotation.*;
+
+/**
+ * 售后日志
+ *
+ * @author 陈賝
+ * @date 2023/6/8 17:04
+ */
+@Target({ElementType.METHOD,ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface AfterSaleLog {
+
+    /**
+     * 售后ID
+     */
+    String id();
+
+    /**
+     * 操作类型
+     */
+    String operateType() default "";
+
+    /**
+     * 日志内容
+     */
+    String content() default "";
+
+}

+ 87 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/aop/AfterSaleLogAspect.java

@@ -0,0 +1,87 @@
+package cn.iocoder.yudao.framework.trade.core.aop;
+
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import cn.iocoder.yudao.framework.common.util.spel.SpelUtil;
+import cn.iocoder.yudao.framework.trade.core.annotations.AfterSaleLog;
+import cn.iocoder.yudao.framework.trade.core.dto.TradeAfterSaleLogDTO;
+import cn.iocoder.yudao.framework.trade.core.enums.AfterSaleStatusEnum;
+import cn.iocoder.yudao.framework.trade.core.service.AfterSaleLogService;
+import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 售后日志
+ *
+ * @author 陈賝
+ * @date 2023/6/13 13:54
+ */
+@Slf4j
+@Aspect
+public class AfterSaleLogAspect {
+
+    @AfterReturning(pointcut = "@annotation(afterSaleLog)", returning = "info")
+    public void doAfterReturning(JoinPoint joinPoint, AfterSaleLog afterSaleLog, Object info) {
+        try {
+            //日志对象拼接
+            Integer userType = WebFrameworkUtils.getLoginUserType();
+            Long id = WebFrameworkUtils.getLoginUserId();
+            Map<String, String> formatObj = spelFormat(joinPoint, info);
+            TradeAfterSaleLogDTO dto = new TradeAfterSaleLogDTO()
+                    .setUserId(id)
+                    .setUserType(userType)
+                    .setAfterSaleId(Long.valueOf(formatObj.get("id")))
+                    .setContent(formatObj.get("content"))
+                    .setOperateType(formatObj.get("operateType"));
+            // 异步存入数据库
+            SpringUtil.getBean(AfterSaleLogService.class).insert(dto);
+            System.out.println(dto.toString());
+        } catch (Exception exception) {
+            log.error("日志记录错误", exception);
+        }
+    }
+
+    /**
+     * 获取描述信息
+     */
+    public static Map<String, String> spelFormat(JoinPoint joinPoint, Object info) {
+
+        Map<String, String> result = new HashMap<>(2);
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        AfterSaleLog afterSaleLogPoint = signature.getMethod().getAnnotation(AfterSaleLog.class);
+
+        /*
+         * 售后ID
+         */
+        String id = SpelUtil.compileParams(joinPoint, info, afterSaleLogPoint.id());
+        result.put("id", id);
+
+        /*
+         * 操作类型
+         */
+        String operateType = SpelUtil.compileParams(joinPoint, info, afterSaleLogPoint.operateType());
+        result.put("operateType", operateType);
+
+        /*
+         * 日志内容
+         */
+        String content = SpelUtil.compileParams(joinPoint, info, afterSaleLogPoint.content());
+        if (CharSequenceUtil.isNotEmpty(afterSaleLogPoint.operateType())) {
+            content += AfterSaleStatusEnum.valueOf(SpelUtil.compileParams(joinPoint, info, afterSaleLogPoint.operateType())).description();
+        }
+        result.put("content", content);
+        return result;
+
+    }
+
+
+}

+ 42 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/dto/TradeAfterSaleLogDTO.java

@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.framework.trade.core.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Accessors(chain = true)
+public class TradeAfterSaleLogDTO {
+
+    /**
+     * 编号
+     */
+    private Long id;
+    /**
+     * 用户编号
+     *
+     * 关联 1:AdminUserDO 的 id 字段
+     * 关联 2:MemberUserDO 的 id 字段
+     */
+    private Long userId;
+    /**
+     * 用户类型
+     */
+    private Integer userType;
+    /**
+     * 售后编号
+     */
+    private Long afterSaleId;
+    /**
+     * 操作类型
+     */
+    private String operateType;
+    /**
+     * 操作明细
+     */
+    private String content;
+
+}

+ 27 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/enums/AfterSaleStatusEnum.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.framework.trade.core.enums;
+
+/**
+ * 售后状态
+ *
+ * @author 陈賝
+ * @date 2023/6/13 13:53
+ */
+public enum AfterSaleStatusEnum {
+
+    /**
+     * 申请中
+     */
+    APPLY("申请中");
+
+    private final String description;
+
+    AfterSaleStatusEnum(String description) {
+        this.description = description;
+    }
+
+    public String description() {
+        return description;
+    }
+
+
+}

+ 1 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/package-info.java

@@ -0,0 +1 @@
+package cn.iocoder.yudao.framework.trade.core;

+ 16 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/service/AfterSaleLogService.java

@@ -0,0 +1,16 @@
+package cn.iocoder.yudao.framework.trade.core.service;
+
+import cn.iocoder.yudao.framework.trade.core.dto.TradeAfterSaleLogDTO;
+import org.springframework.scheduling.annotation.Async;
+
+public interface AfterSaleLogService {
+
+    /**
+     * 日志记录
+     *
+     * @param logDTO 日志记录
+     * @author 陈賝
+     * @date 2023/6/12 14:18
+     */
+    void insert(TradeAfterSaleLogDTO logDTO);
+}

+ 1 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/package-info.java

@@ -0,0 +1 @@
+package cn.iocoder.yudao.framework.trade;

+ 1 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+cn.iocoder.yudao.framework.trade.config.YudaoAfterSaleLogAutoConfiguration

+ 32 - 17
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java

@@ -19,23 +19,38 @@ import static cn.hutool.core.util.ArrayUtil.firstMatch;
 @Getter
 public enum TradeAfterSaleStatusEnum implements IntArrayValuable {
 
-    APPLY(10,"申请中", // 【申请售后】
-            "会员申请退款"),
-    SELLER_AGREE(20, "卖家通过", // 卖家通过售后;【商品待退货】
-            "商家同意退款"),
-    BUYER_DELIVERY(30,"待卖家收货", // 买家已退货,等待卖家收货;【商家待收货】
-            "会员填写退货物流信息"),
-    WAIT_REFUND(40, "等待平台退款", // 卖家已收货,等待平台退款;等待退款【等待退款】
-            "商家收货"),
-    COMPLETE(50, "完成", // 完成退款【退款成功】
-            "商家确认退款"),
-
-    BUYER_CANCEL(61, "买家取消售后", // 【买家取消】
-            "会员取消退款"),
-    SELLER_DISAGREE(62,"卖家拒绝", // 卖家拒绝售后;商家拒绝【商家拒绝】
-            "商家拒绝退款"),
-    SELLER_REFUSE(63,"卖家拒绝收货", // 卖家拒绝收货,终止售后;【商家拒收货】
-            "商家拒绝收货"),
+    /**
+     * 【申请售后】
+     */
+    APPLY(10,"申请中", "会员申请退款"),
+    /**
+     * 卖家通过售后;【商品待退货】
+     */
+    SELLER_AGREE(20, "卖家通过", "商家同意退款"),
+    /**
+     * 买家已退货,等待卖家收货;【商家待收货】
+     */
+    BUYER_DELIVERY(30,"待卖家收货", "会员填写退货物流信息"),
+    /**
+     * 卖家已收货,等待平台退款;等待退款【等待退款】
+     */
+    WAIT_REFUND(40, "等待平台退款", "商家收货"),
+    /**
+     * 完成退款【退款成功】
+     */
+    COMPLETE(50, "完成", "商家确认退款"),
+    /**
+     * 【买家取消】
+     */
+    BUYER_CANCEL(61, "买家取消售后", "会员取消退款"),
+    /**
+     * 卖家拒绝售后;商家拒绝【商家拒绝】
+     */
+    SELLER_DISAGREE(62,"卖家拒绝", "商家拒绝退款"),
+    /**
+     * 卖家拒绝收货,终止售后;【商家拒收货】
+     */
+    SELLER_REFUSE(63,"卖家拒绝收货", "商家拒绝收货"),
     ;
 
     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleStatusEnum::getStatus).toArray();

+ 5 - 0
yudao-module-mall/yudao-module-trade-biz/pom.xml

@@ -58,6 +58,10 @@
             <groupId>cn.iocoder.boot</groupId>
             <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-biz-trade</artifactId>
+        </dependency>
 
         <!-- Web 相关 -->
         <dependency>
@@ -93,6 +97,7 @@
             <groupId>cn.iocoder.boot</groupId>
             <artifactId>yudao-spring-boot-starter-excel</artifactId>
         </dependency>
+
     </dependencies>
 
 </project>

+ 18 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.admin.aftersale;
 import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.trade.core.annotations.AfterSaleLog;
 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi;
@@ -11,6 +12,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSal
 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO;
 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO;
 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO;
+import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
 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.service.aftersale.TradeAfterSaleService;
@@ -110,4 +112,20 @@ public class TradeAfterSaleController {
         return success(true);
     }
 
+
+    /**
+     * 售后日志测试
+     *
+     * @param createReqVO
+     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<java.lang.Long>
+     * @author 陈賝
+     * @date 2023/6/14 21:39
+     */
+    @PostMapping(value = "/create")
+    @AfterSaleLog(id = "#createReqVO.orderItemId", content = "'申请售后:售后编号['+#createReqVO.orderItemId+'] , '", operateType = "#createReqVO.operateType")
+    public CommonResult<Long> createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) {
+        return success(1L);
+//        return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO));
+    }
+
 }

+ 8 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo;
 
 import cn.iocoder.yudao.framework.common.validation.InEnum;
+import cn.iocoder.yudao.framework.trade.core.enums.AfterSaleStatusEnum;
 import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
@@ -31,6 +32,13 @@ public class AppTradeAfterSaleCreateReqVO {
     @NotNull(message = "申请原因不能为空")
     private String applyReason;
 
+    /**
+     * @see AfterSaleStatusEnum
+     */
+    @Schema(description = "操作类型", required = true, example = "1")
+    @NotNull(message = "操作类型不能为空")
+    private String operateType;
+
     @Schema(description = "补充描述", example = "商品质量不好")
     private String applyDescription;
 

+ 2 - 22
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java

@@ -52,29 +52,9 @@ public class TradeAfterSaleLogDO extends BaseDO {
      */
     private Long afterSaleId;
     /**
-     * 订单编号
-     *
-     * 关联 {@link TradeOrderDO#getId()}
-     */
-    private Long orderId;
-    /**
-     * 订单项编号
-     *
-     * 关联 {@link TradeOrderItemDO#getId()}
-     */
-    private Long orderItemId;
-    /**
-     * 售后状态(之前)
-     *
-     * 枚举 {@link TradeAfterSaleStatusEnum}
-     */
-    private Integer beforeStatus;
-    /**
-     * 售后状态(之后)
-     *
-     * 枚举 {@link TradeAfterSaleStatusEnum}
+     * 操作类型 {@link TradeAfterSaleStatusEnum}
      */
-    private Integer afterStatus;
+    private String operateType;
     /**
      * 操作明细
      */

+ 39 - 9
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java

@@ -5,6 +5,8 @@ import cn.hutool.core.util.RandomUtil;
 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.framework.trade.core.dto.TradeAfterSaleLogDTO;
+import cn.iocoder.yudao.framework.trade.core.service.AfterSaleLogService;
 import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
 import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO;
@@ -26,6 +28,8 @@ import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEn
 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
 import cn.iocoder.yudao.module.trade.service.order.TradeOrderService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.TransactionSynchronization;
@@ -43,9 +47,10 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
  *
  * @author 芋道源码
  */
+@Slf4j
 @Service
 @Validated
-public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
+public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSaleLogService {
 
     @Resource
     private TradeOrderService tradeOrderService;
@@ -80,7 +85,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
     /**
      * 校验交易订单项是否可以申请售后
      *
-     * @param userId 用户编号
+     * @param userId      用户编号
      * @param createReqVO 售后创建信息
      * @return 交易订单项
      */
@@ -117,7 +122,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
         }
         // 如果是【退货退款】的情况,需要额外校验是否发货
         if (createReqVO.getWay().equals(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
-            && !TradeOrderStatusEnum.haveDelivered(order.getStatus())) {
+                && !TradeOrderStatusEnum.haveDelivered(order.getStatus())) {
             throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED);
         }
         return orderItem;
@@ -133,7 +138,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
         TradeOrderDO order = tradeOrderService.getOrder(orderItem.getUserId(), orderItem.getOrderId());
         afterSale.setOrderNo(order.getNo()); // 记录 orderNo 订单流水,方便后续检索
         afterSale.setType(TradeOrderStatusEnum.isCompleted(order.getStatus())
-            ? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType());
+                ? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType());
         // TODO 退还积分
         tradeAfterSaleMapper.insert(afterSale);
 
@@ -380,13 +385,38 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
                 TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null);
     }
 
+    @Deprecated
     private void createAfterSaleLog(Long userId, Integer userType, TradeAfterSaleDO afterSale,
                                     Integer beforeStatus, Integer afterStatus) {
-        TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO().setUserId(userId).setUserType(userType)
-                .setAfterSaleId(afterSale.getId()).setOrderId(afterSale.getOrderId())
-                .setOrderItemId(afterSale.getOrderItemId()).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus)
-                .setContent(TradeAfterSaleStatusEnum.valueOf(afterStatus).getContent());
-        tradeAfterSaleLogMapper.insert(afterSaleLog);
+        TradeAfterSaleLogDTO logDTO = new TradeAfterSaleLogDTO()
+                .setUserId(userId)
+                .setUserType(userType)
+                .setAfterSaleId(afterSale.getId())
+                .setOperateType(afterStatus.toString());
+        // TODO 废弃,待删除
+        this.insert(logDTO);
     }
 
+    /**
+     * 日志记录
+     *
+     * @param logDTO 日志记录
+     * @author 陈賝
+     * @date 2023/6/12 14:18
+     */
+    @Override
+    @Async
+    public void insert(TradeAfterSaleLogDTO logDTO) {
+        try {
+            TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO()
+                    .setUserId(logDTO.getUserId())
+                    .setUserType(logDTO.getUserType())
+                    .setAfterSaleId(logDTO.getAfterSaleId())
+                    .setOperateType(logDTO.getOperateType())
+                    .setContent(logDTO.getContent());
+            tradeAfterSaleLogMapper.insert(afterSaleLog);
+        }catch (Exception exception){
+            log.error("日志记录错误", exception);
+        }
+    }
 }

+ 3 - 2
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java

@@ -66,6 +66,7 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
         AppTradeAfterSaleCreateReqVO createReqVO = new AppTradeAfterSaleCreateReqVO()
                 .setOrderItemId(1L).setRefundPrice(100).setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
                 .setApplyReason("退钱").setApplyDescription("快退")
+                .setOperateType("APPLY")
                 .setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png"));
         // mock 方法(交易订单项)
         TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> {
@@ -102,8 +103,8 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
         assertEquals(afterSaleLog.getUserType(), UserTypeEnum.MEMBER.getValue());
         assertEquals(afterSaleLog.getAfterSaleId(), afterSaleId);
         assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime");
-        assertNull(afterSaleLog.getBeforeStatus());
-        assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus());
+//        assertNull(afterSaleLog.getBeforeStatus());
+//        assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus());
         assertEquals(afterSaleLog.getContent(), TradeAfterSaleStatusEnum.APPLY.getContent());
     }