Merge remote-tracking branch 'origin/master'
						commit
						a9168ec6ac
					
				| 
						 | 
					@ -14,4 +14,6 @@ public interface ProductSpuService {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CommonResult<Boolean> updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO);
 | 
					    CommonResult<Boolean> updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,7 @@ public enum ProductErrorCodeEnum {
 | 
				
			||||||
    PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE(1003002000, "一个 Sku 下,不能有重复的规格"),
 | 
					    PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE(1003002000, "一个 Sku 下,不能有重复的规格"),
 | 
				
			||||||
    PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS(1003002001, "一个 Spu 下的每个 Sku ,其规格数必须一致"),
 | 
					    PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS(1003002001, "一个 Spu 下的每个 Sku ,其规格数必须一致"),
 | 
				
			||||||
    PRODUCT_SPU_SKU__NOT_DUPLICATE(1003002002, "一个 Spu 下的每个 Sku ,必须不重复"),
 | 
					    PRODUCT_SPU_SKU__NOT_DUPLICATE(1003002002, "一个 Spu 下的每个 Sku ,必须不重复"),
 | 
				
			||||||
 | 
					    PRODUCT_SPU_NOT_EXISTS(1003002003, "Spu 不存在"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // ========== PRODUCT ATTR + ATTR_VALUE 模块 ==========
 | 
					    // ========== PRODUCT ATTR + ATTR_VALUE 模块 ==========
 | 
				
			||||||
    PRODUCT_ATTR_VALUE_NOT_EXIST(1003003000, "商品属性值不存在"),
 | 
					    PRODUCT_ATTR_VALUE_NOT_EXIST(1003003000, "商品属性值不存在"),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,7 @@ public class ProductSpuUpdateDTO {
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 分类编号
 | 
					     * 分类编号
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @NotEmpty(message = "分类不能为空")
 | 
					    @NotNull(message = "分类不能为空")
 | 
				
			||||||
    private Integer cid;
 | 
					    private Integer cid;
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 商品主图地址
 | 
					     * 商品主图地址
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,13 @@ public interface ProductSkuMapper {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ProductSkuDO selectById(Integer id);
 | 
					    ProductSkuDO selectById(Integer id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    List<ProductSkuDO> selectListBySpuIdAndStatus(@Param("spuId") Integer spuId,
 | 
				
			||||||
 | 
					                                                  @Param("status") Integer status);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void insertList(@Param("productSkuDOs") List<ProductSkuDO> productSkuDOs);
 | 
					    void insertList(@Param("productSkuDOs") List<ProductSkuDO> productSkuDOs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int update(ProductSkuDO productSkuDO);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int updateToDeleted(@Param("ids") List<Integer> ids);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
package cn.iocoder.mall.product.service;
 | 
					package cn.iocoder.mall.product.service;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import cn.iocoder.common.framework.dataobject.BaseDO;
 | 
					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.ServiceExceptionUtil;
 | 
				
			||||||
import cn.iocoder.common.framework.util.StringUtil;
 | 
					import cn.iocoder.common.framework.util.StringUtil;
 | 
				
			||||||
import cn.iocoder.common.framework.vo.CommonResult;
 | 
					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.ProductErrorCodeEnum;
 | 
				
			||||||
import cn.iocoder.mall.product.api.constant.ProductSpuConstants;
 | 
					import cn.iocoder.mall.product.api.constant.ProductSpuConstants;
 | 
				
			||||||
import cn.iocoder.mall.product.api.dto.ProductSkuAddDTO;
 | 
					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.ProductSpuAddDTO;
 | 
				
			||||||
import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO;
 | 
					import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO;
 | 
				
			||||||
import cn.iocoder.mall.product.convert.ProductSpuConvert;
 | 
					import cn.iocoder.mall.product.convert.ProductSpuConvert;
 | 
				
			||||||
| 
						 | 
					@ -90,7 +92,12 @@ public class ProductSpuServiceImpl implements ProductSpuService {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @SuppressWarnings("Duplicates")
 | 
					    @SuppressWarnings("Duplicates")
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
 | 
					    @Transactional
 | 
				
			||||||
    public CommonResult<Boolean> updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) {
 | 
					    public CommonResult<Boolean> updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) {
 | 
				
			||||||
 | 
					        // 校验 Spu 是否存在
 | 
				
			||||||
 | 
					        if (productSpuMapper.selectById(productSpuUpdateDTO.getId()) == null) {
 | 
				
			||||||
 | 
					            return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        // 校验商品分类分类存在
 | 
					        // 校验商品分类分类存在
 | 
				
			||||||
        CommonResult<ProductCategoryDO> validCategoryResult = productCategoryService.validProductCategory(productSpuUpdateDTO.getCid());
 | 
					        CommonResult<ProductCategoryDO> validCategoryResult = productCategoryService.validProductCategory(productSpuUpdateDTO.getCid());
 | 
				
			||||||
        if (validCategoryResult.isError()) {
 | 
					        if (validCategoryResult.isError()) {
 | 
				
			||||||
| 
						 | 
					@ -107,6 +114,44 @@ public class ProductSpuServiceImpl implements ProductSpuService {
 | 
				
			||||||
        ProductSpuDO updateSpu = ProductSpuConvert.INSTANCE.convert(productSpuUpdateDTO)
 | 
					        ProductSpuDO updateSpu = ProductSpuConvert.INSTANCE.convert(productSpuUpdateDTO)
 | 
				
			||||||
                .setPicUrls(StringUtil.join(productSpuUpdateDTO.getPicUrls(), ","));
 | 
					                .setPicUrls(StringUtil.join(productSpuUpdateDTO.getPicUrls(), ","));
 | 
				
			||||||
        productSpuMapper.update(updateSpu);
 | 
					        productSpuMapper.update(updateSpu);
 | 
				
			||||||
 | 
					        // 修改 Sku
 | 
				
			||||||
 | 
					        List<ProductSkuDO> existsSkus = productSkuMapper.selectListBySpuIdAndStatus(productSpuUpdateDTO.getId(), ProductSpuConstants.SKU_STATUS_ENABLE);
 | 
				
			||||||
 | 
					        List<ProductSkuDO> insertSkus = new ArrayList<>(0); // 1、找不到,进行插入
 | 
				
			||||||
 | 
					        List<Integer> deleteSkus = new ArrayList<>(0); // 2、多余的,删除
 | 
				
			||||||
 | 
					        List<ProductSkuDO> 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 规格
 | 
					        // 校验 Sku 规格
 | 
				
			||||||
        return CommonResult.success(true);
 | 
					        return CommonResult.success(true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -140,4 +185,19 @@ public class ProductSpuServiceImpl implements ProductSpuService {
 | 
				
			||||||
        return CommonResult.success(true);
 | 
					        return CommonResult.success(true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private ProductSkuDO findProductSku(Collection<Integer> attrs, List<ProductSkuDO> skus) {
 | 
				
			||||||
 | 
					        if (CollectionUtil.isEmpty(skus)) {
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 创建成 Set ,方便后面比较
 | 
				
			||||||
 | 
					        attrs = new HashSet<>(attrs);
 | 
				
			||||||
 | 
					        for (ProductSkuDO sku : skus) {
 | 
				
			||||||
 | 
					            Set<Integer> skuAttrs = StringUtil.split(sku.getAttrs(), ",").stream().map(Integer::parseInt).collect(Collectors.toSet());
 | 
				
			||||||
 | 
					            if (attrs.equals(skuAttrs)) {
 | 
				
			||||||
 | 
					                return sku;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2,11 +2,17 @@
 | 
				
			||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 | 
					<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 | 
				
			||||||
<mapper namespace="cn.iocoder.mall.product.dao.ProductSkuMapper">
 | 
					<mapper namespace="cn.iocoder.mall.product.dao.ProductSkuMapper">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <sql id="FIELDS">
 | 
				
			||||||
 | 
					        id, spu_id, status, pic_url, attrs,
 | 
				
			||||||
 | 
					        price, quantity, create_time
 | 
				
			||||||
 | 
					    </sql>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <select id="selectById" parameterType="Integer" resultType="ProductSkuDO">
 | 
					    <select id="selectById" parameterType="Integer" resultType="ProductSkuDO">
 | 
				
			||||||
        SELECT
 | 
					        SELECT
 | 
				
			||||||
          id
 | 
					            <include refid="FIELDS" />
 | 
				
			||||||
        FROM product_sku
 | 
					        FROM product_sku
 | 
				
			||||||
        WHERE id = #{id}
 | 
					        WHERE id = #{id}
 | 
				
			||||||
 | 
					        AND delete = 0
 | 
				
			||||||
    </select>
 | 
					    </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <insert id="insertList" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
 | 
					    <insert id="insertList" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
 | 
				
			||||||
| 
						 | 
					@ -21,4 +27,50 @@
 | 
				
			||||||
        </foreach>
 | 
					        </foreach>
 | 
				
			||||||
    </insert>
 | 
					    </insert>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <select id="selectListBySpuIdAndStatus" resultType="ProductSkuDO">
 | 
				
			||||||
 | 
					      SELECT
 | 
				
			||||||
 | 
					          <include refid="FIELDS" />
 | 
				
			||||||
 | 
					      FROM product_sku
 | 
				
			||||||
 | 
					      WHERE spu_id = #{spuId}
 | 
				
			||||||
 | 
					      AND status = #{status}
 | 
				
			||||||
 | 
					      AND deleted = 0
 | 
				
			||||||
 | 
					    </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <update id="update" parameterType="ProductSpuDO">
 | 
				
			||||||
 | 
					        UPDATE product_sku
 | 
				
			||||||
 | 
					        <set>
 | 
				
			||||||
 | 
					            <if test="spuId != null">
 | 
				
			||||||
 | 
					                spu_id = #{spuId},
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					            <if test="status != null">
 | 
				
			||||||
 | 
					                status = #{status},
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					            <if test="picUrl != null">
 | 
				
			||||||
 | 
					                pic_url = #{picUrl},
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					            <if test="attrs != null">
 | 
				
			||||||
 | 
					                attrs = #{attrs},
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					            <if test="price != null">
 | 
				
			||||||
 | 
					                price = #{price},
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					            <if test="quantity != null">
 | 
				
			||||||
 | 
					                quantity = #{quantity},
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					            <if test="deleted != null">
 | 
				
			||||||
 | 
					                deleted = #{deleted}
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					        </set>
 | 
				
			||||||
 | 
					        WHERE id = #{id}
 | 
				
			||||||
 | 
					    </update>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <update id="updateToDeleted" parameterType="Integer">
 | 
				
			||||||
 | 
					        UPDATE product_sku
 | 
				
			||||||
 | 
					        SET deleted = 1
 | 
				
			||||||
 | 
					        WHERE id IN
 | 
				
			||||||
 | 
					            <foreach item="id" collection="ids" separator="," open="(" close=")" index="">
 | 
				
			||||||
 | 
					                #{id}
 | 
				
			||||||
 | 
					            </foreach>
 | 
				
			||||||
 | 
					    </update>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</mapper>
 | 
					</mapper>
 | 
				
			||||||
| 
						 | 
					@ -19,8 +19,35 @@
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    </insert>
 | 
					    </insert>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <update id="update">
 | 
					    <update id="update" parameterType="ProductSpuDO">
 | 
				
			||||||
 | 
					        UPDATE product_spu
 | 
				
			||||||
 | 
					        <set>
 | 
				
			||||||
 | 
					            <if test="name != null">
 | 
				
			||||||
 | 
					                name = #{name},
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					            <if test="sellPoint != null">
 | 
				
			||||||
 | 
					                sell_point = #{sellPoint},
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					            <if test="description != null">
 | 
				
			||||||
 | 
					                description = #{description},
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					            <if test="cid != null">
 | 
				
			||||||
 | 
					                cid = #{cid},
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					            <if test="picUrls != null">
 | 
				
			||||||
 | 
					                pic_urls = #{picUrls},
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					            <if test="visible != null">
 | 
				
			||||||
 | 
					                visible = #{visible},
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					            <if test="sort != null">
 | 
				
			||||||
 | 
					                sort = #{sort},
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					            <if test="deleted != null">
 | 
				
			||||||
 | 
					                deleted = #{deleted}
 | 
				
			||||||
 | 
					            </if>
 | 
				
			||||||
 | 
					        </set>
 | 
				
			||||||
 | 
					        WHERE id = #{id}
 | 
				
			||||||
    </update>
 | 
					    </update>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</mapper>
 | 
					</mapper>
 | 
				
			||||||
		Loading…
	
		Reference in New Issue