Commit 07e5e1b59f6dc19315f7092fa996777afb9472b8

Authored by luowenfeng
1 parent 10caa6e8

feature(管理后台): 商品弹窗

yudao-ui-admin/src/views/mall/product/spu/index.vue
1 1 <template>
2 2 <div class="app-container">
3   -
4 3 <!-- 搜索工作栏 -->
5   - <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
  4 + <el-form
  5 + :model="queryParams"
  6 + ref="queryForm"
  7 + size="small"
  8 + :inline="true"
  9 + v-show="showSearch"
  10 + label-width="68px"
  11 + >
6 12 <el-form-item label="商品名称" prop="name">
7   - <el-input v-model="queryParams.name" placeholder="请输入商品名称" clearable @keyup.enter.native="handleQuery"/>
  13 + <el-input
  14 + v-model="queryParams.name"
  15 + placeholder="请输入商品名称"
  16 + clearable
  17 + @keyup.enter.native="handleQuery"
  18 + />
8 19 </el-form-item>
9 20 <el-form-item label="卖点" prop="sellPoint">
10   - <el-input v-model="queryParams.sellPoint" placeholder="请输入卖点" clearable @keyup.enter.native="handleQuery"/>
  21 + <el-input
  22 + v-model="queryParams.sellPoint"
  23 + placeholder="请输入卖点"
  24 + clearable
  25 + @keyup.enter.native="handleQuery"
  26 + />
11 27 </el-form-item>
12 28 <el-form-item label="分类id" prop="categoryId">
13   - <el-input v-model="queryParams.categoryId" placeholder="请输入分类id" clearable @keyup.enter.native="handleQuery"/>
  29 + <el-input
  30 + v-model="queryParams.categoryId"
  31 + placeholder="请输入分类id"
  32 + clearable
  33 + @keyup.enter.native="handleQuery"
  34 + />
14 35 </el-form-item>
15 36 <el-form-item label="价格(分)" prop="price">
16   - <el-input v-model="queryParams.price" placeholder="请输入价格 单位使用:分" clearable @keyup.enter.native="handleQuery"/>
  37 + <el-input
  38 + v-model="queryParams.price"
  39 + placeholder="请输入价格 单位使用:分"
  40 + clearable
  41 + @keyup.enter.native="handleQuery"
  42 + />
17 43 </el-form-item>
18 44 <el-form-item label="库存数量" prop="quantity">
19   - <el-input v-model="queryParams.quantity" placeholder="请输入库存数量" clearable @keyup.enter.native="handleQuery"/>
  45 + <el-input
  46 + v-model="queryParams.quantity"
  47 + placeholder="请输入库存数量"
  48 + clearable
  49 + @keyup.enter.native="handleQuery"
  50 + />
20 51 </el-form-item>
21 52 <el-form-item label="状态" prop="status">
22   - <el-select v-model="queryParams.status" placeholder="请选择上下架状态" clearable size="small">
23   - <el-option label="请选择字典生成" value=""/>
24   - <el-option label="上架" value="0"/>
25   - <el-option label="下架" value="1"/>
  53 + <el-select
  54 + v-model="queryParams.status"
  55 + placeholder="请选择上下架状态"
  56 + clearable
  57 + size="small"
  58 + >
  59 + <el-option label="请选择字典生成" value="" />
  60 + <el-option label="上架" value="0" />
  61 + <el-option label="下架" value="1" />
26 62 </el-select>
27 63 </el-form-item>
28 64 <el-form-item label="创建时间">
29   - <el-date-picker v-model="dateRangeCreateTime" style="width: 240px" value-format="yyyy-MM-dd"
30   - type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"/>
  65 + <el-date-picker
  66 + v-model="dateRangeCreateTime"
  67 + style="width: 240px"
  68 + value-format="yyyy-MM-dd"
  69 + type="daterange"
  70 + range-separator="-"
  71 + start-placeholder="开始日期"
  72 + end-placeholder="结束日期"
  73 + />
31 74 </el-form-item>
32 75 <el-form-item>
33   - <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
  76 + <el-button type="primary" icon="el-icon-search" @click="handleQuery"
  77 + >搜索</el-button
  78 + >
34 79 <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
35 80 </el-form-item>
36 81 </el-form>
... ... @@ -38,95 +83,150 @@
38 83 <!-- 操作工具栏 -->
39 84 <el-row :gutter="10" class="mb8">
40 85 <el-col :span="1.5">
41   - <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
42   - v-hasPermi="['product:spu:create']">新增
  86 + <el-button
  87 + type="primary"
  88 + plain
  89 + icon="el-icon-plus"
  90 + size="mini"
  91 + @click="handleAdd"
  92 + v-hasPermi="['product:spu:create']"
  93 + >新增
43 94 </el-button>
44 95 </el-col>
45 96 <el-col :span="1.5">
46   - <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
47   - :loading="exportLoading"
48   - v-hasPermi="['product:spu:export']">导出
  97 + <el-button
  98 + type="warning"
  99 + plain
  100 + icon="el-icon-download"
  101 + size="mini"
  102 + @click="handleExport"
  103 + :loading="exportLoading"
  104 + v-hasPermi="['product:spu:export']"
  105 + >导出
49 106 </el-button>
50 107 </el-col>
51   - <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  108 + <right-toolbar
  109 + :showSearch.sync="showSearch"
  110 + @queryTable="getList"
  111 + ></right-toolbar>
52 112 </el-row>
53 113  
54 114 <!-- 列表 -->
55 115 <el-table v-loading="loading" :data="list">
56   - <el-table-column label="主键" align="center" prop="id"/>
57   - <el-table-column label="商品名称" align="center" prop="name"/>
  116 + <el-table-column label="主键" align="center" prop="id" />
  117 + <el-table-column label="商品名称" align="center" prop="name" />
58 118 <!-- <el-table-column label="卖点" align="center" prop="sellPoint"/>-->
59 119 <!-- <el-table-column label="描述" align="center" prop="description"/>-->
60   - <el-table-column label="分类id" align="center" prop="categoryId"/>
  120 + <el-table-column label="分类id" align="center" prop="categoryId" />
61 121 <el-table-column label="商品主图地址" align="center" prop="picUrls">
62 122 <template slot-scope="scope">
63   - <img v-if="scope.row.picUrls" :src="scope.row.picUrls[0]" alt="分类图片" class="img-height"/>
  123 + <img
  124 + v-if="scope.row.picUrls"
  125 + :src="scope.row.picUrls[0]"
  126 + alt="分类图片"
  127 + class="img-height"
  128 + />
64 129 </template>
65 130 </el-table-column>
66   - <el-table-column label="排序字段" align="center" prop="sort"/>
67   - <el-table-column label="点赞初始人数" align="center" prop="likeCount"/>
68   - <el-table-column label="价格 (分)" align="center" prop="price"/>
69   - <el-table-column label="库存数量" align="center" prop="quantity"/>
  131 + <el-table-column label="排序字段" align="center" prop="sort" />
  132 + <el-table-column label="点赞初始人数" align="center" prop="likeCount" />
  133 + <el-table-column label="价格 (分)" align="center" prop="price" />
  134 + <el-table-column label="库存数量" align="center" prop="quantity" />
70 135 <!-- <el-table-column label="状态" align="center" prop="status"/>-->
71   - <el-table-column label="创建时间" align="center" prop="createTime" width="180">
  136 + <el-table-column
  137 + label="创建时间"
  138 + align="center"
  139 + prop="createTime"
  140 + width="180"
  141 + >
72 142 <template slot-scope="scope">
73 143 <span>{{ parseTime(scope.row.createTime) }}</span>
74 144 </template>
75 145 </el-table-column>
76   - <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  146 + <el-table-column
  147 + label="操作"
  148 + align="center"
  149 + class-name="small-padding fixed-width"
  150 + >
77 151 <template slot-scope="scope">
78   - <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
79   - v-hasPermi="['product:spu:update']">修改
  152 + <el-button
  153 + size="mini"
  154 + type="text"
  155 + icon="el-icon-edit"
  156 + @click="handleUpdate(scope.row)"
  157 + v-hasPermi="['product:spu:update']"
  158 + >修改
80 159 </el-button>
81   - <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
82   - v-hasPermi="['product:spu:delete']">删除
  160 + <el-button
  161 + size="mini"
  162 + type="text"
  163 + icon="el-icon-delete"
  164 + @click="handleDelete(scope.row)"
  165 + v-hasPermi="['product:spu:delete']"
  166 + >删除
83 167 </el-button>
84 168 </template>
85 169 </el-table-column>
86 170 </el-table>
87 171 <!-- 分页组件 -->
88   - <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
89   - @pagination="getList"/>
  172 + <pagination
  173 + v-show="total > 0"
  174 + :total="total"
  175 + :page.sync="queryParams.pageNo"
  176 + :limit.sync="queryParams.pageSize"
  177 + @pagination="getList"
  178 + />
  179 +
90 180  
  181 +<el-dialog :title="title" :visible.sync="open" width="900px" append-to-body >
  182 + <save @closeDialog="open = false"/>
  183 +</el-dialog>
91 184 <!-- 对话框(添加 / 修改) -->
92   - <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body>
  185 + <!-- <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body>
93 186 <el-form ref="form" :model="form" :rules="rules" label-width="80px">
94 187 <el-form-item label="商品名称" prop="name">
95   - <el-input v-model="form.name" placeholder="请输入商品名称"/>
  188 + <el-input v-model="form.name" placeholder="请输入商品名称" />
96 189 </el-form-item>
97 190 <el-form-item label="卖点" prop="sellPoint">
98   - <el-input v-model="form.sellPoint" placeholder="请输入卖点"/>
  191 + <el-input v-model="form.sellPoint" placeholder="请输入卖点" />
99 192 </el-form-item>
100 193 <el-form-item label="描述">
101   - <editor v-model="form.description" :min-height="192"/>
  194 + <editor v-model="form.description" :min-height="192" />
102 195 </el-form-item>
103 196 <el-form-item label="分类id" prop="categoryIds">
104 197 <el-cascader
105   - v-model="form.categoryIds"
106   - placeholder="请输入分类id"
107   - style="width: 100%"
108   - :options="categoryList"
109   - :props="propName"
110   - clearable></el-cascader>
  198 + v-model="form.categoryIds"
  199 + placeholder="请输入分类id"
  200 + style="width: 100%"
  201 + :options="categoryList"
  202 + :props="propName"
  203 + clearable
  204 + ></el-cascader>
111 205 </el-form-item>
112 206 <el-form-item label="商品主图地址" prop="picUrls">
113   - <ImageUpload v-model="form.picUrls" :limit="10"/>
  207 + <ImageUpload v-model="form.picUrls" :limit="10" />
114 208 </el-form-item>
115 209 <el-form-item label="商品规格">
116 210 <el-button size="mini" @click="shopTagInput()">添加规格</el-button>
117 211 <div v-for="(tag, tagIndex) in skuTags" :key="tagIndex">
118 212 <span>{{ tag.name }}</span>
119   - <el-button style="margin-left: 10px" class="button-new-tag" type="text" icon="el-icon-delete"
120   - @click="removeTag(tagIndex)">删除
  213 + <el-button
  214 + style="margin-left: 10px"
  215 + class="button-new-tag"
  216 + type="text"
  217 + icon="el-icon-delete"
  218 + @click="removeTag(tagIndex)"
  219 + >删除
121 220 </el-button>
122   - <br/>
  221 + <br />
123 222 <el-tag
124   - v-for="(tagItem, tagItemIndex) in tag.selectValues"
125   - :key="tagItem"
126   - style="margin-right: 10px"
127   - :disable-transitions="false">
  223 + v-for="(tagItem, tagItemIndex) in tag.selectValues"
  224 + :key="tagItemIndex"
  225 + style="margin-right: 10px"
  226 + :disable-transitions="false"
  227 + >
128 228 {{ tagItem }}
129   - </el-tag>
  229 + </el-tag> -->
130 230 <!-- <el-input-->
131 231 <!-- class="input-new-tag"-->
132 232 <!-- v-if="tagItemInputs[tagIndex] && tagItemInputs[tagIndex].visible"-->
... ... @@ -136,134 +236,178 @@
136 236 <!-- @keyup.enter.native="handleInputConfirm(tagIndex)"-->
137 237 <!-- @blur="handleInputConfirm(tagIndex)">-->
138 238 <!-- </el-input>-->
139   - </div>
  239 + <!-- </div>
140 240 </el-form-item>
141 241 <el-form-item label="规格名" v-show="isShowTagInput">
142 242 <el-col :span="8">
143   - <el-select v-model="addTagInput.name" filterable allow-create default-first-option placeholder="请选择"
144   - @change="handleTagClick">
  243 + <el-select
  244 + v-model="addTagInput.name"
  245 + filterable
  246 + allow-create
  247 + default-first-option
  248 + placeholder="请选择"
  249 + @change="handleTagClick"
  250 + >
145 251 <el-option
146   - v-for="item in unUseTags"
147   - :key="item.id"
148   - :label="item.name"
149   - :value="item.name">
  252 + v-for="item in unUseTags"
  253 + :key="item.id"
  254 + :label="item.name"
  255 + :value="item.name"
  256 + >
150 257 </el-option>
151 258 </el-select>
152 259 </el-col>
153 260 </el-form-item>
154 261 <el-form-item label="规格值" v-show="isShowTagInput">
155 262 <el-col :span="8">
156   - <el-select v-model="addTagInput.selectValues" multiple filterable allow-create default-first-option
157   - placeholder="请选择">
  263 + <el-select
  264 + v-model="addTagInput.selectValues"
  265 + multiple
  266 + filterable
  267 + allow-create
  268 + default-first-option
  269 + placeholder="请选择"
  270 + >
158 271 <el-option
159   - v-for="item in dbTagValues"
160   - :key="item.id"
161   - :label="item.name"
162   - :value="item.name">
  272 + v-for="item in dbTagValues"
  273 + :key="item.id"
  274 + :label="item.name"
  275 + :value="item.name"
  276 + >
163 277 </el-option>
164 278 </el-select>
165 279 </el-col>
166 280 </el-form-item>
167 281 <el-form-item>
168   - <el-button size="mini" type="primary" @click="addTag()" v-show="isShowTagInput">确定</el-button>
169   - <el-button size="mini" @click="hideTagInput()" v-show="isShowTagInput">取消</el-button>
  282 + <el-button
  283 + size="mini"
  284 + type="primary"
  285 + @click="addTag()"
  286 + v-show="isShowTagInput"
  287 + >确定</el-button
  288 + >
  289 + <el-button size="mini" @click="hideTagInput()" v-show="isShowTagInput"
  290 + >取消</el-button
  291 + >
170 292 </el-form-item>
171   - <el-form-item v-if="form.skus.length>0">
  293 + <el-form-item v-if="form.skus.length > 0">
172 294 <el-table
173   - :data="form.skus"
174   - border
175   - style="width: 100%; margin-top: 20px"
176   - :span-method="tableSpanMethod">
177   - <el-table-column v-for="(leftTitle, index) in skuTags" :key="index" :label="leftTitle.name">
  295 + :data="form.skus"
  296 + border
  297 + style="width: 100%; margin-top: 20px"
  298 + :span-method="tableSpanMethod"
  299 + >
  300 + <el-table-column
  301 + v-for="(leftTitle, index) in skuTags"
  302 + :key="index"
  303 + :label="leftTitle.name"
  304 + >
178 305 <template slot-scope="scope">
179 306 {{ scope.row.propertyChildNames[index] }}
180 307 </template>
181 308 </el-table-column>
182   - <el-table-column v-if="skuTags.length"
183   - prop="picUrl"
184   - label="sku图片"
185   - width="180">
  309 + <el-table-column
  310 + v-if="skuTags.length"
  311 + prop="picUrl"
  312 + label="sku图片"
  313 + width="180"
  314 + >
186 315 <template slot-scope="scope">
187 316 <ImageUpload v-model="scope.row.picUrl" :limit="1">
188 317 </ImageUpload>
189 318 </template>
190 319 </el-table-column>
191 320 <el-table-column
192   - prop="prodName"
193   - label="条形码"
194   - width="250" v-if="skuTags.length">
  321 + prop="prodName"
  322 + label="条形码"
  323 + width="250"
  324 + v-if="skuTags.length"
  325 + >
195 326 <template slot-scope="scope">
196   - <el-input v-model="scope.row.barCode" type="textarea" :disabled="scope.row.status==1"></el-input>
  327 + <el-input
  328 + v-model="scope.row.barCode"
  329 + type="textarea"
  330 + :disabled="scope.row.status == 1"
  331 + ></el-input>
197 332 </template>
198 333 </el-table-column>
199   - <el-table-column
200   - prop="price"
201   - label="销售价">
  334 + <el-table-column prop="price" label="销售价">
202 335 <template slot-scope="scope">
203 336 <el-input-number
204   - size="small"
205   - v-model="scope.row.price"
206   - controls-position="right"
207   - :precision="2"
208   - :max="1000000000"
209   - :min="0.01"
210   - :disabled="scope.row.status==1">
  337 + size="small"
  338 + v-model="scope.row.price"
  339 + controls-position="right"
  340 + :precision="2"
  341 + :max="1000000000"
  342 + :min="0.01"
  343 + :disabled="scope.row.status == 1"
  344 + >
211 345 </el-input-number>
212 346 </template>
213 347 </el-table-column>
214   - <el-table-column
215   - prop="oriPrice"
216   - label="成本价">
  348 + <el-table-column prop="oriPrice" label="成本价">
217 349 <template slot-scope="scope">
218 350 <el-input-number
219   - size="small"
220   - v-model="scope.row.costPrice"
221   - controls-position="right"
222   - :precision="2"
223   - :max="1000000000"
224   - :min="0.01"
225   - :disabled="scope.row.status==1">
  351 + size="small"
  352 + v-model="scope.row.costPrice"
  353 + controls-position="right"
  354 + :precision="2"
  355 + :max="1000000000"
  356 + :min="0.01"
  357 + :disabled="scope.row.status == 1"
  358 + >
226 359 </el-input-number>
227 360 </template>
228 361 </el-table-column>
229   - <el-table-column
230   - prop="oriPrice"
231   - label="原价">
  362 + <el-table-column prop="oriPrice" label="原价">
232 363 <template slot-scope="scope">
233 364 <el-input-number
234   - size="small"
235   - v-model="scope.row.originalPrice"
236   - controls-position="right"
237   - :precision="2"
238   - :max="1000000000"
239   - :min="0.01"
240   - :disabled="scope.row.status==1">
  365 + size="small"
  366 + v-model="scope.row.originalPrice"
  367 + controls-position="right"
  368 + :precision="2"
  369 + :max="1000000000"
  370 + :min="0.01"
  371 + :disabled="scope.row.status == 1"
  372 + >
241 373 </el-input-number>
242 374 </template>
243 375 </el-table-column>
244   - <el-table-column
245   - label="操作">
  376 + <el-table-column label="操作">
246 377 <template slot-scope="scope">
247   - <el-button type="text" size="small" @click="changeSkuStatus(`${scope.$index}`)"
248   - v-if="scope.row.status===0">
  378 + <el-button
  379 + type="text"
  380 + size="small"
  381 + @click="changeSkuStatus(`${scope.$index}`)"
  382 + v-if="scope.row.status === 0"
  383 + >
249 384 正常
250 385 </el-button>
251   - <el-button type="text" size="small" @click="changeSkuStatus(`${scope.$index}`)" v-else>已禁用</el-button>
  386 + <el-button
  387 + type="text"
  388 + size="small"
  389 + @click="changeSkuStatus(`${scope.$index}`)"
  390 + v-else
  391 + >已禁用</el-button
  392 + >
252 393 </template>
253 394 </el-table-column>
254 395 </el-table>
255 396 </el-form-item>
256 397 <el-form-item label="排序字段" prop="sort">
257   - <el-input v-model="form.sort" placeholder="请输入排序字段"/>
  398 + <el-input v-model="form.sort" placeholder="请输入排序字段" />
258 399 </el-form-item>
259 400 <el-form-item label="点赞初始人数" prop="likeCount">
260   - <el-input v-model="form.likeCount" placeholder="请输入点赞初始人数"/>
  401 + <el-input v-model="form.likeCount" placeholder="请输入点赞初始人数" />
261 402 </el-form-item>
262 403 <el-form-item label="价格 单位使用:分" prop="price">
263   - <el-input v-model="form.price" placeholder="请输入价格 单位使用:分"/>
  404 + <el-input
  405 + v-model="form.price"
  406 + placeholder="请输入价格 单位使用:分"
  407 + />
264 408 </el-form-item>
265 409 <el-form-item label="库存数量" prop="quantity">
266   - <el-input v-model="form.quantity" placeholder="请输入库存数量"/>
  410 + <el-input v-model="form.quantity" placeholder="请输入库存数量" />
267 411 </el-form-item>
268 412 <el-form-item label="上下架状态" prop="status">
269 413 <el-radio-group v-model="form.status">
... ... @@ -276,19 +420,26 @@
276 420 <el-button type="primary" @click="submitForm">确 定</el-button>
277 421 <el-button @click="cancel">取 消</el-button>
278 422 </div>
279   - </el-dialog>
  423 + </el-dialog> -->
280 424 </div>
281 425 </template>
282 426  
283 427 <script>
284   -import {createSpu, updateSpu, deleteSpu, getSpu, getSpuPage, exportSpuExcel} from "@/api/mall/product/spu";
  428 +import {
  429 + createSpu,
  430 + updateSpu,
  431 + deleteSpu,
  432 + getSpu,
  433 + getSpuPage,
  434 + exportSpuExcel,
  435 +} from "@/api/mall/product/spu";
285 436 import {
286 437 createProductCategory,
287 438 deleteProductCategory,
288 439 exportCategoryExcel,
289 440 getProductCategory,
290 441 getProductCategoryList,
291   - updateProductCategory
  442 + updateProductCategory,
292 443 } from "@/api/mall/product/category";
293 444 import {
294 445 createProperty,
... ... @@ -296,16 +447,19 @@ import {
296 447 deleteProperty,
297 448 getProperty,
298 449 getPropertyPage,
299   - exportPropertyExcel
  450 + exportPropertyExcel,
300 451 } from "@/api/mall/product/property";
301 452  
302   -import Editor from '@/components/Editor';
303   -import ImageUpload from '@/components/ImageUpload';
  453 +import Editor from "@/components/Editor";
  454 +import ImageUpload from "@/components/ImageUpload";
  455 +import save from "./save";
304 456  
305 457 export default {
306 458 name: "Spu",
307 459 components: {
308   - Editor, ImageUpload
  460 + Editor,
  461 + ImageUpload,
  462 + save,
309 463 },
310 464 data() {
311 465 return {
... ... @@ -316,17 +470,17 @@ export default {
316 470 propertyPageList: [],
317 471 isShowTagInput: false,
318 472 addTagInput: {
319   - name: '',
320   - propertyId: '',
  473 + name: "",
  474 + propertyId: "",
321 475 selectValues: [],
322 476 selectValueIds: [],
323   - selectObect:[],
  477 + selectObect: [],
324 478 },
325 479 skuTags: [],
326 480 propName: {
327 481 checkStrictly: true,
328   - label: 'name',
329   - value: 'id'
  482 + label: "name",
  483 + value: "id",
330 484 },
331 485 categoryList: [],
332 486 // 遮罩层
... ... @@ -378,91 +532,101 @@ export default {
378 532 },
379 533 // 表单校验
380 534 rules: {
381   - sellPoint: [{required: true, message: "卖点不能为空", trigger: "blur"}],
382   - description: [{required: true, message: "描述不能为空", trigger: "blur"}],
383   - categoryIds: [{required: true, message: "分类id不能为空", trigger: "blur"}],
384   - picUrls: [{required: true, message: "商品主图地址", trigger: "blur"}],
385   - sort: [{required: true, message: "排序字段不能为空", trigger: "blur"}],
  535 + sellPoint: [
  536 + { required: true, message: "卖点不能为空", trigger: "blur" },
  537 + ],
  538 + description: [
  539 + { required: true, message: "描述不能为空", trigger: "blur" },
  540 + ],
  541 + categoryIds: [
  542 + { required: true, message: "分类id不能为空", trigger: "blur" },
  543 + ],
  544 + picUrls: [{ required: true, message: "商品主图地址", trigger: "blur" }],
  545 + sort: [
  546 + { required: true, message: "排序字段不能为空", trigger: "blur" },
  547 + ],
386 548 },
387 549 tagIndex: 0,
388 550 };
389 551 },
390 552 created() {
391   -
392 553 this.getList();
393 554 this.getPropertyPageList();
394 555 this.getListCategory();
395 556 },
396 557 methods: {
397 558 getTableSpecData() {
398   - return this.value
399   - },
400   - tableSpanMethod({row, column, rowIndex, columnIndex}) {
401   -
  559 + return this.value;
402 560 },
  561 + tableSpanMethod({ row, column, rowIndex, columnIndex }) {},
403 562 changeSkuStatus(tagIndex) {
404 563 if (this.form.skus[tagIndex].status == 0) {
405 564 this.form.skus[tagIndex].status = 1;
406 565 } else {
407 566 this.form.skus[tagIndex].status = 0;
408 567 }
409   -
410 568 },
411 569 skuAddProdName() {
412 570 if (this.initing) {
413   - return
  571 + return;
414 572 }
415   - let skuList = []
  573 + let skuList = [];
416 574 for (let i = 0; i < this.value.length; i++) {
417   - const sku = Object.assign({}, this.value[i])
  575 + const sku = Object.assign({}, this.value[i]);
418 576 if (!sku.properties) {
419   - return
  577 + return;
420 578 }
421   - sku.skuName = ''
422   - let properties = sku.properties.split(';')
  579 + sku.skuName = "";
  580 + let properties = sku.properties.split(";");
423 581 for (const propertiesKey in properties) {
424   - sku.skuName += properties[propertiesKey].split(':')[1] + ' '
  582 + sku.skuName += properties[propertiesKey].split(":")[1] + " ";
425 583 }
426   - sku.prodName = this.prodName + ' ' + sku.skuName
427   - skuList.push(sku)
  584 + sku.prodName = this.prodName + " " + sku.skuName;
  585 + skuList.push(sku);
428 586 }
429   - this.$emit('input', skuList)
430   - },
431   - handleTagClose(tagIndex, tagItemIndex) {
432   -
  587 + this.$emit("input", skuList);
433 588 },
  589 + handleTagClose(tagIndex, tagItemIndex) {},
434 590 //确定添加sku规格
435 591 addTag() {
436   -
437 592 let skus = this.unUseTags.map(function (item, index) {
438   - return item.name
  593 + return item.name;
439 594 });
440 595 let index = skus.indexOf(this.addTagInput.name);
441 596  
442 597 this.addTagInput.propertyId = this.unUseTags[index].id;
443 598 for (let i = 0; i < this.addTagInput.selectValues.length; i++) {
444   - for (let j = 0; j < this.unUseTags[index].propertyValueList.length; j++) {
445   - if (this.addTagInput.selectValues[i] === this.unUseTags[index].propertyValueList[j].name) {
446   - this.addTagInput.selectValueIds.push(this.unUseTags[index].propertyValueList[j].id)
  599 + for (
  600 + let j = 0;
  601 + j < this.unUseTags[index].propertyValueList.length;
  602 + j++
  603 + ) {
  604 + if (
  605 + this.addTagInput.selectValues[i] ===
  606 + this.unUseTags[index].propertyValueList[j].name
  607 + ) {
  608 + this.addTagInput.selectValueIds.push(
  609 + this.unUseTags[index].propertyValueList[j].id
  610 + );
447 611 this.addTagInput.selectObect.push({
448   - id:this.unUseTags[index].propertyValueList[j].id,
449   - name:this.unUseTags[index].propertyValueList[j].name,
450   - })
  612 + id: this.unUseTags[index].propertyValueList[j].id,
  613 + name: this.unUseTags[index].propertyValueList[j].name,
  614 + });
451 615 }
452 616 }
453 617 }
454   - let addTagInput = JSON.parse(JSON.stringify(this.addTagInput))
  618 + let addTagInput = JSON.parse(JSON.stringify(this.addTagInput));
455 619 this.skuTags.push(addTagInput);
456 620  
457 621 // if (this.skuTags.length > 1) {
458 622 this.skuTags = this.skuTags.sort((a, b) => a.propertyId - b.propertyId);
459   - this.skuTags.forEach(function (item,index) {
460   - item.selectObect = item.selectObect.sort((a, b) => a.id - b.id)
461   - })
  623 + this.skuTags.forEach(function (item, index) {
  624 + item.selectObect = item.selectObect.sort((a, b) => a.id - b.id);
  625 + });
462 626  
463   - for (let i = 0; i <this.skuTags.length ; i++) {
464   - let selectValueIds=[];
465   - let selectValues=[];
  627 + for (let i = 0; i < this.skuTags.length; i++) {
  628 + let selectValueIds = [];
  629 + let selectValues = [];
466 630 for (let j = 0; j < this.skuTags[i].selectObect.length; j++) {
467 631 selectValueIds.push(this.skuTags[i].selectObect[j].id);
468 632 selectValues.push(this.skuTags[i].selectObect[j].name);
... ... @@ -489,17 +653,23 @@ export default {
489 653 propertyNames.push(skuTags[i].name);
490 654 }
491 655  
492   - let skuAll = sku1s.reduce((x, y) => {
493   - let arr = [];
494   - x.forEach(m => y.forEach(y => arr.push(m.concat([y]))))
495   - return arr;
496   - }, [[]])
  656 + let skuAll = sku1s.reduce(
  657 + (x, y) => {
  658 + let arr = [];
  659 + x.forEach((m) => y.forEach((y) => arr.push(m.concat([y]))));
  660 + return arr;
  661 + },
  662 + [[]]
  663 + );
497 664  
498   - let skuIdAll = skuIds.reduce((x, y) => {
499   - let arr = [];
500   - x.forEach(m => y.forEach(y => arr.push(m.concat([y]))))
501   - return arr;
502   - }, [[]])
  665 + let skuIdAll = skuIds.reduce(
  666 + (x, y) => {
  667 + let arr = [];
  668 + x.forEach((m) => y.forEach((y) => arr.push(m.concat([y]))));
  669 + return arr;
  670 + },
  671 + [[]]
  672 + );
503 673  
504 674 for (let i = 0; i < skuAll.length; i++) {
505 675 let han = {
... ... @@ -508,33 +678,32 @@ export default {
508 678 propertyChildNames: skuAll[i],
509 679 propertyChildIds: skuIdAll[i],
510 680 properties: [],
511   - picUrl: '',
512   - costPrice: '',
513   - originalPrice: '',
514   - spuId: '',
515   - prodName: '',
516   - price: '',
517   - barCode: '',
518   - status: '0',
519   - }
  681 + picUrl: "",
  682 + costPrice: "",
  683 + originalPrice: "",
  684 + spuId: "",
  685 + prodName: "",
  686 + price: "",
  687 + barCode: "",
  688 + status: "0",
  689 + };
520 690 this.form.skus.push(han);
521 691 }
522   - this.form.skus.forEach(x => {
  692 + this.form.skus.forEach((x) => {
523 693 x.properties = [];
524 694 for (let i = 0; i < x.propertyIds.length; i++) {
525 695 x.properties.push({
526 696 propertyId: x.propertyIds[i],
527   - valueId: x.propertyChildIds[i]
528   - })
  697 + valueId: x.propertyChildIds[i],
  698 + });
529 699 }
530   - })
531   -
  700 + });
532 701 },
533 702 hideTagInput() {
534 703 this.isShowTagInput = false;
535 704 this.addTagInput = {
536   - name: '',
537   - propertyId: '',
  705 + name: "",
  706 + propertyId: "",
538 707 selectValues: [],
539 708 selectValueIds: [],
540 709 selectObect: [],
... ... @@ -542,12 +711,12 @@ export default {
542 711 },
543 712 shopTagInput() {
544 713 if (this.unUseTags.length <= 0) {
545   - return this.$message.error("规格已经添加完毕")
  714 + return this.$message.error("规格已经添加完毕");
546 715 }
547 716 this.isShowTagInput = true;
548 717 this.addTagInput = {
549   - name: '',
550   - propertyId: '',
  718 + name: "",
  719 + propertyId: "",
551 720 selectValues: [],
552 721 selectValueIds: [],
553 722 selectObect: [],
... ... @@ -556,8 +725,8 @@ export default {
556 725 //删除已选的规格
557 726 removeTag(row) {
558 727 let skus = this.allhistoryTags.map(function (item, index) {
559   - return item.name
560   - })
  728 + return item.name;
  729 + });
561 730 let index = skus.indexOf(this.skuTags[row].name);
562 731 this.unUseTags.push(this.allhistoryTags[index]);
563 732 this.skuTags.splice(row, 1);
... ... @@ -566,38 +735,37 @@ export default {
566 735 handleTagClick(row) {
567 736 for (let i = 0; i < this.propertyPageList.length; i++) {
568 737 if (row == this.propertyPageList[i].name) {
569   - this.dbTagValues = this.propertyPageList[i].propertyValueList
  738 + this.dbTagValues = this.propertyPageList[i].propertyValueList;
570 739 }
571 740 }
572 741 },
573 742 /** 查询规格 */
574 743 getPropertyPageList() {
575 744 // 执行查询
576   - getPropertyPage().then(response => {
  745 + getPropertyPage().then((response) => {
577 746 this.propertyPageList = response.data.list;
578 747  
579 748 this.unUseTags = this.propertyPageList.map(function (item, index) {
580   - return item
581   - })
  749 + return item;
  750 + });
582 751 this.allhistoryTags = JSON.parse(JSON.stringify(this.unUseTags));
583 752 });
584 753 },
585 754 /** 查询分类 */
586 755 getListCategory() {
587 756 // 执行查询
588   - getProductCategoryList().then(response => {
  757 + getProductCategoryList().then((response) => {
589 758 this.categoryList = this.handleTree(response.data, "id", "parentId");
590   -
591 759 });
592 760 },
593 761 /** 查询列表 */
594 762 getList() {
595 763 this.loading = true;
596 764 // 处理查询参数
597   - let params = {...this.queryParams};
598   - this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
  765 + let params = { ...this.queryParams };
  766 + this.addBeginAndEndTime(params, this.dateRangeCreateTime, "createTime");
599 767 // 执行查询
600   - getSpuPage(params).then(response => {
  768 + getSpuPage(params).then((response) => {
601 769 this.list = response.data.list;
602 770 this.total = response.data.total;
603 771 this.loading = false;
... ... @@ -610,7 +778,6 @@ export default {
610 778 },
611 779 /** 表单重置 */
612 780 reset() {
613   -
614 781 this.form = {
615 782 id: undefined,
616 783 name: undefined,
... ... @@ -652,7 +819,7 @@ export default {
652 819 handleUpdate(row) {
653 820 this.reset();
654 821 const id = row.id;
655   - getSpu(id).then(response => {
  822 + getSpu(id).then((response) => {
656 823 let dataSpu = response.data;
657 824 this.form = {
658 825 id: dataSpu.id,
... ... @@ -680,11 +847,15 @@ export default {
680 847 },
681 848 getDataHandle() {
682 849 let that = this;
683   - let productPropertyViews = JSON.parse(JSON.stringify(this.form.productPropertyViews));
684   - productPropertyViews = productPropertyViews.sort((a, b) => a.propertyId - b.propertyId);
685   - productPropertyViews.forEach(item => {
  850 + let productPropertyViews = JSON.parse(
  851 + JSON.stringify(this.form.productPropertyViews)
  852 + );
  853 + productPropertyViews = productPropertyViews.sort(
  854 + (a, b) => a.propertyId - b.propertyId
  855 + );
  856 + productPropertyViews.forEach((item) => {
686 857 item.propertyValues = item.propertyValues.sort((a, b) => a.v1 - b.v1);
687   - })
  858 + });
688 859 let skuIds = [];
689 860 for (let i = 0; i < productPropertyViews.length; i++) {
690 861 let han = {
... ... @@ -692,17 +863,21 @@ export default {
692 863 propertyId: productPropertyViews[i].propertyId,
693 864 selectValues: [],
694 865 selectValueIds: [],
695   - }
696   - for (let j = 0; j < productPropertyViews[i].propertyValues.length; j++) {
  866 + };
  867 + for (
  868 + let j = 0;
  869 + j < productPropertyViews[i].propertyValues.length;
  870 + j++
  871 + ) {
697 872 han.selectValues.push(productPropertyViews[i].propertyValues[j].v2);
698 873 han.selectValueIds.push(productPropertyViews[i].propertyValues[j].v1);
699 874 }
700   - skuIds.push(han)
  875 + skuIds.push(han);
701 876 }
702 877 this.skuTags = skuIds;
703 878 this.unUseTags = this.allhistoryTags.filter((v) =>
704   - skuIds.every((val) => val.name != v.name)
705   - )
  879 + skuIds.every((val) => val.name != v.name)
  880 + );
706 881 this.getHandleTable();
707 882 },
708 883 getHandleTable() {
... ... @@ -718,17 +893,23 @@ export default {
718 893 propertyIds.push(skuTags[i].propertyId);
719 894 propertyNames.push(skuTags[i].name);
720 895 }
721   - let skuAll = sku1s.reduce((x, y) => {
722   - let arr = [];
723   - x.forEach(m => y.forEach(y => arr.push(m.concat([y]))))
724   - return arr;
725   - }, [[]])
  896 + let skuAll = sku1s.reduce(
  897 + (x, y) => {
  898 + let arr = [];
  899 + x.forEach((m) => y.forEach((y) => arr.push(m.concat([y]))));
  900 + return arr;
  901 + },
  902 + [[]]
  903 + );
726 904  
727   - let skuIdAll = skuIds.reduce((x, y) => {
728   - let arr = [];
729   - x.forEach(m => y.forEach(y => arr.push(m.concat([y]))))
730   - return arr;
731   - }, [[]])
  905 + let skuIdAll = skuIds.reduce(
  906 + (x, y) => {
  907 + let arr = [];
  908 + x.forEach((m) => y.forEach((y) => arr.push(m.concat([y]))));
  909 + return arr;
  910 + },
  911 + [[]]
  912 + );
732 913  
733 914 for (let i = 0; i < skuAll.length; i++) {
734 915 let han = {
... ... @@ -745,33 +926,32 @@ export default {
745 926 price: this.form.skusList[i].price,
746 927 barCode: this.form.skusList[i].barCode,
747 928 status: this.form.skusList[i].status,
748   - }
  929 + };
749 930 this.form.skus.push(han);
750 931 }
751   - this.form.skus.forEach(x => {
  932 + this.form.skus.forEach((x) => {
752 933 x.properties = [];
753 934 for (let i = 0; i < x.propertyIds.length; i++) {
754 935 x.properties.push({
755 936 propertyId: x.propertyIds[i],
756   - valueId: x.propertyChildIds[i]
757   - })
  937 + valueId: x.propertyChildIds[i],
  938 + });
758 939 }
759   - })
760   -
  940 + });
761 941 },
762 942 /** 提交按钮 */
763 943 submitForm() {
764   -
765   - this.$refs["form"].validate(valid => {
  944 + this.$refs["form"].validate((valid) => {
766 945 if (!valid) {
767 946 return;
768 947 }
769   - this.form.picUrls = this.form.picUrls.split(',');
770   - this.form.categoryId = this.form.categoryIds[(this.form.categoryIds.length - 1)];
  948 + this.form.picUrls = this.form.picUrls.split(",");
  949 + this.form.categoryId =
  950 + this.form.categoryIds[this.form.categoryIds.length - 1];
771 951 this.form.status = Number(this.form.status);
772 952 // 修改的提交
773 953 if (this.form.id != null) {
774   - updateSpu(this.form).then(response => {
  954 + updateSpu(this.form).then((response) => {
775 955 this.$modal.msgSuccess("修改成功");
776 956 this.open = false;
777 957 this.getList();
... ... @@ -779,7 +959,7 @@ export default {
779 959 return;
780 960 }
781 961 // 添加的提交
782   - createSpu(this.form).then(response => {
  962 + createSpu(this.form).then((response) => {
783 963 this.$modal.msgSuccess("新增成功");
784 964 this.open = false;
785 965 this.getList();
... ... @@ -789,32 +969,38 @@ export default {
789 969 /** 删除按钮操作 */
790 970 handleDelete(row) {
791 971 const id = row.id;
792   - this.$modal.confirm('是否确认删除商品spu编号为"' + id + '"的数据项?').then(function () {
793   - return deleteSpu(id);
794   - }).then(() => {
795   - this.getList();
796   - this.$modal.msgSuccess("删除成功");
797   - }).catch(() => {
798   - });
  972 + this.$modal
  973 + .confirm('是否确认删除商品spu编号为"' + id + '"的数据项?')
  974 + .then(function () {
  975 + return deleteSpu(id);
  976 + })
  977 + .then(() => {
  978 + this.getList();
  979 + this.$modal.msgSuccess("删除成功");
  980 + })
  981 + .catch(() => {});
799 982 },
800 983 /** 导出按钮操作 */
801 984 handleExport() {
802 985 // 处理查询参数
803   - let params = {...this.queryParams};
  986 + let params = { ...this.queryParams };
804 987 params.pageNo = undefined;
805 988 params.pageSize = undefined;
806   - this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
  989 + this.addBeginAndEndTime(params, this.dateRangeCreateTime, "createTime");
807 990 // 执行导出
808   - this.$modal.confirm('是否确认导出所有商品spu数据项?').then(() => {
809   - this.exportLoading = true;
810   - return exportSpuExcel(params);
811   - }).then(response => {
812   - this.$download.excel(response, '商品spu.xls');
813   - this.exportLoading = false;
814   - }).catch(() => {
815   - });
816   - }
817   - }
  991 + this.$modal
  992 + .confirm("是否确认导出所有商品spu数据项?")
  993 + .then(() => {
  994 + this.exportLoading = true;
  995 + return exportSpuExcel(params);
  996 + })
  997 + .then((response) => {
  998 + this.$download.excel(response, "商品spu.xls");
  999 + this.exportLoading = false;
  1000 + })
  1001 + .catch(() => {});
  1002 + },
  1003 + },
818 1004 };
819 1005 </script>
820 1006 <style lang="scss">
... ...
yudao-ui-admin/src/views/mall/product/spu/save.vue 0 → 100644
  1 +<template>
  2 + <div class="container">
  3 + <el-dialog
  4 + title="请输入规格值,多个请换行"
  5 + :visible.sync="dialogForSpec"
  6 + append-to-body
  7 + width="400px"
  8 + @close="dialogForSpec = false; specValue = null"
  9 + >
  10 + <el-input
  11 + v-model="specValue"
  12 + type="textarea"
  13 + :autosize="{ minRows: 6, maxRows: 6}"
  14 + placeholder="请输入内容"
  15 + />
  16 +
  17 + <div slot="footer" class="dialog-footer">
  18 + <el-button @click="dialogForSpec = false; specValue = null">取 消</el-button>
  19 + <el-button type="primary" @click="addSpecValue">确 定</el-button>
  20 + </div>
  21 + </el-dialog>
  22 +
  23 + <el-tabs v-model="activeName" class="tabs">
  24 + <!-- 基础设置 -->
  25 + <el-tab-pane label="基础设置" name="base">
  26 + <el-form ref="baseForm" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%">
  27 + <el-form-item label="商品名称" prop="name">
  28 + <el-input v-model="baseForm.name" placeholder="请输入商品名称"/>
  29 + </el-form-item>
  30 + <el-form-item label="卖点" prop="sellPoint">
  31 + <el-input v-model="baseForm.sellPoint" placeholder="请输入卖点"/>
  32 + </el-form-item>
  33 + <el-form-item label="分类id" prop="categoryIds">
  34 + <el-cascader
  35 + v-model="baseForm.categoryIds"
  36 + placeholder="请输入分类id"
  37 + style="width: 100%"
  38 + :options="categoryList"
  39 + :props="propName"
  40 + clearable
  41 + ></el-cascader>
  42 + </el-form-item>
  43 + <el-form-item label="商品主图" prop="picUrls">
  44 + <ImageUpload v-model="baseForm.picUrl" :limit="1" />
  45 + </el-form-item>
  46 + <el-form-item label="商品轮播图" prop="picUrl">
  47 + <ImageUpload v-model="baseForm.picUrls" :limit="10" />
  48 + </el-form-item>
  49 + <el-form-item label="排序字段" prop="sort">
  50 + <el-input v-model="baseForm.sort" placeholder="请输入排序字段"/>
  51 + </el-form-item>
  52 + </el-form>
  53 + </el-tab-pane>
  54 +
  55 + <!-- 价格库存 -->
  56 + <el-tab-pane label="价格库存" name="rates" class="rates">
  57 + <el-form :model="ratesForm" :rules="rules.ratesForm">
  58 + <el-form-item label="商品规格">
  59 + <el-radio-group v-model="ratesForm.spec" @change="changeRadio">
  60 + <el-radio :label="0">单规格</el-radio>
  61 + <el-radio :label="1">多规格</el-radio>
  62 + </el-radio-group>
  63 + </el-form-item>
  64 +
  65 + <!-- 动态添加规格属性 -->
  66 + <div v-show="ratesForm.spec === 1">
  67 + <div
  68 + v-for="(specs, index) in dynamicSpec"
  69 + :key="index"
  70 + class="dynamic-spec"
  71 + >
  72 + <!-- 删除按钮 -->
  73 + <el-button
  74 + type="danger"
  75 + icon="el-icon-delete"
  76 + circle
  77 + class="spec-delete"
  78 + @click="dynamicSpec.splice(index, 1)"
  79 + ></el-button>
  80 +
  81 + <div class="spec-header">
  82 + 规格项:
  83 + <el-input
  84 + v-model="specs.spec_name"
  85 + placeholder="请填写规格项"
  86 + class="spec-name"
  87 + ></el-input>
  88 + </div>
  89 + <div class="spec-values">
  90 + <template v-for="(specsValue, i) in specs.spec_values">
  91 + <el-input
  92 + v-model="specs.spec_values[i]"
  93 + class="spec-value"
  94 + :key="specsValue"
  95 + ></el-input>
  96 + </template>
  97 + <el-button
  98 + type="primary"
  99 + icon="el-icon-plus"
  100 + circle
  101 + @click="dialogForSpec = true; currentSpec = index"
  102 + ></el-button>
  103 + </div>
  104 + </div>
  105 + <el-button type="primary" @click="dynamicSpec.push({spec_values: []}); ratesForm.rates = []"
  106 + >添加规格项目
  107 + </el-button
  108 + >
  109 + </div>
  110 +
  111 + <!-- 规格明细 -->
  112 + <el-form-item label="规格明细">
  113 + <el-table :data="ratesForm.rates" border style="width: 100%" ref="rates">
  114 +
  115 + <template v-if="ratesForm.spec == 1" >
  116 + <el-table-column :key="index" v-for="(item, index) in dynamicSpec.filter(v=>v.spec_name != undefined)" :label="item.spec_name" >
  117 + <template slot-scope="scope">
  118 + <el-input
  119 + v-if="scope.row.spec"
  120 + v-model="scope.row.spec[index]"
  121 + disabled
  122 + ></el-input>
  123 + </template>
  124 + </el-table-column>
  125 + </template>
  126 +
  127 + <el-table-column label="规格图片" width="120px">
  128 + <template slot-scope="scope">
  129 + <ImageUpload v-model="scope.row.picUrl" :limit="1" :isShowTip="false" style="width: 100px; height: 50px" />
  130 + </template>
  131 + </el-table-column>
  132 + <el-table-column label="市场价(元)">
  133 + <template slot-scope="scope">
  134 + <el-input
  135 + v-model="scope.row.marketPrice"
  136 + type="number"
  137 + ></el-input>
  138 + </template>
  139 + </el-table-column>
  140 + <el-table-column label="销售价(元)" re>
  141 + <template slot-scope="scope">
  142 + <el-input v-model="scope.row.price" type="number"></el-input>
  143 + </template>
  144 + </el-table-column>
  145 + <el-table-column label="成本价">
  146 + <template slot-scope="scope">
  147 + <el-input
  148 + v-model="scope.row.costPrice"
  149 + type="number"
  150 + ></el-input>
  151 + </template>
  152 + </el-table-column>
  153 + <el-table-column label="库存">
  154 + <template slot-scope="scope">
  155 + <el-input v-model="scope.row.stock" type="number"></el-input>
  156 + </template>
  157 + </el-table-column>
  158 + <el-table-column label="体积">
  159 + <template slot-scope="scope">
  160 + <el-input v-model="scope.row.volume" type="number"></el-input>
  161 + </template>
  162 + </el-table-column>
  163 + <el-table-column label="重量">
  164 + <template slot-scope="scope">
  165 + <el-input v-model="scope.row.weight" type="number"></el-input>
  166 + </template>
  167 + </el-table-column>
  168 + <el-table-column label="条码">
  169 + <template slot-scope="scope">
  170 + <el-input v-model="scope.row.barCode"></el-input>
  171 + </template>
  172 + </el-table-column>
  173 + </el-table>
  174 + </el-form-item>
  175 + </el-form>
  176 + </el-tab-pane>
  177 +
  178 + <!-- 商品详情 -->
  179 + <el-tab-pane label="商品描述" name="third">
  180 + <editor v-model="baseForm.description" :min-height="400" />
  181 + </el-tab-pane>
  182 +
  183 + <!-- 销售设置 -->
  184 + <el-tab-pane label="销售设置" name="fourth">
  185 + <el-form ref="baseForm" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%">
  186 + <el-form-item label="库存数量" prop="quantity">
  187 + <el-input v-model="baseForm.quantity" placeholder="请输入库存数量" />
  188 + </el-form-item>
  189 + <el-form-item label="上下架状态" prop="status">
  190 + <el-radio-group v-model="baseForm.status">
  191 + <el-radio label="0">上架</el-radio>
  192 + <el-radio label="1">下架</el-radio>
  193 + </el-radio-group>
  194 + </el-form-item>
  195 + </el-form>
  196 + </el-tab-pane>
  197 + </el-tabs>
  198 +
  199 + <div class="buttons">
  200 + <el-button type="info" round @click="cancel">取消</el-button>
  201 + <el-button type="success" round @click="submit">确认</el-button>
  202 + </div>
  203 +
  204 + </div>
  205 +</template>
  206 +
  207 +<script>
  208 +import {
  209 + getProductCategoryList
  210 +} from "@/api/mall/product/category";
  211 +
  212 +import Editor from "@/components/Editor";
  213 +import ImageUpload from "@/components/ImageUpload";
  214 +export default {
  215 + components: {
  216 + Editor,
  217 + ImageUpload
  218 + },
  219 + data() {
  220 + return {
  221 + activeName: "base",
  222 + propName: {
  223 + checkStrictly: true,
  224 + label: "name",
  225 + value: "id",
  226 + },
  227 + // 基础设置
  228 + baseForm: {
  229 + name: null,
  230 + sellPoint: null,
  231 + categoryIds: null,
  232 + sort: null,
  233 + description: null,
  234 + picUrl:null,
  235 + picUrls: [],
  236 + quantity: null
  237 + },
  238 + categoryList: [],
  239 +
  240 + // 价格库存
  241 + ratesForm: {
  242 + spec: 0,
  243 + // 规格明细
  244 + rates: [{}]
  245 + },
  246 + dynamicSpec: [
  247 + // {
  248 + // spec_id: 86,
  249 + // spec_name: "颜色",
  250 + // spec_values: [],
  251 + // spec_value_ids: [225],
  252 + // },
  253 + ],
  254 + dialogForSpec: false,
  255 + specValue: null,
  256 + currentSpec: null,
  257 +
  258 + // 表单校验
  259 + rules: {
  260 + description: [
  261 + {required: true, message: "描述不能为空", trigger: "blur"},
  262 + ],
  263 + categoryIds: [
  264 + {required: true, message: "分类id不能为空", trigger: "blur"},
  265 + ],
  266 + picUrls: [{required: true, message: "商品主图地址", trigger: "blur"}],
  267 + sort: [
  268 + {required: true, message: "排序字段不能为空", trigger: "blur"},
  269 + ],
  270 + },
  271 + };
  272 + },
  273 + created() {
  274 + this.getListCategory();
  275 + },
  276 + methods: {
  277 + changeRadio() {
  278 +
  279 + this.$refs.rates.doLayout()
  280 + if(this.ratesForm.spec == 0){
  281 + this.ratesForm.rates = [{}]
  282 + }else{
  283 + this.ratesForm.rates = []
  284 + if(this.dynamicSpec.length > 0){
  285 + this.buildRatesFormRates()
  286 + }
  287 + }
  288 + },
  289 + // 构建规格明细笛卡尔积
  290 + buildRatesFormRates(){
  291 + let rates = [];
  292 + this.dynamicSpec.map(v=>v.spec_values)
  293 + .reduce((last, current) => {
  294 + const array = [];
  295 + last.forEach(par1 => {
  296 + current.forEach(par2 => {
  297 + let v
  298 + if(par1 instanceof Array){
  299 + v = par1.concat(par2)
  300 + }else{
  301 + v = [par1, par2];
  302 + }
  303 + array.push(v)
  304 + });
  305 + });
  306 + return array;
  307 + })
  308 + .forEach(v=>{
  309 + rates.push({spec: v})
  310 + });
  311 + console.log(rates)
  312 + this.ratesForm.rates = rates
  313 + },
  314 + addSpecValue() {
  315 + this.dialogForSpec = false;
  316 + let specValue = this.dynamicSpec[this.currentSpec].spec_values
  317 + .concat(this.specValue.split(/[(\r\n)\r\n]+/))
  318 + .filter(v => v != "");
  319 + console.log(specValue)
  320 + this.dynamicSpec[this.currentSpec].spec_values = [...new Set(specValue)];
  321 + this.currentSpec = null;
  322 + this.buildRatesFormRates()
  323 + },
  324 + /** 查询分类 */
  325 + getListCategory() {
  326 + // 执行查询
  327 + getProductCategoryList().then((response) => {
  328 + this.categoryList = this.handleTree(response.data, "id", "parentId");
  329 + });
  330 + },
  331 + cancel(){
  332 + this.$emit("closeDialog");
  333 + },
  334 + },
  335 +};
  336 +</script>
  337 +
  338 +<style lang="scss">
  339 +.spec-dialog {
  340 + width: 400px;
  341 + height: 300px;
  342 +}
  343 +
  344 +.dynamic-spec {
  345 + background-color: #f2f2f2;
  346 + width: 85%;
  347 + margin: auto;
  348 + margin-bottom: 10px;
  349 +
  350 + .spec-header {
  351 + padding: 30px;
  352 + padding-bottom: 0;
  353 +
  354 + .spec-name {
  355 + display: inline;
  356 +
  357 + input {
  358 + width: 30%;
  359 + }
  360 + }
  361 + }
  362 +
  363 + .spec-values {
  364 + width: 84%;
  365 + padding: 25px;
  366 + margin: auto;
  367 +
  368 + .spec-value {
  369 + display: inline-block;
  370 + margin-right: 10px;
  371 + margin-bottom: 10px;
  372 + width: 13%;
  373 +
  374 + }
  375 + }
  376 +
  377 + .spec-delete {
  378 + float: right;
  379 + margin-top: 10px;
  380 + margin-right: 10px;
  381 + }
  382 +}
  383 +
  384 +.tabs{
  385 + height: 500px;
  386 + border-bottom: 2px solid #f2f2f2;
  387 + .el-tab-pane{
  388 + height: 445px;
  389 + overflow-y: auto;
  390 + }
  391 +}
  392 +
  393 +// 库存价格图片样式修改
  394 +.rates{
  395 +.component-upload-image{
  396 + margin: auto;
  397 +}
  398 +.el-upload--picture-card{
  399 + width: 100px;
  400 + height: 50px;
  401 + line-height: 60px;
  402 + margin: auto;
  403 +}
  404 +.el-upload-list__item{
  405 + width: 100px !important;
  406 + height: 50px !important;
  407 +}
  408 +}
  409 +.buttons{
  410 + margin-top: 20px;
  411 + height: 36px;
  412 + button{
  413 + float: right;
  414 + margin-left: 15px;
  415 + }
  416 +}
  417 +</style>
... ...