Commit 77a676ee07c181027eab6ddb59dbecad949069a8

Authored by luowenfeng
1 parent fdb2d733

feature(管理后台): 商品列表

yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java
1 package cn.iocoder.yudao.module.product.service.category; 1 package cn.iocoder.yudao.module.product.service.category;
2 2
3 -import cn.hutool.core.util.ObjectUtil;  
4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; 4 import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO;
6 import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; 5 import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
@@ -93,33 +92,20 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { @@ -93,33 +92,20 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
93 92
94 @Override 93 @Override
95 public void validateCategoryLevel(Long id) { 94 public void validateCategoryLevel(Long id) {
96 - Integer level = getProductCategoryLevel(id, 1);  
97 - if (level < 3){  
98 - throw exception(CATEGORY_LEVEL_ERROR); 95 + Long parentId = id;
  96 + for (int i = 0; i < 3; i++) {
  97 + if (Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL)) {
  98 + throw exception(CATEGORY_LEVEL_ERROR);
  99 + }
  100 + ProductCategoryDO category = productCategoryMapper.selectById(parentId);
  101 + if (category == null) {
  102 + throw exception(CATEGORY_NOT_EXISTS);
  103 + }
  104 + parentId = category.getParentId();
99 } 105 }
100 - }  
101 -  
102 - // TODO @Luowenfeng:建议使用 for 循环,避免递归  
103 - /**  
104 - * 获得商品分类的级别  
105 - *  
106 - * @param id 商品分类的编号  
107 - * @return 级别  
108 - */  
109 - private Integer getProductCategoryLevel(Long id, int level){  
110 - ProductCategoryDO category = productCategoryMapper.selectById(id);  
111 - if (category == null) {  
112 - throw exception(CATEGORY_NOT_EXISTS);  
113 - }  
114 - // TODO Luowenfeng:去掉是否开启,它不影响级别哈  
115 - if (ObjectUtil.notEqual(category.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {  
116 - throw exception(CATEGORY_DISABLED);  
117 - }  
118 - // TODO Luowenfeng:不使用 0 直接比较哈,使用枚举  
119 - if (category.getParentId() == 0) {  
120 - return level; 106 + if (!Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL)) {
  107 + throw exception(CATEGORY_LEVEL_ERROR);
121 } 108 }
122 - return getProductCategoryLevel(category.getParentId(), ++level);  
123 } 109 }
124 110
125 @Override 111 @Override
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
@@ -144,36 +144,52 @@ public class ProductSkuServiceImpl implements ProductSkuService { @@ -144,36 +144,52 @@ public class ProductSkuServiceImpl implements ProductSkuService {
144 public void updateProductSkus(Long spuId, List<ProductSkuCreateOrUpdateReqVO> skus) { 144 public void updateProductSkus(Long spuId, List<ProductSkuCreateOrUpdateReqVO> skus) {
145 // 查询 SPU 下已经存在的 SKU 的集合 145 // 查询 SPU 下已经存在的 SKU 的集合
146 List<ProductSkuDO> existsSkus = productSkuMapper.selectListBySpuId(spuId); 146 List<ProductSkuDO> existsSkus = productSkuMapper.selectListBySpuId(spuId);
147 - Map<Long, ProductSkuDO> existsSkuMap = CollectionUtils.convertMap(existsSkus, ProductSkuDO::getId); 147 +
  148 + Map<String, Long> existsSkuMap = existsSkus.stream()
  149 + .map(v -> {
  150 + String collect = v.getProperties() == null? "null": v.getProperties()
  151 + .stream()
  152 + .map(m -> String.valueOf(m.getValueId()))
  153 + .collect(Collectors.joining());
  154 + return String.join("-", collect, String.valueOf(v.getId()));
  155 + })
  156 + .collect(Collectors.toMap(v -> v.split("-")[0], v -> Long.valueOf(v.split("-")[1])));
  157 +
148 158
149 // 拆分三个集合,新插入的、需要更新的、需要删除的 159 // 拆分三个集合,新插入的、需要更新的、需要删除的
150 List<ProductSkuDO> insertSkus = new ArrayList<>(); 160 List<ProductSkuDO> insertSkus = new ArrayList<>();
151 - List<ProductSkuDO> updateSkus = new ArrayList<>(); // TODO Luowenfeng:使用 Long 即可  
152 - List<ProductSkuDO> deleteSkus = new ArrayList<>(); 161 + List<ProductSkuDO> updateSkus = new ArrayList<>();
  162 + List<Long> deleteSkus = new ArrayList<>();
153 163
154 - // TODO @Luowenfeng:是不是基于规格匹配会比较好。可以参考下 onemall 的 ProductSpuServiceImpl 的 updateProductSpu 逻辑  
155 List<ProductSkuDO> allUpdateSkus = ProductSkuConvert.INSTANCE.convertSkuDOList(skus); 164 List<ProductSkuDO> allUpdateSkus = ProductSkuConvert.INSTANCE.convertSkuDOList(skus);
156 allUpdateSkus.forEach(p -> { 165 allUpdateSkus.forEach(p -> {
157 - if (p.getId() != null) {  
158 - if (existsSkuMap.containsKey(p.getId())) {  
159 - updateSkus.add(p);  
160 - return;  
161 - }  
162 - deleteSkus.add(p); 166 + String propertiesKey = p.getProperties() == null? "null": p.getProperties().stream().map(m -> String.valueOf(m.getValueId())).collect(Collectors.joining());
  167 + // 1、找得到的,进行更新
  168 + if (existsSkuMap.containsKey(propertiesKey)) {
  169 + updateSkus.add(p);
  170 + existsSkuMap.remove(propertiesKey);
163 return; 171 return;
164 } 172 }
  173 + // 2、找不到,进行插入
165 p.setSpuId(spuId); 174 p.setSpuId(spuId);
166 insertSkus.add(p); 175 insertSkus.add(p);
167 }); 176 });
  177 + // 3、多余的,删除
  178 + if(!existsSkuMap.isEmpty()){
  179 + deleteSkus = new ArrayList<>(existsSkuMap.values());
  180 + }
168 181
169 - if (CollectionUtil.isNotEmpty(insertSkus)) { 182 + // 4、执行修改 Sku
  183 + if (!insertSkus.isEmpty()) {
170 productSkuMapper.insertBatch(insertSkus); 184 productSkuMapper.insertBatch(insertSkus);
171 } 185 }
172 - if (updateSkus.size() > 0) { 186 + if (!updateSkus.isEmpty()) {
173 updateSkus.forEach(p -> productSkuMapper.updateById(p)); 187 updateSkus.forEach(p -> productSkuMapper.updateById(p));
174 } 188 }
175 - if (deleteSkus.size() > 0) {  
176 - productSkuMapper.deleteBatchIds(deleteSkus.stream().map(ProductSkuDO::getId).collect(Collectors.toList())); 189 + if (!deleteSkus.isEmpty()) {
  190 + productSkuMapper.deleteBatchIds(deleteSkus);
177 } 191 }
178 } 192 }
  193 +
  194 +
179 } 195 }
yudao-ui-admin/src/views/mall/product/spu/save.vue
@@ -361,7 +361,7 @@ export default { @@ -361,7 +361,7 @@ export default {
361 if (!valid) { 361 if (!valid) {
362 return; 362 return;
363 } 363 }
364 - let rates = this.ratesForm.rates; 364 + let rates = JSON.parse(JSON.stringify(this.ratesForm.rates));
365 365
366 // 价格元转分 366 // 价格元转分
367 rates.forEach(r => { 367 rates.forEach(r => {