@lambo-design/workflow-approve 1.0.0-beta.10

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.
@@ -0,0 +1,1059 @@
1
+ <template>
2
+ <LamboPageContainer>
3
+ <template slot="page-title">
4
+ {{ title }}
5
+ </template>
6
+ <template slot="page-extend">
7
+ <slot name="return-button"></slot>
8
+ </template>
9
+ <div class="portrait-lambo-indicator-card" :style="{float: 'left', width: isExpanded ? `calc(100% - ${portraitWidth+10}px)` : '99%'}">
10
+ <slot name="business-content">
11
+ </slot>
12
+ </div>
13
+
14
+ <a @click="isExpanded = !isExpanded" class="arrow-button-container" :style="{right: isExpanded ? portraitWidth+10 + 'px' : '10px'}">
15
+ <Icon class="icon-class" v-if="isExpanded" type="ios-arrow-forward"/>
16
+ <Icon class="icon-class" v-if="!isExpanded" type="ios-arrow-back"/>
17
+ </a>
18
+ <transition name="draw" @before-enter="beforeFlowInfoEnter" @enter="flowInfoEnter"
19
+ @before-leave="beforeFlowInfoLeave" @leave="flowInfoLeave">
20
+ <lamboIndicatorCard v-if="isExpanded" class="portrait-lambo-indicator-card" :style="{width: portraitWidth + 'px', float: 'right'}" :hasExtend="false">
21
+ <div slot="content-title">流程信息</div>
22
+ <a v-if="!isDetail" @click="auditShow = !auditShow">
23
+ <Title v-if="!handleButtons || handleButtons.includes('auditOpinion') || handleButtons.includes('attachmentFile')">
24
+ <a style="color: #989898">
25
+ <Icon v-if="auditShow" type="ios-arrow-down"/>
26
+ <Icon v-if="!auditShow" type="ios-arrow-up"/>
27
+ 审批信息
28
+ </a>
29
+ </Title>
30
+ </a>
31
+ <transition v-if="!isDetail" name="draw" @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave" @leave="leave">
32
+ <div class="box" v-show="auditShow">
33
+ <Form ref="auditOpinion" justify="center" :label-width="100" :model="form"
34
+ v-if="!handleButtons || handleButtons.includes('auditOpinion')"
35
+ style="margin: 10px 0 0 10px;" :rules="ruleValidate">
36
+ <FormItem label="审批意见:" prop="auditOpinion" >
37
+ <AuditOpinion v-model="form.auditOpinion" :attachment-file="handleButtons.includes('attachmentFile')"
38
+ :attachmentdata="fileList" :smart-flow-server-context="smartFlowServerContext"></AuditOpinion>
39
+ </FormItem>
40
+ </Form>
41
+ <Form ref="auditOpinion" justify="center" :label-width="100"
42
+ v-if="handleButtons && !handleButtons.includes('auditOpinion') && handleButtons.includes('attachmentFile')"
43
+ style="margin: 10px 0 0 10px;">
44
+ <FormItem style="min-height: 70px">
45
+ <Tooltip placement="bottom" max-width="200">
46
+ <div style="font-size: smaller" slot="content">支持扩展名:.pdf .doc .docx .txt .xls .xlsx .jpg .jpeg .png .gif</div>
47
+ <UploadFile @upload-result="uploadFile" :multiple="true"
48
+ :oss-server-context="smartFlowServerContext" :oss-file-put-url="ossFilePutUrl"></UploadFile>
49
+ </Tooltip>
50
+ </FormItem>
51
+ </Form>
52
+ </div>
53
+ </transition>
54
+ <a v-if="isDetail && hisAuditOpinion[0].auditOpinion" @click="auditShow = !auditShow">
55
+ <Title v-if="!handleButtons || handleButtons.includes('auditOpinion') || handleButtons.includes('attachmentFile')">
56
+ <a style="color: #989898">
57
+ <Icon v-if="auditShow" type="ios-arrow-down"/>
58
+ <Icon v-if="!auditShow" type="ios-arrow-up"/>
59
+ 审批信息
60
+ </a>
61
+ </Title>
62
+ </a>
63
+ <transition v-if="isDetail && hisAuditOpinion[0].auditOpinion" name="draw" @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave" @leave="leave">
64
+ <div class="box" v-show="auditShow">
65
+ <Form ref="auditOpinion" justify="center" :model="form"
66
+ v-if="!handleButtons || handleButtons.includes('auditOpinion')"
67
+ style="margin: 10px 0 0 10px;" :rules="ruleValidate">
68
+ <FormItem style="margin-left: -60px">
69
+ <Card v-for="(item, index) in hisAuditOpinion" :key="index">
70
+ <Row>
71
+ <Col span="12" style="word-wrap: break-word">{{ item.auditOpinion }}</Col>
72
+ <Col span="2"></Col>
73
+ <Col span="10">{{ item.auditTime }}</Col>
74
+ </Row>
75
+ </Card>
76
+ </FormItem>
77
+ </Form>
78
+ </div>
79
+ </transition>
80
+ <a @click="historyShow = !historyShow">
81
+ <Title v-if="!handleButtons || handleButtons.includes('auditHistory')">
82
+ <a style="color: #989898">
83
+ <Icon v-if="historyShow" type="ios-arrow-down"/>
84
+ <Icon v-if="!historyShow" type="ios-arrow-up"/>
85
+ 审批记录
86
+ </a>
87
+ </Title>
88
+ </a>
89
+ <transition name="draw" @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave" @leave="leave">
90
+ <div class="box" v-show="historyShow">
91
+ <Card class="process-history" :style="processHistoryHeight" dis-hover :bordered="false"
92
+ v-if="!handleButtons || handleButtons.includes('auditHistory')">
93
+ <processHistory :portrait-width="portraitWidth" :list="processHistory" :done-page="isDetail"
94
+ :smart-flow-server-context="smartFlowServerContext"></processHistory>
95
+ </Card>
96
+ </div>
97
+ </transition>
98
+
99
+ <a @click="attachListShow = !attachListShow">
100
+ <Title v-if="(!handleButtons || handleButtons.includes('attachmentFile')) && attachmentList.length > 0">
101
+ <a style="color: #989898">
102
+ <Icon v-if="attachListShow" type="ios-arrow-down"/>
103
+ <Icon v-if="!attachListShow" type="ios-arrow-up"/>
104
+ 查看附件
105
+ </a>
106
+ </Title>
107
+ </a>
108
+ <transition name="draw" @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave" @leave="leave">
109
+ <div class="box" v-show="(!handleButtons || handleButtons.includes('attachmentFile')) && attachmentList.length > 0 && attachListShow">
110
+ <div v-for="(item, index) in attachmentList" :key="index">
111
+ <Card dis-hover class="attach-card">
112
+ <List item-layout="vertical">
113
+ <ListItem style="margin-top: -8px">
114
+ <Row style="display: flex; align-items: center;">
115
+ <!-- 左边:图片 -->
116
+ <Col span="4" style="margin-top: -25px">
117
+ <avatar v-if="item.fileType === 'image'" icon="ios-image-outline" class="attach-avatar" style="background-color: #005aff" :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
118
+ :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
119
+ <avatar v-else-if="item.fileType === 'doc'" icon="ios-document-outline" class="attach-avatar" style="background-color: #005aff" :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
120
+ :size="portraitWidth >= 600 ? 'middle' : 'small'">
121
+ </avatar>
122
+ <avatar v-else-if="item.fileType === 'xlsx'" icon="ios-document-outline" class="attach-avatar" style="background-color: #19be6b" :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
123
+ :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
124
+ <avatar v-else-if="item.fileType === 'pdf'" icon="ios-document-outline" class="attach-avatar" style="background-color: #ed4014" :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
125
+ :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
126
+ <avatar v-else icon="ios-document-outline" class="attach-avatar" :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
127
+ :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
128
+ </Col>
129
+ <!-- 右边:附件信息 -->
130
+ <Col span="20">
131
+ <Row>
132
+ <tooltip>
133
+ <span class="attach-name-style"> {{ item.attachName }}</span>
134
+ <div slot="content" style="white-space: normal"> {{ item.attachName }}</div>
135
+ </tooltip>
136
+ </Row>
137
+ <Row style="margin-top: 3px">
138
+ <span style="color: #005aff; font-size: 13px;">{{ item.uploadUserName }}</span>
139
+ <Divider style="background-color:#808695;height: 1em;margin: 4px 9px 0 6px;"
140
+ type="vertical"/>
141
+ <span style="color: #808695;font-size: 13px"
142
+ >{{ showTaskNode(item.taskId) }}</span>
143
+ </Row>
144
+ <Row style="margin-bottom: -10px; margin-top: 10px">
145
+ <template>
146
+ <Button @click="getAttach(item)" size="small">下载</Button>
147
+ <Button v-if="item.showPreview" ghost type="primary" @click="preViewAttach(item)"
148
+ style="margin-left: 10px" size="small">预览
149
+ </Button>
150
+ </template>
151
+ </Row>
152
+ </Col>
153
+ </Row>
154
+
155
+ </ListItem>
156
+ </List>
157
+ </Card>
158
+ </div>
159
+ </div>
160
+ </transition>
161
+ <Modal title="查看附件" v-model="modalVisible" fullscreen scrollable :mask="false">
162
+ <img :src="imageUrl" v-if="modalVisible" alt="" style="width: 100%">
163
+ <div slot="footer">
164
+ <Button type="primary" @click="modalVisible = false">关闭</Button>
165
+ </div>
166
+ </Modal>
167
+ <Modal title="查看附件" v-model="modalDocx" fullscreen scrollable :mask="false">
168
+ <div ref="file" ></div>
169
+ </Modal>
170
+ <Modal v-model="modal1" title="选择节点"
171
+ @on-cancel="cancel"
172
+ @on-ok="ok">
173
+ <Table border
174
+ :data="allNode"
175
+ :columns="nodeColumn"
176
+ highlight-row
177
+ @on-current-change="selectNode">
178
+ </Table>
179
+ </Modal>
180
+ <assigneeBox ref="assigneeHelpBox" :executionCompleted="executionCompleted" @update-selected="handleSelectedUser"
181
+ :data="assigneeBoxData" :smart-flow-server-context="smartFlowServerContext" :upms-server-context="upmsServerContext"/>
182
+ <Modal v-model="modalBoxShow" width="1000" title="流程跟踪图">
183
+ <Workflow_Diagram ref="processTrace" :instanceId="process.instanceId" :applyId="process.applyId"
184
+ :procId="process.procId"
185
+ :tableData="process.tableData" :hisAudit="hisAudit"
186
+ :smart-flow-server-context="smartFlowServerContext">
187
+ </Workflow_Diagram>
188
+ </Modal>
189
+ </lamboIndicatorCard>
190
+ </transition>
191
+ <template slot="page-footer">
192
+ <div>
193
+ <slot name="footer-button"></slot>
194
+ <Button style="margin-left: 10px;" v-if="(!handleButtons || handleButtons.includes('auditTo70')) && !isDetail"
195
+ :disabled="disable" :loading="loading" @click="audit('70')">驳回到原点
196
+ </Button>
197
+ <Button style="margin-left: 10px;" v-if="(!handleButtons || handleButtons.includes('auditTo40')) && !isDetail"
198
+ :disabled="disable" :loading="loading" @click="audit('40')">驳回到上一级
199
+ </Button>
200
+ <Button style="margin-left: 10px;" v-if="(!handleButtons || handleButtons.includes('auditTo90')) && !isDetail"
201
+ :disabled="disable" :loading="loading" @click="audit('90')">驳回指定节点
202
+ </Button>
203
+ <Button style="margin-left: 10px;" v-if="(!handleButtons || handleButtons.includes('auditTo80')) && !isDetail"
204
+ :disabled="disable" :loading="loading" @click="audit('80')">跳转指定节点
205
+ </Button>
206
+ <Button style="margin-left: 10px;" v-if="(!handleButtons || handleButtons.includes('auditTo82')) && !isDetail"
207
+ :disabled="disable" :loading="loading" @click="audit('82')">指定他人处理
208
+ </Button>
209
+ <Button style="margin-left: 10px;" v-if="(!handleButtons || handleButtons.includes('auditTo50')) && !isDetail"
210
+ :disabled="disable" :loading="loading" @click="audit('50')">直接结束流程
211
+ </Button>
212
+ <Button style="margin-left: 10px;" v-if="!handleButtons || handleButtons.includes('processTrace')"
213
+ @click="processPrint" >流程跟踪图</Button>
214
+ <Button style="margin-left: 10px;" v-if="(!handleButtons || handleButtons.includes('auditTo30')) && !isDetail"
215
+ :disabled="disable" :loading="loading" type="primary" @click="audit('30')">通过
216
+ </Button>
217
+ </div>
218
+ </template>
219
+ </LamboPageContainer>
220
+ </template>
221
+
222
+
223
+ <script>
224
+ import LamboPageContainer from '@lambo-design/page-container'
225
+ import LamboIndicatorCard from '@lambo-design/indicator-card'
226
+ import Workflow_Diagram from './workflow-diagram'
227
+ import ajax from "@lambo-design/shared/utils/ajax";
228
+ import bus from '@lambo-design/shared/utils/bus';
229
+ import Title from "./components/title";
230
+ import processHistory from "./components/history";
231
+ import assigneeBox from "./components/assignee-box";
232
+ import LamboPagingTable from "@lambo-design/paging-table";
233
+ import AuditOpinion from "./components/opinion";
234
+ import axios from "axios";
235
+ import UploadFile from "@lambo-design/upload-file";
236
+ import {timestampToTime} from "@lambo-design/shared/utils/date";
237
+
238
+ // 引入docx-preview插件
239
+ let docx = require('docx-preview');
240
+
241
+
242
+ export default {
243
+ props: {
244
+ isDetail: {
245
+ type: Boolean,
246
+ required: false,
247
+ default: false
248
+ },
249
+ width: {
250
+ type: Number,
251
+ required: false,
252
+ default: 400
253
+ },
254
+ procId: {
255
+ type: String,
256
+ required: true,
257
+ },
258
+ taskNode: {
259
+ type: String,
260
+ required: true,
261
+ },
262
+ applyId: {
263
+ type: String,
264
+ required: true,
265
+ },
266
+ //业务表单保存方法
267
+ businessFormSave: {
268
+ type: Function,
269
+ required: false
270
+ },
271
+ //按钮执行完毕回调方法
272
+ executionCompleted: {
273
+ type: Function,
274
+ required: false,
275
+ },
276
+ title:{
277
+ type: String,
278
+ default: "流程办理"
279
+ },
280
+ smartFlowServerContext: {
281
+ type: String,
282
+ default: '/api/smart-flow-server',
283
+ },
284
+ upmsServerContext: {
285
+ type: String,
286
+ default: '/api/upms-server',
287
+ },
288
+ },
289
+ components: {
290
+ Title,
291
+ LamboPageContainer,
292
+ Workflow_Diagram,
293
+ processHistory,
294
+ assigneeBox,
295
+ LamboPagingTable,
296
+ AuditOpinion,
297
+ LamboIndicatorCard,
298
+ UploadFile
299
+ },
300
+ data() {
301
+ return {
302
+ isExpanded: true,
303
+ portraitWidth: 0,
304
+ requestSuccessCodes: [200, "200"],
305
+ auditShow: true,
306
+ historyShow: true,
307
+ attachListShow: true,
308
+ attachmentList: [],
309
+ modalVisible: false,
310
+ modalDocx: false,
311
+ imageUrl: '',
312
+ assigneeBoxData: {},
313
+ selectedUserId: '',
314
+ targetTaskNode: '',
315
+ allNode: [],
316
+ auditParams: {},
317
+ modal1: false,
318
+ modalBoxShow: false,
319
+ hisNode: [],
320
+ processHistory: [],
321
+ ruleValidate: {
322
+ auditOpinion: [{required: true, trigger: "blur", message: "审批意见不能为空"}]
323
+ },
324
+ form: {
325
+ auditOpinion: '',
326
+ },
327
+ loading: false,
328
+ disable: false,
329
+ instanceId: '',
330
+ taskId: '',
331
+ handleButtons: [],
332
+ auditResult: '',
333
+ custChange: 'auditInfo',
334
+ auditInfo: "auditInfo",
335
+ auditProcess: "auditProcess",
336
+ fileList: [],
337
+ ossFilePutUrl: '/manage/oss/file/put',
338
+ hisAudit: [],
339
+ hisAuditOpinion: [{
340
+ auditOpinion: '',
341
+ auditTime: '',
342
+ }],
343
+ datas: {
344
+ orgName: "",
345
+ orgId: ""
346
+ },
347
+ editForm: {
348
+ approvalCost: '',
349
+ cost: '',
350
+ activityDate: []
351
+ },
352
+ process: {
353
+ tableData: [],
354
+ instanceId: '',
355
+ applyId: '',
356
+ procId: ''
357
+ },
358
+ handleButtonsNames: {
359
+ '30': '同意',
360
+ '70': '驳回原点',
361
+ '40': '驳回上一节点',
362
+ '90': '驳回指定节点',
363
+ '80': '跳转指定节点',
364
+ '82': '转办',
365
+ '50': '人工终止'
366
+ },
367
+ }
368
+
369
+ },
370
+
371
+ mounted() {
372
+ this.getWidth()
373
+ if (this.procId){
374
+ this.initData()
375
+ }
376
+
377
+ },
378
+ computed: {
379
+ processHistoryHeight(){
380
+ let str = '';
381
+ const hasAuditOpinion = !this.handleButtons || this.handleButtons.includes('auditOpinion')
382
+ const hasAttachmentFile = (!this.handleButtons || this.handleButtons.includes('attachmentFile')) && this.attachmentList.length > 0
383
+ const isDetail = this.isDetail && this.hisAuditOpinion[0].auditOpinion
384
+ if (hasAuditOpinion && !hasAttachmentFile && !isDetail){
385
+ str+= "height: 43vh"
386
+ } else if (hasAuditOpinion && hasAttachmentFile && !isDetail){
387
+ str+= "height: 40vh"
388
+ } else {
389
+ str+= "height: 60vh"
390
+ }
391
+ return str;
392
+ },
393
+ nodeColumn: function () {
394
+ let column = []
395
+ column.push({title: '序号', type: 'index', width: 70, align: 'center', fixed: 'left'});
396
+ column.push({title: '节点名称', key: 'taskName', minWidth: 150, align: 'center', fixed: 'left'})
397
+
398
+ column.push({
399
+ title: '节点状态', key: 'auditResult', minWidth: 150, align: 'center', fixed: 'left',
400
+ render: (h, params) => {
401
+ if (params.row.taskNode == this.taskNode) {
402
+ return h('div', [
403
+ h('tag', {
404
+ props: {
405
+ color: '#ff9900'
406
+ }
407
+ }, '当前节点')
408
+ ])
409
+ } else if (!params.row.auditResult) {
410
+ return h('div', [
411
+ h('tag', {
412
+ props: {
413
+ color: '#ff9900'
414
+ }
415
+ }, '未审批')
416
+ ])
417
+ } else {
418
+ if (params.row.auditResult == '30' && params.row.taskNode != this.taskNode) {
419
+ return h('div', [
420
+ h('tag', {
421
+ props: {
422
+ color: '#19be6b'
423
+ }
424
+ }, '已审批通过')
425
+ ])
426
+ } else if (params.row.auditResult == '40' && params.row.taskNode != this.taskNode) {
427
+ return h('div', [
428
+ h('tag', {
429
+ props: {
430
+ color: '#ed4014'
431
+ }
432
+ }, '已驳回到上一节点')
433
+ ])
434
+ } else if (params.row.auditResult == '60' && params.row.taskNode != this.taskNode) {
435
+ return h('div', [
436
+ h('tag', {
437
+ props: {
438
+ color: '#ed4014'
439
+ }
440
+ }, '已撤回')
441
+ ])
442
+ } else if (params.row.auditResult == '80' && params.row.taskNode != this.taskNode) {
443
+ return h('div', [
444
+ h('tag', {
445
+ props: {
446
+ color: '#19be6b'
447
+ }
448
+ }, '已跳转到指定节点')
449
+ ])
450
+ } else if (params.row.auditResult == '80' && params.row.taskNode != this.taskNode) {
451
+ return h('div', [
452
+ h('tag', {
453
+ props: {
454
+ color: '#19be6b'
455
+ }
456
+ }, '已驳回到指定节点')
457
+ ])
458
+ }
459
+ }
460
+ }
461
+ })
462
+ column.push({
463
+ title: "操作", width: 100, align: 'center',
464
+ render: (h, params) => {
465
+ return h('div', [
466
+ h('Button', {
467
+ props: {
468
+ type: 'primary',
469
+ size: 'small'
470
+ },
471
+ style: {
472
+ marginRight: '5px'
473
+ },
474
+ on: {
475
+ click: () => {
476
+ this.selectNode(params.row)
477
+ }
478
+ }
479
+ }, '选择')
480
+ ])
481
+ },
482
+ })
483
+ return column
484
+ },
485
+
486
+ },
487
+ provide() {
488
+ return {
489
+ toBeDoneListDoSearch: this.doSearch
490
+ };
491
+ },
492
+ methods: {
493
+ getWidth() {
494
+ if (this.width && this.width < 400) {
495
+ this.portraitWidth = 400
496
+ }
497
+ this.portraitWidth = this.width
498
+ },
499
+ initData(){
500
+ this.getAttachList()
501
+ if (!this.isDetail){
502
+ this.getTodoTaskId()
503
+ } else {
504
+ this.getDoneTaskId()
505
+ }
506
+ this.getHandleButtons()
507
+ this.getHisAudit();
508
+ this.getProcessHistory();
509
+ },
510
+ saveBusinessForm() {
511
+ this.businessFormSave(() => {
512
+ })
513
+ },
514
+ getAttachList() {
515
+ const self = this
516
+ const param = {
517
+ procId: this.procId,
518
+ applyId: this.applyId
519
+ }
520
+ ajax.get(self.smartFlowServerContext + '/manage/processDone/getAttachmentList', {params: param}).then(function (resp) {
521
+ self.attachmentList = resp.data.data.rows
522
+ self.attachmentList.forEach(item => {
523
+ const index = item.fileName.lastIndexOf(".")
524
+ const fileType = item.fileName.substr(index + 1).toLowerCase()
525
+ const imageList = ['jpg', 'gif', 'png', 'svg']
526
+ const docList = ['doc', 'docx']
527
+ const zipList = ['rar', 'zip']
528
+ const typeList = ['jpg', 'gif', 'png', 'docx']
529
+ item.fileType = imageList.indexOf(fileType) !== -1 ? 'image' : docList.indexOf(fileType) !== -1 ? 'doc' : zipList.indexOf(fileType) !== -1 ? 'zip' : fileType
530
+ item.showPreview = typeList.indexOf(fileType) !== -1
531
+ })
532
+ }).catch(err => {
533
+ console.log(err);
534
+ })
535
+ },
536
+ getTodoTaskId() {
537
+ const self = this
538
+ let param = {
539
+ procId: this.procId,
540
+ applyId: this.applyId,
541
+ taskNode:this.taskNode
542
+ }
543
+ ajax.get(self.smartFlowServerContext + "/manage/processTodo/list", {params: param}).then(function (resp) {
544
+ if (resp.data.code === '200') {
545
+ self.taskId = resp.data.data.rows[0].taskId
546
+ self.instanceId = resp.data.data.rows[0].procInstanceId
547
+ } else {
548
+ self.$Message.error(resp.data.message)
549
+ }
550
+ }).catch((err) => {
551
+ console.log(err)
552
+ })
553
+ },
554
+ getDoneTaskId() {
555
+ const self = this
556
+ let param = {
557
+ procId: this.procId,
558
+ applyId: this.applyId,
559
+ taskNode:this.taskNode
560
+ }
561
+ ajax.get(self.smartFlowServerContext + "/manage/processDone/getDoneDetail", {params: param}).then(function (resp) {
562
+ if (resp.data.code === '200') {
563
+ let rows = resp.data.data.rows
564
+ if (rows.length > 0) {
565
+ self.hisAuditOpinion = []
566
+ let taskList = resp.data.data.rows
567
+ taskList.forEach(item => {
568
+ self.hisAuditOpinion.push({
569
+ auditOpinion: item.auditComment,
570
+ auditTime: timestampToTime(item.auditDate)
571
+ })
572
+ })
573
+ self.taskId = taskList[0].taskId
574
+ self.instanceId = taskList[0].procInstanceId
575
+ } else {
576
+ ajax.get(self.smartFlowServerContext + "/manage/processTodo/list", {params: param}).then(function (todoResp) {
577
+ if (todoResp.data.code === '200') {
578
+ self.taskId = todoResp.data.data.rows[0].taskId
579
+ self.instanceId = todoResp.data.data.rows[0].procInstanceId
580
+ } else {
581
+ self.$Message.error(todoResp.data.message)
582
+ }
583
+ }).catch((err) => {
584
+ console.log(err)
585
+ })
586
+ }
587
+ } else {
588
+ self.$Message.error(resp.data.message)
589
+ }
590
+ }).catch((err) => {
591
+ console.log(err)
592
+ })
593
+ },
594
+ getHandleButtons() {
595
+ const self = this
596
+ let param = {
597
+ procId: this.procId,
598
+ taskNode: this.taskNode
599
+ }
600
+ ajax.post(self.smartFlowServerContext + '/manage/approvalCenter/getNodeData', param).then(function (resp) {
601
+ if (resp.data.code === '200') {
602
+ self.handleButtons = resp.data.data[0].handleButtons
603
+ } else {
604
+ self.$Message.error(resp.data.message)
605
+ }
606
+ }).catch((err) => {
607
+ console.log(err)
608
+ })
609
+ },
610
+ handleSaveResult(saveResult) {
611
+ if (saveResult) {
612
+ this.executeButtonAction((execResult, instanceId, taskIds, auditResult, curTaskId) => {
613
+ if (this.executionCompleted) {
614
+ this.executionCompleted(execResult, instanceId, taskIds, auditResult, curTaskId);
615
+ }
616
+ });
617
+ } else {
618
+ console.error('保存失败');
619
+ }
620
+ },
621
+ executeButtonAction(callback) {
622
+ const self = this;
623
+ let auditResult = {
624
+ code: self.auditResult,
625
+ name: self.handleButtonsNames[self.auditResult]
626
+ }
627
+ if (self.auditResult === '82') {
628
+ self.assigneeBoxData = self.auditParams
629
+ self.assigneeBoxData.auditResultName = self.handleButtonsNames[self.auditResult]
630
+ self.assigneeBoxData.instanceId = self.instanceId
631
+ self.$refs.assigneeHelpBox.toggleShowHelpBox();
632
+ } else if (self.auditResult === '80') {
633
+ self.getNodesBehind()
634
+ } else if (self.auditResult === '90') {
635
+ self.getAllPreNodes()
636
+ } else if (self.auditResult === '40') {
637
+ self.loading = true
638
+ self.disable = true
639
+ let url = self.smartFlowServerContext + '/manage/processTodo/getPreNode'
640
+ ajax.post(url, self.auditParams).then(function (resp) {
641
+ let result = resp.data
642
+ if (result.code == '30010') {
643
+ self.$Modal.confirm({
644
+ title: "提示",
645
+ content: result.message,
646
+ onOk: () => {
647
+ self.auditParams.auditResult = '70'
648
+ let url = self.smartFlowServerContext + '/manage/processTodo/audit'
649
+ ajax.post(url, self.auditParams).then(function (resp) {
650
+ let result = resp.data
651
+ if (result.code == '200') {
652
+ self.loading = false
653
+ self.disable = false
654
+ self.$Message.success(result.message);
655
+ //后端没有返回数据
656
+ callback(true, null, null, auditResult, self.taskId);
657
+ bus.$emit('triggerTimer')
658
+ } else {
659
+ self.loading = false
660
+ self.disable = false
661
+ self.$Message.error(result.message)
662
+ callback(false, null, null, auditResult, self.taskId);
663
+ }
664
+ bus.$emit('triggerTimer')
665
+ })
666
+ },
667
+ onCancel: () => {
668
+ self.loading = false
669
+ self.disable = false
670
+ }
671
+ })
672
+ } else {
673
+ self.loading = true
674
+ self.disable = true
675
+ let url = self.smartFlowServerContext + '/manage/processTodo/audit'
676
+ ajax.post(url, self.auditParams).then(function (resp) {
677
+ let result = resp.data
678
+ if (result.code == '200') {
679
+ self.loading = false
680
+ self.disable = false
681
+ self.$Message.success(result.message);
682
+ if (result.data){
683
+ let taskIds = result.data.map(item => item.id).join(',');
684
+ callback(true, result.data[0].processInstanceId, taskIds, auditResult, self.taskId)
685
+ } else {
686
+ callback(true, null, null)
687
+ }
688
+ } else {
689
+ self.loading = false
690
+ self.disable = false
691
+ self.$Message.error(result.message)
692
+ callback(false, null, null, auditResult, self.taskId);
693
+ }
694
+ bus.$emit('triggerTimer')
695
+ })
696
+ }
697
+ })
698
+ } else {
699
+ self.loading = true
700
+ self.disable = true
701
+ let url = self.smartFlowServerContext + '/manage/processTodo/audit'
702
+ ajax.post(url, self.auditParams).then(function (resp) {
703
+ let result = resp.data
704
+ if (result.code == '200') {
705
+ self.loading = false
706
+ self.disable = false
707
+ if (result.data){
708
+ let taskIds = result.data.map(item => item.id).join(',');
709
+ callback(true, result.data[0].processInstanceId, taskIds, auditResult, self.taskId)
710
+ } else {
711
+ callback(true, null, null, auditResult, self.taskId)
712
+ }
713
+ self.$Message.success(result.message);
714
+ } else if (result.code == '20002') {
715
+ // 流程结束
716
+ self.loading = false
717
+ self.disable = false
718
+ callback(true, '流程已结束', '流程已结束', auditResult, self.taskId)
719
+ self.$Message.success(result.message)
720
+ } else {
721
+ self.loading = false
722
+ self.disable = false
723
+ callback(false, null, null, auditResult, self.taskId)
724
+ self.$Message.error(result.message)
725
+ }
726
+ bus.$emit('triggerTimer')
727
+ })
728
+
729
+ }
730
+ },
731
+
732
+ doSearch() {
733
+ //不需要实现,是子组件assigneeBox要求使用父组件的这个方法
734
+ },
735
+ tabsChange(tab) {
736
+ console.log(tab)
737
+ },
738
+ audit: function (auditResult) {
739
+ let self = this
740
+ self.auditResult = auditResult
741
+ self.submit()
742
+ },
743
+ getAttach(row) {
744
+ window.open(this.smartFlowServerContext + "/manage/oss/file/get/" + row.fileId, "_blank");
745
+ },
746
+ preViewAttach(row) {
747
+ let reg = /\.(gif|jpg|jpeg|bmp|png|PNG)$/
748
+ let regs = /\.(pdf)$/
749
+ if (reg.test(row.fileName)) {
750
+ let url = this.smartFlowServerContext + "/manage/oss/file/get/" + row.fileId;
751
+ this.imgPreview(url);
752
+ } else if (regs.test(row.fileName)) {
753
+ window.open(this.smartFlowServerContext + "/manage/oss/file/getFileStream?fileId=" + row.fileId, "_blank");
754
+ } else {
755
+ this.modalDocx = true
756
+ axios({
757
+ method: 'get',
758
+ responseType: 'blob', // 因为是流文件,所以要指定blob类型
759
+ url: this.smartFlowServerContext + "/manage/oss/file/get/" + row.fileId// 一个word下载文件的接口
760
+ }).then(({data}) => {
761
+ docx.renderAsync(data, this.$refs.file, null, {
762
+ className: "docx", //默认和文档样式类的类名/前缀
763
+ inWrapper: true, //启用围绕文档内容呈现包装器
764
+ ignoreWidth: false, //禁用页面的渲染宽度
765
+ ignoreHeight: false, //禁用页面的渲染高度
766
+ ignoreFonts: false, //禁用字体渲染
767
+ breakPages: true, //在分页符上启用分页
768
+ ignoreLastRenderedPageBreak: true, //在lastRenderedPageBreak元素上禁用分页
769
+ experimental: false, //启用实验功能(制表符停止计算)
770
+ trimXmlDeclaration: true, //如果为true,则在解析之前将从xml文档中删除xml声明
771
+ useBase64URL: false, //如果为true,图像、字体等将转换为base 64 URL,否则使用URL.createObjectURL
772
+ useMathMLPolyfill: false, //包括用于铬、边等的MathML多填充。
773
+ showChanges: false, //启用文档更改的实验渲染(插入/删除)
774
+ debug: false, //启用额外的日志记录
775
+ })
776
+ }
777
+ )
778
+ }
779
+ },
780
+ imgPreview(url) {
781
+ this.imageUrl = url;
782
+ this.modalVisible = true;
783
+ },
784
+ submit() {
785
+ let self = this;
786
+
787
+ self.auditParams = {
788
+ procId: self.procId,
789
+ applyId: self.applyId,
790
+ taskId: self.taskId,
791
+ auditOpinion: self.form.auditOpinion,
792
+ fileListStr: JSON.stringify(self.fileList),
793
+ auditResult: self.auditResult,
794
+ params: JSON.stringify(self.datas),
795
+ targetTaskNode: self.targetTaskNode,
796
+ selectedUserId: self.selectedUserId,
797
+ }
798
+ if (self.auditResult == '' || self.auditResult == null) {
799
+ self.$Message.error("请选择审批结果!");
800
+ return;
801
+ }
802
+ if (self.form.auditOpinion == '' || self.form.auditOpinion == null) {
803
+ if (!self.handleButtons || self.handleButtons.includes('auditOpinion')) {
804
+ self.$Message.error("请输入审批意见!")
805
+ return;
806
+ } else {
807
+ self.auditParams.auditOpinion = self.handleButtonsNames[self.auditResult];
808
+ }
809
+ }
810
+
811
+ self.businessFormSave ? self.businessFormSave(self.handleSaveResult) : self.handleSaveResult(true)
812
+ },
813
+
814
+ //打印流程图信息
815
+ processPrint() {
816
+ let self = this
817
+ let params = {
818
+ applyId: self.applyId,
819
+ instanceId: self.instanceId,
820
+ procId: self.procId,
821
+ taskId: self.taskId,
822
+ }
823
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/getPrintData', {params: params}).then(function (resp) {
824
+ let result = resp.data.data
825
+ if (resp.data.code === '200') {
826
+ let tableData = result
827
+ self.process.tableData = tableData
828
+ self.process.applyId = self.applyId
829
+ self.process.instanceId = self.instanceId
830
+ self.process.procId = self.procId
831
+ self.datas.orgId = tableData[0].orgId
832
+ self.datas.orgName = tableData[0].orgName
833
+ self.modalBoxShow = true
834
+ }
835
+ })
836
+ },
837
+
838
+ getHisAudit() {
839
+ let self = this
840
+ let params = {
841
+ applyId: self.applyId,
842
+ instanceId: self.instanceId,
843
+ procId: self.procId,
844
+ taskId: self.taskId
845
+ }
846
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/getHisAudit', {params: params}).then(function (resp) {
847
+ if (resp.data.code === '200') {
848
+ self.hisAudit = resp.data.data
849
+ let uniqueDataMap = {};
850
+ self.hisAudit.forEach((item) => {
851
+ uniqueDataMap[item["taskNode"]] = item;
852
+ })
853
+ self.hisNode = Object.values(uniqueDataMap);
854
+
855
+ }
856
+ })
857
+ },
858
+ showTaskNode(taskId) {
859
+ if (this.processHistory.length > 0) {
860
+ let task = null
861
+ this.processHistory.some(itemList => {
862
+ task = itemList.find(item => item.taskId === taskId);
863
+ return task !== undefined;
864
+ });
865
+ return task ? task.taskName : ''
866
+ }
867
+ return ''
868
+ },
869
+ getProcessHistory() {
870
+ let self = this
871
+ let params = {
872
+ applyId: self.applyId,
873
+ instanceId: self.instanceId,
874
+ procId: self.procId,
875
+ taskId: self.taskId
876
+ }
877
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/getProcessHis', {params: params}).then(function (resp) {
878
+ if (resp.data.code === '200') {
879
+ self.processHistory = resp.data.data
880
+ }
881
+ })
882
+ },
883
+ cancel() {
884
+ this.modal = false
885
+ this.auditResult = '';
886
+ },
887
+ ok() {
888
+ this.modal = false
889
+ let auditResult = {
890
+ code: self.auditResult,
891
+ name: self.handleButtonsNames[self.auditResult]
892
+ }
893
+ if (this.targetTaskNode == '' || this.targetTaskNode == null) {
894
+ this.auditResult = '';
895
+ this.$Message.error("请选择审批节点!");
896
+ } else {
897
+ let self = this;
898
+
899
+ self.auditParams = {
900
+ procId: self.procId,
901
+ applyId: self.applyId,
902
+ taskId: self.taskId,
903
+ auditOpinion: self.form.auditOpinion,
904
+ fileListStr: JSON.stringify(self.fileList),
905
+ auditResult: self.auditResult,
906
+ params: JSON.stringify(self.datas),
907
+ targetTaskNode: self.targetTaskNode,
908
+ selectedUserId: self.selectedUserId,
909
+ }
910
+ self.loading = true
911
+ self.disable = true
912
+
913
+ let url = self.smartFlowServerContext + '/manage/processTodo/audit'
914
+ ajax.post(url, self.auditParams).then(function (resp) {
915
+ let result = resp.data
916
+ if (result.code === '200') {
917
+ setTimeout(() => {
918
+ self.loading = false
919
+ self.disable = false
920
+ self.$Message.success("审批成功");
921
+ if (self.executionCompleted) {
922
+ let taskIds = result.data.map(item => item.id).join(',');
923
+ self.executionCompleted(true, result.data[0].processInstanceId, taskIds, auditResult, self.taskId)
924
+ }
925
+ bus.$emit('triggerTimer')
926
+ }, 500)
927
+ } else {
928
+ self.loading = false
929
+ self.disable = false
930
+ self.$Message.error(result.message)
931
+ if (self.executionCompleted) {
932
+ self.executionCompleted(false, null, null);
933
+ }
934
+ }
935
+ })
936
+ }
937
+ },
938
+ selectNode(currentRow, oldCurrentRow) {
939
+ let self = this
940
+ self.targetTaskNode = currentRow.taskNode
941
+ },
942
+ getAllPreNodes() {
943
+ let self = this
944
+ let params = {
945
+ processDefId: self.procId,
946
+ taskId: self.taskId,
947
+ }
948
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/getAllPreNodes', {params: params}).then(function (resp) {
949
+ if (resp.data.code === '200') {
950
+ if (resp.data.data.length > 0){
951
+ self.allNode = resp.data.data
952
+ self.modal1 = true
953
+ }else {
954
+ self.$Message.warning('当前流程无前序节点')
955
+ }
956
+ } else {
957
+ self.$Message.error(resp.data.message)
958
+ }
959
+ })
960
+ },
961
+ getNodesBehind() {
962
+ let self = this
963
+ let params = {
964
+ processDefId: self.procId,
965
+ taskId: self.taskId,
966
+ }
967
+ ajax.get(self.smartFlowServerContext + '/manage/processTodo/getNodesBehind', {params: params}).then(function (resp) {
968
+ if (resp.data.code === '200') {
969
+ if (resp.data.data.length > 0){
970
+ self.allNode = resp.data.data
971
+ self.modal1 = true
972
+ }else {
973
+ self.$Message.warning('当前流程无后续节点')
974
+ }
975
+ } else {
976
+ self.$Message.error(resp.data.message)
977
+ }
978
+ })
979
+ },
980
+ handleSelectedUser(userId) {
981
+ this.selectedUserId = userId;
982
+ },
983
+
984
+ //折叠动画效果
985
+ beforeEnter(el) {
986
+ el.style.height = '0';
987
+ },
988
+ enter(el, done) {
989
+ setTimeout(() => {
990
+ el.style.height = el.scrollHeight + 'px';
991
+ }, 0);
992
+
993
+ el.addEventListener('transitionend', done);
994
+ },
995
+ beforeLeave(el) {
996
+ el.style.height = el.scrollHeight + 'px';
997
+ },
998
+ leave(el, done) {
999
+ setTimeout(() => {
1000
+ el.style.height = '0';
1001
+ }, 0);
1002
+
1003
+ el.addEventListener('transitionend', done);
1004
+ },
1005
+
1006
+ beforeFlowInfoEnter(el) {
1007
+ el.style.transform = 'translateX(100%)';
1008
+ },
1009
+ flowInfoEnter(el, done) {
1010
+ const transitionDuration = 0.5;
1011
+ el.style.transition = `transform ${transitionDuration}s`;
1012
+ el.style.transform = 'translateX(0)';
1013
+ el.addEventListener('transitionend', done);
1014
+ },
1015
+ beforeFlowInfoLeave(el) {
1016
+ el.style.transform = 'translateX(0)';
1017
+ },
1018
+ flowInfoLeave(el, done) {
1019
+ const transitionDuration = 0.5;
1020
+ el.style.transition = `transform ${transitionDuration}s`;
1021
+ el.style.transform = 'translateX(100%)';
1022
+ el.addEventListener('transitionend', done);
1023
+ },
1024
+ uploadFile(file){
1025
+ const self = this;
1026
+ self.fileList = []
1027
+ file.forEach(item => {
1028
+ self.fileList.push({
1029
+ fileName: item.fileName,
1030
+ fileId: item.fileCode,
1031
+ });
1032
+ })
1033
+ },
1034
+ },
1035
+ watch: {
1036
+ auditOpinionText(label) {
1037
+ this.form.auditOpinion = label;
1038
+ },
1039
+ procId(val) {
1040
+ this.procId = val;
1041
+ this.initData()
1042
+ },
1043
+ }
1044
+ }
1045
+ </script>
1046
+
1047
+ <style lang="less" scoped>
1048
+ @import "./styles/css/index.less";
1049
+ /deep/ .ivu-table-row-highlight td {
1050
+ background-color: #50c1ff !important;
1051
+ color: #fff !important;
1052
+ }
1053
+ /deep/ .ivu-card-body{
1054
+ padding: 10px;
1055
+ }
1056
+ .page-info /deep/ .page-body{
1057
+ overflow-y: hidden;
1058
+ }
1059
+ </style>