商品更新接口

This commit is contained in:
YunaiV 2019-03-05 21:14:23 +08:00
parent 1c134a20ef
commit ce044f1bb5
8 changed files with 154 additions and 6 deletions

View File

@ -14,4 +14,6 @@ public interface ProductSpuService {
CommonResult<Boolean> updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO);
}

View File

@ -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, "商品属性值不存在"),

View File

@ -34,7 +34,7 @@ public class ProductSpuUpdateDTO {
/**
* 分类编号
*/
@NotEmpty(message = "分类不能为空")
@NotNull(message = "分类不能为空")
private Integer cid;
/**
* 商品主图地址

View File

@ -11,6 +11,13 @@ public interface ProductSkuMapper {
ProductSkuDO selectById(Integer id);
List<ProductSkuDO> selectListBySpuIdAndStatus(@Param("spuId") Integer spuId,
@Param("status") Integer status);
void insertList(@Param("productSkuDOs") List<ProductSkuDO> productSkuDOs);
int update(ProductSkuDO productSkuDO);
int updateToDeleted(@Param("ids") List<Integer> ids);
}

View File

@ -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<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());
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<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 规格
return CommonResult.success(true);
}
@ -140,4 +185,19 @@ public class ProductSpuServiceImpl implements ProductSpuService {
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;
}
}

View File

@ -2,11 +2,17 @@
<!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">
<sql id="FIELDS">
id, spu_id, status, pic_url, attrs,
price, quantity, create_time
</sql>
<select id="selectById" parameterType="Integer" resultType="ProductSkuDO">
SELECT
id
<include refid="FIELDS" />
FROM product_sku
WHERE id = #{id}
AND delete = 0
</select>
<insert id="insertList" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
@ -21,4 +27,50 @@
</foreach>
</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>

View File

@ -19,8 +19,35 @@
)
</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>
</mapper>