@lambo-design/workflow-approve 1.0.0-beta.64 → 1.0.0-beta.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/portrait.vue CHANGED
@@ -1,1814 +1,1866 @@
1
- <template>
2
- <LamboPageContainer>
3
- <template slot="page-title">
4
- {{ title }}
5
- </template>
6
- <template slot="page-extend">
7
- <slot name="return-button"></slot>
8
- </template>
9
- <div class="portrait-lambo-indicator-card"
10
- :style="{float: 'left', width: isExpanded && showProcessInfo ? `calc(100% - ${portraitWidth+10}px)` : '99%'}">
11
- <slot name="business-content">
12
- </slot>
13
- </div>
14
-
15
- <a v-if="showProcessInfo" @click="isExpanded = !isExpanded" class="arrow-button-container"
16
- :style="{right: isExpanded ? portraitWidth+10 + 'px' : '10px'}">
17
- <Icon class="icon-class" v-if="isExpanded" type="ios-arrow-forward"/>
18
- <Icon class="icon-class" v-if="!isExpanded" type="ios-arrow-back"/>
19
- </a>
20
- <transition v-if="showProcessInfo" name="draw" @before-enter="beforeFlowInfoEnter" @enter="flowInfoEnter"
21
- @before-leave="beforeFlowInfoLeave" @leave="flowInfoLeave">
22
- <lamboIndicatorCard v-show="isExpanded" class="portrait-lambo-indicator-card"
23
- :style="{width: portraitWidth + 'px', float: 'right'}" :hasExtend="false">
24
- <div slot="content-title">流程信息</div>
25
- <a v-if="!isDetail" @click="auditShow = !auditShow">
26
- <Title
27
- v-if="handleButtons && (handleButtons.includes('auditOpinion') || handleButtons.includes('attachmentFile'))">
28
- <a style="color: #989898">
29
- <Icon v-if="auditShow" type="ios-arrow-down"/>
30
- <Icon v-if="!auditShow" type="ios-arrow-up"/>
31
- {{ handleName }}信息
32
- </a>
33
- </Title>
34
- </a>
35
- <transition v-if="!isDetail" name="draw" @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave"
36
- @leave="leave">
37
- <div class="box" v-show="auditShow">
38
- <Form ref="auditOpinion" justify="center" :label-width="100" :model="form"
39
- v-if="handleButtons && handleButtons.includes('auditOpinion')"
40
- style="margin: 10px 0 0 10px;" :rules="ruleValidate">
41
- <FormItem :label="auditOpinionTitle" prop="auditOpinion">
42
- <AuditOpinion v-model="form.auditOpinion" :attachment-file="handleButtons.includes('attachmentFile')"
43
- :attachmentdata="fileList" :default-audit-opinion="defaultAuditOpinion"
44
- :smart-flow-server-context="smartFlowServerContext"></AuditOpinion>
45
- </FormItem>
46
- </Form>
47
- <Form ref="auditOpinion" justify="center" :label-width="100"
48
- v-if="handleButtons && !handleButtons.includes('auditOpinion') && handleButtons.includes('attachmentFile')"
49
- style="margin: 10px 0 0 10px;">
50
- <FormItem style="min-height: 70px">
51
- <Tooltip placement="bottom" max-width="200">
52
- <div style="font-size: smaller" slot="content">支持扩展名:.pdf .doc .docx .txt .xls .xlsx .jpg .jpeg
53
- .png .gif
54
- </div>
55
- <UploadFile @upload-result="uploadFile" :multiple="true"
56
- :oss-server-context="smartFlowServerContext"
57
- :oss-file-put-url="ossFilePutUrl"></UploadFile>
58
- </Tooltip>
59
- </FormItem>
60
- </Form>
61
- </div>
62
- </transition>
63
- <a v-if="taskNode && isDetail && hisAuditOpinion[0].auditOpinion" @click="auditShow = !auditShow">
64
- <Title
65
- v-if="handleButtons && (handleButtons.includes('auditOpinion') || handleButtons.includes('attachmentFile'))">
66
- <a style="color: #989898">
67
- <Icon v-if="auditShow" type="ios-arrow-down"/>
68
- <Icon v-if="!auditShow" type="ios-arrow-up"/>
69
- {{ handleName }}信息
70
- </a>
71
- </Title>
72
- </a>
73
- <transition v-if="taskNode && isDetail && hisAuditOpinion[0].auditOpinion" name="draw"
74
- @before-enter="beforeEnter"
75
- @enter="enter" @before-leave="beforeLeave" @leave="leave">
76
- <div class="box" v-show="auditShow">
77
- <Form ref="auditOpinion" justify="center" :model="form"
78
- v-if="handleButtons && handleButtons.includes('auditOpinion')"
79
- style="margin: 10px 0 0 10px;" :rules="ruleValidate">
80
- <FormItem style="margin-left: -60px">
81
- <Card v-for="(item, index) in hisAuditOpinion" :key="index">
82
- <Row style="display: flex">
83
- <Col span="24">
84
- <div style="word-wrap: break-word;">
85
- <span>{{ item.auditOpinion }}</span>
86
- <div style="position: absolute; right: 0;bottom: -18px;color: grey">{{ item.auditTime }}</div>
87
- </div>
88
- </Col>
89
- </Row>
90
- </Card>
91
- </FormItem>
92
- </Form>
93
- </div>
94
- </transition>
95
- <a @click="historyShow = !historyShow">
96
- <Title v-if="handleButtons && handleButtons.includes('auditHistory')">
97
- <a style="color: #989898">
98
- <Icon v-if="historyShow" type="ios-arrow-down"/>
99
- <Icon v-if="!historyShow" type="ios-arrow-up"/>
100
- {{ handleName }}记录
101
- </a>
102
- </Title>
103
- </a>
104
- <transition name="draw" @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave" @leave="leave">
105
- <div class="box" v-show="historyShow">
106
- <Card class="process-history" :style="processHistoryHeight" dis-hover :bordered="false"
107
- v-if="handleButtons && handleButtons.includes('auditHistory')">
108
- <processHistory :portrait-width="portraitWidth" :list="processHistory" :done-page="isDetail"
109
- :push-button="pushButton"
110
- :smart-flow-server-context="smartFlowServerContext"></processHistory>
111
- </Card>
112
- </div>
113
- </transition>
114
-
115
- <a @click="attachListShow = !attachListShow">
116
- <Title v-if="handleButtons && handleButtons.includes('attachmentFile') && attachmentList.length > 0">
117
- <a style="color: #989898">
118
- <Icon v-if="attachListShow" type="ios-arrow-down"/>
119
- <Icon v-if="!attachListShow" type="ios-arrow-up"/>
120
- 查看附件
121
- </a>
122
- </Title>
123
- </a>
124
- <transition name="draw" @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave" @leave="leave">
125
- <div class="box"
126
- v-show="handleButtons && handleButtons.includes('auditHistory') && attachmentList.length > 0 && attachListShow">
127
- <div v-for="(item, index) in attachmentList" :key="index">
128
- <Card dis-hover class="attach-card">
129
- <List item-layout="vertical">
130
- <ListItem style="margin-top: -8px">
131
- <Row style="display: flex; align-items: center;">
132
- <!-- 左边:图片 -->
133
- <Col span="4" style="margin-top: -25px">
134
- <avatar v-if="item.fileType === 'image'" icon="ios-image-outline" class="attach-avatar"
135
- style="background-color: #005aff"
136
- :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
137
- :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
138
- <avatar v-else-if="item.fileType === 'doc'" icon="ios-document-outline" class="attach-avatar"
139
- style="background-color: #005aff"
140
- :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
141
- :size="portraitWidth >= 600 ? 'middle' : 'small'">
142
- </avatar>
143
- <avatar v-else-if="item.fileType === 'xlsx'" icon="ios-document-outline" class="attach-avatar"
144
- style="background-color: #19be6b"
145
- :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
146
- :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
147
- <avatar v-else-if="item.fileType === 'pdf'" icon="ios-document-outline" class="attach-avatar"
148
- style="background-color: #ed4014"
149
- :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
150
- :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
151
- <avatar v-else icon="ios-document-outline" class="attach-avatar"
152
- :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
153
- :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
154
- </Col>
155
- <!-- 右边:附件信息 -->
156
- <Col span="20">
157
- <Row>
158
- <tooltip>
159
- <span class="attach-name-style"> {{ item.attachName }}</span>
160
- <div slot="content" style="white-space: normal"> {{ item.attachName }}</div>
161
- </tooltip>
162
- </Row>
163
- <Row style="margin-top: 3px">
164
- <span style="color: #005aff; font-size: 13px;">{{ item.uploadUserName }}</span>
165
- <Divider style="background-color:#808695;height: 1em;margin: 4px 9px 0 6px;"
166
- type="vertical"/>
167
- <span style="color: #808695;font-size: 13px"
168
- >{{ showTaskNode(item.taskId) }}</span>
169
- </Row>
170
- <Row style="margin-bottom: -10px; margin-top: 10px">
171
- <template>
172
- <Button @click="getAttach(item)" size="small">下载</Button>
173
- <Button v-if="item.showPreview" ghost type="primary" @click="preViewAttach(item)"
174
- style="margin-left: 10px" size="small">预览
175
- </Button>
176
- </template>
177
- </Row>
178
- </Col>
179
- </Row>
180
-
181
- </ListItem>
182
- </List>
183
- </Card>
184
- </div>
185
- </div>
186
- </transition>
187
- <Modal title="查看附件" v-model="modalVisible" fullscreen scrollable :mask="false">
188
- <img :src="imageUrl" v-if="modalVisible" alt="" style="width: 100%">
189
- <div slot="footer">
190
- <Button type="primary" @click="modalVisible = false">关闭</Button>
191
- </div>
192
- </Modal>
193
- <Modal title="查看附件" v-model="modalDocx" fullscreen scrollable :mask="false">
194
- <div ref="file"></div>
195
- </Modal>
196
- </lamboIndicatorCard>
197
- </transition>
198
-
199
- <Modal v-model="modal1" title="选择节点"
200
- @on-cancel="cancel"
201
- @on-ok="doPass">
202
- <Table border
203
- :data="allNode"
204
- :columns="nodeColumn"
205
- highlight-row
206
- @on-current-change="selectNode">
207
- </Table>
208
- </Modal>
209
- <assigneeBox ref="assigneeHelpBox" :execution-completed="executionCompleted"
210
- @update-selected="handleSelectedUser" @update-next-node-assignee="updateNextNodeAssignee"
211
- @add-multitask-instance="addMultitaskInstance" @delegate-task-assignee="delegateTask"
212
- :data="assigneeBoxData" :smart-flow-server-context="smartFlowServerContext"
213
- :upms-server-context="upmsServerContext"/>
214
- <Modal ref="processTraceModal" v-model="modalBoxShow" width="1000" title="流程跟踪图">
215
- <Workflow_Diagram ref="processTrace" :instanceId="process.instanceId" :applyId="process.applyId"
216
- :procId="process.procId" :table-columns="diagramTableColumns" :scroll-element="scrollElement"
217
- :tableData="process.tableData" :hisAudit="hisAudit"
218
- :approve-detail-show-way="approveDetailShowWay"
219
- :smart-flow-server-context="smartFlowServerContext">
220
- </Workflow_Diagram>
221
- </Modal>
222
- <Modal v-model="reductionMultitaskInstanceModal" title="选择减签人员"
223
- @on-cancel="reductionModalCancel"
224
- @on-ok="reductionMultitaskInstance">
225
- <Table border
226
- :data="unapprovedAssigneeList"
227
- :columns="reductionColumn"
228
- @on-selection-change="selectAssignee">
229
- </Table>
230
- </Modal>
231
- <Modal v-model="appointBoxShow" title="下一环节设置"
232
- @on-cancel="appointBoxShow = false" width="600"
233
- @on-ok="appointOk">
234
- <Card v-for="(item,index) of nextNodesFormList" :key="index" style="margin-bottom: 10px"
235
- v-if="handleButtons && (handleButtons.includes('appointHandler') || handleButtons.includes('appointTimeoutTime'))">
236
- <Form ref="appointBox" justify="center" :label-width="100" :model="item"
237
- style="margin: 10px 0 0 10px;" :rules="ruleValidate">
238
- <div v-if="handleButtons && handleButtons.includes('appointHandler')">
239
- <FormItem label="下一环节:">
240
- {{ item.name }}
241
- </FormItem>
242
- <FormItem label="人员类型:" v-if="!item.isMultiInstance">
243
- <RadioGroup v-model="item.actionType">
244
- <Radio label="ASSIGNEE">办理人</Radio>
245
- <Radio label="CAND">候选人</Radio>
246
- </RadioGroup>
247
- </FormItem>
248
- <FormItem label="办理人员:" prop="assignee" v-if="!item.isMultiInstance && item.actionType === 'ASSIGNEE'">
249
- <Input v-model="item.assigneeName"
250
- placeholder="请选择办理人"
251
- style="width: 68%"
252
- icon="md-apps"
253
- @on-focus="readingRangeClick(item)"
254
- @on-click="readingRangeClick(item)"/>
255
- </FormItem>
256
- <FormItem label="候选人员:" prop="candidateGroups"
257
- v-if="!item.isMultiInstance && item.actionType === 'CAND'">
258
- <Input v-model="item.candidateNames"
259
- placeholder="请选择候选人"
260
- style="width: 68%"
261
- icon="md-apps"
262
- @on-focus="candidateGroupsReadingRangeClick(item)"
263
- @on-click="candidateGroupsReadingRangeClick(item)"/>
264
- </FormItem>
265
- <FormItem label="候选人员:" prop="candidateGroups"
266
- v-if="item.isMultiInstance && item.actionType === 'CAND'">
267
- </FormItem>
268
-
269
- <countersingersBox style="margin-bottom: 10px" v-model="item.candidateNames"
270
- v-if="item.isMultiInstance && item.actionType === 'CAND'"
271
- :item="item" :permScope="permScope" @update-cand-groups="updateCandGroups"
272
- :upms-server-context="upmsServerContext"
273
- :smart-flow-server-context="smartFlowServerContext"/>
274
- </div>
275
- <div v-if="handleButtons && handleButtons.includes('appointTimeoutTime')">
276
- <Row>
277
- <Col span="12">
278
- <FormItem label="停留时间:">
279
- <Input v-model="item.remainDay" style="width: 100px" type="number" :min="0"></Input>
280
-
281
- </FormItem>
282
- </Col>
283
- <Col span="12">
284
- <FormItem>
285
- <Input v-model="item.remainTime" style="margin-left: -140px; width: 100px" type="number"
286
- :min="0"></Input>
287
- 小时 自动处理
288
- </FormItem>
289
- </Col>
290
- </Row>
291
- <Row>
292
- <Col span="12">
293
- <FormItem label="任务提前:">
294
- <Input v-model="item.inAdvanceDay" style="width: 100px" type="number" :min="0"></Input>
295
-
296
- </FormItem>
297
- </Col>
298
- <Col span="12">
299
- <FormItem>
300
- <Input v-model="item.inAdvanceTime" style="margin-left: -140px;width: 100px" type="number"
301
- :min="0"></Input>
302
- 小时 标红预警
303
- </FormItem>
304
- </Col>
305
- </Row>
306
- <FormItem label="处理方式:">
307
- <Select v-model="item.processing" style="width:200px" placeholder="自动同意">
308
- <Option v-for="item in handleTypeList" :value="item.value" :key="item.value">
309
- {{ item.label }}
310
- </Option>
311
- </Select>
312
- </FormItem>
313
- </div>
314
- </Form>
315
- </Card>
316
- </Modal>
317
- <candidateGroupsHelpBox ref="candidateGroupsHelpBox" :show="candidateGroupsHelpBoxShow"
318
- @update-cand-groups="updateCandGroups"
319
- :upms-server-context="upmsServerContext"
320
- :smart-flow-server-context="smartFlowServerContext"/>
321
- <template slot="page-footer">
322
- <div>
323
- <slot name="footer-button"></slot>
324
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo70') && !isDetail && !appointTask"
325
- :disabled="disable" :loading="loading" @click="audit('70')">驳回到原点
326
- </Button>
327
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo40') && !isDetail && !appointTask"
328
- :disabled="disable" :loading="loading" @click="audit('40')">驳回上一节点
329
- </Button>
330
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo90') && !isDetail && !appointTask"
331
- :disabled="disable" :loading="loading" @click="audit('90')">驳回指定节点
332
- </Button>
333
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo80') && !isDetail && !appointTask"
334
- :disabled="disable" :loading="loading" @click="audit('80')">跳转指定节点
335
- </Button>
336
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo82') && !isDetail && !appointTask"
337
- :disabled="disable" :loading="loading" @click="audit('82')">指定他人处理
338
- </Button>
339
- <Button style="margin-left: 10px;"
340
- v-if="curNodeType === 'userTask' && handleButtons && handleButtons.includes('delegateTask') && !isDetail && !appointTask"
341
- :disabled="disable" :loading="loading" @click="audit('84')">委派
342
- </Button>
343
- <Button style="margin-left: 10px;"
344
- v-if="curNodeType === 'multiNode' && handleButtons && handleButtons.includes('addMultitaskInstance') && !isDetail && !appointTask"
345
- :disabled="disable" :loading="loading" @click="showUpdateMultitaskInstanceModal('81')">加签
346
- </Button>
347
- <Button style="margin-left: 10px;"
348
- v-if="curNodeType === 'multiNode' && handleButtons && handleButtons.includes('reductionMultitaskInstance') && !isDetail && !appointTask"
349
- :disabled="disable" :loading="loading" @click="showUpdateMultitaskInstanceModal('83')">减签
350
- </Button>
351
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo50') && !isDetail && !appointTask"
352
- :disabled="disable" :loading="loading" @click="audit('50')">直接结束流程
353
- </Button>
354
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('processTrace')"
355
- @click="processPrint">流程跟踪图
356
- </Button>
357
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo30') && !isDetail && !appointTask"
358
- :disabled="disable" :loading="loading" type="primary" @click="audit('30')">通过
359
- </Button>
360
- <Button style="margin-left: 10px;" v-if="revokeDelegateTask"
361
- :disabled="!revokeDelegateTask && disable" :loading="loading" @click="audit('62')">撤回委派
362
- </Button>
363
- <Button style="margin-left: 10px;" v-if="appointTask" :disabled="disable" :loading="loading" type="primary" @click="audit('61')">交回</Button>
364
- </div>
365
- </template>
366
- </LamboPageContainer>
367
- </template>
368
-
369
-
370
- <script>
371
- import LamboPageContainer from '@lambo-design/page-container'
372
- import LamboIndicatorCard from '@lambo-design/indicator-card'
373
- import Workflow_Diagram from './workflow-diagram'
374
- import ajax from '@lambo-design/shared/utils/ajax'
375
- import bus from '@lambo-design/shared/utils/bus'
376
- import Title from './components/title'
377
- import processHistory from './components/history'
378
- import assigneeBox from './components/assignee-box'
379
- import CandidateGroupsHelpBox from './components/candidate-groups-box'
380
- import CountersingersBox from './components/countersigners-box'
381
- import LamboPagingTable from '@lambo-design/paging-table'
382
- import AuditOpinion from './components/opinion'
383
- import axios from 'axios'
384
- import UploadFile from '@lambo-design/upload-file'
385
- import { timestampToTime } from '@lambo-design/shared/utils/date'
386
-
387
- // 引入docx-preview插件
388
- let docx = require('docx-preview')
389
-
390
- export default {
391
- props: {
392
- isDetail: {
393
- type: Boolean,
394
- required: false,
395
- default: false
396
- },
397
- width: {
398
- type: Number,
399
- required: false,
400
- default: 400
401
- },
402
- procId: {
403
- type: String,
404
- required: true,
405
- },
406
- taskNode: {
407
- type: String,
408
- required: true,
409
- },
410
- applyId: {
411
- type: String,
412
- required: true,
413
- },
414
- taskId: {
415
- type: String,
416
- required: false,
417
- default: '',
418
- },
419
- auditGroup: {
420
- type: String,
421
- required: false,
422
- default: '',
423
- },
424
- defaultAuditOpinion: {
425
- type: String,
426
- required: false,
427
- default: '',
428
- },
429
- //详情页催办按钮
430
- pushButton: {
431
- type: Boolean,
432
- required: false,
433
- default: true,
434
- },
435
- //流程跟踪图附件列
436
- showAttachmentFile: {
437
- type: Boolean,
438
- required: false,
439
- default: true,
440
- },
441
- //流程跟踪图审批详情触发方式
442
- approveDetailShowWay: {
443
- type: String,
444
- required: false,
445
- default: 'click',
446
- },
447
- //业务表单保存方法
448
- businessFormSave: {
449
- type: Function,
450
- required: false
451
- },
452
- //按钮执行完毕回调方法
453
- executionCompleted: {
454
- type: Function,
455
- required: false,
456
- default: () => {
457
- }
458
- },
459
- title: {
460
- type: String,
461
- default: '流程办理'
462
- },
463
- smartFlowServerContext: {
464
- type: String,
465
- default: '/api/smart-flow-server',
466
- },
467
- upmsServerContext: {
468
- type: String,
469
- default: '/api/upms-server',
470
- },
471
- },
472
- components: {
473
- Title,
474
- LamboPageContainer,
475
- Workflow_Diagram,
476
- processHistory,
477
- assigneeBox,
478
- LamboPagingTable,
479
- AuditOpinion,
480
- LamboIndicatorCard,
481
- UploadFile,
482
- CandidateGroupsHelpBox,
483
- CountersingersBox
484
- },
485
- data() {
486
- return {
487
- isExpanded: true,
488
- showProcessInfo: true,
489
- portraitWidth: 0,
490
- requestSuccessCodes: [200, '200'],
491
- auditShow: true,
492
- historyShow: true,
493
- attachListShow: true,
494
- attachmentList: [],
495
- modalVisible: false,
496
- modalDocx: false,
497
- imageUrl: '',
498
- assigneeBoxData: {},
499
- selectedUserId: '',
500
- targetTaskNode: '',
501
- allNode: [],
502
- auditParams: {},
503
- scrollElement: null,
504
- modal1: false,
505
- modalBoxShow: false,
506
- reductionMultitaskInstanceModal: false,
507
- candidateGroupsHelpBoxShow: false,
508
- appointBoxShow: false,
509
- autoOpenNode: '0',
510
- unapprovedAssigneeList: [],
511
- reductionAssigneeList: [],
512
- nextNodesOldSettings: [],
513
- nextNodesFormList: [],
514
- hisNode: [],
515
- processHistory: [],
516
- permScope: '',
517
- organTreeType: '00',
518
- defaultOrganTreeType: '00',
519
- ruleValidate: {
520
- auditOpinion: [{ required: true, trigger: 'blur', message: '意见不能为空' }],
521
- assignee: [{ required: true, trigger: 'blur', message: '办理人不能为空' }],
522
- candidateGroups: [{ required: true, trigger: 'blur', message: '候选人不能为空' }],
523
- },
524
- form: {
525
- auditOpinion: '',
526
- },
527
- loading: false,
528
- disable: false,
529
- revokeDelegateTask: false,
530
- appointTask: false,
531
- instanceId: '',
532
- curTaskId: '',
533
- curNodeType: 'userTask',
534
- handleButtons: [],
535
- handleName: '',
536
- auditOpinionTitle: '',
537
- auditResult: '',
538
- curAuditGroup: '',
539
- custChange: 'auditInfo',
540
- auditInfo: 'auditInfo',
541
- auditProcess: 'auditProcess',
542
- fileList: [],
543
- ossFilePutUrl: '/manage/oss/file/put',
544
- hisAudit: [],
545
- hisAuditOpinion: [{
546
- auditOpinion: '',
547
- auditTime: '',
548
- }],
549
- datas: {
550
- orgName: '',
551
- orgId: ''
552
- },
553
- editForm: {
554
- approvalCost: '',
555
- cost: '',
556
- activityDate: []
557
- },
558
- process: {
559
- tableData: [],
560
- instanceId: '',
561
- applyId: '',
562
- procId: ''
563
- },
564
- handleButtonsNames: {
565
- '30': '通过',
566
- '70': '驳回到原点',
567
- '40': '驳回上一节点',
568
- '90': '驳回指定节点',
569
- '80': '跳转指定节点',
570
- '82': '指定他人处理',
571
- '50': '直接结束流程',
572
- '84': '委派任务',
573
- '61': '交回委派任务',
574
- '62': '撤回委派任务',
575
- },
576
- handleTypeList: [
577
- {
578
- value: '00',
579
- label: '只预警不处理'
580
- },
581
- {
582
- value: '10',
583
- label: '自动同意'
584
- },
585
- {
586
- value: '20',
587
- label: '直接终止流程'
588
- },
589
- {
590
- value: '90',
591
- label: '自动驳回'
592
- }
593
- ],
594
- }
595
-
596
- },
597
-
598
- mounted() {
599
- this.getWidth()
600
- if (this.procId) {
601
- this.initData()
602
- }
603
- let modalElement = this.$refs.processTraceModal.$el
604
- for (let i = 0; i < modalElement.children.length; i++) {
605
- //找到滚动的目标element
606
- let targetElement = modalElement.children[i]
607
- if (targetElement.classList.toString().includes('-wrap')){
608
- this.scrollElement = targetElement
609
- break
610
- }
611
- }
612
- },
613
- computed: {
614
- processHistoryHeight() {
615
- let str = ''
616
- const hasAuditOpinion = this.taskNode && this.handleButtons && this.handleButtons.includes('auditOpinion')
617
- const hasAttachmentFile = this.handleButtons && this.handleButtons.includes('auditHistory') && this.attachmentList.length > 0
618
- const isDetail = this.isDetail && !this.hisAuditOpinion[0].auditOpinion.length > 0
619
- if (hasAuditOpinion && !hasAttachmentFile && !isDetail) {
620
- str += 'height: 43vh'
621
- } else if (hasAuditOpinion && hasAttachmentFile && !isDetail) {
622
- str += 'height: 40vh'
623
- } else {
624
- str += 'height: 67vh'
625
- }
626
- return str
627
- },
628
- nodeColumn: function () {
629
- let column = []
630
- column.push({ title: '序号', type: 'index', width: 70, align: 'center', fixed: 'left' })
631
- column.push({ title: '节点名称', key: 'taskName', minWidth: 150, align: 'center', fixed: 'left' })
632
-
633
- column.push({
634
- title: '节点状态', key: 'auditResult', minWidth: 150, align: 'center', fixed: 'left',
635
- render: (h, params) => {
636
- if (params.row.taskNode == this.taskNode) {
637
- return h('div', [
638
- h('tag', {
639
- props: {
640
- color: '#ff9900'
641
- }
642
- }, '当前节点')
643
- ])
644
- } else if (!params.row.auditResult) {
645
- return h('div', [
646
- h('tag', {
647
- props: {
648
- color: '#ff9900'
649
- }
650
- }, `未${params.row.handleName ? params.row.handleName : '审批'}`)
651
- ])
652
- } else {
653
- if (params.row.auditResult == '30' && params.row.taskNode != this.taskNode) {
654
- return h('div', [
655
- h('tag', {
656
- props: {
657
- color: '#19be6b'
658
- }
659
- }, `已${params.row.handleName ? params.row.handleName : '审批'}通过`)
660
- ])
661
- } else if (params.row.auditResult == '40' && params.row.taskNode != this.taskNode) {
662
- return h('div', [
663
- h('tag', {
664
- props: {
665
- color: '#ed4014'
666
- }
667
- }, '已驳回到上一节点')
668
- ])
669
- } else if (params.row.auditResult == '60' && params.row.taskNode != this.taskNode) {
670
- return h('div', [
671
- h('tag', {
672
- props: {
673
- color: '#ed4014'
674
- }
675
- }, '已撤回')
676
- ])
677
- } else if (params.row.auditResult == '61' && params.row.taskNode != this.taskNode) {
678
- return h('div', [
679
- h('tag', {
680
- props: {
681
- color: '#19be6b'
682
- }
683
- }, '已交回委派任务')
684
- ])
685
- } else if (params.row.auditResult == '62' && params.row.taskNode != this.taskNode) {
686
- return h('div', [
687
- h('tag', {
688
- props: {
689
- color: '#ed4014'
690
- }
691
- }, '委派任务已撤回')
692
- ])
693
- } else if (params.row.auditResult == '80' && params.row.taskNode != this.taskNode) {
694
- return h('div', [
695
- h('tag', {
696
- props: {
697
- color: '#19be6b'
698
- }
699
- }, '已跳转到指定节点')
700
- ])
701
- } else if (params.row.auditResult == '90' && params.row.taskNode != this.taskNode) {
702
- return h('div', [
703
- h('tag', {
704
- props: {
705
- color: '#19be6b'
706
- }
707
- }, '已驳回到指定节点')
708
- ])
709
- }
710
- }
711
- }
712
- })
713
- column.push({
714
- title: '操作', width: 100, align: 'center',
715
- render: (h, params) => {
716
- return h('div', [
717
- h('Button', {
718
- props: {
719
- type: 'primary',
720
- size: 'small'
721
- },
722
- style: {
723
- marginRight: '5px'
724
- },
725
- on: {
726
- click: () => {
727
- this.selectNode(params.row)
728
- }
729
- }
730
- }, '选择')
731
- ])
732
- },
733
- })
734
- return column
735
- },
736
- reductionColumn: function () {
737
- let column = []
738
- column.push({ title: '#', key: 'selectId', type: 'selection', align: 'center', width: 55 })
739
- column.push({ title: '账号', key: 'auditId', align: 'center' })
740
- column.push({ title: '姓名', key: 'auditName', align: 'center' })
741
- return column
742
- },
743
- diagramTableColumns: function () {
744
- let column = []
745
- column.push({ title: '序号', type: 'index', width: 60 })
746
- column.push({ title: `${this.handleName}节点`, key: 'taskName', minWidth: 130 })
747
- column.push({ title: `${this.handleName}人`, key: 'auditName', minWidth: 150, tooltip: true })
748
- column.push({
749
- title: `${this.handleName}结果`, key: 'auditResult', minWidth: 150, align: 'center',
750
- render: (h, { row, column, index }) => {
751
- let label = ''
752
- let tagColor = ''
753
- if (row.auditResult == '00') {
754
- label = '流程发起'
755
- tagColor = 'green' // 绿色
756
- } else if (row.auditResult == '10') {
757
- label = '自动跳过'
758
- tagColor = 'green' // 绿色
759
- } else if (row.auditResult == '30') {
760
- label = '通过'
761
- tagColor = 'green' // 绿色
762
- } else if (row.auditResult == '40') {
763
- label = '驳回到上一级'
764
- tagColor = 'volcano' // 火红色
765
- } else if (row.auditResult == '50') {
766
- label = '驳回到原点'
767
- tagColor = 'red' // 红色
768
- } else if (row.auditResult == '51') {
769
- label = '流程终止'
770
- tagColor = 'purple' // 紫色
771
- } else if (row.auditResult == '60') {
772
- label = '撤回'
773
- tagColor = 'blue' // 蓝色
774
- } else if (row.auditResult == '61') {
775
- label = '交回委派任务'
776
- tagColor = 'green' // 绿色
777
- } else if (row.auditResult == '62') {
778
- label = '委派任务被撤回'
779
- tagColor = 'blue' // 蓝色
780
- } else if (row.auditResult == '80') {
781
- label = '跳转到指定节点'
782
- tagColor = 'cyan' // 青色
783
- } else if (row.auditResult == '82') {
784
- label = '指定他人处理'
785
- tagColor = 'cyan' // 青色
786
- } else if (row.auditResult == '83') {
787
- label = '会签减签'
788
- tagColor = 'red' // 红色
789
- } else if (row.auditResult == '90') {
790
- label = '驳回到指定节点'
791
- tagColor = 'magenta' // 品红色
792
- } else {
793
- label = '待审核'
794
- tagColor = 'orange' // 默认橙色
795
- }
796
- return h('Tag', {
797
- props: {
798
- color: tagColor,
799
- value: row.auditResult
800
- }
801
- }, label)
802
- }
803
- })
804
- column.push({
805
- title: `${this.handleName}时间`, key: 'auditTime', minWidth: 150,
806
- render: (h, { row }) => {
807
- const displayDate = row.auditDate
808
- return h('span', displayDate)
809
- }
810
- })
811
- column.push({
812
- title: `${this.handleName}意见`, key: 'auditComment', minWidth: 180, tooltip: true,
813
- render: (h, { row, column, index }) => {
814
- let label = ''
815
- if (row.auditComment == '' || row.auditComment == null) {
816
- label = ''
817
- } else {
818
- label = row.auditComment
819
- }
820
- return h('Label', {
821
- props: {
822
- value: row.auditComment
823
- }
824
- }, label)
825
- }
826
- })
827
- if (this.showAttachmentFile) {
828
- column.push({
829
- title: `附件`, key: 'fileList', minWidth: 200,
830
- render: (h, { row }) => {
831
- if (!row.fileList || row.fileList.length === 0) {
832
- return h('span', '') // 如果没有附件,显示“无”
833
- }
834
-
835
- //显示所有附件
836
- return h('div', row.fileList.map(file => {
837
- return h('a', {
838
- style: {
839
- display: 'block',
840
- marginTop: '5px',
841
- marginRight: '5px',
842
- whiteSpace: 'nowrap',
843
- overflow: 'hidden',
844
- textOverflow: 'ellipsis',
845
- maxWidth: '100px',
846
- },
847
- attrs: {
848
- title: file.attachName // 鼠标悬停时显示完整名称
849
- },
850
- on: {
851
- click: () => {
852
- this.getAttach(file)
853
- }
854
- },
855
- }, file.attachName)
856
- }))
857
- }
858
- })
859
- }
860
-
861
- return column
862
- },
863
- },
864
- provide() {
865
- return {
866
- toBeDoneListDoSearch: this.doSearch
867
- }
868
- },
869
- methods: {
870
- getWidth() {
871
- if (this.width && this.width < 400) {
872
- this.portraitWidth = 400
873
- }
874
- this.portraitWidth = this.width
875
- },
876
- initData() {
877
- if (!this.isDetail) {
878
- this.getTodoTask()
879
- } else {
880
- this.getDoneTask()
881
- }
882
- this.getHandleButtons()
883
- },
884
- getTodoTask() {
885
- const self = this
886
- let param = {
887
- procId: this.procId,
888
- applyId: this.applyId,
889
- taskNode: this.taskNode,
890
- taskId: this.taskId,
891
- auditGroup: this.auditGroup
892
- }
893
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/list', { params: param }).then(function (resp) {
894
- if (resp.data.code === '200') {
895
- let todoData = resp.data.data.rows[0]
896
- self.curTaskId = todoData.taskId
897
- self.instanceId = todoData.procInstanceId
898
- self.curAuditGroup = todoData.auditGroup
899
- self.revokeDelegateTask = todoData.delegateStatus ? todoData.delegateStatus === '10' : false
900
- self.appointTask = todoData.delegateStatus ? todoData.delegateStatus === '20' : false
901
- if (self.revokeDelegateTask) self.disable = true
902
- let procType = todoData.procType
903
- ajax.get(self.smartFlowServerContext + '/manage/processType/lists?proType=' + procType)
904
- .then(resp => {
905
- let data = resp.data.data.rows
906
- self.permScope = data[0].permScope
907
- self.defaultOrganTreeType = data[0].organTreeType ? data[0].organTreeType : '00'
908
- self.getNodeOrganTreeType(procType)
909
- }).catch(err => {
910
- console.log(err)
911
- })
912
- self.getAttachList(self.curTaskId)
913
- self.getHisAudit(self.curTaskId)
914
- self.getProcessHistory(self.curTaskId)
915
- } else {
916
- self.$Message.error(resp.data.message)
917
- }
918
- }).catch((err) => {
919
- console.log(err)
920
- })
921
- },
922
- getNodeOrganTreeType(procType) {
923
- const self = this
924
- let param = {
925
- procType: procType,
926
- procId: this.procId,
927
- taskNode: this.taskNode
928
- }
929
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/getNodeOrganTreeType', { params: param }).then(function (resp) {
930
- if (resp.data.code === '200') {
931
- self.organTreeType = resp.data.data ? resp.data.data : self.defaultOrganTreeType
932
- } else {
933
- self.$Message.error(resp.data.message)
934
- }
935
- }).catch((err) => {
936
- console.log(err)
937
- })
938
- },
939
- getDoneTask() {
940
- const self = this
941
- let param = {
942
- procId: this.procId,
943
- applyId: this.applyId,
944
- taskNode: this.taskNode,
945
- taskId: this.taskId,
946
- auditGroup: this.auditGroup
947
- }
948
- ajax.get(self.smartFlowServerContext + '/manage/processDone/getDoneDetail', { params: param }).then(function (resp) {
949
- if (resp.data.code === '200') {
950
- let rows = resp.data.data.rows
951
- if (rows.length > 0) {
952
- self.curAuditGroup = rows[0].auditGroup
953
- self.hisAuditOpinion = []
954
- let taskList = resp.data.data.rows
955
- taskList.forEach(item => {
956
- self.hisAuditOpinion.push({
957
- auditOpinion: item.auditComment,
958
- auditTime: timestampToTime(item.auditDate)
959
- })
960
- })
961
- self.curTaskId = taskList[0].taskId
962
- self.instanceId = taskList[0].procInstanceId
963
- } else {
964
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/list', { params: param }).then(function (todoResp) {
965
- if (todoResp.data.code === '200') {
966
- self.curTaskId = todoResp.data.data.rows[0].taskId
967
- self.instanceId = todoResp.data.data.rows[0].procInstanceId
968
- self.curAuditGroup = todoResp.data.data.rows[0].auditGroup
969
- } else {
970
- self.$Message.error(todoResp.data.message)
971
- }
972
- }).catch((err) => {
973
- console.log(err)
974
- })
975
- }
976
- self.getAttachList(self.curTaskId)
977
- self.getHisAudit(self.curTaskId)
978
- self.getProcessHistory(self.curTaskId)
979
- } else {
980
- self.$Message.error(resp.data.message)
981
- }
982
- }).catch((err) => {
983
- console.log(err)
984
- })
985
- },
986
- getHandleButtons() {
987
- const self = this
988
- let param = {
989
- procId: this.procId,
990
- taskNode: this.taskNode
991
- }
992
- ajax.post(self.smartFlowServerContext + '/manage/approvalCenter/getNodeData', param).then(function (resp) {
993
- if (resp.data.code === '200') {
994
- self.handleButtons = resp.data.data[0].handleButtons
995
- if (resp.data.data[0].hasOwnProperty('isSequential')) {
996
- self.curNodeType = resp.data.data[0].isSequential ? 'sequentialMultiNode' : 'multiNode'
997
- }
998
- self.handleName = resp.data.data[0].handleName ? resp.data.data[0].handleName : '审批'
999
- self.auditOpinionTitle = resp.data.data[0].handleName ? resp.data.data[0].handleName + '意见' : '审批意见'
1000
- if (!self.handleButtons || (!self.handleButtons.includes('auditOpinion') && !self.handleButtons.includes('attachmentFile') && !self.handleButtons.includes('auditHistory'))) {
1001
- self.showProcessInfo = false
1002
- }
1003
- } else {
1004
- self.$Message.error(resp.data.message)
1005
- }
1006
- }).catch((err) => {
1007
- console.log(err)
1008
- })
1009
- },
1010
- getNextNodes() {
1011
- const self = this
1012
- self.nextNodesFormList = []
1013
- self.nextNodesOldSettings = []
1014
- let param = {
1015
- procId: this.procId,
1016
- taskNode: this.taskNode
1017
- }
1018
- ajax.post(self.smartFlowServerContext + '/manage/processTodo/getNextNodes', param).then(function (resp) {
1019
- if (resp.data.code === '200') {
1020
- let nextNodeForm = {}
1021
- let nextNodeOldForm = {}
1022
- let data = resp.data.data
1023
- for (let i = 0; i < data.length; i++) {
1024
- nextNodeOldForm = {
1025
- id: data[i].id,
1026
- assignee: data[i].assignee ? data[i].assignee.id : '',
1027
- timeLimit: data[i].timeLimit,
1028
- }
1029
- nextNodeForm = {
1030
- id: data[i].id,
1031
- name: data[i].name,
1032
- orgTreeType: data[i].orgTreeType,
1033
- assignee: data[i].assignee ? data[i].assignee.id : '',
1034
- assigneeName: data[i].assignee ? data[i].assignee.name : '',
1035
- candidateGroups: '',
1036
- isMultiInstance: data[i].isMultiInstance,
1037
- actionType: 'ASSIGNEE',
1038
- remainDay: 0,
1039
- remainTime: 0,
1040
- inAdvanceDay: 0,
1041
- inAdvanceTime: 0,
1042
- processing: '00'
1043
- }
1044
- //显示具体候选人信息
1045
- if (data[i].candidateGroups) {
1046
- nextNodeForm.actionType = 'CAND'
1047
- let names = []
1048
- let candidates = {}
1049
- for (let groupName in data[i].candidateGroups) {
1050
- if (data[i].candidateGroups.hasOwnProperty(groupName)) {
1051
- let group = data[i].candidateGroups[groupName]
1052
- group.forEach(item => {
1053
- names.push(item.name)
1054
- })
1055
- candidates[groupName] = group.map(item => item.id + ':' + item.name).join(',')
1056
- }
1057
- }
1058
- nextNodeForm.candidateNames = names.join(',')
1059
- nextNodeForm.candidates = candidates
1060
- nextNodeOldForm.candidates = candidates
1061
- }
1062
- if (data[i].timeLimit) {
1063
- let expireTime = data[i].timeLimit.split(';')[0].split(':')[1]
1064
- let warningTime = data[i].timeLimit.split(';')[1].split(':')[1]
1065
- let handleType = data[i].timeLimit.split(';')[2].split(':')[1]
1066
- let days = expireTime.slice(0, expireTime.indexOf('D')) //过期天
1067
- let hourOfDay = expireTime.slice(expireTime.indexOf('D') + 1, expireTime.indexOf('H')) //过期小时
1068
- let daysWarn = warningTime.slice(0, warningTime.indexOf('D')) //警告天
1069
- let hourOfDayWarn = warningTime.slice(warningTime.indexOf('D') + 1, warningTime.indexOf('H')) //警告小时
1070
- nextNodeForm.remainDay = parseInt(days)
1071
- nextNodeForm.remainTime = parseInt(hourOfDay)
1072
- nextNodeForm.inAdvanceDay = parseInt(daysWarn)
1073
- nextNodeForm.inAdvanceTime = parseInt(hourOfDayWarn)
1074
- nextNodeForm.processing = handleType
1075
- }
1076
- self.nextNodesFormList.push(nextNodeForm)
1077
- self.nextNodesOldSettings.push(nextNodeOldForm)
1078
- }
1079
- } else {
1080
- self.$Message.error(resp.data.message)
1081
- }
1082
- }).catch((err) => {
1083
- console.log(err)
1084
- })
1085
- },
1086
- getAttachList(taskId) {
1087
- const self = this
1088
- const param = {
1089
- taskId: taskId,
1090
- procId: this.procId,
1091
- applyId: this.applyId
1092
- }
1093
- ajax.get(self.smartFlowServerContext + '/manage/processDone/getAttachmentList', { params: param }).then(function (resp) {
1094
- self.attachmentList = resp.data.data.rows
1095
- self.attachmentList.forEach(item => {
1096
- const index = item.fileName.lastIndexOf('.')
1097
- const fileType = item.fileName.substr(index + 1).toLowerCase()
1098
- const imageList = ['jpg', 'gif', 'png', 'svg']
1099
- const docList = ['doc', 'docx']
1100
- const zipList = ['rar', 'zip']
1101
- const typeList = ['jpg', 'gif', 'png', 'docx']
1102
- item.fileType = imageList.indexOf(fileType) !== -1 ? 'image' : docList.indexOf(fileType) !== -1 ? 'doc' : zipList.indexOf(fileType) !== -1 ? 'zip' : fileType
1103
- item.showPreview = typeList.indexOf(fileType) !== -1
1104
- })
1105
- }).catch(err => {
1106
- console.log(err)
1107
- })
1108
- },
1109
- getHisAudit(taskId) {
1110
- let self = this
1111
- let params = {
1112
- applyId: self.applyId,
1113
- instanceId: self.instanceId,
1114
- procId: self.procId,
1115
- taskId: taskId
1116
- }
1117
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/getHisAudit', { params: params }).then(function (resp) {
1118
- if (resp.data.code === '200') {
1119
- self.hisAudit = resp.data.data
1120
- let uniqueDataMap = {}
1121
- self.hisAudit.forEach((item) => {
1122
- uniqueDataMap[item['taskNode']] = item
1123
- })
1124
- self.hisNode = Object.values(uniqueDataMap)
1125
-
1126
- }
1127
- })
1128
- },
1129
- getProcessHistory(taskId) {
1130
- let self = this
1131
- let params = {
1132
- applyId: self.applyId,
1133
- instanceId: self.instanceId,
1134
- procId: self.procId,
1135
- taskId: taskId
1136
- }
1137
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/getProcessHis', { params: params }).then(function (resp) {
1138
- if (resp.data.code === '200') {
1139
- self.processHistory = resp.data.data
1140
- }
1141
- })
1142
- },
1143
-
1144
- audit: function (auditResult) {
1145
- let self = this
1146
- self.auditResult = auditResult
1147
- self.submit()
1148
- },
1149
- submit() {
1150
- let self = this
1151
- self.auditParams = {
1152
- procId: self.procId,
1153
- applyId: self.applyId,
1154
- taskId: self.curTaskId,
1155
- auditOpinion: self.form.auditOpinion,
1156
- fileListStr: JSON.stringify(self.fileList),
1157
- auditResult: self.auditResult,
1158
- params: JSON.stringify(self.datas),
1159
- targetTaskNode: self.targetTaskNode,
1160
- selectedUserId: self.selectedUserId,
1161
- }
1162
- if (self.auditResult == '' || self.auditResult == null) {
1163
- self.$Message.error(`请选择${self.handleName}结果!`)
1164
- return
1165
- }
1166
- if (self.form.auditOpinion == '' || self.form.auditOpinion == null) {
1167
- if (self.auditResult === '30') {
1168
- self.auditParams.auditOpinion = '通过'
1169
- self.businessFormSave ? self.businessFormSave(self.handleSaveResult) : self.handleSaveResult(true)
1170
- return
1171
- }
1172
- if ((!self.handleButtons || self.handleButtons.includes('auditOpinion')) && self.auditResult !== '84') {
1173
- self.$Message.error(`请输入${self.handleName}意见!`)
1174
- return
1175
- } else {
1176
- self.auditParams.auditOpinion = self.handleButtonsNames[self.auditResult]
1177
- }
1178
- }
1179
- self.businessFormSave ? self.businessFormSave(self.handleSaveResult) : self.handleSaveResult(true)
1180
- },
1181
- handleSaveResult(saveResult, businessParams) {
1182
- if (saveResult) {
1183
- this.executeButtonAction(businessParams)
1184
- } else {
1185
- console.error('保存失败')
1186
- }
1187
- },
1188
- executeButtonAction(businessParams) {
1189
- const self = this
1190
- if (businessParams) {
1191
- Object.assign(self.datas, businessParams)
1192
- self.auditParams.params = JSON.stringify(self.datas)
1193
- }
1194
- let auditResult = {
1195
- code: self.auditResult,
1196
- name: self.handleButtonsNames[self.auditResult]
1197
- }
1198
- if (self.auditResult === '82') {
1199
- //指定他人处理
1200
- self.assigneeBoxData = self.auditParams
1201
- self.assigneeBoxData.auditResultName = self.handleButtonsNames[self.auditResult]
1202
- self.assigneeBoxData.instanceId = self.instanceId
1203
- self.$refs.assigneeHelpBox.toggleShowHelpBox(self.organTreeType, '', 'transferCurTask')
1204
- } else if (self.auditResult === '84') {
1205
- //委派任务
1206
- self.$refs.assigneeHelpBox.toggleShowHelpBox(self.organTreeType, '', 'delegateTask')
1207
- } else if (self.auditResult === '62') {
1208
- //撤回委派任务
1209
- ajax.post(self.smartFlowServerContext + '/manage/processTodo/audit', self.auditParams).then(resp => {
1210
- let result = resp.data
1211
- if (result.code == '200') {
1212
- self.loading = false
1213
- self.disable = false
1214
- self.revokeDelegateTask = false
1215
- self.$Message.success('撤回委派成功')
1216
- } else {
1217
- self.loading = false
1218
- self.disable = false
1219
- self.$Message.error(result.message)
1220
- }
1221
- })
1222
- } else if (self.auditResult === '61') {
1223
- //交回委派任务
1224
- ajax.post(self.smartFlowServerContext + '/manage/processTodo/audit', self.auditParams).then(resp => {
1225
- let result = resp.data
1226
- if (result.code == '200') {
1227
- self.loading = false
1228
- self.disable = false
1229
- self.$Message.success('交回委派任务成功')
1230
- if (result.data) {
1231
- let taskIds = result.data.id ? result.data.id : result.data.map(item => item.id).join(',')
1232
- setTimeout(() => {
1233
- self.executionCompleted(true, result.data.id ? result.data.processInstanceId : result.data[0].processInstanceId, taskIds, auditResult, self.curTaskId)
1234
- }, 1000)
1235
- }
1236
- } else {
1237
- self.loading = false
1238
- self.disable = false
1239
- self.$Message.error(result.message)
1240
- }
1241
- })
1242
- } else if (self.auditResult === '80') {
1243
- //跳转到后序指定节点
1244
- self.getNodesBehind()
1245
- } else if (self.auditResult === '90') {
1246
- //驳回到前序指定节点
1247
- self.getAllPreNodes()
1248
- } else if (self.auditResult === '40') {
1249
- //驳回到上一级
1250
- self.loading = true
1251
- self.disable = true
1252
- let url = self.smartFlowServerContext + '/manage/processTodo/getPreNode'
1253
- ajax.post(url, self.auditParams).then(function (resp) {
1254
- let result = resp.data
1255
- if (result.code == '30013' || result.code == '30014') {
1256
- //前序节点为子流程或当前节点为子流程第一个节点不可驳回上一级节点
1257
- self.$Message.warning(result.message)
1258
- //避免未提示消息直接回调
1259
- setTimeout(() => {
1260
- self.executionCompleted(false, null, null, auditResult, self.curTaskId)
1261
- }, 1000)
1262
- } else if (result.code == '30010') {
1263
- self.$Modal.confirm({
1264
- title: '提示',
1265
- content: result.message,
1266
- onOk: () => {
1267
- self.auditParams.auditResult = '70'
1268
- let url = self.smartFlowServerContext + '/manage/processTodo/audit'
1269
- ajax.post(url, self.auditParams).then(function (resp) {
1270
- let result = resp.data
1271
- if (result.code == '200') {
1272
- self.loading = false
1273
- self.disable = false
1274
- self.$Message.success(result.message)
1275
- //后端没有返回数据
1276
- setTimeout(() => {
1277
- self.executionCompleted(true, null, null, auditResult, self.curTaskId)
1278
- }, 1000)
1279
- bus.$emit('triggerTimer')
1280
- } else {
1281
- self.loading = false
1282
- self.disable = false
1283
- self.$Message.error(result.message)
1284
- setTimeout(() => {
1285
- self.executionCompleted(false, null, null, auditResult, self.curTaskId)
1286
- }, 1000)
1287
- }
1288
- bus.$emit('triggerTimer')
1289
- })
1290
- },
1291
- onCancel: () => {
1292
- self.loading = false
1293
- self.disable = false
1294
- }
1295
- })
1296
- } else if (result.code == '10012') {
1297
- // 数据同步
1298
- self.loading = false
1299
- self.disable = false
1300
- self.$Message.warning(result.message)
1301
- setTimeout(() => {
1302
- self.executionCompleted(true, null, null, auditResult, self.curTaskId)
1303
- }, 1000)
1304
- } else {
1305
- self.loading = true
1306
- self.disable = true
1307
- let url = self.smartFlowServerContext + '/manage/processTodo/audit'
1308
- ajax.post(url, self.auditParams).then(function (resp) {
1309
- let result = resp.data
1310
- if (result.code == '200') {
1311
- self.loading = false
1312
- self.disable = false
1313
- self.$Message.success(result.message)
1314
- setTimeout(() => {
1315
- if (result.data) {
1316
- let taskIds = result.data.map(item => item.id).join(',')
1317
- self.executionCompleted(true, result.data[0].processInstanceId, taskIds, auditResult, self.curTaskId)
1318
- } else {
1319
- self.executionCompleted(true, null, null, auditResult, self.curTaskId)
1320
- }
1321
- }, 1000)
1322
- } else {
1323
- self.loading = false
1324
- self.disable = false
1325
- self.$Message.error(result.message)
1326
- setTimeout(() => {
1327
- self.executionCompleted(false, null, null, auditResult, self.curTaskId)
1328
- }, 1000)
1329
- }
1330
- bus.$emit('triggerTimer')
1331
- })
1332
- }
1333
- })
1334
- } else {
1335
- if (self.auditResult === '30' && (!self.handleButtons || self.handleButtons.includes('appointHandler') || self.handleButtons.includes('appointTimeoutTime'))) {
1336
- self.getNextNodes()
1337
- self.appointBoxShow = true
1338
- } else {
1339
- self.doPass()
1340
- }
1341
- }
1342
- },
1343
- doPass() {
1344
- let self = this
1345
- this.modal = false
1346
- let auditResult = {
1347
- code: self.auditResult,
1348
- name: self.handleButtonsNames[self.auditResult]
1349
- }
1350
- if (self.auditResult === '82' && (self.targetTaskNode == '' || self.targetTaskNode == null)) {
1351
- self.auditResult = ''
1352
- self.$Message.error(`请选择${self.handleName}节点!`)
1353
- } else {
1354
- self.loading = true
1355
- self.disable = true
1356
- self.auditParams.targetTaskNode = self.targetTaskNode
1357
- let url = self.smartFlowServerContext + '/manage/processTodo/audit'
1358
- ajax.post(url, self.auditParams).then(function (resp) {
1359
- let result = resp.data
1360
- if (result.code == '200') {
1361
- self.loading = false
1362
- self.disable = false
1363
- self.$Message.success(result.message ? result.message : `${self.handleName}成功`)
1364
- if (result.data) {
1365
- let taskIds = result.data.id ? result.data.id : result.data.map(item => item.id).join(',')
1366
- setTimeout(() => {
1367
- self.executionCompleted(true, result.data.id ? result.data.processInstanceId : result.data[0].processInstanceId, taskIds, auditResult, self.curTaskId)
1368
- }, 1000)
1369
- } else {
1370
- setTimeout(() => {
1371
- self.executionCompleted(true, null, null, auditResult, self.curTaskId)
1372
- }, 1000)
1373
- }
1374
- } else if (result.code == '10012') {
1375
- // 数据同步
1376
- self.loading = false
1377
- self.disable = false
1378
- self.$Message.warning(result.message)
1379
- setTimeout(() => {
1380
- self.executionCompleted(true, null, null, auditResult, self.curTaskId)
1381
- }, 1000)
1382
- } else if (result.code == '20002') {
1383
- // 流程结束
1384
- self.loading = false
1385
- self.disable = false
1386
- self.$Message.success(result.message)
1387
- setTimeout(() => {
1388
- self.executionCompleted(true, '流程已结束', '流程已结束', auditResult, self.curTaskId)
1389
- }, 1000)
1390
- } else {
1391
- self.loading = false
1392
- self.disable = false
1393
- self.$Message.error(result.message ? result.message : `${self.handleName}失败`)
1394
- setTimeout(() => {
1395
- self.executionCompleted(false, null, null, auditResult, self.curTaskId)
1396
- }, 1000)
1397
- }
1398
- bus.$emit('triggerTimer')
1399
- })
1400
- }
1401
- },
1402
- showUpdateMultitaskInstanceModal(updateType) {
1403
- const self = this
1404
- if (updateType === '81') {
1405
- this.$refs.assigneeHelpBox.toggleShowHelpBox(this.organTreeType, '', 'addMultitaskInstance')
1406
- } else if (updateType === '83') {
1407
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/getUnapprovedListOfMultiNode?taskId=' + self.curTaskId).then(function (resp) {
1408
- if (resp.data.code === '200') {
1409
- self.unapprovedAssigneeList = resp.data.data
1410
- self.reductionMultitaskInstanceModal = true
1411
- } else {
1412
- self.$Message.error(resp.data.message)
1413
- }
1414
- }).catch(err => {
1415
- console.log(err)
1416
- })
1417
- }
1418
- },
1419
- updateMultitaskInstance(updateType, assignees) {
1420
- const self = this
1421
- self.loading = true
1422
- self.disable = true
1423
- let param = {
1424
- taskId: self.curTaskId,
1425
- applyId: self.applyId,
1426
- assignees: assignees,
1427
- updateType: updateType
1428
- }
1429
- ajax.post(self.smartFlowServerContext + '/manage/processTodo/updateMultitaskInstance', param).then(resp => {
1430
- let result = resp.data
1431
- if (result.code == '200') {
1432
- self.loading = false
1433
- self.disable = false
1434
- self.$Message.success(result.message)
1435
- } else {
1436
- self.loading = false
1437
- self.disable = false
1438
- self.$Message.error(result.message)
1439
- }
1440
- }).catch(err => {
1441
- console.log(err)
1442
- })
1443
- },
1444
- //委派
1445
- delegateTask(assignee) {
1446
- const self = this
1447
- if (!assignee){
1448
- self.$Message.error('请选择加签人员')
1449
- return
1450
- }
1451
- let auditResult = {
1452
- code: self.auditResult,
1453
- name: self.handleButtonsNames[self.auditResult]
1454
- }
1455
- self.auditParams.selectedUserId = assignee
1456
- ajax.post(self.smartFlowServerContext + '/manage/processTodo/audit', self.auditParams).then(resp => {
1457
- let result = resp.data
1458
- if (result.code == '200') {
1459
- self.loading = false
1460
- self.disable = false
1461
- self.$Message.success('委派成功')
1462
- if (result.data) {
1463
- let taskIds = result.data.id ? result.data.id : result.data.map(item => item.id).join(',')
1464
- setTimeout(() => {
1465
- self.executionCompleted(true, result.data.id ? result.data.processInstanceId : result.data[0].processInstanceId, taskIds, auditResult, self.curTaskId)
1466
- }, 1000)
1467
- }
1468
- } else {
1469
- self.loading = false
1470
- self.disable = false
1471
- self.$Message.error(result.message)
1472
- }
1473
- }).catch(err => {
1474
- console.log(err)
1475
- })
1476
- },
1477
- //加签
1478
- addMultitaskInstance(assingeeList) {
1479
- const assingees = assingeeList.join(',')
1480
- this.updateMultitaskInstance('81', assingees)
1481
- },
1482
- //减签
1483
- reductionMultitaskInstance() {
1484
- if (this.reductionAssigneeList.length === 0) {
1485
- this.$Message.error('请选择减签人员')
1486
- return
1487
- }
1488
- const assingees = this.reductionAssigneeList.map(item => item.auditId).join(',')
1489
- this.updateMultitaskInstance('83', assingees)
1490
- },
1491
-
1492
- doSearch() {
1493
- //不需要实现,是子组件assigneeBox要求使用父组件的这个方法
1494
- },
1495
- tabsChange(tab) {
1496
- console.log(tab)
1497
- },
1498
- getAttach(row) {
1499
- window.open(this.smartFlowServerContext + '/manage/oss/file/get/' + row.fileId, '_blank')
1500
- },
1501
- preViewAttach(row) {
1502
- let reg = /\.(gif|jpg|jpeg|bmp|png|PNG)$/
1503
- let regs = /\.(pdf)$/
1504
- if (reg.test(row.fileName)) {
1505
- let url = this.smartFlowServerContext + '/manage/oss/file/get/' + row.fileId
1506
- this.imgPreview(url)
1507
- } else if (regs.test(row.fileName)) {
1508
- window.open(this.smartFlowServerContext + '/manage/oss/file/getFileStream?fileId=' + row.fileId, '_blank')
1509
- } else {
1510
- this.modalDocx = true
1511
- axios({
1512
- method: 'get',
1513
- responseType: 'blob', // 因为是流文件,所以要指定blob类型
1514
- url: this.smartFlowServerContext + '/manage/oss/file/get/' + row.fileId// 一个word下载文件的接口
1515
- }).then(({ data }) => {
1516
- docx.renderAsync(data, this.$refs.file, null, {
1517
- className: 'docx', //默认和文档样式类的类名/前缀
1518
- inWrapper: true, //启用围绕文档内容呈现包装器
1519
- ignoreWidth: false, //禁用页面的渲染宽度
1520
- ignoreHeight: false, //禁用页面的渲染高度
1521
- ignoreFonts: false, //禁用字体渲染
1522
- breakPages: true, //在分页符上启用分页
1523
- ignoreLastRenderedPageBreak: true, //在lastRenderedPageBreak元素上禁用分页
1524
- experimental: false, //启用实验功能(制表符停止计算)
1525
- trimXmlDeclaration: true, //如果为true,则在解析之前将从xml文档中删除xml声明
1526
- useBase64URL: false, //如果为true,图像、字体等将转换为base 64 URL,否则使用URL.createObjectURL
1527
- useMathMLPolyfill: false, //包括用于铬、边等的MathML多填充。
1528
- showChanges: false, //启用文档更改的实验渲染(插入/删除)
1529
- debug: false, //启用额外的日志记录
1530
- })
1531
- }
1532
- )
1533
- }
1534
- },
1535
- imgPreview(url) {
1536
- this.imageUrl = url
1537
- this.modalVisible = true
1538
- },
1539
-
1540
- //打印流程图信息
1541
- processPrint() {
1542
- let self = this
1543
- let params = {
1544
- applyId: self.applyId,
1545
- instanceId: self.instanceId,
1546
- procId: self.procId,
1547
- taskId: self.curTaskId,
1548
- }
1549
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/getPrintData', { params: params }).then(function (resp) {
1550
- let result = resp.data.data
1551
- if (resp.data.code === '200') {
1552
- let tableData = result
1553
- self.process.tableData = tableData
1554
- self.process.applyId = self.applyId
1555
- self.process.instanceId = self.instanceId
1556
- self.process.procId = self.procId
1557
- self.datas.orgId = tableData[0].orgId
1558
- self.datas.orgName = tableData[0].orgName
1559
- self.modalBoxShow = true
1560
- }
1561
- })
1562
- },
1563
-
1564
- showTaskNode(taskId) {
1565
- if (this.processHistory.length > 0) {
1566
- let task = null
1567
- this.processHistory.some(itemList => {
1568
- task = itemList.find(item => item.taskId === taskId)
1569
- return task !== undefined
1570
- })
1571
- return task ? task.taskName : ''
1572
- }
1573
- return ''
1574
- },
1575
- cancel() {
1576
- this.modal = false
1577
- this.auditResult = ''
1578
- },
1579
- reductionModalCancel() {
1580
- this.reductionMultitaskInstanceModal = false
1581
- this.reductionAssigneeList = []
1582
- },
1583
- selectAssignee(selection) {
1584
- this.reductionAssigneeList = selection
1585
- },
1586
- selectNode(currentRow, oldCurrentRow) {
1587
- let self = this
1588
- self.targetTaskNode = currentRow.taskNode
1589
- },
1590
- getAllPreNodes() {
1591
- let self = this
1592
- let params = {
1593
- processDefId: self.procId,
1594
- taskId: self.curTaskId,
1595
- }
1596
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/getAllPreNodes', { params: params }).then(function (resp) {
1597
- if (resp.data.code === '200') {
1598
- if (resp.data.data.length > 0) {
1599
- self.allNode = resp.data.data
1600
- self.modal1 = true
1601
- } else {
1602
- self.$Message.warning('当前流程无前序节点')
1603
- }
1604
- } else {
1605
- self.$Message.error(resp.data.message)
1606
- }
1607
- })
1608
- },
1609
- getNodesBehind() {
1610
- let self = this
1611
- let params = {
1612
- processDefId: self.procId,
1613
- taskId: self.curTaskId,
1614
- }
1615
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/getNodesBehind', { params: params }).then(function (resp) {
1616
- if (resp.data.code === '200') {
1617
- if (resp.data.data.length > 0) {
1618
- self.allNode = resp.data.data
1619
- self.modal1 = true
1620
- } else {
1621
- self.$Message.warning('当前流程无后续节点')
1622
- }
1623
- } else {
1624
- self.$Message.error(resp.data.message)
1625
- }
1626
- })
1627
- },
1628
- handleSelectedUser(userId) {
1629
- this.selectedUserId = userId
1630
- },
1631
-
1632
- //折叠动画效果
1633
- beforeEnter(el) {
1634
- el.style.height = '0'
1635
- },
1636
- enter(el, done) {
1637
- setTimeout(() => {
1638
- el.style.height = el.scrollHeight + 'px'
1639
- }, 0)
1640
-
1641
- el.addEventListener('transitionend', done)
1642
- },
1643
- beforeLeave(el) {
1644
- el.style.height = el.scrollHeight + 'px'
1645
- },
1646
- leave(el, done) {
1647
- setTimeout(() => {
1648
- el.style.height = '0'
1649
- }, 0)
1650
-
1651
- el.addEventListener('transitionend', done)
1652
- },
1653
-
1654
- beforeFlowInfoEnter(el) {
1655
- el.style.transform = 'translateX(100%)'
1656
- },
1657
- flowInfoEnter(el, done) {
1658
- const transitionDuration = 0.5
1659
- el.style.transition = `transform ${transitionDuration}s`
1660
- el.style.transform = 'translateX(0)'
1661
- el.addEventListener('transitionend', done)
1662
- },
1663
- beforeFlowInfoLeave(el) {
1664
- el.style.transform = 'translateX(0)'
1665
- },
1666
- flowInfoLeave(el, done) {
1667
- const transitionDuration = 0.5
1668
- el.style.transition = `transform ${transitionDuration}s`
1669
- el.style.transform = 'translateX(100%)'
1670
- el.addEventListener('transitionend', done)
1671
- },
1672
- uploadFile(file) {
1673
- const self = this
1674
- self.fileList = []
1675
- file.forEach(item => {
1676
- self.fileList.push({
1677
- fileName: item.fileName,
1678
- fileId: item.fileCode,
1679
- })
1680
- })
1681
- },
1682
-
1683
- appointOk() {
1684
- const self = this
1685
- let oldSettings
1686
- let params = this.nextNodesFormList.reduce((acc, item) => {
1687
- acc[item.id] = {
1688
- needUpdate: 'false',
1689
- }
1690
- item.assignee ? acc[item.id].assignee = item.assignee : ''
1691
- item.candidateGroups ? acc[item.id].candidateGroup = item.candidateGroups : ''
1692
- let timeLimit = 'expireTime:0D0H;warningTime:0D0H;handleType:00'
1693
- if (!(item.remainDay === 0 && item.remainTime === 0 && item.inAdvanceDay === 0 && item.inAdvanceTime === 0)) {
1694
- timeLimit = 'expireTime:' + parseInt(item.remainDay) + 'D' + parseInt(item.remainTime) + 'H' + ';warningTime:' + parseInt(item.inAdvanceDay) + 'D' + parseInt(item.inAdvanceTime) + 'H;' + 'handleType:' + item.processing
1695
- acc[item.id].timeLimit = timeLimit
1696
- } else {
1697
- acc[item.id].timeLimit = ''
1698
- }
1699
- oldSettings = self.nextNodesOldSettings.filter(oldSetting => oldSetting.id === item.id)[0]
1700
- if (oldSettings.assignee !== item.assignee || self.checkGroupsUpdate(oldSettings.candidates, item.candidateGroups, item.isMultiInstance) || self.checkTimeLimitUpdate(oldSettings.timeLimit, timeLimit)) {
1701
- acc[item.id].needUpdate = 'true'
1702
- }
1703
- return acc
1704
- }, {})
1705
- self.auditParams.nodeConfigMaps = JSON.stringify(params)
1706
- self.doPass((execResult, instanceId, taskIds, auditResult, curTaskId) => {
1707
- if (this.executionCompleted) {
1708
- this.executionCompleted(execResult, instanceId, taskIds, auditResult, curTaskId)
1709
- }
1710
- })
1711
- },
1712
- checkGroupsUpdate(oldSetting, newSetting, isMultiInstance) {
1713
- if (oldSetting && newSetting) {
1714
- let oldIdList = []
1715
- for (let [key, value] of Object.entries(oldSetting)) {
1716
- if (value) {
1717
- value.split(',').forEach(part => {
1718
- const [id] = part.split(':')
1719
- if (id) {
1720
- oldIdList.push(id)
1721
- }
1722
- })
1723
- }
1724
- }
1725
- const regex = /(?:O:|U:|P:|R:|T:)([^,]+)/g
1726
- let match
1727
- const newIds = []
1728
- while ((match = regex.exec(newSetting)) !== null) {
1729
- newIds.push(...match[1].split(';'))
1730
- }
1731
-
1732
- if (isMultiInstance) {
1733
- //串签的情况下可能只有顺序发生了变化
1734
- const oldStr = oldIdList.join(',')
1735
- const newStr = newIds.join(',')
1736
- return oldStr !== newStr
1737
- }else {
1738
- const allInString = oldIdList.every(item => newIds.includes(item));
1739
- const hasExtra = newIds.some(item => !oldIdList.includes(item));
1740
- return !allInString || hasExtra
1741
- }
1742
-
1743
- }
1744
- return false
1745
- },
1746
- checkTimeLimitUpdate(oldSetting, newSetting) {
1747
- if (oldSetting && newSetting) {
1748
- return oldSetting !== newSetting
1749
- }
1750
- if (!oldSetting) {
1751
- return newSetting !== 'expireTime:0D0H;warningTime:0D0H;handleType:00'
1752
- }
1753
- return false
1754
- },
1755
- readingRangeClick(item) {
1756
- let permScope = item.orgTreeType === this.defaultOrganTreeType ? this.permScope : 'all'
1757
- let orgTreeType = item.orgTreeType ? item.orgTreeType : this.defaultOrganTreeType
1758
- this.$refs.assigneeHelpBox.toggleShowHelpBox(orgTreeType, permScope, 'transferNextTask', item.id)
1759
- },
1760
- candidateGroupsReadingRangeClick(item) {
1761
- let permScope = item.orgTreeType === this.defaultOrganTreeType ? this.permScope : 'all'
1762
- let orgTreeType = item.orgTreeType ? item.orgTreeType : this.defaultOrganTreeType
1763
- this.$refs.candidateGroupsHelpBox.toggleShowHelpBox(permScope, item.candidates, orgTreeType, item.id)
1764
- },
1765
- updateCandGroups(newCandGroups, nameStr, detail, nodeId) {
1766
- let oldSettings = this.nextNodesOldSettings.filter(item => item.id === nodeId)[0]
1767
- if (JSON.stringify(oldSettings.candidates) != JSON.stringify(detail)) {
1768
- let node = this.nextNodesFormList.filter(item => item.id === nodeId)[0]
1769
- node.candidateGroups = newCandGroups
1770
- node.candidateNames = nameStr
1771
- node.candidates = detail
1772
- node.needUpdate = true
1773
- this.$forceUpdate()
1774
- }
1775
- },
1776
- updateNextNodeAssignee(selectedAssigneeId, selectedAssigneeName, nodeId) {
1777
- let oldSettings = this.nextNodesOldSettings.filter(item => item.id === nodeId)[0]
1778
- if (oldSettings.assignee != selectedAssigneeId) {
1779
- let node = this.nextNodesFormList.filter(item => item.id === nodeId)[0]
1780
- node.assignee = selectedAssigneeId
1781
- node.assigneeName = selectedAssigneeName
1782
- node.needUpdate = true
1783
- this.$forceUpdate()
1784
- }
1785
- },
1786
- },
1787
- watch: {
1788
- auditOpinionText(label) {
1789
- this.form.auditOpinion = label
1790
- },
1791
- procId(val) {
1792
- this.procId = val
1793
- this.initData()
1794
- },
1795
- }
1796
- }
1797
- </script>
1798
-
1799
- <style lang="less" scoped>
1800
- @import "./styles/css/index.less";
1801
-
1802
- /deep/ .ivu-table-row-highlight td {
1803
- background-color: #50c1ff !important;
1804
- color: #fff !important;
1805
- }
1806
-
1807
- /deep/ .ivu-card-body {
1808
- padding: 10px;
1809
- }
1810
-
1811
- .page-info /deep/ .page-body {
1812
- overflow-y: hidden;
1813
- }
1814
- </style>
1
+ <template>
2
+ <LamboPageContainer>
3
+ <template slot="page-title">
4
+ {{ title }}
5
+ </template>
6
+ <template slot="page-extend">
7
+ <slot name="return-button"></slot>
8
+ </template>
9
+ <div class="portrait-lambo-indicator-card"
10
+ :style="{float: 'left', width: isExpanded && showProcessInfo ? `calc(100% - ${portraitWidth+10}px)` : '99%'}">
11
+ <slot name="business-content">
12
+ </slot>
13
+ </div>
14
+
15
+ <a v-if="showProcessInfo" @click="isExpanded = !isExpanded" class="arrow-button-container"
16
+ :style="{right: isExpanded ? portraitWidth+10 + 'px' : '10px'}">
17
+ <Icon class="icon-class" v-if="isExpanded" type="ios-arrow-forward"/>
18
+ <Icon class="icon-class" v-if="!isExpanded" type="ios-arrow-back"/>
19
+ </a>
20
+ <transition v-if="showProcessInfo" name="draw" @before-enter="beforeFlowInfoEnter" @enter="flowInfoEnter"
21
+ @before-leave="beforeFlowInfoLeave" @leave="flowInfoLeave">
22
+ <lamboIndicatorCard v-show="isExpanded" class="portrait-lambo-indicator-card"
23
+ :style="{width: portraitWidth + 'px', float: 'right'}" :hasExtend="false">
24
+ <div slot="content-title">流程信息</div>
25
+ <a v-if="!isDetail" @click="auditShow = !auditShow">
26
+ <Title
27
+ v-if="handleButtons && (handleButtons.includes('auditOpinion') || handleButtons.includes('attachmentFile'))">
28
+ <a style="color: #989898">
29
+ <Icon v-if="auditShow" type="ios-arrow-down"/>
30
+ <Icon v-if="!auditShow" type="ios-arrow-up"/>
31
+ {{ handleName }}信息
32
+ </a>
33
+ </Title>
34
+ </a>
35
+ <transition v-if="!isDetail" name="draw" @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave"
36
+ @leave="leave">
37
+ <div class="box" v-show="auditShow">
38
+ <Form ref="auditOpinion" justify="center" :label-width="100" :model="form"
39
+ v-if="handleButtons && handleButtons.includes('auditOpinion')"
40
+ style="margin: 10px 0 0 10px;" :rules="ruleValidate">
41
+ <FormItem :label="auditOpinionTitle" prop="auditOpinion">
42
+ <AuditOpinion v-model="form.auditOpinion" :attachment-file="handleButtons.includes('attachmentFile')"
43
+ :attachmentdata="fileList" :default-audit-opinion="defaultAuditOpinion"
44
+ :smart-flow-server-context="smartFlowServerContext"></AuditOpinion>
45
+ </FormItem>
46
+ </Form>
47
+ <Form ref="auditOpinion" justify="center" :label-width="100"
48
+ v-if="handleButtons && !handleButtons.includes('auditOpinion') && handleButtons.includes('attachmentFile')"
49
+ style="margin: 10px 0 0 10px;">
50
+ <FormItem style="min-height: 70px">
51
+ <Tooltip placement="bottom" max-width="200">
52
+ <div style="font-size: smaller" slot="content">支持扩展名:.pdf .doc .docx .txt .xls .xlsx .jpg .jpeg
53
+ .png .gif
54
+ </div>
55
+ <UploadFile @upload-result="uploadFile" :multiple="true"
56
+ :oss-server-context="smartFlowServerContext"
57
+ :oss-file-put-url="ossFilePutUrl"></UploadFile>
58
+ </Tooltip>
59
+ </FormItem>
60
+ </Form>
61
+ </div>
62
+ </transition>
63
+ <a v-if="taskNode && isDetail && hisAuditOpinion[0].auditOpinion" @click="auditShow = !auditShow">
64
+ <Title
65
+ v-if="handleButtons && (handleButtons.includes('auditOpinion') || handleButtons.includes('attachmentFile'))">
66
+ <a style="color: #989898">
67
+ <Icon v-if="auditShow" type="ios-arrow-down"/>
68
+ <Icon v-if="!auditShow" type="ios-arrow-up"/>
69
+ {{ handleName }}信息
70
+ </a>
71
+ </Title>
72
+ </a>
73
+ <transition v-if="taskNode && isDetail && hisAuditOpinion[0].auditOpinion" name="draw"
74
+ @before-enter="beforeEnter"
75
+ @enter="enter" @before-leave="beforeLeave" @leave="leave">
76
+ <div class="box" v-show="auditShow">
77
+ <Form ref="auditOpinion" justify="center" :model="form"
78
+ v-if="handleButtons && handleButtons.includes('auditOpinion')"
79
+ style="margin: 10px 0 0 10px;" :rules="ruleValidate">
80
+ <FormItem style="margin-left: -60px">
81
+ <Card v-for="(item, index) in hisAuditOpinion" :key="index">
82
+ <Row style="display: flex">
83
+ <Col span="24">
84
+ <div style="word-wrap: break-word;">
85
+ <span>{{ item.auditOpinion }}</span>
86
+ <div style="position: absolute; right: 0;bottom: -18px;color: grey">{{ item.auditTime }}</div>
87
+ </div>
88
+ </Col>
89
+ </Row>
90
+ </Card>
91
+ </FormItem>
92
+ </Form>
93
+ </div>
94
+ </transition>
95
+ <a @click="historyShow = !historyShow">
96
+ <Title v-if="handleButtons && handleButtons.includes('auditHistory')">
97
+ <a style="color: #989898">
98
+ <Icon v-if="historyShow" type="ios-arrow-down"/>
99
+ <Icon v-if="!historyShow" type="ios-arrow-up"/>
100
+ {{ handleName }}记录
101
+ </a>
102
+ </Title>
103
+ </a>
104
+ <transition name="draw" @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave" @leave="leave">
105
+ <div class="box" v-show="historyShow">
106
+ <Card class="process-history" :style="processHistoryHeight" dis-hover :bordered="false"
107
+ v-if="handleButtons && handleButtons.includes('auditHistory')">
108
+ <processHistory :portrait-width="portraitWidth" :list="processHistory" :done-page="isDetail"
109
+ :push-button="pushButton"
110
+ :smart-flow-server-context="smartFlowServerContext"></processHistory>
111
+ </Card>
112
+ </div>
113
+ </transition>
114
+
115
+ <a @click="attachListShow = !attachListShow">
116
+ <Title v-if="handleButtons && handleButtons.includes('attachmentFile') && attachmentList.length > 0">
117
+ <a style="color: #989898">
118
+ <Icon v-if="attachListShow" type="ios-arrow-down"/>
119
+ <Icon v-if="!attachListShow" type="ios-arrow-up"/>
120
+ 查看附件
121
+ </a>
122
+ </Title>
123
+ </a>
124
+ <transition name="draw" @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave" @leave="leave">
125
+ <div class="box"
126
+ v-show="handleButtons && handleButtons.includes('auditHistory') && attachmentList.length > 0 && attachListShow">
127
+ <div v-for="(item, index) in attachmentList" :key="index">
128
+ <Card dis-hover class="attach-card">
129
+ <List item-layout="vertical">
130
+ <ListItem style="margin-top: -8px">
131
+ <Row style="display: flex; align-items: center;">
132
+ <!-- 左边:图片 -->
133
+ <Col span="4" style="margin-top: -25px">
134
+ <avatar v-if="item.fileType === 'image'" icon="ios-image-outline" class="attach-avatar"
135
+ style="background-color: #005aff"
136
+ :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
137
+ :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
138
+ <avatar v-else-if="item.fileType === 'doc'" icon="ios-document-outline" class="attach-avatar"
139
+ style="background-color: #005aff"
140
+ :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
141
+ :size="portraitWidth >= 600 ? 'middle' : 'small'">
142
+ </avatar>
143
+ <avatar v-else-if="item.fileType === 'xlsx'" icon="ios-document-outline" class="attach-avatar"
144
+ style="background-color: #19be6b"
145
+ :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
146
+ :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
147
+ <avatar v-else-if="item.fileType === 'pdf'" icon="ios-document-outline" class="attach-avatar"
148
+ style="background-color: #ed4014"
149
+ :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
150
+ :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
151
+ <avatar v-else icon="ios-document-outline" class="attach-avatar"
152
+ :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
153
+ :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
154
+ </Col>
155
+ <!-- 右边:附件信息 -->
156
+ <Col span="20">
157
+ <Row>
158
+ <tooltip>
159
+ <span class="attach-name-style"> {{ item.attachName }}</span>
160
+ <div slot="content" style="white-space: normal"> {{ item.attachName }}</div>
161
+ </tooltip>
162
+ </Row>
163
+ <Row style="margin-top: 3px">
164
+ <span style="color: #005aff; font-size: 13px;">{{ item.uploadUserName }}</span>
165
+ <Divider style="background-color:#808695;height: 1em;margin: 4px 9px 0 6px;"
166
+ type="vertical"/>
167
+ <span style="color: #808695;font-size: 13px"
168
+ >{{ showTaskNode(item.taskId) }}</span>
169
+ </Row>
170
+ <Row style="margin-bottom: -10px; margin-top: 10px">
171
+ <template>
172
+ <Button @click="getAttach(item)" size="small">下载</Button>
173
+ <Button v-if="item.showPreview" ghost type="primary" @click="preViewAttach(item)"
174
+ style="margin-left: 10px" size="small">预览
175
+ </Button>
176
+ </template>
177
+ </Row>
178
+ </Col>
179
+ </Row>
180
+
181
+ </ListItem>
182
+ </List>
183
+ </Card>
184
+ </div>
185
+ </div>
186
+ </transition>
187
+ <Modal title="查看附件" v-model="modalVisible" fullscreen scrollable :mask="false">
188
+ <img :src="imageUrl" v-if="modalVisible" alt="" style="width: 100%">
189
+ <div slot="footer">
190
+ <Button type="primary" @click="modalVisible = false">关闭</Button>
191
+ </div>
192
+ </Modal>
193
+ <Modal title="查看附件" v-model="modalDocx" fullscreen scrollable :mask="false">
194
+ <div ref="file"></div>
195
+ </Modal>
196
+ </lamboIndicatorCard>
197
+ </transition>
198
+
199
+ <Modal v-model="modal1" title="选择节点"
200
+ @on-cancel="cancel"
201
+ @on-ok="doPass">
202
+ <Table border
203
+ :data="allNode"
204
+ :columns="nodeColumn"
205
+ highlight-row
206
+ @on-current-change="selectNode">
207
+ </Table>
208
+ </Modal>
209
+ <assigneeBox ref="assigneeHelpBox" :execution-completed="executionCompleted"
210
+ @update-selected="handleSelectedUser" @update-next-node-assignee="updateNextNodeAssignee"
211
+ @add-multitask-instance="addMultitaskInstance" @delegate-task-assignee="delegateTask"
212
+ :data="assigneeBoxData" :smart-flow-server-context="smartFlowServerContext"
213
+ :upms-server-context="upmsServerContext"/>
214
+ <Modal ref="processTraceModal" v-model="modalBoxShow" width="1000" title="流程跟踪图">
215
+ <Workflow_Diagram ref="processTrace" :instanceId="process.instanceId" :applyId="process.applyId"
216
+ :procId="process.procId" :table-columns="diagramTableColumns" :scroll-element="scrollElement"
217
+ :tableData="process.tableData" :hisAudit="hisAudit"
218
+ :approve-detail-show-way="approveDetailShowWay"
219
+ :smart-flow-server-context="smartFlowServerContext">
220
+ </Workflow_Diagram>
221
+ </Modal>
222
+ <Modal v-model="reductionMultitaskInstanceModal" title="选择减签人员"
223
+ @on-cancel="reductionModalCancel"
224
+ @on-ok="reductionMultitaskInstance">
225
+ <Table border
226
+ :data="unapprovedAssigneeList"
227
+ :columns="reductionColumn"
228
+ @on-selection-change="selectAssignee">
229
+ </Table>
230
+ </Modal>
231
+ <Modal v-model="appointBoxShow" title="下一环节设置"
232
+ @on-cancel="appointBoxShow = false" width="600"
233
+ @on-ok="appointOk">
234
+ <Card v-for="(item,index) of nextNodesFormList" :key="index" style="margin-bottom: 10px"
235
+ v-if="handleButtons && (handleButtons.includes('appointHandler') || handleButtons.includes('appointTimeoutTime'))">
236
+ <Form ref="appointBox" justify="center" :label-width="100" :model="item"
237
+ style="margin: 10px 0 0 10px;" :rules="ruleValidate">
238
+ <div v-if="handleButtons && handleButtons.includes('appointHandler')">
239
+ <FormItem label="下一环节:">
240
+ {{ item.name }}
241
+ </FormItem>
242
+ <FormItem label="人员类型:" v-if="!item.isMultiInstance">
243
+ <RadioGroup v-model="item.actionType">
244
+ <Radio label="ASSIGNEE">办理人</Radio>
245
+ <Radio label="CAND">候选人</Radio>
246
+ </RadioGroup>
247
+ </FormItem>
248
+ <FormItem label="办理人员:" prop="assignee" v-if="!item.isMultiInstance && item.actionType === 'ASSIGNEE'">
249
+ <Input v-model="item.assigneeName"
250
+ placeholder="请选择办理人"
251
+ style="width: 68%"
252
+ icon="md-apps"
253
+ @on-focus="readingRangeClick(item)"
254
+ @on-click="readingRangeClick(item)"/>
255
+ </FormItem>
256
+ <FormItem label="候选人员:" prop="candidateGroups"
257
+ v-if="!item.isMultiInstance && item.actionType === 'CAND'">
258
+ <Input v-model="item.candidateNames"
259
+ placeholder="请选择候选人"
260
+ style="width: 68%"
261
+ icon="md-apps"
262
+ @on-focus="candidateGroupsReadingRangeClick(item)"
263
+ @on-click="candidateGroupsReadingRangeClick(item)"/>
264
+ </FormItem>
265
+ <FormItem label="候选人员:" prop="candidateGroups"
266
+ v-if="item.isMultiInstance && item.actionType === 'CAND'">
267
+ </FormItem>
268
+
269
+ <countersingersBox style="margin-bottom: 10px" v-model="item.candidateNames"
270
+ v-if="item.isMultiInstance && item.actionType === 'CAND'"
271
+ :item="item" :permScope="permScope" @update-cand-groups="updateCandGroups"
272
+ :upms-server-context="upmsServerContext"
273
+ :smart-flow-server-context="smartFlowServerContext"/>
274
+ </div>
275
+ <div v-if="handleButtons && handleButtons.includes('appointTimeoutTime')">
276
+ <Row>
277
+ <Col span="12">
278
+ <FormItem label="停留时间:">
279
+ <Input v-model="item.remainDay" style="width: 100px" type="number" :min="0"></Input>
280
+
281
+ </FormItem>
282
+ </Col>
283
+ <Col span="12">
284
+ <FormItem>
285
+ <Input v-model="item.remainTime" style="margin-left: -140px; width: 100px" type="number"
286
+ :min="0"></Input>
287
+ 小时 自动处理
288
+ </FormItem>
289
+ </Col>
290
+ </Row>
291
+ <Row>
292
+ <Col span="12">
293
+ <FormItem label="任务提前:">
294
+ <Input v-model="item.inAdvanceDay" style="width: 100px" type="number" :min="0"></Input>
295
+
296
+ </FormItem>
297
+ </Col>
298
+ <Col span="12">
299
+ <FormItem>
300
+ <Input v-model="item.inAdvanceTime" style="margin-left: -140px;width: 100px" type="number"
301
+ :min="0"></Input>
302
+ 小时 标红预警
303
+ </FormItem>
304
+ </Col>
305
+ </Row>
306
+ <FormItem label="处理方式:">
307
+ <Select v-model="item.processing" style="width:200px" placeholder="自动同意">
308
+ <Option v-for="item in handleTypeList" :value="item.value" :key="item.value">
309
+ {{ item.label }}
310
+ </Option>
311
+ </Select>
312
+ </FormItem>
313
+ </div>
314
+ </Form>
315
+ </Card>
316
+ </Modal>
317
+ <candidateGroupsHelpBox ref="candidateGroupsHelpBox" :show="candidateGroupsHelpBoxShow"
318
+ @update-cand-groups="updateCandGroups"
319
+ :upms-server-context="upmsServerContext"
320
+ :smart-flow-server-context="smartFlowServerContext"/>
321
+ <template slot="page-footer">
322
+ <div>
323
+ <slot name="footer-button"></slot>
324
+ <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo70') && !isDetail && !appointTask"
325
+ :disabled="disable" :loading="loading" @click="audit('70')">驳回到原点
326
+ </Button>
327
+ <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo40') && !isDetail && !appointTask"
328
+ :disabled="disable" :loading="loading" @click="audit('40')">驳回上一节点
329
+ </Button>
330
+ <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo90') && !isDetail && !appointTask"
331
+ :disabled="disable" :loading="loading" @click="audit('90')">驳回指定节点
332
+ </Button>
333
+ <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo80') && !isDetail && !appointTask"
334
+ :disabled="disable" :loading="loading" @click="audit('80')">跳转指定节点
335
+ </Button>
336
+ <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo82') && !isDetail && !appointTask"
337
+ :disabled="disable" :loading="loading" @click="audit('82')">指定他人处理
338
+ </Button>
339
+ <Button style="margin-left: 10px;"
340
+ v-if="curNodeType === 'userTask' && handleButtons && handleButtons.includes('delegateTask') && !isDetail && !appointTask"
341
+ :disabled="disable" :loading="loading" @click="audit('84')">委派
342
+ </Button>
343
+ <Button style="margin-left: 10px;"
344
+ v-if="curNodeType === 'multiNode' && handleButtons && handleButtons.includes('addMultitaskInstance') && !isDetail && !appointTask"
345
+ :disabled="disable" :loading="loading" @click="showUpdateMultitaskInstanceModal('81')">加签
346
+ </Button>
347
+ <Button style="margin-left: 10px;"
348
+ v-if="curNodeType === 'multiNode' && handleButtons && handleButtons.includes('reductionMultitaskInstance') && !isDetail && !appointTask"
349
+ :disabled="disable" :loading="loading" @click="showUpdateMultitaskInstanceModal('83')">减签
350
+ </Button>
351
+ <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo50') && !isDetail && !appointTask"
352
+ :disabled="disable" :loading="loading" @click="audit('50')">直接结束流程
353
+ </Button>
354
+ <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('processTrace')"
355
+ @click="processPrint">流程跟踪图
356
+ </Button>
357
+ <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo30') && !isDetail && !appointTask"
358
+ :disabled="disable" :loading="loading" type="primary" @click="audit('30')">通过
359
+ </Button>
360
+ <Button style="margin-left: 10px;" v-if="revokeDelegateTask"
361
+ :disabled="!revokeDelegateTask && disable" :loading="loading" @click="audit('62')">撤回委派
362
+ </Button>
363
+ <Button style="margin-left: 10px;" v-if="appointTask" :disabled="disable" :loading="loading" type="primary" @click="audit('61')">交回</Button>
364
+ </div>
365
+ </template>
366
+ </LamboPageContainer>
367
+ </template>
368
+
369
+
370
+ <script>
371
+ import LamboPageContainer from '@lambo-design/page-container'
372
+ import LamboIndicatorCard from '@lambo-design/indicator-card'
373
+ import Workflow_Diagram from './workflow-diagram'
374
+ import ajax from '@lambo-design/shared/utils/ajax'
375
+ import bus from '@lambo-design/shared/utils/bus'
376
+ import Title from './components/title'
377
+ import processHistory from './components/history'
378
+ import assigneeBox from './components/assignee-box'
379
+ import CandidateGroupsHelpBox from './components/candidate-groups-box'
380
+ import CountersingersBox from './components/countersigners-box'
381
+ import LamboPagingTable from '@lambo-design/paging-table'
382
+ import AuditOpinion from './components/opinion'
383
+ import axios from 'axios'
384
+ import UploadFile from '@lambo-design/upload-file'
385
+ import { timestampToTime } from '@lambo-design/shared/utils/date'
386
+
387
+ // 引入docx-preview插件
388
+ let docx = require('docx-preview')
389
+
390
+ export default {
391
+ props: {
392
+ isDetail: {
393
+ type: Boolean,
394
+ required: false,
395
+ default: false
396
+ },
397
+ width: {
398
+ type: Number,
399
+ required: false,
400
+ default: 400
401
+ },
402
+ procId: {
403
+ type: String,
404
+ required: true,
405
+ },
406
+ taskNode: {
407
+ type: String,
408
+ required: true,
409
+ },
410
+ applyId: {
411
+ type: String,
412
+ required: true,
413
+ },
414
+ taskId: {
415
+ type: String,
416
+ required: false,
417
+ default: '',
418
+ },
419
+ auditGroup: {
420
+ type: String,
421
+ required: false,
422
+ default: '',
423
+ },
424
+ defaultAuditOpinion: {
425
+ type: String,
426
+ required: false,
427
+ default: '',
428
+ },
429
+ //详情页催办按钮
430
+ pushButton: {
431
+ type: Boolean,
432
+ required: false,
433
+ default: true,
434
+ },
435
+ //流程跟踪图附件列
436
+ showAttachmentFile: {
437
+ type: Boolean,
438
+ required: false,
439
+ default: true,
440
+ },
441
+ //流程跟踪图审批详情触发方式
442
+ approveDetailShowWay: {
443
+ type: String,
444
+ required: false,
445
+ default: 'click',
446
+ },
447
+ //业务表单保存方法
448
+ businessFormSave: {
449
+ type: Function,
450
+ required: false
451
+ },
452
+ //按钮执行完毕回调方法
453
+ executionCompleted: {
454
+ type: Function,
455
+ required: false,
456
+ default: () => {
457
+ }
458
+ },
459
+ title: {
460
+ type: String,
461
+ default: '流程办理'
462
+ },
463
+ smartFlowServerContext: {
464
+ type: String,
465
+ default: '/api/smart-flow-server',
466
+ },
467
+ upmsServerContext: {
468
+ type: String,
469
+ default: '/api/upms-server',
470
+ },
471
+ },
472
+ components: {
473
+ Title,
474
+ LamboPageContainer,
475
+ Workflow_Diagram,
476
+ processHistory,
477
+ assigneeBox,
478
+ LamboPagingTable,
479
+ AuditOpinion,
480
+ LamboIndicatorCard,
481
+ UploadFile,
482
+ CandidateGroupsHelpBox,
483
+ CountersingersBox
484
+ },
485
+ data() {
486
+ return {
487
+ isExpanded: true,
488
+ showProcessInfo: true,
489
+ portraitWidth: 0,
490
+ requestSuccessCodes: [200, '200'],
491
+ auditShow: true,
492
+ historyShow: true,
493
+ attachListShow: true,
494
+ attachmentList: [],
495
+ modalVisible: false,
496
+ modalDocx: false,
497
+ imageUrl: '',
498
+ assigneeBoxData: {},
499
+ selectedUserId: '',
500
+ targetTaskNode: '',
501
+ allNode: [],
502
+ auditParams: {},
503
+ scrollElement: null,
504
+ modal1: false,
505
+ modalBoxShow: false,
506
+ reductionMultitaskInstanceModal: false,
507
+ candidateGroupsHelpBoxShow: false,
508
+ appointBoxShow: false,
509
+ autoOpenNode: '0',
510
+ unapprovedAssigneeList: [],
511
+ reductionAssigneeList: [],
512
+ nextNodesOldSettings: [],
513
+ nextNodesFormList: [],
514
+ hisNode: [],
515
+ processHistory: [],
516
+ permScope: '',
517
+ organTreeType: '00',
518
+ defaultOrganTreeType: '00',
519
+ ruleValidate: {
520
+ auditOpinion: [{ required: true, trigger: 'blur', message: '意见不能为空' }],
521
+ assignee: [{ required: true, trigger: 'blur', message: '办理人不能为空' }],
522
+ candidateGroups: [{ required: true, trigger: 'blur', message: '候选人不能为空' }],
523
+ },
524
+ form: {
525
+ auditOpinion: '',
526
+ },
527
+ loading: false,
528
+ disable: false,
529
+ revokeDelegateTask: false,
530
+ appointTask: false,
531
+ instanceId: '',
532
+ curTaskId: '',
533
+ curNodeType: 'userTask',
534
+ handleButtons: [],
535
+ handleName: '',
536
+ auditOpinionTitle: '',
537
+ auditResult: '',
538
+ curAuditGroup: '',
539
+ custChange: 'auditInfo',
540
+ auditInfo: 'auditInfo',
541
+ auditProcess: 'auditProcess',
542
+ fileList: [],
543
+ ossFilePutUrl: '/manage/oss/file/put',
544
+ hisAudit: [],
545
+ hisAuditOpinion: [{
546
+ auditOpinion: '',
547
+ auditTime: '',
548
+ }],
549
+ datas: {
550
+ orgName: '',
551
+ orgId: ''
552
+ },
553
+ editForm: {
554
+ approvalCost: '',
555
+ cost: '',
556
+ activityDate: []
557
+ },
558
+ process: {
559
+ tableData: [],
560
+ instanceId: '',
561
+ applyId: '',
562
+ procId: ''
563
+ },
564
+ handleButtonsNames: {
565
+ '30': '通过',
566
+ '70': '驳回到原点',
567
+ '40': '驳回上一节点',
568
+ '90': '驳回指定节点',
569
+ '80': '跳转指定节点',
570
+ '82': '指定他人处理',
571
+ '50': '直接结束流程',
572
+ '84': '委派任务',
573
+ '61': '交回委派任务',
574
+ '62': '撤回委派任务',
575
+ },
576
+ handleTypeList: [
577
+ {
578
+ value: '00',
579
+ label: '只预警不处理'
580
+ },
581
+ {
582
+ value: '10',
583
+ label: '自动同意'
584
+ },
585
+ {
586
+ value: '20',
587
+ label: '直接终止流程'
588
+ },
589
+ {
590
+ value: '90',
591
+ label: '自动驳回'
592
+ }
593
+ ],
594
+ }
595
+
596
+ },
597
+
598
+ mounted() {
599
+ this.getWidth()
600
+ if (this.procId) {
601
+ this.initData()
602
+ }
603
+ let modalElement = this.$refs.processTraceModal.$el
604
+ for (let i = 0; i < modalElement.children.length; i++) {
605
+ //找到滚动的目标element
606
+ let targetElement = modalElement.children[i]
607
+ if (targetElement.classList.toString().includes('-wrap')){
608
+ this.scrollElement = targetElement
609
+ break
610
+ }
611
+ }
612
+ },
613
+ computed: {
614
+ processHistoryHeight() {
615
+ let str = ''
616
+ const hasAuditOpinion = this.taskNode && this.handleButtons && this.handleButtons.includes('auditOpinion')
617
+ const hasAttachmentFile = this.handleButtons && this.handleButtons.includes('auditHistory') && this.attachmentList.length > 0
618
+ const isDetail = this.isDetail && !this.hisAuditOpinion[0].auditOpinion.length > 0
619
+ if (hasAuditOpinion && !hasAttachmentFile && !isDetail) {
620
+ str += 'height: 43vh'
621
+ } else if (hasAuditOpinion && hasAttachmentFile && !isDetail) {
622
+ str += 'height: 40vh'
623
+ } else {
624
+ str += 'height: 67vh'
625
+ }
626
+ return str
627
+ },
628
+ nodeColumn: function () {
629
+ let column = []
630
+ column.push({ title: '序号', type: 'index', width: 70, align: 'center', fixed: 'left' })
631
+ column.push({ title: '节点名称', key: 'taskName', minWidth: 150, align: 'center', fixed: 'left' })
632
+
633
+ column.push({
634
+ title: '节点状态', key: 'auditResult', minWidth: 150, align: 'center', fixed: 'left',
635
+ render: (h, params) => {
636
+ if (params.row.taskNode == this.taskNode) {
637
+ return h('div', [
638
+ h('tag', {
639
+ props: {
640
+ color: '#ff9900'
641
+ }
642
+ }, '当前节点')
643
+ ])
644
+ } else if (!params.row.auditResult) {
645
+ return h('div', [
646
+ h('tag', {
647
+ props: {
648
+ color: '#ff9900'
649
+ }
650
+ }, `未${params.row.handleName ? params.row.handleName : '审批'}`)
651
+ ])
652
+ } else {
653
+ if (params.row.auditResult == '30' && params.row.taskNode != this.taskNode) {
654
+ return h('div', [
655
+ h('tag', {
656
+ props: {
657
+ color: '#19be6b'
658
+ }
659
+ }, `已${params.row.handleName ? params.row.handleName : '审批'}通过`)
660
+ ])
661
+ } else if (params.row.auditResult == '10' && params.row.taskNode != this.taskNode) {
662
+ return h('div', [
663
+ h('tag', {
664
+ props: {
665
+ color: '#19be6b'
666
+ }
667
+ }, '已自动跳过')
668
+ ])
669
+ } else if (params.row.auditResult == '11' && params.row.taskNode != this.taskNode) {
670
+ return h('div', [
671
+ h('tag', {
672
+ props: {
673
+ color: '#19be6b'
674
+ }
675
+ }, '与上一环节办理人相同自动跳过')
676
+ ])
677
+ } else if (params.row.auditResult == '12' && params.row.taskNode != this.taskNode) {
678
+ return h('div', [
679
+ h('tag', {
680
+ props: {
681
+ color: '#19be6b'
682
+ }
683
+ }, '与发起人相同自动跳过')
684
+ ])
685
+ } else if (params.row.auditResult == '13' && params.row.taskNode != this.taskNode) {
686
+ return h('div', [
687
+ h('tag', {
688
+ props: {
689
+ color: '#19be6b'
690
+ }
691
+ }, '办理人为空自动跳过')
692
+ ])
693
+ } else if (params.row.auditResult == '14' && params.row.taskNode != this.taskNode) {
694
+ return h('div', [
695
+ h('tag', {
696
+ props: {
697
+ color: '#19be6b'
698
+ }
699
+ }, '符合流程变量条件自动跳过')
700
+ ])
701
+ } else if (params.row.auditResult == '40' && params.row.taskNode != this.taskNode) {
702
+ return h('div', [
703
+ h('tag', {
704
+ props: {
705
+ color: '#ed4014'
706
+ }
707
+ }, '已驳回到上一节点')
708
+ ])
709
+ } else if (params.row.auditResult == '60' && params.row.taskNode != this.taskNode) {
710
+ return h('div', [
711
+ h('tag', {
712
+ props: {
713
+ color: '#ed4014'
714
+ }
715
+ }, '已撤回')
716
+ ])
717
+ } else if (params.row.auditResult == '61' && params.row.taskNode != this.taskNode) {
718
+ return h('div', [
719
+ h('tag', {
720
+ props: {
721
+ color: '#19be6b'
722
+ }
723
+ }, '已交回委派任务')
724
+ ])
725
+ } else if (params.row.auditResult == '62' && params.row.taskNode != this.taskNode) {
726
+ return h('div', [
727
+ h('tag', {
728
+ props: {
729
+ color: '#ed4014'
730
+ }
731
+ }, '委派任务已撤回')
732
+ ])
733
+ } else if (params.row.auditResult == '80' && params.row.taskNode != this.taskNode) {
734
+ return h('div', [
735
+ h('tag', {
736
+ props: {
737
+ color: '#19be6b'
738
+ }
739
+ }, '已跳转到指定节点')
740
+ ])
741
+ } else if (params.row.auditResult == '90' && params.row.taskNode != this.taskNode) {
742
+ return h('div', [
743
+ h('tag', {
744
+ props: {
745
+ color: '#19be6b'
746
+ }
747
+ }, '已驳回到指定节点')
748
+ ])
749
+ }
750
+ }
751
+ }
752
+ })
753
+ column.push({
754
+ title: '操作', width: 100, align: 'center',
755
+ render: (h, params) => {
756
+ return h('div', [
757
+ h('Button', {
758
+ props: {
759
+ type: 'primary',
760
+ size: 'small'
761
+ },
762
+ style: {
763
+ marginRight: '5px'
764
+ },
765
+ on: {
766
+ click: () => {
767
+ this.selectNode(params.row)
768
+ }
769
+ }
770
+ }, '选择')
771
+ ])
772
+ },
773
+ })
774
+ return column
775
+ },
776
+ reductionColumn: function () {
777
+ let column = []
778
+ column.push({ title: '#', key: 'selectId', type: 'selection', align: 'center', width: 55 })
779
+ column.push({ title: '账号', key: 'auditId', align: 'center' })
780
+ column.push({ title: '姓名', key: 'auditName', align: 'center' })
781
+ return column
782
+ },
783
+ diagramTableColumns: function () {
784
+ let column = []
785
+ column.push({ title: '序号', type: 'index', width: 60 })
786
+ column.push({ title: `${this.handleName}节点`, key: 'taskName', minWidth: 130 })
787
+ column.push({ title: `${this.handleName}人`, key: 'auditName', minWidth: 150, tooltip: true })
788
+ column.push({
789
+ title: `${this.handleName}结果`, key: 'auditResult', minWidth: 150, align: 'center',
790
+ render: (h, { row, column, index }) => {
791
+ let label = ''
792
+ let tagColor = ''
793
+ if (row.auditResult == '00') {
794
+ label = '流程发起'
795
+ tagColor = 'green' // 绿色
796
+ } else if (row.auditResult == '10') {
797
+ label = '自动跳过'
798
+ tagColor = 'green' // 绿色
799
+ } else if (row.auditResult == '11') {
800
+ label = '与上一环节办理人相同自动跳过'
801
+ tagColor = 'green' // 绿色
802
+ } else if (row.auditResult == '12') {
803
+ label = '与发起人相同自动跳过'
804
+ tagColor = 'green' // 绿色
805
+ } else if (row.auditResult == '13') {
806
+ label = '办理人为空自动跳过'
807
+ tagColor = 'green' // 绿色
808
+ } else if (row.auditResult == '14') {
809
+ label = '符合流程变量条件自动跳过'
810
+ tagColor = 'green' // 绿色
811
+ } else if (row.auditResult == '30') {
812
+ label = '通过'
813
+ tagColor = 'green' // 绿色
814
+ } else if (row.auditResult == '40') {
815
+ label = '驳回到上一级'
816
+ tagColor = 'volcano' // 火红色
817
+ } else if (row.auditResult == '50') {
818
+ label = '驳回到原点'
819
+ tagColor = 'red' // 红色
820
+ } else if (row.auditResult == '51') {
821
+ label = '流程终止'
822
+ tagColor = 'purple' // 紫色
823
+ } else if (row.auditResult == '60') {
824
+ label = '撤回'
825
+ tagColor = 'blue' // 蓝色
826
+ } else if (row.auditResult == '61') {
827
+ label = '交回委派任务'
828
+ tagColor = 'green' // 绿色
829
+ } else if (row.auditResult == '62') {
830
+ label = '委派任务被撤回'
831
+ tagColor = 'blue' // 蓝色
832
+ } else if (row.auditResult == '80') {
833
+ label = '跳转到指定节点'
834
+ tagColor = 'cyan' // 青色
835
+ } else if (row.auditResult == '82') {
836
+ label = '指定他人处理'
837
+ tagColor = 'cyan' // 青色
838
+ } else if (row.auditResult == '83') {
839
+ label = '会签减签'
840
+ tagColor = 'red' // 红色
841
+ } else if (row.auditResult == '90') {
842
+ label = '驳回到指定节点'
843
+ tagColor = 'magenta' // 品红色
844
+ } else {
845
+ label = '待审核'
846
+ tagColor = 'orange' // 默认橙色
847
+ }
848
+ return h('Tag', {
849
+ props: {
850
+ color: tagColor,
851
+ value: row.auditResult
852
+ }
853
+ }, label)
854
+ }
855
+ })
856
+ column.push({
857
+ title: `${this.handleName}时间`, key: 'auditTime', minWidth: 150,
858
+ render: (h, { row }) => {
859
+ const displayDate = row.auditDate
860
+ return h('span', displayDate)
861
+ }
862
+ })
863
+ column.push({
864
+ title: `${this.handleName}意见`, key: 'auditComment', minWidth: 180, tooltip: true,
865
+ render: (h, { row, column, index }) => {
866
+ let label = ''
867
+ if (row.auditComment == '' || row.auditComment == null) {
868
+ label = '无'
869
+ } else {
870
+ label = row.auditComment
871
+ }
872
+ return h('Label', {
873
+ props: {
874
+ value: row.auditComment
875
+ }
876
+ }, label)
877
+ }
878
+ })
879
+ if (this.showAttachmentFile) {
880
+ column.push({
881
+ title: `附件`, key: 'fileList', minWidth: 200,
882
+ render: (h, { row }) => {
883
+ if (!row.fileList || row.fileList.length === 0) {
884
+ return h('span', '无') // 如果没有附件,显示“无”
885
+ }
886
+
887
+ //显示所有附件
888
+ return h('div', row.fileList.map(file => {
889
+ return h('a', {
890
+ style: {
891
+ display: 'block',
892
+ marginTop: '5px',
893
+ marginRight: '5px',
894
+ whiteSpace: 'nowrap',
895
+ overflow: 'hidden',
896
+ textOverflow: 'ellipsis',
897
+ maxWidth: '100px',
898
+ },
899
+ attrs: {
900
+ title: file.attachName // 鼠标悬停时显示完整名称
901
+ },
902
+ on: {
903
+ click: () => {
904
+ this.getAttach(file)
905
+ }
906
+ },
907
+ }, file.attachName)
908
+ }))
909
+ }
910
+ })
911
+ }
912
+
913
+ return column
914
+ },
915
+ },
916
+ provide() {
917
+ return {
918
+ toBeDoneListDoSearch: this.doSearch
919
+ }
920
+ },
921
+ methods: {
922
+ getWidth() {
923
+ if (this.width && this.width < 400) {
924
+ this.portraitWidth = 400
925
+ }
926
+ this.portraitWidth = this.width
927
+ },
928
+ initData() {
929
+ if (!this.isDetail) {
930
+ this.getTodoTask()
931
+ } else {
932
+ this.getDoneTask()
933
+ }
934
+ this.getHandleButtons()
935
+ },
936
+ getTodoTask() {
937
+ const self = this
938
+ let param = {
939
+ procId: this.procId,
940
+ applyId: this.applyId,
941
+ taskNode: this.taskNode,
942
+ taskId: this.taskId,
943
+ auditGroup: this.auditGroup
944
+ }
945
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/list', { params: param }).then(function (resp) {
946
+ if (resp.data.code === '200') {
947
+ let todoData = resp.data.data.rows[0]
948
+ self.curTaskId = todoData.taskId
949
+ self.instanceId = todoData.procInstanceId
950
+ self.curAuditGroup = todoData.auditGroup
951
+ self.revokeDelegateTask = todoData.delegateStatus ? todoData.delegateStatus === '10' : false
952
+ self.appointTask = todoData.delegateStatus ? todoData.delegateStatus === '20' : false
953
+ if (self.revokeDelegateTask) self.disable = true
954
+ let procType = todoData.procType
955
+ ajax.get(self.smartFlowServerContext + '/manage/processType/lists?proType=' + procType)
956
+ .then(resp => {
957
+ let data = resp.data.data.rows
958
+ self.permScope = data[0].permScope
959
+ self.defaultOrganTreeType = data[0].organTreeType ? data[0].organTreeType : '00'
960
+ self.getNodeOrganTreeType(procType)
961
+ }).catch(err => {
962
+ console.log(err)
963
+ })
964
+ self.getAttachList(self.curTaskId)
965
+ self.getHisAudit(self.curTaskId)
966
+ self.getProcessHistory(self.curTaskId)
967
+ } else {
968
+ self.$Message.error(resp.data.message)
969
+ }
970
+ }).catch((err) => {
971
+ console.log(err)
972
+ })
973
+ },
974
+ getNodeOrganTreeType(procType) {
975
+ const self = this
976
+ let param = {
977
+ procType: procType,
978
+ procId: this.procId,
979
+ taskNode: this.taskNode
980
+ }
981
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/getNodeOrganTreeType', { params: param }).then(function (resp) {
982
+ if (resp.data.code === '200') {
983
+ self.organTreeType = resp.data.data ? resp.data.data : self.defaultOrganTreeType
984
+ } else {
985
+ self.$Message.error(resp.data.message)
986
+ }
987
+ }).catch((err) => {
988
+ console.log(err)
989
+ })
990
+ },
991
+ getDoneTask() {
992
+ const self = this
993
+ let param = {
994
+ procId: this.procId,
995
+ applyId: this.applyId,
996
+ taskNode: this.taskNode,
997
+ taskId: this.taskId,
998
+ auditGroup: this.auditGroup
999
+ }
1000
+ ajax.get(self.smartFlowServerContext + '/manage/processDone/getDoneDetail', { params: param }).then(function (resp) {
1001
+ if (resp.data.code === '200') {
1002
+ let rows = resp.data.data.rows
1003
+ if (rows.length > 0) {
1004
+ self.curAuditGroup = rows[0].auditGroup
1005
+ self.hisAuditOpinion = []
1006
+ let taskList = resp.data.data.rows
1007
+ taskList.forEach(item => {
1008
+ self.hisAuditOpinion.push({
1009
+ auditOpinion: item.auditComment,
1010
+ auditTime: timestampToTime(item.auditDate)
1011
+ })
1012
+ })
1013
+ self.curTaskId = taskList[0].taskId
1014
+ self.instanceId = taskList[0].procInstanceId
1015
+ } else {
1016
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/list', { params: param }).then(function (todoResp) {
1017
+ if (todoResp.data.code === '200') {
1018
+ self.curTaskId = todoResp.data.data.rows[0].taskId
1019
+ self.instanceId = todoResp.data.data.rows[0].procInstanceId
1020
+ self.curAuditGroup = todoResp.data.data.rows[0].auditGroup
1021
+ } else {
1022
+ self.$Message.error(todoResp.data.message)
1023
+ }
1024
+ }).catch((err) => {
1025
+ console.log(err)
1026
+ })
1027
+ }
1028
+ self.getAttachList(self.curTaskId)
1029
+ self.getHisAudit(self.curTaskId)
1030
+ self.getProcessHistory(self.curTaskId)
1031
+ } else {
1032
+ self.$Message.error(resp.data.message)
1033
+ }
1034
+ }).catch((err) => {
1035
+ console.log(err)
1036
+ })
1037
+ },
1038
+ getHandleButtons() {
1039
+ const self = this
1040
+ let param = {
1041
+ procId: this.procId,
1042
+ taskNode: this.taskNode
1043
+ }
1044
+ ajax.post(self.smartFlowServerContext + '/manage/approvalCenter/getNodeData', param).then(function (resp) {
1045
+ if (resp.data.code === '200') {
1046
+ self.handleButtons = resp.data.data[0].handleButtons
1047
+ if (resp.data.data[0].hasOwnProperty('isSequential')) {
1048
+ self.curNodeType = resp.data.data[0].isSequential ? 'sequentialMultiNode' : 'multiNode'
1049
+ }
1050
+ self.handleName = resp.data.data[0].handleName ? resp.data.data[0].handleName : '审批'
1051
+ self.auditOpinionTitle = resp.data.data[0].handleName ? resp.data.data[0].handleName + '意见' : '审批意见'
1052
+ if (!self.handleButtons || (!self.handleButtons.includes('auditOpinion') && !self.handleButtons.includes('attachmentFile') && !self.handleButtons.includes('auditHistory'))) {
1053
+ self.showProcessInfo = false
1054
+ }
1055
+ } else {
1056
+ self.$Message.error(resp.data.message)
1057
+ }
1058
+ }).catch((err) => {
1059
+ console.log(err)
1060
+ })
1061
+ },
1062
+ getNextNodes() {
1063
+ const self = this
1064
+ self.nextNodesFormList = []
1065
+ self.nextNodesOldSettings = []
1066
+ let param = {
1067
+ procId: this.procId,
1068
+ taskNode: this.taskNode
1069
+ }
1070
+ ajax.post(self.smartFlowServerContext + '/manage/processTodo/getNextNodes', param).then(function (resp) {
1071
+ if (resp.data.code === '200') {
1072
+ let nextNodeForm = {}
1073
+ let nextNodeOldForm = {}
1074
+ let data = resp.data.data
1075
+ for (let i = 0; i < data.length; i++) {
1076
+ nextNodeOldForm = {
1077
+ id: data[i].id,
1078
+ assignee: data[i].assignee ? data[i].assignee.id : '',
1079
+ timeLimit: data[i].timeLimit,
1080
+ }
1081
+ nextNodeForm = {
1082
+ id: data[i].id,
1083
+ name: data[i].name,
1084
+ orgTreeType: data[i].orgTreeType,
1085
+ assignee: data[i].assignee ? data[i].assignee.id : '',
1086
+ assigneeName: data[i].assignee ? data[i].assignee.name : '',
1087
+ candidateGroups: '',
1088
+ isMultiInstance: data[i].isMultiInstance,
1089
+ actionType: 'ASSIGNEE',
1090
+ remainDay: 0,
1091
+ remainTime: 0,
1092
+ inAdvanceDay: 0,
1093
+ inAdvanceTime: 0,
1094
+ processing: '00'
1095
+ }
1096
+ //显示具体候选人信息
1097
+ if (data[i].candidateGroups) {
1098
+ nextNodeForm.actionType = 'CAND'
1099
+ let names = []
1100
+ let candidates = {}
1101
+ for (let groupName in data[i].candidateGroups) {
1102
+ if (data[i].candidateGroups.hasOwnProperty(groupName)) {
1103
+ let group = data[i].candidateGroups[groupName]
1104
+ group.forEach(item => {
1105
+ names.push(item.name)
1106
+ })
1107
+ candidates[groupName] = group.map(item => item.id + ':' + item.name).join(',')
1108
+ }
1109
+ }
1110
+ nextNodeForm.candidateNames = names.join(',')
1111
+ nextNodeForm.candidates = candidates
1112
+ nextNodeOldForm.candidates = candidates
1113
+ }
1114
+ if (data[i].timeLimit) {
1115
+ let expireTime = data[i].timeLimit.split(';')[0].split(':')[1]
1116
+ let warningTime = data[i].timeLimit.split(';')[1].split(':')[1]
1117
+ let handleType = data[i].timeLimit.split(';')[2].split(':')[1]
1118
+ let days = expireTime.slice(0, expireTime.indexOf('D')) //过期天
1119
+ let hourOfDay = expireTime.slice(expireTime.indexOf('D') + 1, expireTime.indexOf('H')) //过期小时
1120
+ let daysWarn = warningTime.slice(0, warningTime.indexOf('D')) //警告天
1121
+ let hourOfDayWarn = warningTime.slice(warningTime.indexOf('D') + 1, warningTime.indexOf('H')) //警告小时
1122
+ nextNodeForm.remainDay = parseInt(days)
1123
+ nextNodeForm.remainTime = parseInt(hourOfDay)
1124
+ nextNodeForm.inAdvanceDay = parseInt(daysWarn)
1125
+ nextNodeForm.inAdvanceTime = parseInt(hourOfDayWarn)
1126
+ nextNodeForm.processing = handleType
1127
+ }
1128
+ self.nextNodesFormList.push(nextNodeForm)
1129
+ self.nextNodesOldSettings.push(nextNodeOldForm)
1130
+ }
1131
+ } else {
1132
+ self.$Message.error(resp.data.message)
1133
+ }
1134
+ }).catch((err) => {
1135
+ console.log(err)
1136
+ })
1137
+ },
1138
+ getAttachList(taskId) {
1139
+ const self = this
1140
+ const param = {
1141
+ taskId: taskId,
1142
+ procId: this.procId,
1143
+ applyId: this.applyId
1144
+ }
1145
+ ajax.get(self.smartFlowServerContext + '/manage/processDone/getAttachmentList', { params: param }).then(function (resp) {
1146
+ self.attachmentList = resp.data.data.rows
1147
+ self.attachmentList.forEach(item => {
1148
+ const index = item.fileName.lastIndexOf('.')
1149
+ const fileType = item.fileName.substr(index + 1).toLowerCase()
1150
+ const imageList = ['jpg', 'gif', 'png', 'svg']
1151
+ const docList = ['doc', 'docx']
1152
+ const zipList = ['rar', 'zip']
1153
+ const typeList = ['jpg', 'gif', 'png', 'docx']
1154
+ item.fileType = imageList.indexOf(fileType) !== -1 ? 'image' : docList.indexOf(fileType) !== -1 ? 'doc' : zipList.indexOf(fileType) !== -1 ? 'zip' : fileType
1155
+ item.showPreview = typeList.indexOf(fileType) !== -1
1156
+ })
1157
+ }).catch(err => {
1158
+ console.log(err)
1159
+ })
1160
+ },
1161
+ getHisAudit(taskId) {
1162
+ let self = this
1163
+ let params = {
1164
+ applyId: self.applyId,
1165
+ instanceId: self.instanceId,
1166
+ procId: self.procId,
1167
+ taskId: taskId
1168
+ }
1169
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/getHisAudit', { params: params }).then(function (resp) {
1170
+ if (resp.data.code === '200') {
1171
+ self.hisAudit = resp.data.data
1172
+ let uniqueDataMap = {}
1173
+ self.hisAudit.forEach((item) => {
1174
+ uniqueDataMap[item['taskNode']] = item
1175
+ })
1176
+ self.hisNode = Object.values(uniqueDataMap)
1177
+
1178
+ }
1179
+ })
1180
+ },
1181
+ getProcessHistory(taskId) {
1182
+ let self = this
1183
+ let params = {
1184
+ applyId: self.applyId,
1185
+ instanceId: self.instanceId,
1186
+ procId: self.procId,
1187
+ taskId: taskId
1188
+ }
1189
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/getProcessHis', { params: params }).then(function (resp) {
1190
+ if (resp.data.code === '200') {
1191
+ self.processHistory = resp.data.data
1192
+ }
1193
+ })
1194
+ },
1195
+
1196
+ audit: function (auditResult) {
1197
+ let self = this
1198
+ self.auditResult = auditResult
1199
+ self.submit()
1200
+ },
1201
+ submit() {
1202
+ let self = this
1203
+ self.auditParams = {
1204
+ procId: self.procId,
1205
+ applyId: self.applyId,
1206
+ taskId: self.curTaskId,
1207
+ auditOpinion: self.form.auditOpinion,
1208
+ fileListStr: JSON.stringify(self.fileList),
1209
+ auditResult: self.auditResult,
1210
+ params: JSON.stringify(self.datas),
1211
+ targetTaskNode: self.targetTaskNode,
1212
+ selectedUserId: self.selectedUserId,
1213
+ }
1214
+ if (self.auditResult == '' || self.auditResult == null) {
1215
+ self.$Message.error(`请选择${self.handleName}结果!`)
1216
+ return
1217
+ }
1218
+ if (self.form.auditOpinion == '' || self.form.auditOpinion == null) {
1219
+ if (self.auditResult === '30') {
1220
+ self.auditParams.auditOpinion = '通过'
1221
+ self.businessFormSave ? self.businessFormSave(self.handleSaveResult) : self.handleSaveResult(true)
1222
+ return
1223
+ }
1224
+ if ((!self.handleButtons || self.handleButtons.includes('auditOpinion')) && self.auditResult !== '84') {
1225
+ self.$Message.error(`请输入${self.handleName}意见!`)
1226
+ return
1227
+ } else {
1228
+ self.auditParams.auditOpinion = self.handleButtonsNames[self.auditResult]
1229
+ }
1230
+ }
1231
+ self.businessFormSave ? self.businessFormSave(self.handleSaveResult) : self.handleSaveResult(true)
1232
+ },
1233
+ handleSaveResult(saveResult, businessParams) {
1234
+ if (saveResult) {
1235
+ this.executeButtonAction(businessParams)
1236
+ } else {
1237
+ console.error('保存失败')
1238
+ }
1239
+ },
1240
+ executeButtonAction(businessParams) {
1241
+ const self = this
1242
+ if (businessParams) {
1243
+ Object.assign(self.datas, businessParams)
1244
+ self.auditParams.params = JSON.stringify(self.datas)
1245
+ }
1246
+ let auditResult = {
1247
+ code: self.auditResult,
1248
+ name: self.handleButtonsNames[self.auditResult]
1249
+ }
1250
+ if (self.auditResult === '82') {
1251
+ //指定他人处理
1252
+ self.assigneeBoxData = self.auditParams
1253
+ self.assigneeBoxData.auditResultName = self.handleButtonsNames[self.auditResult]
1254
+ self.assigneeBoxData.instanceId = self.instanceId
1255
+ self.$refs.assigneeHelpBox.toggleShowHelpBox(self.organTreeType, '', 'transferCurTask')
1256
+ } else if (self.auditResult === '84') {
1257
+ //委派任务
1258
+ self.$refs.assigneeHelpBox.toggleShowHelpBox(self.organTreeType, '', 'delegateTask')
1259
+ } else if (self.auditResult === '62') {
1260
+ //撤回委派任务
1261
+ ajax.post(self.smartFlowServerContext + '/manage/processTodo/audit', self.auditParams).then(resp => {
1262
+ let result = resp.data
1263
+ if (result.code == '200') {
1264
+ self.loading = false
1265
+ self.disable = false
1266
+ self.revokeDelegateTask = false
1267
+ self.$Message.success('撤回委派成功')
1268
+ } else {
1269
+ self.loading = false
1270
+ self.disable = false
1271
+ self.$Message.error(result.message)
1272
+ }
1273
+ })
1274
+ } else if (self.auditResult === '61') {
1275
+ //交回委派任务
1276
+ ajax.post(self.smartFlowServerContext + '/manage/processTodo/audit', self.auditParams).then(resp => {
1277
+ let result = resp.data
1278
+ if (result.code == '200') {
1279
+ self.loading = false
1280
+ self.disable = false
1281
+ self.$Message.success('交回委派任务成功')
1282
+ if (result.data) {
1283
+ let taskIds = result.data.id ? result.data.id : result.data.map(item => item.id).join(',')
1284
+ setTimeout(() => {
1285
+ self.executionCompleted(true, result.data.id ? result.data.processInstanceId : result.data[0].processInstanceId, taskIds, auditResult, self.curTaskId)
1286
+ }, 1000)
1287
+ }
1288
+ } else {
1289
+ self.loading = false
1290
+ self.disable = false
1291
+ self.$Message.error(result.message)
1292
+ }
1293
+ })
1294
+ } else if (self.auditResult === '80') {
1295
+ //跳转到后序指定节点
1296
+ self.getNodesBehind()
1297
+ } else if (self.auditResult === '90') {
1298
+ //驳回到前序指定节点
1299
+ self.getAllPreNodes()
1300
+ } else if (self.auditResult === '40') {
1301
+ //驳回到上一级
1302
+ self.loading = true
1303
+ self.disable = true
1304
+ let url = self.smartFlowServerContext + '/manage/processTodo/getPreNode'
1305
+ ajax.post(url, self.auditParams).then(function (resp) {
1306
+ let result = resp.data
1307
+ if (result.code == '30013' || result.code == '30014') {
1308
+ //前序节点为子流程或当前节点为子流程第一个节点不可驳回上一级节点
1309
+ self.$Message.warning(result.message)
1310
+ //避免未提示消息直接回调
1311
+ setTimeout(() => {
1312
+ self.executionCompleted(false, null, null, auditResult, self.curTaskId)
1313
+ }, 1000)
1314
+ } else if (result.code == '30010') {
1315
+ self.$Modal.confirm({
1316
+ title: '提示',
1317
+ content: result.message,
1318
+ onOk: () => {
1319
+ self.auditParams.auditResult = '70'
1320
+ let url = self.smartFlowServerContext + '/manage/processTodo/audit'
1321
+ ajax.post(url, self.auditParams).then(function (resp) {
1322
+ let result = resp.data
1323
+ if (result.code == '200') {
1324
+ self.loading = false
1325
+ self.disable = false
1326
+ self.$Message.success(result.message)
1327
+ //后端没有返回数据
1328
+ setTimeout(() => {
1329
+ self.executionCompleted(true, null, null, auditResult, self.curTaskId)
1330
+ }, 1000)
1331
+ bus.$emit('triggerTimer')
1332
+ } else {
1333
+ self.loading = false
1334
+ self.disable = false
1335
+ self.$Message.error(result.message)
1336
+ setTimeout(() => {
1337
+ self.executionCompleted(false, null, null, auditResult, self.curTaskId)
1338
+ }, 1000)
1339
+ }
1340
+ bus.$emit('triggerTimer')
1341
+ })
1342
+ },
1343
+ onCancel: () => {
1344
+ self.loading = false
1345
+ self.disable = false
1346
+ }
1347
+ })
1348
+ } else if (result.code == '10012') {
1349
+ // 数据同步
1350
+ self.loading = false
1351
+ self.disable = false
1352
+ self.$Message.warning(result.message)
1353
+ setTimeout(() => {
1354
+ self.executionCompleted(true, null, null, auditResult, self.curTaskId)
1355
+ }, 1000)
1356
+ } else {
1357
+ self.loading = true
1358
+ self.disable = true
1359
+ let url = self.smartFlowServerContext + '/manage/processTodo/audit'
1360
+ ajax.post(url, self.auditParams).then(function (resp) {
1361
+ let result = resp.data
1362
+ if (result.code == '200') {
1363
+ self.loading = false
1364
+ self.disable = false
1365
+ self.$Message.success(result.message)
1366
+ setTimeout(() => {
1367
+ if (result.data) {
1368
+ let taskIds = result.data.map(item => item.id).join(',')
1369
+ self.executionCompleted(true, result.data[0].processInstanceId, taskIds, auditResult, self.curTaskId)
1370
+ } else {
1371
+ self.executionCompleted(true, null, null, auditResult, self.curTaskId)
1372
+ }
1373
+ }, 1000)
1374
+ } else {
1375
+ self.loading = false
1376
+ self.disable = false
1377
+ self.$Message.error(result.message)
1378
+ setTimeout(() => {
1379
+ self.executionCompleted(false, null, null, auditResult, self.curTaskId)
1380
+ }, 1000)
1381
+ }
1382
+ bus.$emit('triggerTimer')
1383
+ })
1384
+ }
1385
+ })
1386
+ } else {
1387
+ if (self.auditResult === '30' && (!self.handleButtons || self.handleButtons.includes('appointHandler') || self.handleButtons.includes('appointTimeoutTime'))) {
1388
+ self.getNextNodes()
1389
+ self.appointBoxShow = true
1390
+ } else {
1391
+ self.doPass()
1392
+ }
1393
+ }
1394
+ },
1395
+ doPass() {
1396
+ let self = this
1397
+ this.modal = false
1398
+ let auditResult = {
1399
+ code: self.auditResult,
1400
+ name: self.handleButtonsNames[self.auditResult]
1401
+ }
1402
+ if (self.auditResult === '82' && (self.targetTaskNode == '' || self.targetTaskNode == null)) {
1403
+ self.auditResult = ''
1404
+ self.$Message.error(`请选择${self.handleName}节点!`)
1405
+ } else {
1406
+ self.loading = true
1407
+ self.disable = true
1408
+ self.auditParams.targetTaskNode = self.targetTaskNode
1409
+ let url = self.smartFlowServerContext + '/manage/processTodo/audit'
1410
+ ajax.post(url, self.auditParams).then(function (resp) {
1411
+ let result = resp.data
1412
+ if (result.code == '200') {
1413
+ self.loading = false
1414
+ self.disable = false
1415
+ self.$Message.success(result.message ? result.message : `${self.handleName}成功`)
1416
+ if (result.data) {
1417
+ let taskIds = result.data.id ? result.data.id : result.data.map(item => item.id).join(',')
1418
+ setTimeout(() => {
1419
+ self.executionCompleted(true, result.data.id ? result.data.processInstanceId : result.data[0].processInstanceId, taskIds, auditResult, self.curTaskId)
1420
+ }, 1000)
1421
+ } else {
1422
+ setTimeout(() => {
1423
+ self.executionCompleted(true, null, null, auditResult, self.curTaskId)
1424
+ }, 1000)
1425
+ }
1426
+ } else if (result.code == '10012') {
1427
+ // 数据同步
1428
+ self.loading = false
1429
+ self.disable = false
1430
+ self.$Message.warning(result.message)
1431
+ setTimeout(() => {
1432
+ self.executionCompleted(true, null, null, auditResult, self.curTaskId)
1433
+ }, 1000)
1434
+ } else if (result.code == '20002') {
1435
+ // 流程结束
1436
+ self.loading = false
1437
+ self.disable = false
1438
+ self.$Message.success(result.message)
1439
+ setTimeout(() => {
1440
+ self.executionCompleted(true, '流程已结束', '流程已结束', auditResult, self.curTaskId)
1441
+ }, 1000)
1442
+ } else {
1443
+ self.loading = false
1444
+ self.disable = false
1445
+ self.$Message.error(result.message ? result.message : `${self.handleName}失败`)
1446
+ setTimeout(() => {
1447
+ self.executionCompleted(false, null, null, auditResult, self.curTaskId)
1448
+ }, 1000)
1449
+ }
1450
+ bus.$emit('triggerTimer')
1451
+ })
1452
+ }
1453
+ },
1454
+ showUpdateMultitaskInstanceModal(updateType) {
1455
+ const self = this
1456
+ if (updateType === '81') {
1457
+ this.$refs.assigneeHelpBox.toggleShowHelpBox(this.organTreeType, '', 'addMultitaskInstance')
1458
+ } else if (updateType === '83') {
1459
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/getUnapprovedListOfMultiNode?taskId=' + self.curTaskId).then(function (resp) {
1460
+ if (resp.data.code === '200') {
1461
+ self.unapprovedAssigneeList = resp.data.data
1462
+ self.reductionMultitaskInstanceModal = true
1463
+ } else {
1464
+ self.$Message.error(resp.data.message)
1465
+ }
1466
+ }).catch(err => {
1467
+ console.log(err)
1468
+ })
1469
+ }
1470
+ },
1471
+ updateMultitaskInstance(updateType, assignees) {
1472
+ const self = this
1473
+ self.loading = true
1474
+ self.disable = true
1475
+ let param = {
1476
+ taskId: self.curTaskId,
1477
+ applyId: self.applyId,
1478
+ assignees: assignees,
1479
+ updateType: updateType
1480
+ }
1481
+ ajax.post(self.smartFlowServerContext + '/manage/processTodo/updateMultitaskInstance', param).then(resp => {
1482
+ let result = resp.data
1483
+ if (result.code == '200') {
1484
+ self.loading = false
1485
+ self.disable = false
1486
+ self.$Message.success(result.message)
1487
+ } else {
1488
+ self.loading = false
1489
+ self.disable = false
1490
+ self.$Message.error(result.message)
1491
+ }
1492
+ }).catch(err => {
1493
+ console.log(err)
1494
+ })
1495
+ },
1496
+ //委派
1497
+ delegateTask(assignee) {
1498
+ const self = this
1499
+ if (!assignee){
1500
+ self.$Message.error('请选择加签人员')
1501
+ return
1502
+ }
1503
+ let auditResult = {
1504
+ code: self.auditResult,
1505
+ name: self.handleButtonsNames[self.auditResult]
1506
+ }
1507
+ self.auditParams.selectedUserId = assignee
1508
+ ajax.post(self.smartFlowServerContext + '/manage/processTodo/audit', self.auditParams).then(resp => {
1509
+ let result = resp.data
1510
+ if (result.code == '200') {
1511
+ self.loading = false
1512
+ self.disable = false
1513
+ self.$Message.success('委派成功')
1514
+ if (result.data) {
1515
+ let taskIds = result.data.id ? result.data.id : result.data.map(item => item.id).join(',')
1516
+ setTimeout(() => {
1517
+ self.executionCompleted(true, result.data.id ? result.data.processInstanceId : result.data[0].processInstanceId, taskIds, auditResult, self.curTaskId)
1518
+ }, 1000)
1519
+ }
1520
+ } else {
1521
+ self.loading = false
1522
+ self.disable = false
1523
+ self.$Message.error(result.message)
1524
+ }
1525
+ }).catch(err => {
1526
+ console.log(err)
1527
+ })
1528
+ },
1529
+ //加签
1530
+ addMultitaskInstance(assingeeList) {
1531
+ const assingees = assingeeList.join(',')
1532
+ this.updateMultitaskInstance('81', assingees)
1533
+ },
1534
+ //减签
1535
+ reductionMultitaskInstance() {
1536
+ if (this.reductionAssigneeList.length === 0) {
1537
+ this.$Message.error('请选择减签人员')
1538
+ return
1539
+ }
1540
+ const assingees = this.reductionAssigneeList.map(item => item.auditId).join(',')
1541
+ this.updateMultitaskInstance('83', assingees)
1542
+ },
1543
+
1544
+ doSearch() {
1545
+ //不需要实现,是子组件assigneeBox要求使用父组件的这个方法
1546
+ },
1547
+ tabsChange(tab) {
1548
+ console.log(tab)
1549
+ },
1550
+ getAttach(row) {
1551
+ window.open(this.smartFlowServerContext + '/manage/oss/file/get/' + row.fileId, '_blank')
1552
+ },
1553
+ preViewAttach(row) {
1554
+ let reg = /\.(gif|jpg|jpeg|bmp|png|PNG)$/
1555
+ let regs = /\.(pdf)$/
1556
+ if (reg.test(row.fileName)) {
1557
+ let url = this.smartFlowServerContext + '/manage/oss/file/get/' + row.fileId
1558
+ this.imgPreview(url)
1559
+ } else if (regs.test(row.fileName)) {
1560
+ window.open(this.smartFlowServerContext + '/manage/oss/file/getFileStream?fileId=' + row.fileId, '_blank')
1561
+ } else {
1562
+ this.modalDocx = true
1563
+ axios({
1564
+ method: 'get',
1565
+ responseType: 'blob', // 因为是流文件,所以要指定blob类型
1566
+ url: this.smartFlowServerContext + '/manage/oss/file/get/' + row.fileId// 一个word下载文件的接口
1567
+ }).then(({ data }) => {
1568
+ docx.renderAsync(data, this.$refs.file, null, {
1569
+ className: 'docx', //默认和文档样式类的类名/前缀
1570
+ inWrapper: true, //启用围绕文档内容呈现包装器
1571
+ ignoreWidth: false, //禁用页面的渲染宽度
1572
+ ignoreHeight: false, //禁用页面的渲染高度
1573
+ ignoreFonts: false, //禁用字体渲染
1574
+ breakPages: true, //在分页符上启用分页
1575
+ ignoreLastRenderedPageBreak: true, //在lastRenderedPageBreak元素上禁用分页
1576
+ experimental: false, //启用实验功能(制表符停止计算)
1577
+ trimXmlDeclaration: true, //如果为true,则在解析之前将从xml文档中删除xml声明
1578
+ useBase64URL: false, //如果为true,图像、字体等将转换为base 64 URL,否则使用URL.createObjectURL
1579
+ useMathMLPolyfill: false, //包括用于铬、边等的MathML多填充。
1580
+ showChanges: false, //启用文档更改的实验渲染(插入/删除)
1581
+ debug: false, //启用额外的日志记录
1582
+ })
1583
+ }
1584
+ )
1585
+ }
1586
+ },
1587
+ imgPreview(url) {
1588
+ this.imageUrl = url
1589
+ this.modalVisible = true
1590
+ },
1591
+
1592
+ //打印流程图信息
1593
+ processPrint() {
1594
+ let self = this
1595
+ let params = {
1596
+ applyId: self.applyId,
1597
+ instanceId: self.instanceId,
1598
+ procId: self.procId,
1599
+ taskId: self.curTaskId,
1600
+ }
1601
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/getPrintData', { params: params }).then(function (resp) {
1602
+ let result = resp.data.data
1603
+ if (resp.data.code === '200') {
1604
+ let tableData = result
1605
+ self.process.tableData = tableData
1606
+ self.process.applyId = self.applyId
1607
+ self.process.instanceId = self.instanceId
1608
+ self.process.procId = self.procId
1609
+ self.datas.orgId = tableData[0].orgId
1610
+ self.datas.orgName = tableData[0].orgName
1611
+ self.modalBoxShow = true
1612
+ }
1613
+ })
1614
+ },
1615
+
1616
+ showTaskNode(taskId) {
1617
+ if (this.processHistory.length > 0) {
1618
+ let task = null
1619
+ this.processHistory.some(itemList => {
1620
+ task = itemList.find(item => item.taskId === taskId)
1621
+ return task !== undefined
1622
+ })
1623
+ return task ? task.taskName : ''
1624
+ }
1625
+ return ''
1626
+ },
1627
+ cancel() {
1628
+ this.modal = false
1629
+ this.auditResult = ''
1630
+ },
1631
+ reductionModalCancel() {
1632
+ this.reductionMultitaskInstanceModal = false
1633
+ this.reductionAssigneeList = []
1634
+ },
1635
+ selectAssignee(selection) {
1636
+ this.reductionAssigneeList = selection
1637
+ },
1638
+ selectNode(currentRow, oldCurrentRow) {
1639
+ let self = this
1640
+ self.targetTaskNode = currentRow.taskNode
1641
+ },
1642
+ getAllPreNodes() {
1643
+ let self = this
1644
+ let params = {
1645
+ processDefId: self.procId,
1646
+ taskId: self.curTaskId,
1647
+ }
1648
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/getAllPreNodes', { params: params }).then(function (resp) {
1649
+ if (resp.data.code === '200') {
1650
+ if (resp.data.data.length > 0) {
1651
+ self.allNode = resp.data.data
1652
+ self.modal1 = true
1653
+ } else {
1654
+ self.$Message.warning('当前流程无前序节点')
1655
+ }
1656
+ } else {
1657
+ self.$Message.error(resp.data.message)
1658
+ }
1659
+ })
1660
+ },
1661
+ getNodesBehind() {
1662
+ let self = this
1663
+ let params = {
1664
+ processDefId: self.procId,
1665
+ taskId: self.curTaskId,
1666
+ }
1667
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/getNodesBehind', { params: params }).then(function (resp) {
1668
+ if (resp.data.code === '200') {
1669
+ if (resp.data.data.length > 0) {
1670
+ self.allNode = resp.data.data
1671
+ self.modal1 = true
1672
+ } else {
1673
+ self.$Message.warning('当前流程无后续节点')
1674
+ }
1675
+ } else {
1676
+ self.$Message.error(resp.data.message)
1677
+ }
1678
+ })
1679
+ },
1680
+ handleSelectedUser(userId) {
1681
+ this.selectedUserId = userId
1682
+ },
1683
+
1684
+ //折叠动画效果
1685
+ beforeEnter(el) {
1686
+ el.style.height = '0'
1687
+ },
1688
+ enter(el, done) {
1689
+ setTimeout(() => {
1690
+ el.style.height = el.scrollHeight + 'px'
1691
+ }, 0)
1692
+
1693
+ el.addEventListener('transitionend', done)
1694
+ },
1695
+ beforeLeave(el) {
1696
+ el.style.height = el.scrollHeight + 'px'
1697
+ },
1698
+ leave(el, done) {
1699
+ setTimeout(() => {
1700
+ el.style.height = '0'
1701
+ }, 0)
1702
+
1703
+ el.addEventListener('transitionend', done)
1704
+ },
1705
+
1706
+ beforeFlowInfoEnter(el) {
1707
+ el.style.transform = 'translateX(100%)'
1708
+ },
1709
+ flowInfoEnter(el, done) {
1710
+ const transitionDuration = 0.5
1711
+ el.style.transition = `transform ${transitionDuration}s`
1712
+ el.style.transform = 'translateX(0)'
1713
+ el.addEventListener('transitionend', done)
1714
+ },
1715
+ beforeFlowInfoLeave(el) {
1716
+ el.style.transform = 'translateX(0)'
1717
+ },
1718
+ flowInfoLeave(el, done) {
1719
+ const transitionDuration = 0.5
1720
+ el.style.transition = `transform ${transitionDuration}s`
1721
+ el.style.transform = 'translateX(100%)'
1722
+ el.addEventListener('transitionend', done)
1723
+ },
1724
+ uploadFile(file) {
1725
+ const self = this
1726
+ self.fileList = []
1727
+ file.forEach(item => {
1728
+ self.fileList.push({
1729
+ fileName: item.fileName,
1730
+ fileId: item.fileCode,
1731
+ })
1732
+ })
1733
+ },
1734
+
1735
+ appointOk() {
1736
+ const self = this
1737
+ let oldSettings
1738
+ let params = this.nextNodesFormList.reduce((acc, item) => {
1739
+ acc[item.id] = {
1740
+ needUpdate: 'false',
1741
+ }
1742
+ item.assignee ? acc[item.id].assignee = item.assignee : ''
1743
+ item.candidateGroups ? acc[item.id].candidateGroup = item.candidateGroups : ''
1744
+ let timeLimit = 'expireTime:0D0H;warningTime:0D0H;handleType:00'
1745
+ if (!(item.remainDay === 0 && item.remainTime === 0 && item.inAdvanceDay === 0 && item.inAdvanceTime === 0)) {
1746
+ timeLimit = 'expireTime:' + parseInt(item.remainDay) + 'D' + parseInt(item.remainTime) + 'H' + ';warningTime:' + parseInt(item.inAdvanceDay) + 'D' + parseInt(item.inAdvanceTime) + 'H;' + 'handleType:' + item.processing
1747
+ acc[item.id].timeLimit = timeLimit
1748
+ } else {
1749
+ acc[item.id].timeLimit = ''
1750
+ }
1751
+ oldSettings = self.nextNodesOldSettings.filter(oldSetting => oldSetting.id === item.id)[0]
1752
+ if (oldSettings.assignee !== item.assignee || self.checkGroupsUpdate(oldSettings.candidates, item.candidateGroups, item.isMultiInstance) || self.checkTimeLimitUpdate(oldSettings.timeLimit, timeLimit)) {
1753
+ acc[item.id].needUpdate = 'true'
1754
+ }
1755
+ return acc
1756
+ }, {})
1757
+ self.auditParams.nodeConfigMaps = JSON.stringify(params)
1758
+ self.doPass((execResult, instanceId, taskIds, auditResult, curTaskId) => {
1759
+ if (this.executionCompleted) {
1760
+ this.executionCompleted(execResult, instanceId, taskIds, auditResult, curTaskId)
1761
+ }
1762
+ })
1763
+ },
1764
+ checkGroupsUpdate(oldSetting, newSetting, isMultiInstance) {
1765
+ if (oldSetting && newSetting) {
1766
+ let oldIdList = []
1767
+ for (let [key, value] of Object.entries(oldSetting)) {
1768
+ if (value) {
1769
+ value.split(',').forEach(part => {
1770
+ const [id] = part.split(':')
1771
+ if (id) {
1772
+ oldIdList.push(id)
1773
+ }
1774
+ })
1775
+ }
1776
+ }
1777
+ const regex = /(?:O:|U:|P:|R:|T:)([^,]+)/g
1778
+ let match
1779
+ const newIds = []
1780
+ while ((match = regex.exec(newSetting)) !== null) {
1781
+ newIds.push(...match[1].split(';'))
1782
+ }
1783
+
1784
+ if (isMultiInstance) {
1785
+ //串签的情况下可能只有顺序发生了变化
1786
+ const oldStr = oldIdList.join(',')
1787
+ const newStr = newIds.join(',')
1788
+ return oldStr !== newStr
1789
+ }else {
1790
+ const allInString = oldIdList.every(item => newIds.includes(item));
1791
+ const hasExtra = newIds.some(item => !oldIdList.includes(item));
1792
+ return !allInString || hasExtra
1793
+ }
1794
+
1795
+ }
1796
+ return false
1797
+ },
1798
+ checkTimeLimitUpdate(oldSetting, newSetting) {
1799
+ if (oldSetting && newSetting) {
1800
+ return oldSetting !== newSetting
1801
+ }
1802
+ if (!oldSetting) {
1803
+ return newSetting !== 'expireTime:0D0H;warningTime:0D0H;handleType:00'
1804
+ }
1805
+ return false
1806
+ },
1807
+ readingRangeClick(item) {
1808
+ let permScope = item.orgTreeType === this.defaultOrganTreeType ? this.permScope : 'all'
1809
+ let orgTreeType = item.orgTreeType ? item.orgTreeType : this.defaultOrganTreeType
1810
+ this.$refs.assigneeHelpBox.toggleShowHelpBox(orgTreeType, permScope, 'transferNextTask', item.id)
1811
+ },
1812
+ candidateGroupsReadingRangeClick(item) {
1813
+ let permScope = item.orgTreeType === this.defaultOrganTreeType ? this.permScope : 'all'
1814
+ let orgTreeType = item.orgTreeType ? item.orgTreeType : this.defaultOrganTreeType
1815
+ this.$refs.candidateGroupsHelpBox.toggleShowHelpBox(permScope, item.candidates, orgTreeType, item.id)
1816
+ },
1817
+ updateCandGroups(newCandGroups, nameStr, detail, nodeId) {
1818
+ let oldSettings = this.nextNodesOldSettings.filter(item => item.id === nodeId)[0]
1819
+ if (JSON.stringify(oldSettings.candidates) != JSON.stringify(detail)) {
1820
+ let node = this.nextNodesFormList.filter(item => item.id === nodeId)[0]
1821
+ node.candidateGroups = newCandGroups
1822
+ node.candidateNames = nameStr
1823
+ node.candidates = detail
1824
+ node.needUpdate = true
1825
+ this.$forceUpdate()
1826
+ }
1827
+ },
1828
+ updateNextNodeAssignee(selectedAssigneeId, selectedAssigneeName, nodeId) {
1829
+ let oldSettings = this.nextNodesOldSettings.filter(item => item.id === nodeId)[0]
1830
+ if (oldSettings.assignee != selectedAssigneeId) {
1831
+ let node = this.nextNodesFormList.filter(item => item.id === nodeId)[0]
1832
+ node.assignee = selectedAssigneeId
1833
+ node.assigneeName = selectedAssigneeName
1834
+ node.needUpdate = true
1835
+ this.$forceUpdate()
1836
+ }
1837
+ },
1838
+ },
1839
+ watch: {
1840
+ auditOpinionText(label) {
1841
+ this.form.auditOpinion = label
1842
+ },
1843
+ procId(val) {
1844
+ this.procId = val
1845
+ this.initData()
1846
+ },
1847
+ }
1848
+ }
1849
+ </script>
1850
+
1851
+ <style lang="less" scoped>
1852
+ @import "./styles/css/index.less";
1853
+
1854
+ /deep/ .ivu-table-row-highlight td {
1855
+ background-color: #50c1ff !important;
1856
+ color: #fff !important;
1857
+ }
1858
+
1859
+ /deep/ .ivu-card-body {
1860
+ padding: 10px;
1861
+ }
1862
+
1863
+ .page-info /deep/ .page-body {
1864
+ overflow-y: hidden;
1865
+ }
1866
+ </style>