@lambo-design/workflow-approve 1.0.0-beta.9 → 1.0.0-beta.91

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