index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. <template>
  2. <div class="my-container">
  3. <div class="bill-left">
  4. <div class="bill-tab">
  5. <div class="title">导航</div>
  6. <el-tree :data="data" node-key="id" :default-expanded-keys="expandedKeys" :props="props"
  7. @node-click="handleNodeClick"></el-tree>
  8. </div>
  9. </div>
  10. <div class="bill-main">
  11. <module-view :propConfig="config" ref="moduleView" @pagination="getDataList" @search="getDataList"
  12. @resert="getDataList" @clickHandle="clickHandle" @detail="openEdit">
  13. </module-view>
  14. </div>
  15. <!-- 新增/编辑弹窗 -->
  16. <el-dialog :title="popTitle+'商品分类'" :visible.sync="dialogFormVisible" width="30%">
  17. <by-form :propConfig="addConfig" ref="addFormId">
  18. <template v-slot:status class="clearfix">
  19. <el-radio class="fl" style="margin-top: 8px;" v-model="radio" :label="0">正常</el-radio>
  20. <el-radio class="fl" style="margin-top: 8px;" v-model="radio" :label="1">禁用</el-radio>
  21. </template>
  22. </by-form>
  23. <div slot="footer" class="dialog-footer">
  24. <el-button @click="dialogFormVisible = false">取 消</el-button>
  25. <el-button type="primary" @click="confirm">确 定</el-button>
  26. </div>
  27. </el-dialog>
  28. </div>
  29. </template>
  30. <script lang="ts">
  31. import { Component, Prop, Vue, Watch } from "vue-property-decorator";
  32. import api from "@/api/currency";
  33. import Assembly from "@/components/Assembly/material.vue";
  34. @Component
  35. export default class ProductClassification extends Vue {
  36. // 左边
  37. data : any = []
  38. expandedKeys : any = []
  39. parentId : any = ''
  40. props = {
  41. label: 'name',
  42. children: 'children'
  43. }
  44. // 右边
  45. baseURL : any = process.env.VUE_APP_BASE_API
  46. timeNum = 0;
  47. timer : any = null
  48. popTitle : any = ''
  49. radio : any = 0
  50. dialogFormVisible : boolean = false
  51. config : any = {
  52. search: {
  53. attr: {
  54. size: 'mini'
  55. },
  56. columns: [
  57. [{
  58. span: 6,
  59. label: '名称',
  60. prop: 'name',
  61. component: 'by-input',
  62. labelWidth: '70px',
  63. compConfig: {
  64. attr: {
  65. placeholder: '请输入名称',
  66. clearable: true
  67. },
  68. },
  69. },
  70. {
  71. span: 6,
  72. label: '简称',
  73. prop: 'shortName',
  74. component: 'by-input',
  75. labelWidth: '70px',
  76. compConfig: {
  77. attr: {
  78. placeholder: '请输入简称',
  79. clearable: true
  80. },
  81. },
  82. },
  83. {
  84. span: 6,
  85. label: '状态',
  86. prop: 'status',
  87. component: 'by-select',
  88. labelWidth: '70px',
  89. compConfig: {
  90. attr: {
  91. placeholder: '请选择数据',
  92. clearable: true,
  93. data: [{
  94. value: 0,
  95. label: '正常'
  96. }, {
  97. value: 1,
  98. label: '禁用'
  99. }]
  100. }
  101. }
  102. },
  103. ]
  104. ]
  105. },
  106. tool: {
  107. tools: {
  108. add: true,
  109. // delete: true,
  110. search: true,
  111. refresh: true
  112. }
  113. },
  114. table: {
  115. attr: {
  116. size: 'mini',
  117. seq: true,
  118. align: 'center',
  119. checkbox: false,
  120. height: 600,
  121. },
  122. columns: [{
  123. width: 300,
  124. title: '名称',
  125. field: 'name',
  126. isDetail: true,
  127. }, {
  128. title: '简称',
  129. field: 'shortName'
  130. }, {
  131. width: 80,
  132. title: '状态',
  133. field: 'status',
  134. component: Assembly,
  135. },
  136. {
  137. title: '备注',
  138. field: 'remark',
  139. }, {
  140. width: 120,
  141. title: '操作',
  142. action: true,
  143. plugins: [{
  144. icon: 'el-icon-edit',
  145. name: '编辑',
  146. audit: '',
  147. event: {
  148. click: (item : any) => {
  149. (this as any).openEdit(item)
  150. }
  151. }
  152. }, {
  153. name: '删除',
  154. event: {
  155. click: (item : any) => (this as any).doDelete2(item)
  156. }
  157. }]
  158. }]
  159. },
  160. }
  161. addConfig = {
  162. attr: {
  163. size: 'small',
  164. rules: {
  165. name: [{
  166. required: true, message: '请输入名称', trigger: 'blur'
  167. }],
  168. parentName: [{
  169. required: true, message: '请选择父级', trigger: 'blur'
  170. }],
  171. }
  172. },
  173. columns: [
  174. [
  175. {
  176. span: 23,
  177. label: '父级',
  178. labelWidth: '70px',
  179. prop: 'parentName',
  180. component: 'select-tree',
  181. compConfig: {
  182. attr: {
  183. label: 'name',
  184. clearable: true,
  185. retConfig: {
  186. parentId: 'id',
  187. parentName: 'name',
  188. },
  189. defaultExpandAll: true
  190. },
  191. request: {
  192. url: '/maindata/maindataMaterialCategory/treeList'
  193. }
  194. }
  195. },
  196. {
  197. span: 23,
  198. labelWidth: '70px',
  199. label: '名称',
  200. prop: 'name',
  201. component: 'by-input',
  202. },
  203. {
  204. span: 23,
  205. labelWidth: '70px',
  206. label: '简称',
  207. slot: true,
  208. prop: 'shortName',
  209. component: 'by-input',
  210. },
  211. {
  212. span: 23,
  213. labelWidth: '70px',
  214. label: '状态',
  215. slot: true,
  216. prop: 'status',
  217. },
  218. {
  219. span: 23,
  220. labelWidth: '70px',
  221. label: '备注',
  222. slot: true,
  223. prop: 'remark',
  224. component: 'by-input',
  225. },
  226. ],
  227. ]
  228. }
  229. mounted() {
  230. this.getTreeList()
  231. this.timer = setInterval(() => {
  232. this.getDataList()
  233. }, 500)
  234. }
  235. // 获取树型导航数据
  236. getTreeList() {
  237. api.treeList('maindataMaterialCategory').then((res : any) => {
  238. if (res.code === 200) {
  239. this.data = res.data;
  240. this.expandedKeys.push(res.data[0].id)
  241. res.data[0].children.map((v : any) => {
  242. this.expandedKeys.push(v.id)
  243. })
  244. } else this.failHandle(res)
  245. })
  246. }
  247. // 确认新增/编辑
  248. confirm() {
  249. (this as any).$refs.addFormId.validate().then(() => {
  250. let query = (this as any).$refs.addFormId.getValue();
  251. console.log('确认新增/编辑 ==> ', query);
  252. if (!query.parentId) query.parentId = 0;
  253. query.status = this.radio;
  254. this.dialogFormVisible = false;
  255. if (this.popTitle === '新增') {
  256. api.saveList(query, 'maindataMaterialCategory').then((res : any) => {
  257. if (res.code === 200) {
  258. this.$message({
  259. type: 'success',
  260. message: this.popTitle + '成功!'
  261. });
  262. this.getTreeList();
  263. this.getDataList();
  264. } else this.failHandle(res)
  265. })
  266. } else if (this.popTitle === '编辑') {
  267. api.updateList(query, 'maindataMaterialCategory').then((res : any) => {
  268. if (res.code === 200) {
  269. this.$message({
  270. type: 'success',
  271. message: this.popTitle + '成功!'
  272. });
  273. this.getTreeList();
  274. this.getDataList();
  275. } else this.failHandle(res)
  276. })
  277. }
  278. })
  279. }
  280. // 获取列表数据
  281. getDataList() {
  282. if (!this.$refs.moduleView) {
  283. if (this.timeNum > 5) {
  284. clearInterval(this.timer)
  285. }
  286. this.timeNum++;
  287. return
  288. }
  289. clearInterval(this.timer)
  290. let query = (this.$refs.moduleView as any).getQuery();
  291. query.parentId = this.parentId;
  292. let newData : any = {}
  293. for (let key in query) {
  294. if (query[key].toString()) {
  295. newData[key] = query[key]
  296. }
  297. }
  298. console.log('表单字段 ==> ', newData);
  299. api.pageList(newData, 'maindataMaterialCategory').then((res : any) => {
  300. if (res.code === 200) {
  301. (this.$refs.moduleView as any).setTableValue(res.data.records);
  302. let page = {
  303. pageNo: res.data.current, //当前页
  304. pageSize: res.data.size, //每页条数
  305. total: res.data.total //总条数
  306. };
  307. (this.$refs.moduleView as any).setPage(page)
  308. } else this.failHandle(res)
  309. })
  310. }
  311. // 工具栏方法
  312. clickHandle(e : any) {
  313. if (e === 'onRefresh') (this.$refs.moduleView as any).resert();
  314. if (e === 'onAdd') this.onAdd();
  315. if (e === 'onDelete') this.onDelete();
  316. if (e === 'onExport') this.onExport();
  317. }
  318. // 打开新增
  319. onAdd() {
  320. this.popTitle = '新增'
  321. this.dialogFormVisible = true;
  322. this.radio = 0
  323. setTimeout(() => {
  324. if ((this as any).$refs.addFormId) (this as any).$refs.addFormId.setValue({});
  325. }, 0)
  326. }
  327. // 打开编辑
  328. openEdit(e : any) {
  329. console.log('打开编辑 ==> ', e);
  330. this.popTitle = '编辑'
  331. this.dialogFormVisible = true;
  332. this.radio = e.status
  333. api.single({ id: e.parentId }, 'maindataMaterialCategory').then((res : any) => {
  334. if (res.code === 200) {
  335. e.parentName = res.data.name
  336. setTimeout(() => {
  337. if ((this as any).$refs.addFormId) (this as any).$refs.addFormId.setValue(e);
  338. }, 0)
  339. }
  340. })
  341. }
  342. // 工具栏删除
  343. onDelete() {
  344. let selectData = (this.$refs.moduleView as any).getSelectData()
  345. let ids = '';
  346. if (selectData.length > 0) {
  347. selectData.map((v : any) => {
  348. ids += v.id + ','
  349. })
  350. } else return this.$message({ type: 'warning', message: '请选择删除数据' })
  351. ids = ids.slice(0, ids.length - 1);
  352. this.$confirm('确定删除吗,此操作不能撤销!', '注意', {
  353. confirmButtonText: '确定',
  354. cancelButtonText: '取消',
  355. type: 'warning',
  356. center: true
  357. }).then(() => {
  358. api.deleteList({ ids: ids }, 'maindataMaterialCategory').then((res : any) => {
  359. if (res.code === 200) {
  360. this.getTreeList();
  361. this.getDataList();
  362. this.$message({
  363. type: 'success',
  364. message: '删除成功!'
  365. });
  366. } else this.failHandle(res)
  367. })
  368. }).catch(() => {
  369. this.$message({
  370. type: 'info',
  371. message: '已取消删除'
  372. });
  373. });
  374. }
  375. // 操作删除
  376. doDelete2(item : any) {
  377. this.$confirm('确定删除吗,此操作不能撤销!', '注意', {
  378. confirmButtonText: '确定',
  379. cancelButtonText: '取消',
  380. type: 'warning',
  381. center: true
  382. }).then(() => {
  383. api.childrenTreeList({ id: item.id }, 'maindataMaterialCategory').then((v : any) => {
  384. if (v.code === 200) {
  385. if (v.data.length > 0) return this.$message({ type: 'error', message: '此数据有子节点,不能进行删除!' })
  386. api.deleteList({ ids: item.id }, 'maindataMaterialCategory').then((res : any) => {
  387. if (res.code === 200) {
  388. this.getTreeList();
  389. this.getDataList();
  390. this.$message({
  391. type: 'success',
  392. message: '删除成功!'
  393. });
  394. } else this.failHandle(res)
  395. })
  396. } else this.$message({ type: 'error', message: '删除失败!请稍后再试' })
  397. })
  398. }).catch(() => {
  399. this.$message({
  400. type: 'info',
  401. message: '已取消删除'
  402. });
  403. });
  404. }
  405. // 导航切换
  406. handleNodeClick(e : any) {
  407. this.parentId = e.id
  408. api.childrenTreeList({ id: e.id }, 'maindataMaterialCategory').then((res : any) => {
  409. if (res.code === 200) {
  410. (this.$refs.moduleView as any).setTableValue(res.data);
  411. let page = {
  412. pageNo: res.data.current, //当前页
  413. pageSize: res.data.size, //每页条数
  414. total: res.data.total //总条数
  415. };
  416. (this.$refs.moduleView as any).setPage(page)
  417. }
  418. })
  419. }
  420. //导出
  421. onExport() {
  422. let urlArr = '/maindata/maindataMaterial';
  423. let query = (this.$refs.moduleView as any).getQuery();
  424. (this as any).$download(urlArr + '/export', {
  425. ...query
  426. }, urlArr[urlArr.length - 1] + `_${new Date().getTime()}.xlsx`)
  427. }
  428. // 运行错误
  429. failHandle(err : any) {
  430. let msg = err.msg ? err.msg : '运行错误!';
  431. this.$message.error(msg)
  432. }
  433. }
  434. </script>
  435. <style lang="scss" scoped>
  436. .my-container {
  437. width: 100%;
  438. box-sizing: border-box;
  439. display: flex;
  440. padding: 16px;
  441. .search-btn {
  442. width: 100%;
  443. display: flex;
  444. justify-content: flex-end;
  445. margin-bottom: 20px;
  446. }
  447. .bill-left {
  448. position: relative;
  449. border-right: solid #EEE 1px;
  450. padding-right: 16px;
  451. flex-shrink: 0;
  452. // box-sizing: border-box;
  453. .bill-tab {
  454. width: 150px;
  455. height: 100%;
  456. transition: all .5s;
  457. overflow: hidden;
  458. }
  459. .title {
  460. font-size: 16px;
  461. padding-bottom: 16px;
  462. width: 200px;
  463. }
  464. .bill-nav {
  465. font-size: 14px;
  466. height: 30px;
  467. line-height: 30px;
  468. width: 200px;
  469. box-sizing: border-box;
  470. padding: 0 8px;
  471. cursor: pointer;
  472. margin-bottom: 2px;
  473. border-radius: 5px;
  474. }
  475. .onBill {
  476. background-color: #bde3f7;
  477. }
  478. .bill-nav:hover {
  479. background-color: #bde3f7;
  480. }
  481. .close {
  482. height: 22px;
  483. width: 22px;
  484. border-radius: 50%;
  485. border: solid #EEE 1px;
  486. position: absolute;
  487. top: 30px;
  488. right: -11px;
  489. background-color: #FFF;
  490. display: flex;
  491. justify-content: center;
  492. align-items: center;
  493. cursor: pointer;
  494. }
  495. }
  496. .bill-main {
  497. width: calc(100% - 16px);
  498. box-sizing: border-box;
  499. margin-left: 16px;
  500. position: relative;
  501. .bill-box {
  502. width: 100%;
  503. position: absolute;
  504. left: 0;
  505. top: 0;
  506. opacity: 0;
  507. z-index: -1;
  508. transition: all .5s;
  509. .bill-tool,
  510. .table-tool {
  511. width: 100%;
  512. padding-bottom: 16px;
  513. }
  514. .form {
  515. margin-bottom: 8px;
  516. }
  517. }
  518. .on-show {
  519. opacity: 1;
  520. z-index: 1;
  521. }
  522. }
  523. }
  524. </style>