商品更新接口

This commit is contained in:
YunaiV 2019-03-05 21:53:49 +08:00
parent be03d101a3
commit 83fdf181b8
9 changed files with 52 additions and 89 deletions

View File

@ -4,8 +4,7 @@ import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder; import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
import cn.iocoder.mall.product.api.ProductSpuService; import cn.iocoder.mall.product.api.ProductSpuService;
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO; import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
import cn.iocoder.mall.product.api.dto.ProductSkuAddDTO; import cn.iocoder.mall.product.api.dto.ProductSkuAddOrUpdateDTO;
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.application.convert.ProductSpuConvert; import cn.iocoder.mall.product.application.convert.ProductSpuConvert;
@ -57,7 +56,7 @@ public class AdminsProductSpuController {
// 创建 ProductSpuAddDTO 对象 // 创建 ProductSpuAddDTO 对象
ProductSpuAddDTO productSpuAddDTO = new ProductSpuAddDTO().setName(name).setSellPoint(sellPoint) ProductSpuAddDTO productSpuAddDTO = new ProductSpuAddDTO().setName(name).setSellPoint(sellPoint)
.setDescription(description).setCid(cid).setPicUrls(picUrls).setVisible(visible) .setDescription(description).setCid(cid).setPicUrls(picUrls).setVisible(visible)
.setSkus(parseSkus(skuStr, ProductSkuAddDTO.class)); .setSkus(parseSkus(skuStr, ProductSkuAddOrUpdateDTO.class));
// 保存商品 // 保存商品
CommonResult<ProductSpuDetailBO> result = productSpuService.addProductSpu(AdminSecurityContextHolder.getContext().getAdminId(), productSpuAddDTO); CommonResult<ProductSpuDetailBO> result = productSpuService.addProductSpu(AdminSecurityContextHolder.getContext().getAdminId(), productSpuAddDTO);
// 返回结果 // 返回结果
@ -88,7 +87,7 @@ public class AdminsProductSpuController {
// 创建 ProductSpuUpdateDTO 对象 // 创建 ProductSpuUpdateDTO 对象
ProductSpuUpdateDTO productSpuUpdateDTO = new ProductSpuUpdateDTO().setId(id).setName(name).setSellPoint(sellPoint) ProductSpuUpdateDTO productSpuUpdateDTO = new ProductSpuUpdateDTO().setId(id).setName(name).setSellPoint(sellPoint)
.setDescription(description).setCid(cid).setPicUrls(picUrls).setVisible(visible) .setDescription(description).setCid(cid).setPicUrls(picUrls).setVisible(visible)
.setSkus(parseSkus(skuStr, ProductSkuUpdateDTO.class)); .setSkus(parseSkus(skuStr, ProductSkuAddOrUpdateDTO.class));
// 更新商品 // 更新商品
return productSpuService.updateProductSpu(AdminSecurityContextHolder.getContext().getAdminId(), productSpuUpdateDTO); return productSpuService.updateProductSpu(AdminSecurityContextHolder.getContext().getAdminId(), productSpuUpdateDTO);
} }
@ -97,9 +96,11 @@ public class AdminsProductSpuController {
@ApiOperation("更新商品的排序") @ApiOperation("更新商品的排序")
public CommonResult<Boolean> updateSort(@RequestParam("id") Integer id, public CommonResult<Boolean> updateSort(@RequestParam("id") Integer id,
@RequestParam("sort") Integer sort) { @RequestParam("sort") Integer sort) {
return null; return productSpuService.updateProductSpuSort(AdminSecurityContextHolder.getContext().getAdminId(), id, sort);
} }
// TODO 芋艿删除功能暂时不做主要原因是关联的数据太多删除带来的问题会比较大
@GetMapping("/spu/page") @GetMapping("/spu/page")
@ApiOperation("商品 SPU 分页列表") @ApiOperation("商品 SPU 分页列表")
public CommonResult<AdminsProductSpuPageVO> spuPage() { public CommonResult<AdminsProductSpuPageVO> spuPage() {

View File

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

View File

@ -1,30 +1,37 @@
package cn.iocoder.mall.product.api.dto; package cn.iocoder.mall.product.api.dto;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.List; import java.util.List;
/** /**
* 商品 Sku 添加 DTO * 商品 Sku 添加 DTO
*/ */
public class ProductSkuAddDTO { public class ProductSkuAddOrUpdateDTO {
/** /**
* 规格值数组 * 规格值数组
*/ */
@NotNull(message = "规格值数组不能为空")
private List<Integer> attrs; private List<Integer> attrs;
/** /**
* 价格单位 * 价格单位
*/ */
@NotNull(message = "价格不能为空")
@Min(value = 1L, message = "最小价格为 1")
private Integer price; private Integer price;
/** /**
* 库存数量 * 库存数量
*/ */
@NotNull(message = "库存数量不能为空")
@Min(value = 1L, message = "最小库存为 1")
private Integer quantity; private Integer quantity;
public List<Integer> getAttrs() { public List<Integer> getAttrs() {
return attrs; return attrs;
} }
public ProductSkuAddDTO setAttrs(List<Integer> attrs) { public ProductSkuAddOrUpdateDTO setAttrs(List<Integer> attrs) {
this.attrs = attrs; this.attrs = attrs;
return this; return this;
} }
@ -33,7 +40,7 @@ public class ProductSkuAddDTO {
return price; return price;
} }
public ProductSkuAddDTO setPrice(Integer price) { public ProductSkuAddOrUpdateDTO setPrice(Integer price) {
this.price = price; this.price = price;
return this; return this;
} }
@ -42,7 +49,7 @@ public class ProductSkuAddDTO {
return quantity; return quantity;
} }
public ProductSkuAddDTO setQuantity(Integer quantity) { public ProductSkuAddOrUpdateDTO setQuantity(Integer quantity) {
this.quantity = quantity; this.quantity = quantity;
return this; return this;
} }

View File

@ -1,50 +0,0 @@
package cn.iocoder.mall.product.api.dto;
import java.util.List;
/**
* 商品 Sku 更新 DTO
*/
public class ProductSkuUpdateDTO {
/**
* 规格值数组
*/
private List<Integer> attrs;
/**
* 价格单位
*/
private Integer price;
/**
* 库存数量
*/
private Integer quantity;
public List<Integer> getAttrs() {
return attrs;
}
public ProductSkuUpdateDTO setAttrs(List<Integer> attrs) {
this.attrs = attrs;
return this;
}
public Integer getPrice() {
return price;
}
public ProductSkuUpdateDTO setPrice(Integer price) {
this.price = price;
return this;
}
public Integer getQuantity() {
return quantity;
}
public ProductSkuUpdateDTO setQuantity(Integer quantity) {
this.quantity = quantity;
return this;
}
}

View File

@ -52,7 +52,7 @@ public class ProductSpuAddDTO {
* SKU 数组 * SKU 数组
*/ */
@NotNull(message = "SKU 不能为空") @NotNull(message = "SKU 不能为空")
private List<ProductSkuAddDTO> skus; private List<ProductSkuAddOrUpdateDTO> skus;
public String getName() { public String getName() {
return name; return name;
@ -108,11 +108,11 @@ public class ProductSpuAddDTO {
return this; return this;
} }
public List<ProductSkuAddDTO> getSkus() { public List<ProductSkuAddOrUpdateDTO> getSkus() {
return skus; return skus;
} }
public ProductSpuAddDTO setSkus(List<ProductSkuAddDTO> skus) { public ProductSpuAddDTO setSkus(List<ProductSkuAddOrUpdateDTO> skus) {
this.skus = skus; this.skus = skus;
return this; return this;
} }

View File

@ -58,7 +58,7 @@ public class ProductSpuUpdateDTO {
* SKU 数组 * SKU 数组
*/ */
@NotNull(message = "SKU 不能为空") @NotNull(message = "SKU 不能为空")
private List<ProductSkuUpdateDTO> skus; private List<ProductSkuAddOrUpdateDTO> skus;
public String getName() { public String getName() {
return name; return name;
@ -114,11 +114,11 @@ public class ProductSpuUpdateDTO {
return this; return this;
} }
public List<ProductSkuUpdateDTO> getSkus() { public List<ProductSkuAddOrUpdateDTO> getSkus() {
return skus; return skus;
} }
public ProductSpuUpdateDTO setSkus(List<ProductSkuUpdateDTO> skus) { public ProductSpuUpdateDTO setSkus(List<ProductSkuAddOrUpdateDTO> skus) {
this.skus = skus; this.skus = skus;
return this; return this;
} }

View File

@ -5,8 +5,7 @@ import cn.iocoder.mall.product.api.bo.ProductAttrDetailBO;
import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO; import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO;
import cn.iocoder.mall.product.api.bo.ProductSpuBO; import cn.iocoder.mall.product.api.bo.ProductSpuBO;
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO; import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
import cn.iocoder.mall.product.api.dto.ProductSkuAddDTO; import cn.iocoder.mall.product.api.dto.ProductSkuAddOrUpdateDTO;
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.dataobject.ProductSkuDO; import cn.iocoder.mall.product.dataobject.ProductSkuDO;
@ -37,7 +36,7 @@ public interface ProductSpuConvert {
@Mappings({ @Mappings({
@Mapping(source = "attrs", target = "attrs", ignore = true) @Mapping(source = "attrs", target = "attrs", ignore = true)
}) })
ProductSkuDO convert(ProductSkuAddDTO productSkuAddDTO); ProductSkuDO convert(ProductSkuAddOrUpdateDTO productSkuAddDTO);
@Mappings({ @Mappings({
@ -45,11 +44,6 @@ public interface ProductSpuConvert {
}) })
ProductSpuDO convert(ProductSpuUpdateDTO productSpuUpdateDTO); ProductSpuDO convert(ProductSpuUpdateDTO productSpuUpdateDTO);
@Mappings({
@Mapping(source = "attrs", target = "attrs", ignore = true)
})
ProductSkuDO convert(ProductSkuUpdateDTO productSkuUpdateDTO);
@Mappings({}) @Mappings({})
ProductSpuDetailBO convert(ProductSpuBO spu); ProductSpuDetailBO convert(ProductSpuBO spu);

View File

@ -61,8 +61,9 @@ public class ProductSpuDO extends BaseDO {
return id; return id;
} }
public void setId(Integer id) { public ProductSpuDO setId(Integer id) {
this.id = id; this.id = id;
return this;
} }
public String getName() { public String getName() {
@ -127,7 +128,4 @@ public class ProductSpuDO extends BaseDO {
this.sort = sort; this.sort = sort;
return this; return this;
} }
} }

View File

@ -11,8 +11,7 @@ import cn.iocoder.mall.product.api.bo.ProductSpuBO;
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO; 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.ProductSkuAddOrUpdateDTO;
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;
@ -110,6 +109,11 @@ public class ProductSpuServiceImpl implements ProductSpuService {
if (validAttrResult.isError()) { if (validAttrResult.isError()) {
return CommonResult.error(validAttrResult); return CommonResult.error(validAttrResult);
} }
// 校验 Sku 规格
CommonResult<Boolean> validProductSkuResult = validProductSku(productSpuUpdateDTO.getSkus(), validAttrResult.getData());
if (validProductSkuResult.isError()) {
return CommonResult.error(validProductSkuResult);
}
// 更新 Spu // 更新 Spu
ProductSpuDO updateSpu = ProductSpuConvert.INSTANCE.convert(productSpuUpdateDTO) ProductSpuDO updateSpu = ProductSpuConvert.INSTANCE.convert(productSpuUpdateDTO)
.setPicUrls(StringUtil.join(productSpuUpdateDTO.getPicUrls(), ",")); .setPicUrls(StringUtil.join(productSpuUpdateDTO.getPicUrls(), ","));
@ -119,7 +123,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
List<ProductSkuDO> insertSkus = new ArrayList<>(0); // 1找不到进行插入 List<ProductSkuDO> insertSkus = new ArrayList<>(0); // 1找不到进行插入
List<Integer> deleteSkus = new ArrayList<>(0); // 2多余的删除 List<Integer> deleteSkus = new ArrayList<>(0); // 2多余的删除
List<ProductSkuDO> updateSkus = new ArrayList<>(0); // 3找的到进行更新 List<ProductSkuDO> updateSkus = new ArrayList<>(0); // 3找的到进行更新
for (ProductSkuUpdateDTO skuUpdateDTO : productSpuUpdateDTO.getSkus()) { for (ProductSkuAddOrUpdateDTO skuUpdateDTO : productSpuUpdateDTO.getSkus()) {
ProductSkuDO existsSku = findProductSku(skuUpdateDTO.getAttrs(), existsSkus); ProductSkuDO existsSku = findProductSku(skuUpdateDTO.getAttrs(), existsSkus);
// 3找的到进行更新 // 3找的到进行更新
if (existsSku != null) { if (existsSku != null) {
@ -149,19 +153,28 @@ public class ProductSpuServiceImpl implements ProductSpuService {
if (!deleteSkus.isEmpty()) { if (!deleteSkus.isEmpty()) {
productSkuMapper.updateToDeleted(deleteSkus); productSkuMapper.updateToDeleted(deleteSkus);
} }
// if (true) {
// throw new RuntimeException("test");
// }
// 校验 Sku 规格
return CommonResult.success(true); return CommonResult.success(true);
} }
private CommonResult<Boolean> validProductSku(List<ProductSkuAddDTO> productSkuAddDTOs, List<ProductAttrDetailBO> productAttrDetailBOs) { @Override
public CommonResult<Boolean> updateProductSpuSort(Integer adminId, Integer spuId, Integer sort) {
// 校验 Spu 是否存在
if (productSpuMapper.selectById(spuId) == null) {
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode());
}
// 更新排序
ProductSpuDO updateSpu = new ProductSpuDO().setId(spuId).setSort(sort);
productSpuMapper.update(updateSpu);
// 返回成功
return CommonResult.success(true);
}
private CommonResult<Boolean> validProductSku(List<ProductSkuAddOrUpdateDTO> productSkuAddDTOs, List<ProductAttrDetailBO> productAttrDetailBOs) {
// 创建 ProductAttrDetailBO 的映射其中KEY ProductAttrDetailBO.attrValueId 即规格值的编号 // 创建 ProductAttrDetailBO 的映射其中KEY ProductAttrDetailBO.attrValueId 即规格值的编号
Map<Integer, ProductAttrDetailBO> productAttrDetailBOMap = productAttrDetailBOs.stream().collect( Map<Integer, ProductAttrDetailBO> productAttrDetailBOMap = productAttrDetailBOs.stream().collect(
Collectors.toMap(ProductAttrDetailBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO)); Collectors.toMap(ProductAttrDetailBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO));
// 1. 先校验一个 Sku 没有重复的规格校验方式是遍历每个 Sku 看看是否有重复的规格 attrId // 1. 先校验一个 Sku 没有重复的规格校验方式是遍历每个 Sku 看看是否有重复的规格 attrId
for (ProductSkuAddDTO sku : productSkuAddDTOs) { for (ProductSkuAddOrUpdateDTO sku : productSkuAddDTOs) {
Set<Integer> attrIds = sku.getAttrs().stream().map(attrValueId -> productAttrDetailBOMap.get(attrValueId).getAttrId()).collect(Collectors.toSet()); Set<Integer> attrIds = sku.getAttrs().stream().map(attrValueId -> productAttrDetailBOMap.get(attrValueId).getAttrId()).collect(Collectors.toSet());
if (attrIds.size() != sku.getAttrs().size()) { if (attrIds.size() != sku.getAttrs().size()) {
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE.getCode()); return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE.getCode());
@ -176,7 +189,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
} }
// 3. 最后校验每个 Sku 之间不是重复的 // 3. 最后校验每个 Sku 之间不是重复的
Set<Set<Integer>> skuAttrValues = new HashSet<>(); // 每个元素都是一个 Sku attrValueId 集合这样通过最外层的 Set 判断是否有重复的. Set<Set<Integer>> skuAttrValues = new HashSet<>(); // 每个元素都是一个 Sku attrValueId 集合这样通过最外层的 Set 判断是否有重复的.
for (ProductSkuAddDTO sku : productSkuAddDTOs) { for (ProductSkuAddOrUpdateDTO sku : productSkuAddDTOs) {
if (!skuAttrValues.add(new HashSet<>(sku.getAttrs()))) { // 添加失败说明重复 if (!skuAttrValues.add(new HashSet<>(sku.getAttrs()))) { // 添加失败说明重复
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_SKU__NOT_DUPLICATE.getCode()); return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_SKU__NOT_DUPLICATE.getCode());
} }