From 407cbb109f02c278db913a06dea675639f5d9db7 Mon Sep 17 00:00:00 2001 From: franky Date: Wed, 8 Jun 2022 18:38:14 +0800 Subject: [PATCH] =?UTF-8?q?spu=20=E8=B0=83=E6=95=B4=E4=B8=80=E6=B3=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/spu/ProductSpuController.java | 3 +- .../controller/admin/spu/vo/SpuRespVO.java | 4 +- .../admin/spu/vo/SpuUpdateReqVO.java | 2 +- .../dal/mysql/sku/ProductSkuMapper.java | 10 +++- .../service/sku/ProductSkuService.java | 20 +++++++ .../service/sku/ProductSkuServiceImpl.java | 56 ++++++++++++++++++- .../service/spu/ProductSpuService.java | 2 +- .../service/spu/ProductSpuServiceImpl.java | 35 ++++++++++-- .../spu/ProductSpuServiceImplTest.java | 2 +- 9 files changed, 117 insertions(+), 17 deletions(-) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java index f54425463..71bfa82bd 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java @@ -80,8 +80,7 @@ public class ProductSpuController { @ApiOperation("获得商品spu分页") @PreAuthorize("@ss.hasPermission('product:spu:query')") public CommonResult> getSpuPage(@Valid SpuPageReqVO pageVO) { - PageResult pageResult = spuService.getSpuPage(pageVO); - return success(ProductSpuConvert.INSTANCE.convertPage(pageResult)); + return success(spuService.getSpuPage(pageVO)); } @GetMapping("/export-excel") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/SpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/SpuRespVO.java index 95567e27e..390746cd3 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/SpuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/SpuRespVO.java @@ -12,11 +12,11 @@ import io.swagger.annotations.*; public class SpuRespVO extends ProductSpuBaseVO { @ApiModelProperty(value = "主键", required = true) - private Integer id; + private Long id; @ApiModelProperty(value = "创建时间") private Date createTime; - List productSkuRespVOS; + List skus; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/SpuUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/SpuUpdateReqVO.java index cb4cd7cb9..9e4092235 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/SpuUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/SpuUpdateReqVO.java @@ -20,6 +20,6 @@ public class SpuUpdateReqVO extends ProductSpuBaseVO { @ApiModelProperty(value = "sku组合") @Valid - List productSkuCreateReqVOS; + List skus; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java index 37e537bfa..a42a50773 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java @@ -46,9 +46,15 @@ public interface ProductSkuMapper extends BaseMapperX { .orderByDesc(ProductSkuDO::getId)); } - default List selectBySpuId(Long spuId) { + default List selectBySpuIds(List spuIds) { return selectList(new LambdaQueryWrapperX() - .eqIfPresent(ProductSkuDO::getSpuId, spuId) + .inIfPresent(ProductSkuDO::getSpuId, spuIds) ); } + + default void deleteBySpuId(Long spuId) { + LambdaQueryWrapperX lambdaQueryWrapperX = new LambdaQueryWrapperX() + .eqIfPresent(ProductSkuDO::getSpuId, spuId); + delete(lambdaQueryWrapperX); + } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java index d93da5986..a398b4620 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java @@ -92,4 +92,24 @@ public interface ProductSkuService { * @return 商品sku 集合 */ List getSkusBySpuId(Long spuId); + + /** + * + * @param spuIds spu 编码集合 + * @return 商品 sku 集合 + */ + List getSkusBySpuIds(List spuIds); + + /** + * 通过 spuId 删除 sku 信息 + * @param spuId spu 编码 + */ + void deleteSkuBySpuId(Long spuId); + + /** + * 根据 spuId 更新 spu 下的 sku 信息 + * @param spuId spu 编码 + * @param skus sku 的集合 + */ + void updateSkus(Long spuId, List skus); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java index 92e84f211..4bab281d1 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper; import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants; import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; @@ -89,14 +90,16 @@ public class ProductSkuServiceImpl implements ProductSkuService { } // TODO @franky:这个方法,貌似实现的还是有点问题哈。例如说,throw 异常,后面还执行逻辑~ + // TODO @艿艿 咳咳,throw 那里我是偷懒省略了{},哈哈,我加上,然后我调试下,在优化下 @Override public void validateSkus(List list) { List skuPropertyList = list.stream().flatMap(p -> p.getProperties().stream()).collect(Collectors.toList()); // 校验规格属性以及规格值是否存在 List propertyIds = skuPropertyList.stream().map(ProductSkuBaseVO.Property::getPropertyId).collect(Collectors.toList()); List propertyAndValueList = productPropertyService.selectByIds(propertyIds); - if (propertyAndValueList.isEmpty()) + if (propertyAndValueList.isEmpty()) { throw ServiceExceptionUtil.exception(PROPERTY_NOT_EXISTS); + } Map propertyMap = propertyAndValueList.stream().collect(Collectors.toMap(ProductPropertyRespVO::getId, p -> p)); skuPropertyList.forEach(p -> { ProductPropertyRespVO productPropertyRespVO = propertyMap.get(p.getPropertyId()); @@ -126,6 +129,55 @@ public class ProductSkuServiceImpl implements ProductSkuService { @Override public List getSkusBySpuId(Long spuId) { - return productSkuMapper.selectBySpuId(spuId); + return productSkuMapper.selectBySpuIds(Collections.singletonList(spuId)); + } + + @Override + public List getSkusBySpuIds(List spuIds) { + return productSkuMapper.selectBySpuIds(spuIds); + } + + @Override + public void deleteSkuBySpuId(Long spuId) { + productSkuMapper.deleteBySpuId(spuId); + } + + @Override + @Transactional + public void updateSkus(Long spuId, List skus) { + List allUpdateSkus = ProductSkuConvert.INSTANCE.convertSkuDOList(skus); + // 查询 spu 下已经存在的 sku 的集合 + List existsSkus = productSkuMapper.selectBySpuIds(Collections.singletonList(spuId)); + Map existsSkuMap = existsSkus.stream().collect(Collectors.toMap(ProductSkuDO::getId, p -> p)); + + // 拆分三个集合, 新插入的, 需要更新的,需要删除的 + List insertSkus = new ArrayList<>(); + List updateSkus = new ArrayList<>(); + List deleteSkus = new ArrayList<>(); + + allUpdateSkus.forEach(p -> { + if (null != p.getId()) { + if (existsSkuMap.get(p.getId()) != null) { + updateSkus.add(p); + return; + } + deleteSkus.add(p); + return; + } + p.setSpuId(spuId); + insertSkus.add(p); + }); + + if (insertSkus.size() > 0) { + productSkuMapper.insertBatch(insertSkus); + } + + if (updateSkus.size() > 0) { + updateSkus.forEach(p -> productSkuMapper.updateById(p)); + } + + if (deleteSkus.size() > 0) { + productSkuMapper.deleteBatchIds(deleteSkus.stream().map(ProductSkuDO::getId).collect(Collectors.toList())); + } } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java index d51c8d678..e4fc47d56 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java @@ -57,7 +57,7 @@ public interface ProductSpuService { * @param pageReqVO 分页查询 * @return 商品spu分页 */ - PageResult getSpuPage(SpuPageReqVO pageReqVO); + PageResult getSpuPage(SpuPageReqVO pageReqVO); /** * 获得商品spu列表, 用于 Excel 导出 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 820fc901f..4ce99d0b5 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.service.category.CategoryService; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import org.springframework.stereotype.Service; + import javax.annotation.Resource; import javax.validation.Valid; @@ -67,20 +68,31 @@ public class ProductSpuServiceImpl implements ProductSpuService { } @Override + @Transactional public void updateSpu(SpuUpdateReqVO updateReqVO) { - // 校验存在 + // 校验 spu 是否存在 this.validateSpuExists(updateReqVO.getId()); + // 校验分类 + categoryService.validatedCategoryById(updateReqVO.getCategoryId()); + // 校验SKU + List skuCreateReqList = updateReqVO.getSkus(); + productSkuService.validateSkus(skuCreateReqList); // 更新 ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO); ProductSpuMapper.updateById(updateObj); + // 更新 sku + productSkuService.updateSkus(updateObj.getId(), updateReqVO.getSkus()); } @Override + @Transactional public void deleteSpu(Long id) { // 校验存在 this.validateSpuExists(id); - // 删除 + // 删除 SPU ProductSpuMapper.deleteById(id); + // 删除关联的 SKU + productSkuService.deleteSkuBySpuId(id); } private void validateSpuExists(Long id) { @@ -93,8 +105,10 @@ public class ProductSpuServiceImpl implements ProductSpuService { public SpuRespVO getSpu(Long id) { ProductSpuDO spu = ProductSpuMapper.selectById(id); SpuRespVO spuVO = ProductSpuConvert.INSTANCE.convert(spu); - List skuReqs = ProductSkuConvert.INSTANCE.convertList( productSkuService.getSkusBySpuId(id)); - spuVO.setProductSkuRespVOS(skuReqs); + if (null != spuVO) { + List skuReqs = ProductSkuConvert.INSTANCE.convertList(productSkuService.getSkusBySpuId(id)); + spuVO.setSkus(skuReqs); + } return spuVO; } @@ -104,8 +118,17 @@ public class ProductSpuServiceImpl implements ProductSpuService { } @Override - public PageResult getSpuPage(SpuPageReqVO pageReqVO) { - return ProductSpuMapper.selectPage(pageReqVO); + public PageResult getSpuPage(SpuPageReqVO pageReqVO) { + PageResult spuVOs = ProductSpuConvert.INSTANCE.convertPage(ProductSpuMapper.selectPage(pageReqVO)); + // 查询 sku 的信息 + List spuIds = spuVOs.getList().stream().map(SpuRespVO::getId).collect(Collectors.toList()); + List skus = ProductSkuConvert.INSTANCE.convertList(productSkuService.getSkusBySpuIds(spuIds)); + Map> skuMap = skus.stream().collect(Collectors.groupingBy(ProductSkuRespVO::getSpuId)); + // 将 spu 和 sku 进行组装 + spuVOs.getList().forEach(p -> { + p.setSkus(skuMap.get(p.getId())); + }); + return spuVOs; } @Override diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java index 3ed353e31..6e943f234 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java @@ -159,7 +159,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { reqVO.setEndCreateTime(null); // 调用 - PageResult pageResult = spuService.getSpuPage(reqVO); + PageResult pageResult = spuService.getSpuPage(reqVO); // 断言 assertEquals(1, pageResult.getTotal()); assertEquals(1, pageResult.getList().size());