index.vue 12 KB

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