fix:修复 mall review @puhui999

This commit is contained in:
puhui999
2023-07-10 16:35:49 +08:00
parent 9cbd0fec1c
commit e7d8643665
38 changed files with 207 additions and 244 deletions

View File

@@ -26,23 +26,10 @@ public class ProductCommentBaseVO {
@NotNull(message = "评价人头像不能为空")
private String userAvatar;
// TODO @puhuispuId、spuName 是不是只有 ProductCommentRespVO 有呀。
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑透气小短袖")
@NotNull(message = "商品 SPU 编号不能为空")
private Long spuId;
@Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
@NotNull(message = "商品 SPU 名称不能为空")
private String spuName;
@Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "商品 SKU 编号不能为空")
private Long skuId;
@Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
@NotNull(message = "评分星级不能为空")
private Integer scores;
@Schema(description = "描述星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
@NotNull(message = "描述星级不能为空")
private Integer descriptionScores;

View File

@@ -35,9 +35,8 @@ public class ProductCommentPageReqVO extends PageParam {
@InEnum(ProductCommentScoresEnum.class)
private Integer scores;
// TODO @puhui999replyStatus 哈
@Schema(description = "商家是否回复", example = "true")
private Boolean replied;
private Boolean replyStatus;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)

View File

@@ -5,6 +5,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 商品评价 Response VO")
@@ -40,4 +41,15 @@ public class ProductCommentRespVO extends ProductCommentBaseVO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
private Integer scores;
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑透气小短袖")
@NotNull(message = "商品 SPU 编号不能为空")
private Long spuId;
@Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
@NotNull(message = "商品 SPU 名称不能为空")
private String spuName;
}

View File

@@ -30,11 +30,6 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
/**
* 商品 SPU 相关接口
*
* @author HUIHUI
*/
@Tag(name = "管理后台 - 商品 SPU")
@RestController
@RequestMapping("/product/spu")

View File

@@ -9,11 +9,6 @@ import lombok.ToString;
import javax.validation.Valid;
import java.util.List;
/**
* 商品 SPU 创建 Request VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 商品 SPU 创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)

View File

@@ -8,12 +8,6 @@ import lombok.ToString;
import java.util.List;
/**
* 商品 SPU 详细 Response VO
* 包括关联的 SKU 等信息
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 商品 SPU 详细 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)

View File

@@ -10,11 +10,6 @@ import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的")
@Data
@NoArgsConstructor

View File

@@ -11,11 +11,6 @@ import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 商品 SPU 分页 Request VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 商品 SPU 分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)

View File

@@ -7,11 +7,6 @@ import lombok.ToString;
import java.time.LocalDateTime;
/**
* 商品 SPU Response VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 商品 SPU Response VO")
@Data
@EqualsAndHashCode(callSuper = true)

View File

@@ -4,11 +4,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
/**
* 商品 SPU 精简 Response VO
* TODO 商品 SPU 精简 VO 暂时没有使用到,用到的时候再按需添加\修改属性
* @author HUIHUI
*/
@Schema(description = "管理后台 - 商品 SPU 精简 Response VO")
@Data
@ToString(callSuper = true)

View File

@@ -12,11 +12,6 @@ import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 商品 SPU 更新 Request VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 商品 SPU 更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)

View File

@@ -7,11 +7,6 @@ import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 商品 SPU Status 更新 Request VO
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 商品 SPU Status 更新 Request VO")
@Data
public class ProductSpuUpdateStatusReqVO{

View File

@@ -1,18 +1,18 @@
package cn.iocoder.yudao.module.product.controller.app.comment;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO;
import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
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.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.service.comment.ProductCommentService;
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
@@ -26,11 +26,9 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -61,26 +59,14 @@ public class AppProductCommentController {
@GetMapping("/page")
@Operation(summary = "获得商品评价分页")
public CommonResult<PageResult<AppProductCommentRespVO>> getCommentPage(@Valid AppCommentPageReqVO pageVO) {
PageResult<AppProductCommentRespVO> page = productCommentService.getCommentPage(pageVO, Boolean.TRUE);
// TODO @puhui CollUtils 有简化 convertmap 和 list 的方法
Set<Long> skuIds = page.getList().stream().map(AppProductCommentRespVO::getSkuId).collect(Collectors.toSet());
PageResult<ProductCommentDO> commentDOPage = productCommentService.getCommentPage(pageVO, Boolean.TRUE);
Set<Long> skuIds = CollectionUtils.convertSet(commentDOPage.getList(), ProductCommentDO::getSkuId);
List<ProductSkuDO> skuList = productSkuService.getSkuList(skuIds);
Map<Long, ProductSkuDO> skuDOMap = new HashMap<>(skuIds.size());
Map<Long, ProductSkuDO> skuDOMap = Maps.newLinkedHashMapWithExpectedSize(skuIds.size());
if (CollUtil.isNotEmpty(skuList)) {
skuDOMap.putAll(skuList.stream().collect(Collectors.toMap(ProductSkuDO::getId, c -> c)));
skuDOMap.putAll(CollectionUtils.convertMap(skuList, ProductSkuDO::getId, c -> c));
}
// TODO @puihui999下面也可以放到 convert 里哈
page.getList().forEach(item -> {
// 判断用户是否选择匿名
if (ObjectUtil.equal(item.getAnonymous(), true)) {
item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS);
}
ProductSkuDO productSkuDO = skuDOMap.get(item.getSkuId());
if (productSkuDO != null) {
List<AppProductPropertyValueDetailRespVO> skuProperties = ProductCommentConvert.INSTANCE.convertList01(productSkuDO.getProperties());
item.setSkuProperties(skuProperties);
}
});
PageResult<AppProductCommentRespVO> page = ProductCommentConvert.INSTANCE.convertPage02(commentDOPage, skuDOMap);
return success(page);
}

View File

@@ -10,11 +10,6 @@ import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.List;
/**
* 用户 App - 商品评价详情 Response VO
*
* @author HUIHUI
*/
@Schema(description = "用户 App - 商品评价详情 Response VO")
@Data
@ToString(callSuper = true)

View File

@@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.product.convert.comment;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
@@ -19,6 +20,7 @@ import org.mapstruct.factory.Mappers;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
/**
* 商品评价 Convert
@@ -32,10 +34,12 @@ public interface ProductCommentConvert {
ProductCommentRespVO convert(ProductCommentDO bean);
// TODO @puhui999这里貌似字段对上就不用 mapping 了;可以测试下看看哈
@Mapping(target = "goodCount", source = "goodCount")
@Mapping(target = "mediocreCount", source = "mediocreCount")
@Mapping(target = "negativeCount", source = "negativeCount")
@Named("calculateOverallScore")
default double calculateOverallScore(long goodCount, long mediocreCount, long negativeCount) {
return (goodCount * 5 + mediocreCount * 3 + negativeCount) / (double) (goodCount + mediocreCount + negativeCount);
}
@Mapping(target = "scores", expression = "java(calculateOverallScore(goodCount, mediocreCount, negativeCount))")
AppCommentStatisticsRespVO convert(Long goodCount, Long mediocreCount, Long negativeCount);
List<ProductCommentRespVO> convertList(List<ProductCommentDO> list);
@@ -44,7 +48,23 @@ public interface ProductCommentConvert {
PageResult<ProductCommentRespVO> convertPage(PageResult<ProductCommentDO> page);
PageResult<AppProductCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult);
PageResult<AppProductCommentRespVO> convertPage01(PageResult<ProductCommentDO> pageResult);
default PageResult<AppProductCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult, Map<Long, ProductSkuDO> skuDOMap) {
PageResult<AppProductCommentRespVO> page = convertPage01(pageResult);
page.getList().forEach(item -> {
// 判断用户是否选择匿名
if (ObjectUtil.equal(item.getAnonymous(), true)) {
item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS);
}
ProductSkuDO productSkuDO = skuDOMap.get(item.getSkuId());
if (productSkuDO != null) {
List<AppProductPropertyValueDetailRespVO> skuProperties = ProductCommentConvert.INSTANCE.convertList01(productSkuDO.getProperties());
item.setSkuProperties(skuProperties);
}
});
return page;
}
/**
* 计算综合评分

View File

@@ -51,11 +51,11 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
return selectPage(reqVO, queryWrapper);
}
default ProductCommentDO selectByUserIdAndOrderItemIdAndSpuId(Long userId, Long orderItemId, Long spuId) {
default ProductCommentDO selectByUserIdAndOrderItemIdAndSpuId(Long userId, Long orderItemId, Long skuId) {
return selectOne(new LambdaQueryWrapperX<ProductCommentDO>()
.eq(ProductCommentDO::getUserId, userId)
.eq(ProductCommentDO::getOrderItemId, orderItemId)
.eq(ProductCommentDO::getSpuId, spuId));
.eq(ProductCommentDO::getSpuId, skuId));
}
default Long selectCountBySpuId(Long spuId, Boolean visible, Integer type) {

View File

@@ -54,7 +54,7 @@ public interface ProductCommentService {
* @param visible 是否可见
* @return 商品评价分页
*/
PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
PageResult<ProductCommentDO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible);
/**
* 创建商品评论

View File

@@ -81,7 +81,7 @@ public class ProductCommentServiceImpl implements ProductCommentService {
@Transactional(rollbackFor = Exception.class)
public void createComment(ProductCommentCreateReqVO createReqVO) {
// 校验评论
validateComment(createReqVO.getSpuId(), createReqVO.getUserId(), createReqVO.getOrderItemId());
validateComment(createReqVO.getSkuId(), createReqVO.getUserId(), createReqVO.getOrderItemId());
ProductCommentDO commentDO = ProductCommentConvert.INSTANCE.convert(createReqVO);
productCommentMapper.insert(commentDO);
@@ -108,11 +108,11 @@ public class ProductCommentServiceImpl implements ProductCommentService {
return commentDO.getId();
}
private void validateComment(Long spuId, Long userId, Long orderItemId) {
private void validateComment(Long skuId, Long userId, Long orderItemId) {
// 判断当前订单的当前商品用户是否评价过
ProductCommentDO exist = productCommentMapper.selectByUserIdAndOrderItemIdAndSpuId(userId, orderItemId, spuId);
ProductCommentDO exist = productCommentMapper.selectByUserIdAndOrderItemIdAndSpuId(userId, orderItemId, skuId);
if (null != exist) {
throw exception(ORDER_SPU_COMMENT_EXISTS);
throw exception(ORDER_SKU_COMMENT_EXISTS);
}
}
@@ -141,23 +141,17 @@ public class ProductCommentServiceImpl implements ProductCommentService {
productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT),
// 查询商品 id = spuId 的所有差评数量
productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT)
).setScores(3.0); // TODO @puhui999这里要实现下
);
}
@Override
public List<AppProductCommentRespVO> getCommentList(Long spuId, Integer count) {
// 校验商品 spu 是否存在
// TODO @puhui 这里校验可以去掉哈。
ProductSpuDO spuDO = validateSpu(spuId);
return ProductCommentConvert.INSTANCE.convertList02(productCommentMapper.selectCommentList(spuDO.getId(), count).getList());
return ProductCommentConvert.INSTANCE.convertList02(productCommentMapper.selectCommentList(spuId, count).getList());
}
// TODO @puhui 可以放到 controller 去 convert 哈
@Override
public PageResult<AppProductCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
// TODO @puhui 可以放到 controller 去 convert 哈
return ProductCommentConvert.INSTANCE.convertPage02(
productCommentMapper.selectPage(pageVO, visible));
public PageResult<ProductCommentDO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
return productCommentMapper.selectPage(pageVO, visible);
}
@Override

View File

@@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommen
import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO;
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO;
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO;
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO;
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;
@@ -128,7 +127,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
productCommentPageReqVO.setSpuId(spuId);
productCommentPageReqVO.setSpuName("感冒药");
productCommentPageReqVO.setScores(ProductCommentScoresEnum.FOUR.getScores());
productCommentPageReqVO.setReplied(Boolean.TRUE);
productCommentPageReqVO.setReplyStatus(Boolean.TRUE);
PageResult<ProductCommentDO> commentPage = productCommentService.getCommentPage(productCommentPageReqVO);
PageResult<ProductCommentRespVO> result = ProductCommentConvert.INSTANCE.convertPage(productCommentMapper.selectPage(productCommentPageReqVO));
@@ -138,15 +137,15 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
assertEquals(8, all.getTotal());
// 测试获取所有商品分页评论数据
PageResult<AppProductCommentRespVO> result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE);
PageResult<ProductCommentDO> result1 = productCommentService.getCommentPage(new AppCommentPageReqVO(), Boolean.TRUE);
assertEquals(7, result1.getTotal());
// 测试获取所有商品分页中评数据
PageResult<AppProductCommentRespVO> result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
PageResult<ProductCommentDO> result2 = productCommentService.getCommentPage(new AppCommentPageReqVO().setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
assertEquals(2, result2.getTotal());
// 测试获取指定 spuId 商品分页中评数据
PageResult<AppProductCommentRespVO> result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
PageResult<ProductCommentDO> result3 = productCommentService.getCommentPage(new AppCommentPageReqVO().setSpuId(spuId).setType(AppCommentPageReqVO.MEDIOCRE_COMMENT), Boolean.TRUE);
assertEquals(2, result3.getTotal());
// 测试分页 tab count