增加商品详情 RPC 接口
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package cn.iocoder.mall.productservice.enums.spu;
|
||||
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuDetailRespDTO;
|
||||
|
||||
/**
|
||||
* 商品 SPU 明细的字段枚举
|
||||
*
|
||||
* @see ProductSpuDetailRespDTO
|
||||
*/
|
||||
public enum ProductSpuDetailFieldEnum {
|
||||
|
||||
SKU("sku"),
|
||||
ATTR("attr");
|
||||
|
||||
/**
|
||||
* 字段
|
||||
*/
|
||||
private final String field;
|
||||
|
||||
ProductSpuDetailFieldEnum(String field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public String getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -79,6 +79,6 @@ public interface ProductAttrRpc {
|
||||
* @param queryDTO 商品规格值的列表查询条件 DTO
|
||||
* @return 商品规格值列表
|
||||
*/
|
||||
CommonResult<List<ProductAttrValueRespDTO>> listProductAttrValues(ProductAttrValueListQueryRequestDTO queryDTO);
|
||||
CommonResult<List<ProductAttrValueRespDTO>> listProductAttrValues(ProductAttrValueListQueryReqDTO queryDTO);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.iocoder.mall.productservice.rpc.attr.dto;
|
||||
|
||||
/**
|
||||
* 商品规格 KEY + VALUE 对的 Response DTO
|
||||
*/
|
||||
public class ProductAttrKeyValueRespDTO {
|
||||
|
||||
/**
|
||||
* 规格 KEY 编号
|
||||
*/
|
||||
private Integer attrKeyId;
|
||||
/**
|
||||
* 规格 KEY 名
|
||||
*/
|
||||
private String attrKeyName;
|
||||
/**
|
||||
* 规格 VALUE 编号
|
||||
*/
|
||||
private Integer attrValueId;
|
||||
/**
|
||||
* 规格 VALUE 名
|
||||
*/
|
||||
private String attrValueName;
|
||||
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import java.util.List;
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrValueListQueryRequestDTO implements Serializable {
|
||||
public class ProductAttrValueListQueryReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 商品规格值编号列表
|
||||
@@ -2,11 +2,9 @@ package cn.iocoder.mall.productservice.rpc.spu;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuCreateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuUpdateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -62,4 +60,6 @@ public interface ProductSpuRpc {
|
||||
*/
|
||||
CommonResult<List<Integer>> listProductSpuIds(Integer lastSpuId, Integer limit);
|
||||
|
||||
CommonResult<ProductSpuDetailRespDTO> getProductSpuDetail(Integer productSpuId, Collection<String> fields);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package cn.iocoder.mall.productservice.rpc.spu.dto;
|
||||
|
||||
import cn.iocoder.mall.productservice.rpc.attr.dto.ProductAttrKeyValueRespDTO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SPU 明细 Response DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuDetailRespDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* SPU 编号
|
||||
*/
|
||||
private Integer id;
|
||||
|
||||
// ========== 基本信息 =========
|
||||
/**
|
||||
* SPU 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 卖点
|
||||
*/
|
||||
private String sellPoint;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
private Integer cid;
|
||||
/**
|
||||
* 分类名
|
||||
*/
|
||||
private String categoryName;
|
||||
/**
|
||||
* 商品主图地址
|
||||
*
|
||||
* 数组,以逗号分隔
|
||||
*
|
||||
* 建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张
|
||||
*/
|
||||
private List<String> picUrls;
|
||||
|
||||
// ========== 其他信息 =========
|
||||
/**
|
||||
* 是否上架商品(是否可见)。
|
||||
*
|
||||
* true 为已上架
|
||||
* false 为已下架
|
||||
*/
|
||||
private Boolean visible;
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
// ========== SKU =========
|
||||
|
||||
/**
|
||||
* SKU 数组
|
||||
*/
|
||||
private List<Sku> skus;
|
||||
|
||||
/**
|
||||
* 商品 Sku 明细
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Sku implements Serializable {
|
||||
|
||||
/**
|
||||
* sku 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 商品编号
|
||||
*/
|
||||
private Integer spuId;
|
||||
/**
|
||||
* 图片地址
|
||||
*/
|
||||
private String picURL;
|
||||
/**
|
||||
* 规格值数组
|
||||
*/
|
||||
private List<ProductAttrKeyValueRespDTO> attrs;
|
||||
/**
|
||||
* 价格,单位:分
|
||||
*/
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -56,6 +56,6 @@ public interface ProductAttrConvert {
|
||||
|
||||
List<ProductAttrValueRespDTO> convertList04(List<ProductAttrValueBO> list);
|
||||
|
||||
ProductAttrValueListQueryBO convert(ProductAttrValueListQueryRequestDTO bean);
|
||||
ProductAttrValueListQueryBO convert(ProductAttrValueListQueryReqDTO bean);
|
||||
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@ package cn.iocoder.mall.productservice.convert.spu;
|
||||
import cn.iocoder.common.framework.util.StringUtils;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.productservice.dal.mysql.dataobject.spu.ProductSpuDO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuCreateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuUpdateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.attr.dto.ProductAttrKeyValueRespDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.*;
|
||||
import cn.iocoder.mall.productservice.service.attr.bo.ProductAttrKeyValueBO;
|
||||
import cn.iocoder.mall.productservice.service.category.bo.ProductCategoryBO;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuBO;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuCreateOrUpdateBO;
|
||||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuBO;
|
||||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuCreateBO;
|
||||
@@ -18,7 +19,10 @@ import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Named;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Mapper
|
||||
public interface ProductSpuConvert {
|
||||
@@ -44,6 +48,7 @@ public interface ProductSpuConvert {
|
||||
ProductSpuUpdateBO convert(ProductSpuAndSkuUpdateReqDTO bean);
|
||||
|
||||
ProductSpuRespDTO convert(ProductSpuBO bean);
|
||||
ProductSpuDetailRespDTO convert2(ProductSpuBO bean);
|
||||
|
||||
List<ProductSpuRespDTO> convertList02(List<ProductSpuBO> list);
|
||||
|
||||
@@ -54,6 +59,32 @@ public interface ProductSpuConvert {
|
||||
List<ProductSkuCreateOrUpdateBO> convert(List<ProductSpuAndSkuCreateReqDTO.Sku> list);
|
||||
List<ProductSkuCreateOrUpdateBO> convert02(List<ProductSpuAndSkuUpdateReqDTO.Sku> list);
|
||||
|
||||
ProductSpuDetailRespDTO.Sku convert(ProductSkuBO bean);
|
||||
|
||||
ProductAttrKeyValueRespDTO convert(ProductAttrKeyValueBO bean);
|
||||
|
||||
default ProductSpuDetailRespDTO convert(ProductSpuBO spuBO, List<ProductSkuBO> skuBOs, List<ProductAttrKeyValueBO> attrBOs,
|
||||
ProductCategoryBO categoryBO) {
|
||||
// 创建并转换 ProductSpuDetailBO 对象
|
||||
ProductSpuDetailRespDTO spuDetailDTO = this.convert2(spuBO);
|
||||
// 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
|
||||
Map<Integer, ProductAttrKeyValueBO> productAttrDetailBOMap = attrBOs.stream().collect(
|
||||
Collectors.toMap(ProductAttrKeyValueBO::getAttrValueId, attrBO -> attrBO));
|
||||
// 创建并转换 ProductSpuDetailBO 数组
|
||||
spuDetailDTO.setSkus(new ArrayList<>());
|
||||
skuBOs.forEach(sku -> {
|
||||
// 创建 ProductSpuDetailBO 对象
|
||||
ProductSpuDetailRespDTO.Sku skuDetail = convert(sku).setAttrs(new ArrayList<>());
|
||||
spuDetailDTO.getSkus().add(skuDetail);
|
||||
// 设置 ProductSpuDetailBO 的 attrs 规格属性
|
||||
sku.getAttrValueIds().forEach(attrValueId -> skuDetail.getAttrs().add(convert(productAttrDetailBOMap.get(attrValueId))));
|
||||
});
|
||||
// 设置分类名
|
||||
spuDetailDTO.setCategoryName(categoryBO.getName());
|
||||
// 返回
|
||||
return spuDetailDTO;
|
||||
}
|
||||
|
||||
@Named("translatePicUrlsFromString")
|
||||
default List<String> translatePicUrlsFromList(String picUrls) {
|
||||
return StringUtils.split(picUrls, ",");
|
||||
|
||||
@@ -21,7 +21,8 @@ public interface ProductSkuMapper extends BaseMapper<ProductSkuDO> {
|
||||
|
||||
default List<ProductSkuDO> selectList(ProductSkuListQueryBO queryBO) {
|
||||
return selectList(new QueryWrapperX<ProductSkuDO>().eqIfPresent("id", queryBO.getProductSkuId())
|
||||
.eqIfPresent("spu_id", queryBO.getProductSpuId()));
|
||||
.eqIfPresent("spu_id", queryBO.getProductSpuId())
|
||||
.eqIfPresent("status", queryBO.getProductSkuStatus()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public class ProductAttrManager {
|
||||
* @param queryDTO 商品规格值的列表查询条件 DTO
|
||||
* @return 商品规格值列表
|
||||
*/
|
||||
public List<ProductAttrValueRespDTO> listProductAttrValues(ProductAttrValueListQueryRequestDTO queryDTO) {
|
||||
public List<ProductAttrValueRespDTO> listProductAttrValues(ProductAttrValueListQueryReqDTO queryDTO) {
|
||||
List<ProductAttrValueBO> productAttrValueBOs = productAttrService.listProductAttrValues(ProductAttrConvert.INSTANCE.convert(queryDTO));
|
||||
return ProductAttrConvert.INSTANCE.convertList04(productAttrValueBOs);
|
||||
}
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
package cn.iocoder.mall.productservice.manager.spu;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.util.CollectionUtils;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.productservice.convert.spu.ProductSpuConvert;
|
||||
import cn.iocoder.mall.productservice.enums.category.ProductCategoryIdEnum;
|
||||
import cn.iocoder.mall.productservice.enums.spu.ProductSpuDetailFieldEnum;
|
||||
import cn.iocoder.mall.productservice.mq.producer.ProductMQProducer;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuCreateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuUpdateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.*;
|
||||
import cn.iocoder.mall.productservice.service.attr.ProductAttrService;
|
||||
import cn.iocoder.mall.productservice.service.attr.bo.ProductAttrKeyValueBO;
|
||||
import cn.iocoder.mall.productservice.service.category.ProductCategoryService;
|
||||
import cn.iocoder.mall.productservice.service.category.bo.ProductCategoryBO;
|
||||
import cn.iocoder.mall.productservice.service.sku.ProductSkuService;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuBO;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuCreateOrUpdateBO;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuListQueryBO;
|
||||
import cn.iocoder.mall.productservice.service.spu.ProductSpuService;
|
||||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuBO;
|
||||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuCreateBO;
|
||||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuUpdateBO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.aop.framework.AopContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -33,6 +36,7 @@ import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.*;
|
||||
* 商品 SPU Manager
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ProductSpuManager {
|
||||
|
||||
@Autowired
|
||||
@@ -207,4 +211,32 @@ public class ProductSpuManager {
|
||||
return attrKeyValueBOs;
|
||||
}
|
||||
|
||||
public ProductSpuDetailRespDTO getProductSpuDetail(Integer productSpuId, Collection<String> fields) {
|
||||
// 获得商品 SPU 信息
|
||||
ProductSpuBO spuBO = productSpuService.getProductSpu(productSpuId);
|
||||
if (spuBO == null) {
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_SPU_NOT_EXISTS);
|
||||
}
|
||||
// 获取商品分类
|
||||
ProductCategoryBO categoryBO = productCategoryService.getProductCategory(spuBO.getCid());
|
||||
if (categoryBO == null) {
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
// 获得商品 SKU 数组
|
||||
List<ProductSkuBO> skuBOs = Collections.emptyList();
|
||||
if (fields.contains(ProductSpuDetailFieldEnum.SKU.getField())) {
|
||||
skuBOs = productSkuService.listProductSkus(new ProductSkuListQueryBO().setProductSpuId(productSpuId)
|
||||
.setProductSkuStatus(CommonStatusEnum.ENABLE.getValue()));
|
||||
}
|
||||
// 获取商品 SKU 的规格数组
|
||||
List<ProductAttrKeyValueBO> attrBOs = Collections.emptyList();
|
||||
if (fields.contains(ProductSpuDetailFieldEnum.ATTR.getField()) && !CollectionUtils.isEmpty(skuBOs)) {
|
||||
Set<Integer> productAttrValueIds = new HashSet<>();
|
||||
skuBOs.forEach(sku -> productAttrValueIds.addAll(sku.getAttrValueIds()));
|
||||
attrBOs = productAttrService.validProductAttr(productAttrValueIds, false); // 读取规格时,不考虑规格是否被禁用
|
||||
}
|
||||
// 拼接最终返回
|
||||
return ProductSpuConvert.INSTANCE.convert(spuBO, skuBOs, attrBOs, categoryBO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class ProductAttrRpcImpl implements ProductAttrRpc {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<List<ProductAttrValueRespDTO>> listProductAttrValues(ProductAttrValueListQueryRequestDTO queryDTO) {
|
||||
public CommonResult<List<ProductAttrValueRespDTO>> listProductAttrValues(ProductAttrValueListQueryReqDTO queryDTO) {
|
||||
return success(productAttrManager.listProductAttrValues(queryDTO));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,11 @@ package cn.iocoder.mall.productservice.rpc.spu;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.productservice.manager.spu.ProductSpuManager;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuCreateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuUpdateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.*;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
@@ -54,4 +52,9 @@ public class ProductSpuRpcImpl implements ProductSpuRpc {
|
||||
return success(productSpuManager.listProductSpuIds(lastSpuId, limit));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<ProductSpuDetailRespDTO> getProductSpuDetail(Integer productSpuId, Collection<String> fields) {
|
||||
return success(productSpuManager.getProductSpuDetail(productSpuId, fields));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,5 +18,9 @@ public class ProductSkuListQueryBO {
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
private Integer productSpuId;
|
||||
/**
|
||||
* 商品 SKU 状态
|
||||
*/
|
||||
private Integer productSkuStatus;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user