From 59e16795be0009d381ae501bb0ddf92526d04cb6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=99=88=E8=B3=9D?= <934298133@qq.com>
Date: Sat, 17 Jun 2023 14:00:10 +0000
Subject: [PATCH] =?UTF-8?q?!514=20mall=E4=BA=A4=E6=98=93=E6=97=A5=E5=BF=97?=
=?UTF-8?q?=E5=B0=81=E8=A3=85=20*=20=E4=BA=A4=E6=98=93=E6=97=A5=E5=BF=97?=
=?UTF-8?q?=E5=B0=81=E8=A3=85=20*=20=E4=BA=A4=E6=98=93=E6=97=A5=E5=BF=97?=
=?UTF-8?q?=E5=B0=81=E8=A3=85=20*=20=E4=BA=A4=E6=98=93=E6=97=A5=E5=BF=97?=
=?UTF-8?q?=E6=A8=A1=E5=9D=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
yudao-framework/pom.xml | 1 +
.../framework/common/util/spel/SpelUtil.java | 81 +++++++++++++++++
.../pom.xml | 2 +-
.../pom.xml | 54 ++++++++++++
.../YudaoAfterSaleLogAutoConfiguration.java | 17 ++++
.../trade/core/annotations/AfterSaleLog.java | 34 ++++++++
.../trade/core/aop/AfterSaleLogAspect.java | 87 +++++++++++++++++++
.../trade/core/dto/TradeAfterSaleLogDTO.java | 42 +++++++++
.../trade/core/enums/AfterSaleStatusEnum.java | 27 ++++++
.../framework/trade/core/package-info.java | 1 +
.../core/service/AfterSaleLogService.java | 16 ++++
.../yudao/framework/trade/package-info.java | 1 +
...ot.autoconfigure.AutoConfiguration.imports | 1 +
.../aftersale/TradeAfterSaleStatusEnum.java | 49 +++++++----
.../yudao-module-trade-biz/pom.xml | 5 ++
.../aftersale/TradeAfterSaleController.java | 18 ++++
.../vo/AppTradeAfterSaleCreateReqVO.java | 8 ++
.../aftersale/TradeAfterSaleLogDO.java | 24 +----
.../aftersale/TradeAfterSaleServiceImpl.java | 48 ++++++++--
.../aftersale/TradeAfterSaleServiceTest.java | 5 +-
20 files changed, 470 insertions(+), 51 deletions(-)
create mode 100644 yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spel/SpelUtil.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-trade/pom.xml
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/config/YudaoAfterSaleLogAutoConfiguration.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/annotations/AfterSaleLog.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/aop/AfterSaleLogAspect.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/dto/TradeAfterSaleLogDTO.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/enums/AfterSaleStatusEnum.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/package-info.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/service/AfterSaleLogService.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/package-info.java
create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
diff --git a/yudao-framework/pom.xml b/yudao-framework/pom.xml
index 12244f5ce..a25ff0f74 100644
--- a/yudao-framework/pom.xml
+++ b/yudao-framework/pom.xml
@@ -31,6 +31,7 @@
yudao-spring-boot-starter-biz-sms
yudao-spring-boot-starter-biz-pay
+ yudao-spring-boot-starter-biz-trade
yudao-spring-boot-starter-biz-weixin
yudao-spring-boot-starter-biz-social
yudao-spring-boot-starter-biz-tenant
diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spel/SpelUtil.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spel/SpelUtil.java
new file mode 100644
index 000000000..55bad6910
--- /dev/null
+++ b/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 "";
+ }
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-operatelog/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-operatelog/pom.xml
index 01deef06f..5792b4cb4 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-operatelog/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-biz-operatelog/pom.xml
@@ -37,7 +37,7 @@
cn.iocoder.boot
- yudao-module-system-api
+ yudao-module-system-api
${revision}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-trade/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-trade/pom.xml
new file mode 100644
index 000000000..ab9c820bf
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-biz-trade/pom.xml
@@ -0,0 +1,54 @@
+
+
+
+ cn.iocoder.boot
+ yudao-framework
+ ${revision}
+
+ 4.0.0
+ yudao-spring-boot-starter-biz-trade
+ jar
+
+ ${project.artifactId}
+ 交易模块
+ https://github.com/YunaiV/ruoyi-vue-pro
+
+
+
+ cn.iocoder.boot
+ yudao-common
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+
+
+ cn.iocoder.boot
+ yudao-spring-boot-starter-web
+ provided
+
+
+
+
+ cn.iocoder.boot
+ yudao-module-system-api
+ ${revision}
+
+
+
+
+ com.google.guava
+ guava
+
+
+ cn.iocoder.boot
+ yudao-spring-boot-starter-security
+
+
+
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/config/YudaoAfterSaleLogAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/config/YudaoAfterSaleLogAutoConfiguration.java
new file mode 100644
index 000000000..98c1a4547
--- /dev/null
+++ b/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();
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/annotations/AfterSaleLog.java b/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/annotations/AfterSaleLog.java
new file mode 100644
index 000000000..7bf61f2cd
--- /dev/null
+++ b/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 "";
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/aop/AfterSaleLogAspect.java b/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/aop/AfterSaleLogAspect.java
new file mode 100644
index 000000000..6b7e9533e
--- /dev/null
+++ b/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 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 spelFormat(JoinPoint joinPoint, Object info) {
+
+ Map 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;
+
+ }
+
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/dto/TradeAfterSaleLogDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/dto/TradeAfterSaleLogDTO.java
new file mode 100644
index 000000000..9efafa1ad
--- /dev/null
+++ b/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;
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/enums/AfterSaleStatusEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/enums/AfterSaleStatusEnum.java
new file mode 100644
index 000000000..584863a78
--- /dev/null
+++ b/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;
+ }
+
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/package-info.java b/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/package-info.java
new file mode 100644
index 000000000..7e96e62d8
--- /dev/null
+++ b/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;
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/service/AfterSaleLogService.java b/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/service/AfterSaleLogService.java
new file mode 100644
index 000000000..82333fcb7
--- /dev/null
+++ b/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);
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/package-info.java b/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/package-info.java
new file mode 100644
index 000000000..24659f2ca
--- /dev/null
+++ b/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;
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 000000000..12e306893
--- /dev/null
+++ b/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
diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java
index 88ea5230c..102eff32b 100644
--- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java
+++ b/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();
diff --git a/yudao-module-mall/yudao-module-trade-biz/pom.xml b/yudao-module-mall/yudao-module-trade-biz/pom.xml
index 24b2097ba..634df0071 100644
--- a/yudao-module-mall/yudao-module-trade-biz/pom.xml
+++ b/yudao-module-mall/yudao-module-trade-biz/pom.xml
@@ -58,6 +58,10 @@
cn.iocoder.boot
yudao-spring-boot-starter-biz-ip
+
+ cn.iocoder.boot
+ yudao-spring-boot-starter-biz-trade
+
@@ -93,6 +97,7 @@
cn.iocoder.boot
yudao-spring-boot-starter-excel
+
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java
index a1bf5d544..f8cfa7904 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java
+++ b/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
+ * @author 陈賝
+ * @date 2023/6/14 21:39
+ */
+ @PostMapping(value = "/create")
+ @AfterSaleLog(id = "#createReqVO.orderItemId", content = "'申请售后:售后编号['+#createReqVO.orderItemId+'] , '", operateType = "#createReqVO.operateType")
+ public CommonResult createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) {
+ return success(1L);
+// return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO));
+ }
+
}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java
index 3bf8dd944..e4d34188f 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java
+++ b/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;
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java
index 5aa627403..0887e765b 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java
+++ b/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()}
+ * 操作类型 {@link TradeAfterSaleStatusEnum}
*/
- private Long orderId;
- /**
- * 订单项编号
- *
- * 关联 {@link TradeOrderItemDO#getId()}
- */
- private Long orderItemId;
- /**
- * 售后状态(之前)
- *
- * 枚举 {@link TradeAfterSaleStatusEnum}
- */
- private Integer beforeStatus;
- /**
- * 售后状态(之后)
- *
- * 枚举 {@link TradeAfterSaleStatusEnum}
- */
- private Integer afterStatus;
+ private String operateType;
/**
* 操作明细
*/
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 374af0a16..42829a2a9 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
@@ -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);
+ }
+ }
}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java
index 0602c6649..7f94b6d19 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java
+++ b/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());
}