page.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  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. StatisticsData().then(data => {
  237. //将参数替换成对应参数
  238. if (data.state === 200 && data.variables.data.length > 0) {
  239. let h = this.$createElement,
  240. cont = data.variables.data
  241. for (let i = 0; i < cont.length; i++) {
  242. window.setTimeout(() => {
  243. this.infoMessage[i] = this.$notify.info({
  244. title: '定时任务:' + cont[i].ren_wu_biao_ti_,
  245. message: h('p', null, [
  246. h('span', null, '任务时间: ' + cont[i].ren_wu_shi_jian_),
  247. h('br'),
  248. h('span', null, '任务内容: '),
  249. h('span', { style: 'color: #FF8C00;font-size:12px;' }, cont[i].ding_shi_ren_wu_n),
  250. h('br'),
  251. h('el-button',{
  252. attrs: {
  253. size: 'mini',
  254. plain: true
  255. },
  256. on: {
  257. click: () => {
  258. this.infoMessage[i].close()
  259. } // 路由加载之后,调用关闭消息弹窗的方法
  260. }
  261. }, '忽略关闭')
  262. ]),
  263. duration: 0
  264. })
  265. }, 0)
  266. }
  267. }
  268. })
  269. },
  270. beforeDestroy() {
  271. for (let i = 0; i < this.infoMessage.length; i++) {
  272. this.infoMessage[i].close()
  273. }
  274. },
  275. methods: {
  276. cancelInfo(cronId, title, num, processData, taskId) {
  277. /* 调用流程*/
  278. if (taskId) {
  279. this.$router.push({
  280. name: 'pendingItems'
  281. })
  282. } else if (processData) {
  283. this.defId = processData
  284. this.bpmnFormrenderDialogVisible = true
  285. }
  286. this.infoMessage[num].close()
  287. },
  288. downloadData() {
  289. window.location.href = BASE_API() + BUSINESS_BASE_URL() + '/sys/SysDataContext/downloadData'
  290. },
  291. scrollToTop() {
  292. this.$refs.dashboardContainer.scrollToTop()
  293. },
  294. initData() {
  295. this.initInterval = setInterval(() => {
  296. if (this.$utils.isNotEmpty(this.systemAlias)) {
  297. this.initLoading = true
  298. if (this.localSystem) {
  299. // this.fetchData()
  300. } else {
  301. this.initSystemUrl(this.system.homePage)
  302. }
  303. clearInterval(this.initInterval)
  304. }
  305. }, 100)
  306. },
  307. // 抓取数据
  308. // fetchData() {
  309. // initColumn(this.systemAlias)
  310. // this.loading = true
  311. // const interval = setInterval(() => {
  312. // if (isInit()) {
  313. // // getMyDesktop({
  314. // // systemAlias: this.systemAlias
  315. // // }).then(response => {
  316. // // try {
  317. // // this.layout = this.$utils.parseData(response.data)
  318. // // this.defaultData = this.$utils.parseData(response.data)
  319. // // } catch (error) {
  320. // // this.layout = []
  321. // // this.defaultData = []
  322. // // }
  323. // // this.loading = false
  324. // // }).catch(() => {
  325. // // this.loading = false
  326. // // })
  327. // clearInterval(interval)
  328. // }
  329. // }, 100)
  330. // },
  331. getHeight(h) {
  332. return (h - 1) * (this.rowHeight + this.margin[1]) + this.margin[1]
  333. },
  334. hasComponent(alias) {
  335. const name = 'ibps-desktop-' + alias
  336. const components = getComponents()
  337. if (components) {
  338. return components.includes(name)
  339. } else {
  340. return false
  341. }
  342. },
  343. resizedHandler(i, newH, newW, newHPx, newWPx) {
  344. if (!this.layout) return
  345. this.layout.layout.find(n => {
  346. if (i === n.i) {
  347. n.widthPx = this.getWidth(n.w)
  348. n.heightPx = this.getHeight(n.h)
  349. }
  350. })
  351. },
  352. goMyLayout() {
  353. this.$router.push({ path: '/officeDesk/grzlsw/desktopMyLayout' })
  354. },
  355. handleActionEvent(command, params, index) {
  356. this.layoutIndex = index
  357. this.alias = params.$alias
  358. switch (command) {
  359. case 'fullscreen':
  360. this.handleFullscreen(params.id)
  361. break
  362. case 'collapse':
  363. case 'expansion':
  364. this.handleCollapseExpansion(index, command === 'collapse')
  365. break
  366. case 'flow':
  367. this.handleFlow(params)
  368. break
  369. case 'approve':
  370. this.handleApprove(params)
  371. break
  372. case 'unRead':
  373. this.handleUnreadMessage(params)
  374. break
  375. default:
  376. break
  377. }
  378. },
  379. /**
  380. * 全屏展示切换
  381. */
  382. handleFullscreen(id) {
  383. this.dialogPreviewVisible = true
  384. this.id = id
  385. },
  386. // 处理收缩/展开
  387. handleCollapseExpansion(index, isCollapse) {
  388. this.layout[index].h = isCollapse ? 2 : this.defaultData[index].h
  389. this.layout.push({ i: '0' })
  390. const deleteIndex = this.layout.findIndex(item => item.i === '0')
  391. this.layout.splice(deleteIndex, 1)
  392. },
  393. handleApprove(id) {
  394. this.ibpsNewsDialogVisible = true
  395. this.newsEditId = id
  396. },
  397. handleUnreadMessage(id) {
  398. this.ibpsMessageDialogVisible = true
  399. this.messageEditId = id
  400. },
  401. fileErr(err, file, fileList) {
  402. this.$message.error('文件上传失败,请检查格式!')
  403. },
  404. handleFlow(params) {
  405. this.defId = params.defId || null
  406. this.taskId = params.taskId || null
  407. this.instanceId = params.instanceId || null
  408. this.instanceId = params.instanceId || null
  409. this.instanceId = params.instanceId || null
  410. this.bpmnFormrenderDialogVisible = true
  411. },
  412. handleFlowCallback() {
  413. this.$refs[this.alias] ? this.$refs[this.alias][0].refreshData() : null
  414. },
  415. //
  416. initSystemUrl(url) {
  417. if (url.startsWith('http')) {
  418. this.systemUrlType = 'iframe'
  419. this.$nextTick(() => {
  420. this.$refs.systemrender.src = url
  421. // 传递消息
  422. // this.$refs.systemrender.contentWindow.postMessage({ data: this.attributes }, '*')
  423. })
  424. } else {
  425. const component = url.split('?')[0]
  426. this.systemUrlParams.attrs = this.urlParse(url)
  427. this.systemUrlType = 'inner'
  428. const systemUrlName = 'IbpsBpmnSystemUrl'
  429. this.$options.components[systemUrlName] = _import(component)
  430. this.systemUrlName = systemUrlName
  431. }
  432. },
  433. urlParse(str) {
  434. const obj = {}
  435. if (str.indexOf('?') !== -1) {
  436. const str1 = str.split('?')[1].split('&')
  437. for (let i = 0; i < str1.length; i++) {
  438. const params = str1[i].split('=')
  439. obj[params[0]] = params[1]
  440. }
  441. }
  442. return obj
  443. },
  444. /* 文件类型*/
  445. beforeUpload(file) {
  446. var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)
  447. const extension = testmsg === 'xls'
  448. const extension2 = testmsg === 'xlsx'
  449. if (!extension && !extension2) {
  450. this.$message({
  451. message: '上传文件只能是excel格式!',
  452. type: 'warning'
  453. })
  454. return false
  455. }
  456. return extension || extension2
  457. },
  458. /* 文件类型*/
  459. ReportBeforeUpload(file) {
  460. var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)
  461. const extension = testmsg === 'rpx'
  462. if (!extension) {
  463. this.$message({
  464. message: '上传文件只能是rpx格式!',
  465. type: 'warning'
  466. })
  467. return false
  468. }
  469. return extension
  470. },
  471. handleSuccess(res, file, fileList) {
  472. if (res.state === 200) {
  473. this.$message({
  474. message: '上传数据成功!',
  475. type: 'success'
  476. })
  477. } else {
  478. this.$message({
  479. message: res.message,
  480. type: 'error'
  481. })
  482. }
  483. },
  484. // 获取检测流程数据,存储到store中
  485. getTestingData() {
  486. let testingList = this.$store.getters.testingList
  487. if (testingList.length) {
  488. return
  489. } else {
  490. let sql = 'select xiang_mu_ming_ as name, liu_cheng_bian_ha as processKey from t_jcxmlcpzb'
  491. curdPost('sql', sql).then(res => {
  492. const { data } = res.variables
  493. this.$store.dispatch('ibps/param/setTestingList', data)
  494. }).catch(error => {
  495. this.$message.error('获取检测流程数据失败!')
  496. console.log(error)
  497. })
  498. }
  499. }
  500. }
  501. }
  502. </script>
  503. <style lang="scss" scoped>
  504. @import '~@/assets/styles/public.scss';
  505. .ibps-desktop-page {
  506. .ibps-container-frame {
  507. position: absolute;
  508. top: 0px;
  509. left: 0px;
  510. height: 100%;
  511. width: 100%;
  512. }
  513. .ibps-grid-item, .el-card {
  514. height: 100%;
  515. }
  516. .vue-grid-layout {
  517. border-radius: 4px;
  518. // margin: -10px;
  519. .page_card {
  520. height: 100%;
  521. @extend %unable-select;
  522. }
  523. .vue-resizable-handle {
  524. opacity: 0.3;
  525. &:hover {
  526. opacity: 1;
  527. }
  528. }
  529. }
  530. }
  531. </style>
  532. <style lang="scss">
  533. .ibps-desktop-dashboard {
  534. .item {
  535. position: relative;
  536. margin: 12px;
  537. padding: 12px;
  538. height: 90px;
  539. border-radius: 4px;
  540. box-sizing: border-box;
  541. overflow: hidden;
  542. color: #fff;
  543. }
  544. .item-header {
  545. position: relative;
  546. & > p {
  547. margin: 0px;
  548. font-size: 14px;
  549. }
  550. & > span {
  551. position: absolute;
  552. right: 0px;
  553. top: 0px;
  554. padding: 2px 8px;
  555. border-radius: 4px;
  556. font-size: 12px;
  557. background: rgba(255, 255, 255, 0.3);
  558. }
  559. }
  560. .item-body {
  561. & > h2 {
  562. margin: 0;
  563. font-size: 32px;
  564. line-height: 60px;
  565. }
  566. }
  567. .item-tip {
  568. display: flex;
  569. align-items: center;
  570. justify-content: center;
  571. position: absolute;
  572. width: 80px;
  573. height: 80px;
  574. bottom: -35px;
  575. right: 50px;
  576. border: 2px solid #fff;
  577. border-radius: 100%;
  578. font-size: 48px;
  579. transform: rotate(-40deg);
  580. opacity: 0.1;
  581. }
  582. }
  583. </style>