Browse Source

Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product

# Conflicts:
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java
jason 1 year ago
parent
commit
ebd4ea548c
11 changed files with 379 additions and 0 deletions
  1. 2 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java
  2. 3 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java
  3. 29 0
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderOperateTypeEnum.java
  4. 7 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
  5. 81 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderLogDO.java
  6. 26 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/annotations/TradeOrderLog.java
  7. 112 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java
  8. 23 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/utils/TradeOrderLogUtils.java
  9. 24 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderLogService.java
  10. 21 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderLogServiceImpl.java
  11. 51 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/logger/TradeOrderLogCreateReqBO.java

+ 2 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.api.combination;
 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO;
 import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService;
 import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 
@@ -12,6 +13,7 @@ import javax.annotation.Resource;
  * @author HUIHUI
  */
 @Service
+@Validated
 public class CombinationApiImpl implements CombinationApi {
 
     @Resource

+ 3 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java

@@ -22,6 +22,7 @@ import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationActivi
 import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationProductMapper;
 import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
 import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
@@ -52,7 +53,9 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
     private CombinationActivityMapper combinationActivityMapper;
     @Resource
     private CombinationProductMapper combinationProductMapper;
+
     @Resource
+    @Lazy // TODO @puhui999:我感觉 validateCombination 可以挪到 CombinationRecordServiceImpl 中,因为它更偏向能不能创建拼团记录;
     private CombinationRecordService combinationRecordService;
 
     @Resource

+ 29 - 0
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderOperateTypeEnum.java

@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.trade.enums.order;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 订单操作类型的枚举
+ *
+ * @author 陈賝
+ * @since 2023/7/6 15:31
+ */
+@RequiredArgsConstructor
+@Getter
+public enum TradeOrderOperateTypeEnum {
+
+    MEMBER_CREATE(1, "用户下单"),
+    TEST(2, "用户({nickname})做了({thing})"),
+    ;
+
+    /**
+     * 类型
+     */
+    private final Integer type;
+    /**
+     * 类型
+     */
+    private final String content;
+
+}

+ 7 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.trade.controller.app.order;
 
+import cn.hutool.core.map.MapUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
@@ -11,8 +12,11 @@ import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
 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.order.TradeOrderOperateTypeEnum;
 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.core.annotations.TradeOrderLog;
+import cn.iocoder.yudao.module.trade.framework.order.core.utils.TradeOrderLogUtils;
 import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
 import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
 import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
@@ -61,7 +65,10 @@ public class AppTradeOrderController {
     @PostMapping("/create")
     @Operation(summary = "创建订单")
     @PreAuthenticated
+    @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.TEST)
     public CommonResult<AppTradeOrderCreateRespVO> createOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO) {
+        TradeOrderLogUtils.setOrderInfo(10L, 1, 2,
+                MapUtil.<String, Object>builder().put("nickname", "小明").put("thing", "种土豆").build());
         TradeOrderDO order = tradeOrderUpdateService.createOrder(getLoginUserId(), getClientIP(), createReqVO);
         return success(new AppTradeOrderCreateRespVO().setId(order.getId()).setPayOrderId(order.getPayOrderId()));
     }

+ 81 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderLogDO.java

@@ -0,0 +1,81 @@
+package cn.iocoder.yudao.module.trade.dal.dataobject.order;
+
+import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.trade.enums.order.TradeOrderOperateTypeEnum;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+/**
+ * 订单日志 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 TradeOrderLogDO extends BaseDO {
+
+    /**
+     * 用户类型 - 系统
+     *
+     * 例如说:Job 自动过期订单时,通过系统自动操作
+     */
+    public static final Integer USER_TYPE_SYSTEM = 0;
+    /**
+     * 用户编号 - 系统
+     */
+    public static final Long USER_ID_SYSTEM = 0L;
+
+    /**
+     * 编号
+     */
+    @TableId
+    private Long id;
+    /**
+     * 用户编号
+     *
+     * 关联 AdminUserDO 的 id 字段、或者 MemberUserDO 的 id 字段
+     */
+    private Long userId;
+    /**
+     * 用户类型
+     *
+     * 枚举 {@link UserTypeEnum}
+     */
+    private Integer userType;
+
+    /**
+     * 订单号
+     *
+     * 关联 {@link TradeOrderDO#getId()}
+     */
+    private Long orderId;
+    /**
+     * 操作前状态
+     */
+    private Integer beforeStatus;
+    /**
+     * 操作后状态
+     */
+    private Integer afterStatus;
+
+    /**
+     * 操作类型
+     *
+     * {@link TradeOrderOperateTypeEnum}
+     */
+    private Integer operateType;
+    /**
+     * 订单日志信息
+     */
+    private String content;
+
+}

+ 26 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/annotations/TradeOrderLog.java

@@ -0,0 +1,26 @@
+package cn.iocoder.yudao.module.trade.framework.order.core.annotations;
+
+import cn.iocoder.yudao.module.trade.enums.order.TradeOrderOperateTypeEnum;
+
+import java.lang.annotation.*;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.METHOD;
+
+/**
+ * 交易订单的操作日志 AOP 注解
+ *
+ * @author 陈賝
+ * @since 2023/7/6 15:37
+ */
+@Target({METHOD, ANNOTATION_TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface TradeOrderLog {
+
+    /**
+     * 操作类型
+     */
+    TradeOrderOperateTypeEnum operateType();
+
+}

+ 112 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java

@@ -0,0 +1,112 @@
+package cn.iocoder.yudao.module.trade.framework.order.core.aop;
+
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
+import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
+import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog;
+import cn.iocoder.yudao.module.trade.service.order.TradeOrderLogService;
+import cn.iocoder.yudao.module.trade.service.order.bo.logger.TradeOrderLogCreateReqBO;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.Map;
+
+import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
+import static java.util.Collections.emptyMap;
+
+/**
+ * 交易订单的操作日志的记录 AOP 切面
+ *
+ * @author 陈賝
+ * @since 2023/6/13 13:54
+ */
+@Component
+@Aspect
+@Slf4j
+public class TradeOrderLogAspect {
+
+    /**
+     * 订单编号
+     */
+    private static final ThreadLocal<Long> ORDER_ID = new ThreadLocal<>();
+    /**
+     * 操作前的状态
+     */
+    private static final ThreadLocal<Integer> BEFORE_STATUS = new ThreadLocal<>();
+    /**
+     * 操作后的状态
+     */
+    private static final ThreadLocal<Integer> AFTER_STATUS = new ThreadLocal<>();
+    /**
+     * 拓展参数 Map,用于格式化操作内容
+     */
+    private static final ThreadLocal<Map<String, Object>> EXTS = new ThreadLocal<>();
+
+    public TradeOrderLogAspect() {
+        System.out.println();
+    }
+
+    @Resource
+    private TradeOrderLogService orderLogService;
+
+    @AfterReturning("@annotation(orderLog)")
+    public void doAfterReturning(JoinPoint joinPoint, TradeOrderLog orderLog) {
+        try {
+            // 1.1 操作用户
+            Integer userType = getUserType();
+            Long userId = getUserId();
+            // 1.2 订单信息
+            Long orderId = ORDER_ID.get();
+            Integer beforeStatus = BEFORE_STATUS.get();
+            Integer afterStatus = AFTER_STATUS.get();
+            Map<String, Object> exts = ObjectUtil.defaultIfNull(EXTS.get(), emptyMap());
+            String content = StrUtil.format(orderLog.operateType().getContent(), exts);
+
+            // 2.1 记录日志
+            TradeOrderLogCreateReqBO createBO = new TradeOrderLogCreateReqBO()
+                    .setUserId(userId).setUserType(userType)
+                    .setOrderId(orderId).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus)
+                    .setOperateType(orderLog.operateType().getType()).setContent(content);
+            orderLogService.createOrderLog(createBO);
+        } catch (Exception ex) {
+            // todo 芋艿:清理上下文
+            log.error("[doAfterReturning][orderLog({}) 订单日志错误]", toJsonString(orderLog), ex);
+        }
+    }
+
+    /**
+     * 获得用户类型
+     *
+     * 如果没有,则约定为 {@link TradeOrderLogDO#getUserType()} 系统
+     *
+     * @return 用户类型
+     */
+    private static Integer getUserType() {
+        return ObjectUtil.defaultIfNull(WebFrameworkUtils.getLoginUserType(), TradeOrderLogDO.USER_TYPE_SYSTEM);
+    }
+
+    /**
+     * 获得用户编号
+     *
+     * 如果没有,则约定为 {@link TradeOrderLogDO#getUserId()} 系统
+     *
+     * @return 用户类型
+     */
+    private static Long getUserId() {
+        return ObjectUtil.defaultIfNull(WebFrameworkUtils.getLoginUserId(), TradeOrderLogDO.USER_ID_SYSTEM);
+    }
+
+    public static void setOrderInfo(Long id, Integer beforeStatus, Integer afterStatus, Map<String, Object> exts) {
+        ORDER_ID.set(id);
+        BEFORE_STATUS.set(beforeStatus);
+        AFTER_STATUS.set(afterStatus);
+        EXTS.set(exts);
+    }
+
+}

+ 23 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/utils/TradeOrderLogUtils.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.trade.framework.order.core.utils;
+
+import cn.iocoder.yudao.module.trade.framework.order.core.aop.TradeOrderLogAspect;
+
+import java.util.Map;
+
+/**
+ * 交易订单的操作日志 Utils
+ *
+ * @author 芋道源码
+ */
+public class TradeOrderLogUtils {
+
+    public static void setOrderInfo(Long id, Integer beforeStatus, Integer afterStatus) {
+        TradeOrderLogAspect.setOrderInfo(id, beforeStatus, afterStatus, null);
+    }
+
+    public static void setOrderInfo(Long id, Integer beforeStatus, Integer afterStatus,
+                                    Map<String, Object> exts) {
+        TradeOrderLogAspect.setOrderInfo(id, beforeStatus, afterStatus, exts);
+    }
+
+}

+ 24 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderLogService.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.trade.service.order;
+
+import cn.iocoder.yudao.module.trade.service.order.bo.logger.TradeOrderLogCreateReqBO;
+import org.springframework.scheduling.annotation.Async;
+
+/**
+ * 交易下单日志 Service 接口
+ *
+ * @author 陈賝
+ * @since 2023/7/6 15:44
+ */
+public interface TradeOrderLogService {
+
+    /**
+     * 创建交易下单日志
+     *
+     * @param logDTO 日志记录
+     * @author 陈賝
+     * @since 2023/7/6 15:45
+     */
+    @Async
+    void createOrderLog(TradeOrderLogCreateReqBO logDTO);
+
+}

+ 21 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderLogServiceImpl.java

@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.module.trade.service.order;
+
+import cn.iocoder.yudao.module.trade.service.order.bo.logger.TradeOrderLogCreateReqBO;
+import org.springframework.stereotype.Service;
+
+/**
+ * 交易下单日志 Service 实现类
+ *
+ * @author 陈賝
+ * @since 2023/7/6 15:44
+ */
+@Service
+public class TradeOrderLogServiceImpl implements TradeOrderLogService {
+
+    @Override
+    public void createOrderLog(TradeOrderLogCreateReqBO createReqBO) {
+        // TODO 芋艿:存储还没搞
+        System.out.println();
+    }
+
+}

+ 51 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/logger/TradeOrderLogCreateReqBO.java

@@ -0,0 +1,51 @@
+package cn.iocoder.yudao.module.trade.service.order.bo.logger;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 订单日志的创建 Request BO
+ *
+ * @author 陈賝
+ * @since 2023/7/6 15:27
+ */
+@Data
+public class TradeOrderLogCreateReqBO {
+
+    /**
+     * 用户编号
+     */
+    @NotNull(message = "用户编号不能为空")
+    private Long userId;
+    /**
+     * 用户类型
+     */
+    @NotNull(message = "用户类型不能为空")
+    private Integer userType;
+
+    /**
+     * 订单编号
+     */
+    @NotNull(message = "订单编号")
+    private Long orderId;
+    /**
+     * 操作前状态
+     */
+    private Integer beforeStatus;
+    /**
+     * 操作后状态
+     */
+    @NotNull(message = "操作后的状态不能为空")
+    private Integer afterStatus;
+
+    /**
+     * 操作类型
+     */
+    private Integer operateType;
+    /**
+     * 操作明细
+     */
+    private String content;
+
+}