Commit f4324a22f267da7b16d1725dab8df37b683c6aab

Authored by YunaiV
1 parent 833fd338

mall: code review 商品模块的代码

Showing 27 changed files with 226 additions and 214 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
@@ -10,30 +10,29 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode; @@ -10,30 +10,29 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
10 public interface ErrorCodeConstants { 10 public interface ErrorCodeConstants {
11 11
12 // ========== 商品分类相关 1008001000 ============ 12 // ========== 商品分类相关 1008001000 ============
13 - ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在");  
14 - ErrorCode PRODUCT_CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1008001001, "父分类不存在");  
15 - ErrorCode PRODUCT_CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类");  
16 - ErrorCode PRODUCT_CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除");  
17 - ErrorCode PRODUCT_CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用");  
18 - ErrorCode PRODUCT_CATEGORY_LEVEL = new ErrorCode(1008001005, "商品需挂在三级分类下"); 13 + ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在");
  14 + ErrorCode CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1008001001, "父分类不存在");
  15 + ErrorCode CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类");
  16 + ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除");
  17 + ErrorCode CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用");
  18 + ErrorCode CATEGORY_LEVEL_ERROR = new ErrorCode(1008001005, "商品分类不正确,原因:必须使用第三级的商品分类下");
19 19
20 - // ========== 品牌相关编号 1008002000 ==========  
21 - ErrorCode PRODUCT_BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在"); 20 + // ========== 商品品牌相关编号 1008002000 ==========
  21 + ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在");
22 22
23 - // ========== 规格名称 1008003000 ========== 23 + // ========== 商品规格名称 1008003000 ==========
24 ErrorCode PROPERTY_NOT_EXISTS = new ErrorCode(1008003000, "规格名称不存在"); 24 ErrorCode PROPERTY_NOT_EXISTS = new ErrorCode(1008003000, "规格名称不存在");
25 25
26 // ========== 规格值 1008004000 ========== 26 // ========== 规格值 1008004000 ==========
27 ErrorCode PROPERTY_VALUE_NOT_EXISTS = new ErrorCode(1008004000, "规格值不存在"); 27 ErrorCode PROPERTY_VALUE_NOT_EXISTS = new ErrorCode(1008004000, "规格值不存在");
28 28
29 - // ========== 商品spu 1008005000 ==========  
30 - ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品spu不存在"); 29 + // ========== 商品 SPU 1008005000 ==========
  30 + ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在");
31 31
32 - // ========== 商品sku 1008006000 ==========  
33 - ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品sku不存在");  
34 - ErrorCode SKU_PROPERTIES_DUPLICATED = new ErrorCode(1008006001, "商品sku的属性组合存在重复"); 32 + // ========== 商品 SKU 1008006000 ==========
  33 + ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品 SKU 不存在");
  34 + ErrorCode SKU_PROPERTIES_DUPLICATED = new ErrorCode(1008006001, "商品 SKU 的属性组合存在重复");
  35 + ErrorCode SPU_ATTR_NUMBERS_MUST_BE_EQUALS = new ErrorCode(1008006002, "一个 SPU 下的每个 SKU,其规格数必须一致");
  36 + ErrorCode SPU_SKU_NOT_DUPLICATE = new ErrorCode(1008006003, "一个 SPU 下的每个 SKU,必须不重复");
35 37
36 - ErrorCode PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS = new ErrorCode(1008006002, "一个 Spu 下的每个 SKU ,其规格数必须一致");  
37 -  
38 - ErrorCode PRODUCT_SPU_SKU_NOT_DUPLICATE = new ErrorCode(1008006003, "一个 SPU 下的每个 SKU ,必须不重复");  
39 } 38 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java
@@ -2,15 +2,9 @@ package cn.iocoder.yudao.module.product.controller.admin.brand; @@ -2,15 +2,9 @@ package cn.iocoder.yudao.module.product.controller.admin.brand;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;  
6 -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;  
7 import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*; 5 import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*;
8 -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;  
9 -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO;  
10 import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert; 6 import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert;
11 -import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert;  
12 import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; 7 import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
13 -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;  
14 import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; 8 import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
15 import io.swagger.annotations.Api; 9 import io.swagger.annotations.Api;
16 import io.swagger.annotations.ApiImplicitParam; 10 import io.swagger.annotations.ApiImplicitParam;
@@ -20,14 +14,11 @@ import org.springframework.validation.annotation.Validated; @@ -20,14 +14,11 @@ import org.springframework.validation.annotation.Validated;
20 import org.springframework.web.bind.annotation.*; 14 import org.springframework.web.bind.annotation.*;
21 15
22 import javax.annotation.Resource; 16 import javax.annotation.Resource;
23 -import javax.servlet.http.HttpServletResponse;  
24 import javax.validation.Valid; 17 import javax.validation.Valid;
25 -import java.io.IOException;  
26 import java.util.Comparator; 18 import java.util.Comparator;
27 import java.util.List; 19 import java.util.List;
28 20
29 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 21 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
30 -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;  
31 22
32 @Api(tags = "管理后台 - 商品品牌") 23 @Api(tags = "管理后台 - 商品品牌")
33 @RestController 24 @RestController
@@ -88,5 +79,4 @@ public class ProductBrandController { @@ -88,5 +79,4 @@ public class ProductBrandController {
88 return success(ProductBrandConvert.INSTANCE.convertList(list)); 79 return success(ProductBrandConvert.INSTANCE.convertList(list));
89 } 80 }
90 81
91 -  
92 } 82 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java
@@ -35,14 +35,14 @@ public class ProductCategoryController { @@ -35,14 +35,14 @@ public class ProductCategoryController {
35 @ApiOperation("创建商品分类") 35 @ApiOperation("创建商品分类")
36 @PreAuthorize("@ss.hasPermission('product:category:create')") 36 @PreAuthorize("@ss.hasPermission('product:category:create')")
37 public CommonResult<Long> createProductCategory(@Valid @RequestBody ProductCategoryCreateReqVO createReqVO) { 37 public CommonResult<Long> createProductCategory(@Valid @RequestBody ProductCategoryCreateReqVO createReqVO) {
38 - return success(categoryService.createProductCategory(createReqVO)); 38 + return success(categoryService.createCategory(createReqVO));
39 } 39 }
40 40
41 @PutMapping("/update") 41 @PutMapping("/update")
42 @ApiOperation("更新商品分类") 42 @ApiOperation("更新商品分类")
43 @PreAuthorize("@ss.hasPermission('product:category:update')") 43 @PreAuthorize("@ss.hasPermission('product:category:update')")
44 public CommonResult<Boolean> updateProductCategory(@Valid @RequestBody ProductCategoryUpdateReqVO updateReqVO) { 44 public CommonResult<Boolean> updateProductCategory(@Valid @RequestBody ProductCategoryUpdateReqVO updateReqVO) {
45 - categoryService.updateProductCategory(updateReqVO); 45 + categoryService.updateCategory(updateReqVO);
46 return success(true); 46 return success(true);
47 } 47 }
48 48
@@ -51,7 +51,7 @@ public class ProductCategoryController { @@ -51,7 +51,7 @@ public class ProductCategoryController {
51 @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) 51 @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
52 @PreAuthorize("@ss.hasPermission('product:category:delete')") 52 @PreAuthorize("@ss.hasPermission('product:category:delete')")
53 public CommonResult<Boolean> deleteProductCategory(@RequestParam("id") Long id) { 53 public CommonResult<Boolean> deleteProductCategory(@RequestParam("id") Long id) {
54 - categoryService.deleteProductCategory(id); 54 + categoryService.deleteCategory(id);
55 return success(true); 55 return success(true);
56 } 56 }
57 57
@@ -60,7 +60,7 @@ public class ProductCategoryController { @@ -60,7 +60,7 @@ public class ProductCategoryController {
60 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) 60 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
61 @PreAuthorize("@ss.hasPermission('product:category:query')") 61 @PreAuthorize("@ss.hasPermission('product:category:query')")
62 public CommonResult<ProductCategoryRespVO> getProductCategory(@RequestParam("id") Long id) { 62 public CommonResult<ProductCategoryRespVO> getProductCategory(@RequestParam("id") Long id) {
63 - ProductCategoryDO category = categoryService.getProductCategory(id); 63 + ProductCategoryDO category = categoryService.getCategory(id);
64 return success(ProductCategoryConvert.INSTANCE.convert(category)); 64 return success(ProductCategoryConvert.INSTANCE.convert(category));
65 } 65 }
66 66
@@ -68,7 +68,7 @@ public class ProductCategoryController { @@ -68,7 +68,7 @@ public class ProductCategoryController {
68 @ApiOperation("获得商品分类列表") 68 @ApiOperation("获得商品分类列表")
69 @PreAuthorize("@ss.hasPermission('product:category:query')") 69 @PreAuthorize("@ss.hasPermission('product:category:query')")
70 public CommonResult<List<ProductCategoryRespVO>> getProductCategoryList(@Valid ProductCategoryListReqVO treeListReqVO) { 70 public CommonResult<List<ProductCategoryRespVO>> getProductCategoryList(@Valid ProductCategoryListReqVO treeListReqVO) {
71 - List<ProductCategoryDO> list = categoryService.getEnableProductCategoryList(treeListReqVO); 71 + List<ProductCategoryDO> list = categoryService.getEnableCategoryList(treeListReqVO);
72 list.sort(Comparator.comparing(ProductCategoryDO::getSort)); 72 list.sort(Comparator.comparing(ProductCategoryDO::getSort));
73 return success(ProductCategoryConvert.INSTANCE.convertList(list)); 73 return success(ProductCategoryConvert.INSTANCE.convertList(list));
74 } 74 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java
@@ -62,7 +62,7 @@ public class ProductPropertyController { @@ -62,7 +62,7 @@ public class ProductPropertyController {
62 @ApiOperation("获得规格名称") 62 @ApiOperation("获得规格名称")
63 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) 63 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
64 @PreAuthorize("@ss.hasPermission('product:property:query')") 64 @PreAuthorize("@ss.hasPermission('product:property:query')")
65 - public CommonResult<ProductPropertyRespVO> getProperty(@RequestParam("id") Long id) { 65 + public CommonResult<ProductPropertyAndValueRespVO> getProperty(@RequestParam("id") Long id) {
66 return success(productPropertyService.getPropertyResp(id)); 66 return success(productPropertyService.getPropertyResp(id));
67 } 67 }
68 68
@@ -70,7 +70,7 @@ public class ProductPropertyController { @@ -70,7 +70,7 @@ public class ProductPropertyController {
70 @ApiOperation("获得规格名称列表") 70 @ApiOperation("获得规格名称列表")
71 @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) 71 @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
72 @PreAuthorize("@ss.hasPermission('product:property:query')") 72 @PreAuthorize("@ss.hasPermission('product:property:query')")
73 - public CommonResult<List<ProductPropertyRespVO>> getPropertyList(@RequestParam("ids") Collection<Long> ids) { 73 + public CommonResult<List<ProductPropertyAndValueRespVO>> getPropertyList(@RequestParam("ids") Collection<Long> ids) {
74 List<ProductPropertyDO> list = productPropertyService.getPropertyList(ids); 74 List<ProductPropertyDO> list = productPropertyService.getPropertyList(ids);
75 return success(ProductPropertyConvert.INSTANCE.convertList(list)); 75 return success(ProductPropertyConvert.INSTANCE.convertList(list));
76 } 76 }
@@ -78,7 +78,7 @@ public class ProductPropertyController { @@ -78,7 +78,7 @@ public class ProductPropertyController {
78 @GetMapping("/page") 78 @GetMapping("/page")
79 @ApiOperation("获得规格名称分页") 79 @ApiOperation("获得规格名称分页")
80 @PreAuthorize("@ss.hasPermission('product:property:query')") 80 @PreAuthorize("@ss.hasPermission('product:property:query')")
81 - public CommonResult<PageResult<ProductPropertyRespVO>> getPropertyPage(@Valid ProductPropertyPageReqVO pageVO) { 81 + public CommonResult<PageResult<ProductPropertyAndValueRespVO>> getPropertyPage(@Valid ProductPropertyPageReqVO pageVO) {
82 return success(productPropertyService.getPropertyListPage(pageVO)); 82 return success(productPropertyService.getPropertyListPage(pageVO));
83 } 83 }
84 84
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyAndValueRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo;
  2 +
  3 +import cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo.ProductPropertyValueRespVO;
  4 +import io.swagger.annotations.ApiModel;
  5 +import io.swagger.annotations.ApiModelProperty;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +import lombok.ToString;
  9 +
  10 +import java.util.Date;
  11 +import java.util.List;
  12 +
  13 +@ApiModel("管理后台 - 规格 + 规格值 Response VO")
  14 +@Data
  15 +@EqualsAndHashCode(callSuper = true)
  16 +@ToString(callSuper = true)
  17 +public class ProductPropertyAndValueRespVO extends ProductPropertyBaseVO {
  18 +
  19 + @ApiModelProperty(value = "规格的编号", required = true, example = "1024")
  20 + private Long id;
  21 +
  22 + @ApiModelProperty(value = "创建时间", required = true)
  23 + private Date createTime;
  24 +
  25 + /**
  26 + * 规格值的集合
  27 + */
  28 + private List<ProductPropertyValueRespVO> values;
  29 +
  30 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyBaseVO.java
1 package cn.iocoder.yudao.module.product.controller.admin.property.vo; 1 package cn.iocoder.yudao.module.product.controller.admin.property.vo;
2 2
3 -import lombok.*;  
4 -import java.util.*;  
5 -import io.swagger.annotations.*;  
6 -import javax.validation.constraints.*; 3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
7 5
  6 +// TODO @芋艿:完整的 review 下规格
8 /** 7 /**
9 * 规格名称 Base VO,提供给添加、修改、详细的子 VO 使用 8 * 规格名称 Base VO,提供给添加、修改、详细的子 VO 使用
10 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 9 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyRespVO.java deleted
1 -package cn.iocoder.yudao.module.product.controller.admin.property.vo;  
2 -  
3 -import cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo.ProductPropertyValueRespVO;  
4 -import lombok.*;  
5 -import java.util.*;  
6 -import io.swagger.annotations.*;  
7 -  
8 -@ApiModel("管理后台 - 规格名称 Response VO")  
9 -@Data  
10 -@EqualsAndHashCode(callSuper = true)  
11 -@ToString(callSuper = true)  
12 -public class ProductPropertyRespVO extends ProductPropertyBaseVO {  
13 -  
14 - @ApiModelProperty(value = "主键", required = true)  
15 - private Long id;  
16 -  
17 - @ApiModelProperty(value = "创建时间")  
18 - private Date createTime;  
19 -  
20 - @ApiModelProperty(value = "属性值")  
21 - private List<ProductPropertyValueRespVO> propertyValueList;  
22 -  
23 -}  
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java
@@ -6,14 +6,13 @@ import lombok.Data; @@ -6,14 +6,13 @@ import lombok.Data;
6 import lombok.EqualsAndHashCode; 6 import lombok.EqualsAndHashCode;
7 import lombok.ToString; 7 import lombok.ToString;
8 8
9 -import javax.validation.constraints.NotEmpty;  
10 -  
11 @ApiModel("管理后台 - 商品 SKU 创建/更新 Request VO") 9 @ApiModel("管理后台 - 商品 SKU 创建/更新 Request VO")
12 @Data 10 @Data
13 @EqualsAndHashCode(callSuper = true) 11 @EqualsAndHashCode(callSuper = true)
14 @ToString(callSuper = true) 12 @ToString(callSuper = true)
15 public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO { 13 public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO {
16 14
  15 + // TODO @Luowenfeng:可以不用哈,如果基于规格匹配
17 @ApiModelProperty(value = "商品 id 更新时须有", example = "1") 16 @ApiModelProperty(value = "商品 id 更新时须有", example = "1")
18 private Long id; 17 private Long id;
19 18
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
@@ -36,14 +36,14 @@ public class ProductSpuController { @@ -36,14 +36,14 @@ public class ProductSpuController {
36 @ApiOperation("创建商品 SPU") 36 @ApiOperation("创建商品 SPU")
37 @PreAuthorize("@ss.hasPermission('product:spu:create')") 37 @PreAuthorize("@ss.hasPermission('product:spu:create')")
38 public CommonResult<Long> createProductSpu(@Valid @RequestBody ProductSpuCreateReqVO createReqVO) { 38 public CommonResult<Long> createProductSpu(@Valid @RequestBody ProductSpuCreateReqVO createReqVO) {
39 - return success(spuService.createProductSpu(createReqVO)); 39 + return success(spuService.createSpu(createReqVO));
40 } 40 }
41 41
42 @PutMapping("/update") 42 @PutMapping("/update")
43 @ApiOperation("更新商品 SPU") 43 @ApiOperation("更新商品 SPU")
44 @PreAuthorize("@ss.hasPermission('product:spu:update')") 44 @PreAuthorize("@ss.hasPermission('product:spu:update')")
45 public CommonResult<Boolean> updateSpu(@Valid @RequestBody ProductSpuUpdateReqVO updateReqVO) { 45 public CommonResult<Boolean> updateSpu(@Valid @RequestBody ProductSpuUpdateReqVO updateReqVO) {
46 - spuService.updateProductSpu(updateReqVO); 46 + spuService.updateSpu(updateReqVO);
47 return success(true); 47 return success(true);
48 } 48 }
49 49
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/SpuRespVO.java
@@ -35,6 +35,8 @@ public class SpuRespVO extends ProductSpuBaseVO { @@ -35,6 +35,8 @@ public class SpuRespVO extends ProductSpuBaseVO {
35 @ApiModelProperty(value = "分类id数组,一直递归到一级父节点", example = "[1,2,4]") 35 @ApiModelProperty(value = "分类id数组,一直递归到一级父节点", example = "[1,2,4]")
36 private LinkedList<Long> categoryIds; 36 private LinkedList<Long> categoryIds;
37 37
  38 + // TODO @芋艿:再琢磨下 这个 VO 类,其实变成 SpuRespVO 内嵌的 VO 类会更好一点;然后把 SpuRespVO 改成 SpuDetailSpuVO
  39 +
38 @ApiModelProperty(value = "规格属性修改和详情展示组合", example = "[{\"propertyId\":2,\"name\":\"内存\",\"propertyValues\":[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]},{\"propertyId\":3,\"name\":\"尺寸\",\"propertyValues\":[{\"v1\":16,\"v2\":\"6.1\"},{\"v1\":15,\"v2\":\"5.7\"}]}]") 40 @ApiModelProperty(value = "规格属性修改和详情展示组合", example = "[{\"propertyId\":2,\"name\":\"内存\",\"propertyValues\":[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]},{\"propertyId\":3,\"name\":\"尺寸\",\"propertyValues\":[{\"v1\":16,\"v2\":\"6.1\"},{\"v1\":15,\"v2\":\"5.7\"}]}]")
39 private List<ProductPropertyViewRespVO> productPropertyViews; 41 private List<ProductPropertyViewRespVO> productPropertyViews;
40 42
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java
@@ -30,7 +30,7 @@ public class AppCategoryController { @@ -30,7 +30,7 @@ public class AppCategoryController {
30 @GetMapping("/list") 30 @GetMapping("/list")
31 @ApiOperation("获得商品分类列表") 31 @ApiOperation("获得商品分类列表")
32 public CommonResult<List<AppCategoryRespVO>> getProductCategoryList() { 32 public CommonResult<List<AppCategoryRespVO>> getProductCategoryList() {
33 - List<ProductCategoryDO> list = categoryService.getEnableProductCategoryList(); 33 + List<ProductCategoryDO> list = categoryService.getEnableCategoryList();
34 list.sort(Comparator.comparing(ProductCategoryDO::getSort)); 34 list.sort(Comparator.comparing(ProductCategoryDO::getSort));
35 return success(ProductCategoryConvert.INSTANCE.convertList03(list)); 35 return success(ProductCategoryConvert.INSTANCE.convertList03(list));
36 } 36 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java
@@ -23,11 +23,11 @@ public interface ProductPropertyConvert { @@ -23,11 +23,11 @@ public interface ProductPropertyConvert {
23 23
24 ProductPropertyDO convert(ProductPropertyUpdateReqVO bean); 24 ProductPropertyDO convert(ProductPropertyUpdateReqVO bean);
25 25
26 - ProductPropertyRespVO convert(ProductPropertyDO bean); 26 + ProductPropertyAndValueRespVO convert(ProductPropertyDO bean);
27 27
28 - List<ProductPropertyRespVO> convertList(List<ProductPropertyDO> list); 28 + List<ProductPropertyAndValueRespVO> convertList(List<ProductPropertyDO> list);
29 29
30 - PageResult<ProductPropertyRespVO> convertPage(PageResult<ProductPropertyDO> page); 30 + PageResult<ProductPropertyAndValueRespVO> convertPage(PageResult<ProductPropertyDO> page);
31 31
32 List<ProductPropertyExcelVO> convertList02(List<ProductPropertyDO> list); 32 List<ProductPropertyExcelVO> convertList02(List<ProductPropertyDO> list);
33 33
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.product.dal.mysql.brand; @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.product.dal.mysql.brand;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandBaseVO;  
7 import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandListReqVO; 6 import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandListReqVO;
8 import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO; 7 import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO;
9 import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; 8 import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
@@ -27,4 +26,5 @@ public interface ProductBrandMapper extends BaseMapperX&lt;ProductBrandDO&gt; { @@ -27,4 +26,5 @@ public interface ProductBrandMapper extends BaseMapperX&lt;ProductBrandDO&gt; {
27 return selectList(new LambdaQueryWrapperX<ProductBrandDO>() 26 return selectList(new LambdaQueryWrapperX<ProductBrandDO>()
28 .likeIfPresent(ProductBrandDO::getName, reqVO.getName())); 27 .likeIfPresent(ProductBrandDO::getName, reqVO.getName()));
29 } 28 }
  29 +
30 } 30 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java
@@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuPageReq @@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuPageReq
7 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; 7 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
8 import org.apache.ibatis.annotations.Mapper; 8 import org.apache.ibatis.annotations.Mapper;
9 9
10 -import java.util.Collections;  
11 import java.util.List; 10 import java.util.List;
12 11
13 /** 12 /**
@@ -34,13 +33,12 @@ public interface ProductSkuMapper extends BaseMapperX&lt;ProductSkuDO&gt; { @@ -34,13 +33,12 @@ public interface ProductSkuMapper extends BaseMapperX&lt;ProductSkuDO&gt; {
34 33
35 34
36 // TODO @franky:方法名 selectList; 可以直接调用 selectList 35 // TODO @franky:方法名 selectList; 可以直接调用 selectList
37 - default List<ProductSkuDO> selectBySpuIds(List<Long> spuIds) {  
38 - return selectList(new LambdaQueryWrapperX<ProductSkuDO>()  
39 - .inIfPresent(ProductSkuDO::getSpuId, spuIds)); 36 + default List<ProductSkuDO> selectListBySpuIds(List<Long> spuIds) {
  37 + return selectList(ProductSkuDO::getSpuId, spuIds);
40 } 38 }
41 39
42 - default List<ProductSkuDO> selectBySpuId(Long spuIds) {  
43 - return selectBySpuIds(Collections.singletonList(spuIds)); 40 + default List<ProductSkuDO> selectListBySpuId(Long spuId) {
  41 + return selectList(ProductSkuDO::getSpuId, spuId);
44 } 42 }
45 43
46 default void deleteBySpuId(Long spuId) { 44 default void deleteBySpuId(Long spuId) {
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java
@@ -55,10 +55,11 @@ public interface ProductBrandService { @@ -55,10 +55,11 @@ public interface ProductBrandService {
55 55
56 /** 56 /**
57 * 获得品牌列表 57 * 获得品牌列表
58 - * @param listVo 请求参数 58 + *
  59 + * @param listReqVO 请求参数
59 * @return 品牌列表 60 * @return 品牌列表
60 */ 61 */
61 - List<ProductBrandDO> getBrandList(ProductBrandListReqVO listVo); 62 + List<ProductBrandDO> getBrandList(ProductBrandListReqVO listReqVO);
62 63
63 /** 64 /**
64 * 验证选择的商品分类是否合法 65 * 验证选择的商品分类是否合法
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java
1 package cn.iocoder.yudao.module.product.service.brand; 1 package cn.iocoder.yudao.module.product.service.brand;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*; 4 +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandCreateReqVO;
  5 +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandListReqVO;
  6 +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO;
  7 +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandUpdateReqVO;
5 import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert; 8 import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert;
6 import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; 9 import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
7 import cn.iocoder.yudao.module.product.dal.mysql.brand.ProductBrandMapper; 10 import cn.iocoder.yudao.module.product.dal.mysql.brand.ProductBrandMapper;
8 -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;  
9 import org.springframework.stereotype.Service; 11 import org.springframework.stereotype.Service;
10 import org.springframework.validation.annotation.Validated; 12 import org.springframework.validation.annotation.Validated;
11 13
@@ -14,8 +16,7 @@ import java.util.Collection; @@ -14,8 +16,7 @@ import java.util.Collection;
14 import java.util.List; 16 import java.util.List;
15 17
16 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 18 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
17 -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_BRAND_NOT_EXISTS;  
18 -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_CATEGORY_LEVEL; 19 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.BRAND_NOT_EXISTS;
19 20
20 /** 21 /**
21 * 品牌 Service 实现类 22 * 品牌 Service 实现类
@@ -57,7 +58,7 @@ public class ProductBrandServiceImpl implements ProductBrandService { @@ -57,7 +58,7 @@ public class ProductBrandServiceImpl implements ProductBrandService {
57 58
58 private void validateBrandExists(Long id) { 59 private void validateBrandExists(Long id) {
59 if (brandMapper.selectById(id) == null) { 60 if (brandMapper.selectById(id) == null) {
60 - throw exception(PRODUCT_BRAND_NOT_EXISTS); 61 + throw exception(BRAND_NOT_EXISTS);
61 } 62 }
62 } 63 }
63 64
@@ -72,14 +73,14 @@ public class ProductBrandServiceImpl implements ProductBrandService { @@ -72,14 +73,14 @@ public class ProductBrandServiceImpl implements ProductBrandService {
72 } 73 }
73 74
74 @Override 75 @Override
75 - public List<ProductBrandDO> getBrandList(ProductBrandListReqVO listVo) {  
76 - return brandMapper.selectList(listVo); 76 + public List<ProductBrandDO> getBrandList(ProductBrandListReqVO listReqVO) {
  77 + return brandMapper.selectList(listReqVO);
77 } 78 }
78 79
79 @Override 80 @Override
80 public void validateProductBrand(Long id) { 81 public void validateProductBrand(Long id) {
81 if(getBrand(id) == null){ 82 if(getBrand(id) == null){
82 - throw exception(PRODUCT_BRAND_NOT_EXISTS); 83 + throw exception(BRAND_NOT_EXISTS);
83 } 84 }
84 } 85 }
85 86
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java
@@ -22,21 +22,21 @@ public interface ProductCategoryService { @@ -22,21 +22,21 @@ public interface ProductCategoryService {
22 * @param createReqVO 创建信息 22 * @param createReqVO 创建信息
23 * @return 编号 23 * @return 编号
24 */ 24 */
25 - Long createProductCategory(@Valid ProductCategoryCreateReqVO createReqVO); 25 + Long createCategory(@Valid ProductCategoryCreateReqVO createReqVO);
26 26
27 /** 27 /**
28 * 更新商品分类 28 * 更新商品分类
29 * 29 *
30 * @param updateReqVO 更新信息 30 * @param updateReqVO 更新信息
31 */ 31 */
32 - void updateProductCategory(@Valid ProductCategoryUpdateReqVO updateReqVO); 32 + void updateCategory(@Valid ProductCategoryUpdateReqVO updateReqVO);
33 33
34 /** 34 /**
35 * 删除商品分类 35 * 删除商品分类
36 * 36 *
37 * @param id 编号 37 * @param id 编号
38 */ 38 */
39 - void deleteProductCategory(Long id); 39 + void deleteCategory(Long id);
40 40
41 /** 41 /**
42 * 获得商品分类 42 * 获得商品分类
@@ -44,7 +44,7 @@ public interface ProductCategoryService { @@ -44,7 +44,7 @@ public interface ProductCategoryService {
44 * @param id 编号 44 * @param id 编号
45 * @return 商品分类 45 * @return 商品分类
46 */ 46 */
47 - ProductCategoryDO getProductCategory(Long id); 47 + ProductCategoryDO getCategory(Long id);
48 48
49 /** 49 /**
50 * 获得商品分类列表 50 * 获得商品分类列表
@@ -52,7 +52,7 @@ public interface ProductCategoryService { @@ -52,7 +52,7 @@ public interface ProductCategoryService {
52 * @param ids 编号 52 * @param ids 编号
53 * @return 商品分类列表 53 * @return 商品分类列表
54 */ 54 */
55 - List<ProductCategoryDO> getEnableProductCategoryList(Collection<Long> ids); 55 + List<ProductCategoryDO> getEnableCategoryList(Collection<Long> ids);
56 56
57 /** 57 /**
58 * 获得商品分类列表 58 * 获得商品分类列表
@@ -60,20 +60,21 @@ public interface ProductCategoryService { @@ -60,20 +60,21 @@ public interface ProductCategoryService {
60 * @param listReqVO 查询条件 60 * @param listReqVO 查询条件
61 * @return 商品分类列表 61 * @return 商品分类列表
62 */ 62 */
63 - List<ProductCategoryDO> getEnableProductCategoryList(ProductCategoryListReqVO listReqVO); 63 + List<ProductCategoryDO> getEnableCategoryList(ProductCategoryListReqVO listReqVO);
64 64
65 /** 65 /**
66 - * 验证选择的商品分类是否合法 66 + * 验证选择的商品分类的级别是否合法
  67 + * 例如说,商品发布的时候,必须在第 3 级别
67 * 68 *
68 * @param id 分类编号 69 * @param id 分类编号
69 */ 70 */
70 - void validateProductCategory(Long id); 71 + void validateCategoryLevel(Long id);
71 72
72 /** 73 /**
73 * 获得开启状态的商品分类列表 74 * 获得开启状态的商品分类列表
74 * 75 *
75 * @return 商品分类列表 76 * @return 商品分类列表
76 */ 77 */
77 - List<ProductCategoryDO> getEnableProductCategoryList(); 78 + List<ProductCategoryDO> getEnableCategoryList();
78 79
79 } 80 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java
@@ -32,7 +32,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { @@ -32,7 +32,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
32 private ProductCategoryMapper productCategoryMapper; 32 private ProductCategoryMapper productCategoryMapper;
33 33
34 @Override 34 @Override
35 - public Long createProductCategory(ProductCategoryCreateReqVO createReqVO) { 35 + public Long createCategory(ProductCategoryCreateReqVO createReqVO) {
36 // 校验父分类存在 36 // 校验父分类存在
37 validateParentProductCategory(createReqVO.getParentId()); 37 validateParentProductCategory(createReqVO.getParentId());
38 38
@@ -44,7 +44,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { @@ -44,7 +44,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
44 } 44 }
45 45
46 @Override 46 @Override
47 - public void updateProductCategory(ProductCategoryUpdateReqVO updateReqVO) { 47 + public void updateCategory(ProductCategoryUpdateReqVO updateReqVO) {
48 // 校验分类是否存在 48 // 校验分类是否存在
49 validateProductCategoryExists(updateReqVO.getId()); 49 validateProductCategoryExists(updateReqVO.getId());
50 // 校验父分类存在 50 // 校验父分类存在
@@ -56,12 +56,12 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { @@ -56,12 +56,12 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
56 } 56 }
57 57
58 @Override 58 @Override
59 - public void deleteProductCategory(Long id) { 59 + public void deleteCategory(Long id) {
60 // 校验分类是否存在 60 // 校验分类是否存在
61 validateProductCategoryExists(id); 61 validateProductCategoryExists(id);
62 // 校验是否还有子分类 62 // 校验是否还有子分类
63 if (productCategoryMapper.selectCountByParentId(id) > 0) { 63 if (productCategoryMapper.selectCountByParentId(id) > 0) {
64 - throw exception(PRODUCT_CATEGORY_EXISTS_CHILDREN); 64 + throw exception(CATEGORY_EXISTS_CHILDREN);
65 } 65 }
66 66
67 // 删除 67 // 删除
@@ -76,61 +76,69 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { @@ -76,61 +76,69 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
76 // 父分类不存在 76 // 父分类不存在
77 ProductCategoryDO category = productCategoryMapper.selectById(id); 77 ProductCategoryDO category = productCategoryMapper.selectById(id);
78 if (category == null) { 78 if (category == null) {
79 - throw exception(PRODUCT_CATEGORY_PARENT_NOT_EXISTS); 79 + throw exception(CATEGORY_PARENT_NOT_EXISTS);
80 } 80 }
81 // 父分类不能是二级分类 81 // 父分类不能是二级分类
82 if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) { 82 if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) {
83 - throw exception(PRODUCT_CATEGORY_PARENT_NOT_FIRST_LEVEL); 83 + throw exception(CATEGORY_PARENT_NOT_FIRST_LEVEL);
84 } 84 }
85 } 85 }
86 86
87 private void validateProductCategoryExists(Long id) { 87 private void validateProductCategoryExists(Long id) {
88 ProductCategoryDO category = productCategoryMapper.selectById(id); 88 ProductCategoryDO category = productCategoryMapper.selectById(id);
89 if (category == null) { 89 if (category == null) {
90 - throw exception(PRODUCT_CATEGORY_NOT_EXISTS); 90 + throw exception(CATEGORY_NOT_EXISTS);
91 } 91 }
92 } 92 }
93 93
94 @Override 94 @Override
95 - public void validateProductCategory(Long id) {  
96 - Integer level = categoryLevel(id, 1); 95 + public void validateCategoryLevel(Long id) {
  96 + Integer level = getProductCategoryLevel(id, 1);
97 if(level < 3){ 97 if(level < 3){
98 - throw exception(PRODUCT_CATEGORY_LEVEL); 98 + throw exception(CATEGORY_LEVEL_ERROR);
99 } 99 }
100 } 100 }
101 101
102 - // 校验分类级别  
103 - private Integer categoryLevel(Long id, int level){ 102 + // TODO @Luowenfeng:建议使用 for 循环,避免递归
  103 + /**
  104 + * 获得商品分类的级别
  105 + *
  106 + * @param id 商品分类的编号
  107 + * @return 级别
  108 + */
  109 + private Integer getProductCategoryLevel(Long id, int level){
104 ProductCategoryDO category = productCategoryMapper.selectById(id); 110 ProductCategoryDO category = productCategoryMapper.selectById(id);
105 if (category == null) { 111 if (category == null) {
106 - throw exception(PRODUCT_CATEGORY_NOT_EXISTS); 112 + throw exception(CATEGORY_NOT_EXISTS);
107 } 113 }
  114 + // TODO Luowenfeng:去掉是否开启,它不影响级别哈
108 if (ObjectUtil.notEqual(category.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { 115 if (ObjectUtil.notEqual(category.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
109 - throw exception(PRODUCT_CATEGORY_DISABLED); 116 + throw exception(CATEGORY_DISABLED);
110 } 117 }
111 - if(category.getParentId() == 0) { 118 + // TODO Luowenfeng:不使用 0 直接比较哈,使用枚举
  119 + if (category.getParentId() == 0) {
112 return level; 120 return level;
113 } 121 }
114 - return categoryLevel(category.getParentId(), ++level); 122 + return getProductCategoryLevel(category.getParentId(), ++level);
115 } 123 }
116 124
117 @Override 125 @Override
118 - public ProductCategoryDO getProductCategory(Long id) { 126 + public ProductCategoryDO getCategory(Long id) {
119 return productCategoryMapper.selectById(id); 127 return productCategoryMapper.selectById(id);
120 } 128 }
121 129
122 @Override 130 @Override
123 - public List<ProductCategoryDO> getEnableProductCategoryList(Collection<Long> ids) { 131 + public List<ProductCategoryDO> getEnableCategoryList(Collection<Long> ids) {
124 return productCategoryMapper.selectBatchIds(ids); 132 return productCategoryMapper.selectBatchIds(ids);
125 } 133 }
126 134
127 @Override 135 @Override
128 - public List<ProductCategoryDO> getEnableProductCategoryList(ProductCategoryListReqVO listReqVO) { 136 + public List<ProductCategoryDO> getEnableCategoryList(ProductCategoryListReqVO listReqVO) {
129 return productCategoryMapper.selectList(listReqVO); 137 return productCategoryMapper.selectList(listReqVO);
130 } 138 }
131 139
132 @Override 140 @Override
133 - public List<ProductCategoryDO> getEnableProductCategoryList() { 141 + public List<ProductCategoryDO> getEnableCategoryList() {
134 return productCategoryMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus()); 142 return productCategoryMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
135 } 143 }
136 144
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java
1 package cn.iocoder.yudao.module.product.service.property; 1 package cn.iocoder.yudao.module.product.service.property;
2 2
3 -import java.util.*;  
4 -import javax.validation.*; 3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.module.product.controller.admin.property.vo.*; 4 import cn.iocoder.yudao.module.product.controller.admin.property.vo.*;
6 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; 5 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
7 -import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 +
  7 +import javax.validation.Valid;
  8 +import java.util.Collection;
  9 +import java.util.List;
8 10
9 /** 11 /**
10 * 规格名称 Service 接口 12 * 规格名称 Service 接口
@@ -72,14 +74,16 @@ public interface ProductPropertyService { @@ -72,14 +74,16 @@ public interface ProductPropertyService {
72 * @param pageReqVO 74 * @param pageReqVO
73 * @return 75 * @return
74 */ 76 */
75 - PageResult<ProductPropertyRespVO> getPropertyListPage(ProductPropertyPageReqVO pageReqVO); 77 + PageResult<ProductPropertyAndValueRespVO> getPropertyListPage(ProductPropertyPageReqVO pageReqVO);
76 78
77 - ProductPropertyRespVO getPropertyResp(Long id); 79 + ProductPropertyAndValueRespVO getPropertyResp(Long id);
78 80
79 /** 81 /**
80 - * 根据数据名id集合查询属性名以及属性值的集合  
81 - * @param propertyIds 属性名id集合  
82 - * @return 82 + * 根据规格属性编号的集合,获得对应的规格 + 规格值的集合
  83 + *
  84 + * @param ids 规格编号的集合
  85 + * @return 对应的规格 + 规格值的集合
83 */ 86 */
84 - List<ProductPropertyRespVO> selectByIds(List<Long> propertyIds); 87 + List<ProductPropertyAndValueRespVO> getPropertyAndValueList(Collection<Long> ids);
  88 +
85 } 89 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java
@@ -108,11 +108,11 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { @@ -108,11 +108,11 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
108 } 108 }
109 109
110 @Override 110 @Override
111 - public PageResult<ProductPropertyRespVO> getPropertyListPage(ProductPropertyPageReqVO pageReqVO) { 111 + public PageResult<ProductPropertyAndValueRespVO> getPropertyListPage(ProductPropertyPageReqVO pageReqVO) {
112 //获取属性列表 112 //获取属性列表
113 PageResult<ProductPropertyDO> pageResult = productPropertyMapper.selectPage(pageReqVO); 113 PageResult<ProductPropertyDO> pageResult = productPropertyMapper.selectPage(pageReqVO);
114 - PageResult<ProductPropertyRespVO> propertyRespVOPageResult = ProductPropertyConvert.INSTANCE.convertPage(pageResult);  
115 - List<Long> propertyIds = propertyRespVOPageResult.getList().stream().map(ProductPropertyRespVO::getId).collect(Collectors.toList()); 114 + PageResult<ProductPropertyAndValueRespVO> propertyRespVOPageResult = ProductPropertyConvert.INSTANCE.convertPage(pageResult);
  115 + List<Long> propertyIds = propertyRespVOPageResult.getList().stream().map(ProductPropertyAndValueRespVO::getId).collect(Collectors.toList());
116 116
117 //获取属性值列表 117 //获取属性值列表
118 List<ProductPropertyValueDO> productPropertyValueDOList = productPropertyValueMapper.getPropertyValueListByPropertyId(propertyIds); 118 List<ProductPropertyValueDO> productPropertyValueDOList = productPropertyValueMapper.getPropertyValueListByPropertyId(propertyIds);
@@ -121,7 +121,7 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { @@ -121,7 +121,7 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
121 propertyRespVOPageResult.getList().forEach(x->{ 121 propertyRespVOPageResult.getList().forEach(x->{
122 Long propertyId = x.getId(); 122 Long propertyId = x.getId();
123 List<ProductPropertyValueRespVO> valueDOList = propertyValueRespVOList.stream().filter(v -> v.getPropertyId().equals(propertyId)).collect(Collectors.toList()); 123 List<ProductPropertyValueRespVO> valueDOList = propertyValueRespVOList.stream().filter(v -> v.getPropertyId().equals(propertyId)).collect(Collectors.toList());
124 - x.setPropertyValueList(valueDOList); 124 + x.setValues(valueDOList);
125 }); 125 });
126 return propertyRespVOPageResult; 126 return propertyRespVOPageResult;
127 } 127 }
@@ -131,25 +131,25 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { @@ -131,25 +131,25 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
131 } 131 }
132 132
133 @Override 133 @Override
134 - public ProductPropertyRespVO getPropertyResp(Long id) { 134 + public ProductPropertyAndValueRespVO getPropertyResp(Long id) {
135 //查询规格 135 //查询规格
136 ProductPropertyDO property = getProperty(id); 136 ProductPropertyDO property = getProperty(id);
137 - ProductPropertyRespVO propertyRespVO = ProductPropertyConvert.INSTANCE.convert(property); 137 + ProductPropertyAndValueRespVO propertyRespVO = ProductPropertyConvert.INSTANCE.convert(property);
138 //查询属性值 138 //查询属性值
139 List<ProductPropertyValueDO> valueDOList = productPropertyValueMapper.getPropertyValueListByPropertyId(Arrays.asList(id)); 139 List<ProductPropertyValueDO> valueDOList = productPropertyValueMapper.getPropertyValueListByPropertyId(Arrays.asList(id));
140 List<ProductPropertyValueRespVO> propertyValueRespVOS = ProductPropertyValueConvert.INSTANCE.convertList(valueDOList); 140 List<ProductPropertyValueRespVO> propertyValueRespVOS = ProductPropertyValueConvert.INSTANCE.convertList(valueDOList);
141 //组装 141 //组装
142 - propertyRespVO.setPropertyValueList(propertyValueRespVOS); 142 + propertyRespVO.setValues(propertyValueRespVOS);
143 return propertyRespVO; 143 return propertyRespVO;
144 } 144 }
145 145
146 @Override 146 @Override
147 - public List<ProductPropertyRespVO> selectByIds(List<Long> propertyIds) {  
148 - List<ProductPropertyRespVO> productPropertyRespVO = ProductPropertyConvert.INSTANCE.convertList(productPropertyMapper.selectBatchIds(propertyIds)); 147 + public List<ProductPropertyAndValueRespVO> getPropertyAndValueList(Collection<Long> ids) {
  148 + List<ProductPropertyAndValueRespVO> productPropertyRespVO = ProductPropertyConvert.INSTANCE.convertList(productPropertyMapper.selectBatchIds(ids));
149 //查询属性值 149 //查询属性值
150 - List<ProductPropertyValueDO> valueDOList = productPropertyValueMapper.getPropertyValueListByPropertyId(propertyIds); 150 + List<ProductPropertyValueDO> valueDOList = productPropertyValueMapper.selectBatchIds(ids);
151 Map<Long, List<ProductPropertyValueDO>> propertyValuesMap = valueDOList.stream().collect(Collectors.groupingBy(ProductPropertyValueDO::getPropertyId)); 151 Map<Long, List<ProductPropertyValueDO>> propertyValuesMap = valueDOList.stream().collect(Collectors.groupingBy(ProductPropertyValueDO::getPropertyId));
152 - productPropertyRespVO.forEach(p -> p.setPropertyValueList(ProductPropertyValueConvert.INSTANCE.convertList(propertyValuesMap.get(p.getId())))); 152 + productPropertyRespVO.forEach(p -> p.setValues(ProductPropertyValueConvert.INSTANCE.convertList(propertyValuesMap.get(p.getId()))));
153 return productPropertyRespVO; 153 return productPropertyRespVO;
154 } 154 }
155 } 155 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java
@@ -11,14 +11,14 @@ import java.util.Collection; @@ -11,14 +11,14 @@ import java.util.Collection;
11 import java.util.List; 11 import java.util.List;
12 12
13 /** 13 /**
14 - * 商品sku Service 接口 14 + * 商品 SKU Service 接口
15 * 15 *
16 * @author 芋道源码 16 * @author 芋道源码
17 */ 17 */
18 public interface ProductSkuService { 18 public interface ProductSkuService {
19 19
20 /** 20 /**
21 - * 创建商品sku 21 + * 创建商品 SKU
22 * 22 *
23 * @param createReqVO 创建信息 23 * @param createReqVO 创建信息
24 * @return 编号 24 * @return 编号
@@ -68,14 +68,15 @@ public interface ProductSkuService { @@ -68,14 +68,15 @@ public interface ProductSkuService {
68 * 68 *
69 * @param list sku组合的集合 69 * @param list sku组合的集合
70 */ 70 */
71 - void validateProductSkus(List<ProductSkuCreateOrUpdateReqVO> list, Integer specType); 71 + void validateSkus(List<ProductSkuCreateOrUpdateReqVO> list, Integer specType);
72 72
73 /** 73 /**
74 * 批量创建 SKU 74 * 批量创建 SKU
75 * 75 *
  76 + * @param spuId 商品 SPU 编号
76 * @param list SKU 对象集合 77 * @param list SKU 对象集合
77 */ 78 */
78 - void createProductSkus(List<ProductSkuCreateOrUpdateReqVO> list, Long spuId); 79 + void createSkus(Long spuId, List<ProductSkuCreateOrUpdateReqVO> list);
79 80
80 /** 81 /**
81 * 根据 SPU 编号,批量更新它的 SKU 信息 82 * 根据 SPU 编号,批量更新它的 SKU 信息
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
1 package cn.iocoder.yudao.module.product.service.sku; 1 package cn.iocoder.yudao.module.product.service.sku;
2 2
3 import cn.hutool.core.collection.CollectionUtil; 3 import cn.hutool.core.collection.CollectionUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 -import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyRespVO; 7 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyAndValueRespVO;
7 import cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo.ProductPropertyValueRespVO; 8 import cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo.ProductPropertyValueRespVO;
8 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; 9 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
9 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; 10 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
@@ -24,11 +25,10 @@ import java.util.*; @@ -24,11 +25,10 @@ import java.util.*;
24 import java.util.stream.Collectors; 25 import java.util.stream.Collectors;
25 26
26 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 27 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
27 -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_NOT_EXISTS;  
28 -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; 28 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
29 29
30 /** 30 /**
31 - * 商品sku Service 实现类 31 + * 商品 SKU Service 实现类
32 * 32 *
33 * @author 芋道源码 33 * @author 芋道源码
34 */ 34 */
@@ -90,48 +90,51 @@ public class ProductSkuServiceImpl implements ProductSkuService { @@ -90,48 +90,51 @@ public class ProductSkuServiceImpl implements ProductSkuService {
90 } 90 }
91 91
92 @Override 92 @Override
93 - public void validateProductSkus(List<ProductSkuCreateOrUpdateReqVO> list, Integer specType) {  
94 - // 多规格才需校验  
95 - if (specType.equals(ProductSpuSpecTypeEnum.DISABLE.getType())) {  
96 - List<ProductSkuBaseVO.Property> skuPropertyList = list.stream().flatMap(p -> Optional.of(p.getProperties()).orElse(new ArrayList<>()).stream()).collect(Collectors.toList());  
97 - // 1、校验规格属性存在  
98 - List<Long> propertyIds = CollectionUtils.convertList(skuPropertyList, ProductSkuBaseVO.Property::getPropertyId);  
99 - List<ProductPropertyRespVO> propertyAndValueList = productPropertyService.selectByIds(propertyIds);  
100 - if (propertyAndValueList.size() == propertyIds.size()) {  
101 - throw exception(PROPERTY_NOT_EXISTS); 93 + public void validateSkus(List<ProductSkuCreateOrUpdateReqVO> skus, Integer specType) {
  94 + // 非多规格,不需要校验
  95 + if (ObjectUtil.notEqual(specType, ProductSpuSpecTypeEnum.DISABLE.getType())) {
  96 + return;
  97 + }
  98 +
  99 + // 1、校验规格属性存在
  100 + // TODO @Luowenfeng:stream 的写法;不用改哈,就是说下可以酱紫写;
  101 + Set<Long> propertyIds = skus.stream().filter(p -> p.getProperties() != null).flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性
  102 + .map(ProductSkuBaseVO.Property::getPropertyId).collect(Collectors.toSet()); // 将每个 Property 转换成对应的 propertyId,最后形成集合
  103 + List<ProductPropertyAndValueRespVO> propertyAndValueList = productPropertyService.getPropertyAndValueList(propertyIds);
  104 + if (propertyAndValueList.size() == propertyIds.size()) {
  105 + throw exception(PROPERTY_NOT_EXISTS);
  106 + }
  107 +
  108 + // 2. 校验,一个 SKU 下,没有重复的规格。校验方式是,遍历每个 SKU ,看看是否有重复的规格 propertyId
  109 + Map<Long, ProductPropertyValueRespVO> propertyValueMap = propertyAndValueList.stream().filter(p -> p.getValues() != null).flatMap(p -> p.getValues().stream())
  110 + .collect(Collectors.toMap(ProductPropertyValueRespVO::getId, value -> value)); // KEY:规格属性值的编号
  111 + skus.forEach(sku -> {
  112 + Set<Long> skuPropertyIds = CollectionUtils.convertSet(sku.getProperties(), propertyItem -> propertyValueMap.get(propertyItem.getValueId()).getPropertyId());
  113 + if (skuPropertyIds.size() != sku.getProperties().size()) {
  114 + throw exception(SKU_PROPERTIES_DUPLICATED);
102 } 115 }
103 - // 2. 校验,一个 Sku 下,没有重复的规格。校验方式是,遍历每个 Sku ,看看是否有重复的规格 attrId  
104 - List<ProductPropertyValueRespVO> collect = propertyAndValueList.stream()  
105 - .flatMap(v -> Optional.of(v.getPropertyValueList())  
106 - .orElse(new ArrayList<>()).stream()).collect(Collectors.toList());  
107 - Map<Long, ProductPropertyValueRespVO> propertyValueRespVOMap = CollectionUtils.convertMap(collect, ProductPropertyValueRespVO::getId);  
108 - list.forEach(v -> {  
109 - Set<Long> keys = v.getProperties().stream().map(k -> propertyValueRespVOMap.get(k.getValueId()).getPropertyId()).collect(Collectors.toSet());  
110 - if (keys.size() != v.getProperties().size()) {  
111 - throw exception(ErrorCodeConstants.SKU_PROPERTIES_DUPLICATED);  
112 - }  
113 - }); 116 + });
114 117
115 - // 3. 再校验,每个 Sku 的规格值的数量,是一致的。  
116 - int attrValueIdsSize = list.get(0).getProperties().size();  
117 - for (int i = 1; i < list.size(); i++) {  
118 - if (attrValueIdsSize != list.get(i).getProperties().size()) {  
119 - throw exception(ErrorCodeConstants.PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS);  
120 - } 118 + // 3. 再校验,每个 Sku 的规格值的数量,是一致的。
  119 + int attrValueIdsSize = skus.get(0).getProperties().size();
  120 + for (int i = 1; i < skus.size(); i++) {
  121 + if (attrValueIdsSize != skus.get(i).getProperties().size()) {
  122 + throw exception(ErrorCodeConstants.SPU_ATTR_NUMBERS_MUST_BE_EQUALS);
121 } 123 }
  124 + }
122 125
123 - // 4. 最后校验,每个 Sku 之间不是重复的  
124 - Set<Set<Long>> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的.  
125 - for (ProductSkuCreateOrUpdateReqVO sku : list) {  
126 - if (!skuAttrValues.add(sku.getProperties().stream().map(ProductSkuBaseVO.Property::getValueId).collect(Collectors.toSet()))) { // 添加失败,说明重复  
127 - throw exception(ErrorCodeConstants.PRODUCT_SPU_SKU_NOT_DUPLICATE);  
128 - } 126 + // 4. 最后校验,每个 Sku 之间不是重复的
  127 + Set<Set<Long>> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的.
  128 + for (ProductSkuCreateOrUpdateReqVO sku : skus) {
  129 + // TODO @Luowenfeng:可以使用 CollectionUtils.convertSet(),简化下面的 stream 操作
  130 + if (!skuAttrValues.add(sku.getProperties().stream().map(ProductSkuBaseVO.Property::getValueId).collect(Collectors.toSet()))) { // 添加失败,说明重复
  131 + throw exception(ErrorCodeConstants.SPU_SKU_NOT_DUPLICATE);
129 } 132 }
130 } 133 }
131 } 134 }
132 135
133 @Override 136 @Override
134 - public void createProductSkus(List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList, Long spuId) { 137 + public void createSkus(Long spuId, List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList) {
135 // 批量插入 SKU 138 // 批量插入 SKU
136 List<ProductSkuDO> skuDOList = ProductSkuConvert.INSTANCE.convertSkuDOList(skuCreateReqList); 139 List<ProductSkuDO> skuDOList = ProductSkuConvert.INSTANCE.convertSkuDOList(skuCreateReqList);
137 skuDOList.forEach(v -> v.setSpuId(spuId)); 140 skuDOList.forEach(v -> v.setSpuId(spuId));
@@ -140,13 +143,12 @@ public class ProductSkuServiceImpl implements ProductSkuService { @@ -140,13 +143,12 @@ public class ProductSkuServiceImpl implements ProductSkuService {
140 143
141 @Override 144 @Override
142 public List<ProductSkuDO> getSkusBySpuId(Long spuId) { 145 public List<ProductSkuDO> getSkusBySpuId(Long spuId) {
143 - List<ProductSkuDO> productSkuDOS = productSkuMapper.selectBySpuIds(Collections.singletonList(spuId));  
144 - return productSkuDOS; 146 + return productSkuMapper.selectListBySpuIds(Collections.singletonList(spuId));
145 } 147 }
146 148
147 @Override 149 @Override
148 public List<ProductSkuDO> getSkusBySpuIds(List<Long> spuIds) { 150 public List<ProductSkuDO> getSkusBySpuIds(List<Long> spuIds) {
149 - return productSkuMapper.selectBySpuIds(spuIds); 151 + return productSkuMapper.selectListBySpuIds(spuIds);
150 } 152 }
151 153
152 @Override 154 @Override
@@ -157,16 +159,16 @@ public class ProductSkuServiceImpl implements ProductSkuService { @@ -157,16 +159,16 @@ public class ProductSkuServiceImpl implements ProductSkuService {
157 @Override 159 @Override
158 @Transactional 160 @Transactional
159 public void updateProductSkus(Long spuId, List<ProductSkuCreateOrUpdateReqVO> skus) { 161 public void updateProductSkus(Long spuId, List<ProductSkuCreateOrUpdateReqVO> skus) {
160 - // 查询 spu 下已经存在的 sku 的集合  
161 - List<ProductSkuDO> existsSkus = productSkuMapper.selectBySpuId(spuId); 162 + // 查询 SPU 下已经存在的 SKU 的集合
  163 + List<ProductSkuDO> existsSkus = productSkuMapper.selectListBySpuId(spuId);
162 Map<Long, ProductSkuDO> existsSkuMap = CollectionUtils.convertMap(existsSkus, ProductSkuDO::getId); 164 Map<Long, ProductSkuDO> existsSkuMap = CollectionUtils.convertMap(existsSkus, ProductSkuDO::getId);
163 165
164 // 拆分三个集合,新插入的、需要更新的、需要删除的 166 // 拆分三个集合,新插入的、需要更新的、需要删除的
165 List<ProductSkuDO> insertSkus = new ArrayList<>(); 167 List<ProductSkuDO> insertSkus = new ArrayList<>();
166 - List<ProductSkuDO> updateSkus = new ArrayList<>(); 168 + List<ProductSkuDO> updateSkus = new ArrayList<>(); // TODO Luowenfeng:使用 Long 即可
167 List<ProductSkuDO> deleteSkus = new ArrayList<>(); 169 List<ProductSkuDO> deleteSkus = new ArrayList<>();
168 170
169 - // TODO @芋艿:是不是基于规格匹配会比较好。 171 + // TODO @Luowenfeng:是不是基于规格匹配会比较好。可以参考下 onemall 的 ProductSpuServiceImpl 的 updateProductSpu 逻辑
170 List<ProductSkuDO> allUpdateSkus = ProductSkuConvert.INSTANCE.convertSkuDOList(skus); 172 List<ProductSkuDO> allUpdateSkus = ProductSkuConvert.INSTANCE.convertSkuDOList(skus);
171 allUpdateSkus.forEach(p -> { 173 allUpdateSkus.forEach(p -> {
172 if (p.getId() != null) { 174 if (p.getId() != null) {
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java
@@ -26,14 +26,14 @@ public interface ProductSpuService { @@ -26,14 +26,14 @@ public interface ProductSpuService {
26 * @param createReqVO 创建信息 26 * @param createReqVO 创建信息
27 * @return 编号 27 * @return 编号
28 */ 28 */
29 - Long createProductSpu(@Valid ProductSpuCreateReqVO createReqVO); 29 + Long createSpu(@Valid ProductSpuCreateReqVO createReqVO);
30 30
31 /** 31 /**
32 * 更新商品 SPU 32 * 更新商品 SPU
33 * 33 *
34 * @param updateReqVO 更新信息 34 * @param updateReqVO 更新信息
35 */ 35 */
36 - void updateProductSpu(@Valid ProductSpuUpdateReqVO updateReqVO); 36 + void updateSpu(@Valid ProductSpuUpdateReqVO updateReqVO);
37 37
38 /** 38 /**
39 * 删除商品spu 39 * 删除商品spu
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.product.service.spu; @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.product.service.spu;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 -import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyRespVO; 5 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyAndValueRespVO;
6 import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO; 6 import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO;
7 import cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo.ProductPropertyValueRespVO; 7 import cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo.ProductPropertyValueRespVO;
8 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; 8 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
@@ -16,7 +16,6 @@ import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO; @@ -16,7 +16,6 @@ import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
16 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO; 16 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
17 import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; 17 import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
18 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; 18 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
19 -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;  
20 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; 19 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
21 import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; 20 import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
22 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; 21 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
@@ -30,7 +29,6 @@ import org.springframework.validation.annotation.Validated; @@ -30,7 +29,6 @@ import org.springframework.validation.annotation.Validated;
30 29
31 import javax.annotation.Resource; 30 import javax.annotation.Resource;
32 import java.util.*; 31 import java.util.*;
33 -import java.util.function.Function;  
34 import java.util.stream.Collectors; 32 import java.util.stream.Collectors;
35 33
36 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 34 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -62,14 +60,14 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -62,14 +60,14 @@ public class ProductSpuServiceImpl implements ProductSpuService {
62 60
63 @Override 61 @Override
64 @Transactional 62 @Transactional
65 - public Long createProductSpu(ProductSpuCreateReqVO createReqVO) { 63 + public Long createSpu(ProductSpuCreateReqVO createReqVO) {
66 // 校验分类 64 // 校验分类
67 - categoryService.validateProductCategory(createReqVO.getCategoryId()); 65 + categoryService.validateCategoryLevel(createReqVO.getCategoryId());
68 // 校验品牌 66 // 校验品牌
69 brandService.validateProductBrand(createReqVO.getBrandId()); 67 brandService.validateProductBrand(createReqVO.getBrandId());
70 // 校验SKU 68 // 校验SKU
71 List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = createReqVO.getSkus(); 69 List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = createReqVO.getSkus();
72 - productSkuService.validateProductSkus(skuCreateReqList, createReqVO.getSpecType()); 70 + productSkuService.validateSkus(skuCreateReqList, createReqVO.getSpecType());
73 // 插入 SPU 71 // 插入 SPU
74 ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO); 72 ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO);
75 spu.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); 73 spu.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice));
@@ -78,24 +76,25 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -78,24 +76,25 @@ public class ProductSpuServiceImpl implements ProductSpuService {
78 spu.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); 76 spu.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
79 ProductSpuMapper.insert(spu); 77 ProductSpuMapper.insert(spu);
80 // 插入 SKU 78 // 插入 SKU
81 - productSkuService.createProductSkus(skuCreateReqList, spu.getId()); 79 + productSkuService.createSkus(spu.getId(), skuCreateReqList);
82 // 返回 80 // 返回
83 return spu.getId(); 81 return spu.getId();
84 } 82 }
85 83
86 @Override 84 @Override
87 @Transactional 85 @Transactional
88 - public void updateProductSpu(ProductSpuUpdateReqVO updateReqVO) { 86 + public void updateSpu(ProductSpuUpdateReqVO updateReqVO) {
89 // 校验 SPU 是否存在 87 // 校验 SPU 是否存在
90 validateSpuExists(updateReqVO.getId()); 88 validateSpuExists(updateReqVO.getId());
91 // 校验分类 89 // 校验分类
92 - categoryService.validateProductCategory(updateReqVO.getCategoryId()); 90 + categoryService.validateCategoryLevel(updateReqVO.getCategoryId());
93 // 校验品牌 91 // 校验品牌
94 brandService.validateProductBrand(updateReqVO.getBrandId()); 92 brandService.validateProductBrand(updateReqVO.getBrandId());
95 // 校验SKU 93 // 校验SKU
96 List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = updateReqVO.getSkus(); 94 List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = updateReqVO.getSkus();
97 // 多规格才需校验 95 // 多规格才需校验
98 - productSkuService.validateProductSkus(skuCreateReqList, updateReqVO.getSpecType()); 96 + productSkuService.validateSkus(skuCreateReqList, updateReqVO.getSpecType());
  97 +
99 // 更新 SPU 98 // 更新 SPU
100 ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO); 99 ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO);
101 updateObj.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); 100 updateObj.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice));
@@ -103,7 +102,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -103,7 +102,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
103 updateObj.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); 102 updateObj.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice));
104 updateObj.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); 103 updateObj.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
105 ProductSpuMapper.updateById(updateObj); 104 ProductSpuMapper.updateById(updateObj);
106 - // 更新 SKU 105 + // 批量更新 SKU
107 productSkuService.updateProductSkus(updateObj.getId(), updateReqVO.getSkus()); 106 productSkuService.updateProductSkus(updateObj.getId(), updateReqVO.getSkus());
108 } 107 }
109 108
@@ -111,7 +110,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -111,7 +110,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
111 @Transactional 110 @Transactional
112 public void deleteSpu(Long id) { 111 public void deleteSpu(Long id) {
113 // 校验存在 112 // 校验存在
114 - this.validateSpuExists(id); 113 + validateSpuExists(id);
115 // 删除 SPU 114 // 删除 SPU
116 ProductSpuMapper.deleteById(id); 115 ProductSpuMapper.deleteById(id);
117 // 删除关联的 SKU 116 // 删除关联的 SKU
@@ -125,6 +124,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -125,6 +124,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
125 } 124 }
126 125
127 @Override 126 @Override
  127 + // TODO @芋艿:需要再 review 下
128 public SpuRespVO getSpu(Long id) { 128 public SpuRespVO getSpu(Long id) {
129 ProductSpuDO spu = ProductSpuMapper.selectById(id); 129 ProductSpuDO spu = ProductSpuMapper.selectById(id);
130 SpuRespVO spuVO = ProductSpuConvert.INSTANCE.convert(spu); 130 SpuRespVO spuVO = ProductSpuConvert.INSTANCE.convert(spu);
@@ -138,7 +138,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -138,7 +138,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
138 properties.addAll(productSkuRespVO.getProperties()); 138 properties.addAll(productSkuRespVO.getProperties());
139 } 139 }
140 Map<Long, List<ProductSkuBaseVO.Property>> propertyMaps = properties.stream().collect(Collectors.groupingBy(ProductSkuBaseVO.Property::getPropertyId)); 140 Map<Long, List<ProductSkuBaseVO.Property>> propertyMaps = properties.stream().collect(Collectors.groupingBy(ProductSkuBaseVO.Property::getPropertyId));
141 - List<ProductPropertyRespVO> propertyAndValueList = productPropertyService.selectByIds(new ArrayList<>(propertyMaps.keySet())); 141 + List<ProductPropertyAndValueRespVO> propertyAndValueList = productPropertyService.getPropertyAndValueList(new ArrayList<>(propertyMaps.keySet()));
142 // 装载组装过后的属性 142 // 装载组装过后的属性
143 List<ProductPropertyViewRespVO> productPropertyViews = new ArrayList<>(); 143 List<ProductPropertyViewRespVO> productPropertyViews = new ArrayList<>();
144 propertyAndValueList.forEach(p -> { 144 propertyAndValueList.forEach(p -> {
@@ -146,7 +146,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -146,7 +146,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
146 productPropertyViewRespVO.setPropertyId(p.getId()); 146 productPropertyViewRespVO.setPropertyId(p.getId());
147 productPropertyViewRespVO.setName(p.getName()); 147 productPropertyViewRespVO.setName(p.getName());
148 List<ProductPropertyViewRespVO.Tuple2> propertyValues = new ArrayList<>(); 148 List<ProductPropertyViewRespVO.Tuple2> propertyValues = new ArrayList<>();
149 - Map<Long, ProductPropertyValueRespVO> propertyValueMaps = p.getPropertyValueList().stream().collect(Collectors.toMap(ProductPropertyValueRespVO::getId, pv -> pv)); 149 + Map<Long, ProductPropertyValueRespVO> propertyValueMaps = p.getValues().stream().collect(Collectors.toMap(ProductPropertyValueRespVO::getId, pv -> pv));
150 propertyMaps.get(p.getId()).forEach(pv -> { 150 propertyMaps.get(p.getId()).forEach(pv -> {
151 ProductPropertyViewRespVO.Tuple2 tuple2 = new ProductPropertyViewRespVO.Tuple2(pv.getValueId(), propertyValueMaps.get(pv.getValueId()).getName()); 151 ProductPropertyViewRespVO.Tuple2 tuple2 = new ProductPropertyViewRespVO.Tuple2(pv.getValueId(), propertyValueMaps.get(pv.getValueId()).getName());
152 propertyValues.add(tuple2); 152 propertyValues.add(tuple2);
@@ -162,7 +162,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -162,7 +162,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
162 Long parentId = spuVO.getCategoryId(); 162 Long parentId = spuVO.getCategoryId();
163 categoryArray.addFirst(parentId); 163 categoryArray.addFirst(parentId);
164 while (parentId != 0) { 164 while (parentId != 0) {
165 - parentId = categoryService.getProductCategory(parentId).getParentId(); 165 + parentId = categoryService.getCategory(parentId).getParentId();
166 if (parentId > 0) { 166 if (parentId > 0) {
167 categoryArray.addFirst(parentId); 167 categoryArray.addFirst(parentId);
168 } 168 }
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImplTest.java
@@ -20,7 +20,7 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq @@ -20,7 +20,7 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq
20 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 20 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
21 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; 21 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
22 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; 22 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
23 -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_BRAND_NOT_EXISTS; 23 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.BRAND_NOT_EXISTS;
24 import static org.junit.jupiter.api.Assertions.*; 24 import static org.junit.jupiter.api.Assertions.*;
25 25
26 /** 26 /**
@@ -74,7 +74,7 @@ public class ProductBrandServiceImplTest extends BaseDbUnitTest { @@ -74,7 +74,7 @@ public class ProductBrandServiceImplTest extends BaseDbUnitTest {
74 ProductBrandUpdateReqVO reqVO = randomPojo(ProductBrandUpdateReqVO.class); 74 ProductBrandUpdateReqVO reqVO = randomPojo(ProductBrandUpdateReqVO.class);
75 75
76 // 调用, 并断言异常 76 // 调用, 并断言异常
77 - assertServiceException(() -> brandService.updateBrand(reqVO), PRODUCT_BRAND_NOT_EXISTS); 77 + assertServiceException(() -> brandService.updateBrand(reqVO), BRAND_NOT_EXISTS);
78 } 78 }
79 79
80 @Test 80 @Test
@@ -97,7 +97,7 @@ public class ProductBrandServiceImplTest extends BaseDbUnitTest { @@ -97,7 +97,7 @@ public class ProductBrandServiceImplTest extends BaseDbUnitTest {
97 Long id = randomLongId(); 97 Long id = randomLongId();
98 98
99 // 调用, 并断言异常 99 // 调用, 并断言异常
100 - assertServiceException(() -> brandService.deleteBrand(id), PRODUCT_BRAND_NOT_EXISTS); 100 + assertServiceException(() -> brandService.deleteBrand(id), BRAND_NOT_EXISTS);
101 } 101 }
102 102
103 @Test 103 @Test
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java
@@ -17,7 +17,7 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq @@ -17,7 +17,7 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq
17 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 17 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
18 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; 18 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
19 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; 19 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
20 -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_CATEGORY_NOT_EXISTS; 20 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS;
21 import static org.junit.jupiter.api.Assertions.*; 21 import static org.junit.jupiter.api.Assertions.*;
22 22
23 /** 23 /**
@@ -43,7 +43,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { @@ -43,7 +43,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest {
43 productCategoryMapper.insert(parentProductCategory); 43 productCategoryMapper.insert(parentProductCategory);
44 44
45 // 调用 45 // 调用
46 - Long categoryId = productCategoryService.createProductCategory(reqVO); 46 + Long categoryId = productCategoryService.createCategory(reqVO);
47 // 断言 47 // 断言
48 assertNotNull(categoryId); 48 assertNotNull(categoryId);
49 // 校验记录的属性是否正确 49 // 校验记录的属性是否正确
@@ -65,7 +65,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { @@ -65,7 +65,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest {
65 productCategoryMapper.insert(parentProductCategory); 65 productCategoryMapper.insert(parentProductCategory);
66 66
67 // 调用 67 // 调用
68 - productCategoryService.updateProductCategory(reqVO); 68 + productCategoryService.updateCategory(reqVO);
69 // 校验是否更新正确 69 // 校验是否更新正确
70 ProductCategoryDO category = productCategoryMapper.selectById(reqVO.getId()); // 获取最新的 70 ProductCategoryDO category = productCategoryMapper.selectById(reqVO.getId()); // 获取最新的
71 assertPojoEquals(reqVO, category); 71 assertPojoEquals(reqVO, category);
@@ -77,7 +77,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { @@ -77,7 +77,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest {
77 ProductCategoryUpdateReqVO reqVO = randomPojo(ProductCategoryUpdateReqVO.class); 77 ProductCategoryUpdateReqVO reqVO = randomPojo(ProductCategoryUpdateReqVO.class);
78 78
79 // 调用, 并断言异常 79 // 调用, 并断言异常
80 - assertServiceException(() -> productCategoryService.updateProductCategory(reqVO), PRODUCT_CATEGORY_NOT_EXISTS); 80 + assertServiceException(() -> productCategoryService.updateCategory(reqVO), CATEGORY_NOT_EXISTS);
81 } 81 }
82 82
83 @Test 83 @Test
@@ -89,7 +89,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { @@ -89,7 +89,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest {
89 Long id = dbCategory.getId(); 89 Long id = dbCategory.getId();
90 90
91 // 调用 91 // 调用
92 - productCategoryService.deleteProductCategory(id); 92 + productCategoryService.deleteCategory(id);
93 // 校验数据不存在了 93 // 校验数据不存在了
94 assertNull(productCategoryMapper.selectById(id)); 94 assertNull(productCategoryMapper.selectById(id));
95 } 95 }
@@ -100,7 +100,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { @@ -100,7 +100,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest {
100 Long id = randomLongId(); 100 Long id = randomLongId();
101 101
102 // 调用, 并断言异常 102 // 调用, 并断言异常
103 - assertServiceException(() -> productCategoryService.deleteProductCategory(id), PRODUCT_CATEGORY_NOT_EXISTS); 103 + assertServiceException(() -> productCategoryService.deleteCategory(id), CATEGORY_NOT_EXISTS);
104 } 104 }
105 105
106 @Test 106 @Test
@@ -117,7 +117,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { @@ -117,7 +117,7 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest {
117 reqVO.setName("特曼"); 117 reqVO.setName("特曼");
118 118
119 // 调用 119 // 调用
120 - List<ProductCategoryDO> list = productCategoryService.getEnableProductCategoryList(reqVO); 120 + List<ProductCategoryDO> list = productCategoryService.getEnableCategoryList(reqVO);
121 // 断言 121 // 断言
122 assertEquals(1, list.size()); 122 assertEquals(1, list.size());
123 assertPojoEquals(dbCategory, list.get(0)); 123 assertPojoEquals(dbCategory, list.get(0));
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java
@@ -41,7 +41,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @@ -41,7 +41,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
41 ProductSpuCreateReqVO reqVO = randomPojo(ProductSpuCreateReqVO.class); 41 ProductSpuCreateReqVO reqVO = randomPojo(ProductSpuCreateReqVO.class);
42 42
43 // 调用 43 // 调用
44 - Long spuId = spuService.createProductSpu(reqVO); 44 + Long spuId = spuService.createSpu(reqVO);
45 // 断言 45 // 断言
46 assertNotNull(spuId); 46 assertNotNull(spuId);
47 // 校验记录的属性是否正确 47 // 校验记录的属性是否正确
@@ -60,7 +60,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @@ -60,7 +60,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
60 }); 60 });
61 61
62 // 调用 62 // 调用
63 - spuService.updateProductSpu(reqVO); 63 + spuService.updateSpu(reqVO);
64 // 校验是否更新正确 64 // 校验是否更新正确
65 ProductSpuDO spu = ProductSpuMapper.selectById(reqVO.getId()); // 获取最新的 65 ProductSpuDO spu = ProductSpuMapper.selectById(reqVO.getId()); // 获取最新的
66 assertPojoEquals(reqVO, spu); 66 assertPojoEquals(reqVO, spu);
@@ -72,7 +72,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @@ -72,7 +72,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
72 ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class); 72 ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class);
73 73
74 // 调用, 并断言异常 74 // 调用, 并断言异常
75 - assertServiceException(() -> spuService.updateProductSpu(reqVO), SPU_NOT_EXISTS); 75 + assertServiceException(() -> spuService.updateSpu(reqVO), SPU_NOT_EXISTS);
76 } 76 }
77 77
78 @Test 78 @Test