Merge remote-tracking branch 'origin/master'

This commit is contained in:
sin 2019-03-05 21:20:19 +08:00
commit a9168ec6ac
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); 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_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, "商品属性值不存在"),

View File

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

View File

@ -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);
} }

View File

@ -43,7 +43,7 @@ public class ProductSkuDO extends BaseDO {
* 库存数量 * 库存数量
*/ */
private Integer quantity; private Integer quantity;
// /** // /**
// * 商品在付款减库存的状态下该Sku上未付款的订单数量 // * 商品在付款减库存的状态下该Sku上未付款的订单数量
// */ // */
// private Integer withHoldQuantity; // private Integer withHoldQuantity;

View File

@ -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;
}
} }

View File

@ -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>

View File

@ -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>