Commit 2113e825d7b085478e8a352e077146f1c4e2581f

Authored by YunaiV
1 parent 3ced6a32

完善 App 商品详情逻辑的 10%

yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http
@@ -14,5 +14,5 @@ Authorization: Bearer {{appToken}} @@ -14,5 +14,5 @@ Authorization: Bearer {{appToken}}
14 tenant-id: {{appTenentId}} 14 tenant-id: {{appTenentId}}
15 15
16 ### 获得商品 SPU 明细 16 ### 获得商品 SPU 明细
17 -GET {{appApi}}/product/spu/get-detail?id=4 17 +GET {{appApi}}/product/spu/get-detail?id=102
18 tenant-id: {{appTenentId}} 18 tenant-id: {{appTenentId}}
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,7 +73,7 @@ public class AppProductSpuController {
73 List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService 73 List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
74 .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); 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,17 +18,17 @@ public class AppProductSpuDetailRespVO {
18 @Schema(description = "商品名称", required = true, example = "芋道") 18 @Schema(description = "商品名称", required = true, example = "芋道")
19 private String name; 19 private String name;
20 20
21 - @Schema(description = "促销语", example = "好吃!")  
22 - private String sellPoint;  
23 -  
24 @Schema(description = "商品详情", required = true, example = "我是商品描述") 21 @Schema(description = "商品详情", required = true, example = "我是商品描述")
25 private String description; 22 private String description;
26 23
27 @Schema(description = "商品分类编号", required = true, example = "1") 24 @Schema(description = "商品分类编号", required = true, example = "1")
28 private Long categoryId; 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 @Schema(description = "商品视频", required = true) 33 @Schema(description = "商品视频", required = true)
34 private String videoUrl; 34 private String videoUrl;
@@ -38,14 +38,14 @@ public class AppProductSpuDetailRespVO { @@ -38,14 +38,14 @@ public class AppProductSpuDetailRespVO {
38 @Schema(description = "规格类型", required = true, example = "true") 38 @Schema(description = "规格类型", required = true, example = "true")
39 private Boolean specType; 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 * SKU 数组 51 * SKU 数组
@@ -72,7 +72,7 @@ public class AppProductSpuDetailRespVO { @@ -72,7 +72,7 @@ public class AppProductSpuDetailRespVO {
72 @Schema(description = "销售价格,单位:分", required = true, example = "1024") 72 @Schema(description = "销售价格,单位:分", required = true, example = "1024")
73 private Integer price; 73 private Integer price;
74 74
75 - @Schema(description = "市场价", example = "1024") 75 + @Schema(description = "市场价,单位使用:分", required = true, example = "1024")
76 private Integer marketPrice; 76 private Integer marketPrice;
77 77
78 @Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png") 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 package cn.iocoder.yudao.module.product.controller.app.spu.vo; 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 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 4 import lombok.Data;
6 5
7 -import javax.validation.constraints.NotEmpty;  
8 -import javax.validation.constraints.NotNull;  
9 import java.util.List; 6 import java.util.List;
10 7
11 @Schema(description = "用户 App - 商品 SPU 分页项 Response VO") 8 @Schema(description = "用户 App - 商品 SPU 分页项 Response VO")
@@ -27,17 +24,17 @@ public class AppProductSpuPageItemRespVO { @@ -27,17 +24,17 @@ public class AppProductSpuPageItemRespVO {
27 @Schema(description = "商品轮播图", required = true) 24 @Schema(description = "商品轮播图", required = true)
28 private List<String> sliderPicUrls; 25 private List<String> sliderPicUrls;
29 26
  27 + // ========== SKU 相关字段 =========
  28 +
30 @Schema(description = "商品价格,单位使用:分", required = true, example = "1024") 29 @Schema(description = "商品价格,单位使用:分", required = true, example = "1024")
31 private Integer price; 30 private Integer price;
32 31
33 - // ========== SKU 相关字段 =========  
34 -  
35 @Schema(description = "库存", required = true, example = "666") 32 @Schema(description = "库存", required = true, example = "666")
36 private Integer stock; 33 private Integer stock;
37 34
38 // ========== 统计相关字段 ========= 35 // ========== 统计相关字段 =========
39 36
40 - @Schema(description = "商品销量", example = "1024") 37 + @Schema(description = "商品销量", required = true, example = "1024")
41 private Integer salesCount; 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,7 +13,6 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
13 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; 13 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
14 import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; 14 import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
15 import org.mapstruct.Mapper; 15 import org.mapstruct.Mapper;
16 -import org.mapstruct.Named;  
17 import org.mapstruct.factory.Mappers; 16 import org.mapstruct.factory.Mappers;
18 17
19 import java.util.ArrayList; 18 import java.util.ArrayList;
@@ -33,48 +32,18 @@ public interface ProductSpuConvert { @@ -33,48 +32,18 @@ public interface ProductSpuConvert {
33 32
34 ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class); 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 List<ProductSpuDO> convertList(List<ProductSpuDO> list); 39 List<ProductSpuDO> convertList(List<ProductSpuDO> list);
41 40
42 PageResult<ProductSpuRespVO> convertPage(PageResult<ProductSpuDO> page); 41 PageResult<ProductSpuRespVO> convertPage(PageResult<ProductSpuDO> page);
43 42
44 - ProductSpuPageReqVO convert(AppProductSpuPageReqVO bean);  
45 -  
46 List<ProductSpuRespDTO> convertList2(List<ProductSpuDO> list); 43 List<ProductSpuRespDTO> convertList2(List<ProductSpuDO> list);
47 44
48 List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list); 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 default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List<ProductSkuDO> skus, 48 default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List<ProductSkuDO> skus,
80 List<ProductPropertyValueDetailRespBO> propertyValues) { 49 List<ProductPropertyValueDetailRespBO> propertyValues) {
@@ -114,4 +83,33 @@ public interface ProductSpuConvert { @@ -114,4 +83,33 @@ public interface ProductSpuConvert {
114 } 83 }
115 PageResult<AppProductSpuPageItemRespVO> convertPageForGetSpuPage0(PageResult<ProductSpuDO> page); 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 package cn.iocoder.yudao.module.product.service.spu; 1 package cn.iocoder.yudao.module.product.service.spu;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 -import cn.hutool.core.util.NumberUtil;  
5 -import cn.hutool.core.util.ObjUtil;  
6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
9 -import cn.iocoder.yudao.framework.common.util.number.NumberUtils;  
10 import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; 7 import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
11 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; 8 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
12 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; 9 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;
@@ -66,7 +63,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -66,7 +63,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
66 productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType()); 63 productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType());
67 64
68 // 插入 SPU 65 // 插入 SPU
69 - ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO); 66 + ProductSpuDO spu = ProductSpuConvert.INSTANCE.convertForGetSpuDetail(createReqVO);
70 initSpuFromSkus(spu, skuSaveReqList); 67 initSpuFromSkus(spu, skuSaveReqList);
71 productSpuMapper.insert(spu); 68 productSpuMapper.insert(spu);
72 // 插入 SKU 69 // 插入 SKU
@@ -89,7 +86,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -89,7 +86,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
89 productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType()); 86 productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType());
90 87
91 // 更新 SPU 88 // 更新 SPU
92 - ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO); 89 + ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convertForGetSpuDetail(updateReqVO);
93 initSpuFromSkus(updateObj, skuSaveReqList); 90 initSpuFromSkus(updateObj, skuSaveReqList);
94 productSpuMapper.updateById(updateObj); 91 productSpuMapper.updateById(updateObj);
95 // 批量更新 SKU 92 // 批量更新 SKU