售后日志优化

This commit is contained in:
chenchen
2023-06-19 10:19:29 +08:00
parent 7d0e9ea762
commit a93b9a616f
20 changed files with 202 additions and 279 deletions

View File

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

View File

@ -3,7 +3,6 @@ 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;
@ -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.convert.aftersale.TradeAfterSaleConvert;
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 io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@ -122,7 +123,7 @@ public class TradeAfterSaleController {
* @date 2023/6/14 21:39
*/
@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) {
return success(1L);
// return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO));

View File

@ -1,7 +1,6 @@
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;
@ -32,14 +31,6 @@ public class AppTradeAfterSaleCreateReqVO {
@NotNull(message = "申请原因不能为空")
private String applyReason;
// TODO @陈賝:这个参数不应该有呀。
/**
* @see AfterSaleStatusEnum
*/
@Schema(description = "操作类型", required = true, example = "1")
@NotNull(message = "操作类型不能为空")
private String operateType;
@Schema(description = "补充描述", example = "商品质量不好")
private String applyDescription;

View File

@ -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();
}
}

View File

@ -0,0 +1,33 @@
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.*;
/**
* 售后日志
*
* @author 陈賝
* @since 2023/6/8 17:04
*/
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AfterSaleLog {
/**
* 售后 ID
*/
String id();
/**
* 操作类型
*/
AfterSaleStatusEnum operateType() default AfterSaleStatusEnum.APPLY;
/**
* 日志内容
*/
String content() default "";
}

View File

@ -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;
}
}

View File

@ -0,0 +1,46 @@
package cn.iocoder.yudao.module.trade.framework.aftersalelog.core.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 售后日志的创建 Request DTO
*
* @author 陈賝
* @since 2023/6/19 09:54
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TradeAfterSaleLogCreateReqDTO {
/**
* 编号
*/
private Long id;
/**
* 用户编号
* <p>
* 关联 1AdminUserDO 的 id 字段
* 关联 2MemberUserDO 的 id 字段
*/
private Long userId;
/**
* 用户类型
*/
private Integer userType;
/**
* 售后编号
*/
private Long afterSaleId;
/**
* 操作类型
*/
private String operateType;
/**
* 操作明细
*/
private String content;
}

View File

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

View File

@ -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);
}

View File

@ -5,8 +5,6 @@ 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.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.dto.PayRefundCreateReqDTO;
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.order.TradeOrderItemAfterSaleStatusEnum;
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.service.order.TradeOrderService;
import lombok.extern.slf4j.Slf4j;
@ -40,6 +40,7 @@ import javax.annotation.Resource;
import java.time.LocalDateTime;
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.*;
/**
@ -394,7 +395,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
.setAfterSaleId(afterSale.getId())
.setOperateType(afterStatus.toString());
// TODO 废弃,待删除
this.insert(logDTO);
this.createLog(logDTO);
}
/**
@ -406,7 +407,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
*/
@Override
@Async
public void insert(TradeAfterSaleLogCreateReqDTO logDTO) {
public void createLog(TradeAfterSaleLogCreateReqDTO logDTO) {
try {
TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO()
.setUserId(logDTO.getUserId())
@ -416,7 +417,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa
.setContent(logDTO.getContent());
tradeAfterSaleLogMapper.insert(afterSaleLog);
}catch (Exception exception){
log.error("日志记录错误", exception);
log.error("[request({}) 日志记录错误]", toJsonString(logDTO), exception);
}
}
}