Commit 20100aa78b95cd976ec8180a1a26d9ad1eca6d1c

Authored by puhui999
1 parent dde89d51

fix:完善商品评论

Showing 27 changed files with 536 additions and 326 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApi.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.comment;
  2 +
  3 +import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
  4 +
  5 +/**
  6 + * 产品评论 API 接口
  7 + *
  8 + * @author HUIHUI
  9 + */
  10 +public interface ProductCommentApi {
  11 +
  12 + /**
  13 + * 创建评论
  14 + *
  15 + * @param createReqDTO 评论参数
  16 + * @param orderId 订单 id
  17 + * @return 返回评论创建后的 id
  18 + */
  19 + Long createComment(CommentCreateReqDTO createReqDTO, Long orderId);
  20 +
  21 +}
... ...
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/dto/CommentCreateReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.comment.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import java.util.List;
  6 +
  7 +/**
  8 + * 评论创建请求 DTO
  9 + *
  10 + * @author HUIHUI
  11 + */
  12 +@Data
  13 +public class CommentCreateReqDTO {
  14 +
  15 + /**
  16 + * 是否匿名
  17 + */
  18 + private Boolean anonymous;
  19 +
  20 + /**
  21 + * 交易订单项编号
  22 + */
  23 + private Long orderItemId;
  24 +
  25 + /**
  26 + * 商品 SPU 编号
  27 + */
  28 + private Long spuId;
  29 +
  30 + /**
  31 + * 商品 SPU 名称
  32 + */
  33 + private String spuName;
  34 +
  35 + /**
  36 + * 商品 SKU 编号
  37 + */
  38 + private Long skuId;
  39 +
  40 + /**
  41 + * 评分星级 1-5 分
  42 + */
  43 + private Integer scores;
  44 +
  45 + /**
  46 + * 描述星级 1-5 分
  47 + */
  48 + private Integer descriptionScores;
  49 +
  50 + /**
  51 + * 服务星级 1-5 分
  52 + */
  53 + private Integer benefitScores;
  54 +
  55 + /**
  56 + * 评论内容
  57 + */
  58 + private String content;
  59 +
  60 + /**
  61 + * 评论图片地址数组,以逗号分隔最多上传9张
  62 + */
  63 + private List<String> picUrls;
  64 +
  65 + /**
  66 + * 评价人名称
  67 + */
  68 + private String userNickname;
  69 +
  70 + /**
  71 + * 评价人头像
  72 + */
  73 + private String userAvatar;
  74 +
  75 + /**
  76 + * 评价人
  77 + */
  78 + private Long userId;
  79 +
  80 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/comment/ProductCommentApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.comment;
  2 +
  3 +import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
  4 +import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
  5 +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
  6 +import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
  7 +import org.springframework.stereotype.Service;
  8 +import org.springframework.validation.annotation.Validated;
  9 +
  10 +import javax.annotation.Resource;
  11 +
  12 +/**
  13 + * 商品评论 API 实现类
  14 + *
  15 + * @author HUIHUI
  16 + */
  17 +@Service
  18 +@Validated
  19 +public class ProductCommentApiImpl implements ProductCommentApi {
  20 + @Resource
  21 + private ProductCommentService productCommentService;
  22 +
  23 + @Override
  24 + public Long createComment(CommentCreateReqDTO createReqDTO, Long orderId) {
  25 + ProductCommentDO commentDO = ProductCommentConvert.INSTANCE.convert(createReqDTO, orderId);
  26 + return productCommentService.createComment(commentDO);
  27 + }
  28 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java
... ... @@ -35,8 +35,7 @@ public class ProductCommentController {
35 35 return success(ProductCommentConvert.INSTANCE.convertPage(pageResult));
36 36 }
37 37  
38   - // TODO @puhui999:update-visible
39   - @PutMapping("/update/visible")
  38 + @PutMapping("/update-visible")
40 39 @Operation(summary = "显示 / 隐藏评论")
41 40 @PreAuthorize("@ss.hasPermission('product:comment:update')")
42 41 public CommonResult<Boolean> updateCommentVisible(@Valid @RequestBody ProductCommentUpdateVisibleReqVO updateReqVO) {
... ... @@ -48,7 +47,7 @@ public class ProductCommentController {
48 47 @Operation(summary = "商家回复")
49 48 @PreAuthorize("@ss.hasPermission('product:comment:update')")
50 49 public CommonResult<Boolean> commentReply(@Valid @RequestBody ProductCommentReplyVO replyVO) {
51   - productCommentService.commentReply(replyVO, getLoginUserId());
  50 + productCommentService.replyComment(replyVO, getLoginUserId());
52 51 return success(true);
53 52 }
54 53  
... ... @@ -56,8 +55,7 @@ public class ProductCommentController {
56 55 @Operation(summary = "添加自评")
57 56 @PreAuthorize("@ss.hasPermission('product:comment:update')")
58 57 public CommonResult<Boolean> createComment(@Valid @RequestBody ProductCommentCreateReqVO createReqVO) {
59   - // TODO @puhui999:不用 ProductCommentConvert.INSTANCE.convert(createReqVO) 哈;多写一个 create 方法即可;
60   - productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(createReqVO), Boolean.TRUE);
  58 + productCommentService.createComment(createReqVO);
61 59 return success(true);
62 60 }
63 61  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java
... ... @@ -10,17 +10,15 @@ import java.util.List;
10 10 @Data
11 11 public class ProductCommentBaseVO {
12 12  
13   - // TODO @puhui999:把 example 补充下
14   -
15   - @Schema(description = "评价人名称", required = true, example = "张三")
  13 + @Schema(description = "评价人名称", required = true, example = "小姑凉")
16 14 @NotNull(message = "评价人名称不能为空")
17 15 private String userNickname;
18 16  
19   - @Schema(description = "评价人头像", required = true)
  17 + @Schema(description = "评价人头像", required = true, example = "https://www.iocoder.cn/xx.png")
20 18 @NotNull(message = "评价人头像不能为空")
21 19 private String userAvatar;
22 20  
23   - @Schema(description = "商品 SPU 编号", required = true, example = "29502")
  21 + @Schema(description = "商品 SPU 编号", required = true, example = "清凉丝滑透气小短袖")
24 22 @NotNull(message = "商品 SPU 编号不能为空")
25 23 private Long spuId;
26 24  
... ... @@ -28,27 +26,27 @@ public class ProductCommentBaseVO {
28 26 @NotNull(message = "商品 SPU 名称不能为空")
29 27 private String spuName;
30 28  
31   - @Schema(description = "商品 SKU 编号", required = true, example = "3082")
  29 + @Schema(description = "商品 SKU 编号", required = true, example = "1")
32 30 @NotNull(message = "商品 SKU 编号不能为空")
33 31 private Long skuId;
34 32  
35   - @Schema(description = "评分星级 1-5分", required = true)
  33 + @Schema(description = "评分星级 1-5分", required = true, example = "5")
36 34 @NotNull(message = "评分星级不能为空")
37 35 private Integer scores;
38 36  
39   - @Schema(description = "描述星级 1-5分", required = true)
  37 + @Schema(description = "描述星级 1-5分", required = true, example = "5")
40 38 @NotNull(message = "描述星级不能为空")
41 39 private Integer descriptionScores;
42 40  
43   - @Schema(description = "服务星级 1-5分", required = true)
  41 + @Schema(description = "服务星级 1-5分", required = true, example = "5")
44 42 @NotNull(message = "服务星级分不能为空")
45 43 private Integer benefitScores;
46 44  
47   - @Schema(description = "评论内容", required = true)
  45 + @Schema(description = "评论内容", required = true, example = "穿起来非常丝滑凉快")
48 46 @NotNull(message = "评论内容不能为空")
49 47 private String content;
50 48  
51   - @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true)
  49 + @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
52 50 @Size(max = 9, message = "评论图片地址数组长度不能超过9张")
53 51 private List<String> picUrls;
54 52  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java
1 1 package cn.iocoder.yudao.module.product.controller.admin.comment.vo;
2 2  
3   -import lombok.*;
4 3 import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import javax.validation.constraints.NotNull;
5 9  
6 10 @Schema(description = "管理后台 - 商品评价创建 Request VO")
7 11 @Data
... ... @@ -9,4 +13,12 @@ import io.swagger.v3.oas.annotations.media.Schema;
9 13 @ToString(callSuper = true)
10 14 public class ProductCommentCreateReqVO extends ProductCommentBaseVO {
11 15  
  16 + @Schema(description = "评价人", required = true, example = "16868")
  17 + @NotNull(message = "评价人不能为空")
  18 + private Long userId;
  19 +
  20 + @Schema(description = "评价订单项", required = true, example = "19292")
  21 + @NotNull(message = "评价订单项不能为空")
  22 + private Long orderItemId;
  23 +
12 24 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java
... ... @@ -31,11 +31,11 @@ public class ProductCommentPageReqVO extends PageParam {
31 31 @Schema(description = "商品SPU名称", example = "感冒药")
32 32 private String spuName;
33 33  
34   - @Schema(description = "评分星级 1-5分")
  34 + @Schema(description = "评分星级 1-5分", example = "5")
35 35 @InEnum(ProductCommentScoresEnum.class)
36 36 private Integer scores;
37 37  
38   - @Schema(description = "商家是否回复")
  38 + @Schema(description = "商家是否回复", example = "true")
39 39 private Boolean replied;
40 40  
41 41 @Schema(description = "创建时间")
... ...
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 16 @Schema(description = "订单项编号", required = true, example = "24965")
17 17 private Long id;
18 18  
19   - @Schema(description = "是否匿名:[false:不匿名 true:匿名]", required = true)
  19 + @Schema(description = "是否匿名:[false:不匿名 true:匿名]", required = true, example = "false")
20 20 private Boolean anonymous;
21 21  
22 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/AppCommentController.java deleted
1   -package cn.iocoder.yudao.module.product.controller.app.comment;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
5   -import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
6   -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
7   -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentCreateReqVO;
8   -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
9   -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO;
10   -import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
11   -import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
12   -import io.swagger.v3.oas.annotations.Operation;
13   -import io.swagger.v3.oas.annotations.tags.Tag;
14   -import org.springframework.validation.annotation.Validated;
15   -import org.springframework.web.bind.annotation.*;
16   -
17   -import javax.annotation.Resource;
18   -import javax.validation.Valid;
19   -import java.util.Map;
20   -
21   -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
22   -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
23   -
24   -// TODO @puhui999:AppCommentController =》 AppProductCommentController
25   -@Tag(name = "用户 APP - 商品评价")
26   -@RestController
27   -@RequestMapping("/product/comment")
28   -@Validated
29   -public class AppCommentController {
30   -
31   - @Resource
32   - private ProductCommentService productCommentService;
33   -
34   - @Resource
35   - private MemberUserApi memberUserApi;
36   -
37   - @GetMapping("/page")
38   - @Operation(summary = "获得商品评价分页")
39   - public CommonResult<PageResult<AppCommentRespVO>> getCommentPage(@Valid AppCommentPageReqVO pageVO) {
40   - return success(productCommentService.getCommentPage(pageVO, Boolean.TRUE));
41   - }
42   -
43   - // TODO @puhui999:方法名改成 getCommentStatistics?然后搞个对应的 vo?想了下,这样更优雅
44   - @GetMapping("/get-count")
45   - @Operation(summary = "获得商品的评价统计") // TODO @puhui999:@RequestParam 哈,针对 spuId
46   - public CommonResult<Map<String, Long>> getCommentPage(@Valid Long spuId) {
47   - return success(productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE));
48   - }
49   -
50   - @PostMapping(value = "/create")
51   - @Operation(summary = "创建商品评价")
52   - public CommonResult<Boolean> createComment(@RequestBody AppCommentCreateReqVO createReqVO) {
53   - // TODO: 2023/3/20 要不要判断订单、商品是否存在
54   - // TODO @ouhui999:这个接口,搞到交易那比较合适;
55   - MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId());
56   - productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(user, createReqVO), Boolean.FALSE);
57   - return success(true);
58   - }
59   -
60   -}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.app.comment;
  2 +
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
  7 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
  8 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO;
  9 +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
  10 +import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
  11 +import io.swagger.v3.oas.annotations.Operation;
  12 +import io.swagger.v3.oas.annotations.tags.Tag;
  13 +import org.springframework.validation.annotation.Validated;
  14 +import org.springframework.web.bind.annotation.GetMapping;
  15 +import org.springframework.web.bind.annotation.RequestMapping;
  16 +import org.springframework.web.bind.annotation.RequestParam;
  17 +import org.springframework.web.bind.annotation.RestController;
  18 +
  19 +import javax.annotation.Resource;
  20 +import javax.validation.Valid;
  21 +
  22 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  23 +
  24 +@Tag(name = "用户 APP - 商品评价")
  25 +@RestController
  26 +@RequestMapping("/product/comment")
  27 +@Validated
  28 +public class AppProductCommentController {
  29 +
  30 + @Resource
  31 + private ProductCommentService productCommentService;
  32 +
  33 + @GetMapping("/page")
  34 + @Operation(summary = "获得商品评价分页")
  35 + public CommonResult<PageResult<AppProductCommentRespVO>> getCommentPage(@Valid AppCommentPageReqVO pageVO) {
  36 + PageResult<AppProductCommentRespVO> result = productCommentService.getCommentPage(pageVO, Boolean.TRUE);
  37 + result.getList().forEach(item -> {
  38 + // 判断用户是否选择匿名
  39 + if (ObjectUtil.equal(item.getAnonymous(), true)) {
  40 + item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS);
  41 + }
  42 + });
  43 + return success(result);
  44 + }
  45 +
  46 + @GetMapping("/getCommentStatistics")
  47 + @Operation(summary = "获得商品的评价统计")
  48 + public CommonResult<AppCommentStatisticsRespVO> getCommentPage(@Valid @RequestParam("spuId") Long spuId) {
  49 + return success(productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE));
  50 + }
  51 +
  52 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java
... ... @@ -14,28 +14,10 @@ import javax.validation.constraints.NotNull;
14 14 @ToString(callSuper = true)
15 15 public class AppCommentPageReqVO extends PageParam {
16 16  
17   - // TODO @puhui999:不传递就是 all;
18   - /**
19   - * 所有
20   - */
21   - public static final Integer ALL = 0;
22   -
23   - /**
24   - * 所有数量 key
25   - */
26   - public static final String ALL_COUNT = "allCount";
27   -
28   - // TODO @puhui999:good 好评;
29 17 /**
30 18 * 好评
31 19 */
32   - public static final Integer FAVOURABLE_COMMENT = 1;
33   -
34   - // TODO @puhui999:medium 中评;然后 mediumCount 就好啦;
35   - /**
36   - * 好评数量 key
37   - */
38   - public static final String FAVOURABLE_COMMENT_COUNT = "favourableCommentCount";
  20 + public static final Integer GOOD_COMMENT = 1;
39 21  
40 22 /**
41 23 * 中评
... ... @@ -43,26 +25,10 @@ public class AppCommentPageReqVO extends PageParam {
43 25 public static final Integer MEDIOCRE_COMMENT = 2;
44 26  
45 27 /**
46   - * 中评数量 key
47   - */
48   - public static final String MEDIOCRE_COMMENT_COUNT = "mediocreCommentCount";
49   -
50   - /**
51 28 * 差评
52 29 */
53 30 public static final Integer NEGATIVE_COMMENT = 3;
54 31  
55   - /**
56   - * 差评数量 key
57   - */
58   - public static final String NEGATIVE_COMMENT_COUNT = "negativeCommentCount";
59   -
60   - // TODO @puhui999:这个挪到 DO 那没问题的哈;NICKNAME_ANONYMOUS
61   - /**
62   - * 默认匿名昵称
63   - */
64   - public static final String ANONYMOUS_NICKNAME = "匿名用户";
65   -
66 32 @Schema(description = "商品SPU编号", example = "29502")
67 33 @NotNull(message = "商品SPU编号不能为空")
68 34 private Long spuId;
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentStatisticsRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.app.comment.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.ToString;
  6 +
  7 +/**
  8 + * APP 商品评价页评论分类数统计 Response VO
  9 + *
  10 + * @author HUIHUI
  11 + */
  12 +@Schema(description = "APP - 商品评价页评论分类数统计 Response VO")
  13 +@Data
  14 +@ToString(callSuper = true)
  15 +public class AppCommentStatisticsRespVO {
  16 +
  17 + @Schema(description = "所有评论数量", required = true, example = "15721")
  18 + private Long allCount;
  19 +
  20 + @Schema(description = "好评数量", required = true, example = "15721")
  21 + private Long goodCount;
  22 +
  23 + @Schema(description = "中评数量", required = true, example = "15721")
  24 + private Long mediocreCount;
  25 +
  26 + @Schema(description = "差评数量", required = true, example = "15721")
  27 + private Long negativeCount;
  28 +
  29 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java renamed to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentBaseVO.java
... ... @@ -7,39 +7,43 @@ import javax.validation.constraints.NotNull;
7 7 import javax.validation.constraints.Size;
8 8 import java.util.List;
9 9  
10   -// TODO @puhui999:把 Product 前缀给补下哈
  10 +/**
  11 + * 商品评论 Base VO
  12 + *
  13 + * @author HUIHUI
  14 + */
11 15 @Data
12   -public class AppCommentBaseVO {
  16 +public class AppProductCommentBaseVO {
13 17  
14   - @Schema(description = "商品SPU编号", required = true, example = "29502")
  18 + @Schema(description = "商品SPU编号", required = true, example = "91192")
15 19 @NotNull(message = "商品SPU编号不能为空")
16 20 private Long spuId;
17 21  
18   - @Schema(description = "商品SPU名称", required = true, example = "赵六")
  22 + @Schema(description = "商品SPU名称", required = true, example = "清凉丝滑小短袖")
19 23 @NotNull(message = "商品SPU名称不能为空")
20 24 private String spuName;
21 25  
22   - @Schema(description = "商品SKU编号", required = true, example = "3082")
  26 + @Schema(description = "商品SKU编号", required = true, example = "81192")
23 27 @NotNull(message = "商品SKU编号不能为空")
24 28 private Long skuId;
25 29  
26   - @Schema(description = "评分星级 1-5分", required = true)
  30 + @Schema(description = "评分星级 1-5分", required = true, example = "5")
27 31 @NotNull(message = "评分星级 1-5分不能为空")
28 32 private Integer scores;
29 33  
30   - @Schema(description = "描述星级 1-5分", required = true)
  34 + @Schema(description = "描述星级 1-5分", required = true, example = "5")
31 35 @NotNull(message = "描述星级 1-5分不能为空")
32 36 private Integer descriptionScores;
33 37  
34   - @Schema(description = "服务星级 1-5分", required = true)
  38 + @Schema(description = "服务星级 1-5分", required = true, example = "5")
35 39 @NotNull(message = "服务星级 1-5分不能为空")
36 40 private Integer benefitScores;
37 41  
38   - @Schema(description = "评论内容", required = true)
  42 + @Schema(description = "评论内容", required = true, example = "哇,真的很丝滑凉快诶,好评")
39 43 @NotNull(message = "评论内容不能为空")
40 44 private String content;
41 45  
42   - @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true)
  46 + @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
43 47 @Size(max = 9, message = "评论图片地址数组长度不能超过9张")
44 48 private List<String> picUrls;
45 49  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java renamed to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentCreateReqVO.java
... ... @@ -7,23 +7,17 @@ import lombok.ToString;
7 7  
8 8 import javax.validation.constraints.NotNull;
9 9  
10   -// TODO @puhui999:不应该继承 AppCommentCreateReqVO
  10 +// TODO @puhui999:不应该继承 AppProductCommentCreateReqVO
11 11 @Schema(description = "用户APP - 商品评价创建 Request VO")
12 12 @Data
13 13 @EqualsAndHashCode(callSuper = true)
14 14 @ToString(callSuper = true)
15   -public class AppCommentCreateReqVO extends AppCommentBaseVO {
  15 +public class AppProductCommentCreateReqVO extends AppProductCommentBaseVO {
16 16  
17 17 @Schema(description = "是否匿名", required = true, example = "true")
18 18 @NotNull(message = "是否匿名不能为空")
19 19 private Boolean anonymous;
20 20  
21   - // TODO @puhui999:不应该传递 orderId
22   -
23   - @Schema(description = "交易订单编号", required = true, example = "12312")
24   - @NotNull(message = "交易订单编号不能为空")
25   - private Long orderId;
26   -
27 21 @Schema(description = "交易订单项编号", required = true, example = "2312312")
28 22 @NotNull(message = "交易订单项编号不能为空")
29 23 private Long orderItemId;
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java renamed to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java
... ... @@ -4,17 +4,18 @@ import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
5 5 import lombok.EqualsAndHashCode;
6 6 import lombok.ToString;
  7 +import org.springframework.format.annotation.DateTimeFormat;
7 8  
8 9 import java.time.LocalDateTime;
9 10 import java.util.List;
10 11  
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
11 14 @Schema(description = "用户APP - 商品评价 Response VO")
12 15 @Data
13 16 @EqualsAndHashCode(callSuper = true)
14 17 @ToString(callSuper = true)
15   -public class AppCommentRespVO extends AppCommentBaseVO {
16   -
17   - // TODO puhui999:把 example 也补充下哈
  18 +public class AppProductCommentRespVO extends AppProductCommentBaseVO {
18 19  
19 20 @Schema(description = "评价人的用户编号", required = true, example = "15721")
20 21 private Long userId;
... ... @@ -22,13 +23,13 @@ public class AppCommentRespVO extends AppCommentBaseVO {
22 23 @Schema(description = "评价人名称", required = true, example = "张三")
23 24 private String userNickname;
24 25  
25   - @Schema(description = "评价人头像", required = true)
  26 + @Schema(description = "评价人头像", required = true, example = "https://www.iocoder.cn/xx.png")
26 27 private String userAvatar;
27 28  
28 29 @Schema(description = "订单项编号", required = true, example = "24965")
29 30 private Long id;
30 31  
31   - @Schema(description = "是否匿名", required = true)
  32 + @Schema(description = "是否匿名", required = true, example = "false")
32 33 private Boolean anonymous;
33 34  
34 35 @Schema(description = "交易订单编号", required = true, example = "24428")
... ... @@ -37,31 +38,31 @@ public class AppCommentRespVO extends AppCommentBaseVO {
37 38 @Schema(description = "交易订单项编号", required = true, example = "8233")
38 39 private Long orderItemId;
39 40  
40   - @Schema(description = "商家是否回复", required = true)
  41 + @Schema(description = "商家是否回复", required = true, example = "true")
41 42 private Boolean replyStatus;
42 43  
43 44 @Schema(description = "回复管理员编号", example = "22212")
44 45 private Long replyUserId;
45 46  
46   - @Schema(description = "商家回复内容")
  47 + @Schema(description = "商家回复内容", example = "亲,你的好评就是我的动力(*^▽^*)")
47 48 private String replyContent;
48 49  
49 50 @Schema(description = "商家回复时间")
  51 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
50 52 private LocalDateTime replyTime;
51 53  
52   - @Schema(description = "追加评价内容")
  54 + @Schema(description = "追加评价内容", example = "穿了很久都很丝滑诶")
53 55 private String additionalContent;
54 56  
55   - @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张")
  57 + @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张", example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
56 58 private List<String> additionalPicUrls;
57 59  
58 60 @Schema(description = "追加评价时间")
  61 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
59 62 private LocalDateTime additionalTime;
60 63  
61   - @Schema(description = "创建时间", required = true)
  64 + @Schema(description = "创建时间")
  65 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
62 66 private LocalDateTime createTime;
63 67  
64   - @Schema(description = "最终评分", required = true)
65   - private Integer finalScore;
66   -
67 68 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java
... ... @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
9 9 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
10 10 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
11 11 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
12   -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
13 12 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
14 13 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
15 14 import io.swagger.v3.oas.annotations.Operation;
... ... @@ -40,8 +39,6 @@ public class AppProductSpuController {
40 39 private ProductSpuService productSpuService;
41 40 @Resource
42 41 private ProductSkuService productSkuService;
43   - @Resource
44   - private ProductPropertyValueService productPropertyValueService;
45 42  
46 43 @GetMapping("/page")
47 44 @Operation(summary = "获得商品 SPU 分页")
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java
1 1 package cn.iocoder.yudao.module.product.convert.comment;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
  4 +import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
5 5 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO;
6 6 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO;
7   -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentCreateReqVO;
8   -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO;
  7 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
  8 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO;
9 9 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
10 10 import org.mapstruct.Mapper;
  11 +import org.mapstruct.Mapping;
  12 +import org.mapstruct.Named;
11 13 import org.mapstruct.factory.Mappers;
12 14  
  15 +import java.math.BigDecimal;
  16 +import java.math.RoundingMode;
13 17 import java.util.List;
14 18  
15 19 /**
... ... @@ -24,50 +28,42 @@ public interface ProductCommentConvert {
24 28  
25 29 ProductCommentRespVO convert(ProductCommentDO bean);
26 30  
  31 + @Mapping(target = "allCount", source = "allCount")
  32 + @Mapping(target = "goodCount", source = "goodCount")
  33 + @Mapping(target = "mediocreCount", source = "mediocreCount")
  34 + @Mapping(target = "negativeCount", source = "negativeCount")
  35 + AppCommentStatisticsRespVO convert(Long allCount, Long goodCount, Long mediocreCount, Long negativeCount);
  36 +
27 37 List<ProductCommentRespVO> convertList(List<ProductCommentDO> list);
28 38  
29 39 PageResult<ProductCommentRespVO> convertPage(PageResult<ProductCommentDO> page);
30 40  
31   - PageResult<AppCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult);
  41 + PageResult<AppProductCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult);
32 42  
33   - // TODO @puhui999:用 mapstruct 的映射
34   - default ProductCommentDO convert(MemberUserRespDTO user, AppCommentCreateReqVO createReqVO) {
35   - ProductCommentDO productComment = new ProductCommentDO();
36   - productComment.setUserId(user.getId());
37   - productComment.setUserNickname(user.getNickname());
38   - productComment.setUserAvatar(user.getAvatar());
39   - productComment.setAnonymous(createReqVO.getAnonymous());
40   - productComment.setOrderId(createReqVO.getOrderId());
41   - productComment.setOrderItemId(createReqVO.getOrderItemId());
42   - productComment.setSpuId(createReqVO.getSpuId());
43   - productComment.setSpuName(createReqVO.getSpuName());
44   - productComment.setSkuId(createReqVO.getSkuId());
45   - productComment.setScores(createReqVO.getScores());
46   - productComment.setDescriptionScores(createReqVO.getDescriptionScores());
47   - productComment.setBenefitScores(createReqVO.getBenefitScores());
48   - productComment.setContent(createReqVO.getContent());
49   - productComment.setPicUrls(createReqVO.getPicUrls());
50   - return productComment;
  43 + /**
  44 + * 计算综合评分
  45 + *
  46 + * @param descriptionScores 描述星级
  47 + * @param benefitScores 服务星级
  48 + * @return {@link Integer}
  49 + */
  50 + @Named("convertScores")
  51 + default Integer convertScores(Integer descriptionScores, Integer benefitScores) {
  52 + // 计算评价最终综合评分 最终星数 = (商品评星 + 服务评星) / 2
  53 + BigDecimal sumScore = new BigDecimal(descriptionScores + benefitScores);
  54 + BigDecimal divide = sumScore.divide(BigDecimal.valueOf(2L), 0, RoundingMode.DOWN);
  55 + return divide.intValue();
51 56 }
52 57  
53   - // TODO @puhui999:用 mapstruct 的映射
54   - default ProductCommentDO convert(ProductCommentCreateReqVO createReq) {
55   - ProductCommentDO productComment = new ProductCommentDO();
56   - productComment.setUserId(0L);
57   - productComment.setUserNickname(createReq.getUserNickname());
58   - productComment.setUserAvatar(createReq.getUserAvatar());
59   - productComment.setAnonymous(Boolean.FALSE);
60   - productComment.setOrderId(0L);
61   - productComment.setOrderItemId(0L);
62   - productComment.setSpuId(createReq.getSpuId());
63   - productComment.setSpuName(createReq.getSpuName());
64   - productComment.setSkuId(createReq.getSkuId());
65   - productComment.setScores(createReq.getScores());
66   - productComment.setDescriptionScores(createReq.getDescriptionScores());
67   - productComment.setBenefitScores(createReq.getBenefitScores());
68   - productComment.setContent(createReq.getContent());
69   - productComment.setPicUrls(createReq.getPicUrls());
70   - return productComment;
71   - }
  58 + @Mapping(target = "orderId", source = "orderId")
  59 + @Mapping(target = "scores", expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))")
  60 + ProductCommentDO convert(CommentCreateReqDTO createReqDTO, Long orderId);
  61 +
  62 + @Mapping(target = "userId", constant = "0L")
  63 + @Mapping(target = "orderId", constant = "0L")
  64 + @Mapping(target = "orderItemId", constant = "0L")
  65 + @Mapping(target = "anonymous", expression = "java(Boolean.FALSE)")
  66 + @Mapping(target = "scores", expression = "java(convertScores(createReq.getDescriptionScores(), createReq.getBenefitScores()))")
  67 + ProductCommentDO convert(ProductCommentCreateReqVO createReq);
72 68  
73 69 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java
... ... @@ -29,6 +29,11 @@ import java.util.List;
29 29 public class ProductCommentDO extends BaseDO {
30 30  
31 31 /**
  32 + * 默认匿名昵称
  33 + */
  34 + public static final String NICKNAME_ANONYMOUS = "匿名用户";
  35 +
  36 + /**
32 37 * 评论编号,主键自增
33 38 */
34 39 @TableId
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java
... ... @@ -31,7 +31,7 @@ public interface ProductCommentMapper extends BaseMapperX&lt;ProductCommentDO&gt; {
31 31 // TODO 芋艿:在看看这块
32 32 static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) {
33 33 // 构建好评查询语句:好评计算 (商品评分星级+服务评分星级) >= 8
34   - if (ObjectUtil.equal(type, AppCommentPageReqVO.FAVOURABLE_COMMENT)) {
  34 + if (ObjectUtil.equal(type, AppCommentPageReqVO.GOOD_COMMENT)) {
35 35 queryWrapper.apply("(scores + benefit_scores) >= 8");
36 36 }
37 37 // 构建中评查询语句:中评计算 (商品评分星级+服务评分星级) > 4 且 (商品评分星级+服务评分星级) < 8
... ... @@ -72,16 +72,14 @@ public interface ProductCommentMapper extends BaseMapperX&lt;ProductCommentDO&gt; {
72 72 update(null, lambdaUpdateWrapper);
73 73 }
74 74  
75   - // TODO @puhui999:使用 select 替代 find
76   - default ProductCommentDO findByUserIdAndOrderIdAndSpuId(Long userId, Long orderId, Long spuId) {
  75 + default ProductCommentDO selectByUserIdAndOrderIdAndSpuId(Long userId, Long orderId, Long spuId) {
77 76 return selectOne(new LambdaQueryWrapperX<ProductCommentDO>()
78 77 .eq(ProductCommentDO::getUserId, userId)
79 78 .eq(ProductCommentDO::getOrderId, orderId)
80 79 .eq(ProductCommentDO::getSpuId, spuId));
81 80 }
82 81  
83   - // TODO @puhui999:selectCountBySpuId 即可
84   - default Long selectTabCount(Long spuId, Boolean visible, Integer type) {
  82 + default Long selectCountBySpuId(Long spuId, Boolean visible, Integer type) {
85 83 LambdaQueryWrapperX<ProductCommentDO> queryWrapper = new LambdaQueryWrapperX<ProductCommentDO>()
86 84 .eqIfPresent(ProductCommentDO::getSpuId, spuId)
87 85 .eqIfPresent(ProductCommentDO::getVisible, visible);
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java
1 1 package cn.iocoder.yudao.module.product.service.comment;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO;
4 5 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO;
5 6 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO;
6 7 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO;
7 8 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
8   -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO;
  9 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
  10 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO;
9 11 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
10 12 import org.springframework.stereotype.Service;
11 13 import org.springframework.validation.annotation.Validated;
12 14  
13   -import java.util.Map;
14   -
15 15 /**
16 16 * 商品评论 Service 接口
17 17 *
... ... @@ -37,13 +37,14 @@ public interface ProductCommentService {
37 37 void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO);
38 38  
39 39 // TODO @puhui999:replyComment
  40 +
40 41 /**
41 42 * 商家回复
42 43 *
43 44 * @param replyVO 商家回复
44 45 * @param loginUserId 管理后台商家登陆人 ID
45 46 */
46   - void commentReply(ProductCommentReplyVO replyVO, Long loginUserId);
  47 + void replyComment(ProductCommentReplyVO replyVO, Long loginUserId);
47 48  
48 49 /**
49 50 * 获得商品评价分页
... ... @@ -52,15 +53,23 @@ public interface ProductCommentService {
52 53 * @param visible 是否可见
53 54 * @return 商品评价分页
54 55 */
55   - PageResult<AppCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
  56 + PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
  57 +
  58 + /**
  59 + * 创建商品评论 后台管理员创建评论使用
  60 + *
  61 + * @param createReqVO 商品评价创建 Request VO 对象
  62 + */
  63 + void createComment(ProductCommentCreateReqVO createReqVO);
56 64  
57 65 /**
58   - * 创建商品评论
  66 + * 创建评论
  67 + * 创建商品评论 APP 端创建商品评论使用
59 68 *
60   - * @param productComment 创建实体
61   - * @param system 是否系统评价
  69 + * @param commentDO 评论对象
  70 + * @return 返回评论 id
62 71 */
63   - void createComment(ProductCommentDO productComment, Boolean system);
  72 + Long createComment(ProductCommentDO commentDO);
64 73  
65 74 /**
66 75 * 获得商品的评价统计
... ... @@ -69,6 +78,6 @@ public interface ProductCommentService {
69 78 * @param visible 是否可见
70 79 * @return 评价统计
71 80 */
72   - Map<String, Long> getCommentPageTabsCount(Long spuId, Boolean visible);
  81 + AppCommentStatisticsRespVO getCommentPageTabsCount(Long spuId, Boolean visible);
73 82  
74 83 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java
1 1 package cn.iocoder.yudao.module.product.service.comment;
2 2  
3   -import cn.hutool.core.util.ObjectUtil;
4 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO;
5 5 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO;
6 6 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO;
7 7 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO;
8 8 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
9   -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO;
  9 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
  10 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO;
10 11 import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
11 12 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
12 13 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
13 14 import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper;
14 15 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
15 16 import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi;
16   -import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
17 17 import org.springframework.stereotype.Service;
  18 +import org.springframework.transaction.annotation.Transactional;
18 19 import org.springframework.validation.annotation.Validated;
19 20  
20 21 import javax.annotation.Resource;
21   -import java.math.BigDecimal;
22   -import java.math.RoundingMode;
23   -import java.util.HashMap;
24   -import java.util.Map;
  22 +import java.time.LocalDateTime;
25 23  
26 24 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
27 25 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
28   -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
29 26  
30 27 /**
31 28 * 商品评论 Service 实现类
... ... @@ -46,94 +43,96 @@ public class ProductCommentServiceImpl implements ProductCommentService {
46 43 private ProductSpuService productSpuService;
47 44  
48 45 @Override
49   - public PageResult<ProductCommentDO> getCommentPage(ProductCommentPageReqVO pageReqVO) {
50   - return productCommentMapper.selectPage(pageReqVO);
51   - }
52   -
53   - @Override
  46 + @Transactional(rollbackFor = Exception.class)
54 47 public void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO) {
55 48 // 校验评论是否存在
56   - validateCommentExists(updateReqVO.getId());
  49 + ProductCommentDO productCommentDO = validateCommentExists(updateReqVO.getId());
  50 + productCommentDO.setVisible(updateReqVO.getVisible());
57 51  
58 52 // 更新可见状态
59   - // TODO @puhui999:直接使用 update 操作
60   - productCommentMapper.updateCommentVisible(updateReqVO.getId(), updateReqVO.getVisible());
  53 + productCommentMapper.updateById(productCommentDO);
61 54 }
62 55  
63 56 @Override
64   - public void commentReply(ProductCommentReplyVO replyVO, Long loginUserId) {
  57 + @Transactional(rollbackFor = Exception.class)
  58 + public void replyComment(ProductCommentReplyVO replyVO, Long loginUserId) {
65 59 // 校验评论是否存在
66   - validateCommentExists(replyVO.getId());
  60 + ProductCommentDO productCommentDO = validateCommentExists(replyVO.getId());
  61 + productCommentDO.setReplyTime(LocalDateTime.now());
  62 + productCommentDO.setReplyUserId(loginUserId);
  63 + productCommentDO.setReplyStatus(Boolean.TRUE);
  64 + productCommentDO.setReplyContent(replyVO.getReplyContent());
67 65  
68 66 // 回复评论
69   - // TODO @puhui999:直接使用 update 操作
70   - productCommentMapper.commentReply(replyVO, loginUserId);
  67 + productCommentMapper.updateById(productCommentDO);
71 68 }
72 69  
73 70 @Override
74   - public Map<String, Long> getCommentPageTabsCount(Long spuId, Boolean visible) {
75   - Map<String, Long> countMap = new HashMap<>(4);
76   - // 查询商品 id = spuId 的所有评论数量
77   - countMap.put(AppCommentPageReqVO.ALL_COUNT,
78   - productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.ALL));
79   - // 查询商品 id = spuId 的所有好评数量
80   - countMap.put(AppCommentPageReqVO.FAVOURABLE_COMMENT_COUNT,
81   - productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.FAVOURABLE_COMMENT));
82   - // 查询商品 id = spuId 的所有中评数量
83   - countMap.put(AppCommentPageReqVO.MEDIOCRE_COMMENT_COUNT,
84   - productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT));
85   - // 查询商品 id = spuId 的所有差评数量
86   - countMap.put(AppCommentPageReqVO.NEGATIVE_COMMENT_COUNT,
87   - productCommentMapper.selectTabCount(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT));
88   - return countMap;
  71 + @Transactional(rollbackFor = Exception.class)
  72 + public void createComment(ProductCommentCreateReqVO createReqVO) {
  73 + // 校验订单
  74 + Long orderId = tradeOrderApi.validateOrder(createReqVO.getUserId(), createReqVO.getOrderItemId());
  75 + // 校验评论
  76 + validateComment(createReqVO.getSpuId(), createReqVO.getUserId(), orderId);
  77 +
  78 + ProductCommentDO commentDO = ProductCommentConvert.INSTANCE.convert(createReqVO);
  79 + productCommentMapper.insert(commentDO);
89 80 }
90 81  
91 82 @Override
92   - public PageResult<AppCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
93   - // TODO @puhui999:逻辑可以在 controller 做哈。让 service 简介一点;因为是 view 需要不展示昵称
94   - PageResult<AppCommentRespVO> result = ProductCommentConvert.INSTANCE.convertPage02(productCommentMapper.selectPage(pageVO, visible));
95   - result.getList().forEach(item -> {
96   - // 判断用户是否选择匿名
97   - if (ObjectUtil.equal(item.getAnonymous(), true)) {
98   - item.setUserNickname(AppCommentPageReqVO.ANONYMOUS_NICKNAME);
99   - }
100   - // TODO @puhui999:直接插入的时候,计算到 scores 字段里;这样就去掉 finalScore 字段哈
101   - // 计算评价最终综合评分 最终星数 = (商品评星 + 服务评星) / 2
102   - BigDecimal sumScore = new BigDecimal(item.getScores() + item.getBenefitScores());
103   - BigDecimal divide = sumScore.divide(BigDecimal.valueOf(2L), 0, RoundingMode.DOWN);
104   - item.setFinalScore(divide.intValue());
105   - });
106   - return result;
  83 + @Transactional(rollbackFor = Exception.class)
  84 + public Long createComment(ProductCommentDO commentDO) {
  85 + // 校验评论
  86 + validateComment(commentDO.getSpuId(), commentDO.getUserId(), commentDO.getOrderId());
  87 +
  88 + productCommentMapper.insert(commentDO);
  89 + return commentDO.getId();
107 90 }
108 91  
109   - @Override
110   - public void createComment(ProductCommentDO productComment, Boolean system) {
111   - // TODO @puhui999:这里不区分是否为 system;直接都校验
112   - if (!system) {
113   - // TODO 判断订单是否存在 fix;
114   - // TODO @puhui999:改成 order 那有个 comment 接口,哪里校验下;商品评论这里不校验订单是否存在哈
115   - TradeOrderRespDTO order = tradeOrderApi.getOrder(productComment.getOrderId());
116   - if (null == order) {
117   - throw exception(ORDER_NOT_FOUND);
118   - }
119   - ProductSpuDO spu = productSpuService.getSpu(productComment.getSpuId());
120   - if (null == spu) {
121   - throw exception(SPU_NOT_EXISTS);
122   - }
123   - // 判断当前订单的当前商品用户是否评价过
124   - ProductCommentDO exist = productCommentMapper.findByUserIdAndOrderIdAndSpuId(productComment.getId(), productComment.getOrderId(), productComment.getSpuId());
125   - if (null != exist) {
126   - throw exception(ORDER_SPU_COMMENT_EXISTS);
127   - }
  92 + // TODO 只有创建和更新诶 要不要删除接口
  93 +
  94 + private void validateComment(Long spuId, Long userId, Long orderId) {
  95 + ProductSpuDO spu = productSpuService.getSpu(spuId);
  96 + if (null == spu) {
  97 + throw exception(SPU_NOT_EXISTS);
  98 + }
  99 + // 判断当前订单的当前商品用户是否评价过
  100 + ProductCommentDO exist = productCommentMapper.selectByUserIdAndOrderIdAndSpuId(userId, orderId, spuId);
  101 + if (null != exist) {
  102 + throw exception(ORDER_SPU_COMMENT_EXISTS);
128 103 }
129   - productCommentMapper.insert(productComment);
130 104 }
131 105  
132   - private void validateCommentExists(Long id) {
  106 + private ProductCommentDO validateCommentExists(Long id) {
133 107 ProductCommentDO productComment = productCommentMapper.selectById(id);
134 108 if (productComment == null) {
135 109 throw exception(COMMENT_NOT_EXISTS);
136 110 }
  111 + return productComment;
  112 + }
  113 +
  114 + @Override
  115 + public AppCommentStatisticsRespVO getCommentPageTabsCount(Long spuId, Boolean visible) {
  116 + return ProductCommentConvert.INSTANCE.convert(
  117 + // 查询商品 id = spuId 的所有评论数量
  118 + productCommentMapper.selectCountBySpuId(spuId, visible, null),
  119 + // 查询商品 id = spuId 的所有好评数量
  120 + productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.GOOD_COMMENT),
  121 + // 查询商品 id = spuId 的所有中评数量
  122 + productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT),
  123 + // 查询商品 id = spuId 的所有差评数量
  124 + productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT)
  125 + );
  126 + }
  127 +
  128 + @Override
  129 + public PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
  130 + return ProductCommentConvert.INSTANCE.convertPage02(productCommentMapper.selectPage(pageVO, visible));
  131 + }
  132 +
  133 + @Override
  134 + public PageResult<ProductCommentDO> getCommentPage(ProductCommentPageReqVO pageReqVO) {
  135 + return productCommentMapper.selectPage(pageReqVO);
137 136 }
138 137  
139 138 }
... ...
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java
... ... @@ -4,14 +4,13 @@ import cn.hutool.core.date.DateUtil;
4 4 import cn.hutool.core.util.RandomUtil;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
7   -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
8 7 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO;
9 8 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO;
10 9 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO;
11 10 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO;
12   -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO;
13 11 import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
14   -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO;
  12 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
  13 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO;
15 14 import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
16 15 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
17 16 import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper;
... ... @@ -26,7 +25,6 @@ import org.springframework.context.annotation.Lazy;
26 25 import javax.annotation.Resource;
27 26 import java.time.LocalDateTime;
28 27 import java.util.Date;
29   -import java.util.Map;
30 28  
31 29 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
32 30 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
... ... @@ -93,12 +91,10 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
93 91 o.setSkuId(generateId());
94 92 o.setDescriptionScores(ProductCommentScoresEnum.FOUR.getScores());
95 93 o.setBenefitScores(ProductCommentScoresEnum.FOUR.getScores());
96   - o.setDeliveryScores(ProductCommentScoresEnum.FOUR.getScores());
97 94 o.setContent("真好吃");
98 95 o.setReplyUserId(generateId());
99 96 o.setReplyContent("确实");
100 97 o.setReplyTime(LocalDateTime.now());
101   - o.setAdditionalTime(LocalDateTime.now());
102 98 o.setCreateTime(LocalDateTime.now());
103 99 o.setUpdateTime(LocalDateTime.now());
104 100 });
... ... @@ -139,23 +135,23 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
139 135 assertEquals(8, all.getTotal());
140 136  
141 137 // 测试获取所有商品分页评论数据
142   - PageResult<AppCommentRespVO> result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE);
  138 + PageResult<AppProductCommentRespVO> result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE);
143 139 assertEquals(7, result1.getTotal());
144 140  
145 141 // 测试获取所有商品分页中评数据
146   - PageResult<AppCommentRespVO> result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
  142 + PageResult<AppProductCommentRespVO> result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
147 143 assertEquals(2, result2.getTotal());
148 144  
149 145 // 测试获取指定 spuId 商品分页中评数据
150   - PageResult<AppCommentRespVO> result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
  146 + PageResult<AppProductCommentRespVO> result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
151 147 assertEquals(2, result3.getTotal());
152 148  
153 149 // 测试分页 tab count
154   - Map<String, Long> tabsCount = productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE);
155   - assertEquals(6, tabsCount.get(AppCommentPageReqVO.ALL_COUNT));
156   - assertEquals(4, tabsCount.get(AppCommentPageReqVO.FAVOURABLE_COMMENT_COUNT));
157   - assertEquals(2, tabsCount.get(AppCommentPageReqVO.MEDIOCRE_COMMENT_COUNT));
158   - assertEquals(0, tabsCount.get(AppCommentPageReqVO.NEGATIVE_COMMENT_COUNT));
  150 + AppCommentStatisticsRespVO tabsCount = productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE);
  151 + assertEquals(6, tabsCount.getAllCount());
  152 + assertEquals(4, tabsCount.getGoodCount());
  153 + assertEquals(2, tabsCount.getMediocreCount());
  154 + assertEquals(0, tabsCount.getNegativeCount());
159 155  
160 156 }
161 157  
... ... @@ -190,7 +186,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
190 186 ProductCommentReplyVO replyVO = new ProductCommentReplyVO();
191 187 replyVO.setId(productCommentId);
192 188 replyVO.setReplyContent("测试");
193   - productCommentService.commentReply(replyVO, 1L);
  189 + productCommentService.replyComment(replyVO, 1L);
194 190  
195 191 ProductCommentDO productCommentDO = productCommentMapper.selectById(productCommentId);
196 192 assertEquals("测试", productCommentDO.getReplyContent());
... ... @@ -199,24 +195,6 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
199 195 @Test
200 196 public void testCreateComment_success() {
201 197 // mock 测试
202   - ProductCommentDO productComment = randomPojo(ProductCommentDO.class, o -> {
203   - o.setAdditionalContent("");
204   - });
205   -
206   - productCommentService.createComment(productComment, Boolean.TRUE);
207   -
208   - MemberUserRespDTO user = new MemberUserRespDTO();
209   - user.setId(productComment.getUserId());
210   -
211   - AppCommentAdditionalReqVO createReqVO = new AppCommentAdditionalReqVO();
212   - createReqVO.setId(productComment.getId());
213   - createReqVO.setAdditionalContent("追加");
214   - createReqVO.setAdditionalPicUrls(productComment.getAdditionalPicUrls());
215   -
216   - productCommentService.additionalComment(user, createReqVO);
217   - ProductCommentDO exist = productCommentMapper.selectById(productComment.getId());
218   -
219   - assertEquals("追加", exist.getAdditionalContent());
220 198 }
221 199  
222 200 }
... ...
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java
1 1 package cn.iocoder.yudao.module.trade.api.order;
2 2  
3   -import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
4   -
5 3 /**
6 4 * 订单 API 接口
7 5 *
... ... @@ -10,11 +8,12 @@ import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
10 8 public interface TradeOrderApi {
11 9  
12 10 /**
13   - * 获取订单通过订单 id
  11 + * 验证订单
14 12 *
15   - * @param id id
16   - * @return 订单信息 Response DTO
  13 + * @param userId 用户 id
  14 + * @param orderItemId 订单项 id
  15 + * @return 校验通过返回订单 id
17 16 */
18   - TradeOrderRespDTO getOrder(Long id);
  17 + Long validateOrder(Long userId, Long orderItemId);
19 18  
20 19 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java
1 1 package cn.iocoder.yudao.module.trade.api.order;
2 2  
3   -import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
4   -import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
  3 +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
5 4 import cn.iocoder.yudao.module.trade.service.order.TradeOrderService;
6 5 import org.springframework.stereotype.Service;
7 6 import org.springframework.validation.annotation.Validated;
8 7  
9 8 import javax.annotation.Resource;
10 9  
  10 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  11 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_ITEM_NOT_FOUND;
  12 +
11 13 /**
12 14 * 订单 API 接口实现类
13 15 *
... ... @@ -21,8 +23,14 @@ public class TradeOrderApiImpl implements TradeOrderApi {
21 23 private TradeOrderService tradeOrderService;
22 24  
23 25 @Override
24   - public TradeOrderRespDTO getOrder(Long id) {
25   - return TradeOrderConvert.INSTANCE.convert(tradeOrderService.getOrder(id));
  26 + public Long validateOrder(Long userId, Long orderItemId) {
  27 + // 校验订单项,订单项存在订单就存在
  28 + TradeOrderItemDO item = tradeOrderService.getOrderItem(userId, orderItemId);
  29 + if (item == null) {
  30 + throw exception(ORDER_ITEM_NOT_FOUND);
  31 + }
  32 +
  33 + return item.getOrderId();
26 34 }
27 35  
28 36 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
... ... @@ -4,9 +4,11 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
6 6 import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
  7 +import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
7 8 import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi;
8 9 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
9 10 import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
  11 +import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
10 12 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
11 13 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
12 14 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
... ... @@ -14,6 +16,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
14 16 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
15 17 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
16 18 import cn.iocoder.yudao.module.trade.service.order.TradeOrderService;
  19 +import com.google.common.collect.Maps;
17 20 import io.swagger.v3.oas.annotations.Operation;
18 21 import io.swagger.v3.oas.annotations.Parameter;
19 22 import io.swagger.v3.oas.annotations.tags.Tag;
... ... @@ -23,14 +26,15 @@ import org.springframework.web.bind.annotation.*;
23 26  
24 27 import javax.annotation.Resource;
25 28 import javax.validation.Valid;
26   -import java.util.HashMap;
27 29 import java.util.List;
28 30 import java.util.Map;
29 31  
  32 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
30 33 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
31 34 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
32 35 import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
33 36 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  37 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_ITEM_NOT_FOUND;
34 38  
35 39 @Tag(name = "用户 App - 交易订单")
36 40 @RestController
... ... @@ -48,6 +52,9 @@ public class AppTradeOrderController {
48 52 @Resource
49 53 private TradeOrderProperties tradeOrderProperties;
50 54  
  55 + @Resource
  56 + private ProductCommentApi productCommentApi;
  57 +
51 58 @GetMapping("/settlement")
52 59 @Operation(summary = "获得订单结算信息")
53 60 @PreAuthenticated
... ... @@ -105,7 +112,7 @@ public class AppTradeOrderController {
105 112 @GetMapping("/get-count")
106 113 @Operation(summary = "获得交易订单数量")
107 114 public CommonResult<Map<String, Long>> getOrderCount() {
108   - Map<String, Long> orderCount = new HashMap<>();
  115 + Map<String, Long> orderCount = Maps.newLinkedHashMapWithExpectedSize(5);
109 116 // 全部
110 117 orderCount.put("allCount", tradeOrderService.getOrderCount(getLoginUserId(), null, null));
111 118 // 待付款(未支付)
... ... @@ -129,11 +136,16 @@ public class AppTradeOrderController {
129 136 return success(TradeOrderConvert.INSTANCE.convert03(item));
130 137 }
131 138  
132   - // TODO 芋艿:待实现
133 139 @PostMapping("/item/create-comment")
134 140 @Operation(summary = "创建交易订单项的评价")
135   - public CommonResult<Long> createOrderItemComment() {
136   - return success(0L);
  141 + public CommonResult<Long> createOrderItemComment(@RequestBody AppTradeOrderItemCommentCreateReqVO createReqVO) {
  142 + // 校验订单项,订单项存在订单就存在
  143 + TradeOrderItemDO item = tradeOrderService.getOrderItem(createReqVO.getUserId(), createReqVO.getOrderItemId());
  144 + if (item == null) {
  145 + throw exception(ORDER_ITEM_NOT_FOUND);
  146 + }
  147 +
  148 + return success(productCommentApi.createComment(TradeOrderConvert.INSTANCE.convert04(createReqVO), item.getOrderId()));
137 149 }
138 150  
139 151 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemCommentCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.order.vo.item;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotNull;
  7 +import javax.validation.constraints.Size;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * 商品评价创建 Request VO
  12 + *
  13 + * @author HUIHUI
  14 + */
  15 +@Schema(description = "用户APP - 商品评价创建 Request VO")
  16 +@Data
  17 +public class AppTradeOrderItemCommentCreateReqVO {
  18 +
  19 + @Schema(description = "是否匿名", required = true, example = "true")
  20 + @NotNull(message = "是否匿名不能为空")
  21 + private Boolean anonymous;
  22 +
  23 + @Schema(description = "交易订单项编号", required = true, example = "2312312")
  24 + @NotNull(message = "交易订单项编号不能为空")
  25 + private Long orderItemId;
  26 +
  27 + @Schema(description = "商品SPU编号", required = true, example = "29502")
  28 + @NotNull(message = "商品SPU编号不能为空")
  29 + private Long spuId;
  30 +
  31 + @Schema(description = "商品SPU名称", required = true, example = "丝滑飘逸小短裙")
  32 + @NotNull(message = "商品SPU名称不能为空")
  33 + private String spuName;
  34 +
  35 + @Schema(description = "商品SKU编号", required = true, example = "3082")
  36 + @NotNull(message = "商品SKU编号不能为空")
  37 + private Long skuId;
  38 +
  39 + @Schema(description = "评分星级 1-5分", required = true, example = "5")
  40 + @NotNull(message = "评分星级 1-5分不能为空")
  41 + private Integer scores;
  42 +
  43 + @Schema(description = "描述星级 1-5分", required = true, example = "5")
  44 + @NotNull(message = "描述星级 1-5分不能为空")
  45 + private Integer descriptionScores;
  46 +
  47 + @Schema(description = "服务星级 1-5分", required = true, example = "5")
  48 + @NotNull(message = "服务星级 1-5分不能为空")
  49 + private Integer benefitScores;
  50 +
  51 + @Schema(description = "评论内容", required = true, example = "穿身上很漂亮诶(*^▽^*)")
  52 + @NotNull(message = "评论内容不能为空")
  53 + private String content;
  54 +
  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张")
  57 + private List<String> picUrls;
  58 +
  59 + @Schema(description = "评价人名称", required = true, example = "小姑凉")
  60 + @NotNull(message = "评价人名称不能为空")
  61 + private String userNickname;
  62 +
  63 + @Schema(description = "评价人头像", required = true, example = "https://www.iocoder.cn/xx.png")
  64 + @NotNull(message = "评价人头像不能为空")
  65 + private String userAvatar;
  66 +
  67 + @Schema(description = "评价人", required = true, example = "16868")
  68 + @NotNull(message = "评价人不能为空")
  69 + private Long userId;
  70 +
  71 +}
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
... ... @@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
8 8 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
9 9 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
10 10 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
  11 +import cn.iocoder.yudao.module.product.api.comment.dto.CommentCreateReqDTO;
11 12 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
12 13 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
13 14 import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO;
... ... @@ -18,6 +19,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailR
18 19 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO;
19 20 import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO;
20 21 import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
  22 +import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
21 23 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
22 24 import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO;
23 25 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
... ... @@ -75,9 +77,10 @@ public interface TradeOrderConvert {
75 77 return orderItem;
76 78 });
77 79 }
  80 +
78 81 TradeOrderItemDO convert(TradePriceCalculateRespBO.OrderItem item);
79 82  
80   - @Mapping(source = "userId" , target = "userId")
  83 + @Mapping(source = "userId", target = "userId")
81 84 PriceCalculateReqDTO convert(AppTradeOrderCreateReqVO createReqVO, Long userId);
82 85  
83 86 @Mappings({
... ... @@ -85,6 +88,7 @@ public interface TradeOrderConvert {
85 88 @Mapping(source = "count", target = "incrCount"),
86 89 })
87 90 ProductSkuUpdateStockReqDTO.Item convert(TradeOrderItemDO bean);
  91 +
88 92 List<ProductSkuUpdateStockReqDTO.Item> convertList(List<TradeOrderItemDO> list);
89 93  
90 94 default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
... ... @@ -136,7 +140,7 @@ public interface TradeOrderConvert {
136 140 properties.forEach(property -> {
137 141 ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId());
138 142 if (propertyValueDetail == null) {
139   - return;
  143 + return;
140 144 }
141 145 item.getProperties().add(convert(propertyValueDetail));
142 146 });
... ... @@ -148,7 +152,9 @@ public interface TradeOrderConvert {
148 152 });
149 153 return new PageResult<>(orderVOs, pageResult.getTotal());
150 154 }
  155 +
151 156 TradeOrderPageItemRespVO convert(TradeOrderDO order, List<TradeOrderItemDO> items);
  157 +
152 158 ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean);
153 159  
154 160 // TODO 芋艿:可简化
... ... @@ -179,7 +185,9 @@ public interface TradeOrderConvert {
179 185 orderVO.setUser(convert(user));
180 186 return orderVO;
181 187 }
  188 +
182 189 TradeOrderDetailRespVO convert2(TradeOrderDO order, List<TradeOrderItemDO> items);
  190 +
183 191 MemberUserRespVO convert(MemberUserRespDTO bean);
184 192  
185 193 // TODO 芋艿:可简化
... ... @@ -214,7 +222,9 @@ public interface TradeOrderConvert {
214 222 });
215 223 return new PageResult<>(orderVOs, pageResult.getTotal());
216 224 }
  225 +
217 226 AppTradeOrderPageItemRespVO convert02(TradeOrderDO order, List<TradeOrderItemDO> items);
  227 +
218 228 AppProductPropertyValueDetailRespVO convert02(ProductPropertyValueDetailRespDTO bean);
219 229  
220 230 default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
... ... @@ -243,10 +253,13 @@ public interface TradeOrderConvert {
243 253 orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId()));
244 254 return orderVO;
245 255 }
  256 +
246 257 AppTradeOrderDetailRespVO convert3(TradeOrderDO order, List<TradeOrderItemDO> items);
247 258  
248 259 AppTradeOrderItemRespVO convert03(TradeOrderItemDO bean);
249 260  
  261 + CommentCreateReqDTO convert04(AppTradeOrderItemCommentCreateReqVO createReqVO);
  262 +
250 263 default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO,
251 264 List<TradeCartDO> cartList) {
252 265 TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO();
... ... @@ -286,6 +299,8 @@ public interface TradeOrderConvert {
286 299 }
287 300 return respVO;
288 301 }
  302 +
289 303 AppTradeOrderSettlementRespVO convert0(TradePriceCalculateRespBO calculate, AddressRespDTO address);
290 304  
  305 +
291 306 }
... ...