Commit 1e2c83d90f2fa6e4c95c9541559b00eae5efa772
1 parent
02abe862
mall: 商品评论表增加冗余 SKU 的图片地址, 规格
Showing
6 changed files
with
58 additions
and
37 deletions
sql/mysql/product_comment.sql
0 → 100644
| 1 | +-- 1.冗余 SKU 图片地址, 规格 | ||
| 2 | +alter table product_comment | ||
| 3 | + add column sku_pic_url varchar(256) not null comment '图片地址' after sku_id; | ||
| 4 | + | ||
| 5 | +alter table product_comment | ||
| 6 | + add column sku_properties varchar(512) null | ||
| 7 | + comment '属性数组,JSON 格式 [{propertId: , valueId: }, {propertId: , valueId: }]' after sku_pic_url; | ||
| 8 | + | ||
| 9 | +-- 2.修复已有数据 | ||
| 10 | +update product_comment pc | ||
| 11 | + join product_sku ps on pc.spu_id = ps.spu_id | ||
| 12 | +set pc.sku_pic_url = ps.pic_url, | ||
| 13 | + pc.sku_properties = ps.properties | ||
| 14 | +where pc.sku_id is not null; | ||
| 0 | \ No newline at end of file | 15 | \ No newline at end of file |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java
| @@ -5,9 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -5,9 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 5 | import cn.iocoder.yudao.module.product.controller.admin.comment.vo.*; | 5 | import cn.iocoder.yudao.module.product.controller.admin.comment.vo.*; |
| 6 | import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; | 6 | import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; |
| 7 | import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; | 7 | import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; |
| 8 | -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; | ||
| 9 | import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; | 8 | import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; |
| 10 | -import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; | ||
| 11 | import io.swagger.v3.oas.annotations.Operation; | 9 | import io.swagger.v3.oas.annotations.Operation; |
| 12 | import io.swagger.v3.oas.annotations.tags.Tag; | 10 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 13 | import org.springframework.security.access.prepost.PreAuthorize; | 11 | import org.springframework.security.access.prepost.PreAuthorize; |
| @@ -16,10 +14,8 @@ import org.springframework.web.bind.annotation.*; | @@ -16,10 +14,8 @@ import org.springframework.web.bind.annotation.*; | ||
| 16 | 14 | ||
| 17 | import javax.annotation.Resource; | 15 | import javax.annotation.Resource; |
| 18 | import javax.validation.Valid; | 16 | import javax.validation.Valid; |
| 19 | -import java.util.List; | ||
| 20 | 17 | ||
| 21 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 18 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 22 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | ||
| 23 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | 19 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| 24 | 20 | ||
| 25 | @Tag(name = "管理后台 - 商品评价") | 21 | @Tag(name = "管理后台 - 商品评价") |
| @@ -30,18 +26,13 @@ public class ProductCommentController { | @@ -30,18 +26,13 @@ public class ProductCommentController { | ||
| 30 | 26 | ||
| 31 | @Resource | 27 | @Resource |
| 32 | private ProductCommentService productCommentService; | 28 | private ProductCommentService productCommentService; |
| 33 | - @Resource | ||
| 34 | - private ProductSkuService productSkuService; | ||
| 35 | 29 | ||
| 36 | @GetMapping("/page") | 30 | @GetMapping("/page") |
| 37 | @Operation(summary = "获得商品评价分页") | 31 | @Operation(summary = "获得商品评价分页") |
| 38 | @PreAuthorize("@ss.hasPermission('product:comment:query')") | 32 | @PreAuthorize("@ss.hasPermission('product:comment:query')") |
| 39 | public CommonResult<PageResult<ProductCommentRespVO>> getCommentPage(@Valid ProductCommentPageReqVO pageVO) { | 33 | public CommonResult<PageResult<ProductCommentRespVO>> getCommentPage(@Valid ProductCommentPageReqVO pageVO) { |
| 40 | PageResult<ProductCommentDO> pageResult = productCommentService.getCommentPage(pageVO); | 34 | PageResult<ProductCommentDO> pageResult = productCommentService.getCommentPage(pageVO); |
| 41 | - // 拼接返回 | ||
| 42 | - List<ProductSkuDO> skuList = productSkuService.getSkuList( | ||
| 43 | - convertSet(pageResult.getList(), ProductCommentDO::getSkuId)); | ||
| 44 | - return success(ProductCommentConvert.INSTANCE.convertPage(pageResult, skuList)); | 35 | + return success(ProductCommentConvert.INSTANCE.convertPage2(pageResult)); |
| 45 | } | 36 | } |
| 46 | 37 | ||
| 47 | @PutMapping("/update-visible") | 38 | @PutMapping("/update-visible") |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java
| 1 | package cn.iocoder.yudao.module.product.convert.comment; | 1 | package cn.iocoder.yudao.module.product.convert.comment; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 3 | import cn.hutool.core.util.ObjectUtil; | 4 | import cn.hutool.core.util.ObjectUtil; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 6 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| @@ -91,7 +92,7 @@ public interface ProductCommentConvert { | @@ -91,7 +92,7 @@ public interface ProductCommentConvert { | ||
| 91 | 92 | ||
| 92 | @Mapping(target = "scores", | 93 | @Mapping(target = "scores", |
| 93 | expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))") | 94 | expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))") |
| 94 | - default ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO, ProductSpuDO spuDO, MemberUserRespDTO user) { | 95 | + default ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO, ProductSpuDO spuDO, ProductSkuDO skuDO, MemberUserRespDTO user) { |
| 95 | ProductCommentDO commentDO = convert(createReqDTO); | 96 | ProductCommentDO commentDO = convert(createReqDTO); |
| 96 | if (user != null) { | 97 | if (user != null) { |
| 97 | commentDO.setUserId(user.getId()); | 98 | commentDO.setUserId(user.getId()); |
| @@ -102,6 +103,10 @@ public interface ProductCommentConvert { | @@ -102,6 +103,10 @@ public interface ProductCommentConvert { | ||
| 102 | commentDO.setSpuId(spuDO.getId()); | 103 | commentDO.setSpuId(spuDO.getId()); |
| 103 | commentDO.setSpuName(spuDO.getName()); | 104 | commentDO.setSpuName(spuDO.getName()); |
| 104 | } | 105 | } |
| 106 | + if (skuDO != null) { | ||
| 107 | + commentDO.setSkuPicUrl(skuDO.getPicUrl()); | ||
| 108 | + commentDO.setSkuProperties(skuDO.getProperties()); | ||
| 109 | + } | ||
| 105 | return commentDO; | 110 | return commentDO; |
| 106 | } | 111 | } |
| 107 | 112 | ||
| @@ -117,27 +122,32 @@ public interface ProductCommentConvert { | @@ -117,27 +122,32 @@ public interface ProductCommentConvert { | ||
| 117 | 122 | ||
| 118 | List<AppProductCommentRespVO> convertList02(List<ProductCommentDO> list); | 123 | List<AppProductCommentRespVO> convertList02(List<ProductCommentDO> list); |
| 119 | 124 | ||
| 120 | - default ProductCommentDO convert(ProductCommentCreateReqVO createReq, ProductSpuDO spu) { | 125 | + default ProductCommentDO convert(ProductCommentCreateReqVO createReq, ProductSpuDO spuDO, ProductSkuDO skuDO) { |
| 121 | ProductCommentDO commentDO = convert(createReq); | 126 | ProductCommentDO commentDO = convert(createReq); |
| 122 | - if (spu != null) { | ||
| 123 | - commentDO.setSpuId(spu.getId()).setSpuName(spu.getName()); | 127 | + if (spuDO != null) { |
| 128 | + commentDO.setSpuId(spuDO.getId()); | ||
| 129 | + commentDO.setSpuName(spuDO.getName()); | ||
| 130 | + } | ||
| 131 | + if (skuDO != null) { | ||
| 132 | + commentDO.setSkuPicUrl(skuDO.getPicUrl()); | ||
| 133 | + commentDO.setSkuProperties(skuDO.getProperties()); | ||
| 124 | } | 134 | } |
| 125 | return commentDO; | 135 | return commentDO; |
| 126 | } | 136 | } |
| 127 | 137 | ||
| 128 | - default PageResult<ProductCommentRespVO> convertPage(PageResult<ProductCommentDO> pageResult, | ||
| 129 | - List<ProductSkuDO> skus) { | 138 | + default PageResult<ProductCommentRespVO> convertPage2(PageResult<ProductCommentDO> pageResult) { |
| 139 | + Map<Long, List<ProductSkuDO.Property>> propertiesMap = convertMap(pageResult.getList(), | ||
| 140 | + ProductCommentDO::getId, | ||
| 141 | + // 这里会有NULL异常, 需要处理一下 | ||
| 142 | + comment -> CollUtil.emptyIfNull(comment.getSkuProperties())); | ||
| 143 | + | ||
| 130 | PageResult<ProductCommentRespVO> result = convertPage(pageResult); | 144 | PageResult<ProductCommentRespVO> result = convertPage(pageResult); |
| 131 | - // 拼接数据 | ||
| 132 | - Map<Long, ProductSkuDO> skuMap = convertMap(skus, ProductSkuDO::getId); | ||
| 133 | for (ProductCommentRespVO vo : result.getList()) { | 145 | for (ProductCommentRespVO vo : result.getList()) { |
| 134 | - findAndThen(skuMap, vo.getSkuId(), sku -> { | ||
| 135 | - String propertyNames = sku.getProperties().stream() | 146 | + findAndThen(propertiesMap, vo.getId(), properties -> { |
| 147 | + String propertyNames = properties.stream() | ||
| 136 | .map(ProductSkuDO.Property::getValueName) | 148 | .map(ProductSkuDO.Property::getValueName) |
| 137 | .filter(Objects::nonNull) | 149 | .filter(Objects::nonNull) |
| 138 | .collect(Collectors.joining(" ")); | 150 | .collect(Collectors.joining(" ")); |
| 139 | - // TODO @疯狂:要不写入评论的时候,把商品图片、商品属性,都冗余进去。因为这种东西有“快照”的需求。商品后续会编辑掉 | ||
| 140 | - vo.setSkuPicUrl(sku.getPicUrl()); | ||
| 141 | vo.setSpuName(vo.getSpuName() + " " + propertyNames); | 151 | vo.setSpuName(vo.getSpuName() + " " + propertyNames); |
| 142 | }); | 152 | }); |
| 143 | } | 153 | } |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java
| @@ -86,6 +86,15 @@ public class ProductCommentDO extends BaseDO { | @@ -86,6 +86,15 @@ public class ProductCommentDO extends BaseDO { | ||
| 86 | * 关联 {@link ProductSkuDO#getId()} | 86 | * 关联 {@link ProductSkuDO#getId()} |
| 87 | */ | 87 | */ |
| 88 | private Long skuId; | 88 | private Long skuId; |
| 89 | + /** | ||
| 90 | + * 商品 SKU 图片地址 | ||
| 91 | + */ | ||
| 92 | + private String skuPicUrl; | ||
| 93 | + /** | ||
| 94 | + * 属性数组,JSON 格式 | ||
| 95 | + */ | ||
| 96 | + @TableField(typeHandler = ProductSkuDO.PropertyTypeHandler.class) | ||
| 97 | + private List<ProductSkuDO.Property> skuProperties; | ||
| 89 | 98 | ||
| 90 | /** | 99 | /** |
| 91 | * 是否可见 | 100 | * 是否可见 |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java
| @@ -53,25 +53,29 @@ public class ProductCommentServiceImpl implements ProductCommentService { | @@ -53,25 +53,29 @@ public class ProductCommentServiceImpl implements ProductCommentService { | ||
| 53 | 53 | ||
| 54 | @Override | 54 | @Override |
| 55 | public void createComment(ProductCommentCreateReqVO createReqVO) { | 55 | public void createComment(ProductCommentCreateReqVO createReqVO) { |
| 56 | - // 校验商品 | ||
| 57 | - ProductSpuDO spu = validateSpuBySkuId(createReqVO.getSkuId()); | 56 | + // 校验 SKU |
| 57 | + ProductSkuDO skuDO = validateSku(createReqVO.getSkuId()); | ||
| 58 | + // 校验 SPU | ||
| 59 | + ProductSpuDO spuDO = validateSpu(skuDO.getSpuId()); | ||
| 58 | 60 | ||
| 59 | // 创建评论 | 61 | // 创建评论 |
| 60 | - ProductCommentDO comment = ProductCommentConvert.INSTANCE.convert(createReqVO, spu); | 62 | + ProductCommentDO comment = ProductCommentConvert.INSTANCE.convert(createReqVO, spuDO, skuDO); |
| 61 | productCommentMapper.insert(comment); | 63 | productCommentMapper.insert(comment); |
| 62 | } | 64 | } |
| 63 | 65 | ||
| 64 | @Override | 66 | @Override |
| 65 | public Long createComment(ProductCommentCreateReqDTO createReqDTO) { | 67 | public Long createComment(ProductCommentCreateReqDTO createReqDTO) { |
| 66 | - // 校验商品 | ||
| 67 | - ProductSpuDO spuDO = validateSpuBySkuId(createReqDTO.getSkuId()); | 68 | + // 校验 SKU |
| 69 | + ProductSkuDO skuDO = validateSku(createReqDTO.getSkuId()); | ||
| 70 | + // 校验 SPU | ||
| 71 | + ProductSpuDO spuDO = validateSpu(skuDO.getSpuId()); | ||
| 68 | // 校验评论 | 72 | // 校验评论 |
| 69 | validateCommentExists(createReqDTO.getUserId(), createReqDTO.getOrderId()); | 73 | validateCommentExists(createReqDTO.getUserId(), createReqDTO.getOrderId()); |
| 70 | // 获取用户详细信息 | 74 | // 获取用户详细信息 |
| 71 | MemberUserRespDTO user = memberUserApi.getUser(createReqDTO.getUserId()); | 75 | MemberUserRespDTO user = memberUserApi.getUser(createReqDTO.getUserId()); |
| 72 | 76 | ||
| 73 | // 创建评论 | 77 | // 创建评论 |
| 74 | - ProductCommentDO comment = ProductCommentConvert.INSTANCE.convert(createReqDTO, spuDO, user); | 78 | + ProductCommentDO comment = ProductCommentConvert.INSTANCE.convert(createReqDTO, spuDO, skuDO, user); |
| 75 | productCommentMapper.insert(comment); | 79 | productCommentMapper.insert(comment); |
| 76 | return comment.getId(); | 80 | return comment.getId(); |
| 77 | } | 81 | } |
| @@ -79,7 +83,7 @@ public class ProductCommentServiceImpl implements ProductCommentService { | @@ -79,7 +83,7 @@ public class ProductCommentServiceImpl implements ProductCommentService { | ||
| 79 | /** | 83 | /** |
| 80 | * 判断当前订单的当前商品用户是否评价过 | 84 | * 判断当前订单的当前商品用户是否评价过 |
| 81 | * | 85 | * |
| 82 | - * @param userId 用户编号 | 86 | + * @param userId 用户编号 |
| 83 | * @param orderItemId 订单项编号 | 87 | * @param orderItemId 订单项编号 |
| 84 | */ | 88 | */ |
| 85 | private void validateCommentExists(Long userId, Long orderItemId) { | 89 | private void validateCommentExists(Long userId, Long orderItemId) { |
| @@ -105,13 +109,6 @@ public class ProductCommentServiceImpl implements ProductCommentService { | @@ -105,13 +109,6 @@ public class ProductCommentServiceImpl implements ProductCommentService { | ||
| 105 | return spu; | 109 | return spu; |
| 106 | } | 110 | } |
| 107 | 111 | ||
| 108 | - private ProductSpuDO validateSpuBySkuId(Long skuId) { | ||
| 109 | - // 通过 sku ID 拿到 spu 相关信息 | ||
| 110 | - ProductSkuDO sku = validateSku(skuId); | ||
| 111 | - // 校验 spu 如果存在返回详情 | ||
| 112 | - return validateSpu(sku.getSpuId()); | ||
| 113 | - } | ||
| 114 | - | ||
| 115 | @Override | 112 | @Override |
| 116 | public void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO) { | 113 | public void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO) { |
| 117 | // 校验评论是否存在 | 114 | // 校验评论是否存在 |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java
| @@ -200,7 +200,7 @@ public class MemberLevelServiceImpl implements MemberLevelService { | @@ -200,7 +200,7 @@ public class MemberLevelServiceImpl implements MemberLevelService { | ||
| 200 | if (updateReqVO.getLevelId() == null) { | 200 | if (updateReqVO.getLevelId() == null) { |
| 201 | // 取消用户等级时,需要扣减经验 | 201 | // 取消用户等级时,需要扣减经验 |
| 202 | levelRecord.setExperience(-user.getExperience()); | 202 | levelRecord.setExperience(-user.getExperience()); |
| 203 | - // TODO @疯狂:这里是不是也要设置下 setUserExperience 属性; | 203 | + levelRecord.setUserExperience(0); |
| 204 | levelRecord.setDescription("管理员取消了等级"); | 204 | levelRecord.setDescription("管理员取消了等级"); |
| 205 | } else { | 205 | } else { |
| 206 | // 复制等级配置 | 206 | // 复制等级配置 |