Browse Source

mall:code review 商品的添加和修改 VO;微调商品的 SPU/SKU 表

YunaiV 2 years ago
parent
commit
f03d679f2c
19 changed files with 184 additions and 137 deletions
  1. 2 2
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java
  2. 46 24
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java
  3. 14 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java
  4. 0 14
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateReqVO.java
  5. 5 6
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
  6. 44 20
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java
  7. 6 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java
  8. 30 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java
  9. 0 25
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/SpuUpdateReqVO.java
  10. 3 3
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java
  11. 1 1
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
  12. 4 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java
  13. 5 9
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java
  14. 4 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java
  15. 3 3
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
  16. 3 3
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java
  17. 9 12
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
  18. 2 2
      yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/SkuServiceImplTest.java
  19. 3 3
      yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java

+ 2 - 2
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java

@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.sku;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuPageReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuUpdateReqVO;
@@ -35,7 +35,7 @@ public class ProductSkuController {
     @PostMapping("/create")
     @ApiOperation("创建商品sku")
     @PreAuthorize("@ss.hasPermission('product:sku:create')")
-    public CommonResult<Long> createSku(@Valid @RequestBody ProductSkuCreateReqVO createReqVO) {
+    public CommonResult<Long> createSku(@Valid @RequestBody ProductSkuCreateOrUpdateReqVO createReqVO) {
         return success(ProductSkuService.createSku(createReqVO));
     }
 

+ 46 - 24
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java

@@ -1,58 +1,80 @@
 package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
 
-import lombok.*;
-import java.util.*;
-import io.swagger.annotations.*;
-import javax.validation.constraints.*;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.validation.InEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
 
 /**
-* 商品sku Base VO,提供给添加、修改、详细的子 VO 使用
+* 商品 SKU Base VO,提供给添加、修改、详细的子 VO 使用
 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
 */
 @Data
 public class ProductSkuBaseVO {
 
-    // TODO @franky:example 要写哈;
-
-    @ApiModelProperty(value = "spu编号")
-    private Long spuId;
-
-    // TODO @franky:类似这种字段,有额外说明的。可以写成;    @ApiModelProperty(value = "规格值数组", required = true, notes = "json格式, [{propertyId: , valueId: }, {propertyId: , valueId: }]")
+    @ApiModelProperty(value = "商品 SKU 名字", required = true, example = "芋道")
+    @NotEmpty(message = "商品 SKU 名字不能为空")
+    private String name;
 
-    @ApiModelProperty(value = "规格值数组-json格式, [{propertyId: , valueId: }, {propertyId: , valueId: }]", required = true)
-    @NotNull(message = "规格值数组-json格式, [{propertyId: , valueId: }, {propertyId: , valueId: }]不能为空")
+    /**
+     * 规格值数组
+     */
+    @NotNull(message = "规格值数组不能为空")
     private List<Property> properties;
 
-    @ApiModelProperty(value = "销售价格,单位:分", required = true)
+    @ApiModelProperty(value = "销售价格,单位:分", required = true, example = "1024", notes = "单位:分")
     @NotNull(message = "销售价格,单位:分不能为空")
     private Integer price;
 
-    @ApiModelProperty(value = "原价, 单位: 分", required = true)
-    @NotNull(message = "原价, 单位: 分不能为空")
+    @ApiModelProperty(value = "市场价", example = "1024", notes = "单位:分")
     private Integer originalPrice;
 
-    @ApiModelProperty(value = "成本价,单位: 分", required = true)
-    @NotNull(message = "成本价,单位: 分不能为空")
+    @ApiModelProperty(value = "成本价", example = "1024", notes = "单位:分")
     private Integer costPrice;
 
-    @ApiModelProperty(value = "条形码", required = true)
+    @ApiModelProperty(value = "条形码", example = "haha")
     @NotNull(message = "条形码不能为空")
     private String barCode;
 
-    @ApiModelProperty(value = "图片地址", required = true)
+    @ApiModelProperty(value = "图片地址")
     @NotNull(message = "图片地址不能为空")
     private String picUrl;
 
-    @ApiModelProperty(value = "状态: 0-正常 1-禁用")
+    @ApiModelProperty(value = "SKU 状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
+    @NotNull(message = "SKU 状态不能为空")
+    @InEnum(CommonStatusEnum.class)
     private Integer status;
 
-    // TODO @franky 要有 swagger 注解
+    @ApiModelProperty(value = "库存", required = true, example = "1")
+    @NotNull(message = "库存不能为空")
+    private Integer stock;
+
+    @ApiModelProperty(value = "预警预存", example = "1")
+    private Integer warnStock;
+
+    @ApiModelProperty(value = "商品重量", example = "1", notes = "单位:kg 千克")
+    private Double weight;
+
+    @ApiModelProperty(value = "商品体积", example = "1024", notes = "单位:m^3 平米")
+    private Double volume;
+
+    @ApiModel("规格值")
     @Data
     public static class Property {
-        @NotNull(message = "规格属性名id不能为空")
+
+        @ApiModelProperty(value = "属性编号", required = true, example = "1")
+        @NotNull(message = "属性编号不能为空")
         private Long propertyId;
-        @NotNull(message = "规格属性值id不能为空")
+
+        @ApiModelProperty(value = "属性值编号", required = true, example = "1024")
+        @NotNull(message = "属性值编号不能为空")
         private Long valueId;
+
     }
 
 }

+ 14 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java

@@ -0,0 +1,14 @@
+package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@ApiModel("管理后台 - 商品 SKU 创建/更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO {
+
+}

+ 0 - 14
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateReqVO.java

@@ -1,14 +0,0 @@
-package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
-
-import lombok.*;
-import java.util.*;
-import io.swagger.annotations.*;
-import javax.validation.constraints.*;
-
-@ApiModel("管理后台 - 商品sku创建 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class ProductSkuCreateReqVO extends ProductSkuBaseVO {
-
-}

+ 5 - 6
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java

@@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.product.controller.admin.spu;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuPageReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuRespVO;
-import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuUpdateReqVO;
 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
@@ -23,7 +23,7 @@ import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
-@Api(tags = "管理后台 - 商品spu")
+@Api(tags = "管理后台 - 商品 SPU")
 @RestController
 @RequestMapping("/product/spu")
 @Validated
@@ -33,17 +33,16 @@ public class ProductSpuController {
     private ProductSpuService spuService;
 
     @PostMapping("/create")
-    @ApiOperation("创建商品spu")
+    @ApiOperation("创建商品 SPU")
     @PreAuthorize("@ss.hasPermission('product:spu:create')")
     public CommonResult<Long> createSpu(@Valid @RequestBody ProductSpuCreateReqVO createReqVO) {
         return success(spuService.createSpu(createReqVO));
     }
 
-    // TODO @franky:SpuUpdateReqVO 缺少前缀
     @PutMapping("/update")
-    @ApiOperation("更新商品spu")
+    @ApiOperation("更新商品 SPU")
     @PreAuthorize("@ss.hasPermission('product:spu:update')")
-    public CommonResult<Boolean> updateSpu(@Valid @RequestBody SpuUpdateReqVO updateReqVO) {
+    public CommonResult<Boolean> updateSpu(@Valid @RequestBody ProductSpuUpdateReqVO updateReqVO) {
         spuService.updateSpu(updateReqVO);
         return success(true);
     }

+ 44 - 20
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java

@@ -1,51 +1,75 @@
 package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
 
+import cn.iocoder.yudao.framework.common.validation.InEnum;
+import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
+import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
 import java.util.List;
 
 /**
-* 商品spu Base VO,提供给添加、修改、详细的子 VO 使用
+* 商品 SPU Base VO,提供给添加、修改、详细的子 VO 使用
 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
 */
 @Data
 public class ProductSpuBaseVO {
 
-    @ApiModelProperty(value = "商品名称")
+    @ApiModelProperty(value = "商品名称", required = true, example = "芋道")
+    @NotEmpty(message = "商品名称不能为空")
     private String name;
 
-    @ApiModelProperty(value = "卖点", required = true)
-    @NotNull(message = "卖点不能为空")
+    @ApiModelProperty(value = "商品编码", example = "yudaoyuanma")
+    private String code;
+
+    @ApiModelProperty(value = "商品卖点", example = "好吃!")
     private String sellPoint;
 
-    @ApiModelProperty(value = "描述", required = true)
-    @NotNull(message = "描述不能为空")
+    @ApiModelProperty(value = "商品详情", required = true, example = "我是商品描述")
+    @NotNull(message = "商品详情不能为空")
     private String description;
 
-    @ApiModelProperty(value = "分类id", required = true)
-    @NotNull(message = "分类id不能为空")
+    @ApiModelProperty(value = "商品分类编号", required = true, example = "1")
+    @NotNull(message = "商品分类编号不能为空")
     private Long categoryId;
 
-    @ApiModelProperty(value = "商品主图地址,* 数组,以逗号分隔,最多上传15张", required = true)
-    @NotNull(message = "商品主图地址,* 数组,以逗号分隔,最多上传15张不能为空")
+    @ApiModelProperty(value = "商品品牌编号", required = true, example = "1")
+    @NotNull(message = "商品品牌编号不能为空")
+    private Long brandId;
+
+    @ApiModelProperty(value = "商品图片的数组", required = true)
+    @NotNull(message = "商品图片的数组不能为空")
     private List<String> picUrls;
 
-    @ApiModelProperty(value = "排序字段", required = true)
-    @NotNull(message = "排序字段不能为空")
+    @ApiModelProperty(value = "商品视频", required = true)
+    @NotEmpty(message = "商品视频不能为空")
+    private String videoUrl;
+
+    @ApiModelProperty(value = "排序字段", required = true, example = "1")
     private Integer sort;
 
-    @ApiModelProperty(value = "点赞初始人数")
-    private Integer likeCount;
+    @ApiModelProperty(value = "商品状态", required = true, example = "1", notes = "参见 ProductSpuStatusEnum 枚举类")
+    @NotNull(message = "商品状态不能为空")
+    @InEnum(ProductSpuStatusEnum.class)
+    private Integer status;
 
-    @ApiModelProperty(value = "价格 单位使用:分")
-    private Integer price;
+    // ========== SKU 相关字段 =========
 
-    @ApiModelProperty(value = "库存数量")
-    private Integer quantity;
+    @ApiModelProperty(value = "规格类型", required = true, example = "1", notes = "参见 ProductSpuSpecTypeEnum 枚举类")
+    @NotNull(message = "规格类型不能为空")
+    @InEnum(ProductSpuSpecTypeEnum.class)
+    private Integer specType;
 
-    @ApiModelProperty(value = "上下架状态: 0 上架(开启) 1 下架(禁用)")
-    private Integer status;
+    @ApiModelProperty(value = "是否展示库存", required = true, example = "true")
+    @NotNull(message = "是否展示库存不能为空")
+    private Boolean showStock;
+
+    // ========== 统计相关字段 =========
+
+    @ApiModelProperty(value = "虚拟销量", required = true, example = "1024")
+    @NotNull(message = "虚拟销量不能为空")
+    private Integer virtualSalesCount;
 
 }

+ 6 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java

@@ -1,8 +1,7 @@
 package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
 
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
 import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
@@ -10,14 +9,16 @@ import lombok.ToString;
 import javax.validation.Valid;
 import java.util.List;
 
-@ApiModel("管理后台 - 商品spu创建 Request VO")
+@ApiModel("管理后台 - 商品 SPU 创建 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
 public class ProductSpuCreateReqVO extends ProductSpuBaseVO {
 
-    @ApiModelProperty(value = "sku组合")
+    /**
+     * SKU 数组
+     */
     @Valid
-    List<ProductSkuCreateReqVO> skus;
+    private List<ProductSkuCreateOrUpdateReqVO> skus;
 
 }

+ 30 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java

@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
+
+import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@ApiModel("管理后台 - 商品 SPU 更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class ProductSpuUpdateReqVO extends ProductSpuBaseVO {
+
+    @ApiModelProperty(value = "商品编号", required = true, example = "1")
+    @NotNull(message = "商品编号不能为空")
+    private Long id;
+
+    /**
+     * SKU 数组
+     */
+    @Valid
+    private List<ProductSkuCreateOrUpdateReqVO> skus;
+
+}

+ 0 - 25
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/SpuUpdateReqVO.java

@@ -1,25 +0,0 @@
-package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
-
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateReqVO;
-import lombok.*;
-import java.util.*;
-import io.swagger.annotations.*;
-
-import javax.validation.Valid;
-import javax.validation.constraints.*;
-
-@ApiModel("管理后台 - 商品spu更新 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class SpuUpdateReqVO extends ProductSpuBaseVO {
-
-    @ApiModelProperty(value = "主键", required = true)
-    @NotNull(message = "主键不能为空")
-    private Long id;
-
-    @ApiModelProperty(value = "sku组合")
-    @Valid
-    List<ProductSkuCreateReqVO> skus;
-
-}

+ 3 - 3
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java

@@ -1,7 +1,7 @@
 package cn.iocoder.yudao.module.product.convert.sku;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuExcelVO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuUpdateReqVO;
@@ -22,7 +22,7 @@ public interface ProductSkuConvert {
 
     ProductSkuConvert INSTANCE = Mappers.getMapper(ProductSkuConvert.class);
 
-    ProductSkuDO convert(ProductSkuCreateReqVO bean);
+    ProductSkuDO convert(ProductSkuCreateOrUpdateReqVO bean);
 
     ProductSkuDO convert(ProductSkuUpdateReqVO bean);
 
@@ -31,7 +31,7 @@ public interface ProductSkuConvert {
 
     List<ProductSkuRespVO> convertList(List<ProductSkuDO> list);
 
-    List<ProductSkuDO> convertSkuDOList(List<ProductSkuCreateReqVO> list);
+    List<ProductSkuDO> convertSkuDOList(List<ProductSkuCreateOrUpdateReqVO> list);
 
     PageResult<ProductSkuRespVO> convertPage(PageResult<ProductSkuDO> page);
 

+ 1 - 1
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java

@@ -22,7 +22,7 @@ public interface ProductSpuConvert {
 
     ProductSpuDO convert(ProductSpuCreateReqVO bean);
 
-    ProductSpuDO convert(SpuUpdateReqVO bean);
+    ProductSpuDO convert(ProductSpuUpdateReqVO bean);
 
     SpuRespVO convert(ProductSpuDO bean);
 

+ 4 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java

@@ -79,6 +79,10 @@ public class ProductSkuDO extends BaseDO {
      * 库存
      */
     private Integer stock;
+    /**
+     * 预警预存
+     */
+    private Integer warnStock;
     /**
      * 商品重量,单位:kg 千克
      */

+ 5 - 9
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java

@@ -67,11 +67,11 @@ public class ProductSpuDO extends BaseDO {
      */
     private Long brandId;
     /**
-     * 商品
-     */
-    private String bannerUrl;
-    /**
-     * 商品轮播图数组
+     * 商品图片的数组
+     *
+     * 1. 第一张图片将作为商品主图,支持同时上传多张图;
+     * 2. 建议使用尺寸 800x800 像素以上、大小不超过 1M 的正方形图片;
+     * 3. 至少 1 张,最多上传 10 张
      */
     @TableField(typeHandler = JacksonTypeHandler.class)
     private List<String> picUrls;
@@ -123,10 +123,6 @@ public class ProductSpuDO extends BaseDO {
      * 基于其对应的 {@link ProductSkuDO#getStock()} 求和
      */
     private Integer totalStock;
-    /**
-     * 预警预存
-     */
-    private Integer warnStock;
     /**
      * 是否展示库存
      */

+ 4 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java

@@ -1,8 +1,7 @@
 package cn.iocoder.yudao.module.product.service.sku;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateReqVO;
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuExportReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuPageReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuUpdateReqVO;
 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
@@ -24,7 +23,7 @@ public interface ProductSkuService {
      * @param createReqVO 创建信息
      * @return 编号
      */
-    Long createSku(@Valid ProductSkuCreateReqVO createReqVO);
+    Long createSku(@Valid ProductSkuCreateOrUpdateReqVO createReqVO);
 
     /**
      * 更新商品sku
@@ -69,7 +68,7 @@ public interface ProductSkuService {
      *
      * @param list sku组合的集合
      */
-    void validateSkus(List<ProductSkuCreateReqVO> list);
+    void validateSkus(List<ProductSkuCreateOrUpdateReqVO> list);
 
     /**
      * 批量保存 sku
@@ -107,5 +106,5 @@ public interface ProductSkuService {
      * @param spuId spu 编码
      * @param skus sku 的集合
      */
-    void updateSkus(Long spuId, List<ProductSkuCreateReqVO> skus);
+    void updateSkus(Long spuId, List<ProductSkuCreateOrUpdateReqVO> skus);
 }

+ 3 - 3
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java

@@ -38,7 +38,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
     private ProductPropertyService productPropertyService;
 
     @Override
-    public Long createSku(ProductSkuCreateReqVO createReqVO) {
+    public Long createSku(ProductSkuCreateOrUpdateReqVO createReqVO) {
         // 插入
         ProductSkuDO sku = ProductSkuConvert.INSTANCE.convert(createReqVO);
         productSkuMapper.insert(sku);
@@ -87,7 +87,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
     // TODO @franky:这个方法,貌似实现的还是有点问题哈。例如说,throw 异常,后面还执行逻辑~
     // TODO @艿艿 咳咳,throw 那里我是偷懒省略了{},哈哈,我加上,然后我调试下,在优化下
     @Override
-    public void validateSkus(List<ProductSkuCreateReqVO> list) {
+    public void validateSkus(List<ProductSkuCreateOrUpdateReqVO> list) {
         List<ProductSkuBaseVO.Property> skuPropertyList = list.stream().flatMap(p -> p.getProperties().stream()).collect(Collectors.toList());
         // 校验规格属性以及规格值是否存在
         List<Long> propertyIds = skuPropertyList.stream().map(ProductSkuBaseVO.Property::getPropertyId).collect(Collectors.toList());
@@ -139,7 +139,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
 
     @Override
     @Transactional
-    public void updateSkus(Long spuId, List<ProductSkuCreateReqVO> skus) {
+    public void updateSkus(Long spuId, List<ProductSkuCreateOrUpdateReqVO> skus) {
         List<ProductSkuDO> allUpdateSkus = ProductSkuConvert.INSTANCE.convertSkuDOList(skus);
         // 查询 spu 下已经存在的 sku 的集合
         List<ProductSkuDO> existsSkus = productSkuMapper.selectBySpuIds(Collections.singletonList(spuId));

+ 3 - 3
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java

@@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.product.service.spu;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuPageReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuRespVO;
-import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuUpdateReqVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
@@ -14,7 +14,7 @@ import java.util.Collection;
 import java.util.List;
 
 /**
- * 商品spu Service 接口
+ * 商品 SPU Service 接口
  *
  * @author 芋道源码
  */
@@ -33,7 +33,7 @@ public interface ProductSpuService {
      *
      * @param updateReqVO 更新信息
      */
-    void updateSpu(@Valid SpuUpdateReqVO updateReqVO);
+    void updateSpu(@Valid ProductSpuUpdateReqVO updateReqVO);
 
     /**
      * 删除商品spu

+ 9 - 12
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java

@@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPrope
 import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO;
 import cn.iocoder.yudao.module.product.controller.admin.propertyvalue.vo.ProductPropertyValueRespVO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
@@ -30,7 +30,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
 
 /**
- * 商品spu Service 实现类
+ * 商品 SPU Service 实现类
  *
  * @author 芋道源码
  */
@@ -56,15 +56,11 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         // 校验分类
         categoryService.validateProductCategory(createReqVO.getCategoryId());
         // 校验SKU
-        List<ProductSkuCreateReqVO> skuCreateReqList = createReqVO.getSkus();
+        List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = createReqVO.getSkus();
         productSkuService.validateSkus(skuCreateReqList);
         // 插入SPU
         ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO);
         ProductSpuMapper.insert(spu);
-        // sku关联SPU属性
-        skuCreateReqList.forEach(p -> {
-            p.setSpuId(spu.getId());
-        });
         List<ProductSkuDO> skuDOList = ProductSkuConvert.INSTANCE.convertSkuDOList(skuCreateReqList);
         // 批量插入sku
         productSkuService.createSkus(skuDOList);
@@ -74,13 +70,13 @@ public class ProductSpuServiceImpl implements ProductSpuService {
 
     @Override
     @Transactional
-    public void updateSpu(SpuUpdateReqVO updateReqVO) {
+    public void updateSpu(ProductSpuUpdateReqVO updateReqVO) {
         // 校验 spu 是否存在
         this.validateSpuExists(updateReqVO.getId());
         // 校验分类
         categoryService.validateProductCategory(updateReqVO.getCategoryId());
         // 校验SKU
-        List<ProductSkuCreateReqVO> skuCreateReqList = updateReqVO.getSkus();
+        List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = updateReqVO.getSkus();
         productSkuService.validateSkus(skuCreateReqList);
         // 更新
         ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO);
@@ -165,9 +161,10 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         List<Long> spuIds = spuVOs.getList().stream().map(SpuRespVO::getId).collect(Collectors.toList());
         List<ProductSkuRespVO> skus = ProductSkuConvert.INSTANCE.convertList(productSkuService.getSkusBySpuIds(spuIds));
         // TODO @franky:使用 CollUtil 里的方法替代哈
-        Map<Long, List<ProductSkuRespVO>> skuMap = skus.stream().collect(Collectors.groupingBy(ProductSkuRespVO::getSpuId));
-        // 将 spu 和 sku 进行组装
-        spuVOs.getList().forEach(p -> p.setSkus(skuMap.get(p.getId())));
+        // TODO 芋艿:临时注释
+//        Map<Long, List<ProductSkuRespVO>> skuMap = skus.stream().collect(Collectors.groupingBy(ProductSkuRespVO::getSpuId));
+//        // 将 spu 和 sku 进行组装
+//        spuVOs.getList().forEach(p -> p.setSkus(skuMap.get(p.getId())));
         return spuVOs;
     }
 

+ 2 - 2
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/SkuServiceImplTest.java

@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.product.service.sku;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuPageReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuUpdateReqVO;
 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
@@ -37,7 +37,7 @@ public class SkuServiceImplTest extends BaseDbUnitTest {
     @Test
     public void testCreateSku_success() {
         // 准备参数
-        ProductSkuCreateReqVO reqVO = randomPojo(ProductSkuCreateReqVO.class);
+        ProductSkuCreateOrUpdateReqVO reqVO = randomPojo(ProductSkuCreateOrUpdateReqVO.class);
 
         // 调用
         Long skuId = ProductSkuService.createSku(reqVO);

+ 3 - 3
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java

@@ -5,7 +5,7 @@ import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuPageReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuRespVO;
-import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuUpdateReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO;
 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
 import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
 import org.junit.jupiter.api.Disabled;
@@ -55,7 +55,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
         ProductSpuDO dbSpu = randomPojo(ProductSpuDO.class);
         ProductSpuMapper.insert(dbSpu);// @Sql: 先插入出一条存在的数据
         // 准备参数
-        SpuUpdateReqVO reqVO = randomPojo(SpuUpdateReqVO.class, o -> {
+        ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> {
             o.setId(dbSpu.getId()); // 设置更新的 ID
         });
 
@@ -69,7 +69,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
     @Test
     public void testUpdateSpu_notExists() {
         // 准备参数
-        SpuUpdateReqVO reqVO = randomPojo(SpuUpdateReqVO.class);
+        ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class);
 
         // 调用, 并断言异常
         assertServiceException(() -> spuService.updateSpu(reqVO), SPU_NOT_EXISTS);