index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. <template> 
  2. <div class="app-container">
  3. <el-card class="filter-container" shadow="never">
  4. <div>
  5. <i class="el-icon-search"></i>
  6. <span>筛选搜索</span>
  7. <el-button
  8. style="float: right"
  9. @click="handleSearchList()"
  10. type="primary"
  11. size="small">
  12. 查询结果
  13. </el-button>
  14. <el-button
  15. style="float: right;margin-right: 15px"
  16. @click="handleResetSearch()"
  17. size="small">
  18. 重置
  19. </el-button>
  20. </div>
  21. <div style="margin-top: 15px">
  22. <el-form :inline="true" :model="listQuery" size="small" label-width="140px">
  23. <el-form-item label="输入搜索:">
  24. <el-input style="width: 203px" v-model="listQuery.keyword" placeholder="商品名称"></el-input>
  25. </el-form-item>
  26. <el-form-item label="商品货号:">
  27. <el-input style="width: 203px" v-model="listQuery.productSn" placeholder="商品货号"></el-input>
  28. </el-form-item>
  29. <el-form-item label="商品分类:">
  30. <el-cascader
  31. clearable
  32. v-model="selectProductCateValue"
  33. :options="productCateOptions">
  34. </el-cascader>
  35. </el-form-item>
  36. <el-form-item label="商品品牌:">
  37. <el-select v-model="listQuery.brandId" placeholder="请选择品牌" clearable>
  38. <el-option
  39. v-for="item in brandOptions"
  40. :key="item.value"
  41. :label="item.label"
  42. :value="item.value">
  43. </el-option>
  44. </el-select>
  45. </el-form-item>
  46. <el-form-item label="上架状态:">
  47. <el-select v-model="listQuery.publishStatus" placeholder="全部" clearable>
  48. <el-option
  49. v-for="item in publishStatusOptions"
  50. :key="item.value"
  51. :label="item.label"
  52. :value="item.value">
  53. </el-option>
  54. </el-select>
  55. </el-form-item>
  56. <el-form-item label="审核状态:">
  57. <el-select v-model="listQuery.verifyStatus" placeholder="全部" clearable>
  58. <el-option
  59. v-for="item in verifyStatusOptions"
  60. :key="item.value"
  61. :label="item.label"
  62. :value="item.value">
  63. </el-option>
  64. </el-select>
  65. </el-form-item>
  66. </el-form>
  67. </div>
  68. </el-card>
  69. <el-card class="operate-container" shadow="never">
  70. <i class="el-icon-tickets"></i>
  71. <span>数据列表</span>
  72. <el-button
  73. class="btn-add"
  74. @click="handleAddItem()"
  75. size="mini">
  76. 添加
  77. </el-button>
  78. </el-card>
  79. <div class="table-container">
  80. <el-table ref="productTable"
  81. :data="list"
  82. style="width: 100%"
  83. @selection-change="handleSelectionChange"
  84. v-loading="listLoading"
  85. border>
  86. <el-table-column type="selection" width="60" align="center"></el-table-column>
  87. <el-table-column label="编号" width="100" align="center">
  88. <template slot-scope="scope">{{scope.row.id}}</template>
  89. </el-table-column>
  90. <el-table-column label="商品图片" width="120" align="center">
  91. <template slot-scope="scope"><img style="height: 80px" :src="scope.row.pic"></template>
  92. </el-table-column>
  93. <el-table-column label="商品名称" align="center">
  94. <template slot-scope="scope">
  95. <p>{{scope.row.name}}</p>
  96. <p>品牌:{{scope.row.brandName}}</p>
  97. </template>
  98. </el-table-column>
  99. <el-table-column label="价格/货号" width="120" align="center">
  100. <template slot-scope="scope">
  101. <p>价格:¥{{scope.row.price}}</p>
  102. <p>货号:{{scope.row.productSn}}</p>
  103. </template>
  104. </el-table-column>
  105. <el-table-column label="标签" width="140" align="center">
  106. <template slot-scope="scope">
  107. <p>上架:
  108. <el-switch
  109. @change="handlePublishStatusChange(scope.$index, scope.row)"
  110. :active-value="1"
  111. :inactive-value="0"
  112. v-model="scope.row.publishStatus">
  113. </el-switch>
  114. </p>
  115. <p>新品:
  116. <el-switch
  117. @change="handleNewStatusChange(scope.$index, scope.row)"
  118. :active-value="1"
  119. :inactive-value="0"
  120. v-model="scope.row.newStatus">
  121. </el-switch>
  122. </p>
  123. <p>推荐:
  124. <el-switch
  125. @change="handleRecommendStatusChange(scope.$index, scope.row)"
  126. :active-value="1"
  127. :inactive-value="0"
  128. v-model="scope.row.recommandStatus">
  129. </el-switch>
  130. </p>
  131. </template>
  132. </el-table-column>
  133. <el-table-column label="排序" width="100" align="center">
  134. <template slot-scope="scope">{{scope.row.sort}}</template>
  135. </el-table-column>
  136. <el-table-column label="SKU库存" width="100" align="center">
  137. <template slot-scope="scope">
  138. <el-button type="primary" icon="el-icon-edit" circle></el-button>
  139. </template>
  140. </el-table-column>
  141. <el-table-column label="销量" width="100" align="center">
  142. <template slot-scope="scope">{{scope.row.sale}}</template>
  143. </el-table-column>
  144. <el-table-column label="审核状态" width="100" align="center">
  145. <template slot-scope="scope">
  146. <p>{{scope.row.verifyStatus | verifyStatusFilter}}</p>
  147. <p>
  148. <el-button
  149. type="text"
  150. @click="handleDelete(scope.$index, scope.row)">审核详情
  151. </el-button>
  152. </p>
  153. </template>
  154. </el-table-column>
  155. <el-table-column label="操作" width="160" align="center">
  156. <template slot-scope="scope">
  157. <p>
  158. <el-button
  159. size="mini"
  160. @click="handleShowProduct(scope.$index, scope.row)">查看
  161. </el-button>
  162. <el-button
  163. size="mini"
  164. @click="handleEdit(scope.$index, scope.row)">编辑
  165. </el-button>
  166. </p>
  167. <p>
  168. <el-button
  169. size="mini"
  170. @click="handleShowLog(scope.$index, scope.row)">日志
  171. </el-button>
  172. <el-button
  173. size="mini"
  174. type="danger"
  175. @click="handleDelete(scope.$index, scope.row)">删除
  176. </el-button>
  177. </p>
  178. </template>
  179. </el-table-column>
  180. </el-table>
  181. </div>
  182. <div class="batch-operate-container">
  183. <el-select
  184. size="small"
  185. v-model="operateType" placeholder="批量操作">
  186. <el-option
  187. v-for="item in operates"
  188. :key="item.value"
  189. :label="item.label"
  190. :value="item.value">
  191. </el-option>
  192. </el-select>
  193. <el-button
  194. style="margin-left: 20px"
  195. class="search-button"
  196. @click="handleBatchOperate()"
  197. type="primary"
  198. size="small">
  199. 确定
  200. </el-button>
  201. </div>
  202. <div class="pagination-container">
  203. <el-pagination
  204. background
  205. @size-change="handleSizeChange"
  206. @current-change="handleCurrentChange"
  207. layout="total, sizes,prev, pager, next,jumper"
  208. :page-size="listQuery.pageSize"
  209. :page-sizes="[5,10,15]"
  210. :current-page.sync="listQuery.pageNum"
  211. :total="total">
  212. </el-pagination>
  213. </div>
  214. </div>
  215. </template>
  216. <script>
  217. import {
  218. fetchList,
  219. updateDeleteStatus,
  220. updateNewStatus,
  221. updateRecommendStatus,
  222. updatePublishStatus
  223. } from '@/api/product'
  224. import {fetchList as fetchBrandList} from '@/api/brand'
  225. import {fetchListWithChildren} from '@/api/productCate'
  226. const defaultListQuery = {
  227. keyword: null,
  228. pageNum: 1,
  229. pageSize: 5,
  230. publishStatus: null,
  231. verifyStatus: null,
  232. productSn: null,
  233. productCategoryId: null,
  234. brandId: null
  235. };
  236. export default {
  237. name: "productList",
  238. data() {
  239. return {
  240. operates: [
  241. {
  242. label: "商品上架",
  243. value: "publishOn"
  244. },
  245. {
  246. label: "商品下架",
  247. value: "publishOff"
  248. },
  249. {
  250. label: "设为推荐",
  251. value: "recommendOn"
  252. },
  253. {
  254. label: "取消推荐",
  255. value: "recommendOff"
  256. },
  257. {
  258. label: "设为新品",
  259. value: "newOn"
  260. },
  261. {
  262. label: "取消新品",
  263. value: "newOff"
  264. },
  265. {
  266. label: "转移到分类",
  267. value: "transferCategory"
  268. },
  269. {
  270. label: "移入回收站",
  271. value: "recycle"
  272. }
  273. ],
  274. operateType: null,
  275. listQuery: Object.assign({}, defaultListQuery),
  276. list: null,
  277. total: null,
  278. listLoading: true,
  279. selectProductCateValue: null,
  280. multipleSelection: [],
  281. productCateOptions: [],
  282. brandOptions: [],
  283. publishStatusOptions: [{
  284. value: 1,
  285. label: '上架'
  286. }, {
  287. value: 0,
  288. label: '下架'
  289. }],
  290. verifyStatusOptions: [{
  291. value: 1,
  292. label: '审核通过'
  293. }, {
  294. value: 0,
  295. label: '未审核'
  296. }]
  297. }
  298. },
  299. created() {
  300. this.getList();
  301. this.getBrandList();
  302. this.getProductCateList();
  303. },
  304. watch: {
  305. selectProductCateValue: function (newValue) {
  306. if (newValue != null && newValue.length == 2) {
  307. this.listQuery.productCategoryId = newValue[1];
  308. } else {
  309. this.listQuery.productCategoryId = null;
  310. }
  311. }
  312. },
  313. filters: {
  314. verifyStatusFilter(value) {
  315. if (value === 1) {
  316. return '审核通过';
  317. } else {
  318. return '未审核';
  319. }
  320. }
  321. },
  322. methods: {
  323. getList() {
  324. this.listLoading = true;
  325. fetchList(this.listQuery).then(response => {
  326. this.listLoading = false;
  327. this.list = response.data.list;
  328. this.total = response.data.total;
  329. });
  330. },
  331. getBrandList() {
  332. fetchBrandList({pageNum: 1, pageSize: 100}).then(response => {
  333. this.brandOptions = [];
  334. let brandList = response.data.list;
  335. for (let i = 0; i < brandList.length; i++) {
  336. this.brandOptions.push({label: brandList[i].name, value: brandList[i].id});
  337. }
  338. });
  339. },
  340. getProductCateList() {
  341. fetchListWithChildren().then(response => {
  342. let list = response.data;
  343. this.productCateOptions = [];
  344. for (let i = 0; i < list.length; i++) {
  345. let children = [];
  346. if (list[i].children != null && list[i].children.length > 0) {
  347. for (let j = 0; j < list[i].children.length; j++) {
  348. children.push({label: list[i].children[j].name, value: list[i].children[j].id});
  349. }
  350. }
  351. this.productCateOptions.push({label: list[i].name, value: list[i].id, children: children});
  352. }
  353. });
  354. },
  355. handleSearchList() {
  356. this.listQuery.pageNum = 1;
  357. this.getList();
  358. },
  359. handleAddItem() {
  360. console.log("handleAddItem");
  361. },
  362. handleBatchOperate() {
  363. if(this.operateType==null){
  364. this.$message({
  365. message: '请选择操作类型',
  366. type: 'warning',
  367. duration: 1000
  368. });
  369. return;
  370. }
  371. if(this.multipleSelection==null||this.multipleSelection.length<1){
  372. this.$message({
  373. message: '请选择要操作的商品',
  374. type: 'warning',
  375. duration: 1000
  376. });
  377. return;
  378. }
  379. this.$confirm('是否要进行该批量操作?', '提示', {
  380. confirmButtonText: '确定',
  381. cancelButtonText: '取消',
  382. type: 'warning'
  383. }).then(() => {
  384. let ids=[];
  385. for(let i=0;i<this.multipleSelection.length;i++){
  386. ids.push(this.multipleSelection[i].id);
  387. }
  388. switch (this.operateType) {
  389. case this.operates[0].value:
  390. this.updatePublishStatus(1,ids);
  391. break;
  392. case this.operates[1].value:
  393. this.updatePublishStatus(0,ids);
  394. break;
  395. case this.operates[2].value:
  396. this.updateRecommendStatus(1,ids);
  397. break;
  398. case this.operates[3].value:
  399. this.updateRecommendStatus(0,ids);
  400. break;
  401. case this.operates[4].value:
  402. this.updateNewStatus(1,ids);
  403. break;
  404. case this.operates[5].value:
  405. this.updateNewStatus(0,ids);
  406. break;
  407. case this.operates[6].value:
  408. break;
  409. case this.operates[7].value:
  410. this.updateDeleteStatus(1,ids);
  411. break;
  412. default:
  413. break;
  414. }
  415. this.getList();
  416. });
  417. },
  418. handleSizeChange(val) {
  419. this.listQuery.pageNum = 1;
  420. this.listQuery.pageSize = val;
  421. this.getList();
  422. },
  423. handleCurrentChange(val) {
  424. this.listQuery.pageNum = val;
  425. this.getList();
  426. },
  427. handleSelectionChange(val) {
  428. this.multipleSelection = val;
  429. },
  430. handlePublishStatusChange(index, row) {
  431. let ids = [];
  432. ids.push(row.id);
  433. this.updatePublishStatus(row.publishStatus, ids);
  434. },
  435. handleNewStatusChange(index, row) {
  436. let ids = [];
  437. ids.push(row.id);
  438. this.updateNewStatus(row.newStatus, ids);
  439. },
  440. handleRecommendStatusChange(index, row) {
  441. let ids = [];
  442. ids.push(row.id);
  443. this.updateRecommendStatus(row.recommandStatus, ids);
  444. },
  445. handleResetSearch() {
  446. this.selectProductCateValue = [];
  447. this.listQuery = Object.assign({}, defaultListQuery);
  448. },
  449. handleDelete(index, row){
  450. this.$confirm('是否要进行删除操作?', '提示', {
  451. confirmButtonText: '确定',
  452. cancelButtonText: '取消',
  453. type: 'warning'
  454. }).then(() => {
  455. let ids = [];
  456. ids.push(row.id);
  457. this.updateDeleteStatus(1,ids);
  458. });
  459. },
  460. updatePublishStatus(publishStatus, ids) {
  461. let params = new URLSearchParams();
  462. params.append('ids', ids);
  463. params.append('publishStatus', publishStatus);
  464. updatePublishStatus(params).then(response => {
  465. this.$message({
  466. message: '修改成功',
  467. type: 'success',
  468. duration: 1000
  469. });
  470. });
  471. },
  472. updateNewStatus(newStatus, ids) {
  473. let params = new URLSearchParams();
  474. params.append('ids', ids);
  475. params.append('newStatus', newStatus);
  476. updateNewStatus(params).then(response => {
  477. this.$message({
  478. message: '修改成功',
  479. type: 'success',
  480. duration: 1000
  481. });
  482. });
  483. },
  484. updateRecommendStatus(recommendStatus, ids) {
  485. let params = new URLSearchParams();
  486. params.append('ids', ids);
  487. params.append('recommendStatus', recommendStatus);
  488. updateRecommendStatus(params).then(response => {
  489. this.$message({
  490. message: '修改成功',
  491. type: 'success',
  492. duration: 1000
  493. });
  494. });
  495. },
  496. updateDeleteStatus(deleteStatus, ids) {
  497. let params = new URLSearchParams();
  498. params.append('ids', ids);
  499. params.append('deleteStatus', deleteStatus);
  500. updateDeleteStatus(params).then(response => {
  501. this.$message({
  502. message: '删除成功',
  503. type: 'success',
  504. duration: 1000
  505. });
  506. });
  507. this.getList();
  508. }
  509. }
  510. }
  511. </script>
  512. <style></style>