Commit 8ad1439fda6e05f59a710fca7b24df5887a0639c

Authored by luowenfeng
1 parent 81666e3b

feature(uniapp商品): 新增商品

yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java
@@ -21,10 +21,7 @@ public class ProductSkuBaseVO { @@ -21,10 +21,7 @@ public class ProductSkuBaseVO {
21 @NotEmpty(message = "商品 SKU 名字不能为空") 21 @NotEmpty(message = "商品 SKU 名字不能为空")
22 private String name; 22 private String name;
23 23
24 - /**  
25 - * 规格值数组  
26 - */  
27 - @NotNull(message = "规格值数组不能为空") 24 + @ApiModelProperty(value = "规格值数组-json格式 单规格中无此列表, [{propertyId: , valueId: }, {propertyId: , valueId: }]")
28 private List<Property> properties; 25 private List<Property> properties;
29 26
30 @ApiModelProperty(value = "销售价格,单位:分", required = true, example = "1024", notes = "单位:分") 27 @ApiModelProperty(value = "销售价格,单位:分", required = true, example = "1024", notes = "单位:分")
@@ -32,7 +29,7 @@ public class ProductSkuBaseVO { @@ -32,7 +29,7 @@ public class ProductSkuBaseVO {
32 private Integer price; 29 private Integer price;
33 30
34 @ApiModelProperty(value = "市场价", example = "1024", notes = "单位:分") 31 @ApiModelProperty(value = "市场价", example = "1024", notes = "单位:分")
35 - private Integer originalPrice; 32 + private Integer marketPrice;
36 33
37 @ApiModelProperty(value = "成本价", example = "1024", notes = "单位:分") 34 @ApiModelProperty(value = "成本价", example = "1024", notes = "单位:分")
38 private Integer costPrice; 35 private Integer costPrice;
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java
@@ -36,7 +36,7 @@ public class ProductSpuBaseVO { @@ -36,7 +36,7 @@ public class ProductSpuBaseVO {
36 private Long categoryId; 36 private Long categoryId;
37 37
38 @ApiModelProperty(value = "商品品牌编号", required = true, example = "1") 38 @ApiModelProperty(value = "商品品牌编号", required = true, example = "1")
39 - @NotNull(message = "商品品牌编号不能为空") 39 +// @NotNull(message = "商品品牌编号不能为空")
40 private Long brandId; 40 private Long brandId;
41 41
42 @ApiModelProperty(value = "商品图片的数组", required = true) 42 @ApiModelProperty(value = "商品图片的数组", required = true)
@@ -44,7 +44,6 @@ public class ProductSpuBaseVO { @@ -44,7 +44,6 @@ public class ProductSpuBaseVO {
44 private List<String> picUrls; 44 private List<String> picUrls;
45 45
46 @ApiModelProperty(value = "商品视频", required = true) 46 @ApiModelProperty(value = "商品视频", required = true)
47 - @NotEmpty(message = "商品视频不能为空")  
48 private String videoUrl; 47 private String videoUrl;
49 48
50 @ApiModelProperty(value = "排序字段", required = true, example = "1") 49 @ApiModelProperty(value = "排序字段", required = true, example = "1")
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
@@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; @@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
15 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; 15 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
16 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; 16 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
17 import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; 17 import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
  18 +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
18 import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; 19 import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
19 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; 20 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
20 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; 21 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
@@ -57,13 +58,18 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -57,13 +58,18 @@ public class ProductSpuServiceImpl implements ProductSpuService {
57 categoryService.validateProductCategory(createReqVO.getCategoryId()); 58 categoryService.validateProductCategory(createReqVO.getCategoryId());
58 // 校验SKU 59 // 校验SKU
59 List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = createReqVO.getSkus(); 60 List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = createReqVO.getSkus();
60 - if(createReqVO.getSpecType() == 1) { 61 + // 多规格才需校验
  62 + if(Objects.equals(createReqVO.getSpecType(), ProductSpuSpecTypeEnum.DISABLE.getType())) {
61 productSkuService.validateSkus(skuCreateReqList); 63 productSkuService.validateSkus(skuCreateReqList);
62 } 64 }
63 // 插入SPU 65 // 插入SPU
64 ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO); 66 ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO);
  67 + spu.setMarketPrice(skuCreateReqList.stream().map(ProductSkuCreateOrUpdateReqVO::getMarketPrice).max(Integer::compare).orElse(0));
  68 + spu.setMaxPrice(skuCreateReqList.stream().map(ProductSkuCreateOrUpdateReqVO::getPrice).max(Integer::compare).orElse(0));
  69 + spu.setMinPrice(skuCreateReqList.stream().map(ProductSkuCreateOrUpdateReqVO::getPrice).min(Integer::compare).orElse(0));
65 ProductSpuMapper.insert(spu); 70 ProductSpuMapper.insert(spu);
66 List<ProductSkuDO> skuDOList = ProductSkuConvert.INSTANCE.convertSkuDOList(skuCreateReqList); 71 List<ProductSkuDO> skuDOList = ProductSkuConvert.INSTANCE.convertSkuDOList(skuCreateReqList);
  72 + skuDOList.forEach(v->v.setSpuId(spu.getId()));
67 // 批量插入sku 73 // 批量插入sku
68 productSkuService.createSkus(skuDOList); 74 productSkuService.createSkus(skuDOList);
69 // 返回 75 // 返回
@@ -79,7 +85,8 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -79,7 +85,8 @@ public class ProductSpuServiceImpl implements ProductSpuService {
79 categoryService.validateProductCategory(updateReqVO.getCategoryId()); 85 categoryService.validateProductCategory(updateReqVO.getCategoryId());
80 // 校验SKU 86 // 校验SKU
81 List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = updateReqVO.getSkus(); 87 List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = updateReqVO.getSkus();
82 - if(updateReqVO.getSpecType() == 1) { 88 + // 多规格才需校验
  89 + if(updateReqVO.getSpecType().equals(ProductSpuSpecTypeEnum.DISABLE.getType())) {
83 productSkuService.validateSkus(skuCreateReqList); 90 productSkuService.validateSkus(skuCreateReqList);
84 } 91 }
85 // 更新 92 // 更新
yudao-ui-admin/src/components/ImageUpload/index.vue
@@ -85,8 +85,8 @@ export default { @@ -85,8 +85,8 @@ export default {
85 value: { 85 value: {
86 handler(val) { 86 handler(val) {
87 if (val) { 87 if (val) {
88 - // 首先将值转为数组  
89 - const list = Array.isArray(val) ? val : this.value.split(','); 88 + // 首先将值转为数组, 当只穿了一个图片时,会报map方法错误
  89 + const list = Array.isArray(val) ? val : Array.isArray(this.value.split(',')) ? this.value.split(','): Array.of(this.value);
90 // 然后将数组转为对象数组 90 // 然后将数组转为对象数组
91 this.fileList = list.map(item => { 91 this.fileList = list.map(item => {
92 if (typeof item === "string") { 92 if (typeof item === "string") {
yudao-ui-admin/src/views/mall/product/spu/index.vue
@@ -178,7 +178,7 @@ @@ -178,7 +178,7 @@
178 /> 178 />
179 179
180 180
181 - <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body destroy-on-close> 181 + <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body destroy-on-close :close-on-click-modal="false" >
182 <save @closeDialog="open = false; getList()"/> 182 <save @closeDialog="open = false; getList()"/>
183 </el-dialog> 183 </el-dialog>
184 </div> 184 </div>
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"> 3 + <el-tabs v-model="activeName" class="tabs" :before-leave="confirmLeave">
4 <!-- 基础设置 --> 4 <!-- 基础设置 -->
5 <el-tab-pane label="基础设置" name="base"> 5 <el-tab-pane label="基础设置" name="base">
6 - <el-form ref="baseForm" :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%">
7 <el-form-item label="商品名称" prop="name"> 7 <el-form-item label="商品名称" prop="name">
8 <el-input v-model="baseForm.name" placeholder="请输入商品名称"/> 8 <el-input v-model="baseForm.name" placeholder="请输入商品名称"/>
9 </el-form-item> 9 </el-form-item>
10 - <el-form-item label="卖点" prop="sellPoint"> 10 + <el-form-item label="卖点">
11 <el-input v-model="baseForm.sellPoint" placeholder="请输入卖点"/> 11 <el-input v-model="baseForm.sellPoint" placeholder="请输入卖点"/>
12 </el-form-item> 12 </el-form-item>
13 <el-form-item label="分类id" prop="categoryIds"> 13 <el-form-item label="分类id" prop="categoryIds">
@@ -20,30 +20,27 @@ @@ -20,30 +20,27 @@
20 clearable 20 clearable
21 ></el-cascader> 21 ></el-cascader>
22 </el-form-item> 22 </el-form-item>
23 - <el-form-item label="商品主图" prop="bannerUrl">  
24 - <ImageUpload v-model="baseForm.bannerUrl" :limit="1"/>  
25 - </el-form-item>  
26 <el-form-item label="商品轮播图" prop="picUrls"> 23 <el-form-item label="商品轮播图" prop="picUrls">
27 - <ImageUpload v-model="baseForm.picUrls" :limit="10"/> 24 + <ImageUpload v-model="baseForm.picUrls" :value="baseForm.picUrls" :limit="10"/>
28 </el-form-item> 25 </el-form-item>
29 - <el-form-item label="排序字段" prop="sort">  
30 - <el-input v-model="baseForm.sort" placeholder="请输入排序字段"/> 26 + <el-form-item label="排序字段">
  27 + <el-input v-model="baseForm.sort" placeholder="请输入排序字段" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/>
31 </el-form-item> 28 </el-form-item>
32 </el-form> 29 </el-form>
33 </el-tab-pane> 30 </el-tab-pane>
34 31
35 <!-- 价格库存 --> 32 <!-- 价格库存 -->
36 <el-tab-pane label="价格库存" name="rates" class="rates"> 33 <el-tab-pane label="价格库存" name="rates" class="rates">
37 - <el-form :model="ratesForm" :rules="rules.ratesForm"> 34 + <el-form ref="rates" :model="ratesForm" :rules="rules">
38 <el-form-item label="商品规格"> 35 <el-form-item label="商品规格">
39 <el-radio-group v-model="ratesForm.spec" @change="changeRadio"> 36 <el-radio-group v-model="ratesForm.spec" @change="changeRadio">
40 - <el-radio :label="0">单规格</el-radio>  
41 - <el-radio :label="1">多规格</el-radio> 37 + <el-radio :label="1">单规格</el-radio>
  38 + <el-radio :label="2">多规格</el-radio>
42 </el-radio-group> 39 </el-radio-group>
43 </el-form-item> 40 </el-form-item>
44 41
45 <!-- 动态添加规格属性 --> 42 <!-- 动态添加规格属性 -->
46 - <div v-show="ratesForm.spec === 1"> 43 + <div v-show="ratesForm.spec === 2">
47 <div 44 <div
48 v-for="(specs, index) in dynamicSpec" 45 v-for="(specs, index) in dynamicSpec"
49 :key="index" 46 :key="index"
@@ -71,14 +68,8 @@ @@ -71,14 +68,8 @@
71 </div> 68 </div>
72 <div class="spec-values"> 69 <div class="spec-values">
73 <template v-for="(v, i) in specs.specValue"> 70 <template v-for="(v, i) in specs.specValue">
74 - <el-input v-model="v.name" class="spec-value" :key="i"/> 71 + <el-input v-model="v.name" class="spec-value" :key="i" disabled/>
75 </template> 72 </template>
76 - <!-- <el-button  
77 - type="primary"  
78 - icon="el-icon-plus"  
79 - circle  
80 - @click="dialogForSpec = true; currentSpec = index"  
81 - ></el-button> -->  
82 </div> 73 </div>
83 </div> 74 </div>
84 <el-button type="primary" @click="dynamicSpec.push({specValue: []}); ratesForm.rates = []" 75 <el-button type="primary" @click="dynamicSpec.push({specValue: []}); ratesForm.rates = []"
@@ -89,9 +80,8 @@ @@ -89,9 +80,8 @@
89 80
90 <!-- 规格明细 --> 81 <!-- 规格明细 -->
91 <el-form-item label="规格明细"> 82 <el-form-item label="规格明细">
92 - <el-table :data="ratesForm.rates" border style="width: 100%" ref="rates">  
93 -  
94 - <template v-if="ratesForm.spec == 1"> 83 + <el-table :data="ratesForm.rates" border style="width: 100%" ref="ratesTable">
  84 + <template v-if="ratesForm.spec == 2">
95 <el-table-column :key="index" v-for="(item, index) in dynamicSpec.filter(v=>v.specName != undefined)" 85 <el-table-column :key="index" v-for="(item, index) in dynamicSpec.filter(v=>v.specName != undefined)"
96 :label="item.specName"> 86 :label="item.specName">
97 <template slot-scope="scope"> 87 <template slot-scope="scope">
@@ -103,54 +93,90 @@ @@ -103,54 +93,90 @@
103 </template> 93 </template>
104 </el-table-column> 94 </el-table-column>
105 </template> 95 </template>
106 -  
107 - <el-table-column label="规格图片" width="120px"> 96 + <el-table-column label="规格图片" width="120px" :render-header="addRedStar" key="90">
108 <template slot-scope="scope"> 97 <template slot-scope="scope">
109 - <ImageUpload v-model="scope.row.picUrl" :limit="1" :isShowTip="false" 98 + <ImageUpload v-model="scope.row.picUrl" :limit="1" :isShowTip="false"
110 style="width: 100px; height: 50px"/> 99 style="width: 100px; height: 50px"/>
111 </template> 100 </template>
112 </el-table-column> 101 </el-table-column>
113 - <el-table-column label="市场价(元)"> 102 + <template v-if="ratesForm.spec == 2">
  103 + <el-table-column label="sku名称" :render-header="addRedStar" key="91">
  104 + <template slot-scope="scope">
  105 + <el-form-item :prop="'rates.'+ scope.$index + '.name'" :rules="[{required: true, trigger: 'change'}]">
  106 + <el-input
  107 + v-model="scope.row.name"
  108 + ></el-input>
  109 + </el-form-item>
  110 + </template>
  111 + </el-table-column>
  112 + </template>
  113 +
  114 + <el-table-column label="市场价(元)" :render-header="addRedStar" key="92">
114 <template slot-scope="scope"> 115 <template slot-scope="scope">
115 - <el-input  
116 - v-model="scope.row.marketPrice"  
117 - type="number"  
118 - ></el-input> 116 + <el-form-item :prop="'rates.'+ scope.$index + '.marketPrice'" :rules="[{required: true, trigger: 'change'}]">
  117 + <el-input
  118 + v-model="scope.row.marketPrice"
  119 + oninput="value= value.match(/\d+(\.\d{0,2})?/) ? value.match(/\d+(\.\d{0,2})?/)[0] : ''"
  120 + ></el-input>
  121 + </el-form-item>
119 </template> 122 </template>
120 </el-table-column> 123 </el-table-column>
121 - <el-table-column label="销售价(元)" re> 124 + <el-table-column label="销售价(元)" :render-header="addRedStar" key="93">
122 <template slot-scope="scope"> 125 <template slot-scope="scope">
123 - <el-input v-model="scope.row.price" type="number"></el-input> 126 + <el-form-item :prop="'rates.'+ scope.$index + '.price'" :rules="[{required: true, trigger: 'change'}]">
  127 + <el-input v-model="scope.row.price" oninput="value= value.match(/\d+(\.\d{0,2})?/) ? value.match(/\d+(\.\d{0,2})?/)[0] : ''"></el-input>
  128 + </el-form-item>
124 </template> 129 </template>
125 </el-table-column> 130 </el-table-column>
126 - <el-table-column label="成本价"> 131 + <el-table-column label="成本价" :render-header="addRedStar" key="94">
127 <template slot-scope="scope"> 132 <template slot-scope="scope">
  133 + <el-form-item :prop="'rates.'+ scope.$index + '.costPrice'" :rules="[{required: true, trigger: 'change'}]">
128 <el-input 134 <el-input
129 v-model="scope.row.costPrice" 135 v-model="scope.row.costPrice"
130 - type="number" 136 + oninput="value= value.match(/\d+(\.\d{0,2})?/) ? value.match(/\d+(\.\d{0,2})?/)[0] : ''"
131 ></el-input> 137 ></el-input>
  138 + </el-form-item>
  139 + </template>
  140 + </el-table-column>
  141 + <el-table-column label="库存" :render-header="addRedStar" key="95">
  142 + <template slot-scope="scope">
  143 + <el-form-item :prop="'rates.'+ scope.$index + '.stock'" :rules="[{required: true, trigger: 'change'}]">
  144 + <el-input v-model="scope.row.stock" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"></el-input>
  145 + </el-form-item>
132 </template> 146 </template>
133 </el-table-column> 147 </el-table-column>
134 - <el-table-column label="库存"> 148 + <el-table-column label="预警库存" key="96">
135 <template slot-scope="scope"> 149 <template slot-scope="scope">
136 - <el-input v-model="scope.row.stock" type="number"></el-input> 150 + <el-input v-model="scope.row.warnStock" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"></el-input>
137 </template> 151 </template>
138 </el-table-column> 152 </el-table-column>
139 - <el-table-column label="体积"> 153 + <el-table-column label="体积" key="97">
140 <template slot-scope="scope"> 154 <template slot-scope="scope">
141 - <el-input v-model="scope.row.volume" type="number"></el-input> 155 + <el-input v-model="scope.row.volume" ></el-input>
142 </template> 156 </template>
143 </el-table-column> 157 </el-table-column>
144 - <el-table-column label="重量"> 158 + <el-table-column label="重量" key="98">
145 <template slot-scope="scope"> 159 <template slot-scope="scope">
146 - <el-input v-model="scope.row.weight" type="number"></el-input> 160 + <el-input v-model="scope.row.weight" ></el-input>
147 </template> 161 </template>
148 </el-table-column> 162 </el-table-column>
149 - <el-table-column label="条码"> 163 + <el-table-column label="条码" key="99">
150 <template slot-scope="scope"> 164 <template slot-scope="scope">
151 <el-input v-model="scope.row.barCode"></el-input> 165 <el-input v-model="scope.row.barCode"></el-input>
152 </template> 166 </template>
153 </el-table-column> 167 </el-table-column>
  168 + <template v-if="ratesForm.spec == 2">
  169 + <el-table-column
  170 + fixed="right"
  171 + label="操作"
  172 + width="50"
  173 + key="100">
  174 + <template slot-scope="scope">
  175 + <el-button @click="scope.row.status = 1" type="text" size="small" v-show="scope.row.status == undefined || scope.row.status == 0 ">禁用</el-button>
  176 + <el-button @click="scope.row.status = 0" type="text" size="small" v-show="scope.row.status == 1">启用</el-button>
  177 + </template>
  178 + </el-table-column>
  179 + </template>
154 </el-table> 180 </el-table>
155 </el-form-item> 181 </el-form-item>
156 </el-form> 182 </el-form>
@@ -158,16 +184,26 @@ @@ -158,16 +184,26 @@
158 184
159 <!-- 商品详情 --> 185 <!-- 商品详情 -->
160 <el-tab-pane label="商品描述" name="third"> 186 <el-tab-pane label="商品描述" name="third">
161 - <editor v-model="baseForm.description" :min-height="400"/> 187 + <el-form ref="third" :model="baseForm" :rules="rules">
  188 + <el-form-item prop="description">
  189 + <editor v-model="baseForm.description" :min-height="380"/>
  190 + </el-form-item>
  191 + </el-form>
162 </el-tab-pane> 192 </el-tab-pane>
163 193
164 <!-- 销售设置 --> 194 <!-- 销售设置 -->
165 <el-tab-pane label="销售设置" name="fourth"> 195 <el-tab-pane label="销售设置" name="fourth">
166 - <el-form ref="baseForm" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%">  
167 - <el-form-item label="库存数量" prop="totalStock">  
168 - <el-input v-model="baseForm.totalStock" placeholder="请输入库存数量"/> 196 + <el-form ref="fourth" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%">
  197 + <el-form-item label="虚拟销量" prop="virtualSalesCount">
  198 + <el-input v-model="baseForm.virtualSalesCount" placeholder="请输入虚拟销量" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/>
169 </el-form-item> 199 </el-form-item>
170 - <el-form-item label="上下架状态" prop="status"> 200 + <el-form-item label="是否展示库存" prop="showStock">
  201 + <el-radio-group v-model="baseForm.showStock">
  202 + <el-radio :label="true">是</el-radio>
  203 + <el-radio :label="false">否</el-radio>
  204 + </el-radio-group>
  205 + </el-form-item>
  206 + <el-form-item label="商品状态" prop="status">
171 <el-radio-group v-model="baseForm.status"> 207 <el-radio-group v-model="baseForm.status">
172 <el-radio :label="0">上架</el-radio> 208 <el-radio :label="0">上架</el-radio>
173 <el-radio :label="1">下架</el-radio> 209 <el-radio :label="1">下架</el-radio>
@@ -212,15 +248,15 @@ export default { @@ -212,15 +248,15 @@ export default {
212 categoryIds: null, 248 categoryIds: null,
213 sort: null, 249 sort: null,
214 description: null, 250 description: null,
215 - bannerUrl: null,  
216 - picUrls: [],  
217 - totalStock: null,  
218 - status: 0 251 + picUrls: null,
  252 + status: 0,
  253 + virtualSalesCount: 0,
  254 + showStock: true,
219 }, 255 },
220 categoryList: [], 256 categoryList: [],
221 // 价格库存 257 // 价格库存
222 ratesForm: { 258 ratesForm: {
223 - spec: 0, 259 + spec: 1,
224 // 规格明细 260 // 规格明细
225 rates: [{}] 261 rates: [{}]
226 }, 262 },
@@ -239,28 +275,39 @@ export default { @@ -239,28 +275,39 @@ export default {
239 275
240 // 表单校验 276 // 表单校验
241 rules: { 277 rules: {
242 - description: [  
243 - {required: true, message: "描述不能为空", trigger: "blur"},  
244 - ],  
245 - categoryIds: [  
246 - {required: true, message: "分类id不能为空", trigger: "blur"},  
247 - ],  
248 - bannerUrl: [{required: true, message: "商品主图地址", trigger: "blur"}],  
249 - sort: [  
250 - {required: true, message: "排序字段不能为空", trigger: "blur"},  
251 - ], 278 + name:[{required: true, message: "商品名称不能为空", trigger: "blur"},],
  279 + description: [{required: true, message: "描述不能为空", trigger: "blur"},],
  280 + categoryIds: [{required: true, message: "分类id不能为空", trigger: "blur"},],
  281 + status: [{required: true, message: "商品状态不能为空", trigger: "blur"}],
  282 + picUrls: [{required: true, message: "商品轮播图地址不能为空", trigger: "blur"}],
  283 + virtualSalesCount: [{required: true, message: "虚拟销量不能为空", trigger: "blur"}],
252 }, 284 },
253 }; 285 };
254 }, 286 },
  287 +
255 created() { 288 created() {
256 this.getListCategory(); 289 this.getListCategory();
257 this.getPropertyPageList(); 290 this.getPropertyPageList();
258 }, 291 },
259 methods: { 292 methods: {
  293 + async confirmLeave(active, old){
  294 + await this.$refs[old].validate((valid) => {
  295 + console.log(valid)
  296 + if (!valid) {
  297 + return reject();
  298 + }
  299 + });
  300 + },
  301 + // 必选标识
  302 + addRedStar(h, { column }) {
  303 + return [
  304 + h('span', { style: 'color: #F56C6C' }, '*'),
  305 + h('span', ' ' + column.label)
  306 + ];
  307 + },
260 changeRadio() { 308 changeRadio() {
261 -  
262 - this.$refs.rates.doLayout()  
263 - if (this.ratesForm.spec == 0) { 309 + this.$refs.ratesTable.doLayout()
  310 + if (this.ratesForm.spec == 1) {
264 this.ratesForm.rates = [{}] 311 this.ratesForm.rates = [{}]
265 } else { 312 } else {
266 this.ratesForm.rates = [] 313 this.ratesForm.rates = []
@@ -289,7 +336,7 @@ export default { @@ -289,7 +336,7 @@ export default {
289 return array; 336 return array;
290 }) 337 })
291 .forEach(v => { 338 .forEach(v => {
292 - rates.push({spec: v}) 339 + rates.push({spec: v, status: 0, name: Array.of(v).join()})
293 }); 340 });
294 this.ratesForm.rates = rates 341 this.ratesForm.rates = rates
295 }, 342 },
@@ -304,38 +351,51 @@ export default { @@ -304,38 +351,51 @@ export default {
304 this.$emit("closeDialog"); 351 this.$emit("closeDialog");
305 }, 352 },
306 submit() { 353 submit() {
  354 + this.$refs[this.activeName].validate((valid) => {
  355 + if (!valid) {
  356 + return;
  357 + }
307 let rates = this.ratesForm.rates; 358 let rates = this.ratesForm.rates;
308 // 动态规格调整字段 359 // 动态规格调整字段
309 - if (this.ratesForm.spec == 1) { 360 + if (this.ratesForm.spec == 2) {
310 rates.forEach(r => { 361 rates.forEach(r => {
311 let properties = [] 362 let properties = []
312 - if(r.spec instanceof Array){  
313 - r.spec.forEach((v, i) => { 363 + Array.of(r.spec).forEach((v, i) => {
314 let specValue = this.dynamicSpec[i].specValue.find(o => o.name == v); 364 let specValue = this.dynamicSpec[i].specValue.find(o => o.name == v);
315 let propertie = {}; 365 let propertie = {};
316 propertie.propertyId = this.dynamicSpec[i].specId; 366 propertie.propertyId = this.dynamicSpec[i].specId;
317 propertie.valueId = specValue.id; 367 propertie.valueId = specValue.id;
318 properties.push(propertie); 368 properties.push(propertie);
319 }) 369 })
320 - }else{  
321 - let specValue = this.dynamicSpec[0].specValue.find(o => o.name == r.spec);  
322 - let propertie = {};  
323 - propertie.propertyId = this.dynamicSpec[0].specId;  
324 - propertie.valueId = specValue.id;  
325 - properties.push(propertie);  
326 - }  
327 r.properties = properties; 370 r.properties = properties;
328 }) 371 })
  372 + }else{
  373 + rates[0].name = this.baseForm.name;
  374 + rates[0].status = this.baseForm.status;
329 } 375 }
330 - this.baseForm.skus = rates;  
331 - this.baseForm.specType = this.ratesForm.spec;  
332 - this.baseForm.categoryId = this.baseForm.categoryIds[this.baseForm.categoryIds.length - 1];  
333 - createSpu(this.baseForm).then((response) => { 376 +
  377 + console.log(rates)
  378 +
  379 + let form = this.baseForm
  380 + if(form.picUrls instanceof Array){
  381 + form.picUrls = form.picUrls.flatMap(m=>m.split(','))
  382 + }else if(form.picUrls.split(',') instanceof Array){
  383 + form.picUrls = form.picUrls.split(',').flatMap(m=>m.split(','))
  384 + }else{
  385 + form.picUrls = Array.of(form.picUrls)
  386 + }
  387 +
  388 + form.skus = rates;
  389 + form.specType = this.ratesForm.spec;
  390 + form.categoryId = form.categoryIds[this.baseForm.categoryIds.length - 1];
  391 + createSpu(form).then((response) => {
334 console.log(response) 392 console.log(response)
335 this.$modal.msgSuccess("新增成功"); 393 this.$modal.msgSuccess("新增成功");
336 this.$emit("closeDialog"); 394 this.$emit("closeDialog");
  395 + }).catch((err) => {
  396 + console.log(this.baseForm.picUrls)
  397 + });
337 }); 398 });
338 -  
339 }, 399 },
340 /** 查询规格 */ 400 /** 查询规格 */
341 getPropertyPageList() { 401 getPropertyPageList() {