Commit da53a041daaa9d2a2e2b3b2f70d2733bacdcbf0f

Authored by wangzhs
1 parent f69d8503

[新增][商品评价]管理后台分页查询

Showing 14 changed files with 389 additions and 2 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentScoresEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.enums.comment;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 商品评论的星级枚举
  11 + *
  12 + * @author wangzhs
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum ProductCommentScoresEnum implements IntArrayValuable {
  17 +
  18 + ONE(1, "1星"),
  19 + TWO(2, "2星"),
  20 + THREE(3, "3星"),
  21 + FOUR(4, "4星"),
  22 + FIVE(5, "5星");
  23 +
  24 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductCommentScoresEnum::getScores).toArray();
  25 +
  26 + /**
  27 + * 星级
  28 + */
  29 + private final Integer scores;
  30 +
  31 + /**
  32 + * 星级名
  33 + */
  34 + private final String name;
  35 +
  36 + @Override
  37 + public int[] array() {
  38 + return ARRAYS;
  39 + }
  40 +
  41 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.http 0 → 100644
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.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.product.controller.admin.comment.vo.ProductCommentPageReqVO;
  6 +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO;
  7 +import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
  8 +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
  9 +import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
  10 +import io.swagger.v3.oas.annotations.Operation;
  11 +import io.swagger.v3.oas.annotations.tags.Tag;
  12 +import org.springframework.security.access.prepost.PreAuthorize;
  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.RestController;
  17 +
  18 +import javax.annotation.Resource;
  19 +import javax.validation.Valid;
  20 +
  21 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  22 +
  23 +@Tag(name = "管理后台 - 商品评价")
  24 +@RestController
  25 +@RequestMapping("/product/comment")
  26 +@Validated
  27 +public class ProductCommentController {
  28 +
  29 + @Resource
  30 + private ProductCommentService productCommentService;
  31 +
  32 + @GetMapping("/page")
  33 + @Operation(summary = "获得商品评价分页")
  34 + @PreAuthorize("@ss.hasPermission('product:comment:query')")
  35 + public CommonResult<PageResult<ProductCommentRespVO>> getCommentPage(@Valid ProductCommentPageReqVO pageVO) {
  36 + PageResult<ProductCommentDO> pageResult = productCommentService.getCommentPage(pageVO);
  37 + return success(ProductCommentConvert.INSTANCE.convertPage(pageResult));
  38 + }
  39 +
  40 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.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 ProductCommentBaseVO {
  11 +
  12 + @Schema(description = "评价人 用户编号", required = true, example = "15721")
  13 + @NotNull(message = "评价人 用户编号不能为空")
  14 + private Long userId;
  15 +
  16 + @Schema(description = "评价人名称", required = true, example = "张三")
  17 + @NotNull(message = "评价人名称不能为空")
  18 + private String userNickname;
  19 +
  20 + @Schema(description = "评价人头像", required = true)
  21 + @NotNull(message = "评价人头像不能为空")
  22 + private String userAvatar;
  23 +
  24 + @Schema(description = "商品SPU编号", required = true, example = "29502")
  25 + @NotNull(message = "商品SPU编号不能为空")
  26 + private Long spuId;
  27 +
  28 + @Schema(description = "商品SPU名称", required = true, example = "赵六")
  29 + @NotNull(message = "商品SPU名称不能为空")
  30 + private String spuName;
  31 +
  32 + @Schema(description = "商品SKU编号", required = true, example = "3082")
  33 + @NotNull(message = "商品SKU编号不能为空")
  34 + private Long skuId;
  35 +
  36 + @Schema(description = "评分星级 1-5分", required = true)
  37 + @NotNull(message = "评分星级 1-5分不能为空")
  38 + private Integer scores;
  39 +
  40 + @Schema(description = "描述星级 1-5分", required = true)
  41 + @NotNull(message = "描述星级 1-5分不能为空")
  42 + private Integer descriptionScores;
  43 +
  44 + @Schema(description = "服务星级 1-5分", required = true)
  45 + @NotNull(message = "服务星级 1-5分不能为空")
  46 + private Integer benefitScores;
  47 +
  48 + @Schema(description = "配送星级 1-5分", required = true)
  49 + @NotNull(message = "配送星级 1-5分不能为空")
  50 + private Integer deliveryScores;
  51 +
  52 + @Schema(description = "评论内容", required = true)
  53 + @NotNull(message = "评论内容不能为空")
  54 + private String content;
  55 +
  56 + @Schema(description = "评论图片地址数组,以逗号分隔最多上传9张", required = true)
  57 + @NotNull(message = "评论图片地址数组,以逗号分隔最多上传9张不能为空")
  58 + private List<String> picUrls;
  59 +
  60 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.comment.vo;
  2 +
  3 +import lombok.*;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +
  6 +@Schema(description = "管理后台 - 商品评价创建 Request VO")
  7 +@Data
  8 +@EqualsAndHashCode(callSuper = true)
  9 +@ToString(callSuper = true)
  10 +public class ProductCommentCreateReqVO extends ProductCommentBaseVO {
  11 +
  12 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.comment.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.product.enums.comment.ProductCommentScoresEnum;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +import lombok.ToString;
  10 +import org.springframework.format.annotation.DateTimeFormat;
  11 +
  12 +import java.time.LocalDateTime;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  15 +
  16 +@Schema(description = "管理后台 - 商品评价分页 Request VO")
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +public class ProductCommentPageReqVO extends PageParam {
  21 +
  22 + @Schema(description = "评价人名称", example = "王二狗")
  23 + private String userNickname;
  24 +
  25 + @Schema(description = "交易订单编号", example = "24428")
  26 + private Long orderId;
  27 +
  28 + @Schema(description = "商品SPU编号", example = "29502")
  29 + private Long spuId;
  30 +
  31 + @Schema(description = "商品SPU名称", example = "感冒药")
  32 + private String spuName;
  33 +
  34 + @Schema(description = "评分星级 1-5分")
  35 + @InEnum(ProductCommentScoresEnum.class)
  36 + private Integer scores;
  37 +
  38 + @Schema(description = "创建时间")
  39 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  40 + private LocalDateTime[] createTime;
  41 +
  42 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.comment.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +import java.time.LocalDateTime;
  6 +import java.util.List;
  7 +
  8 +@Schema(description = "管理后台 - 商品评价 Response VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class ProductCommentRespVO extends ProductCommentBaseVO {
  13 +
  14 + @Schema(description = "订单项编号", required = true, example = "24965")
  15 + private Long id;
  16 +
  17 + @Schema(description = "是否匿名:[0:不匿名 1:匿名]", required = true)
  18 + private Boolean anonymous;
  19 +
  20 + @Schema(description = "交易订单编号", required = true, example = "24428")
  21 + private Long orderId;
  22 +
  23 + @Schema(description = "交易订单项编号", required = true, example = "8233")
  24 + private Long orderItemId;
  25 +
  26 + @Schema(description = "是否可见:[1:显示 0:隐藏]", required = true)
  27 + private Boolean visible;
  28 +
  29 + @Schema(description = "商家是否回复:[1:回复 0:未回复]", required = true)
  30 + private Boolean replied;
  31 +
  32 + @Schema(description = "回复管理员编号", example = "22212")
  33 + private Long replyUserId;
  34 +
  35 + @Schema(description = "商家回复内容")
  36 + private String replyContent;
  37 +
  38 + @Schema(description = "商家回复时间")
  39 + private LocalDateTime replyTime;
  40 +
  41 + @Schema(description = "追加评价内容")
  42 + private String additionalContent;
  43 +
  44 + @Schema(description = "追评评价图片地址数组,以逗号分隔最多上传9张")
  45 + private List<String> additionalPicUrls;
  46 +
  47 + @Schema(description = "追加评价时间")
  48 + private LocalDateTime additionalCreateTime;
  49 +
  50 + @Schema(description = "创建时间", required = true)
  51 + private LocalDateTime createTime;
  52 +
  53 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.convert.comment;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO;
  5 +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
  6 +import org.mapstruct.Mapper;
  7 +import org.mapstruct.factory.Mappers;
  8 +
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * 商品评价 Convert
  13 + *
  14 + * @author wangzhs
  15 + */
  16 +@Mapper
  17 +public interface ProductCommentConvert {
  18 +
  19 + ProductCommentConvert INSTANCE = Mappers.getMapper(ProductCommentConvert.class);
  20 +
  21 + ProductCommentRespVO convert(ProductCommentDO bean);
  22 +
  23 + List<ProductCommentRespVO> convertList(List<ProductCommentDO> list);
  24 +
  25 + PageResult<ProductCommentRespVO> convertPage(PageResult<ProductCommentDO> page);
  26 +
  27 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java
... ... @@ -44,7 +44,7 @@ public class ProductCommentDO extends BaseDO {
44 44 /**
45 45 * 评价人名称
46 46 */
47   - private Long userNickname;
  47 + private String userNickname;
48 48  
49 49 /**
50 50 * 评价人头像
... ... @@ -78,6 +78,11 @@ public class ProductCommentDO extends BaseDO {
78 78 private Long spuId;
79 79  
80 80 /**
  81 + * 商品 SPU 名称
  82 + */
  83 + private String spuName;
  84 +
  85 + /**
81 86 * 商品 SKU 编号
82 87 * <p>
83 88 * 关联 {@link ProductSkuDO#getId()}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java
1 1 package cn.iocoder.yudao.module.product.dal.mysql.comment;
2 2  
3 3  
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  6 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  7 +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO;
5 8 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
6 9 import org.apache.ibatis.annotations.Mapper;
7 10  
... ... @@ -13,4 +16,16 @@ import org.apache.ibatis.annotations.Mapper;
13 16 */
14 17 @Mapper
15 18 public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
  19 +
  20 + default PageResult<ProductCommentDO> selectPage(ProductCommentPageReqVO reqVO) {
  21 + return selectPage(reqVO, new LambdaQueryWrapperX<ProductCommentDO>()
  22 + .likeIfPresent(ProductCommentDO::getUserNickname, reqVO.getUserNickname())
  23 + .eqIfPresent(ProductCommentDO::getOrderId, reqVO.getOrderId())
  24 + .eqIfPresent(ProductCommentDO::getSpuId, reqVO.getSpuId())
  25 + .eqIfPresent(ProductCommentDO::getScores, reqVO.getScores())
  26 + .betweenIfPresent(ProductCommentDO::getCreateTime, reqVO.getCreateTime())
  27 + .likeIfPresent(ProductCommentDO::getSpuName, reqVO.getSpuName())
  28 + .orderByDesc(ProductCommentDO::getId));
  29 + }
  30 +
16 31 }
... ...
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 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO;
  5 +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
3 6 import org.springframework.stereotype.Service;
4 7 import org.springframework.validation.annotation.Validated;
5 8  
... ... @@ -11,4 +14,13 @@ import org.springframework.validation.annotation.Validated;
11 14 @Service
12 15 @Validated
13 16 public interface ProductCommentService {
  17 +
  18 + /**
  19 + * 获得商品评价分页
  20 + *
  21 + * @param pageReqVO 分页查询
  22 + * @return 商品评价分页
  23 + */
  24 + PageResult<ProductCommentDO> getCommentPage(ProductCommentPageReqVO pageReqVO);
  25 +
14 26 }
... ...
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.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO;
  5 +import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
  6 +import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper;
  7 +import org.springframework.stereotype.Service;
  8 +import org.springframework.validation.annotation.Validated;
  9 +
  10 +import javax.annotation.Resource;
  11 +
3 12 /**
4 13 * 商品评论 Service 实现类
5 14 *
6 15 * @author wangzhs
7 16 */
  17 +@Service
  18 +@Validated
8 19 public class ProductCommentServiceImpl implements ProductCommentService {
  20 +
  21 + @Resource
  22 + private ProductCommentMapper productCommentMapper;
  23 +
  24 + @Override
  25 + public PageResult<ProductCommentDO> getCommentPage(ProductCommentPageReqVO pageReqVO) {
  26 + return productCommentMapper.selectPage(pageReqVO);
  27 + }
  28 +
9 29 }
... ...
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java
1 1 package cn.iocoder.yudao.module.product.service.comment;
2 2  
  3 +import cn.hutool.core.date.DateUtil;
  4 +import cn.hutool.core.util.RandomUtil;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 6 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
4   -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
  7 +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO;
  8 +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO;
  9 +import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert;
5 10 import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
6 11 import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper;
  12 +import cn.iocoder.yudao.module.product.enums.comment.ProductCommentScoresEnum;
7 13 import org.junit.jupiter.api.Test;
8 14 import org.springframework.context.annotation.Import;
9 15  
10 16 import javax.annotation.Resource;
  17 +import java.util.Date;
11 18  
  19 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
12 20 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
13 21 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  22 +import static org.junit.jupiter.api.Assertions.assertEquals;
14 23  
15 24 /**
16 25 * {@link ProductCommentServiceImpl} 的单元测试类
... ... @@ -23,6 +32,17 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
23 32 @Resource
24 33 private ProductCommentMapper productCommentMapper;
25 34  
  35 + @Resource
  36 + private ProductCommentServiceImpl productCommentService;
  37 +
  38 + public String generateNo() {
  39 + return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999);
  40 + }
  41 +
  42 + public Long generateId() {
  43 + return RandomUtil.randomLong(100000, 999999);
  44 + }
  45 +
26 46 @Test
27 47 public void testCreateCommentAndGet_success() {
28 48 // mock 测试
... ... @@ -35,5 +55,44 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
35 55 assertPojoEquals(productComment, comment);
36 56 }
37 57  
  58 + @Test
  59 + public void testGetCommentPage_success() {
  60 + // 准备参数
  61 + ProductCommentDO productComment = randomPojo(ProductCommentDO.class, o -> {
  62 + o.setUserNickname("王二狗");
  63 + o.setSpuName("感冒药");
  64 + o.setScores(ProductCommentScoresEnum.FOUR.getScores());
  65 + });
  66 + productCommentMapper.insert(productComment);
  67 +
  68 + Long orderId = productComment.getOrderId();
  69 + Long spuId = productComment.getSpuId();
  70 +
  71 + // 测试 userNickname 不匹配
  72 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setUserNickname("王三")));
  73 + // 测试 orderId 不匹配
  74 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setOrderId(generateId())));
  75 + // 测试 spuId 不匹配
  76 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setSpuId(generateId())));
  77 + // 测试 spuName 不匹配
  78 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setSpuName("感康")));
  79 + // 测试 scores 不匹配
  80 + productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setScores(ProductCommentScoresEnum.ONE.getScores())));
  81 +
  82 + // 调用
  83 + ProductCommentPageReqVO productCommentPageReqVO = new ProductCommentPageReqVO();
  84 + productCommentPageReqVO.setUserNickname("王二");
  85 + productCommentPageReqVO.setOrderId(orderId);
  86 + productCommentPageReqVO.setSpuId(spuId);
  87 + productCommentPageReqVO.setSpuName("感冒药");
  88 + productCommentPageReqVO.setScores(ProductCommentScoresEnum.FOUR.getScores());
  89 +
  90 + PageResult<ProductCommentDO> commentPage = productCommentService.getCommentPage(productCommentPageReqVO);
  91 + PageResult<ProductCommentRespVO> result = ProductCommentConvert.INSTANCE.convertPage(productCommentMapper.selectPage(productCommentPageReqVO));
  92 + assertEquals(result.getTotal(), commentPage.getTotal());
  93 +
  94 + PageResult<ProductCommentDO> all = productCommentService.getCommentPage(new ProductCommentPageReqVO());
  95 + assertEquals(6, all.getTotal());
  96 + }
38 97  
39 98 }
... ...
yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql
... ... @@ -92,6 +92,7 @@ CREATE TABLE IF NOT EXISTS `product_comment` (
92 92 `order_id` bigint NOT NULL COMMENT '交易订单编号',
93 93 `order_item_id` bigint NOT NULL COMMENT '交易订单项编号',
94 94 `spu_id` bigint NOT NULL COMMENT '商品SPU编号',
  95 + `spu_name` varchar NOT NULL COMMENT '商品SPU名称',
95 96 `sku_id` bigint NOT NULL COMMENT '商品SKU编号',
96 97 `visible` bit(1) NOT NULL DEFAULT 1 COMMENT '是否可见 1:显示 0:隐藏',
97 98 `scores` int NOT NULL COMMENT '评分星级 1-5分',
... ...