Commit 07e5e1b59f6dc19315f7092fa996777afb9472b8

Authored by luowenfeng
1 parent 10caa6e8

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

yudao-ui-admin/src/views/mall/product/spu/index.vue
1 <template> 1 <template>
2 <div class="app-container"> 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 <el-form-item label="商品名称" prop="name"> 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 </el-form-item> 19 </el-form-item>
9 <el-form-item label="卖点" prop="sellPoint"> 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 </el-form-item> 27 </el-form-item>
12 <el-form-item label="分类id" prop="categoryId"> 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 </el-form-item> 35 </el-form-item>
15 <el-form-item label="价格(分)" prop="price"> 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 </el-form-item> 43 </el-form-item>
18 <el-form-item label="库存数量" prop="quantity"> 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 </el-form-item> 51 </el-form-item>
21 <el-form-item label="状态" prop="status"> 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 </el-select> 62 </el-select>
27 </el-form-item> 63 </el-form-item>
28 <el-form-item label="创建时间"> 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 </el-form-item> 74 </el-form-item>
32 <el-form-item> 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 <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button> 79 <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
35 </el-form-item> 80 </el-form-item>
36 </el-form> 81 </el-form>
@@ -38,95 +83,150 @@ @@ -38,95 +83,150 @@
38 <!-- 操作工具栏 --> 83 <!-- 操作工具栏 -->
39 <el-row :gutter="10" class="mb8"> 84 <el-row :gutter="10" class="mb8">
40 <el-col :span="1.5"> 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 </el-button> 94 </el-button>
44 </el-col> 95 </el-col>
45 <el-col :span="1.5"> 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 </el-button> 106 </el-button>
50 </el-col> 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 </el-row> 112 </el-row>
53 113
54 <!-- 列表 --> 114 <!-- 列表 -->
55 <el-table v-loading="loading" :data="list"> 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 <!-- <el-table-column label="卖点" align="center" prop="sellPoint"/>--> 118 <!-- <el-table-column label="卖点" align="center" prop="sellPoint"/>-->
59 <!-- <el-table-column label="描述" align="center" prop="description"/>--> 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 <el-table-column label="商品主图地址" align="center" prop="picUrls"> 121 <el-table-column label="商品主图地址" align="center" prop="picUrls">
62 <template slot-scope="scope"> 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 </template> 129 </template>
65 </el-table-column> 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 <!-- <el-table-column label="状态" align="center" prop="status"/>--> 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 <template slot-scope="scope"> 142 <template slot-scope="scope">
73 <span>{{ parseTime(scope.row.createTime) }}</span> 143 <span>{{ parseTime(scope.row.createTime) }}</span>
74 </template> 144 </template>
75 </el-table-column> 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 <template slot-scope="scope"> 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 </el-button> 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 </el-button> 167 </el-button>
84 </template> 168 </template>
85 </el-table-column> 169 </el-table-column>
86 </el-table> 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 <el-form ref="form" :model="form" :rules="rules" label-width="80px"> 186 <el-form ref="form" :model="form" :rules="rules" label-width="80px">
94 <el-form-item label="商品名称" prop="name"> 187 <el-form-item label="商品名称" prop="name">
95 - <el-input v-model="form.name" placeholder="请输入商品名称"/> 188 + <el-input v-model="form.name" placeholder="请输入商品名称" />
96 </el-form-item> 189 </el-form-item>
97 <el-form-item label="卖点" prop="sellPoint"> 190 <el-form-item label="卖点" prop="sellPoint">
98 - <el-input v-model="form.sellPoint" placeholder="请输入卖点"/> 191 + <el-input v-model="form.sellPoint" placeholder="请输入卖点" />
99 </el-form-item> 192 </el-form-item>
100 <el-form-item label="描述"> 193 <el-form-item label="描述">
101 - <editor v-model="form.description" :min-height="192"/> 194 + <editor v-model="form.description" :min-height="192" />
102 </el-form-item> 195 </el-form-item>
103 <el-form-item label="分类id" prop="categoryIds"> 196 <el-form-item label="分类id" prop="categoryIds">
104 <el-cascader 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 </el-form-item> 205 </el-form-item>
112 <el-form-item label="商品主图地址" prop="picUrls"> 206 <el-form-item label="商品主图地址" prop="picUrls">
113 - <ImageUpload v-model="form.picUrls" :limit="10"/> 207 + <ImageUpload v-model="form.picUrls" :limit="10" />
114 </el-form-item> 208 </el-form-item>
115 <el-form-item label="商品规格"> 209 <el-form-item label="商品规格">
116 <el-button size="mini" @click="shopTagInput()">添加规格</el-button> 210 <el-button size="mini" @click="shopTagInput()">添加规格</el-button>
117 <div v-for="(tag, tagIndex) in skuTags" :key="tagIndex"> 211 <div v-for="(tag, tagIndex) in skuTags" :key="tagIndex">
118 <span>{{ tag.name }}</span> 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 </el-button> 220 </el-button>
122 - <br/> 221 + <br />
123 <el-tag 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 {{ tagItem }} 228 {{ tagItem }}
129 - </el-tag> 229 + </el-tag> -->
130 <!-- <el-input--> 230 <!-- <el-input-->
131 <!-- class="input-new-tag"--> 231 <!-- class="input-new-tag"-->
132 <!-- v-if="tagItemInputs[tagIndex] && tagItemInputs[tagIndex].visible"--> 232 <!-- v-if="tagItemInputs[tagIndex] && tagItemInputs[tagIndex].visible"-->
@@ -136,134 +236,178 @@ @@ -136,134 +236,178 @@
136 <!-- @keyup.enter.native="handleInputConfirm(tagIndex)"--> 236 <!-- @keyup.enter.native="handleInputConfirm(tagIndex)"-->
137 <!-- @blur="handleInputConfirm(tagIndex)">--> 237 <!-- @blur="handleInputConfirm(tagIndex)">-->
138 <!-- </el-input>--> 238 <!-- </el-input>-->
139 - </div> 239 + <!-- </div>
140 </el-form-item> 240 </el-form-item>
141 <el-form-item label="规格名" v-show="isShowTagInput"> 241 <el-form-item label="规格名" v-show="isShowTagInput">
142 <el-col :span="8"> 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 <el-option 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 </el-option> 257 </el-option>
151 </el-select> 258 </el-select>
152 </el-col> 259 </el-col>
153 </el-form-item> 260 </el-form-item>
154 <el-form-item label="规格值" v-show="isShowTagInput"> 261 <el-form-item label="规格值" v-show="isShowTagInput">
155 <el-col :span="8"> 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 <el-option 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 </el-option> 277 </el-option>
164 </el-select> 278 </el-select>
165 </el-col> 279 </el-col>
166 </el-form-item> 280 </el-form-item>
167 <el-form-item> 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 </el-form-item> 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 <el-table 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 <template slot-scope="scope"> 305 <template slot-scope="scope">
179 {{ scope.row.propertyChildNames[index] }} 306 {{ scope.row.propertyChildNames[index] }}
180 </template> 307 </template>
181 </el-table-column> 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 <template slot-scope="scope"> 315 <template slot-scope="scope">
187 <ImageUpload v-model="scope.row.picUrl" :limit="1"> 316 <ImageUpload v-model="scope.row.picUrl" :limit="1">
188 </ImageUpload> 317 </ImageUpload>
189 </template> 318 </template>
190 </el-table-column> 319 </el-table-column>
191 <el-table-column 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 <template slot-scope="scope"> 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 </template> 332 </template>
198 </el-table-column> 333 </el-table-column>
199 - <el-table-column  
200 - prop="price"  
201 - label="销售价"> 334 + <el-table-column prop="price" label="销售价">
202 <template slot-scope="scope"> 335 <template slot-scope="scope">
203 <el-input-number 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 </el-input-number> 345 </el-input-number>
212 </template> 346 </template>
213 </el-table-column> 347 </el-table-column>
214 - <el-table-column  
215 - prop="oriPrice"  
216 - label="成本价"> 348 + <el-table-column prop="oriPrice" label="成本价">
217 <template slot-scope="scope"> 349 <template slot-scope="scope">
218 <el-input-number 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 </el-input-number> 359 </el-input-number>
227 </template> 360 </template>
228 </el-table-column> 361 </el-table-column>
229 - <el-table-column  
230 - prop="oriPrice"  
231 - label="原价"> 362 + <el-table-column prop="oriPrice" label="原价">
232 <template slot-scope="scope"> 363 <template slot-scope="scope">
233 <el-input-number 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 </el-input-number> 373 </el-input-number>
242 </template> 374 </template>
243 </el-table-column> 375 </el-table-column>
244 - <el-table-column  
245 - label="操作"> 376 + <el-table-column label="操作">
246 <template slot-scope="scope"> 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 </el-button> 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 </template> 393 </template>
253 </el-table-column> 394 </el-table-column>
254 </el-table> 395 </el-table>
255 </el-form-item> 396 </el-form-item>
256 <el-form-item label="排序字段" prop="sort"> 397 <el-form-item label="排序字段" prop="sort">
257 - <el-input v-model="form.sort" placeholder="请输入排序字段"/> 398 + <el-input v-model="form.sort" placeholder="请输入排序字段" />
258 </el-form-item> 399 </el-form-item>
259 <el-form-item label="点赞初始人数" prop="likeCount"> 400 <el-form-item label="点赞初始人数" prop="likeCount">
260 - <el-input v-model="form.likeCount" placeholder="请输入点赞初始人数"/> 401 + <el-input v-model="form.likeCount" placeholder="请输入点赞初始人数" />
261 </el-form-item> 402 </el-form-item>
262 <el-form-item label="价格 单位使用:分" prop="price"> 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 </el-form-item> 408 </el-form-item>
265 <el-form-item label="库存数量" prop="quantity"> 409 <el-form-item label="库存数量" prop="quantity">
266 - <el-input v-model="form.quantity" placeholder="请输入库存数量"/> 410 + <el-input v-model="form.quantity" placeholder="请输入库存数量" />
267 </el-form-item> 411 </el-form-item>
268 <el-form-item label="上下架状态" prop="status"> 412 <el-form-item label="上下架状态" prop="status">
269 <el-radio-group v-model="form.status"> 413 <el-radio-group v-model="form.status">
@@ -276,19 +420,26 @@ @@ -276,19 +420,26 @@
276 <el-button type="primary" @click="submitForm">确 定</el-button> 420 <el-button type="primary" @click="submitForm">确 定</el-button>
277 <el-button @click="cancel">取 消</el-button> 421 <el-button @click="cancel">取 消</el-button>
278 </div> 422 </div>
279 - </el-dialog> 423 + </el-dialog> -->
280 </div> 424 </div>
281 </template> 425 </template>
282 426
283 <script> 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 import { 436 import {
286 createProductCategory, 437 createProductCategory,
287 deleteProductCategory, 438 deleteProductCategory,
288 exportCategoryExcel, 439 exportCategoryExcel,
289 getProductCategory, 440 getProductCategory,
290 getProductCategoryList, 441 getProductCategoryList,
291 - updateProductCategory 442 + updateProductCategory,
292 } from "@/api/mall/product/category"; 443 } from "@/api/mall/product/category";
293 import { 444 import {
294 createProperty, 445 createProperty,
@@ -296,16 +447,19 @@ import { @@ -296,16 +447,19 @@ import {
296 deleteProperty, 447 deleteProperty,
297 getProperty, 448 getProperty,
298 getPropertyPage, 449 getPropertyPage,
299 - exportPropertyExcel 450 + exportPropertyExcel,
300 } from "@/api/mall/product/property"; 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 export default { 457 export default {
306 name: "Spu", 458 name: "Spu",
307 components: { 459 components: {
308 - Editor, ImageUpload 460 + Editor,
  461 + ImageUpload,
  462 + save,
309 }, 463 },
310 data() { 464 data() {
311 return { 465 return {
@@ -316,17 +470,17 @@ export default { @@ -316,17 +470,17 @@ export default {
316 propertyPageList: [], 470 propertyPageList: [],
317 isShowTagInput: false, 471 isShowTagInput: false,
318 addTagInput: { 472 addTagInput: {
319 - name: '',  
320 - propertyId: '', 473 + name: "",
  474 + propertyId: "",
321 selectValues: [], 475 selectValues: [],
322 selectValueIds: [], 476 selectValueIds: [],
323 - selectObect:[], 477 + selectObect: [],
324 }, 478 },
325 skuTags: [], 479 skuTags: [],
326 propName: { 480 propName: {
327 checkStrictly: true, 481 checkStrictly: true,
328 - label: 'name',  
329 - value: 'id' 482 + label: "name",
  483 + value: "id",
330 }, 484 },
331 categoryList: [], 485 categoryList: [],
332 // 遮罩层 486 // 遮罩层
@@ -378,91 +532,101 @@ export default { @@ -378,91 +532,101 @@ export default {
378 }, 532 },
379 // 表单校验 533 // 表单校验
380 rules: { 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 tagIndex: 0, 549 tagIndex: 0,
388 }; 550 };
389 }, 551 },
390 created() { 552 created() {
391 -  
392 this.getList(); 553 this.getList();
393 this.getPropertyPageList(); 554 this.getPropertyPageList();
394 this.getListCategory(); 555 this.getListCategory();
395 }, 556 },
396 methods: { 557 methods: {
397 getTableSpecData() { 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 changeSkuStatus(tagIndex) { 562 changeSkuStatus(tagIndex) {
404 if (this.form.skus[tagIndex].status == 0) { 563 if (this.form.skus[tagIndex].status == 0) {
405 this.form.skus[tagIndex].status = 1; 564 this.form.skus[tagIndex].status = 1;
406 } else { 565 } else {
407 this.form.skus[tagIndex].status = 0; 566 this.form.skus[tagIndex].status = 0;
408 } 567 }
409 -  
410 }, 568 },
411 skuAddProdName() { 569 skuAddProdName() {
412 if (this.initing) { 570 if (this.initing) {
413 - return 571 + return;
414 } 572 }
415 - let skuList = [] 573 + let skuList = [];
416 for (let i = 0; i < this.value.length; i++) { 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 if (!sku.properties) { 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 for (const propertiesKey in properties) { 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 //确定添加sku规格 590 //确定添加sku规格
435 addTag() { 591 addTag() {
436 -  
437 let skus = this.unUseTags.map(function (item, index) { 592 let skus = this.unUseTags.map(function (item, index) {
438 - return item.name 593 + return item.name;
439 }); 594 });
440 let index = skus.indexOf(this.addTagInput.name); 595 let index = skus.indexOf(this.addTagInput.name);
441 596
442 this.addTagInput.propertyId = this.unUseTags[index].id; 597 this.addTagInput.propertyId = this.unUseTags[index].id;
443 for (let i = 0; i < this.addTagInput.selectValues.length; i++) { 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 this.addTagInput.selectObect.push({ 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 this.skuTags.push(addTagInput); 619 this.skuTags.push(addTagInput);
456 620
457 // if (this.skuTags.length > 1) { 621 // if (this.skuTags.length > 1) {
458 this.skuTags = this.skuTags.sort((a, b) => a.propertyId - b.propertyId); 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 for (let j = 0; j < this.skuTags[i].selectObect.length; j++) { 630 for (let j = 0; j < this.skuTags[i].selectObect.length; j++) {
467 selectValueIds.push(this.skuTags[i].selectObect[j].id); 631 selectValueIds.push(this.skuTags[i].selectObect[j].id);
468 selectValues.push(this.skuTags[i].selectObect[j].name); 632 selectValues.push(this.skuTags[i].selectObect[j].name);
@@ -489,17 +653,23 @@ export default { @@ -489,17 +653,23 @@ export default {
489 propertyNames.push(skuTags[i].name); 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 for (let i = 0; i < skuAll.length; i++) { 674 for (let i = 0; i < skuAll.length; i++) {
505 let han = { 675 let han = {
@@ -508,33 +678,32 @@ export default { @@ -508,33 +678,32 @@ export default {
508 propertyChildNames: skuAll[i], 678 propertyChildNames: skuAll[i],
509 propertyChildIds: skuIdAll[i], 679 propertyChildIds: skuIdAll[i],
510 properties: [], 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 this.form.skus.push(han); 690 this.form.skus.push(han);
521 } 691 }
522 - this.form.skus.forEach(x => { 692 + this.form.skus.forEach((x) => {
523 x.properties = []; 693 x.properties = [];
524 for (let i = 0; i < x.propertyIds.length; i++) { 694 for (let i = 0; i < x.propertyIds.length; i++) {
525 x.properties.push({ 695 x.properties.push({
526 propertyId: x.propertyIds[i], 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 hideTagInput() { 702 hideTagInput() {
534 this.isShowTagInput = false; 703 this.isShowTagInput = false;
535 this.addTagInput = { 704 this.addTagInput = {
536 - name: '',  
537 - propertyId: '', 705 + name: "",
  706 + propertyId: "",
538 selectValues: [], 707 selectValues: [],
539 selectValueIds: [], 708 selectValueIds: [],
540 selectObect: [], 709 selectObect: [],
@@ -542,12 +711,12 @@ export default { @@ -542,12 +711,12 @@ export default {
542 }, 711 },
543 shopTagInput() { 712 shopTagInput() {
544 if (this.unUseTags.length <= 0) { 713 if (this.unUseTags.length <= 0) {
545 - return this.$message.error("规格已经添加完毕") 714 + return this.$message.error("规格已经添加完毕");
546 } 715 }
547 this.isShowTagInput = true; 716 this.isShowTagInput = true;
548 this.addTagInput = { 717 this.addTagInput = {
549 - name: '',  
550 - propertyId: '', 718 + name: "",
  719 + propertyId: "",
551 selectValues: [], 720 selectValues: [],
552 selectValueIds: [], 721 selectValueIds: [],
553 selectObect: [], 722 selectObect: [],
@@ -556,8 +725,8 @@ export default { @@ -556,8 +725,8 @@ export default {
556 //删除已选的规格 725 //删除已选的规格
557 removeTag(row) { 726 removeTag(row) {
558 let skus = this.allhistoryTags.map(function (item, index) { 727 let skus = this.allhistoryTags.map(function (item, index) {
559 - return item.name  
560 - }) 728 + return item.name;
  729 + });
561 let index = skus.indexOf(this.skuTags[row].name); 730 let index = skus.indexOf(this.skuTags[row].name);
562 this.unUseTags.push(this.allhistoryTags[index]); 731 this.unUseTags.push(this.allhistoryTags[index]);
563 this.skuTags.splice(row, 1); 732 this.skuTags.splice(row, 1);
@@ -566,38 +735,37 @@ export default { @@ -566,38 +735,37 @@ export default {
566 handleTagClick(row) { 735 handleTagClick(row) {
567 for (let i = 0; i < this.propertyPageList.length; i++) { 736 for (let i = 0; i < this.propertyPageList.length; i++) {
568 if (row == this.propertyPageList[i].name) { 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 getPropertyPageList() { 743 getPropertyPageList() {
575 // 执行查询 744 // 执行查询
576 - getPropertyPage().then(response => { 745 + getPropertyPage().then((response) => {
577 this.propertyPageList = response.data.list; 746 this.propertyPageList = response.data.list;
578 747
579 this.unUseTags = this.propertyPageList.map(function (item, index) { 748 this.unUseTags = this.propertyPageList.map(function (item, index) {
580 - return item  
581 - }) 749 + return item;
  750 + });
582 this.allhistoryTags = JSON.parse(JSON.stringify(this.unUseTags)); 751 this.allhistoryTags = JSON.parse(JSON.stringify(this.unUseTags));
583 }); 752 });
584 }, 753 },
585 /** 查询分类 */ 754 /** 查询分类 */
586 getListCategory() { 755 getListCategory() {
587 // 执行查询 756 // 执行查询
588 - getProductCategoryList().then(response => { 757 + getProductCategoryList().then((response) => {
589 this.categoryList = this.handleTree(response.data, "id", "parentId"); 758 this.categoryList = this.handleTree(response.data, "id", "parentId");
590 -  
591 }); 759 });
592 }, 760 },
593 /** 查询列表 */ 761 /** 查询列表 */
594 getList() { 762 getList() {
595 this.loading = true; 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 this.list = response.data.list; 769 this.list = response.data.list;
602 this.total = response.data.total; 770 this.total = response.data.total;
603 this.loading = false; 771 this.loading = false;
@@ -610,7 +778,6 @@ export default { @@ -610,7 +778,6 @@ export default {
610 }, 778 },
611 /** 表单重置 */ 779 /** 表单重置 */
612 reset() { 780 reset() {
613 -  
614 this.form = { 781 this.form = {
615 id: undefined, 782 id: undefined,
616 name: undefined, 783 name: undefined,
@@ -652,7 +819,7 @@ export default { @@ -652,7 +819,7 @@ export default {
652 handleUpdate(row) { 819 handleUpdate(row) {
653 this.reset(); 820 this.reset();
654 const id = row.id; 821 const id = row.id;
655 - getSpu(id).then(response => { 822 + getSpu(id).then((response) => {
656 let dataSpu = response.data; 823 let dataSpu = response.data;
657 this.form = { 824 this.form = {
658 id: dataSpu.id, 825 id: dataSpu.id,
@@ -680,11 +847,15 @@ export default { @@ -680,11 +847,15 @@ export default {
680 }, 847 },
681 getDataHandle() { 848 getDataHandle() {
682 let that = this; 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 item.propertyValues = item.propertyValues.sort((a, b) => a.v1 - b.v1); 857 item.propertyValues = item.propertyValues.sort((a, b) => a.v1 - b.v1);
687 - }) 858 + });
688 let skuIds = []; 859 let skuIds = [];
689 for (let i = 0; i < productPropertyViews.length; i++) { 860 for (let i = 0; i < productPropertyViews.length; i++) {
690 let han = { 861 let han = {
@@ -692,17 +863,21 @@ export default { @@ -692,17 +863,21 @@ export default {
692 propertyId: productPropertyViews[i].propertyId, 863 propertyId: productPropertyViews[i].propertyId,
693 selectValues: [], 864 selectValues: [],
694 selectValueIds: [], 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 han.selectValues.push(productPropertyViews[i].propertyValues[j].v2); 872 han.selectValues.push(productPropertyViews[i].propertyValues[j].v2);
698 han.selectValueIds.push(productPropertyViews[i].propertyValues[j].v1); 873 han.selectValueIds.push(productPropertyViews[i].propertyValues[j].v1);
699 } 874 }
700 - skuIds.push(han) 875 + skuIds.push(han);
701 } 876 }
702 this.skuTags = skuIds; 877 this.skuTags = skuIds;
703 this.unUseTags = this.allhistoryTags.filter((v) => 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 this.getHandleTable(); 881 this.getHandleTable();
707 }, 882 },
708 getHandleTable() { 883 getHandleTable() {
@@ -718,17 +893,23 @@ export default { @@ -718,17 +893,23 @@ export default {
718 propertyIds.push(skuTags[i].propertyId); 893 propertyIds.push(skuTags[i].propertyId);
719 propertyNames.push(skuTags[i].name); 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 for (let i = 0; i < skuAll.length; i++) { 914 for (let i = 0; i < skuAll.length; i++) {
734 let han = { 915 let han = {
@@ -745,33 +926,32 @@ export default { @@ -745,33 +926,32 @@ export default {
745 price: this.form.skusList[i].price, 926 price: this.form.skusList[i].price,
746 barCode: this.form.skusList[i].barCode, 927 barCode: this.form.skusList[i].barCode,
747 status: this.form.skusList[i].status, 928 status: this.form.skusList[i].status,
748 - } 929 + };
749 this.form.skus.push(han); 930 this.form.skus.push(han);
750 } 931 }
751 - this.form.skus.forEach(x => { 932 + this.form.skus.forEach((x) => {
752 x.properties = []; 933 x.properties = [];
753 for (let i = 0; i < x.propertyIds.length; i++) { 934 for (let i = 0; i < x.propertyIds.length; i++) {
754 x.properties.push({ 935 x.properties.push({
755 propertyId: x.propertyIds[i], 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 submitForm() { 943 submitForm() {
764 -  
765 - this.$refs["form"].validate(valid => { 944 + this.$refs["form"].validate((valid) => {
766 if (!valid) { 945 if (!valid) {
767 return; 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 this.form.status = Number(this.form.status); 951 this.form.status = Number(this.form.status);
772 // 修改的提交 952 // 修改的提交
773 if (this.form.id != null) { 953 if (this.form.id != null) {
774 - updateSpu(this.form).then(response => { 954 + updateSpu(this.form).then((response) => {
775 this.$modal.msgSuccess("修改成功"); 955 this.$modal.msgSuccess("修改成功");
776 this.open = false; 956 this.open = false;
777 this.getList(); 957 this.getList();
@@ -779,7 +959,7 @@ export default { @@ -779,7 +959,7 @@ export default {
779 return; 959 return;
780 } 960 }
781 // 添加的提交 961 // 添加的提交
782 - createSpu(this.form).then(response => { 962 + createSpu(this.form).then((response) => {
783 this.$modal.msgSuccess("新增成功"); 963 this.$modal.msgSuccess("新增成功");
784 this.open = false; 964 this.open = false;
785 this.getList(); 965 this.getList();
@@ -789,32 +969,38 @@ export default { @@ -789,32 +969,38 @@ export default {
789 /** 删除按钮操作 */ 969 /** 删除按钮操作 */
790 handleDelete(row) { 970 handleDelete(row) {
791 const id = row.id; 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 handleExport() { 984 handleExport() {
802 // 处理查询参数 985 // 处理查询参数
803 - let params = {...this.queryParams}; 986 + let params = { ...this.queryParams };
804 params.pageNo = undefined; 987 params.pageNo = undefined;
805 params.pageSize = undefined; 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 </script> 1005 </script>
820 <style lang="scss"> 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>