Commit 2113e825d7b085478e8a352e077146f1c4e2581f
1 parent
3ced6a32
完善 App 商品详情逻辑的 10%
Showing
6 changed files
with
50 additions
and
58 deletions
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java
| ... | ... | @@ -73,7 +73,7 @@ public class AppProductSpuController { |
| 73 | 73 | List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService |
| 74 | 74 | .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); |
| 75 | 75 | // 拼接 |
| 76 | - return success(ProductSpuConvert.INSTANCE.convert(spu, skus, propertyValues)); | |
| 76 | + return success(ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus, propertyValues)); | |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java
| ... | ... | @@ -18,17 +18,17 @@ public class AppProductSpuDetailRespVO { |
| 18 | 18 | @Schema(description = "商品名称", required = true, example = "芋道") |
| 19 | 19 | private String name; |
| 20 | 20 | |
| 21 | - @Schema(description = "促销语", example = "好吃!") | |
| 22 | - private String sellPoint; | |
| 23 | - | |
| 24 | 21 | @Schema(description = "商品详情", required = true, example = "我是商品描述") |
| 25 | 22 | private String description; |
| 26 | 23 | |
| 27 | 24 | @Schema(description = "商品分类编号", required = true, example = "1") |
| 28 | 25 | private Long categoryId; |
| 29 | 26 | |
| 30 | - @Schema(description = "商品图片的数组", required = true) | |
| 31 | - private List<String> picUrls; | |
| 27 | + @Schema(description = "商品封面图", required = true) | |
| 28 | + private String picUrl; | |
| 29 | + | |
| 30 | + @Schema(description = "商品轮播图", required = true) | |
| 31 | + private List<String> sliderPicUrls; | |
| 32 | 32 | |
| 33 | 33 | @Schema(description = "商品视频", required = true) |
| 34 | 34 | private String videoUrl; |
| ... | ... | @@ -38,14 +38,14 @@ public class AppProductSpuDetailRespVO { |
| 38 | 38 | @Schema(description = "规格类型", required = true, example = "true") |
| 39 | 39 | private Boolean specType; |
| 40 | 40 | |
| 41 | - @Schema(description = "是否展示库存", required = true, example = "true") | |
| 42 | - private Boolean showStock; | |
| 41 | + @Schema(description = "商品价格,单位使用:分", required = true, example = "1024") | |
| 42 | + private Integer price; | |
| 43 | 43 | |
| 44 | - @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024") | |
| 45 | - private Integer minPrice; | |
| 44 | + @Schema(description = "市场价,单位使用:分", required = true, example = "1024") | |
| 45 | + private Integer marketPrice; | |
| 46 | 46 | |
| 47 | - @Schema(description = "最大价格,单位使用:分", required = true, example = "1024") | |
| 48 | - private Integer maxPrice; | |
| 47 | + @Schema(description = "库存", required = true, example = "666") | |
| 48 | + private Integer stock; | |
| 49 | 49 | |
| 50 | 50 | /** |
| 51 | 51 | * SKU 数组 |
| ... | ... | @@ -72,7 +72,7 @@ public class AppProductSpuDetailRespVO { |
| 72 | 72 | @Schema(description = "销售价格,单位:分", required = true, example = "1024") |
| 73 | 73 | private Integer price; |
| 74 | 74 | |
| 75 | - @Schema(description = "市场价", example = "1024") | |
| 75 | + @Schema(description = "市场价,单位使用:分", required = true, example = "1024") | |
| 76 | 76 | private Integer marketPrice; |
| 77 | 77 | |
| 78 | 78 | @Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png") | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java
| 1 | 1 | package cn.iocoder.yudao.module.product.controller.app.spu.vo; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; | |
| 4 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 5 | 4 | import lombok.Data; |
| 6 | 5 | |
| 7 | -import javax.validation.constraints.NotEmpty; | |
| 8 | -import javax.validation.constraints.NotNull; | |
| 9 | 6 | import java.util.List; |
| 10 | 7 | |
| 11 | 8 | @Schema(description = "用户 App - 商品 SPU 分页项 Response VO") |
| ... | ... | @@ -27,17 +24,17 @@ public class AppProductSpuPageItemRespVO { |
| 27 | 24 | @Schema(description = "商品轮播图", required = true) |
| 28 | 25 | private List<String> sliderPicUrls; |
| 29 | 26 | |
| 27 | + // ========== SKU 相关字段 ========= | |
| 28 | + | |
| 30 | 29 | @Schema(description = "商品价格,单位使用:分", required = true, example = "1024") |
| 31 | 30 | private Integer price; |
| 32 | 31 | |
| 33 | - // ========== SKU 相关字段 ========= | |
| 34 | - | |
| 35 | 32 | @Schema(description = "库存", required = true, example = "666") |
| 36 | 33 | private Integer stock; |
| 37 | 34 | |
| 38 | 35 | // ========== 统计相关字段 ========= |
| 39 | 36 | |
| 40 | - @Schema(description = "商品销量", example = "1024") | |
| 37 | + @Schema(description = "商品销量", required = true, example = "1024") | |
| 41 | 38 | private Integer salesCount; |
| 42 | 39 | |
| 43 | 40 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
| ... | ... | @@ -13,7 +13,6 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; |
| 13 | 13 | import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; |
| 14 | 14 | import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; |
| 15 | 15 | import org.mapstruct.Mapper; |
| 16 | -import org.mapstruct.Named; | |
| 17 | 16 | import org.mapstruct.factory.Mappers; |
| 18 | 17 | |
| 19 | 18 | import java.util.ArrayList; |
| ... | ... | @@ -33,48 +32,18 @@ public interface ProductSpuConvert { |
| 33 | 32 | |
| 34 | 33 | ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class); |
| 35 | 34 | |
| 36 | - ProductSpuDO convert(ProductSpuCreateReqVO bean); | |
| 35 | + ProductSpuDO convertForGetSpuDetail(ProductSpuCreateReqVO bean); | |
| 37 | 36 | |
| 38 | - ProductSpuDO convert(ProductSpuUpdateReqVO bean); | |
| 37 | + ProductSpuDO convertForGetSpuDetail(ProductSpuUpdateReqVO bean); | |
| 39 | 38 | |
| 40 | 39 | List<ProductSpuDO> convertList(List<ProductSpuDO> list); |
| 41 | 40 | |
| 42 | 41 | PageResult<ProductSpuRespVO> convertPage(PageResult<ProductSpuDO> page); |
| 43 | 42 | |
| 44 | - ProductSpuPageReqVO convert(AppProductSpuPageReqVO bean); | |
| 45 | - | |
| 46 | 43 | List<ProductSpuRespDTO> convertList2(List<ProductSpuDO> list); |
| 47 | 44 | |
| 48 | 45 | List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list); |
| 49 | 46 | |
| 50 | - default AppProductSpuDetailRespVO convert(ProductSpuDO spu, List<ProductSkuDO> skus, | |
| 51 | - List<ProductPropertyValueDetailRespBO> propertyValues) { | |
| 52 | - AppProductSpuDetailRespVO spuVO = convert02(spu) | |
| 53 | - .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0)); | |
| 54 | - spuVO.setSkus(convertList03(skus)); | |
| 55 | - // 处理商品属性 | |
| 56 | - Map<Long, ProductPropertyValueDetailRespBO> propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId); | |
| 57 | - for (int i = 0; i < skus.size(); i++) { | |
| 58 | - List<ProductSkuDO.Property> properties = skus.get(i).getProperties(); | |
| 59 | - if (CollUtil.isEmpty(properties)) { | |
| 60 | - continue; | |
| 61 | - } | |
| 62 | - AppProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i); | |
| 63 | - sku.setProperties(new ArrayList<>(properties.size())); | |
| 64 | - // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 | |
| 65 | - properties.forEach(property -> { | |
| 66 | - ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId()); | |
| 67 | - if (propertyValue == null) { | |
| 68 | - return; | |
| 69 | - } | |
| 70 | - sku.getProperties().add(convert03(propertyValue)); | |
| 71 | - }); | |
| 72 | - } | |
| 73 | - return spuVO; | |
| 74 | - } | |
| 75 | - AppProductSpuDetailRespVO convert02(ProductSpuDO spu); | |
| 76 | - List<AppProductSpuDetailRespVO.Sku> convertList03(List<ProductSkuDO> skus); | |
| 77 | - AppProductPropertyValueDetailRespVO convert03(ProductPropertyValueDetailRespBO propertyValue); | |
| 78 | 47 | |
| 79 | 48 | default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List<ProductSkuDO> skus, |
| 80 | 49 | List<ProductPropertyValueDetailRespBO> propertyValues) { |
| ... | ... | @@ -114,4 +83,33 @@ public interface ProductSpuConvert { |
| 114 | 83 | } |
| 115 | 84 | PageResult<AppProductSpuPageItemRespVO> convertPageForGetSpuPage0(PageResult<ProductSpuDO> page); |
| 116 | 85 | |
| 86 | + default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List<ProductSkuDO> skus, | |
| 87 | + List<ProductPropertyValueDetailRespBO> propertyValues) { | |
| 88 | + AppProductSpuDetailRespVO spuVO = convertForGetSpuDetail(spu) | |
| 89 | + .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0)); | |
| 90 | + spuVO.setSkus(convertListForGetSpuDetail(skus)); | |
| 91 | + // 处理商品属性 | |
| 92 | + Map<Long, ProductPropertyValueDetailRespBO> propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId); | |
| 93 | + for (int i = 0; i < skus.size(); i++) { | |
| 94 | + List<ProductSkuDO.Property> properties = skus.get(i).getProperties(); | |
| 95 | + if (CollUtil.isEmpty(properties)) { | |
| 96 | + continue; | |
| 97 | + } | |
| 98 | + AppProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i); | |
| 99 | + sku.setProperties(new ArrayList<>(properties.size())); | |
| 100 | + // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 | |
| 101 | + properties.forEach(property -> { | |
| 102 | + ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId()); | |
| 103 | + if (propertyValue == null) { | |
| 104 | + return; | |
| 105 | + } | |
| 106 | + sku.getProperties().add(convertForGetSpuDetail(propertyValue)); | |
| 107 | + }); | |
| 108 | + } | |
| 109 | + return spuVO; | |
| 110 | + } | |
| 111 | + AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu); | |
| 112 | + List<AppProductSpuDetailRespVO.Sku> convertListForGetSpuDetail(List<ProductSkuDO> skus); | |
| 113 | + AppProductPropertyValueDetailRespVO convertForGetSpuDetail(ProductPropertyValueDetailRespBO propertyValue); | |
| 114 | + | |
| 117 | 115 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.product.service.spu; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | -import cn.hutool.core.util.NumberUtil; | |
| 5 | -import cn.hutool.core.util.ObjUtil; | |
| 6 | 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 7 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 8 | 6 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 9 | -import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | |
| 10 | 7 | import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; |
| 11 | 8 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; |
| 12 | 9 | import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; |
| ... | ... | @@ -66,7 +63,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { |
| 66 | 63 | productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType()); |
| 67 | 64 | |
| 68 | 65 | // 插入 SPU |
| 69 | - ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO); | |
| 66 | + ProductSpuDO spu = ProductSpuConvert.INSTANCE.convertForGetSpuDetail(createReqVO); | |
| 70 | 67 | initSpuFromSkus(spu, skuSaveReqList); |
| 71 | 68 | productSpuMapper.insert(spu); |
| 72 | 69 | // 插入 SKU |
| ... | ... | @@ -89,7 +86,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { |
| 89 | 86 | productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType()); |
| 90 | 87 | |
| 91 | 88 | // 更新 SPU |
| 92 | - ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO); | |
| 89 | + ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convertForGetSpuDetail(updateReqVO); | |
| 93 | 90 | initSpuFromSkus(updateObj, skuSaveReqList); |
| 94 | 91 | productSpuMapper.updateById(updateObj); |
| 95 | 92 | // 批量更新 SKU | ... | ... |