new-home.vue 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. <template>
  2. <div class="app-container">
  3. <el-tabs v-model="activeTab" @tab-click="changeTab">
  4. <el-tab-pane v-for="item in tabList" :key="item.key" :name="item.key">
  5. <span slot="label"><i :class="item.icon" /> {{ item.label }}</span>
  6. <div class="tab-container">
  7. <!-- <div slot="west" class="kind">
  8. <ibps-type-tree
  9. :width="width"
  10. :height="height"
  11. title=""
  12. category-key="FLOW_TYPE"
  13. :hasPermission="true"
  14. @node-click="handleNodeClick"
  15. @expand-collapse="handleExpandCollapse"
  16. />
  17. </div> -->
  18. <div class="table-container">
  19. <div class="search-container">
  20. <div class="search-box">
  21. <span class="label">事务名称</span>
  22. <el-input
  23. v-model="searchParams.subject"
  24. class="input"
  25. placeholder="请输入内容"
  26. clearable
  27. @keyup.enter.native="search"
  28. />
  29. </div>
  30. <div class="search-box">
  31. <span class="label">{{ item.time }}时间</span>
  32. <el-date-picker
  33. v-model="searchParams.createTime"
  34. type="daterange"
  35. class="input"
  36. start-placeholder="请选择"
  37. end-placeholder="请选择"
  38. size="mini"
  39. clearable
  40. @keyup.enter.native="search"
  41. />
  42. </div>
  43. <el-button class="btn" type="primary" @click="search">
  44. <i class="ibps-icon-search" />查询
  45. </el-button>
  46. <el-button v-if="activeTab === 'save'" :key="Date.now() + Math.random()" class="btn" type="danger" @click="remove">
  47. <i class="ibps-icon-close" />删除
  48. </el-button>
  49. </div>
  50. <el-table
  51. ref="dataTable"
  52. v-loading="loading"
  53. :data="dataList"
  54. style="color: #000"
  55. align="center"
  56. size="mini"
  57. border
  58. class="jbd-home-task"
  59. :row-class-name="tableRowClassName"
  60. @row-click="handleLinkClick"
  61. @selection-change="val => selection = val"
  62. >
  63. <el-table-column v-if="activeTab === 'save'" :key="Date.now() + Math.random()" type="selection" width="55" />
  64. <el-table-column
  65. prop="subject"
  66. label="事务名称"
  67. width="250"
  68. show-overflow-tooltip
  69. >
  70. <template slot-scope="scope">{{ scope.row.subject | getWorkInfo('name') }}</template>
  71. </el-table-column>
  72. <el-table-column label="事务说明" show-overflow-tooltip>
  73. <template slot-scope="scope">{{ scope.row.subject | getWorkInfo('desc') }}</template>
  74. </el-table-column>
  75. <template v-if="['wait'].includes(activeTab)">
  76. <el-table-column
  77. show-overflow-tooltip
  78. width="120"
  79. label="事务状态"
  80. >
  81. <template slot-scope="scope">{{ '待' + scope.row.name }}</template>
  82. </el-table-column>
  83. <el-table-column show-overflow-tooltip width="100">
  84. <template slot="header" slot-scope="scope">
  85. <span>办理进度</span>
  86. <el-tooltip effect="dark" placement="top">
  87. <div slot="content">
  88. 普通事务:接收三天之内为待办理,三天之后为已超时
  89. <br>
  90. 计划事务:月底前七天内为即将超时,超过接收当月月底为已超时,其余为待办理
  91. </div>
  92. <i class="el-icon-info" />
  93. </el-tooltip>
  94. </template>
  95. <template slot-scope="scope">
  96. <el-tag :type="scope.row.state ? stateOption[scope.row.state].type : ''">{{ scope.row.state ? stateOption[scope.row.state].label : '待办理' }}</el-tag>
  97. </template>
  98. </el-table-column>
  99. <el-table-column
  100. prop="startDept"
  101. show-overflow-tooltip
  102. width="120"
  103. label="发起部门"
  104. />
  105. <el-table-column
  106. :key="Date.now() + Math.random()"
  107. prop="submitBy"
  108. show-overflow-tooltip
  109. width="100"
  110. >
  111. <template slot="header" slot-scope="scope">
  112. <span>发起人</span>
  113. <el-tooltip effect="dark" placement="top">
  114. <div slot="content">
  115. 该事务对应流程的发起人
  116. </div>
  117. <i class="el-icon-info" />
  118. </el-tooltip>
  119. </template>
  120. </el-table-column>
  121. <el-table-column
  122. :key="Date.now() + Math.random()"
  123. prop="forwardBy"
  124. show-overflow-tooltip
  125. width="100"
  126. >
  127. <template slot="header" slot-scope="scope">
  128. <span>上节点</span><br>
  129. <span>提交人</span>
  130. <el-tooltip effect="dark" placement="top">
  131. <div slot="content">
  132. 该事务对应流程上一节点的提交人
  133. </div>
  134. <i class="el-icon-info" />
  135. </el-tooltip>
  136. </template>
  137. </el-table-column>
  138. </template>
  139. <template v-else-if="['over', 'finish'].includes(activeTab)">
  140. <el-table-column
  141. show-overflow-tooltip
  142. label="事务状态"
  143. width="100"
  144. >
  145. <template slot-scope="scope">{{ scope.row.curNode ? scope.row.status == 'running' ? '已发起' : '已' + scope.row.curNode : contOfValue(scope.row.status) }}</template>
  146. </el-table-column>
  147. <el-table-column
  148. show-overflow-tooltip
  149. label="发起部门"
  150. width="100"
  151. >
  152. <template slot-scope="scope">{{ getParenthesesStr(scope.row.subject)[1] }}</template>
  153. </el-table-column>
  154. <el-table-column
  155. show-overflow-tooltip
  156. label="发起人"
  157. width="100"
  158. >
  159. <template slot-scope="scope">{{ scope.row.createBy | getUserName(userList) }}</template>
  160. </el-table-column>
  161. <el-table-column
  162. show-overflow-tooltip
  163. label="提交人"
  164. width="100"
  165. >
  166. <template slot-scope="scope">{{ getName(scope.row) }}</template>
  167. </el-table-column>
  168. </template>
  169. <el-table-column :key="Date.now() + Math.random()" show-overflow-tooltip width="160">
  170. <template slot="header" slot-scope="scope">
  171. <template v-if="['wait'].includes(activeTab)">
  172. <span>上节点</span><br>
  173. </template>
  174. <span>{{ item.time + '时间' }}</span>
  175. </template>
  176. <template slot-scope="scope">{{ scope.row[item.field] ? scope.row[item.field].slice(0, 16) : scope.row.createTime.slice(0, 16) }}</template>
  177. </el-table-column>
  178. </el-table>
  179. <div v-if="dataList.length">
  180. <el-pagination
  181. :current-page.sync="paginate.page"
  182. :page-size="paginate.limit"
  183. layout="total, prev, pager, next"
  184. :total="paginate.totalCount"
  185. @current-change="changePage"
  186. />
  187. </div>
  188. </div>
  189. </div>
  190. </el-tab-pane>
  191. </el-tabs>
  192. <bpmn-formrender
  193. :visible="dialogFormVisible"
  194. :task-id="activeTab === 'wait' ? taskId : null"
  195. :wai-jian="activeTab === 'wait' ? waiJian : null"
  196. :instance-id="['over', 'finish'].includes(activeTab) ? instanceId : null"
  197. :def-id="activeTab === 'save' ? defId : null"
  198. :pro-inst-id="activeTab === 'save' ? proInstId : null"
  199. :title="['wait', 'save'].includes(activeTab) ? FlowName : null"
  200. @callback="getData(activeTab)"
  201. @close="visible => (dialogFormVisible = visible)"
  202. />
  203. </div>
  204. </template>
  205. <script>
  206. import curdPost from '@/business/platform/form/utils/custom/joinCURD.js'
  207. import homeCalendar from './home-calendar'
  208. import { pending, handledTask } from '@/api/platform/office/bpmReceived'
  209. import { myDraft, removeDraft } from '@/api/platform/office/bpmInitiated'
  210. import { queryOrgManager } from '@/api/platform/org/employee'
  211. import { save } from '@/api/platform/message/innerMessage'
  212. import BpmnFormrender from '@/business/platform/bpmn/form/dialog'
  213. import ActionUtils from '@/utils/action'
  214. import IbpsTypeTree from '@/business/platform/cat/type/tree'
  215. import { dateFormat } from '@/filters'
  216. const tabList = [
  217. {
  218. label: '待办事宜',
  219. key: 'wait',
  220. icon: 'el-icon-edit',
  221. time: '提交',
  222. field: 'createTime'
  223. },
  224. {
  225. label: '已办事宜',
  226. key: 'over',
  227. icon: 'el-icon-document-remove',
  228. time: '创建',
  229. field: 'updateTime'
  230. },
  231. {
  232. label: '办结事宜',
  233. key: 'finish',
  234. icon: 'el-icon-paperclip',
  235. time: '结束',
  236. field: 'updateTime'
  237. },
  238. {
  239. label: '暂存事宜',
  240. key: 'save',
  241. icon: 'el-icon-receiving',
  242. time: '暂存',
  243. field: 'createTime'
  244. }
  245. ]
  246. const taskState = {
  247. running: '已发起',
  248. end: '已结束',
  249. manualend: '人工结束'
  250. }
  251. const paramsType = {
  252. wait: 'temp.',
  253. over: '',
  254. finish: 'inst.',
  255. save: ''
  256. }
  257. const stateOption = {
  258. wait: {
  259. label: '待办理',
  260. type: ''
  261. },
  262. soon: {
  263. label: '即将超时',
  264. type: 'warning'
  265. },
  266. overtime: {
  267. label: '已超时',
  268. type: 'danger'
  269. }
  270. }
  271. const operate = {
  272. wait: pending,
  273. over: handledTask,
  274. finish: handledTask,
  275. save: myDraft
  276. }
  277. export default {
  278. name: 'calendar',
  279. components: { BpmnFormrender, homeCalendar, IbpsTypeTree },
  280. filters: {
  281. getWorkInfo (v, type) {
  282. const hasDesc = v.includes('#')
  283. const res = {
  284. name: {
  285. '0': v.includes('{') ? v.split('{')[0] : v.includes('(') ? v.split('(')[0] : v,
  286. '1': v.split('#')[0]
  287. },
  288. // 无#返回空,有#返回(左边的字符串,
  289. desc: {
  290. '0': '',
  291. '1': v.split('#')[1]
  292. }
  293. }
  294. if (!hasDesc) {
  295. return res[type]['0']
  296. }
  297. return res[type]['1']
  298. },
  299. getUserName (v, list) {
  300. const user = list.find(i => i.userId === v)
  301. return user ? user.userName : ''
  302. }
  303. },
  304. props: {
  305. plan: {
  306. type: Array,
  307. default: () => []
  308. }
  309. },
  310. data () {
  311. return {
  312. tabList,
  313. stateOption,
  314. dataList: [],
  315. paginate: {},
  316. searchParams: {
  317. typeId: '',
  318. subject: '',
  319. createTime: ''
  320. },
  321. selection: [],
  322. taskId: '', // 编辑dialog需要使用
  323. waiJian: '', // 编辑dialog需要使用
  324. instanceId: '',
  325. defId: '',
  326. proInstId: '',
  327. loading: false,
  328. drawer: false,
  329. dialogFormVisible: false,
  330. orgName: '',
  331. roleName: '',
  332. FlowName: '',
  333. posName: '',
  334. defaultPagination: { page: 1, limit: 15 },
  335. sorts: { CREATE_TIME_: 'DESC' },
  336. timer: null,
  337. userList: [],
  338. orgInfo: {},
  339. activeTab: 'wait',
  340. width: 250,
  341. height: document.body.clientHeight - 130
  342. }
  343. },
  344. mounted: function () {
  345. this.loadData()
  346. this.getUserList()
  347. this.getOrgInfo()
  348. if (this.timer) {
  349. clearInterval(this.timer)
  350. }
  351. // 轮询刷新公告数据和任务数据
  352. this.timer = setInterval(() => {
  353. // this.getMessage()
  354. this.getData(this.activeTab)
  355. }, 30 * 1000)
  356. },
  357. beforeDestroy () {
  358. clearInterval(this.timer)
  359. },
  360. // 路由离开时
  361. beforeRouteLeave (to, from, next) {
  362. clearInterval(this.timer)
  363. },
  364. methods: {
  365. loadData () {
  366. // let user = this.$store.getters.userInfo
  367. // let pos, role
  368. // this.orgName = user.employee.orgName
  369. // for (let i in user.positions) {
  370. // if (i == 0) pos = user.positions[0].name
  371. // else pos = pos + ',' + user.positions[i].name
  372. // }
  373. // let contRole = this.unique(user.role) //去重
  374. // for (let i in contRole) {
  375. // if (i == 0) role = contRole[0].name
  376. // else role = role + ',' + contRole[i].name
  377. // }
  378. // this.posName = pos
  379. // this.roleName = role
  380. // this.getMessage()
  381. // 获取任务数据
  382. this.getData(this.activeTab)
  383. },
  384. // 获取系统用户信息
  385. getUserList () {
  386. const { userList } = this.$store.getters
  387. // store中有则无需请求
  388. if (userList && userList.length) {
  389. this.userList = userList
  390. return
  391. }
  392. const sql = `select id_ as userId, name_ as userName, mobile_ as phone from ibps_party_employee where status_ = 'actived'`
  393. curdPost('sql', sql).then(res => {
  394. this.userList = res.variables && res.variables.data
  395. })
  396. },
  397. // 获取用户部门信息
  398. getOrgInfo () {
  399. const { org = {}} = this.$store.getters
  400. if (!org || !org.id) {
  401. return
  402. }
  403. const params = {
  404. parameters: [{ key: 'Q^MANAGER_ORG_ID_^S', value: org.id }]
  405. }
  406. queryOrgManager(params).then(res => {
  407. this.orgInfo = {}
  408. const data = res.data.dataResult
  409. if (data && data.length) {
  410. const { id, name, mobile, account, gender, groupID } = data[0]
  411. this.orgInfo = { id, name, mobile, account, gender, groupID, orgName: org.name }
  412. }
  413. })
  414. },
  415. handleNodeClick (typeId) {
  416. this.dataList = []
  417. this.paginate = {}
  418. this.searchParams.typeId = typeId
  419. this.loadData()
  420. },
  421. handleExpandCollapse (isExpand) {
  422. this.width = isExpand ? 230 : 30
  423. },
  424. getName ({ createBy, updateBy }) {
  425. const id = updateBy || createBy
  426. const { name = '' } = this.$store.getters
  427. if (this.activeTab === 'finish') {
  428. const t = this.userList.find(i => i.userId === id)
  429. return t ? t.userName : ''
  430. }
  431. return name
  432. },
  433. tableRowClassName ({ row, rowIndex }) {
  434. if (rowIndex % 2 === 1) return 'warning-row'
  435. return 'success-row'
  436. },
  437. // 获取表格数据
  438. getData (type) {
  439. this.loading = true
  440. operate[this.activeTab](this.getFormatParams(null, this.defaultPagination)).then(response => {
  441. const { dataResult, pageResult } = response.data
  442. if (dataResult && dataResult.length) {
  443. // 待办事宜对任务发起人做额外处理
  444. if (type === 'wait') {
  445. const instList = []
  446. dataResult.forEach(item => {
  447. instList.push(item.bpmnInstId)
  448. })
  449. const sql = `select b.bpmn_inst_id_, b.create_by_, a.name_ from ibps_bpm_inst b left join ibps_party_employee a on a.id_ = b.create_by_ where b.bpmn_inst_id_ in (${instList.join(',')}) order by find_in_set(b.bpmn_inst_id_,'${instList.join(',')}')`
  450. const currentTime = Date.now()
  451. curdPost('sql', sql).then(res => {
  452. const data = res.variables && res.variables.data
  453. data.forEach((item, index) => {
  454. dataResult[index].submitBy = item.name_
  455. dataResult[index].workName = dataResult[index].subject.includes('#') ? dataResult[index].subject.split('#')[0] : dataResult[index].subject.split('(')[0]
  456. dataResult[index].workType = this.plan.includes(dataResult[index].procDefKey) ? 'plan' : 'normal'
  457. dataResult[index].state = this.judgeExpire(dataResult[index].createTime, currentTime, dataResult[index].workType, '1')
  458. })
  459. this.dataList = dataResult.sort((a, b) => b.createTime.localeCompare(a.createTime))
  460. this.paginate = pageResult
  461. })
  462. this.urgeToManager()
  463. } else {
  464. this.dataList = dataResult
  465. this.paginate = pageResult
  466. }
  467. }
  468. this.loading = false
  469. }).catch(() => {
  470. this.loading = false
  471. })
  472. },
  473. // 查询
  474. search () {
  475. this.dataList = []
  476. this.paginate = {}
  477. this.getData(this.activeTab)
  478. },
  479. // 删除暂存数据
  480. remove () {
  481. if (!this.selection.length) {
  482. this.$message.warning('请选择暂存事务!')
  483. return
  484. }
  485. const idList = []
  486. this.selection.forEach(i => idList.push(i.id))
  487. ActionUtils.removeRecord(idList).then(ids => {
  488. removeDraft({ ids }).then(() => {
  489. ActionUtils.removeSuccessMessage()
  490. this.selection = []
  491. this.search()
  492. })
  493. }).catch(() => { })
  494. },
  495. // 切换tab
  496. changeTab () {
  497. // 数据、筛选条件初始化
  498. this.dataList = []
  499. this.paginate = {}
  500. this.selection = []
  501. this.typeId = ''
  502. this.defaultPagination.page = 1
  503. this.getData(this.activeTab)
  504. },
  505. // 数组去重
  506. unique (arr) {
  507. const res = new Map()
  508. return arr.filter(arr => !res.has(arr.id) && res.set(arr.id, 1))
  509. },
  510. // 分页
  511. changePage (val) {
  512. this.dataList = []
  513. this.paginate = {}
  514. this.defaultPagination.page = val
  515. this.getData(this.activeTab)
  516. },
  517. // 转换状态码
  518. contOfValue (cont) {
  519. const s = taskState[cont]
  520. return s || '暂停'
  521. },
  522. getFormatParams (v, pagination) {
  523. const params = this.$refs['crud'] ? this.$refs['crud'].getSearcFormData() : {}
  524. if (this.$utils.isNotEmpty(this.searchParams.typeId)) {
  525. params[`Q^${paramsType[this.activeTab]}TYPE_ID_^S`] = this.searchParams.typeId
  526. }
  527. if (this.$utils.isNotEmpty(this.searchParams.subject)) {
  528. params[`Q^${paramsType[this.activeTab]}subject_^SL`] = this.searchParams.subject
  529. }
  530. if (this.searchParams.createTime && this.searchParams.createTime.length) {
  531. params[`Q^${paramsType[this.activeTab]}create_time_^DL`] = dateFormat(this.searchParams.createTime[0]).slice(0, 10)
  532. params[`Q^${paramsType[this.activeTab]}create_time_^DG`] = dateFormat(this.searchParams.createTime[1]).slice(0, 10)
  533. }
  534. if (this.activeTab === 'finish') {
  535. params.end = '1'
  536. }
  537. return ActionUtils.formatParams(params, pagination, this.sorts)
  538. },
  539. // 处理表格点击事件
  540. handleLinkClick (data) {
  541. this.taskId = data.id || ''
  542. this.waiJian = data.waiJian || ''
  543. this.instanceId = data.id || ''
  544. this.defId = data.procDefId || ''
  545. this.proInstId = data.id || ''
  546. this.FlowName = data.name
  547. this.dialogFormVisible = true
  548. },
  549. // 开关右侧栏抽屉
  550. handleClose () {
  551. this.drawer = !this.drawer
  552. },
  553. // 文字替换
  554. getParenthesesStr (text) {
  555. let result = ''
  556. if (!text) return result
  557. const regex1 = /\{(.+?)\}/g
  558. const regex2 = /\((.+?)\)/g
  559. const options1 = text.match(regex1)
  560. const options2 = text.match(regex2)
  561. const options = options1 && options1.length ? options1 : options2
  562. if (options) {
  563. const option = options[0]
  564. if (option) {
  565. result = option.substring(1, option.length - 1)
  566. }
  567. if (options[1]) {
  568. const yersOption = options[1]
  569. if (yersOption) {
  570. result = result + '/' + yersOption.substring(1, yersOption.length - 1)
  571. }
  572. }
  573. }
  574. return result.split('/')
  575. },
  576. /**
  577. * 主管提醒
  578. * 数据处理,将所有待办数据根据是否过期处理为两个数组
  579. * 过期判断依据:普通事务-创建时间到当前时间超过三天即为过期;计划事务【事务名称中含计划】-创建当月月末前七天
  580. * 逻辑说明:过期数组中不存于在主管提醒表中的数据插入主管提醒表,并发送内部通知,主管提醒表删除不存在于未过期数组中的数据
  581. */
  582. urgeToManager () {
  583. const { userId } = this.$store.getters
  584. const params = {
  585. parameters: [],
  586. sorts: []
  587. }
  588. const sql = `select id_, shi_wu_id_ as taskId from t_gqswb where position('${userId}' in chu_li_ren_id_) FOR UPDATE`
  589. // Promise.all([pending(params), curdPost('sql', sql)]).then(([res1, res2]) => {
  590. // let workData = res1.data && res1.data.dataResult
  591. // let noticeData = res2.variables && res2.variables.data
  592. // if (!workData || !workData.length) {
  593. // return
  594. // }
  595. // this.dealData(workData, noticeData)
  596. // })
  597. pending(params).then(res1 => {
  598. const workData = res1.data && res1.data.dataResult
  599. curdPost('sql', sql).then(res2 => {
  600. const noticeData = res2.variables && res2.variables.data
  601. if (!workData || !workData.length) {
  602. return
  603. }
  604. this.dealData(workData, noticeData)
  605. })
  606. })
  607. },
  608. // 处理数据
  609. dealData (workList, noticeList) {
  610. const result = {
  611. expire: [],
  612. unexpire: [],
  613. all: []
  614. }
  615. const currentTime = Date.now()
  616. // 筛选已过期数据
  617. workList.forEach(item => {
  618. // 截取流程名
  619. item.workName = item.subject.includes('#') ? item.subject.split('#')[0] : item.subject.split('(')[0]
  620. item.workType = this.plan.includes(item.procDefKey) ? 'plan' : 'normal'
  621. const isExpire = this.judgeExpire(item.createTime, currentTime, item.workType)
  622. if (isExpire) {
  623. result.expire.push(item)
  624. } else {
  625. result.unexpire.push(item)
  626. }
  627. result.all.push(item)
  628. })
  629. // console.log('处理后数据:', result)
  630. // 有过期数据才执行过期数据处理
  631. if (result.expire.length) {
  632. this.dealExpile(result.expire, noticeList)
  633. }
  634. // 主管提醒表中有数据才执行数据删除
  635. if (noticeList && noticeList.length) {
  636. this.dealUnexpile(result.all, noticeList)
  637. }
  638. },
  639. // 判断是否过期、获取办理状态
  640. judgeExpire (time, current, type, isState) {
  641. const D = new Date(time)
  642. const a = new Date(time).getTime()
  643. const b = new Date(current).getTime()
  644. // 创建时间当月最后一天的时间戳
  645. const c = new Date(D.getFullYear(), D.getMonth() + 1, 0).getTime() + 86400000
  646. // 返回办理状态
  647. if (isState) {
  648. let state = ''
  649. if (type === 'plan') {
  650. state = b >= c ? 'overtime' : b + (86400000 * 7) > c ? 'soon' : 'wait'
  651. } else {
  652. state = a + (86400000 * 3) < b ? 'overtime' : 'wait'
  653. }
  654. return state
  655. }
  656. // 返回是否过期
  657. if (type === 'plan') {
  658. return b + (86400000 * 7) > c
  659. } else {
  660. return a + (86400000 * 3) < b
  661. }
  662. },
  663. // 处理已过期数据
  664. dealExpile (data, noticeList) {
  665. // console.log('已过期流程数据:', data)
  666. // console.log('过期事务表数据:', noticeList)
  667. const { userId } = this.$store.getters
  668. const addList = []
  669. const sendList = []
  670. const msgContent = {
  671. plan: '距离过期还剩七天,请及时处理!',
  672. normal: '至今三天未处理,已超时,请及时处理!'
  673. }
  674. const msgTitle = {
  675. plan: '计划事务即将到期提醒',
  676. normal: '事务超时提醒'
  677. }
  678. const nowTime = new Date(new Date().getTime() + 28800000).toJSON().slice(0, 16).replace('T', ' ')
  679. data.forEach(item => {
  680. const isExist = !!noticeList.find(i => i.taskId === item.taskId)
  681. // 筛选出不存在于主管提醒表的过期数据
  682. if (!isExist) {
  683. // 无部门信息的用户不往过期事务表加数据
  684. if (this.orgInfo.groupID) {
  685. const obj = {
  686. // 事务ID
  687. shi_wu_id_: item.taskId,
  688. // 完整名称
  689. wan_zheng_ming_ch: item.subject,
  690. // 事务说明
  691. shi_wu_shuo_ming_: item.subject.includes('#') ? item.subject.split('#')[1] : '',
  692. // 事务名称
  693. shi_wu_ming_cheng: item.workName,
  694. // 事务状态
  695. shi_wu_zhuang_tai: `待${item.name}`,
  696. // 事务类型
  697. shi_wu_lei_xing_: item.workType,
  698. chu_li_ren_ming_: item.ownerName,
  699. chu_li_ren_id_: this.getInfoByName(item.ownerName, 'id'),
  700. chu_li_ren_dian_h: this.getInfoByName(item.ownerName, 'phone'),
  701. bu_men_: this.orgInfo.orgName,
  702. bu_men_id_: this.orgInfo.groupID,
  703. // 主管ID与当前用户id相等时将主管ID设置为主任【】的ID,主管电话设为空
  704. zhu_guan_id_: this.orgInfo.id === userId ? '990927120278487040' : this.orgInfo.id,
  705. zhu_guan_dian_hua: this.orgInfo.id === userId ? '' : this.orgInfo.mobile,
  706. bian_zhi_shi_jian: item.createTime,
  707. ti_xing_ci_shu_: 1,
  708. duan_xin_ci_shu_: 0,
  709. ti_xing_shi_jian_: nowTime
  710. }
  711. addList.push(obj)
  712. }
  713. const msg = {
  714. subject: msgTitle[item.workType],
  715. content: `<p>事务【${item.workName}】${msgContent[item.workType]}<p>`,
  716. receiverId: userId,
  717. canreply: '0',
  718. taskId: item.taskId
  719. }
  720. sendList.push(msg)
  721. }
  722. })
  723. const addParams = {
  724. tableName: 't_gqswb',
  725. paramWhere: addList
  726. }
  727. // console.log('新增过期事务表数据:', addList, '发送消息数据', sendList)
  728. if (addList.length) {
  729. curdPost('add', addParams)
  730. }
  731. if (sendList.length) {
  732. this.sendMsg(sendList)
  733. }
  734. },
  735. // 删除已办的提醒表数据
  736. dealUnexpile (data, noticeList) {
  737. // 清除存在于主管提醒表中【处理人含我】,但是不存在于待办中的数据
  738. const deleteList = []
  739. noticeList.forEach(item => {
  740. const isExist = !!data.find(i => i.taskId === item.taskId)
  741. if (!isExist) {
  742. deleteList.push(item.id_)
  743. }
  744. })
  745. // console.log('过期事务表中需删除的数据:', deleteList)
  746. if (!deleteList.length) {
  747. return
  748. }
  749. const params = {
  750. tableName: 't_gqswb',
  751. paramWhere: {
  752. id_: deleteList.join(',')
  753. }
  754. }
  755. curdPost('delete', params).then(() => {}).catch(err => {
  756. console.log(err)
  757. })
  758. },
  759. // 发送站内消息
  760. sendMsg (data) {
  761. data.forEach(item => {
  762. save(item).then(() => {}).catch(err => {
  763. console.log(err)
  764. })
  765. })
  766. },
  767. // 通过名字获取id/电话
  768. getInfoByName (names, type) {
  769. const res = {
  770. id: [],
  771. phone: []
  772. }
  773. const temp = names.split(',')
  774. temp.forEach(item => {
  775. const t = this.userList.find(i => i.userName === item)
  776. if (t) {
  777. res.id.push(t.userId)
  778. res.phone.push(t.phone)
  779. }
  780. })
  781. return res[type].filter(i => i).join(',')
  782. }
  783. }
  784. }
  785. </script>
  786. <style lang="scss" scoped>
  787. .el-completing {
  788. background: #409eff !important;
  789. }
  790. .el-col {
  791. min-height: 1px;
  792. }
  793. .firstcol {
  794. padding-right: 10px;
  795. }
  796. .el-nothing {
  797. font-size: 13px;
  798. }
  799. .calendar-day {
  800. text-align: center;
  801. color: #202535;
  802. line-height: 30px;
  803. font-size: 12px;
  804. }
  805. .is-selected {
  806. color: #f8a535;
  807. font-size: 10px;
  808. margin-top: 5px;
  809. }
  810. #calendar .el-button-group > .el-button:not(:first-child):not(:last-child):after {
  811. content: '当月';
  812. }
  813. #calendar .item {
  814. position: relative;
  815. margin: 0;
  816. padding: 0;
  817. height: auto;
  818. border-radius: 4px;
  819. -webkit-box-sizing: border-box;
  820. box-sizing: border-box;
  821. overflow: hidden;
  822. color: #f8a535;
  823. }
  824. .ibps-list-split .ibps-list-item {
  825. border-bottom: 1px solid #dcdfe6;
  826. padding: 6px 0;
  827. }
  828. .jbd-font-style {
  829. font-weight: bold;
  830. }
  831. .home-text-border {
  832. color: #999999;
  833. box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.1), 0 0 0 0 rgba(0, 0, 0, 0.1), 0 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 0px 0 rgba(0, 0, 0, 0.1);
  834. min-height: 20px;
  835. font-size: 14px;
  836. margin-left: 60px;
  837. margin-bottom: 5px;
  838. }
  839. .jbd-home-card {
  840. overflow: auto;
  841. }
  842. .jbd-home-task {
  843. width: 100%;
  844. padding: 10px;
  845. cursor: pointer;
  846. font-size: 12px;
  847. margin-bottom: 35px;
  848. }
  849. .jbd-home-card::-webkit-scrollbar {
  850. display: none;
  851. }
  852. .jbd-control-cont {
  853. text-align: center;
  854. position: absolute;
  855. z-index: 10;
  856. right: 0px;
  857. top: 50%;
  858. }
  859. .tab-container {
  860. >div {
  861. display: inline-block;
  862. }
  863. .table-container {
  864. // width: calc(100% - 250px);
  865. width: 100%;
  866. vertical-align: top;
  867. .search-container {
  868. display: flex;
  869. margin-bottom: 10px;
  870. .search-box {
  871. display: flex;
  872. align-items: center;
  873. height: 30px;
  874. margin-right: 20px;
  875. .label {
  876. margin: 0 6px 0 6px;
  877. color: #606266;
  878. font-size: 12px;
  879. }
  880. .input {
  881. width: 200px;
  882. font-size: 12px;
  883. height: 28px !important;
  884. line-height: 28px;
  885. color: #606266;
  886. ::v-deep .el-input__inner {
  887. height: 28px;
  888. line-height: 28px;
  889. }
  890. }
  891. }
  892. .btn {
  893. height: 30px;
  894. margin-left: 10px;
  895. background-color: #409eff;
  896. border-color: #409eff;
  897. font-size: 12px;
  898. border-radius: 3px;
  899. padding: 7px 15px;
  900. }
  901. .el-button--danger {
  902. background-color: #f56c6c;
  903. border-color: #f56c6c;
  904. }
  905. }
  906. }
  907. }
  908. </style>
  909. <style>
  910. .app-container .el-drawer.rtl {
  911. overflow: scroll;
  912. }
  913. .app-container .el-table th {
  914. background-color: #84d5cf !important;
  915. font-size: 14px;
  916. font-weight: bold;
  917. color: #000000;
  918. border: 0px;
  919. }
  920. .app-container .el-table td {
  921. padding: 4px;
  922. }
  923. .app-container .el-table .warning-row {
  924. background: #e0f0ee;
  925. color: #000000;
  926. }
  927. .app-container .el-table .success-row {
  928. background: #f9ffff;
  929. color: #000000;
  930. }
  931. </style>