From 284506b3561205a8bb68631a464c3c2adb59a985 Mon Sep 17 00:00:00 2001
From: chenchen <934298133@qq.com>
Date: Fri, 7 Jul 2023 14:06:32 +0800
Subject: [PATCH] =?UTF-8?q?mall=20=E4=B8=8B=E5=8D=95=E6=97=A5=E5=BF=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../enums/aftersale/OrderOperateTypeEnum.java | 30 +++++++
 .../app/order/AppTradeOrderController.java    |  5 ++
 .../dal/dataobject/order/OrderLogDO.java      | 51 +++++++++++
 .../trade/dal/mysql/order/OrderLogMapper.java | 16 ++++
 .../order/config/TradeOrderConfig.java        |  9 ++
 .../order/core/annotations/OrderLog.java      | 33 +++++++
 .../order/core/aop/OrderLogAspect.java        | 86 +++++++++++++++++++
 .../core/dto/TradeOrderLogCreateReqDTO.java   | 46 ++++++++++
 .../order/core/service/OrderLogService.java   | 22 +++++
 .../service/order/TradeOrderServiceImpl.java  | 31 ++++++-
 10 files changed, 328 insertions(+), 1 deletion(-)
 create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/OrderOperateTypeEnum.java
 create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/OrderLogDO.java
 create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/OrderLogMapper.java
 create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/annotations/OrderLog.java
 create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/OrderLogAspect.java
 create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/dto/TradeOrderLogCreateReqDTO.java
 create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/service/OrderLogService.java

diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/OrderOperateTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/OrderOperateTypeEnum.java
new file mode 100644
index 000000000..04b137f8a
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/OrderOperateTypeEnum.java
@@ -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;
+    }
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
index 6567e3169..2428922e0 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
@@ -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()));
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/OrderLogDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/OrderLogDO.java
new file mode 100644
index 000000000..c65acfe06
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/OrderLogDO.java
@@ -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") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 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;
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/OrderLogMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/OrderLogMapper.java
new file mode 100644
index 000000000..868a962d5
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/OrderLogMapper.java
@@ -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> {
+
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderConfig.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderConfig.java
index 715169275..86466fa92 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderConfig.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderConfig.java
@@ -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();
+    }
 }
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/annotations/OrderLog.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/annotations/OrderLog.java
new file mode 100644
index 000000000..994a6a368
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/annotations/OrderLog.java
@@ -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();
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/OrderLogAspect.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/OrderLogAspect.java
new file mode 100644
index 000000000..460649c43
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/OrderLogAspect.java
@@ -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();
+    }
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/dto/TradeOrderLogCreateReqDTO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/dto/TradeOrderLogCreateReqDTO.java
new file mode 100644
index 000000000..81d87711f
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/dto/TradeOrderLogCreateReqDTO.java
@@ -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>
+     * 关联 1:AdminUserDO 的 id 字段
+     * 关联 2:MemberUserDO 的 id 字段
+     */
+    private Long userId;
+    /**
+     * 用户类型
+     */
+    private Integer userType;
+    /**
+     * 订单编号
+     */
+    private Long orderId;
+    /**
+     * 操作类型
+     */
+    private Integer operateType;
+    /**
+     * 操作明细
+     */
+    private String content;
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/service/OrderLogService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/service/OrderLogService.java
new file mode 100644
index 000000000..0b7541ee6
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/service/OrderLogService.java
@@ -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);
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
index d06987ba6..f79732891 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
@@ -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);
+        }
+    }
 }