mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-26 09:11:52 +08:00
售后日志优化
This commit is contained in:
parent
7d0e9ea762
commit
a93b9a616f
@ -96,11 +96,6 @@
|
|||||||
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
|
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
|
||||||
<artifactId>yudao-spring-boot-starter-biz-trade</artifactId>
|
|
||||||
<version>${revision}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
<artifactId>yudao-spring-boot-starter-biz-dict</artifactId>
|
<artifactId>yudao-spring-boot-starter-biz-dict</artifactId>
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
<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>
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
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;
|
|
||||||
|
|
||||||
// TODO @Chopper:和 SpringExpressionUtils 合并下
|
|
||||||
/**
|
|
||||||
* SpelUtil
|
|
||||||
*
|
|
||||||
* @author Chopper
|
|
||||||
* @version v1.0
|
|
||||||
* @since 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 "";
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.common.util.spring;
|
|||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||||
@ -24,7 +25,15 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class SpringExpressionUtils {
|
public class SpringExpressionUtils {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* spel表达式解析器
|
||||||
|
*/
|
||||||
private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
|
private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
|
||||||
|
/**
|
||||||
|
* 参数名发现器
|
||||||
|
*/
|
||||||
private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
|
private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
|
||||||
|
|
||||||
private SpringExpressionUtils() {
|
private SpringExpressionUtils() {
|
||||||
@ -79,4 +88,47 @@ public class SpringExpressionUtils {
|
|||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JoinPoint 切面 批量解析 EL 表达式,转换 jspl参数
|
||||||
|
*
|
||||||
|
* @param joinPoint 切面点
|
||||||
|
* @param rvt 返回值
|
||||||
|
* @param expressionStrings EL 表达式数组
|
||||||
|
* @return java.lang.String 结果
|
||||||
|
* @author 陈賝
|
||||||
|
* @since 2023/6/18 11:20
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> parseExpression(JoinPoint joinPoint, Object rvt, List<String> expressionStrings) {
|
||||||
|
// 如果为空,则不进行解析
|
||||||
|
if (CollUtil.isEmpty(expressionStrings)) {
|
||||||
|
return MapUtil.newHashMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第一步,构建解析的上下文 EvaluationContext
|
||||||
|
// 通过 joinPoint 获取被注解方法
|
||||||
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||||
|
Method method = signature.getMethod();
|
||||||
|
// 使用 spring 的 ParameterNameDiscoverer 获取方法形参名数组
|
||||||
|
String[] parameterNames = PARAMETER_NAME_DISCOVERER.getParameterNames(method);
|
||||||
|
// Spring 的表达式上下文对象
|
||||||
|
EvaluationContext context = new StandardEvaluationContext();
|
||||||
|
if (ArrayUtil.isNotEmpty(parameterNames)) {
|
||||||
|
//获取方法参数值
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
// 第二步,逐个参数解析
|
||||||
|
Map<String, Object> result = MapUtil.newHashMap(expressionStrings.size(), true);
|
||||||
|
expressionStrings.forEach(key -> {
|
||||||
|
Object value = EXPRESSION_PARSER.parseExpression(key).getValue(context);
|
||||||
|
result.put(key, value);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
<?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>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
@ -1,16 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.trade.config;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.trade.core.aop.AfterSaleLogAspect;
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
|
|
||||||
// TODO @Chopper:和 yudao-module-trade-biz 的 framework 里
|
|
||||||
@AutoConfiguration
|
|
||||||
public class YudaoAfterSaleLogAutoConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public AfterSaleLogAspect afterSaleLogAspect() {
|
|
||||||
return new AfterSaleLogAspect();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.trade.core.aop;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
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.TradeAfterSaleLogCreateReqDTO;
|
|
||||||
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.Aspect;
|
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 记录售后日志的 AOP 切面
|
|
||||||
*
|
|
||||||
* @author 陈賝
|
|
||||||
* @since 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);
|
|
||||||
TradeAfterSaleLogCreateReqDTO dto = new TradeAfterSaleLogCreateReqDTO()
|
|
||||||
.setUserId(id).setUserType(userType)
|
|
||||||
// MapUtil.getLong() TODO @陈賝:试试这个方法
|
|
||||||
.setAfterSaleId(Long.valueOf(formatObj.get("id")))
|
|
||||||
.setContent(formatObj.get("content"))
|
|
||||||
.setOperateType(formatObj.get("operateType"));
|
|
||||||
// 异步存入数据库 TODO 可以注入哈;
|
|
||||||
SpringUtil.getBean(AfterSaleLogService.class).insert(dto);
|
|
||||||
} catch (Exception exception) {
|
|
||||||
// TODO @陈賝:日志要记录下参数哈,不然排查问题不好搞;
|
|
||||||
log.error("日志记录错误", exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取描述信息
|
|
||||||
*/
|
|
||||||
public static Map<String, String> spelFormat(JoinPoint joinPoint, Object info) {
|
|
||||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
|
||||||
AfterSaleLog afterSaleLogPoint = signature.getMethod().getAnnotation(AfterSaleLog.class);
|
|
||||||
Map<String, String> result = new HashMap<>(2); // TODO @陈賝:Maps.newExpectedXXX(3)
|
|
||||||
// 售后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 (StrUtil.isNotEmpty(afterSaleLogPoint.operateType())) {
|
|
||||||
content += AfterSaleStatusEnum.valueOf(SpelUtil.compileParams(joinPoint, info, afterSaleLogPoint.operateType())).description();
|
|
||||||
}
|
|
||||||
result.put("content", content);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.trade.core.service;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.trade.core.dto.TradeAfterSaleLogCreateReqDTO;
|
|
||||||
|
|
||||||
// TODO @陈賝:类注释
|
|
||||||
public interface AfterSaleLogService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建售后日志
|
|
||||||
*
|
|
||||||
* @param logDTO 日志记录
|
|
||||||
* @author 陈賝
|
|
||||||
* @since 2023/6/12 14:18
|
|
||||||
*/
|
|
||||||
// TODO @陈賝:createLog 方法名
|
|
||||||
void insert(TradeAfterSaleLogCreateReqDTO logDTO);
|
|
||||||
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
cn.iocoder.yudao.framework.trade.config.YudaoAfterSaleLogAutoConfiguration
|
|
@ -58,10 +58,6 @@
|
|||||||
<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>
|
||||||
|
@ -3,7 +3,6 @@ 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;
|
||||||
@ -15,6 +14,8 @@ import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSal
|
|||||||
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
|
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.framework.aftersalelog.core.annotations.AfterSaleLog;
|
||||||
|
import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.enums.AfterSaleStatusEnum;
|
||||||
import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService;
|
import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
@ -122,7 +123,7 @@ public class TradeAfterSaleController {
|
|||||||
* @date 2023/6/14 21:39
|
* @date 2023/6/14 21:39
|
||||||
*/
|
*/
|
||||||
@PostMapping(value = "/create")
|
@PostMapping(value = "/create")
|
||||||
@AfterSaleLog(id = "#createReqVO.orderItemId", content = "'申请售后:售后编号['+#createReqVO.orderItemId+'] , '", operateType = "#createReqVO.operateType")
|
@AfterSaleLog(id = "#createReqVO.orderItemId", content = "'申请售后:售后编号['+#createReqVO.orderItemId+'] , '", operateType = AfterSaleStatusEnum.APPLY)
|
||||||
public CommonResult<Long> createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) {
|
public CommonResult<Long> createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) {
|
||||||
return success(1L);
|
return success(1L);
|
||||||
// return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO));
|
// return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO));
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
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;
|
||||||
@ -32,14 +31,6 @@ public class AppTradeAfterSaleCreateReqVO {
|
|||||||
@NotNull(message = "申请原因不能为空")
|
@NotNull(message = "申请原因不能为空")
|
||||||
private String applyReason;
|
private String applyReason;
|
||||||
|
|
||||||
// TODO @陈賝:这个参数不应该有呀。
|
|
||||||
/**
|
|
||||||
* @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;
|
||||||
|
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.framework.aftersalelog.config;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.aop.AfterSaleLogAspect;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* trade 模块的 afterSaleLog 组件的 Configuration
|
||||||
|
*
|
||||||
|
* @author 陈賝
|
||||||
|
* @since 2023/6/18 11:09
|
||||||
|
*/
|
||||||
|
@AutoConfiguration
|
||||||
|
public class AfterSaleLogConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public AfterSaleLogAspect afterSaleLogAspect() {
|
||||||
|
return new AfterSaleLogAspect();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,6 @@
|
|||||||
package cn.iocoder.yudao.framework.trade.core.annotations;
|
package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.annotations;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.enums.AfterSaleStatusEnum;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
@ -18,11 +20,10 @@ public @interface AfterSaleLog {
|
|||||||
*/
|
*/
|
||||||
String id();
|
String id();
|
||||||
|
|
||||||
// TODO @陈賝:是不是改成一个操作的枚举?
|
|
||||||
/**
|
/**
|
||||||
* 操作类型
|
* 操作类型
|
||||||
*/
|
*/
|
||||||
String operateType() default "";
|
AfterSaleStatusEnum operateType() default AfterSaleStatusEnum.APPLY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志内容
|
* 日志内容
|
@ -0,0 +1,80 @@
|
|||||||
|
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.web.core.util.WebFrameworkUtils;
|
||||||
|
import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogCreateReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.annotations.AfterSaleLog;
|
||||||
|
import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service.AfterSaleLogService;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.AfterReturning;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录售后日志的 AOP 切面
|
||||||
|
*
|
||||||
|
* @author 陈賝
|
||||||
|
* @since 2023/6/13 13:54
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Aspect
|
||||||
|
public class AfterSaleLogAspect {
|
||||||
|
@Resource
|
||||||
|
private AfterSaleLogService saleLogService;
|
||||||
|
|
||||||
|
@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);
|
||||||
|
TradeAfterSaleLogCreateReqDTO dto = new TradeAfterSaleLogCreateReqDTO()
|
||||||
|
.setUserId(id).setUserType(userType)
|
||||||
|
.setAfterSaleId(MapUtil.getLong(formatObj, "id"))
|
||||||
|
.setContent(formatObj.get("content"))
|
||||||
|
.setOperateType(formatObj.get("operateType"));
|
||||||
|
// 异步存入数据库
|
||||||
|
saleLogService.createLog(dto);
|
||||||
|
} catch (Exception exception) {
|
||||||
|
log.error("[afterSaleLog({}) 日志记录错误]", toJsonString(afterSaleLog), exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取描述信息
|
||||||
|
*/
|
||||||
|
public static Map<String, String> spelFormat(JoinPoint joinPoint, Object info) {
|
||||||
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||||
|
AfterSaleLog afterSaleLogPoint = signature.getMethod().getAnnotation(AfterSaleLog.class);
|
||||||
|
HashMap<String, String> result = Maps.newHashMapWithExpectedSize(3);
|
||||||
|
Map<String, Object> spelMap = SpringExpressionUtils.parseExpression(joinPoint, info,
|
||||||
|
asList(afterSaleLogPoint.id(), afterSaleLogPoint.operateType().description(), afterSaleLogPoint.content()));
|
||||||
|
// 售后ID
|
||||||
|
String id = MapUtil.getStr(spelMap, afterSaleLogPoint.id());
|
||||||
|
result.put("id", id);
|
||||||
|
// 操作类型
|
||||||
|
String operateType = MapUtil.getStr(spelMap, afterSaleLogPoint.operateType().description());
|
||||||
|
result.put("operateType", operateType);
|
||||||
|
// 日志内容
|
||||||
|
String content = MapUtil.getStr(spelMap, afterSaleLogPoint.content());
|
||||||
|
if (ObjectUtil.isNotNull(afterSaleLogPoint.operateType())) {
|
||||||
|
content += MapUtil.getStr(spelMap, afterSaleLogPoint.operateType().description());
|
||||||
|
}
|
||||||
|
result.put("content", content);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.framework.trade.core.dto;
|
package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -6,6 +6,9 @@ import lombok.NoArgsConstructor;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 售后日志的创建 Request DTO
|
* 售后日志的创建 Request DTO
|
||||||
|
*
|
||||||
|
* @author 陈賝
|
||||||
|
* @since 2023/6/19 09:54
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@ -18,7 +21,7 @@ public class TradeAfterSaleLogCreateReqDTO {
|
|||||||
private Long id;
|
private Long id;
|
||||||
/**
|
/**
|
||||||
* 用户编号
|
* 用户编号
|
||||||
*
|
* <p>
|
||||||
* 关联 1:AdminUserDO 的 id 字段
|
* 关联 1:AdminUserDO 的 id 字段
|
||||||
* 关联 2:MemberUserDO 的 id 字段
|
* 关联 2:MemberUserDO 的 id 字段
|
||||||
*/
|
*/
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.framework.trade.core.enums;
|
package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.enums;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 售后状态的枚举
|
* 售后状态的枚举
|
@ -0,0 +1,23 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto.TradeAfterSaleLogCreateReqDTO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 交易售后日志 Service 接口
|
||||||
|
*
|
||||||
|
* @author 陈賝
|
||||||
|
* @since 2023/6/12 14:18
|
||||||
|
*/
|
||||||
|
public interface AfterSaleLogService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建售后日志
|
||||||
|
*
|
||||||
|
* @param logDTO 日志记录
|
||||||
|
* @author 陈賝
|
||||||
|
* @since 2023/6/12 14:18
|
||||||
|
*/
|
||||||
|
void createLog(TradeAfterSaleLogCreateReqDTO logDTO);
|
||||||
|
|
||||||
|
}
|
@ -5,8 +5,6 @@ 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.TradeAfterSaleLogCreateReqDTO;
|
|
||||||
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 +24,8 @@ 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.aftersale.TradeAfterSaleWayEnum;
|
||||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
|
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
|
||||||
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.aftersalelog.core.dto.TradeAfterSaleLogCreateReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.service.AfterSaleLogService;
|
||||||
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 lombok.extern.slf4j.Slf4j;
|
||||||
@ -40,6 +40,7 @@ import javax.annotation.Resource;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
||||||
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -394,7 +395,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
|
|||||||
.setAfterSaleId(afterSale.getId())
|
.setAfterSaleId(afterSale.getId())
|
||||||
.setOperateType(afterStatus.toString());
|
.setOperateType(afterStatus.toString());
|
||||||
// TODO 废弃,待删除
|
// TODO 废弃,待删除
|
||||||
this.insert(logDTO);
|
this.createLog(logDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -406,7 +407,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Async
|
@Async
|
||||||
public void insert(TradeAfterSaleLogCreateReqDTO logDTO) {
|
public void createLog(TradeAfterSaleLogCreateReqDTO logDTO) {
|
||||||
try {
|
try {
|
||||||
TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO()
|
TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO()
|
||||||
.setUserId(logDTO.getUserId())
|
.setUserId(logDTO.getUserId())
|
||||||
@ -416,7 +417,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
|
|||||||
.setContent(logDTO.getContent());
|
.setContent(logDTO.getContent());
|
||||||
tradeAfterSaleLogMapper.insert(afterSaleLog);
|
tradeAfterSaleLogMapper.insert(afterSaleLog);
|
||||||
}catch (Exception exception){
|
}catch (Exception exception){
|
||||||
log.error("日志记录错误", exception);
|
log.error("[request({}) 日志记录错误]", toJsonString(logDTO), exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,11 +84,11 @@
|
|||||||
<!-- <version>${revision}</version>-->
|
<!-- <version>${revision}</version>-->
|
||||||
<!-- </dependency>-->
|
<!-- </dependency>-->
|
||||||
|
|
||||||
<dependency>
|
<!-- <dependency>-->
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||||
<artifactId>yudao-module-point-biz</artifactId>
|
<!-- <artifactId>yudao-module-point-biz</artifactId>-->
|
||||||
<version>${revision}</version>
|
<!-- <version>${revision}</version>-->
|
||||||
</dependency>
|
<!-- </dependency>-->
|
||||||
|
|
||||||
<!-- spring boot 配置所需依赖 -->
|
<!-- spring boot 配置所需依赖 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
Loading…
Reference in New Issue
Block a user