|
@@ -1,12 +1,9 @@
|
|
|
package cn.iocoder.yudao.module.product.service.spu;
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
-import cn.hutool.core.convert.Convert;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
|
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
|
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|
|
-import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
|
|
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
|
|
|
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
|
|
|
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
|
@@ -23,7 +20,6 @@ import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
|
|
|
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
|
|
|
import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
|
|
|
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
|
|
|
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import org.springframework.context.annotation.Lazy;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
@@ -34,7 +30,7 @@ import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
|
|
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
|
|
|
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
|
|
|
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR;
|
|
|
|
|
@@ -63,17 +59,18 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public Long createSpu(ProductSpuCreateReqVO createReqVO) {
|
|
|
- // 校验分类 TODO 暂不清楚为什么只能选择第三层的结点
|
|
|
+ // 校验分类 TODO puhui999:暂不清楚为什么只能选择第三层的结点;芋艿:改成二级分类,因为商品只能放在叶子节点级别;
|
|
|
//validateCategory(createReqVO.getCategoryId());
|
|
|
- // 校验品牌 TODO 暂不校验,前端没有做品牌选择
|
|
|
+ // 校验品牌 TODO puhui999:暂不校验,前端没有做品牌选择;芋艿:可以加下哈
|
|
|
//brandService.validateProductBrand(createReqVO.getBrandId());
|
|
|
|
|
|
List<ProductSkuCreateOrUpdateReqVO> skuSaveReqList = createReqVO.getSkus();
|
|
|
- // 校验SKU
|
|
|
+ // 校验 SKU
|
|
|
productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType());
|
|
|
ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO);
|
|
|
- // 初始化SPU中SKU相关属性
|
|
|
+ // 初始化 SPU 中 SKU 相关属性
|
|
|
initSpuFromSkus(spu, skuSaveReqList);
|
|
|
+
|
|
|
// 插入 SPU
|
|
|
productSpuMapper.insert(spu);
|
|
|
// 插入 SKU
|
|
@@ -193,6 +190,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|
|
stockIncrCounts.forEach((id, incCount) -> productSpuMapper.updateStock(id, incCount));
|
|
|
}
|
|
|
|
|
|
+ // TODO @puhui999:Service 尽量不做一些跟 VO 相关的拼接逻辑,目的是让 Service 更加简洁一点哈。
|
|
|
@Override
|
|
|
public ProductSpuDetailRespVO getSpuDetail(Long id) {
|
|
|
// 获得商品 SPU
|
|
@@ -204,12 +202,17 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|
|
// 查询商品 SKU
|
|
|
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
|
|
|
if (CollUtil.isNotEmpty(skus)){
|
|
|
+ // TODO @puhui999:skuVOs 更简洁一点。然后大小写要注释哈。RespVOs;因为 VO 是缩写,s 是复数
|
|
|
List<ProductSkuRespVO> skuRespVoS = ProductSkuConvert.INSTANCE.convertList(skus);
|
|
|
// 非多规格,不需要处理
|
|
|
+ // TODO @puhui999:统一模型,即使是单规格,也查询下,问题不大的
|
|
|
if (ObjectUtil.equal(productSpuDetailRespVO.getSpecType(), true)) {
|
|
|
- // 获取所有的属性值id
|
|
|
- Set<Long> valueIds = skus.stream().flatMap(p -> p.getProperties().stream()).map(ProductSkuDO.Property::getValueId).collect(Collectors.toSet());
|
|
|
+ // 获取所有的属性值 id
|
|
|
+ Set<Long> valueIds = skus.stream().flatMap(p -> p.getProperties().stream())
|
|
|
+ .map(ProductSkuDO.Property::getValueId)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
List<ProductPropertyValueDetailRespBO> valueDetailList = productPropertyValueService.getPropertyValueDetailList(valueIds);
|
|
|
+ // TODO @puhui999:拼接的逻辑,最好查询好后,丢到 convert 里面统一处理;这样 Service or Controller 也可以更简洁;原则上,Controller 去组合;Service 写逻辑;Convert 转换
|
|
|
Map<Long, String> stringMap = valueDetailList.stream().collect(Collectors.toMap(ProductPropertyValueDetailRespBO::getValueId, ProductPropertyValueDetailRespBO::getValueName));
|
|
|
// 设置属性值名称
|
|
|
skuRespVoS.stream().flatMap(p -> p.getProperties().stream()).forEach(item ->item.setValueName(stringMap.get(item.getValueId())));
|
|
@@ -232,6 +235,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|
|
|
|
|
@Override
|
|
|
public Map<Integer, Long> getTabsCount() {
|
|
|
+ // TODO @puhui999:map =》counts;尽量避免出现 map 这种命名,无命名含义哈
|
|
|
Map<Integer, Long> map = new HashMap<>();
|
|
|
// 查询销售中的商品数量
|
|
|
map.put(ProductSpuTabTypeEnum.FOR_SALE.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()));
|
|
@@ -240,6 +244,8 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|
|
// 查询售空的商品数量
|
|
|
map.put(ProductSpuTabTypeEnum.SOLD_OUT.getType(),productSpuMapper.selectCount(ProductSpuDO::getStock, 0));
|
|
|
// 查询触发警戒库存的商品数量 TODO 警戒库存暂时为 10,后期需要使用常量或者数据库配置替换
|
|
|
+ // TODO @puhui999:要有空格;, productSpuMapper
|
|
|
+ // TODO @puhui999:Service 不要有 Mapper 的逻辑;想想咋抽象一下哈
|
|
|
map.put(ProductSpuTabTypeEnum.ALERT_STOCK.getType(),productSpuMapper.selectCount(new LambdaQueryWrapperX<ProductSpuDO>().le(ProductSpuDO::getStock, 10)));
|
|
|
// 查询回收站中的商品数量
|
|
|
map.put(ProductSpuTabTypeEnum.RECYCLE_BIN.getType(),productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()));
|