完善 App 商品详情逻辑的 10%
parent
3ced6a3240
commit
2113e825d7
|
@ -14,5 +14,5 @@ Authorization: Bearer {{appToken}}
|
||||||
tenant-id: {{appTenentId}}
|
tenant-id: {{appTenentId}}
|
||||||
|
|
||||||
### 获得商品 SPU 明细
|
### 获得商品 SPU 明细
|
||||||
GET {{appApi}}/product/spu/get-detail?id=4
|
GET {{appApi}}/product/spu/get-detail?id=102
|
||||||
tenant-id: {{appTenentId}}
|
tenant-id: {{appTenentId}}
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class AppProductSpuController {
|
||||||
List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
|
List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
|
||||||
.getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
|
.getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
|
||||||
// 拼接
|
// 拼接
|
||||||
return success(ProductSpuConvert.INSTANCE.convert(spu, skus, propertyValues));
|
return success(ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus, propertyValues));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,17 +18,17 @@ public class AppProductSpuDetailRespVO {
|
||||||
@Schema(description = "商品名称", required = true, example = "芋道")
|
@Schema(description = "商品名称", required = true, example = "芋道")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Schema(description = "促销语", example = "好吃!")
|
|
||||||
private String sellPoint;
|
|
||||||
|
|
||||||
@Schema(description = "商品详情", required = true, example = "我是商品描述")
|
@Schema(description = "商品详情", required = true, example = "我是商品描述")
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
@Schema(description = "商品分类编号", required = true, example = "1")
|
@Schema(description = "商品分类编号", required = true, example = "1")
|
||||||
private Long categoryId;
|
private Long categoryId;
|
||||||
|
|
||||||
@Schema(description = "商品图片的数组", required = true)
|
@Schema(description = "商品封面图", required = true)
|
||||||
private List<String> picUrls;
|
private String picUrl;
|
||||||
|
|
||||||
|
@Schema(description = "商品轮播图", required = true)
|
||||||
|
private List<String> sliderPicUrls;
|
||||||
|
|
||||||
@Schema(description = "商品视频", required = true)
|
@Schema(description = "商品视频", required = true)
|
||||||
private String videoUrl;
|
private String videoUrl;
|
||||||
|
@ -38,14 +38,14 @@ public class AppProductSpuDetailRespVO {
|
||||||
@Schema(description = "规格类型", required = true, example = "true")
|
@Schema(description = "规格类型", required = true, example = "true")
|
||||||
private Boolean specType;
|
private Boolean specType;
|
||||||
|
|
||||||
@Schema(description = "是否展示库存", required = true, example = "true")
|
@Schema(description = "商品价格,单位使用:分", required = true, example = "1024")
|
||||||
private Boolean showStock;
|
private Integer price;
|
||||||
|
|
||||||
@Schema(description = " 最小价格,单位使用:分", required = true, example = "1024")
|
@Schema(description = "市场价,单位使用:分", required = true, example = "1024")
|
||||||
private Integer minPrice;
|
private Integer marketPrice;
|
||||||
|
|
||||||
@Schema(description = "最大价格,单位使用:分", required = true, example = "1024")
|
@Schema(description = "库存", required = true, example = "666")
|
||||||
private Integer maxPrice;
|
private Integer stock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SKU 数组
|
* SKU 数组
|
||||||
|
@ -72,7 +72,7 @@ public class AppProductSpuDetailRespVO {
|
||||||
@Schema(description = "销售价格,单位:分", required = true, example = "1024")
|
@Schema(description = "销售价格,单位:分", required = true, example = "1024")
|
||||||
private Integer price;
|
private Integer price;
|
||||||
|
|
||||||
@Schema(description = "市场价", example = "1024")
|
@Schema(description = "市场价,单位使用:分", required = true, example = "1024")
|
||||||
private Integer marketPrice;
|
private Integer marketPrice;
|
||||||
|
|
||||||
@Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png")
|
@Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png")
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
package cn.iocoder.yudao.module.product.controller.app.spu.vo;
|
package cn.iocoder.yudao.module.product.controller.app.spu.vo;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Schema(description = "用户 App - 商品 SPU 分页项 Response VO")
|
@Schema(description = "用户 App - 商品 SPU 分页项 Response VO")
|
||||||
|
@ -27,17 +24,17 @@ public class AppProductSpuPageItemRespVO {
|
||||||
@Schema(description = "商品轮播图", required = true)
|
@Schema(description = "商品轮播图", required = true)
|
||||||
private List<String> sliderPicUrls;
|
private List<String> sliderPicUrls;
|
||||||
|
|
||||||
|
// ========== SKU 相关字段 =========
|
||||||
|
|
||||||
@Schema(description = "商品价格,单位使用:分", required = true, example = "1024")
|
@Schema(description = "商品价格,单位使用:分", required = true, example = "1024")
|
||||||
private Integer price;
|
private Integer price;
|
||||||
|
|
||||||
// ========== SKU 相关字段 =========
|
|
||||||
|
|
||||||
@Schema(description = "库存", required = true, example = "666")
|
@Schema(description = "库存", required = true, example = "666")
|
||||||
private Integer stock;
|
private Integer stock;
|
||||||
|
|
||||||
// ========== 统计相关字段 =========
|
// ========== 统计相关字段 =========
|
||||||
|
|
||||||
@Schema(description = "商品销量", example = "1024")
|
@Schema(description = "商品销量", required = true, example = "1024")
|
||||||
private Integer salesCount;
|
private Integer salesCount;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||||
import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
|
import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.Named;
|
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -33,48 +32,18 @@ public interface ProductSpuConvert {
|
||||||
|
|
||||||
ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class);
|
ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class);
|
||||||
|
|
||||||
ProductSpuDO convert(ProductSpuCreateReqVO bean);
|
ProductSpuDO convertForGetSpuDetail(ProductSpuCreateReqVO bean);
|
||||||
|
|
||||||
ProductSpuDO convert(ProductSpuUpdateReqVO bean);
|
ProductSpuDO convertForGetSpuDetail(ProductSpuUpdateReqVO bean);
|
||||||
|
|
||||||
List<ProductSpuDO> convertList(List<ProductSpuDO> list);
|
List<ProductSpuDO> convertList(List<ProductSpuDO> list);
|
||||||
|
|
||||||
PageResult<ProductSpuRespVO> convertPage(PageResult<ProductSpuDO> page);
|
PageResult<ProductSpuRespVO> convertPage(PageResult<ProductSpuDO> page);
|
||||||
|
|
||||||
ProductSpuPageReqVO convert(AppProductSpuPageReqVO bean);
|
|
||||||
|
|
||||||
List<ProductSpuRespDTO> convertList2(List<ProductSpuDO> list);
|
List<ProductSpuRespDTO> convertList2(List<ProductSpuDO> list);
|
||||||
|
|
||||||
List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list);
|
List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list);
|
||||||
|
|
||||||
default AppProductSpuDetailRespVO convert(ProductSpuDO spu, List<ProductSkuDO> skus,
|
|
||||||
List<ProductPropertyValueDetailRespBO> propertyValues) {
|
|
||||||
AppProductSpuDetailRespVO spuVO = convert02(spu)
|
|
||||||
.setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0));
|
|
||||||
spuVO.setSkus(convertList03(skus));
|
|
||||||
// 处理商品属性
|
|
||||||
Map<Long, ProductPropertyValueDetailRespBO> propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId);
|
|
||||||
for (int i = 0; i < skus.size(); i++) {
|
|
||||||
List<ProductSkuDO.Property> properties = skus.get(i).getProperties();
|
|
||||||
if (CollUtil.isEmpty(properties)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
AppProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i);
|
|
||||||
sku.setProperties(new ArrayList<>(properties.size()));
|
|
||||||
// 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中
|
|
||||||
properties.forEach(property -> {
|
|
||||||
ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId());
|
|
||||||
if (propertyValue == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sku.getProperties().add(convert03(propertyValue));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return spuVO;
|
|
||||||
}
|
|
||||||
AppProductSpuDetailRespVO convert02(ProductSpuDO spu);
|
|
||||||
List<AppProductSpuDetailRespVO.Sku> convertList03(List<ProductSkuDO> skus);
|
|
||||||
AppProductPropertyValueDetailRespVO convert03(ProductPropertyValueDetailRespBO propertyValue);
|
|
||||||
|
|
||||||
default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List<ProductSkuDO> skus,
|
default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List<ProductSkuDO> skus,
|
||||||
List<ProductPropertyValueDetailRespBO> propertyValues) {
|
List<ProductPropertyValueDetailRespBO> propertyValues) {
|
||||||
|
@ -114,4 +83,33 @@ public interface ProductSpuConvert {
|
||||||
}
|
}
|
||||||
PageResult<AppProductSpuPageItemRespVO> convertPageForGetSpuPage0(PageResult<ProductSpuDO> page);
|
PageResult<AppProductSpuPageItemRespVO> convertPageForGetSpuPage0(PageResult<ProductSpuDO> page);
|
||||||
|
|
||||||
|
default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List<ProductSkuDO> skus,
|
||||||
|
List<ProductPropertyValueDetailRespBO> propertyValues) {
|
||||||
|
AppProductSpuDetailRespVO spuVO = convertForGetSpuDetail(spu)
|
||||||
|
.setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0));
|
||||||
|
spuVO.setSkus(convertListForGetSpuDetail(skus));
|
||||||
|
// 处理商品属性
|
||||||
|
Map<Long, ProductPropertyValueDetailRespBO> propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId);
|
||||||
|
for (int i = 0; i < skus.size(); i++) {
|
||||||
|
List<ProductSkuDO.Property> properties = skus.get(i).getProperties();
|
||||||
|
if (CollUtil.isEmpty(properties)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AppProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i);
|
||||||
|
sku.setProperties(new ArrayList<>(properties.size()));
|
||||||
|
// 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中
|
||||||
|
properties.forEach(property -> {
|
||||||
|
ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId());
|
||||||
|
if (propertyValue == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sku.getProperties().add(convertForGetSpuDetail(propertyValue));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return spuVO;
|
||||||
|
}
|
||||||
|
AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu);
|
||||||
|
List<AppProductSpuDetailRespVO.Sku> convertListForGetSpuDetail(List<ProductSkuDO> skus);
|
||||||
|
AppProductPropertyValueDetailRespVO convertForGetSpuDetail(ProductPropertyValueDetailRespBO propertyValue);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
package cn.iocoder.yudao.module.product.service.spu;
|
package cn.iocoder.yudao.module.product.service.spu;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.NumberUtil;
|
|
||||||
import cn.hutool.core.util.ObjUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
|
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
|
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;
|
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;
|
||||||
|
@ -66,7 +63,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||||
productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType());
|
productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType());
|
||||||
|
|
||||||
// 插入 SPU
|
// 插入 SPU
|
||||||
ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO);
|
ProductSpuDO spu = ProductSpuConvert.INSTANCE.convertForGetSpuDetail(createReqVO);
|
||||||
initSpuFromSkus(spu, skuSaveReqList);
|
initSpuFromSkus(spu, skuSaveReqList);
|
||||||
productSpuMapper.insert(spu);
|
productSpuMapper.insert(spu);
|
||||||
// 插入 SKU
|
// 插入 SKU
|
||||||
|
@ -89,7 +86,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||||
productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType());
|
productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType());
|
||||||
|
|
||||||
// 更新 SPU
|
// 更新 SPU
|
||||||
ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO);
|
ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convertForGetSpuDetail(updateReqVO);
|
||||||
initSpuFromSkus(updateObj, skuSaveReqList);
|
initSpuFromSkus(updateObj, skuSaveReqList);
|
||||||
productSpuMapper.updateById(updateObj);
|
productSpuMapper.updateById(updateObj);
|
||||||
// 批量更新 SKU
|
// 批量更新 SKU
|
||||||
|
|
Loading…
Reference in New Issue