Browse Source

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

puhui999 2 years ago
parent
commit
cd4940d710
47 changed files with 719 additions and 184 deletions
  1. 1 0
      yudao-framework/pom.xml
  2. 82 0
      yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spel/SpelUtil.java
  3. 1 1
      yudao-framework/yudao-spring-boot-starter-biz-operatelog/pom.xml
  4. 54 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/pom.xml
  5. 16 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/config/YudaoAfterSaleLogAutoConfiguration.java
  6. 32 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/annotations/AfterSaleLog.java
  7. 73 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/aop/AfterSaleLogAspect.java
  8. 43 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/dto/TradeAfterSaleLogCreateReqDTO.java
  9. 26 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/enums/AfterSaleStatusEnum.java
  10. 18 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/service/AfterSaleLogService.java
  11. 1 0
      yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  12. 3 2
      yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApi.java
  13. 14 21
      yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/dto/ProductCommentCreateReqDTO.java
  14. 4 2
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApiImpl.java
  15. 5 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java
  16. 1 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java
  17. 1 1
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java
  18. 1 1
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java
  19. 2 1
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java
  20. 0 7
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java
  21. 0 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentStatisticsRespVO.java
  22. 11 16
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentCreateReqVO.java
  23. 9 9
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java
  24. 3 3
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java
  25. 1 1
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java
  26. 1 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java
  27. 2 1
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java
  28. 2 2
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java
  29. 2 1
      yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql
  30. 2 2
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java
  31. 64 7
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java
  32. 33 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillConfigController.java
  33. 3 3
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityDetailRespVO.java
  34. 19 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityNowRespVO.java
  35. 28 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityRespVO.java
  36. 18 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/config/AppSeckillConfigRespVO.java
  37. 32 17
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java
  38. 6 0
      yudao-module-mall/yudao-module-trade-biz/pom.xml
  39. 18 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java
  40. 9 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java
  41. 4 5
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
  42. 11 13
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemCommentCreateReqVO.java
  43. 3 3
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
  44. 2 22
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java
  45. 39 9
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java
  46. 3 2
      yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java
  47. 16 22
      yudao-server/pom.xml

+ 1 - 0
yudao-framework/pom.xml

@@ -31,6 +31,7 @@
         <module>yudao-spring-boot-starter-biz-sms</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-social</module>
         <module>yudao-spring-boot-starter-biz-tenant</module>

+ 82 - 0
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spel/SpelUtil.java

@@ -0,0 +1,82 @@
+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 "";
+    }
+}

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-operatelog/pom.xml

@@ -37,7 +37,7 @@
         <!-- 业务组件 -->
         <dependency>
             <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行操作日志的记录 -->
+            <artifactId>yudao-module-system-api</artifactId>
             <version>${revision}</version>
         </dependency>
 

+ 54 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/pom.xml

@@ -0,0 +1,54 @@
+<?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>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-security</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 16 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/config/YudaoAfterSaleLogAutoConfiguration.java

@@ -0,0 +1,16 @@
+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();
+    }
+
+}

+ 32 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/annotations/AfterSaleLog.java

@@ -0,0 +1,32 @@
+package cn.iocoder.yudao.framework.trade.core.annotations;
+
+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();
+
+    // TODO @陈賝:是不是改成一个操作的枚举?
+    /**
+     * 操作类型
+     */
+    String operateType() default "";
+
+    /**
+     * 日志内容
+     */
+    String content() default "";
+
+}

+ 73 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/aop/AfterSaleLogAspect.java

@@ -0,0 +1,73 @@
+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;
+    }
+
+}

+ 43 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/dto/TradeAfterSaleLogCreateReqDTO.java

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

+ 26 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/enums/AfterSaleStatusEnum.java

@@ -0,0 +1,26 @@
+package cn.iocoder.yudao.framework.trade.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;
+    }
+
+}

+ 18 - 0
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/service/AfterSaleLogService.java

@@ -0,0 +1,18 @@
+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
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+cn.iocoder.yudao.framework.trade.config.YudaoAfterSaleLogAutoConfiguration

+ 3 - 2
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApi.java

@@ -1,6 +1,6 @@
 package cn.iocoder.yudao.module.product.api.comment;
 
-import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
+import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
 
 /**
  * 产品评论 API 接口
@@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
  */
 public interface ProductCommentApi {
 
+    // TODO @puhui:Long orderId 放到 createReqDTO 里噶?
     /**
      * 创建评论
      *
@@ -16,6 +17,6 @@ public interface ProductCommentApi {
      * @param orderId      订单 id
      * @return 返回评论创建后的 id
      */
-    Long createComment(CommentCreateReqDTO createReqDTO, Long orderId);
+    Long createComment(ProductCommentCreateReqDTO createReqDTO, Long orderId);
 
 }

+ 14 - 21
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/dto/CommentCreateReqDTO.java → yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/dto/ProductCommentCreateReqDTO.java

@@ -10,71 +10,64 @@ import java.util.List;
  * @author HUIHUI
  */
 @Data
-public class CommentCreateReqDTO {
+public class ProductCommentCreateReqDTO {
 
     /**
-     * 是否匿名
+     * 商品 SKU 编号
      */
-    private Boolean anonymous;
-
+    private Long skuId;
     /**
      * 交易订单项编号
      */
     private Long orderItemId;
 
+    // TODO @huihui:spuId、spuName 去查询哇?通过 skuId
     /**
      * 商品 SPU 编号
      */
     private Long spuId;
-
     /**
      * 商品 SPU 名称
      */
     private String spuName;
 
-    /**
-     * 商品 SKU 编号
-     */
-    private Long skuId;
-
     /**
      * 评分星级 1-5 分
      */
     private Integer scores;
-
     /**
      * 描述星级 1-5 分
      */
     private Integer descriptionScores;
-
     /**
      * 服务星级 1-5 分
      */
     private Integer benefitScores;
-
     /**
      * 评论内容
      */
     private String content;
-
     /**
-     * 评论图片地址数组,以逗号分隔最多上传9张
+     * 评论图片地址数组,以逗号分隔最多上传 9 
      */
     private List<String> picUrls;
 
+    /**
+     * 是否匿名
+     */
+    private Boolean anonymous;
+    /**
+     * 评价人
+     */
+    private Long userId;
+    // TODO @puhui999:是不是 userNickname、userAvatar 去掉?通过 userId 查询
     /**
      * 评价人名称
      */
     private String userNickname;
-
     /**
      * 评价人头像
      */
     private String userAvatar;
 
-    /**
-     * 评价人
-     */
-    private Long userId;
-
 }

+ 4 - 2
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApiImpl.java

@@ -1,6 +1,6 @@
 package cn.iocoder.yudao.module.product.api.comment;
 
-import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
+import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
 import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
 import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
@@ -17,12 +17,14 @@ import javax.annotation.Resource;
 @Service
 @Validated
 public class ProductCommentApiImpl implements ProductCommentApi {
+
     @Resource
     private ProductCommentService productCommentService;
 
     @Override
-    public Long createComment(CommentCreateReqDTO createReqDTO, Long orderId) {
+    public Long createComment(ProductCommentCreateReqDTO createReqDTO, Long orderId) {
         ProductCommentDO commentDO = ProductCommentConvert.INSTANCE.convert(createReqDTO, orderId);
         return productCommentService.createComment(commentDO);
     }
+
 }

+ 5 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java

@@ -30,15 +30,15 @@ public class ProductCommentBaseVO {
     @NotNull(message = "商品 SKU 编号不能为空")
     private Long skuId;
 
-    @Schema(description = "评分星级 1-5分", required = true, example = "5")
+    @Schema(description = "评分星级 1-5 分", required = true, example = "5")
     @NotNull(message = "评分星级不能为空")
     private Integer scores;
 
-    @Schema(description = "描述星级 1-5分", required = true, example = "5")
+    @Schema(description = "描述星级 1-5 分", required = true, example = "5")
     @NotNull(message = "描述星级不能为空")
     private Integer descriptionScores;
 
-    @Schema(description = "服务星级 1-5分", required = true, example = "5")
+    @Schema(description = "服务星级 1-5 分", required = true, example = "5")
     @NotNull(message = "服务星级分不能为空")
     private Integer benefitScores;
 
@@ -46,8 +46,8 @@ public class ProductCommentBaseVO {
     @NotNull(message = "评论内容不能为空")
     private String content;
 
-    @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
-    @Size(max = 9, message = "评论图片地址数组长度不能超过9张")
+    @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
+    @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
     private List<String> picUrls;
 
 }

+ 1 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java

@@ -13,6 +13,7 @@ import javax.validation.constraints.NotNull;
 @ToString(callSuper = true)
 public class ProductCommentCreateReqVO extends ProductCommentBaseVO {
 
+    // TODO @puhui999:是不是也放到父类里?
     @Schema(description = "评价人", required = true, example = "16868")
     @NotNull(message = "评价人不能为空")
     private Long userId;

+ 1 - 1
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java

@@ -31,7 +31,7 @@ public class ProductCommentPageReqVO extends PageParam {
     @Schema(description = "商品SPU名称", example = "感冒药")
     private String spuName;
 
-    @Schema(description = "评分星级 1-5分", example = "5")
+    @Schema(description = "评分星级 1-5 分", example = "5")
     @InEnum(ProductCommentScoresEnum.class)
     private Integer scores;
 

+ 1 - 1
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java

@@ -16,7 +16,7 @@ public class ProductCommentRespVO extends ProductCommentBaseVO {
     @Schema(description = "订单项编号", required = true, example = "24965")
     private Long id;
 
-    @Schema(description = "是否匿名:[false:不匿名 true:匿名]", required = true, example = "false")
+    @Schema(description = "是否匿名", required = true, example = "false")
     private Boolean anonymous;
 
     @Schema(description = "交易订单编号", required = true, example = "24428")

+ 2 - 1
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java

@@ -36,6 +36,7 @@ public class AppProductCommentController {
     @Resource
     private ProductCommentService productCommentService;
 
+    // TODO @puhui999:可以实现下
     @GetMapping("/list")
     @Operation(summary = "获得最近的 n 条商品评价")
     @Parameters({
@@ -44,7 +45,6 @@ public class AppProductCommentController {
     })
     public CommonResult<List<AppProductCommentRespVO>> getCommentList(@RequestParam("spuId") Long spuId,
                                                                       @RequestParam(value = "count", defaultValue = "10") Integer count) {
-
         List<AppProductPropertyValueDetailRespVO> list = new ArrayList<>();
 
         AppProductPropertyValueDetailRespVO item1 = new AppProductPropertyValueDetailRespVO();
@@ -101,6 +101,7 @@ public class AppProductCommentController {
         return success(productCommentService.getCommentPage(pageVO, Boolean.TRUE));
     }
 
+    // TODO @puhui:get-statistics;方法改成 getCommentStatistics;getCommentPageTabsCount 也改掉哈
     @GetMapping("/getCommentStatistics")
     @Operation(summary = "获得商品的评价统计")
     public CommonResult<AppCommentStatisticsRespVO> getCommentPage(@Valid @RequestParam("spuId") Long spuId) {

+ 0 - 7
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java

@@ -8,11 +8,6 @@ import lombok.ToString;
 
 import javax.validation.constraints.NotNull;
 
-/**
- * 用户 APP - 商品评价分页 Request VO
- *
- * @author HUIHUI
- */
 @Schema(description = "用户APP - 商品评价分页 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
@@ -23,12 +18,10 @@ public class AppCommentPageReqVO extends PageParam {
      * 好评
      */
     public static final Integer GOOD_COMMENT = 1;
-
     /**
      * 中评
      */
     public static final Integer MEDIOCRE_COMMENT = 2;
-
     /**
      * 差评
      */

+ 0 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentStatisticsRespVO.java

@@ -4,11 +4,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.ToString;
 
-/**
- * APP 商品评价页评论分类数统计 Response VO
- *
- * @author HUIHUI
- */
 @Schema(description = "APP - 商品评价页评论分类数统计 Response VO")
 @Data
 @ToString(callSuper = true)

+ 11 - 16
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentCreateReqVO.java

@@ -8,11 +8,6 @@ import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Size;
 import java.util.List;
 
-/**
- * 用户APP - 商品评价创建 Request VO
- *
- * @author HUIHUI
- */
 @Schema(description = "用户APP - 商品评价创建 Request VO")
 @Data
 @ToString(callSuper = true)
@@ -26,36 +21,36 @@ public class AppProductCommentCreateReqVO {
     @NotNull(message = "交易订单项编号不能为空")
     private Long orderItemId;
 
-    @Schema(description = "商品SPU编号", required = true, example = "91192")
+    @Schema(description = "商品 SPU 编号", required = true, example = "91192")
     @NotNull(message = "商品SPU编号不能为空")
     private Long spuId;
 
-    @Schema(description = "商品SPU名称", required = true, example = "清凉丝滑小短袖")
+    @Schema(description = "商品 SPU 名称", required = true, example = "清凉丝滑小短袖")
     @NotNull(message = "商品SPU名称不能为空")
     private String spuName;
 
-    @Schema(description = "商品SKU编号", required = true, example = "81192")
+    @Schema(description = "商品 SKU 编号", required = true, example = "81192")
     @NotNull(message = "商品SKU编号不能为空")
     private Long skuId;
 
-    @Schema(description = "评分星级 1-5分", required = true, example = "5")
-    @NotNull(message = "评分星级 1-5分不能为空")
+    @Schema(description = "评分星级 1-5 分", required = true, example = "5")
+    @NotNull(message = "评分星级 1-5 分不能为空")
     private Integer scores;
 
-    @Schema(description = "描述星级 1-5分", required = true, example = "5")
-    @NotNull(message = "描述星级 1-5分不能为空")
+    @Schema(description = "描述星级 1-5 分", required = true, example = "5")
+    @NotNull(message = "描述星级 1-5 分不能为空")
     private Integer descriptionScores;
 
-    @Schema(description = "服务星级 1-5分", required = true, example = "5")
-    @NotNull(message = "服务星级 1-5分不能为空")
+    @Schema(description = "服务星级 1-5 分", required = true, example = "5")
+    @NotNull(message = "服务星级 1-5 分不能为空")
     private Integer benefitScores;
 
     @Schema(description = "评论内容", required = true, example = "哇,真的很丝滑凉快诶,好评")
     @NotNull(message = "评论内容不能为空")
     private String content;
 
-    @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
-    @Size(max = 9, message = "评论图片地址数组长度不能超过9张")
+    @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
+    @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
     private List<String> picUrls;
 
 }

+ 9 - 9
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java

@@ -60,7 +60,7 @@ public class AppProductCommentRespVO {
     @Schema(description = "追加评价内容", example = "穿了很久都很丝滑诶")
     private String additionalContent;
 
-    @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张", example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
+    @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传 9 张", example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
     private List<String> additionalPicUrls;
 
     @Schema(description = "追加评价时间")
@@ -86,24 +86,24 @@ public class AppProductCommentRespVO {
     @Schema(description = "商品 SKU 属性", required = true)
     private List<AppProductPropertyValueDetailRespVO> skuProperties;
 
-    @Schema(description = "评分星级 1-5分", required = true, example = "5")
-    @NotNull(message = "评分星级 1-5分不能为空")
+    @Schema(description = "评分星级 1-5 分", required = true, example = "5")
+    @NotNull(message = "评分星级 1-5 分不能为空")
     private Integer scores;
 
-    @Schema(description = "描述星级 1-5分", required = true, example = "5")
-    @NotNull(message = "描述星级 1-5分不能为空")
+    @Schema(description = "描述星级 1-5 分", required = true, example = "5")
+    @NotNull(message = "描述星级 1-5 分不能为空")
     private Integer descriptionScores;
 
-    @Schema(description = "服务星级 1-5分", required = true, example = "5")
-    @NotNull(message = "服务星级 1-5分不能为空")
+    @Schema(description = "服务星级 1-5 分", required = true, example = "5")
+    @NotNull(message = "服务星级 1-5 分不能为空")
     private Integer benefitScores;
 
     @Schema(description = "评论内容", required = true, example = "哇,真的很丝滑凉快诶,好评")
     @NotNull(message = "评论内容不能为空")
     private String content;
 
-    @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
-    @Size(max = 9, message = "评论图片地址数组长度不能超过9张")
+    @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
+    @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
     private List<String> picUrls;
 
 }

+ 3 - 3
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java

@@ -1,7 +1,7 @@
 package cn.iocoder.yudao.module.product.convert.comment;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
+import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO;
 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
@@ -49,7 +49,7 @@ public interface ProductCommentConvert {
      *
      * @param descriptionScores 描述星级
      * @param benefitScores     服务星级
-     * @return {@link Integer}
+     * @return 综合评分
      */
     @Named("convertScores")
     default Integer convertScores(Integer descriptionScores, Integer benefitScores) {
@@ -61,7 +61,7 @@ public interface ProductCommentConvert {
 
     @Mapping(target = "orderId", source = "orderId")
     @Mapping(target = "scores", expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))")
-    ProductCommentDO convert(CommentCreateReqDTO createReqDTO, Long orderId);
+    ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO, Long orderId);
 
     @Mapping(target = "userId", constant = "0L")
     @Mapping(target = "orderId", constant = "0L")

+ 1 - 1
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java

@@ -97,7 +97,7 @@ public class ProductCommentDO extends BaseDO {
     /**
      * 评分星级
      *
-     * 1-5分
+     * 1-5 
      */
     private Integer scores;
     /**

+ 1 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java

@@ -25,6 +25,7 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
     }
 
     // TODO 芋艿:在看看这块
+    // TODO @puhui999:直接使用 scores 来算好评、中评、差评
     static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) {
         // 构建好评查询语句:好评计算 (商品评分星级+服务评分星级) >= 8
         if (ObjectUtil.equal(type, AppCommentPageReqVO.GOOD_COMMENT)) {

+ 2 - 1
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java

@@ -54,7 +54,8 @@ public interface ProductCommentService {
     PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
 
     /**
-     * 创建商品评论 后台管理员创建评论使用
+     * 创建商品评论
+     * 后台管理员创建评论使用
      *
      * @param createReqVO 商品评价创建 Request VO 对象
      */

+ 2 - 2
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java

@@ -86,6 +86,7 @@ public class ProductCommentServiceImpl implements ProductCommentService {
     @Transactional(rollbackFor = Exception.class)
     public void createComment(ProductCommentCreateReqVO createReqVO) {
         // 校验订单
+        // TODO @puhui999:不校验哈;尽可能解耦
         Long orderId = tradeOrderApi.validateOrder(createReqVO.getUserId(), createReqVO.getOrderItemId());
         // 校验评论
         validateComment(createReqVO.getSpuId(), createReqVO.getUserId(), orderId);
@@ -104,8 +105,6 @@ public class ProductCommentServiceImpl implements ProductCommentService {
         return commentDO.getId();
     }
 
-    // TODO 只有创建和更新诶 要不要删除接口
-
     private void validateComment(Long spuId, Long userId, Long orderId) {
         ProductSpuDO spu = productSpuService.getSpu(spuId);
         if (null == spu) {
@@ -144,6 +143,7 @@ public class ProductCommentServiceImpl implements ProductCommentService {
     public PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
         PageResult<AppProductCommentRespVO> result = ProductCommentConvert.INSTANCE.convertPage02(
                 productCommentMapper.selectPage(pageVO, visible));
+        // TODO @puhui999:要不这块放到 controller 里拼接?
         Set<Long> skuIds = result.getList().stream().map(AppProductCommentRespVO::getSkuId).collect(Collectors.toSet());
         List<ProductSkuDO> skuList = productSkuService.getSkuList(skuIds);
         Map<Long, ProductSkuDO> skuDOMap = new HashMap<>(skuIds.size());

+ 2 - 1
yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql

@@ -126,6 +126,7 @@ CREATE TABLE IF NOT EXISTS `product_property_value` (
     PRIMARY KEY("id")
 ) COMMENT '规格值';
 
+-- TODO @puhui999:格式不太对哈
 CREATE TABLE IF NOT EXISTS `product_comment`
 (
     `id`
@@ -166,7 +167,7 @@ CREATE TABLE IF NOT EXISTS `product_comment`
 (
     1
 ) DEFAULT NULL COMMENT '是否可见true:显示false:隐藏',
-    `scores` tinyint DEFAULT NULL COMMENT '评分星级1-5分',
+    `scores` tinyint DEFAULT NULL COMMENT '评分星级1-5 分',
     `description_scores` tinyint DEFAULT NULL COMMENT '描述星级1-5 星',
     `benefit_scores` tinyint DEFAULT NULL COMMENT '服务星级1-5 星',
     `content` varchar

+ 2 - 2
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationActivityController.java

@@ -38,7 +38,7 @@ public class AppCombinationActivityController {
         activity1.setName("618 大拼团");
         activity1.setUserSize(3);
         activity1.setSpuId(2048L);
-        activity1.setPicUrl("商品图片地址");
+        activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");
         activity1.setMarketPrice(50);
         activity1.setCombinationPrice(100);
         activityList.add(activity1);
@@ -48,7 +48,7 @@ public class AppCombinationActivityController {
         activity2.setName("双十一拼团");
         activity2.setUserSize(5);
         activity2.setSpuId(4096L);
-        activity2.setPicUrl("商品图片地址");
+        activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132");
         activity2.setMarketPrice(100);
         activity2.setCombinationPrice(200);
         activityList.add(activity2);

+ 64 - 7
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java

@@ -1,7 +1,11 @@
 package cn.iocoder.yudao.module.promotion.controller.app.seckill;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.AppSeckillActivitiDetailRespVO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO;
+import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO;
+import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO;
+import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -23,12 +27,65 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 @Validated
 public class AppSeckillActivityController {
 
+    @GetMapping("/get-now")
+    @Operation(summary = "获得当前秒杀活动") // 提供给首页使用
+    // TODO 芋艿:需要增加 spring cache
+    public CommonResult<AppSeckillActivityNowRespVO> getNowSeckillActivity() {
+        AppSeckillActivityNowRespVO respVO = new AppSeckillActivityNowRespVO();
+        respVO.setConfig(new AppSeckillConfigRespVO().setId(10L).setStartTime("01:00").setEndTime("09:59"));
+        List<AppSeckillActivityRespVO> activityList = new ArrayList<>();
+        AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO();
+        activity1.setId(1L);
+        activity1.setName("618 大秒杀");
+        activity1.setSpuId(2048L);
+        activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");
+        activity1.setMarketPrice(50);
+        activity1.setSeckillPrice(100);
+        activityList.add(activity1);
+
+        AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO();
+        activity2.setId(2L);
+        activity2.setName("双十一大秒杀");
+        activity2.setSpuId(4096L);
+        activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132");
+        activity2.setMarketPrice(100);
+        activity2.setSeckillPrice(200);
+        activityList.add(activity2);
+        respVO.setActivities(activityList);
+        return success(respVO);
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得秒杀活动分页")
+    // TODO @芋艿:分页参数
+    public CommonResult<PageResult<AppSeckillActivityRespVO>> getSeckillActivityPage() {
+        List<AppSeckillActivityRespVO> activityList = new ArrayList<>();
+        AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO();
+        activity1.setId(1L);
+        activity1.setName("618 大秒杀");
+        activity1.setSpuId(2048L);
+        activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");
+        activity1.setMarketPrice(50);
+        activity1.setSeckillPrice(100);
+        activityList.add(activity1);
+
+        AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO();
+        activity2.setId(2L);
+        activity2.setName("双十一大秒杀");
+        activity2.setSpuId(4096L);
+        activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132");
+        activity2.setMarketPrice(100);
+        activity2.setSeckillPrice(200);
+        activityList.add(activity2);
+        return success(new PageResult<>(activityList, 100L));
+    }
+
     @GetMapping("/get-detail")
     @Operation(summary = "获得秒杀活动明细")
     @Parameter(name = "id", description = "活动编号", required = true, example = "1024")
-    public CommonResult<AppSeckillActivitiDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) {
+    public CommonResult<AppSeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) {
         // TODO 芋艿:如果禁用的时候,需要抛出异常;
-        AppSeckillActivitiDetailRespVO obj = new AppSeckillActivitiDetailRespVO();
+        AppSeckillActivityDetailRespVO obj = new AppSeckillActivityDetailRespVO();
         // 设置其属性的值
         obj.setId(id);
         obj.setName("晚九点限时秒杀");
@@ -37,9 +94,9 @@ public class AppSeckillActivityController {
         obj.setEndTime(LocalDateTime.of(2023, 6, 11, 23, 59, 0));
         obj.setSpuId(633L);
         // 创建一个Product对象的列表
-        List<AppSeckillActivitiDetailRespVO.Product> productList = new ArrayList<>();
+        List<AppSeckillActivityDetailRespVO.Product> productList = new ArrayList<>();
         // 创建三个新的Product对象并设置其属性的值
-        AppSeckillActivitiDetailRespVO.Product product1 = new AppSeckillActivitiDetailRespVO.Product();
+        AppSeckillActivityDetailRespVO.Product product1 = new AppSeckillActivityDetailRespVO.Product();
         product1.setSkuId(1L);
         product1.setSeckillPrice(100);
         product1.setQuota(50);
@@ -47,7 +104,7 @@ public class AppSeckillActivityController {
         // 将第一个Product对象添加到列表中
         productList.add(product1);
         // 创建第二个Product对象并设置其属性的值
-        AppSeckillActivitiDetailRespVO.Product product2 = new AppSeckillActivitiDetailRespVO.Product();
+        AppSeckillActivityDetailRespVO.Product product2 = new AppSeckillActivityDetailRespVO.Product();
         product2.setSkuId(2L);
         product2.setSeckillPrice(200);
         product2.setQuota(100);
@@ -55,7 +112,7 @@ public class AppSeckillActivityController {
         // 将第二个Product对象添加到列表中
         productList.add(product2);
         // 创建第三个Product对象并设置其属性的值
-        AppSeckillActivitiDetailRespVO.Product product3 = new AppSeckillActivitiDetailRespVO.Product();
+        AppSeckillActivityDetailRespVO.Product product3 = new AppSeckillActivityDetailRespVO.Product();
         product3.setSkuId(3L);
         product3.setSeckillPrice(300);
         product3.setQuota(150);

+ 33 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillConfigController.java

@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.promotion.controller.app.seckill;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "用户 App - 秒杀时间段")
+@RestController
+@RequestMapping("/promotion/seckill-config")
+@Validated
+public class AppSeckillConfigController {
+
+    @GetMapping("/list")
+    @Operation(summary = "获得秒杀时间段列表")
+    public CommonResult<List<AppSeckillConfigRespVO>> getConfigList() {
+        return success(Arrays.asList(
+                new AppSeckillConfigRespVO().setId(1L).setStartTime("00:00").setEndTime("09:59"),
+                new AppSeckillConfigRespVO().setId(2L).setStartTime("10:00").setEndTime("12:59"),
+                new AppSeckillConfigRespVO().setId(2L).setStartTime("13:00").setEndTime("23:59")
+        ));
+    }
+
+}

+ 3 - 3
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java → yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityDetailRespVO.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo;
+package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
@@ -6,9 +6,9 @@ import lombok.Data;
 import java.time.LocalDateTime;
 import java.util.List;
 
-@Schema(description = "用户 App - 秒杀活动 Response VO")
+@Schema(description = "用户 App - 秒杀活动的详细 Response VO")
 @Data
-public class AppSeckillActivitiDetailRespVO {
+public class AppSeckillActivityDetailRespVO {
 
     @Schema(description = "秒杀活动编号", required = true, example = "1024")
     private Long id;

+ 19 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityNowRespVO.java

@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity;
+
+import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+@Schema(description = "用户 App - 当前秒杀活动 Response VO")
+@Data
+public class AppSeckillActivityNowRespVO {
+
+    @Schema(description = "秒杀时间段", required = true)
+    private AppSeckillConfigRespVO config;
+
+    @Schema(description = "秒杀活动数组", required = true)
+    private List<AppSeckillActivityRespVO> activities;
+
+}

+ 28 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityRespVO.java

@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "用户 App - 秒杀活动 Response VO")
+@Data
+public class AppSeckillActivityRespVO {
+
+    @Schema(description = "秒杀活动编号", required = true, example = "1024")
+    private Long id;
+
+    @Schema(description = "秒杀活动名称", required = true, example = "晚九点限时秒杀")
+    private String name;
+
+    @Schema(description = "商品 SPU 编号", required = true, example = "2048")
+    private Long spuId;
+
+    @Schema(description = "商品图片", required = true, example = "4096") // 从 SPU 的 picUrl 读取
+    private String picUrl;
+
+    @Schema(description = "商品市场价,单位:分", required = true, example = "50") // 从 SPU 的 marketPrice 读取
+    private Integer marketPrice;
+
+    @Schema(description = "秒杀金额,单位:分", required = true, example = "100") // 从秒杀商品里取最低价
+    private Integer seckillPrice;
+
+}

+ 18 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/config/AppSeckillConfigRespVO.java

@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "用户 App - 秒杀时间段 Response VO")
+@Data
+public class AppSeckillConfigRespVO {
+
+    @Schema(description = "秒杀时间段编号", required = true, example = "1024")
+    private Long id;
+
+    @Schema(description = "开始时间点", required = true, example = "09:00")
+    private String startTime;
+    @Schema(description = "结束时间点", required = true, example = "09:59")
+    private String endTime;
+
+}

+ 32 - 17
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java

@@ -19,23 +19,38 @@ import static cn.hutool.core.util.ArrayUtil.firstMatch;
 @Getter
 public enum TradeAfterSaleStatusEnum implements IntArrayValuable {
 
-    APPLY(10,"申请中", // 【申请售后】
-            "会员申请退款"),
-    SELLER_AGREE(20, "卖家通过", // 卖家通过售后;【商品待退货】
-            "商家同意退款"),
-    BUYER_DELIVERY(30,"待卖家收货", // 买家已退货,等待卖家收货;【商家待收货】
-            "会员填写退货物流信息"),
-    WAIT_REFUND(40, "等待平台退款", // 卖家已收货,等待平台退款;等待退款【等待退款】
-            "商家收货"),
-    COMPLETE(50, "完成", // 完成退款【退款成功】
-            "商家确认退款"),
-
-    BUYER_CANCEL(61, "买家取消售后", // 【买家取消】
-            "会员取消退款"),
-    SELLER_DISAGREE(62,"卖家拒绝", // 卖家拒绝售后;商家拒绝【商家拒绝】
-            "商家拒绝退款"),
-    SELLER_REFUSE(63,"卖家拒绝收货", // 卖家拒绝收货,终止售后;【商家拒收货】
-            "商家拒绝收货"),
+    /**
+     * 【申请售后】
+     */
+    APPLY(10,"申请中", "会员申请退款"),
+    /**
+     * 卖家通过售后;【商品待退货】
+     */
+    SELLER_AGREE(20, "卖家通过", "商家同意退款"),
+    /**
+     * 买家已退货,等待卖家收货;【商家待收货】
+     */
+    BUYER_DELIVERY(30,"待卖家收货", "会员填写退货物流信息"),
+    /**
+     * 卖家已收货,等待平台退款;等待退款【等待退款】
+     */
+    WAIT_REFUND(40, "等待平台退款", "商家收货"),
+    /**
+     * 完成退款【退款成功】
+     */
+    COMPLETE(50, "完成", "商家确认退款"),
+    /**
+     * 【买家取消】
+     */
+    BUYER_CANCEL(61, "买家取消售后", "会员取消退款"),
+    /**
+     * 卖家拒绝售后;商家拒绝【商家拒绝】
+     */
+    SELLER_DISAGREE(62,"卖家拒绝", "商家拒绝退款"),
+    /**
+     * 卖家拒绝收货,终止售后;【商家拒收货】
+     */
+    SELLER_REFUSE(63,"卖家拒绝收货", "商家拒绝收货"),
     ;
 
     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleStatusEnum::getStatus).toArray();

+ 6 - 0
yudao-module-mall/yudao-module-trade-biz/pom.xml

@@ -58,6 +58,11 @@
             <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>
+            <version>${revision}</version>
+        </dependency>
 
         <!-- Web 相关 -->
         <dependency>
@@ -93,6 +98,7 @@
             <groupId>cn.iocoder.boot</groupId>
             <artifactId>yudao-spring-boot-starter-excel</artifactId>
         </dependency>
+
     </dependencies>
 
 </project>

+ 18 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java

@@ -3,6 +3,7 @@ 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;
@@ -11,6 +12,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSal
 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO;
 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO;
 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO;
+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.service.aftersale.TradeAfterSaleService;
@@ -110,4 +112,20 @@ public class TradeAfterSaleController {
         return success(true);
     }
 
+    // TODO @陈賝:后续要删除下
+    /**
+     * 售后日志测试
+     *
+     * @param createReqVO
+     * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<java.lang.Long>
+     * @author 陈賝
+     * @date 2023/6/14 21:39
+     */
+    @PostMapping(value = "/create")
+    @AfterSaleLog(id = "#createReqVO.orderItemId", content = "'申请售后:售后编号['+#createReqVO.orderItemId+'] , '", operateType = "#createReqVO.operateType")
+    public CommonResult<Long> createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) {
+        return success(1L);
+//        return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO));
+    }
+
 }

+ 9 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java

@@ -1,6 +1,7 @@
 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;
@@ -31,6 +32,14 @@ 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;
 

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

@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.controller.app.order;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
 import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
 import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
@@ -49,12 +48,11 @@ public class AppTradeOrderController {
 
     @Resource
     private ProductPropertyValueApi productPropertyValueApi;
-
     @Resource
-    private TradeOrderProperties tradeOrderProperties;
+    private ProductCommentApi productCommentApi;
 
     @Resource
-    private ProductCommentApi productCommentApi;
+    private TradeOrderProperties tradeOrderProperties;
 
     @GetMapping("/settlement")
     @Operation(summary = "获得订单结算信息")
@@ -141,6 +139,7 @@ public class AppTradeOrderController {
     @Operation(summary = "创建交易订单项的评价")
     public CommonResult<Long> createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) {
         // 校验订单项,订单项存在订单就存在
+        // TODO @puhui999:要去查询订单是不是自己的;不然别人模拟请求哈;
         TradeOrderItemDO item = tradeOrderService.getOrderItem(createReqVO.getUserId(), createReqVO.getOrderItemId());
         if (item == null) {
             throw exception(ORDER_ITEM_NOT_FOUND);
@@ -149,6 +148,6 @@ public class AppTradeOrderController {
         return success(productCommentApi.createComment(TradeOrderConvert.INSTANCE.convert04(createReqVO), item.getOrderId()));
     }
 
-    // TODO 合并代码后发现只有商家回复功能 用户追评不要了吗?
+    // TODO 合并代码后发现只有商家回复功能 用户追评不要了吗?不要了哈;
 
 }

+ 11 - 13
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemCommentCreateReqVO.java

@@ -7,11 +7,6 @@ import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Size;
 import java.util.List;
 
-/**
- * 商品评价创建 Request VO
- *
- * @author HUIHUI
- */
 @Schema(description = "用户APP - 商品评价创建 Request VO")
 @Data
 public class AppTradeOrderItemCommentCreateReqVO {
@@ -24,6 +19,7 @@ public class AppTradeOrderItemCommentCreateReqVO {
     @NotNull(message = "交易订单项编号不能为空")
     private Long orderItemId;
 
+    // TODO @puhui:spuId、spuName、skuId 直接查询出来;
     @Schema(description = "商品SPU编号", required = true, example = "29502")
     @NotNull(message = "商品SPU编号不能为空")
     private Long spuId;
@@ -36,30 +32,32 @@ public class AppTradeOrderItemCommentCreateReqVO {
     @NotNull(message = "商品SKU编号不能为空")
     private Long skuId;
 
-    @Schema(description = "评分星级 1-5分", required = true, example = "5")
-    @NotNull(message = "评分星级 1-5分不能为空")
+    @Schema(description = "评分星级 1-5 分", required = true, example = "5")
+    @NotNull(message = "评分星级 1-5 分不能为空")
     private Integer scores;
 
-    @Schema(description = "描述星级 1-5分", required = true, example = "5")
-    @NotNull(message = "描述星级 1-5分不能为空")
+    @Schema(description = "描述星级 1-5 分", required = true, example = "5")
+    @NotNull(message = "描述星级 1-5 分不能为空")
     private Integer descriptionScores;
 
-    @Schema(description = "服务星级 1-5分", required = true, example = "5")
-    @NotNull(message = "服务星级 1-5分不能为空")
+    @Schema(description = "服务星级 1-5 分", required = true, example = "5")
+    @NotNull(message = "服务星级 1-5 分不能为空")
     private Integer benefitScores;
 
     @Schema(description = "评论内容", required = true, example = "穿身上很漂亮诶(*^▽^*)")
     @NotNull(message = "评论内容不能为空")
     private String content;
 
-    @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xx.png]")
-    @Size(max = 9, message = "评论图片地址数组长度不能超过9张")
+    @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xx.png]")
+    @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
     private List<String> picUrls;
 
     @Schema(description = "评价人名称", required = true, example = "小姑凉")
     @NotNull(message = "评价人名称不能为空")
     private String userNickname;
 
+    // TODO @puhui:userAvatar、userAvatar、userId 直接查询出来;
+
     @Schema(description = "评价人头像", required = true, example = "https://www.iocoder.cn/xx.png")
     @NotNull(message = "评价人头像不能为空")
     private String userAvatar;

+ 3 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java

@@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
-import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
+import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
 import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO;
@@ -227,6 +227,7 @@ public interface TradeOrderConvert {
 
     AppProductPropertyValueDetailRespVO convert02(ProductPropertyValueDetailRespDTO bean);
 
+    // TODO 芋艿:可简化
     default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
                                                 List<ProductPropertyValueDetailRespDTO> propertyValueDetails, TradeOrderProperties tradeOrderProperties) {
         AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems);
@@ -258,7 +259,7 @@ public interface TradeOrderConvert {
 
     AppTradeOrderItemRespVO convert03(TradeOrderItemDO bean);
 
-    CommentCreateReqDTO convert04(AppTradeOrderItemCommentCreateReqVO createReqVO);
+    ProductCommentCreateReqDTO convert04(AppTradeOrderItemCommentCreateReqVO createReqVO);
 
     default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO,
                                              List<TradeCartDO> cartList) {
@@ -302,5 +303,4 @@ public interface TradeOrderConvert {
 
     AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, AddressRespDTO address);
 
-
 }

+ 2 - 22
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java

@@ -52,29 +52,9 @@ public class TradeAfterSaleLogDO extends BaseDO {
      */
     private Long afterSaleId;
     /**
-     * 订单编号
-     *
-     * 关联 {@link TradeOrderDO#getId()}
-     */
-    private Long orderId;
-    /**
-     * 订单项编号
-     *
-     * 关联 {@link TradeOrderItemDO#getId()}
-     */
-    private Long orderItemId;
-    /**
-     * 售后状态(之前)
-     *
-     * 枚举 {@link TradeAfterSaleStatusEnum}
-     */
-    private Integer beforeStatus;
-    /**
-     * 售后状态(之后)
-     *
-     * 枚举 {@link TradeAfterSaleStatusEnum}
+     * 操作类型 {@link TradeAfterSaleStatusEnum}
      */
-    private Integer afterStatus;
+    private String operateType;
     /**
      * 操作明细
      */

+ 39 - 9
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java

@@ -5,6 +5,8 @@ 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 +28,8 @@ import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEn
 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.service.order.TradeOrderService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.TransactionSynchronization;
@@ -43,9 +47,10 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
  *
  * @author 芋道源码
  */
+@Slf4j
 @Service
 @Validated
-public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
+public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSaleLogService {
 
     @Resource
     private TradeOrderService tradeOrderService;
@@ -80,7 +85,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
     /**
      * 校验交易订单项是否可以申请售后
      *
-     * @param userId 用户编号
+     * @param userId      用户编号
      * @param createReqVO 售后创建信息
      * @return 交易订单项
      */
@@ -117,7 +122,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
         }
         // 如果是【退货退款】的情况,需要额外校验是否发货
         if (createReqVO.getWay().equals(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
-            && !TradeOrderStatusEnum.haveDelivered(order.getStatus())) {
+                && !TradeOrderStatusEnum.haveDelivered(order.getStatus())) {
             throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED);
         }
         return orderItem;
@@ -133,7 +138,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
         TradeOrderDO order = tradeOrderService.getOrder(orderItem.getUserId(), orderItem.getOrderId());
         afterSale.setOrderNo(order.getNo()); // 记录 orderNo 订单流水,方便后续检索
         afterSale.setType(TradeOrderStatusEnum.isCompleted(order.getStatus())
-            ? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType());
+                ? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType());
         // TODO 退还积分
         tradeAfterSaleMapper.insert(afterSale);
 
@@ -380,13 +385,38 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
                 TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null);
     }
 
+    @Deprecated
     private void createAfterSaleLog(Long userId, Integer userType, TradeAfterSaleDO afterSale,
                                     Integer beforeStatus, Integer afterStatus) {
-        TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO().setUserId(userId).setUserType(userType)
-                .setAfterSaleId(afterSale.getId()).setOrderId(afterSale.getOrderId())
-                .setOrderItemId(afterSale.getOrderItemId()).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus)
-                .setContent(TradeAfterSaleStatusEnum.valueOf(afterStatus).getContent());
-        tradeAfterSaleLogMapper.insert(afterSaleLog);
+        TradeAfterSaleLogCreateReqDTO logDTO = new TradeAfterSaleLogCreateReqDTO()
+                .setUserId(userId)
+                .setUserType(userType)
+                .setAfterSaleId(afterSale.getId())
+                .setOperateType(afterStatus.toString());
+        // TODO 废弃,待删除
+        this.insert(logDTO);
     }
 
+    /**
+     * 日志记录
+     *
+     * @param logDTO 日志记录
+     * @author 陈賝
+     * @date 2023/6/12 14:18
+     */
+    @Override
+    @Async
+    public void insert(TradeAfterSaleLogCreateReqDTO logDTO) {
+        try {
+            TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO()
+                    .setUserId(logDTO.getUserId())
+                    .setUserType(logDTO.getUserType())
+                    .setAfterSaleId(logDTO.getAfterSaleId())
+                    .setOperateType(logDTO.getOperateType())
+                    .setContent(logDTO.getContent());
+            tradeAfterSaleLogMapper.insert(afterSaleLog);
+        }catch (Exception exception){
+            log.error("日志记录错误", exception);
+        }
+    }
 }

+ 3 - 2
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java

@@ -66,6 +66,7 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
         AppTradeAfterSaleCreateReqVO createReqVO = new AppTradeAfterSaleCreateReqVO()
                 .setOrderItemId(1L).setRefundPrice(100).setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
                 .setApplyReason("退钱").setApplyDescription("快退")
+                .setOperateType("APPLY")
                 .setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png"));
         // mock 方法(交易订单项)
         TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> {
@@ -102,8 +103,8 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
         assertEquals(afterSaleLog.getUserType(), UserTypeEnum.MEMBER.getValue());
         assertEquals(afterSaleLog.getAfterSaleId(), afterSaleId);
         assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime");
-        assertNull(afterSaleLog.getBeforeStatus());
-        assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus());
+//        assertNull(afterSaleLog.getBeforeStatus());
+//        assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus());
         assertEquals(afterSaleLog.getContent(), TradeAfterSaleStatusEnum.APPLY.getContent());
     }
 

+ 16 - 22
yudao-server/pom.xml

@@ -54,11 +54,11 @@
 <!--            <version>${revision}</version>-->
 <!--        </dependency>-->
         <!-- 支付服务 -->
-<!--        <dependency>-->
-<!--            <groupId>cn.iocoder.boot</groupId>-->
-<!--            <artifactId>yudao-module-pay-biz</artifactId>-->
-<!--            <version>${revision}</version>-->
-<!--        </dependency>-->
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-pay-biz</artifactId>
+            <version>${revision}</version>
+        </dependency>
 
         <!-- 微信公众号模块。默认注释,保证编译速度 -->
 <!--        <dependency>-->
@@ -68,25 +68,19 @@
 <!--        </dependency>-->
 
         <!-- 商城相关模块。默认注释,保证编译速度 -->
-<!--        <dependency>-->
-<!--            <groupId>cn.iocoder.boot</groupId>-->
-<!--            <artifactId>yudao-module-promotion-biz</artifactId>-->
-<!--            <version>${revision}</version>-->
-<!--        </dependency>-->
-<!--        <dependency>-->
-<!--            <groupId>cn.iocoder.boot</groupId>-->
-<!--            <artifactId>yudao-module-product-biz</artifactId>-->
-<!--            <version>${revision}</version>-->
-<!--        </dependency>-->
-<!--        <dependency>-->
-<!--            <groupId>cn.iocoder.boot</groupId>-->
-<!--            <artifactId>yudao-module-trade-biz</artifactId>-->
-<!--            <version>${revision}</version>-->
-<!--        </dependency>-->
-
         <dependency>
             <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-point-biz</artifactId>
+            <artifactId>yudao-module-promotion-biz</artifactId>
+            <version>${revision}</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-product-biz</artifactId>
+            <version>${revision}</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-trade-biz</artifactId>
             <version>${revision}</version>
         </dependency>