@lambo-design/workflow-approve 1.0.0-beta.28 → 1.0.0-beta.29

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