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 0c9d2f844..6e0bd04fa 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 cb384ce5f..e378f53ce 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 0985e8f76..6f5e1b59f 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 b03809e3a..2fe331d59 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 c3be206ed..af1d529d8 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 2c2145f54..512175a9d 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 '创建人',