Commit 1bd1c79ff33dc4fc8852275c0b2622dc75f0c0eb

Authored by YunaiV
1 parent 37e948cc

mall:code review 商品模块的代码

yudao-ui-admin/src/api/mall/product/spu.js
... ... @@ -42,13 +42,3 @@ export function getSpuPage(query) {
42 42 params: query
43 43 })
44 44 }
45   -
46   -// 导出商品spu Excel
47   -export function exportSpuExcel(query) {
48   - return request({
49   - url: '/product/spu/export-excel',
50   - method: 'get',
51   - params: query,
52   - responseType: 'blob'
53   - })
54   -}
... ...
yudao-ui-admin/src/views/mall/product/spu/index.vue
1 1 <template>
2 2 <div class="app-container">
3 3 <!-- 搜索工作栏 -->
4   - <el-form
5   - :model="queryParams"
6   - ref="queryForm"
7   - size="small"
8   - :inline="true"
9   - v-show="showSearch"
10   - label-width="68px"
11   - >
  4 + <!-- TODO @Luowenfeng:参考界面;https://v5.niuteam.cn/shop/goods/lists.html
  5 + 商品名称、商品编码、商品分类、商品品牌
  6 + 商品销量、商品价格
  7 + -->
  8 + <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
12 9 <el-form-item label="商品名称" prop="name">
13   - <el-input
14   - v-model="queryParams.name"
15   - placeholder="请输入商品名称"
16   - clearable
17   - @keyup.enter.native="handleQuery"
18   - />
  10 + <el-input v-model="queryParams.name" placeholder="请输入商品名称" clearable @keyup.enter.native="handleQuery"/>
19 11 </el-form-item>
20 12 <el-form-item label="分类id" prop="categoryId">
21   - <el-input
22   - v-model="queryParams.categoryId"
23   - placeholder="请输入分类id"
24   - clearable
25   - @keyup.enter.native="handleQuery"
26   - />
  13 + <el-input v-model="queryParams.categoryId" placeholder="请输入分类id" clearable @keyup.enter.native="handleQuery"/>
27 14 </el-form-item>
28 15 <el-form-item label="状态" prop="status">
29   - <el-select
30   - v-model="queryParams.status"
31   - placeholder="请选择上下架状态"
32   - clearable
33   - size="small"
34   - >
  16 + <el-select v-model="queryParams.status" placeholder="请选择上下架状态" clearable size="small">
35 17 <el-option label="请选择字典生成" value="" />
36 18 <el-option label="上架" value="0" />
37 19 <el-option label="下架" value="1" />
38 20 </el-select>
39 21 </el-form-item>
40 22 <el-form-item label="创建时间">
41   - <el-date-picker
42   - v-model="dateRangeCreateTime"
43   - style="width: 240px"
44   - value-format="yyyy-MM-dd"
45   - type="daterange"
46   - range-separator="-"
47   - start-placeholder="开始日期"
48   - end-placeholder="结束日期"
49   - />
  23 + <el-date-picker v-model="dateRangeCreateTime" style="width: 240px" value-format="yyyy-MM-dd" type="daterange"
  24 + range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"/>
50 25 </el-form-item>
51 26 <el-form-item>
52   - <el-button type="primary" icon="el-icon-search" @click="handleQuery"
53   - >搜索</el-button
54   - >
  27 + <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
55 28 <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
56 29 </el-form-item>
57 30 </el-form>
... ... @@ -59,36 +32,20 @@
59 32 <!-- 操作工具栏 -->
60 33 <el-row :gutter="10" class="mb8">
61 34 <el-col :span="1.5">
62   - <el-button
63   - type="primary"
64   - plain
65   - icon="el-icon-plus"
66   - size="mini"
67   - @click="handleAdd"
68   - v-hasPermi="['product:spu:create']"
69   - >新增
70   - </el-button>
  35 + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
  36 + v-hasPermi="['product:spu:create']">新增</el-button>
71 37 </el-col>
72   - <el-col :span="1.5">
73   - <el-button
74   - type="warning"
75   - plain
76   - icon="el-icon-download"
77   - size="mini"
78   - @click="handleExport"
79   - :loading="exportLoading"
80   - v-hasPermi="['product:spu:export']"
81   - >导出
82   - </el-button>
83   - </el-col>
84   - <right-toolbar
85   - :showSearch.sync="showSearch"
86   - @queryTable="getList"
87   - ></right-toolbar>
  38 + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
88 39 </el-row>
89 40  
90 41 <!-- 列表 -->
91 42 <el-table v-loading="loading" :data="list">
  43 + <!--
  44 + TODO @Luowenfeng:参考界面;
  45 + https://v5.niuteam.cn/shop/goods/lists.html
  46 + 1. 字段:商品信息、价格、库存、销量、排序、创建时间、状态、操作;
  47 + 2. tab 分成全部、销售中、仓库中、预警中
  48 + -->
92 49 <el-table-column label="主键" align="center" prop="id" />
93 50 <el-table-column label="商品名称" align="center" prop="name" />
94 51 <el-table-column label="分类id" align="center" prop="categoryId" />
... ... @@ -111,50 +68,23 @@
111 68 <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/>
112 69 </template>
113 70 </el-table-column>
114   - <el-table-column
115   - label="创建时间"
116   - align="center"
117   - prop="createTime"
118   - width="180"
119   - >
  71 + <el-table-column label="创建时间" align="center" prop="createTime" width="180">
120 72 <template slot-scope="scope">
121 73 <span>{{ parseTime(scope.row.createTime) }}</span>
122 74 </template>
123 75 </el-table-column>
124   - <el-table-column
125   - label="操作"
126   - align="center"
127   - class-name="small-padding fixed-width"
128   - >
  76 + <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
129 77 <template slot-scope="scope">
130   - <el-button
131   - size="mini"
132   - type="text"
133   - icon="el-icon-edit"
134   - @click="handleUpdate(scope.row)"
135   - v-hasPermi="['product:spu:update']"
136   - >修改
137   - </el-button>
138   - <el-button
139   - size="mini"
140   - type="text"
141   - icon="el-icon-delete"
142   - @click="handleDelete(scope.row)"
143   - v-hasPermi="['product:spu:delete']"
144   - >删除
145   - </el-button>
  78 + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  79 + v-hasPermi="['product:spu:update']">修改</el-button>
  80 + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
  81 + v-hasPermi="['product:spu:delete']">删除</el-button>
146 82 </template>
147 83 </el-table-column>
148 84 </el-table>
149 85 <!-- 分页组件 -->
150   - <pagination
151   - v-show="total > 0"
152   - :total="total"
153   - :page.sync="queryParams.pageNo"
154   - :limit.sync="queryParams.pageSize"
155   - @pagination="getList"
156   - />
157   -
  86 + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
  87 + @pagination="getList"/>
158 88  
159 89 <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body destroy-on-close :close-on-click-modal="false" >
160 90 <save @closeDialog="closeDialog" :type="dialogType" :obj="dialogObj" v-if="open" />
... ... @@ -166,13 +96,15 @@
166 96 import {
167 97 deleteSpu,
168 98 getSpuPage,
169   - exportSpuExcel,
170 99 } from "@/api/mall/product/spu";
171 100  
172 101 import Editor from "@/components/Editor";
173 102 import ImageUpload from "@/components/ImageUpload";
174 103 import save from "./save";
175 104  
  105 +// 1. TODO @Luowenfeng:商品的添加、修改,走一个单独的页面,不走弹窗;https://v5.niuteam.cn/shop/goods/addgoods.html
  106 +// 2. TODO
  107 +
176 108 export default {
177 109 name: "Spu",
178 110 components: {
... ... @@ -306,27 +238,7 @@ export default {
306 238 this.$modal.msgSuccess("删除成功");
307 239 })
308 240 .catch(() => {});
309   - },
310   - /** 导出按钮操作 */
311   - handleExport() {
312   - // 处理查询参数
313   - let params = { ...this.queryParams };
314   - params.pageNo = undefined;
315   - params.pageSize = undefined;
316   - this.addBeginAndEndTime(params, this.dateRangeCreateTime, "createTime");
317   - // 执行导出
318   - this.$modal
319   - .confirm("是否确认导出所有商品spu数据项?")
320   - .then(() => {
321   - this.exportLoading = true;
322   - return exportSpuExcel(params);
323   - })
324   - .then((response) => {
325   - this.$download.excel(response, "商品spu.xls");
326   - this.exportLoading = false;
327   - })
328   - .catch(() => {});
329   - },
  241 + }
330 242 },
331 243 };
332 244 </script>
... ...
yudao-ui-admin/src/views/mall/product/spu/save.vue
... ... @@ -7,24 +7,28 @@
7 7 <el-form-item label="商品名称" prop="name">
8 8 <el-input v-model="baseForm.name" placeholder="请输入商品名称"/>
9 9 </el-form-item>
10   - <el-form-item label="卖点">
11   - <el-input v-model="baseForm.sellPoint" placeholder="请输入卖点"/>
  10 + <el-form-item label="商品卖点">
  11 + <el-input type="textarea" v-model="baseForm.sellPoint" placeholder="请输入商品卖点"/>
12 12 </el-form-item>
13   - <el-form-item label="分类id" prop="categoryIds">
14   - <el-cascader
15   - v-model="baseForm.categoryIds"
16   - placeholder="请输入分类id"
17   - style="width: 100%"
18   - :options="categoryList"
19   - :props="propName"
20   - clearable
21   - ></el-cascader>
22   - </el-form-item>
23   - <el-form-item label="商品轮播图" prop="picUrls">
  13 + <!-- TODO @Luowenfeng:商品主图,80 x 80 即可 -->
  14 + <el-form-item label="商品主图" prop="picUrls">
24 15 <ImageUpload v-model="baseForm.picUrls" :value="baseForm.picUrls" :limit="10"/>
25 16 </el-form-item>
26   - <el-form-item label="排序字段">
27   - <el-input v-model="baseForm.sort" placeholder="请输入排序字段" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/>
  17 + <!-- TODO @Luowenfeng:商品视频 -->
  18 + <el-form-item label="商品品牌" prop="brandId">
  19 + <el-select v-model="baseForm.brandId" placeholder="请选择商品品牌">
  20 + <el-option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id" />
  21 + </el-select>
  22 + </el-form-item>
  23 + <el-form-item label="商品分类" prop="categoryIds">
  24 + <el-cascader v-model="baseForm.categoryIds" placeholder="商品分类" style="width: 100%"
  25 + :options="categoryList" :props="propName" clearable />
  26 + </el-form-item>
  27 + <el-form-item label="是否上架" prop="status">
  28 + <el-radio-group v-model="baseForm.status">
  29 + <el-radio :label="0">立即上架</el-radio>
  30 + <el-radio :label="1">放入仓库</el-radio>
  31 + </el-radio-group>
28 32 </el-form-item>
29 33 </el-form>
30 34 </el-tab-pane>
... ... @@ -32,7 +36,8 @@
32 36 <!-- 价格库存 -->
33 37 <el-tab-pane label="价格库存" name="rates" class="rates">
34 38 <el-form ref="rates" :model="ratesForm" :rules="rules">
35   - <el-form-item label="商品规格">
  39 + <el-form-item label="启用多规格">
  40 + <!-- TODO @Luowenfeng:改成开关的按钮;关闭,单规格;开启,多规格 -->
36 41 <el-radio-group v-model="ratesForm.spec" @change="changeRadio">
37 42 <el-radio :label="1">单规格</el-radio>
38 43 <el-radio :label="2">多规格</el-radio>
... ... @@ -41,28 +46,13 @@
41 46  
42 47 <!-- 动态添加规格属性 -->
43 48 <div v-show="ratesForm.spec === 2">
44   - <div
45   - v-for="(specs, index) in dynamicSpec"
46   - :key="index"
47   - class="dynamic-spec"
48   - >
  49 + <div v-for="(specs, index) in dynamicSpec" :key="index" class="dynamic-spec">
49 50 <!-- 删除按钮 -->
50   - <el-button
51   - type="danger"
52   - icon="el-icon-delete"
53   - circle
54   - class="spec-delete"
55   - @click="removeSpec(index)"
56   - ></el-button>
  51 + <el-button type="danger" icon="el-icon-delete" circle class="spec-delete" @click="removeSpec(index)" />
57 52 <div class="spec-header">
58 53 规格项:
59 54 <el-select v-model="specs.specId" filterable placeholder="请选择" @change="changeSpec">
60   - <el-option
61   - v-for="item in propertyPageList"
62   - :key="item.id"
63   - :label="item.name"
64   - :value="item.id">
65   - </el-option>
  55 + <el-option v-for="item in propertyPageList" :key="item.id" :label="item.name" :value="item.id" />
66 56 </el-select>
67 57 </div>
68 58 <div class="spec-values">
... ... @@ -71,24 +61,17 @@
71 61 </template>
72 62 </div>
73 63 </div>
74   - <el-button type="primary" @click="dynamicSpec.push({specValue: []}); ratesForm.rates = []"
75   - >添加规格项目
76   - </el-button
77   - >
  64 + <el-button type="primary" @click="dynamicSpec.push({specValue: []}); ratesForm.rates = []">添加规格项目</el-button>
78 65 </div>
79 66  
80 67 <!-- 规格明细 -->
81 68 <el-form-item label="规格明细">
82 69 <el-table :data="ratesForm.rates" border style="width: 100%" ref="ratesTable">
83 70 <template v-if="ratesForm.spec == 2">
84   - <el-table-column :key="index" v-for="(item, index) in dynamicSpec.filter(v=>v.specName != undefined)"
  71 + <el-table-column :key="index" v-for="(item, index) in dynamicSpec.filter(v => v.specName !== undefined)"
85 72 :label="item.specName">
86 73 <template slot-scope="scope">
87   - <el-input
88   - v-if="scope.row.spec"
89   - v-model="scope.row.spec[index]"
90   - disabled
91   - ></el-input>
  74 + <el-input v-if="scope.row.spec" v-model="scope.row.spec[index]" disabled />
92 75 </template>
93 76 </el-table-column>
94 77 </template>
... ... @@ -98,25 +81,20 @@
98 81 style="width: 100px; height: 50px"/>
99 82 </template>
100 83 </el-table-column>
101   - <template v-if="ratesForm.spec == 2">
  84 + <template v-if="ratesForm.spec === 2">
102 85 <el-table-column label="sku名称" :render-header="addRedStar" key="91">
103 86 <template slot-scope="scope">
104   - <el-form-item :prop="'rates.'+ scope.$index + '.name'" :rules="[{required: true, trigger: 'change'}]">
105   - <el-input
106   - v-model="scope.row.name"
107   - ></el-input>
108   - </el-form-item>
  87 + <el-form-item :prop="'rates.'+ scope.$index + '.name'" :rules="[{required: true, trigger: 'change'}]">
  88 + <el-input v-model="scope.row.name" />
  89 + </el-form-item>
109 90 </template>
110 91 </el-table-column>
111   - </template>
112   -
  92 + </template>
113 93 <el-table-column label="市场价(元)" :render-header="addRedStar" key="92">
114 94 <template slot-scope="scope">
115 95 <el-form-item :prop="'rates.'+ scope.$index + '.marketPrice'" :rules="[{required: true, trigger: 'change'}]">
116   - <el-input
117   - v-model="scope.row.marketPrice"
118   - oninput="value= value.match(/\d+(\.\d{0,2})?/) ? value.match(/\d+(\.\d{0,2})?/)[0] : ''"
119   - ></el-input>
  96 + <el-input v-model="scope.row.marketPrice"
  97 + oninput="value= value.match(/\d+(\.\d{0,2})?/) ? value.match(/\d+(\.\d{0,2})?/)[0] : ''"/>
120 98 </el-form-item>
121 99 </template>
122 100 </el-table-column>
... ... @@ -164,12 +142,8 @@
164 142 <el-input v-model="scope.row.barCode"></el-input>
165 143 </template>
166 144 </el-table-column>
167   - <template v-if="ratesForm.spec == 2">
168   - <el-table-column
169   - fixed="right"
170   - label="操作"
171   - width="50"
172   - key="100">
  145 + <template v-if="ratesForm.spec === 2">
  146 + <el-table-column fixed="right" label="操作" width="50" key="100">
173 147 <template slot-scope="scope">
174 148 <el-button @click="scope.row.status = 1" type="text" size="small" v-show="scope.row.status == undefined || scope.row.status == 0 ">禁用</el-button>
175 149 <el-button @click="scope.row.status = 0" type="text" size="small" v-show="scope.row.status == 1">启用</el-button>
... ... @@ -178,11 +152,15 @@
178 152 </template>
179 153 </el-table>
180 154 </el-form-item>
  155 + <el-form-item label="虚拟销量" prop="virtualSalesCount">
  156 + <!-- TODO @Luowenfeng:使用 input 类型即可 -->
  157 + <el-input v-model="baseForm.virtualSalesCount" placeholder="请输入虚拟销量" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/>
  158 + </el-form-item>
181 159 </el-form>
182 160 </el-tab-pane>
183 161  
184 162 <!-- 商品详情 -->
185   - <el-tab-pane label="商品描述" name="third">
  163 + <el-tab-pane label="商品详情" name="third">
186 164 <el-form ref="third" :model="baseForm" :rules="rules">
187 165 <el-form-item prop="description">
188 166 <editor v-model="baseForm.description" :min-height="380"/>
... ... @@ -191,20 +169,10 @@
191 169 </el-tab-pane>
192 170  
193 171 <!-- 销售设置 -->
194   - <el-tab-pane label="销售设置" name="fourth">
  172 + <el-tab-pane label="高级设置" name="fourth">
195 173 <el-form ref="fourth" :model="baseForm" :rules="rules" label-width="100px" style="width: 95%">
196   - <el-form-item label="所属品牌" prop="brandId">
197   - <el-select v-model="baseForm.brandId" placeholder="请选择">
198   - <el-option
199   - v-for="item in brandList"
200   - :key="item.id"
201   - :label="item.name"
202   - :value="item.id">
203   - </el-option>
204   - </el-select>
205   - </el-form-item>
206   - <el-form-item label="虚拟销量" prop="virtualSalesCount">
207   - <el-input v-model="baseForm.virtualSalesCount" placeholder="请输入虚拟销量" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/>
  174 + <el-form-item label="排序字段">
  175 + <el-input v-model="baseForm.sort" placeholder="请输入排序字段" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')"/>
208 176 </el-form-item>
209 177 <el-form-item label="是否展示库存" prop="showStock">
210 178 <el-radio-group v-model="baseForm.showStock">
... ... @@ -212,12 +180,6 @@
212 180 <el-radio :label="false">否</el-radio>
213 181 </el-radio-group>
214 182 </el-form-item>
215   - <el-form-item label="商品状态" prop="status">
216   - <el-radio-group v-model="baseForm.status">
217   - <el-radio :label="0">上架</el-radio>
218   - <el-radio :label="1">下架</el-radio>
219   - </el-radio-group>
220   - </el-form-item>
221 183 </el-form>
222 184 </el-tab-pane>
223 185 </el-tabs>
... ... @@ -253,7 +215,7 @@ export default {
253 215 },
254 216 data() {
255 217 return {
256   - activeName: "base",
  218 + activeName: "base", // TODO @Luowenfeng:切换时,不需要校验通过
257 219 propName: {
258 220 checkStrictly: true,
259 221 label: "name",
... ...