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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/portrait.vue CHANGED
@@ -1,1491 +1,1510 @@
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
- //业务表单保存方法
370
- businessFormSave: {
371
- type: Function,
372
- required: false
373
- },
374
- //按钮执行完毕回调方法
375
- executionCompleted: {
376
- type: Function,
377
- required: false,
378
- default: () => {}
379
- },
380
- title: {
381
- type: String,
382
- default: "流程办理"
383
- },
384
- smartFlowServerContext: {
385
- type: String,
386
- default: '/api/smart-flow-server',
387
- },
388
- upmsServerContext: {
389
- type: String,
390
- default: '/api/upms-server',
391
- },
392
- },
393
- components: {
394
- Title,
395
- LamboPageContainer,
396
- Workflow_Diagram,
397
- processHistory,
398
- assigneeBox,
399
- LamboPagingTable,
400
- AuditOpinion,
401
- LamboIndicatorCard,
402
- UploadFile,
403
- CandidateGroupsHelpBox
404
- },
405
- data() {
406
- return {
407
- isExpanded: true,
408
- showProcessInfo: true,
409
- portraitWidth: 0,
410
- requestSuccessCodes: [200, "200"],
411
- auditShow: true,
412
- historyShow: true,
413
- attachListShow: true,
414
- attachmentList: [],
415
- modalVisible: false,
416
- modalDocx: false,
417
- imageUrl: '',
418
- assigneeBoxData: {},
419
- selectedUserId: '',
420
- targetTaskNode: '',
421
- allNode: [],
422
- auditParams: {},
423
- modal1: false,
424
- modalBoxShow: false,
425
- candidateGroupsHelpBoxShow: false,
426
- appointBoxShow: false,
427
- autoOpenNode: '0',
428
- nextNodesOldSettings: [],
429
- nextNodesFormList: [],
430
- hisNode: [],
431
- processHistory: [],
432
- permScope: '',
433
- organTreeType: '00',
434
- defaultOrganTreeType: '00',
435
- ruleValidate: {
436
- auditOpinion: [{required: true, trigger: "blur", message: '意见不能为空'}],
437
- assignee: [{required: true, trigger: "blur", message: "办理人不能为空"}],
438
- candidateGroups: [{required: true, trigger: "blur", message: "候选人不能为空"}],
439
- },
440
- form: {
441
- auditOpinion: '',
442
- },
443
- loading: false,
444
- disable: false,
445
- instanceId: '',
446
- taskId: '',
447
- handleButtons: [],
448
- handleName: '',
449
- auditOpinionTitle: '',
450
- auditResult: '',
451
- auditGroup: '',
452
- custChange: 'auditInfo',
453
- auditInfo: "auditInfo",
454
- auditProcess: "auditProcess",
455
- fileList: [],
456
- ossFilePutUrl: '/manage/oss/file/put',
457
- hisAudit: [],
458
- hisAuditOpinion: [{
459
- auditOpinion: '',
460
- auditTime: '',
461
- }],
462
- datas: {
463
- orgName: "",
464
- orgId: ""
465
- },
466
- editForm: {
467
- approvalCost: '',
468
- cost: '',
469
- activityDate: []
470
- },
471
- process: {
472
- tableData: [],
473
- instanceId: '',
474
- applyId: '',
475
- procId: ''
476
- },
477
- handleButtonsNames: {
478
- '30': '通过',
479
- '70': '驳回到原点',
480
- '40': '驳回上一节点',
481
- '90': '驳回指定节点',
482
- '80': '跳转指定节点',
483
- '82': '指定他人处理',
484
- '50': '直接结束流程'
485
- },
486
- handleTypeList: [
487
- {
488
- value: '00',
489
- label: '只预警不处理'
490
- },
491
- {
492
- value: '10',
493
- label: '自动同意'
494
- },
495
- {
496
- value: '20',
497
- label: '直接终止流程'
498
- },
499
- {
500
- value: '90',
501
- label: '自动驳回'
502
- }
503
- ],
504
- }
505
-
506
- },
507
-
508
- mounted() {
509
- this.getWidth()
510
- if (this.procId) {
511
- this.initData()
512
- }
513
-
514
- },
515
- computed: {
516
- processHistoryHeight() {
517
- let str = '';
518
- const hasAuditOpinion = this.taskNode && this.handleButtons && this.handleButtons.includes('auditOpinion')
519
- const hasAttachmentFile = this.handleButtons && this.handleButtons.includes('auditHistory') && this.attachmentList.length > 0
520
- const isDetail = this.isDetail && !this.hisAuditOpinion[0].auditOpinion.length > 0
521
- if (hasAuditOpinion && !hasAttachmentFile && !isDetail) {
522
- str += "height: 43vh"
523
- } else if (hasAuditOpinion && hasAttachmentFile && !isDetail) {
524
- str += "height: 40vh"
525
- } else {
526
- str += "height: 67vh"
527
- }
528
- return str;
529
- },
530
- nodeColumn: function () {
531
- let column = []
532
- column.push({title: '序号', type: 'index', width: 70, align: 'center', fixed: 'left'});
533
- column.push({title: '节点名称', key: 'taskName', minWidth: 150, align: 'center', fixed: 'left'})
534
-
535
- column.push({
536
- title: '节点状态', key: 'auditResult', minWidth: 150, align: 'center', fixed: 'left',
537
- render: (h, params) => {
538
- if (params.row.taskNode == this.taskNode) {
539
- return h('div', [
540
- h('tag', {
541
- props: {
542
- color: '#ff9900'
543
- }
544
- }, '当前节点')
545
- ])
546
- } else if (!params.row.auditResult) {
547
- return h('div', [
548
- h('tag', {
549
- props: {
550
- color: '#ff9900'
551
- }
552
- }, `未${params.row.handleName ? params.row.handleName : '审批'}`)
553
- ])
554
- } else {
555
- if (params.row.auditResult == '30' && params.row.taskNode != this.taskNode) {
556
- return h('div', [
557
- h('tag', {
558
- props: {
559
- color: '#19be6b'
560
- }
561
- }, `已${params.row.handleName ? params.row.handleName : '审批'}通过`)
562
- ])
563
- } else if (params.row.auditResult == '40' && params.row.taskNode != this.taskNode) {
564
- return h('div', [
565
- h('tag', {
566
- props: {
567
- color: '#ed4014'
568
- }
569
- }, '已驳回到上一节点')
570
- ])
571
- } else if (params.row.auditResult == '60' && params.row.taskNode != this.taskNode) {
572
- return h('div', [
573
- h('tag', {
574
- props: {
575
- color: '#ed4014'
576
- }
577
- }, '已撤回')
578
- ])
579
- } else if (params.row.auditResult == '80' && params.row.taskNode != this.taskNode) {
580
- return h('div', [
581
- h('tag', {
582
- props: {
583
- color: '#19be6b'
584
- }
585
- }, '已跳转到指定节点')
586
- ])
587
- } else if (params.row.auditResult == '90' && params.row.taskNode != this.taskNode) {
588
- return h('div', [
589
- h('tag', {
590
- props: {
591
- color: '#19be6b'
592
- }
593
- }, '已驳回到指定节点')
594
- ])
595
- }
596
- }
597
- }
598
- })
599
- column.push({
600
- title: "操作", width: 100, align: 'center',
601
- render: (h, params) => {
602
- return h('div', [
603
- h('Button', {
604
- props: {
605
- type: 'primary',
606
- size: 'small'
607
- },
608
- style: {
609
- marginRight: '5px'
610
- },
611
- on: {
612
- click: () => {
613
- this.selectNode(params.row)
614
- }
615
- }
616
- }, '选择')
617
- ])
618
- },
619
- })
620
- return column
621
- },
622
- diagramTableColumns: function () {
623
- let column = []
624
- column.push({title: '序号', type: 'index', width: 80});
625
- column.push({title: `${this.handleName}节点`, key: 'taskName', minWidth: 130})
626
- column.push({title: `${this.handleName}人`, key: 'auditName', minWidth: 180, tooltip: true})
627
- column.push({
628
- title: `${this.handleName}结果`, key: 'auditResult', minWidth: 100,
629
- render: (h, {row, column, index}) => {
630
- let label = "";
631
- let tagColor = "";
632
- if (row.auditResult == '30'){
633
- label = '通过';
634
- tagColor = 'green'; // 绿色
635
- }
636
- else if (row.auditResult == '40'){
637
- label = '驳回到上一级';
638
- tagColor = 'volcano'; // 火红色
639
- }
640
- else if (row.auditResult == '50'){
641
- label = '驳回到原点';
642
- tagColor = 'red'; // 红色
643
- }
644
- else if (row.auditResult == '51'){
645
- label = '流程终止';
646
- tagColor = 'purple'; // 紫色
647
- }
648
- else if (row.auditResult == '60'){
649
- label = '撤回';
650
- tagColor = 'blue'; // 蓝色
651
- }
652
- else if (row.auditResult == '80'){
653
- label = '跳转到指定节点';
654
- tagColor = 'cyan'; // 青色
655
- }
656
- else if (row.auditResult == '90'){
657
- label = '驳回到指定节点';
658
- tagColor = 'magenta'; // 品红色
659
- }
660
- else{
661
- label = '待审核';
662
- tagColor = 'orange'; // 默认橙色
663
- }
664
- return h('Tag', {
665
- props: {
666
- color: tagColor,
667
- value: row.auditResult
668
- }
669
- }, label);
670
- }
671
- })
672
- column.push({
673
- title: `${this.handleName}时间`, key: 'auditTime', minWidth: 150,
674
- render: (h, {row}) => {
675
- const displayDate = row.startDate || row.auditDate;
676
- return h('span', displayDate);
677
- }
678
- })
679
- column.push({
680
- title: `${this.handleName}意见`, key: 'auditComment', minWidth: 180, tooltip: true,
681
- render: (h, {row, column, index}) => {
682
- let label = "";
683
- if (row.auditComment == '' || row.auditComment == null) label = '无';
684
- else label = row.auditComment;
685
- return h('Label', {
686
- props: {
687
- value: row.auditComment
688
- }
689
- }, label)
690
- }
691
- })
692
- column.push({
693
- title: `附件`, key: 'fileList', minWidth: 200,
694
- render: (h, { row }) => {
695
- if (!row.fileList || row.fileList.length === 0) {
696
- return h('span', '无'); // 如果没有附件,显示“无”
697
- }
698
-
699
- //显示所有附件
700
- return h('div', row.fileList.map(file => {
701
- return h('a', {
702
- style: {
703
- display: 'block',
704
- marginTop: '5px',
705
- marginRight:'5px',
706
- whiteSpace: 'nowrap',
707
- overflow: 'hidden',
708
- textOverflow: 'ellipsis',
709
- maxWidth: '100px',
710
- },
711
- attrs: {
712
- title: file.attachName // 鼠标悬停时显示完整名称
713
- },
714
- on: {
715
- click: () => {
716
- this.getAttach(file);
717
- }
718
- },
719
- }, file.attachName);
720
- }));
721
- }
722
- })
723
-
724
- return column
725
- },
726
- },
727
- provide() {
728
- return {
729
- toBeDoneListDoSearch: this.doSearch
730
- };
731
- },
732
- methods: {
733
- getWidth() {
734
- if (this.width && this.width < 400) {
735
- this.portraitWidth = 400
736
- }
737
- this.portraitWidth = this.width
738
- },
739
- initData() {
740
- this.getAttachList()
741
- if (!this.isDetail) {
742
- this.getTodoTaskId()
743
- } else {
744
- this.getDoneTaskId()
745
- }
746
- this.getHandleButtons()
747
- this.getHisAudit();
748
- this.getProcessHistory();
749
- },
750
- getAttachList() {
751
- const self = this
752
- const param = {
753
- procId: this.procId,
754
- applyId: this.applyId
755
- }
756
- ajax.get(self.smartFlowServerContext + '/manage/processDone/getAttachmentList', {params: param}).then(function (resp) {
757
- self.attachmentList = resp.data.data.rows
758
- self.attachmentList.forEach(item => {
759
- const index = item.fileName.lastIndexOf(".")
760
- const fileType = item.fileName.substr(index + 1).toLowerCase()
761
- const imageList = ['jpg', 'gif', 'png', 'svg']
762
- const docList = ['doc', 'docx']
763
- const zipList = ['rar', 'zip']
764
- const typeList = ['jpg', 'gif', 'png', 'docx']
765
- item.fileType = imageList.indexOf(fileType) !== -1 ? 'image' : docList.indexOf(fileType) !== -1 ? 'doc' : zipList.indexOf(fileType) !== -1 ? 'zip' : fileType
766
- item.showPreview = typeList.indexOf(fileType) !== -1
767
- })
768
- }).catch(err => {
769
- console.log(err);
770
- })
771
- },
772
- getTodoTaskId() {
773
- const self = this
774
- let param = {
775
- procId: this.procId,
776
- applyId: this.applyId,
777
- taskNode: this.taskNode
778
- }
779
- ajax.get(self.smartFlowServerContext + "/manage/processTodo/list", {params: param}).then(function (resp) {
780
- if (resp.data.code === '200') {
781
- self.taskId = resp.data.data.rows[0].taskId
782
- self.instanceId = resp.data.data.rows[0].procInstanceId
783
- let procType = resp.data.data.rows[0].procType
784
- ajax.get(self.smartFlowServerContext + "/manage/processType/lists?proType=" + procType)
785
- .then(resp => {
786
- let data = resp.data.data.rows
787
- self.permScope = data[0].permScope
788
- self.auditGroup = data[0].auditGroup
789
- self.defaultOrganTreeType = data[0].organTreeType ? data[0].organTreeType : '00'
790
- self.getNodeOrganTreeType(procType)
791
- }).catch(err => {
792
- console.log(err);
793
- })
794
- } else {
795
- self.$Message.error(resp.data.message)
796
- }
797
- }).catch((err) => {
798
- console.log(err)
799
- })
800
- },
801
- getNodeOrganTreeType(procType){
802
- const self = this
803
- let param = {
804
- procType: procType,
805
- procId: this.procId,
806
- taskNode: this.taskNode
807
- }
808
- ajax.get(self.smartFlowServerContext + "/manage/processTodo/getNodeOrganTreeType", {params: param}).then(function (resp) {
809
- if (resp.data.code === '200') {
810
- self.organTreeType = resp.data.data ? resp.data.data : self.defaultOrganTreeType
811
- } else {
812
- self.$Message.error(resp.data.message)
813
- }
814
- }).catch((err) => {
815
- console.log(err)
816
- })
817
- },
818
- getDoneTaskId() {
819
- const self = this
820
- let param = {
821
- procId: this.procId,
822
- applyId: this.applyId,
823
- taskNode: this.taskNode
824
- }
825
- ajax.get(self.smartFlowServerContext + "/manage/processDone/getDoneDetail", {params: param}).then(function (resp) {
826
- if (resp.data.code === '200') {
827
- let rows = resp.data.data.rows
828
- self.auditGroup = rows[0].auditGroup
829
- if (rows.length > 0) {
830
- self.hisAuditOpinion = []
831
- let taskList = resp.data.data.rows
832
- taskList.forEach(item => {
833
- self.hisAuditOpinion.push({
834
- auditOpinion: item.auditComment,
835
- auditTime: timestampToTime(item.auditDate)
836
- })
837
- })
838
- self.taskId = taskList[0].taskId
839
- self.instanceId = taskList[0].procInstanceId
840
- } else {
841
- ajax.get(self.smartFlowServerContext + "/manage/processTodo/list", {params: param}).then(function (todoResp) {
842
- if (todoResp.data.code === '200') {
843
- self.taskId = todoResp.data.data.rows[0].taskId
844
- self.instanceId = todoResp.data.data.rows[0].procInstanceId
845
- } else {
846
- self.$Message.error(todoResp.data.message)
847
- }
848
- }).catch((err) => {
849
- console.log(err)
850
- })
851
- }
852
- } else {
853
- self.$Message.error(resp.data.message)
854
- }
855
- }).catch((err) => {
856
- console.log(err)
857
- })
858
- },
859
- getHandleButtons() {
860
- const self = this
861
- let param = {
862
- procId: this.procId,
863
- taskNode: this.taskNode
864
- }
865
- ajax.post(self.smartFlowServerContext + '/manage/approvalCenter/getNodeData', param).then(function (resp) {
866
- if (resp.data.code === '200') {
867
- self.handleButtons = resp.data.data[0].handleButtons
868
- self.handleName = resp.data.data[0].handleName ? resp.data.data[0].handleName : '审批'
869
- self.auditOpinionTitle = resp.data.data[0].handleName ? resp.data.data[0].handleName + '意见' : '审批意见'
870
- if (!self.handleButtons || (!self.handleButtons.includes('auditOpinion') && !self.handleButtons.includes('attachmentFile') && !self.handleButtons.includes('auditHistory'))){
871
- self.showProcessInfo = false
872
- }
873
- } else {
874
- self.$Message.error(resp.data.message)
875
- }
876
- }).catch((err) => {
877
- console.log(err)
878
- })
879
- },
880
- getNextNodes(){
881
- const self = this
882
- self.nextNodesFormList = []
883
- self.nextNodesOldSettings = []
884
- let param = {
885
- procId: this.procId,
886
- taskNode: this.taskNode
887
- }
888
- ajax.post(self.smartFlowServerContext + '/manage/processTodo/getNextNodes', param).then(function (resp) {
889
- if (resp.data.code === '200') {
890
- let nextNodeForm = {}
891
- let nextNodeOldForm = {}
892
- let data = resp.data.data
893
- for (let i = 0; i < data.length; i++) {
894
- nextNodeOldForm = {
895
- id: data[i].id,
896
- assignee: data[i].assignee ? data[i].assignee.id : '',
897
- timeLimit: data[i].timeLimit,
898
- }
899
- nextNodeForm = {
900
- id: data[i].id,
901
- name: data[i].name,
902
- orgTreeType: data[i].orgTreeType,
903
- assignee: data[i].assignee ? data[i].assignee.id : '',
904
- assigneeName: data[i].assignee ? data[i].assignee.name : '',
905
- candidateGroups: '',
906
- isMultiInstance: data[i].isMultiInstance,
907
- actionType: 'ASSIGNEE',
908
- remainDay : 0,
909
- remainTime : 0,
910
- inAdvanceDay : 0,
911
- inAdvanceTime : 0,
912
- processing : '00'
913
- }
914
- //显示具体候选人信息
915
- if (data[i].candidateGroups){
916
- nextNodeForm.actionType = 'CAND'
917
- let names = [];
918
- let candidates = {};
919
- for (let groupName in data[i].candidateGroups) {
920
- if (data[i].candidateGroups.hasOwnProperty(groupName)) {
921
- let group = data[i].candidateGroups[groupName];
922
- group.forEach(item => {
923
- names.push(item.name);
924
- });
925
- candidates[groupName] = group.map(item => item.id + ':' + item.name).join(',');
926
- }
927
- }
928
- nextNodeForm.candidateNames = names.join(',');
929
- nextNodeForm.candidates = candidates;
930
- nextNodeOldForm.candidates = candidates;
931
- }
932
- if (data[i].timeLimit) {
933
- let expireTime = data[i].timeLimit.split(";")[0].split(":")[1]
934
- let warningTime = data[i].timeLimit.split(";")[1].split(":")[1]
935
- let handleType = data[i].timeLimit.split(";")[2].split(":")[1]
936
- let days = expireTime.slice(0, expireTime.indexOf("D")) //过期天
937
- let hourOfDay = expireTime.slice(expireTime.indexOf("D") + 1, expireTime.indexOf("H")) //过期小时
938
- let daysWarn = warningTime.slice(0, warningTime.indexOf("D")) //警告天
939
- let hourOfDayWarn = warningTime.slice(warningTime.indexOf("D") + 1, warningTime.indexOf("H")) //警告小时
940
- nextNodeForm.remainDay = parseInt(days)
941
- nextNodeForm.remainTime = parseInt(hourOfDay)
942
- nextNodeForm.inAdvanceDay = parseInt(daysWarn)
943
- nextNodeForm.inAdvanceTime = parseInt(hourOfDayWarn)
944
- nextNodeForm.processing = handleType
945
- }
946
- self.nextNodesFormList.push(nextNodeForm)
947
- self.nextNodesOldSettings.push(nextNodeOldForm)
948
- }
949
- } else {
950
- self.$Message.error(resp.data.message)
951
- }
952
- }).catch((err) => {
953
- console.log(err)
954
- })
955
- },
956
- getHisAudit() {
957
- let self = this
958
- let params = {
959
- applyId: self.applyId,
960
- instanceId: self.instanceId,
961
- procId: self.procId,
962
- taskId: self.taskId
963
- }
964
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/getHisAudit', {params: params}).then(function (resp) {
965
- if (resp.data.code === '200') {
966
- self.hisAudit = resp.data.data
967
- let uniqueDataMap = {};
968
- self.hisAudit.forEach((item) => {
969
- uniqueDataMap[item["taskNode"]] = item;
970
- })
971
- self.hisNode = Object.values(uniqueDataMap);
972
-
973
- }
974
- })
975
- },
976
- getProcessHistory() {
977
- let self = this
978
- let params = {
979
- applyId: self.applyId,
980
- instanceId: self.instanceId,
981
- procId: self.procId,
982
- taskId: self.taskId
983
- }
984
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/getProcessHis', {params: params}).then(function (resp) {
985
- if (resp.data.code === '200') {
986
- self.processHistory = resp.data.data
987
- }
988
- })
989
- },
990
-
991
- audit: function (auditResult) {
992
- let self = this
993
- self.auditResult = auditResult
994
- self.submit()
995
- },
996
- submit() {
997
- let self = this;
998
- self.auditParams = {
999
- procId: self.procId,
1000
- applyId: self.applyId,
1001
- taskId: self.taskId,
1002
- auditOpinion: self.form.auditOpinion,
1003
- fileListStr: JSON.stringify(self.fileList),
1004
- auditResult: self.auditResult,
1005
- params: JSON.stringify(self.datas),
1006
- targetTaskNode: self.targetTaskNode,
1007
- selectedUserId: self.selectedUserId,
1008
- }
1009
- if (self.auditResult == '' || self.auditResult == null) {
1010
- self.$Message.error(`请选择${self.handleName}结果!`);
1011
- return;
1012
- }
1013
- if (self.form.auditOpinion == '' || self.form.auditOpinion == null) {
1014
- if (!self.handleButtons || self.handleButtons.includes('auditOpinion')) {
1015
- self.$Message.error(`请输入${self.handleName}意见!`)
1016
- return;
1017
- } else {
1018
- self.auditParams.auditOpinion = self.handleButtonsNames[self.auditResult];
1019
- }
1020
- }
1021
- self.businessFormSave ? self.businessFormSave(self.handleSaveResult) : self.handleSaveResult(true)
1022
- },
1023
- handleSaveResult(saveResult, businessParams) {
1024
- if (saveResult) {
1025
- this.executeButtonAction(businessParams);
1026
- } else {
1027
- console.error('保存失败');
1028
- }
1029
- },
1030
- executeButtonAction(businessParams) {
1031
- const self = this;
1032
- if (businessParams) {
1033
- Object.assign(self.datas, businessParams)
1034
- self.auditParams.params = JSON.stringify(self.datas)
1035
- }
1036
- let auditResult = {
1037
- code: self.auditResult,
1038
- name: self.handleButtonsNames[self.auditResult]
1039
- }
1040
- if (self.auditResult === '82') {
1041
- self.assigneeBoxData = self.auditParams
1042
- self.assigneeBoxData.auditResultName = self.handleButtonsNames[self.auditResult]
1043
- self.assigneeBoxData.instanceId = self.instanceId
1044
- self.$refs.assigneeHelpBox.toggleShowHelpBox(self.organTreeType, '', 'transferCurTask')
1045
- } else if (self.auditResult === '80') {
1046
- self.getNodesBehind()
1047
- } else if (self.auditResult === '90') {
1048
- self.getAllPreNodes()
1049
- } else if (self.auditResult === '40') {
1050
- self.loading = true
1051
- self.disable = true
1052
- let url = self.smartFlowServerContext + '/manage/processTodo/getPreNode'
1053
- ajax.post(url, self.auditParams).then(function (resp) {
1054
- let result = resp.data
1055
- if (result.code == '30013' || result.code == '30014') {
1056
- //前序节点为子流程或当前节点为子流程第一个节点不可驳回上一级节点
1057
- self.$Message.warning(result.message)
1058
- //避免未提示消息直接回调
1059
- setTimeout(() => {
1060
- self.executionCompleted(false, null, null, auditResult, self.taskId);
1061
- }, 1000)
1062
- } else if (result.code == '30010') {
1063
- self.$Modal.confirm({
1064
- title: "提示",
1065
- content: result.message,
1066
- onOk: () => {
1067
- self.auditParams.auditResult = '70'
1068
- let url = self.smartFlowServerContext + '/manage/processTodo/audit'
1069
- ajax.post(url, self.auditParams).then(function (resp) {
1070
- let result = resp.data
1071
- if (result.code == '200') {
1072
- self.loading = false
1073
- self.disable = false
1074
- self.$Message.success(result.message);
1075
- //后端没有返回数据
1076
- setTimeout(() => {
1077
- self.executionCompleted(true, null, null, auditResult, self.taskId);
1078
- }, 1000)
1079
- bus.$emit('triggerTimer')
1080
- } else {
1081
- self.loading = false
1082
- self.disable = false
1083
- self.$Message.error(result.message)
1084
- setTimeout(() => {
1085
- self.executionCompleted(false, null, null, auditResult, self.taskId);
1086
- }, 1000)
1087
- }
1088
- bus.$emit('triggerTimer')
1089
- })
1090
- },
1091
- onCancel: () => {
1092
- self.loading = false
1093
- self.disable = false
1094
- }
1095
- })
1096
- } else {
1097
- self.loading = true
1098
- self.disable = true
1099
- let url = self.smartFlowServerContext + '/manage/processTodo/audit'
1100
- ajax.post(url, self.auditParams).then(function (resp) {
1101
- let result = resp.data
1102
- if (result.code == '200') {
1103
- self.loading = false
1104
- self.disable = false
1105
- self.$Message.success(result.message);
1106
- if (result.data) {
1107
- let taskIds = result.data.map(item => item.id).join(',');
1108
- self.executionCompleted(true, result.data[0].processInstanceId, taskIds, auditResult, self.taskId)
1109
- } else {
1110
- self.executionCompleted(true, null, null, auditResult, self.taskId)
1111
- }
1112
- } else {
1113
- self.loading = false
1114
- self.disable = false
1115
- self.$Message.error(result.message)
1116
- setTimeout(() => {
1117
- self.executionCompleted(false, null, null, auditResult, self.taskId);
1118
- }, 1000)
1119
- }
1120
- bus.$emit('triggerTimer')
1121
- })
1122
- }
1123
- })
1124
- } else {
1125
- if (!self.handleButtons || self.handleButtons.includes('appointHandler') || self.handleButtons.includes('appointTimeoutTime')){
1126
- self.getNextNodes()
1127
- self.appointBoxShow = true
1128
- } else {
1129
- self.doPass()
1130
- }
1131
- }
1132
- },
1133
- doPass(){
1134
- let self = this;
1135
- this.modal = false
1136
- let auditResult = {
1137
- code: self.auditResult,
1138
- name: self.handleButtonsNames[self.auditResult]
1139
- }
1140
- if (self.auditResult === '82' && (self.targetTaskNode == '' || self.targetTaskNode == null)) {
1141
- self.auditResult = '';
1142
- self.$Message.error(`请选择${self.handleName}节点!`);
1143
- } else {
1144
- self.loading = true
1145
- self.disable = true
1146
- self.auditParams.targetTaskNode = self.targetTaskNode
1147
- let url = self.smartFlowServerContext + '/manage/processTodo/audit'
1148
- ajax.post(url, self.auditParams).then(function (resp) {
1149
- let result = resp.data
1150
- if (result.code == '200') {
1151
- self.loading = false
1152
- self.disable = false
1153
- self.$Message.success(result.message ? result.message : `${self.handleName}成功`);
1154
- if (result.data){
1155
- let taskIds = result.data.id ? result.data.id : result.data.map(item => item.id).join(',');
1156
- setTimeout(() => {
1157
- self.executionCompleted(true, result.data.id ? result.data.processInstanceId : result.data[0].processInstanceId, taskIds, auditResult, self.taskId)
1158
- }, 1000)
1159
- } else {
1160
- setTimeout(() => {
1161
- self.executionCompleted(true, null, null, auditResult, self.taskId)
1162
- }, 1000)
1163
- }
1164
- } else if (result.code == '20002') {
1165
- // 流程结束
1166
- self.loading = false
1167
- self.disable = false
1168
- self.$Message.success(result.message)
1169
- setTimeout(() => {
1170
- self.executionCompleted(true, '流程已结束', '流程已结束', auditResult, self.taskId)
1171
- }, 1000)
1172
- } else {
1173
- self.loading = false
1174
- self.disable = false
1175
- self.$Message.error(result.message ? result.message : `${self.handleName}失败`)
1176
- setTimeout(() => {
1177
- self.executionCompleted(false, null, null, auditResult, self.taskId)
1178
- }, 1000)
1179
- }
1180
- bus.$emit('triggerTimer')
1181
- })
1182
- }
1183
- },
1184
-
1185
- doSearch() {
1186
- //不需要实现,是子组件assigneeBox要求使用父组件的这个方法
1187
- },
1188
- tabsChange(tab) {
1189
- console.log(tab)
1190
- },
1191
- getAttach(row) {
1192
- window.open(this.smartFlowServerContext + "/manage/oss/file/get/" + row.fileId, "_blank");
1193
- },
1194
- preViewAttach(row) {
1195
- let reg = /\.(gif|jpg|jpeg|bmp|png|PNG)$/
1196
- let regs = /\.(pdf)$/
1197
- if (reg.test(row.fileName)) {
1198
- let url = this.smartFlowServerContext + "/manage/oss/file/get/" + row.fileId;
1199
- this.imgPreview(url);
1200
- } else if (regs.test(row.fileName)) {
1201
- window.open(this.smartFlowServerContext + "/manage/oss/file/getFileStream?fileId=" + row.fileId, "_blank");
1202
- } else {
1203
- this.modalDocx = true
1204
- axios({
1205
- method: 'get',
1206
- responseType: 'blob', // 因为是流文件,所以要指定blob类型
1207
- url: this.smartFlowServerContext + "/manage/oss/file/get/" + row.fileId// 一个word下载文件的接口
1208
- }).then(({data}) => {
1209
- docx.renderAsync(data, this.$refs.file, null, {
1210
- className: "docx", //默认和文档样式类的类名/前缀
1211
- inWrapper: true, //启用围绕文档内容呈现包装器
1212
- ignoreWidth: false, //禁用页面的渲染宽度
1213
- ignoreHeight: false, //禁用页面的渲染高度
1214
- ignoreFonts: false, //禁用字体渲染
1215
- breakPages: true, //在分页符上启用分页
1216
- ignoreLastRenderedPageBreak: true, //在lastRenderedPageBreak元素上禁用分页
1217
- experimental: false, //启用实验功能(制表符停止计算)
1218
- trimXmlDeclaration: true, //如果为true,则在解析之前将从xml文档中删除xml声明
1219
- useBase64URL: false, //如果为true,图像、字体等将转换为base 64 URL,否则使用URL.createObjectURL
1220
- useMathMLPolyfill: false, //包括用于铬、边等的MathML多填充。
1221
- showChanges: false, //启用文档更改的实验渲染(插入/删除)
1222
- debug: false, //启用额外的日志记录
1223
- })
1224
- }
1225
- )
1226
- }
1227
- },
1228
- imgPreview(url) {
1229
- this.imageUrl = url;
1230
- this.modalVisible = true;
1231
- },
1232
-
1233
- //打印流程图信息
1234
- processPrint() {
1235
- let self = this
1236
- let params = {
1237
- applyId: self.applyId,
1238
- instanceId: self.instanceId,
1239
- procId: self.procId,
1240
- taskId: self.taskId,
1241
- }
1242
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/getPrintData', {params: params}).then(function (resp) {
1243
- let result = resp.data.data
1244
- if (resp.data.code === '200') {
1245
- let tableData = result
1246
- self.process.tableData = tableData
1247
- self.process.applyId = self.applyId
1248
- self.process.instanceId = self.instanceId
1249
- self.process.procId = self.procId
1250
- self.datas.orgId = tableData[0].orgId
1251
- self.datas.orgName = tableData[0].orgName
1252
- self.modalBoxShow = true
1253
- }
1254
- })
1255
- },
1256
-
1257
- showTaskNode(taskId) {
1258
- if (this.processHistory.length > 0) {
1259
- let task = null
1260
- this.processHistory.some(itemList => {
1261
- task = itemList.find(item => item.taskId === taskId);
1262
- return task !== undefined;
1263
- });
1264
- return task ? task.taskName : ''
1265
- }
1266
- return ''
1267
- },
1268
- cancel() {
1269
- this.modal = false
1270
- this.auditResult = '';
1271
- },
1272
- selectNode(currentRow, oldCurrentRow) {
1273
- let self = this
1274
- self.targetTaskNode = currentRow.taskNode
1275
- },
1276
- getAllPreNodes() {
1277
- let self = this
1278
- let params = {
1279
- processDefId: self.procId,
1280
- taskId: self.taskId,
1281
- }
1282
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/getAllPreNodes', {params: params}).then(function (resp) {
1283
- if (resp.data.code === '200') {
1284
- if (resp.data.data.length > 0) {
1285
- self.allNode = resp.data.data
1286
- self.modal1 = true
1287
- } else {
1288
- self.$Message.warning('当前流程无前序节点')
1289
- }
1290
- } else {
1291
- self.$Message.error(resp.data.message)
1292
- }
1293
- })
1294
- },
1295
- getNodesBehind() {
1296
- let self = this
1297
- let params = {
1298
- processDefId: self.procId,
1299
- taskId: self.taskId,
1300
- }
1301
- ajax.get(self.smartFlowServerContext + '/manage/processTodo/getNodesBehind', {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
- handleSelectedUser(userId) {
1315
- this.selectedUserId = userId;
1316
- },
1317
-
1318
- //折叠动画效果
1319
- beforeEnter(el) {
1320
- el.style.height = '0';
1321
- },
1322
- enter(el, done) {
1323
- setTimeout(() => {
1324
- el.style.height = el.scrollHeight + 'px';
1325
- }, 0);
1326
-
1327
- el.addEventListener('transitionend', done);
1328
- },
1329
- beforeLeave(el) {
1330
- el.style.height = el.scrollHeight + 'px';
1331
- },
1332
- leave(el, done) {
1333
- setTimeout(() => {
1334
- el.style.height = '0';
1335
- }, 0);
1336
-
1337
- el.addEventListener('transitionend', done);
1338
- },
1339
-
1340
- beforeFlowInfoEnter(el) {
1341
- el.style.transform = 'translateX(100%)';
1342
- },
1343
- flowInfoEnter(el, done) {
1344
- const transitionDuration = 0.5;
1345
- el.style.transition = `transform ${transitionDuration}s`;
1346
- el.style.transform = 'translateX(0)';
1347
- el.addEventListener('transitionend', done);
1348
- },
1349
- beforeFlowInfoLeave(el) {
1350
- el.style.transform = 'translateX(0)';
1351
- },
1352
- flowInfoLeave(el, done) {
1353
- const transitionDuration = 0.5;
1354
- el.style.transition = `transform ${transitionDuration}s`;
1355
- el.style.transform = 'translateX(100%)';
1356
- el.addEventListener('transitionend', done);
1357
- },
1358
- uploadFile(file) {
1359
- const self = this;
1360
- self.fileList = []
1361
- file.forEach(item => {
1362
- self.fileList.push({
1363
- fileName: item.fileName,
1364
- fileId: item.fileCode,
1365
- });
1366
- })
1367
- },
1368
-
1369
- appointOk() {
1370
- const self = this
1371
- let oldSettings
1372
- let params = this.nextNodesFormList.reduce((acc, item) => {
1373
- acc[item.id] = {
1374
- needUpdate: 'false',
1375
- }
1376
- item.assignee ? acc[item.id].assignee = item.assignee : ''
1377
- item.candidateGroups ? acc[item.id].candidateGroup = item.candidateGroups : ''
1378
- let timeLimit = 'expireTime:0D0H;warningTime:0D0H;handleType:00'
1379
- if(!(item.remainDay === 0 && item.remainTime === 0 && item.inAdvanceDay === 0 && item.inAdvanceTime === 0)) {
1380
- timeLimit = 'expireTime:' + parseInt(item.remainDay) + "D" + parseInt(item.remainTime) + "H" + ";warningTime:" + parseInt(item.inAdvanceDay) + "D" + parseInt(item.inAdvanceTime) + "H;" + "handleType:" + item.processing;
1381
- acc[item.id].timeLimit = timeLimit
1382
- } else {
1383
- acc[item.id].timeLimit = ''
1384
- }
1385
- oldSettings = self.nextNodesOldSettings.filter(oldSetting => oldSetting.id === item.id)[0]
1386
- if (oldSettings.assignee !== item.assignee || self.checkGroupsUpdate(oldSettings.candidates, item.candidateGroups) || self.checkTimeLimitUpdate(oldSettings.timeLimit, timeLimit)) {
1387
- acc[item.id].needUpdate = 'true'
1388
- }
1389
- return acc;
1390
- }, {});
1391
- self.auditParams.nodeConfigMaps = JSON.stringify(params)
1392
- self.doPass((execResult, instanceId, taskIds, auditResult, curTaskId) => {
1393
- if (this.executionCompleted) {
1394
- this.executionCompleted(execResult, instanceId, taskIds, auditResult, curTaskId);
1395
- }
1396
- })
1397
- },
1398
- checkGroupsUpdate(oldSetting, newSetting) {
1399
- if (oldSetting && newSetting) {
1400
- let oldIdList = []
1401
- for (let [key, value] of Object.entries(oldSetting)) {
1402
- if (value) {
1403
- value.split(',').forEach(part => {
1404
- const [id] = part.split(':');
1405
- if (id) {
1406
- oldIdList.push(id);
1407
- }
1408
- })
1409
- }
1410
- }
1411
- const regex = /(?:O:|U:|P:|R:|T:)([^,]+)/g;
1412
- let match;
1413
- const newIds = [];
1414
- while ((match = regex.exec(newSetting)) !== null) {
1415
- newIds.push(...match[1].split(';'))
1416
- }
1417
- const allInString = oldIdList.every(item => newIds.includes(item));
1418
- const hasExtra = newIds.some(item => !oldIdList.includes(item));
1419
- return !allInString || hasExtra
1420
- }
1421
- return false
1422
- },
1423
- checkTimeLimitUpdate(oldSetting, newSetting){
1424
- if (oldSetting && newSetting){
1425
- return oldSetting !== newSetting
1426
- }
1427
- if (!oldSetting){
1428
- return newSetting !== 'expireTime:0D0H;warningTime:0D0H;handleType:00'
1429
- }
1430
- return false
1431
- },
1432
- readingRangeClick(item) {
1433
- let permScope = item.organTreeType === this.defaultOrganTreeType ? this.permScope : 'all'
1434
- let orgTreeType = item.orgTreeType ? item.orgTreeType : this.defaultOrganTreeType
1435
- this.$refs.assigneeHelpBox.toggleShowHelpBox(orgTreeType, permScope, 'transferNextTask', item.id)
1436
- },
1437
- candidateGroupsReadingRangeClick(item) {
1438
- let permScope = item.organTreeType === this.defaultOrganTreeType ? this.permScope : 'all'
1439
- let orgTreeType = item.orgTreeType ? item.orgTreeType : this.defaultOrganTreeType
1440
- this.$refs.candidateGroupsHelpBox.toggleShowHelpBox(permScope, item.candidates, orgTreeType, item.id);
1441
- },
1442
- updateCandGroups(newCandGroups, nameStr, detail, nodeId){
1443
- let oldSettings = this.nextNodesOldSettings.filter(item => item.id === nodeId)[0]
1444
- if (JSON.stringify(oldSettings.candidates) != JSON.stringify(detail)) {
1445
- let node = this.nextNodesFormList.filter(item => item.id === nodeId)[0]
1446
- node.candidateGroups = newCandGroups
1447
- node.candidateNames = nameStr
1448
- node.candidates = detail
1449
- node.needUpdate = true
1450
- this.$forceUpdate();
1451
- }
1452
- },
1453
- updateNextNodeAssignee(selectedAssigneeId, selectedAssigneeName, nodeId){
1454
- let oldSettings = this.nextNodesOldSettings.filter(item => item.id === nodeId)[0]
1455
- if (oldSettings.assignee != selectedAssigneeId) {
1456
- let node = this.nextNodesFormList.filter(item => item.id === nodeId)[0]
1457
- node.assignee = selectedAssigneeId
1458
- node.assigneeName = selectedAssigneeName
1459
- node.needUpdate = true
1460
- this.$forceUpdate();
1461
- }
1462
- }
1463
- },
1464
- watch: {
1465
- auditOpinionText(label) {
1466
- this.form.auditOpinion = label;
1467
- },
1468
- procId(val) {
1469
- this.procId = val;
1470
- this.initData()
1471
- },
1472
- }
1473
- }
1474
- </script>
1475
-
1476
- <style lang="less" scoped>
1477
- @import "./styles/css/index.less";
1478
-
1479
- /deep/ .ivu-table-row-highlight td {
1480
- background-color: #50c1ff !important;
1481
- color: #fff !important;
1482
- }
1483
-
1484
- /deep/ .ivu-card-body {
1485
- padding: 10px;
1486
- }
1487
-
1488
- .page-info /deep/ .page-body {
1489
- overflow-y: hidden;
1490
- }
1491
- </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
+ <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>