进行商品修改的迁移

This commit is contained in:
YunaiV
2020-07-28 20:10:03 +08:00
parent e107b42f53
commit 75876682fb
28 changed files with 337 additions and 759 deletions

View File

@@ -3,9 +3,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.ProductSpuUpdateReqDTO;
import java.util.List;
@@ -27,7 +27,7 @@ public interface ProductSpuRpc {
*
* @param updateDTO 更新商品 SPU DTO
*/
CommonResult<Boolean> updateProductSpu(ProductSpuUpdateReqDTO updateDTO);
CommonResult<Boolean> updateProductSpu(ProductSpuAndSkuUpdateReqDTO updateDTO);
/**
* 获得商品 SPU

View File

@@ -0,0 +1,96 @@
package cn.iocoder.mall.productservice.rpc.spu.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* 商品 SPU 和 SKU 更新 Request DTO
*/
@Data
@Accessors(chain = true)
public class ProductSpuAndSkuUpdateReqDTO implements Serializable {
/**
* SKU 信息
*/
@Data
@Accessors(chain = true)
public static class Sku implements Serializable {
/**
* 规格值数组
*/
@NotNull(message = "规格值数组不能为空")
private List<Integer> attrValueIds;
/**
* 价格,单位:分
*/
@NotNull(message = "价格不能为空")
@Min(value = 1L, message = "最小价格为 1")
private Integer price;
/**
* 库存数量
*/
@NotNull(message = "库存数量不能为空")
@Min(value = 1L, message = "最小库存为 1")
private Integer quantity;
}
/**
* Spu 编号
*/
@NotNull(message = "SPU 编号不能为空")
private Integer id;
// ========== 基本信息 =========
/**
* SPU 名字
*/
@NotEmpty(message = "SPU 名字不能为空")
private String name;
/**
* 卖点
*/
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
/**
* 描述
*/
@NotEmpty(message = "描述不能为空")
private String description;
/**
* 分类编号
*/
@NotNull(message = "分类编号不能为空")
private Integer cid;
/**
* 商品主图地址
*/
@NotEmpty(message = "商品主图地址不能为空")
private List<String> picUrls;
// ========== 其他信息 =========
/**
* 是否上架商品
*/
@NotNull(message = "是否上架商品不能为空")
private Boolean visible;
// ========== SKU =========
/**
* SKU 数组
*/
@NotNull(message = "SKU 不能为空")
@Valid
private List<Sku> skus;
}

View File

@@ -1,69 +0,0 @@
package cn.iocoder.mall.productservice.rpc.spu.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* 商品 SPU 更新 Request DTO
*/
@Data
@Accessors(chain = true)
public class ProductSpuUpdateReqDTO implements Serializable {
/**
* 商品 SPU 编号
*/
@NotNull(message = "商品 SPU 编号不能为空")
private Integer id;
/**
* SPU 名字
*/
@NotEmpty(message = "SPU 名字不能为空")
private String name;
/**
* 卖点
*/
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
/**
* 描述
*/
@NotEmpty(message = "描述不能为空")
private String description;
/**
* 分类编号
*/
@NotNull(message = "分类编号不能为空")
private Integer cid;
/**
* 商品主图地址
*/
@NotEmpty(message = "商品主图地址不能为空")
private List<String> picUrls;
/**
* 是否上架商品
*/
@NotNull(message = "是否上架商品不能为空")
private Boolean visible;
/**
* 排序字段
*/
@NotNull(message = "排序字段不能为空")
private Integer sort;
/**
* 价格
*/
@NotNull(message = "价格不能为空")
private Integer price;
/**
* 库存数量
*/
@NotNull(message = "库存数量不能为空")
private Integer quantity;
}

View File

@@ -18,7 +18,7 @@ public interface ProductSkuConvert {
List<ProductSkuDO> convertList(List<ProductSkuCreateOrUpdateBO> list);
@Mapping(source = "attrValueIds", target = "attrs", qualifiedByName = "translatePicUrlsFromStringList")
ProductSkuDO convertList(ProductSkuCreateOrUpdateBO bean);
ProductSkuDO convert(ProductSkuCreateOrUpdateBO skuUpdateDTO);
@Named("translateAttrValueIdsFromString")
default List<String> translateAttrValueIdsFromString(String attrValueIdsStar) {

View File

@@ -3,11 +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.service.sku.bo.ProductSkuCreateOrUpdateBO;
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.ProductSpuUpdateReqDTO;
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;
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuPageBO;
@@ -41,7 +41,7 @@ public interface ProductSpuConvert {
ProductSpuCreateBO convert(ProductSpuAndSkuCreateReqDTO bean);
ProductSpuUpdateBO convert(ProductSpuUpdateReqDTO bean);
ProductSpuUpdateBO convert(ProductSpuAndSkuUpdateReqDTO bean);
ProductSpuRespDTO convert(ProductSpuBO bean);
@@ -51,6 +51,9 @@ public interface ProductSpuConvert {
PageResult<ProductSpuRespDTO> convertPage(PageResult<ProductSpuBO> page);
List<ProductSkuCreateOrUpdateBO> convert(List<ProductSpuAndSkuCreateReqDTO.Sku> list);
List<ProductSkuCreateOrUpdateBO> convert02(List<ProductSpuAndSkuUpdateReqDTO.Sku> list);
@Named("translatePicUrlsFromString")
default List<String> translatePicUrlsFromList(String picUrls) {
return StringUtils.split(picUrls, ",");
@@ -61,6 +64,5 @@ public interface ProductSpuConvert {
return StringUtils.join(picUrls, ",");
}
List<ProductSkuCreateOrUpdateBO> convert(List<ProductSpuAndSkuCreateReqDTO.Sku> list);
}

View File

@@ -5,9 +5,9 @@ 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.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.ProductSpuUpdateReqDTO;
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;
@@ -17,17 +17,15 @@ import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuCreateOrUpdateBO;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.PRODUCT_CATEGORY_NOT_EXISTS;
import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2;
import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.*;
/**
* 商品 SPU Manager
@@ -52,30 +50,18 @@ public class ProductSpuManager {
*/
@Transactional
public Integer createProductSpu(ProductSpuAndSkuCreateReqDTO createDTO) {
// 校验商品分类分类存在
ProductCategoryBO categoryBO = productCategoryService.getProductCategory(createDTO.getCid());
if (categoryBO == null) {
// 不存在
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_NOT_EXISTS);
}
if (ProductCategoryIdEnum.ROOT.getId().equals(categoryBO.getPid())) {
// 商品只能添加到二级分类下
throw ServiceExceptionUtil.exception(PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2);
}
// 校验规格是否存在
Set<Integer> attrValueIds = new HashSet<>();
createDTO.getSkus().forEach(productSkuAddDTO -> attrValueIds.addAll(productSkuAddDTO.getAttrValueIds()));
List<ProductAttrKeyValueBO> attrKeyValueBOs = productAttrService.validProductAttr(attrValueIds, true);
// 校验商品分类是否合法
this.checkProductCategory(createDTO.getCid());
// 创建商品 SKU 对象,并进行校验
List<ProductSkuCreateOrUpdateBO> skus = ProductSpuConvert.INSTANCE.convert(createDTO.getSkus());
productSkuService.validProductSku(skus, attrKeyValueBOs);
List<ProductSkuCreateOrUpdateBO> skuBOs = ProductSpuConvert.INSTANCE.convert(createDTO.getSkus());
this.checkProductAttr(skuBOs);
// 插入商品 SPU 记录
ProductSpuCreateBO spuCreateBO = ProductSpuConvert.INSTANCE.convert(createDTO).setSort(0);
spuCreateBO.setPrice(skus.stream().min(Comparator.comparing(ProductSkuCreateOrUpdateBO::getPrice)).get().getPrice()); // 求最小价格
spuCreateBO.setQuantity(skus.stream().mapToInt(ProductSkuCreateOrUpdateBO::getQuantity).sum()); // 求库存之和
spuCreateBO.setPrice(skuBOs.stream().min(Comparator.comparing(ProductSkuCreateOrUpdateBO::getPrice)).get().getPrice()); // 求最小价格
spuCreateBO.setQuantity(skuBOs.stream().mapToInt(ProductSkuCreateOrUpdateBO::getQuantity).sum()); // 求库存之和
ProductSpuBO spuBO = productSpuService.createProductSpu(spuCreateBO);
// 插入商品 SKU 记录
productSkuService.createProductSkus(spuBO.getId(), skus);
// 插入商品 SKU 记录
productSkuService.createProductSkus(spuBO.getId(), skuBOs);
return spuBO.getId();
}
@@ -84,8 +70,19 @@ public class ProductSpuManager {
*
* @param updateDTO 更新商品 SPU DTO
*/
public void updateProductSpu(ProductSpuUpdateReqDTO updateDTO) {
productSpuService.updateProductSpu(ProductSpuConvert.INSTANCE.convert(updateDTO));
public void updateProductSpu(ProductSpuAndSkuUpdateReqDTO updateDTO) {
// 校验商品分类是否合法
this.checkProductCategory(updateDTO.getCid());
// 创建商品 SKU 对象,并进行校验
List<ProductSkuCreateOrUpdateBO> skuBOs = ProductSpuConvert.INSTANCE.convert02(updateDTO.getSkus());
this.checkProductAttr(skuBOs);
// 更新商品 SPU 记录
ProductSpuUpdateBO spuUpdateBO = ProductSpuConvert.INSTANCE.convert(updateDTO);
spuUpdateBO.setPrice(skuBOs.stream().min(Comparator.comparing(ProductSkuCreateOrUpdateBO::getPrice)).get().getPrice()); // 求最小价格
spuUpdateBO.setQuantity(skuBOs.stream().mapToInt(ProductSkuCreateOrUpdateBO::getQuantity).sum()); // 求库存之和
productSpuService.updateProductSpu(spuUpdateBO);
// 更新商品 SKU 记录
productSkuService.updateProductSkus(updateDTO.getId(), skuBOs);
}
/**
@@ -121,4 +118,57 @@ public class ProductSpuManager {
return ProductSpuConvert.INSTANCE.convertPage(pageResultBO);
}
/**
* 添加或修改商品 SPU 时,校验商品分类是否合法
*
* @param cid 商品分类编号
* @return 商品分类
*/
private ProductCategoryBO checkProductCategory(Integer cid) {
ProductCategoryBO categoryBO = productCategoryService.getProductCategory(cid);
if (categoryBO == null) {
// 不存在
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_NOT_EXISTS);
}
if (ProductCategoryIdEnum.ROOT.getId().equals(categoryBO.getPid())) {
// 商品只能添加到二级分类下
throw ServiceExceptionUtil.exception(PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2);
}
return categoryBO;
}
private List<ProductAttrKeyValueBO> checkProductAttr(List<ProductSkuCreateOrUpdateBO> skuBOs) {
// 第一步,校验 SKU 使用到的规格是否存在
Set<Integer> attrValueIds = new HashSet<>();
skuBOs.forEach(sku -> attrValueIds.addAll(sku.getAttrValueIds()));
List<ProductAttrKeyValueBO> attrKeyValueBOs = productAttrService.validProductAttr(attrValueIds, true);
// 第二步,校验 SKU 设置的规格是否合法,例如说数量是否一致,是否重复等等
// 创建 ProductAttrDetailBO 的映射。其中KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
Map<Integer, ProductAttrKeyValueBO> productAttrDetailBOMap = attrKeyValueBOs.stream().collect(
Collectors.toMap(ProductAttrKeyValueBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO));
// 1. 先校验,一个 Sku 下,没有重复的规格。校验方式是,遍历每个 Sku ,看看是否有重复的规格 attrId
for (ProductSkuCreateOrUpdateBO sku : skuBOs) {
Set<Integer> attrIds = sku.getAttrValueIds().stream().map(attrValueId -> productAttrDetailBOMap.get(attrValueId).getAttrKeyId())
.collect(Collectors.toSet());
if (attrIds.size() != sku.getAttrValueIds().size()) {
throw ServiceExceptionUtil.exception(PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE);
}
}
// 2. 再校验,每个 Sku 的规格值的数量,是一致的。
int attrValueIdsSize = skuBOs.get(0).getAttrValueIds().size();
for (int i = 1; i < skuBOs.size(); i++) {
if (attrValueIdsSize != skuBOs.get(i).getAttrValueIds().size()) {
throw ServiceExceptionUtil.exception(PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS);
}
}
// 3. 最后校验,每个 Sku 之间不是重复的
Set<Set<Integer>> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的.
for (ProductSkuCreateOrUpdateBO sku : skuBOs) {
if (!skuAttrValues.add(new HashSet<>(sku.getAttrValueIds()))) { // 添加失败,说明重复
throw ServiceExceptionUtil.exception(PRODUCT_SPU_SKU_NOT_DUPLICATE);
}
}
return attrKeyValueBOs;
}
}

View File

@@ -4,9 +4,9 @@ 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.ProductSpuUpdateReqDTO;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
@@ -29,7 +29,7 @@ public class ProductSpuRpcImpl implements ProductSpuRpc {
}
@Override
public CommonResult<Boolean> updateProductSpu(ProductSpuUpdateReqDTO updateDTO) {
public CommonResult<Boolean> updateProductSpu(ProductSpuAndSkuUpdateReqDTO updateDTO) {
productSpuManager.updateProductSpu(updateDTO);
return success(true);
}

View File

@@ -1,31 +1,26 @@
package cn.iocoder.mall.productservice.service.sku;
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.util.StringUtils;
import cn.iocoder.mall.productservice.convert.sku.ProductSkuConvert;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.spu.ProductSkuDO;
import cn.iocoder.mall.productservice.dal.mysql.mapper.sku.ProductSkuMapper;
import cn.iocoder.mall.productservice.service.attr.bo.ProductAttrKeyValueBO;
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuCreateOrUpdateBO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.*;
@Service
public class ProductSkuService {
@Autowired
private ProductSkuMapper productSkuMapper;
public void createProductSkus(Integer spuId, List<ProductSkuCreateOrUpdateBO> createBOs) {
List<ProductSkuDO> skus = ProductSkuConvert.INSTANCE.convertList(createBOs);
public void createProductSkus(Integer spuId, List<ProductSkuCreateOrUpdateBO> createSkuBOs) {
List<ProductSkuDO> skus = ProductSkuConvert.INSTANCE.convertList(createSkuBOs);
skus.forEach(sku -> {
sku.setStatus(CommonStatusEnum.ENABLE.getValue());
sku.setSpuId(spuId);
@@ -33,42 +28,64 @@ public class ProductSkuService {
productSkuMapper.insertList(skus);
}
public void updateProductSkus(Integer spuId, List<ProductSkuCreateOrUpdateBO> createBOs) {
public void updateProductSkus(Integer spuId, List<ProductSkuCreateOrUpdateBO> skuUpdateBOs) {
List<ProductSkuDO> existsSkus = productSkuMapper.selectListBySpuIdAndStatus(spuId,
CommonStatusEnum.ENABLE.getValue());
List<ProductSkuDO> insertSkus = new ArrayList<>(); // 1、找不到进行插入
List<Integer> deleteSkus = new ArrayList<>(); // 2、多余的删除
List<ProductSkuDO> updateSkus = new ArrayList<>(); // 3、找的到进行更新。
for (ProductSkuCreateOrUpdateBO skuUpdateDTO : skuUpdateBOs) {
ProductSkuDO existsSku = findProductSku(skuUpdateDTO.getAttrValueIds(), existsSkus);
// 3、找的到进行更新。
if (existsSku != null) {
// 移除
existsSkus.remove(existsSku);
// 创建 ProductSkuDO
updateSkus.add(ProductSkuConvert.INSTANCE.convert(skuUpdateDTO).setId(existsSku.getId()));
continue;
}
// 1、找不到进行插入
ProductSkuDO insertSku = ProductSkuConvert.INSTANCE.convert(skuUpdateDTO)
.setSpuId(spuId).setStatus(CommonStatusEnum.ENABLE.getValue());
insertSkus.add(insertSku);
}
// 2、多余的删除
if (!existsSkus.isEmpty()) {
deleteSkus.addAll(existsSkus.stream().map(ProductSkuDO::getId).collect(Collectors.toList()));
}
// 执行修改 Sku
if (!insertSkus.isEmpty()) {
productSkuMapper.insertList(insertSkus);
}
if (!updateSkus.isEmpty()) {
updateSkus.forEach(productSkuDO -> productSkuMapper.updateById(productSkuDO));
}
if (!deleteSkus.isEmpty()) {
productSkuMapper.deleteBatchIds(deleteSkus);
}
}
/**
* 校验 sku 是否合法
* 获得 sku 数组中,指定规格的 sku
*
* @param skuBOs 商品 SKU 添加信息
* @param attrKeyValueBOs 商品规格明细数组
* @param attrValueIds 指定规格 Value 的编号数组
* @param skus sku 数组
* @return 符合条件的 sku
*/
public void validProductSku(List<ProductSkuCreateOrUpdateBO> skuBOs, List<ProductAttrKeyValueBO> attrKeyValueBOs) {
// 创建 ProductAttrDetailBO 的映射。其中KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
Map<Integer, ProductAttrKeyValueBO> productAttrDetailBOMap = attrKeyValueBOs.stream().collect(
Collectors.toMap(ProductAttrKeyValueBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO));
// 1. 先校验,一个 Sku 下,没有重复的规格。校验方式是,遍历每个 Sku ,看看是否有重复的规格 attrId
for (ProductSkuCreateOrUpdateBO sku : skuBOs) {
Set<Integer> attrIds = sku.getAttrValueIds().stream().map(attrValueId -> productAttrDetailBOMap.get(attrValueId).getAttrKeyId())
.collect(Collectors.toSet());
if (attrIds.size() != sku.getAttrValueIds().size()) {
throw ServiceExceptionUtil.exception(PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE);
}
}
// 2. 再校验,每个 Sku 的规格值的数量,是一致的。
int attrValueIdsSize = skuBOs.get(0).getAttrValueIds().size();
for (int i = 1; i < skuBOs.size(); i++) {
if (attrValueIdsSize != skuBOs.get(i).getAttrValueIds().size()) {
throw ServiceExceptionUtil.exception(PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS);
}
}
// 3. 最后校验,每个 Sku 之间不是重复的
Set<Set<Integer>> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的.
for (ProductSkuCreateOrUpdateBO sku : skuBOs) {
if (!skuAttrValues.add(new HashSet<>(sku.getAttrValueIds()))) { // 添加失败,说明重复
throw ServiceExceptionUtil.exception(PRODUCT_SPU_SKU_NOT_DUPLICATE);
private ProductSkuDO findProductSku(Collection<Integer> attrValueIds, List<ProductSkuDO> skus) {
if (CollectionUtils.isEmpty(skus)) {
return null;
}
// 创建成 Set ,方便后面比较
attrValueIds = new HashSet<>(attrValueIds);
for (ProductSkuDO sku : skus) {
Set<Integer> skuAttrValueIds = StringUtils.split(sku.getAttrs(), ",")
.stream().map(Integer::parseInt).collect(Collectors.toSet());
if (attrValueIds.equals(skuAttrValueIds)) {
return sku;
}
}
return null;
}
}

View File

@@ -52,7 +52,6 @@ public class ProductSpuUpdateBO {
/**
* 排序字段
*/
@NotNull(message = "排序字段不能为空")
private Integer sort;
/**
* 价格