mall + product:评论的 review

This commit is contained in:
YunaiV
2023-06-09 22:41:16 +08:00
parent 84b365a707
commit 1e1a22c256
17 changed files with 70 additions and 175 deletions

View File

@ -35,6 +35,7 @@ public class ProductCommentController {
return success(ProductCommentConvert.INSTANCE.convertPage(pageResult)); return success(ProductCommentConvert.INSTANCE.convertPage(pageResult));
} }
// TODO @puhui999update-visible
@PutMapping("/update/visible") @PutMapping("/update/visible")
@Operation(summary = "显示 / 隐藏评论") @Operation(summary = "显示 / 隐藏评论")
@PreAuthorize("@ss.hasPermission('product:comment:update')") @PreAuthorize("@ss.hasPermission('product:comment:update')")
@ -55,6 +56,7 @@ public class ProductCommentController {
@Operation(summary = "添加自评") @Operation(summary = "添加自评")
@PreAuthorize("@ss.hasPermission('product:comment:update')") @PreAuthorize("@ss.hasPermission('product:comment:update')")
public CommonResult<Boolean> createComment(@Valid @RequestBody ProductCommentCreateReqVO createReqVO) { public CommonResult<Boolean> createComment(@Valid @RequestBody ProductCommentCreateReqVO createReqVO) {
// TODO @puhui999不用 ProductCommentConvert.INSTANCE.convert(createReqVO) 哈;多写一个 create 方法即可;
productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(createReqVO), Boolean.TRUE); productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(createReqVO), Boolean.TRUE);
return success(true); return success(true);
} }

View File

@ -10,6 +10,8 @@ import java.util.List;
@Data @Data
public class ProductCommentBaseVO { public class ProductCommentBaseVO {
// TODO @puhui999把 example 补充下
@Schema(description = "评价人名称", required = true, example = "张三") @Schema(description = "评价人名称", required = true, example = "张三")
@NotNull(message = "评价人名称不能为空") @NotNull(message = "评价人名称不能为空")
private String userNickname; private String userNickname;
@ -31,21 +33,17 @@ public class ProductCommentBaseVO {
private Long skuId; private Long skuId;
@Schema(description = "评分星级 1-5分", required = true) @Schema(description = "评分星级 1-5分", required = true)
@NotNull(message = "评分星级 1-5分不能为空") @NotNull(message = "评分星级不能为空")
private Integer scores; private Integer scores;
@Schema(description = "描述星级 1-5分", required = true) @Schema(description = "描述星级 1-5分", required = true)
@NotNull(message = "描述星级 1-5分不能为空") @NotNull(message = "描述星级不能为空")
private Integer descriptionScores; private Integer descriptionScores;
@Schema(description = "服务星级 1-5分", required = true) @Schema(description = "服务星级 1-5分", required = true)
@NotNull(message = "服务星级 1-5分不能为空") @NotNull(message = "服务星级分不能为空")
private Integer benefitScores; private Integer benefitScores;
@Schema(description = "配送星级 1-5分", required = true)
@NotNull(message = "配送星级 1-5分不能为空")
private Integer deliveryScores;
@Schema(description = "评论内容", required = true) @Schema(description = "评论内容", required = true)
@NotNull(message = "评论内容不能为空") @NotNull(message = "评论内容不能为空")
private String content; private String content;

View File

@ -4,8 +4,10 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.ToString; import lombok.ToString;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
// TODO @puhui999ReqVO
@Schema(description = "管理后台 - 商品评价可见修改 Request VO") @Schema(description = "管理后台 - 商品评价可见修改 Request VO")
@Data @Data
@ToString(callSuper = true) @ToString(callSuper = true)
@ -16,7 +18,7 @@ public class ProductCommentReplyVO {
private Long id; private Long id;
@Schema(description = "商家回复内容", required = true, example = "谢谢亲") @Schema(description = "商家回复内容", required = true, example = "谢谢亲")
@NotNull(message = "商家回复内容不能为空") @NotEmpty(message = "商家回复内容不能为空")
private String replyContent; private String replyContent;
} }

View File

@ -6,7 +6,6 @@ import lombok.EqualsAndHashCode;
import lombok.ToString; import lombok.ToString;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 商品评价 Response VO") @Schema(description = "管理后台 - 商品评价 Response VO")
@Data @Data
@ -33,7 +32,7 @@ public class ProductCommentRespVO extends ProductCommentBaseVO {
private Boolean visible; private Boolean visible;
@Schema(description = "商家是否回复:[1:回复 0:未回复]", required = true) @Schema(description = "商家是否回复:[1:回复 0:未回复]", required = true)
private Boolean replied; private Boolean replyStatus;
@Schema(description = "回复管理员编号", example = "22212") @Schema(description = "回复管理员编号", example = "22212")
private Long replyUserId; private Long replyUserId;
@ -44,15 +43,6 @@ public class ProductCommentRespVO extends ProductCommentBaseVO {
@Schema(description = "商家回复时间") @Schema(description = "商家回复时间")
private LocalDateTime replyTime; private LocalDateTime replyTime;
@Schema(description = "追加评价内容")
private String additionalContent;
@Schema(description = "追评评价图片地址数组以逗号分隔最多上传9张")
private List<String> additionalPicUrls;
@Schema(description = "追加评价时间")
private LocalDateTime additionalTime;
@Schema(description = "创建时间", required = true) @Schema(description = "创建时间", required = true)
private LocalDateTime createTime; private LocalDateTime createTime;

View File

@ -15,7 +15,7 @@ public class ProductCommentUpdateVisibleReqVO {
@NotNull(message = "评价编号不能为空") @NotNull(message = "评价编号不能为空")
private Long id; private Long id;
@Schema(description = "是否可见 true:显示 false:隐藏", required = true, example = "false") @Schema(description = "是否可见", required = true, example = "false")
@NotNull(message = "是否可见不能为空") @NotNull(message = "是否可见不能为空")
private Boolean visible; private Boolean visible;

View File

@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 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.AppCommentCreateReqVO;
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; 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.controller.app.comment.vo.AppCommentRespVO;
@ -22,6 +21,7 @@ import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
// TODO @puhui999AppCommentController =》 AppProductCommentController
@Tag(name = "用户 APP - 商品评价") @Tag(name = "用户 APP - 商品评价")
@RestController @RestController
@RequestMapping("/product/comment") @RequestMapping("/product/comment")
@ -40,8 +40,9 @@ public class AppCommentController {
return success(productCommentService.getCommentPage(pageVO, Boolean.TRUE)); return success(productCommentService.getCommentPage(pageVO, Boolean.TRUE));
} }
// TODO @puhui999方法名改成 getCommentStatistics然后搞个对应的 vo想了下这样更优雅
@GetMapping("/get-count") @GetMapping("/get-count")
@Operation(summary = "获得商品评价分页 tab count") @Operation(summary = "获得商品评价统计") // TODO @puhui999@RequestParam 哈,针对 spuId
public CommonResult<Map<String, Long>> getCommentPage(@Valid Long spuId) { public CommonResult<Map<String, Long>> getCommentPage(@Valid Long spuId) {
return success(productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE)); return success(productCommentService.getCommentPageTabsCount(spuId, Boolean.TRUE));
} }
@ -50,18 +51,10 @@ public class AppCommentController {
@Operation(summary = "创建商品评价") @Operation(summary = "创建商品评价")
public CommonResult<Boolean> createComment(@RequestBody AppCommentCreateReqVO createReqVO) { public CommonResult<Boolean> createComment(@RequestBody AppCommentCreateReqVO createReqVO) {
// TODO: 2023/3/20 要不要判断订单、商品是否存在 // TODO: 2023/3/20 要不要判断订单、商品是否存在
// TODO @ouhui999这个接口搞到交易那比较合适
MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId()); MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId());
productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(user, createReqVO), Boolean.FALSE); productCommentService.createComment(ProductCommentConvert.INSTANCE.convert(user, createReqVO), Boolean.FALSE);
return success(true); return success(true);
} }
@PostMapping(value = "/additional")
@Operation(summary = "追加评论")
public CommonResult<Boolean> additionalComment(@RequestBody AppCommentAdditionalReqVO createReqVO) {
// 查询会员
MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId());
productCommentService.additionalComment(user, createReqVO);
return success(true);
}
} }

View File

@ -1,28 +0,0 @@
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 javax.validation.constraints.Size;
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)
@Size(max = 9, message = "追评评价图片地址数组长度不能超过9张")
private List<String> additionalPicUrls;
}

View File

@ -7,6 +7,7 @@ import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import java.util.List; import java.util.List;
// TODO @puhui999把 Product 前缀给补下哈
@Data @Data
public class AppCommentBaseVO { public class AppCommentBaseVO {
@ -34,10 +35,6 @@ public class AppCommentBaseVO {
@NotNull(message = "服务星级 1-5分不能为空") @NotNull(message = "服务星级 1-5分不能为空")
private Integer benefitScores; private Integer benefitScores;
@Schema(description = "配送星级 1-5分", required = true)
@NotNull(message = "配送星级 1-5分不能为空")
private Integer deliveryScores;
@Schema(description = "评论内容", required = true) @Schema(description = "评论内容", required = true)
@NotNull(message = "评论内容不能为空") @NotNull(message = "评论内容不能为空")
private String content; private String content;

View File

@ -7,16 +7,19 @@ import lombok.ToString;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
// TODO @puhui999不应该继承 AppCommentCreateReqVO
@Schema(description = "用户APP - 商品评价创建 Request VO") @Schema(description = "用户APP - 商品评价创建 Request VO")
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
public class AppCommentCreateReqVO extends AppCommentBaseVO { public class AppCommentCreateReqVO extends AppCommentBaseVO {
@Schema(description = "是否匿名 true:是 false:否", required = true, example = "true") @Schema(description = "是否匿名", required = true, example = "true")
@NotNull(message = "是否匿名不能为空") @NotNull(message = "是否匿名不能为空")
private Boolean anonymous; private Boolean anonymous;
// TODO @puhui999:不应该传递 orderId
@Schema(description = "交易订单编号", required = true, example = "12312") @Schema(description = "交易订单编号", required = true, example = "12312")
@NotNull(message = "交易订单编号不能为空") @NotNull(message = "交易订单编号不能为空")
private Long orderId; private Long orderId;

View File

@ -14,6 +14,7 @@ import javax.validation.constraints.NotNull;
@ToString(callSuper = true) @ToString(callSuper = true)
public class AppCommentPageReqVO extends PageParam { public class AppCommentPageReqVO extends PageParam {
// TODO @puhui999不传递就是 all
/** /**
* 所有 * 所有
*/ */
@ -24,11 +25,13 @@ public class AppCommentPageReqVO extends PageParam {
*/ */
public static final String ALL_COUNT = "allCount"; public static final String ALL_COUNT = "allCount";
// TODO @puhui999good 好评;
/** /**
* 好评 * 好评
*/ */
public static final Integer FAVOURABLE_COMMENT = 1; public static final Integer FAVOURABLE_COMMENT = 1;
// TODO @puhui999medium 中评;然后 mediumCount 就好啦;
/** /**
* 好评数量 key * 好评数量 key
*/ */
@ -54,6 +57,7 @@ public class AppCommentPageReqVO extends PageParam {
*/ */
public static final String NEGATIVE_COMMENT_COUNT = "negativeCommentCount"; public static final String NEGATIVE_COMMENT_COUNT = "negativeCommentCount";
// TODO @puhui999这个挪到 DO 那没问题的哈NICKNAME_ANONYMOUS
/** /**
* 默认匿名昵称 * 默认匿名昵称
*/ */

View File

@ -14,7 +14,9 @@ import java.util.List;
@ToString(callSuper = true) @ToString(callSuper = true)
public class AppCommentRespVO extends AppCommentBaseVO { public class AppCommentRespVO extends AppCommentBaseVO {
@Schema(description = "评价人 用户编号", required = true, example = "15721") // TODO puhui999把 example 也补充下哈
@Schema(description = "评价人的用户编号", required = true, example = "15721")
private Long userId; private Long userId;
@Schema(description = "评价人名称", required = true, example = "张三") @Schema(description = "评价人名称", required = true, example = "张三")
@ -36,7 +38,7 @@ public class AppCommentRespVO extends AppCommentBaseVO {
private Long orderItemId; private Long orderItemId;
@Schema(description = "商家是否回复", required = true) @Schema(description = "商家是否回复", required = true)
private Boolean replied; private Boolean replyStatus;
@Schema(description = "回复管理员编号", example = "22212") @Schema(description = "回复管理员编号", example = "22212")
private Long replyUserId; private Long replyUserId;
@ -61,4 +63,5 @@ public class AppCommentRespVO extends AppCommentBaseVO {
@Schema(description = "最终评分", required = true) @Schema(description = "最终评分", required = true)
private Integer finalScore; private Integer finalScore;
} }

View File

@ -30,6 +30,7 @@ public interface ProductCommentConvert {
PageResult<AppCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult); PageResult<AppCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult);
// TODO @puhui999用 mapstruct 的映射
default ProductCommentDO convert(MemberUserRespDTO user, AppCommentCreateReqVO createReqVO) { default ProductCommentDO convert(MemberUserRespDTO user, AppCommentCreateReqVO createReqVO) {
ProductCommentDO productComment = new ProductCommentDO(); ProductCommentDO productComment = new ProductCommentDO();
productComment.setUserId(user.getId()); productComment.setUserId(user.getId());
@ -44,12 +45,12 @@ public interface ProductCommentConvert {
productComment.setScores(createReqVO.getScores()); productComment.setScores(createReqVO.getScores());
productComment.setDescriptionScores(createReqVO.getDescriptionScores()); productComment.setDescriptionScores(createReqVO.getDescriptionScores());
productComment.setBenefitScores(createReqVO.getBenefitScores()); productComment.setBenefitScores(createReqVO.getBenefitScores());
productComment.setDeliveryScores(createReqVO.getDeliveryScores());
productComment.setContent(createReqVO.getContent()); productComment.setContent(createReqVO.getContent());
productComment.setPicUrls(createReqVO.getPicUrls()); productComment.setPicUrls(createReqVO.getPicUrls());
return productComment; return productComment;
} }
// TODO @puhui999用 mapstruct 的映射
default ProductCommentDO convert(ProductCommentCreateReqVO createReq) { default ProductCommentDO convert(ProductCommentCreateReqVO createReq) {
ProductCommentDO productComment = new ProductCommentDO(); ProductCommentDO productComment = new ProductCommentDO();
productComment.setUserId(0L); productComment.setUserId(0L);
@ -64,7 +65,6 @@ public interface ProductCommentConvert {
productComment.setScores(createReq.getScores()); productComment.setScores(createReq.getScores());
productComment.setDescriptionScores(createReq.getDescriptionScores()); productComment.setDescriptionScores(createReq.getDescriptionScores());
productComment.setBenefitScores(createReq.getBenefitScores()); productComment.setBenefitScores(createReq.getBenefitScores());
productComment.setDeliveryScores(createReq.getDeliveryScores());
productComment.setContent(createReq.getContent()); productComment.setContent(createReq.getContent());
productComment.setPicUrls(createReq.getPicUrls()); productComment.setPicUrls(createReq.getPicUrls());
return productComment; return productComment;

View File

@ -36,20 +36,18 @@ public class ProductCommentDO extends BaseDO {
/** /**
* 评价人 用户编号 * 评价人 用户编号
*
* 关联 MemberUserDO 的 id 编号 * 关联 MemberUserDO 的 id 编号
*/ */
private Long userId; private Long userId;
/** /**
* 评价人名称 * 评价人名称
*/ */
private String userNickname; private String userNickname;
/** /**
* 评价人头像 * 评价人头像
*/ */
private String userAvatar; private String userAvatar;
/** /**
* 是否匿名 * 是否匿名
*/ */
@ -57,12 +55,13 @@ public class ProductCommentDO extends BaseDO {
/** /**
* 交易订单编号 * 交易订单编号
*
* 关联 TradeOrderDO 的 id 编号 * 关联 TradeOrderDO 的 id 编号
*/ */
private Long orderId; private Long orderId;
/** /**
* 交易订单项编号 * 交易订单项编号
*
* 关联 TradeOrderItemDO 的 id 编号 * 关联 TradeOrderItemDO 的 id 编号
*/ */
private Long orderItemId; private Long orderItemId;
@ -72,53 +71,46 @@ public class ProductCommentDO extends BaseDO {
* 关联 {@link ProductSpuDO#getId()} * 关联 {@link ProductSpuDO#getId()}
*/ */
private Long spuId; private Long spuId;
/** /**
* 商品 SPU 名称 * 商品 SPU 名称
*/ */
private String spuName; private String spuName;
/** /**
* 商品 SKU 编号 * 商品 SKU 编号
*
* 关联 {@link ProductSkuDO#getId()} * 关联 {@link ProductSkuDO#getId()}
*/ */
private Long skuId; private Long skuId;
/** /**
* 是否可见 * 是否可见
* true:显示 false:隐藏 *
* true:显示
* false:隐藏
*/ */
private Boolean visible; private Boolean visible;
/** /**
* 评分星级 * 评分星级
*
* 1-5分 * 1-5分
*/ */
private Integer scores; private Integer scores;
/** /**
* 描述星级 * 描述星级
*
* 1-5 星 * 1-5 星
*/ */
private Integer descriptionScores; private Integer descriptionScores;
/** /**
* 服务星级 * 服务星级
*
* 1-5 星 * 1-5 星
*/ */
private Integer benefitScores; private Integer benefitScores;
/**
* 配送星级
* 1-5 星
*/
private Integer deliveryScores;
/** /**
* 评论内容 * 评论内容
*/ */
private String content; private String content;
/** /**
* 评论图片地址数组 * 评论图片地址数组
*/ */
@ -128,38 +120,19 @@ public class ProductCommentDO extends BaseDO {
/** /**
* 商家是否回复 * 商家是否回复
*/ */
private Boolean replied; private Boolean replyStatus;
/** /**
* 回复管理员编号 * 回复管理员编号
* 关联 AdminUserDO 的 id 编号 * 关联 AdminUserDO 的 id 编号
*/ */
private Long replyUserId; private Long replyUserId;
/** /**
* 商家回复内容 * 商家回复内容
*/ */
private String replyContent; private String replyContent;
/** /**
* 商家回复时间 * 商家回复时间
*/ */
private LocalDateTime replyTime; private LocalDateTime replyTime;
/**
* 追加评价内容
*/
private String additionalContent;
/**
* 追评评价图片地址数组
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> additionalPicUrls;
/**
* 追加评价时间
*/
private LocalDateTime additionalTime;
} }

View File

@ -7,7 +7,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 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.ProductCommentPageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; 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.controller.app.comment.vo.AppCommentPageReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@ -15,12 +14,6 @@ import org.apache.ibatis.annotations.Mapper;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/**
* 商品评论 Mapper
*
* @author wangzhs
*/
@Mapper @Mapper
public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> { public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
@ -37,19 +30,16 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
// TODO 芋艿:在看看这块 // TODO 芋艿:在看看这块
static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) { static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) {
// 构建好评查询语句 // 构建好评查询语句:好评计算 (商品评分星级+服务评分星级) >= 8
if (ObjectUtil.equal(type, AppCommentPageReqVO.FAVOURABLE_COMMENT)) { if (ObjectUtil.equal(type, AppCommentPageReqVO.FAVOURABLE_COMMENT)) {
// 好评计算 (商品评分星级+服务评分星级) >= 8
queryWrapper.apply("(scores + benefit_scores) >= 8"); queryWrapper.apply("(scores + benefit_scores) >= 8");
} }
// 构建中评查询语句 // 构建中评查询语句:中评计算 (商品评分星级+服务评分星级) > 4 且 (商品评分星级+服务评分星级) < 8
if (ObjectUtil.equal(type, AppCommentPageReqVO.MEDIOCRE_COMMENT)) { if (ObjectUtil.equal(type, AppCommentPageReqVO.MEDIOCRE_COMMENT)) {
// 中评计算 (商品评分星级+服务评分星级) > 4 且 (商品评分星级+服务评分星级) < 8
queryWrapper.apply("(scores + benefit_scores) > 4 and (scores + benefit_scores) < 8"); queryWrapper.apply("(scores + benefit_scores) > 4 and (scores + benefit_scores) < 8");
} }
// 构建差评查询语句 // 构建差评查询语句:差评计算 (商品评分星级+服务评分星级) <= 4
if (ObjectUtil.equal(type, AppCommentPageReqVO.NEGATIVE_COMMENT)) { if (ObjectUtil.equal(type, AppCommentPageReqVO.NEGATIVE_COMMENT)) {
// 差评计算 (商品评分星级+服务评分星级) <= 4
queryWrapper.apply("(scores + benefit_scores) <= 4"); queryWrapper.apply("(scores + benefit_scores) <= 4");
} }
} }
@ -74,7 +64,7 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
default void commentReply(ProductCommentReplyVO replyVO, Long loginUserId) { default void commentReply(ProductCommentReplyVO replyVO, Long loginUserId) {
LambdaUpdateWrapper<ProductCommentDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<ProductCommentDO>() LambdaUpdateWrapper<ProductCommentDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<ProductCommentDO>()
.set(ProductCommentDO::getReplied, Boolean.TRUE) .set(ProductCommentDO::getReplyStatus, Boolean.TRUE)
.set(ProductCommentDO::getReplyTime, LocalDateTime.now()) .set(ProductCommentDO::getReplyTime, LocalDateTime.now())
.set(ProductCommentDO::getReplyUserId, loginUserId) .set(ProductCommentDO::getReplyUserId, loginUserId)
.set(ProductCommentDO::getReplyContent, replyVO.getReplyContent()) .set(ProductCommentDO::getReplyContent, replyVO.getReplyContent())
@ -82,6 +72,7 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
update(null, lambdaUpdateWrapper); update(null, lambdaUpdateWrapper);
} }
// TODO @puhui999使用 select 替代 find
default ProductCommentDO findByUserIdAndOrderIdAndSpuId(Long userId, Long orderId, Long spuId) { default ProductCommentDO findByUserIdAndOrderIdAndSpuId(Long userId, Long orderId, Long spuId) {
return selectOne(new LambdaQueryWrapperX<ProductCommentDO>() return selectOne(new LambdaQueryWrapperX<ProductCommentDO>()
.eq(ProductCommentDO::getUserId, userId) .eq(ProductCommentDO::getUserId, userId)
@ -89,15 +80,7 @@ public interface ProductCommentMapper extends BaseMapperX<ProductCommentDO> {
.eq(ProductCommentDO::getSpuId, spuId)); .eq(ProductCommentDO::getSpuId, spuId));
} }
default void additionalComment(AppCommentAdditionalReqVO createReqVO) { // TODO @puhui999selectCountBySpuId 即可
LambdaUpdateWrapper<ProductCommentDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<ProductCommentDO>()
.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);
}
default Long selectTabCount(Long spuId, Boolean visible, Integer type) { default Long selectTabCount(Long spuId, Boolean visible, Integer type) {
LambdaQueryWrapperX<ProductCommentDO> queryWrapper = new LambdaQueryWrapperX<ProductCommentDO>() LambdaQueryWrapperX<ProductCommentDO> queryWrapper = new LambdaQueryWrapperX<ProductCommentDO>()
.eqIfPresent(ProductCommentDO::getSpuId, spuId) .eqIfPresent(ProductCommentDO::getSpuId, spuId)

View File

@ -1,11 +1,9 @@
package cn.iocoder.yudao.module.product.service.comment; package cn.iocoder.yudao.module.product.service.comment;
import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.ProductCommentPageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; 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.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.controller.app.comment.vo.AppCommentPageReqVO;
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO;
import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO;
@ -38,6 +36,7 @@ public interface ProductCommentService {
*/ */
void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO); void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO);
// TODO @puhui999replyComment
/** /**
* 商家回复 * 商家回复
* *
@ -64,19 +63,12 @@ public interface ProductCommentService {
void createComment(ProductCommentDO productComment, Boolean system); void createComment(ProductCommentDO productComment, Boolean system);
/** /**
* 追加商品评论 * 获得商品的评价统计
*
* @param user 用户相关信息
* @param createReqVO 创建实体
*/
void additionalComment(MemberUserRespDTO user, AppCommentAdditionalReqVO createReqVO);
/**
* 评论页面标签数
* *
* @param spuId spu id * @param spuId spu id
* @param visible 是否可见 * @param visible 是否可见
* @return 获得商品评价分页 tab count * @return 评价统计
*/ */
Map<String, Long> getCommentPageTabsCount(Long spuId, Boolean visible); Map<String, Long> getCommentPageTabsCount(Long spuId, Boolean visible);
} }

View File

@ -2,11 +2,9 @@ package cn.iocoder.yudao.module.product.service.comment;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.ProductCommentPageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyVO; 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.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.controller.app.comment.vo.AppCommentPageReqVO;
import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentRespVO; 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.convert.comment.ProductCommentConvert;
@ -17,7 +15,6 @@ import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi; import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi;
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -25,13 +22,11 @@ import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
// TODO @芋艿:详细 review 下
/** /**
* 商品评论 Service 实现类 * 商品评论 Service 实现类
* *
@ -43,6 +38,7 @@ public class ProductCommentServiceImpl implements ProductCommentService {
@Resource @Resource
private ProductCommentMapper productCommentMapper; private ProductCommentMapper productCommentMapper;
@Resource @Resource
private TradeOrderApi tradeOrderApi; private TradeOrderApi tradeOrderApi;
@ -59,6 +55,8 @@ public class ProductCommentServiceImpl implements ProductCommentService {
// 校验评论是否存在 // 校验评论是否存在
validateCommentExists(updateReqVO.getId()); validateCommentExists(updateReqVO.getId());
// 更新可见状态
// TODO @puhui999直接使用 update 操作
productCommentMapper.updateCommentVisible(updateReqVO.getId(), updateReqVO.getVisible()); productCommentMapper.updateCommentVisible(updateReqVO.getId(), updateReqVO.getVisible());
} }
@ -67,6 +65,8 @@ public class ProductCommentServiceImpl implements ProductCommentService {
// 校验评论是否存在 // 校验评论是否存在
validateCommentExists(replyVO.getId()); validateCommentExists(replyVO.getId());
// 回复评论
// TODO @puhui999直接使用 update 操作
productCommentMapper.commentReply(replyVO, loginUserId); productCommentMapper.commentReply(replyVO, loginUserId);
} }
@ -90,12 +90,14 @@ public class ProductCommentServiceImpl implements ProductCommentService {
@Override @Override
public PageResult<AppCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) { public PageResult<AppCommentRespVO> getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) {
// TODO @puhui999逻辑可以在 controller 做哈。让 service 简介一点;因为是 view 需要不展示昵称
PageResult<AppCommentRespVO> result = ProductCommentConvert.INSTANCE.convertPage02(productCommentMapper.selectPage(pageVO, visible)); PageResult<AppCommentRespVO> result = ProductCommentConvert.INSTANCE.convertPage02(productCommentMapper.selectPage(pageVO, visible));
result.getList().forEach(item -> { result.getList().forEach(item -> {
// 判断用户是否选择匿名 // 判断用户是否选择匿名
if (ObjectUtil.equal(item.getAnonymous(), true)) { if (ObjectUtil.equal(item.getAnonymous(), true)) {
item.setUserNickname(AppCommentPageReqVO.ANONYMOUS_NICKNAME); item.setUserNickname(AppCommentPageReqVO.ANONYMOUS_NICKNAME);
} }
// TODO @puhui999直接插入的时候计算到 scores 字段里;这样就去掉 finalScore 字段哈
// 计算评价最终综合评分 最终星数 = (商品评星 + 服务评星) / 2 // 计算评价最终综合评分 最终星数 = (商品评星 + 服务评星) / 2
BigDecimal sumScore = new BigDecimal(item.getScores() + item.getBenefitScores()); BigDecimal sumScore = new BigDecimal(item.getScores() + item.getBenefitScores());
BigDecimal divide = sumScore.divide(BigDecimal.valueOf(2L), 0, RoundingMode.DOWN); BigDecimal divide = sumScore.divide(BigDecimal.valueOf(2L), 0, RoundingMode.DOWN);
@ -127,30 +129,11 @@ public class ProductCommentServiceImpl implements ProductCommentService {
productCommentMapper.insert(productComment); productCommentMapper.insert(productComment);
} }
@Override private void validateCommentExists(Long id) {
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); ProductCommentDO productComment = productCommentMapper.selectById(id);
if (productComment == null) { if (productComment == null) {
throw exception(COMMENT_NOT_EXISTS); throw exception(COMMENT_NOT_EXISTS);
} }
return productComment;
} }
} }

View File

@ -82,7 +82,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
o.setUserNickname("王二狗"); o.setUserNickname("王二狗");
o.setSpuName("感冒药"); o.setSpuName("感冒药");
o.setScores(ProductCommentScoresEnum.FOUR.getScores()); o.setScores(ProductCommentScoresEnum.FOUR.getScores());
o.setReplied(Boolean.TRUE); o.setReplyStatus(Boolean.TRUE);
o.setVisible(Boolean.TRUE); o.setVisible(Boolean.TRUE);
o.setId(generateId()); o.setId(generateId());
o.setUserId(generateId()); o.setUserId(generateId());
@ -118,7 +118,7 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest {
// 测试 scores 不匹配 // 测试 scores 不匹配
productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setScores(ProductCommentScoresEnum.ONE.getScores()))); productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setScores(ProductCommentScoresEnum.ONE.getScores())));
// 测试 replied 不匹配 // 测试 replied 不匹配
productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setReplied(Boolean.FALSE))); productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setReplyStatus(Boolean.FALSE)));
// 测试 visible 不匹配 // 测试 visible 不匹配
productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setVisible(Boolean.FALSE))); productCommentMapper.insert(cloneIgnoreId(productComment, o -> o.setVisible(Boolean.FALSE)));