template-page-1.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. <template>
  2. <div class="template-page-1">
  3. <zj-page-template
  4. ref="zjpage"
  5. tableMinHeight="300px"
  6. :getTableData="getTableData"
  7. :columnParsing="columnParsing"
  8. :reduction="reduction"
  9. :showTable="showTable"
  10. :codeGather="codeGather"
  11. :loading="loading"
  12. :lowerLine="true"
  13. :onSavePlan="onSavePlan"
  14. :onClosePlain="onClosePlain"
  15. :defaultSearchData="defaultSearchData"
  16. :replaceOrNotMap="replaceOrNotMap"
  17. :optionsEvensGroup="selBtn([...optionsEvensGroup, evens])"
  18. :operation="operation"
  19. :operationColumnWidth="operationColumnWidth"
  20. :plan="[...defaultPlan, ...timePlan, ...paramList, ...morePlan]"
  21. :tableEvents="{ ...defaultTableEvents, ...tableEvents }"
  22. :tableAttributes="{ ...defaultTableAttributes, ...tableAttributes }"
  23. :ellipsis="ellipsis"
  24. :pageSizes="pageSizes"
  25. @columnWidthChange="columnWidthChange"
  26. @columnListChange="columnListChange"
  27. :screeningAnalysis="screeningAnalysis"
  28. :filterMethod="filterMethod"
  29. :sortMethod="sortMethod"
  30. :moreParameters="moreParameters"
  31. >
  32. <template slot="more-search">
  33. <slot name="moreSearch"></slot>
  34. </template>
  35. </zj-page-template>
  36. <sel-export-column-list :columnList="columnList" @determine="exportDetermine" @cancel="columnList = []" />
  37. <slot />
  38. <el-dialog title="定义方案名" :visible.sync="dialogVisible" width="380px" :before-close="handleClose">
  39. <el-input size="mini" maxlength="8" show-word-limit v-model="inputText" placeholder="请输入名称"></el-input>
  40. <span slot="footer" class="dialog-footer">
  41. <el-button size="mini" @click="handleClose">取 消</el-button>
  42. <el-button size="mini" type="primary" @click="onSavePlanqd">确 定</el-button>
  43. </span>
  44. </el-dialog>
  45. </div>
  46. </template>
  47. <script>
  48. import { zfireSave, zfireDel } from '@/api/fieldMan.js'
  49. import { dictListDict } from '@/api/dataDictionary.js'
  50. import { zfireParamList, zfireParamSave, zfireParamDelete } from '@/api/zfireParam.js'
  51. import SelExportColumnList from './sel-export-column-list.vue'
  52. import selectData from './selectData.js'
  53. import operation_mixin from '@/components/template/operation_mixin.js'
  54. export default {
  55. components: {
  56. SelExportColumnList
  57. },
  58. mixins: [operation_mixin],
  59. props: {
  60. ellipsis: {
  61. type: Boolean,
  62. default: true
  63. },
  64. moreParameters: {
  65. type: Array,
  66. default: () => []
  67. },
  68. loading: {
  69. type: Boolean,
  70. default: false
  71. },
  72. // 事件组合
  73. optionsEvensGroup: {
  74. type: Array,
  75. default: () => []
  76. },
  77. // 表格属性
  78. tableAttributes: {
  79. type: Object,
  80. default: () => ({})
  81. },
  82. // 表格事件
  83. tableEvents: {
  84. type: Object,
  85. default: () => ({})
  86. },
  87. // 表格列解析渲染数据更改
  88. columnParsing: {
  89. type: Function
  90. },
  91. // 获取列表的方法
  92. getList: {
  93. type: Function
  94. },
  95. // 导出的方法
  96. exportList: {
  97. type: Function
  98. },
  99. // 更多方案
  100. morePlan: {
  101. type: Array,
  102. default: () => []
  103. },
  104. // 操作按钮
  105. operation: {
  106. type: Function
  107. },
  108. // 获取操作记录的主键字段
  109. operationRecordkey: {
  110. type: String,
  111. default: ''
  112. },
  113. // 操作按钮单元格宽度
  114. operationColumnWidth: {
  115. type: Number,
  116. default: 140
  117. },
  118. // 自定义列
  119. cstomClumn: {
  120. type: Function
  121. },
  122. // 结构数据钩子
  123. fieldBeansHook: {
  124. type: Function
  125. },
  126. // 菜单名称
  127. customModuleName: {
  128. type: String,
  129. default: ''
  130. },
  131. defaultSearchData: {
  132. type: Array,
  133. default: () => []
  134. },
  135. replaceOrNotMap: {
  136. type: Boolean,
  137. default: false
  138. },
  139. setModuleId: {
  140. type: [String, Number],
  141. default: null
  142. },
  143. screeningAnalysis: {
  144. type: Function,
  145. default: (jname, val) => {
  146. return val
  147. }
  148. },
  149. filterMethod: {
  150. type: Function,
  151. default: (value, row, column) => {
  152. return row[column['property']] === value
  153. }
  154. },
  155. sortMethod: {
  156. type: Function,
  157. default: undefined
  158. },
  159. pageSizes: {
  160. type: Array,
  161. default: () => [15, 30, 50, 100, 150, 200]
  162. },
  163. expCode: {
  164. type: String,
  165. default: 'exp'
  166. },
  167. // 数据钩子
  168. recordsHook: {
  169. type: Function
  170. },
  171. expName: {
  172. type: String,
  173. default: ''
  174. }
  175. },
  176. data() {
  177. return {
  178. dialogVisible: false,
  179. // 搜索的参数
  180. parameter: {},
  181. // 表格属性
  182. defaultTableAttributes: {},
  183. // 表格事件
  184. defaultTableEvents: {},
  185. // 记录初始的id
  186. columnsIds: {},
  187. // 导出弹窗
  188. columnList: [],
  189. showTable: false,
  190. codeGather: {},
  191. frontCodes: [],
  192. planItem: null,
  193. inputText: '',
  194. defaultPlan: [
  195. {
  196. name: '默认方案',
  197. paramCallback: () => {
  198. return []
  199. }
  200. }
  201. ],
  202. paramList: [],
  203. timePlan: [],
  204. pk: ''
  205. }
  206. },
  207. computed: {
  208. userid() {
  209. return this.$store.getters.userid
  210. },
  211. moduleId() {
  212. return this.setModuleId || this.$route.meta.moduleId
  213. },
  214. moduleName() {
  215. return this.customModuleName || this.$route.meta.title
  216. },
  217. evens() {
  218. return this.exportList
  219. ? [
  220. [
  221. this.optionsEvensAuth(this.expCode, {
  222. click: this.export
  223. })
  224. ]
  225. ]
  226. : []
  227. }
  228. },
  229. mounted() {
  230. this.getZfireParamList()
  231. },
  232. methods: {
  233. insertionData(...p) {
  234. this.$refs.zjpage.insertionData(...p)
  235. },
  236. deleteRowData(...p) {
  237. this.$refs.zjpage.deleteRowData(...p)
  238. },
  239. tableForm() {
  240. return this.$refs.zjpage.$refs.tableForm
  241. },
  242. getTimeDay(num = 0) {
  243. var day2 = new Date()
  244. if (num > 0) {
  245. day2.setTime(day2.getTime() + 24 * 60 * 60 * 1000 * Math.abs(num))
  246. } else if (num < 0) {
  247. day2.setTime(day2.getTime() - 24 * 60 * 60 * 1000 * Math.abs(num))
  248. } else {
  249. day2.setTime(day2.getTime())
  250. }
  251. return (
  252. day2.getFullYear() +
  253. '-' +
  254. (day2.getMonth() + 1 < 10 ? `0${day2.getMonth() + 1}` : day2.getMonth() + 1) +
  255. '-' +
  256. (day2.getDate() < 10 ? `0${day2.getDate()}` : day2.getDate())
  257. )
  258. },
  259. setDefaultPlan(createTimeKey) {
  260. this.$nextTick(() => {
  261. if (createTimeKey) {
  262. var day = this.getTimeDay()
  263. var day1 = this.getTimeDay(-1)
  264. this.timePlan = [
  265. {
  266. name: '今日',
  267. paramCallback: () => {
  268. return [
  269. { param: createTimeKey, compare: '>=', value: `${day} 00:00:00` },
  270. { param: createTimeKey, compare: '<=', value: `${day} 23:59:59` }
  271. ]
  272. }
  273. },
  274. {
  275. name: '昨日',
  276. paramCallback: () => {
  277. return [
  278. { param: createTimeKey, compare: '>=', value: `${day1} 00:00:00` },
  279. { param: createTimeKey, compare: '<=', value: `${day1} 23:59:59` }
  280. ]
  281. }
  282. }
  283. ]
  284. }
  285. })
  286. },
  287. // 关闭方案命名弹窗
  288. handleClose() {
  289. this.planItem = null
  290. this.inputText = ''
  291. this.dialogVisible = false
  292. },
  293. // 获取方案记录
  294. getZfireParamList() {
  295. zfireParamList({
  296. moduleId: this.moduleId
  297. }).then(res => {
  298. this.paramList = res.data.map(item => {
  299. return {
  300. name: item.name,
  301. id: item.id,
  302. closable: true,
  303. paramCallback: () => {
  304. return item.items.map(dav => {
  305. if (dav.value[0] == '[' && dav.value[dav.value.length - 1] == ']') {
  306. return {
  307. param: dav.param,
  308. compare: dav.compare,
  309. value: dav.value.substring(1, dav.value.length - 1).split(',')
  310. }
  311. }
  312. return { param: dav.param, compare: dav.compare, value: dav.value }
  313. })
  314. }
  315. }
  316. })
  317. })
  318. },
  319. // 点击获取保存方案数据
  320. onSavePlan(p) {
  321. if (this.paramList.length >= 10) {
  322. this.$message.error('自定义方案最多支持保留10个')
  323. return
  324. }
  325. if (p.length) {
  326. this.planItem = p
  327. this.dialogVisible = true
  328. } else {
  329. this.$message.error('请先设置搜索条件')
  330. }
  331. },
  332. // 确定保存方案
  333. onSavePlanqd() {
  334. if (this.inputText) {
  335. zfireParamSave({
  336. moduleId: this.moduleId,
  337. name: this.inputText,
  338. items: this.planItem
  339. }).then(res => {
  340. this.handleClose()
  341. this.getZfireParamList()
  342. })
  343. } else {
  344. this.$message.error('请先填写方案名称')
  345. }
  346. },
  347. // 删除方案
  348. onClosePlain(p) {
  349. if (p.id) {
  350. this.$confirm('删除此方案, 是否继续?', '提示', {
  351. confirmButtonText: '确定',
  352. cancelButtonText: '取消',
  353. type: 'warning'
  354. })
  355. .then(() => {
  356. zfireParamDelete({ id: p.id }).then(res => {
  357. this.$message({
  358. message: '删除成功',
  359. type: 'success'
  360. })
  361. this.getZfireParamList()
  362. })
  363. })
  364. .catch(() => {})
  365. }
  366. },
  367. // 过滤按钮集合
  368. selBtn(arr) {
  369. for (var i = 0; i < arr.length; i++) {
  370. if (Array.isArray(arr[i])) {
  371. this.selBtn(arr[i])
  372. }
  373. if (!(arr[i].isRole === undefined ? true : this.carryOutIsRole(arr[i].isRole)) || arr[i].length == 0) {
  374. arr.splice(i, 1)
  375. i--
  376. }
  377. }
  378. return arr
  379. },
  380. carryOutIsRole(isRole) {
  381. if (typeof isRole === 'function') {
  382. return isRole()
  383. }
  384. return isRole
  385. },
  386. // 获取下拉对应数据
  387. getCodeGather() {
  388. let codes = this.frontCodes.filter(key => (this.codeGather[key] ? false : true))
  389. if (codes && codes.length) {
  390. var codeGather = {}
  391. Promise.all(
  392. codes.map(code => {
  393. if (selectData[code]) {
  394. return selectData[code]()
  395. }
  396. return dictListDict({ dictType: code })
  397. })
  398. ).then(resAll => {
  399. codes.map((code, index) => {
  400. var arr = resAll[index].data.map(item => {
  401. return { value: item.dictCode, label: item.dictValue }
  402. })
  403. codeGather[code] = arr
  404. })
  405. this.codeGather = { ...this.codeGather, ...codeGather }
  406. })
  407. }
  408. },
  409. // 获取列表数据函数
  410. async getTableData(data) {
  411. if (!this.getList) {
  412. return
  413. }
  414. try {
  415. var { querylist, page, size, ...data_ } = data
  416. this.parameter = {
  417. ...data_,
  418. pageNum: page,
  419. pageSize: size,
  420. params: querylist,
  421. moduleId: this.moduleId
  422. }
  423. var res = await this.getList(this.parameter)
  424. // alert('接收到数据断点')
  425. if (res.code == 200) {
  426. if (this.recordsHook) {
  427. res.data.records =
  428. this.recordsHook([...(res?.data?.records.map(item => ({ ...item, selectMapData: {} })) || [])]) ||
  429. res?.data?.records.map(item => ({ ...item, selectMapData: {} })) ||
  430. []
  431. } else {
  432. res.data.records = res?.data?.records.map(item => ({ ...item, selectMapData: {} })) || []
  433. }
  434. if (this.fieldBeansHook) {
  435. res.fieldBeans = this.fieldBeansHook(res.fieldBeans) || res.fieldBeans
  436. }
  437. for (let item of res.fieldBeans) {
  438. if (item.jname === 'createTime') {
  439. this.setDefaultPlan(`${item.tbName ? item.tbName + '.' : ''}${item.colName}`)
  440. }
  441. if (item.pk) {
  442. this.$nextTick(() => {
  443. this.pk = item.colName
  444. })
  445. }
  446. if (item.frontCode && !~this.frontCodes.indexOf(item.frontCode)) {
  447. this.frontCodes.push(item.frontCode)
  448. }
  449. if (item.label === 'cstomClumn' && this.cstomClumn) {
  450. this.cstomClumn(item.jname, res.data.records, res.fieldBeans, this.parameter)
  451. }
  452. }
  453. this.getCodeGather()
  454. return res
  455. }
  456. } catch (error) {
  457. console.log(error)
  458. } finally {
  459. if (!this.showTable) {
  460. this.$nextTick(() => {
  461. this.showTable = true
  462. })
  463. }
  464. }
  465. },
  466. // 监听列表显示状态与排序变化
  467. columnListChange(columnList) {
  468. zfireSave(
  469. this.$refs.zjpage.columnList.map((item, index) => {
  470. var data = {
  471. ...item.exportField,
  472. sortNum: Number(item.sortNum),
  473. isCopy: item.isCopy,
  474. tiling: item.tiling,
  475. isTotal: item.isTotal,
  476. isShow: !item.hidden,
  477. moduleId: this.moduleId,
  478. adminUserId: this.userid
  479. }
  480. return data
  481. }),
  482. this.moduleId
  483. )
  484. .then(res => {})
  485. .catch(err => {
  486. this.$message.error('保存失败')
  487. })
  488. },
  489. // 监听列宽度变化
  490. columnWidthChange({ newWidth, oldWidth, column }) {
  491. zfireSave(
  492. this.$refs.zjpage.columnList.map((item, index) => {
  493. if (item.exportField.jname === column.property) {
  494. item.exportField.width = newWidth
  495. }
  496. return {
  497. ...item.exportField,
  498. sortNum: index,
  499. isCopy: item.isCopy,
  500. isTotal: item.isTotal,
  501. isShow: !item.hidden,
  502. moduleId: this.moduleId,
  503. adminUserId: this.userid
  504. }
  505. }),
  506. this.moduleId
  507. )
  508. .then(res => {})
  509. .catch(err => {
  510. this.$message.error('保存失败')
  511. })
  512. },
  513. // 表格恢复初始默认状态
  514. reduction() {
  515. zfireDel({}, this.userid, this.moduleId)
  516. .then(res => {
  517. this.refreshList(true)
  518. })
  519. .catch(err => {
  520. this.$message.error('操作失败')
  521. })
  522. },
  523. getParams() {
  524. var querylist_ = this.$refs.zjpage.$refs.dynamicCondition.jiexi(
  525. JSON.parse(JSON.stringify(this.$refs.zjpage.$refs.dynamicCondition.queryData))
  526. )
  527. return this.$refs.zjpage.parameterAnalysis({ querylist: querylist_ })
  528. },
  529. processString(input) {
  530. // 去除首尾的空格和换行符
  531. let trimmedString = input.trim()
  532. // 将字符串中的换行符替换为逗号
  533. // let result = trimmedString.replace(/\n+/g, ',')
  534. return trimmedString
  535. },
  536. // 导出
  537. export() {
  538. this.columnList = this.$refs.zjpage.columnList.filter(item => !item.hidden)
  539. },
  540. async exportDetermine(data) {
  541. if (!this.exportList) {
  542. return
  543. }
  544. const loading = this.$loading({
  545. lock: true,
  546. text: '正在导出',
  547. spinner: 'el-icon-loading',
  548. background: 'rgba(0, 0, 0, 0.7)'
  549. })
  550. var { querylist, ...p } = this.getParams()
  551. var pms = {
  552. ...this.parameter,
  553. ...p,
  554. pageSize: 1,
  555. params: querylist.map(item => {
  556. item.param = item.param.replace(/>=/g, '')
  557. item.param = item.param.replace(/<=/g, '')
  558. if (
  559. // item.compare === '=' &&
  560. typeof item.value == 'string' &&
  561. (item.value.includes(',') || item.value.includes(','))
  562. ) {
  563. // item.value.replace(/\\n/g, '');
  564. // 去除字符串首尾的空格以及换行符号,然后把内容中的换行符号转换成逗号
  565. var str = this.processString(item.value)
  566. // 去除空格
  567. str = str.replace(/[\t\r\f\n\s]*/g, '')
  568. // 转中文逗号
  569. str = str.replace(/,/g, ',')
  570. // 切割为数组
  571. item.value = str.split(',').map(v => this.processString(v))
  572. } else if (typeof item.value == 'string') {
  573. item.value = this.processString(item.value)
  574. }
  575. return item
  576. })
  577. }
  578. var newPms = {}
  579. var res = await this.getList(pms, data => {
  580. newPms = data
  581. })
  582. // alert('接收到数据断点')
  583. if (res.code == 200) {
  584. if (res?.data?.records?.length) {
  585. this.exportList(
  586. {
  587. ...pms,
  588. ...newPms,
  589. pageSize: -1,
  590. exportFields: data
  591. },
  592. `${this.expName || this.moduleName}.xlsx`
  593. )
  594. .then(res => {
  595. this.$message({
  596. message: '导出成功',
  597. type: 'success'
  598. })
  599. this.columnList = []
  600. loading.close()
  601. })
  602. .catch(err => {
  603. this.$message.error('导出失败')
  604. this.columnList = []
  605. loading.close()
  606. })
  607. } else {
  608. this.$message.error('导出条件没有查到任何符合条件的数据,请调整查询条件再导出。')
  609. this.columnList = []
  610. loading.close()
  611. }
  612. } else {
  613. this.columnList = []
  614. loading.close()
  615. }
  616. },
  617. refreshList() {
  618. this.$refs.zjpage.refresh()
  619. }
  620. }
  621. }
  622. </script>
  623. <style lang="scss" scoped>
  624. .template-page-1 {
  625. width: 100%;
  626. height: 100%;
  627. position: relative;
  628. box-sizing: border-box;
  629. overflow: auto;
  630. }
  631. .zj-page-template {
  632. position: relative;
  633. z-index: 0;
  634. }
  635. @font-face {
  636. font-family: 'aliyun_iconfont';
  637. src: url('~@/components/template/font/font_2075393_0cjq4n8ykvds.woff2') format('woff2'),
  638. url('~@/components/template/font/font_2075393_0cjq4n8ykvds.woff') format('woff'),
  639. url('~@/components/template/font/font_2075393_0cjq4n8ykvds.ttf') format('truetype');
  640. }
  641. ::v-deep .el-table__cell {
  642. padding: 0 !important;
  643. }
  644. ::v-deep .el-table--mini td,
  645. ::v-deep .el-table--mini th {
  646. padding: 0 !important;
  647. }
  648. ::v-deep .el-table__column-filter-trigger {
  649. .el-icon-arrow-down {
  650. font-family: aliyun_iconfont !important;
  651. font-size: 13px;
  652. line-height: 34px;
  653. font-style: normal;
  654. font-weight: 400;
  655. font-variant: normal;
  656. text-transform: none;
  657. vertical-align: baseline;
  658. display: inline-block;
  659. -webkit-font-smoothing: antialiased;
  660. transform: translate(-2px, 1px);
  661. color: #c0c4cc;
  662. width: 20px;
  663. text-align: center;
  664. }
  665. .el-icon-arrow-down:before {
  666. content: '\e64c' !important;
  667. }
  668. }
  669. ::v-deep .zj-buttons-group {
  670. .el-upload-list {
  671. display: none !important;
  672. }
  673. }
  674. ::v-deep .operation-btns {
  675. width: 100%;
  676. height: 35px;
  677. display: flex;
  678. flex-direction: row;
  679. align-items: center;
  680. & > *:not(:last-child) {
  681. margin-right: 5px;
  682. }
  683. .el-button {
  684. margin-left: 0 !important;
  685. }
  686. }
  687. // ::v-deep .is-disabled {
  688. // .el-textarea__inner,
  689. // .el-input__inner,
  690. // .el-radio__label,
  691. // .el-radio__input {
  692. // background-color: rgba(228, 231, 237, 0.35) !important;
  693. // color: #606266 !important;
  694. // }
  695. // }
  696. ::v-deep .el-checkbox.is-bordered.is-checked,
  697. ::v-deep .el-radio.is-bordered.is-checked {
  698. border-color: #409eff !important;
  699. }
  700. ::v-deep .el-checkbox__input.is-checked .el-checkbox__inner,
  701. ::v-deep .el-radio__input.is-checked .el-radio__inner {
  702. border-color: #409eff !important;
  703. background: #409eff !important;
  704. }
  705. ::v-deep .el-checkbox.is-bordered {
  706. margin-left: 0 !important;
  707. margin-right: 10px !important;
  708. }
  709. ::v-deep .teshudeshangchuananniu {
  710. color: #fff !important;
  711. }
  712. ::v-deep .el-table__row {
  713. .is-right {
  714. .text-view {
  715. text-align: right !important;
  716. display: flex;
  717. justify-content: flex-end !important;
  718. flex-wrap: wrap;
  719. }
  720. }
  721. .is-left {
  722. .text-view {
  723. text-align: left !important;
  724. justify-content: flex-start !important;
  725. flex-wrap: wrap;
  726. }
  727. }
  728. }
  729. </style>