index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. <template>
  2. <zj-tab-page ref="tabPage" :defaultActives="[{ key: 'list', label: $route.meta.title + '-列表', essential: true }]">
  3. <template slot-scope="{ activeKey, data }">
  4. <div v-if="activeKey == 'list'" class="app-container">
  5. <div class="btn-group clearfix">
  6. <div class="fl">
  7. <el-button
  8. v-if="$restrict('add')"
  9. size="small"
  10. type="primary"
  11. icon="el-icon-plus"
  12. @click="addOrEditParent('add1')"
  13. >添加分类</el-button
  14. >
  15. </div>
  16. <div class="fr">
  17. <el-input
  18. placeholder="请输入分类名称进行搜索"
  19. v-model="screenForm.keyword"
  20. size="small"
  21. style="width: 240px"
  22. clearable
  23. >
  24. <el-button slot="append" icon="el-icon-search" size="small" @click="getListByScreen"></el-button>
  25. </el-input>
  26. </div>
  27. </div>
  28. <div class="table">
  29. <el-table
  30. :data="dataList"
  31. row-key="categoryId"
  32. border
  33. default-expand-all
  34. :tree-props="{ children: 'children' }"
  35. >
  36. <el-table-column prop="name" label="分类名称" min-width="150"></el-table-column>
  37. <el-table-column align="center" label="分类图片" prop="imgUrl" width="80">
  38. <template slot-scope="scope">
  39. <el-image
  40. style="width: 40px; height: 40px; display: block; margin: 0 auto"
  41. :src="$showImgUrl(scope.row.imgUrl)"
  42. :preview-src-list="[$showImgUrl(scope.row.imgUrl)]"
  43. fit="cover"
  44. >
  45. <div slot="error" style="height: 100%; font-size: 40px">
  46. <i class="el-icon-picture-outline"></i>
  47. </div>
  48. </el-image>
  49. </template>
  50. </el-table-column>
  51. <el-table-column align="center" prop="createTime" label="创建时间" min-width="160"></el-table-column>
  52. <!-- <el-table-column align="center" prop="goodsNum" label="商品数"></el-table-column> -->
  53. <el-table-column align="center" prop="sortNum" label="排序"></el-table-column>
  54. <el-table-column align="center" prop="companyName" label="商户" min-width="120"></el-table-column>
  55. <el-table-column align="center" label="状态" class-name="status-col">
  56. <template slot-scope="scope">
  57. <el-tag :type="scope.row.status ? 'success' : 'danger'">{{
  58. scope.row.status ? '显示' : '隐藏'
  59. }}</el-tag>
  60. </template>
  61. </el-table-column>
  62. <el-table-column align="right" label="操作" width="150" fixed="right">
  63. <template slot-scope="scope">
  64. <el-button
  65. type="primary"
  66. size="mini"
  67. icon="el-icon-plus"
  68. v-if="scope.row.level == 1 && $restrict('add')"
  69. @click="addOrEditChild('add2', scope.row.categoryId)"
  70. ></el-button>
  71. <el-button
  72. type="primary"
  73. size="mini"
  74. icon="el-icon-edit"
  75. v-if="scope.row.level == 1 && $restrict('edit')"
  76. @click="addOrEditParent('edit1', scope.row.categoryId)"
  77. ></el-button>
  78. <el-button
  79. type="primary"
  80. size="mini"
  81. icon="el-icon-edit"
  82. v-if="scope.row.level == 2 && $restrict('edit')"
  83. @click="addOrEditChild('edit2', scope.row.categoryId)"
  84. ></el-button>
  85. <el-popconfirm
  86. v-if="$restrict('del')"
  87. style="margin-left: 10px"
  88. title="确定删除吗?"
  89. @confirm="handleDelete(scope.row.categoryId)"
  90. >
  91. <el-button slot="reference" size="mini" icon="el-icon-delete"></el-button>
  92. </el-popconfirm>
  93. </template>
  94. </el-table-column>
  95. </el-table>
  96. </div>
  97. </div>
  98. <!-- 新增编辑 一级分类 -->
  99. <div v-if="addParentFormVisible" class="app-container">
  100. <el-form
  101. ref="addParentForm"
  102. :model="addParentForm"
  103. :rules="addParentFormRules"
  104. label-position="left"
  105. label-width="80px"
  106. >
  107. <el-row :gutter="20">
  108. <el-col :span="6">
  109. <el-form-item label="一级分类" prop="oneClassify">
  110. <el-input
  111. type="text"
  112. placeholder="请输入一级分类名称"
  113. v-model="addParentForm.oneClassify"
  114. maxlength="10"
  115. show-word-limit
  116. style="width: 250px"
  117. ></el-input>
  118. </el-form-item>
  119. </el-col>
  120. <el-col :span="6">
  121. <el-form-item label="状态" prop="status">
  122. <el-radio-group v-model="addParentForm.status">
  123. <el-radio :label="true">显示</el-radio>
  124. <el-radio :label="false">隐藏</el-radio>
  125. </el-radio-group>
  126. </el-form-item>
  127. </el-col>
  128. <el-col :span="6">
  129. <el-form-item label="排序" prop="sort">
  130. <el-input placeholder="请输入排序" v-model.number="addParentForm.sort" style="width: 250px"></el-input>
  131. </el-form-item>
  132. </el-col>
  133. <el-col :span="24">
  134. <el-form-item label="分类图片" prop="imgUrl">
  135. <el-upload
  136. class="avatar-uploader"
  137. style="height: 122px"
  138. :action="baseURL + 'common/upload'"
  139. :headers="myHeaders"
  140. :show-file-list="false"
  141. :on-success="uploadSuccess"
  142. :before-upload="beforeUpload"
  143. >
  144. <img v-if="addParentForm.imgUrl" :src="$showImgUrl(addParentForm.imgUrl)" class="avatar" />
  145. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  146. </el-upload>
  147. </el-form-item>
  148. </el-col>
  149. </el-row>
  150. </el-form>
  151. <div slot="footer" class="dialog-footer">
  152. <el-button @click="data.removeTab()">取 消</el-button>
  153. <el-button type="primary" @click="submitAddParentForm(data.removeTab)">确 定</el-button>
  154. </div>
  155. </div>
  156. <!-- 新增编辑 二级分类 -->
  157. <div v-if="addChildFormVisible" class="app-container">
  158. <el-form
  159. ref="addChildForm"
  160. :model="addChildForm"
  161. :rules="addChildFormRules"
  162. label-position="left"
  163. label-width="80px"
  164. >
  165. <el-row :gutter="20">
  166. <el-col :span="6">
  167. <el-form-item label="一级分类" prop="oneClassify">
  168. <el-select
  169. v-model="addChildForm.oneClassify"
  170. placeholder="请选择一级分类"
  171. disabled
  172. style="width: 250px"
  173. >
  174. <el-option
  175. :label="item.name"
  176. :value="item.categoryId"
  177. v-for="(item, index) in classifyList"
  178. :key="index"
  179. ></el-option>
  180. </el-select>
  181. </el-form-item>
  182. </el-col>
  183. <el-col :span="6">
  184. <el-form-item label="二级分类" prop="twoClassify">
  185. <el-input
  186. type="text"
  187. placeholder="请输入二级分类名称"
  188. v-model="addChildForm.twoClassify"
  189. maxlength="10"
  190. show-word-limit
  191. style="width: 250px"
  192. ></el-input>
  193. </el-form-item>
  194. </el-col>
  195. <el-col :span="6">
  196. <el-form-item label="状态" prop="status">
  197. <el-radio-group v-model="addChildForm.status">
  198. <el-radio :label="true">显示</el-radio>
  199. <el-radio :label="false">隐藏</el-radio>
  200. </el-radio-group>
  201. </el-form-item>
  202. </el-col>
  203. <el-col :span="6">
  204. <el-form-item label="排序" prop="sort">
  205. <el-input placeholder="请输入排序" v-model.number="addChildForm.sort" style="width: 250px"></el-input>
  206. </el-form-item>
  207. </el-col>
  208. <el-col :span="24">
  209. <el-form-item label="分类图片" prop="imgUrl">
  210. <el-upload
  211. class="avatar-uploader"
  212. style="height: 122px"
  213. :action="baseURL + 'common/upload'"
  214. :headers="myHeaders"
  215. :show-file-list="false"
  216. :on-success="uploadSuccess"
  217. :before-upload="beforeUpload"
  218. >
  219. <img v-if="addChildForm.imgUrl" :src="$showImgUrl(addChildForm.imgUrl)" class="avatar" />
  220. <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  221. </el-upload>
  222. </el-form-item>
  223. </el-col>
  224. </el-row>
  225. </el-form>
  226. <div slot="footer" class="dialog-footer">
  227. <el-button @click="data.removeTab()">取 消</el-button>
  228. <el-button type="primary" @click="submitAddChildForm(data.removeTab)">确 定</el-button>
  229. </div>
  230. </div>
  231. </template>
  232. </zj-tab-page>
  233. </template>
  234. <script>
  235. import { getToken } from '@/utils/auth'
  236. import {
  237. getClassifyList,
  238. addClassify,
  239. editClassify,
  240. deleteClassify,
  241. getClassifyDetail,
  242. getSmallType
  243. } from '@/api/goods'
  244. import { ORDER_MAIN_TYPE } from '@/utils/select_data'
  245. import { findElem } from '@/utils/util.js'
  246. export default {
  247. data() {
  248. return {
  249. baseURL: process.env.VUE_APP_BASE_API,
  250. myHeaders: { 'x-token': getToken() },
  251. dataList: [], // 列表数据
  252. listLoading: true, // 列表加载loading
  253. screenForm: {
  254. // 筛选表单数据
  255. keyword: '' // 关键词
  256. },
  257. editParentId: null,
  258. addParentFormType: 'add',
  259. addParentFormVisible: false,
  260. addParentForm: {
  261. oneClassify: '',
  262. twoClassify: '',
  263. imgUrl: '',
  264. status: true,
  265. sort: 0
  266. },
  267. addParentFormRules: {
  268. oneClassify: [{ required: true, message: '请填写一级分类名称', trigger: 'blur' }],
  269. imgUrl: [{ required: true, message: '请上传分类图片', trigger: 'change' }]
  270. },
  271. editChildId: null,
  272. addChildFormType: 'add',
  273. addChildFormVisible: false,
  274. addChildForm: {
  275. oneClassify: '',
  276. twoClassify: '',
  277. imgUrl: '',
  278. status: true,
  279. sort: 0
  280. },
  281. addChildFormRules: {
  282. oneClassify: [{ required: true, message: '请选择一级分类', trigger: 'change' }],
  283. twoClassify: [{ required: true, message: '请填写二级分类', trigger: 'blur' }],
  284. imgUrl: [{ required: true, message: '请上传分类图片', trigger: 'change' }]
  285. },
  286. classifyList: [],
  287. orderMainType: ORDER_MAIN_TYPE,
  288. orderSmallType: [],
  289. formType: 'add',
  290. formVisible: false
  291. }
  292. },
  293. created() {
  294. this.getList()
  295. },
  296. methods: {
  297. getList() {
  298. this.listLoading = true
  299. let params = {
  300. type: 2,
  301. name: this.screenForm.keyword
  302. }
  303. getClassifyList(params).then(res => {
  304. this.dataList = res.data
  305. })
  306. },
  307. // 筛选后重新获取列表
  308. getListByScreen() {
  309. this.currentPage = 1
  310. this.getList()
  311. },
  312. // 打开 新增编辑 一级分类
  313. addOrEditParent(type, cid) {
  314. this.$refs.tabPage.addTab({
  315. // 对应显示的模块
  316. activeKey: type,
  317. // 唯一标识
  318. key: type,
  319. // 页签名称
  320. label: { edit1: '编辑一级分类', add1: '添加一级分类' }[type],
  321. // 打开时事件
  322. triggerEvent: () => {
  323. this.$nextTick(() => {
  324. this.formType = type
  325. this.formVisible = true
  326. this.addParentFormType = type
  327. this.addParentFormVisible = true
  328. if (type == 'edit1') {
  329. this.editParentId = cid
  330. getClassifyDetail({ categoryId: cid }).then(res => {
  331. this.addParentForm = {
  332. oneClassify: res.data.name,
  333. status: res.data.status,
  334. imgUrl: res.data.imgUrl,
  335. sort: res.data.sortNum
  336. }
  337. })
  338. }
  339. })
  340. },
  341. // 关闭时事件
  342. closeEvent: () => {
  343. this.cancelAddParentForm()
  344. }
  345. })
  346. },
  347. // 取消 新增编辑 一级分类
  348. cancelAddParentForm() {
  349. this.addParentFormVisible = false
  350. this.$refs?.addParentForm?.resetFields()
  351. },
  352. // 提交 一级分类
  353. submitAddParentForm(cancel) {
  354. this.$refs.addParentForm.validate(valid => {
  355. if (valid) {
  356. let params = {
  357. type: 2,
  358. name: this.addParentForm.oneClassify,
  359. imgUrl: this.addParentForm.imgUrl,
  360. status: this.addParentForm.status,
  361. sortNum: this.addParentForm.sort
  362. }
  363. if (this.addParentFormType == 'edit1') {
  364. params.categoryId = this.editParentId
  365. editClassify(params).then(res => {
  366. cancel('list')
  367. this.cancelAddParentForm()
  368. this.getList()
  369. this.$successMsg('编辑成功')
  370. })
  371. } else {
  372. addClassify(params).then(res => {
  373. cancel('list')
  374. this.cancelAddParentForm()
  375. this.getList()
  376. this.$successMsg('添加成功')
  377. })
  378. }
  379. }
  380. })
  381. },
  382. // 改变大类
  383. changeOrderType() {
  384. this.addChildForm.smallType = ''
  385. this.getSmallType()
  386. },
  387. getSmallType() {
  388. getSmallType({
  389. mainNumber: this.addChildForm.orderType,
  390. categoryId: this.addChildForm.oneClassify
  391. }).then(res => {
  392. this.orderSmallType = res.data
  393. })
  394. },
  395. // 打开 新增编辑 二级分类
  396. addOrEditChild(type, cid) {
  397. this.$refs.tabPage.addTab({
  398. // 对应显示的模块
  399. activeKey: type,
  400. // 唯一标识
  401. key: type,
  402. // 页签名称
  403. label: { edit2: '编辑二级分类', add2: '添加二级分类' }[type],
  404. // 打开时事件
  405. triggerEvent: () => {
  406. this.$nextTick(() => {
  407. this.formType = type
  408. this.formVisible = true
  409. this.addChildFormType = type
  410. this.addChildFormVisible = true
  411. getClassifyList({ name: '', type: 2 }).then(res => {
  412. this.classifyList = res.data
  413. })
  414. if (type == 'add2') {
  415. this.addChildForm.oneClassify = cid
  416. }
  417. if (type == 'edit2') {
  418. this.editChildId = cid
  419. getClassifyDetail({ categoryId: cid }).then(res => {
  420. this.addChildForm = {
  421. oneClassify: res.data.parentId,
  422. twoClassify: res.data.name,
  423. imgUrl: res.data.imgUrl,
  424. status: res.data.status,
  425. sort: res.data.sortNum
  426. }
  427. this.getSmallType()
  428. })
  429. }
  430. })
  431. },
  432. // 关闭时事件
  433. closeEvent: () => {
  434. this.cancelAddChildForm()
  435. }
  436. })
  437. },
  438. // 取消 新增编辑 二级分类
  439. cancelAddChildForm() {
  440. this.addChildFormVisible = false
  441. this.$refs?.addChildForm?.resetFields()
  442. },
  443. // 提交 二级分类
  444. submitAddChildForm(cancel) {
  445. this.$refs.addChildForm.validate(valid => {
  446. if (valid) {
  447. let params = {}
  448. if (this.addChildFormType == 'edit2') {
  449. params = {
  450. type: 2,
  451. categoryId: this.editChildId,
  452. name: this.addChildForm.twoClassify,
  453. imgUrl: this.addChildForm.imgUrl,
  454. status: this.addChildForm.status,
  455. sortNum: this.addChildForm.sort
  456. }
  457. editClassify(params).then(res => {
  458. cancel('list')
  459. this.cancelAddChildForm()
  460. this.getList()
  461. this.$successMsg('编辑成功')
  462. })
  463. } else {
  464. params = {
  465. children: [
  466. {
  467. type: 2,
  468. parentId: this.addChildForm.oneClassify,
  469. name: this.addChildForm.twoClassify,
  470. imgUrl: this.addChildForm.imgUrl,
  471. status: this.addChildForm.status,
  472. sortNum: this.addChildForm.sort
  473. }
  474. ]
  475. }
  476. addClassify(params).then(res => {
  477. cancel('list')
  478. this.cancelAddChildForm()
  479. this.getList()
  480. this.$successMsg('添加成功')
  481. })
  482. }
  483. }
  484. })
  485. },
  486. // 操作 - 删除
  487. handleDelete(id) {
  488. console.log(id)
  489. deleteClassify({ categoryId: id }).then(res => {
  490. this.getList()
  491. this.$successMsg()
  492. })
  493. },
  494. uploadSuccess(res, file, index) {
  495. if (this.addParentFormVisible) {
  496. this.addParentForm.imgUrl = res.data.url
  497. } else {
  498. this.addChildForm.imgUrl = res.data.url
  499. }
  500. },
  501. beforeUpload(file) {
  502. const fileSuffix = file.name.substring(file.name.lastIndexOf('.') + 1)
  503. const whiteList = ['jpg', 'jpeg', 'png']
  504. if (whiteList.indexOf(fileSuffix) === -1) {
  505. this.$errorMsg('只支持上传jpg/png文件!')
  506. return false
  507. }
  508. }
  509. }
  510. }
  511. </script>
  512. <style scoped lang="scss"></style>
  513. <style lang="scss">
  514. .el-image-viewer__wrapper .el-icon-circle-close {
  515. color: #ffffff !important;
  516. font-size: 60px;
  517. }
  518. .el-table__row.expanded {
  519. background: #f5f5f5;
  520. }
  521. th:first-child,
  522. th:last-child {
  523. text-align: center !important;
  524. }
  525. </style>