Commit 407cbb109f02c278db913a06dea675639f5d9db7

Authored by franky
1 parent 2382ddfb

spu 调整一波

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 {
80 80 @ApiOperation("获得商品spu分页")
81 81 @PreAuthorize("@ss.hasPermission('product:spu:query')")
82 82 public CommonResult<PageResult<SpuRespVO>> getSpuPage(@Valid SpuPageReqVO pageVO) {
83   - PageResult<ProductSpuDO> pageResult = spuService.getSpuPage(pageVO);
84   - return success(ProductSpuConvert.INSTANCE.convertPage(pageResult));
  83 + return success(spuService.getSpuPage(pageVO));
85 84 }
86 85  
87 86 @GetMapping("/export-excel")
... ...
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.*;
12 12 public class SpuRespVO extends ProductSpuBaseVO {
13 13  
14 14 @ApiModelProperty(value = "主键", required = true)
15   - private Integer id;
  15 + private Long id;
16 16  
17 17 @ApiModelProperty(value = "创建时间")
18 18 private Date createTime;
19 19  
20   - List<ProductSkuRespVO> productSkuRespVOS;
  20 + List<ProductSkuRespVO> skus;
21 21  
22 22 }
... ...
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 {
20 20  
21 21 @ApiModelProperty(value = "sku组合")
22 22 @Valid
23   - List<ProductSkuCreateReqVO> productSkuCreateReqVOS;
  23 + List<ProductSkuCreateReqVO> skus;
24 24  
25 25 }
... ...
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&lt;ProductSkuDO&gt; {
46 46 .orderByDesc(ProductSkuDO::getId));
47 47 }
48 48  
49   - default List<ProductSkuDO> selectBySpuId(Long spuId) {
  49 + default List<ProductSkuDO> selectBySpuIds(List<Long> spuIds) {
50 50 return selectList(new LambdaQueryWrapperX<ProductSkuDO>()
51   - .eqIfPresent(ProductSkuDO::getSpuId, spuId)
  51 + .inIfPresent(ProductSkuDO::getSpuId, spuIds)
52 52 );
53 53 }
  54 +
  55 + default void deleteBySpuId(Long spuId) {
  56 + LambdaQueryWrapperX<ProductSkuDO> lambdaQueryWrapperX = new LambdaQueryWrapperX<ProductSkuDO>()
  57 + .eqIfPresent(ProductSkuDO::getSpuId, spuId);
  58 + delete(lambdaQueryWrapperX);
  59 + }
54 60 }
... ...
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 {
92 92 * @return 商品sku 集合
93 93 */
94 94 List<ProductSkuDO> getSkusBySpuId(Long spuId);
  95 +
  96 + /**
  97 + *
  98 + * @param spuIds spu 编码集合
  99 + * @return 商品 sku 集合
  100 + */
  101 + List<ProductSkuDO> getSkusBySpuIds(List<Long> spuIds);
  102 +
  103 + /**
  104 + * 通过 spuId 删除 sku 信息
  105 + * @param spuId spu 编码
  106 + */
  107 + void deleteSkuBySpuId(Long spuId);
  108 +
  109 + /**
  110 + * 根据 spuId 更新 spu 下的 sku 信息
  111 + * @param spuId spu 编码
  112 + * @param skus sku 的集合
  113 + */
  114 + void updateSkus(Long spuId, List<ProductSkuCreateReqVO> skus);
95 115 }
... ...
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;
11 11 import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants;
12 12 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
13 13 import org.springframework.stereotype.Service;
  14 +import org.springframework.transaction.annotation.Transactional;
14 15 import org.springframework.validation.annotation.Validated;
15 16  
16 17 import javax.annotation.Resource;
... ... @@ -89,14 +90,16 @@ public class ProductSkuServiceImpl implements ProductSkuService {
89 90 }
90 91  
91 92 // TODO @franky:这个方法,貌似实现的还是有点问题哈。例如说,throw 异常,后面还执行逻辑~
  93 + // TODO @艿艿 咳咳,throw 那里我是偷懒省略了{},哈哈,我加上,然后我调试下,在优化下
92 94 @Override
93 95 public void validateSkus(List<ProductSkuCreateReqVO> list) {
94 96 List<ProductSkuBaseVO.Property> skuPropertyList = list.stream().flatMap(p -> p.getProperties().stream()).collect(Collectors.toList());
95 97 // 校验规格属性以及规格值是否存在
96 98 List<Long> propertyIds = skuPropertyList.stream().map(ProductSkuBaseVO.Property::getPropertyId).collect(Collectors.toList());
97 99 List<ProductPropertyRespVO> propertyAndValueList = productPropertyService.selectByIds(propertyIds);
98   - if (propertyAndValueList.isEmpty())
  100 + if (propertyAndValueList.isEmpty()) {
99 101 throw ServiceExceptionUtil.exception(PROPERTY_NOT_EXISTS);
  102 + }
100 103 Map<Long, ProductPropertyRespVO> propertyMap = propertyAndValueList.stream().collect(Collectors.toMap(ProductPropertyRespVO::getId, p -> p));
101 104 skuPropertyList.forEach(p -> {
102 105 ProductPropertyRespVO productPropertyRespVO = propertyMap.get(p.getPropertyId());
... ... @@ -126,6 +129,55 @@ public class ProductSkuServiceImpl implements ProductSkuService {
126 129  
127 130 @Override
128 131 public List<ProductSkuDO> getSkusBySpuId(Long spuId) {
129   - return productSkuMapper.selectBySpuId(spuId);
  132 + return productSkuMapper.selectBySpuIds(Collections.singletonList(spuId));
  133 + }
  134 +
  135 + @Override
  136 + public List<ProductSkuDO> getSkusBySpuIds(List<Long> spuIds) {
  137 + return productSkuMapper.selectBySpuIds(spuIds);
  138 + }
  139 +
  140 + @Override
  141 + public void deleteSkuBySpuId(Long spuId) {
  142 + productSkuMapper.deleteBySpuId(spuId);
  143 + }
  144 +
  145 + @Override
  146 + @Transactional
  147 + public void updateSkus(Long spuId, List<ProductSkuCreateReqVO> skus) {
  148 + List<ProductSkuDO> allUpdateSkus = ProductSkuConvert.INSTANCE.convertSkuDOList(skus);
  149 + // 查询 spu 下已经存在的 sku 的集合
  150 + List<ProductSkuDO> existsSkus = productSkuMapper.selectBySpuIds(Collections.singletonList(spuId));
  151 + Map<Long, ProductSkuDO> existsSkuMap = existsSkus.stream().collect(Collectors.toMap(ProductSkuDO::getId, p -> p));
  152 +
  153 + // 拆分三个集合, 新插入的, 需要更新的,需要删除的
  154 + List<ProductSkuDO> insertSkus = new ArrayList<>();
  155 + List<ProductSkuDO> updateSkus = new ArrayList<>();
  156 + List<ProductSkuDO> deleteSkus = new ArrayList<>();
  157 +
  158 + allUpdateSkus.forEach(p -> {
  159 + if (null != p.getId()) {
  160 + if (existsSkuMap.get(p.getId()) != null) {
  161 + updateSkus.add(p);
  162 + return;
  163 + }
  164 + deleteSkus.add(p);
  165 + return;
  166 + }
  167 + p.setSpuId(spuId);
  168 + insertSkus.add(p);
  169 + });
  170 +
  171 + if (insertSkus.size() > 0) {
  172 + productSkuMapper.insertBatch(insertSkus);
  173 + }
  174 +
  175 + if (updateSkus.size() > 0) {
  176 + updateSkus.forEach(p -> productSkuMapper.updateById(p));
  177 + }
  178 +
  179 + if (deleteSkus.size() > 0) {
  180 + productSkuMapper.deleteBatchIds(deleteSkus.stream().map(ProductSkuDO::getId).collect(Collectors.toList()));
  181 + }
130 182 }
131 183 }
... ...
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 {
57 57 * @param pageReqVO 分页查询
58 58 * @return 商品spu分页
59 59 */
60   - PageResult<ProductSpuDO> getSpuPage(SpuPageReqVO pageReqVO);
  60 + PageResult<SpuRespVO> getSpuPage(SpuPageReqVO pageReqVO);
61 61  
62 62 /**
63 63 * 获得商品spu列表, 用于 Excel 导出
... ...
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;
7 7 import cn.iocoder.yudao.module.product.service.category.CategoryService;
8 8 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
9 9 import org.springframework.stereotype.Service;
  10 +
10 11 import javax.annotation.Resource;
11 12 import javax.validation.Valid;
12 13  
... ... @@ -67,20 +68,31 @@ public class ProductSpuServiceImpl implements ProductSpuService {
67 68 }
68 69  
69 70 @Override
  71 + @Transactional
70 72 public void updateSpu(SpuUpdateReqVO updateReqVO) {
71   - // 校验存在
  73 + // 校验 spu 是否存在
72 74 this.validateSpuExists(updateReqVO.getId());
  75 + // 校验分类
  76 + categoryService.validatedCategoryById(updateReqVO.getCategoryId());
  77 + // 校验SKU
  78 + List<ProductSkuCreateReqVO> skuCreateReqList = updateReqVO.getSkus();
  79 + productSkuService.validateSkus(skuCreateReqList);
73 80 // 更新
74 81 ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO);
75 82 ProductSpuMapper.updateById(updateObj);
  83 + // 更新 sku
  84 + productSkuService.updateSkus(updateObj.getId(), updateReqVO.getSkus());
76 85 }
77 86  
78 87 @Override
  88 + @Transactional
79 89 public void deleteSpu(Long id) {
80 90 // 校验存在
81 91 this.validateSpuExists(id);
82   - // 删除
  92 + // 删除 SPU
83 93 ProductSpuMapper.deleteById(id);
  94 + // 删除关联的 SKU
  95 + productSkuService.deleteSkuBySpuId(id);
84 96 }
85 97  
86 98 private void validateSpuExists(Long id) {
... ... @@ -93,8 +105,10 @@ public class ProductSpuServiceImpl implements ProductSpuService {
93 105 public SpuRespVO getSpu(Long id) {
94 106 ProductSpuDO spu = ProductSpuMapper.selectById(id);
95 107 SpuRespVO spuVO = ProductSpuConvert.INSTANCE.convert(spu);
96   - List<ProductSkuRespVO> skuReqs = ProductSkuConvert.INSTANCE.convertList( productSkuService.getSkusBySpuId(id));
97   - spuVO.setProductSkuRespVOS(skuReqs);
  108 + if (null != spuVO) {
  109 + List<ProductSkuRespVO> skuReqs = ProductSkuConvert.INSTANCE.convertList(productSkuService.getSkusBySpuId(id));
  110 + spuVO.setSkus(skuReqs);
  111 + }
98 112 return spuVO;
99 113 }
100 114  
... ... @@ -104,8 +118,17 @@ public class ProductSpuServiceImpl implements ProductSpuService {
104 118 }
105 119  
106 120 @Override
107   - public PageResult<ProductSpuDO> getSpuPage(SpuPageReqVO pageReqVO) {
108   - return ProductSpuMapper.selectPage(pageReqVO);
  121 + public PageResult<SpuRespVO> getSpuPage(SpuPageReqVO pageReqVO) {
  122 + PageResult<SpuRespVO> spuVOs = ProductSpuConvert.INSTANCE.convertPage(ProductSpuMapper.selectPage(pageReqVO));
  123 + // 查询 sku 的信息
  124 + List<Long> spuIds = spuVOs.getList().stream().map(SpuRespVO::getId).collect(Collectors.toList());
  125 + List<ProductSkuRespVO> skus = ProductSkuConvert.INSTANCE.convertList(productSkuService.getSkusBySpuIds(spuIds));
  126 + Map<Long, List<ProductSkuRespVO>> skuMap = skus.stream().collect(Collectors.groupingBy(ProductSkuRespVO::getSpuId));
  127 + // 将 spu 和 sku 进行组装
  128 + spuVOs.getList().forEach(p -> {
  129 + p.setSkus(skuMap.get(p.getId()));
  130 + });
  131 + return spuVOs;
109 132 }
110 133  
111 134 @Override
... ...
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 {
159 159 reqVO.setEndCreateTime(null);
160 160  
161 161 // 调用
162   - PageResult<ProductSpuDO> pageResult = spuService.getSpuPage(reqVO);
  162 + PageResult<SpuRespVO> pageResult = spuService.getSpuPage(reqVO);
163 163 // 断言
164 164 assertEquals(1, pageResult.getTotal());
165 165 assertEquals(1, pageResult.getList().size());
... ...