Commit 6fe5f4bc0d369d918bbeb9d453a93edd0c3f7f31

Authored by wangzhs
1 parent cbf5ef59

[新增][商品评价]管理后台/APP端

Showing 18 changed files with 461 additions and 28 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
... ... @@ -44,5 +44,8 @@ public interface ErrorCodeConstants {
44 44  
45 45 // ========== 商品 评价 1008007000 ==========
46 46 ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1008007000, "商品 评价 不存在");
  47 + ErrorCode ORDER_SPU_COMMENT_EXISTS = new ErrorCode(1008007001, "订单 商品评价 已存在");
  48 + ErrorCode COMMENT_ERROR_OPT = new ErrorCode(1008007002, "商品评价非法操作");
  49 + ErrorCode COMMENT_ADDITIONAL_EXISTS = new ErrorCode(1008007003, "商品追加评价已存在");
47 50  
48 51 }
... ...
yudao-module-mall/yudao-module-product-biz/pom.xml
... ... @@ -24,6 +24,12 @@
24 24 <version>${revision}</version>
25 25 </dependency>
26 26  
  27 + <dependency>
  28 + <groupId>cn.iocoder.boot</groupId>
  29 + <artifactId>yudao-module-member-api</artifactId>
  30 + <version>${revision}</version>
  31 + </dependency>
  32 +
27 33 <!-- 业务组件 -->
28 34 <dependency>
29 35 <groupId>cn.iocoder.boot</groupId>
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java
... ... @@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.comment;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5   -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO;
6   -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO;
7   -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO;
8   -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO;
  5 +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.*;
9 6 import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
10 7 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
11 8 import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
... ... @@ -54,4 +51,12 @@ public class ProductCommentController {
54 51 return success(true);
55 52 }
56 53  
  54 + @PutMapping("/create")
  55 + @Operation(summary = "添加自评")
  56 + @PreAuthorize("@ss.hasPermission('product:comment:update')")
  57 + public CommonResult<Boolean> createComment(@Valid @RequestBody ProductCommentCreateReqVO createReqVO) {
  58 + productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(createReqVO), Boolean.TRUE);
  59 + return success(true);
  60 + }
  61 +
57 62 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java
1 1 package cn.iocoder.yudao.module.product.controller.admin.comment.vo;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4   -import lombok.*;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
5 8 import java.time.LocalDateTime;
6 9 import java.util.List;
7 10  
... ... @@ -23,7 +26,7 @@ public class ProductCommentRespVO extends ProductCommentBaseVO {
23 26 @Schema(description = "交易订单项编号", required = true, example = "8233")
24 27 private Long orderItemId;
25 28  
26   - @Schema(description = "是否可见:[1:显示 0:隐藏]", required = true)
  29 + @Schema(description = "是否可见:[true:显示 false:隐藏]", required = true)
27 30 private Boolean visible;
28 31  
29 32 @Schema(description = "商家是否回复:[1:回复 0:未回复]", required = true)
... ... @@ -45,7 +48,7 @@ public class ProductCommentRespVO extends ProductCommentBaseVO {
45 48 private List<String> additionalPicUrls;
46 49  
47 50 @Schema(description = "追加评价时间")
48   - private LocalDateTime additionalCreateTime;
  51 + private LocalDateTime additionalTime;
49 52  
50 53 @Schema(description = "创建时间", required = true)
51 54 private LocalDateTime createTime;
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.http 0 → 100644
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java 0 → 100644
  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.AppCommentAdditionalReqVO;
  8 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentCreateReqVO;
  9 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
  10 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO;
  11 +import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
  12 +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
  13 +import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
  14 +import io.swagger.v3.oas.annotations.Operation;
  15 +import io.swagger.v3.oas.annotations.tags.Tag;
  16 +import org.springframework.validation.annotation.Validated;
  17 +import org.springframework.web.bind.annotation.*;
  18 +
  19 +import javax.annotation.Resource;
  20 +import javax.validation.Valid;
  21 +
  22 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  23 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  24 +
  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 + PageResult<ProductCommentDO> pageResult = productCommentService.getCommentPage(pageVO, Boolean.TRUE);
  41 + return success(ProductCommentConvert.INSTANCE.convertPage02(pageResult));
  42 + }
  43 +
  44 + @PostMapping(value = "/create")
  45 + @Operation(summary = "创建商品评价")
  46 + public CommonResult<Boolean> createComment(@RequestBody AppCommentCreateReqVO createReqVO) {
  47 + // 查询会员 todo@艿艿 获取用户头像
  48 + // TODO: 2023/3/20 要不要判断订单、商品是否存在
  49 + MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId());
  50 + productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(user, createReqVO), Boolean.FALSE);
  51 + return success(true);
  52 + }
  53 +
  54 + @PostMapping(value = "/additional")
  55 + @Operation(summary = "追加评论")
  56 + public CommonResult<Boolean> additionalComment(@RequestBody AppCommentAdditionalReqVO createReqVO) {
  57 + // 查询会员
  58 + MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId());
  59 + productCommentService.additionalComment(user, createReqVO);
  60 + return success(true);
  61 + }
  62 +
  63 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.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 +import javax.validation.constraints.NotNull;
  8 +import java.util.List;
  9 +
  10 +@Schema(description = "用户APP - 商品追加评价创建 Request VO")
  11 +@Data
  12 +@ToString(callSuper = true)
  13 +public class AppCommentAdditionalReqVO {
  14 +
  15 + @Schema(description = "评论编号", required = true)
  16 + @NotNull(message = "评论编号不能为空")
  17 + private Long id;
  18 +
  19 + @Schema(description = "追加评价内容", required = true)
  20 + @NotNull(message = "追加评价内容不能为空")
  21 + private String additionalContent;
  22 +
  23 + @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张", required = true)
  24 + @NotNull(message = "追评评价图片地址数组,以逗号分隔最多上传9张不能为空")
  25 + private List<String> additionalPicUrls;
  26 +
  27 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.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 +
  6 +import javax.validation.constraints.NotNull;
  7 +import java.util.List;
  8 +
  9 +@Data
  10 +public class AppCommentBaseVO {
  11 +
  12 + @Schema(description = "商品SPU编号", required = true, example = "29502")
  13 + @NotNull(message = "商品SPU编号不能为空")
  14 + private Long spuId;
  15 +
  16 + @Schema(description = "商品SPU名称", required = true, example = "赵六")
  17 + @NotNull(message = "商品SPU名称不能为空")
  18 + private String spuName;
  19 +
  20 + @Schema(description = "商品SKU编号", required = true, example = "3082")
  21 + @NotNull(message = "商品SKU编号不能为空")
  22 + private Long skuId;
  23 +
  24 + @Schema(description = "评分星级 1-5分", required = true)
  25 + @NotNull(message = "评分星级 1-5分不能为空")
  26 + private Integer scores;
  27 +
  28 + @Schema(description = "描述星级 1-5分", required = true)
  29 + @NotNull(message = "描述星级 1-5分不能为空")
  30 + private Integer descriptionScores;
  31 +
  32 + @Schema(description = "服务星级 1-5分", required = true)
  33 + @NotNull(message = "服务星级 1-5分不能为空")
  34 + private Integer benefitScores;
  35 +
  36 + @Schema(description = "配送星级 1-5分", required = true)
  37 + @NotNull(message = "配送星级 1-5分不能为空")
  38 + private Integer deliveryScores;
  39 +
  40 + @Schema(description = "评论内容", required = true)
  41 + @NotNull(message = "评论内容不能为空")
  42 + private String content;
  43 +
  44 + @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true)
  45 + @NotNull(message = "评论图片地址数组,以逗号分隔最多上传9张不能为空")
  46 + private List<String> picUrls;
  47 +
  48 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.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.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import javax.validation.constraints.NotNull;
  9 +
  10 +@Schema(description = "用户APP - 商品评价创建 Request VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class AppCommentCreateReqVO extends AppCommentBaseVO {
  15 +
  16 + @Schema(description = "是否匿名 true:是 false:否", required = true, example = "true")
  17 + @NotNull(message = "是否匿名不能为空")
  18 + private Boolean anonymous;
  19 +
  20 + @Schema(description = "交易订单编号", required = true, example = "12312")
  21 + @NotNull(message = "交易订单编号不能为空")
  22 + private Long orderId;
  23 +
  24 + @Schema(description = "交易订单项编号", required = true, example = "2312312")
  25 + @NotNull(message = "交易订单项编号不能为空")
  26 + private Long orderItemId;
  27 +
  28 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.app.comment.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import javax.validation.constraints.NotNull;
  10 +
  11 +@Schema(description = "用户APP - 商品评价分页 Request VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class AppCommentPageReqVO extends PageParam {
  16 +
  17 + @Schema(description = "商品SPU编号", example = "29502")
  18 + @NotNull(message = "商品SPU编号不能为空")
  19 + private Long spuId;
  20 +
  21 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.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.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import javax.validation.constraints.NotNull;
  9 +import java.time.LocalDateTime;
  10 +import java.util.List;
  11 +
  12 +@Schema(description = "用户APP - 商品评价 Response VO")
  13 +@Data
  14 +@EqualsAndHashCode(callSuper = true)
  15 +@ToString(callSuper = true)
  16 +public class AppCommentRespVO extends AppCommentBaseVO {
  17 +
  18 + @Schema(description = "评价人 用户编号", required = true, example = "15721")
  19 + private Long userId;
  20 +
  21 + @Schema(description = "评价人名称", required = true, example = "张三")
  22 + private String userNickname;
  23 +
  24 + @Schema(description = "评价人头像", required = true)
  25 + private String userAvatar;
  26 +
  27 + @Schema(description = "订单项编号", required = true, example = "24965")
  28 + private Long id;
  29 +
  30 + @Schema(description = "是否匿名:[0:不匿名 1:匿名]", required = true)
  31 + private Boolean anonymous;
  32 +
  33 + @Schema(description = "交易订单编号", required = true, example = "24428")
  34 + private Long orderId;
  35 +
  36 + @Schema(description = "交易订单项编号", required = true, example = "8233")
  37 + private Long orderItemId;
  38 +
  39 + @Schema(description = "商家是否回复:[1:回复 0:未回复]", required = true)
  40 + private Boolean replied;
  41 +
  42 + @Schema(description = "回复管理员编号", example = "22212")
  43 + private Long replyUserId;
  44 +
  45 + @Schema(description = "商家回复内容")
  46 + private String replyContent;
  47 +
  48 + @Schema(description = "商家回复时间")
  49 + private LocalDateTime replyTime;
  50 +
  51 + @Schema(description = "追加评价内容")
  52 + private String additionalContent;
  53 +
  54 + @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张")
  55 + private List<String> additionalPicUrls;
  56 +
  57 + @Schema(description = "追加评价时间")
  58 + private LocalDateTime additionalTime;
  59 +
  60 + @Schema(description = "创建时间", required = true)
  61 + private LocalDateTime createTime;
  62 +
  63 +}
... ...
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;
  5 +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO;
4 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;
5 9 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
6 10 import org.mapstruct.Mapper;
7 11 import org.mapstruct.factory.Mappers;
... ... @@ -24,4 +28,47 @@ public interface ProductCommentConvert {
24 28  
25 29 PageResult<ProductCommentRespVO> convertPage(PageResult<ProductCommentDO> page);
26 30  
  31 + PageResult<AppCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult);
  32 +
  33 + default ProductCommentDO convert(MemberUserRespDTO user, AppCommentCreateReqVO createReqVO) {
  34 + ProductCommentDO productComment = new ProductCommentDO();
  35 + productComment.setUserId(user.getId());
  36 + productComment.setUserNickname(user.getNickname());
  37 +// productComment.setUserAvatar();
  38 + productComment.setAnonymous(createReqVO.getAnonymous());
  39 + productComment.setOrderId(createReqVO.getOrderId());
  40 + productComment.setOrderItemId(createReqVO.getOrderItemId());
  41 + productComment.setSpuId(createReqVO.getSpuId());
  42 + productComment.setSpuName(createReqVO.getSpuName());
  43 + productComment.setSkuId(createReqVO.getSkuId());
  44 + productComment.setScores(createReqVO.getScores());
  45 + productComment.setDescriptionScores(createReqVO.getDescriptionScores());
  46 + productComment.setBenefitScores(createReqVO.getBenefitScores());
  47 + productComment.setDeliveryScores(createReqVO.getDeliveryScores());
  48 + productComment.setContent(createReqVO.getContent());
  49 + productComment.setPicUrls(createReqVO.getPicUrls());
  50 + return productComment;
  51 + }
  52 +
  53 + default ProductCommentDO convert(ProductCommentCreateReqVO createReq) {
  54 + ProductCommentDO productComment = new ProductCommentDO();
  55 + productComment.setUserId(createReq.getUserId());
  56 + productComment.setUserNickname(createReq.getUserNickname());
  57 + productComment.setUserAvatar(createReq.getUserAvatar());
  58 + productComment.setAnonymous(Boolean.FALSE);
  59 + // TODO: 2023/3/21 自评订单ID来源
  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.setDeliveryScores(createReq.getDeliveryScores());
  69 + productComment.setContent(createReq.getContent());
  70 + productComment.setPicUrls(createReq.getPicUrls());
  71 + return productComment;
  72 + }
  73 +
27 74 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java
... ... @@ -36,7 +36,6 @@ public class ProductCommentDO extends BaseDO {
36 36  
37 37 /**
38 38 * 评价人 用户编号
39   - * <p>
40 39 * 关联 MemberUserDO 的 id 编号
41 40 */
42 41 private Long userId;
... ... @@ -49,7 +48,7 @@ public class ProductCommentDO extends BaseDO {
49 48 /**
50 49 * 评价人头像
51 50 */
52   - private Long userAvatar;
  51 + private String userAvatar;
53 52  
54 53 /**
55 54 * 是否匿名
... ... @@ -58,21 +57,18 @@ public class ProductCommentDO extends BaseDO {
58 57  
59 58 /**
60 59 * 交易订单编号
61   - * <p>
62 60 * 关联 TradeOrderDO 的 id 编号
63 61 */
64 62 private Long orderId;
65 63  
66 64 /**
67 65 * 交易订单项编号
68   - * <p>
69 66 * 关联 TradeOrderItemDO 的 id 编号
70 67 */
71 68 private Long orderItemId;
72 69  
73 70 /**
74 71 * 商品 SPU 编号
75   - * <p>
76 72 * 关联 {@link ProductSpuDO#getId()}
77 73 */
78 74 private Long spuId;
... ... @@ -84,42 +80,36 @@ public class ProductCommentDO extends BaseDO {
84 80  
85 81 /**
86 82 * 商品 SKU 编号
87   - * <p>
88 83 * 关联 {@link ProductSkuDO#getId()}
89 84 */
90 85 private Long skuId;
91 86  
92 87 /**
93 88 * 是否可见
94   - * <p>
95   - * 1:显示 0:隐藏
  89 + * true:显示 false:隐藏
96 90 */
97 91 private Boolean visible;
98 92  
99 93 /**
100 94 * 评分星级
101   - * <p>
102 95 * 1-5分
103 96 */
104 97 private Integer scores;
105 98  
106 99 /**
107 100 * 描述星级
108   - * <p>
109 101 * 1-5 星
110 102 */
111 103 private Integer descriptionScores;
112 104  
113 105 /**
114 106 * 服务星级
115   - * <p>
116 107 * 1-5 星
117 108 */
118 109 private Integer benefitScores;
119 110  
120 111 /**
121 112 * 配送星级
122   - * <p>
123 113 * 1-5 星
124 114 */
125 115 private Integer deliveryScores;
... ... @@ -142,7 +132,6 @@ public class ProductCommentDO extends BaseDO {
142 132  
143 133 /**
144 134 * 回复管理员编号
145   - * <p>
146 135 * 关联 AdminUserDO 的 id 编号
147 136 */
148 137 private Long replyUserId;
... ... @@ -171,6 +160,6 @@ public class ProductCommentDO extends BaseDO {
171 160 /**
172 161 * 追加评价时间
173 162 */
174   - private LocalDateTime additionalCreateTime;
  163 + private LocalDateTime additionalTime;
175 164  
176 165 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java
... ... @@ -6,6 +6,8 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
7 7 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO;
8 8 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO;
  9 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO;
  10 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
9 11 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
10 12 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
11 13 import org.apache.ibatis.annotations.Mapper;
... ... @@ -32,6 +34,13 @@ public interface ProductCommentMapper extends BaseMapperX&lt;ProductCommentDO&gt; {
32 34 .orderByDesc(ProductCommentDO::getId));
33 35 }
34 36  
  37 + default PageResult<ProductCommentDO> selectPage(AppCommentPageReqVO reqVO, Boolean visible) {
  38 + return selectPage(reqVO, new LambdaQueryWrapperX<ProductCommentDO>()
  39 + .eqIfPresent(ProductCommentDO::getSpuId, reqVO.getSpuId())
  40 + .eqIfPresent(ProductCommentDO::getVisible, visible)
  41 + .orderByDesc(ProductCommentDO::getId));
  42 + }
  43 +
35 44 default void updateCommentVisible(Long id, Boolean visible) {
36 45 LambdaUpdateWrapper<ProductCommentDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<ProductCommentDO>()
37 46 .set(ProductCommentDO::getVisible, visible)
... ... @@ -48,4 +57,21 @@ public interface ProductCommentMapper extends BaseMapperX&lt;ProductCommentDO&gt; {
48 57 .eq(ProductCommentDO::getId, replyVO.getId());
49 58 update(null, lambdaUpdateWrapper);
50 59 }
  60 +
  61 + default ProductCommentDO findByUserIdAndOrderIdAndSpuId(Long userId, Long orderId, Long spuId) {
  62 + return selectOne(new LambdaQueryWrapperX<ProductCommentDO>()
  63 + .eq(ProductCommentDO::getUserId, userId)
  64 + .eq(ProductCommentDO::getOrderId, orderId)
  65 + .eq(ProductCommentDO::getSpuId, spuId));
  66 + }
  67 +
  68 + default void additionalComment(AppCommentAdditionalReqVO createReqVO) {
  69 + LambdaUpdateWrapper<ProductCommentDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<ProductCommentDO>()
  70 + .set(ProductCommentDO::getAdditionalTime, LocalDateTime.now())
  71 + .set(ProductCommentDO::getAdditionalPicUrls, createReqVO.getAdditionalPicUrls(), "javaType=List,jdbcType=VARCHAR,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler")
  72 + .set(ProductCommentDO::getAdditionalContent, createReqVO.getAdditionalContent())
  73 + .eq(ProductCommentDO::getId, createReqVO.getId());
  74 + update(null, lambdaUpdateWrapper);
  75 + }
  76 +
51 77 }
... ...
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.member.api.user.dto.MemberUserRespDTO;
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;
  8 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO;
  9 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
7 10 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
8 11 import org.springframework.stereotype.Service;
9 12 import org.springframework.validation.annotation.Validated;
... ... @@ -40,4 +43,29 @@ public interface ProductCommentService {
40 43 */
41 44 void commentReply(ProductCommentReplyVO replyVO, Long loginUserId);
42 45  
  46 + /**
  47 + * 获得商品评价分页
  48 + *
  49 + * @param pageVO 分页查询
  50 + * @param visible 是否可见
  51 + * @return 商品评价分页
  52 + */
  53 + PageResult<ProductCommentDO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
  54 +
  55 + /**
  56 + * 创建商品评论
  57 + *
  58 + * @param productComment 创建实体
  59 + * @param system 是否系统评价
  60 + */
  61 + void createComment(ProductCommentDO productComment, Boolean system);
  62 +
  63 + /**
  64 + * 追加商品评论
  65 + *
  66 + * @param user 用户相关信息
  67 + * @param createReqVO 创建实体
  68 + */
  69 + void additionalComment(MemberUserRespDTO user, AppCommentAdditionalReqVO createReqVO);
  70 +
43 71 }
... ...
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 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
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;
  8 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO;
  9 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
7 10 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
8 11 import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper;
9 12 import org.springframework.stereotype.Service;
  13 +import org.springframework.util.StringUtils;
10 14 import org.springframework.validation.annotation.Validated;
11 15  
12 16 import javax.annotation.Resource;
  17 +import java.util.Objects;
13 18  
14 19 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
15   -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COMMENT_NOT_EXISTS;
  20 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
16 21  
17 22 /**
18 23 * 商品评论 Service 实现类
... ... @@ -47,10 +52,47 @@ public class ProductCommentServiceImpl implements ProductCommentService {
47 52 productCommentMapper.commentReply(replyVO, loginUserId);
48 53 }
49 54  
50   - private void validateCommentExists(Long id) {
51   - if (productCommentMapper.selectById(id) == null) {
  55 + @Override
  56 + public PageResult<ProductCommentDO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
  57 + return productCommentMapper.selectPage(pageVO, visible);
  58 + }
  59 +
  60 + @Override
  61 + public void createComment(ProductCommentDO productComment, Boolean system) {
  62 + if (!system) {
  63 + // 判断当前订单的当前商品用户是否评价过
  64 + ProductCommentDO exist = productCommentMapper.findByUserIdAndOrderIdAndSpuId(productComment.getId(), productComment.getOrderId(), productComment.getSpuId());
  65 + if (null != exist) {
  66 + throw exception(ORDER_SPU_COMMENT_EXISTS);
  67 + }
  68 + }
  69 + productCommentMapper.insert(productComment);
  70 + }
  71 +
  72 + @Override
  73 + public void additionalComment(MemberUserRespDTO user, AppCommentAdditionalReqVO createReqVO) {
  74 + // 校验评论是否存在
  75 + ProductCommentDO productComment = validateCommentExists(createReqVO.getId());
  76 +
  77 + // 判断是否是同一用户追加评论
  78 + if (!Objects.equals(productComment.getUserId(), user.getId())) {
  79 + throw exception(COMMENT_ERROR_OPT);
  80 + }
  81 +
  82 + // 判断是否已经追加评论过了
  83 + if (StringUtils.hasText(productComment.getAdditionalContent())) {
  84 + throw exception(COMMENT_ADDITIONAL_EXISTS);
  85 + }
  86 +
  87 + productCommentMapper.additionalComment(createReqVO);
  88 + }
  89 +
  90 + private ProductCommentDO validateCommentExists(Long id) {
  91 + ProductCommentDO productComment = productCommentMapper.selectById(id);
  92 + if (productComment == null) {
52 93 throw exception(COMMENT_NOT_EXISTS);
53 94 }
  95 + return productComment;
54 96 }
55 97  
56 98  
... ...
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java
... ... @@ -4,10 +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;
7 8 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO;
8 9 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO;
9 10 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO;
10 11 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO;
  12 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO;
  13 +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
11 14 import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
12 15 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
13 16 import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper;
... ... @@ -21,7 +24,8 @@ import java.util.Date;
21 24 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
22 25 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
23 26 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
24   -import static org.junit.jupiter.api.Assertions.*;
  27 +import static org.junit.jupiter.api.Assertions.assertEquals;
  28 +import static org.junit.jupiter.api.Assertions.assertFalse;
25 29  
26 30 /**
27 31 * {@link ProductCommentServiceImpl} 的单元测试类
... ... @@ -65,6 +69,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
65 69 o.setSpuName("感冒药");
66 70 o.setScores(ProductCommentScoresEnum.FOUR.getScores());
67 71 o.setReplied(Boolean.TRUE);
  72 + o.setVisible(Boolean.TRUE);
68 73 });
69 74 productCommentMapper.insert(productComment);
70 75  
... ... @@ -83,6 +88,8 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
83 88 productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setScores(ProductCommentScoresEnum.ONE.getScores())));
84 89 // 测试 replied 不匹配
85 90 productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setReplied(Boolean.FALSE)));
  91 + // 测试 visible 不匹配
  92 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setVisible(Boolean.FALSE)));
86 93  
87 94 // 调用
88 95 ProductCommentPageReqVO productCommentPageReqVO = new ProductCommentPageReqVO();
... ... @@ -98,7 +105,10 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
98 105 assertEquals(result.getTotal(), commentPage.getTotal());
99 106  
100 107 PageResult<ProductCommentDO> all = productCommentService.getCommentPage(new ProductCommentPageReqVO());
101   - assertEquals(7, all.getTotal());
  108 + assertEquals(8, all.getTotal());
  109 +
  110 + PageResult<ProductCommentDO> visible = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE);
  111 + assertEquals(7, visible.getTotal());
102 112 }
103 113  
104 114 @Test
... ... @@ -137,4 +147,28 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
137 147 ProductCommentDO productCommentDO = productCommentMapper.selectById(productCommentId);
138 148 assertEquals("测试", productCommentDO.getReplyContent());
139 149 }
  150 +
  151 + @Test
  152 + public void testCreateComment_success() {
  153 + // mock 测试
  154 + ProductCommentDO productComment = randomPojo(ProductCommentDO.class, o -> {
  155 + o.setAdditionalContent("");
  156 + });
  157 +
  158 + productCommentService.createComment(productComment, Boolean.TRUE);
  159 +
  160 + MemberUserRespDTO user = new MemberUserRespDTO();
  161 + user.setId(productComment.getUserId());
  162 +
  163 + AppCommentAdditionalReqVO createReqVO = new AppCommentAdditionalReqVO();
  164 + createReqVO.setId(productComment.getId());
  165 + createReqVO.setAdditionalContent("追加");
  166 + createReqVO.setAdditionalPicUrls(productComment.getAdditionalPicUrls());
  167 +
  168 + productCommentService.additionalComment(user, createReqVO);
  169 + ProductCommentDO exist = productCommentMapper.selectById(productComment.getId());
  170 +
  171 + assertEquals("追加", exist.getAdditionalContent());
  172 + }
  173 +
140 174 }
... ...
yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql
... ... @@ -94,7 +94,7 @@ CREATE TABLE IF NOT EXISTS `product_comment` (
94 94 `spu_id` bigint NOT NULL COMMENT '商品SPU编号',
95 95 `spu_name` varchar NOT NULL COMMENT '商品SPU名称',
96 96 `sku_id` bigint NOT NULL COMMENT '商品SKU编号',
97   - `visible` bit(1) NOT NULL DEFAULT 1 COMMENT '是否可见 1:显示 0:隐藏',
  97 + `visible` bit(1) NOT NULL DEFAULT 1 COMMENT '是否可见 true:显示 false:隐藏',
98 98 `scores` int NOT NULL COMMENT '评分星级 1-5分',
99 99 `description_scores` int NOT NULL COMMENT '描述星级 1-5分',
100 100 `benefit_scores` int NOT NULL COMMENT '服务星级 1-5分',
... ... @@ -107,7 +107,7 @@ CREATE TABLE IF NOT EXISTS `product_comment` (
107 107 `reply_time` datetime COMMENT '商家回复时间',
108 108 `additional_content` varchar(2000) COMMENT '追加评价内容',
109 109 `additional_pic_urls` varchar(1024) COMMENT '追评评价图片地址数组,以逗号分隔最多上传9张',
110   - `additional_create_time` datetime COMMENT '追加评价时间',
  110 + `additional_time` datetime COMMENT '追加评价时间',
111 111 `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
112 112 `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
113 113 `creator` varchar DEFAULT NULL COMMENT '创建人',
... ...