page.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. <template>
  2. <ibps-container
  3. ref="dashboardContainer"
  4. v-loading="loading"
  5. :element-loading-text="$t('common.loading')"
  6. :scroll-delay="scrollDelay"
  7. type="full"
  8. class="ibps-desktop-page"
  9. @scroll="({ x, y }) => { scrollTop = y }"
  10. >
  11. <newHome @handleApprove="handleApprove" @handleUnreadMessage="handleUnreadMessage">
  12. <template slot="myslot">
  13. <el-upload
  14. style="display: inline-block"
  15. class="upload-demo"
  16. :action="uloadPath"
  17. :headers="headers"
  18. :before-upload="beforeUpload"
  19. :show-file-list="false"
  20. :on-error="fileErr"
  21. :on-success="handleSuccess"
  22. >
  23. <el-button size="small" icon="el-icon-s-management" plain type="primary">导入委托单</el-button>
  24. </el-upload>
  25. <el-upload
  26. style="display: inline-block; margin-left: 10px"
  27. class="upload-demo"
  28. :action="reportPath"
  29. v-if="showRepost"
  30. :headers="headers"
  31. :before-upload="ReportBeforeUpload"
  32. :show-file-list="false"
  33. :on-error="fileErr"
  34. :on-success="handleSuccess"
  35. >
  36. <el-button size="small" plain icon="el-icon-s-order" type="primary">替换/新增报表</el-button>
  37. </el-upload>
  38. <el-button
  39. type="primary"
  40. plain
  41. size="small"
  42. style="display: inline-block; margin-left: 10px"
  43. icon="el-icon-download"
  44. @click="downloadData()"
  45. >
  46. 下载桌面应用</el-button
  47. >
  48. </template>
  49. </newHome>
  50. <ibps-back-to-top
  51. :visibility-height="150"
  52. :scroll-top="scrollTop"
  53. transition-name="fade"
  54. @scrollToTop="scrollToTop"
  55. />
  56. <preview
  57. :id="id"
  58. :visible="dialogPreviewVisible"
  59. title="全屏预览"
  60. screen
  61. @close="visible => (dialogPreviewVisible = visible)"
  62. />
  63. <bpmn-formrender
  64. :visible="bpmnFormrenderDialogVisible"
  65. :def-id="defId"
  66. :task-id="taskId"
  67. :instance-id="instanceId"
  68. @close="visible => (bpmnFormrenderDialogVisible = visible)"
  69. @callback="handleFlowCallback"
  70. />
  71. <ibps-news-dialog
  72. :id="newsEditId"
  73. title="公告栏目明细"
  74. :visible="ibpsNewsDialogVisible"
  75. :readonly="true"
  76. @close="visible => (ibpsNewsDialogVisible = visible)"
  77. />
  78. <ibps-message-dialog
  79. :id="messageEditId"
  80. title="消息明细"
  81. :readonly="true"
  82. :visible="ibpsMessageDialogVisible"
  83. @close="visible => (ibpsMessageDialogVisible = visible)"
  84. />
  85. </ibps-container>
  86. <!-- <template v-if="initLoading">
  87. <template v-if="localSystem">
  88. <ibps-grid-layout
  89. v-if="layout && layout.length >0"
  90. :layout.sync="layout"
  91. :col-num="colNum"
  92. :row-height="rowHeight"
  93. :is-draggable="isDraggable"
  94. :is-resizable="isResizable"
  95. :is-mirrored="isMirrored"
  96. :vertical-compact="verticalCompact"
  97. :margin="margin"
  98. :use-css-transforms="useCssTransforms"
  99. >
  100. <ibps-grid-item
  101. v-for="(item,index) in layout"
  102. :key="item.i"
  103. :x="item.x"
  104. :y="item.y"
  105. :w="item.w"
  106. :h="item.h"
  107. :i="item.i"
  108. >
  109. <component
  110. :is="'ibps-desktop-'+item.alias"
  111. v-if="hasComponent(item.alias)"
  112. :id="item.i" :ref="item.alias"
  113. :alias="item.alias"
  114. :height="getHeight(item.h)"
  115. @action-event="(command,data)=> handleActionEvent(command,data,index)"
  116. />
  117. </ibps-grid-item>
  118. </ibps-grid-layout>
  119. <el-alert
  120. v-else-if="!loading"
  121. :closable="false"
  122. type="warning"
  123. show-icon
  124. style="height:50px"
  125. >
  126. <span slot="title">未设置个人桌面布局,可以通过“<a href="javascript:void(0)" @click="goMyLayout">个人办公-》个人桌面布局</a>”进行设置</span>
  127. </el-alert>
  128. </template>
  129. <!==不是本地系统==>
  130. <template v-else>
  131. <!==iframe方式==>
  132. <iframe
  133. v-if="systemUrlType === 'iframe'"
  134. ref="systemrender"
  135. class="ibps-container-frame"
  136. frameborder="0"
  137. />
  138. <!==vue组件方式==>
  139. <component
  140. v-else
  141. ref="systemrender"
  142. :is="systemUrlName"
  143. :params="systemUrlParams"
  144. />
  145. </template>
  146. </template> -->
  147. </template>
  148. <script>
  149. import { getMyDesktop } from '@/api/platform/desktop/myLayout'
  150. import { initColumn, isInit, getComponents } from './components'
  151. import { BASE_API, BUSINESS_BASE_URL } from '@/api/baseUrl' //引用导出地址
  152. // 网格布局组件
  153. import { GridLayout, GridItem } from 'vue-grid-layout'
  154. import IbpsBackToTop from '@/components/ibps-back-to-top'
  155. import Preview from '@/views/platform/desktop/column/preview'
  156. import BpmnFormrender from '@/business/platform/bpmn/form/dialog'
  157. import IbpsNewsDialog from '@/views/platform/system/news/cms'
  158. import IbpsMessageDialog from '@/views/platform/message/inner/detail/dialog'
  159. import { StatisticsData } from '@/api/platform/system/jbdHome'
  160. import { StatisticsSign } from '@/api/platform/system/jbdHome'
  161. import { getToken } from '@/utils/auth'
  162. import newHome from './components/new-home'
  163. import curdPost from '@/business/platform/form/utils/custom/joinCURD.js'
  164. const _import = require('@/utils/util.import.' + process.env.NODE_ENV)
  165. export default {
  166. components: {
  167. 'ibps-news-dialog': IbpsNewsDialog,
  168. 'ibps-message-dialog': IbpsMessageDialog,
  169. IbpsBackToTop,
  170. Preview,
  171. newHome,
  172. BpmnFormrender,
  173. 'ibps-grid-layout': GridLayout,
  174. 'ibps-grid-item': GridItem
  175. },
  176. data() {
  177. return {
  178. infoMessage: [],
  179. uloadPath: BASE_API() + BUSINESS_BASE_URL() + '/ck/task/importExcel',
  180. reportPath: BASE_API() + BUSINESS_BASE_URL() + '/sys/SysDataContext/replaceReportFile',
  181. layout: null,
  182. colNum: 24,
  183. rowHeight: 30,
  184. isDraggable: false,
  185. isResizable: false,
  186. isMirrored: false,
  187. verticalCompact: true,
  188. margin: [15, 15],
  189. useCssTransforms: true,
  190. taskId: '',
  191. ibpsNewsDialogVisible: false,
  192. newsEditId: '',
  193. showRepost: true,
  194. ibpsMessageDialogVisible: false,
  195. messageEditId: '',
  196. scrollDelay: 0,
  197. scrollTop: 0,
  198. initLoading: false,
  199. loading: false,
  200. id: '',
  201. dialogPreviewVisible: false, // 预览
  202. defaultData: [],
  203. bpmnFormrenderDialogVisible: false, // 流程
  204. defId: '',
  205. taskId: '',
  206. instanceId: '',
  207. layoutIndex: '',
  208. initInterval: null,
  209. systemUrlType: 'iframe',
  210. systemUrlName: '',
  211. systemUrlParams: {},
  212. alias: '',
  213. headers: {
  214. 'X-Authorization-access_token': getToken()
  215. }
  216. }
  217. },
  218. computed: {
  219. system() {
  220. return this.$store.getters.system ? this.$store.getters.system : null
  221. },
  222. systemAlias() {
  223. return this.$store.getters.system ? this.$store.getters.system.alias : ''
  224. },
  225. localSystem() {
  226. return this.system.isLocal
  227. }
  228. },
  229. mounted() {
  230. if ('isNormal' == localStorage.getItem('statistic')) this.showRepost = false
  231. this.initLoading = false
  232. this.initData()
  233. },
  234. created() {
  235. this.getTestingData()
  236. this.getUsersList()
  237. StatisticsData().then(data => {
  238. //将参数替换成对应参数
  239. if (data.state === 200 && data.variables.data.length > 0) {
  240. let h = this.$createElement,
  241. cont = data.variables.data
  242. for (let i = 0; i < cont.length; i++) {
  243. window.setTimeout(() => {
  244. this.infoMessage[i] = this.$notify.info({
  245. title: '定时任务:' + cont[i].ren_wu_biao_ti_,
  246. message: h('p', null, [
  247. h('span', null, '任务时间: ' + cont[i].ren_wu_shi_jian_),
  248. h('br'),
  249. h('span', null, '任务内容: '),
  250. h('span', { style: 'color: #FF8C00;font-size:12px;' }, cont[i].ding_shi_ren_wu_n),
  251. h('br'),
  252. h('el-button',{
  253. attrs: {
  254. size: 'mini',
  255. plain: true
  256. },
  257. on: {
  258. click: () => {
  259. this.infoMessage[i].close()
  260. } // 路由加载之后,调用关闭消息弹窗的方法
  261. }
  262. }, '忽略关闭')
  263. ]),
  264. duration: 0
  265. })
  266. }, 0)
  267. }
  268. }
  269. })
  270. },
  271. beforeDestroy() {
  272. for (let i = 0; i < this.infoMessage.length; i++) {
  273. this.infoMessage[i].close()
  274. }
  275. },
  276. methods: {
  277. cancelInfo(cronId, title, num, processData, taskId) {
  278. /* 调用流程*/
  279. if (taskId) {
  280. this.$router.push({
  281. name: 'pendingItems'
  282. })
  283. } else if (processData) {
  284. this.defId = processData
  285. this.bpmnFormrenderDialogVisible = true
  286. }
  287. this.infoMessage[num].close()
  288. },
  289. downloadData() {
  290. window.location.href = BASE_API() + BUSINESS_BASE_URL() + '/sys/SysDataContext/downloadData'
  291. },
  292. scrollToTop() {
  293. this.$refs.dashboardContainer.scrollToTop()
  294. },
  295. initData() {
  296. this.initInterval = setInterval(() => {
  297. if (this.$utils.isNotEmpty(this.systemAlias)) {
  298. this.initLoading = true
  299. if (this.localSystem) {
  300. // this.fetchData()
  301. } else {
  302. this.initSystemUrl(this.system.homePage)
  303. }
  304. clearInterval(this.initInterval)
  305. }
  306. }, 100)
  307. },
  308. // 抓取数据
  309. // fetchData() {
  310. // initColumn(this.systemAlias)
  311. // this.loading = true
  312. // const interval = setInterval(() => {
  313. // if (isInit()) {
  314. // // getMyDesktop({
  315. // // systemAlias: this.systemAlias
  316. // // }).then(response => {
  317. // // try {
  318. // // this.layout = this.$utils.parseData(response.data)
  319. // // this.defaultData = this.$utils.parseData(response.data)
  320. // // } catch (error) {
  321. // // this.layout = []
  322. // // this.defaultData = []
  323. // // }
  324. // // this.loading = false
  325. // // }).catch(() => {
  326. // // this.loading = false
  327. // // })
  328. // clearInterval(interval)
  329. // }
  330. // }, 100)
  331. // },
  332. getHeight(h) {
  333. return (h - 1) * (this.rowHeight + this.margin[1]) + this.margin[1]
  334. },
  335. hasComponent(alias) {
  336. const name = 'ibps-desktop-' + alias
  337. const components = getComponents()
  338. if (components) {
  339. return components.includes(name)
  340. } else {
  341. return false
  342. }
  343. },
  344. resizedHandler(i, newH, newW, newHPx, newWPx) {
  345. if (!this.layout) return
  346. this.layout.layout.find(n => {
  347. if (i === n.i) {
  348. n.widthPx = this.getWidth(n.w)
  349. n.heightPx = this.getHeight(n.h)
  350. }
  351. })
  352. },
  353. goMyLayout() {
  354. this.$router.push({ path: '/officeDesk/grzlsw/desktopMyLayout' })
  355. },
  356. handleActionEvent(command, params, index) {
  357. this.layoutIndex = index
  358. this.alias = params.$alias
  359. switch (command) {
  360. case 'fullscreen':
  361. this.handleFullscreen(params.id)
  362. break
  363. case 'collapse':
  364. case 'expansion':
  365. this.handleCollapseExpansion(index, command === 'collapse')
  366. break
  367. case 'flow':
  368. this.handleFlow(params)
  369. break
  370. case 'approve':
  371. this.handleApprove(params)
  372. break
  373. case 'unRead':
  374. this.handleUnreadMessage(params)
  375. break
  376. default:
  377. break
  378. }
  379. },
  380. /**
  381. * 全屏展示切换
  382. */
  383. handleFullscreen(id) {
  384. this.dialogPreviewVisible = true
  385. this.id = id
  386. },
  387. // 处理收缩/展开
  388. handleCollapseExpansion(index, isCollapse) {
  389. this.layout[index].h = isCollapse ? 2 : this.defaultData[index].h
  390. this.layout.push({ i: '0' })
  391. const deleteIndex = this.layout.findIndex(item => item.i === '0')
  392. this.layout.splice(deleteIndex, 1)
  393. },
  394. handleApprove(id) {
  395. this.ibpsNewsDialogVisible = true
  396. this.newsEditId = id
  397. },
  398. handleUnreadMessage(id) {
  399. this.ibpsMessageDialogVisible = true
  400. this.messageEditId = id
  401. },
  402. fileErr(err, file, fileList) {
  403. this.$message.error('文件上传失败,请检查格式!')
  404. },
  405. handleFlow(params) {
  406. this.defId = params.defId || null
  407. this.taskId = params.taskId || null
  408. this.instanceId = params.instanceId || null
  409. this.instanceId = params.instanceId || null
  410. this.instanceId = params.instanceId || null
  411. this.bpmnFormrenderDialogVisible = true
  412. },
  413. handleFlowCallback() {
  414. this.$refs[this.alias] ? this.$refs[this.alias][0].refreshData() : null
  415. },
  416. //
  417. initSystemUrl(url) {
  418. if (url.startsWith('http')) {
  419. this.systemUrlType = 'iframe'
  420. this.$nextTick(() => {
  421. this.$refs.systemrender.src = url
  422. // 传递消息
  423. // this.$refs.systemrender.contentWindow.postMessage({ data: this.attributes }, '*')
  424. })
  425. } else {
  426. const component = url.split('?')[0]
  427. this.systemUrlParams.attrs = this.urlParse(url)
  428. this.systemUrlType = 'inner'
  429. const systemUrlName = 'IbpsBpmnSystemUrl'
  430. this.$options.components[systemUrlName] = _import(component)
  431. this.systemUrlName = systemUrlName
  432. }
  433. },
  434. urlParse(str) {
  435. const obj = {}
  436. if (str.indexOf('?') !== -1) {
  437. const str1 = str.split('?')[1].split('&')
  438. for (let i = 0; i < str1.length; i++) {
  439. const params = str1[i].split('=')
  440. obj[params[0]] = params[1]
  441. }
  442. }
  443. return obj
  444. },
  445. /* 文件类型*/
  446. beforeUpload(file) {
  447. var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)
  448. const extension = testmsg === 'xls'
  449. const extension2 = testmsg === 'xlsx'
  450. if (!extension && !extension2) {
  451. this.$message({
  452. message: '上传文件只能是excel格式!',
  453. type: 'warning'
  454. })
  455. return false
  456. }
  457. return extension || extension2
  458. },
  459. /* 文件类型*/
  460. ReportBeforeUpload(file) {
  461. var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)
  462. const extension = testmsg === 'rpx'
  463. if (!extension) {
  464. this.$message({
  465. message: '上传文件只能是rpx格式!',
  466. type: 'warning'
  467. })
  468. return false
  469. }
  470. return extension
  471. },
  472. handleSuccess(res, file, fileList) {
  473. if (res.state === 200) {
  474. this.$message({
  475. message: '上传数据成功!',
  476. type: 'success'
  477. })
  478. } else {
  479. this.$message({
  480. message: res.message,
  481. type: 'error'
  482. })
  483. }
  484. },
  485. // 获取所有检测流程的peocessKey,存储到store中
  486. getTestingData() {
  487. let testingList = this.$store.getters.testingList
  488. if (testingList.length) {
  489. return
  490. } else {
  491. // let sql = 'select xiang_mu_ming_ as name, liu_cheng_bian_ha as processKey from t_jcxmlcpzb'
  492. let sql = 'select distinct defkey_ as processKey from t_mjjcnlfw where length(defkey_) > 0'
  493. curdPost('sql', sql).then(res => {
  494. const { data } = res.variables
  495. const testingData = []
  496. data.forEach(item => testingData.push(item.processKey))
  497. this.$store.dispatch('ibps/param/setTestingList', testingData)
  498. }).catch(error => {
  499. this.$message.error('获取检测流程数据失败!')
  500. console.log(error)
  501. })
  502. }
  503. },
  504. // 获取所有用户id及姓名存储到store中
  505. getUsersList() {
  506. let usersList = this.$store.getters.usersList
  507. if (usersList.length) {
  508. return
  509. } else {
  510. let sql = 'select id_ as userId, name_ as userName, mobile_ as phone from ibps_party_employee'
  511. curdPost('sql', sql).then(res => {
  512. const { data } = res.variables
  513. this.$store.dispatch('ibps/param/setUsersList', data)
  514. }).catch(error => {
  515. this.$message.error('获取所有用户信息失败!')
  516. console.log(error)
  517. })
  518. }
  519. }
  520. }
  521. }
  522. </script>
  523. <style lang="scss" scoped>
  524. @import '~@/assets/styles/public.scss';
  525. .ibps-desktop-page {
  526. .ibps-container-frame {
  527. position: absolute;
  528. top: 0px;
  529. left: 0px;
  530. height: 100%;
  531. width: 100%;
  532. }
  533. .ibps-grid-item, .el-card {
  534. height: 100%;
  535. }
  536. .vue-grid-layout {
  537. border-radius: 4px;
  538. // margin: -10px;
  539. .page_card {
  540. height: 100%;
  541. @extend %unable-select;
  542. }
  543. .vue-resizable-handle {
  544. opacity: 0.3;
  545. &:hover {
  546. opacity: 1;
  547. }
  548. }
  549. }
  550. }
  551. </style>
  552. <style lang="scss">
  553. .ibps-desktop-dashboard {
  554. .item {
  555. position: relative;
  556. margin: 12px;
  557. padding: 12px;
  558. height: 90px;
  559. border-radius: 4px;
  560. box-sizing: border-box;
  561. overflow: hidden;
  562. color: #fff;
  563. }
  564. .item-header {
  565. position: relative;
  566. & > p {
  567. margin: 0px;
  568. font-size: 14px;
  569. }
  570. & > span {
  571. position: absolute;
  572. right: 0px;
  573. top: 0px;
  574. padding: 2px 8px;
  575. border-radius: 4px;
  576. font-size: 12px;
  577. background: rgba(255, 255, 255, 0.3);
  578. }
  579. }
  580. .item-body {
  581. & > h2 {
  582. margin: 0;
  583. font-size: 32px;
  584. line-height: 60px;
  585. }
  586. }
  587. .item-tip {
  588. display: flex;
  589. align-items: center;
  590. justify-content: center;
  591. position: absolute;
  592. width: 80px;
  593. height: 80px;
  594. bottom: -35px;
  595. right: 50px;
  596. border: 2px solid #fff;
  597. border-radius: 100%;
  598. font-size: 48px;
  599. transform: rotate(-40deg);
  600. opacity: 0.1;
  601. }
  602. }
  603. </style>