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 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 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 6 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
10 7 import io.swagger.annotations.Api;
11 8 import io.swagger.annotations.ApiImplicitParam;
... ... @@ -17,6 +14,8 @@ import org.springframework.web.bind.annotation.*;
17 14 import javax.annotation.Resource;
18 15 import javax.validation.Valid;
19 16  
  17 +import java.util.List;
  18 +
20 19 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
21 20  
22 21 @Api(tags = "管理后台 - 规格名称")
... ... @@ -56,15 +55,29 @@ public class ProductPropertyController {
56 55 @ApiOperation("获得规格名称")
57 56 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
58 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 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 69 @GetMapping("/page")
64 70 @ApiOperation("获得规格名称分页")
65 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 3 import io.swagger.annotations.ApiModelProperty;
4 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 13 @Data
13 14 public class ProductPropertyBaseVO {
14 15  
15 16 @ApiModelProperty(value = "规格名称", required = true, example = "颜色")
16   - @NotEmpty(message = "规格名称不能为空")
  17 + @NotBlank(message = "规格名称不能为空")
17 18 private String name;
18 19  
  20 + @ApiModelProperty(value = "备注", example = "颜色")
  21 + private String remark;
  22 +
19 23 @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
20   - @NotEmpty(message = "状态不能为空")
  24 + @NotNull(message = "状态不能为空")
21 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 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 8 @ApiModel("管理后台 - 规格名称创建 Request VO")
11 9 @Data
... ... @@ -13,9 +11,5 @@ import java.util.List;
13 11 @ToString(callSuper = true)
14 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 16 @NotNull(message = "主键不能为空")
17 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 22 private String name;
23 23  
24 24 @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
25   - @NotEmpty(message = "状态不能为空")
  25 + @NotNull(message = "状态不能为空")
26 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 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 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 6 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
10 7 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
11 8 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
... ... @@ -56,6 +53,14 @@ public class ProductSpuController {
56 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 64 @GetMapping("/get")
60 65 @ApiOperation("获得商品 SPU")
61 66 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
... ... @@ -64,7 +69,6 @@ public class ProductSpuController {
64 69 return success(spuService.getSpu(id));
65 70 }
66 71  
67   - // TODO @luowenfeng:新增 get-detail,返回 SpuDetailRespVO
68 72  
69 73 @GetMapping("/list")
70 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 1 package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
2 2  
3 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
4 5 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
5 6 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
6 7 import io.swagger.annotations.ApiModelProperty;
... ... @@ -67,6 +68,9 @@ public class ProductSpuBaseVO {
67 68 @ApiModelProperty(value = "库存", required = true, example = "true")
68 69 private Integer totalStock;
69 70  
  71 + @ApiModelProperty(value = "市场价", example = "1024")
  72 + private Integer marketPrice;
  73 +
70 74 @ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024")
71 75 private Integer minPrice;
72 76  
... ... @@ -75,10 +79,14 @@ public class ProductSpuBaseVO {
75 79  
76 80 // ========== 统计相关字段 =========
77 81  
  82 + @ApiModelProperty(value = "商品销量", example = "1024")
  83 + private Integer salesCount;
  84 +
78 85 @ApiModelProperty(value = "虚拟销量", required = true, example = "1024")
79 86 @NotNull(message = "虚拟销量不能为空")
80 87 private Integer virtualSalesCount;
81 88  
82 89 @ApiModelProperty(value = "点击量", example = "1024")
83 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 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 4 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
4 5 import io.swagger.annotations.ApiModel;
5 6 import io.swagger.annotations.ApiModelProperty;
... ... @@ -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 17 @ApiModelProperty(value = "商品名称")
18 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 23 @ApiModelProperty(value = "分类id")
27 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 29 @ApiModelProperty(value = "上下架状态: 0 上架(开启) 1 下架(禁用)")
45 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 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 3 import io.swagger.annotations.ApiModel;
6 4 import io.swagger.annotations.ApiModelProperty;
7 5 import lombok.Data;
... ... @@ -9,9 +7,7 @@ import lombok.EqualsAndHashCode;
9 7 import lombok.ToString;
10 8  
11 9 import java.util.Date;
12   -import java.util.List;
13 10  
14   -// TODO @Luowenfeng:这个类只返回 SPU 相关的信息,删除 skus、categoryIds、productPropertyViews;明细使用 SpuDetailRespVO 替代
15 11 @ApiModel("管理后台 - 商品 SPU Response VO")
16 12 @Data
17 13 @EqualsAndHashCode(callSuper = true)
... ... @@ -24,18 +20,4 @@ public class ProductSpuRespVO extends ProductSpuBaseVO {
24 20 @ApiModelProperty(value = "创建时间")
25 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 1 package cn.iocoder.yudao.module.product.convert.property;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyAndValueRespVO;
5 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 6 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO;
7 7 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
8 8 import org.mapstruct.Mapper;
... ... @@ -24,10 +24,10 @@ public interface ProductPropertyConvert {
24 24  
25 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 3 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
4 4 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
5 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 7 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
7 8 import org.mapstruct.Mapper;
8 9 import org.mapstruct.factory.Mappers;
... ... @@ -31,4 +32,6 @@ public interface ProductSkuConvert {
31 32  
32 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 37 * 枚举 {@link CommonStatusEnum}
38 38 */
39 39 private Integer status;
  40 + /**
  41 + * 备注
  42 + */
  43 + private String remark;
40 44  
41 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 44 * 枚举 {@link CommonStatusEnum}
45 45 */
46 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 1 package cn.iocoder.yudao.module.product.dal.mysql.property;
2 2  
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
4 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO;
5 7 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
6 8 import org.apache.ibatis.annotations.Mapper;
7 9  
... ... @@ -16,17 +18,25 @@ import java.util.List;
16 18 public interface ProductPropertyValueMapper extends BaseMapperX<ProductPropertyValueDO> {
17 19  
18 20 // TODO @franky:方法名,selectListByXXX。mapper 的操作都是 crud
19   - default List<ProductPropertyValueDO> getPropertyValueListByPropertyId(List<Long> propertyIds){
  21 + default List<ProductPropertyValueDO> getPropertyValueListByPropertyId(List<Long> propertyIds) {
20 22 // TODO @franky:调用父类的 selectList
21 23 return selectList(new LambdaQueryWrapperX<ProductPropertyValueDO>()
22 24 .inIfPresent(ProductPropertyValueDO::getPropertyId, propertyIds));
23 25 }
24 26  
25   - default void deletePropertyValueByPropertyId(Long propertyId){
  27 + default void deletePropertyValueByPropertyId(Long propertyId) {
26 28 // TODO @franky:delete(new ) 即可
27 29 LambdaQueryWrapperX<ProductPropertyValueDO> queryWrapperX = new LambdaQueryWrapperX<>();
28 30 queryWrapperX.eq(ProductPropertyValueDO::getPropertyId, propertyId)
29 31 .eq(ProductPropertyValueDO::getDeleted, false);
30 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 18 default PageResult<ProductSpuDO> selectPage(ProductSpuPageReqVO reqVO) {
19 19 return selectPage(reqVO, new LambdaQueryWrapperX<ProductSpuDO>()
20 20 .likeIfPresent(ProductSpuDO::getName, reqVO.getName())
21   - .eqIfPresent(ProductSpuDO::getSellPoint, reqVO.getSellPoint())
22 21 .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId())
23   - .eqIfPresent(ProductSpuDO::getPicUrls, reqVO.getPicUrls())
24 22 .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus())
25   - .betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime())
26 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 1 package cn.iocoder.yudao.module.product.service.property;
2 2  
3 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 5 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*;
6 6 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
7 7  
... ... @@ -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 58 * @param pageReqVO
68 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 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 1 package cn.iocoder.yudao.module.product.service.property;
2 2  
  3 +import cn.hutool.core.bean.BeanUtil;
3 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 8 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*;
6 9 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
7 10 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
... ... @@ -46,12 +49,6 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
46 49 // 插入
47 50 ProductPropertyDO property = ProductPropertyConvert.INSTANCE.convert(createReqVO);
48 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 53 return property.getId();
57 54 }
... ... @@ -64,12 +61,6 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
64 61 // 更新
65 62 ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO);
66 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 66 @Override
... ... @@ -94,31 +85,28 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
94 85 }
95 86  
96 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 94 @Override
107   - public PageResult<ProductPropertyAndValueRespVO> getPropertyListPage(ProductPropertyPageReqVO pageReqVO) {
  95 + public PageResult<ProductPropertyRespVO> getPropertyPage(ProductPropertyPageReqVO pageReqVO) {
108 96 //获取属性列表
109 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 110 return propertyRespVOPageResult;
123 111 }
124 112  
... ... @@ -127,25 +115,31 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
127 115 }
128 116  
129 117 @Override
130   - public ProductPropertyAndValueRespVO getPropertyResp(Long id) {
  118 + public ProductPropertyRespVO getPropertyResp(Long id) {
131 119 //查询规格
132 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 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 3 import cn.hutool.core.collection.CollectionUtil;
4 4 import cn.hutool.core.util.ObjectUtil;
5 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 7 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
8 8 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
9 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 13 import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants;
14 14 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
15 15 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
  16 +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
16 17 import org.springframework.stereotype.Service;
17 18 import org.springframework.transaction.annotation.Transactional;
18 19 import org.springframework.validation.annotation.Validated;
... ... @@ -39,6 +40,9 @@ public class ProductSkuServiceImpl implements ProductSkuService {
39 40 @Resource
40 41 private ProductPropertyService productPropertyService;
41 42  
  43 + @Resource
  44 + private ProductPropertyValueService productPropertyValueService;
  45 +
42 46 @Override
43 47 public void deleteSku(Long id) {
44 48 // 校验存在
... ... @@ -71,17 +75,15 @@ public class ProductSkuServiceImpl implements ProductSkuService {
71 75 }
72 76  
73 77 // 1、校验规格属性存在
74   - // TODO @Luowenfeng:stream 的写法;不用改哈,就是说下可以酱紫写;
75 78 Set<Long> propertyIds = skus.stream().filter(p -> p.getProperties() != null).flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性
76 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 82 throw exception(PROPERTY_NOT_EXISTS);
80 83 }
81 84  
82 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 87 skus.forEach(sku -> {
86 88 Set<Long> skuPropertyIds = CollectionUtils.convertSet(sku.getProperties(), propertyItem -> propertyValueMap.get(propertyItem.getValueId()).getPropertyId());
87 89 if (skuPropertyIds.size() != sku.getProperties().size()) {
... ... @@ -100,8 +102,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
100 102 // 4. 最后校验,每个 Sku 之间不是重复的
101 103 Set<Set<Long>> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的.
102 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 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 1 package cn.iocoder.yudao.module.product.service.spu;
2 2  
3 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 5 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
9 6 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
10 7 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
... ... @@ -43,6 +40,14 @@ public interface ProductSpuService {
43 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 51 * 获得商品spu
47 52 *
48 53 * @param id 编号
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
1 1 package cn.iocoder.yudao.module.product.service.spu;
2 2  
  3 +import cn.hutool.core.bean.BeanUtil;
3 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 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 7 import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO;
7 8 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
8 9 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
9 10 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
10 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 13 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
16 14 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
17 15 import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
... ... @@ -22,6 +20,7 @@ import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
22 20 import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
23 21 import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
24 22 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
  23 +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
25 24 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
26 25 import org.springframework.stereotype.Service;
27 26 import org.springframework.transaction.annotation.Transactional;
... ... @@ -56,6 +55,9 @@ public class ProductSpuServiceImpl implements ProductSpuService {
56 55 private ProductPropertyService productPropertyService;
57 56  
58 57 @Resource
  58 + private ProductPropertyValueService productPropertyValueService;
  59 +
  60 + @Resource
59 61 private ProductBrandService brandService;
60 62  
61 63 @Override
... ... @@ -125,28 +127,31 @@ public class ProductSpuServiceImpl implements ProductSpuService {
125 127  
126 128 @Override
127 129 // TODO @芋艿:需要再 review 下
128   - public ProductSpuRespVO getSpu(Long id) {
  130 + public ProductSpuDetailRespVO getSpuDetail(Long id) {
129 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 136 // 组合 sku 规格属性
136 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 140 properties.addAll(productSkuRespVO.getProperties());
139 141 }
140 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 147 List<ProductPropertyViewRespVO> productPropertyViews = new ArrayList<>();
144   - propertyAndValueList.forEach(p -> {
  148 + propertyList.forEach(p -> {
145 149 ProductPropertyViewRespVO productPropertyViewRespVO = new ProductPropertyViewRespVO();
146 150 productPropertyViewRespVO.setPropertyId(p.getId());
147 151 productPropertyViewRespVO.setName(p.getName());
148 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 155 propertyMaps.get(p.getId()).forEach(pv -> {
151 156 ProductPropertyViewRespVO.Tuple2 tuple2 = new ProductPropertyViewRespVO.Tuple2(pv.getValueId(), propertyValueMaps.get(pv.getValueId()).getName());
152 157 propertyValues.add(tuple2);
... ... @@ -154,12 +159,12 @@ public class ProductSpuServiceImpl implements ProductSpuService {
154 159 productPropertyViewRespVO.setPropertyValues(propertyValues.stream().distinct().collect(Collectors.toList()));
155 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 166 LinkedList<Long> categoryArray = new LinkedList<>();
162   - Long parentId = spuVO.getCategoryId();
  167 + Long parentId = respVO.getCategoryId();
163 168 categoryArray.addFirst(parentId);
164 169 while (parentId != 0) {
165 170 parentId = categoryService.getCategory(parentId).getParentId();
... ... @@ -167,10 +172,15 @@ public class ProductSpuServiceImpl implements ProductSpuService {
167 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 186 @Override
... ... @@ -182,8 +192,8 @@ public class ProductSpuServiceImpl implements ProductSpuService {
182 192 public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) {
183 193 PageResult<ProductSpuRespVO> spuVOs = ProductSpuConvert.INSTANCE.convertPage(ProductSpuMapper.selectPage(pageReqVO));
184 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 197 // TODO @franky:使用 CollUtil 里的方法替代哈
188 198 // TODO 芋艿:临时注释
189 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 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 65 // 导出规格名称 Excel
47 66 export function exportPropertyExcel(query) {
48 67 return request({
... ... @@ -52,3 +71,49 @@ export function exportPropertyExcel(query) {
52 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 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 45 // 获得商品spu分页
38 46 export function getSpuPage(query) {
39 47 return request({
... ...
yudao-ui-admin/src/router/index.js
... ... @@ -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 111 path: '/job',
101 112 component: Layout,
102 113 hidden: true,
... ...
yudao-ui-admin/src/views/mall/product/property/index.vue
... ... @@ -6,7 +6,7 @@
6 6 <el-form-item label="规格名称" prop="name">
7 7 <el-input v-model="queryParams.name" placeholder="请输入规格名称" clearable @keyup.enter.native="handleQuery"/>
8 8 </el-form-item>
9   - <el-form-item label="开启状态" prop="status">
  9 + <el-form-item label="状态" prop="status">
10 10 <el-select v-model="queryParams.status" placeholder="请选择开启状态" clearable size="small">
11 11 <el-option v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
12 12 :key="dict.value" :label="dict.label" :value="dict.value"/>
... ... @@ -33,12 +33,14 @@
33 33  
34 34 <!-- 列表 -->
35 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 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 42 </template>
41   - </el-table-column>
  43 + </el-table-column>
42 44 <el-table-column label="开启状态" align="center" prop="status">
43 45 <template slot-scope="scope">
44 46 <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/>
... ... @@ -49,6 +51,7 @@
49 51 <span>{{ parseTime(scope.row.createTime) }}</span>
50 52 </template>
51 53 </el-table-column>
  54 + <el-table-column label="备注" align="center" prop="left" />
52 55 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
53 56 <template slot-scope="scope">
54 57 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
... ... @@ -65,6 +68,9 @@
65 68 <!-- 对话框(添加 / 修改) -->
66 69 <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
67 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 74 <el-form-item label="规格名称" prop="name">
69 75 <el-input v-model="form.name" placeholder="请输入规格名称" />
70 76 </el-form-item>
... ... @@ -75,26 +81,9 @@
75 81 </el-radio>
76 82 </el-radio-group>
77 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 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 87 </el-form>
99 88 <div slot="footer" class="dialog-footer">
100 89 <el-button type="primary" @click="submitForm">确 定</el-button>
... ... @@ -139,12 +128,17 @@ export default {
139 128 form: {
140 129 name:'',
141 130 status:'',
142   - propertyValueList: [{
143   - name: ''
144   - }],
  131 + remark:"",
  132 + id: null,
145 133 },
146 134 // 表单校验
147 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 164 /** 表单重置 */
171 165 reset() {
172 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 172 this.resetForm("form");
181 173 },
... ... @@ -253,27 +245,6 @@ export default {
253 245 this.exportLoading = false;
254 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 250 </script>
... ...
yudao-ui-admin/src/views/mall/product/spu/index.vue
... ... @@ -9,20 +9,22 @@
9 9 <el-form-item label="商品名称" prop="name">
10 10 <el-input v-model="queryParams.name" placeholder="请输入商品名称" clearable @keyup.enter.native="handleQuery"/>
11 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 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 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 26 </el-form-item>
  27 +
26 28 <el-form-item>
27 29 <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
28 30 <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
... ... @@ -46,33 +48,35 @@
46 48 1. 字段:商品信息、价格、库存、销量、排序、创建时间、状态、操作;
47 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 63 </template>
61 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 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 72 </template>
70 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 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 77 </template>
75 78 </el-table-column>
  79 +
76 80 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
77 81 <template slot-scope="scope">
78 82 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
... ... @@ -87,7 +91,7 @@
87 91 @pagination="getList"/>
88 92  
89 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 95 </el-dialog>
92 96 </div>
93 97 </template>
... ... @@ -97,7 +101,8 @@ import {
97 101 deleteSpu,
98 102 getSpuPage,
99 103 } from "@/api/mall/product/spu";
100   -
  104 +import {getProductCategoryList} from "@/api/mall/product/category";
  105 +import {getBrandList} from "@/api/mall/product/brand";
101 106 import Editor from "@/components/Editor";
102 107 import ImageUpload from "@/components/ImageUpload";
103 108 import save from "./save";
... ... @@ -114,20 +119,12 @@ export default {
114 119 },
115 120 data() {
116 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 128 categoryList: [],
132 129 // 遮罩层
133 130 loading: true,
... ... @@ -143,8 +140,6 @@ export default {
143 140 title: "",
144 141 // 是否显示弹出层
145 142 open: false,
146   - // 弹出层类型
147   - dialogType: "add",
148 143 // 弹出层参数
149 144 dialogObj:{},
150 145 dateRangeCreateTime: [],
... ... @@ -153,14 +148,10 @@ export default {
153 148 pageNo: 1,
154 149 pageSize: 10,
155 150 name: null,
156   - sellPoint: null,
157   - description: null,
  151 + code: null,
  152 + categoryIds: [],
158 153 categoryId: null,
159   - picUrls: null,
160   - sort: null,
161   - likeCount: null,
162   - price: null,
163   - quantity: null,
  154 + brandId: null,
164 155 status: null,
165 156 },
166 157 tagIndex: 0,
... ... @@ -168,13 +159,30 @@ export default {
168 159 },
169 160 created() {
170 161 this.getList();
  162 + this.getListCategory()
  163 + this.getListBrand()
171 164 },
172 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 181 getList() {
175 182 this.loading = true;
176 183 // 处理查询参数
177 184 let params = { ...this.queryParams };
  185 + params.categoryId = this.queryParams.categoryIds[ this.queryParams.categoryIds.length - 1];
178 186 this.addBeginAndEndTime(params, this.dateRangeCreateTime, "createTime");
179 187 // 执行查询
180 188 getSpuPage(params).then((response) => {
... ... @@ -200,27 +208,26 @@ export default {
200 208 /** 重置按钮操作 */
201 209 resetQuery() {
202 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 215 this.resetForm("queryForm");
204 216 this.handleQuery();
205 217 },
206 218 /** 新增按钮操作 */
207 219 handleAdd() {
208   - this.dialogType = "add";
209 220 this.dialogObj={};
210 221 this.open = true;
211 222 this.title = "添加商品spu";
212 223 },
213 224 /** 修改按钮操作 */
214 225 handleUpdate(row) {
215   - this.dialogType = "upd";
216 226 this.dialogObj.id = row.id;
217 227 this.open = true;
218   - console.log("修改")
219 228 this.title = "修改商品spu";
220 229 },
221 230 closeDialog(){
222   - console.log("关闭")
223   - this.dialogType = "add";
224 231 this.dialogObj={};
225 232 this.open = false;
226 233 this.getList()
... ... @@ -238,6 +245,9 @@ export default {
238 245 this.$modal.msgSuccess("删除成功");
239 246 })
240 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 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 296 </style>
... ...
yudao-ui-admin/src/views/mall/product/spu/save.vue
1 1 <template>
2 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 5 <el-tab-pane label="基础设置" name="base">
6 6 <el-form ref="base" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%">
... ... @@ -12,7 +12,7 @@
12 12 </el-form-item>
13 13 <!-- TODO @Luowenfeng:商品主图,80 x 80 即可 -->
14 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 16 </el-form-item>
17 17 <!-- TODO @Luowenfeng:商品视频 -->
18 18 <el-form-item label="商品品牌" prop="brandId">
... ... @@ -38,10 +38,7 @@
38 38 <el-form ref="rates" :model="ratesForm" :rules="rules">
39 39 <el-form-item label="启用多规格">
40 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 42 </el-form-item>
46 43  
47 44 <!-- 动态添加规格属性 -->
... ... @@ -67,7 +64,7 @@
67 64 <!-- 规格明细 -->
68 65 <el-form-item label="规格明细">
69 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 68 <el-table-column :key="index" v-for="(item, index) in dynamicSpec.filter(v => v.specName !== undefined)"
72 69 :label="item.specName">
73 70 <template slot-scope="scope">
... ... @@ -81,7 +78,7 @@
81 78 style="width: 100px; height: 50px"/>
82 79 </template>
83 80 </el-table-column>
84   - <template v-if="ratesForm.spec === 2">
  81 + <template v-if="this.activeSwitch">
85 82 <el-table-column label="sku名称" :render-header="addRedStar" key="91">
86 83 <template slot-scope="scope">
87 84 <el-form-item :prop="'rates.'+ scope.$index + '.name'" :rules="[{required: true, trigger: 'change'}]">
... ... @@ -142,7 +139,7 @@
142 139 <el-input v-model="scope.row.barCode"></el-input>
143 140 </template>
144 141 </el-table-column>
145   - <template v-if="ratesForm.spec === 2">
  142 + <template v-if="this.activeSwitch">
146 143 <el-table-column fixed="right" label="操作" width="50" key="100">
147 144 <template slot-scope="scope">
148 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 150 </el-table>
154 151 </el-form-item>
155 152 <el-form-item label="虚拟销量" prop="virtualSalesCount">
156   - <!-- TODO @Luowenfeng:使用 input 类型即可 -->
157 153 <el-input v-model="baseForm.virtualSalesCount" placeholder="请输入虚拟销量" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/>
158 154 </el-form-item>
159 155 </el-form>
... ... @@ -196,8 +192,8 @@
196 192  
197 193 import {getBrandList} from "@/api/mall/product/brand";
198 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 197 import Editor from "@/components/Editor";
202 198 import ImageUpload from "@/components/ImageUpload";
203 199  
... ... @@ -206,16 +202,13 @@ export default {
206 202 Editor,
207 203 ImageUpload
208 204 },
209   - props:{//props列表
210   - type:{
211   - type:String,
212   - default:"add" //定义参数默认值
213   - },
  205 + props:{
214 206 obj: Object
215 207 },
216 208 data() {
217 209 return {
218   - activeName: "base", // TODO @Luowenfeng:切换时,不需要校验通过
  210 + activeSwitch: false,
  211 + activeName: "base",
219 212 propName: {
220 213 checkStrictly: true,
221 214 label: "name",
... ... @@ -271,7 +264,7 @@ export default {
271 264 this.getListBrand();
272 265 this.getListCategory();
273 266 this.getPropertyPageList();
274   - if(this.type == 'upd'){
  267 + if(this.obj.id != null){
275 268 this.updateType(this.obj.id)
276 269 }
277 270 },
... ... @@ -280,14 +273,6 @@ export default {
280 273 this.dynamicSpec.splice(index, 1);
281 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 277 addRedStar(h, { column }) {
293 278 return [
... ... @@ -296,13 +281,13 @@ export default {
296 281 ];
297 282 },
298 283 changeRadio() {
  284 + this.activeSwitch ? this.ratesForm.spec = 2: this.ratesForm.spec = 1;
299 285 this.$refs.ratesTable.doLayout();
300 286 if (this.ratesForm.spec == 1) {
301 287 this.ratesForm.rates = [{}]
302 288 } else {
303 289 this.ratesForm.rates = []
304 290 if (this.dynamicSpec.length > 0) {
305   - console.log( this.dynamicSpec)
306 291 this.buildRatesFormRates()
307 292 }
308 293 }
... ... @@ -316,6 +301,7 @@ export default {
316 301 last.forEach(par1 => {
317 302 current.forEach(par2 => {
318 303 let v
  304 + // 当两个对象合并时,需使用[1,2]方式生成数组,而当数组和对象合并时,需使用concat
319 305 if (par1 instanceof Array) {
320 306 v = par1.concat(par2)
321 307 } else {
... ... @@ -327,7 +313,12 @@ export default {
327 313 return array;
328 314 })
329 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 323 this.ratesForm.rates = rates
333 324 },
... ... @@ -363,7 +354,7 @@ export default {
363 354 })
364 355  
365 356 // 动态规格调整字段
366   - if (this.ratesForm.spec == 2) {
  357 + if (this.activeSwitch) {
367 358 rates.forEach(r => {
368 359 let properties = []
369 360 Array.of(r.spec).forEach(s => {
... ... @@ -396,43 +387,42 @@ export default {
396 387 }else{
397 388 form.picUrls = Array.of(form.picUrls)
398 389 }
399   - console.log(rates)
400 390 form.skus = rates;
401 391 form.specType = this.ratesForm.spec;
402 392 form.categoryId = form.categoryIds[this.baseForm.categoryIds.length - 1];
403 393  
404   -
405 394 if(form.id == null){
406 395 createSpu(form).then((response) => {
407 396 this.$modal.msgSuccess("新增成功");
  397 + this.$emit("closeDialog");
408 398 })
409 399 }else{
410 400 updateSpu(form).then((response) => {
411 401 this.$modal.msgSuccess("修改成功");
  402 + this.$emit("closeDialog");
412 403 })
413 404 }
414 405 });
415   - this.$emit("closeDialog");
  406 +
416 407 },
417 408 /** 查询规格 */
418 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 416 changeSpec(val) {
425 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 419 spec.specId = obj.id;
429 420 spec.specName = obj.name;
430   - spec.specValue = obj.propertyValueList;
431   - this.dynamicSpec = dynamicSpec;
  421 + spec.specValue = obj.values;
432 422 this.buildRatesFormRates();
433 423 },
434 424 updateType(id){
435   - getSpu(id).then((response) =>{
  425 + getSpuDetail(id).then((response) =>{
436 426 let data = response.data;
437 427 this.baseForm.id=data.id;
438 428 this.baseForm.name=data.name;
... ... @@ -452,6 +442,7 @@ export default {
452 442 r.costPrice = this.divide(r.costPrice, 100)
453 443 })
454 444 if(this.ratesForm.spec == 2){
  445 + this.activeSwitch = true;
455 446 data.productPropertyViews.forEach(p=>{
456 447 let obj = {};
457 448 obj.specId = p.propertyId;
... ...