Commit cd4940d71090955f5cd88cada7cf121b93b7e472

Authored by puhui999
2 parents 1871a019 a93acd2a

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

Showing 47 changed files with 719 additions and 184 deletions
yudao-framework/pom.xml
@@ -31,6 +31,7 @@ @@ -31,6 +31,7 @@
31 <module>yudao-spring-boot-starter-biz-sms</module> 31 <module>yudao-spring-boot-starter-biz-sms</module>
32 32
33 <module>yudao-spring-boot-starter-biz-pay</module> 33 <module>yudao-spring-boot-starter-biz-pay</module>
  34 + <module>yudao-spring-boot-starter-biz-trade</module>
34 <module>yudao-spring-boot-starter-biz-weixin</module> 35 <module>yudao-spring-boot-starter-biz-weixin</module>
35 <module>yudao-spring-boot-starter-biz-social</module> 36 <module>yudao-spring-boot-starter-biz-social</module>
36 <module>yudao-spring-boot-starter-biz-tenant</module> 37 <module>yudao-spring-boot-starter-biz-tenant</module>
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/spel/SpelUtil.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.common.util.spel;
  2 +
  3 +import org.aspectj.lang.JoinPoint;
  4 +import org.aspectj.lang.reflect.MethodSignature;
  5 +import org.springframework.core.DefaultParameterNameDiscoverer;
  6 +import org.springframework.expression.EvaluationContext;
  7 +import org.springframework.expression.spel.standard.SpelExpressionParser;
  8 +import org.springframework.expression.spel.support.StandardEvaluationContext;
  9 +
  10 +// TODO @Chopper:和 SpringExpressionUtils 合并下
  11 +/**
  12 + * SpelUtil
  13 + *
  14 + * @author Chopper
  15 + * @version v1.0
  16 + * @since 2021-01-11 10:45
  17 + */
  18 +public class SpelUtil {
  19 +
  20 +
  21 + /**
  22 + * spel表达式解析器
  23 + */
  24 + private static SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
  25 + /**
  26 + * 参数名发现器
  27 + */
  28 + private static DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
  29 +
  30 + /**
  31 + * 转换 jspl参数
  32 + *
  33 + * @param joinPoint
  34 + * @param spel
  35 + * @return
  36 + */
  37 + public static String compileParams(JoinPoint joinPoint, String spel) { //Spel表达式解析日志信息
  38 + //获得方法参数名数组
  39 + MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  40 +
  41 + String[] parameterNames = parameterNameDiscoverer.getParameterNames(signature.getMethod());
  42 + if (parameterNames != null && parameterNames.length > 0) {
  43 + EvaluationContext context = new StandardEvaluationContext();
  44 +
  45 + //获取方法参数值
  46 + Object[] args = joinPoint.getArgs();
  47 + for (int i = 0; i < args.length; i++) {
  48 + //替换spel里的变量值为实际值, 比如 #user --> user对象
  49 + context.setVariable(parameterNames[i], args[i]);
  50 + }
  51 + return spelExpressionParser.parseExpression(spel).getValue(context).toString();
  52 + }
  53 + return "";
  54 + }
  55 +
  56 + /**
  57 + * 转换 jspl参数
  58 + *
  59 + * @param joinPoint
  60 + * @param spel
  61 + * @return
  62 + */
  63 + public static String compileParams(JoinPoint joinPoint, Object rvt, String spel) { //Spel表达式解析日志信息
  64 + //获得方法参数名数组
  65 + MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  66 +
  67 + String[] parameterNames = parameterNameDiscoverer.getParameterNames(signature.getMethod());
  68 + if (parameterNames != null && parameterNames.length > 0) {
  69 + EvaluationContext context = new StandardEvaluationContext();
  70 +
  71 + //获取方法参数值
  72 + Object[] args = joinPoint.getArgs();
  73 + for (int i = 0; i < args.length; i++) {
  74 + //替换spel里的变量值为实际值, 比如 #user --> user对象
  75 + context.setVariable(parameterNames[i], args[i]);
  76 + }
  77 + context.setVariable("rvt", rvt);
  78 + return spelExpressionParser.parseExpression(spel).getValue(context).toString();
  79 + }
  80 + return "";
  81 + }
  82 +}
yudao-framework/yudao-spring-boot-starter-biz-operatelog/pom.xml
@@ -37,7 +37,7 @@ @@ -37,7 +37,7 @@
37 <!-- 业务组件 --> 37 <!-- 业务组件 -->
38 <dependency> 38 <dependency>
39 <groupId>cn.iocoder.boot</groupId> 39 <groupId>cn.iocoder.boot</groupId>
40 - <artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行操作日志的记录 --> 40 + <artifactId>yudao-module-system-api</artifactId>
41 <version>${revision}</version> 41 <version>${revision}</version>
42 </dependency> 42 </dependency>
43 43
yudao-framework/yudao-spring-boot-starter-biz-trade/pom.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <parent>
  6 + <groupId>cn.iocoder.boot</groupId>
  7 + <artifactId>yudao-framework</artifactId>
  8 + <version>${revision}</version>
  9 + </parent>
  10 + <modelVersion>4.0.0</modelVersion>
  11 + <artifactId>yudao-spring-boot-starter-biz-trade</artifactId>
  12 + <packaging>jar</packaging>
  13 +
  14 + <name>${project.artifactId}</name>
  15 + <description>交易模块</description>
  16 + <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
  17 +
  18 + <dependencies>
  19 + <dependency>
  20 + <groupId>cn.iocoder.boot</groupId>
  21 + <artifactId>yudao-common</artifactId>
  22 + </dependency>
  23 +
  24 + <!-- Spring 核心 -->
  25 + <dependency>
  26 + <groupId>org.springframework.boot</groupId>
  27 + <artifactId>spring-boot-starter-aop</artifactId>
  28 + </dependency>
  29 +
  30 + <!-- Web 相关 -->
  31 + <dependency>
  32 + <groupId>cn.iocoder.boot</groupId>
  33 + <artifactId>yudao-spring-boot-starter-web</artifactId>
  34 + <scope>provided</scope>
  35 + </dependency>
  36 +
  37 + <!-- 业务组件 -->
  38 + <dependency>
  39 + <groupId>cn.iocoder.boot</groupId>
  40 + <artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行操作日志的记录 -->
  41 + <version>${revision}</version>
  42 + </dependency>
  43 +
  44 + <!-- 工具类相关 -->
  45 + <dependency>
  46 + <groupId>com.google.guava</groupId>
  47 + <artifactId>guava</artifactId>
  48 + </dependency>
  49 + <dependency>
  50 + <groupId>cn.iocoder.boot</groupId>
  51 + <artifactId>yudao-spring-boot-starter-security</artifactId>
  52 + </dependency>
  53 + </dependencies>
  54 +</project>
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/config/YudaoAfterSaleLogAutoConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.trade.config;
  2 +
  3 +import cn.iocoder.yudao.framework.trade.core.aop.AfterSaleLogAspect;
  4 +import org.springframework.boot.autoconfigure.AutoConfiguration;
  5 +import org.springframework.context.annotation.Bean;
  6 +
  7 +// TODO @Chopper:和 yudao-module-trade-biz 的 framework 里
  8 +@AutoConfiguration
  9 +public class YudaoAfterSaleLogAutoConfiguration {
  10 +
  11 + @Bean
  12 + public AfterSaleLogAspect afterSaleLogAspect() {
  13 + return new AfterSaleLogAspect();
  14 + }
  15 +
  16 +}
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/annotations/AfterSaleLog.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.trade.core.annotations;
  2 +
  3 +import java.lang.annotation.*;
  4 +
  5 +/**
  6 + * 售后日志
  7 + *
  8 + * @author 陈賝
  9 + * @since 2023/6/8 17:04
  10 + */
  11 +@Target({ElementType.METHOD,ElementType.TYPE})
  12 +@Retention(RetentionPolicy.RUNTIME)
  13 +@Documented
  14 +public @interface AfterSaleLog {
  15 +
  16 + /**
  17 + * 售后 ID
  18 + */
  19 + String id();
  20 +
  21 + // TODO @陈賝:是不是改成一个操作的枚举?
  22 + /**
  23 + * 操作类型
  24 + */
  25 + String operateType() default "";
  26 +
  27 + /**
  28 + * 日志内容
  29 + */
  30 + String content() default "";
  31 +
  32 +}
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/aop/AfterSaleLogAspect.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.trade.core.aop;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.hutool.extra.spring.SpringUtil;
  5 +import cn.iocoder.yudao.framework.common.util.spel.SpelUtil;
  6 +import cn.iocoder.yudao.framework.trade.core.annotations.AfterSaleLog;
  7 +import cn.iocoder.yudao.framework.trade.core.dto.TradeAfterSaleLogCreateReqDTO;
  8 +import cn.iocoder.yudao.framework.trade.core.enums.AfterSaleStatusEnum;
  9 +import cn.iocoder.yudao.framework.trade.core.service.AfterSaleLogService;
  10 +import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
  11 +import lombok.extern.slf4j.Slf4j;
  12 +import org.aspectj.lang.JoinPoint;
  13 +import org.aspectj.lang.annotation.AfterReturning;
  14 +import org.aspectj.lang.annotation.Aspect;
  15 +import org.aspectj.lang.reflect.MethodSignature;
  16 +
  17 +import java.util.HashMap;
  18 +import java.util.Map;
  19 +
  20 +/**
  21 + * 记录售后日志的 AOP 切面
  22 + *
  23 + * @author 陈賝
  24 + * @since 2023/6/13 13:54
  25 + */
  26 +@Slf4j
  27 +@Aspect
  28 +public class AfterSaleLogAspect {
  29 +
  30 + @AfterReturning(pointcut = "@annotation(afterSaleLog)", returning = "info")
  31 + public void doAfterReturning(JoinPoint joinPoint, AfterSaleLog afterSaleLog, Object info) {
  32 + try {
  33 + // 日志对象拼接
  34 + Integer userType = WebFrameworkUtils.getLoginUserType();
  35 + Long id = WebFrameworkUtils.getLoginUserId();
  36 + Map<String, String> formatObj = spelFormat(joinPoint, info);
  37 + TradeAfterSaleLogCreateReqDTO dto = new TradeAfterSaleLogCreateReqDTO()
  38 + .setUserId(id).setUserType(userType)
  39 +// MapUtil.getLong() TODO @陈賝:试试这个方法
  40 + .setAfterSaleId(Long.valueOf(formatObj.get("id")))
  41 + .setContent(formatObj.get("content"))
  42 + .setOperateType(formatObj.get("operateType"));
  43 + // 异步存入数据库 TODO 可以注入哈;
  44 + SpringUtil.getBean(AfterSaleLogService.class).insert(dto);
  45 + } catch (Exception exception) {
  46 + // TODO @陈賝:日志要记录下参数哈,不然排查问题不好搞;
  47 + log.error("日志记录错误", exception);
  48 + }
  49 + }
  50 +
  51 + /**
  52 + * 获取描述信息
  53 + */
  54 + public static Map<String, String> spelFormat(JoinPoint joinPoint, Object info) {
  55 + MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  56 + AfterSaleLog afterSaleLogPoint = signature.getMethod().getAnnotation(AfterSaleLog.class);
  57 + Map<String, String> result = new HashMap<>(2); // TODO @陈賝:Maps.newExpectedXXX(3)
  58 + // 售后ID
  59 + String id = SpelUtil.compileParams(joinPoint, info, afterSaleLogPoint.id());
  60 + result.put("id", id);
  61 + // 操作类型
  62 + String operateType = SpelUtil.compileParams(joinPoint, info, afterSaleLogPoint.operateType());
  63 + result.put("operateType", operateType);
  64 + // 日志内容
  65 + String content = SpelUtil.compileParams(joinPoint, info, afterSaleLogPoint.content());
  66 + if (StrUtil.isNotEmpty(afterSaleLogPoint.operateType())) {
  67 + content += AfterSaleStatusEnum.valueOf(SpelUtil.compileParams(joinPoint, info, afterSaleLogPoint.operateType())).description();
  68 + }
  69 + result.put("content", content);
  70 + return result;
  71 + }
  72 +
  73 +}
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/dto/TradeAfterSaleLogCreateReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.trade.core.dto;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +
  7 +/**
  8 + * 售后日志的创建 Request DTO
  9 + */
  10 +@Data
  11 +@NoArgsConstructor
  12 +@AllArgsConstructor
  13 +public class TradeAfterSaleLogCreateReqDTO {
  14 +
  15 + /**
  16 + * 编号
  17 + */
  18 + private Long id;
  19 + /**
  20 + * 用户编号
  21 + *
  22 + * 关联 1:AdminUserDO 的 id 字段
  23 + * 关联 2:MemberUserDO 的 id 字段
  24 + */
  25 + private Long userId;
  26 + /**
  27 + * 用户类型
  28 + */
  29 + private Integer userType;
  30 + /**
  31 + * 售后编号
  32 + */
  33 + private Long afterSaleId;
  34 + /**
  35 + * 操作类型
  36 + */
  37 + private String operateType;
  38 + /**
  39 + * 操作明细
  40 + */
  41 + private String content;
  42 +
  43 +}
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/enums/AfterSaleStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.trade.core.enums;
  2 +
  3 +/**
  4 + * 售后状态的枚举
  5 + *
  6 + * @author 陈賝
  7 + * @since 2023/6/13 13:53
  8 + */
  9 +public enum AfterSaleStatusEnum {
  10 +
  11 + /**
  12 + * 申请中
  13 + */
  14 + APPLY("申请中");
  15 +
  16 + private final String description;
  17 +
  18 + AfterSaleStatusEnum(String description) {
  19 + this.description = description;
  20 + }
  21 +
  22 + public String description() {
  23 + return description;
  24 + }
  25 +
  26 +}
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/java/cn/iocoder/yudao/framework/trade/core/service/AfterSaleLogService.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.trade.core.service;
  2 +
  3 +import cn.iocoder.yudao.framework.trade.core.dto.TradeAfterSaleLogCreateReqDTO;
  4 +
  5 +// TODO @陈賝:类注释
  6 +public interface AfterSaleLogService {
  7 +
  8 + /**
  9 + * 创建售后日志
  10 + *
  11 + * @param logDTO 日志记录
  12 + * @author 陈賝
  13 + * @since 2023/6/12 14:18
  14 + */
  15 + // TODO @陈賝:createLog 方法名
  16 + void insert(TradeAfterSaleLogCreateReqDTO logDTO);
  17 +
  18 +}
yudao-framework/yudao-spring-boot-starter-biz-trade/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 0 → 100644
  1 +cn.iocoder.yudao.framework.trade.config.YudaoAfterSaleLogAutoConfiguration
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApi.java
1 package cn.iocoder.yudao.module.product.api.comment; 1 package cn.iocoder.yudao.module.product.api.comment;
2 2
3 -import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO; 3 +import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
4 4
5 /** 5 /**
6 * 产品评论 API 接口 6 * 产品评论 API 接口
@@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO; @@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
9 */ 9 */
10 public interface ProductCommentApi { 10 public interface ProductCommentApi {
11 11
  12 + // TODO @puhui:Long orderId 放到 createReqDTO 里噶?
12 /** 13 /**
13 * 创建评论 14 * 创建评论
14 * 15 *
@@ -16,6 +17,6 @@ public interface ProductCommentApi { @@ -16,6 +17,6 @@ public interface ProductCommentApi {
16 * @param orderId 订单 id 17 * @param orderId 订单 id
17 * @return 返回评论创建后的 id 18 * @return 返回评论创建后的 id
18 */ 19 */
19 - Long createComment(CommentCreateReqDTO createReqDTO, Long orderId); 20 + Long createComment(ProductCommentCreateReqDTO createReqDTO, Long orderId);
20 21
21 } 22 }
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/dto/CommentCreateReqDTO.java renamed to 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; @@ -10,71 +10,64 @@ import java.util.List;
10 * @author HUIHUI 10 * @author HUIHUI
11 */ 11 */
12 @Data 12 @Data
13 -public class CommentCreateReqDTO { 13 +public class ProductCommentCreateReqDTO {
14 14
15 /** 15 /**
16 - * 是否匿名 16 + * 商品 SKU 编号
17 */ 17 */
18 - private Boolean anonymous;  
19 - 18 + private Long skuId;
20 /** 19 /**
21 * 交易订单项编号 20 * 交易订单项编号
22 */ 21 */
23 private Long orderItemId; 22 private Long orderItemId;
24 23
  24 + // TODO @huihui:spuId、spuName 去查询哇?通过 skuId
25 /** 25 /**
26 * 商品 SPU 编号 26 * 商品 SPU 编号
27 */ 27 */
28 private Long spuId; 28 private Long spuId;
29 -  
30 /** 29 /**
31 * 商品 SPU 名称 30 * 商品 SPU 名称
32 */ 31 */
33 private String spuName; 32 private String spuName;
34 33
35 /** 34 /**
36 - * 商品 SKU 编号  
37 - */  
38 - private Long skuId;  
39 -  
40 - /**  
41 * 评分星级 1-5 分 35 * 评分星级 1-5 分
42 */ 36 */
43 private Integer scores; 37 private Integer scores;
44 -  
45 /** 38 /**
46 * 描述星级 1-5 分 39 * 描述星级 1-5 分
47 */ 40 */
48 private Integer descriptionScores; 41 private Integer descriptionScores;
49 -  
50 /** 42 /**
51 * 服务星级 1-5 分 43 * 服务星级 1-5 分
52 */ 44 */
53 private Integer benefitScores; 45 private Integer benefitScores;
54 -  
55 /** 46 /**
56 * 评论内容 47 * 评论内容
57 */ 48 */
58 private String content; 49 private String content;
59 -  
60 /** 50 /**
61 - * 评论图片地址数组,以逗号分隔最多上传9张 51 + * 评论图片地址数组,以逗号分隔最多上传 9 张
62 */ 52 */
63 private List<String> picUrls; 53 private List<String> picUrls;
64 54
65 /** 55 /**
  56 + * 是否匿名
  57 + */
  58 + private Boolean anonymous;
  59 + /**
  60 + * 评价人
  61 + */
  62 + private Long userId;
  63 + // TODO @puhui999:是不是 userNickname、userAvatar 去掉?通过 userId 查询
  64 + /**
66 * 评价人名称 65 * 评价人名称
67 */ 66 */
68 private String userNickname; 67 private String userNickname;
69 -  
70 /** 68 /**
71 * 评价人头像 69 * 评价人头像
72 */ 70 */
73 private String userAvatar; 71 private String userAvatar;
74 72
75 - /**  
76 - * 评价人  
77 - */  
78 - private Long userId;  
79 -  
80 } 73 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApiImpl.java
1 package cn.iocoder.yudao.module.product.api.comment; 1 package cn.iocoder.yudao.module.product.api.comment;
2 2
3 -import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO; 3 +import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
4 import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; 4 import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
5 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; 5 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
6 import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; 6 import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
@@ -17,12 +17,14 @@ import javax.annotation.Resource; @@ -17,12 +17,14 @@ import javax.annotation.Resource;
17 @Service 17 @Service
18 @Validated 18 @Validated
19 public class ProductCommentApiImpl implements ProductCommentApi { 19 public class ProductCommentApiImpl implements ProductCommentApi {
  20 +
20 @Resource 21 @Resource
21 private ProductCommentService productCommentService; 22 private ProductCommentService productCommentService;
22 23
23 @Override 24 @Override
24 - public Long createComment(CommentCreateReqDTO createReqDTO, Long orderId) { 25 + public Long createComment(ProductCommentCreateReqDTO createReqDTO, Long orderId) {
25 ProductCommentDO commentDO = ProductCommentConvert.INSTANCE.convert(createReqDTO, orderId); 26 ProductCommentDO commentDO = ProductCommentConvert.INSTANCE.convert(createReqDTO, orderId);
26 return productCommentService.createComment(commentDO); 27 return productCommentService.createComment(commentDO);
27 } 28 }
  29 +
28 } 30 }
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 { @@ -30,15 +30,15 @@ public class ProductCommentBaseVO {
30 @NotNull(message = "商品 SKU 编号不能为空") 30 @NotNull(message = "商品 SKU 编号不能为空")
31 private Long skuId; 31 private Long skuId;
32 32
33 - @Schema(description = "评分星级 1-5分", required = true, example = "5") 33 + @Schema(description = "评分星级 1-5 分", required = true, example = "5")
34 @NotNull(message = "评分星级不能为空") 34 @NotNull(message = "评分星级不能为空")
35 private Integer scores; 35 private Integer scores;
36 36
37 - @Schema(description = "描述星级 1-5分", required = true, example = "5") 37 + @Schema(description = "描述星级 1-5 分", required = true, example = "5")
38 @NotNull(message = "描述星级不能为空") 38 @NotNull(message = "描述星级不能为空")
39 private Integer descriptionScores; 39 private Integer descriptionScores;
40 40
41 - @Schema(description = "服务星级 1-5分", required = true, example = "5") 41 + @Schema(description = "服务星级 1-5 分", required = true, example = "5")
42 @NotNull(message = "服务星级分不能为空") 42 @NotNull(message = "服务星级分不能为空")
43 private Integer benefitScores; 43 private Integer benefitScores;
44 44
@@ -46,8 +46,8 @@ public class ProductCommentBaseVO { @@ -46,8 +46,8 @@ public class ProductCommentBaseVO {
46 @NotNull(message = "评论内容不能为空") 46 @NotNull(message = "评论内容不能为空")
47 private String content; 47 private String content;
48 48
49 - @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")  
50 - @Size(max = 9, message = "评论图片地址数组长度不能超过9张") 49 + @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
  50 + @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
51 private List<String> picUrls; 51 private List<String> picUrls;
52 52
53 } 53 }
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; @@ -13,6 +13,7 @@ import javax.validation.constraints.NotNull;
13 @ToString(callSuper = true) 13 @ToString(callSuper = true)
14 public class ProductCommentCreateReqVO extends ProductCommentBaseVO { 14 public class ProductCommentCreateReqVO extends ProductCommentBaseVO {
15 15
  16 + // TODO @puhui999:是不是也放到父类里?
16 @Schema(description = "评价人", required = true, example = "16868") 17 @Schema(description = "评价人", required = true, example = "16868")
17 @NotNull(message = "评价人不能为空") 18 @NotNull(message = "评价人不能为空")
18 private Long userId; 19 private Long userId;
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 { @@ -31,7 +31,7 @@ public class ProductCommentPageReqVO extends PageParam {
31 @Schema(description = "商品SPU名称", example = "感冒药") 31 @Schema(description = "商品SPU名称", example = "感冒药")
32 private String spuName; 32 private String spuName;
33 33
34 - @Schema(description = "评分星级 1-5分", example = "5") 34 + @Schema(description = "评分星级 1-5 分", example = "5")
35 @InEnum(ProductCommentScoresEnum.class) 35 @InEnum(ProductCommentScoresEnum.class)
36 private Integer scores; 36 private Integer scores;
37 37
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 { @@ -16,7 +16,7 @@ public class ProductCommentRespVO extends ProductCommentBaseVO {
16 @Schema(description = "订单项编号", required = true, example = "24965") 16 @Schema(description = "订单项编号", required = true, example = "24965")
17 private Long id; 17 private Long id;
18 18
19 - @Schema(description = "是否匿名:[false:不匿名 true:匿名]", required = true, example = "false") 19 + @Schema(description = "是否匿名", required = true, example = "false")
20 private Boolean anonymous; 20 private Boolean anonymous;
21 21
22 @Schema(description = "交易订单编号", required = true, example = "24428") 22 @Schema(description = "交易订单编号", required = true, example = "24428")
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 { @@ -36,6 +36,7 @@ public class AppProductCommentController {
36 @Resource 36 @Resource
37 private ProductCommentService productCommentService; 37 private ProductCommentService productCommentService;
38 38
  39 + // TODO @puhui999:可以实现下
39 @GetMapping("/list") 40 @GetMapping("/list")
40 @Operation(summary = "获得最近的 n 条商品评价") 41 @Operation(summary = "获得最近的 n 条商品评价")
41 @Parameters({ 42 @Parameters({
@@ -44,7 +45,6 @@ public class AppProductCommentController { @@ -44,7 +45,6 @@ public class AppProductCommentController {
44 }) 45 })
45 public CommonResult<List<AppProductCommentRespVO>> getCommentList(@RequestParam("spuId") Long spuId, 46 public CommonResult<List<AppProductCommentRespVO>> getCommentList(@RequestParam("spuId") Long spuId,
46 @RequestParam(value = "count", defaultValue = "10") Integer count) { 47 @RequestParam(value = "count", defaultValue = "10") Integer count) {
47 -  
48 List<AppProductPropertyValueDetailRespVO> list = new ArrayList<>(); 48 List<AppProductPropertyValueDetailRespVO> list = new ArrayList<>();
49 49
50 AppProductPropertyValueDetailRespVO item1 = new AppProductPropertyValueDetailRespVO(); 50 AppProductPropertyValueDetailRespVO item1 = new AppProductPropertyValueDetailRespVO();
@@ -101,6 +101,7 @@ public class AppProductCommentController { @@ -101,6 +101,7 @@ public class AppProductCommentController {
101 return success(productCommentService.getCommentPage(pageVO, Boolean.TRUE)); 101 return success(productCommentService.getCommentPage(pageVO, Boolean.TRUE));
102 } 102 }
103 103
  104 + // TODO @puhui:get-statistics;方法改成 getCommentStatistics;getCommentPageTabsCount 也改掉哈
104 @GetMapping("/getCommentStatistics") 105 @GetMapping("/getCommentStatistics")
105 @Operation(summary = "获得商品的评价统计") 106 @Operation(summary = "获得商品的评价统计")
106 public CommonResult<AppCommentStatisticsRespVO> getCommentPage(@Valid @RequestParam("spuId") Long spuId) { 107 public CommonResult<AppCommentStatisticsRespVO> getCommentPage(@Valid @RequestParam("spuId") Long spuId) {
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; @@ -8,11 +8,6 @@ import lombok.ToString;
8 8
9 import javax.validation.constraints.NotNull; 9 import javax.validation.constraints.NotNull;
10 10
11 -/**  
12 - * 用户 APP - 商品评价分页 Request VO  
13 - *  
14 - * @author HUIHUI  
15 - */  
16 @Schema(description = "用户APP - 商品评价分页 Request VO") 11 @Schema(description = "用户APP - 商品评价分页 Request VO")
17 @Data 12 @Data
18 @EqualsAndHashCode(callSuper = true) 13 @EqualsAndHashCode(callSuper = true)
@@ -23,12 +18,10 @@ public class AppCommentPageReqVO extends PageParam { @@ -23,12 +18,10 @@ public class AppCommentPageReqVO extends PageParam {
23 * 好评 18 * 好评
24 */ 19 */
25 public static final Integer GOOD_COMMENT = 1; 20 public static final Integer GOOD_COMMENT = 1;
26 -  
27 /** 21 /**
28 * 中评 22 * 中评
29 */ 23 */
30 public static final Integer MEDIOCRE_COMMENT = 2; 24 public static final Integer MEDIOCRE_COMMENT = 2;
31 -  
32 /** 25 /**
33 * 差评 26 * 差评
34 */ 27 */
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; @@ -4,11 +4,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 import lombok.ToString; 5 import lombok.ToString;
6 6
7 -/**  
8 - * APP 商品评价页评论分类数统计 Response VO  
9 - *  
10 - * @author HUIHUI  
11 - */  
12 @Schema(description = "APP - 商品评价页评论分类数统计 Response VO") 7 @Schema(description = "APP - 商品评价页评论分类数统计 Response VO")
13 @Data 8 @Data
14 @ToString(callSuper = true) 9 @ToString(callSuper = true)
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; @@ -8,11 +8,6 @@ import javax.validation.constraints.NotNull;
8 import javax.validation.constraints.Size; 8 import javax.validation.constraints.Size;
9 import java.util.List; 9 import java.util.List;
10 10
11 -/**  
12 - * 用户APP - 商品评价创建 Request VO  
13 - *  
14 - * @author HUIHUI  
15 - */  
16 @Schema(description = "用户APP - 商品评价创建 Request VO") 11 @Schema(description = "用户APP - 商品评价创建 Request VO")
17 @Data 12 @Data
18 @ToString(callSuper = true) 13 @ToString(callSuper = true)
@@ -26,36 +21,36 @@ public class AppProductCommentCreateReqVO { @@ -26,36 +21,36 @@ public class AppProductCommentCreateReqVO {
26 @NotNull(message = "交易订单项编号不能为空") 21 @NotNull(message = "交易订单项编号不能为空")
27 private Long orderItemId; 22 private Long orderItemId;
28 23
29 - @Schema(description = "商品SPU编号", required = true, example = "91192") 24 + @Schema(description = "商品 SPU 编号", required = true, example = "91192")
30 @NotNull(message = "商品SPU编号不能为空") 25 @NotNull(message = "商品SPU编号不能为空")
31 private Long spuId; 26 private Long spuId;
32 27
33 - @Schema(description = "商品SPU名称", required = true, example = "清凉丝滑小短袖") 28 + @Schema(description = "商品 SPU 名称", required = true, example = "清凉丝滑小短袖")
34 @NotNull(message = "商品SPU名称不能为空") 29 @NotNull(message = "商品SPU名称不能为空")
35 private String spuName; 30 private String spuName;
36 31
37 - @Schema(description = "商品SKU编号", required = true, example = "81192") 32 + @Schema(description = "商品 SKU 编号", required = true, example = "81192")
38 @NotNull(message = "商品SKU编号不能为空") 33 @NotNull(message = "商品SKU编号不能为空")
39 private Long skuId; 34 private Long skuId;
40 35
41 - @Schema(description = "评分星级 1-5分", required = true, example = "5")  
42 - @NotNull(message = "评分星级 1-5分不能为空") 36 + @Schema(description = "评分星级 1-5 分", required = true, example = "5")
  37 + @NotNull(message = "评分星级 1-5 分不能为空")
43 private Integer scores; 38 private Integer scores;
44 39
45 - @Schema(description = "描述星级 1-5分", required = true, example = "5")  
46 - @NotNull(message = "描述星级 1-5分不能为空") 40 + @Schema(description = "描述星级 1-5 分", required = true, example = "5")
  41 + @NotNull(message = "描述星级 1-5 分不能为空")
47 private Integer descriptionScores; 42 private Integer descriptionScores;
48 43
49 - @Schema(description = "服务星级 1-5分", required = true, example = "5")  
50 - @NotNull(message = "服务星级 1-5分不能为空") 44 + @Schema(description = "服务星级 1-5 分", required = true, example = "5")
  45 + @NotNull(message = "服务星级 1-5 分不能为空")
51 private Integer benefitScores; 46 private Integer benefitScores;
52 47
53 @Schema(description = "评论内容", required = true, example = "哇,真的很丝滑凉快诶,好评") 48 @Schema(description = "评论内容", required = true, example = "哇,真的很丝滑凉快诶,好评")
54 @NotNull(message = "评论内容不能为空") 49 @NotNull(message = "评论内容不能为空")
55 private String content; 50 private String content;
56 51
57 - @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")  
58 - @Size(max = 9, message = "评论图片地址数组长度不能超过9张") 52 + @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
  53 + @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
59 private List<String> picUrls; 54 private List<String> picUrls;
60 55
61 } 56 }
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 { @@ -60,7 +60,7 @@ public class AppProductCommentRespVO {
60 @Schema(description = "追加评价内容", example = "穿了很久都很丝滑诶") 60 @Schema(description = "追加评价内容", example = "穿了很久都很丝滑诶")
61 private String additionalContent; 61 private String additionalContent;
62 62
63 - @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张", example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]") 63 + @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传 9 张", example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
64 private List<String> additionalPicUrls; 64 private List<String> additionalPicUrls;
65 65
66 @Schema(description = "追加评价时间") 66 @Schema(description = "追加评价时间")
@@ -86,24 +86,24 @@ public class AppProductCommentRespVO { @@ -86,24 +86,24 @@ public class AppProductCommentRespVO {
86 @Schema(description = "商品 SKU 属性", required = true) 86 @Schema(description = "商品 SKU 属性", required = true)
87 private List<AppProductPropertyValueDetailRespVO> skuProperties; 87 private List<AppProductPropertyValueDetailRespVO> skuProperties;
88 88
89 - @Schema(description = "评分星级 1-5分", required = true, example = "5")  
90 - @NotNull(message = "评分星级 1-5分不能为空") 89 + @Schema(description = "评分星级 1-5 分", required = true, example = "5")
  90 + @NotNull(message = "评分星级 1-5 分不能为空")
91 private Integer scores; 91 private Integer scores;
92 92
93 - @Schema(description = "描述星级 1-5分", required = true, example = "5")  
94 - @NotNull(message = "描述星级 1-5分不能为空") 93 + @Schema(description = "描述星级 1-5 分", required = true, example = "5")
  94 + @NotNull(message = "描述星级 1-5 分不能为空")
95 private Integer descriptionScores; 95 private Integer descriptionScores;
96 96
97 - @Schema(description = "服务星级 1-5分", required = true, example = "5")  
98 - @NotNull(message = "服务星级 1-5分不能为空") 97 + @Schema(description = "服务星级 1-5 分", required = true, example = "5")
  98 + @NotNull(message = "服务星级 1-5 分不能为空")
99 private Integer benefitScores; 99 private Integer benefitScores;
100 100
101 @Schema(description = "评论内容", required = true, example = "哇,真的很丝滑凉快诶,好评") 101 @Schema(description = "评论内容", required = true, example = "哇,真的很丝滑凉快诶,好评")
102 @NotNull(message = "评论内容不能为空") 102 @NotNull(message = "评论内容不能为空")
103 private String content; 103 private String content;
104 104
105 - @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")  
106 - @Size(max = 9, message = "评论图片地址数组长度不能超过9张") 105 + @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
  106 + @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
107 private List<String> picUrls; 107 private List<String> picUrls;
108 108
109 } 109 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java
1 package cn.iocoder.yudao.module.product.convert.comment; 1 package cn.iocoder.yudao.module.product.convert.comment;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 -import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO; 4 +import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
5 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO; 5 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO;
6 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; 6 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO;
7 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; 7 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
@@ -49,7 +49,7 @@ public interface ProductCommentConvert { @@ -49,7 +49,7 @@ public interface ProductCommentConvert {
49 * 49 *
50 * @param descriptionScores 描述星级 50 * @param descriptionScores 描述星级
51 * @param benefitScores 服务星级 51 * @param benefitScores 服务星级
52 - * @return {@link Integer} 52 + * @return 综合评分
53 */ 53 */
54 @Named("convertScores") 54 @Named("convertScores")
55 default Integer convertScores(Integer descriptionScores, Integer benefitScores) { 55 default Integer convertScores(Integer descriptionScores, Integer benefitScores) {
@@ -61,7 +61,7 @@ public interface ProductCommentConvert { @@ -61,7 +61,7 @@ public interface ProductCommentConvert {
61 61
62 @Mapping(target = "orderId", source = "orderId") 62 @Mapping(target = "orderId", source = "orderId")
63 @Mapping(target = "scores", expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))") 63 @Mapping(target = "scores", expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))")
64 - ProductCommentDO convert(CommentCreateReqDTO createReqDTO, Long orderId); 64 + ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO, Long orderId);
65 65
66 @Mapping(target = "userId", constant = "0L") 66 @Mapping(target = "userId", constant = "0L")
67 @Mapping(target = "orderId", constant = "0L") 67 @Mapping(target = "orderId", constant = "0L")
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 { @@ -97,7 +97,7 @@ public class ProductCommentDO extends BaseDO {
97 /** 97 /**
98 * 评分星级 98 * 评分星级
99 * 99 *
100 - * 1-5分 100 + * 1-5 分
101 */ 101 */
102 private Integer scores; 102 private Integer scores;
103 /** 103 /**
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&lt;ProductCommentDO&gt; { @@ -25,6 +25,7 @@ public interface ProductCommentMapper extends BaseMapperX&lt;ProductCommentDO&gt; {
25 } 25 }
26 26
27 // TODO 芋艿:在看看这块 27 // TODO 芋艿:在看看这块
  28 + // TODO @puhui999:直接使用 scores 来算好评、中评、差评
28 static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) { 29 static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) {
29 // 构建好评查询语句:好评计算 (商品评分星级+服务评分星级) >= 8 30 // 构建好评查询语句:好评计算 (商品评分星级+服务评分星级) >= 8
30 if (ObjectUtil.equal(type, AppCommentPageReqVO.GOOD_COMMENT)) { 31 if (ObjectUtil.equal(type, AppCommentPageReqVO.GOOD_COMMENT)) {
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 { @@ -54,7 +54,8 @@ public interface ProductCommentService {
54 PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible); 54 PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
55 55
56 /** 56 /**
57 - * 创建商品评论 后台管理员创建评论使用 57 + * 创建商品评论
  58 + * 后台管理员创建评论使用
58 * 59 *
59 * @param createReqVO 商品评价创建 Request VO 对象 60 * @param createReqVO 商品评价创建 Request VO 对象
60 */ 61 */
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 { @@ -86,6 +86,7 @@ public class ProductCommentServiceImpl implements ProductCommentService {
86 @Transactional(rollbackFor = Exception.class) 86 @Transactional(rollbackFor = Exception.class)
87 public void createComment(ProductCommentCreateReqVO createReqVO) { 87 public void createComment(ProductCommentCreateReqVO createReqVO) {
88 // 校验订单 88 // 校验订单
  89 + // TODO @puhui999:不校验哈;尽可能解耦
89 Long orderId = tradeOrderApi.validateOrder(createReqVO.getUserId(), createReqVO.getOrderItemId()); 90 Long orderId = tradeOrderApi.validateOrder(createReqVO.getUserId(), createReqVO.getOrderItemId());
90 // 校验评论 91 // 校验评论
91 validateComment(createReqVO.getSpuId(), createReqVO.getUserId(), orderId); 92 validateComment(createReqVO.getSpuId(), createReqVO.getUserId(), orderId);
@@ -104,8 +105,6 @@ public class ProductCommentServiceImpl implements ProductCommentService { @@ -104,8 +105,6 @@ public class ProductCommentServiceImpl implements ProductCommentService {
104 return commentDO.getId(); 105 return commentDO.getId();
105 } 106 }
106 107
107 - // TODO 只有创建和更新诶 要不要删除接口  
108 -  
109 private void validateComment(Long spuId, Long userId, Long orderId) { 108 private void validateComment(Long spuId, Long userId, Long orderId) {
110 ProductSpuDO spu = productSpuService.getSpu(spuId); 109 ProductSpuDO spu = productSpuService.getSpu(spuId);
111 if (null == spu) { 110 if (null == spu) {
@@ -144,6 +143,7 @@ public class ProductCommentServiceImpl implements ProductCommentService { @@ -144,6 +143,7 @@ public class ProductCommentServiceImpl implements ProductCommentService {
144 public PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) { 143 public PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
145 PageResult<AppProductCommentRespVO> result = ProductCommentConvert.INSTANCE.convertPage02( 144 PageResult<AppProductCommentRespVO> result = ProductCommentConvert.INSTANCE.convertPage02(
146 productCommentMapper.selectPage(pageVO, visible)); 145 productCommentMapper.selectPage(pageVO, visible));
  146 + // TODO @puhui999:要不这块放到 controller 里拼接?
147 Set<Long> skuIds = result.getList().stream().map(AppProductCommentRespVO::getSkuId).collect(Collectors.toSet()); 147 Set<Long> skuIds = result.getList().stream().map(AppProductCommentRespVO::getSkuId).collect(Collectors.toSet());
148 List<ProductSkuDO> skuList = productSkuService.getSkuList(skuIds); 148 List<ProductSkuDO> skuList = productSkuService.getSkuList(skuIds);
149 Map<Long, ProductSkuDO> skuDOMap = new HashMap<>(skuIds.size()); 149 Map<Long, ProductSkuDO> skuDOMap = new HashMap<>(skuIds.size());
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` ( @@ -126,6 +126,7 @@ CREATE TABLE IF NOT EXISTS `product_property_value` (
126 PRIMARY KEY("id") 126 PRIMARY KEY("id")
127 ) COMMENT '规格值'; 127 ) COMMENT '规格值';
128 128
  129 +-- TODO @puhui999:格式不太对哈
129 CREATE TABLE IF NOT EXISTS `product_comment` 130 CREATE TABLE IF NOT EXISTS `product_comment`
130 ( 131 (
131 `id` 132 `id`
@@ -166,7 +167,7 @@ CREATE TABLE IF NOT EXISTS `product_comment` @@ -166,7 +167,7 @@ CREATE TABLE IF NOT EXISTS `product_comment`
166 ( 167 (
167 1 168 1
168 ) DEFAULT NULL COMMENT '是否可见true:显示false:隐藏', 169 ) DEFAULT NULL COMMENT '是否可见true:显示false:隐藏',
169 - `scores` tinyint DEFAULT NULL COMMENT '评分星级1-5分', 170 + `scores` tinyint DEFAULT NULL COMMENT '评分星级1-5 分',
170 `description_scores` tinyint DEFAULT NULL COMMENT '描述星级1-5 星', 171 `description_scores` tinyint DEFAULT NULL COMMENT '描述星级1-5 星',
171 `benefit_scores` tinyint DEFAULT NULL COMMENT '服务星级1-5 星', 172 `benefit_scores` tinyint DEFAULT NULL COMMENT '服务星级1-5 星',
172 `content` varchar 173 `content` varchar
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 { @@ -38,7 +38,7 @@ public class AppCombinationActivityController {
38 activity1.setName("618 大拼团"); 38 activity1.setName("618 大拼团");
39 activity1.setUserSize(3); 39 activity1.setUserSize(3);
40 activity1.setSpuId(2048L); 40 activity1.setSpuId(2048L);
41 - activity1.setPicUrl("商品图片地址"); 41 + activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");
42 activity1.setMarketPrice(50); 42 activity1.setMarketPrice(50);
43 activity1.setCombinationPrice(100); 43 activity1.setCombinationPrice(100);
44 activityList.add(activity1); 44 activityList.add(activity1);
@@ -48,7 +48,7 @@ public class AppCombinationActivityController { @@ -48,7 +48,7 @@ public class AppCombinationActivityController {
48 activity2.setName("双十一拼团"); 48 activity2.setName("双十一拼团");
49 activity2.setUserSize(5); 49 activity2.setUserSize(5);
50 activity2.setSpuId(4096L); 50 activity2.setSpuId(4096L);
51 - activity2.setPicUrl("商品图片地址"); 51 + activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132");
52 activity2.setMarketPrice(100); 52 activity2.setMarketPrice(100);
53 activity2.setCombinationPrice(200); 53 activity2.setCombinationPrice(200);
54 activityList.add(activity2); 54 activityList.add(activity2);
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java
1 package cn.iocoder.yudao.module.promotion.controller.app.seckill; 1 package cn.iocoder.yudao.module.promotion.controller.app.seckill;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 -import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.AppSeckillActivitiDetailRespVO; 4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO;
  6 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO;
  8 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
5 import io.swagger.v3.oas.annotations.Operation; 9 import io.swagger.v3.oas.annotations.Operation;
6 import io.swagger.v3.oas.annotations.Parameter; 10 import io.swagger.v3.oas.annotations.Parameter;
7 import io.swagger.v3.oas.annotations.tags.Tag; 11 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -23,12 +27,65 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -23,12 +27,65 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
23 @Validated 27 @Validated
24 public class AppSeckillActivityController { 28 public class AppSeckillActivityController {
25 29
  30 + @GetMapping("/get-now")
  31 + @Operation(summary = "获得当前秒杀活动") // 提供给首页使用
  32 + // TODO 芋艿:需要增加 spring cache
  33 + public CommonResult<AppSeckillActivityNowRespVO> getNowSeckillActivity() {
  34 + AppSeckillActivityNowRespVO respVO = new AppSeckillActivityNowRespVO();
  35 + respVO.setConfig(new AppSeckillConfigRespVO().setId(10L).setStartTime("01:00").setEndTime("09:59"));
  36 + List<AppSeckillActivityRespVO> activityList = new ArrayList<>();
  37 + AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO();
  38 + activity1.setId(1L);
  39 + activity1.setName("618 大秒杀");
  40 + activity1.setSpuId(2048L);
  41 + activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");
  42 + activity1.setMarketPrice(50);
  43 + activity1.setSeckillPrice(100);
  44 + activityList.add(activity1);
  45 +
  46 + AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO();
  47 + activity2.setId(2L);
  48 + activity2.setName("双十一大秒杀");
  49 + activity2.setSpuId(4096L);
  50 + activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132");
  51 + activity2.setMarketPrice(100);
  52 + activity2.setSeckillPrice(200);
  53 + activityList.add(activity2);
  54 + respVO.setActivities(activityList);
  55 + return success(respVO);
  56 + }
  57 +
  58 + @GetMapping("/page")
  59 + @Operation(summary = "获得秒杀活动分页")
  60 + // TODO @芋艿:分页参数
  61 + public CommonResult<PageResult<AppSeckillActivityRespVO>> getSeckillActivityPage() {
  62 + List<AppSeckillActivityRespVO> activityList = new ArrayList<>();
  63 + AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO();
  64 + activity1.setId(1L);
  65 + activity1.setName("618 大秒杀");
  66 + activity1.setSpuId(2048L);
  67 + activity1.setPicUrl("https://demo26.crmeb.net/uploads/attach/2021/11/15/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");
  68 + activity1.setMarketPrice(50);
  69 + activity1.setSeckillPrice(100);
  70 + activityList.add(activity1);
  71 +
  72 + AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO();
  73 + activity2.setId(2L);
  74 + activity2.setName("双十一大秒杀");
  75 + activity2.setSpuId(4096L);
  76 + activity2.setPicUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKXMYJOomfp7cebz3cIeb8sHk3GGSIJtWEgREe3j7J1WoAbTvIOicpcNdFkWAziatBSMod8b5RyS4CQ/132");
  77 + activity2.setMarketPrice(100);
  78 + activity2.setSeckillPrice(200);
  79 + activityList.add(activity2);
  80 + return success(new PageResult<>(activityList, 100L));
  81 + }
  82 +
26 @GetMapping("/get-detail") 83 @GetMapping("/get-detail")
27 @Operation(summary = "获得秒杀活动明细") 84 @Operation(summary = "获得秒杀活动明细")
28 @Parameter(name = "id", description = "活动编号", required = true, example = "1024") 85 @Parameter(name = "id", description = "活动编号", required = true, example = "1024")
29 - public CommonResult<AppSeckillActivitiDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) { 86 + public CommonResult<AppSeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) {
30 // TODO 芋艿:如果禁用的时候,需要抛出异常; 87 // TODO 芋艿:如果禁用的时候,需要抛出异常;
31 - AppSeckillActivitiDetailRespVO obj = new AppSeckillActivitiDetailRespVO(); 88 + AppSeckillActivityDetailRespVO obj = new AppSeckillActivityDetailRespVO();
32 // 设置其属性的值 89 // 设置其属性的值
33 obj.setId(id); 90 obj.setId(id);
34 obj.setName("晚九点限时秒杀"); 91 obj.setName("晚九点限时秒杀");
@@ -37,9 +94,9 @@ public class AppSeckillActivityController { @@ -37,9 +94,9 @@ public class AppSeckillActivityController {
37 obj.setEndTime(LocalDateTime.of(2023, 6, 11, 23, 59, 0)); 94 obj.setEndTime(LocalDateTime.of(2023, 6, 11, 23, 59, 0));
38 obj.setSpuId(633L); 95 obj.setSpuId(633L);
39 // 创建一个Product对象的列表 96 // 创建一个Product对象的列表
40 - List<AppSeckillActivitiDetailRespVO.Product> productList = new ArrayList<>(); 97 + List<AppSeckillActivityDetailRespVO.Product> productList = new ArrayList<>();
41 // 创建三个新的Product对象并设置其属性的值 98 // 创建三个新的Product对象并设置其属性的值
42 - AppSeckillActivitiDetailRespVO.Product product1 = new AppSeckillActivitiDetailRespVO.Product(); 99 + AppSeckillActivityDetailRespVO.Product product1 = new AppSeckillActivityDetailRespVO.Product();
43 product1.setSkuId(1L); 100 product1.setSkuId(1L);
44 product1.setSeckillPrice(100); 101 product1.setSeckillPrice(100);
45 product1.setQuota(50); 102 product1.setQuota(50);
@@ -47,7 +104,7 @@ public class AppSeckillActivityController { @@ -47,7 +104,7 @@ public class AppSeckillActivityController {
47 // 将第一个Product对象添加到列表中 104 // 将第一个Product对象添加到列表中
48 productList.add(product1); 105 productList.add(product1);
49 // 创建第二个Product对象并设置其属性的值 106 // 创建第二个Product对象并设置其属性的值
50 - AppSeckillActivitiDetailRespVO.Product product2 = new AppSeckillActivitiDetailRespVO.Product(); 107 + AppSeckillActivityDetailRespVO.Product product2 = new AppSeckillActivityDetailRespVO.Product();
51 product2.setSkuId(2L); 108 product2.setSkuId(2L);
52 product2.setSeckillPrice(200); 109 product2.setSeckillPrice(200);
53 product2.setQuota(100); 110 product2.setQuota(100);
@@ -55,7 +112,7 @@ public class AppSeckillActivityController { @@ -55,7 +112,7 @@ public class AppSeckillActivityController {
55 // 将第二个Product对象添加到列表中 112 // 将第二个Product对象添加到列表中
56 productList.add(product2); 113 productList.add(product2);
57 // 创建第三个Product对象并设置其属性的值 114 // 创建第三个Product对象并设置其属性的值
58 - AppSeckillActivitiDetailRespVO.Product product3 = new AppSeckillActivitiDetailRespVO.Product(); 115 + AppSeckillActivityDetailRespVO.Product product3 = new AppSeckillActivityDetailRespVO.Product();
59 product3.setSkuId(3L); 116 product3.setSkuId(3L);
60 product3.setSeckillPrice(300); 117 product3.setSeckillPrice(300);
61 product3.setQuota(150); 118 product3.setQuota(150);
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillConfigController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.app.seckill;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
  5 +import io.swagger.v3.oas.annotations.Operation;
  6 +import io.swagger.v3.oas.annotations.tags.Tag;
  7 +import org.springframework.validation.annotation.Validated;
  8 +import org.springframework.web.bind.annotation.GetMapping;
  9 +import org.springframework.web.bind.annotation.RequestMapping;
  10 +import org.springframework.web.bind.annotation.RestController;
  11 +
  12 +import java.util.Arrays;
  13 +import java.util.List;
  14 +
  15 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  16 +
  17 +@Tag(name = "用户 App - 秒杀时间段")
  18 +@RestController
  19 +@RequestMapping("/promotion/seckill-config")
  20 +@Validated
  21 +public class AppSeckillConfigController {
  22 +
  23 + @GetMapping("/list")
  24 + @Operation(summary = "获得秒杀时间段列表")
  25 + public CommonResult<List<AppSeckillConfigRespVO>> getConfigList() {
  26 + return success(Arrays.asList(
  27 + new AppSeckillConfigRespVO().setId(1L).setStartTime("00:00").setEndTime("09:59"),
  28 + new AppSeckillConfigRespVO().setId(2L).setStartTime("10:00").setEndTime("12:59"),
  29 + new AppSeckillConfigRespVO().setId(2L).setStartTime("13:00").setEndTime("23:59")
  30 + ));
  31 + }
  32 +
  33 +}
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/AppSeckillActivitiDetailRespVO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityDetailRespVO.java
1 -package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo; 1 +package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
@@ -6,9 +6,9 @@ import lombok.Data; @@ -6,9 +6,9 @@ import lombok.Data;
6 import java.time.LocalDateTime; 6 import java.time.LocalDateTime;
7 import java.util.List; 7 import java.util.List;
8 8
9 -@Schema(description = "用户 App - 秒杀活动 Response VO") 9 +@Schema(description = "用户 App - 秒杀活动的详细 Response VO")
10 @Data 10 @Data
11 -public class AppSeckillActivitiDetailRespVO { 11 +public class AppSeckillActivityDetailRespVO {
12 12
13 @Schema(description = "秒杀活动编号", required = true, example = "1024") 13 @Schema(description = "秒杀活动编号", required = true, example = "1024")
14 private Long id; 14 private Long id;
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityNowRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity;
  2 +
  3 +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +
  7 +import java.util.List;
  8 +
  9 +@Schema(description = "用户 App - 当前秒杀活动 Response VO")
  10 +@Data
  11 +public class AppSeckillActivityNowRespVO {
  12 +
  13 + @Schema(description = "秒杀时间段", required = true)
  14 + private AppSeckillConfigRespVO config;
  15 +
  16 + @Schema(description = "秒杀活动数组", required = true)
  17 + private List<AppSeckillActivityRespVO> activities;
  18 +
  19 +}
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "用户 App - 秒杀活动 Response VO")
  7 +@Data
  8 +public class AppSeckillActivityRespVO {
  9 +
  10 + @Schema(description = "秒杀活动编号", required = true, example = "1024")
  11 + private Long id;
  12 +
  13 + @Schema(description = "秒杀活动名称", required = true, example = "晚九点限时秒杀")
  14 + private String name;
  15 +
  16 + @Schema(description = "商品 SPU 编号", required = true, example = "2048")
  17 + private Long spuId;
  18 +
  19 + @Schema(description = "商品图片", required = true, example = "4096") // 从 SPU 的 picUrl 读取
  20 + private String picUrl;
  21 +
  22 + @Schema(description = "商品市场价,单位:分", required = true, example = "50") // 从 SPU 的 marketPrice 读取
  23 + private Integer marketPrice;
  24 +
  25 + @Schema(description = "秒杀金额,单位:分", required = true, example = "100") // 从秒杀商品里取最低价
  26 + private Integer seckillPrice;
  27 +
  28 +}
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/config/AppSeckillConfigRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "用户 App - 秒杀时间段 Response VO")
  7 +@Data
  8 +public class AppSeckillConfigRespVO {
  9 +
  10 + @Schema(description = "秒杀时间段编号", required = true, example = "1024")
  11 + private Long id;
  12 +
  13 + @Schema(description = "开始时间点", required = true, example = "09:00")
  14 + private String startTime;
  15 + @Schema(description = "结束时间点", required = true, example = "09:59")
  16 + private String endTime;
  17 +
  18 +}
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; @@ -19,23 +19,38 @@ import static cn.hutool.core.util.ArrayUtil.firstMatch;
19 @Getter 19 @Getter
20 public enum TradeAfterSaleStatusEnum implements IntArrayValuable { 20 public enum TradeAfterSaleStatusEnum implements IntArrayValuable {
21 21
22 - APPLY(10,"申请中", // 【申请售后】  
23 - "会员申请退款"),  
24 - SELLER_AGREE(20, "卖家通过", // 卖家通过售后;【商品待退货】  
25 - "商家同意退款"),  
26 - BUYER_DELIVERY(30,"待卖家收货", // 买家已退货,等待卖家收货;【商家待收货】  
27 - "会员填写退货物流信息"),  
28 - WAIT_REFUND(40, "等待平台退款", // 卖家已收货,等待平台退款;等待退款【等待退款】  
29 - "商家收货"),  
30 - COMPLETE(50, "完成", // 完成退款【退款成功】  
31 - "商家确认退款"),  
32 -  
33 - BUYER_CANCEL(61, "买家取消售后", // 【买家取消】  
34 - "会员取消退款"),  
35 - SELLER_DISAGREE(62,"卖家拒绝", // 卖家拒绝售后;商家拒绝【商家拒绝】  
36 - "商家拒绝退款"),  
37 - SELLER_REFUSE(63,"卖家拒绝收货", // 卖家拒绝收货,终止售后;【商家拒收货】  
38 - "商家拒绝收货"), 22 + /**
  23 + * 【申请售后】
  24 + */
  25 + APPLY(10,"申请中", "会员申请退款"),
  26 + /**
  27 + * 卖家通过售后;【商品待退货】
  28 + */
  29 + SELLER_AGREE(20, "卖家通过", "商家同意退款"),
  30 + /**
  31 + * 买家已退货,等待卖家收货;【商家待收货】
  32 + */
  33 + BUYER_DELIVERY(30,"待卖家收货", "会员填写退货物流信息"),
  34 + /**
  35 + * 卖家已收货,等待平台退款;等待退款【等待退款】
  36 + */
  37 + WAIT_REFUND(40, "等待平台退款", "商家收货"),
  38 + /**
  39 + * 完成退款【退款成功】
  40 + */
  41 + COMPLETE(50, "完成", "商家确认退款"),
  42 + /**
  43 + * 【买家取消】
  44 + */
  45 + BUYER_CANCEL(61, "买家取消售后", "会员取消退款"),
  46 + /**
  47 + * 卖家拒绝售后;商家拒绝【商家拒绝】
  48 + */
  49 + SELLER_DISAGREE(62,"卖家拒绝", "商家拒绝退款"),
  50 + /**
  51 + * 卖家拒绝收货,终止售后;【商家拒收货】
  52 + */
  53 + SELLER_REFUSE(63,"卖家拒绝收货", "商家拒绝收货"),
39 ; 54 ;
40 55
41 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleStatusEnum::getStatus).toArray(); 56 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleStatusEnum::getStatus).toArray();
yudao-module-mall/yudao-module-trade-biz/pom.xml
@@ -58,6 +58,11 @@ @@ -58,6 +58,11 @@
58 <groupId>cn.iocoder.boot</groupId> 58 <groupId>cn.iocoder.boot</groupId>
59 <artifactId>yudao-spring-boot-starter-biz-ip</artifactId> 59 <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
60 </dependency> 60 </dependency>
  61 + <dependency>
  62 + <groupId>cn.iocoder.boot</groupId>
  63 + <artifactId>yudao-spring-boot-starter-biz-trade</artifactId>
  64 + <version>${revision}</version>
  65 + </dependency>
61 66
62 <!-- Web 相关 --> 67 <!-- Web 相关 -->
63 <dependency> 68 <dependency>
@@ -93,6 +98,7 @@ @@ -93,6 +98,7 @@
93 <groupId>cn.iocoder.boot</groupId> 98 <groupId>cn.iocoder.boot</groupId>
94 <artifactId>yudao-spring-boot-starter-excel</artifactId> 99 <artifactId>yudao-spring-boot-starter-excel</artifactId>
95 </dependency> 100 </dependency>
  101 +
96 </dependencies> 102 </dependencies>
97 103
98 </project> 104 </project>
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; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.admin.aftersale;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.trade.core.annotations.AfterSaleLog;
6 import cn.iocoder.yudao.module.member.api.user.MemberUserApi; 7 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
7 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 8 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
8 import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; 9 import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi;
@@ -11,6 +12,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSal @@ -11,6 +12,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSal
11 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; 12 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO;
12 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO; 13 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO;
13 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO; 14 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO;
  15 +import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
14 import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert; 16 import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert;
15 import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; 17 import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
16 import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService; 18 import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService;
@@ -110,4 +112,20 @@ public class TradeAfterSaleController { @@ -110,4 +112,20 @@ public class TradeAfterSaleController {
110 return success(true); 112 return success(true);
111 } 113 }
112 114
  115 + // TODO @陈賝:后续要删除下
  116 + /**
  117 + * 售后日志测试
  118 + *
  119 + * @param createReqVO
  120 + * @return cn.iocoder.yudao.framework.common.pojo.CommonResult<java.lang.Long>
  121 + * @author 陈賝
  122 + * @date 2023/6/14 21:39
  123 + */
  124 + @PostMapping(value = "/create")
  125 + @AfterSaleLog(id = "#createReqVO.orderItemId", content = "'申请售后:售后编号['+#createReqVO.orderItemId+'] , '", operateType = "#createReqVO.operateType")
  126 + public CommonResult<Long> createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) {
  127 + return success(1L);
  128 +// return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO));
  129 + }
  130 +
113 } 131 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java
1 package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo; 1 package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo;
2 2
3 import cn.iocoder.yudao.framework.common.validation.InEnum; 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.framework.trade.core.enums.AfterSaleStatusEnum;
4 import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; 5 import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum;
5 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
6 import lombok.Data; 7 import lombok.Data;
@@ -31,6 +32,14 @@ public class AppTradeAfterSaleCreateReqVO { @@ -31,6 +32,14 @@ public class AppTradeAfterSaleCreateReqVO {
31 @NotNull(message = "申请原因不能为空") 32 @NotNull(message = "申请原因不能为空")
32 private String applyReason; 33 private String applyReason;
33 34
  35 + // TODO @陈賝:这个参数不应该有呀。
  36 + /**
  37 + * @see AfterSaleStatusEnum
  38 + */
  39 + @Schema(description = "操作类型", required = true, example = "1")
  40 + @NotNull(message = "操作类型不能为空")
  41 + private String operateType;
  42 +
34 @Schema(description = "补充描述", example = "商品质量不好") 43 @Schema(description = "补充描述", example = "商品质量不好")
35 private String applyDescription; 44 private String applyDescription;
36 45
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; @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.controller.app.order;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;  
6 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; 5 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
7 import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; 6 import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
8 import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi; 7 import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
@@ -49,12 +48,11 @@ public class AppTradeOrderController { @@ -49,12 +48,11 @@ public class AppTradeOrderController {
49 48
50 @Resource 49 @Resource
51 private ProductPropertyValueApi productPropertyValueApi; 50 private ProductPropertyValueApi productPropertyValueApi;
52 -  
53 @Resource 51 @Resource
54 - private TradeOrderProperties tradeOrderProperties; 52 + private ProductCommentApi productCommentApi;
55 53
56 @Resource 54 @Resource
57 - private ProductCommentApi productCommentApi; 55 + private TradeOrderProperties tradeOrderProperties;
58 56
59 @GetMapping("/settlement") 57 @GetMapping("/settlement")
60 @Operation(summary = "获得订单结算信息") 58 @Operation(summary = "获得订单结算信息")
@@ -141,6 +139,7 @@ public class AppTradeOrderController { @@ -141,6 +139,7 @@ public class AppTradeOrderController {
141 @Operation(summary = "创建交易订单项的评价") 139 @Operation(summary = "创建交易订单项的评价")
142 public CommonResult<Long> createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) { 140 public CommonResult<Long> createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) {
143 // 校验订单项,订单项存在订单就存在 141 // 校验订单项,订单项存在订单就存在
  142 + // TODO @puhui999:要去查询订单是不是自己的;不然别人模拟请求哈;
144 TradeOrderItemDO item = tradeOrderService.getOrderItem(createReqVO.getUserId(), createReqVO.getOrderItemId()); 143 TradeOrderItemDO item = tradeOrderService.getOrderItem(createReqVO.getUserId(), createReqVO.getOrderItemId());
145 if (item == null) { 144 if (item == null) {
146 throw exception(ORDER_ITEM_NOT_FOUND); 145 throw exception(ORDER_ITEM_NOT_FOUND);
@@ -149,6 +148,6 @@ public class AppTradeOrderController { @@ -149,6 +148,6 @@ public class AppTradeOrderController {
149 return success(productCommentApi.createComment(TradeOrderConvert.INSTANCE.convert04(createReqVO), item.getOrderId())); 148 return success(productCommentApi.createComment(TradeOrderConvert.INSTANCE.convert04(createReqVO), item.getOrderId()));
150 } 149 }
151 150
152 - // TODO 合并代码后发现只有商家回复功能 用户追评不要了吗? 151 + // TODO 合并代码后发现只有商家回复功能 用户追评不要了吗?不要了哈;
153 152
154 } 153 }
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; @@ -7,11 +7,6 @@ import javax.validation.constraints.NotNull;
7 import javax.validation.constraints.Size; 7 import javax.validation.constraints.Size;
8 import java.util.List; 8 import java.util.List;
9 9
10 -/**  
11 - * 商品评价创建 Request VO  
12 - *  
13 - * @author HUIHUI  
14 - */  
15 @Schema(description = "用户APP - 商品评价创建 Request VO") 10 @Schema(description = "用户APP - 商品评价创建 Request VO")
16 @Data 11 @Data
17 public class AppTradeOrderItemCommentCreateReqVO { 12 public class AppTradeOrderItemCommentCreateReqVO {
@@ -24,6 +19,7 @@ public class AppTradeOrderItemCommentCreateReqVO { @@ -24,6 +19,7 @@ public class AppTradeOrderItemCommentCreateReqVO {
24 @NotNull(message = "交易订单项编号不能为空") 19 @NotNull(message = "交易订单项编号不能为空")
25 private Long orderItemId; 20 private Long orderItemId;
26 21
  22 + // TODO @puhui:spuId、spuName、skuId 直接查询出来;
27 @Schema(description = "商品SPU编号", required = true, example = "29502") 23 @Schema(description = "商品SPU编号", required = true, example = "29502")
28 @NotNull(message = "商品SPU编号不能为空") 24 @NotNull(message = "商品SPU编号不能为空")
29 private Long spuId; 25 private Long spuId;
@@ -36,30 +32,32 @@ public class AppTradeOrderItemCommentCreateReqVO { @@ -36,30 +32,32 @@ public class AppTradeOrderItemCommentCreateReqVO {
36 @NotNull(message = "商品SKU编号不能为空") 32 @NotNull(message = "商品SKU编号不能为空")
37 private Long skuId; 33 private Long skuId;
38 34
39 - @Schema(description = "评分星级 1-5分", required = true, example = "5")  
40 - @NotNull(message = "评分星级 1-5分不能为空") 35 + @Schema(description = "评分星级 1-5 分", required = true, example = "5")
  36 + @NotNull(message = "评分星级 1-5 分不能为空")
41 private Integer scores; 37 private Integer scores;
42 38
43 - @Schema(description = "描述星级 1-5分", required = true, example = "5")  
44 - @NotNull(message = "描述星级 1-5分不能为空") 39 + @Schema(description = "描述星级 1-5 分", required = true, example = "5")
  40 + @NotNull(message = "描述星级 1-5 分不能为空")
45 private Integer descriptionScores; 41 private Integer descriptionScores;
46 42
47 - @Schema(description = "服务星级 1-5分", required = true, example = "5")  
48 - @NotNull(message = "服务星级 1-5分不能为空") 43 + @Schema(description = "服务星级 1-5 分", required = true, example = "5")
  44 + @NotNull(message = "服务星级 1-5 分不能为空")
49 private Integer benefitScores; 45 private Integer benefitScores;
50 46
51 @Schema(description = "评论内容", required = true, example = "穿身上很漂亮诶(*^▽^*)") 47 @Schema(description = "评论内容", required = true, example = "穿身上很漂亮诶(*^▽^*)")
52 @NotNull(message = "评论内容不能为空") 48 @NotNull(message = "评论内容不能为空")
53 private String content; 49 private String content;
54 50
55 - @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xx.png]")  
56 - @Size(max = 9, message = "评论图片地址数组长度不能超过9张") 51 + @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xx.png]")
  52 + @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
57 private List<String> picUrls; 53 private List<String> picUrls;
58 54
59 @Schema(description = "评价人名称", required = true, example = "小姑凉") 55 @Schema(description = "评价人名称", required = true, example = "小姑凉")
60 @NotNull(message = "评价人名称不能为空") 56 @NotNull(message = "评价人名称不能为空")
61 private String userNickname; 57 private String userNickname;
62 58
  59 + // TODO @puhui:userAvatar、userAvatar、userId 直接查询出来;
  60 +
63 @Schema(description = "评价人头像", required = true, example = "https://www.iocoder.cn/xx.png") 61 @Schema(description = "评价人头像", required = true, example = "https://www.iocoder.cn/xx.png")
64 @NotNull(message = "评价人头像不能为空") 62 @NotNull(message = "评价人头像不能为空")
65 private String userAvatar; 63 private String userAvatar;
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; @@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
8 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; 8 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
9 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 9 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
10 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; 10 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
11 -import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO; 11 +import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
12 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; 12 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
13 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; 13 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
14 import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; 14 import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO;
@@ -227,6 +227,7 @@ public interface TradeOrderConvert { @@ -227,6 +227,7 @@ public interface TradeOrderConvert {
227 227
228 AppProductPropertyValueDetailRespVO convert02(ProductPropertyValueDetailRespDTO bean); 228 AppProductPropertyValueDetailRespVO convert02(ProductPropertyValueDetailRespDTO bean);
229 229
  230 + // TODO 芋艿:可简化
230 default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List<TradeOrderItemDO> orderItems, 231 default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
231 List<ProductPropertyValueDetailRespDTO> propertyValueDetails, TradeOrderProperties tradeOrderProperties) { 232 List<ProductPropertyValueDetailRespDTO> propertyValueDetails, TradeOrderProperties tradeOrderProperties) {
232 AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems); 233 AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems);
@@ -258,7 +259,7 @@ public interface TradeOrderConvert { @@ -258,7 +259,7 @@ public interface TradeOrderConvert {
258 259
259 AppTradeOrderItemRespVO convert03(TradeOrderItemDO bean); 260 AppTradeOrderItemRespVO convert03(TradeOrderItemDO bean);
260 261
261 - CommentCreateReqDTO convert04(AppTradeOrderItemCommentCreateReqVO createReqVO); 262 + ProductCommentCreateReqDTO convert04(AppTradeOrderItemCommentCreateReqVO createReqVO);
262 263
263 default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO, 264 default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO,
264 List<TradeCartDO> cartList) { 265 List<TradeCartDO> cartList) {
@@ -302,5 +303,4 @@ public interface TradeOrderConvert { @@ -302,5 +303,4 @@ public interface TradeOrderConvert {
302 303
303 AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, AddressRespDTO address); 304 AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, AddressRespDTO address);
304 305
305 -  
306 } 306 }
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 { @@ -52,29 +52,9 @@ public class TradeAfterSaleLogDO extends BaseDO {
52 */ 52 */
53 private Long afterSaleId; 53 private Long afterSaleId;
54 /** 54 /**
55 - * 订单编号  
56 - *  
57 - * 关联 {@link TradeOrderDO#getId()}  
58 - */  
59 - private Long orderId;  
60 - /**  
61 - * 订单项编号  
62 - *  
63 - * 关联 {@link TradeOrderItemDO#getId()}  
64 - */  
65 - private Long orderItemId;  
66 - /**  
67 - * 售后状态(之前)  
68 - *  
69 - * 枚举 {@link TradeAfterSaleStatusEnum}  
70 - */  
71 - private Integer beforeStatus;  
72 - /**  
73 - * 售后状态(之后)  
74 - *  
75 - * 枚举 {@link TradeAfterSaleStatusEnum} 55 + * 操作类型 {@link TradeAfterSaleStatusEnum}
76 */ 56 */
77 - private Integer afterStatus; 57 + private String operateType;
78 /** 58 /**
79 * 操作明细 59 * 操作明细
80 */ 60 */
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; @@ -5,6 +5,8 @@ import cn.hutool.core.util.RandomUtil;
5 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; 5 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 7 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
  8 +import cn.iocoder.yudao.framework.trade.core.dto.TradeAfterSaleLogCreateReqDTO;
  9 +import cn.iocoder.yudao.framework.trade.core.service.AfterSaleLogService;
8 import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; 10 import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
9 import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; 11 import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
10 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO; 12 import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO;
@@ -26,6 +28,8 @@ import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEn @@ -26,6 +28,8 @@ import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEn
26 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; 28 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
27 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; 29 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
28 import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; 30 import cn.iocoder.yudao.module.trade.service.order.TradeOrderService;
  31 +import lombok.extern.slf4j.Slf4j;
  32 +import org.springframework.scheduling.annotation.Async;
29 import org.springframework.stereotype.Service; 33 import org.springframework.stereotype.Service;
30 import org.springframework.transaction.annotation.Transactional; 34 import org.springframework.transaction.annotation.Transactional;
31 import org.springframework.transaction.support.TransactionSynchronization; 35 import org.springframework.transaction.support.TransactionSynchronization;
@@ -43,9 +47,10 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; @@ -43,9 +47,10 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
43 * 47 *
44 * @author 芋道源码 48 * @author 芋道源码
45 */ 49 */
  50 +@Slf4j
46 @Service 51 @Service
47 @Validated 52 @Validated
48 -public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { 53 +public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSaleLogService {
49 54
50 @Resource 55 @Resource
51 private TradeOrderService tradeOrderService; 56 private TradeOrderService tradeOrderService;
@@ -80,7 +85,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { @@ -80,7 +85,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
80 /** 85 /**
81 * 校验交易订单项是否可以申请售后 86 * 校验交易订单项是否可以申请售后
82 * 87 *
83 - * @param userId 用户编号 88 + * @param userId 用户编号
84 * @param createReqVO 售后创建信息 89 * @param createReqVO 售后创建信息
85 * @return 交易订单项 90 * @return 交易订单项
86 */ 91 */
@@ -117,7 +122,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { @@ -117,7 +122,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
117 } 122 }
118 // 如果是【退货退款】的情况,需要额外校验是否发货 123 // 如果是【退货退款】的情况,需要额外校验是否发货
119 if (createReqVO.getWay().equals(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay()) 124 if (createReqVO.getWay().equals(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
120 - && !TradeOrderStatusEnum.haveDelivered(order.getStatus())) { 125 + && !TradeOrderStatusEnum.haveDelivered(order.getStatus())) {
121 throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED); 126 throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED);
122 } 127 }
123 return orderItem; 128 return orderItem;
@@ -133,7 +138,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { @@ -133,7 +138,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
133 TradeOrderDO order = tradeOrderService.getOrder(orderItem.getUserId(), orderItem.getOrderId()); 138 TradeOrderDO order = tradeOrderService.getOrder(orderItem.getUserId(), orderItem.getOrderId());
134 afterSale.setOrderNo(order.getNo()); // 记录 orderNo 订单流水,方便后续检索 139 afterSale.setOrderNo(order.getNo()); // 记录 orderNo 订单流水,方便后续检索
135 afterSale.setType(TradeOrderStatusEnum.isCompleted(order.getStatus()) 140 afterSale.setType(TradeOrderStatusEnum.isCompleted(order.getStatus())
136 - ? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType()); 141 + ? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType());
137 // TODO 退还积分 142 // TODO 退还积分
138 tradeAfterSaleMapper.insert(afterSale); 143 tradeAfterSaleMapper.insert(afterSale);
139 144
@@ -380,13 +385,38 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { @@ -380,13 +385,38 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
380 TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null); 385 TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null);
381 } 386 }
382 387
  388 + @Deprecated
383 private void createAfterSaleLog(Long userId, Integer userType, TradeAfterSaleDO afterSale, 389 private void createAfterSaleLog(Long userId, Integer userType, TradeAfterSaleDO afterSale,
384 Integer beforeStatus, Integer afterStatus) { 390 Integer beforeStatus, Integer afterStatus) {
385 - TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO().setUserId(userId).setUserType(userType)  
386 - .setAfterSaleId(afterSale.getId()).setOrderId(afterSale.getOrderId())  
387 - .setOrderItemId(afterSale.getOrderItemId()).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus)  
388 - .setContent(TradeAfterSaleStatusEnum.valueOf(afterStatus).getContent());  
389 - tradeAfterSaleLogMapper.insert(afterSaleLog); 391 + TradeAfterSaleLogCreateReqDTO logDTO = new TradeAfterSaleLogCreateReqDTO()
  392 + .setUserId(userId)
  393 + .setUserType(userType)
  394 + .setAfterSaleId(afterSale.getId())
  395 + .setOperateType(afterStatus.toString());
  396 + // TODO 废弃,待删除
  397 + this.insert(logDTO);
390 } 398 }
391 399
  400 + /**
  401 + * 日志记录
  402 + *
  403 + * @param logDTO 日志记录
  404 + * @author 陈賝
  405 + * @date 2023/6/12 14:18
  406 + */
  407 + @Override
  408 + @Async
  409 + public void insert(TradeAfterSaleLogCreateReqDTO logDTO) {
  410 + try {
  411 + TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO()
  412 + .setUserId(logDTO.getUserId())
  413 + .setUserType(logDTO.getUserType())
  414 + .setAfterSaleId(logDTO.getAfterSaleId())
  415 + .setOperateType(logDTO.getOperateType())
  416 + .setContent(logDTO.getContent());
  417 + tradeAfterSaleLogMapper.insert(afterSaleLog);
  418 + }catch (Exception exception){
  419 + log.error("日志记录错误", exception);
  420 + }
  421 + }
392 } 422 }
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 { @@ -66,6 +66,7 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
66 AppTradeAfterSaleCreateReqVO createReqVO = new AppTradeAfterSaleCreateReqVO() 66 AppTradeAfterSaleCreateReqVO createReqVO = new AppTradeAfterSaleCreateReqVO()
67 .setOrderItemId(1L).setRefundPrice(100).setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay()) 67 .setOrderItemId(1L).setRefundPrice(100).setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
68 .setApplyReason("退钱").setApplyDescription("快退") 68 .setApplyReason("退钱").setApplyDescription("快退")
  69 + .setOperateType("APPLY")
69 .setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png")); 70 .setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png"));
70 // mock 方法(交易订单项) 71 // mock 方法(交易订单项)
71 TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> { 72 TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> {
@@ -102,8 +103,8 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest { @@ -102,8 +103,8 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
102 assertEquals(afterSaleLog.getUserType(), UserTypeEnum.MEMBER.getValue()); 103 assertEquals(afterSaleLog.getUserType(), UserTypeEnum.MEMBER.getValue());
103 assertEquals(afterSaleLog.getAfterSaleId(), afterSaleId); 104 assertEquals(afterSaleLog.getAfterSaleId(), afterSaleId);
104 assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime"); 105 assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime");
105 - assertNull(afterSaleLog.getBeforeStatus());  
106 - assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus()); 106 +// assertNull(afterSaleLog.getBeforeStatus());
  107 +// assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus());
107 assertEquals(afterSaleLog.getContent(), TradeAfterSaleStatusEnum.APPLY.getContent()); 108 assertEquals(afterSaleLog.getContent(), TradeAfterSaleStatusEnum.APPLY.getContent());
108 } 109 }
109 110
yudao-server/pom.xml
@@ -54,11 +54,11 @@ @@ -54,11 +54,11 @@
54 <!-- <version>${revision}</version>--> 54 <!-- <version>${revision}</version>-->
55 <!-- </dependency>--> 55 <!-- </dependency>-->
56 <!-- 支付服务 --> 56 <!-- 支付服务 -->
57 -<!-- <dependency>-->  
58 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
59 -<!-- <artifactId>yudao-module-pay-biz</artifactId>-->  
60 -<!-- <version>${revision}</version>-->  
61 -<!-- </dependency>--> 57 + <dependency>
  58 + <groupId>cn.iocoder.boot</groupId>
  59 + <artifactId>yudao-module-pay-biz</artifactId>
  60 + <version>${revision}</version>
  61 + </dependency>
62 62
63 <!-- 微信公众号模块。默认注释,保证编译速度 --> 63 <!-- 微信公众号模块。默认注释,保证编译速度 -->
64 <!-- <dependency>--> 64 <!-- <dependency>-->
@@ -68,25 +68,19 @@ @@ -68,25 +68,19 @@
68 <!-- </dependency>--> 68 <!-- </dependency>-->
69 69
70 <!-- 商城相关模块。默认注释,保证编译速度 --> 70 <!-- 商城相关模块。默认注释,保证编译速度 -->
71 -<!-- <dependency>-->  
72 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
73 -<!-- <artifactId>yudao-module-promotion-biz</artifactId>-->  
74 -<!-- <version>${revision}</version>-->  
75 -<!-- </dependency>-->  
76 -<!-- <dependency>-->  
77 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
78 -<!-- <artifactId>yudao-module-product-biz</artifactId>-->  
79 -<!-- <version>${revision}</version>-->  
80 -<!-- </dependency>-->  
81 -<!-- <dependency>-->  
82 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
83 -<!-- <artifactId>yudao-module-trade-biz</artifactId>-->  
84 -<!-- <version>${revision}</version>-->  
85 -<!-- </dependency>-->  
86 -  
87 <dependency> 71 <dependency>
88 <groupId>cn.iocoder.boot</groupId> 72 <groupId>cn.iocoder.boot</groupId>
89 - <artifactId>yudao-module-point-biz</artifactId> 73 + <artifactId>yudao-module-promotion-biz</artifactId>
  74 + <version>${revision}</version>
  75 + </dependency>
  76 + <dependency>
  77 + <groupId>cn.iocoder.boot</groupId>
  78 + <artifactId>yudao-module-product-biz</artifactId>
  79 + <version>${revision}</version>
  80 + </dependency>
  81 + <dependency>
  82 + <groupId>cn.iocoder.boot</groupId>
  83 + <artifactId>yudao-module-trade-biz</artifactId>
90 <version>${revision}</version> 84 <version>${revision}</version>
91 </dependency> 85 </dependency>
92 86