Commit b065a2a741853df5ce087e35e12890da6bbda1f1

Authored by puhui999
1 parent c62da6a0

fix:修复商品 review 提到的问题

Showing 30 changed files with 155 additions and 283 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductUnitEnum.java deleted
1   -package cn.iocoder.yudao.module.product.enums.spu;
2   -
3   -import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
4   -import lombok.AllArgsConstructor;
5   -import lombok.Getter;
6   -
7   -import java.util.Arrays;
8   -
9   -// TODO @puhui999:是不是放到数据字典里?
10   -/**
11   - * 产品单位枚举
12   - *
13   - * @author HUIHUI
14   - */
15   -@Getter
16   -@AllArgsConstructor
17   -public enum ProductUnitEnum implements IntArrayValuable {
18   -
19   - PIECE(1, "个"),
20   - DOZEN(2, "打"),
21   - BOX(3, "盒"),
22   - BAG(4, "袋"),
23   - CASE(5, "箱"),
24   - SET(6, "套"),
25   - PACK(7, "包"),
26   - PAIR(8, "双"),
27   - ROLL(9, "卷"),
28   - SHEET(10, "张"),
29   - WEIGHT(11, "克"),
30   - KILOGRAM(12, "千克"),
31   - MILLIGRAM(13, "毫克"),
32   - MICROGRAM(14, "微克"),
33   - TON(15, "吨"),
34   - LITER(16, "升"),
35   - MILLILITER(17, "毫升"),
36   - SQUARE_METER(19, "平方米"),
37   - SQUARE_KILOMETER(20, "平方千米"),
38   - SQUARE_MILE(21, "平方英里"),
39   - SQUARE_YARD(22, "平方码"),
40   - SQUARE_FOOT(23, "平方英尺"),
41   - CUBIC_METER(24, "立方米"),
42   - CUBIC_CENTIMETER(25, "立方厘米"),
43   - CUBIC_INCH(26, "立方英寸"),
44   - METER(27, "米"),
45   - CENTIMETER(29, "厘米"),
46   - MILLIMETER(30, "毫米"),
47   - INCH(31, "英寸"),
48   - FOOT(32, "英尺"),
49   - YARD(33, "码"),
50   - ;
51   -
52   - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductUnitEnum::getStatus).toArray();
53   -
54   - /**
55   - * 状态
56   - */
57   - private final Integer status;
58   - /**
59   - * 状态名
60   - */
61   - private final String name;
62   -
63   - @Override
64   - public int[] array() {
65   - return ARRAYS;
66   - }
67   -}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java
... ... @@ -61,7 +61,8 @@ public class ProductBrandController {
61 61 public CommonResult<ProductBrandRespVO> getBrand(@RequestParam("id") Long id) {
62 62 ProductBrandDO brand = brandService.getBrand(id);
63 63 return success(ProductBrandConvert.INSTANCE.convert(brand));
64   - } // TODO @puhui999:方法和方法之间,要有空行。
  64 + }
  65 +
65 66 @GetMapping("/list-all-simple")
66 67 @Operation(summary = "获取品牌精简信息列表", description = "主要用于前端的下拉选项")
67 68 public CommonResult<List<ProductBrandSimpleRespVO>> getSimpleUserList() {
... ... @@ -70,6 +71,7 @@ public class ProductBrandController {
70 71 // 排序后,返回给前端
71 72 return success(ProductBrandConvert.INSTANCE.convertList1(list));
72 73 }
  74 +
73 75 @GetMapping("/page")
74 76 @Operation(summary = "获得品牌分页")
75 77 @PreAuthorize("@ss.hasPermission('product:brand:query')")
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java
... ... @@ -12,7 +12,7 @@ import javax.validation.constraints.NotNull;
12 12 @Data
13 13 public class ProductBrandBaseVO {
14 14  
15   - @Schema(description = "品牌名称", required = true, example = "芋道")
  15 + @Schema(description = "品牌名称", required = true, example = "苹果")
16 16 @NotNull(message = "品牌名称不能为空")
17 17 private String name;
18 18  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java
... ... @@ -7,7 +7,7 @@ import lombok.Data;
7 7 @Data
8 8 public class ProductBrandListReqVO {
9 9  
10   - @Schema(description = "品牌名称", example = "芋道")
  10 + @Schema(description = "品牌名称", example = "苹果")
11 11 private String name;
12 12  
13 13 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java
... ... @@ -17,7 +17,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
17 17 @ToString(callSuper = true)
18 18 public class ProductBrandPageReqVO extends PageParam {
19 19  
20   - @Schema(description = "品牌名称", example = "芋道")
  20 + @Schema(description = "品牌名称", example = "苹果")
21 21 private String name;
22 22  
23 23 @Schema(description = "状态", example = "0")
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandSimpleRespVO.java
... ... @@ -11,8 +11,11 @@ import lombok.NoArgsConstructor;
11 11 @NoArgsConstructor
12 12 @AllArgsConstructor
13 13 public class ProductBrandSimpleRespVO {
  14 +
14 15 @Schema(description = "品牌编号", required = true, example = "1024")
15 16 private Long id;
16   - @Schema(description = "品牌名称", required = true, example = "芋道")
  17 +
  18 + @Schema(description = "品牌名称", required = true, example = "苹果")
17 19 private String name;
  20 +
18 21 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java
... ... @@ -12,6 +12,8 @@ import javax.validation.constraints.NotBlank;
12 12 @EqualsAndHashCode(callSuper = true)
13 13 @ToString(callSuper = true)
14 14 public class ProductCategoryCreateReqVO extends ProductCategoryBaseVO {
15   - @Schema(description = "分类描述")
  15 +
  16 + @Schema(description = "分类描述", example = "描述")
16 17 private String description;
  18 +
17 19 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java
... ... @@ -17,7 +17,8 @@ public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO {
17 17 @Schema(description = "分类编号", required = true, example = "2")
18 18 @NotNull(message = "分类编号不能为空")
19 19 private Long id;
20   - @Schema(description = "分类描述")
  20 +
  21 + @Schema(description = "分类描述", example = "描述")
21 22 private String description;
22 23  
23 24 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java
... ... @@ -7,6 +7,7 @@ import lombok.NoArgsConstructor;
7 7  
8 8 import javax.validation.constraints.NotEmpty;
9 9 import javax.validation.constraints.NotNull;
  10 +import java.util.List;
10 11  
11 12 /**
12 13 * 商品 SKU Base VO,提供给添加、修改、详细的子 VO 使用
... ... @@ -15,72 +16,67 @@ import javax.validation.constraints.NotNull;
15 16 @Data
16 17 public class ProductSkuBaseVO {
17 18  
18   - @Schema(description = "商品 SKU 名字", required = true, example = "芋道")
  19 + @Schema(description = "商品 SKU 名字", required = true, example = "清凉小短袖")
19 20 @NotEmpty(message = "商品 SKU 名字不能为空")
20 21 private String name;
21 22  
22   - @Schema(description = "销售价格,单位:分", required = true, example = "1024")
  23 + @Schema(description = "销售价格,单位:分", required = true, example = "1999")
23 24 @NotNull(message = "销售价格,单位:分不能为空")
24 25 private Integer price;
25 26  
26   - @Schema(description = "市场价", example = "1024")
  27 + @Schema(description = "市场价", example = "2999")
27 28 private Integer marketPrice;
28 29  
29   - @Schema(description = "成本价", example = "1024")
  30 + @Schema(description = "成本价", example = "19")
30 31 private Integer costPrice;
31 32  
32   - @Schema(description = "条形码", example = "haha")
  33 + @Schema(description = "条形码", example = "15156165456")
33 34 private String barCode;
34 35  
35 36 @Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png")
36 37 @NotNull(message = "图片地址不能为空")
37 38 private String picUrl;
38 39  
39   - @Schema(description = "库存", required = true, example = "1")
  40 + @Schema(description = "库存", required = true, example = "200")
40 41 @NotNull(message = "库存不能为空")
41 42 private Integer stock;
42 43  
43   - @Schema(description = "预警预存", example = "1")
  44 + @Schema(description = "预警预存", example = "10")
44 45 private Integer warnStock;
45 46  
46   - @Schema(description = "商品重量,单位:kg 千克", example = "1")
  47 + @Schema(description = "商品重量,单位:kg 千克", example = "1.2")
47 48 private Double weight;
48 49  
49   - @Schema(description = "商品体积,单位:m^3 平米", example = "1024")
  50 + @Schema(description = "商品体积,单位:m^3 平米", example = "2.5")
50 51 private Double volume;
51 52  
52   - @Schema(description = "一级分销的佣金,单位:分", example = "1024")
  53 + @Schema(description = "一级分销的佣金,单位:分", example = "199")
53 54 private Integer subCommissionFirstPrice;
54 55  
55   - @Schema(description = "二级分销的佣金,单位:分", example = "1024")
  56 + @Schema(description = "二级分销的佣金,单位:分", example = "19")
56 57 private Integer subCommissionSecondPrice;
57 58  
58   - // TODO @puhui999:这里要写 swagger 注解哈
59   - /**
60   - * 商品属性
61   - */
  59 + @Schema(description = "属性数组")
  60 + private List<Property> properties;
  61 +
  62 + @Schema(description = "商品属性")
62 63 @Data
63 64 @NoArgsConstructor
64 65 @AllArgsConstructor
65 66 public static class Property {
66 67  
67   - /**
68   - * 属性编号
69   - */
  68 + @Schema(description = "属性编号", example = "10")
70 69 private Long propertyId;
71   - /**
72   - * 属性名字
73   - */
  70 +
  71 + @Schema(description = "属性名字", example = "颜色")
74 72 private String propertyName;
75 73  
76   - /**
77   - * 属性值编号
78   - */
  74 + @Schema(description = "属性值编号", example = "10")
79 75 private Long valueId;
80   - /**
81   - * 属性值名字
82   - */
  76 +
  77 + @Schema(description = "属性值名字", example = "红色")
83 78 private String valueName;
84 79  
85 80 }
  81 +
86 82 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java
... ... @@ -13,10 +13,4 @@ import java.util.List;
13 13 @ToString(callSuper = true)
14 14 public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO {
15 15  
16   - // TODO @puhui999:是不是可以抽到父类里?
17   - /**
18   - * 属性数组
19   - */
20   - private List<Property> properties;
21   -
22 16 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java
... ... @@ -15,9 +15,4 @@ public class ProductSkuRespVO extends ProductSkuBaseVO {
15 15 @Schema(description = "主键", required = true, example = "1024")
16 16 private Long id;
17 17  
18   - /**
19   - * 属性数组
20   - */
21   - private List<Property> properties;
22   -
23 18 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
... ... @@ -94,11 +94,10 @@ public class ProductSpuController {
94 94 return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO)));
95 95 }
96 96  
97   - // TODO @puhui999:方法名改成 getSpuCount,只是用于 tab 哈,这样更抽象一点。
98 97 @GetMapping("/get-count")
99 98 @Operation(summary = "获得商品 SPU 分页 tab count")
100 99 @PreAuthorize("@ss.hasPermission('product:spu:query')")
101   - public CommonResult<Map<Integer, Long>> getTabsCount() {
  100 + public CommonResult<Map<Integer, Long>> getSpuCount() {
102 101 return success(productSpuService.getTabsCount());
103 102 }
104 103  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java
... ... @@ -16,19 +16,19 @@ import java.util.List;
16 16 @Data
17 17 public class ProductSpuBaseVO {
18 18  
19   - @Schema(description = "商品名称", required = true, example = "芋道")
  19 + @Schema(description = "商品名称", required = true, example = "清凉小短袖")
20 20 @NotEmpty(message = "商品名称不能为空")
21 21 private String name;
22 22  
23   - @Schema(description = "关键字", required = true, example = "芋道")
  23 + @Schema(description = "关键字", required = true, example = "清凉丝滑不出汗")
24 24 @NotEmpty(message = "商品关键字不能为空")
25 25 private String keyword;
26 26  
27   - @Schema(description = "商品简介", required = true, example = "芋道")
  27 + @Schema(description = "商品简介", required = true, example = "清凉小短袖简介")
28 28 @NotEmpty(message = "商品简介不能为空")
29 29 private String introduction;
30 30  
31   - @Schema(description = "商品详情", required = true, example = "芋道")
  31 + @Schema(description = "商品详情", required = true, example = "清凉小短袖详情")
32 32 @NotEmpty(message = "商品详情不能为空")
33 33 private String description;
34 34  
... ... @@ -40,14 +40,14 @@ public class ProductSpuBaseVO {
40 40 @NotNull(message = "商品品牌不能为空")
41 41 private Long brandId;
42 42  
43   - @Schema(description = "商品封面图", required = true, example = "芋道")
  43 + @Schema(description = "商品封面图", required = true, example = "https://www.iocoder.cn/xx.png")
44 44 @NotEmpty(message = "商品封面图不能为空")
45 45 private String picUrl;
46 46  
47   - @Schema(description = "商品轮播图", required = true)
  47 + @Schema(description = "商品轮播图", required = true, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
48 48 private List<String> sliderPicUrls;
49 49  
50   - @Schema(description = "商品视频")
  50 + @Schema(description = "商品视频", example = "https://www.iocoder.cn/xx.mp4")
51 51 private String videoUrl;
52 52  
53 53 @Schema(description = "单位", required = true, example = "1")
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java
... ... @@ -20,18 +20,16 @@ import java.util.List;
20 20 @ToString(callSuper = true)
21 21 public class ProductSpuDetailRespVO extends ProductSpuBaseVO {
22 22  
23   - // TODO @puhui999:swagger 的 required 和 example 写下
24   -
25   - @Schema(description = "商品 SPU 编号")
  23 + @Schema(description = "商品 SPU 编号", required = true, example = "1212")
26 24 private Long id;
27 25  
28   - @Schema(description = "商品销量")
  26 + @Schema(description = "商品销量", required = true, example = "10000")
29 27 private Integer salesCount;
30 28  
31   - @Schema(description = "浏览量")
  29 + @Schema(description = "浏览量", required = true, example = "20000")
32 30 private Integer browseCount;
33 31  
34   - @Schema(description = "商品状态")
  32 + @Schema(description = "商品状态", required = true, example = "1")
35 33 private Integer status;
36 34  
37 35 // ========== SKU 相关字段 =========
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java
... ... @@ -16,6 +16,7 @@ import java.time.LocalDateTime;
16 16 */
17 17 @Data
18 18 public class ProductSpuExcelVO {
  19 +
19 20 @ExcelProperty("商品编号")
20 21 private Long id;
21 22  
... ... @@ -116,4 +117,5 @@ public class ProductSpuExcelVO {
116 117  
117 118 @ExcelProperty("创建时间")
118 119 private LocalDateTime createTime;
  120 +
119 121 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java
... ... @@ -18,14 +18,14 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
18 18 @AllArgsConstructor
19 19 public class ProductSpuExportReqVO {
20 20  
21   - @Schema(description = "商品名称", example = "yutou")
  21 + @Schema(description = "商品名称", example = "清凉小短袖")
22 22 private String name;
23 23  
24 24 @Schema(description = "前端请求的tab类型", example = "1")
25 25 @InEnum(ProductSpuPageTabEnum.class)
26 26 private Integer tabType;
27 27  
28   - @Schema(description = "商品分类编号")
  28 + @Schema(description = "商品分类编号", example = "100")
29 29 private Long categoryId;
30 30  
31 31 @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java
... ... @@ -25,17 +25,17 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
25 25 @ToString(callSuper = true)
26 26 public class ProductSpuPageReqVO extends PageParam {
27 27  
28   - @Schema(description = "商品名称", example = "yutou")
  28 + @Schema(description = "商品名称", example = "清凉小短袖")
29 29 private String name;
30 30  
31   - @Schema(description = "前端请求的tab类型", example = "1")
  31 + @Schema(description = "前端请求的tab类型", required = true, example = "1")
32 32 @InEnum(ProductSpuPageTabEnum.class)
33 33 private Integer tabType;
34 34  
35   - @Schema(description = "商品分类编号")
  35 + @Schema(description = "商品分类编号", example = "1")
36 36 private Long categoryId;
37 37  
38   - @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
  38 + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00, 2022-07-01 23:59:59]")
39 39 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
40 40 private LocalDateTime[] createTime;
41 41  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java
... ... @@ -18,30 +18,28 @@ import java.time.LocalDateTime;
18 18 @ToString(callSuper = true)
19 19 public class ProductSpuRespVO extends ProductSpuBaseVO {
20 20  
21   - // TODO @puhui999:swagger 的 required 和 example 写下
22   -
23   - @Schema(description = "spuId")
  21 + @Schema(description = "spuId", required = true, example = "111")
24 22 private Long id;
25 23  
26   - @Schema(description = "商品价格")
  24 + @Schema(description = "商品价格", required = true, example = "1999")
27 25 private Integer price;
28 26  
29   - @Schema(description = "商品销量")
  27 + @Schema(description = "商品销量", required = true, example = "2000")
30 28 private Integer salesCount;
31 29  
32   - @Schema(description = "市场价,单位使用:分")
  30 + @Schema(description = "市场价,单位使用:分", required = true, example = "199")
33 31 private Integer marketPrice;
34 32  
35   - @Schema(description = "成本价,单位使用:分")
  33 + @Schema(description = "成本价,单位使用:分", required = true, example = "19")
36 34 private Integer costPrice;
37 35  
38   - @Schema(description = "商品库存")
  36 + @Schema(description = "商品库存", required = true, example = "10000")
39 37 private Integer stock;
40 38  
41   - @Schema(description = "商品创建时间")
  39 + @Schema(description = "商品创建时间", required = true, example = "2023-05-24 00:00:00")
42 40 private LocalDateTime createTime;
43 41  
44   - @Schema(description = "商品状态")
  42 + @Schema(description = "商品状态", required = true, example = "1")
45 43 private Integer status;
46 44  
47 45 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java
... ... @@ -14,35 +14,33 @@ import lombok.ToString;
14 14 @ToString(callSuper = true)
15 15 public class ProductSpuSimpleRespVO {
16 16  
17   - // TODO @puhui999:swagger 的 required 和 example 写下
18   -
19   - @Schema(description = "主键")
  17 + @Schema(description = "主键", required = true, example = "213")
20 18 private Long id;
21 19  
22   - @Schema(description = "商品名称")
  20 + @Schema(description = "商品名称", required = true, example = "清凉小短袖")
23 21 private String name;
24 22  
25   - @Schema(description = "商品价格,单位使用:分")
  23 + @Schema(description = "商品价格,单位使用:分", required = true, example = "1999")
26 24 private Integer price;
27 25  
28   - @Schema(description = "商品市场价,单位使用:分")
  26 + @Schema(description = "商品市场价,单位使用:分", required = true, example = "199")
29 27 private Integer marketPrice;
30 28  
31   - @Schema(description = "商品成本价,单位使用:分")
  29 + @Schema(description = "商品成本价,单位使用:分", required = true, example = "19")
32 30 private Integer costPrice;
33 31  
34   - @Schema(description = "商品库存")
  32 + @Schema(description = "商品库存", required = true, example = "2000")
35 33 private Integer stock;
36 34  
37 35 // ========== 统计相关字段 =========
38 36  
39   - @Schema(description = "商品销量")
  37 + @Schema(description = "商品销量", required = true, example = "200")
40 38 private Integer salesCount;
41 39  
42   - @Schema(description = "商品虚拟销量")
  40 + @Schema(description = "商品虚拟销量", required = true, example = "20000")
43 41 private Integer virtualSalesCount;
44 42  
45   - @Schema(description = "商品浏览量")
  43 + @Schema(description = "商品浏览量", required = true, example = "2000")
46 44 private Integer browseCount;
47 45  
48 46 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java
... ... @@ -23,19 +23,17 @@ import java.util.List;
23 23 @ToString(callSuper = true)
24 24 public class ProductSpuUpdateReqVO extends ProductSpuBaseVO {
25 25  
26   - // TODO @puhui999:swagger 的 required 和 example 写下
27   -
28 26 @Schema(description = "商品编号", required = true, example = "1")
29 27 @NotNull(message = "商品编号不能为空")
30 28 private Long id;
31 29  
32   - @Schema(description = "商品销量")
  30 + @Schema(description = "商品销量", required = true, example = "1999")
33 31 private Integer salesCount;
34 32  
35   - @Schema(description = "浏览量")
  33 + @Schema(description = "浏览量", required = true, example = "1999")
36 34 private Integer browseCount;
37 35  
38   - @Schema(description = "商品状态")
  36 + @Schema(description = "商品状态", required = true, example = "1")
39 37 @InEnum(ProductSpuStatusEnum.class)
40 38 private Integer status;
41 39  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java
... ... @@ -67,8 +67,7 @@ public class AppProductSpuController {
67 67 }
68 68  
69 69 // 查询商品 SKU
70   - List<ProductSkuDO> skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(),
71   - CommonStatusEnum.ENABLE.getStatus());
  70 + List<ProductSkuDO> skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId());
72 71 // 查询商品属性
73 72 List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
74 73 .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java
... ... @@ -43,8 +43,6 @@ public interface ProductSkuConvert {
43 43  
44 44 ProductSkuRespDTO convert02(ProductSkuDO bean);
45 45  
46   - List<ProductSkuRespVO> convertList03(List<ProductSkuDO> list);
47   -
48 46 List<ProductSkuRespDTO> convertList04(List<ProductSkuDO> list);
49 47  
50 48 List<ProductSkuOptionRespVO> convertList05(List<ProductSkuDO> skus);
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
... ... @@ -16,6 +16,8 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
16 16 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
17 17 import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
18 18 import org.mapstruct.Mapper;
  19 +import org.mapstruct.Mapping;
  20 +import org.mapstruct.Named;
19 21 import org.mapstruct.factory.Mappers;
20 22  
21 23 import java.util.ArrayList;
... ... @@ -52,54 +54,37 @@ public interface ProductSpuConvert {
52 54  
53 55 List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list);
54 56  
55   - // TODO @puhui999:部分属性,可以通过 mapstruct 的 @Mapping(source = , target = , ) 映射转换,可以查下文档
56   - default List<ProductSpuExcelVO> convertList03(List<ProductSpuDO> list){
57   - ArrayList<ProductSpuExcelVO> spuExcelVOs = new ArrayList<>();
58   - list.forEach((spu)->{
59   - ProductSpuExcelVO spuExcelVO = new ProductSpuExcelVO();
60   - spuExcelVO.setId(spu.getId());
61   - spuExcelVO.setName(spu.getName());
62   - spuExcelVO.setKeyword(spu.getKeyword());
63   - spuExcelVO.setIntroduction(spu.getIntroduction());
64   - spuExcelVO.setDescription(spu.getDescription());
65   - spuExcelVO.setBarCode(spu.getBarCode());
66   - spuExcelVO.setCategoryId(spu.getCategoryId());
67   - spuExcelVO.setBrandId(spu.getBrandId());
68   - spuExcelVO.setPicUrl(spu.getPicUrl());
69   - spuExcelVO.setSliderPicUrls(StrUtil.toString(spu.getSliderPicUrls()));
70   - spuExcelVO.setVideoUrl(spu.getVideoUrl());
71   - spuExcelVO.setUnit(spu.getUnit());
72   - spuExcelVO.setSort(spu.getSort());
73   - spuExcelVO.setStatus(spu.getStatus());
74   - spuExcelVO.setSpecType(spu.getSpecType());
75   - spuExcelVO.setPrice(spu.getPrice()/100);
76   - spuExcelVO.setMarketPrice(spu.getMarketPrice()/100);
77   - spuExcelVO.setCostPrice(spu.getCostPrice()/100);
78   - spuExcelVO.setStock(spu.getStock());
79   - spuExcelVO.setDeliveryTemplateId(spu.getDeliveryTemplateId());
80   - spuExcelVO.setRecommendHot(spu.getRecommendHot());
81   - spuExcelVO.setRecommendBenefit(spu.getRecommendBenefit());
82   - spuExcelVO.setRecommendBest(spu.getRecommendBest());
83   - spuExcelVO.setRecommendNew(spu.getRecommendNew());
84   - spuExcelVO.setRecommendGood(spu.getRecommendGood());
85   - spuExcelVO.setGiveIntegral(spu.getGiveIntegral());
86   - spuExcelVO.setGiveCouponTemplateIds(StrUtil.toString(spu.getGiveCouponTemplateIds())); // TODO 暂定
87   - spuExcelVO.setSubCommissionType(spu.getSubCommissionType());
88   - spuExcelVO.setActivityOrders(StrUtil.toString(spu.getActivityOrders())); // TODO 暂定
89   - spuExcelVO.setSalesCount(spu.getSalesCount());
90   - spuExcelVO.setVirtualSalesCount(spu.getVirtualSalesCount());
91   - spuExcelVO.setBrowseCount(spu.getBrowseCount());
92   - spuExcelVO.setCreateTime(spu.getCreateTime());
  57 + /**
  58 + * 列表转字符串
  59 + *
  60 + * @param list 列表
  61 + * @return 字符串
  62 + */
  63 + @Named("convertListToString")
  64 + default String convertListToString(List<?> list) {
  65 + return StrUtil.toString(list);
  66 + }
  67 +
  68 + // TODO @puhui999:部分属性,可以通过 mapstruct 的 @Mapping(source = , target = , ) 映射转换,可以查下文档 fix:哈哈 这样确实丝滑哈
  69 +
  70 + @Mapping(source = "sliderPicUrls", target = "sliderPicUrls", qualifiedByName = "convertListToString")
  71 + @Mapping(source = "giveCouponTemplateIds", target = "giveCouponTemplateIds", qualifiedByName = "convertListToString")
  72 + @Mapping(source = "activityOrders", target = "activityOrders", qualifiedByName = "convertListToString")
  73 + @Mapping(target = "price", expression = "java(spu.getPrice() / 100)")
  74 + @Mapping(target = "marketPrice", expression = "java(spu.getMarketPrice() / 100)")
  75 + @Mapping(target = "costPrice", expression = "java(spu.getCostPrice() / 100)")
  76 + ProductSpuExcelVO convert(ProductSpuDO spu);
  77 +
  78 + default List<ProductSpuExcelVO> convertList03(List<ProductSpuDO> list) {
  79 + List<ProductSpuExcelVO> spuExcelVOs = new ArrayList<>();
  80 + list.forEach(spu -> {
  81 + ProductSpuExcelVO spuExcelVO = convert(spu);
93 82 spuExcelVOs.add(spuExcelVO);
94 83 });
95 84 return spuExcelVOs;
96 85 }
97   - ProductSpuDetailRespVO convert03(ProductSpuDO spu);
98   -
99   - // TODO @puhui999:下面两个没用到,是不是删除呀?
100   - List<ProductSkuRespVO> convertList04(List<ProductSkuDO> skus);
101 86  
102   - ProductPropertyValueDetailRespVO convert04(ProductPropertyValueDetailRespBO propertyValue);
  87 + ProductSpuDetailRespVO convert03(ProductSpuDO spu);
103 88  
104 89 // ========== 用户 App 相关 ==========
105 90  
... ... @@ -144,26 +129,15 @@ public interface ProductSpuConvert {
144 129  
145 130 AppProductPropertyValueDetailRespVO convertForGetSpuDetail(ProductPropertyValueDetailRespBO propertyValue);
146 131  
147   - default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List<ProductSkuDO> skus,
148   - Function<Set<Long>, List<ProductPropertyValueDetailRespBO>> func) {
  132 + default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List<ProductSkuDO> skus) {
149 133 ProductSpuDetailRespVO productSpuDetailRespVO = convert03(spu);
150   - // TODO @puhui999:if return 哈,减少嵌套层数。
151   - if (CollUtil.isNotEmpty(skus)) {
152   - List<ProductSkuRespVO> skuVOs = ProductSkuConvert.INSTANCE.convertList(skus);
153   - // fix:统一模型,即使是单规格,也查询下,如若 Properties 为空报错则为单属性不做处理
154   - try {
155   - // 获取所有的属性值 id
156   - Set<Long> valueIds = skus.stream().flatMap(p -> p.getProperties().stream())
157   - .map(ProductSkuDO.Property::getValueId)
158   - .collect(Collectors.toSet());
159   - List<ProductPropertyValueDetailRespBO> valueDetailList = func.apply(valueIds);
160   - Map<Long, String> stringMap = valueDetailList.stream().collect(Collectors.toMap(ProductPropertyValueDetailRespBO::getValueId, ProductPropertyValueDetailRespBO::getValueName));
161   - // 设置属性值名称
162   - skuVOs.stream().flatMap(p -> p.getProperties().stream()).forEach(item -> item.setValueName(stringMap.get(item.getValueId())));
163   - } catch (Exception ignored) {
164   - }
165   - productSpuDetailRespVO.setSkus(skuVOs);
  134 + // skus 为空直接返回
  135 + if (CollUtil.isEmpty(skus)) {
  136 + return productSpuDetailRespVO;
166 137 }
  138 + List<ProductSkuRespVO> skuVOs = ProductSkuConvert.INSTANCE.convertList(skus);
  139 + // fix: 因为现在已改为 sku 属性列表 属性 已包含 属性名字 属性值名字 所以不需要再额外处理,属性更新时更新 sku 中的属性相关冗余即可
  140 + productSpuDetailRespVO.setSkus(skuVOs);
167 141 return productSpuDetailRespVO;
168 142 }
169 143  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java
... ... @@ -19,7 +19,7 @@ import java.util.List;
19 19 *
20 20 * @author 芋道源码
21 21 */
22   -@TableName(value = "product_sku",autoResultMap = true)
  22 +@TableName(value = "product_sku", autoResultMap = true)
23 23 @KeySequence("product_sku_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
24 24 @Data
25 25 @EqualsAndHashCode(callSuper = true)
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java
... ... @@ -31,8 +31,7 @@ public interface ProductBrandMapper extends BaseMapperX&lt;ProductBrandDO&gt; {
31 31 return selectOne(ProductBrandDO::getName, name);
32 32 }
33 33  
34   - // TODO @puhui999:) { 中间要有空格哈。
35   - default List<ProductBrandDO> selectListByStatus(Integer status){
36   - return selectList(ProductBrandDO::getStatus,status);
  34 + default List<ProductBrandDO> selectListByStatus(Integer status) {
  35 + return selectList(ProductBrandDO::getStatus, status);
37 36 }
38 37 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java
... ... @@ -23,11 +23,9 @@ public interface ProductSkuMapper extends BaseMapperX&lt;ProductSkuDO&gt; {
23 23 return selectList(ProductSkuDO::getSpuId, spuId);
24 24 }
25 25  
26   - default List<ProductSkuDO> selectListBySpuIdAndStatus(Long spuId,
27   - Integer status) {
  26 + default List<ProductSkuDO> selectListBySpuIdAndStatus(Long spuId) {
28 27 return selectList(new LambdaQueryWrapperX<ProductSkuDO>()
29   - .eq(ProductSkuDO::getSpuId, spuId)// eqIfPresent(ProductSkuDO::getStatus, status) TODO ProductSkuDO已经没有status属性
30   - );
  28 + .eq(ProductSkuDO::getSpuId, spuId));
31 29 }
32 30  
33 31 default List<ProductSkuDO> selectListBySpuId(Collection<Long> spuIds) {
... ... @@ -41,7 +39,7 @@ public interface ProductSkuMapper extends BaseMapperX&lt;ProductSkuDO&gt; {
41 39 /**
42 40 * 更新 SKU 库存(增加)
43 41 *
44   - * @param id 编号
  42 + * @param id 编号
45 43 * @param incrCount 增加库存(正数)
46 44 */
47 45 default void updateStockIncr(Long id, Integer incrCount) {
... ... @@ -55,7 +53,7 @@ public interface ProductSkuMapper extends BaseMapperX&lt;ProductSkuDO&gt; {
55 53 /**
56 54 * 更新 SKU 库存(减少)
57 55 *
58   - * @param id 编号
  56 + * @param id 编号
59 57 * @param incrCount 减少库存(负数)
60 58 * @return 更新条数
61 59 */
... ... @@ -68,8 +66,8 @@ public interface ProductSkuMapper extends BaseMapperX&lt;ProductSkuDO&gt; {
68 66 return update(null, updateWrapper);
69 67 }
70 68  
71   - default List<ProductSkuDO> selectListByAlarmStock(){
72   - return selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock"));
  69 + default List<ProductSkuDO> selectListByAlarmStock() {
  70 + return selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock"));
73 71 }
74 72  
75 73 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java
... ... @@ -35,21 +35,21 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; {
35 35 .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId())
36 36 .betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime())
37 37 .orderByDesc(ProductSpuDO::getSort);
38   - validateTabType(tabType, queryWrapper);
  38 + appendTabQuery(tabType, queryWrapper);
39 39 return selectPage(reqVO, queryWrapper);
40 40 }
41 41  
42 42 /**
43   - * 获取库存小于 value ,且状态不等于 status 的的个数
  43 + * 查询触发警戒库存的 SPU 数量
44 44 *
45   - * @return 个数
  45 + * @return 触发警戒库存的 SPU 数量
46 46 */
47   - default Long selectCountByStockAndStatus() {
  47 + default Long selectCount() {
48 48 LambdaQueryWrapperX<ProductSpuDO> queryWrapper = new LambdaQueryWrapperX<>();
  49 + // 库存小于等于警戒库存
49 50 queryWrapper.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK)
50   - // TODO @puhui999:IN 另外两个状态,会不会好点哈。尽量不用 !=
51 51 // 如果库存触发警戒库存且状态为回收站的话则不计入触发警戒库存的个数
52   - .and(q -> q.ne(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()));
  52 + .notIn(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus());
53 53 return selectCount(queryWrapper);
54 54 }
55 55  
... ... @@ -101,43 +101,43 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; {
101 101 * @param reqVO 查询条件
102 102 * @return Spu 列表
103 103 */
104   - default List<ProductSpuDO> selectList(ProductSpuExportReqVO reqVO){
  104 + default List<ProductSpuDO> selectList(ProductSpuExportReqVO reqVO) {
105 105 Integer tabType = reqVO.getTabType();
106 106 LambdaQueryWrapperX<ProductSpuDO> queryWrapper = new LambdaQueryWrapperX<>();
107   - queryWrapper.eqIfPresent(ProductSpuDO::getName,reqVO.getName());
108   - queryWrapper.eqIfPresent(ProductSpuDO::getCategoryId,reqVO.getCategoryId());
109   - queryWrapper.betweenIfPresent(ProductSpuDO::getCreateTime,reqVO.getCreateTime());
110   - validateTabType(tabType, queryWrapper);
  107 + queryWrapper.eqIfPresent(ProductSpuDO::getName, reqVO.getName());
  108 + queryWrapper.eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId());
  109 + queryWrapper.betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime());
  110 + appendTabQuery(tabType, queryWrapper);
111 111 return selectList(queryWrapper);
112 112 }
113 113  
114   - // TODO @puhui999:应该不太适合 validate 验证,应该是补充条件,例如说 appendTabQuery
115 114 /**
116 115 * 验证选项卡类型构建条件
117 116 *
118 117 * @param tabType 标签类型
119 118 * @param queryWrapper 查询条件
120 119 */
121   - static void validateTabType(Integer tabType, LambdaQueryWrapperX<ProductSpuDO> queryWrapper) {
122   - // 出售中商品 TODO puhui999:这样好点
  120 + static void appendTabQuery(Integer tabType, LambdaQueryWrapperX<ProductSpuDO> queryWrapper) {
  121 + // 出售中商品
123 122 if (ObjectUtil.equals(ProductSpuPageTabEnum.FOR_SALE.getType(), tabType)) {
124 123 queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus());
125 124 }
  125 + // 仓储中商品
126 126 if (ObjectUtil.equals(ProductSpuPageTabEnum.IN_WAREHOUSE.getType(), tabType)) {
127   - // 仓储中商品
128 127 queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus());
129 128 }
  129 + // 已售空商品
130 130 if (ObjectUtil.equals(ProductSpuPageTabEnum.SOLD_OUT.getType(), tabType)) {
131   - // 已售空商品
132 131 queryWrapper.eqIfPresent(ProductSpuDO::getStock, 0);
133 132 }
  133 + // 警戒库存
134 134 if (ObjectUtil.equals(ProductSpuPageTabEnum.ALERT_STOCK.getType(), tabType)) {
135 135 queryWrapper.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK)
136 136 // 如果库存触发警戒库存且状态为回收站的话则不在警戒库存列表展示
137   - .and(q -> q.ne(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()));
  137 + .notIn(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus());
138 138 }
  139 + // 回收站
139 140 if (ObjectUtil.equals(ProductSpuPageTabEnum.RECYCLE_BIN.getType(), tabType)) {
140   - // 回收站
141 141 queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus());
142 142 }
143 143 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java
... ... @@ -88,14 +88,10 @@ public interface ProductSkuService {
88 88 /**
89 89 * 基于 SPU 编号和状态,获得商品 SKU 集合
90 90 *
91   - * TODO @puhui999:SKU中已经不存在status属性;芋艿:那就去掉 status 哈
92   - *
93 91 * @param spuId SPU 编号
94   - * @param status 状态
95 92 * @return 商品 SKU 集合
96 93 */
97   - List<ProductSkuDO> getSkuListBySpuIdAndStatus(Long spuId,
98   - @Nullable Integer status);
  94 + List<ProductSkuDO> getSkuListBySpuIdAndStatus(Long spuId);
99 95  
100 96 /**
101 97 * 获得 spu 对应的 SKU 集合
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
... ... @@ -3,14 +3,12 @@ package cn.iocoder.yudao.module.product.service.sku;
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.ObjectUtil;
5 5 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
6   -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
7 6 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
8 7 import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
9 8 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
10 9 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
11 10 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
12 11 import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper;
13   -import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants;
14 12 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
15 13 import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
16 14 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
... ... @@ -85,7 +83,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
85 83 }
86 84  
87 85 // 0、校验skus是否为空
88   - if (CollUtil.isEmpty(skus)){
  86 + if (CollUtil.isEmpty(skus)) {
89 87 throw exception(SKU_NOT_EXISTS);
90 88 }
91 89  
... ... @@ -140,8 +138,8 @@ public class ProductSkuServiceImpl implements ProductSkuService {
140 138 }
141 139  
142 140 @Override
143   - public List<ProductSkuDO> getSkuListBySpuIdAndStatus(Long spuId, Integer status) {
144   - return productSkuMapper.selectListBySpuIdAndStatus(spuId, status);
  141 + public List<ProductSkuDO> getSkuListBySpuIdAndStatus(Long spuId) {
  142 + return productSkuMapper.selectListBySpuIdAndStatus(spuId);
145 143 }
146 144  
147 145 @Override
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
... ... @@ -18,7 +18,6 @@ import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum;
18 18 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
19 19 import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
20 20 import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
21   -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
22 21 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
23 22 import org.springframework.context.annotation.Lazy;
24 23 import org.springframework.stereotype.Service;
... ... @@ -51,8 +50,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
51 50 private ProductBrandService brandService;
52 51 @Resource
53 52 private ProductCategoryService categoryService;
54   - @Resource
55   - private ProductPropertyValueService productPropertyValueService;
56 53  
57 54 @Override
58 55 @Transactional(rollbackFor = Exception.class)
... ... @@ -63,10 +60,10 @@ public class ProductSpuServiceImpl implements ProductSpuService {
63 60 // 校验 SKU
64 61 List<ProductSkuCreateOrUpdateReqVO> skuSaveReqList = createReqVO.getSkus();
65 62 productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType());
  63 +
66 64 ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO);
67 65 // 初始化 SPU 中 SKU 相关属性
68 66 initSpuFromSkus(spu, skuSaveReqList);
69   -
70 67 // 插入 SPU
71 68 productSpuMapper.insert(spu);
72 69 // 插入 SKU
... ... @@ -86,7 +83,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
86 83 // 校验SKU
87 84 List<ProductSkuCreateOrUpdateReqVO> skuSaveReqList = updateReqVO.getSkus();
88 85 productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType());
89   - // TODO @puhui999:可以校验逻辑,和更新逻辑,中间有个空行,这样会发现,哟 这里到了关键逻辑啦,更有层次感
  86 +
90 87 // 更新 SPU
91 88 ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO);
92 89 initSpuFromSkus(updateObj, skuSaveReqList);
... ... @@ -103,20 +100,14 @@ public class ProductSpuServiceImpl implements ProductSpuService {
103 100 * @param skus 商品 SKU 数组
104 101 */
105 102 private void initSpuFromSkus(ProductSpuDO spu, List<ProductSkuCreateOrUpdateReqVO> skus) {
106   - // 断言,避免告警
107   - assert skus.size() > 0;
108   - // 获取 sku 单价最低的商品
109   - // TODO @puhui999:vo 改成 sku 会更好。vo dto 只是我们用来区分的,如果能区分的情况下,用更明确的名字会更好。
110   -// CollectionUtils.getMinValue(); TODO @puhui999:可以用这个方法,常见的 stream 操作,封装成方法,让逻辑更简洁
111   - ProductSkuCreateOrUpdateReqVO vo = skus.stream().min(Comparator.comparing(ProductSkuCreateOrUpdateReqVO::getPrice)).get();
112 103 // sku 单价最低的商品的价格
113   - spu.setPrice(vo.getPrice());
  104 + spu.setPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice));
114 105 // sku 单价最低的商品的市场价格
115   - spu.setMarketPrice(vo.getMarketPrice());
  106 + spu.setMarketPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice));
116 107 // sku单价最低的商品的成本价格
117   - spu.setCostPrice(vo.getCostPrice());
  108 + spu.setCostPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getCostPrice));
118 109 // sku单价最低的商品的条形码
119   - spu.setBarCode(vo.getBarCode());
  110 + spu.setBarCode(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getBarCode));
120 111 // skus 库存总数
121 112 spu.setStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
122 113 // 若是 spu 已有状态则不处理
... ... @@ -150,6 +141,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
150 141 validateSpuExists(id);
151 142 // 校验商品状态不是回收站不能删除
152 143 validateSpuStatus(id);
  144 +
153 145 // 删除 SPU
154 146 productSpuMapper.deleteById(id);
155 147 // 删除关联的 SKU
... ... @@ -229,8 +221,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
229 221 }
230 222 // 查询商品 SKU
231 223 List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
232   - // TODO @puhui999:感觉还是查询好 productPropertyValueService,然后 propertyId 可以交给 convert 处理下即可。
233   - return ProductSpuConvert.INSTANCE.convertForSpuDetailRespVO(spu, skus, productPropertyValueService::getPropertyValueDetailList);
  224 + return ProductSpuConvert.INSTANCE.convertForSpuDetailRespVO(spu, skus);
234 225 }
235 226  
236 227 @Override
... ... @@ -238,10 +229,10 @@ public class ProductSpuServiceImpl implements ProductSpuService {
238 229 public void updateStatus(ProductSpuUpdateStatusReqVO updateReqVO) {
239 230 // 校验存在
240 231 validateSpuExists(updateReqVO.getId());
  232 +
241 233 // 更新状态
242 234 ProductSpuDO productSpuDO = productSpuMapper.selectById(updateReqVO.getId()).setStatus(updateReqVO.getStatus());
243 235 productSpuMapper.updateById(productSpuDO);
244   -
245 236 }
246 237  
247 238 @Override
... ... @@ -254,7 +245,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
254 245 // 查询售空的商品数量
255 246 counts.put(ProductSpuPageTabEnum.SOLD_OUT.getType(), productSpuMapper.selectCount(ProductSpuDO::getStock, 0));
256 247 // 查询触发警戒库存的商品数量
257   - counts.put(ProductSpuPageTabEnum.ALERT_STOCK.getType(), productSpuMapper.selectCountByStockAndStatus());
  248 + counts.put(ProductSpuPageTabEnum.ALERT_STOCK.getType(), productSpuMapper.selectCount());
258 249 // 查询回收站中的商品数量
259 250 counts.put(ProductSpuPageTabEnum.RECYCLE_BIN.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()));
260 251 return counts;
... ...