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