mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 15:21:53 +08:00
parent
35df912be7
commit
59e16795be
@ -31,6 +31,7 @@
|
|||||||
<module>yudao-spring-boot-starter-biz-sms</module>
|
<module>yudao-spring-boot-starter-biz-sms</module>
|
||||||
|
|
||||||
<module>yudao-spring-boot-starter-biz-pay</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-weixin</module>
|
||||||
<module>yudao-spring-boot-starter-biz-social</module>
|
<module>yudao-spring-boot-starter-biz-social</module>
|
||||||
<module>yudao-spring-boot-starter-biz-tenant</module>
|
<module>yudao-spring-boot-starter-biz-tenant</module>
|
||||||
|
@ -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 "";
|
||||||
|
}
|
||||||
|
}
|
@ -37,7 +37,7 @@
|
|||||||
<!-- 业务组件 -->
|
<!-- 业务组件 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
<artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行操作日志的记录 -->
|
<artifactId>yudao-module-system-api</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
54
yudao-framework/yudao-spring-boot-starter-biz-trade/pom.xml
Normal file
54
yudao-framework/yudao-spring-boot-starter-biz-trade/pom.xml
Normal file
@ -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>
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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 "";
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
package cn.iocoder.yudao.framework.trade.core;
|
@ -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);
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
package cn.iocoder.yudao.framework.trade;
|
@ -0,0 +1 @@
|
|||||||
|
cn.iocoder.yudao.framework.trade.config.YudaoAfterSaleLogAutoConfiguration
|
@ -19,23 +19,38 @@ import static cn.hutool.core.util.ArrayUtil.firstMatch;
|
|||||||
@Getter
|
@Getter
|
||||||
public enum TradeAfterSaleStatusEnum implements IntArrayValuable {
|
public enum TradeAfterSaleStatusEnum implements IntArrayValuable {
|
||||||
|
|
||||||
APPLY(10,"申请中", // 【申请售后】
|
/**
|
||||||
"会员申请退款"),
|
* 【申请售后】
|
||||||
SELLER_AGREE(20, "卖家通过", // 卖家通过售后;【商品待退货】
|
*/
|
||||||
"商家同意退款"),
|
APPLY(10,"申请中", "会员申请退款"),
|
||||||
BUYER_DELIVERY(30,"待卖家收货", // 买家已退货,等待卖家收货;【商家待收货】
|
/**
|
||||||
"会员填写退货物流信息"),
|
* 卖家通过售后;【商品待退货】
|
||||||
WAIT_REFUND(40, "等待平台退款", // 卖家已收货,等待平台退款;等待退款【等待退款】
|
*/
|
||||||
"商家收货"),
|
SELLER_AGREE(20, "卖家通过", "商家同意退款"),
|
||||||
COMPLETE(50, "完成", // 完成退款【退款成功】
|
/**
|
||||||
"商家确认退款"),
|
* 买家已退货,等待卖家收货;【商家待收货】
|
||||||
|
*/
|
||||||
BUYER_CANCEL(61, "买家取消售后", // 【买家取消】
|
BUYER_DELIVERY(30,"待卖家收货", "会员填写退货物流信息"),
|
||||||
"会员取消退款"),
|
/**
|
||||||
SELLER_DISAGREE(62,"卖家拒绝", // 卖家拒绝售后;商家拒绝【商家拒绝】
|
* 卖家已收货,等待平台退款;等待退款【等待退款】
|
||||||
"商家拒绝退款"),
|
*/
|
||||||
SELLER_REFUSE(63,"卖家拒绝收货", // 卖家拒绝收货,终止售后;【商家拒收货】
|
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();
|
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleStatusEnum::getStatus).toArray();
|
||||||
|
@ -58,6 +58,10 @@
|
|||||||
<groupId>cn.iocoder.boot</groupId>
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
|
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
|
<artifactId>yudao-spring-boot-starter-biz-trade</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Web 相关 -->
|
<!-- Web 相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -93,6 +97,7 @@
|
|||||||
<groupId>cn.iocoder.boot</groupId>
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
<artifactId>yudao-spring-boot-starter-excel</artifactId>
|
<artifactId>yudao-spring-boot-starter-excel</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.admin.aftersale;
|
|||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
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.MemberUserApi;
|
||||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||||
import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi;
|
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.TradeAfterSalePageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO;
|
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.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.convert.aftersale.TradeAfterSaleConvert;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
|
||||||
import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService;
|
import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService;
|
||||||
@ -110,4 +112,20 @@ public class TradeAfterSaleController {
|
|||||||
return success(true);
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo;
|
package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
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 cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -31,6 +32,13 @@ public class AppTradeAfterSaleCreateReqVO {
|
|||||||
@NotNull(message = "申请原因不能为空")
|
@NotNull(message = "申请原因不能为空")
|
||||||
private String applyReason;
|
private String applyReason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see AfterSaleStatusEnum
|
||||||
|
*/
|
||||||
|
@Schema(description = "操作类型", required = true, example = "1")
|
||||||
|
@NotNull(message = "操作类型不能为空")
|
||||||
|
private String operateType;
|
||||||
|
|
||||||
@Schema(description = "补充描述", example = "商品质量不好")
|
@Schema(description = "补充描述", example = "商品质量不好")
|
||||||
private String applyDescription;
|
private String applyDescription;
|
||||||
|
|
||||||
|
@ -52,29 +52,9 @@ public class TradeAfterSaleLogDO extends BaseDO {
|
|||||||
*/
|
*/
|
||||||
private Long afterSaleId;
|
private Long afterSaleId;
|
||||||
/**
|
/**
|
||||||
* 订单编号
|
* 操作类型 {@link TradeAfterSaleStatusEnum}
|
||||||
*
|
|
||||||
* 关联 {@link TradeOrderDO#getId()}
|
|
||||||
*/
|
*/
|
||||||
private Long orderId;
|
private String operateType;
|
||||||
/**
|
|
||||||
* 订单项编号
|
|
||||||
*
|
|
||||||
* 关联 {@link TradeOrderItemDO#getId()}
|
|
||||||
*/
|
|
||||||
private Long orderItemId;
|
|
||||||
/**
|
|
||||||
* 售后状态(之前)
|
|
||||||
*
|
|
||||||
* 枚举 {@link TradeAfterSaleStatusEnum}
|
|
||||||
*/
|
|
||||||
private Integer beforeStatus;
|
|
||||||
/**
|
|
||||||
* 售后状态(之后)
|
|
||||||
*
|
|
||||||
* 枚举 {@link TradeAfterSaleStatusEnum}
|
|
||||||
*/
|
|
||||||
private Integer afterStatus;
|
|
||||||
/**
|
/**
|
||||||
* 操作明细
|
* 操作明细
|
||||||
*/
|
*/
|
||||||
|
@ -5,6 +5,8 @@ import cn.hutool.core.util.RandomUtil;
|
|||||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
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.PayRefundApi;
|
||||||
import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
|
import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO;
|
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.enums.order.TradeOrderStatusEnum;
|
||||||
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
|
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
|
||||||
import cn.iocoder.yudao.module.trade.service.order.TradeOrderService;
|
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.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.transaction.support.TransactionSynchronization;
|
import org.springframework.transaction.support.TransactionSynchronization;
|
||||||
@ -43,9 +47,10 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
|||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@Validated
|
@Validated
|
||||||
public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
|
public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSaleLogService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private TradeOrderService tradeOrderService;
|
private TradeOrderService tradeOrderService;
|
||||||
@ -80,7 +85,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
|
|||||||
/**
|
/**
|
||||||
* 校验交易订单项是否可以申请售后
|
* 校验交易订单项是否可以申请售后
|
||||||
*
|
*
|
||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
* @param createReqVO 售后创建信息
|
* @param createReqVO 售后创建信息
|
||||||
* @return 交易订单项
|
* @return 交易订单项
|
||||||
*/
|
*/
|
||||||
@ -117,7 +122,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
|
|||||||
}
|
}
|
||||||
// 如果是【退货退款】的情况,需要额外校验是否发货
|
// 如果是【退货退款】的情况,需要额外校验是否发货
|
||||||
if (createReqVO.getWay().equals(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
|
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);
|
throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED);
|
||||||
}
|
}
|
||||||
return orderItem;
|
return orderItem;
|
||||||
@ -133,7 +138,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
|
|||||||
TradeOrderDO order = tradeOrderService.getOrder(orderItem.getUserId(), orderItem.getOrderId());
|
TradeOrderDO order = tradeOrderService.getOrder(orderItem.getUserId(), orderItem.getOrderId());
|
||||||
afterSale.setOrderNo(order.getNo()); // 记录 orderNo 订单流水,方便后续检索
|
afterSale.setOrderNo(order.getNo()); // 记录 orderNo 订单流水,方便后续检索
|
||||||
afterSale.setType(TradeOrderStatusEnum.isCompleted(order.getStatus())
|
afterSale.setType(TradeOrderStatusEnum.isCompleted(order.getStatus())
|
||||||
? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType());
|
? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType());
|
||||||
// TODO 退还积分
|
// TODO 退还积分
|
||||||
tradeAfterSaleMapper.insert(afterSale);
|
tradeAfterSaleMapper.insert(afterSale);
|
||||||
|
|
||||||
@ -380,13 +385,38 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
|
|||||||
TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null);
|
TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
private void createAfterSaleLog(Long userId, Integer userType, TradeAfterSaleDO afterSale,
|
private void createAfterSaleLog(Long userId, Integer userType, TradeAfterSaleDO afterSale,
|
||||||
Integer beforeStatus, Integer afterStatus) {
|
Integer beforeStatus, Integer afterStatus) {
|
||||||
TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO().setUserId(userId).setUserType(userType)
|
TradeAfterSaleLogDTO logDTO = new TradeAfterSaleLogDTO()
|
||||||
.setAfterSaleId(afterSale.getId()).setOrderId(afterSale.getOrderId())
|
.setUserId(userId)
|
||||||
.setOrderItemId(afterSale.getOrderItemId()).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus)
|
.setUserType(userType)
|
||||||
.setContent(TradeAfterSaleStatusEnum.valueOf(afterStatus).getContent());
|
.setAfterSaleId(afterSale.getId())
|
||||||
tradeAfterSaleLogMapper.insert(afterSaleLog);
|
.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,7 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
|
|||||||
AppTradeAfterSaleCreateReqVO createReqVO = new AppTradeAfterSaleCreateReqVO()
|
AppTradeAfterSaleCreateReqVO createReqVO = new AppTradeAfterSaleCreateReqVO()
|
||||||
.setOrderItemId(1L).setRefundPrice(100).setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
|
.setOrderItemId(1L).setRefundPrice(100).setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
|
||||||
.setApplyReason("退钱").setApplyDescription("快退")
|
.setApplyReason("退钱").setApplyDescription("快退")
|
||||||
|
.setOperateType("APPLY")
|
||||||
.setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png"));
|
.setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png"));
|
||||||
// mock 方法(交易订单项)
|
// mock 方法(交易订单项)
|
||||||
TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> {
|
TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> {
|
||||||
@ -102,8 +103,8 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
|
|||||||
assertEquals(afterSaleLog.getUserType(), UserTypeEnum.MEMBER.getValue());
|
assertEquals(afterSaleLog.getUserType(), UserTypeEnum.MEMBER.getValue());
|
||||||
assertEquals(afterSaleLog.getAfterSaleId(), afterSaleId);
|
assertEquals(afterSaleLog.getAfterSaleId(), afterSaleId);
|
||||||
assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime");
|
assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime");
|
||||||
assertNull(afterSaleLog.getBeforeStatus());
|
// assertNull(afterSaleLog.getBeforeStatus());
|
||||||
assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus());
|
// assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus());
|
||||||
assertEquals(afterSaleLog.getContent(), TradeAfterSaleStatusEnum.APPLY.getContent());
|
assertEquals(afterSaleLog.getContent(), TradeAfterSaleStatusEnum.APPLY.getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user