提交 a347d2a1 authored 作者: YunaiV's avatar YunaiV

清理已迁移的 product 代码

上级 98ad0274
<?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>onemall</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>management-web-app</artifactId>
<description>管理后台,提供管理员管理的所有功能</description>
<dependencyManagement>
<dependencies>
<!-- onemall 基础 bom 文件 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-dependencies</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Web 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-swagger</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-security-admin</artifactId>
</dependency>
<!-- RPC 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-dubbo</artifactId>
</dependency>
<dependency>
<!-- 用户服务 -->
<groupId>cn.iocoder.mall</groupId>
<artifactId>user-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<!-- 系统服务 -->
<groupId>cn.iocoder.mall</groupId>
<artifactId>system-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<!-- 商品服务 -->
<groupId>cn.iocoder.mall</groupId>
<artifactId>product-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<!-- 营销服务 -->
<groupId>cn.iocoder.mall</groupId>
<artifactId>promotion-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<!-- 支付服务 -->
<groupId>cn.iocoder.mall</groupId>
<artifactId>pay-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Registry 和 Config 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<build>
<!-- 设置构建的 jar 包名 -->
<finalName>${project.artifactId}</finalName>
<!-- 使用 spring-boot-maven-plugin 插件打包 -->
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
### /product-attr/page 成功(全部)
GET http://127.0.0.1:18083/management-api/product-attr/key/page?pageNo=1&pageSize=10
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
###
POST http://127.0.0.1:18083/management-api/product-attr/key/create
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
name=桶&status=1
###
POST http://127.0.0.1:18083/management-api/product-attr/value/create
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
attrKeyId=12&name=大桶&status=1
###
\ No newline at end of file
package cn.iocoder.mall.managementweb.controller.product;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.managementweb.controller.product.vo.attr.*;
import cn.iocoder.mall.managementweb.manager.product.ProductAttrKeyManager;
import cn.iocoder.security.annotations.RequiresPermissions;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.common.framework.vo.CommonResult.success;
/**
* 商品规格键 Controller
*/
@RestController
@RequestMapping("/product-attr/")
@Api(tags = "商品规格")
@Validated
public class ProductAttrController {
@Autowired
private ProductAttrKeyManager productAttrKeyManager;
@PostMapping("/key/create")
@ApiOperation("创建商品规格键")
@RequiresPermissions("product:attr-key:create")
public CommonResult<Integer> createProductAttrKey(@Valid ProductAttrKeyCreateReqVO createVO) {
return success(productAttrKeyManager.createProductAttrKey(createVO));
}
@PostMapping("/key/update")
@ApiOperation("更新商品规格键")
@RequiresPermissions("product:attr-key:update")
public CommonResult<Boolean> updateProductAttrKey(@Valid ProductAttrKeyUpdateReqVO updateVO) {
productAttrKeyManager.updateProductAttrKey(updateVO);
return success(true);
}
@GetMapping("/key/get")
@ApiOperation("获得商品规格键")
@ApiImplicitParam(name = "productAttrKeyId", value = "商品规格键编号", required = true, example = "1")
@RequiresPermissions("product:attr-key:page")
public CommonResult<ProductAttrKeyRespVO> getProductAttrKey(@RequestParam("productAttrKeyId") Integer productAttrKeyId) {
return success(productAttrKeyManager.getProductAttrKey(productAttrKeyId));
}
@GetMapping("/key/list")
@ApiOperation("获得商品规格键列表")
@ApiImplicitParam(name = "productAttrKeyIds", value = "商品规格键编号列表", required = true, example = "1,3")
@RequiresPermissions("product:attr-key:page")
public CommonResult<List<ProductAttrKeyRespVO>> listProductAttrKeys(@RequestParam("productAttrKeyIds") List<Integer> productAttrKeyIds) {
return success(productAttrKeyManager.listProductAttrKeys(productAttrKeyIds));
}
@GetMapping("/key/page")
@ApiOperation("获得商品规格键分页")
@RequiresPermissions("product:attr-key:page")
public CommonResult<PageResult<ProductAttrKeyRespVO>> pageProductAttrKey(ProductAttrKeyPageReqVO pageVO) {
return success(productAttrKeyManager.pageProductAttrKey(pageVO));
}
@PostMapping("/value/create")
@ApiOperation("创建商品规格值")
@RequiresPermissions("product:attr-value:create")
public CommonResult<Integer> createProductAttrValue(@Valid ProductAttrValueCreateReqVO createVO) {
return success(productAttrKeyManager.createProductAttrValue(createVO));
}
@PostMapping("/value/update")
@ApiOperation("更新商品规格值")
@RequiresPermissions("product:attr-value:update")
public CommonResult<Boolean> updateProductAttrValue(@Valid ProductAttrValueUpdateReqVO updateVO) {
productAttrKeyManager.updateProductAttrValue(updateVO);
return success(true);
}
@GetMapping("/value/get")
@ApiOperation("获得商品规格值")
@ApiImplicitParam(name = "productAttrValueId", value = "商品规格值编号", required = true)
@RequiresPermissions("product:attr-value:list")
public CommonResult<ProductAttrValueRespVO> getProductAttrValue(@RequestParam("productAttrValueId") Integer productAttrValueId) {
return success(productAttrKeyManager.getProductAttrValue(productAttrValueId));
}
@GetMapping("/value/list")
@ApiOperation("获得商品规格值列表")
@RequiresPermissions("product:attr-value:list")
public CommonResult<List<ProductAttrValueRespVO>> listProductAttrValues(@Valid ProductAttrValueListQueryReqVO queryReqVO) {
return success(productAttrKeyManager.listProductAttrValues(queryReqVO));
}
}
### /product-attr/page 成功(全部)
GET http://127.0.0.1:18083/management-api/product-attr/key/page?pageNo=1&pageSize=10
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
###
POST http://127.0.0.1:18083/management-api/product-brand/create
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
name=光明牌&description=光明牌电灯泡&status=1
###
GET http://127.0.0.1:18083/management-api/product-brand/get?productBrandId=3
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
###
\ No newline at end of file
package cn.iocoder.mall.managementweb.controller.product;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.managementweb.controller.product.vo.brand.ProductBrandCreateReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.brand.ProductBrandPageReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.brand.ProductBrandRespVO;
import cn.iocoder.mall.managementweb.controller.product.vo.brand.ProductBrandUpdateReqVO;
import cn.iocoder.mall.managementweb.manager.product.ProductBrandManager;
import cn.iocoder.security.annotations.RequiresPermissions;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.common.framework.vo.CommonResult.success;
/**
* 商品品牌 Controller
*/
@RestController
@RequestMapping("/product-brand")
@Api(tags = "商品品牌")
@Validated
public class ProductBrandController {
@Autowired
private ProductBrandManager productBrandManager;
@PostMapping("/create")
@ApiOperation("创建商品品牌")
@RequiresPermissions("product:brand:create")
public CommonResult<Integer> createProductBrand(@Valid ProductBrandCreateReqVO createVO) {
return success(productBrandManager.createProductBrand(createVO));
}
@PostMapping("/update")
@ApiOperation("更新商品品牌")
@RequiresPermissions("product:brand:update")
public CommonResult<Boolean> updateProductBrand(@Valid ProductBrandUpdateReqVO updateVO) {
productBrandManager.updateProductBrand(updateVO);
return success(true);
}
@PostMapping("/delete")
@ApiOperation("删除商品品牌")
@ApiImplicitParam(name = "productBrandId", value = "商品品牌编号", required = true)
@RequiresPermissions("product:brand:delete")
public CommonResult<Boolean> deleteProductBrand(@RequestParam("productBrandId") Integer productBrandId) {
productBrandManager.deleteProductBrand(productBrandId);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得商品品牌")
@ApiImplicitParam(name = "productBrandId", value = "商品品牌编号", required = true)
@RequiresPermissions("product:brand:page")
public CommonResult<ProductBrandRespVO> getProductBrand(@RequestParam("productBrandId") Integer productBrandId) {
return success(productBrandManager.getProductBrand(productBrandId));
}
@GetMapping("/list")
@ApiOperation("获得商品品牌列表")
@ApiImplicitParam(name = "productBrandIds", value = "商品品牌编号列表", required = true)
@RequiresPermissions("product:brand:page")
public CommonResult<List<ProductBrandRespVO>> listProductBrands(@RequestParam("productBrandIds") List<Integer> productBrandIds) {
return success(productBrandManager.listProductBrands(productBrandIds));
}
@GetMapping("/page")
@ApiOperation("获得商品品牌分页")
@RequiresPermissions("product:brand:page")
public CommonResult<PageResult<ProductBrandRespVO>> pageProductBrand(ProductBrandPageReqVO pageVO) {
return success(productBrandManager.pageProductBrand(pageVO));
}
}
### /product-category/tree 成功
GET http://127.0.0.1:18083/management-api/product-category/tree
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
###
POST http://127.0.0.1:18083/management-api/product-category/create
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
pid=0&name=美食&description=吃喝拉撒&sort=7&status=1
###
\ No newline at end of file
package cn.iocoder.mall.managementweb.controller.product;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.managementweb.controller.product.vo.category.ProductCategoryCreateReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.category.ProductCategoryTreeNodeRespVO;
import cn.iocoder.mall.managementweb.controller.product.vo.category.ProductCategoryUpdateReqVO;
import cn.iocoder.mall.managementweb.manager.product.ProductCategoryManager;
import cn.iocoder.security.annotations.RequiresPermissions;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.common.framework.vo.CommonResult.success;
/**
* 商品分类 Controller
*/
@RestController
@RequestMapping("/product-category")
@Api(tags = "商品分类")
@Validated
public class ProductCategoryController {
@Autowired
private ProductCategoryManager productCategoryManager;
@PostMapping("/create")
@ApiOperation("创建商品分类")
@RequiresPermissions("product:category:create")
public CommonResult<Integer> createProductCategory(@Valid ProductCategoryCreateReqVO createVO) {
return success(productCategoryManager.createProductCategory(createVO));
}
@PostMapping("/update")
@ApiOperation("更新商品分类")
@RequiresPermissions("product:category:update")
public CommonResult<Boolean> updateProductCategory(@Valid ProductCategoryUpdateReqVO updateVO) {
productCategoryManager.updateProductCategory(updateVO);
return success(true);
}
@PostMapping("/delete")
@ApiOperation("删除商品分类")
@RequiresPermissions("product:category:delete")
@ApiImplicitParam(name = "productCategoryId", value = "商品分类编号", required = true)
public CommonResult<Boolean> deleteProductCategory(@RequestParam("productCategoryId") Integer productCategoryId) {
productCategoryManager.deleteProductCategory(productCategoryId);
return success(true);
}
@GetMapping("/tree")
@ApiOperation("获得资源树")
@RequiresPermissions("product:category:tree")
public CommonResult<List<ProductCategoryTreeNodeRespVO>> treeProductCategory() {
return success(productCategoryManager.treeProductCategory());
}
}
### /product-spu/page 成功(全部)
GET http://127.0.0.1:18083/management-api/product-spu/page?pageNo=1&pageSize=100
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
### /product-spu/page 成功(有库存 + 上架)
GET http://127.0.0.1:18083/management-api/product-spu/page?pageNo=1&pageSize=10&hasQuantity=true&visible=true
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
### /product-spu/page 成功(无库存 + 下架)
GET http://127.0.0.1:18083/management-api/product-spu/page?pageNo=1&pageSize=10&hasQuantity=false&visible=false
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
### /product-spu/create 成功
POST http://127.0.0.1:18083/management-api/product-spu/create
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
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 http://127.0.0.1:18083/management-api/product-spu/create
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
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 http://127.0.0.1:18083/management-api/product-spu/create
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
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 http://127.0.0.1:18083/management-api/product-spu/update
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer yudaoyuanma
id=64&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/get
GET http://127.0.0.1:18083/management-api/product-spu/get?productSpuId=32
Content-Type: application/x-www-form-urlencoded
Authorization:Bearer yudaoyuanma
###
### /product-spu/get
GET http://127.0.0.1:18083/management-api/product-spu/list?productSpuIds=32,33,34
Content-Type: application/x-www-form-urlencoded
Authorization:Bearer yudaoyuanma
###
...@@ -31,33 +31,6 @@ public class ProductSpuController { ...@@ -31,33 +31,6 @@ public class ProductSpuController {
@Autowired @Autowired
private ProductSpuManager productSpuManager; private ProductSpuManager productSpuManager;
@PostMapping("/create")
@ApiOperation("创建商品 SPU")
public CommonResult<Integer> createProductSpu(@Valid ProductSpuCreateReqVO createVO) {
return success(productSpuManager.createProductSpu(createVO));
}
@PostMapping("/update")
@ApiOperation("更新商品 SPU")
public CommonResult<Boolean> updateProductSpu(@Valid ProductSpuUpdateReqVO updateVO) {
productSpuManager.updateProductSpu(updateVO);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得商品 SPU")
@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)
public CommonResult<List<ProductSpuRespVO>> listProductSpus(@RequestParam("productSpuIds") List<Integer> productSpuIds) {
return success(productSpuManager.listProductSpus(productSpuIds));
}
@GetMapping("/page") @GetMapping("/page")
@ApiOperation("获得商品 SPU 分页") @ApiOperation("获得商品 SPU 分页")
public CommonResult<PageResult<ProductSpuRespVO>> pageProductSpu(ProductSpuPageReqVO pageVO) { public CommonResult<PageResult<ProductSpuRespVO>> pageProductSpu(ProductSpuPageReqVO pageVO) {
......
package cn.iocoder.mall.managementweb.controller.product.vo.attr;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@ApiModel("商品规格键创建 Request VO")
@Data
public class ProductAttrKeyCreateReqVO {
@ApiModelProperty(value = "规格键名称", required = true, example = "尺寸")
@NotEmpty(message = "规格键名称不能为空")
private String name;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}
package cn.iocoder.mall.managementweb.controller.product.vo.attr;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import cn.iocoder.common.framework.vo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ApiModel("商品规格键分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
public class ProductAttrKeyPageReqVO extends PageParam {
@ApiModelProperty(value = "规格键名称", required = true, example = "尺寸", notes = "模糊匹配")
private String name;
@ApiModelProperty(value = "状态", example = "1", notes = "见 CommonStatusEnum 枚举")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}
package cn.iocoder.mall.managementweb.controller.product.vo.attr;
import lombok.*;
import io.swagger.annotations.*;
import java.util.*;
@ApiModel("商品规格键 Response VO")
@Data
public class ProductAttrKeyRespVO {
@ApiModelProperty(value = "规格键编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "规格键名称", required = true, example = "尺寸")
private String name;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
private Integer status;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}
package cn.iocoder.mall.managementweb.controller.product.vo.attr;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@ApiModel("商品规格键更新 Request VO")
@Data
public class ProductAttrKeyUpdateReqVO {
@ApiModelProperty(value = "规格键编号", required = true, example = "1")
@NotNull(message = "规格键编号不能为空")
private Integer id;
@ApiModelProperty(value = "规格键名称", required = true, example = "尺寸")
@NotEmpty(message = "规格键名称不能为空")
private String name;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}
package cn.iocoder.mall.managementweb.controller.product.vo.attr;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@ApiModel("商品规格值创建 Request VO")
@Data
public class ProductAttrValueCreateReqVO {
@ApiModelProperty(value = "规格键编号", required = true, example = "2")
@NotNull(message = "规格键编号不能为空")
private Integer attrKeyId;
@ApiModelProperty(value = "规格值名字", required = true, example = "XXL")
@NotEmpty(message = "规格值名字不能为空")
private String name;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}
package cn.iocoder.mall.managementweb.controller.product.vo.attr;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
@ApiModel("商品规格值的列表查询条件 Request VO")
@Data
@Accessors(chain = true)
public class ProductAttrValueListQueryReqVO {
@ApiModelProperty(value = "商品规格值编号列表", example = "1, 3")
private List<Integer> productAttrValueIds;
@ApiModelProperty(value = "规格键编号", required = true, example = "2")
private Integer productAttrKeyId;
}
package cn.iocoder.mall.managementweb.controller.product.vo.attr;
import lombok.*;
import io.swagger.annotations.*;
import java.util.*;
@ApiModel("商品规格值 Response VO")
@Data
public class ProductAttrValueRespVO {
@ApiModelProperty(value = "规格值编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "规格键编号", required = true, example = "2")
private Integer attrKeyId;
@ApiModelProperty(value = "规格值名字", required = true, example = "XXL")
private String name;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
private Integer status;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}
package cn.iocoder.mall.managementweb.controller.product.vo.attr;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@ApiModel("商品规格值更新 Request VO")
@Data
public class ProductAttrValueUpdateReqVO {
@ApiModelProperty(value = "规格值编号", required = true, example = "1")
@NotNull(message = "规格值编号不能为空")
private Integer id;
@ApiModelProperty(value = "规格值名字", required = true, example = "XXL")
@NotEmpty(message = "规格值名字不能为空")
private String name;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}
package cn.iocoder.mall.managementweb.controller.product.vo.brand;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("商品品牌创建 Request VO")
@Data
public class ProductBrandCreateReqVO {
@ApiModelProperty(value = "品牌名称", required = true, example = "这个商品品牌很吊")
private String name;
@ApiModelProperty(value = "品牌描述", example = "这个商品描述很吊")
private String description;
@ApiModelProperty(value = "品牌名图片", example = "http://www.iocoder.cn/xx.jpg")
private String picUrl;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
private Integer status;
}
package cn.iocoder.mall.managementweb.controller.product.vo.brand;
import cn.iocoder.common.framework.vo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ApiModel("商品品牌分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
public class ProductBrandPageReqVO extends PageParam {
@ApiModelProperty(value = "品牌名称", required = true, notes = "模糊匹配", example = "这个商品品牌很吊")
private String name;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
private Integer status;
}
package cn.iocoder.mall.managementweb.controller.product.vo.brand;
import lombok.*;
import io.swagger.annotations.*;
import java.util.*;
@ApiModel("商品品牌 Response VO")
@Data
public class ProductBrandRespVO {
@ApiModelProperty(value = "品牌编号", required = true, example = "1024")
private Integer id;
@ApiModelProperty(value = "品牌名称", required = true, example = "这个商品品牌很吊")
private String name;
@ApiModelProperty(value = "品牌描述", example = "这个商品描述很吊")
private String description;
@ApiModelProperty(value = "品牌名图片", example = "http://www.iocoder.cn/xx.jpg")
private String picUrl;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
private Integer status;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}
package cn.iocoder.mall.managementweb.controller.product.vo.brand;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("商品品牌更新 Request VO")
@Data
public class ProductBrandUpdateReqVO {
@ApiModelProperty(value = "品牌编号", required = true, example = "1024")
private Integer id;
@ApiModelProperty(value = "品牌名称", required = true, example = "这个商品品牌很吊")
private String name;
@ApiModelProperty(value = "品牌描述", example = "这个商品描述很吊")
private String description;
@ApiModelProperty(value = "品牌名图片", example = "http://www.iocoder.cn/xx.jpg")
private String picUrl;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
private Integer status;
}
package cn.iocoder.mall.managementweb.controller.product.vo.category;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@ApiModel("商品分类创建 Request VO")
@Data
public class ProductCategoryCreateReqVO {
@ApiModelProperty(value = "父分类编号", required = true, example = "0")
@NotNull(message = "父分类编号不能为空")
private Integer pid;
@ApiModelProperty(value = "分类名称", required = true, example = "手机")
@NotEmpty(message = "分类名称不能为空")
private String name;
@ApiModelProperty(value = "分类描述", required = true, example = "这个商品很吊")
private String description;
@ApiModelProperty(value = "分类图片", notes = "一般情况下,只有根分类才有图片", example = "http://www.iocoder.cn/xx.jpg")
private String picUrl;
@ApiModelProperty(value = "分类排序", required = true, example = "10")
@NotNull(message = "分类排序不能为空")
private Integer sort;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}
package cn.iocoder.mall.managementweb.controller.product.vo.category;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@ApiModel("商品分类 Response VO")
@Data
public class ProductCategoryRespVO {
@ApiModelProperty(value = "分类编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "父分类编号", required = true, example = "0")
private Integer pid;
@ApiModelProperty(value = "分类名称", required = true, example = "手机")
private String name;
@ApiModelProperty(value = "分类描述", required = true, example = "这个商品分类很吊")
private String description;
@ApiModelProperty(value = "分类图片", notes = "一般情况下,只有根分类才有图片", example = "http://www.iocoder.cn/xx.jpg")
private String picUrl;
@ApiModelProperty(value = "分类排序", required = true, example = "10")
private Integer sort;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
private Integer status;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}
package cn.iocoder.mall.managementweb.controller.product.vo.category;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
import java.util.List;
@ApiModel("商品分类 Response VO")
@Data
public class ProductCategoryTreeNodeRespVO {
@ApiModelProperty(value = "分类编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "父分类编号", required = true, example = "0")
private Integer pid;
@ApiModelProperty(value = "分类名称", required = true, example = "手机")
private String name;
@ApiModelProperty(value = "分类描述", required = true, example = "这个商品很吊")
private String description;
@ApiModelProperty(value = "分类图片", notes = "一般情况下,只有根分类才有图片", example = "http://www.iocoder.cn/xx.jpg")
private String picUrl;
@ApiModelProperty(value = "分类排序", required = true, example = "10")
private Integer sort;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
private Integer status;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
/**
* 子节点
*/
private List<ProductCategoryTreeNodeRespVO> children;
}
package cn.iocoder.mall.managementweb.controller.product.vo.category;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@ApiModel("商品分类更新 Request VO")
@Data
public class ProductCategoryUpdateReqVO {
@ApiModelProperty(value = "分类编号", required = true, example = "1")
@NotNull(message = "分类编号不能为空")
private Integer id;
@ApiModelProperty(value = "父分类编号", required = true, example = "0")
@NotNull(message = "父分类编号不能为空")
private Integer pid;
@ApiModelProperty(value = "分类名称", required = true, example = "手机")
@NotEmpty(message = "分类名称不能为空")
private String name;
@ApiModelProperty(value = "分类描述", required = true, example = "这个商品很吊")
private String description;
@ApiModelProperty(value = "分类图片", notes = "一般情况下,只有根分类才有图片", example = "http://www.iocoder.cn/xx.jpg")
private String picUrl;
@ApiModelProperty(value = "分类排序", required = true, example = "10")
@NotNull(message = "分类排序不能为空")
private Integer sort;
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}
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")
@Data
public class ProductSpuCreateReqVO {
/**
* 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, example = "芋艿")
@NotEmpty(message = "SPU 名字不能为空")
private String name;
@ApiModelProperty(value = "卖点", required = true, example = "好吃好玩")
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
@ApiModelProperty(value = "描述", required = true, example = "我是哈哈哈")
@NotEmpty(message = "描述不能为空")
private String description;
@ApiModelProperty(value = "分类编号", required = true, example = "1")
@NotNull(message = "分类编号不能为空")
private Integer cid;
@ApiModelProperty(value = "商品主图地址", required = true, example = "http://www.iocoder.cn/xxx.jpg", notes = "多个之间,使用逗号分隔")
@NotEmpty(message = "商品主图地址不能为空")
private List<String> picUrls;
@ApiModelProperty(value = "是否上架商品", required = true, example = "true")
@NotNull(message = "是否上架商品不能为空")
private Boolean visible;
// ========== SKU =========
/**
* SKU 数组
*/
@NotNull(message = "SKU 不能为空")
@Valid
private List<Sku> skus;
}
package cn.iocoder.mall.managementweb.controller.product.vo.spu;
import lombok.*;
import io.swagger.annotations.*;
import java.util.*;
@ApiModel("商品 SPU Response VO")
@Data
public class ProductSpuRespVO {
@ApiModelProperty(value = "SPU 编号", required = true)
private Integer id;
@ApiModelProperty(value = "SPU 名字", required = true, example = "芋艿")
private String name;
@ApiModelProperty(value = "卖点", required = true, example = "好吃好玩")
private String sellPoint;
@ApiModelProperty(value = "描述", required = true, example = "我是哈哈哈")
private String description;
@ApiModelProperty(value = "分类编号", required = true, example = "1")
private Integer cid;
@ApiModelProperty(value = "商品主图地址", required = true, example = "http://www.iocoder.cn/xxx.jpg", notes = "多个之间,使用逗号分隔")
private List<String> picUrls;
@ApiModelProperty(value = "是否上架商品", required = true, example = "true")
private Boolean visible;
@ApiModelProperty(value = "排序字段", required = true, example = "1024")
private Integer sort;
@ApiModelProperty(value = "价格", required = true, example = "233", notes = "单位:分")
private Integer price;
@ApiModelProperty(value = "库存数量", required = true, example = "1024")
private Integer quantity;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}
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")
@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, example = "芋艿")
@NotEmpty(message = "SPU 名字不能为空")
private String name;
@ApiModelProperty(value = "卖点", required = true, example = "好吃好玩")
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
@ApiModelProperty(value = "描述", required = true, example = "我是哈哈哈")
@NotEmpty(message = "描述不能为空")
private String description;
@ApiModelProperty(value = "分类编号", required = true, example = "1")
@NotNull(message = "分类编号不能为空")
private Integer cid;
@ApiModelProperty(value = "商品主图地址", required = true, example = "http://www.iocoder.cn/xxx.jpg", notes = "多个之间,使用逗号分隔")
@NotEmpty(message = "商品主图地址不能为空")
private List<String> picUrls;
@ApiModelProperty(value = "是否上架商品", required = true, example = "true")
@NotNull(message = "是否上架商品不能为空")
private Boolean visible;
// ========== SKU =========
/**
* SKU 数组
*/
@NotNull(message = "SKU 不能为空")
@Valid
private List<ProductSpuCreateReqVO.Sku> skus;
}
package cn.iocoder.mall.managementweb.convert.product;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.managementweb.controller.product.vo.attr.*;
import cn.iocoder.mall.productservice.rpc.attr.dto.*;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductAttrConvert {
ProductAttrConvert INSTANCE = Mappers.getMapper(ProductAttrConvert.class);
ProductAttrKeyCreateReqDTO convert(ProductAttrKeyCreateReqVO bean);
ProductAttrKeyUpdateReqDTO convert(ProductAttrKeyUpdateReqVO bean);
ProductAttrKeyRespVO convert(ProductAttrKeyRespDTO bean);
List<ProductAttrKeyRespVO> convertList(List<ProductAttrKeyRespDTO> list);
PageResult<ProductAttrKeyRespVO> convertPage(PageResult<ProductAttrKeyRespDTO> page);
ProductAttrKeyPageReqDTO convert(ProductAttrKeyPageReqVO bean);
ProductAttrValueCreateReqDTO convert(ProductAttrValueCreateReqVO bean);
ProductAttrValueUpdateReqDTO convert(ProductAttrValueUpdateReqVO bean);
ProductAttrValueRespVO convert(ProductAttrValueRespDTO bean);
List<ProductAttrValueRespVO> convertList02(List<ProductAttrValueRespDTO> list);
ProductAttrValueListQueryReqDTO convert(ProductAttrValueListQueryReqVO bean);
}
package cn.iocoder.mall.managementweb.convert.product;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.managementweb.controller.product.vo.brand.ProductBrandCreateReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.brand.ProductBrandPageReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.brand.ProductBrandRespVO;
import cn.iocoder.mall.managementweb.controller.product.vo.brand.ProductBrandUpdateReqVO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandPageReqDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandRespDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandUpdateReqDTO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductBrandConvert {
ProductBrandConvert INSTANCE = Mappers.getMapper(ProductBrandConvert.class);
ProductBrandCreateReqDTO convert(ProductBrandCreateReqVO bean);
ProductBrandUpdateReqDTO convert(ProductBrandUpdateReqVO bean);
ProductBrandRespVO convert(ProductBrandRespDTO bean);
List<ProductBrandRespVO> convertList(List<ProductBrandRespDTO> list);
PageResult<ProductBrandRespVO> convertPage(PageResult<ProductBrandRespDTO> page);
ProductBrandPageReqDTO convert(ProductBrandPageReqVO bean);
}
package cn.iocoder.mall.managementweb.convert.product;
import cn.iocoder.mall.managementweb.controller.product.vo.category.ProductCategoryCreateReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.category.ProductCategoryRespVO;
import cn.iocoder.mall.managementweb.controller.product.vo.category.ProductCategoryTreeNodeRespVO;
import cn.iocoder.mall.managementweb.controller.product.vo.category.ProductCategoryUpdateReqVO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryRespDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryUpdateReqDTO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface ProductCategoryConvert {
ProductCategoryConvert INSTANCE = Mappers.getMapper(ProductCategoryConvert.class);
ProductCategoryCreateReqDTO convert(ProductCategoryCreateReqVO bean);
ProductCategoryUpdateReqDTO convert(ProductCategoryUpdateReqVO bean);
ProductCategoryRespVO convert(ProductCategoryRespDTO bean);
ProductCategoryTreeNodeRespVO convertTreeNode(ProductCategoryRespDTO bean);
}
package cn.iocoder.mall.managementweb.convert.product;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuCreateReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuPageReqVO;
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 org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductSpuConvert {
ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class);
ProductSpuAndSkuCreateReqDTO convert(ProductSpuCreateReqVO bean);
ProductSpuAndSkuUpdateReqDTO convert(ProductSpuUpdateReqVO bean);
ProductSpuRespVO convert(ProductSpuRespDTO bean);
List<ProductSpuRespVO> convertList(List<ProductSpuRespDTO> list);
PageResult<ProductSpuRespVO> convertPage(PageResult<ProductSpuRespDTO> page);
ProductSpuPageReqDTO convert(ProductSpuPageReqVO bean);
}
package cn.iocoder.mall.managementweb.convert.user;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.managementweb.controller.user.vo.UserPageReqVO;
import cn.iocoder.mall.managementweb.controller.user.vo.UserRespVO;
import cn.iocoder.mall.managementweb.controller.user.vo.UserUpdateInfoReqVO;
import cn.iocoder.mall.managementweb.controller.user.vo.UserUpdateStatusReqVO;
import cn.iocoder.mall.userservice.rpc.user.dto.UserPageReqDTO;
import cn.iocoder.mall.userservice.rpc.user.dto.UserRespDTO;
import cn.iocoder.mall.userservice.rpc.user.dto.UserUpdateReqDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface UserConvert {
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
UserUpdateReqDTO convert(UserUpdateInfoReqVO bean);
UserRespVO convert(UserRespDTO bean);
List<UserRespVO> convertList(List<UserRespDTO> list);
UserPageReqDTO convert(UserPageReqVO bean);
PageResult<UserRespVO> convertPage(PageResult<UserRespDTO> bean);
@Mapping(source = "userId", target = "id")
UserUpdateReqDTO convert(UserUpdateStatusReqVO bean);
}
package cn.iocoder.mall.managementweb.manager.product;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.managementweb.controller.product.vo.brand.ProductBrandCreateReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.brand.ProductBrandPageReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.brand.ProductBrandRespVO;
import cn.iocoder.mall.managementweb.controller.product.vo.brand.ProductBrandUpdateReqVO;
import cn.iocoder.mall.managementweb.convert.product.ProductBrandConvert;
import cn.iocoder.mall.productservice.rpc.brand.ProductBrandFeign;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandRespDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 商品品牌 Manager
*/
@Service
public class ProductBrandManager {
@Autowired
ProductBrandFeign productBrandFeign;
/**
* 创建商品品牌
*
* @param createVO 创建商品品牌 VO
* @return 商品品牌
*/
public Integer createProductBrand(ProductBrandCreateReqVO createVO) {
CommonResult<Integer> createProductBrandResult = productBrandFeign.createProductBrand(ProductBrandConvert.INSTANCE.convert(createVO));
createProductBrandResult.checkError();
return createProductBrandResult.getData();
}
/**
* 更新商品品牌
*
* @param updateVO 更新商品品牌 VO
*/
public void updateProductBrand(ProductBrandUpdateReqVO updateVO) {
CommonResult<Boolean> updateProductBrandResult = productBrandFeign.updateProductBrand(ProductBrandConvert.INSTANCE.convert(updateVO));
updateProductBrandResult.checkError();
}
/**
* 删除商品品牌
*
* @param productBrandId 商品品牌编号
*/
public void deleteProductBrand(Integer productBrandId) {
CommonResult<Boolean> deleteProductBrandResult = productBrandFeign.deleteProductBrand(productBrandId);
deleteProductBrandResult.checkError();
}
/**
* 获得商品品牌
*
* @param productBrandId 商品品牌编号
* @return 商品品牌
*/
public ProductBrandRespVO getProductBrand(Integer productBrandId) {
CommonResult<ProductBrandRespDTO> getProductBrandResult = productBrandFeign.getProductBrand(productBrandId);
getProductBrandResult.checkError();
return ProductBrandConvert.INSTANCE.convert(getProductBrandResult.getData());
}
/**
* 获得商品品牌列表
*
* @param productBrandIds 商品品牌编号列表
* @return 商品品牌列表
*/
public List<ProductBrandRespVO> listProductBrands(List<Integer> productBrandIds) {
CommonResult<List<ProductBrandRespDTO>> listProductBrandResult = productBrandFeign.listProductBrands(productBrandIds);
listProductBrandResult.checkError();
return ProductBrandConvert.INSTANCE.convertList(listProductBrandResult.getData());
}
/**
* 获得商品品牌分页
*
* @param pageVO 商品品牌分页查询
* @return 商品品牌分页结果
*/
public PageResult<ProductBrandRespVO> pageProductBrand(ProductBrandPageReqVO pageVO) {
CommonResult<PageResult<ProductBrandRespDTO>> pageProductBrandResult = productBrandFeign.pageProductBrand(ProductBrandConvert.INSTANCE.convert(pageVO));
pageProductBrandResult.checkError();
return ProductBrandConvert.INSTANCE.convertPage(pageProductBrandResult.getData());
}
}
package cn.iocoder.mall.managementweb.manager.product;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.managementweb.controller.product.vo.category.ProductCategoryCreateReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.category.ProductCategoryTreeNodeRespVO;
import cn.iocoder.mall.managementweb.controller.product.vo.category.ProductCategoryUpdateReqVO;
import cn.iocoder.mall.managementweb.convert.product.ProductCategoryConvert;
import cn.iocoder.mall.productservice.enums.category.ProductCategoryIdEnum;
import cn.iocoder.mall.productservice.rpc.category.ProductCategoryFeign;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryListQueryReqDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryRespDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
* 商品分类表 Manager
*/
@Service
@Slf4j
public class ProductCategoryManager {
@Autowired
private ProductCategoryFeign productCategoryFeign;
/**
* 创建商品分类表
*
* @param createVO 创建商品分类表 VO
* @return 商品分类表
*/
public Integer createProductCategory(ProductCategoryCreateReqVO createVO) {
CommonResult<Integer> createProductCategoryResult = productCategoryFeign.createProductCategory(ProductCategoryConvert.INSTANCE.convert(createVO));
createProductCategoryResult.checkError();
return createProductCategoryResult.getData();
}
/**
* 更新商品分类表
*
* @param updateVO 更新商品分类表 VO
*/
public void updateProductCategory(ProductCategoryUpdateReqVO updateVO) {
CommonResult<Boolean> updateProductCategoryResult = productCategoryFeign.updateProductCategory(ProductCategoryConvert.INSTANCE.convert(updateVO));
updateProductCategoryResult.checkError();
}
/**
* 删除商品分类表
*
* @param productCategoryId 商品分类表编号
*/
public void deleteProductCategory(Integer productCategoryId) {
CommonResult<Boolean> deleteProductCategoryResult = productCategoryFeign.deleteProductCategory(productCategoryId);
deleteProductCategoryResult.checkError();
}
/**
* 获得商品分类树结构
*
* @return 商品分类树结构
*/
public List<ProductCategoryTreeNodeRespVO> treeProductCategory() {
// 获得商品分类全列表
CommonResult<List<ProductCategoryRespDTO>> listProductCategories = productCategoryFeign.listProductCategories(new ProductCategoryListQueryReqDTO());
listProductCategories.checkError();
// 构建菜单树
return buildProductCategoryTree(listProductCategories.getData());
}
/**
* 构建商品分类树
*
* @param productCategories 商品分类列表
* @return 商品分类树
*/
private static List<ProductCategoryTreeNodeRespVO> buildProductCategoryTree(List<ProductCategoryRespDTO> productCategories) {
// 排序,保证菜单的有序性
productCategories.sort(Comparator.comparing(ProductCategoryRespDTO::getSort));
// 构建菜单树
// 使用 LinkedHashMap 的原因,是为了排序 。实际也可以用 Stream API ,就是太丑了。
Map<Integer, ProductCategoryTreeNodeRespVO> treeNodeMap = new LinkedHashMap<>();
productCategories.forEach(category -> treeNodeMap.put(category.getId(), ProductCategoryConvert.INSTANCE.convertTreeNode(category)));
// 处理父子关系
treeNodeMap.values().stream().filter(node -> !node.getPid().equals(ProductCategoryIdEnum.ROOT.getId())).forEach((childNode) -> {
// 获得父节点
ProductCategoryTreeNodeRespVO parentNode = treeNodeMap.get(childNode.getPid());
if (parentNode == null) {
log.error("[buildProductCategoryTree][category({}) 找不到父商品分类({})]", childNode.getId(), childNode.getPid());
return;
}
// 将自己添加到父节点中
if (parentNode.getChildren() == null) {
parentNode.setChildren(new ArrayList<>());
}
parentNode.getChildren().add(childNode);
});
// 获得到所有的根节点
return treeNodeMap.values().stream().filter(node -> node.getPid().equals(ProductCategoryIdEnum.ROOT.getId()))
.collect(Collectors.toList());
}
}
package cn.iocoder.mall.managementweb.manager.product;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuCreateReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuPageReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuRespVO;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuUpdateReqVO;
import cn.iocoder.mall.managementweb.convert.product.ProductSpuConvert;
import cn.iocoder.mall.productservice.rpc.spu.ProductSpuFeign;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 商品 SPU Manager
*/
@Service
public class ProductSpuManager {
@Autowired
private ProductSpuFeign productSpuFeign;
/**
* 获得商品 SPU
*
* @param productSpuId 商品 SPU编号
* @return 商品 SPU
*/
public ProductSpuRespVO getProductSpu(Integer productSpuId) {
CommonResult<ProductSpuRespDTO> getProductSpuResult = productSpuFeign.getProductSpu(productSpuId);
getProductSpuResult.checkError();
return ProductSpuConvert.INSTANCE.convert(getProductSpuResult.getData());
}
/**
* 获得商品 SPU列表
*
* @param productSpuIds 商品 SPU编号列表
* @return 商品 SPU列表
*/
public List<ProductSpuRespVO> listProductSpus(List<Integer> productSpuIds) {
CommonResult<List<ProductSpuRespDTO>> listProductSpuResult = productSpuFeign.listProductSpus(productSpuIds);
listProductSpuResult.checkError();
return ProductSpuConvert.INSTANCE.convertList(listProductSpuResult.getData());
}
/**
* 获得商品 SPU分页
*
* @param pageVO 商品 SPU分页查询
* @return 商品 SPU分页结果
*/
public PageResult<ProductSpuRespVO> pageProductSpu(ProductSpuPageReqVO pageVO) {
CommonResult<PageResult<ProductSpuRespDTO>> pageProductSpuResult = productSpuFeign.pageProductSpu(ProductSpuConvert.INSTANCE.convert(pageVO));
pageProductSpuResult.checkError();
return ProductSpuConvert.INSTANCE.convertPage(pageProductSpuResult.getData());
}
}
<?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>product</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>product-service-impl</artifactId>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>product-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>user-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- RPC 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!-- Registry 和 Config 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Transaction 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-seata</artifactId>
</dependency>
<!-- MQ 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>user-biz</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 提供给 mapstruct 使用 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package cn.iocoder.mall.product.convert;
import cn.iocoder.mall.product.api.bo.*;
import cn.iocoder.mall.product.api.dto.ProductAttrAddDTO;
import cn.iocoder.mall.product.api.dto.ProductAttrUpdateDTO;
import cn.iocoder.mall.product.api.dto.ProductAttrValueAddDTO;
import cn.iocoder.mall.product.api.dto.ProductAttrValueUpdateDTO;
import cn.iocoder.mall.product.dataobject.ProductAttrDO;
import cn.iocoder.mall.product.dataobject.ProductAttrValueDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductAttrConvert {
ProductAttrConvert INSTANCE = Mappers.getMapper(ProductAttrConvert.class);
@Mappings({})
List<ProductAttrDetailBO> convert(List<ProductAttrDO> attrs);
@Mappings({})
ProductAttrValueDetailBO convert(ProductAttrValueDO value);
@Mappings({})
List<ProductAttrValueDetailBO> convert2(List<ProductAttrValueDO> values);
@Mappings({})
List<ProductAttrSimpleBO> convert3(List<ProductAttrDO> attrs);
@Mappings({})
ProductAttrValueSimpleBO convert3(ProductAttrValueDO value); // 保证 convert4 能够映射到这个方法
@Mappings({})
List<ProductAttrValueSimpleBO> convert4(List<ProductAttrValueDO> values);
@Mappings({})
ProductAttrDO convert(ProductAttrAddDTO productAttrAddDTO);
@Mappings({})
ProductAttrDO convert(ProductAttrUpdateDTO productAttrUpdateDTO);
@Mappings({})
ProductAttrValueDO convert(ProductAttrValueAddDTO productAttrValueAddDTO);
@Mappings({})
ProductAttrValueDO convert(ProductAttrValueUpdateDTO productAttrValueUpdateDTO);
@Mappings({})
ProductAttrBO convert(ProductAttrDO productAttrDO);
@Mappings({})
ProductAttrValueBO convert2(ProductAttrValueDO productAttrValueDO);
}
\ No newline at end of file
package cn.iocoder.mall.product.dao;
import cn.iocoder.mall.product.dataobject.ProductAttrDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.List;
@Repository
public interface ProductAttrMapper {
ProductAttrDO selectById(@Param("id") Integer id);
ProductAttrDO selectByName(@Param("name") String name);
List<ProductAttrDO> selectListByIds(@Param("ids") Collection<Integer> ids);
List<ProductAttrDO> selectListByStatus(@Param("status") Integer status);
List<ProductAttrDO> selectListByNameLike(@Param("name") String name,
@Param("offset") Integer offset,
@Param("limit") Integer limit);
Integer selectCountByNameLike(@Param("name") String name);
void insert(ProductAttrDO productAttrDO);
void update(ProductAttrDO productAttrDO);
}
\ No newline at end of file
package cn.iocoder.mall.product.dao;
import cn.iocoder.mall.product.dataobject.ProductAttrValueDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.List;
@Repository
public interface ProductAttrValueMapper {
ProductAttrValueDO selectById(@Param("id") Integer id);
List<ProductAttrValueDO> selectListByIds(@Param("ids") Collection<Integer> ids);
List<ProductAttrValueDO> selectListByStatus(@Param("status") Integer status);
List<ProductAttrValueDO> selectListByAttrIds(@Param("attrIds") Collection<Integer> attrIds);
ProductAttrValueDO selectByAttrIdAndName(@Param("attrId") Integer attrId,
@Param("name") String name);
void insert(ProductAttrValueDO productAttrValueDO);
void update(ProductAttrValueDO productAttrValueDO);
}
\ No newline at end of file
package cn.iocoder.mall.product.dao;
import cn.iocoder.mall.product.dataobject.ProductSkuDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.List;
@Repository
public interface ProductSkuMapper {
ProductSkuDO selectById(Integer id);
List<ProductSkuDO> selectByIds(@Param("ids") Collection<Integer> ids);
List<ProductSkuDO> selectListBySpuIdAndStatus(@Param("spuId") Integer spuId,
@Param("status") Integer status);
void insertList(@Param("productSkuDOs") List<ProductSkuDO> productSkuDOs);
int update(ProductSkuDO productSkuDO);
int updateToDeleted(@Param("ids") List<Integer> ids);
}
package cn.iocoder.mall.product.dao;
import cn.iocoder.mall.product.dataobject.UserProductSpuCollectionsDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 用户_商品_收藏记录表
*
* @author xiaofeng
* @date 2019-07-01 20:23:30
*/
@Repository
public interface UserProductSpuCollectionsMapper extends BaseMapper<UserProductSpuCollectionsDO> {
/**
* 根据用户id 和 spuId 查找用户商品收藏
* @param userId
* @param spuId
* @return
*/
default UserProductSpuCollectionsDO getUserSpuCollectionsByUserIdAndSpuId(final Integer userId,
final Integer spuId) {
QueryWrapper<UserProductSpuCollectionsDO> query = new QueryWrapper<UserProductSpuCollectionsDO>()
.eq("user_id", userId).eq("spu_id", spuId);
return selectOne(query);
}
/**
* 查询用户收藏列表
* @param userId
* @param offset
* @param limit
* @return
*/
List<UserProductSpuCollectionsDO> selectListByUser(@Param("userId") Integer userId, @Param("offset") Integer offset,
@Param("limit") Integer limit);
/**
* 根据用户ID 查找总数
* @param userId
* @return
*/
Integer selectCountByUser(Integer userId);
}
package cn.iocoder.mall.product.dataobject;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* Product 库存
*/
@Deprecated // TODO 芋艿,咱暂时不加库存表和库存服务
@Data
@Accessors(chain = true)
public class ProductStockDO {
/**
* 编号,自增
*/
private Integer id;
/**
* SKU 编号
*/
private Integer skuId;
/**
* 库存数
*/
private Integer quantity;
/**
* 创建时间
*/
private Date createTime;
/**
* 最后更新时间
*/
private Date updateTime;
/**
* 状态
*
* 1-正常
* 2-删除
*/
private Integer status;
}
package cn.iocoder.mall.product.dataobject;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 用户_商品_收藏记录表
*
* @author xiaofeng
* @date 2019-07-01 20:23:30
*/
@TableName("user_spu_collections")
@Data
@Accessors(chain = true)
public class UserProductSpuCollectionsDO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id自增长
*/
private Integer id;
/**
* 用户id
*/
private Integer userId;
/**
* 用户名称
*/
private String nickname;
/**
* 商品id
*/
private Integer spuId;
/**
* 商品名字
*/
private String spuName;
/**
* 图片名字
*/
private String spuImage;
/**
* 卖点
*/
private String sellPoint;
/**
* 价格,单位:分
*/
private Integer price;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 删除状态
*/
private Integer deleted;
}
package cn.iocoder.mall.product.service;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.mall.product.api.ProductSpuCollectionService;
import cn.iocoder.mall.product.api.constant.ProductErrorCodeEnum;
import cn.iocoder.mall.product.api.message.ProductSpuCollectionMessage;
import cn.iocoder.mall.product.dao.ProductSpuMapper;
import cn.iocoder.mall.product.dataobject.ProductSpuDO;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* ProductSpuCollectionServiceImpl
* @author xiaofeng
* @date 2019/07/01 23:14
* @version 1.0
*/
@Service // 实际上不用添加。添加的原因是,必须 Spring 报错提示
@org.apache.dubbo.config.annotation.Service(validation = "true", version = "${dubbo.provider.ProductSpuCollectionService.version}")
public class ProductSpuCollectionServiceImpl implements ProductSpuCollectionService {
@Autowired
private ProductSpuMapper productSpuMapper;
@Resource
private RocketMQTemplate rocketMQTemplate;
@Override
public boolean productSpuCollection(Integer spuId, Integer hasCollectionType, Integer userId) {
ProductSpuDO productSpuDO = this.productSpuMapper.selectById(spuId);
// 校验 Spu 是否存在
if (productSpuDO == null) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode());
}
this.sendProductSpuCollectionMessage(productSpuDO, hasCollectionType, userId);
return Boolean.TRUE;
}
/**
* 发送商品收藏或取消消息
* @param productSpuDO
* @param hasCollectionType
*/
// TODO FROM 芋艿 to ??:切换到 Spring Cloud Stream 发送消息
private void sendProductSpuCollectionMessage(final ProductSpuDO productSpuDO, final Integer hasCollectionType,
final Integer userId) {
List<String> result = Lists.newArrayList(Splitter.on(",").omitEmptyStrings().trimResults().split(productSpuDO.getPicUrls()));
ProductSpuCollectionMessage productSpuCollectionMessage = new ProductSpuCollectionMessage()
.setSpuId(productSpuDO.getId())
.setSpuName(productSpuDO.getName())
.setSpuImage(result.size() > 0 ? result.get(0) : "")
.setSellPoint(productSpuDO.getSellPoint())
.setPrice(productSpuDO.getPrice())
.setHasCollectionType(hasCollectionType)
.setUserId(userId);
rocketMQTemplate.convertAndSend(ProductSpuCollectionMessage.TOPIC, productSpuCollectionMessage);
}
}
spring:
# datasource
datasource:
url: jdbc:mysql://s1.iocoder.cn:3306/mall_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: zhuyang
# Spring Cloud 配置项
cloud:
nacos:
# Spring Cloud Nacos Discovery 配置项
discovery:
server-addr: s1.iocoder.cn:8848 # Nacos 服务器地址
# Spring Cloud Stream 配置
stream:
# Binding 配置项
bindings:
product-update-output:
destination: ProductUpdate
# Spring Cloud Stream RocketMQ 配置项
rocketmq:
# RocketMQ Binder 配置项
binder:
name-server: s1.iocoder.cn:9876 # RocketMQ Namesrv 地址
# RocketMQ 默认 Binding 配置项
default:
# RocketMQ 生产者
producer:
group: product-producer-group # 生产者分组
sync: true # 是否同步发送消息,默认为 false 异步。
# mybatis
mybatis-plus:
config-location: classpath:mybatis-config.xml
mapper-locations: classpath:mapper/*.xml
type-aliases-package: cn.iocoder.mall.product.dataobject
# Dubbo 配置项
dubbo:
# Dubbo 注册中心
registry:
address: spring-cloud://s1.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址
# Spring Cloud Alibaba Dubbo 专属配置
cloud:
subscribed-services: admin-application, user-application # 设置订阅的应用列表,默认为 * 订阅所有应用
# Dubbo 提供者的协议
protocol:
name: dubbo
port: -1
# Dubbo 提供服务的扫描基础包
scan:
base-packages: cn.iocoder.mall.product.service
# Dubbo 服务提供者的配置
provider:
filter: -exception
ProductAttrService:
version: 1.0.0
ProductCategoryService:
version: 1.0.0
ProductSpuService:
version: 1.0.0
ProductBrandService:
version: 1.0.0
OAuth2Service:
version: 1.0.0
ProductSpuCollectionService:
version: 1.0.0
UserProductSpuCollectionsService:
version: 1.0.0
consumer:
UserService:
version: 1.0.0
# Seata 配置项
seata:
tx-service-group: default # Seata 事务组编号,用于 TC 集群名
# 服务配置项,对应 ServiceProperties 类
service:
# 虚拟组和分组的映射
vgroup-mapping:
default: default
# Seata 注册中心配置项
registry:
type: nacos # 注册中心类型
nacos:
serverAddr: ${spring.cloud.nacos.discovery.server-addr} # Nacos 服务地址
namespace: # Nacos 命名空间
cluster: default # 使用的 Seata 分组
<?xml version="1.0" encoding="UTF-8" ?>
<!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.ProductAttrMapper">
<select id="selectByName" parameterType="String" resultType="ProductAttrDO">
SELECT
<include refid="FIELDS" />
FROM product_attr
WHERE name = #{name}
AND deleted = 0
LIMIT 1
</select>
<insert id="insert" parameterType="ProductAttrDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO product_attr (
name, status, create_time, deleted
) VALUES (
#{name}, #{status}, #{createTime}, #{deleted}
)
</insert>
<update id="update" parameterType="ProductAttrDO">
UPDATE product_attr
<set>
<if test="name != null">
name = #{name},
</if>
<if test="status != null">
status = #{status},
</if>
<if test="deleted != null">
deleted = #{deleted}
</if>
</set>
WHERE id = #{id}
</update>
<select id="selectListByIds" resultType="ProductAttrDO">
SELECT
<include refid="FIELDS" />
FROM product_attr
WHERE id IN
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
#{id}
</foreach>
AND deleted = 0
</select>
<select id="selectListByNameLike" resultType="ProductAttrDO">
SELECT
<include refid="FIELDS" />
FROM product_attr
<where>
<if test="name != null">
name LIKE "%"#{name}"%"
</if>
AND deleted = 0
</where>
LIMIT #{offset}, #{limit}
</select>
<select id="selectCountByNameLike" resultType="Integer">
SELECT
COUNT(1)
FROM product_attr
<where>
<if test="name != null">
name LIKE "%"#{name}"%"
</if>
AND deleted = 0
</where>
</select>
<select id="selectListByStatus" parameterType="Integer" resultType="ProductAttrDO">
SELECT
<include refid="FIELDS" />
FROM product_attr
<where>
<if test="status != null">
status = #{status}
</if>
AND deleted = 0
</where>
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!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.ProductAttrValueMapper">
<sql id="FIELDS">
id, attr_id, name, status, create_time
</sql>
<!--<select id="selectList" resultType="ProductCategoryDO">-->
<!--SELECT-->
<!--<include refid="FIELDS" />-->
<!--FROM product_category-->
<!--WHERE deleted = 0-->
<!--</select>-->
<select id="selectById" parameterType="Integer" resultType="ProductAttrValueDO">
SELECT
<include refid="FIELDS" />
FROM product_attr_value
WHERE id = #{id}
AND deleted = 0
</select>
<!--<insert id="insert" parameterType="ProductCategoryDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">-->
<!--INSERT INTO product_category (-->
<!--pid, name, description, pic_url, sort,-->
<!--status, create_time, deleted-->
<!--) VALUES (-->
<!--#{pid}, #{name}, #{description}, #{picUrl}, #{sort},-->
<!--#{status}, #{createTime}, #{deleted}-->
<!--)-->
<!--</insert>-->
<!--<update id="update" parameterType="ProductCategoryDO">-->
<!--UPDATE product_category-->
<!--<set>-->
<!--<if test="pid != null">-->
<!--pid = #{pid},-->
<!--</if>-->
<!--<if test="name != null">-->
<!--name = #{name},-->
<!--</if>-->
<!--<if test="description != null">-->
<!--description = #{description},-->
<!--</if>-->
<!--<if test="picUrl != null">-->
<!--pic_url = #{picUrl},-->
<!--</if>-->
<!--<if test="sort != null">-->
<!--sort = #{sort},-->
<!--</if>-->
<!--<if test="status != null">-->
<!--status = #{status},-->
<!--</if>-->
<!--<if test="deleted != null">-->
<!--deleted = #{deleted}-->
<!--</if>-->
<!--</set>-->
<!--WHERE id = #{id}-->
<!--</update>-->
<select id="selectListByIds" resultType="ProductAttrValueDO">
SELECT
<include refid="FIELDS" />
FROM product_attr_value
WHERE id IN
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
#{id}
</foreach>
AND deleted = 0
</select>
<select id="selectListByAttrIds" resultType="ProductAttrValueDO">
SELECT
<include refid="FIELDS" />
FROM product_attr_value
WHERE attr_id IN
<foreach item="attrId" collection="attrIds" separator="," open="(" close=")" index="">
#{attrId}
</foreach>
AND deleted = 0
</select>
<select id="selectListByStatus" resultType="ProductAttrValueDO">
SELECT
<include refid="FIELDS" />
FROM product_attr_value
<where>
<if test="status != null">
status = #{status}
</if>
AND deleted = 0
</where>
</select>
<select id="selectByAttrIdAndName" resultType="ProductAttrValueDO">
SELECT
<include refid="FIELDS" />
FROM product_attr_value
WHERE name = #{name}
AND deleted = 0
LIMIT 1
</select>
<insert id="insert" parameterType="ProductAttrValueDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO product_attr_value (
attr_id, name, status, create_time, deleted
) VALUES (
#{attrId}, #{name}, #{status}, #{createTime}, #{deleted}
)
</insert>
<update id="update" parameterType="ProductAttrValueDO">
UPDATE product_attr_value
<set>
<if test="name != null">
name = #{name},
</if>
<if test="status != null">
status = #{status},
</if>
<if test="deleted != null">
deleted = #{deleted}
</if>
</set>
WHERE id = #{id}
</update>
</mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.mall.product.dao.ProductSkuMapper">
<sql id="FIELDS">
id, spu_id, status, pic_url, attrs,
price, quantity, create_time
</sql>
<select id="selectById" parameterType="Integer" resultType="ProductSkuDO">
SELECT
<include refid="FIELDS" />
FROM product_sku
WHERE id = #{id}
AND deleted = 0
</select>
<select id="selectByIds" resultType="ProductSkuDO">
SELECT
<include refid="FIELDS" />
FROM product_sku
WHERE id IN
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
#{id}
</foreach>
AND deleted = 0
</select>
<insert id="insertList" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO product_sku (
spu_id, status, pic_url, attrs, price,
quantity, deleted, create_time
) VALUES
<foreach collection="productSkuDOs" item="productSkuDO" separator=",">
(#{productSkuDO.spuId}, #{productSkuDO.status}, #{productSkuDO.picUrl}, #{productSkuDO.attrs}, #{productSkuDO.price},
#{productSkuDO.quantity}, #{productSkuDO.deleted}, #{productSkuDO.createTime}
)
</foreach>
</insert>
<select id="selectListBySpuIdAndStatus" resultType="ProductSkuDO">
SELECT
<include refid="FIELDS" />
FROM product_sku
WHERE spu_id = #{spuId}
AND status = #{status}
AND deleted = 0
</select>
<update id="update" parameterType="ProductSpuDO">
UPDATE product_sku
<set>
<if test="spuId != null">
spu_id = #{spuId},
</if>
<if test="status != null">
status = #{status},
</if>
<if test="picUrl != null">
pic_url = #{picUrl},
</if>
<if test="attrs != null">
attrs = #{attrs},
</if>
<if test="price != null">
price = #{price},
</if>
<if test="quantity != null">
quantity = #{quantity},
</if>
<if test="deleted != null">
deleted = #{deleted}
</if>
</set>
WHERE id = #{id}
</update>
<update id="updateToDeleted" parameterType="Integer">
UPDATE product_sku
SET deleted = 1
WHERE id IN
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
#{id}
</foreach>
</update>
</mapper>
<?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>onemall</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>product-service-project</artifactId>
<packaging>pom</packaging>
<modules>
<module>product-service-api</module>
<module>product-service-app</module>
</modules>
<dependencyManagement>
<dependencies>
<!-- onemall 基础 bom 文件 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-dependencies</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 自身项目 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>product-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
<?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>product-service-project</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>product-service-api</artifactId>
<dependencies>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>common-framework</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
</project>
package cn.iocoder.mall.productservice.enums;
import cn.iocoder.common.framework.exception.ErrorCode;
/**
* 错误码枚举类
*
* 商品系统,使用 1-003-000-000 段
*/
public interface ProductErrorCodeConstants {
// ========== PRODUCT CATEGORY 模块 ==========
ErrorCode PRODUCT_CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1003001000, "父分类不存在");
ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1003001001, "商品分类不存在");
ErrorCode PRODUCT_CATEGORY_PARENT_NOT_SELF = new ErrorCode(1003001002, "不能设置自己为父分类");
ErrorCode PRODUCT_CATEGORY_DELETE_ONLY_NO_CHILD = new ErrorCode(1002001004, "只有无子分类的商品分类才可以删除");
ErrorCode PRODUCT_CATEGORY_MUST_ENABLE = new ErrorCode(1002001005, "只有开启的商品分类,才可以使用");
ErrorCode PRODUCT_CATEGORY_PARENT_CAN_NOT_BE_LEVEL2 = new ErrorCode(1002001005, "父分类必须是一级分类");
// ========== PRODUCT SPU + SKU 模块 ==========
ErrorCode PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE = new ErrorCode(1003002000, "一个 SKU 下,不能有重复的规格");
ErrorCode PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS = new ErrorCode(1003002001, "一个 Spu 下的每个 SKU ,其规格数必须一致");
ErrorCode PRODUCT_SPU_SKU_NOT_DUPLICATE = new ErrorCode(1003002002, "一个 SPU 下的每个 SKU ,必须不重复");
ErrorCode PRODUCT_SPU_NOT_EXISTS = new ErrorCode(1003002003, "SPU 不存在");
ErrorCode PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2 = new ErrorCode(1003002003, "SPU 只能添加在二级分类下");
// ========== PRODUCT ATTR + ATTR_VALUE 模块 ==========
ErrorCode PRODUCT_ATTR_VALUE_NOT_EXIST = new ErrorCode(1003003000, "商品属性值不存在");
ErrorCode PRODUCT_ATTR_KEY_NOT_EXIST = new ErrorCode(1003003001, "商品属性键不存在");
ErrorCode PRODUCT_ATTR_KEY_EXISTS = new ErrorCode(1003003002, "商品规格键已经存在");
ErrorCode PRODUCT_ATTR_VALUE_EXISTS = new ErrorCode(1003003004, "商品规格值已经存在");
// ========== PRODUCT BRAND模块 ==========
ErrorCode PRODUCT_BRAND_NAME_EXIST = new ErrorCode(1003004000,"商品品牌的名字已经存在");
ErrorCode PRODUCT_BRAND_NOT_FOUND = new ErrorCode(1003004001, "商品品牌不粗糙你在");
}
package cn.iocoder.mall.productservice.enums.category;
/**
* 商品分类的编号枚举
*/
public enum ProductCategoryIdEnum {
/**
* 根节点
*/
ROOT(0);
private final Integer id;
ProductCategoryIdEnum(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
}
package cn.iocoder.mall.productservice.rpc.brand;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandPageReqDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandRespDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandUpdateReqDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(value = "product-service")
public interface ProductBrandFeign {
/**
* 创建商品品牌
*
* @param createDTO 创建商品品牌 DTO
* @return 商品品牌编号
*/
@PostMapping("/product/brand/createProductBrand")
CommonResult<Integer> createProductBrand(@RequestBody ProductBrandCreateReqDTO createDTO);
/**
* 更新商品品牌
*
* @param updateDTO 更新商品品牌 DTO
*/
@PostMapping("/product/brand/updateProductBrand")
CommonResult<Boolean> updateProductBrand(@RequestBody ProductBrandUpdateReqDTO updateDTO);
/**
* 删除商品品牌
*
* @param productBrandId 商品品牌编号
*/
@GetMapping("/product/brand/deleteProductBrand")
CommonResult<Boolean> deleteProductBrand(@RequestParam("productBrandId") Integer productBrandId);
/**
* 获得商品品牌
*
* @param productBrandId 商品品牌编号
* @return 商品品牌
*/
@GetMapping("/product/brand/getProductBrand")
CommonResult<ProductBrandRespDTO> getProductBrand(@RequestParam("productBrandId")Integer productBrandId);
/**
* 获得商品品牌列表
*
* @param productBrandIds 商品品牌编号列表
* @return 商品品牌列表
*/
@GetMapping("/product/brand/listProductBrands")
CommonResult<List<ProductBrandRespDTO>> listProductBrands(@RequestParam("productBrandIds") List<Integer> productBrandIds);
/**
* 获得商品品牌分页
*
* @param pageDTO 商品品牌分页查询
* @return 商品品牌分页结果
*/
@PostMapping("/product/brand/pageProductBrand")
CommonResult<PageResult<ProductBrandRespDTO>> pageProductBrand(@RequestBody ProductBrandPageReqDTO pageDTO);
}
package cn.iocoder.mall.productservice.rpc.brand.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 商品品牌创建 Request DTO
*/
@Data
@Accessors(chain = true)
public class ProductBrandCreateReqDTO implements Serializable {
/**
* 品牌名称
*/
@NotEmpty(message = "品牌名称不能为空")
private String name;
/**
* 品牌描述
*/
private String description;
/**
* 品牌名图片
*/
private String picUrl;
/**
* 状态
*/
@NotNull(message = "状态不能为空")
private Integer status;
}
package cn.iocoder.mall.productservice.rpc.brand.dto;
import cn.iocoder.common.framework.vo.PageParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 商品品牌分页 Request DTO
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class ProductBrandPageReqDTO extends PageParam {
/**
* 品牌名称
*/
private String name;
/**
* 状态
*/
private Integer status;
}
package cn.iocoder.mall.productservice.rpc.brand.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 商品品牌 Response DTO
*/
@Data
@Accessors(chain = true)
public class ProductBrandRespDTO implements Serializable {
/**
* 品牌编号(主键)
*/
private Integer id;
/**
* 品牌名称
*/
private String name;
/**
* 品牌描述
*/
private String description;
/**
* 品牌名图片
*/
private String picUrl;
/**
* 状态
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
}
package cn.iocoder.mall.productservice.rpc.brand.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 商品品牌更新 Request DTO
*/
@Data
@Accessors(chain = true)
public class ProductBrandUpdateReqDTO implements Serializable {
/**
* 品牌编号
*/
@NotNull(message = "品牌编号不能为空")
private Integer id;
/**
* 品牌名称
*/
@NotEmpty(message = "品牌名称不能为空")
private String name;
/**
* 品牌描述
*/
private String description;
/**
* 品牌名图片
*/
private String picUrl;
/**
* 状态
*/
@NotNull(message = "状态不能为空")
private Integer status;
}
package cn.iocoder.mall.productservice.rpc.category;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryListQueryReqDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryRespDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryUpdateReqDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Collection;
import java.util.List;
@FeignClient(value = "product-service")
public interface ProductCategoryFeign {
/**
* 创建商品分类
*
* @param createDTO 创建商品分类 DTO
* @return 商品分类编号
*/
@PostMapping("/product/category/createProductCategory")
CommonResult<Integer> createProductCategory(@RequestBody ProductCategoryCreateReqDTO createDTO);
/**
* 更新商品分类
*
* @param updateDTO 更新商品分类 DTO
*/
@PostMapping("/product/category/updateProductCategory")
CommonResult<Boolean> updateProductCategory(@RequestBody ProductCategoryUpdateReqDTO updateDTO);
/**
* 删除商品分类
*
* @param productCategoryId 商品分类编号
*/
@GetMapping("/product/category/deleteProductCategory")
CommonResult<Boolean> deleteProductCategory(@RequestParam("productCategoryId") Integer productCategoryId);
/**
* 获得商品分类
*
* @param productCategoryId 商品分类编号
* @return 商品分类
*/
@GetMapping("/product/category/getProductCategory")
CommonResult<ProductCategoryRespDTO> getProductCategory(@RequestParam("productCategoryId")Integer productCategoryId);
/**
* 获得商品分类列表
*
* @param productCategoryIds 商品分类编号列表
* @return 商品分类列表
*/
@GetMapping("/product/category/listProductCategoriesByIds")
CommonResult<List<ProductCategoryRespDTO>> listProductCategoriesByIds(@RequestParam("productCategoryIds")Collection<Integer> productCategoryIds);
/**
* 获得符合条件的商品分类列表
*
* @return 商品分类列表
*/
@PostMapping("/product/category/listProductCategories")
CommonResult<List<ProductCategoryRespDTO>> listProductCategories(@RequestBody ProductCategoryListQueryReqDTO listQueryReqDTO);
}
package cn.iocoder.mall.productservice.rpc.category.dto;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 商品分类创建 Request DTO
*/
@Data
@Accessors(chain = true)
public class ProductCategoryCreateReqDTO implements Serializable {
/**
* 父分类编号
*/
@NotNull(message = "父分类编号不能为空")
private Integer pid;
/**
* 分类名称
*/
@NotEmpty(message = "分类名称不能为空")
private String name;
/**
* 分类描述
*/
private String description;
/**
* 分类图片
*/
private String picUrl;
/**
* 分类排序
*/
@NotNull(message = "分类排序不能为空")
private Integer sort;
/**
* 状态
*/
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}")
private Integer status;
}
package cn.iocoder.mall.productservice.rpc.category.dto;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 商品分类列表查询 DTO
*/
@Data
@Accessors(chain = true)
public class ProductCategoryListQueryReqDTO implements Serializable {
/**
* 父编号
*/
private Integer pid;
/**
* 状态
*/
@InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}")
private Integer status;
}
package cn.iocoder.mall.productservice.rpc.category.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 商品分类 Response DTO
*/
@Data
@Accessors(chain = true)
public class ProductCategoryRespDTO implements Serializable {
/**
* 分类编号
*/
private Integer id;
/**
* 父分类编号
*/
private Integer pid;
/**
* 分类名称
*/
private String name;
/**
* 分类描述
*/
private String description;
/**
* 分类图片
*/
private String picUrl;
/**
* 分类排序
*/
private Integer sort;
/**
* 状态
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
}
package cn.iocoder.mall.productservice.rpc.category.dto;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 商品分类更新 Request DTO
*/
@Data
@Accessors(chain = true)
public class ProductCategoryUpdateReqDTO implements Serializable {
/**
* 分类编号
*/
@NotNull(message = "分类编号不能为空")
private Integer id;
/**
* 父分类编号
*/
@NotNull(message = "父分类编号不能为空")
private Integer pid;
/**
* 分类名称
*/
@NotEmpty(message = "分类名称不能为空")
private String name;
/**
* 分类描述
*/
private String description;
/**
* 分类图片
*/
private String picUrl;
/**
* 分类排序
*/
@NotNull(message = "分类排序不能为空")
private Integer sort;
/**
* 状态
*/
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}")
private Integer status;
}
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.*;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Collection;
import java.util.List;
@FeignClient(value = "product-service")
public interface ProductSpuFeign {
/**
* 获得商品 SPU
*
* @param productSpuId 商品 SPU 编号
* @return 商品 SPU
*/
@GetMapping(value = "/product/spu/get")
CommonResult<ProductSpuRespDTO> getProductSpu(@RequestParam("productSpuId") Integer productSpuId);
/**
* 获得商品 SPU列表
*
* @param productSpuIds 商品 SPU 编号列表
* @return 商品 SPU 列表
*/
@GetMapping(value = "/product/spu/list")
CommonResult<List<ProductSpuRespDTO>> listProductSpus(@RequestParam("productSpuIds") Collection<Integer> productSpuIds);
/**
* 获得商品 SPU 分页
*
* @param pageDTO 商品 SPU 分页查询
* @return 商品 SPU 分页结果
*/
@PostMapping(value = "/product/spu/page")
CommonResult<PageResult<ProductSpuRespDTO>> pageProductSpu(@RequestBody ProductSpuPageReqDTO pageDTO);
/**
* 顺序获得商品 SPU 编号数组
*
* @param lastSpuId 最后一个商品 SPU 编号
* @param limit 数量
* @return 商品 SPU 编号数组
*/
@GetMapping(value = "/product/spu/lislistProductSpuIdst")
CommonResult<List<Integer>> listProductSpuIds(@RequestParam("lastSpuId")Integer lastSpuId, @RequestParam("limit")Integer limit);
@GetMapping(value = "/product/spu/getProductSpuDetail")
CommonResult<ProductSpuDetailRespDTO> getProductSpuDetail(@RequestParam("productSpuId") Integer productSpuId,@RequestParam("fields") Collection<String> fields);
}
package cn.iocoder.mall.productservice.rpc.spu.dto;
import cn.iocoder.common.framework.vo.PageParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 商品 SPU 分页 Request DTO
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class ProductSpuPageReqDTO extends PageParam {
/**
* SPU 名字
*/
private String name;
/**
* 分类编号
*/
private Integer cid;
/**
* 是否可见
*/
private Boolean visible;
/**
* 是否有库存
*/
private Boolean hasQuantity;
}
package cn.iocoder.mall.productservice.rpc.spu.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 商品 SPU 信息 Response DTO
*/
@Data
@Accessors(chain = true)
public class ProductSpuRespDTO implements Serializable {
/**
* 商品 SPU 编号
*/
private Integer id;
/**
* SPU 名字
*/
private String name;
/**
* 卖点
*/
private String sellPoint;
/**
* 描述
*/
private String description;
/**
* 分类编号
*/
private Integer cid;
/**
* 商品主图地址
*/
private List<String> picUrls;
/**
* 是否上架商品
*/
private Boolean visible;
/**
* 排序字段
*/
private Integer sort;
/**
* 价格
*/
private Integer price;
/**
* 库存数量
*/
private Integer quantity;
/**
* 创建时间
*/
private Date createTime;
}
<?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>product-service-project</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>product-service-app</artifactId>
<dependencies>
<!-- RPC 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-dubbo</artifactId>
</dependency>
<dependency>
<!-- 系统服务 -->
<groupId>cn.iocoder.mall</groupId>
<artifactId>system-service-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<!-- 商品服务 -->
<groupId>cn.iocoder.mall</groupId>
<artifactId>product-service-api</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <!-- 需要开启 Web 容器,因为 Actuator 需要使用到 -->
</dependency>
<!-- MQ 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-rocketmq</artifactId>
</dependency>
<!-- Registry 和 Config 相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-mybatis</artifactId>
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Test 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
</dependencies>
<build>
<!-- 设置构建的 jar 包名 -->
<finalName>${project.artifactId}</finalName>
<!-- 使用 spring-boot-maven-plugin 插件打包 -->
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package cn.iocoder.mall.productservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ProductServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ProductServiceApplication.class, args);
}
}
package cn.iocoder.mall.productservice.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* Spring Aop 配置类
*/
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
public class AopConfiguration {
}
package cn.iocoder.mall.productservice.config;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@MapperScan("cn.iocoder.mall.productservice.dal.mysql.mapper") // 扫描对应的 Mapper 接口
@EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理。
public class DatabaseConfiguration {
// 数据库连接池 Druid
@Bean
public ISqlInjector sqlInjector() {
return new DefaultSqlInjector(); // MyBatis Plus 逻辑删除
}
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor(); // MyBatis Plus 分页插件
}
}
package cn.iocoder.mall.productservice.controller;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.manager.brand.ProductBrandManager;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandPageReqDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandRespDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandUpdateReqDTO;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import static cn.iocoder.common.framework.vo.CommonResult.success;
/**
* Title:
* Description:
*
* @author zhuyang
* @version 1.0 2021/10/7
*/
@RestController
@RequestMapping("/product/brand")
@Api("商品品牌")
public class ProductBrandController {
@Autowired
private ProductBrandManager productBrandManager;
/**
* 创建商品品牌
*
* @param createDTO 创建商品品牌 DTO
* @return 商品品牌编号
*/
@PostMapping("createProductBrand")
CommonResult<Integer> createProductBrand(@RequestBody ProductBrandCreateReqDTO createDTO){
return success(productBrandManager.createProductBrand(createDTO));
}
/**
* 更新商品品牌
*
* @param updateDTO 更新商品品牌 DTO
*/
@PostMapping("updateProductBrand")
CommonResult<Boolean> updateProductBrand(@RequestBody ProductBrandUpdateReqDTO updateDTO){
productBrandManager.updateProductBrand(updateDTO);
return success(true);
}
/**
* 删除商品品牌
*
* @param productBrandId 商品品牌编号
*/
@GetMapping("deleteProductBrand")
CommonResult<Boolean> deleteProductBrand(@RequestParam("productBrandId") Integer productBrandId){
productBrandManager.deleteProductBrand(productBrandId);
return success(true);
}
/**
* 获得商品品牌
*
* @param productBrandId 商品品牌编号
* @return 商品品牌
*/
@GetMapping("getProductBrand")
CommonResult<ProductBrandRespDTO> getProductBrand(@RequestParam("productBrandId")Integer productBrandId){
return success(productBrandManager.getProductBrand(productBrandId));
}
/**
* 获得商品品牌列表
*
* @param productBrandIds 商品品牌编号列表
* @return 商品品牌列表
*/
@GetMapping("listProductBrands")
CommonResult<List<ProductBrandRespDTO>> listProductBrands(@RequestParam("productBrandIds") List<Integer> productBrandIds){
return success(productBrandManager.listProductBrands(productBrandIds));
}
/**
* 获得商品品牌分页
*
* @param pageDTO 商品品牌分页查询
* @return 商品品牌分页结果
*/
@PostMapping("pageProductBrand")
CommonResult<PageResult<ProductBrandRespDTO>> pageProductBrand(@RequestBody ProductBrandPageReqDTO pageDTO){
return success(productBrandManager.pageProductBrand(pageDTO));
}
}
package cn.iocoder.mall.productservice.controller;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.manager.brand.ProductBrandManager;
import cn.iocoder.mall.productservice.manager.category.ProductCategoryManager;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandPageReqDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandRespDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandUpdateReqDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryListQueryReqDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryRespDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryUpdateReqDTO;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.common.framework.vo.CommonResult.success;
/**
* Title:
* Description:
*
* @author zhuyang
* @version 1.0 2021/10/7
*/
@RestController
@RequestMapping("/product/category")
@Api("商品品牌")
public class ProductCategoryController {
@Autowired
private ProductCategoryManager productCategoryManager;
/**
* 创建商品分类
*
* @param createDTO 创建商品分类 DTO
* @return 商品分类编号
*/
@PostMapping("createProductCategory")
CommonResult<Integer> createProductCategory(@RequestBody ProductCategoryCreateReqDTO createDTO){
return success(productCategoryManager.createProductCategory(createDTO));
}
/**
* 更新商品分类
*
* @param updateDTO 更新商品分类 DTO
*/
@PostMapping("updateProductCategory")
CommonResult<Boolean> updateProductCategory(@RequestBody ProductCategoryUpdateReqDTO updateDTO){
productCategoryManager.updateProductCategory(updateDTO);
return success(true);
}
/**
* 删除商品分类
*
* @param productCategoryId 商品分类编号
*/
@GetMapping("deleteProductCategory")
CommonResult<Boolean> deleteProductCategory(@RequestParam("productCategoryId") Integer productCategoryId){
productCategoryManager.deleteProductCategory(productCategoryId);
return success(true);
}
/**
* 获得商品分类
*
* @param productCategoryId 商品分类编号
* @return 商品分类
*/
@GetMapping("getProductCategory")
CommonResult<ProductCategoryRespDTO> getProductCategory(@RequestParam("productCategoryId")Integer productCategoryId){
return success(productCategoryManager.getProductCategory(productCategoryId));
}
/**
* 获得商品分类列表
*
* @param productCategoryIds 商品分类编号列表
* @return 商品分类列表
*/
@GetMapping("listProductCategoriesByIds")
CommonResult<List<ProductCategoryRespDTO>> listProductCategoriesByIds(@RequestParam("productCategoryIds")Collection<Integer> productCategoryIds){
return success(productCategoryManager.listProductCategories(productCategoryIds));
}
/**
* 获得符合条件的商品分类列表
*
* @return 商品分类列表
*/
@PostMapping("listProductCategories")
CommonResult<List<ProductCategoryRespDTO>> listProductCategories(@RequestBody ProductCategoryListQueryReqDTO listQueryReqDTO){
return success(productCategoryManager.listProductCategories(listQueryReqDTO));
}
}
package cn.iocoder.mall.productservice.convert.attr;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.attr.ProductAttrKeyDO;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.attr.ProductAttrValueDO;
import cn.iocoder.mall.productservice.rpc.attr.dto.*;
import cn.iocoder.mall.productservice.service.attr.bo.*;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductAttrConvert {
ProductAttrConvert INSTANCE = Mappers.getMapper(ProductAttrConvert.class);
ProductAttrKeyDO convert(ProductAttrKeyCreateBO bean);
ProductAttrKeyBO convert(ProductAttrKeyDO bean);
ProductAttrKeyDO convert(ProductAttrKeyUpdateBO bean);
List<ProductAttrKeyBO> convertList(List<ProductAttrKeyDO> list);
@Mapping(source = "records", target = "list")
PageResult<ProductAttrKeyBO> convertPage(IPage<ProductAttrKeyDO> page);
ProductAttrKeyCreateBO convert(ProductAttrKeyCreateReqDTO bean);
ProductAttrKeyUpdateBO convert(ProductAttrKeyUpdateReqDTO bean);
ProductAttrKeyRespDTO convert(ProductAttrKeyBO bean);
List<ProductAttrKeyRespDTO> convertList02(List<ProductAttrKeyBO> list);
ProductAttrKeyPageBO convert(ProductAttrKeyPageReqDTO bean);
PageResult<ProductAttrKeyRespDTO> convertPage(PageResult<ProductAttrKeyBO> page);
ProductAttrValueDO convert(ProductAttrValueCreateBO bean);
ProductAttrValueBO convert(ProductAttrValueDO bean);
ProductAttrValueDO convert(ProductAttrValueUpdateBO bean);
List<ProductAttrValueBO> convertList03(List<ProductAttrValueDO> list);
ProductAttrValueCreateBO convert(ProductAttrValueCreateReqDTO bean);
ProductAttrValueUpdateBO convert(ProductAttrValueUpdateReqDTO bean);
ProductAttrValueRespDTO convert(ProductAttrValueBO bean);
List<ProductAttrValueRespDTO> convertList04(List<ProductAttrValueBO> list);
ProductAttrValueListQueryBO convert(ProductAttrValueListQueryReqDTO bean);
}
package cn.iocoder.mall.productservice.convert.brand;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.brand.ProductBrandDO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandPageReqDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandRespDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandUpdateReqDTO;
import cn.iocoder.mall.productservice.service.brand.bo.ProductBrandBO;
import cn.iocoder.mall.productservice.service.brand.bo.ProductBrandCreateBO;
import cn.iocoder.mall.productservice.service.brand.bo.ProductBrandPageBO;
import cn.iocoder.mall.productservice.service.brand.bo.ProductBrandUpdateBO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductBrandConvert {
ProductBrandConvert INSTANCE = Mappers.getMapper(ProductBrandConvert.class);
ProductBrandDO convert(ProductBrandCreateBO bean);
ProductBrandBO convert(ProductBrandDO bean);
ProductBrandDO convert(ProductBrandUpdateBO bean);
List<ProductBrandBO> convertList(List<ProductBrandDO> list);
@Mapping(source = "records", target = "list")
PageResult<ProductBrandBO> convertPage(IPage<ProductBrandDO> page);
ProductBrandCreateBO convert(ProductBrandCreateReqDTO bean);
ProductBrandUpdateBO convert(ProductBrandUpdateReqDTO bean);
ProductBrandRespDTO convert(ProductBrandBO bean);
List<ProductBrandRespDTO> convertList02(List<ProductBrandBO> list);
ProductBrandPageBO convert(ProductBrandPageReqDTO bean);
PageResult<ProductBrandRespDTO> convertPage(PageResult<ProductBrandBO> page);
}
package cn.iocoder.mall.productservice.convert.category;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.category.ProductCategoryDO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryListQueryReqDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryRespDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryUpdateReqDTO;
import cn.iocoder.mall.productservice.service.category.bo.ProductCategoryBO;
import cn.iocoder.mall.productservice.service.category.bo.ProductCategoryCreateBO;
import cn.iocoder.mall.productservice.service.category.bo.ProductCategoryListQueryBO;
import cn.iocoder.mall.productservice.service.category.bo.ProductCategoryUpdateBO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductCategoryConvert {
ProductCategoryConvert INSTANCE = Mappers.getMapper(ProductCategoryConvert.class);
ProductCategoryDO convert(ProductCategoryCreateBO bean);
ProductCategoryBO convert(ProductCategoryDO bean);
List<ProductCategoryBO> convertList(List<ProductCategoryDO> list);
ProductCategoryDO convert(ProductCategoryUpdateBO bean);
ProductCategoryCreateBO convert(ProductCategoryCreateReqDTO bean);
ProductCategoryUpdateBO convert(ProductCategoryUpdateReqDTO bean);
ProductCategoryRespDTO convert(ProductCategoryBO bean);
List<ProductCategoryRespDTO> convertList02(List<ProductCategoryBO> list);
ProductCategoryListQueryBO convert(ProductCategoryListQueryReqDTO bean);
}
package cn.iocoder.mall.productservice.dal.mysql.dataobject.attr;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* Product 规格键 DO
*/
@TableName("product_attr_key")
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
public class ProductAttrKeyDO extends DeletableDO {
/**
* 规格编号
*/
private Integer id;
/**
* 名称
*/
private String name;
/**
* 状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
}
package cn.iocoder.mall.productservice.dal.mysql.dataobject.attr;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 商品规格值 DO
*/
@TableName("product_attr_value")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class ProductAttrValueDO extends DeletableDO {
/**
* 规格值编号
*/
private Integer id;
/**
* 规格键编号
*
* 外键 {@link ProductAttrKeyDO#getId()}
*/
private Integer attrKeyId;
/**
* 规格值名字
*/
private String name;
/**
* 状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
}
package cn.iocoder.mall.productservice.dal.mysql.dataobject.brand;
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 商品品牌
*/
@TableName("product_brand")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class ProductBrandDO extends DeletableDO {
/**
* 品牌编号(主键)
*/
@TableId
private Integer id;
/**
* 品牌名称
*/
private String name;
/**
* 品牌描述
*/
private String description;
/**
* 品牌名图片
*/
private String picUrl;
/**
* 状态
*/
private Integer status;
}
package cn.iocoder.mall.productservice.dal.mysql.dataobject.category;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 商品分类 DO
*/
@TableName("product_category")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class ProductCategoryDO extends DeletableDO {
/**
* 分类编号
*/
@TableId
private Integer id;
/**
* 父分类编号
*/
private Integer pid;
/**
* 分类名称
*/
private String name;
/**
* 分类描述
*/
private String description;
/**
* 分类图片
*/
private String picUrl;
/**
* 分类排序
*/
private Integer sort;
/**
* 状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
}
package cn.iocoder.mall.productservice.dal.mysql.mapper.attr;
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.attr.ProductAttrKeyDO;
import cn.iocoder.mall.productservice.service.attr.bo.ProductAttrKeyPageBO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductAttrKeyMapper extends BaseMapper<ProductAttrKeyDO> {
default IPage<ProductAttrKeyDO> selectPage(ProductAttrKeyPageBO pageBO) {
return selectPage(new Page<>(pageBO.getPageNo(), pageBO.getPageSize()),
new QueryWrapperX<ProductAttrKeyDO>().likeIfPresent("name", pageBO.getName())
.eqIfPresent("status", pageBO.getStatus()));
}
default ProductAttrKeyDO selectByName(String name) {
return selectOne(new QueryWrapper<ProductAttrKeyDO>().eq("name", name));
}
}
package cn.iocoder.mall.productservice.dal.mysql.mapper.attr;
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.attr.ProductAttrValueDO;
import cn.iocoder.mall.productservice.service.attr.bo.ProductAttrValueListQueryBO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ProductAttrValueMapper extends BaseMapper<ProductAttrValueDO> {
default ProductAttrValueDO selectByAttrKeyIdAndName(Integer attrKeyId, String name) {
return selectOne(new QueryWrapper<ProductAttrValueDO>().eq("attr_key_id", attrKeyId).eq("name", name));
}
default List<ProductAttrValueDO> selectList(ProductAttrValueListQueryBO queryBO) {
return selectList(new QueryWrapperX<ProductAttrValueDO>().inIfPresent("id", queryBO.getProductAttrValueIds())
.eqIfPresent("attr_key_id", queryBO.getProductAttrKeyId()));
}
}
package cn.iocoder.mall.productservice.dal.mysql.mapper.brand;
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.brand.ProductBrandDO;
import cn.iocoder.mall.productservice.service.brand.bo.ProductBrandPageBO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductBrandMapper extends BaseMapper<ProductBrandDO> {
default IPage<ProductBrandDO> selectPage(ProductBrandPageBO pageBO) {
return selectPage(new Page<>(pageBO.getPageNo(), pageBO.getPageSize()),
new QueryWrapperX<ProductBrandDO>().likeIfPresent("name", pageBO.getName())
.eqIfPresent("status", pageBO.getStatus()));
}
default ProductBrandDO selectByName(String name) {
return selectOne(new QueryWrapper<ProductBrandDO>().eq("name", name));
}
}
package cn.iocoder.mall.productservice.dal.mysql.mapper.category;
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.category.ProductCategoryDO;
import cn.iocoder.mall.productservice.service.category.bo.ProductCategoryListQueryBO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ProductCategoryMapper extends BaseMapper<ProductCategoryDO> {
default Integer selectCountByPid(Integer pid) {
return selectCount(new QueryWrapper<ProductCategoryDO>().eq("pid", pid));
}
default List<ProductCategoryDO> selectList(ProductCategoryListQueryBO listQueryBO) {
return selectList(new QueryWrapperX<ProductCategoryDO>().eqIfPresent("pid", listQueryBO.getPid())
.eqIfPresent("status", listQueryBO.getStatus()));
}
}
package cn.iocoder.mall.productservice.manager.brand;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.convert.brand.ProductBrandConvert;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandPageReqDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandRespDTO;
import cn.iocoder.mall.productservice.rpc.brand.dto.ProductBrandUpdateReqDTO;
import cn.iocoder.mall.productservice.service.brand.ProductBrandService;
import cn.iocoder.mall.productservice.service.brand.bo.ProductBrandBO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 商品品牌 Manager
*/
@Service
public class ProductBrandManager {
@Autowired
private ProductBrandService productBrandService;
/**
* 创建商品品牌
*
* @param createDTO 创建商品品牌 DTO
* @return 商品品牌
*/
public Integer createProductBrand(ProductBrandCreateReqDTO createDTO) {
ProductBrandBO productBrandBO = productBrandService.createProductBrand(ProductBrandConvert.INSTANCE.convert(createDTO));
return productBrandBO.getId();
}
/**
* 更新商品品牌
*
* @param updateDTO 更新商品品牌 DTO
*/
public void updateProductBrand(ProductBrandUpdateReqDTO updateDTO) {
productBrandService.updateProductBrand(ProductBrandConvert.INSTANCE.convert(updateDTO));
}
/**
* 删除商品品牌
*
* @param productBrandId 商品品牌编号
*/
public void deleteProductBrand(Integer productBrandId) {
productBrandService.deleteProductBrand(productBrandId);
}
/**
* 获得商品品牌
*
* @param productBrandId 商品品牌编号
* @return 商品品牌
*/
public ProductBrandRespDTO getProductBrand(Integer productBrandId) {
ProductBrandBO productBrandBO = productBrandService.getProductBrand(productBrandId);
return ProductBrandConvert.INSTANCE.convert(productBrandBO);
}
/**
* 获得商品品牌列表
*
* @param productBrandIds 商品品牌编号列表
* @return 商品品牌列表
*/
public List<ProductBrandRespDTO> listProductBrands(List<Integer> productBrandIds) {
List<ProductBrandBO> productBrandBOs = productBrandService.listProductBrands(productBrandIds);
return ProductBrandConvert.INSTANCE.convertList02(productBrandBOs);
}
/**
* 获得商品品牌分页
*
* @param pageDTO 商品品牌分页查询
* @return 商品品牌分页结果
*/
public PageResult<ProductBrandRespDTO> pageProductBrand(ProductBrandPageReqDTO pageDTO) {
PageResult<ProductBrandBO> pageResultBO = productBrandService.pageProductBrand(ProductBrandConvert.INSTANCE.convert(pageDTO));
return ProductBrandConvert.INSTANCE.convertPage(pageResultBO);
}
}
package cn.iocoder.mall.productservice.manager.category;
import cn.iocoder.mall.productservice.convert.category.ProductCategoryConvert;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryListQueryReqDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryRespDTO;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryUpdateReqDTO;
import cn.iocoder.mall.productservice.service.category.ProductCategoryService;
import cn.iocoder.mall.productservice.service.category.bo.ProductCategoryBO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
/**
* 商品分类 Manager
*/
@Service
public class ProductCategoryManager {
@Autowired
private ProductCategoryService productCategoryService;
/**
* 创建商品分类
*
* @param createDTO 创建商品分类 DTO
* @return 商品分类
*/
public Integer createProductCategory(ProductCategoryCreateReqDTO createDTO) {
ProductCategoryBO productCategoryBO = productCategoryService.createProductCategory(ProductCategoryConvert.INSTANCE.convert(createDTO));
return productCategoryBO.getId();
}
/**
* 更新商品分类
*
* @param updateDTO 更新商品分类 DTO
*/
public void updateProductCategory(ProductCategoryUpdateReqDTO updateDTO) {
productCategoryService.updateProductCategory(ProductCategoryConvert.INSTANCE.convert(updateDTO));
}
/**
* 删除商品分类
*
* @param productCategoryId 商品分类编号
*/
public void deleteProductCategory(Integer productCategoryId) {
productCategoryService.deleteProductCategory(productCategoryId);
}
/**
* 获得商品分类
*
* @param productCategoryId 商品分类编号
* @return 商品分类
*/
public ProductCategoryRespDTO getProductCategory(Integer productCategoryId) {
ProductCategoryBO productCategoryBO = productCategoryService.getProductCategory(productCategoryId);
return ProductCategoryConvert.INSTANCE.convert(productCategoryBO);
}
/**
* 获得商品分类列表
*
* @param productCategoryIds 商品分类编号列表
* @return 商品分类列表
*/
public List<ProductCategoryRespDTO> listProductCategories(Collection<Integer> productCategoryIds) {
List<ProductCategoryBO> productCategoryBOs = productCategoryService.listProductCategories(productCategoryIds);
return ProductCategoryConvert.INSTANCE.convertList02(productCategoryBOs);
}
/**
* 获得商品分类全列表
*
* @return 商品分类全列表
*/
public List<ProductCategoryRespDTO> listProductCategories(ProductCategoryListQueryReqDTO listQueryReqDTO) {
List<ProductCategoryBO> productCategoryBOs = productCategoryService.listProductCategories(
ProductCategoryConvert.INSTANCE.convert(listQueryReqDTO));
return ProductCategoryConvert.INSTANCE.convertList02(productCategoryBOs);
}
}
...@@ -114,40 +114,6 @@ public class ProductSpuManager { ...@@ -114,40 +114,6 @@ public class ProductSpuManager {
return productSpuService.listProductSpuIds(lastSpuId, limit); return productSpuService.listProductSpuIds(lastSpuId, limit);
} }
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;
}
public ProductSpuDetailRespDTO getProductSpuDetail(Integer productSpuId, Collection<String> fields) { public ProductSpuDetailRespDTO getProductSpuDetail(Integer productSpuId, Collection<String> fields) {
// 获得商品 SPU 信息 // 获得商品 SPU 信息
ProductSpuBO spuBO = productSpuService.getProductSpu(productSpuId); ProductSpuBO spuBO = productSpuService.getProductSpu(productSpuId);
......
package cn.iocoder.mall.productservice.service.brand;
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.convert.brand.ProductBrandConvert;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.brand.ProductBrandDO;
import cn.iocoder.mall.productservice.dal.mysql.mapper.brand.ProductBrandMapper;
import cn.iocoder.mall.productservice.service.brand.bo.ProductBrandBO;
import cn.iocoder.mall.productservice.service.brand.bo.ProductBrandCreateBO;
import cn.iocoder.mall.productservice.service.brand.bo.ProductBrandPageBO;
import cn.iocoder.mall.productservice.service.brand.bo.ProductBrandUpdateBO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.PRODUCT_BRAND_NAME_EXIST;
import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.PRODUCT_BRAND_NOT_FOUND;
/**
* 商品品牌 Service
*/
@Service
@Validated
public class ProductBrandService {
@Autowired
private ProductBrandMapper productBrandMapper;
/**
* 创建商品品牌
*
* @param createBO 创建商品品牌 BO
* @return 商品品牌
*/
public ProductBrandBO createProductBrand(@Valid ProductBrandCreateBO createBO) {
// 校验商品品牌的名字是否已经使用
if (productBrandMapper.selectByName(createBO.getName()) != null) {
throw ServiceExceptionUtil.exception(PRODUCT_BRAND_NAME_EXIST);
}
// 插入到数据库
ProductBrandDO productBrandDO = ProductBrandConvert.INSTANCE.convert(createBO);
productBrandMapper.insert(productBrandDO);
// 返回
return ProductBrandConvert.INSTANCE.convert(productBrandDO);
}
/**
* 更新商品品牌
*
* @param updateBO 更新商品品牌 BO
*/
public void updateProductBrand(@Valid ProductBrandUpdateBO updateBO) {
// 校验更新的商品品牌是否存在
if (productBrandMapper.selectById(updateBO.getId()) == null) {
throw ServiceExceptionUtil.exception(PRODUCT_BRAND_NOT_FOUND);
}
// 校验商品品牌的名字是否已经使用
ProductBrandDO productBrandDOByName = productBrandMapper.selectByName(updateBO.getName());
if (productBrandDOByName != null && !updateBO.getId().equals(productBrandDOByName.getId())) {
throw ServiceExceptionUtil.exception(PRODUCT_BRAND_NAME_EXIST);
}
// 更新到数据库
ProductBrandDO updateObject = ProductBrandConvert.INSTANCE.convert(updateBO);
productBrandMapper.updateById(updateObject);
}
/**
* 删除商品品牌
*
* @param productBrandId 商品品牌编号
*/
public void deleteProductBrand(Integer productBrandId) {
// 校验删除的商品品牌是否存在
if (productBrandMapper.selectById(productBrandId) == null) {
throw ServiceExceptionUtil.exception(PRODUCT_BRAND_NOT_FOUND);
}
// TODO 功能点:需要品牌下没有分类
// 标记删除
productBrandMapper.deleteById(productBrandId);
}
/**
* 获得商品品牌
*
* @param productBrandId 商品品牌编号
* @return 商品品牌
*/
public ProductBrandBO getProductBrand(Integer productBrandId) {
ProductBrandDO productBrandDO = productBrandMapper.selectById(productBrandId);
return ProductBrandConvert.INSTANCE.convert(productBrandDO);
}
/**
* 获得商品品牌列表
*
* @param productBrandIds 商品品牌编号列表
* @return 商品品牌列表
*/
public List<ProductBrandBO> listProductBrands(List<Integer> productBrandIds) {
List<ProductBrandDO> productBrandDOs = productBrandMapper.selectBatchIds(productBrandIds);
return ProductBrandConvert.INSTANCE.convertList(productBrandDOs);
}
/**
* 获得商品品牌分页
*
* @param pageBO 商品品牌分页查询
* @return 商品品牌分页结果
*/
public PageResult<ProductBrandBO> pageProductBrand(ProductBrandPageBO pageBO) {
IPage<ProductBrandDO> productBrandDOPage = productBrandMapper.selectPage(pageBO);
return ProductBrandConvert.INSTANCE.convertPage(productBrandDOPage);
}
}
package cn.iocoder.mall.productservice.service.brand.bo;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 商品品牌 BO
*/
@Data
@Accessors(chain = true)
public class ProductBrandBO {
/**
* 品牌编号(主键)
*/
private Integer id;
/**
* 品牌名称
*/
private String name;
/**
* 品牌描述
*/
private String description;
/**
* 品牌名图片
*/
private String picUrl;
/**
* 状态
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
}
package cn.iocoder.mall.productservice.service.brand.bo;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 商品品牌创建 BO
*/
@Data
@Accessors(chain = true)
public class ProductBrandCreateBO {
/**
* 品牌名称
*/
@NotEmpty(message = "品牌名称不能为空")
private String name;
/**
* 品牌描述
*/
private String description;
/**
* 品牌名图片
*/
private String picUrl;
/**
* 状态
*/
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}
package cn.iocoder.mall.productservice.service.brand.bo;
import cn.iocoder.common.framework.vo.PageParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 商品品牌分页 BO
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class ProductBrandPageBO extends PageParam {
/**
* 品牌名称
*
* 模糊匹配
*/
private String name;
/**
* 状态
*/
private Integer status;
}
package cn.iocoder.mall.productservice.service.brand.bo;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 商品品牌更新 BO
*/
@Data
@Accessors(chain = true)
public class ProductBrandUpdateBO {
/**
* 品牌编号(主键)
*/
@NotNull(message = "品牌编号(主键)不能为空")
private Integer id;
/**
* 品牌名称
*/
@NotEmpty(message = "品牌名称不能为空")
private String name;
/**
* 品牌描述
*/
private String description;
/**
* 品牌名图片
*/
private String picUrl;
/**
* 状态
*/
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}
package cn.iocoder.mall.productservice.service.category;
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
import cn.iocoder.mall.productservice.convert.category.ProductCategoryConvert;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.category.ProductCategoryDO;
import cn.iocoder.mall.productservice.dal.mysql.mapper.category.ProductCategoryMapper;
import cn.iocoder.mall.productservice.enums.category.ProductCategoryIdEnum;
import cn.iocoder.mall.productservice.service.category.bo.ProductCategoryBO;
import cn.iocoder.mall.productservice.service.category.bo.ProductCategoryCreateBO;
import cn.iocoder.mall.productservice.service.category.bo.ProductCategoryListQueryBO;
import cn.iocoder.mall.productservice.service.category.bo.ProductCategoryUpdateBO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.*;
/**
* 商品分类 Service
*/
@Service
@Validated
public class ProductCategoryService {
@Autowired
private ProductCategoryMapper productCategoryMapper;
/**
* 创建商品分类
*
* @param createBO 创建商品分类 BO
* @return 商品分类
*/
public ProductCategoryBO createProductCategory(@Valid ProductCategoryCreateBO createBO) {
// 校验父分类
validParent(createBO.getPid());
// 插入到数据库
ProductCategoryDO productCategoryDO = ProductCategoryConvert.INSTANCE.convert(createBO);
productCategoryMapper.insert(productCategoryDO);
// 返回
return ProductCategoryConvert.INSTANCE.convert(productCategoryDO);
}
/**
* 更新商品分类
*
* @param updateBO 更新商品分类 BO
*/
public void updateProductCategory(@Valid ProductCategoryUpdateBO updateBO) {
// 校验父分类
validParent(updateBO.getPid());
// 校验不能设置自己为父分类
if (updateBO.getId().equals(updateBO.getPid())) {
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_PARENT_NOT_SELF);
}
// 校验更新的商品分类是否存在
if (productCategoryMapper.selectById(updateBO.getId()) == null) {
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_NOT_EXISTS);
}
// 更新到数据库
ProductCategoryDO updateObject = ProductCategoryConvert.INSTANCE.convert(updateBO);
productCategoryMapper.updateById(updateObject);
}
/**
* 删除商品分类
*
* @param productCategoryId 商品分类编号
*/
public void deleteProductCategory(Integer productCategoryId) {
// 校验删除的商品分类是否存在
if (productCategoryMapper.selectById(productCategoryId) == null) {
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_NOT_EXISTS);
}
// 只有不存在子分类才可以删除
Integer childCount = productCategoryMapper.selectCountByPid(productCategoryId);
if (childCount > 0) {
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_DELETE_ONLY_NO_CHILD);
}
// TODO 芋艿 补充只有不存在商品才可以删除
// 标记删除
productCategoryMapper.deleteById(productCategoryId);
}
/**
* 获得商品分类
*
* @param productCategoryId 商品分类编号
* @return 商品分类
*/
public ProductCategoryBO getProductCategory(Integer productCategoryId) {
ProductCategoryDO productCategoryDO = productCategoryMapper.selectById(productCategoryId);
return ProductCategoryConvert.INSTANCE.convert(productCategoryDO);
}
/**
* 获得商品分类列表
*
* @param productCategoryIds 商品分类编号列表
* @return 商品分类列表
*/
public List<ProductCategoryBO> listProductCategories(Collection<Integer> productCategoryIds) {
List<ProductCategoryDO> productCategoryDOs = productCategoryMapper.selectBatchIds(productCategoryIds);
return ProductCategoryConvert.INSTANCE.convertList(productCategoryDOs);
}
/**
* 获得商品分类全列表
*
* @return 商品分类全列表
*/
public List<ProductCategoryBO> listProductCategories(ProductCategoryListQueryBO listQueryBO) {
List<ProductCategoryDO> resourceDOs = productCategoryMapper.selectList(listQueryBO);
return ProductCategoryConvert.INSTANCE.convertList(resourceDOs);
}
private void validParent(Integer pid) {
if (!ProductCategoryIdEnum.ROOT.getId().equals(pid)) {
ProductCategoryDO parentCategory = productCategoryMapper.selectById(pid);
// 校验父分类是否存在
if (parentCategory == null) {
throw ServiceExceptionUtil.exception(PRODUCT_CATEGORY_PARENT_NOT_EXISTS);
}
// 父分类必须是一级分类
if (!ProductCategoryIdEnum.ROOT.getId().equals(parentCategory.getPid())) {
throw ServiceExceptionUtil.exception((PRODUCT_CATEGORY_PARENT_CAN_NOT_BE_LEVEL2));
}
}
}
}
package cn.iocoder.mall.productservice.service.category.bo;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 商品分类 BO
*/
@Data
@Accessors(chain = true)
public class ProductCategoryBO {
/**
* 分类编号
*/
private Integer id;
/**
* 父分类编号
*/
private Integer pid;
/**
* 分类名称
*/
private String name;
/**
* 分类描述
*/
private String description;
/**
* 分类图片
*/
private String picUrl;
/**
* 分类排序
*/
private Integer sort;
/**
* 状态
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
}
package cn.iocoder.mall.productservice.service.category.bo;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 商品分类创建 BO
*/
@Data
@Accessors(chain = true)
public class ProductCategoryCreateBO {
/**
* 父分类编号
*/
@NotNull(message = "父分类编号不能为空")
private Integer pid;
/**
* 分类名称
*/
@NotEmpty(message = "分类名称不能为空")
private String name;
/**
* 分类描述
*/
private String description;
/**
* 分类图片
*/
private String picUrl;
/**
* 分类排序
*/
@NotNull(message = "分类排序不能为空")
private Integer sort;
/**
* 状态
*/
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}
package cn.iocoder.mall.productservice.service.category.bo;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 商品分类列表查询 BO
*/
@Data
@Accessors(chain = true)
public class ProductCategoryListQueryBO {
/**
* 父编号
*/
private Integer pid;
/**
* 状态
*/
@InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}")
private Integer status;
}
package cn.iocoder.mall.productservice.service.category.bo;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 商品分类更新 BO
*/
@Data
@Accessors(chain = true)
public class ProductCategoryUpdateBO {
/**
* 分类编号
*/
@NotNull(message = "分类编号不能为空")
private Integer id;
/**
* 父分类编号
*/
@NotNull(message = "父分类编号不能为空")
private Integer pid;
/**
* 分类名称
*/
@NotEmpty(message = "分类名称不能为空")
private String name;
/**
* 分类描述
*/
private String description;
/**
* 分类图片
*/
private String picUrl;
/**
* 分类排序
*/
@NotNull(message = "分类排序不能为空")
private Integer sort;
/**
* 状态
*/
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}
package cn.iocoder.mall.productservice.service.spu;
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.util.CollectionUtils;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.convert.spu.ProductSpuConvert;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.spu.ProductSpuDO;
import cn.iocoder.mall.productservice.dal.mysql.mapper.spu.ProductSpuMapper;
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;
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuUpdateBO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.PRODUCT_SPU_NOT_EXISTS;
/**
* 商品 SPU Service
*/
@Service
@Validated
public class ProductSpuService {
@Autowired
private ProductSpuMapper productSpuMapper;
/**
* 创建商品 SPU
*
* @param createBO 创建商品 SPU BO
* @return 商品 SPU
*/
public ProductSpuBO createProductSpu(@Valid ProductSpuCreateBO createBO) {
// 插入到数据库
ProductSpuDO productSpuDO = ProductSpuConvert.INSTANCE.convert(createBO);
productSpuMapper.insert(productSpuDO);
// 返回
return ProductSpuConvert.INSTANCE.convert(productSpuDO);
}
/**
* 更新商品 SPU
*
* @param updateBO 更新商品 SPU BO
*/
public void updateProductSpu(@Valid ProductSpuUpdateBO updateBO) {
// 校验更新的商品 SPU是否存在
if (productSpuMapper.selectById(updateBO.getId()) == null) {
throw ServiceExceptionUtil.exception(PRODUCT_SPU_NOT_EXISTS);
}
// 更新到数据库
ProductSpuDO updateObject = ProductSpuConvert.INSTANCE.convert(updateBO);
productSpuMapper.updateById(updateObject);
}
/**
* 获得商品 SPU
*
* @param productSpuId 商品 SPU编号
* @return 商品 SPU
*/
public ProductSpuBO getProductSpu(Integer productSpuId) {
ProductSpuDO productSpuDO = productSpuMapper.selectById(productSpuId);
return ProductSpuConvert.INSTANCE.convert(productSpuDO);
}
/**
* 获得商品 SPU列表
*
* @param productSpuIds 商品 SPU编号列表
* @return 商品 SPU列表
*/
public List<ProductSpuBO> listProductSpus(Collection<Integer> productSpuIds) {
List<ProductSpuDO> productSpuDOs = productSpuMapper.selectBatchIds(productSpuIds);
return ProductSpuConvert.INSTANCE.convertList(productSpuDOs);
}
/**
* 获得商品 SPU分页
*
* @param pageBO 商品 SPU分页查询
* @return 商品 SPU分页结果
*/
public PageResult<ProductSpuBO> pageProductSpu(ProductSpuPageBO pageBO) {
IPage<ProductSpuDO> productSpuDOPage = productSpuMapper.selectPage(pageBO);
return ProductSpuConvert.INSTANCE.convertPage(productSpuDOPage);
}
/**
* 顺序获得商品 SPU 编号数组
*
* 一般情况下,该接口我们用于提供顺序的 SPU 编号数组,以便调用方进一步根据自己需要获取商品信息
* 例如说,搜索服务会不断获取商品编号,重建该商品编号的索引
*
* @param lastSpuId 最后一个商品 SPU 编号
* @param limit 数量
* @return 商品 SPU 编号数组
*/
public List<Integer> listProductSpuIds(Integer lastSpuId, Integer limit) {
return CollectionUtils.convertList(productSpuMapper.selectListByIdGt(lastSpuId, limit), ProductSpuDO::getId);
}
}
spring:
# 数据源配置项
datasource:
url: jdbc:mysql://localhost:3306/mall_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
driver-class-name: com.mysql.jdbc.Driver
username: root
password: zhuyang
# Spring Cloud 配置项
cloud:
nacos:
# Spring Cloud Nacos Discovery 配置项
discovery:
server-addr: localhost:8848 # Nacos 服务器地址
namespace: dev # Nacos 命名空间
# Dubbo 配置项
dubbo:
# Dubbo 注册中心
registry:
# address: spring-cloud://localhost:8848 # 指定 Dubbo 服务注册中心的地址
address: nacos://localhost:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址
spring:
# 数据源配置项
datasource:
url: jdbc:mysql://localhost:3306/mall_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
driver-class-name: com.mysql.jdbc.Driver
username: root
password: zhuyang
# Spring Cloud 配置项
cloud:
nacos:
# Spring Cloud Nacos Discovery 配置项
discovery:
server-addr: localhost:8848 # Nacos 服务器地址
namespace: dev # Nacos 命名空间
# Dubbo 配置项
dubbo:
# Dubbo 注册中心
registry:
# address: spring-cloud://localhost:8848 # 指定 Dubbo 服务注册中心的地址
address: nacos://localhost:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址
# Dubbo 服务提供者的配置
provider:
tag: ${DUBBO_TAG} # Dubbo 路由分组
spring:
# Application 的配置项
application:
name: product-service
# Profile 的配置项
profiles:
active: local
# MyBatis Plus 配置项
mybatis-plus:
configuration:
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
global-config:
db-config:
id-type: auto
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: cn.iocoder.mall.productservice.dal.mysql.dataobject
# Dubbo 配置项
dubbo:
# Spring Cloud Alibaba Dubbo 专属配置
cloud:
subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用
# Dubbo 提供者的协议
protocol:
name: dubbo
port: -1
# Dubbo 提供服务的扫描基础包
scan:
base-packages: cn.iocoder.mall.productservice.rpc
# Dubbo 服务提供者的配置
provider:
filter: -exception
validation: true # 开启 Provider 参数校验
version: 1.0.0 # 服务的版本号
# Dubbo 服务消费者的配置
consumer:
ErrorCodeRpc:
version: 1.0.0
# RocketMQ 配置项
rocketmq:
name-server: localhost:9876
producer:
group: ${spring.application.name}-producer-group
# Actuator 监控配置项
management:
server.port: 38082 # 独立端口,避免被暴露出去
endpoints.web.exposure.include: '*' # 暴露所有监控端点
server.port: ${management.server.port} # 设置使用 Actuator 的服务器端口,因为 RPC 服务不需要 Web 端口
# Mall 配置项
mall:
# 错误码配置项对应 ErrorCodeProperties 配置类
error-code:
group: ${spring.application.name}
constants-class: cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.mall.productservice.dal.mysql.mapper.sku.ProductSkuMapper">
<insert id="insertList" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
INSERT INTO product_sku (
spu_id, status, pic_url, attrs, price,
quantity
) VALUES
<foreach collection="productSkuDOs" item="productSkuDO" separator=",">
(#{productSkuDO.spuId}, #{productSkuDO.status}, #{productSkuDO.picUrl}, #{productSkuDO.attrs}, #{productSkuDO.price},
#{productSkuDO.quantity}
)
</foreach>
</insert>
</mapper>
-- ----------------------------
-- Table structure for product_spu
-- ----------------------------
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (7, '测试商品', '又大又长', '厮大牛逼', 791, 'https://img2.woyaogexing.com/2019/03/15/5d4374f27d078462!400x400_big.jpg', 1, 0, 7, 10, '2019-03-05 02:45:44', '2019-04-24 11:47:20', b'1');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (8, '测试商品', '又大又长', '厮大牛逼', 791, 'https://img2.woyaogexing.com/2019/03/15/52c349020e992e04!400x400_big.jpg', 1, 0, 8, 20, '2019-03-05 02:48:52', '2019-04-24 11:47:22', b'1');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (9, '测试商品', '又大又长', '厮大牛逼', 791, 'https://img2.woyaogexing.com/2019/03/15/4ba4264eb3416283!400x400_big.jpg', 1, 0, 9, 30, '2019-03-05 02:51:22', '2019-04-24 11:47:23', b'1');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (10, '测试商品', '又大又长', '厮大牛逼', 791, 'https://img2.woyaogexing.com/2019/03/15/b258b691c543172d!400x400_big.jpg', 1, 0, 10, 40, '2019-03-05 02:52:25', '2019-04-24 11:47:25', b'1');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (11, '测试商品', '又大又长', '厮大牛逼', 791, 'https://img2.woyaogexing.com/2019/03/15/976d2210182f6816!400x400_big.jpg', 1, 0, 11, 50, '2019-03-05 03:21:46', '2019-04-24 11:47:47', b'1');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (28, '测试商品', '又大又长', '<p>厮大牛逼</p>', 638, 'https://user-gold-cdn.xitu.io/2019/4/1/169d694b02ef0df7?imageView2/0/w/1280/h/960/format/jpeg/ignore-error/1,http://static.shop.iocoder.cn/49ace70a-bebc-4d1c-b4e7-2115cedbf2a8', 1, 1, 100, 300, '2019-03-07 01:34:15', '2019-05-13 14:48:36', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (29, 'kafka 实战第一版', '最强', '<p>我是一个骚气的描述</p>', 637, 'https://user-gold-cdn.xitu.io/2019/4/1/169d694ae392047b?imageView2/0/w/1280/h/960/format/jpeg/ignore-error/1,http://static.shop.iocoder.cn/ab34d8e5-3b28-4f74-bafa-48aa66b4cf58', 1, 2, 10000000, 60, '2019-03-18 17:50:00', '2019-05-06 15:31:21', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (32, '农夫山泉', '有点甜', '<p>我就是一个水</p>', 637, 'https://img.1000.com/qm-a-img/prod/000000/68635d48f57444c8a5ffd47a257dc3d7.jpg', 1, 1, 125000000, 50, '2019-04-16 13:45:13', '2019-09-06 10:58:36', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (33, 'Kafka 书籍汇总', '分布式发布订阅消息系统', 'kafka是一种高吞吐量的分布式发布订阅消息系统,她有如下特性:\n\n通过O(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能。\n\n高吞吐量:即使是非常普通的硬件kafka也可以支持每秒数十万的消息。\n\n支持通过kafka服务器和消费机集群来分区消息。\n\n支持Hadoop并行数据加载。\n\n卡夫卡的目的是提供一个发布订阅解决方案,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群机来提供实时的消费。', 783, 'http://static.iocoder.cn/kafka.png', 1, 0, 10000, 120, '2019-04-22 13:08:27', '2019-04-22 13:08:26', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (34, 'MySQL', '数据库服务器', 'MySQL是一个开放源码的小型关联式数据库管理系统,开发者为瑞典MySQL AB公司。目前MySQL被广泛地应用在Internet上的中小型网站中。由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本而选择了MySQL作为网站数据库。', 579, 'https://static.oschina.net/img/logo/mysql.png', 1, 0, 2000, 300, '2019-04-22 13:11:56', '2019-04-22 13:11:55', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (35, 'Oracle', '数据库服务器', '<p>Oracle是一个面向Internet计算环境的数据库。它是在数据库领域一直处于领先地位的Oracle(即甲骨文公司)的产品。可以说Oracle 关系数据库系统是目前世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小、微机环境。它是一种高效率、可靠性好的 适应高吞吐量的数据库解决方案。</p>', 639, 'https://static.oschina.net/img/logo/oracle.gif', 1, 0, 200000, 33, '2019-04-22 13:14:33', '2019-08-12 23:38:32', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (36, 'Java', '编程语言', 'Java,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台的总称,最初推出的时候提出 “Write Once, Run Anywhere” 的理想愿景。\n\n 用 Java 实现的 HotJava 浏览器(支持Java applet)显示了 Java 的魅力:跨平台、动态的Web、Internet计算。从此,Java被广泛接受并推动了Web的迅速发展,常用的浏览器现在均支持Java applet。', 639, 'https://static.oschina.net/img/logo/java.png', 1, 0, 2100, 33, '2019-04-22 13:15:15', '2019-04-22 13:15:14', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (37, '狼哥很骚', '骚气十足', '狼哥,死于 JVM 之手', 637, 'https://img.1000.com/qm-a-img/prod/000000/68635d48f57444c8a5ffd47a257dc3d7.jpg', 1, 0, 2000, 90, '2019-04-25 15:42:36', '2019-04-25 15:42:35', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (38, '天天吃饭', '不吃不行', '美团外卖饿了么外卖', 783, 'https://static.oschina.net/img/logo/mysql.png', 1, 0, 1000, 20, '2019-04-25 15:44:56', '2019-04-25 15:44:56', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (39, 'admin-server', '测试卖点', '30', 637, 'http://static.shop.iocoder.cn/8702680d-9145-490c-9bc1-13ed3337c4d1', 1, 0, 1000, 20, '2019-05-02 02:20:50', '2019-05-02 02:20:49', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (40, '测试多规格商品', '我是多规格', 'nice', 637, 'http://static.shop.iocoder.cn/d434dc76-3766-4d82-bdb7-229d1db4749c', 1, 0, 1000, 60, '2019-05-02 12:38:00', '2019-05-02 12:37:59', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (41, 'kafka 实战', '很吊', '厮大牛逼', 637, 'https://user-gold-cdn.xitu.io/2019/4/1/169d694ae392047b?imageView2/0/w/1280/h/960/format/jpeg/ignore-error/1', 1, 0, 1000, 0, '2019-05-02 17:44:05', '2019-05-06 13:27:22', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (42, '我和僵尸有个约会', '有点甜', '我就是描述', 637, 'http://static.shop.iocoder.cn/e3904ca3-d37c-47ae-b53f-3b46c5916e41', 0, 0, 1000, 60, '2019-05-02 22:17:01', '2019-05-06 13:27:05', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (43, '111', '111', '<p>123</p><div class=\"media-wrap image-wrap align-center\" style=\"text-align:center\"><img src=\"http://static.shop.iocoder.cn/57aa3c2a-56d7-4491-92b4-61c2461b3412\"/></div><p></p>', 784, 'http://static.shop.iocoder.cn/f97c1bce-48ff-4b26-8d34-d38137a306dd', 1, 0, 111100, 2222, '2019-07-02 11:36:25', '2019-07-02 11:36:24', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (44, '111', '111', '<p>123</p><div class=\"media-wrap image-wrap align-center\" style=\"text-align:center\"><img src=\"http://static.shop.iocoder.cn/57aa3c2a-56d7-4491-92b4-61c2461b3412\"/></div><p></p>', 784, 'http://static.shop.iocoder.cn/f97c1bce-48ff-4b26-8d34-d38137a306dd', 1, 0, 111100, 2222, '2019-07-02 11:36:39', '2019-07-02 11:36:38', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (45, '111', '111', '<p>123</p><div class=\"media-wrap image-wrap align-center\" style=\"text-align:center\"><img src=\"http://static.shop.iocoder.cn/57aa3c2a-56d7-4491-92b4-61c2461b3412\"/></div><p></p>', 784, 'http://static.shop.iocoder.cn/f97c1bce-48ff-4b26-8d34-d38137a306dd', 1, 0, 11100, 222, '2019-07-02 11:37:53', '2019-07-02 11:37:52', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (46, 'aaaa', 'a', '<p>111111111111111111111111</p>', 784, 'http://static.shop.iocoder.cn/c7f1a2c8-4015-4c28-bc64-a92ad72fbe12', 1, 0, 1100, 1222, '2019-07-05 15:41:02', '2019-07-05 15:41:01', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (47, '测试', '测试', '<p>21121212121</p>', 784, 'http://static.shop.iocoder.cn/1b4195db-93b9-4f8d-b8bb-3a88df28459d', 1, 0, 21213300, 23123, '2019-07-09 20:29:30', '2019-07-09 20:29:30', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (48, '测试', '测试', '<p>21121212121</p>', 784, 'http://static.shop.iocoder.cn/1b4195db-93b9-4f8d-b8bb-3a88df28459d', 1, 0, 21213300, 23123, '2019-07-09 20:29:40', '2019-07-09 20:29:40', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (49, '测试', '测试', '<p>21121212121</p>', 784, 'http://static.shop.iocoder.cn/124519dc-5b11-4bf1-96e3-ac29d18a603b', 1, 0, 21213300, 23123, '2019-07-09 20:32:27', '2019-07-09 20:32:26', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (50, '<script>alert(1111)</script>', '123', '<p>123123321</p><div class=\"media-wrap image-wrap\"><img src=\"http://static.shop.iocoder.cn/45bae085-0f13-42c8-a048-296ecc2dba2c\"/></div><p></p>', 784, 'http://static.shop.iocoder.cn/a7c70291-3d6e-46c2-90b8-f2b43f134b2b', 1, 0, 1200, 2, '2019-08-12 18:48:58', '2019-08-12 18:48:58', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (51, '<script>alert(1111)</script>', '123', '<p>123123321</p><div class=\"media-wrap image-wrap\"><img src=\"http://static.shop.iocoder.cn/45bae085-0f13-42c8-a048-296ecc2dba2c\"/></div><p></p>', 784, 'http://static.shop.iocoder.cn/a7c70291-3d6e-46c2-90b8-f2b43f134b2b', 1, 0, 1200, 2, '2019-08-12 18:49:03', '2019-08-12 18:49:02', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (52, '<script>alert(1111)</script>', '123', '<p>123123321</p><div class=\"media-wrap image-wrap\"><img src=\"http://static.shop.iocoder.cn/45bae085-0f13-42c8-a048-296ecc2dba2c\"/></div><p></p>', 784, 'http://static.shop.iocoder.cn/a7c70291-3d6e-46c2-90b8-f2b43f134b2b', 1, 0, 1200, 2, '2019-08-12 18:49:19', '2019-08-12 18:49:19', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (53, '<script>alert(1111)</script>', '123', '<p>123123321</p><div class=\"media-wrap image-wrap\"><img src=\"http://static.shop.iocoder.cn/45bae085-0f13-42c8-a048-296ecc2dba2c\"/></div><p></p>', 784, 'http://static.shop.iocoder.cn/a7c70291-3d6e-46c2-90b8-f2b43f134b2b', 1, 0, 1200, 2, '2019-08-12 18:50:48', '2019-08-12 18:50:48', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (54, 'Hadoop', '有点小贵', '<p>好看的不得了</p><div class=\"media-wrap image-wrap\"><img src=\"http://static.shop.iocoder.cn/d5dccd13-1f82-483e-bb87-fc47e14cb19f\"/></div><p></p>', 794, 'http://static.shop.iocoder.cn/4870d103-1c00-42e1-8eb7-177e227d5e03', 1, 0, 10000, 100, '2019-08-12 23:46:12', '2019-08-12 23:46:11', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (55, '金坷垃', '农民伯伯都爱它', '<p>金坷拉</p>', 783, 'http://static.shop.iocoder.cn/8fb41fd6-2ace-4e66-870d-28cff91084ae', 1, 0, 10000, 0, '2019-09-05 10:41:24', '2020-07-27 14:12:59', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (58, '测试商品标题', '丑', '测试商品描述', 637, '1,2,3', 1, 0, 1, 150, '2020-07-27 23:22:56', '2020-07-27 23:22:56', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (59, '测试商品标题', '丑', '测试商品描述', 637, '1,2,3', 1, 0, 1, 150, '2020-07-28 11:38:43', '2020-07-28 11:38:43', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (60, '测试商品标题', '丑', '测试商品描述', 637, '1,2,3', 1, 0, 1, 150, '2020-07-28 13:08:35', '2020-07-28 13:08:35', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (61, '测试商品标题', '丑', '测试商品描述', 637, '1,2,3', 1, 0, 1, 150, '2020-07-30 16:25:47', '2020-07-30 16:25:47', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (62, '测试商品标题', '丑', '测试商品描述', 637, '1,2,3', 1, 0, 1, 150, '2020-07-30 16:26:02', '2020-07-30 16:26:02', b'0');
INSERT INTO `mall_product`.`product_spu`(`id`, `name`, `sell_point`, `description`, `cid`, `pic_urls`, `visible`, `sort`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (63, '测试商品标题', '丑', '测试商品描述', 637, '1,2,3', 1, 0, 1, 150, '2020-07-30 16:26:13', '2020-07-30 16:26:13', b'0');
-- ----------------------------
-- Table structure for product_sku
-- ----------------------------
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (3, 8, 1, NULL, '1', 1, 100, '2019-03-05 02:48:52', '2019-03-05 16:48:52', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (4, 8, 1, NULL, '2', 1, 100, '2019-03-05 02:48:52', '2019-03-05 16:48:52', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (5, 9, 1, NULL, '1', 1, 100, '2019-03-05 02:51:22', '2019-03-05 16:51:21', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (6, 9, 1, NULL, '2', 1, 100, '2019-03-05 02:51:22', '2019-03-05 16:51:21', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (7, 10, 1, NULL, '1', 1, 100, '2019-03-05 02:52:25', '2019-03-05 16:52:25', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (8, 10, 1, NULL, '2', 1, 100, '2019-03-05 02:52:25', '2019-03-05 16:52:25', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (9, 13, 1, NULL, '1', 1, 100, '2019-03-05 03:22:24', '2019-03-05 17:22:26', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (10, 13, 1, NULL, '2', 1, 100, '2019-03-05 03:22:24', '2019-03-05 17:22:26', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (11, 14, 1, NULL, '1', 1, 100, '2019-03-05 03:22:33', '2019-03-05 17:22:40', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (12, 14, 1, NULL, '2', 1, 100, '2019-03-05 03:22:33', '2019-03-05 17:22:40', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (13, 20, 1, NULL, '1,3', 1, 100, '2019-03-05 03:25:39', '2019-03-05 17:25:39', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (14, 20, 1, NULL, '1,4', 1, 100, '2019-03-05 03:25:39', '2019-03-05 17:25:39', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (15, 21, 1, NULL, '1,3', 1, 100, '2019-03-05 03:34:07', '2019-03-05 17:34:06', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (16, 21, 1, NULL, '1,4', 1, 100, '2019-03-05 03:34:07', '2019-03-05 17:34:06', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (17, 22, 1, NULL, '1,3', 1, 100, '2019-03-05 03:34:50', '2019-03-05 17:34:49', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (18, 22, 1, NULL, '1,4', 1, 100, '2019-03-05 03:34:50', '2019-03-05 17:34:49', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (19, 23, 1, NULL, '1,3', 1, 1, '2019-03-05 03:37:03', '2019-03-26 23:51:23', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (20, 23, 1, NULL, '1,4', 2, 10, '2019-03-05 03:37:03', '2019-03-26 23:51:25', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (23, 25, 1, NULL, '1,3', 1, 100, '2019-03-05 03:43:30', '2019-03-05 17:43:30', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (24, 25, 1, NULL, '1,4', 1, 100, '2019-03-05 03:43:30', '2019-03-05 17:43:30', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (25, 26, 1, NULL, '1', 1, 100, '2019-03-05 07:00:38', '2019-03-05 21:00:38', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (26, 27, 1, NULL, '1', 1, 100, '2019-03-05 07:01:33', '2019-03-05 21:10:52', b'1');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (27, 27, 1, NULL, '2', 21, 200, '2019-03-05 07:01:33', '2019-03-05 21:10:52', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (30, 27, 1, NULL, '3', 3, 300, '2019-03-05 07:10:52', '2019-03-05 21:10:52', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (31, 28, 1, NULL, '1', 100, 100, '2019-03-07 01:34:15', '2019-05-13 14:48:36', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (32, 28, 1, NULL, '2', 200, 200, '2019-03-07 01:34:15', '2019-05-13 14:48:36', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (33, 29, 1, NULL, '1', 10000000, 20, '2019-03-18 17:50:01', '2019-05-05 23:48:10', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (34, 32, 1, NULL, '1,3', 125000000, 20, '2019-04-16 13:45:13', '2019-05-09 10:43:55', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (35, 32, 1, NULL, '1,4', 1410065408, 30, '2019-04-16 13:45:13', '2019-05-09 10:43:55', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (36, 33, 1, NULL, '3', 10000, 100, '2019-04-22 13:08:27', '2019-04-22 13:08:26', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (37, 33, 1, NULL, '4', 20000, 20, '2019-04-22 13:08:27', '2019-04-22 13:08:26', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (38, 34, 1, NULL, '1', 2000, 100, '2019-04-22 13:11:56', '2019-04-22 13:11:55', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (39, 34, 1, NULL, '2', 3000, 200, '2019-04-22 13:11:56', '2019-04-22 13:11:55', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (40, 35, 1, NULL, '3', 500000, 11, '2019-04-22 13:14:33', '2019-08-12 23:38:32', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (41, 35, 1, NULL, '4', 200000, 22, '2019-04-22 13:14:33', '2019-08-12 23:38:33', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (42, 36, 1, NULL, '3', 5100, 11, '2019-04-22 13:15:15', '2019-04-22 13:15:14', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (43, 36, 1, NULL, '4', 2100, 22, '2019-04-22 13:15:15', '2019-04-22 13:15:14', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (44, 37, 1, NULL, '3,2', 2000, 40, '2019-04-25 15:42:36', '2019-04-25 15:42:35', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (45, 37, 1, NULL, '4,2', 3000, 50, '2019-04-25 15:42:36', '2019-04-25 15:42:35', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (46, 38, 1, NULL, '2', 1000, 20, '2019-04-25 15:44:56', '2019-04-25 15:44:56', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (47, 39, 1, NULL, '1,3', 1000, 20, '2019-05-02 02:20:50', '2019-05-02 02:20:49', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (48, 40, 1, NULL, '1', 1000, 20, '2019-05-02 12:38:00', '2019-05-02 12:37:59', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (49, 40, 1, NULL, '2', 3000, 40, '2019-05-02 12:38:00', '2019-05-02 12:37:59', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (50, 41, 1, NULL, '1', 1000, 20, '2019-05-02 17:44:05', '2019-05-02 17:44:05', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (51, 29, 1, NULL, '2', 30000000, 40, '2019-05-02 18:19:15', '2019-05-05 23:48:10', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (54, 42, 1, NULL, '2', 3000, 40, '2019-05-02 22:25:19', '2019-05-02 22:54:16', b'1');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (55, 42, 1, NULL, '28', 1000, 20, '2019-05-02 22:54:17', '2019-05-02 22:54:16', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (56, 42, 1, NULL, '35', 3000, 40, '2019-05-02 23:01:17', '2019-05-02 23:01:17', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (57, 43, 1, NULL, '1,3', 111100, 1111, '2019-07-02 11:36:25', '2019-07-02 11:36:25', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (58, 43, 1, NULL, '2,3', 111100, 1111, '2019-07-02 11:36:25', '2019-07-02 11:36:25', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (59, 44, 1, NULL, '1,3', 111100, 1111, '2019-07-02 11:36:39', '2019-07-02 11:36:38', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (60, 44, 1, NULL, '2,3', 111100, 1111, '2019-07-02 11:36:39', '2019-07-02 11:36:38', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (61, 45, 1, NULL, '1,3,6', 11100, 111, '2019-07-02 11:37:53', '2019-07-02 11:37:52', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (62, 45, 1, NULL, '2,3,6', 11100, 111, '2019-07-02 11:37:53', '2019-07-02 11:37:52', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (63, 46, 1, NULL, '46', 1100, 1111, '2019-07-05 15:41:02', '2019-07-05 15:41:01', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (64, 46, 1, NULL, '4', 1100, 111, '2019-07-05 15:41:02', '2019-07-05 15:41:01', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (65, 47, 1, NULL, '3', 21213300, 23123, '2019-07-09 20:29:31', '2019-07-09 20:29:30', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (66, 48, 1, NULL, '3', 21213300, 23123, '2019-07-09 20:29:40', '2019-07-09 20:29:40', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (67, 49, 1, NULL, '3', 21213300, 23123, '2019-07-09 20:32:27', '2019-07-09 20:32:27', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (68, 50, 1, NULL, '47,48', 1200, 2, '2019-08-12 18:48:58', '2019-08-12 18:48:58', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (69, 51, 1, NULL, '47,48', 1200, 2, '2019-08-12 18:49:03', '2019-08-12 18:49:02', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (70, 52, 1, NULL, '47,48', 1200, 2, '2019-08-12 18:49:19', '2019-08-12 18:49:19', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (71, 53, 1, NULL, '47,48', 1200, 2, '2019-08-12 18:50:48', '2019-08-12 18:50:48', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (72, 54, 1, NULL, '1', 10000, 100, '2019-08-12 23:46:12', '2019-08-12 23:46:11', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (73, 55, 1, NULL, '49,50', 10000, 100, '2019-09-05 10:41:24', '2019-09-05 10:41:24', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (76, 58, 1, NULL, '1,3', 1, 100, '2020-07-27 23:22:56', '2020-07-27 23:22:56', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (77, 58, 1, NULL, '2,4', 2, 50, '2020-07-27 23:22:56', '2020-07-27 23:22:56', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (78, 59, 1, NULL, '1,3', 1, 100, '2020-07-28 11:38:43', '2020-07-28 11:38:43', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (79, 59, 1, NULL, '2,4', 2, 50, '2020-07-28 11:38:43', '2020-07-28 11:38:43', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (80, 60, 1, NULL, '1,3', 1, 100, '2020-07-28 13:08:35', '2020-07-28 13:08:35', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (81, 60, 1, NULL, '2,4', 2, 50, '2020-07-28 13:08:35', '2020-07-28 13:08:35', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (82, 61, 1, NULL, '1,3', 1, 100, '2020-07-30 16:25:47', '2020-07-30 16:25:47', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (83, 61, 1, NULL, '2,4', 2, 50, '2020-07-30 16:25:47', '2020-07-30 16:25:47', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (84, 62, 1, NULL, '1,3', 1, 100, '2020-07-30 16:26:02', '2020-07-30 16:26:02', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (85, 62, 1, NULL, '2,4', 2, 50, '2020-07-30 16:26:02', '2020-07-30 16:26:02', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (86, 63, 1, NULL, '1,3', 1, 100, '2020-07-30 16:26:13', '2020-07-30 16:26:13', b'0');
INSERT INTO `mall_product`.`product_sku`(`id`, `spu_id`, `status`, `pic_url`, `attrs`, `price`, `quantity`, `create_time`, `update_time`, `deleted`) VALUES (87, 63, 1, NULL, '2,4', 2, 50, '2020-07-30 16:26:13', '2020-07-30 16:26:13', b'0');
-- ----------------------------
-- Table structure for product_attr_key
-- ----------------------------
INSERT INTO `mall_product`.`product_attr_key`(`id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (1, '颜色', 1, '2019-03-05 15:40:56', '2019-03-05 15:40:58', b'0');
INSERT INTO `mall_product`.`product_attr_key`(`id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (2, '尺寸', 1, '2019-03-05 17:23:07', '2019-03-05 17:23:07', b'0');
INSERT INTO `mall_product`.`product_attr_key`(`id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (3, '测试规格1', 1, '2019-03-06 10:29:58', '2020-07-29 11:13:41', b'0');
INSERT INTO `mall_product`.`product_attr_key`(`id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (4, '厮大牛逼规格', 1, '2019-03-06 10:31:01', '2019-03-07 00:33:53', b'0');
INSERT INTO `mall_product`.`product_attr_key`(`id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (5, '狼哥规格', 2, '2019-03-06 10:31:47', '2019-03-07 00:34:27', b'0');
INSERT INTO `mall_product`.`product_attr_key`(`id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (6, '老徐规格', 1, '2019-03-06 10:48:42', '2019-03-07 00:48:41', b'0');
INSERT INTO `mall_product`.`product_attr_key`(`id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (7, '徐妈规格', 1, '2019-03-06 10:53:37', '2019-03-07 00:53:37', b'0');
INSERT INTO `mall_product`.`product_attr_key`(`id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (8, '粉色', 1, '2019-05-02 22:05:21', '2019-05-02 22:05:21', b'0');
INSERT INTO `mall_product`.`product_attr_key`(`id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (9, 'test', 1, '2020-07-29 11:04:26', '2020-07-29 11:04:26', b'0');
INSERT INTO `mall_product`.`product_attr_key`(`id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (10, 'test02', 1, '2020-07-29 11:13:48', '2020-07-29 11:13:48', b'0');
INSERT INTO `mall_product`.`product_attr_key`(`id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (11, '电视剧', 1, '2020-07-30 00:37:52', '2020-07-30 00:37:52', b'0');
-- ----------------------------
-- Table structure for product_attr_value
-- ----------------------------
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (1, 1, '蓝色', 1, '2019-03-05 15:41:09', '2019-03-05 15:41:09', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (2, 1, '绿色', 1, '2019-03-05 15:41:14', '2019-03-05 15:42:58', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (3, 2, 'XL', 1, '2019-03-05 17:23:19', '2019-03-05 17:23:19', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (4, 2, 'L', 1, '2019-03-05 17:23:25', '2019-03-05 17:23:25', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (5, 1, '红色', 1, '2019-03-05 20:59:48', '2019-03-05 20:59:48', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (6, 4, '狼哥规格', 1, '2019-03-06 19:55:38', '2019-03-07 09:55:38', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (7, 4, '狼哥规格1', 1, '2019-03-06 19:56:26', '2019-03-07 09:56:25', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (8, 4, '狼哥规格2', 1, '2019-03-06 19:57:19', '2019-03-07 09:57:19', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (9, 4, '狼哥规格345', 1, '2019-03-06 20:00:02', '2019-03-07 10:01:18', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (10, 9, '狼哥规格34', 2, '2019-03-06 20:00:59', '2019-03-07 10:02:43', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (11, 1, '粉色', 1, '2019-05-02 22:08:22', '2019-05-02 22:08:21', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (12, 1, '黄色', 1, '2019-05-02 22:10:30', '2019-05-02 22:10:30', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (13, 1, '橙色', 1, '2019-05-02 22:12:20', '2019-05-02 22:12:19', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (14, 1, '青色', 1, '2019-05-02 22:13:12', '2019-05-02 22:13:11', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (15, 1, '海蓝色', 1, '2019-05-02 22:15:47', '2019-05-02 22:15:47', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (16, 1, '浅蓝色', 1, '2019-05-02 22:16:25', '2019-05-02 22:16:25', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (17, 1, '天蓝色', 1, '2019-05-02 22:17:36', '2019-05-02 22:17:35', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (18, 9, '不破不灭', 1, '2019-05-02 22:18:24', '2019-05-02 22:30:29', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (19, 9, '各种浪', 1, '2019-05-02 22:19:17', '2019-05-02 22:30:27', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (20, 9, '测试01', 1, '2019-05-02 22:21:21', '2019-05-02 22:30:27', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (21, 9, '测试02', 1, '2019-05-02 22:23:17', '2019-05-02 22:30:25', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (22, 9, '测试03', 1, '2019-05-02 22:24:13', '2019-05-02 22:30:24', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (23, 9, 'biubiubiu', 1, '2019-05-02 22:24:42', '2019-05-02 22:30:23', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (24, 9, '特特', 1, '2019-05-02 22:35:35', '2019-05-02 22:35:42', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (25, 9, '01', 1, '2019-05-02 22:37:24', '2019-05-02 22:37:56', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (26, 9, 'liubi', 1, '2019-05-02 22:38:02', '2019-05-02 22:38:14', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (27, 9, 'zei6', 1, '2019-05-02 22:38:33', '2019-05-02 22:39:52', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (28, 3, 'niubi', 1, '2019-05-02 22:52:03', '2019-05-02 22:52:03', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (29, 3, 'wocao', 1, '2019-05-02 22:52:27', '2019-05-02 22:52:27', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (30, 3, '666', 1, '2019-05-02 22:54:44', '2019-05-02 22:54:43', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (31, 3, 'gouwazi', 1, '2019-05-02 22:58:52', '2019-05-02 22:58:51', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (32, 3, 'abc', 1, '2019-05-02 22:59:46', '2019-05-02 22:59:46', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (33, 3, 'qilin', 1, '2019-05-02 23:00:06', '2019-05-02 23:00:05', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (34, 3, 'xigua', 1, '2019-05-02 23:00:43', '2019-05-02 23:00:43', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (35, 3, 'zhanxiaolang', 1, '2019-05-02 23:01:07', '2019-05-02 23:01:07', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (36, 1, '粉绿色', 1, '2019-05-02 23:33:55', '2020-07-30 00:59:01', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (37, 6, '111', 1, '2019-05-31 18:55:56', '2019-05-31 18:55:55', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (38, 3, '22', 1, '2019-05-31 18:55:59', '2019-05-31 18:55:58', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (39, 2, '112', 1, '2019-05-31 18:56:06', '2019-05-31 18:56:05', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (40, 7, 'kk', 1, '2019-05-31 19:53:01', '2019-05-31 19:53:00', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (41, 7, 'nm', 1, '2019-05-31 19:53:05', '2019-05-31 19:53:04', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (42, 6, 'sss', 1, '2019-06-02 12:22:44', '2019-06-02 12:22:43', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (43, 6, 'sds', 1, '2019-06-02 12:22:46', '2019-06-02 12:22:45', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (44, 2, '3333', 1, '2019-07-02 11:19:32', '2019-07-02 11:19:32', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (45, 2, '123', 1, '2019-07-02 11:33:15', '2019-07-02 11:33:15', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (46, 2, 'a', 1, '2019-07-05 15:40:51', '2019-07-05 15:40:51', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (47, 2, '12312', 1, '2019-08-12 18:48:48', '2019-08-12 18:48:47', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (48, 3, '222', 1, '2019-08-12 18:48:54', '2019-08-12 18:48:53', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (49, 1, '金色', 1, '2019-09-05 10:38:55', '2019-09-05 10:38:55', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (50, 2, '一克拉', 1, '2019-09-05 10:39:05', '2019-09-05 10:39:04', b'0');
INSERT INTO `mall_product`.`product_attr_value`(`id`, `attr_key_id`, `name`, `status`, `create_time`, `update_time`, `deleted`) VALUES (51, 1, '花色', 1, '2020-07-30 01:00:22', '2020-07-30 01:00:22', b'0');
-- ----------------------------
-- Table structure for product_category
-- ----------------------------
INSERT INTO `mall_product`.`product_category`(`id`, `pid`, `name`, `description`, `pic_url`, `sort`, `status`, `create_time`, `update_time`, `deleted`) VALUES (90, 0, '电视影音', NULL, NULL, 0, 1, '2019-02-21 18:35:00', '2019-03-03 20:42:01', b'0');
INSERT INTO `mall_product`.`product_category`(`id`, `pid`, `name`, `description`, `pic_url`, `sort`, `status`, `create_time`, `update_time`, `deleted`) VALUES (579, 0, '手机电脑', NULL, NULL, 0, 1, '2019-02-21 18:33:26', '2019-03-03 20:42:03', b'0');
INSERT INTO `mall_product`.`product_category`(`id`, `pid`, `name`, `description`, `pic_url`, `sort`, `status`, `create_time`, `update_time`, `deleted`) VALUES (637, 90, '32-40英寸', NULL, 'https://shop.io.mi-img.com/app/shop/img?id=shop_904483f8aa3bbaaa9f53e4aae2382275.jpeg', 1, 1, '2019-02-21 18:35:20', '2019-03-03 20:42:05', b'0');
INSERT INTO `mall_product`.`product_category`(`id`, `pid`, `name`, `description`, `pic_url`, `sort`, `status`, `create_time`, `update_time`, `deleted`) VALUES (638, 90, '43英寸', NULL, 'https://shop.io.mi-img.com/app/shop/img?id=shop_0f26088b420afbe2c63df02246b94a34.jpeg', 2, 1, '2019-02-21 18:35:41', '2019-03-03 20:42:07', b'0');
INSERT INTO `mall_product`.`product_category`(`id`, `pid`, `name`, `description`, `pic_url`, `sort`, `status`, `create_time`, `update_time`, `deleted`) VALUES (639, 90, '49-50英寸', NULL, 'https://shop.io.mi-img.com/app/shop/img?id=shop_c2c741283b2ce1c4bc8b0abe9ea4f65e.jpeg', 3, 1, '2019-02-21 18:36:01', '2019-03-03 20:42:10', b'0');
INSERT INTO `mall_product`.`product_category`(`id`, `pid`, `name`, `description`, `pic_url`, `sort`, `status`, `create_time`, `update_time`, `deleted`) VALUES (783, 579, '小米系列', NULL, 'https://shop.io.mi-img.com/app/shop/img?id=shop_af3ae1e1444bc54af8b2251dd14aaa6b.jpeg', 1, 1, '2019-02-21 18:33:56', '2019-03-03 20:42:12', b'0');
INSERT INTO `mall_product`.`product_category`(`id`, `pid`, `name`, `description`, `pic_url`, `sort`, `status`, `create_time`, `update_time`, `deleted`) VALUES (784, 579, '红米系列', NULL, 'https://shop.io.mi-img.com/app/shop/img?id=shop_72605808146ee82c9961f9e3be6d8696.jpeg', 2, 1, '2019-02-21 18:34:29', '2019-03-03 20:42:14', b'0');
INSERT INTO `mall_product`.`product_category`(`id`, `pid`, `name`, `description`, `pic_url`, `sort`, `status`, `create_time`, `update_time`, `deleted`) VALUES (793, 0, '图书', '书是个好东西,可惜看的少。', NULL, 3, 1, '2019-05-05 16:12:39', '2019-05-05 16:12:39', b'0');
INSERT INTO `mall_product`.`product_category`(`id`, `pid`, `name`, `description`, `pic_url`, `sort`, `status`, `create_time`, `update_time`, `deleted`) VALUES (794, 793, 'Java', '半年一更,妥妥的', 'http://static.shop.iocoder.cn/5fd5709e-988d-4efd-b5d8-54a599ca538f', 1, 1, '2019-05-05 16:35:03', '2019-05-06 23:05:53', b'0');
INSERT INTO `mall_product`.`product_category`(`id`, `pid`, `name`, `description`, `pic_url`, `sort`, `status`, `create_time`, `update_time`, `deleted`) VALUES (796, 579, '订单系统设计', 'sss', 'http://static.shop.iocoder.cn/3fd98e94-ad50-415a-8f17-8bd8a998e508', 5, 1, '2019-06-26 20:28:35', '2019-06-26 20:28:34', b'0');
INSERT INTO `mall_product`.`product_category`(`id`, `pid`, `name`, `description`, `pic_url`, `sort`, `status`, `create_time`, `update_time`, `deleted`) VALUES (797, 0, '测试分类', NULL, NULL, 1, 1, '2020-07-25 19:16:24', '2020-07-25 19:16:24', b'0');
-- ----------------------------
-- Table structure for product_brand
-- ----------------------------
INSERT INTO `mall_product`.`product_brand`(`id`, `name`, `description`, `pic_url`, `status`, `create_time`, `update_time`, `deleted`) VALUES (1, '安踏更新', '安踏拖鞋更新', 'https://pic.17qq.com/uploads/hddeefhgbz.jpeg', 1, '2019-05-30 13:43:44', '2020-07-26 00:27:23', b'0');
INSERT INTO `mall_product`.`product_brand`(`id`, `name`, `description`, `pic_url`, `status`, `create_time`, `update_time`, `deleted`) VALUES (2, '特步', '特步描述', 'https://www.mask9.com/re/wp-content/uploads/2020/02/87285695_2755663391137244_8679130282952782166_n.jpg', 1, '2019-05-31 13:42:22', '2020-07-26 00:27:40', b'0');
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for product_spu
-- ----------------------------
CREATE TABLE `product_spu` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'SPU 编号',
`name` varchar(50) NOT NULL DEFAULT '' COMMENT 'SPU 名字',
`sell_point` varchar(50) NOT NULL DEFAULT '' COMMENT '卖点',
`description` text NOT NULL COMMENT '描述',
`cid` int(11) NOT NULL DEFAULT '-1' COMMENT '分类编号',
`pic_urls` varchar(1024) NOT NULL DEFAULT '' COMMENT '商品主图地址\n *\n * 数组,以逗号分隔\n *\n * 建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张',
`visible` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否上架商品(是否可见)。\n *\n * true 为已上架\n * false 为已下架',
`sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序字段',
`price` int(11) NOT NULL COMMENT '价格',
`quantity` int(11) NOT NULL COMMENT '库存数量',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=68 DEFAULT CHARSET=utf8mb4 COMMENT='商品 SPU';
-- ----------------------------
-- Table structure for product_sku
-- ----------------------------
CREATE TABLE `product_sku` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'sku 编号',
`spu_id` int(11) NOT NULL DEFAULT '-1' COMMENT '商品编号',
`status` int(11) NOT NULL DEFAULT '-1' COMMENT '状态\n *\n * 1-正常\n * 2-禁用',
`pic_url` varchar(50) DEFAULT '' COMMENT '图片地址',
`attrs` varchar(50) NOT NULL DEFAULT '' COMMENT '规格值({@link ProductAttrDO})数组\n *\n * 数组,以逗号分隔',
`price` int(11) NOT NULL DEFAULT '-1' COMMENT '价格,单位:分',
`quantity` int(11) NOT NULL DEFAULT '-1' COMMENT '库存数量',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=88 DEFAULT CHARSET=utf8mb4 COMMENT='商品 SKU';
-- ----------------------------
-- Table structure for product_attr_key
-- ----------------------------
CREATE TABLE `product_attr_key` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '规格键编号',
`name` varchar(50) NOT NULL DEFAULT '' COMMENT '规格键名称',
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态\n *\n * 1-开启\n * 2-禁用',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COMMENT='商品规格键';
-- ----------------------------
-- Table structure for product_attr_value
-- ----------------------------
CREATE TABLE `product_attr_value` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '规格值编号',
`attr_key_id` int(11) NOT NULL COMMENT '规格键编号',
`name` varchar(50) NOT NULL DEFAULT '' COMMENT '规格值名字',
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态\n *\n * 1-开启\n * 2-禁用',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=52 DEFAULT CHARSET=utf8mb4 COMMENT='商品规格值';
-- ----------------------------
-- Table structure for product_category
-- ----------------------------
CREATE TABLE `product_category` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '分类编号',
`pid` int(11) NOT NULL COMMENT '父分类编号',
`name` varchar(16) NOT NULL COMMENT '分类名称',
`description` varchar(255) DEFAULT NULL COMMENT '分类描述',
`pic_url` varchar(255) DEFAULT NULL COMMENT '分类图片',
`sort` int(11) NOT NULL COMMENT '分类排序',
`status` tinyint(4) NOT NULL COMMENT '状态',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=801 DEFAULT CHARSET=utf8mb4 COMMENT='商品分类表';
-- ----------------------------
-- Table structure for product_brand
-- ----------------------------
CREATE TABLE `product_brand` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '品牌编号',
`name` varchar(50) NOT NULL COMMENT '品牌名称',
`description` varchar(255) DEFAULT NULL COMMENT '品牌描述',
`pic_url` varchar(1024) DEFAULT NULL COMMENT '品牌名图片',
`status` tinyint(4) NOT NULL COMMENT '状态 1开启 2禁用',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='商品品牌';
package cn.iocoder.mall.productservice.manager.spu;
import cn.iocoder.mall.productservice.enums.sku.ProductSkuDetailFieldEnum;
import cn.iocoder.mall.productservice.manager.sku.ProductSkuManager;
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO;
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Arrays;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
@Slf4j
public class ProductSkuManagerTest {
@Autowired
private ProductSkuManager productSkuManager;
@Test
public void testListProductSkus() {
List<ProductSkuRespDTO> skuRespDTOs = productSkuManager.listProductSkus(
new ProductSkuListQueryReqDTO().setProductSkuIds(Arrays.asList(3, 4))
.setFields(Arrays.asList(ProductSkuDetailFieldEnum.SPU.getField(),
ProductSkuDetailFieldEnum.ATTR.getField())));
log.info("结果:{}", skuRespDTOs);
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论