@lambo-design/workflow-approve 1.0.0-beta.5 → 1.0.0-beta.50

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