diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java index 047c3b788..17256f3d6 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java @@ -14,4 +14,6 @@ public interface ProductSpuService { CommonResult updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO); + + } diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/constant/ProductErrorCodeEnum.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/constant/ProductErrorCodeEnum.java index 4808658a3..122cd2e54 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/constant/ProductErrorCodeEnum.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/constant/ProductErrorCodeEnum.java @@ -19,7 +19,7 @@ public enum ProductErrorCodeEnum { PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE(1003002000, "一个 Sku 下,不能有重复的规格"), PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS(1003002001, "一个 Spu 下的每个 Sku ,其规格数必须一致"), PRODUCT_SPU_SKU__NOT_DUPLICATE(1003002002, "一个 Spu 下的每个 Sku ,必须不重复"), - + PRODUCT_SPU_NOT_EXISTS(1003002003, "Spu 不存在"), // ========== PRODUCT ATTR + ATTR_VALUE 模块 ========== PRODUCT_ATTR_VALUE_NOT_EXIST(1003003000, "商品属性值不存在"), diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuUpdateDTO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuUpdateDTO.java index 07566ae2d..4021f7fb0 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuUpdateDTO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuUpdateDTO.java @@ -34,7 +34,7 @@ public class ProductSpuUpdateDTO { /** * 分类编号 */ - @NotEmpty(message = "分类不能为空") + @NotNull(message = "分类不能为空") private Integer cid; /** * 商品主图地址 diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSkuMapper.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSkuMapper.java index 936161507..2069e02f7 100644 --- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSkuMapper.java +++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSkuMapper.java @@ -11,6 +11,13 @@ public interface ProductSkuMapper { ProductSkuDO selectById(Integer id); + List selectListBySpuIdAndStatus(@Param("spuId") Integer spuId, + @Param("status") Integer status); + void insertList(@Param("productSkuDOs") List productSkuDOs); + int update(ProductSkuDO productSkuDO); + + int updateToDeleted(@Param("ids") List ids); + } \ No newline at end of file diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dataobject/ProductSkuDO.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dataobject/ProductSkuDO.java index 6ee66af63..8ab2d4c4b 100644 --- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dataobject/ProductSkuDO.java +++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dataobject/ProductSkuDO.java @@ -43,7 +43,7 @@ public class ProductSkuDO extends BaseDO { * 库存数量 */ private Integer quantity; - // /** +// /** // * 商品在付款减库存的状态下,该Sku上未付款的订单数量 // */ // private Integer withHoldQuantity; diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java index 1892f8a04..9bf868b21 100644 --- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java +++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.mall.product.service; import cn.iocoder.common.framework.dataobject.BaseDO; +import cn.iocoder.common.framework.util.CollectionUtil; import cn.iocoder.common.framework.util.ServiceExceptionUtil; import cn.iocoder.common.framework.util.StringUtil; import cn.iocoder.common.framework.vo.CommonResult; @@ -11,6 +12,7 @@ import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO; import cn.iocoder.mall.product.api.constant.ProductErrorCodeEnum; import cn.iocoder.mall.product.api.constant.ProductSpuConstants; import cn.iocoder.mall.product.api.dto.ProductSkuAddDTO; +import cn.iocoder.mall.product.api.dto.ProductSkuUpdateDTO; import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO; import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO; import cn.iocoder.mall.product.convert.ProductSpuConvert; @@ -90,7 +92,12 @@ public class ProductSpuServiceImpl implements ProductSpuService { @SuppressWarnings("Duplicates") @Override + @Transactional public CommonResult updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) { + // 校验 Spu 是否存在 + if (productSpuMapper.selectById(productSpuUpdateDTO.getId()) == null) { + return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode()); + } // 校验商品分类分类存在 CommonResult validCategoryResult = productCategoryService.validProductCategory(productSpuUpdateDTO.getCid()); if (validCategoryResult.isError()) { @@ -107,6 +114,44 @@ public class ProductSpuServiceImpl implements ProductSpuService { ProductSpuDO updateSpu = ProductSpuConvert.INSTANCE.convert(productSpuUpdateDTO) .setPicUrls(StringUtil.join(productSpuUpdateDTO.getPicUrls(), ",")); productSpuMapper.update(updateSpu); + // 修改 Sku + List existsSkus = productSkuMapper.selectListBySpuIdAndStatus(productSpuUpdateDTO.getId(), ProductSpuConstants.SKU_STATUS_ENABLE); + List insertSkus = new ArrayList<>(0); // 1、找不到,进行插入 + List deleteSkus = new ArrayList<>(0); // 2、多余的,删除 + List updateSkus = new ArrayList<>(0); // 3、找的到,进行更新。 + for (ProductSkuUpdateDTO skuUpdateDTO : productSpuUpdateDTO.getSkus()) { + ProductSkuDO existsSku = findProductSku(skuUpdateDTO.getAttrs(), existsSkus); + // 3、找的到,进行更新。 + if (existsSku != null) { + // 移除 + existsSkus.remove(existsSku); + // 创建 ProductSkuDO + updateSkus.add(ProductSpuConvert.INSTANCE.convert(skuUpdateDTO).setId(existsSku.getId())); + continue; + } + // 1、找不到,进行插入 + ProductSkuDO insertSku = ProductSpuConvert.INSTANCE.convert(skuUpdateDTO) + .setSpuId(productSpuUpdateDTO.getId()).setStatus(ProductSpuConstants.SKU_STATUS_ENABLE).setAttrs(StringUtil.join(skuUpdateDTO.getAttrs(), ",")); + insertSku.setCreateTime(new Date()).setDeleted(BaseDO.DELETED_NO); + insertSkus.add(insertSku); + } + // 2、多余的,删除 + if (!existsSkus.isEmpty()) { + deleteSkus.addAll(existsSkus.stream().map(ProductSkuDO::getId).collect(Collectors.toList())); + } + // 执行修改 Sku + if (!insertSkus.isEmpty()) { + productSkuMapper.insertList(insertSkus); + } + if (!updateSkus.isEmpty()) { + updateSkus.forEach(productSkuDO -> productSkuMapper.update(productSkuDO)); + } + if (!deleteSkus.isEmpty()) { + productSkuMapper.updateToDeleted(deleteSkus); + } +// if (true) { +// throw new RuntimeException("test"); +// } // 校验 Sku 规格 return CommonResult.success(true); } @@ -140,4 +185,19 @@ public class ProductSpuServiceImpl implements ProductSpuService { return CommonResult.success(true); } + private ProductSkuDO findProductSku(Collection attrs, List skus) { + if (CollectionUtil.isEmpty(skus)) { + return null; + } + // 创建成 Set ,方便后面比较 + attrs = new HashSet<>(attrs); + for (ProductSkuDO sku : skus) { + Set skuAttrs = StringUtil.split(sku.getAttrs(), ",").stream().map(Integer::parseInt).collect(Collectors.toSet()); + if (attrs.equals(skuAttrs)) { + return sku; + } + } + return null; + } + } \ No newline at end of file diff --git a/product/product-service-impl/src/main/resources/mapper/ProductSkuMapper.xml b/product/product-service-impl/src/main/resources/mapper/ProductSkuMapper.xml index 983835d57..ce3c19b08 100644 --- a/product/product-service-impl/src/main/resources/mapper/ProductSkuMapper.xml +++ b/product/product-service-impl/src/main/resources/mapper/ProductSkuMapper.xml @@ -2,11 +2,17 @@ + + id, spu_id, status, pic_url, attrs, + price, quantity, create_time + + @@ -21,4 +27,50 @@ + + + + UPDATE product_sku + + + spu_id = #{spuId}, + + + status = #{status}, + + + pic_url = #{picUrl}, + + + attrs = #{attrs}, + + + price = #{price}, + + + quantity = #{quantity}, + + + deleted = #{deleted} + + + WHERE id = #{id} + + + + UPDATE product_sku + SET deleted = 1 + WHERE id IN + + #{id} + + + \ No newline at end of file diff --git a/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml b/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml index bc2e16f5e..d5b04aa49 100644 --- a/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml +++ b/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml @@ -19,8 +19,35 @@ ) - - + + UPDATE product_spu + + + name = #{name}, + + + sell_point = #{sellPoint}, + + + description = #{description}, + + + cid = #{cid}, + + + pic_urls = #{picUrls}, + + + visible = #{visible}, + + + sort = #{sort}, + + + deleted = #{deleted} + + + WHERE id = #{id} \ No newline at end of file