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,8 +80,7 @@ public class ProductSpuController {
80 @ApiOperation("获得商品spu分页") 80 @ApiOperation("获得商品spu分页")
81 @PreAuthorize("@ss.hasPermission('product:spu:query')") 81 @PreAuthorize("@ss.hasPermission('product:spu:query')")
82 public CommonResult<PageResult<SpuRespVO>> getSpuPage(@Valid SpuPageReqVO pageVO) { 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 @GetMapping("/export-excel") 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,11 +12,11 @@ import io.swagger.annotations.*;
12 public class SpuRespVO extends ProductSpuBaseVO { 12 public class SpuRespVO extends ProductSpuBaseVO {
13 13
14 @ApiModelProperty(value = "主键", required = true) 14 @ApiModelProperty(value = "主键", required = true)
15 - private Integer id; 15 + private Long id;
16 16
17 @ApiModelProperty(value = "创建时间") 17 @ApiModelProperty(value = "创建时间")
18 private Date createTime; 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,6 +20,6 @@ public class SpuUpdateReqVO extends ProductSpuBaseVO {
20 20
21 @ApiModelProperty(value = "sku组合") 21 @ApiModelProperty(value = "sku组合")
22 @Valid 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,9 +46,15 @@ public interface ProductSkuMapper extends BaseMapperX&lt;ProductSkuDO&gt; {
46 .orderByDesc(ProductSkuDO::getId)); 46 .orderByDesc(ProductSkuDO::getId));
47 } 47 }
48 48
49 - default List<ProductSkuDO> selectBySpuId(Long spuId) { 49 + default List<ProductSkuDO> selectBySpuIds(List<Long> spuIds) {
50 return selectList(new LambdaQueryWrapperX<ProductSkuDO>() 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,4 +92,24 @@ public interface ProductSkuService {
92 * @return 商品sku 集合 92 * @return 商品sku 集合
93 */ 93 */
94 List<ProductSkuDO> getSkusBySpuId(Long spuId); 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,6 +11,7 @@ import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper;
11 import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants; 11 import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants;
12 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; 12 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
13 import org.springframework.stereotype.Service; 13 import org.springframework.stereotype.Service;
  14 +import org.springframework.transaction.annotation.Transactional;
14 import org.springframework.validation.annotation.Validated; 15 import org.springframework.validation.annotation.Validated;
15 16
16 import javax.annotation.Resource; 17 import javax.annotation.Resource;
@@ -89,14 +90,16 @@ public class ProductSkuServiceImpl implements ProductSkuService { @@ -89,14 +90,16 @@ public class ProductSkuServiceImpl implements ProductSkuService {
89 } 90 }
90 91
91 // TODO @franky:这个方法,貌似实现的还是有点问题哈。例如说,throw 异常,后面还执行逻辑~ 92 // TODO @franky:这个方法,貌似实现的还是有点问题哈。例如说,throw 异常,后面还执行逻辑~
  93 + // TODO @艿艿 咳咳,throw 那里我是偷懒省略了{},哈哈,我加上,然后我调试下,在优化下
92 @Override 94 @Override
93 public void validateSkus(List<ProductSkuCreateReqVO> list) { 95 public void validateSkus(List<ProductSkuCreateReqVO> list) {
94 List<ProductSkuBaseVO.Property> skuPropertyList = list.stream().flatMap(p -> p.getProperties().stream()).collect(Collectors.toList()); 96 List<ProductSkuBaseVO.Property> skuPropertyList = list.stream().flatMap(p -> p.getProperties().stream()).collect(Collectors.toList());
95 // 校验规格属性以及规格值是否存在 97 // 校验规格属性以及规格值是否存在
96 List<Long> propertyIds = skuPropertyList.stream().map(ProductSkuBaseVO.Property::getPropertyId).collect(Collectors.toList()); 98 List<Long> propertyIds = skuPropertyList.stream().map(ProductSkuBaseVO.Property::getPropertyId).collect(Collectors.toList());
97 List<ProductPropertyRespVO> propertyAndValueList = productPropertyService.selectByIds(propertyIds); 99 List<ProductPropertyRespVO> propertyAndValueList = productPropertyService.selectByIds(propertyIds);
98 - if (propertyAndValueList.isEmpty()) 100 + if (propertyAndValueList.isEmpty()) {
99 throw ServiceExceptionUtil.exception(PROPERTY_NOT_EXISTS); 101 throw ServiceExceptionUtil.exception(PROPERTY_NOT_EXISTS);
  102 + }
100 Map<Long, ProductPropertyRespVO> propertyMap = propertyAndValueList.stream().collect(Collectors.toMap(ProductPropertyRespVO::getId, p -> p)); 103 Map<Long, ProductPropertyRespVO> propertyMap = propertyAndValueList.stream().collect(Collectors.toMap(ProductPropertyRespVO::getId, p -> p));
101 skuPropertyList.forEach(p -> { 104 skuPropertyList.forEach(p -> {
102 ProductPropertyRespVO productPropertyRespVO = propertyMap.get(p.getPropertyId()); 105 ProductPropertyRespVO productPropertyRespVO = propertyMap.get(p.getPropertyId());
@@ -126,6 +129,55 @@ public class ProductSkuServiceImpl implements ProductSkuService { @@ -126,6 +129,55 @@ public class ProductSkuServiceImpl implements ProductSkuService {
126 129
127 @Override 130 @Override
128 public List<ProductSkuDO> getSkusBySpuId(Long spuId) { 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,7 +57,7 @@ public interface ProductSpuService {
57 * @param pageReqVO 分页查询 57 * @param pageReqVO 分页查询
58 * @return 商品spu分页 58 * @return 商品spu分页
59 */ 59 */
60 - PageResult<ProductSpuDO> getSpuPage(SpuPageReqVO pageReqVO); 60 + PageResult<SpuRespVO> getSpuPage(SpuPageReqVO pageReqVO);
61 61
62 /** 62 /**
63 * 获得商品spu列表, 用于 Excel 导出 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,6 +7,7 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
7 import cn.iocoder.yudao.module.product.service.category.CategoryService; 7 import cn.iocoder.yudao.module.product.service.category.CategoryService;
8 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; 8 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
9 import org.springframework.stereotype.Service; 9 import org.springframework.stereotype.Service;
  10 +
10 import javax.annotation.Resource; 11 import javax.annotation.Resource;
11 import javax.validation.Valid; 12 import javax.validation.Valid;
12 13
@@ -67,20 +68,31 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -67,20 +68,31 @@ public class ProductSpuServiceImpl implements ProductSpuService {
67 } 68 }
68 69
69 @Override 70 @Override
  71 + @Transactional
70 public void updateSpu(SpuUpdateReqVO updateReqVO) { 72 public void updateSpu(SpuUpdateReqVO updateReqVO) {
71 - // 校验存在 73 + // 校验 spu 是否存在
72 this.validateSpuExists(updateReqVO.getId()); 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 ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO); 81 ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO);
75 ProductSpuMapper.updateById(updateObj); 82 ProductSpuMapper.updateById(updateObj);
  83 + // 更新 sku
  84 + productSkuService.updateSkus(updateObj.getId(), updateReqVO.getSkus());
76 } 85 }
77 86
78 @Override 87 @Override
  88 + @Transactional
79 public void deleteSpu(Long id) { 89 public void deleteSpu(Long id) {
80 // 校验存在 90 // 校验存在
81 this.validateSpuExists(id); 91 this.validateSpuExists(id);
82 - // 删除 92 + // 删除 SPU
83 ProductSpuMapper.deleteById(id); 93 ProductSpuMapper.deleteById(id);
  94 + // 删除关联的 SKU
  95 + productSkuService.deleteSkuBySpuId(id);
84 } 96 }
85 97
86 private void validateSpuExists(Long id) { 98 private void validateSpuExists(Long id) {
@@ -93,8 +105,10 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -93,8 +105,10 @@ public class ProductSpuServiceImpl implements ProductSpuService {
93 public SpuRespVO getSpu(Long id) { 105 public SpuRespVO getSpu(Long id) {
94 ProductSpuDO spu = ProductSpuMapper.selectById(id); 106 ProductSpuDO spu = ProductSpuMapper.selectById(id);
95 SpuRespVO spuVO = ProductSpuConvert.INSTANCE.convert(spu); 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 return spuVO; 112 return spuVO;
99 } 113 }
100 114
@@ -104,8 +118,17 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -104,8 +118,17 @@ public class ProductSpuServiceImpl implements ProductSpuService {
104 } 118 }
105 119
106 @Override 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 @Override 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,7 +159,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
159 reqVO.setEndCreateTime(null); 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 assertEquals(1, pageResult.getTotal()); 164 assertEquals(1, pageResult.getTotal());
165 assertEquals(1, pageResult.getList().size()); 165 assertEquals(1, pageResult.getList().size());