From 6fe5f4bc0d369d918bbeb9d453a93edd0c3f7f31 Mon Sep 17 00:00:00 2001 From: wangzhs Date: Tue, 21 Mar 2023 11:09:10 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=96=B0=E5=A2=9E][=E5=95=86=E5=93=81?= =?UTF-8?q?=E8=AF=84=E4=BB=B7]=E7=AE=A1=E7=90=86=E5=90=8E=E5=8F=B0/APP?= =?UTF-8?q?=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/enums/ErrorCodeConstants.java | 3 + .../yudao-module-product-biz/pom.xml | 6 ++ .../comment/ProductCommentController.java | 13 ++-- .../comment/vo/ProductCommentRespVO.java | 9 ++- .../app/comment/AppCommentController.http | 0 .../app/comment/AppCommentController.java | 63 +++++++++++++++++++ .../comment/vo/AppCommentAdditionalReqVO.java | 27 ++++++++ .../app/comment/vo/AppCommentBaseVO.java | 48 ++++++++++++++ .../app/comment/vo/AppCommentCreateReqVO.java | 28 +++++++++ .../app/comment/vo/AppCommentPageReqVO.java | 21 +++++++ .../app/comment/vo/AppCommentRespVO.java | 63 +++++++++++++++++++ .../comment/ProductCommentConvert.java | 47 ++++++++++++++ .../dataobject/comment/ProductCommentDO.java | 17 +---- .../mysql/comment/ProductCommentMapper.java | 26 ++++++++ .../comment/ProductCommentService.java | 28 +++++++++ .../comment/ProductCommentServiceImpl.java | 48 +++++++++++++- .../ProductCommentServiceImplTest.java | 38 ++++++++++- .../src/test/resources/sql/create_tables.sql | 4 +- 18 files changed, 461 insertions(+), 28 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.http create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java index df3413986c..fe9319dae1 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java +++ b/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 { // ========== 商品 评价 1008007000 ========== ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1008007000, "商品 评价 不存在"); + ErrorCode ORDER_SPU_COMMENT_EXISTS = new ErrorCode(1008007001, "订单 商品评价 已存在"); + ErrorCode COMMENT_ERROR_OPT = new ErrorCode(1008007002, "商品评价非法操作"); + ErrorCode COMMENT_ADDITIONAL_EXISTS = new ErrorCode(1008007003, "商品追加评价已存在"); } diff --git a/yudao-module-mall/yudao-module-product-biz/pom.xml b/yudao-module-mall/yudao-module-product-biz/pom.xml index e89ed105e7..8a06a4cde3 100644 --- a/yudao-module-mall/yudao-module-product-biz/pom.xml +++ b/yudao-module-mall/yudao-module-product-biz/pom.xml @@ -24,6 +24,12 @@ ${revision} + + cn.iocoder.boot + yudao-module-member-api + ${revision} + + cn.iocoder.boot diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java index 8970f7860d..9a49cbba05 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java +++ b/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; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.*; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; @@ -54,4 +51,12 @@ public class ProductCommentController { return success(true); } + @PutMapping("/create") + @Operation(summary = "添加自评") + @PreAuthorize("@ss.hasPermission('product:comment:update')") + public CommonResult createComment(@Valid @RequestBody ProductCommentCreateReqVO createReqVO) { + productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(createReqVO), Boolean.TRUE); + return success(true); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java index c194f0b033..b934c1bf34 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java @@ -1,7 +1,10 @@ package cn.iocoder.yudao.module.product.controller.admin.comment.vo; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + import java.time.LocalDateTime; import java.util.List; @@ -23,7 +26,7 @@ public class ProductCommentRespVO extends ProductCommentBaseVO { @Schema(description = "交易订单项编号", required = true, example = "8233") private Long orderItemId; - @Schema(description = "是否可见:[1:显示 0:隐藏]", required = true) + @Schema(description = "是否可见:[true:显示 false:隐藏]", required = true) private Boolean visible; @Schema(description = "商家是否回复:[1:回复 0:未回复]", required = true) @@ -45,7 +48,7 @@ public class ProductCommentRespVO extends ProductCommentBaseVO { private List additionalPicUrls; @Schema(description = "追加评价时间") - private LocalDateTime additionalCreateTime; + private LocalDateTime additionalTime; @Schema(description = "创建时间", required = true) private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.http b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.http new file mode 100644 index 0000000000..e69de29bb2 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java new file mode 100644 index 0000000000..9e5e645508 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppCommentController.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.product.controller.app.comment; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentCreateReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; +import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; +import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Tag(name = "用户 APP - 商品评价") +@RestController +@RequestMapping("/product/comment") +@Validated +public class AppCommentController { + + @Resource + private ProductCommentService productCommentService; + + @Resource + private MemberUserApi memberUserApi; + + @GetMapping("/page") + @Operation(summary = "获得商品评价分页") + public CommonResult> getCommentPage(@Valid AppCommentPageReqVO pageVO) { + PageResult pageResult = productCommentService.getCommentPage(pageVO, Boolean.TRUE); + return success(ProductCommentConvert.INSTANCE.convertPage02(pageResult)); + } + + @PostMapping(value = "/create") + @Operation(summary = "创建商品评价") + public CommonResult createComment(@RequestBody AppCommentCreateReqVO createReqVO) { + // 查询会员 todo@艿艿 获取用户头像 + // TODO: 2023/3/20 要不要判断订单、商品是否存在 + MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId()); + productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(user, createReqVO), Boolean.FALSE); + return success(true); + } + + @PostMapping(value = "/additional") + @Operation(summary = "追加评论") + public CommonResult additionalComment(@RequestBody AppCommentAdditionalReqVO createReqVO) { + // 查询会员 + MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId()); + productCommentService.additionalComment(user, createReqVO); + return success(true); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java new file mode 100644 index 0000000000..2b10b85a22 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentAdditionalReqVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.product.controller.app.comment.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.ToString; + +import javax.validation.constraints.NotNull; +import java.util.List; + +@Schema(description = "用户APP - 商品追加评价创建 Request VO") +@Data +@ToString(callSuper = true) +public class AppCommentAdditionalReqVO { + + @Schema(description = "评论编号", required = true) + @NotNull(message = "评论编号不能为空") + private Long id; + + @Schema(description = "追加评价内容", required = true) + @NotNull(message = "追加评价内容不能为空") + private String additionalContent; + + @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张", required = true) + @NotNull(message = "追评评价图片地址数组,以逗号分隔最多上传9张不能为空") + private List additionalPicUrls; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java new file mode 100644 index 0000000000..49803c4b1d --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentBaseVO.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.product.controller.app.comment.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +@Data +public class AppCommentBaseVO { + + @Schema(description = "商品SPU编号", required = true, example = "29502") + @NotNull(message = "商品SPU编号不能为空") + private Long spuId; + + @Schema(description = "商品SPU名称", required = true, example = "赵六") + @NotNull(message = "商品SPU名称不能为空") + private String spuName; + + @Schema(description = "商品SKU编号", required = true, example = "3082") + @NotNull(message = "商品SKU编号不能为空") + private Long skuId; + + @Schema(description = "评分星级 1-5分", required = true) + @NotNull(message = "评分星级 1-5分不能为空") + private Integer scores; + + @Schema(description = "描述星级 1-5分", required = true) + @NotNull(message = "描述星级 1-5分不能为空") + private Integer descriptionScores; + + @Schema(description = "服务星级 1-5分", required = true) + @NotNull(message = "服务星级 1-5分不能为空") + private Integer benefitScores; + + @Schema(description = "配送星级 1-5分", required = true) + @NotNull(message = "配送星级 1-5分不能为空") + private Integer deliveryScores; + + @Schema(description = "评论内容", required = true) + @NotNull(message = "评论内容不能为空") + private String content; + + @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true) + @NotNull(message = "评论图片地址数组,以逗号分隔最多上传9张不能为空") + private List picUrls; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java new file mode 100644 index 0000000000..9bfdf52c0b --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentCreateReqVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.product.controller.app.comment.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "用户APP - 商品评价创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AppCommentCreateReqVO extends AppCommentBaseVO { + + @Schema(description = "是否匿名 true:是 false:否", required = true, example = "true") + @NotNull(message = "是否匿名不能为空") + private Boolean anonymous; + + @Schema(description = "交易订单编号", required = true, example = "12312") + @NotNull(message = "交易订单编号不能为空") + private Long orderId; + + @Schema(description = "交易订单项编号", required = true, example = "2312312") + @NotNull(message = "交易订单项编号不能为空") + private Long orderItemId; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java new file mode 100644 index 0000000000..f557d77797 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.product.controller.app.comment.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "用户APP - 商品评价分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AppCommentPageReqVO extends PageParam { + + @Schema(description = "商品SPU编号", example = "29502") + @NotNull(message = "商品SPU编号不能为空") + private Long spuId; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java new file mode 100644 index 0000000000..43aeb23556 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentRespVO.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.product.controller.app.comment.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +@Schema(description = "用户APP - 商品评价 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AppCommentRespVO extends AppCommentBaseVO { + + @Schema(description = "评价人 用户编号", required = true, example = "15721") + private Long userId; + + @Schema(description = "评价人名称", required = true, example = "张三") + private String userNickname; + + @Schema(description = "评价人头像", required = true) + private String userAvatar; + + @Schema(description = "订单项编号", required = true, example = "24965") + private Long id; + + @Schema(description = "是否匿名:[0:不匿名 1:匿名]", required = true) + private Boolean anonymous; + + @Schema(description = "交易订单编号", required = true, example = "24428") + private Long orderId; + + @Schema(description = "交易订单项编号", required = true, example = "8233") + private Long orderItemId; + + @Schema(description = "商家是否回复:[1:回复 0:未回复]", required = true) + private Boolean replied; + + @Schema(description = "回复管理员编号", example = "22212") + private Long replyUserId; + + @Schema(description = "商家回复内容") + private String replyContent; + + @Schema(description = "商家回复时间") + private LocalDateTime replyTime; + + @Schema(description = "追加评价内容") + private String additionalContent; + + @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张") + private List additionalPicUrls; + + @Schema(description = "追加评价时间") + private LocalDateTime additionalTime; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java index c9fe64a21e..dd88fadcda 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java @@ -1,7 +1,11 @@ package cn.iocoder.yudao.module.product.convert.comment; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentCreateReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -24,4 +28,47 @@ public interface ProductCommentConvert { PageResult convertPage(PageResult page); + PageResult convertPage02(PageResult pageResult); + + default ProductCommentDO convert(MemberUserRespDTO user, AppCommentCreateReqVO createReqVO) { + ProductCommentDO productComment = new ProductCommentDO(); + productComment.setUserId(user.getId()); + productComment.setUserNickname(user.getNickname()); +// productComment.setUserAvatar(); + productComment.setAnonymous(createReqVO.getAnonymous()); + productComment.setOrderId(createReqVO.getOrderId()); + productComment.setOrderItemId(createReqVO.getOrderItemId()); + productComment.setSpuId(createReqVO.getSpuId()); + productComment.setSpuName(createReqVO.getSpuName()); + productComment.setSkuId(createReqVO.getSkuId()); + productComment.setScores(createReqVO.getScores()); + productComment.setDescriptionScores(createReqVO.getDescriptionScores()); + productComment.setBenefitScores(createReqVO.getBenefitScores()); + productComment.setDeliveryScores(createReqVO.getDeliveryScores()); + productComment.setContent(createReqVO.getContent()); + productComment.setPicUrls(createReqVO.getPicUrls()); + return productComment; + } + + default ProductCommentDO convert(ProductCommentCreateReqVO createReq) { + ProductCommentDO productComment = new ProductCommentDO(); + productComment.setUserId(createReq.getUserId()); + productComment.setUserNickname(createReq.getUserNickname()); + productComment.setUserAvatar(createReq.getUserAvatar()); + productComment.setAnonymous(Boolean.FALSE); + // TODO: 2023/3/21 自评订单ID来源 + productComment.setOrderId(0L); + productComment.setOrderItemId(0L); + productComment.setSpuId(createReq.getSpuId()); + productComment.setSpuName(createReq.getSpuName()); + productComment.setSkuId(createReq.getSkuId()); + productComment.setScores(createReq.getScores()); + productComment.setDescriptionScores(createReq.getDescriptionScores()); + productComment.setBenefitScores(createReq.getBenefitScores()); + productComment.setDeliveryScores(createReq.getDeliveryScores()); + productComment.setContent(createReq.getContent()); + productComment.setPicUrls(createReq.getPicUrls()); + return productComment; + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java index 0c9d2f8441..6e0bd04fa3 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java +++ b/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 { /** * 评价人 用户编号 - *

* 关联 MemberUserDO 的 id 编号 */ private Long userId; @@ -49,7 +48,7 @@ public class ProductCommentDO extends BaseDO { /** * 评价人头像 */ - private Long userAvatar; + private String userAvatar; /** * 是否匿名 @@ -58,21 +57,18 @@ public class ProductCommentDO extends BaseDO { /** * 交易订单编号 - *

* 关联 TradeOrderDO 的 id 编号 */ private Long orderId; /** * 交易订单项编号 - *

* 关联 TradeOrderItemDO 的 id 编号 */ private Long orderItemId; /** * 商品 SPU 编号 - *

* 关联 {@link ProductSpuDO#getId()} */ private Long spuId; @@ -84,42 +80,36 @@ public class ProductCommentDO extends BaseDO { /** * 商品 SKU 编号 - *

* 关联 {@link ProductSkuDO#getId()} */ private Long skuId; /** * 是否可见 - *

- * 1:显示 0:隐藏 + * true:显示 false:隐藏 */ private Boolean visible; /** * 评分星级 - *

* 1-5分 */ private Integer scores; /** * 描述星级 - *

* 1-5 星 */ private Integer descriptionScores; /** * 服务星级 - *

* 1-5 星 */ private Integer benefitScores; /** * 配送星级 - *

* 1-5 星 */ private Integer deliveryScores; @@ -142,7 +132,6 @@ public class ProductCommentDO extends BaseDO { /** * 回复管理员编号 - *

* 关联 AdminUserDO 的 id 编号 */ private Long replyUserId; @@ -171,6 +160,6 @@ public class ProductCommentDO extends BaseDO { /** * 追加评价时间 */ - private LocalDateTime additionalCreateTime; + private LocalDateTime additionalTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java index cb384ce5fc..e378f53cee 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java +++ b/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; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @@ -32,6 +34,13 @@ public interface ProductCommentMapper extends BaseMapperX { .orderByDesc(ProductCommentDO::getId)); } + default PageResult selectPage(AppCommentPageReqVO reqVO, Boolean visible) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(ProductCommentDO::getSpuId, reqVO.getSpuId()) + .eqIfPresent(ProductCommentDO::getVisible, visible) + .orderByDesc(ProductCommentDO::getId)); + } + default void updateCommentVisible(Long id, Boolean visible) { LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() .set(ProductCommentDO::getVisible, visible) @@ -48,4 +57,21 @@ public interface ProductCommentMapper extends BaseMapperX { .eq(ProductCommentDO::getId, replyVO.getId()); update(null, lambdaUpdateWrapper); } + + default ProductCommentDO findByUserIdAndOrderIdAndSpuId(Long userId, Long orderId, Long spuId) { + return selectOne(new LambdaQueryWrapperX() + .eq(ProductCommentDO::getUserId, userId) + .eq(ProductCommentDO::getOrderId, orderId) + .eq(ProductCommentDO::getSpuId, spuId)); + } + + default void additionalComment(AppCommentAdditionalReqVO createReqVO) { + LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() + .set(ProductCommentDO::getAdditionalTime, LocalDateTime.now()) + .set(ProductCommentDO::getAdditionalPicUrls, createReqVO.getAdditionalPicUrls(), "javaType=List,jdbcType=VARCHAR,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler") + .set(ProductCommentDO::getAdditionalContent, createReqVO.getAdditionalContent()) + .eq(ProductCommentDO::getId, createReqVO.getId()); + update(null, lambdaUpdateWrapper); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java index 0985e8f76f..6f5e1b59f3 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java @@ -1,9 +1,12 @@ package cn.iocoder.yudao.module.product.service.comment; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -40,4 +43,29 @@ public interface ProductCommentService { */ void commentReply(ProductCommentReplyVO replyVO, Long loginUserId); + /** + * 获得商品评价分页 + * + * @param pageVO 分页查询 + * @param visible 是否可见 + * @return 商品评价分页 + */ + PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible); + + /** + * 创建商品评论 + * + * @param productComment 创建实体 + * @param system 是否系统评价 + */ + void createComment(ProductCommentDO productComment, Boolean system); + + /** + * 追加商品评论 + * + * @param user 用户相关信息 + * @param createReqVO 创建实体 + */ + void additionalComment(MemberUserRespDTO user, AppCommentAdditionalReqVO createReqVO); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java index b03809e3a9..2fe331d599 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -1,18 +1,23 @@ package cn.iocoder.yudao.module.product.service.comment; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COMMENT_NOT_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; /** * 商品评论 Service 实现类 @@ -47,10 +52,47 @@ public class ProductCommentServiceImpl implements ProductCommentService { productCommentMapper.commentReply(replyVO, loginUserId); } - private void validateCommentExists(Long id) { - if (productCommentMapper.selectById(id) == null) { + @Override + public PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) { + return productCommentMapper.selectPage(pageVO, visible); + } + + @Override + public void createComment(ProductCommentDO productComment, Boolean system) { + if (!system) { + // 判断当前订单的当前商品用户是否评价过 + ProductCommentDO exist = productCommentMapper.findByUserIdAndOrderIdAndSpuId(productComment.getId(), productComment.getOrderId(), productComment.getSpuId()); + if (null != exist) { + throw exception(ORDER_SPU_COMMENT_EXISTS); + } + } + productCommentMapper.insert(productComment); + } + + @Override + public void additionalComment(MemberUserRespDTO user, AppCommentAdditionalReqVO createReqVO) { + // 校验评论是否存在 + ProductCommentDO productComment = validateCommentExists(createReqVO.getId()); + + // 判断是否是同一用户追加评论 + if (!Objects.equals(productComment.getUserId(), user.getId())) { + throw exception(COMMENT_ERROR_OPT); + } + + // 判断是否已经追加评论过了 + if (StringUtils.hasText(productComment.getAdditionalContent())) { + throw exception(COMMENT_ADDITIONAL_EXISTS); + } + + productCommentMapper.additionalComment(createReqVO); + } + + private ProductCommentDO validateCommentExists(Long id) { + ProductCommentDO productComment = productCommentMapper.selectById(id); + if (productComment == null) { throw exception(COMMENT_NOT_EXISTS); } + return productComment; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index c3be206ede..af1d529d8f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/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; import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentAdditionalReqVO; +import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; @@ -21,7 +24,8 @@ import java.util.Date; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; /** * {@link ProductCommentServiceImpl} 的单元测试类 @@ -65,6 +69,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { o.setSpuName("感冒药"); o.setScores(ProductCommentScoresEnum.FOUR.getScores()); o.setReplied(Boolean.TRUE); + o.setVisible(Boolean.TRUE); }); productCommentMapper.insert(productComment); @@ -83,6 +88,8 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setScores(ProductCommentScoresEnum.ONE.getScores()))); // 测试 replied 不匹配 productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setReplied(Boolean.FALSE))); + // 测试 visible 不匹配 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setVisible(Boolean.FALSE))); // 调用 ProductCommentPageReqVO productCommentPageReqVO = new ProductCommentPageReqVO(); @@ -98,7 +105,10 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { assertEquals(result.getTotal(), commentPage.getTotal()); PageResult all = productCommentService.getCommentPage(new ProductCommentPageReqVO()); - assertEquals(7, all.getTotal()); + assertEquals(8, all.getTotal()); + + PageResult visible = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE); + assertEquals(7, visible.getTotal()); } @Test @@ -137,4 +147,28 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { ProductCommentDO productCommentDO = productCommentMapper.selectById(productCommentId); assertEquals("测试", productCommentDO.getReplyContent()); } + + @Test + public void testCreateComment_success() { + // mock 测试 + ProductCommentDO productComment = randomPojo(ProductCommentDO.class, o -> { + o.setAdditionalContent(""); + }); + + productCommentService.createComment(productComment, Boolean.TRUE); + + MemberUserRespDTO user = new MemberUserRespDTO(); + user.setId(productComment.getUserId()); + + AppCommentAdditionalReqVO createReqVO = new AppCommentAdditionalReqVO(); + createReqVO.setId(productComment.getId()); + createReqVO.setAdditionalContent("追加"); + createReqVO.setAdditionalPicUrls(productComment.getAdditionalPicUrls()); + + productCommentService.additionalComment(user, createReqVO); + ProductCommentDO exist = productCommentMapper.selectById(productComment.getId()); + + assertEquals("追加", exist.getAdditionalContent()); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql index 2c2145f54e..512175a9d0 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql +++ b/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` ( `spu_id` bigint NOT NULL COMMENT '商品SPU编号', `spu_name` varchar NOT NULL COMMENT '商品SPU名称', `sku_id` bigint NOT NULL COMMENT '商品SKU编号', - `visible` bit(1) NOT NULL DEFAULT 1 COMMENT '是否可见 1:显示 0:隐藏', + `visible` bit(1) NOT NULL DEFAULT 1 COMMENT '是否可见 true:显示 false:隐藏', `scores` int NOT NULL COMMENT '评分星级 1-5分', `description_scores` int NOT NULL COMMENT '描述星级 1-5分', `benefit_scores` int NOT NULL COMMENT '服务星级 1-5分', @@ -107,7 +107,7 @@ CREATE TABLE IF NOT EXISTS `product_comment` ( `reply_time` datetime COMMENT '商家回复时间', `additional_content` varchar(2000) COMMENT '追加评价内容', `additional_pic_urls` varchar(1024) COMMENT '追评评价图片地址数组,以逗号分隔最多上传9张', - `additional_create_time` datetime COMMENT '追加评价时间', + `additional_time` datetime COMMENT '追加评价时间', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `creator` varchar DEFAULT NULL COMMENT '创建人',