Commit e1e55dc841df7b6ceead7f3a2ae05799050c7f95

Authored by luowenfeng
1 parent 15798cea

feature(商品添加): 规格调整连带商品调整

Showing 33 changed files with 704 additions and 336 deletions
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java
@@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.property; @@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.property;
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.module.product.controller.admin.property.vo.property.ProductPropertyAndValueRespVO;  
6 -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO;  
7 -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO;  
8 -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO; 5 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*;
9 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; 6 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
10 import io.swagger.annotations.Api; 7 import io.swagger.annotations.Api;
11 import io.swagger.annotations.ApiImplicitParam; 8 import io.swagger.annotations.ApiImplicitParam;
@@ -17,6 +14,8 @@ import org.springframework.web.bind.annotation.*; @@ -17,6 +14,8 @@ import org.springframework.web.bind.annotation.*;
17 import javax.annotation.Resource; 14 import javax.annotation.Resource;
18 import javax.validation.Valid; 15 import javax.validation.Valid;
19 16
  17 +import java.util.List;
  18 +
20 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 19 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
21 20
22 @Api(tags = "管理后台 - 规格名称") 21 @Api(tags = "管理后台 - 规格名称")
@@ -56,15 +55,29 @@ public class ProductPropertyController { @@ -56,15 +55,29 @@ public class ProductPropertyController {
56 @ApiOperation("获得规格名称") 55 @ApiOperation("获得规格名称")
57 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) 56 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
58 @PreAuthorize("@ss.hasPermission('product:property:query')") 57 @PreAuthorize("@ss.hasPermission('product:property:query')")
59 - public CommonResult<ProductPropertyAndValueRespVO> getProperty(@RequestParam("id") Long id) { 58 + public CommonResult<ProductPropertyRespVO> getProperty(@RequestParam("id") Long id) {
60 return success(productPropertyService.getPropertyResp(id)); 59 return success(productPropertyService.getPropertyResp(id));
61 } 60 }
62 61
  62 + @GetMapping("/list")
  63 + @ApiOperation("获得规格名称列表")
  64 + @PreAuthorize("@ss.hasPermission('product:property:query')")
  65 + public CommonResult<List<ProductPropertyRespVO>> getPropertyList(@Valid ProductPropertyListReqVO listReqVO) {
  66 + return success(productPropertyService.getPropertyList(listReqVO));
  67 + }
  68 +
63 @GetMapping("/page") 69 @GetMapping("/page")
64 @ApiOperation("获得规格名称分页") 70 @ApiOperation("获得规格名称分页")
65 @PreAuthorize("@ss.hasPermission('product:property:query')") 71 @PreAuthorize("@ss.hasPermission('product:property:query')")
66 - public CommonResult<PageResult<ProductPropertyAndValueRespVO>> getPropertyPage(@Valid ProductPropertyPageReqVO pageVO) {  
67 - return success(productPropertyService.getPropertyListPage(pageVO)); 72 + public CommonResult<PageResult<ProductPropertyRespVO>> getPropertyPage(@Valid ProductPropertyPageReqVO pageVO) {
  73 + return success(productPropertyService.getPropertyPage(pageVO));
  74 + }
  75 +
  76 + @GetMapping("/listAndValue")
  77 + @ApiOperation("获得规格名称列表")
  78 + @PreAuthorize("@ss.hasPermission('product:property:query')")
  79 + public CommonResult<List<ProductPropertyAndValueRespVO>> getPropertyAndValueList(@Valid ProductPropertyListReqVO listReqVO) {
  80 + return success(productPropertyService.getPropertyAndValueList(listReqVO));
68 } 81 }
69 82
70 } 83 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO;
  6 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
  7 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO;
  8 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
  9 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO;
  10 +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
  11 +import io.swagger.annotations.Api;
  12 +import io.swagger.annotations.ApiImplicitParam;
  13 +import io.swagger.annotations.ApiOperation;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.*;
  17 +
  18 +import javax.annotation.Resource;
  19 +import javax.validation.Valid;
  20 +
  21 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  22 +
  23 +@Api(tags = "管理后台 - 规格值名称")
  24 +@RestController
  25 +@RequestMapping("/product/property/value")
  26 +@Validated
  27 +public class ProductPropertyValueController {
  28 +
  29 + @Resource
  30 + private ProductPropertyValueService productPropertyValueService;
  31 +
  32 + @PostMapping("/create")
  33 + @ApiOperation("创建规格名称")
  34 + @PreAuthorize("@ss.hasPermission('product:property:create')")
  35 + public CommonResult<Long> createProperty(@Valid @RequestBody ProductPropertyValueCreateReqVO createReqVO) {
  36 + return success(productPropertyValueService.createPropertyValue(createReqVO));
  37 + }
  38 +
  39 + @PutMapping("/update")
  40 + @ApiOperation("更新规格名称")
  41 + @PreAuthorize("@ss.hasPermission('product:property:update')")
  42 + public CommonResult<Boolean> updateProperty(@Valid @RequestBody ProductPropertyValueUpdateReqVO updateReqVO) {
  43 + productPropertyValueService.updatePropertyValue(updateReqVO);
  44 + return success(true);
  45 + }
  46 +
  47 + @DeleteMapping("/delete")
  48 + @ApiOperation("删除规格名称")
  49 + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
  50 + @PreAuthorize("@ss.hasPermission('product:property:delete')")
  51 + public CommonResult<Boolean> deleteProperty(@RequestParam("id") Long id) {
  52 + productPropertyValueService.deletePropertyValue(id);
  53 + return success(true);
  54 + }
  55 +
  56 + @GetMapping("/get")
  57 + @ApiOperation("获得规格名称")
  58 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  59 + @PreAuthorize("@ss.hasPermission('product:property:query')")
  60 + public CommonResult<ProductPropertyValueRespVO> getProperty(@RequestParam("id") Long id) {
  61 + return success(productPropertyValueService.getPropertyValue(id));
  62 + }
  63 +
  64 + @GetMapping("/page")
  65 + @ApiOperation("获得规格名称分页")
  66 + @PreAuthorize("@ss.hasPermission('product:property:query')")
  67 + public CommonResult<PageResult<ProductPropertyValueRespVO>> getPropertyValuePage(@Valid ProductPropertyValuePageReqVO pageVO) {
  68 + return success(productPropertyValueService.getPropertyValueListPage(pageVO));
  69 + }
  70 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java
@@ -3,21 +3,25 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; @@ -3,21 +3,25 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
3 import io.swagger.annotations.ApiModelProperty; 3 import io.swagger.annotations.ApiModelProperty;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 -import javax.validation.constraints.NotEmpty; 6 +import javax.validation.constraints.NotBlank;
  7 +import javax.validation.constraints.NotNull;
7 8
8 /** 9 /**
9 -* 规格名称 Base VO,提供给添加、修改、详细的子 VO 使用  
10 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成  
11 -*/ 10 + * 规格名称 Base VO,提供给添加、修改、详细的子 VO 使用
  11 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  12 + */
12 @Data 13 @Data
13 public class ProductPropertyBaseVO { 14 public class ProductPropertyBaseVO {
14 15
15 @ApiModelProperty(value = "规格名称", required = true, example = "颜色") 16 @ApiModelProperty(value = "规格名称", required = true, example = "颜色")
16 - @NotEmpty(message = "规格名称不能为空") 17 + @NotBlank(message = "规格名称不能为空")
17 private String name; 18 private String name;
18 19
  20 + @ApiModelProperty(value = "备注", example = "颜色")
  21 + private String remark;
  22 +
19 @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") 23 @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
20 - @NotEmpty(message = "状态不能为空") 24 + @NotNull(message = "状态不能为空")
21 private Integer status; 25 private Integer status;
22 26
23 } 27 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java
1 package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; 1 package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
2 2
3 -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;  
4 -import lombok.*;  
5 -import io.swagger.annotations.*;  
6 -  
7 -import javax.validation.constraints.NotNull;  
8 -import java.util.List; 3 +import io.swagger.annotations.ApiModel;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
9 7
10 @ApiModel("管理后台 - 规格名称创建 Request VO") 8 @ApiModel("管理后台 - 规格名称创建 Request VO")
11 @Data 9 @Data
@@ -13,9 +11,5 @@ import java.util.List; @@ -13,9 +11,5 @@ import java.util.List;
13 @ToString(callSuper = true) 11 @ToString(callSuper = true)
14 public class ProductPropertyCreateReqVO extends ProductPropertyBaseVO { 12 public class ProductPropertyCreateReqVO extends ProductPropertyBaseVO {
15 13
16 - // TODO @Luowenfeng:规格值的 CRUD 可以单独;前端 + 后端,改成类似字典类型、字典数据的这种交互;在加一个 ProductPropertyValueController  
17 - @ApiModelProperty(value = "属性值")  
18 - @NotNull(message = "属性值不能为空")  
19 - List<ProductPropertyValueCreateReqVO> propertyValueList;  
20 14
21 } 15 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.ToString;
  7 +
  8 +@ApiModel("管理后台 - 规格名称 List Request VO")
  9 +@Data
  10 +@ToString(callSuper = true)
  11 +public class ProductPropertyListReqVO {
  12 +
  13 + @ApiModelProperty(value = "规格名称", example = "颜色")
  14 + private String name;
  15 +
  16 + @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
  17 + private Integer status;
  18 +
  19 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import java.util.Date;
  10 +
  11 +@ApiModel("管理后台 - 规格 + 规格值 Response VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class ProductPropertyRespVO extends ProductPropertyBaseVO {
  16 +
  17 + @ApiModelProperty(value = "规格的编号", required = true, example = "1024")
  18 + private Long id;
  19 +
  20 + @ApiModelProperty(value = "创建时间", required = true)
  21 + private Date createTime;
  22 +
  23 +
  24 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java
@@ -16,8 +16,4 @@ public class ProductPropertyUpdateReqVO extends ProductPropertyBaseVO { @@ -16,8 +16,4 @@ public class ProductPropertyUpdateReqVO extends ProductPropertyBaseVO {
16 @NotNull(message = "主键不能为空") 16 @NotNull(message = "主键不能为空")
17 private Long id; 17 private Long id;
18 18
19 - @ApiModelProperty(value = "属性值")  
20 - @NotNull(message = "属性值不能为空")  
21 - List<ProductPropertyValueCreateReqVO> propertyValueList;  
22 -  
23 } 19 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java
@@ -22,7 +22,9 @@ public class ProductPropertyValueBaseVO { @@ -22,7 +22,9 @@ public class ProductPropertyValueBaseVO {
22 private String name; 22 private String name;
23 23
24 @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") 24 @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
25 - @NotEmpty(message = "状态不能为空") 25 + @NotNull(message = "状态不能为空")
26 private Integer status; 26 private Integer status;
27 27
  28 + @ApiModelProperty(value = "备注", example = "颜色")
  29 + private String remark;
28 } 30 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  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 +import org.springframework.format.annotation.DateTimeFormat;
  10 +
  11 +import javax.validation.constraints.NotEmpty;
  12 +import java.util.Date;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  15 +
  16 +@ApiModel("管理后台 - 规格名称值分页 Request VO")
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +public class ProductPropertyValuePageReqVO extends PageParam {
  21 +
  22 + @ApiModelProperty(value = "规格id", example = "1024")
  23 + private String propertyId;
  24 +
  25 + @ApiModelProperty(value = "规格值", example = "红色")
  26 + private String name;
  27 +
  28 + @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
  29 + private Integer status;
  30 +
  31 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
@@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.spu; @@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.spu;
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.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;  
6 -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO;  
7 -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO;  
8 -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; 5 +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
9 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; 6 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
10 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; 7 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
11 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; 8 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
@@ -56,6 +53,14 @@ public class ProductSpuController { @@ -56,6 +53,14 @@ public class ProductSpuController {
56 return success(true); 53 return success(true);
57 } 54 }
58 55
  56 + @GetMapping("/get/detail")
  57 + @ApiOperation("获得商品 SPU")
  58 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  59 + @PreAuthorize("@ss.hasPermission('product:spu:query')")
  60 + public CommonResult<ProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) {
  61 + return success(spuService.getSpuDetail(id));
  62 + }
  63 +
59 @GetMapping("/get") 64 @GetMapping("/get")
60 @ApiOperation("获得商品 SPU") 65 @ApiOperation("获得商品 SPU")
61 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) 66 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@@ -64,7 +69,6 @@ public class ProductSpuController { @@ -64,7 +69,6 @@ public class ProductSpuController {
64 return success(spuService.getSpu(id)); 69 return success(spuService.getSpu(id));
65 } 70 }
66 71
67 - // TODO @luowenfeng:新增 get-detail,返回 SpuDetailRespVO  
68 72
69 @GetMapping("/list") 73 @GetMapping("/list")
70 @ApiOperation("获得商品 SPU 列表") 74 @ApiOperation("获得商品 SPU 列表")
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java
1 package cn.iocoder.yudao.module.product.controller.admin.spu.vo; 1 package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
2 2
3 import cn.iocoder.yudao.framework.common.validation.InEnum; 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
4 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; 5 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
5 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; 6 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
6 import io.swagger.annotations.ApiModelProperty; 7 import io.swagger.annotations.ApiModelProperty;
@@ -67,6 +68,9 @@ public class ProductSpuBaseVO { @@ -67,6 +68,9 @@ public class ProductSpuBaseVO {
67 @ApiModelProperty(value = "库存", required = true, example = "true") 68 @ApiModelProperty(value = "库存", required = true, example = "true")
68 private Integer totalStock; 69 private Integer totalStock;
69 70
  71 + @ApiModelProperty(value = "市场价", example = "1024")
  72 + private Integer marketPrice;
  73 +
70 @ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024") 74 @ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024")
71 private Integer minPrice; 75 private Integer minPrice;
72 76
@@ -75,10 +79,14 @@ public class ProductSpuBaseVO { @@ -75,10 +79,14 @@ public class ProductSpuBaseVO {
75 79
76 // ========== 统计相关字段 ========= 80 // ========== 统计相关字段 =========
77 81
  82 + @ApiModelProperty(value = "商品销量", example = "1024")
  83 + private Integer salesCount;
  84 +
78 @ApiModelProperty(value = "虚拟销量", required = true, example = "1024") 85 @ApiModelProperty(value = "虚拟销量", required = true, example = "1024")
79 @NotNull(message = "虚拟销量不能为空") 86 @NotNull(message = "虚拟销量不能为空")
80 private Integer virtualSalesCount; 87 private Integer virtualSalesCount;
81 88
82 @ApiModelProperty(value = "点击量", example = "1024") 89 @ApiModelProperty(value = "点击量", example = "1024")
83 private Integer clickCount; 90 private Integer clickCount;
  91 +
84 } 92 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java
1 package cn.iocoder.yudao.module.product.controller.admin.spu.vo; 1 package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
2 2
  3 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO;
3 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; 4 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
4 import io.swagger.annotations.ApiModel; 5 import io.swagger.annotations.ApiModel;
5 import io.swagger.annotations.ApiModelProperty; 6 import io.swagger.annotations.ApiModelProperty;
@@ -54,4 +55,10 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO { @@ -54,4 +55,10 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO {
54 55
55 } 56 }
56 57
  58 + @ApiModelProperty(value = "分类id数组,一直递归到一级父节点", example = "[1,2,4]")
  59 + private List<Long> categoryIds;
  60 +
  61 + @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\"}]}]")
  62 + private List<ProductPropertyViewRespVO> productPropertyViews;
  63 +
57 } 64 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java
@@ -17,35 +17,16 @@ public class ProductSpuPageReqVO extends PageParam { @@ -17,35 +17,16 @@ public class ProductSpuPageReqVO extends PageParam {
17 @ApiModelProperty(value = "商品名称") 17 @ApiModelProperty(value = "商品名称")
18 private String name; 18 private String name;
19 19
20 - @ApiModelProperty(value = "卖点")  
21 - private String sellPoint;  
22 -  
23 - @ApiModelProperty(value = "描述")  
24 - private String description; 20 + @ApiModelProperty(value = "商品编码", example = "yudaoyuanma")
  21 + private String code;
25 22
26 @ApiModelProperty(value = "分类id") 23 @ApiModelProperty(value = "分类id")
27 private Long categoryId; 24 private Long categoryId;
28 25
29 - @ApiModelProperty(value = "商品主图地址,* 数组,以逗号分隔,最多上传15张")  
30 - private String picUrls;  
31 -  
32 - @ApiModelProperty(value = "排序字段")  
33 - private Integer sort;  
34 -  
35 - @ApiModelProperty(value = "点赞初始人数")  
36 - private Integer likeCount;  
37 -  
38 - @ApiModelProperty(value = "价格 单位使用:分")  
39 - private Integer price;  
40 -  
41 - @ApiModelProperty(value = "库存数量")  
42 - private Integer quantity; 26 + @ApiModelProperty(value = "商品品牌编号", example = "1")
  27 + private Long brandId;
43 28
44 @ApiModelProperty(value = "上下架状态: 0 上架(开启) 1 下架(禁用)") 29 @ApiModelProperty(value = "上下架状态: 0 上架(开启) 1 下架(禁用)")
45 private Integer status; 30 private Integer status;
46 31
47 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
48 - @ApiModelProperty(value = "创建时间")  
49 - private Date[] createTime;  
50 -  
51 } 32 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java
1 package cn.iocoder.yudao.module.product.controller.admin.spu.vo; 1 package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
2 2
3 -import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO;  
4 -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;  
5 import io.swagger.annotations.ApiModel; 3 import io.swagger.annotations.ApiModel;
6 import io.swagger.annotations.ApiModelProperty; 4 import io.swagger.annotations.ApiModelProperty;
7 import lombok.Data; 5 import lombok.Data;
@@ -9,9 +7,7 @@ import lombok.EqualsAndHashCode; @@ -9,9 +7,7 @@ import lombok.EqualsAndHashCode;
9 import lombok.ToString; 7 import lombok.ToString;
10 8
11 import java.util.Date; 9 import java.util.Date;
12 -import java.util.List;  
13 10
14 -// TODO @Luowenfeng:这个类只返回 SPU 相关的信息,删除 skus、categoryIds、productPropertyViews;明细使用 SpuDetailRespVO 替代  
15 @ApiModel("管理后台 - 商品 SPU Response VO") 11 @ApiModel("管理后台 - 商品 SPU Response VO")
16 @Data 12 @Data
17 @EqualsAndHashCode(callSuper = true) 13 @EqualsAndHashCode(callSuper = true)
@@ -24,18 +20,4 @@ public class ProductSpuRespVO extends ProductSpuBaseVO { @@ -24,18 +20,4 @@ public class ProductSpuRespVO extends ProductSpuBaseVO {
24 @ApiModelProperty(value = "创建时间") 20 @ApiModelProperty(value = "创建时间")
25 private Date createTime; 21 private Date createTime;
26 22
27 - /**  
28 - * SKU 数组  
29 - */  
30 - @ApiModelProperty(value = "sku 数组", example = "[{\"spuId\":4,\"properties\":[{\"propertyId\":3,\"valueId\":15},{\"propertyId\":2,\"valueId\":10}],\"price\":12,\"originalPrice\":32,\"costPrice\":22,\"barCode\":\"765670123123\",\"picUrl\":\"http://test.yudao.iocoder.cn/72938088f1ca8438837c3b51394aea43.jpg\",\"status\":0,\"id\":7,\"createTime\":1656683270000},{\"spuId\":4,\"properties\":[{\"propertyId\":3,\"valueId\":15},{\"propertyId\":2,\"valueId\":11}],\"price\":13,\"originalPrice\":33,\"costPrice\":23,\"barCode\":\"888788770999\",\"picUrl\":\"http://test.yudao.iocoder.cn/6b902c700e5d32e862b6fd9af2e1c0e4.jpg\",\"status\":0,\"id\":8,\"createTime\":1656683270000},{\"spuId\":4,\"properties\":[{\"propertyId\":3,\"valueId\":16},{\"propertyId\":2,\"valueId\":10}],\"price\":14,\"originalPrice\":34,\"costPrice\":24,\"barCode\":\"9999981212\",\"picUrl\":\"http://test.yudao.iocoder.cn/eddf3c79b1917160d94d05244e1f47da.jpg\",\"status\":0,\"id\":9,\"createTime\":1656683270000},{\"spuId\":4,\"properties\":[{\"propertyId\":3,\"valueId\":16},{\"propertyId\":2,\"valueId\":11}],\"price\":15,\"originalPrice\":35,\"costPrice\":25,\"barCode\":\"4444121212\",\"picUrl\":\"http://test.yudao.iocoder.cn/88ac3eb068ea9cfac4726879b2776ccf.jpg\",\"status\":0,\"id\":10,\"createTime\":1656683270000}]")  
31 - private List<ProductSkuRespVO> skus;  
32 -  
33 - @ApiModelProperty(value = "分类id数组,一直递归到一级父节点", example = "[1,2,4]")  
34 - private List<Long> categoryIds;  
35 -  
36 - // TODO @芋艿:再琢磨下 这个 VO 类,其实变成 SpuRespVO 内嵌的 VO 类会更好一点;然后把 SpuRespVO 改成 SpuDetailSpuVO  
37 -  
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\"}]}]")  
39 - private List<ProductPropertyViewRespVO> productPropertyViews;  
40 -  
41 } 23 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java
1 package cn.iocoder.yudao.module.product.convert.property; 1 package cn.iocoder.yudao.module.product.convert.property;
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.property.vo.property.ProductPropertyAndValueRespVO;  
5 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO; 4 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO;
  5 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
6 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO; 6 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO;
7 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; 7 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
8 import org.mapstruct.Mapper; 8 import org.mapstruct.Mapper;
@@ -24,10 +24,10 @@ public interface ProductPropertyConvert { @@ -24,10 +24,10 @@ public interface ProductPropertyConvert {
24 24
25 ProductPropertyDO convert(ProductPropertyUpdateReqVO bean); 25 ProductPropertyDO convert(ProductPropertyUpdateReqVO bean);
26 26
27 - ProductPropertyAndValueRespVO convert(ProductPropertyDO bean); 27 + ProductPropertyRespVO convert(ProductPropertyDO bean);
28 28
29 - List<ProductPropertyAndValueRespVO> convertList(List<ProductPropertyDO> list); 29 + List<ProductPropertyRespVO> convertList(List<ProductPropertyDO> list);
30 30
31 - PageResult<ProductPropertyAndValueRespVO> convertPage(PageResult<ProductPropertyDO> page); 31 + PageResult<ProductPropertyRespVO> convertPage(PageResult<ProductPropertyDO> page);
32 32
33 } 33 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.product.convert.sku; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.product.convert.sku;
3 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; 3 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
4 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; 4 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
5 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; 5 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
  6 +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuDetailRespVO;
6 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; 7 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
7 import org.mapstruct.Mapper; 8 import org.mapstruct.Mapper;
8 import org.mapstruct.factory.Mappers; 9 import org.mapstruct.factory.Mappers;
@@ -31,4 +32,6 @@ public interface ProductSkuConvert { @@ -31,4 +32,6 @@ public interface ProductSkuConvert {
31 32
32 List<ProductSkuRespDTO> convertList02(List<ProductSkuDO> list); 33 List<ProductSkuRespDTO> convertList02(List<ProductSkuDO> list);
33 34
  35 + List<ProductSpuDetailRespVO.Sku> convertList03(List<ProductSkuDO> list);
  36 +
34 } 37 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java
@@ -37,6 +37,10 @@ public class ProductPropertyDO extends BaseDO { @@ -37,6 +37,10 @@ public class ProductPropertyDO extends BaseDO {
37 * 枚举 {@link CommonStatusEnum} 37 * 枚举 {@link CommonStatusEnum}
38 */ 38 */
39 private Integer status; 39 private Integer status;
  40 + /**
  41 + * 备注
  42 + */
  43 + private String remark;
40 44
41 // TODO 芋艿:rule;规格属性 (发布商品时,和 SKU 关联);规格参数(搜索商品时,与 Category 关联搜索) 45 // TODO 芋艿:rule;规格属性 (发布商品时,和 SKU 关联);规格参数(搜索商品时,与 Category 关联搜索)
42 46
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java
@@ -44,5 +44,10 @@ public class ProductPropertyValueDO extends BaseDO { @@ -44,5 +44,10 @@ public class ProductPropertyValueDO extends BaseDO {
44 * 枚举 {@link CommonStatusEnum} 44 * 枚举 {@link CommonStatusEnum}
45 */ 45 */
46 private Integer status; 46 private Integer status;
  47 + /**
  48 + * 备注
  49 + *
  50 + */
  51 + private String remark;
47 52
48 } 53 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyValueMapper.java
1 package cn.iocoder.yudao.module.product.dal.mysql.property; 1 package cn.iocoder.yudao.module.product.dal.mysql.property;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4 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.property.vo.value.ProductPropertyValuePageReqVO;
5 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; 7 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
6 import org.apache.ibatis.annotations.Mapper; 8 import org.apache.ibatis.annotations.Mapper;
7 9
@@ -16,17 +18,25 @@ import java.util.List; @@ -16,17 +18,25 @@ import java.util.List;
16 public interface ProductPropertyValueMapper extends BaseMapperX<ProductPropertyValueDO> { 18 public interface ProductPropertyValueMapper extends BaseMapperX<ProductPropertyValueDO> {
17 19
18 // TODO @franky:方法名,selectListByXXX。mapper 的操作都是 crud 20 // TODO @franky:方法名,selectListByXXX。mapper 的操作都是 crud
19 - default List<ProductPropertyValueDO> getPropertyValueListByPropertyId(List<Long> propertyIds){ 21 + default List<ProductPropertyValueDO> getPropertyValueListByPropertyId(List<Long> propertyIds) {
20 // TODO @franky:调用父类的 selectList 22 // TODO @franky:调用父类的 selectList
21 return selectList(new LambdaQueryWrapperX<ProductPropertyValueDO>() 23 return selectList(new LambdaQueryWrapperX<ProductPropertyValueDO>()
22 .inIfPresent(ProductPropertyValueDO::getPropertyId, propertyIds)); 24 .inIfPresent(ProductPropertyValueDO::getPropertyId, propertyIds));
23 } 25 }
24 26
25 - default void deletePropertyValueByPropertyId(Long propertyId){ 27 + default void deletePropertyValueByPropertyId(Long propertyId) {
26 // TODO @franky:delete(new ) 即可 28 // TODO @franky:delete(new ) 即可
27 LambdaQueryWrapperX<ProductPropertyValueDO> queryWrapperX = new LambdaQueryWrapperX<>(); 29 LambdaQueryWrapperX<ProductPropertyValueDO> queryWrapperX = new LambdaQueryWrapperX<>();
28 queryWrapperX.eq(ProductPropertyValueDO::getPropertyId, propertyId) 30 queryWrapperX.eq(ProductPropertyValueDO::getPropertyId, propertyId)
29 .eq(ProductPropertyValueDO::getDeleted, false); 31 .eq(ProductPropertyValueDO::getDeleted, false);
30 delete(queryWrapperX); 32 delete(queryWrapperX);
31 } 33 }
  34 +
  35 + default PageResult<ProductPropertyValueDO> selectPage(ProductPropertyValuePageReqVO reqVO) {
  36 + return selectPage(reqVO, new LambdaQueryWrapperX<ProductPropertyValueDO>()
  37 + .eqIfPresent(ProductPropertyValueDO::getPropertyId, reqVO.getPropertyId())
  38 + .likeIfPresent(ProductPropertyValueDO::getName, reqVO.getName())
  39 + .eqIfPresent(ProductPropertyValueDO::getStatus, reqVO.getStatus())
  40 + .orderByDesc(ProductPropertyValueDO::getId));
  41 + }
32 } 42 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java
@@ -18,11 +18,8 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; { @@ -18,11 +18,8 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; {
18 default PageResult<ProductSpuDO> selectPage(ProductSpuPageReqVO reqVO) { 18 default PageResult<ProductSpuDO> selectPage(ProductSpuPageReqVO reqVO) {
19 return selectPage(reqVO, new LambdaQueryWrapperX<ProductSpuDO>() 19 return selectPage(reqVO, new LambdaQueryWrapperX<ProductSpuDO>()
20 .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) 20 .likeIfPresent(ProductSpuDO::getName, reqVO.getName())
21 - .eqIfPresent(ProductSpuDO::getSellPoint, reqVO.getSellPoint())  
22 .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) 21 .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId())
23 - .eqIfPresent(ProductSpuDO::getPicUrls, reqVO.getPicUrls())  
24 .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) 22 .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus())
25 - .betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime())  
26 .orderByDesc(ProductSpuDO::getSort)); 23 .orderByDesc(ProductSpuDO::getSort));
27 } 24 }
28 25
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 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.property.vo.property.ProductPropertyAndValueRespVO; 4 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
5 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*; 5 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*;
6 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; 6 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
7 7
@@ -48,35 +48,35 @@ public interface ProductPropertyService { @@ -48,35 +48,35 @@ public interface ProductPropertyService {
48 48
49 /** 49 /**
50 * 获得规格名称列表 50 * 获得规格名称列表
51 - *  
52 - * @param ids 编号  
53 - * @return 规格名称列表  
54 - */  
55 - List<ProductPropertyDO> getPropertyList(Collection<Long> ids);  
56 -  
57 - /**  
58 - * 获得规格名称分页  
59 - *  
60 - * @param pageReqVO 分页查询  
61 - * @return 规格名称分页 51 + * @param listReqVO 集合查询
  52 + * @return 规格名称集合
62 */ 53 */
63 - PageResult<ProductPropertyDO> getPropertyPage(ProductPropertyPageReqVO pageReqVO); 54 + List<ProductPropertyRespVO> getPropertyList(ProductPropertyListReqVO listReqVO);
64 55
65 /** 56 /**
66 * 获取属性及属性值列表 分页 57 * 获取属性及属性值列表 分页
67 * @param pageReqVO 58 * @param pageReqVO
68 * @return 59 * @return
69 */ 60 */
70 - PageResult<ProductPropertyAndValueRespVO> getPropertyListPage(ProductPropertyPageReqVO pageReqVO); 61 + PageResult<ProductPropertyRespVO> getPropertyPage(ProductPropertyPageReqVO pageReqVO);
  62 +
71 63
72 - ProductPropertyAndValueRespVO getPropertyResp(Long id); 64 + ProductPropertyRespVO getPropertyResp(Long id);
73 65
74 /** 66 /**
75 * 根据规格属性编号的集合,获得对应的规格 + 规格值的集合 67 * 根据规格属性编号的集合,获得对应的规格 + 规格值的集合
76 * 68 *
77 * @param ids 规格编号的集合 69 * @param ids 规格编号的集合
78 - * @return 对应的规格 + 规格值的集合 70 + * @return 对应的规格
  71 + */
  72 + List<ProductPropertyRespVO> getPropertyList(Collection<Long> ids);
  73 +
  74 +
  75 + /**
  76 + * 获得规格名称列表
  77 + * @param listReqVO 集合查询
  78 + * @return 规格名称集合
79 */ 79 */
80 - List<ProductPropertyAndValueRespVO> getPropertyAndValueList(Collection<Long> ids); 80 + List<ProductPropertyAndValueRespVO> getPropertyAndValueList(ProductPropertyListReqVO listReqVO);
81 81
82 } 82 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java
1 package cn.iocoder.yudao.module.product.service.property; 1 package cn.iocoder.yudao.module.product.service.property;
2 2
  3 +import cn.hutool.core.bean.BeanUtil;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyAndValueRespVO; 5 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  6 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  7 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
5 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*; 8 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*;
6 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; 9 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
7 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; 10 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
@@ -46,12 +49,6 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { @@ -46,12 +49,6 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
46 // 插入 49 // 插入
47 ProductPropertyDO property = ProductPropertyConvert.INSTANCE.convert(createReqVO); 50 ProductPropertyDO property = ProductPropertyConvert.INSTANCE.convert(createReqVO);
48 productPropertyMapper.insert(property); 51 productPropertyMapper.insert(property);
49 -  
50 - //插入属性值  
51 - List<ProductPropertyValueCreateReqVO> propertyValueList = createReqVO.getPropertyValueList();  
52 - List<ProductPropertyValueDO> productPropertyValueDOList = ProductPropertyValueConvert.INSTANCE.convertList03(propertyValueList);  
53 - productPropertyValueDOList.forEach(x-> x.setPropertyId(property.getId()));  
54 - productPropertyValueMapper.insertBatch(productPropertyValueDOList);  
55 // 返回 52 // 返回
56 return property.getId(); 53 return property.getId();
57 } 54 }
@@ -64,12 +61,6 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { @@ -64,12 +61,6 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
64 // 更新 61 // 更新
65 ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO); 62 ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO);
66 productPropertyMapper.updateById(updateObj); 63 productPropertyMapper.updateById(updateObj);
67 - //更新属性值,先删后加  
68 - productPropertyValueMapper.deletePropertyValueByPropertyId(updateReqVO.getId());  
69 - List<ProductPropertyValueCreateReqVO> propertyValueList = updateReqVO.getPropertyValueList();  
70 - List<ProductPropertyValueDO> productPropertyValueDOList = ProductPropertyValueConvert.INSTANCE.convertList03(propertyValueList);  
71 - productPropertyValueDOList.forEach(x-> x.setPropertyId(updateReqVO.getId()));  
72 - productPropertyValueMapper.insertBatch(productPropertyValueDOList);  
73 } 64 }
74 65
75 @Override 66 @Override
@@ -94,31 +85,28 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { @@ -94,31 +85,28 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
94 } 85 }
95 86
96 @Override 87 @Override
97 - public List<ProductPropertyDO> getPropertyList(Collection<Long> ids) {  
98 - return productPropertyMapper.selectBatchIds(ids);  
99 - }  
100 -  
101 - @Override  
102 - public PageResult<ProductPropertyDO> getPropertyPage(ProductPropertyPageReqVO pageReqVO) {  
103 - return productPropertyMapper.selectPage(pageReqVO); 88 + public List<ProductPropertyRespVO> getPropertyList(ProductPropertyListReqVO listReqVO) {
  89 + return ProductPropertyConvert.INSTANCE.convertList(productPropertyMapper.selectList(new LambdaQueryWrapperX<ProductPropertyDO>()
  90 + .likeIfPresent(ProductPropertyDO::getName, listReqVO.getName())
  91 + .eqIfPresent(ProductPropertyDO::getStatus, listReqVO.getStatus())));
104 } 92 }
105 93
106 @Override 94 @Override
107 - public PageResult<ProductPropertyAndValueRespVO> getPropertyListPage(ProductPropertyPageReqVO pageReqVO) { 95 + public PageResult<ProductPropertyRespVO> getPropertyPage(ProductPropertyPageReqVO pageReqVO) {
108 //获取属性列表 96 //获取属性列表
109 PageResult<ProductPropertyDO> pageResult = productPropertyMapper.selectPage(pageReqVO); 97 PageResult<ProductPropertyDO> pageResult = productPropertyMapper.selectPage(pageReqVO);
110 - PageResult<ProductPropertyAndValueRespVO> propertyRespVOPageResult = ProductPropertyConvert.INSTANCE.convertPage(pageResult);  
111 - List<Long> propertyIds = propertyRespVOPageResult.getList().stream().map(ProductPropertyAndValueRespVO::getId).collect(Collectors.toList());  
112 -  
113 - //获取属性值列表  
114 - List<ProductPropertyValueDO> productPropertyValueDOList = productPropertyValueMapper.getPropertyValueListByPropertyId(propertyIds);  
115 - List<ProductPropertyValueRespVO> propertyValueRespVOList = ProductPropertyValueConvert.INSTANCE.convertList(productPropertyValueDOList);  
116 - //组装一对多  
117 - propertyRespVOPageResult.getList().forEach(x->{  
118 - Long propertyId = x.getId();  
119 - List<ProductPropertyValueRespVO> valueDOList = propertyValueRespVOList.stream().filter(v -> v.getPropertyId().equals(propertyId)).collect(Collectors.toList());  
120 - x.setValues(valueDOList);  
121 - }); 98 + PageResult<ProductPropertyRespVO> propertyRespVOPageResult = ProductPropertyConvert.INSTANCE.convertPage(pageResult);
  99 +// List<Long> propertyIds = propertyRespVOPageResult.getList().stream().map(ProductPropertyAndValueRespVO::getId).collect(Collectors.toList());
  100 +//
  101 +// //获取属性值列表
  102 +// List<ProductPropertyValueDO> productPropertyValueDOList = productPropertyValueMapper.getPropertyValueListByPropertyId(propertyIds);
  103 +// List<ProductPropertyValueRespVO> propertyValueRespVOList = ProductPropertyValueConvert.INSTANCE.convertList(productPropertyValueDOList);
  104 +// //组装一对多
  105 +// propertyRespVOPageResult.getList().forEach(x->{
  106 +// Long propertyId = x.getId();
  107 +// List<ProductPropertyValueRespVO> valueDOList = propertyValueRespVOList.stream().filter(v -> v.getPropertyId().equals(propertyId)).collect(Collectors.toList());
  108 +// x.setValues(valueDOList);
  109 +// });
122 return propertyRespVOPageResult; 110 return propertyRespVOPageResult;
123 } 111 }
124 112
@@ -127,25 +115,31 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { @@ -127,25 +115,31 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
127 } 115 }
128 116
129 @Override 117 @Override
130 - public ProductPropertyAndValueRespVO getPropertyResp(Long id) { 118 + public ProductPropertyRespVO getPropertyResp(Long id) {
131 //查询规格 119 //查询规格
132 ProductPropertyDO property = getProperty(id); 120 ProductPropertyDO property = getProperty(id);
133 - ProductPropertyAndValueRespVO propertyRespVO = ProductPropertyConvert.INSTANCE.convert(property);  
134 - //查询属性值  
135 - List<ProductPropertyValueDO> valueDOList = productPropertyValueMapper.getPropertyValueListByPropertyId(Arrays.asList(id));  
136 - List<ProductPropertyValueRespVO> propertyValueRespVOS = ProductPropertyValueConvert.INSTANCE.convertList(valueDOList);  
137 - //组装  
138 - propertyRespVO.setValues(propertyValueRespVOS);  
139 - return propertyRespVO; 121 + return ProductPropertyConvert.INSTANCE.convert(property);
140 } 122 }
141 123
142 @Override 124 @Override
143 - public List<ProductPropertyAndValueRespVO> getPropertyAndValueList(Collection<Long> ids) {  
144 - List<ProductPropertyAndValueRespVO> productPropertyRespVO = ProductPropertyConvert.INSTANCE.convertList(productPropertyMapper.selectBatchIds(ids)); 125 + public List<ProductPropertyRespVO> getPropertyList(Collection<Long> ids) {
  126 + return ProductPropertyConvert.INSTANCE.convertList(productPropertyMapper.selectBatchIds(ids));
  127 + }
  128 +
  129 + @Override
  130 + public List<ProductPropertyAndValueRespVO> getPropertyAndValueList(ProductPropertyListReqVO listReqVO) {
  131 + List<ProductPropertyRespVO> propertyList = getPropertyList(listReqVO);
  132 +
145 //查询属性值 133 //查询属性值
146 - List<ProductPropertyValueDO> valueDOList = productPropertyValueMapper.selectBatchIds(ids);  
147 - Map<Long, List<ProductPropertyValueDO>> propertyValuesMap = valueDOList.stream().collect(Collectors.groupingBy(ProductPropertyValueDO::getPropertyId));  
148 - productPropertyRespVO.forEach(p -> p.setValues(ProductPropertyValueConvert.INSTANCE.convertList(propertyValuesMap.get(p.getId()))));  
149 - return productPropertyRespVO; 134 + List<ProductPropertyValueDO> valueDOList = productPropertyValueMapper.getPropertyValueListByPropertyId(CollectionUtils.convertList(propertyList, ProductPropertyRespVO::getId));
  135 + Map<Long, List<ProductPropertyValueRespVO>> valueDOMap = valueDOList.stream()
  136 + .map(ProductPropertyValueConvert.INSTANCE::convert)
  137 + .collect(Collectors.groupingBy(ProductPropertyValueRespVO::getPropertyId));
  138 + //组装
  139 + return propertyList.stream().map(m -> {
  140 + ProductPropertyAndValueRespVO productPropertyAndValueRespVO = BeanUtil.copyProperties(m, ProductPropertyAndValueRespVO.class);
  141 + productPropertyAndValueRespVO.setValues(valueDOMap.get(m.getId()));
  142 + return productPropertyAndValueRespVO;
  143 + }).collect(Collectors.toList());
150 } 144 }
151 } 145 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.service.property;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
  5 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO;
  6 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
  7 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO;
  8 +
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * <p>
  13 + *
  14 + * </p>
  15 + *
  16 + * @author LuoWenFeng
  17 + */
  18 +public interface ProductPropertyValueService {
  19 +
  20 + /**
  21 + * 创建规格值
  22 + *
  23 + * @param createReqVO 创建信息
  24 + * @return 编号
  25 + */
  26 + Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO);
  27 +
  28 + /**
  29 + * 更新规格值
  30 + *
  31 + * @param updateReqVO 更新信息
  32 + */
  33 + void updatePropertyValue(ProductPropertyValueUpdateReqVO updateReqVO);
  34 +
  35 + /**
  36 + * 删除规格值
  37 + *
  38 + * @param id 编号
  39 + */
  40 + void deletePropertyValue(Long id);
  41 +
  42 + /**
  43 + * 获得规格值
  44 + *
  45 + * @param id 编号
  46 + * @return 规格名称
  47 + */
  48 + ProductPropertyValueRespVO getPropertyValue(Long id);
  49 +
  50 + /**
  51 + * 获得规格值
  52 + *
  53 + * @param id 编号
  54 + * @return 规格名称
  55 + */
  56 + List<ProductPropertyValueRespVO> getPropertyValueListByPropertyId(List<Long> id);
  57 +
  58 + /**
  59 + * 获取规格值 分页
  60 + *
  61 + * @param pageReqVO 查询条件
  62 + * @return
  63 + */
  64 + PageResult<ProductPropertyValueRespVO> getPropertyValueListPage(ProductPropertyValuePageReqVO pageReqVO);
  65 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.service.property;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
  5 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO;
  6 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
  7 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO;
  8 +import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert;
  9 +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
  10 +import cn.iocoder.yudao.module.product.dal.mysql.property.ProductPropertyValueMapper;
  11 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  12 +import org.springframework.stereotype.Service;
  13 +import org.springframework.validation.annotation.Validated;
  14 +
  15 +import javax.annotation.Resource;
  16 +import java.util.List;
  17 +
  18 +/**
  19 + * <p>
  20 + *
  21 + * </p>
  22 + *
  23 + * @author LuoWenFeng
  24 + */
  25 +@Service
  26 +@Validated
  27 +public class ProductPropertyValueServiceImpl implements ProductPropertyValueService {
  28 +
  29 + @Resource
  30 + private ProductPropertyValueMapper productPropertyValueMapper;
  31 +
  32 + @Override
  33 + public Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO) {
  34 + ProductPropertyValueDO convert = ProductPropertyValueConvert.INSTANCE.convert(createReqVO);
  35 + productPropertyValueMapper.insert(convert);
  36 + return convert.getId();
  37 + }
  38 +
  39 + @Override
  40 + public void updatePropertyValue(ProductPropertyValueUpdateReqVO updateReqVO) {
  41 + ProductPropertyValueDO convert = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO);
  42 + productPropertyValueMapper.updateById(convert);
  43 + }
  44 +
  45 + @Override
  46 + public void deletePropertyValue(Long id) {
  47 + productPropertyValueMapper.deleteById(id);
  48 + }
  49 +
  50 + @Override
  51 + public ProductPropertyValueRespVO getPropertyValue(Long id) {
  52 + ProductPropertyValueDO productPropertyValueDO = productPropertyValueMapper.selectOne(new LambdaQueryWrapper<ProductPropertyValueDO>()
  53 + .eq(ProductPropertyValueDO::getId, id));
  54 + return ProductPropertyValueConvert.INSTANCE.convert(productPropertyValueDO);
  55 + }
  56 +
  57 + @Override
  58 + public List<ProductPropertyValueRespVO> getPropertyValueListByPropertyId(List<Long> id) {
  59 + return ProductPropertyValueConvert.INSTANCE.convertList(productPropertyValueMapper.selectList("property_id", id));
  60 + }
  61 +
  62 + @Override
  63 + public PageResult<ProductPropertyValueRespVO> getPropertyValueListPage(ProductPropertyValuePageReqVO pageReqVO) {
  64 + return ProductPropertyValueConvert.INSTANCE.convertPage(productPropertyValueMapper.selectPage(pageReqVO));
  65 + }
  66 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.product.service.sku; @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.product.service.sku;
3 import cn.hutool.core.collection.CollectionUtil; 3 import cn.hutool.core.collection.CollectionUtil;
4 import cn.hutool.core.util.ObjectUtil; 4 import cn.hutool.core.util.ObjectUtil;
5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyAndValueRespVO; 6 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
7 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; 7 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.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;
9 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; 9 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
@@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper; @@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper;
13 import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants; 13 import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants;
14 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; 14 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
15 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; 15 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
  16 +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
16 import org.springframework.stereotype.Service; 17 import org.springframework.stereotype.Service;
17 import org.springframework.transaction.annotation.Transactional; 18 import org.springframework.transaction.annotation.Transactional;
18 import org.springframework.validation.annotation.Validated; 19 import org.springframework.validation.annotation.Validated;
@@ -39,6 +40,9 @@ public class ProductSkuServiceImpl implements ProductSkuService { @@ -39,6 +40,9 @@ public class ProductSkuServiceImpl implements ProductSkuService {
39 @Resource 40 @Resource
40 private ProductPropertyService productPropertyService; 41 private ProductPropertyService productPropertyService;
41 42
  43 + @Resource
  44 + private ProductPropertyValueService productPropertyValueService;
  45 +
42 @Override 46 @Override
43 public void deleteSku(Long id) { 47 public void deleteSku(Long id) {
44 // 校验存在 48 // 校验存在
@@ -71,17 +75,15 @@ public class ProductSkuServiceImpl implements ProductSkuService { @@ -71,17 +75,15 @@ public class ProductSkuServiceImpl implements ProductSkuService {
71 } 75 }
72 76
73 // 1、校验规格属性存在 77 // 1、校验规格属性存在
74 - // TODO @Luowenfeng:stream 的写法;不用改哈,就是说下可以酱紫写;  
75 Set<Long> propertyIds = skus.stream().filter(p -> p.getProperties() != null).flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 78 Set<Long> propertyIds = skus.stream().filter(p -> p.getProperties() != null).flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性
76 .map(ProductSkuBaseVO.Property::getPropertyId).collect(Collectors.toSet()); // 将每个 Property 转换成对应的 propertyId,最后形成集合 79 .map(ProductSkuBaseVO.Property::getPropertyId).collect(Collectors.toSet()); // 将每个 Property 转换成对应的 propertyId,最后形成集合
77 - List<ProductPropertyAndValueRespVO> propertyAndValueList = productPropertyService.getPropertyAndValueList(propertyIds);  
78 - if (propertyAndValueList.size() == propertyIds.size()) { 80 + List<ProductPropertyRespVO> propertyList = productPropertyService.getPropertyList(propertyIds);
  81 + if (propertyList.size() != propertyIds.size()) {
79 throw exception(PROPERTY_NOT_EXISTS); 82 throw exception(PROPERTY_NOT_EXISTS);
80 } 83 }
81 84
82 // 2. 校验,一个 SKU 下,没有重复的规格。校验方式是,遍历每个 SKU ,看看是否有重复的规格 propertyId 85 // 2. 校验,一个 SKU 下,没有重复的规格。校验方式是,遍历每个 SKU ,看看是否有重复的规格 propertyId
83 - Map<Long, ProductPropertyValueRespVO> propertyValueMap = propertyAndValueList.stream().filter(p -> p.getValues() != null).flatMap(p -> p.getValues().stream())  
84 - .collect(Collectors.toMap(ProductPropertyValueRespVO::getId, value -> value)); // KEY:规格属性值的编号 86 + Map<Long, ProductPropertyValueRespVO> propertyValueMap = CollectionUtils.convertMap(productPropertyValueService.getPropertyValueListByPropertyId(new ArrayList<>(propertyIds)), ProductPropertyValueRespVO::getId);
85 skus.forEach(sku -> { 87 skus.forEach(sku -> {
86 Set<Long> skuPropertyIds = CollectionUtils.convertSet(sku.getProperties(), propertyItem -> propertyValueMap.get(propertyItem.getValueId()).getPropertyId()); 88 Set<Long> skuPropertyIds = CollectionUtils.convertSet(sku.getProperties(), propertyItem -> propertyValueMap.get(propertyItem.getValueId()).getPropertyId());
87 if (skuPropertyIds.size() != sku.getProperties().size()) { 89 if (skuPropertyIds.size() != sku.getProperties().size()) {
@@ -100,8 +102,7 @@ public class ProductSkuServiceImpl implements ProductSkuService { @@ -100,8 +102,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
100 // 4. 最后校验,每个 Sku 之间不是重复的 102 // 4. 最后校验,每个 Sku 之间不是重复的
101 Set<Set<Long>> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的. 103 Set<Set<Long>> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的.
102 for (ProductSkuCreateOrUpdateReqVO sku : skus) { 104 for (ProductSkuCreateOrUpdateReqVO sku : skus) {
103 - // TODO @Luowenfeng:可以使用 CollectionUtils.convertSet(),简化下面的 stream 操作  
104 - if (!skuAttrValues.add(sku.getProperties().stream().map(ProductSkuBaseVO.Property::getValueId).collect(Collectors.toSet()))) { // 添加失败,说明重复 105 + if (!skuAttrValues.add(CollectionUtils.convertSet(sku.getProperties(), ProductSkuBaseVO.Property::getValueId))) { // 添加失败,说明重复
105 throw exception(ErrorCodeConstants.SPU_SKU_NOT_DUPLICATE); 106 throw exception(ErrorCodeConstants.SPU_SKU_NOT_DUPLICATE);
106 } 107 }
107 } 108 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java
1 package cn.iocoder.yudao.module.product.service.spu; 1 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.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;  
5 -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO;  
6 -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO;  
7 -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; 4 +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
8 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO; 5 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
9 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO; 6 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
10 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; 7 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
@@ -43,6 +40,14 @@ public interface ProductSpuService { @@ -43,6 +40,14 @@ public interface ProductSpuService {
43 void deleteSpu(Long id); 40 void deleteSpu(Long id);
44 41
45 /** 42 /**
  43 + * 获得商品spu详情
  44 + *
  45 + * @param id 编号
  46 + * @return 商品spu
  47 + */
  48 + ProductSpuDetailRespVO getSpuDetail(Long id);
  49 +
  50 + /**
46 * 获得商品spu 51 * 获得商品spu
47 * 52 *
48 * @param id 编号 53 * @param id 编号
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
1 package cn.iocoder.yudao.module.product.service.spu; 1 package cn.iocoder.yudao.module.product.service.spu;
2 2
  3 +import cn.hutool.core.bean.BeanUtil;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyAndValueRespVO; 6 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
6 import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO; 7 import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO;
7 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; 8 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.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;
10 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; 11 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
11 -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;  
12 -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;  
13 -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO;  
14 -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; 12 +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
15 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO; 13 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
16 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO; 14 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
17 import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; 15 import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
@@ -22,6 +20,7 @@ import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; @@ -22,6 +20,7 @@ import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
22 import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; 20 import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
23 import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; 21 import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
24 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; 22 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
  23 +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
25 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; 24 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
26 import org.springframework.stereotype.Service; 25 import org.springframework.stereotype.Service;
27 import org.springframework.transaction.annotation.Transactional; 26 import org.springframework.transaction.annotation.Transactional;
@@ -56,6 +55,9 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -56,6 +55,9 @@ public class ProductSpuServiceImpl implements ProductSpuService {
56 private ProductPropertyService productPropertyService; 55 private ProductPropertyService productPropertyService;
57 56
58 @Resource 57 @Resource
  58 + private ProductPropertyValueService productPropertyValueService;
  59 +
  60 + @Resource
59 private ProductBrandService brandService; 61 private ProductBrandService brandService;
60 62
61 @Override 63 @Override
@@ -125,28 +127,31 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -125,28 +127,31 @@ public class ProductSpuServiceImpl implements ProductSpuService {
125 127
126 @Override 128 @Override
127 // TODO @芋艿:需要再 review 下 129 // TODO @芋艿:需要再 review 下
128 - public ProductSpuRespVO getSpu(Long id) { 130 + public ProductSpuDetailRespVO getSpuDetail(Long id) {
129 ProductSpuDO spu = ProductSpuMapper.selectById(id); 131 ProductSpuDO spu = ProductSpuMapper.selectById(id);
130 - ProductSpuRespVO spuVO = ProductSpuConvert.INSTANCE.convert(spu);  
131 - if (null != spuVO) {  
132 - List<ProductSkuRespVO> skuReqs = ProductSkuConvert.INSTANCE.convertList(productSkuService.getSkusBySpuId(id));  
133 - spuVO.setSkus(skuReqs);  
134 - List<ProductSkuRespVO.Property> properties = new ArrayList<>(); 132 + ProductSpuDetailRespVO respVO = BeanUtil.copyProperties(spu, ProductSpuDetailRespVO.class);
  133 + if (null != spu) {
  134 + List<ProductSpuDetailRespVO.Sku> skuReqs = ProductSkuConvert.INSTANCE.convertList03(productSkuService.getSkusBySpuId(id));
  135 + respVO.setSkus(skuReqs);
135 // 组合 sku 规格属性 136 // 组合 sku 规格属性
136 if(spu.getSpecType().equals(ProductSpuSpecTypeEnum.DISABLE.getType())) { 137 if(spu.getSpecType().equals(ProductSpuSpecTypeEnum.DISABLE.getType())) {
137 - for (ProductSkuRespVO productSkuRespVO : skuReqs) { 138 + List<ProductSkuRespVO.Property> properties = new ArrayList<>();
  139 + for (ProductSpuDetailRespVO.Sku productSkuRespVO : skuReqs) {
138 properties.addAll(productSkuRespVO.getProperties()); 140 properties.addAll(productSkuRespVO.getProperties());
139 } 141 }
140 Map<Long, List<ProductSkuBaseVO.Property>> propertyMaps = properties.stream().collect(Collectors.groupingBy(ProductSkuBaseVO.Property::getPropertyId)); 142 Map<Long, List<ProductSkuBaseVO.Property>> propertyMaps = properties.stream().collect(Collectors.groupingBy(ProductSkuBaseVO.Property::getPropertyId));
141 - List<ProductPropertyAndValueRespVO> propertyAndValueList = productPropertyService.getPropertyAndValueList(new ArrayList<>(propertyMaps.keySet())); 143 +
  144 + List<ProductPropertyValueRespVO> propertyValueList = productPropertyValueService.getPropertyValueListByPropertyId(new ArrayList<>(propertyMaps.keySet()));
  145 + List<ProductPropertyRespVO> propertyList = productPropertyService.getPropertyList(new ArrayList<>(propertyMaps.keySet()));
142 // 装载组装过后的属性 146 // 装载组装过后的属性
143 List<ProductPropertyViewRespVO> productPropertyViews = new ArrayList<>(); 147 List<ProductPropertyViewRespVO> productPropertyViews = new ArrayList<>();
144 - propertyAndValueList.forEach(p -> { 148 + propertyList.forEach(p -> {
145 ProductPropertyViewRespVO productPropertyViewRespVO = new ProductPropertyViewRespVO(); 149 ProductPropertyViewRespVO productPropertyViewRespVO = new ProductPropertyViewRespVO();
146 productPropertyViewRespVO.setPropertyId(p.getId()); 150 productPropertyViewRespVO.setPropertyId(p.getId());
147 productPropertyViewRespVO.setName(p.getName()); 151 productPropertyViewRespVO.setName(p.getName());
148 List<ProductPropertyViewRespVO.Tuple2> propertyValues = new ArrayList<>(); 152 List<ProductPropertyViewRespVO.Tuple2> propertyValues = new ArrayList<>();
149 - Map<Long, ProductPropertyValueRespVO> propertyValueMaps = p.getValues().stream().collect(Collectors.toMap(ProductPropertyValueRespVO::getId, pv -> pv)); 153 + // 转换成map是为了能快速获取
  154 + Map<Long, ProductPropertyValueRespVO> propertyValueMaps = CollectionUtils.convertMap(propertyValueList, ProductPropertyValueRespVO::getId);
150 propertyMaps.get(p.getId()).forEach(pv -> { 155 propertyMaps.get(p.getId()).forEach(pv -> {
151 ProductPropertyViewRespVO.Tuple2 tuple2 = new ProductPropertyViewRespVO.Tuple2(pv.getValueId(), propertyValueMaps.get(pv.getValueId()).getName()); 156 ProductPropertyViewRespVO.Tuple2 tuple2 = new ProductPropertyViewRespVO.Tuple2(pv.getValueId(), propertyValueMaps.get(pv.getValueId()).getName());
152 propertyValues.add(tuple2); 157 propertyValues.add(tuple2);
@@ -154,12 +159,12 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -154,12 +159,12 @@ public class ProductSpuServiceImpl implements ProductSpuService {
154 productPropertyViewRespVO.setPropertyValues(propertyValues.stream().distinct().collect(Collectors.toList())); 159 productPropertyViewRespVO.setPropertyValues(propertyValues.stream().distinct().collect(Collectors.toList()));
155 productPropertyViews.add(productPropertyViewRespVO); 160 productPropertyViews.add(productPropertyViewRespVO);
156 }); 161 });
157 - spuVO.setProductPropertyViews(productPropertyViews); 162 + respVO.setProductPropertyViews(productPropertyViews);
158 } 163 }
159 // 组合分类 164 // 组合分类
160 - if (null != spuVO.getCategoryId()) { 165 + if (null != respVO.getCategoryId()) {
161 LinkedList<Long> categoryArray = new LinkedList<>(); 166 LinkedList<Long> categoryArray = new LinkedList<>();
162 - Long parentId = spuVO.getCategoryId(); 167 + Long parentId = respVO.getCategoryId();
163 categoryArray.addFirst(parentId); 168 categoryArray.addFirst(parentId);
164 while (parentId != 0) { 169 while (parentId != 0) {
165 parentId = categoryService.getCategory(parentId).getParentId(); 170 parentId = categoryService.getCategory(parentId).getParentId();
@@ -167,10 +172,15 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -167,10 +172,15 @@ public class ProductSpuServiceImpl implements ProductSpuService {
167 categoryArray.addFirst(parentId); 172 categoryArray.addFirst(parentId);
168 } 173 }
169 } 174 }
170 - spuVO.setCategoryIds(categoryArray); 175 + respVO.setCategoryIds(categoryArray);
171 } 176 }
172 } 177 }
173 - return spuVO; 178 + return respVO;
  179 + }
  180 +
  181 + @Override
  182 + public ProductSpuRespVO getSpu(Long id) {
  183 + return ProductSpuConvert.INSTANCE.convert(ProductSpuMapper.selectById(id));
174 } 184 }
175 185
176 @Override 186 @Override
@@ -182,8 +192,8 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -182,8 +192,8 @@ public class ProductSpuServiceImpl implements ProductSpuService {
182 public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) { 192 public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) {
183 PageResult<ProductSpuRespVO> spuVOs = ProductSpuConvert.INSTANCE.convertPage(ProductSpuMapper.selectPage(pageReqVO)); 193 PageResult<ProductSpuRespVO> spuVOs = ProductSpuConvert.INSTANCE.convertPage(ProductSpuMapper.selectPage(pageReqVO));
184 // 查询 sku 的信息 194 // 查询 sku 的信息
185 - List<Long> spuIds = spuVOs.getList().stream().map(ProductSpuRespVO::getId).collect(Collectors.toList());  
186 - List<ProductSkuRespVO> skus = ProductSkuConvert.INSTANCE.convertList(productSkuService.getSkusBySpuIds(spuIds)); 195 +// List<Long> spuIds = spuVOs.getList().stream().map(ProductSpuRespVO::getId).collect(Collectors.toList());
  196 +// List<ProductSkuRespVO> skus = ProductSkuConvert.INSTANCE.convertList(productSkuService.getSkusBySpuIds(spuIds));
187 // TODO @franky:使用 CollUtil 里的方法替代哈 197 // TODO @franky:使用 CollUtil 里的方法替代哈
188 // TODO 芋艿:临时注释 198 // TODO 芋艿:临时注释
189 // Map<Long, List<ProductSkuRespVO>> skuMap = skus.stream().collect(Collectors.groupingBy(ProductSkuRespVO::getSpuId)); 199 // Map<Long, List<ProductSkuRespVO>> skuMap = skus.stream().collect(Collectors.groupingBy(ProductSkuRespVO::getSpuId));
yudao-ui-admin/src/api/mall/product/property.js
@@ -43,6 +43,25 @@ export function getPropertyPage(query) { @@ -43,6 +43,25 @@ export function getPropertyPage(query) {
43 }) 43 })
44 } 44 }
45 45
  46 +// 获得规格名称列表
  47 +export function getPropertyList(query) {
  48 + return request({
  49 + url: '/product/property/list',
  50 + method: 'get',
  51 + params: query
  52 + })
  53 +}
  54 +
  55 +// 获得规格名称列表
  56 +export function getPropertyListAndValue(query) {
  57 + return request({
  58 + url: '/product/property/listAndValue',
  59 + method: 'get',
  60 + params: query
  61 + })
  62 +}
  63 +
  64 +
46 // 导出规格名称 Excel 65 // 导出规格名称 Excel
47 export function exportPropertyExcel(query) { 66 export function exportPropertyExcel(query) {
48 return request({ 67 return request({
@@ -52,3 +71,49 @@ export function exportPropertyExcel(query) { @@ -52,3 +71,49 @@ export function exportPropertyExcel(query) {
52 responseType: 'blob' 71 responseType: 'blob'
53 }) 72 })
54 } 73 }
  74 +
  75 +// ------------------------ 规格名称值 -------------------
  76 +
  77 +// 获得规格名称值分页
  78 +export function getPropertyValuePage(query) {
  79 + return request({
  80 + url: '/product/property/value/page',
  81 + method: 'get',
  82 + params: query
  83 + })
  84 +}
  85 +
  86 +// 获得规格名称值
  87 +export function getPropertyValue(id) {
  88 + return request({
  89 + url: '/product/property/value/get?id=' + id,
  90 + method: 'get'
  91 + })
  92 +}
  93 +
  94 +
  95 +// 创建规格名称值
  96 +export function createPropertyValue(data) {
  97 + return request({
  98 + url: '/product/property/value/create',
  99 + method: 'post',
  100 + data: data
  101 + })
  102 +}
  103 +
  104 +// 更新规格名称值
  105 +export function updatePropertyValue(data) {
  106 + return request({
  107 + url: '/product/property/value/update',
  108 + method: 'put',
  109 + data: data
  110 + })
  111 +}
  112 +
  113 +// 删除规格名称
  114 +export function deletePropertyValue(id) {
  115 + return request({
  116 + url: '/product/property/value/delete?id=' + id,
  117 + method: 'delete'
  118 + })
  119 +}
yudao-ui-admin/src/api/mall/product/spu.js
@@ -34,6 +34,14 @@ export function getSpu(id) { @@ -34,6 +34,14 @@ export function getSpu(id) {
34 }) 34 })
35 } 35 }
36 36
  37 +// 获得商品spu详情
  38 +export function getSpuDetail(id) {
  39 + return request({
  40 + url: '/product/spu/get/detail?id=' + id,
  41 + method: 'get'
  42 + })
  43 +}
  44 +
37 // 获得商品spu分页 45 // 获得商品spu分页
38 export function getSpuPage(query) { 46 export function getSpuPage(query) {
39 return request({ 47 return request({
yudao-ui-admin/src/router/index.js
@@ -97,6 +97,17 @@ export const constantRoutes = [ @@ -97,6 +97,17 @@ export const constantRoutes = [
97 } 97 }
98 ] 98 ]
99 }, { 99 }, {
  100 + path: '/property',
  101 + component: Layout,
  102 + hidden: true,
  103 + children: [{
  104 + path: 'value/:propertyId(\\d+)',
  105 + component: (resolve) => require(['@/views/mall/product/property/value'], resolve),
  106 + name: 'PropertyValue',
  107 + meta: {title: '规格数据', icon: '', activeMenu: '/mall/property'}
  108 + }
  109 + ]
  110 + }, {
100 path: '/job', 111 path: '/job',
101 component: Layout, 112 component: Layout,
102 hidden: true, 113 hidden: true,
yudao-ui-admin/src/views/mall/product/property/index.vue
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <el-form-item label="规格名称" prop="name"> 6 <el-form-item label="规格名称" prop="name">
7 <el-input v-model="queryParams.name" placeholder="请输入规格名称" clearable @keyup.enter.native="handleQuery"/> 7 <el-input v-model="queryParams.name" placeholder="请输入规格名称" clearable @keyup.enter.native="handleQuery"/>
8 </el-form-item> 8 </el-form-item>
9 - <el-form-item label="开启状态" prop="status"> 9 + <el-form-item label="状态" prop="status">
10 <el-select v-model="queryParams.status" placeholder="请选择开启状态" clearable size="small"> 10 <el-select v-model="queryParams.status" placeholder="请选择开启状态" clearable size="small">
11 <el-option v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)" 11 <el-option v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
12 :key="dict.value" :label="dict.label" :value="dict.value"/> 12 :key="dict.value" :label="dict.label" :value="dict.value"/>
@@ -33,12 +33,14 @@ @@ -33,12 +33,14 @@
33 33
34 <!-- 列表 --> 34 <!-- 列表 -->
35 <el-table v-loading="loading" :data="list"> 35 <el-table v-loading="loading" :data="list">
36 - <el-table-column label="规格名称" align="center" prop="name" />  
37 - <el-table-column label="规格名称" align="center" prop="propertyValueList"> 36 + <el-table-column label="规格id" align="center" prop="id" />
  37 + <el-table-column label="规格名称" align="center" :show-overflow-tooltip="true">
38 <template slot-scope="scope"> 38 <template slot-scope="scope">
39 - <span>{{formatList(scope.row.propertyValueList)}}</span> 39 + <router-link :to="'/property/value/' + scope.row.id" class="link-type">
  40 + <span>{{ scope.row.name }}</span>
  41 + </router-link>
40 </template> 42 </template>
41 - </el-table-column> 43 + </el-table-column>
42 <el-table-column label="开启状态" align="center" prop="status"> 44 <el-table-column label="开启状态" align="center" prop="status">
43 <template slot-scope="scope"> 45 <template slot-scope="scope">
44 <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> 46 <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/>
@@ -49,6 +51,7 @@ @@ -49,6 +51,7 @@
49 <span>{{ parseTime(scope.row.createTime) }}</span> 51 <span>{{ parseTime(scope.row.createTime) }}</span>
50 </template> 52 </template>
51 </el-table-column> 53 </el-table-column>
  54 + <el-table-column label="备注" align="center" prop="left" />
52 <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> 55 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
53 <template slot-scope="scope"> 56 <template slot-scope="scope">
54 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" 57 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
@@ -65,6 +68,9 @@ @@ -65,6 +68,9 @@
65 <!-- 对话框(添加 / 修改) --> 68 <!-- 对话框(添加 / 修改) -->
66 <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> 69 <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
67 <el-form ref="form" :model="form" :rules="rules" label-width="80px"> 70 <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  71 + <el-form-item label="规格id" prop="id" v-if="form.id != null">
  72 + <el-input v-model="form.id" disabled />
  73 + </el-form-item>
68 <el-form-item label="规格名称" prop="name"> 74 <el-form-item label="规格名称" prop="name">
69 <el-input v-model="form.name" placeholder="请输入规格名称" /> 75 <el-input v-model="form.name" placeholder="请输入规格名称" />
70 </el-form-item> 76 </el-form-item>
@@ -75,26 +81,9 @@ @@ -75,26 +81,9 @@
75 </el-radio> 81 </el-radio>
76 </el-radio-group> 82 </el-radio-group>
77 </el-form-item> 83 </el-form-item>
78 - <el-form-item label="属性值">  
79 - <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="addPropertyValue()">添加</el-button> 84 + <el-form-item label="备注" prop="remark">
  85 + <el-input v-model="form.remark" placeholder="备注" />
80 </el-form-item> 86 </el-form-item>
81 - <el-form-item  
82 - v-for="(domain, index) in form.propertyValueList"  
83 - :key="domain.key"  
84 - :prop="'propertyValueList.' + index + '.name'"  
85 - :rules="{  
86 - required: true, message: '属性值不能为空', trigger: 'blur'  
87 - }"  
88 - >  
89 - <el-row>  
90 - <el-col :span="18">  
91 - <el-input v-model="domain.name" size="mini"></el-input>  
92 - </el-col>  
93 - <el-col :span="6">  
94 - <el-button style="margin-left: 20px;" size="mini" @click.prevent="removePropertyValue(domain)">删除</el-button>  
95 - </el-col>  
96 - </el-row>  
97 - </el-form-item>  
98 </el-form> 87 </el-form>
99 <div slot="footer" class="dialog-footer"> 88 <div slot="footer" class="dialog-footer">
100 <el-button type="primary" @click="submitForm">确 定</el-button> 89 <el-button type="primary" @click="submitForm">确 定</el-button>
@@ -139,12 +128,17 @@ export default { @@ -139,12 +128,17 @@ export default {
139 form: { 128 form: {
140 name:'', 129 name:'',
141 status:'', 130 status:'',
142 - propertyValueList: [{  
143 - name: ''  
144 - }], 131 + remark:"",
  132 + id: null,
145 }, 133 },
146 // 表单校验 134 // 表单校验
147 rules: { 135 rules: {
  136 + name: [
  137 + { required: true, message: "规格不能为空", trigger: "blur" }
  138 + ],
  139 + status: [
  140 + { required: true, message: "状态不能为空", trigger: "blur" }
  141 + ]
148 } 142 }
149 }; 143 };
150 }, 144 },
@@ -170,12 +164,10 @@ export default { @@ -170,12 +164,10 @@ export default {
170 /** 表单重置 */ 164 /** 表单重置 */
171 reset() { 165 reset() {
172 this.form = { 166 this.form = {
173 - id: undefined,  
174 - name: undefined,  
175 - status: undefined,  
176 - propertyValueList: [{  
177 - name: ''  
178 - }] 167 + name:'',
  168 + status:'',
  169 + remark:"",
  170 + id: null,
179 }; 171 };
180 this.resetForm("form"); 172 this.resetForm("form");
181 }, 173 },
@@ -253,27 +245,6 @@ export default { @@ -253,27 +245,6 @@ export default {
253 this.exportLoading = false; 245 this.exportLoading = false;
254 }).catch(() => {}); 246 }).catch(() => {});
255 }, 247 },
256 - removePropertyValue(item) {  
257 - var index = this.form.propertyValueList.indexOf(item)  
258 - if (index !== -1) {  
259 - this.form.propertyValueList.splice(index, 1)  
260 - }  
261 - },  
262 - addPropertyValue() {  
263 - this.form.propertyValueList.push({  
264 - name: ''  
265 - });  
266 - },  
267 - formatList(list) {  
268 - let str = ''  
269 - for (var i = 0; i < list.length; i++) {  
270 - str += list[i].name;  
271 - if(i != list.length-1){  
272 - str+="/";  
273 - }  
274 - }  
275 - return str  
276 - }  
277 } 248 }
278 }; 249 };
279 </script> 250 </script>
yudao-ui-admin/src/views/mall/product/spu/index.vue
@@ -9,20 +9,22 @@ @@ -9,20 +9,22 @@
9 <el-form-item label="商品名称" prop="name"> 9 <el-form-item label="商品名称" prop="name">
10 <el-input v-model="queryParams.name" placeholder="请输入商品名称" clearable @keyup.enter.native="handleQuery"/> 10 <el-input v-model="queryParams.name" placeholder="请输入商品名称" clearable @keyup.enter.native="handleQuery"/>
11 </el-form-item> 11 </el-form-item>
12 - <el-form-item label="分类id" prop="categoryId">  
13 - <el-input v-model="queryParams.categoryId" placeholder="请输入分类id" clearable @keyup.enter.native="handleQuery"/> 12 +
  13 + <el-form-item label="商品编码" prop="code">
  14 + <el-input v-model="queryParams.code" placeholder="请输入商品名称" clearable @keyup.enter.native="handleQuery"/>
14 </el-form-item> 15 </el-form-item>
15 - <el-form-item label="状态" prop="status">  
16 - <el-select v-model="queryParams.status" placeholder="请选择上下架状态" clearable size="small">  
17 - <el-option label="请选择字典生成" value="" />  
18 - <el-option label="上架" value="0" />  
19 - <el-option label="下架" value="1" />  
20 - </el-select> 16 +
  17 + <el-form-item label="商品分类" prop="categoryId">
  18 + <el-cascader v-model="queryParams.categoryIds" placeholder="请输入商品分类"
  19 + :options="categoryList" :props="propName" clearable ref="category" />
21 </el-form-item> 20 </el-form-item>
22 - <el-form-item label="创建时间">  
23 - <el-date-picker v-model="dateRangeCreateTime" style="width: 240px" value-format="yyyy-MM-dd" type="daterange"  
24 - range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"/> 21 +
  22 + <el-form-item label="商品品牌" prop="brandId">
  23 + <el-select v-model="queryParams.brandId" placeholder="请输入商品品牌" clearable @keyup.enter.native="handleQuery">
  24 + <el-option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id" />
  25 + </el-select>
25 </el-form-item> 26 </el-form-item>
  27 +
26 <el-form-item> 28 <el-form-item>
27 <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> 29 <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
28 <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button> 30 <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
@@ -46,33 +48,35 @@ @@ -46,33 +48,35 @@
46 1. 字段:商品信息、价格、库存、销量、排序、创建时间、状态、操作; 48 1. 字段:商品信息、价格、库存、销量、排序、创建时间、状态、操作;
47 2. tab 分成全部、销售中、仓库中、预警中 49 2. tab 分成全部、销售中、仓库中、预警中
48 --> 50 -->
49 - <el-table-column label="主键" align="center" prop="id" />  
50 - <el-table-column label="商品名称" align="center" prop="name" />  
51 - <el-table-column label="分类id" align="center" prop="categoryId" />  
52 - <el-table-column label="商品主图地址" align="center" prop="picUrls">  
53 - <template slot-scope="scope">  
54 - <img  
55 - v-if="scope.row.picUrls"  
56 - :src="scope.row.picUrls[0]"  
57 - alt="分类图片"  
58 - class="img-height"  
59 - /> 51 + <el-table-column label="商品信息" align="center" width="260">
  52 +
  53 + <template slot-scope="scope" >
  54 + <div class="product-info">
  55 + <img
  56 + v-if="scope.row.picUrls"
  57 + :src="scope.row.picUrls[0]"
  58 + alt="分类图片"
  59 + class="img-height"
  60 + />
  61 + <div class="message">{{scope.row.name}}</div>
  62 + </div>
60 </template> 63 </template>
61 </el-table-column> 64 </el-table-column>
62 - <el-table-column label="排序字段" align="center" prop="sort" />  
63 - <el-table-column label="点击量" align="center" prop="clickCount" />  
64 - <el-table-column label="价格区间" align="center" prop="price" />  
65 - <el-table-column label="总库存" align="center" prop="totalStock" />  
66 - <el-table-column label="状态" align="center" prop="status"> 65 + <el-table-column label="价格" align="center" prop="marketPrice" :formatter="unitConversion"/>
  66 + <el-table-column label="库存" align="center" prop="totalStock" />
  67 + <el-table-column label="销量" align="center" prop="salesCount" />
  68 + <el-table-column label="排序" align="center" prop="sort" />
  69 + <el-table-column label="创建时间" align="center" prop="createTime" width="180">
67 <template slot-scope="scope"> 70 <template slot-scope="scope">
68 - <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> 71 + <span>{{ parseTime(scope.row.createTime) }}</span>
69 </template> 72 </template>
70 </el-table-column> 73 </el-table-column>
71 - <el-table-column label="创建时间" align="center" prop="createTime" width="180"> 74 + <el-table-column label="状态" align="center" prop="status">
72 <template slot-scope="scope"> 75 <template slot-scope="scope">
73 - <span>{{ parseTime(scope.row.createTime) }}</span> 76 + <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/>
74 </template> 77 </template>
75 </el-table-column> 78 </el-table-column>
  79 +
76 <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> 80 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
77 <template slot-scope="scope"> 81 <template slot-scope="scope">
78 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" 82 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
@@ -87,7 +91,7 @@ @@ -87,7 +91,7 @@
87 @pagination="getList"/> 91 @pagination="getList"/>
88 92
89 <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body destroy-on-close :close-on-click-modal="false" > 93 <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body destroy-on-close :close-on-click-modal="false" >
90 - <save @closeDialog="closeDialog" :type="dialogType" :obj="dialogObj" v-if="open" /> 94 + <save @closeDialog="closeDialog" :obj="dialogObj" v-if="open" />
91 </el-dialog> 95 </el-dialog>
92 </div> 96 </div>
93 </template> 97 </template>
@@ -97,7 +101,8 @@ import { @@ -97,7 +101,8 @@ import {
97 deleteSpu, 101 deleteSpu,
98 getSpuPage, 102 getSpuPage,
99 } from "@/api/mall/product/spu"; 103 } from "@/api/mall/product/spu";
100 - 104 +import {getProductCategoryList} from "@/api/mall/product/category";
  105 +import {getBrandList} from "@/api/mall/product/brand";
101 import Editor from "@/components/Editor"; 106 import Editor from "@/components/Editor";
102 import ImageUpload from "@/components/ImageUpload"; 107 import ImageUpload from "@/components/ImageUpload";
103 import save from "./save"; 108 import save from "./save";
@@ -114,20 +119,12 @@ export default { @@ -114,20 +119,12 @@ export default {
114 }, 119 },
115 data() { 120 data() {
116 return { 121 return {
117 - tableLeftTitles: [],  
118 - dbTagValues: [],  
119 - allhistoryTags: [],  
120 - unUseTags: [],  
121 - propertyPageList: [],  
122 - isShowTagInput: false,  
123 - addTagInput: {  
124 - name: "",  
125 - propertyId: "",  
126 - selectValues: [],  
127 - selectValueIds: [],  
128 - selectObect: [], 122 + propName: {
  123 + checkStrictly: true,
  124 + label: "name",
  125 + value: "id",
129 }, 126 },
130 - skuTags: [], 127 + brandList: [],
131 categoryList: [], 128 categoryList: [],
132 // 遮罩层 129 // 遮罩层
133 loading: true, 130 loading: true,
@@ -143,8 +140,6 @@ export default { @@ -143,8 +140,6 @@ export default {
143 title: "", 140 title: "",
144 // 是否显示弹出层 141 // 是否显示弹出层
145 open: false, 142 open: false,
146 - // 弹出层类型  
147 - dialogType: "add",  
148 // 弹出层参数 143 // 弹出层参数
149 dialogObj:{}, 144 dialogObj:{},
150 dateRangeCreateTime: [], 145 dateRangeCreateTime: [],
@@ -153,14 +148,10 @@ export default { @@ -153,14 +148,10 @@ export default {
153 pageNo: 1, 148 pageNo: 1,
154 pageSize: 10, 149 pageSize: 10,
155 name: null, 150 name: null,
156 - sellPoint: null,  
157 - description: null, 151 + code: null,
  152 + categoryIds: [],
158 categoryId: null, 153 categoryId: null,
159 - picUrls: null,  
160 - sort: null,  
161 - likeCount: null,  
162 - price: null,  
163 - quantity: null, 154 + brandId: null,
164 status: null, 155 status: null,
165 }, 156 },
166 tagIndex: 0, 157 tagIndex: 0,
@@ -168,13 +159,30 @@ export default { @@ -168,13 +159,30 @@ export default {
168 }, 159 },
169 created() { 160 created() {
170 this.getList(); 161 this.getList();
  162 + this.getListCategory()
  163 + this.getListBrand()
171 }, 164 },
172 methods: { 165 methods: {
  166 + /** 查询分类列表 */
  167 + getListCategory() {
  168 + // 执行查询
  169 + getProductCategoryList().then((response) => {
  170 + this.categoryList = this.handleTree(response.data, "id", "parentId");
  171 + });
  172 + },
  173 + /** 查询品牌列表 */
  174 + getListBrand() {
  175 + // 执行查询
  176 + getBrandList().then((response) => {
  177 + this.brandList = response.data;
  178 + });
  179 + },
173 /** 查询列表 */ 180 /** 查询列表 */
174 getList() { 181 getList() {
175 this.loading = true; 182 this.loading = true;
176 // 处理查询参数 183 // 处理查询参数
177 let params = { ...this.queryParams }; 184 let params = { ...this.queryParams };
  185 + params.categoryId = this.queryParams.categoryIds[ this.queryParams.categoryIds.length - 1];
178 this.addBeginAndEndTime(params, this.dateRangeCreateTime, "createTime"); 186 this.addBeginAndEndTime(params, this.dateRangeCreateTime, "createTime");
179 // 执行查询 187 // 执行查询
180 getSpuPage(params).then((response) => { 188 getSpuPage(params).then((response) => {
@@ -200,27 +208,26 @@ export default { @@ -200,27 +208,26 @@ export default {
200 /** 重置按钮操作 */ 208 /** 重置按钮操作 */
201 resetQuery() { 209 resetQuery() {
202 this.dateRangeCreateTime = []; 210 this.dateRangeCreateTime = [];
  211 + this.$refs.category.$refs.panel.checkedValue = [];//也可以是指定的值,默认返回值是数组,也可以返回单个值
  212 +   this.$refs.category.$refs.panel.activePath = [];
  213 +   this.$refs.category.$refs.panel.syncActivePath();
  214 + this.queryParams.categoryIds = [];
203 this.resetForm("queryForm"); 215 this.resetForm("queryForm");
204 this.handleQuery(); 216 this.handleQuery();
205 }, 217 },
206 /** 新增按钮操作 */ 218 /** 新增按钮操作 */
207 handleAdd() { 219 handleAdd() {
208 - this.dialogType = "add";  
209 this.dialogObj={}; 220 this.dialogObj={};
210 this.open = true; 221 this.open = true;
211 this.title = "添加商品spu"; 222 this.title = "添加商品spu";
212 }, 223 },
213 /** 修改按钮操作 */ 224 /** 修改按钮操作 */
214 handleUpdate(row) { 225 handleUpdate(row) {
215 - this.dialogType = "upd";  
216 this.dialogObj.id = row.id; 226 this.dialogObj.id = row.id;
217 this.open = true; 227 this.open = true;
218 - console.log("修改")  
219 this.title = "修改商品spu"; 228 this.title = "修改商品spu";
220 }, 229 },
221 closeDialog(){ 230 closeDialog(){
222 - console.log("关闭")  
223 - this.dialogType = "add";  
224 this.dialogObj={}; 231 this.dialogObj={};
225 this.open = false; 232 this.open = false;
226 this.getList() 233 this.getList()
@@ -238,6 +245,9 @@ export default { @@ -238,6 +245,9 @@ export default {
238 this.$modal.msgSuccess("删除成功"); 245 this.$modal.msgSuccess("删除成功");
239 }) 246 })
240 .catch(() => {}); 247 .catch(() => {});
  248 + },
  249 + unitConversion(row, column, cellValue){
  250 + return this.divide(cellValue, 100);
241 } 251 }
242 }, 252 },
243 }; 253 };
@@ -262,8 +272,25 @@ export default { @@ -262,8 +272,25 @@ export default {
262 vertical-align: bottom; 272 vertical-align: bottom;
263 } 273 }
264 274
265 - .img-height {  
266 - height: 65px; 275 + .product-info{
  276 + display: flex;
  277 + .img-height {
  278 + height: 50px;
  279 + width: 50px;
  280 + }
  281 + .message{
  282 + margin-left: 10px;
  283 + text-overflow: ellipsis;
  284 + display: -webkit-box;
  285 + -webkit-line-clamp: 2;
  286 + word-break: break-all;
  287 + -webkit-box-orient: vertical;
  288 + white-space: normal;
  289 + overflow: hidden;
  290 + height: 50px;
  291 + line-height: 25px;
  292 + }
267 } 293 }
  294 +
268 } 295 }
269 </style> 296 </style>
yudao-ui-admin/src/views/mall/product/spu/save.vue
1 <template> 1 <template>
2 <div class="container"> 2 <div class="container">
3 - <el-tabs v-model="activeName" class="tabs" :before-leave="confirmLeave"> 3 + <el-tabs v-model="activeName" class="tabs" >
4 <!-- 基础设置 --> 4 <!-- 基础设置 -->
5 <el-tab-pane label="基础设置" name="base"> 5 <el-tab-pane label="基础设置" name="base">
6 <el-form ref="base" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%"> 6 <el-form ref="base" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%">
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 </el-form-item> 12 </el-form-item>
13 <!-- TODO @Luowenfeng:商品主图,80 x 80 即可 --> 13 <!-- TODO @Luowenfeng:商品主图,80 x 80 即可 -->
14 <el-form-item label="商品主图" prop="picUrls"> 14 <el-form-item label="商品主图" prop="picUrls">
15 - <ImageUpload v-model="baseForm.picUrls" :value="baseForm.picUrls" :limit="10"/> 15 + <ImageUpload v-model="baseForm.picUrls" :value="baseForm.picUrls" :limit="10" />
16 </el-form-item> 16 </el-form-item>
17 <!-- TODO @Luowenfeng:商品视频 --> 17 <!-- TODO @Luowenfeng:商品视频 -->
18 <el-form-item label="商品品牌" prop="brandId"> 18 <el-form-item label="商品品牌" prop="brandId">
@@ -38,10 +38,7 @@ @@ -38,10 +38,7 @@
38 <el-form ref="rates" :model="ratesForm" :rules="rules"> 38 <el-form ref="rates" :model="ratesForm" :rules="rules">
39 <el-form-item label="启用多规格"> 39 <el-form-item label="启用多规格">
40 <!-- TODO @Luowenfeng:改成开关的按钮;关闭,单规格;开启,多规格 --> 40 <!-- TODO @Luowenfeng:改成开关的按钮;关闭,单规格;开启,多规格 -->
41 - <el-radio-group v-model="ratesForm.spec" @change="changeRadio">  
42 - <el-radio :label="1">单规格</el-radio>  
43 - <el-radio :label="2">多规格</el-radio>  
44 - </el-radio-group> 41 + <el-switch v-model="activeSwitch" @change="changeRadio"></el-switch>
45 </el-form-item> 42 </el-form-item>
46 43
47 <!-- 动态添加规格属性 --> 44 <!-- 动态添加规格属性 -->
@@ -67,7 +64,7 @@ @@ -67,7 +64,7 @@
67 <!-- 规格明细 --> 64 <!-- 规格明细 -->
68 <el-form-item label="规格明细"> 65 <el-form-item label="规格明细">
69 <el-table :data="ratesForm.rates" border style="width: 100%" ref="ratesTable"> 66 <el-table :data="ratesForm.rates" border style="width: 100%" ref="ratesTable">
70 - <template v-if="ratesForm.spec == 2"> 67 + <template v-if="this.activeSwitch">
71 <el-table-column :key="index" v-for="(item, index) in dynamicSpec.filter(v => v.specName !== undefined)" 68 <el-table-column :key="index" v-for="(item, index) in dynamicSpec.filter(v => v.specName !== undefined)"
72 :label="item.specName"> 69 :label="item.specName">
73 <template slot-scope="scope"> 70 <template slot-scope="scope">
@@ -81,7 +78,7 @@ @@ -81,7 +78,7 @@
81 style="width: 100px; height: 50px"/> 78 style="width: 100px; height: 50px"/>
82 </template> 79 </template>
83 </el-table-column> 80 </el-table-column>
84 - <template v-if="ratesForm.spec === 2"> 81 + <template v-if="this.activeSwitch">
85 <el-table-column label="sku名称" :render-header="addRedStar" key="91"> 82 <el-table-column label="sku名称" :render-header="addRedStar" key="91">
86 <template slot-scope="scope"> 83 <template slot-scope="scope">
87 <el-form-item :prop="'rates.'+ scope.$index + '.name'" :rules="[{required: true, trigger: 'change'}]"> 84 <el-form-item :prop="'rates.'+ scope.$index + '.name'" :rules="[{required: true, trigger: 'change'}]">
@@ -142,7 +139,7 @@ @@ -142,7 +139,7 @@
142 <el-input v-model="scope.row.barCode"></el-input> 139 <el-input v-model="scope.row.barCode"></el-input>
143 </template> 140 </template>
144 </el-table-column> 141 </el-table-column>
145 - <template v-if="ratesForm.spec === 2"> 142 + <template v-if="this.activeSwitch">
146 <el-table-column fixed="right" label="操作" width="50" key="100"> 143 <el-table-column fixed="right" label="操作" width="50" key="100">
147 <template slot-scope="scope"> 144 <template slot-scope="scope">
148 <el-button @click="scope.row.status = 1" type="text" size="small" v-show="scope.row.status == undefined || scope.row.status == 0 ">禁用</el-button> 145 <el-button @click="scope.row.status = 1" type="text" size="small" v-show="scope.row.status == undefined || scope.row.status == 0 ">禁用</el-button>
@@ -153,7 +150,6 @@ @@ -153,7 +150,6 @@
153 </el-table> 150 </el-table>
154 </el-form-item> 151 </el-form-item>
155 <el-form-item label="虚拟销量" prop="virtualSalesCount"> 152 <el-form-item label="虚拟销量" prop="virtualSalesCount">
156 - <!-- TODO @Luowenfeng:使用 input 类型即可 -->  
157 <el-input v-model="baseForm.virtualSalesCount" placeholder="请输入虚拟销量" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/> 153 <el-input v-model="baseForm.virtualSalesCount" placeholder="请输入虚拟销量" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/>
158 </el-form-item> 154 </el-form-item>
159 </el-form> 155 </el-form>
@@ -196,8 +192,8 @@ @@ -196,8 +192,8 @@
196 192
197 import {getBrandList} from "@/api/mall/product/brand"; 193 import {getBrandList} from "@/api/mall/product/brand";
198 import {getProductCategoryList} from "@/api/mall/product/category"; 194 import {getProductCategoryList} from "@/api/mall/product/category";
199 -import {createSpu, updateSpu, getSpu} from "@/api/mall/product/spu";  
200 -import {getPropertyPage,} from "@/api/mall/product/property"; 195 +import {createSpu, updateSpu, getSpuDetail} from "@/api/mall/product/spu";
  196 +import {getPropertyListAndValue,} from "@/api/mall/product/property";
201 import Editor from "@/components/Editor"; 197 import Editor from "@/components/Editor";
202 import ImageUpload from "@/components/ImageUpload"; 198 import ImageUpload from "@/components/ImageUpload";
203 199
@@ -206,16 +202,13 @@ export default { @@ -206,16 +202,13 @@ export default {
206 Editor, 202 Editor,
207 ImageUpload 203 ImageUpload
208 }, 204 },
209 - props:{//props列表  
210 - type:{  
211 - type:String,  
212 - default:"add" //定义参数默认值  
213 - }, 205 + props:{
214 obj: Object 206 obj: Object
215 }, 207 },
216 data() { 208 data() {
217 return { 209 return {
218 - activeName: "base", // TODO @Luowenfeng:切换时,不需要校验通过 210 + activeSwitch: false,
  211 + activeName: "base",
219 propName: { 212 propName: {
220 checkStrictly: true, 213 checkStrictly: true,
221 label: "name", 214 label: "name",
@@ -271,7 +264,7 @@ export default { @@ -271,7 +264,7 @@ export default {
271 this.getListBrand(); 264 this.getListBrand();
272 this.getListCategory(); 265 this.getListCategory();
273 this.getPropertyPageList(); 266 this.getPropertyPageList();
274 - if(this.type == 'upd'){ 267 + if(this.obj.id != null){
275 this.updateType(this.obj.id) 268 this.updateType(this.obj.id)
276 } 269 }
277 }, 270 },
@@ -280,14 +273,6 @@ export default { @@ -280,14 +273,6 @@ export default {
280 this.dynamicSpec.splice(index, 1); 273 this.dynamicSpec.splice(index, 1);
281 this.changeRadio() 274 this.changeRadio()
282 }, 275 },
283 - async confirmLeave(active, old){  
284 - await this.$refs[old].validate((valid) => {  
285 - console.log(valid)  
286 - if (!valid) {  
287 - return reject();  
288 - }  
289 - });  
290 - },  
291 // 必选标识 276 // 必选标识
292 addRedStar(h, { column }) { 277 addRedStar(h, { column }) {
293 return [ 278 return [
@@ -296,13 +281,13 @@ export default { @@ -296,13 +281,13 @@ export default {
296 ]; 281 ];
297 }, 282 },
298 changeRadio() { 283 changeRadio() {
  284 + this.activeSwitch ? this.ratesForm.spec = 2: this.ratesForm.spec = 1;
299 this.$refs.ratesTable.doLayout(); 285 this.$refs.ratesTable.doLayout();
300 if (this.ratesForm.spec == 1) { 286 if (this.ratesForm.spec == 1) {
301 this.ratesForm.rates = [{}] 287 this.ratesForm.rates = [{}]
302 } else { 288 } else {
303 this.ratesForm.rates = [] 289 this.ratesForm.rates = []
304 if (this.dynamicSpec.length > 0) { 290 if (this.dynamicSpec.length > 0) {
305 - console.log( this.dynamicSpec)  
306 this.buildRatesFormRates() 291 this.buildRatesFormRates()
307 } 292 }
308 } 293 }
@@ -316,6 +301,7 @@ export default { @@ -316,6 +301,7 @@ export default {
316 last.forEach(par1 => { 301 last.forEach(par1 => {
317 current.forEach(par2 => { 302 current.forEach(par2 => {
318 let v 303 let v
  304 + // 当两个对象合并时,需使用[1,2]方式生成数组,而当数组和对象合并时,需使用concat
319 if (par1 instanceof Array) { 305 if (par1 instanceof Array) {
320 v = par1.concat(par2) 306 v = par1.concat(par2)
321 } else { 307 } else {
@@ -327,7 +313,12 @@ export default { @@ -327,7 +313,12 @@ export default {
327 return array; 313 return array;
328 }) 314 })
329 .forEach(v => { 315 .forEach(v => {
330 - rates.push({spec: v, status: 0, name: Array.of(v).join()}) 316 + let spec = v;
  317 + // 当v为单个规格项时,会变成字符串。造成表格只截取第一个字符串,而不是数组的第一个元素
  318 + if (typeof v == 'string') {
  319 + spec = Array.of(v)
  320 + }
  321 + rates.push({spec: spec, status: 0, name: Array.of(v).join()})
331 }); 322 });
332 this.ratesForm.rates = rates 323 this.ratesForm.rates = rates
333 }, 324 },
@@ -363,7 +354,7 @@ export default { @@ -363,7 +354,7 @@ export default {
363 }) 354 })
364 355
365 // 动态规格调整字段 356 // 动态规格调整字段
366 - if (this.ratesForm.spec == 2) { 357 + if (this.activeSwitch) {
367 rates.forEach(r => { 358 rates.forEach(r => {
368 let properties = [] 359 let properties = []
369 Array.of(r.spec).forEach(s => { 360 Array.of(r.spec).forEach(s => {
@@ -396,43 +387,42 @@ export default { @@ -396,43 +387,42 @@ export default {
396 }else{ 387 }else{
397 form.picUrls = Array.of(form.picUrls) 388 form.picUrls = Array.of(form.picUrls)
398 } 389 }
399 - console.log(rates)  
400 form.skus = rates; 390 form.skus = rates;
401 form.specType = this.ratesForm.spec; 391 form.specType = this.ratesForm.spec;
402 form.categoryId = form.categoryIds[this.baseForm.categoryIds.length - 1]; 392 form.categoryId = form.categoryIds[this.baseForm.categoryIds.length - 1];
403 393
404 -  
405 if(form.id == null){ 394 if(form.id == null){
406 createSpu(form).then((response) => { 395 createSpu(form).then((response) => {
407 this.$modal.msgSuccess("新增成功"); 396 this.$modal.msgSuccess("新增成功");
  397 + this.$emit("closeDialog");
408 }) 398 })
409 }else{ 399 }else{
410 updateSpu(form).then((response) => { 400 updateSpu(form).then((response) => {
411 this.$modal.msgSuccess("修改成功"); 401 this.$modal.msgSuccess("修改成功");
  402 + this.$emit("closeDialog");
412 }) 403 })
413 } 404 }
414 }); 405 });
415 - this.$emit("closeDialog"); 406 +
416 }, 407 },
417 /** 查询规格 */ 408 /** 查询规格 */
418 getPropertyPageList() { 409 getPropertyPageList() {
419 // 执行查询 410 // 执行查询
420 - getPropertyPage().then((response) => {  
421 - this.propertyPageList = response.data.list; 411 + getPropertyListAndValue().then((response) => {
  412 + this.propertyPageList = response.data;
422 }); 413 });
423 }, 414 },
  415 + // 添加规格项目
424 changeSpec(val) { 416 changeSpec(val) {
425 let obj = this.propertyPageList.find(o => o.id == val); 417 let obj = this.propertyPageList.find(o => o.id == val);
426 - let dynamicSpec = this.dynamicSpec;  
427 - let spec = dynamicSpec.find(o => o.specId == val) 418 + let spec = this.dynamicSpec.find(o => o.specId == val)
428 spec.specId = obj.id; 419 spec.specId = obj.id;
429 spec.specName = obj.name; 420 spec.specName = obj.name;
430 - spec.specValue = obj.propertyValueList;  
431 - this.dynamicSpec = dynamicSpec; 421 + spec.specValue = obj.values;
432 this.buildRatesFormRates(); 422 this.buildRatesFormRates();
433 }, 423 },
434 updateType(id){ 424 updateType(id){
435 - getSpu(id).then((response) =>{ 425 + getSpuDetail(id).then((response) =>{
436 let data = response.data; 426 let data = response.data;
437 this.baseForm.id=data.id; 427 this.baseForm.id=data.id;
438 this.baseForm.name=data.name; 428 this.baseForm.name=data.name;
@@ -452,6 +442,7 @@ export default { @@ -452,6 +442,7 @@ export default {
452 r.costPrice = this.divide(r.costPrice, 100) 442 r.costPrice = this.divide(r.costPrice, 100)
453 }) 443 })
454 if(this.ratesForm.spec == 2){ 444 if(this.ratesForm.spec == 2){
  445 + this.activeSwitch = true;
455 data.productPropertyViews.forEach(p=>{ 446 data.productPropertyViews.forEach(p=>{
456 let obj = {}; 447 let obj = {};
457 obj.specId = p.propertyId; 448 obj.specId = p.propertyId;