mall 下单日志

This commit is contained in:
chenchen 2023-07-07 14:06:32 +08:00
parent f492797fba
commit 284506b356
10 changed files with 328 additions and 1 deletions

View File

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.trade.enums.aftersale;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* 订单操作类型的枚举
*
* @author 陈賝
* @since 2023/7/6 15:31
*/
@RequiredArgsConstructor
@Getter
public enum OrderOperateTypeEnum {
/**
* 用户下单
*/
ORDER(0, "用户下单"),
;
// 类型
private final Integer type;
// 描述
private final String description;
public String description() {
return description;
}
}

View File

@ -14,8 +14,12 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderI
import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleOperateTypeEnum;
import cn.iocoder.yudao.module.trade.enums.aftersale.OrderOperateTypeEnum;
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.annotations.AfterSaleLog;
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
import cn.iocoder.yudao.module.trade.framework.order.core.annotations.OrderLog;
import cn.iocoder.yudao.module.trade.service.order.TradeOrderService;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
@ -66,6 +70,7 @@ public class AppTradeOrderController {
@PostMapping("/create")
@Operation(summary = "创建订单")
@PreAuthenticated
@OrderLog(id = "#info.id", content = "'创建订单:支付订单编号['+#info.payOrderId+'], 订单编号['+#info.id+'], '", operateType = OrderOperateTypeEnum.ORDER)
public CommonResult<AppTradeOrderCreateRespVO> createOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO) {
TradeOrderDO order = tradeOrderService.createOrder(getLoginUserId(), getClientIP(), createReqVO);
return success(new AppTradeOrderCreateRespVO().setId(order.getId()).setPayOrderId(order.getPayOrderId()));

View File

@ -0,0 +1,51 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.order;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 订单日志 DO
*
* @author 陈賝
*/
@TableName("trade_order_log")
@KeySequence("trade_order_log_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrderLogDO extends BaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 订单号
*/
private Long orderId;
/**
* 订单日志信息
*/
private String content;
/**
* 操作类型
*/
private Integer operateType;
/**
* 创建者ID
*/
private Long userId;
/**
* 创建者类型
*/
private Integer userType;
}

View File

@ -0,0 +1,16 @@
package cn.iocoder.yudao.module.trade.dal.mysql.order;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.OrderLogDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 订单日志 Mapper
*
* @author 陈賝
*/
@Mapper
public interface OrderLogMapper extends BaseMapperX<OrderLogDO> {
}

View File

@ -1,9 +1,13 @@
package cn.iocoder.yudao.module.trade.framework.order.config;
import cn.iocoder.yudao.module.trade.framework.aftersalelog.core.aop.AfterSaleLogAspect;
import cn.iocoder.yudao.module.trade.framework.order.core.aop.OrderLogAspect;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// TODO @LeeYan9: 可以直接给 TradeOrderProperties 一个 @Component生效哈
/**
* @author LeeYan9
* @since 2022-09-15
@ -11,4 +15,9 @@ import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(TradeOrderProperties.class)
public class TradeOrderConfig {
@Bean
public OrderLogAspect orderLogAspect() {
return new OrderLogAspect();
}
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.trade.framework.order.core.annotations;
import cn.iocoder.yudao.module.trade.enums.aftersale.OrderOperateTypeEnum;
import java.lang.annotation.*;
/**
* 订单日志AOP注解
*
* @author 陈賝
* @since 2023/7/6 15:37
*/
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OrderLog {
/**
* 日志内容
*/
String content();
/**
* 订单编号
*/
String id();
/**
* 操作类型
*/
OrderOperateTypeEnum operateType();
}

View File

@ -0,0 +1,86 @@
package cn.iocoder.yudao.module.trade.framework.order.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.enums.aftersale.OrderOperateTypeEnum;
import cn.iocoder.yudao.module.trade.framework.order.core.annotations.OrderLog;
import cn.iocoder.yudao.module.trade.framework.order.core.dto.TradeOrderLogCreateReqDTO;
import cn.iocoder.yudao.module.trade.framework.order.core.service.OrderLogService;
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 javax.annotation.Resource;
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 OrderLogAspect {
@Resource
private OrderLogService orderLogService;
@AfterReturning(pointcut = "@annotation(orderLog)", returning = "info")
public void doAfterReturning(JoinPoint joinPoint, OrderLog orderLog, Object info) {
try {
// 日志对象拼接
Integer userType = WebFrameworkUtils.getLoginUserType();
Long id = WebFrameworkUtils.getLoginUserId();
TradeOrderLogCreateReqDTO dto = new TradeOrderLogCreateReqDTO()
.setUserId(id)
.setUserType(userType)
.setOrderId(getAfterSaleId(joinPoint, info, orderLog.id()))
.setOperateType(orderLog.operateType().getType())
.setContent(getContent(joinPoint, info, orderLog));
// 异步存入数据库
orderLogService.createLog(dto);
} catch (Exception exception) {
log.error("[doAfterReturning][orderLog({}) 订单日志错误]", toJsonString(orderLog), exception);
}
}
/**
* 获取描述信息
*/
private static Map<String, Object> spelFormat(JoinPoint joinPoint, Object info) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
OrderLog afterSaleLogPoint = signature.getMethod().getAnnotation(OrderLog.class);
return SpringExpressionUtils.parseExpression(joinPoint, info,
asList(afterSaleLogPoint.id(), afterSaleLogPoint.content()));
}
/**
* 获取订单ID
*/
private static Long getAfterSaleId(JoinPoint joinPoint, Object info, String spel) {
Map<String, Object> spelMap = spelFormat(joinPoint, info);
return MapUtil.getLong(spelMap, spel);
}
/**
* 获取解析后的日志内容
*/
private static String getContent(JoinPoint joinPoint, Object info, OrderLog afterSaleLog) {
Map<String, Object> spelMap = spelFormat(joinPoint, info);
StringBuilder content = new StringBuilder().append(MapUtil.getStr(spelMap, afterSaleLog.content()));
OrderOperateTypeEnum operateTypeEnum = afterSaleLog.operateType();
return ObjectUtil.isNotNull(operateTypeEnum) ?
content.append(operateTypeEnum.getDescription()).toString() : content.toString();
}
}

View File

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

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.trade.framework.order.core.service;
import cn.iocoder.yudao.module.trade.framework.order.core.dto.TradeOrderLogCreateReqDTO;
/**
* 交易下单日志 Service 接口
*
* @author 陈賝
* @since 2023/7/6 15:44
*/
public interface OrderLogService {
/**
* 创建交易下单日志
*
* @param logDTO 日志记录
* @author 陈賝
* @since 2023/7/6 15:45
*/
void createLog(TradeOrderLogCreateReqDTO logDTO);
}

View File

@ -31,16 +31,21 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageRe
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementReqVO;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO;
import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.OrderLogDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
import cn.iocoder.yudao.module.trade.dal.mysql.order.OrderLogMapper;
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper;
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper;
import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
import cn.iocoder.yudao.module.trade.enums.order.*;
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
import cn.iocoder.yudao.module.trade.framework.order.core.dto.TradeOrderLogCreateReqDTO;
import cn.iocoder.yudao.module.trade.framework.order.core.service.OrderLogService;
import cn.iocoder.yudao.module.trade.service.cart.TradeCartService;
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
import cn.iocoder.yudao.module.trade.service.price.TradePriceService;
@ -57,6 +62,7 @@ import java.util.*;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_ORDER_NOT_FOUND;
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
@ -68,11 +74,13 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
*/
@Service
@Slf4j
public class TradeOrderServiceImpl implements TradeOrderService {
public class TradeOrderServiceImpl implements TradeOrderService, OrderLogService {
@Resource
private TradeOrderMapper tradeOrderMapper;
@Resource
private OrderLogMapper orderLogMapper;
@Resource
private TradeOrderItemMapper tradeOrderItemMapper;
@Resource
@ -568,4 +576,25 @@ public class TradeOrderServiceImpl implements TradeOrderService {
TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus()));
}
/**
* 创建交易下单日志
*
* @param logDTO 日志记录
* @author 陈賝
* @since 2023/7/6 15:45
*/
@Override
public void createLog(TradeOrderLogCreateReqDTO logDTO) {
try {
OrderLogDO orderLogDO = new OrderLogDO()
.setUserId(logDTO.getUserId())
.setUserType(logDTO.getUserType())
.setOrderId(logDTO.getOrderId())
.setOperateType(logDTO.getOperateType())
.setContent(logDTO.getContent());
orderLogMapper.insert(orderLogDO);
} catch (Exception exception) {
log.error("[createLog][request({}) 日志记录错误]", toJsonString(logDTO), exception);
}
}
}