进行商品修改的迁移
This commit is contained in:
parent
e107b42f53
commit
75876682fb
@ -18,6 +18,34 @@ POST {{baseUrl}}/product-spu/create
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Authorization: Bearer {{accessToken}}
|
||||
|
||||
name=测试商品标题&description=测试商品描述&cid=637&sellPoint=丑&picUrls=1,2,3&visible=true&skus[0].price=1&skus[0].quantity=100&skus[0].attrValueIds=1,3
|
||||
name=测试商品标题&description=测试商品描述&cid=637&sellPoint=丑&picUrls=1,2,3&visible=true
|
||||
&skus[0].price=1&skus[0].quantity=100&skus[0].attrValueIds=1,3
|
||||
&skus[1].price=2&skus[1].quantity=50&skus[1].attrValueIds=2,4
|
||||
|
||||
### /product-spu/create 失败(规格不存在)
|
||||
POST {{baseUrl}}/product-spu/create
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Authorization: Bearer {{accessToken}}
|
||||
|
||||
name=测试商品标题&description=测试商品描述&cid=637&sellPoint=丑&picUrls=1,2,3&visible=true
|
||||
&skus[0].price=1&skus[0].quantity=100&skus[0].attrValueIds=1,0
|
||||
|
||||
### /product-spu/create 失败(规格数量不匹配)
|
||||
POST {{baseUrl}}/product-spu/create
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Authorization: Bearer {{accessToken}}
|
||||
|
||||
name=测试商品标题&description=测试商品描述&cid=637&sellPoint=丑&picUrls=1,2,3&visible=true
|
||||
&skus[0].price=1&skus[0].quantity=100&skus[0].attrValueIds=1,3
|
||||
&skus[1].price=2&skus[1].quantity=50&skus[1].attrValueIds=1,2,4
|
||||
|
||||
### /product-spu/update 成功
|
||||
POST {{baseUrl}}/product-spu/update
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Authorization: Bearer {{accessToken}}
|
||||
|
||||
id=59&name=测试商品标题&description=测试商品描述&cid=637&sellPoint=丑&picUrls=1,2,3&visible=true
|
||||
&skus[0].price=1&skus[0].quantity=100&skus[0].attrValueIds=1,3
|
||||
&skus[1].price=2&skus[1].quantity=50&skus[1].attrValueIds=2,4
|
||||
|
||||
###
|
||||
|
@ -46,14 +46,14 @@ public class ProductSpuController {
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得商品 SPU")
|
||||
@ApiImplicitParam(name = "productSpuId", value = "商品 SPU编号", required = true)
|
||||
@ApiImplicitParam(name = "productSpuId", value = "商品 SPU 编号", required = true)
|
||||
public CommonResult<ProductSpuRespVO> getProductSpu(@RequestParam("productSpuId") Integer productSpuId) {
|
||||
return success(productSpuManager.getProductSpu(productSpuId));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获得商品 SPU 列表")
|
||||
@ApiImplicitParam(name = "productSpuIds", value = "商品 SPU编号列表", required = true)
|
||||
@ApiImplicitParam(name = "productSpuIds", value = "商品 SPU 编号列表", required = true)
|
||||
public CommonResult<List<ProductSpuRespVO>> listProductSpus(@RequestParam("productSpuIds") List<Integer> productSpuIds) {
|
||||
return success(productSpuManager.listProductSpus(productSpuIds));
|
||||
}
|
||||
|
@ -42,22 +42,22 @@ public class ProductSpuCreateReqVO {
|
||||
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "SPU 名字", required = true)
|
||||
@ApiModelProperty(value = "SPU 名字", required = true, example = "芋艿")
|
||||
@NotEmpty(message = "SPU 名字不能为空")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "卖点", required = true)
|
||||
@ApiModelProperty(value = "卖点", required = true, example = "好吃好玩")
|
||||
@NotEmpty(message = "卖点不能为空")
|
||||
private String sellPoint;
|
||||
@ApiModelProperty(value = "描述", required = true)
|
||||
@ApiModelProperty(value = "描述", required = true, example = "我是哈哈哈")
|
||||
@NotEmpty(message = "描述不能为空")
|
||||
private String description;
|
||||
@ApiModelProperty(value = "分类编号", required = true)
|
||||
@ApiModelProperty(value = "分类编号", required = true, example = "1")
|
||||
@NotNull(message = "分类编号不能为空")
|
||||
private Integer cid;
|
||||
@ApiModelProperty(value = "商品主图地址", required = true)
|
||||
@ApiModelProperty(value = "商品主图地址", required = true, example = "http://www.iocoder.cn/xxx.jpg", notes = "多个之间,使用逗号分隔")
|
||||
@NotEmpty(message = "商品主图地址不能为空")
|
||||
private List<String> picUrls;
|
||||
@ApiModelProperty(value = "是否上架商品", required = true)
|
||||
@ApiModelProperty(value = "是否上架商品", required = true, example = "true")
|
||||
@NotNull(message = "是否上架商品不能为空")
|
||||
private Boolean visible;
|
||||
|
||||
|
@ -10,27 +10,25 @@ public class ProductSpuRespVO {
|
||||
|
||||
@ApiModelProperty(value = "SPU 编号", required = true)
|
||||
private Integer id;
|
||||
@ApiModelProperty(value = "SPU 名字", required = true)
|
||||
@ApiModelProperty(value = "SPU 名字", required = true, example = "芋艿")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "卖点", required = true)
|
||||
@ApiModelProperty(value = "卖点", required = true, example = "好吃好玩")
|
||||
private String sellPoint;
|
||||
@ApiModelProperty(value = "描述", required = true)
|
||||
@ApiModelProperty(value = "描述", required = true, example = "我是哈哈哈")
|
||||
private String description;
|
||||
@ApiModelProperty(value = "分类编号", required = true)
|
||||
@ApiModelProperty(value = "分类编号", required = true, example = "1")
|
||||
private Integer cid;
|
||||
@ApiModelProperty(value = "商品主图地址", required = true)
|
||||
@ApiModelProperty(value = "商品主图地址", required = true, example = "http://www.iocoder.cn/xxx.jpg", notes = "多个之间,使用逗号分隔")
|
||||
private List<String> picUrls;
|
||||
@ApiModelProperty(value = "是否上架商品", required = true)
|
||||
@ApiModelProperty(value = "是否上架商品", required = true, example = "true")
|
||||
private Boolean visible;
|
||||
@ApiModelProperty(value = "排序字段", required = true)
|
||||
@ApiModelProperty(value = "排序字段", required = true, example = "1024")
|
||||
private Integer sort;
|
||||
@ApiModelProperty(value = "价格", required = true)
|
||||
@ApiModelProperty(value = "价格", required = true, example = "233", notes = "单位:分")
|
||||
private Integer price;
|
||||
@ApiModelProperty(value = "库存数量", required = true)
|
||||
@ApiModelProperty(value = "库存数量", required = true, example = "1024")
|
||||
private Integer quantity;
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private Date createTime;
|
||||
@ApiModelProperty(value = "最后更新时间", required = true)
|
||||
private Date updateTime;
|
||||
|
||||
}
|
||||
|
@ -3,44 +3,75 @@ package cn.iocoder.mall.managementweb.controller.product.vo.spu;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel("商品 SPU更新 Request VO")
|
||||
@ApiModel("商品 SPU 更新 Request VO")
|
||||
@Data
|
||||
public class ProductSpuUpdateReqVO {
|
||||
|
||||
/**
|
||||
* SKU 信息
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Sku {
|
||||
|
||||
/**
|
||||
* 规格值数组
|
||||
*/
|
||||
@NotNull(message = "规格值数组不能为空")
|
||||
private List<Integer> attrValueIds;
|
||||
/**
|
||||
* 价格,单位:分
|
||||
*/
|
||||
@NotNull(message = "价格不能为空")
|
||||
@Min(value = 1L, message = "最小价格为 1")
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
@NotNull(message = "库存数量不能为空")
|
||||
@Min(value = 1L, message = "最小库存为 1")
|
||||
private Integer quantity;
|
||||
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "SPU 编号", required = true)
|
||||
@NotNull(message = "SPU 编号不能为空")
|
||||
private Integer id;
|
||||
@ApiModelProperty(value = "SPU 名字", required = true)
|
||||
|
||||
@ApiModelProperty(value = "SPU 名字", required = true, example = "芋艿")
|
||||
@NotEmpty(message = "SPU 名字不能为空")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "卖点", required = true)
|
||||
@ApiModelProperty(value = "卖点", required = true, example = "好吃好玩")
|
||||
@NotEmpty(message = "卖点不能为空")
|
||||
private String sellPoint;
|
||||
@ApiModelProperty(value = "描述", required = true)
|
||||
@ApiModelProperty(value = "描述", required = true, example = "我是哈哈哈")
|
||||
@NotEmpty(message = "描述不能为空")
|
||||
private String description;
|
||||
@ApiModelProperty(value = "分类编号", required = true)
|
||||
@ApiModelProperty(value = "分类编号", required = true, example = "1")
|
||||
@NotNull(message = "分类编号不能为空")
|
||||
private Integer cid;
|
||||
@ApiModelProperty(value = "商品主图地址", required = true)
|
||||
@ApiModelProperty(value = "商品主图地址", required = true, example = "http://www.iocoder.cn/xxx.jpg", notes = "多个之间,使用逗号分隔")
|
||||
@NotEmpty(message = "商品主图地址不能为空")
|
||||
private List<String> picUrls;
|
||||
@ApiModelProperty(value = "是否上架商品", required = true)
|
||||
@ApiModelProperty(value = "是否上架商品", required = true, example = "true")
|
||||
@NotNull(message = "是否上架商品不能为空")
|
||||
private Boolean visible;
|
||||
@ApiModelProperty(value = "排序字段", required = true)
|
||||
@NotNull(message = "排序字段不能为空")
|
||||
private Integer sort;
|
||||
@ApiModelProperty(value = "价格", required = true)
|
||||
@NotNull(message = "价格不能为空")
|
||||
private Integer price;
|
||||
@ApiModelProperty(value = "库存数量", required = true)
|
||||
@NotNull(message = "库存数量不能为空")
|
||||
private Integer quantity;
|
||||
|
||||
// ========== SKU =========
|
||||
|
||||
/**
|
||||
* SKU 数组
|
||||
*/
|
||||
@NotNull(message = "SKU 不能为空")
|
||||
@Valid
|
||||
private List<ProductSpuCreateReqVO.Sku> skus;
|
||||
|
||||
}
|
||||
|
@ -6,9 +6,9 @@ import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuPageReq
|
||||
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuRespVO;
|
||||
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuUpdateReqVO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuCreateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuUpdateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuUpdateReqDTO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@ -21,7 +21,7 @@ public interface ProductSpuConvert {
|
||||
|
||||
ProductSpuAndSkuCreateReqDTO convert(ProductSpuCreateReqVO bean);
|
||||
|
||||
ProductSpuUpdateReqDTO convert(ProductSpuUpdateReqVO bean);
|
||||
ProductSpuAndSkuUpdateReqDTO convert(ProductSpuUpdateReqVO bean);
|
||||
|
||||
ProductSpuRespVO convert(ProductSpuRespDTO bean);
|
||||
|
||||
|
@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>order</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>order-application</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- Mall 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>order-rest</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>order-rpc</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
@ -1,51 +0,0 @@
|
||||
package cn.iocoder.mall.order.application;
|
||||
|
||||
import org.apache.catalina.connector.Connector;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.config.ConfigFileApplicationListener;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
* @author xiaofeng
|
||||
*/
|
||||
@SpringBootApplication(scanBasePackages = {"cn.iocoder.mall.order"})
|
||||
public class OrderApplication {
|
||||
|
||||
/**
|
||||
* 设置需要读取的配置文件的名字。 基于 {@link org.springframework.boot.context.config.ConfigFileApplicationListener#CONFIG_NAME_PROPERTY}
|
||||
* 实现。
|
||||
*/
|
||||
private static final String CONFIG_NAME_VALUE = "biz,rest,rpc,application";
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 设置环境变量
|
||||
System.setProperty(ConfigFileApplicationListener.CONFIG_NAME_PROPERTY, CONFIG_NAME_VALUE);
|
||||
SpringApplication.run(OrderApplication.class, args);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解决异常信息: java.lang.IllegalArgumentException: Invalid character found in the request target.
|
||||
* The valid characters are defined in RFC 7230 and RFC 3986
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
// TODO FROM 芋艿 to 芋艿:这个不太了解,可能后续要放到 starter 里,统一处理。
|
||||
public ConfigurableServletWebServerFactory webServerFactory() {
|
||||
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
|
||||
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
|
||||
@Override
|
||||
public void customize(Connector connector) {
|
||||
connector.setProperty("relaxedQueryChars", "|{}[]");
|
||||
}
|
||||
});
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
spring:
|
||||
# Application 的配置项
|
||||
application:
|
||||
name: order-application
|
||||
# Profile 的配置项
|
||||
profiles:
|
||||
active: local
|
@ -3,9 +3,9 @@ package cn.iocoder.mall.productservice.rpc.spu;
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuCreateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuUpdateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuUpdateReqDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -27,7 +27,7 @@ public interface ProductSpuRpc {
|
||||
*
|
||||
* @param updateDTO 更新商品 SPU DTO
|
||||
*/
|
||||
CommonResult<Boolean> updateProductSpu(ProductSpuUpdateReqDTO updateDTO);
|
||||
CommonResult<Boolean> updateProductSpu(ProductSpuAndSkuUpdateReqDTO updateDTO);
|
||||
|
||||
/**
|
||||
* 获得商品 SPU
|
||||
|
@ -0,0 +1,96 @@
|
||||
package cn.iocoder.mall.productservice.rpc.spu.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SPU 和 SKU 更新 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuAndSkuUpdateReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* SKU 信息
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class Sku implements Serializable {
|
||||
|
||||
/**
|
||||
* 规格值数组
|
||||
*/
|
||||
@NotNull(message = "规格值数组不能为空")
|
||||
private List<Integer> attrValueIds;
|
||||
/**
|
||||
* 价格,单位:分
|
||||
*/
|
||||
@NotNull(message = "价格不能为空")
|
||||
@Min(value = 1L, message = "最小价格为 1")
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
@NotNull(message = "库存数量不能为空")
|
||||
@Min(value = 1L, message = "最小库存为 1")
|
||||
private Integer quantity;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Spu 编号
|
||||
*/
|
||||
@NotNull(message = "SPU 编号不能为空")
|
||||
private Integer id;
|
||||
|
||||
// ========== 基本信息 =========
|
||||
/**
|
||||
* SPU 名字
|
||||
*/
|
||||
@NotEmpty(message = "SPU 名字不能为空")
|
||||
private String name;
|
||||
/**
|
||||
* 卖点
|
||||
*/
|
||||
@NotEmpty(message = "卖点不能为空")
|
||||
private String sellPoint;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@NotEmpty(message = "描述不能为空")
|
||||
private String description;
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
@NotNull(message = "分类编号不能为空")
|
||||
private Integer cid;
|
||||
/**
|
||||
* 商品主图地址
|
||||
*/
|
||||
@NotEmpty(message = "商品主图地址不能为空")
|
||||
private List<String> picUrls;
|
||||
|
||||
// ========== 其他信息 =========
|
||||
/**
|
||||
* 是否上架商品
|
||||
*/
|
||||
@NotNull(message = "是否上架商品不能为空")
|
||||
private Boolean visible;
|
||||
|
||||
// ========== SKU =========
|
||||
|
||||
/**
|
||||
* SKU 数组
|
||||
*/
|
||||
@NotNull(message = "SKU 不能为空")
|
||||
@Valid
|
||||
private List<Sku> skus;
|
||||
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package cn.iocoder.mall.productservice.rpc.spu.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SPU 更新 Request DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuUpdateReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
@NotNull(message = "商品 SPU 编号不能为空")
|
||||
private Integer id;
|
||||
/**
|
||||
* SPU 名字
|
||||
*/
|
||||
@NotEmpty(message = "SPU 名字不能为空")
|
||||
private String name;
|
||||
/**
|
||||
* 卖点
|
||||
*/
|
||||
@NotEmpty(message = "卖点不能为空")
|
||||
private String sellPoint;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@NotEmpty(message = "描述不能为空")
|
||||
private String description;
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
@NotNull(message = "分类编号不能为空")
|
||||
private Integer cid;
|
||||
/**
|
||||
* 商品主图地址
|
||||
*/
|
||||
@NotEmpty(message = "商品主图地址不能为空")
|
||||
private List<String> picUrls;
|
||||
/**
|
||||
* 是否上架商品
|
||||
*/
|
||||
@NotNull(message = "是否上架商品不能为空")
|
||||
private Boolean visible;
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
@NotNull(message = "排序字段不能为空")
|
||||
private Integer sort;
|
||||
/**
|
||||
* 价格
|
||||
*/
|
||||
@NotNull(message = "价格不能为空")
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
@NotNull(message = "库存数量不能为空")
|
||||
private Integer quantity;
|
||||
|
||||
}
|
@ -18,7 +18,7 @@ public interface ProductSkuConvert {
|
||||
List<ProductSkuDO> convertList(List<ProductSkuCreateOrUpdateBO> list);
|
||||
|
||||
@Mapping(source = "attrValueIds", target = "attrs", qualifiedByName = "translatePicUrlsFromStringList")
|
||||
ProductSkuDO convertList(ProductSkuCreateOrUpdateBO bean);
|
||||
ProductSkuDO convert(ProductSkuCreateOrUpdateBO skuUpdateDTO);
|
||||
|
||||
@Named("translateAttrValueIdsFromString")
|
||||
default List<String> translateAttrValueIdsFromString(String attrValueIdsStar) {
|
||||
|
@ -3,11 +3,11 @@ package cn.iocoder.mall.productservice.convert.spu;
|
||||
import cn.iocoder.common.framework.util.StringUtils;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.productservice.dal.mysql.dataobject.spu.ProductSpuDO;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuCreateOrUpdateBO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuCreateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuUpdateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuUpdateReqDTO;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuCreateOrUpdateBO;
|
||||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuBO;
|
||||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuCreateBO;
|
||||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuPageBO;
|
||||
@ -41,7 +41,7 @@ public interface ProductSpuConvert {
|
||||
|
||||
ProductSpuCreateBO convert(ProductSpuAndSkuCreateReqDTO bean);
|
||||
|
||||
ProductSpuUpdateBO convert(ProductSpuUpdateReqDTO bean);
|
||||
ProductSpuUpdateBO convert(ProductSpuAndSkuUpdateReqDTO bean);
|
||||
|
||||
ProductSpuRespDTO convert(ProductSpuBO bean);
|
||||
|
||||
@ -51,6 +51,9 @@ public interface ProductSpuConvert {
|
||||
|
||||
PageResult<ProductSpuRespDTO> convertPage(PageResult<ProductSpuBO> page);
|
||||
|
||||
List<ProductSkuCreateOrUpdateBO> convert(List<ProductSpuAndSkuCreateReqDTO.Sku> list);
|
||||
List<ProductSkuCreateOrUpdateBO> convert02(List<ProductSpuAndSkuUpdateReqDTO.Sku> list);
|
||||
|
||||
@Named("translatePicUrlsFromString")
|
||||
default List<String> translatePicUrlsFromList(String picUrls) {
|
||||
return StringUtils.split(picUrls, ",");
|
||||
@ -61,6 +64,5 @@ public interface ProductSpuConvert {
|
||||
return StringUtils.join(picUrls, ",");
|
||||
}
|
||||
|
||||
List<ProductSkuCreateOrUpdateBO> convert(List<ProductSpuAndSkuCreateReqDTO.Sku> list);
|
||||
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.productservice.convert.spu.ProductSpuConvert;
|
||||
import cn.iocoder.mall.productservice.enums.category.ProductCategoryIdEnum;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuCreateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuUpdateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuUpdateReqDTO;
|
||||
import cn.iocoder.mall.productservice.service.attr.ProductAttrService;
|
||||
import cn.iocoder.mall.productservice.service.attr.bo.ProductAttrKeyValueBO;
|
||||
import cn.iocoder.mall.productservice.service.category.ProductCategoryService;
|
||||
@ -17,17 +17,15 @@ import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuCreateOrUpdateBO;
|
||||
import cn.iocoder.mall.productservice.service.spu.ProductSpuService;
|
||||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuBO;
|
||||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuCreateBO;
|
||||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuUpdateBO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.PRODUCT_CATEGORY_NOT_EXISTS;
|
||||
import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2;
|
||||
import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 商品 SPU Manager
|
||||
@ -52,30 +50,18 @@ public class ProductSpuManager {
|
||||
*/
|
||||
@Transactional
|
||||
public Integer createProductSpu(ProductSpuAndSkuCreateReqDTO createDTO) {
|
||||
// 校验商品分类分类存在
|
||||
ProductCategoryBO categoryBO = productCategoryService.getProductCategory(createDTO.getCid());
|
||||
if (categoryBO == null) {
|
||||
// 不存在
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
if (ProductCategoryIdEnum.ROOT.getId().equals(categoryBO.getPid())) {
|
||||
// 商品只能添加到二级分类下
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2);
|
||||
}
|
||||
// 校验规格是否存在
|
||||
Set<Integer> attrValueIds = new HashSet<>();
|
||||
createDTO.getSkus().forEach(productSkuAddDTO -> attrValueIds.addAll(productSkuAddDTO.getAttrValueIds()));
|
||||
List<ProductAttrKeyValueBO> attrKeyValueBOs = productAttrService.validProductAttr(attrValueIds, true);
|
||||
// 校验商品分类是否合法
|
||||
this.checkProductCategory(createDTO.getCid());
|
||||
// 创建商品 SKU 对象,并进行校验
|
||||
List<ProductSkuCreateOrUpdateBO> skus = ProductSpuConvert.INSTANCE.convert(createDTO.getSkus());
|
||||
productSkuService.validProductSku(skus, attrKeyValueBOs);
|
||||
List<ProductSkuCreateOrUpdateBO> skuBOs = ProductSpuConvert.INSTANCE.convert(createDTO.getSkus());
|
||||
this.checkProductAttr(skuBOs);
|
||||
// 插入商品 SPU 记录
|
||||
ProductSpuCreateBO spuCreateBO = ProductSpuConvert.INSTANCE.convert(createDTO).setSort(0);
|
||||
spuCreateBO.setPrice(skus.stream().min(Comparator.comparing(ProductSkuCreateOrUpdateBO::getPrice)).get().getPrice()); // 求最小价格
|
||||
spuCreateBO.setQuantity(skus.stream().mapToInt(ProductSkuCreateOrUpdateBO::getQuantity).sum()); // 求库存之和
|
||||
spuCreateBO.setPrice(skuBOs.stream().min(Comparator.comparing(ProductSkuCreateOrUpdateBO::getPrice)).get().getPrice()); // 求最小价格
|
||||
spuCreateBO.setQuantity(skuBOs.stream().mapToInt(ProductSkuCreateOrUpdateBO::getQuantity).sum()); // 求库存之和
|
||||
ProductSpuBO spuBO = productSpuService.createProductSpu(spuCreateBO);
|
||||
// 从插入商品 SKU 记录
|
||||
productSkuService.createProductSkus(spuBO.getId(), skus);
|
||||
// 插入商品 SKU 记录
|
||||
productSkuService.createProductSkus(spuBO.getId(), skuBOs);
|
||||
return spuBO.getId();
|
||||
}
|
||||
|
||||
@ -84,8 +70,19 @@ public class ProductSpuManager {
|
||||
*
|
||||
* @param updateDTO 更新商品 SPU DTO
|
||||
*/
|
||||
public void updateProductSpu(ProductSpuUpdateReqDTO updateDTO) {
|
||||
productSpuService.updateProductSpu(ProductSpuConvert.INSTANCE.convert(updateDTO));
|
||||
public void updateProductSpu(ProductSpuAndSkuUpdateReqDTO updateDTO) {
|
||||
// 校验商品分类是否合法
|
||||
this.checkProductCategory(updateDTO.getCid());
|
||||
// 创建商品 SKU 对象,并进行校验
|
||||
List<ProductSkuCreateOrUpdateBO> skuBOs = ProductSpuConvert.INSTANCE.convert02(updateDTO.getSkus());
|
||||
this.checkProductAttr(skuBOs);
|
||||
// 更新商品 SPU 记录
|
||||
ProductSpuUpdateBO spuUpdateBO = ProductSpuConvert.INSTANCE.convert(updateDTO);
|
||||
spuUpdateBO.setPrice(skuBOs.stream().min(Comparator.comparing(ProductSkuCreateOrUpdateBO::getPrice)).get().getPrice()); // 求最小价格
|
||||
spuUpdateBO.setQuantity(skuBOs.stream().mapToInt(ProductSkuCreateOrUpdateBO::getQuantity).sum()); // 求库存之和
|
||||
productSpuService.updateProductSpu(spuUpdateBO);
|
||||
// 更新商品 SKU 记录
|
||||
productSkuService.updateProductSkus(updateDTO.getId(), skuBOs);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,4 +118,57 @@ public class ProductSpuManager {
|
||||
return ProductSpuConvert.INSTANCE.convertPage(pageResultBO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加或修改商品 SPU 时,校验商品分类是否合法
|
||||
*
|
||||
* @param cid 商品分类编号
|
||||
* @return 商品分类
|
||||
*/
|
||||
private ProductCategoryBO checkProductCategory(Integer cid) {
|
||||
ProductCategoryBO categoryBO = productCategoryService.getProductCategory(cid);
|
||||
if (categoryBO == null) {
|
||||
// 不存在
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_NOT_EXISTS);
|
||||
}
|
||||
if (ProductCategoryIdEnum.ROOT.getId().equals(categoryBO.getPid())) {
|
||||
// 商品只能添加到二级分类下
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2);
|
||||
}
|
||||
return categoryBO;
|
||||
}
|
||||
|
||||
private List<ProductAttrKeyValueBO> checkProductAttr(List<ProductSkuCreateOrUpdateBO> skuBOs) {
|
||||
// 第一步,校验 SKU 使用到的规格是否存在
|
||||
Set<Integer> attrValueIds = new HashSet<>();
|
||||
skuBOs.forEach(sku -> attrValueIds.addAll(sku.getAttrValueIds()));
|
||||
List<ProductAttrKeyValueBO> attrKeyValueBOs = productAttrService.validProductAttr(attrValueIds, true);
|
||||
// 第二步,校验 SKU 设置的规格是否合法,例如说数量是否一致,是否重复等等
|
||||
// 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
|
||||
Map<Integer, ProductAttrKeyValueBO> productAttrDetailBOMap = attrKeyValueBOs.stream().collect(
|
||||
Collectors.toMap(ProductAttrKeyValueBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO));
|
||||
// 1. 先校验,一个 Sku 下,没有重复的规格。校验方式是,遍历每个 Sku ,看看是否有重复的规格 attrId
|
||||
for (ProductSkuCreateOrUpdateBO sku : skuBOs) {
|
||||
Set<Integer> attrIds = sku.getAttrValueIds().stream().map(attrValueId -> productAttrDetailBOMap.get(attrValueId).getAttrKeyId())
|
||||
.collect(Collectors.toSet());
|
||||
if (attrIds.size() != sku.getAttrValueIds().size()) {
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE);
|
||||
}
|
||||
}
|
||||
// 2. 再校验,每个 Sku 的规格值的数量,是一致的。
|
||||
int attrValueIdsSize = skuBOs.get(0).getAttrValueIds().size();
|
||||
for (int i = 1; i < skuBOs.size(); i++) {
|
||||
if (attrValueIdsSize != skuBOs.get(i).getAttrValueIds().size()) {
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS);
|
||||
}
|
||||
}
|
||||
// 3. 最后校验,每个 Sku 之间不是重复的
|
||||
Set<Set<Integer>> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的.
|
||||
for (ProductSkuCreateOrUpdateBO sku : skuBOs) {
|
||||
if (!skuAttrValues.add(new HashSet<>(sku.getAttrValueIds()))) { // 添加失败,说明重复
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_SPU_SKU_NOT_DUPLICATE);
|
||||
}
|
||||
}
|
||||
return attrKeyValueBOs;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.productservice.manager.spu.ProductSpuManager;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuCreateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuUpdateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuUpdateReqDTO;
|
||||
import org.apache.dubbo.config.annotation.Service;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@ -29,7 +29,7 @@ public class ProductSpuRpcImpl implements ProductSpuRpc {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> updateProductSpu(ProductSpuUpdateReqDTO updateDTO) {
|
||||
public CommonResult<Boolean> updateProductSpu(ProductSpuAndSkuUpdateReqDTO updateDTO) {
|
||||
productSpuManager.updateProductSpu(updateDTO);
|
||||
return success(true);
|
||||
}
|
||||
|
@ -1,31 +1,26 @@
|
||||
package cn.iocoder.mall.productservice.service.sku;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.util.CollectionUtils;
|
||||
import cn.iocoder.common.framework.util.StringUtils;
|
||||
import cn.iocoder.mall.productservice.convert.sku.ProductSkuConvert;
|
||||
import cn.iocoder.mall.productservice.dal.mysql.dataobject.spu.ProductSkuDO;
|
||||
import cn.iocoder.mall.productservice.dal.mysql.mapper.sku.ProductSkuMapper;
|
||||
import cn.iocoder.mall.productservice.service.attr.bo.ProductAttrKeyValueBO;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuCreateOrUpdateBO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.*;
|
||||
|
||||
@Service
|
||||
public class ProductSkuService {
|
||||
|
||||
@Autowired
|
||||
private ProductSkuMapper productSkuMapper;
|
||||
|
||||
public void createProductSkus(Integer spuId, List<ProductSkuCreateOrUpdateBO> createBOs) {
|
||||
List<ProductSkuDO> skus = ProductSkuConvert.INSTANCE.convertList(createBOs);
|
||||
public void createProductSkus(Integer spuId, List<ProductSkuCreateOrUpdateBO> createSkuBOs) {
|
||||
List<ProductSkuDO> skus = ProductSkuConvert.INSTANCE.convertList(createSkuBOs);
|
||||
skus.forEach(sku -> {
|
||||
sku.setStatus(CommonStatusEnum.ENABLE.getValue());
|
||||
sku.setSpuId(spuId);
|
||||
@ -33,42 +28,64 @@ public class ProductSkuService {
|
||||
productSkuMapper.insertList(skus);
|
||||
}
|
||||
|
||||
public void updateProductSkus(Integer spuId, List<ProductSkuCreateOrUpdateBO> createBOs) {
|
||||
|
||||
public void updateProductSkus(Integer spuId, List<ProductSkuCreateOrUpdateBO> skuUpdateBOs) {
|
||||
List<ProductSkuDO> existsSkus = productSkuMapper.selectListBySpuIdAndStatus(spuId,
|
||||
CommonStatusEnum.ENABLE.getValue());
|
||||
List<ProductSkuDO> insertSkus = new ArrayList<>(); // 1、找不到,进行插入
|
||||
List<Integer> deleteSkus = new ArrayList<>(); // 2、多余的,删除
|
||||
List<ProductSkuDO> updateSkus = new ArrayList<>(); // 3、找的到,进行更新。
|
||||
for (ProductSkuCreateOrUpdateBO skuUpdateDTO : skuUpdateBOs) {
|
||||
ProductSkuDO existsSku = findProductSku(skuUpdateDTO.getAttrValueIds(), existsSkus);
|
||||
// 3、找的到,进行更新。
|
||||
if (existsSku != null) {
|
||||
// 移除
|
||||
existsSkus.remove(existsSku);
|
||||
// 创建 ProductSkuDO
|
||||
updateSkus.add(ProductSkuConvert.INSTANCE.convert(skuUpdateDTO).setId(existsSku.getId()));
|
||||
continue;
|
||||
}
|
||||
// 1、找不到,进行插入
|
||||
ProductSkuDO insertSku = ProductSkuConvert.INSTANCE.convert(skuUpdateDTO)
|
||||
.setSpuId(spuId).setStatus(CommonStatusEnum.ENABLE.getValue());
|
||||
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.updateById(productSkuDO));
|
||||
}
|
||||
if (!deleteSkus.isEmpty()) {
|
||||
productSkuMapper.deleteBatchIds(deleteSkus);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验 sku 是否合法
|
||||
* 获得 sku 数组中,指定规格的 sku
|
||||
*
|
||||
* @param skuBOs 商品 SKU 添加信息
|
||||
* @param attrKeyValueBOs 商品规格明细数组
|
||||
* @param attrValueIds 指定规格 Value 的编号数组
|
||||
* @param skus sku 数组
|
||||
* @return 符合条件的 sku
|
||||
*/
|
||||
public void validProductSku(List<ProductSkuCreateOrUpdateBO> skuBOs, List<ProductAttrKeyValueBO> attrKeyValueBOs) {
|
||||
// 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
|
||||
Map<Integer, ProductAttrKeyValueBO> productAttrDetailBOMap = attrKeyValueBOs.stream().collect(
|
||||
Collectors.toMap(ProductAttrKeyValueBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO));
|
||||
// 1. 先校验,一个 Sku 下,没有重复的规格。校验方式是,遍历每个 Sku ,看看是否有重复的规格 attrId
|
||||
for (ProductSkuCreateOrUpdateBO sku : skuBOs) {
|
||||
Set<Integer> attrIds = sku.getAttrValueIds().stream().map(attrValueId -> productAttrDetailBOMap.get(attrValueId).getAttrKeyId())
|
||||
.collect(Collectors.toSet());
|
||||
if (attrIds.size() != sku.getAttrValueIds().size()) {
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE);
|
||||
}
|
||||
}
|
||||
// 2. 再校验,每个 Sku 的规格值的数量,是一致的。
|
||||
int attrValueIdsSize = skuBOs.get(0).getAttrValueIds().size();
|
||||
for (int i = 1; i < skuBOs.size(); i++) {
|
||||
if (attrValueIdsSize != skuBOs.get(i).getAttrValueIds().size()) {
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS);
|
||||
}
|
||||
}
|
||||
// 3. 最后校验,每个 Sku 之间不是重复的
|
||||
Set<Set<Integer>> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的.
|
||||
for (ProductSkuCreateOrUpdateBO sku : skuBOs) {
|
||||
if (!skuAttrValues.add(new HashSet<>(sku.getAttrValueIds()))) { // 添加失败,说明重复
|
||||
throw ServiceExceptionUtil.exception(PRODUCT_SPU_SKU_NOT_DUPLICATE);
|
||||
private ProductSkuDO findProductSku(Collection<Integer> attrValueIds, List<ProductSkuDO> skus) {
|
||||
if (CollectionUtils.isEmpty(skus)) {
|
||||
return null;
|
||||
}
|
||||
// 创建成 Set ,方便后面比较
|
||||
attrValueIds = new HashSet<>(attrValueIds);
|
||||
for (ProductSkuDO sku : skus) {
|
||||
Set<Integer> skuAttrValueIds = StringUtils.split(sku.getAttrs(), ",")
|
||||
.stream().map(Integer::parseInt).collect(Collectors.toSet());
|
||||
if (attrValueIds.equals(skuAttrValueIds)) {
|
||||
return sku;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -52,7 +52,6 @@ public class ProductSpuUpdateBO {
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
@NotNull(message = "排序字段不能为空")
|
||||
private Integer sort;
|
||||
/**
|
||||
* 价格
|
||||
|
@ -1,42 +0,0 @@
|
||||
package cn.iocoder.mall.product.biz.bo.brand;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 商品品牌 VO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductBrandBO implements Serializable {
|
||||
|
||||
/**
|
||||
* 规格编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 图片地址
|
||||
*/
|
||||
private String picUrl;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*
|
||||
* 1-开启
|
||||
* 2-禁用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package cn.iocoder.mall.product.biz.dao.sku;
|
||||
|
||||
import cn.iocoder.mall.product.biz.dataobject.spu.ProductSkuDO;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface ProductSkuMapper extends BaseMapper<ProductSkuDO> {
|
||||
|
||||
default List<ProductSkuDO> selectListBySpuIdAndStatus(Integer spuId, Integer status) {
|
||||
return selectList(Wrappers.<ProductSkuDO>query().lambda()
|
||||
.eq(ProductSkuDO::getSpuId, spuId)
|
||||
.eq(ProductSkuDO::getStatus, status)
|
||||
.eq(ProductSkuDO::getDeleted, false));
|
||||
}
|
||||
|
||||
void insertList(@Param("productSkuDOs") List<ProductSkuDO> productSkuDOs);
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
/**
|
||||
* author: sin
|
||||
* time: 2020/5/3 8:29 下午
|
||||
*/
|
||||
package cn.iocoder.mall.product.biz.dto;
|
@ -1,41 +0,0 @@
|
||||
package cn.iocoder.mall.product.biz.dto.product;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 商品 Spu 分页 DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuPageDTO {
|
||||
|
||||
/**
|
||||
* 商品名
|
||||
*
|
||||
* 模糊匹配
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
private Integer cid;
|
||||
/**
|
||||
* 是否可见
|
||||
*/
|
||||
private Boolean visible;
|
||||
/**
|
||||
* 是否有库存
|
||||
*
|
||||
* 允许为空。空时,不进行筛选
|
||||
*/
|
||||
private Boolean hasQuantity;
|
||||
|
||||
@NotNull(message = "页码不能为空")
|
||||
private Integer pageNo;
|
||||
@NotNull(message = "每页条数不能为空")
|
||||
private Integer pageSize;
|
||||
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package cn.iocoder.mall.product.biz.dto.product;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SPU + SKU 更新 DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuUpdateDTO {
|
||||
|
||||
/**
|
||||
* Spu 编号
|
||||
*/
|
||||
@NotNull(message = "SPU 编号不能为空")
|
||||
private Integer id;
|
||||
|
||||
// ========== 基本信息 =========
|
||||
/**
|
||||
* SPU 名字
|
||||
*/
|
||||
@NotEmpty(message = "SPU 名字不能为空")
|
||||
private String name;
|
||||
/**
|
||||
* 卖点
|
||||
*/
|
||||
@NotEmpty(message = "卖点不能为空")
|
||||
private String sellPoint;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@NotEmpty(message = "描述不能为空")
|
||||
private String description;
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
@NotNull(message = "分类不能为空")
|
||||
private Integer cid;
|
||||
/**
|
||||
* 商品主图地址
|
||||
*/
|
||||
@NotNull(message = "商品主图不能为空")
|
||||
private List<String> picUrls;
|
||||
|
||||
// ========== 其他信息 =========
|
||||
/**
|
||||
* 是否上架商品(是否可见)。
|
||||
*
|
||||
* true 为已上架
|
||||
* false 为已下架
|
||||
*/
|
||||
@NotNull(message = "是否上架不能为空")
|
||||
private Boolean visible;
|
||||
|
||||
// ========== SKU =========
|
||||
|
||||
/**
|
||||
* SKU 数组
|
||||
*/
|
||||
@NotNull(message = "SKU 不能为空")
|
||||
private List<ProductSkuAddOrUpdateDTO> skus;
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package cn.iocoder.mall.product.biz.dto.product;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 更新商品收藏参数
|
||||
* @author xiaofeng
|
||||
* @date 2019/07/01 20:38
|
||||
* @version 1.0
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UserProductSpuCollectionsUpdateDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* id自增长
|
||||
*/
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 删除状态
|
||||
*/
|
||||
private Integer deleted;
|
||||
|
||||
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
package cn.iocoder.mall.product.rest.controller.brand;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.product.biz.bo.brand.ProductBrandBO;
|
||||
import cn.iocoder.mall.product.biz.dto.brand.ProductBrandAddDTO;
|
||||
import cn.iocoder.mall.product.biz.dto.brand.ProductBrandPageDTO;
|
||||
import cn.iocoder.mall.product.biz.dto.brand.ProductBrandUpdateDTO;
|
||||
import cn.iocoder.mall.product.biz.service.brand.ProductBrandService;
|
||||
import cn.iocoder.mall.product.rest.convert.brand.ProductBrandConvert;
|
||||
import cn.iocoder.mall.product.rest.request.brand.ProductBrandAddRequest;
|
||||
import cn.iocoder.mall.product.rest.request.brand.ProductBrandPageRequest;
|
||||
import cn.iocoder.mall.product.rest.request.brand.ProductBrandUpdateRequest;
|
||||
import cn.iocoder.mall.product.rest.response.brand.AdminsProductBrandResponse;
|
||||
import cn.iocoder.mall.security.core.context.AdminSecurityContextHolder;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("admins/brand")
|
||||
@Api("管理员 - 商品品牌 API")
|
||||
@AllArgsConstructor
|
||||
public class AdminsProductBrandController {
|
||||
|
||||
private final ProductBrandService productBrandService;
|
||||
|
||||
@PostMapping("/add")
|
||||
@ApiOperation("创建品牌")
|
||||
public CommonResult<AdminsProductBrandResponse> add(@Validated ProductBrandAddRequest addRequest) {
|
||||
// 创建 ProductBrandAddDTO 对象
|
||||
ProductBrandAddDTO productBrandAddDTO = ProductBrandConvert.INSTANCE.convertAdd(addRequest);
|
||||
// 保存品牌
|
||||
ProductBrandBO result = productBrandService.addProductBrand(AdminSecurityContextHolder.getContext().getAdminId(), productBrandAddDTO);
|
||||
// 返回结果
|
||||
return success(ProductBrandConvert.INSTANCE.convert(result));
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
@ApiOperation("更新商品")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "id", value = "品牌主键", required = true, example = "1"),
|
||||
@ApiImplicitParam(name = "name", value = "品牌名称", required = true, example = "安踏"),
|
||||
@ApiImplicitParam(name = "description", value = "品牌描述", required = true, example = "安踏拖鞋"),
|
||||
@ApiImplicitParam(name = "picUrl", value = "品牌图片", required = true, example = "http://www.iocoder.cn"),
|
||||
@ApiImplicitParam(name = "status", value = "状态 1开启 2禁用", required = true, example = "1")
|
||||
})
|
||||
// TODO FROM 芋艿 to q2118cs:只要改成了 bean 接收,就不用在写 @ApiImplicitParam 注解啦,直接在 bean 里写就 ok 啦
|
||||
public CommonResult<Boolean> update(@Validated ProductBrandUpdateRequest updateRequest) {
|
||||
// 创建 productBrandUpdateDTO 对象
|
||||
ProductBrandUpdateDTO productBrandUpdateDTO = ProductBrandConvert.INSTANCE.convertUpdate(updateRequest);
|
||||
// 更新商品
|
||||
return success(productBrandService.updateProductBrand(AdminSecurityContextHolder.getContext().getAdminId(), productBrandUpdateDTO));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获取品牌")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "id", value = "品牌主键", required = true, example = "1")
|
||||
})
|
||||
public CommonResult<AdminsProductBrandResponse> add(@RequestParam("id") Integer id) {
|
||||
// 保存商品
|
||||
ProductBrandBO result = productBrandService.getProductBrand(id);
|
||||
// 返回结果
|
||||
return success(ProductBrandConvert.INSTANCE.convert(result));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得品牌分页")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "name", value = "品牌名称", required = true, example = "安踏"),
|
||||
@ApiImplicitParam(name = "description", value = "品牌描述", required = true, example = "安踏拖鞋"),
|
||||
@ApiImplicitParam(name = "status", value = "状态 1开启 2禁用", required = true, example = "1"),
|
||||
@ApiImplicitParam(name = "pageNo", value = "页码", required = true, example = "1"),
|
||||
@ApiImplicitParam(name = "pageSize", value = "页面大小", required = true, example = "10")
|
||||
})
|
||||
public CommonResult<PageResult<AdminsProductBrandResponse>> attrPage(ProductBrandPageRequest pageRequest) {
|
||||
// 创建 ProductBrandPageDTO 对象
|
||||
ProductBrandPageDTO productBrandPageDTO = ProductBrandConvert.INSTANCE.convertPageRequest(pageRequest);
|
||||
// 查询分页
|
||||
PageResult<ProductBrandBO> productBrandPage = productBrandService.getProductBrandPage(productBrandPageDTO);
|
||||
PageResult<AdminsProductBrandResponse> adminPageResponse = ProductBrandConvert.INSTANCE.convertPage(productBrandPage);
|
||||
return CommonResult.success(adminPageResponse);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -30,10 +30,6 @@ public interface ProductSpuService {
|
||||
|
||||
List<ProductSkuDetailBO> getProductSkuDetailList(Collection<Integer> ids);
|
||||
|
||||
ProductSpuDetailBO addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO);
|
||||
|
||||
void updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO);
|
||||
|
||||
Boolean updateProductSpuSort(Integer adminId, Integer spuId, Integer sort);
|
||||
|
||||
}
|
||||
|
@ -1,68 +0,0 @@
|
||||
package cn.iocoder.mall.product.api.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SPU + SKU 更新 DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuUpdateDTO {
|
||||
|
||||
/**
|
||||
* Spu 编号
|
||||
*/
|
||||
@NotNull(message = "SPU 编号不能为空")
|
||||
private Integer id;
|
||||
|
||||
// ========== 基本信息 =========
|
||||
/**
|
||||
* SPU 名字
|
||||
*/
|
||||
@NotEmpty(message = "SPU 名字不能为空")
|
||||
private String name;
|
||||
/**
|
||||
* 卖点
|
||||
*/
|
||||
@NotEmpty(message = "卖点不能为空")
|
||||
private String sellPoint;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@NotEmpty(message = "描述不能为空")
|
||||
private String description;
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
@NotNull(message = "分类不能为空")
|
||||
private Integer cid;
|
||||
/**
|
||||
* 商品主图地址
|
||||
*/
|
||||
@NotNull(message = "商品主图不能为空")
|
||||
private List<String> picUrls;
|
||||
|
||||
// ========== 其他信息 =========
|
||||
/**
|
||||
* 是否上架商品(是否可见)。
|
||||
*
|
||||
* true 为已上架
|
||||
* false 为已下架
|
||||
*/
|
||||
@NotNull(message = "是否上架不能为空")
|
||||
private Boolean visible;
|
||||
|
||||
// ========== SKU =========
|
||||
|
||||
/**
|
||||
* SKU 数组
|
||||
*/
|
||||
@NotNull(message = "SKU 不能为空")
|
||||
private List<ProductSkuAddOrUpdateDTO> skus;
|
||||
|
||||
}
|
@ -88,7 +88,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
|
||||
@Override
|
||||
public ProductSpuDetailBO addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO) {
|
||||
ProductSpuDetailBO productSpuDetailBO = addProductSpu0(adminId, productSpuAddDTO);
|
||||
// 如果新增生成,发送创建商品 Topic 消息
|
||||
// TODO 芋艿,先不考虑事务的问题。等后面的 fescar 一起搞
|
||||
sendProductUpdateMessage(productSpuDetailBO.getId());
|
||||
@ -96,76 +95,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
return productSpuDetailBO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) {
|
||||
// 更新商品
|
||||
updateProductSpu0(adminId, productSpuUpdateDTO);
|
||||
// TODO 芋艿,先不考虑事务的问题。等后面的 fescar 一起搞
|
||||
sendProductUpdateMessage(productSpuUpdateDTO.getId());
|
||||
}
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
@Transactional
|
||||
public void updateProductSpu0(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) {
|
||||
// 校验 Spu 是否存在
|
||||
if (productSpuMapper.selectById(productSpuUpdateDTO.getId()) == null) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 校验商品分类分类存在
|
||||
ProductCategoryDO category = productCategoryService.validProductCategory(productSpuUpdateDTO.getCid());
|
||||
if (ProductCategoryConstants.PID_ROOT.equals(category.getPid())) { // 商品只能添加到二级分类下
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2.getCode());
|
||||
}
|
||||
// 校验规格是否存在
|
||||
Set<Integer> productAttrValueIds = new HashSet<>();
|
||||
productSpuUpdateDTO.getSkus().forEach(productSkuAddDTO -> productAttrValueIds.addAll(productSkuAddDTO.getAttrs()));
|
||||
List<ProductAttrAndValuePairBO> attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
||||
true); // 读取规格时,需要考虑规格是否被禁用
|
||||
// 校验 Sku 规格
|
||||
validProductSku(productSpuUpdateDTO.getSkus(), attrAndValuePairList);
|
||||
// 更新 Spu
|
||||
ProductSpuDO updateSpu = ProductSpuConvert.INSTANCE.convert(productSpuUpdateDTO)
|
||||
.setPicUrls(StringUtil.join(productSpuUpdateDTO.getPicUrls(), ","));
|
||||
initSpuFromSkus(updateSpu, productSpuUpdateDTO.getSkus()); // 初始化 sku 相关信息到 spu 中
|
||||
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 (ProductSkuAddOrUpdateDTO 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());
|
||||
insertSku.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateProductSpuSort(Integer adminId, Integer spuId, Integer sort) {
|
||||
// 校验 Spu 是否存在
|
||||
@ -181,21 +110,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProductSpuPageBO getProductSpuPage(ProductSpuPageDTO productSpuPageDTO) {
|
||||
ProductSpuPageBO productSpuPage = new ProductSpuPageBO();
|
||||
// 查询分页数据
|
||||
int offset = (productSpuPageDTO.getPageNo() - 1) * productSpuPageDTO.getPageSize();
|
||||
productSpuPage.setList(ProductSpuConvert.INSTANCE.convert(productSpuMapper.selectListByNameLikeOrderBySortAsc(
|
||||
productSpuPageDTO.getName(), productSpuPageDTO.getCid(), productSpuPageDTO.getHasQuantity(), productSpuPageDTO.getVisible(),
|
||||
offset, productSpuPageDTO.getPageSize())));
|
||||
// 查询分页总数
|
||||
productSpuPage.setTotal(productSpuMapper.selectCountByNameLike(productSpuPageDTO.getName(), productSpuPageDTO.getCid(), productSpuPageDTO.getHasQuantity(),
|
||||
productSpuPageDTO.getVisible()));
|
||||
// 返回结果
|
||||
return productSpuPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductSpuBO> getProductSpuSearchList(ProductSpuSearchListDTO productSpuSearchListDTO) {
|
||||
return ProductSpuConvert.INSTANCE.convert(
|
||||
@ -237,28 +151,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
return ProductSpuConvert.INSTANCE.convert3(skus, spus, attrAndValuePairList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得 sku 数组中,指定规格的 sku
|
||||
*
|
||||
* @param attrs 指定规格
|
||||
* @param skus sku 数组
|
||||
* @return 符合条件的 sku
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
private boolean sendProductUpdateMessage(Integer id) {
|
||||
// 创建 Message 对象
|
||||
ProductUpdateMessage message = new ProductUpdateMessage().setId(id);
|
||||
|
Loading…
Reference in New Issue
Block a user