@lambo-design-mobile/workflow-approve 1.0.0-beta.2 → 1.0.0-beta.21
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/CHANGELOG.md +109 -1
- package/api.js +62 -6
- package/package.json +3 -3
- package/src/ApprovalNodeCell.vue +115 -0
- package/src/FlowApproval.vue +295 -153
- package/src/FlowBaseList.vue +89 -21
- package/src/FlowNodeCell.vue +116 -0
- package/src/SelectHandle.vue +83 -39
- package/src/SelectHandleCard.vue +19 -6
- package/src/SelectNormalList.vue +111 -0
- package/src/SelectOrganize.vue +216 -0
- package/src/TodoListCard.vue +12 -10
- package/src/WorkflowDiagram.vue +20 -109
- package/src/assets/icon/iconfont.css +11 -3
- package/src/assets/icon/iconfont.js +1 -1
- package/src/assets/icon/iconfont.json +14 -0
- package/src/assets/icon/iconfont.ttf +0 -0
- package/src/assets/icon/iconfont.woff +0 -0
- package/src/assets/icon/iconfont.woff2 +0 -0
- package/src/js/global.js +19 -0
- package/src/tree/Node.vue +190 -0
- package/src/tree/Tree.vue +212 -0
- package/src/tree/util.js +74 -0
package/src/FlowApproval.vue
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<van-tabs ref="tabs" style="padding-bottom: 60px" v-model="active"
|
|
3
|
+
<van-tabs ref="tabs" style="padding-bottom: 60px" v-model="active"
|
|
4
|
+
@click="onTabClick"
|
|
5
|
+
sticky :offset-top="offsetTop"
|
|
6
|
+
animated>
|
|
4
7
|
<slot name="business-content"/>
|
|
5
8
|
<van-tab title="流程信息">
|
|
6
9
|
<div style="padding: 0 10px">
|
|
@@ -15,6 +18,8 @@
|
|
|
15
18
|
v-model="approvalForm.auditOpinion"
|
|
16
19
|
rows="3"
|
|
17
20
|
autosize
|
|
21
|
+
@focus="handleInputFocus"
|
|
22
|
+
:error="approvalError"
|
|
18
23
|
required
|
|
19
24
|
label="审批意见"
|
|
20
25
|
type="textarea"
|
|
@@ -24,16 +29,14 @@
|
|
|
24
29
|
/>
|
|
25
30
|
<div v-if="approvalForm.nextNode!==''">
|
|
26
31
|
<van-cell title="下一环节" :value="approvalForm.nextNode"/>
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<div v-else>
|
|
36
|
-
<van-cell title="下一环节" value="无下一环节"/>
|
|
32
|
+
<div v-if="handleButtons.includes('appointHandler')">
|
|
33
|
+
<van-cell @click="nextNodePopupShow = true" title="办理人员" value-class="approvalForm-value"
|
|
34
|
+
:value="approvalForm.handlingPersonnel">
|
|
35
|
+
<template #right-icon>
|
|
36
|
+
<van-icon name="friends-o" size="16" style="line-height: inherit;padding-left: 5px"/>
|
|
37
|
+
</template>
|
|
38
|
+
</van-cell>
|
|
39
|
+
</div>
|
|
37
40
|
<div class="van-hairline--bottom"></div>
|
|
38
41
|
</div>
|
|
39
42
|
<div v-if="handleButtons.includes('attachmentFile')">
|
|
@@ -59,43 +62,10 @@
|
|
|
59
62
|
<van-collapse-item v-for="(items,index) in processHistory" :key="index" :title="items[0].taskName"
|
|
60
63
|
:name="index">
|
|
61
64
|
<div v-for="(item,index) in items" :key="index" class="record-item">
|
|
62
|
-
<
|
|
63
|
-
<template #icon>
|
|
64
|
-
<div
|
|
65
|
-
v-if="['通过', '跳转指定节点'].includes(getAuditStatus(item.auditResult).text)"
|
|
66
|
-
class="completed-icon">
|
|
67
|
-
<van-icon class="iconfont" class-prefix='icon' :name=getAuditStatus(item.auditResult).icon
|
|
68
|
-
size="30px" color="#fff"/>
|
|
69
|
-
</div>
|
|
70
|
-
<div v-else class="pending-icon">
|
|
71
|
-
<van-icon class="iconfont" class-prefix='icon' :name=getAuditStatus(item.auditResult).icon
|
|
72
|
-
size="30px" color="#fff"/>
|
|
73
|
-
</div>
|
|
74
|
-
</template>
|
|
75
|
-
<template #title>
|
|
76
|
-
<div :style="{ color: getAuditStatus(item.auditResult).color }"
|
|
77
|
-
style="font-size: 16px;font-weight: bold;padding:5px 0;">
|
|
78
|
-
{{ item.auditName[0] }}
|
|
79
|
-
</div>
|
|
80
|
-
<div>{{ item.auditOrganName[0] }}
|
|
81
|
-
<span v-if="item.auditComment" @click="showAuditDetail(item.auditComment)">
|
|
82
|
-
| 审批意见 <van-icon name="comment-circle-o"/>
|
|
83
|
-
</span>
|
|
84
|
-
</div>
|
|
85
|
-
</template>
|
|
86
|
-
<template #label>
|
|
87
|
-
<div>{{ item.startDate }}{{ item.auditDate }}</div>
|
|
88
|
-
</template>
|
|
89
|
-
<template #default>
|
|
90
|
-
<span :style="{ color: getAuditStatus(item.auditResult).color }">{{
|
|
91
|
-
getAuditStatus(item.auditResult).text
|
|
92
|
-
}}</span>
|
|
93
|
-
</template>
|
|
94
|
-
</van-cell>
|
|
65
|
+
<approval-node-cell :node-detail="item" :folding-approval-comments="foldingApprovalComments" />
|
|
95
66
|
<div v-if="index !== items.length - 1" class="van-hairline--bottom"></div>
|
|
96
67
|
</div>
|
|
97
68
|
</van-collapse-item>
|
|
98
|
-
|
|
99
69
|
</van-collapse>
|
|
100
70
|
</div>
|
|
101
71
|
</div>
|
|
@@ -165,7 +135,10 @@
|
|
|
165
135
|
</div>
|
|
166
136
|
</van-popup>
|
|
167
137
|
<div class="custom-bottom-bar">
|
|
168
|
-
<div v-if="!isDetail" class="bar-item" @click="onMore">更多</div>
|
|
138
|
+
<div v-if="!isDetail && getVisibleButtonsCount() > 1" class="bar-item" @click="onMore">更多</div>
|
|
139
|
+
<div v-else-if="!isDetail && getVisibleButtonsCount() === 1" class="bar-item" @click="handleSingleButton()">
|
|
140
|
+
{{ getSingleButtonText() }}
|
|
141
|
+
</div>
|
|
169
142
|
<div class="bar-item" @click="onTrack">流程跟踪</div>
|
|
170
143
|
<div v-if="!isDetail" class="bar-item approve" @click="audit('30')">{{ getAuditButtonStatus(30) }}</div>
|
|
171
144
|
</div>
|
|
@@ -195,57 +168,59 @@
|
|
|
195
168
|
:is-link="true" :arrow-direction="detailsVisible[index] ? 'down' : ''">
|
|
196
169
|
</van-cell>
|
|
197
170
|
<div v-if="detailsVisible[index] && item.personType === 'candidate'">
|
|
198
|
-
<van-
|
|
199
|
-
|
|
200
|
-
</van-
|
|
201
|
-
<van-
|
|
202
|
-
|
|
203
|
-
</van-
|
|
204
|
-
<van-
|
|
205
|
-
|
|
206
|
-
</van-
|
|
207
|
-
<van-
|
|
208
|
-
|
|
209
|
-
</van-
|
|
171
|
+
<van-field @click="handleSelectUserPopupShow(index)" label="候选用户" readonly placeholder="点击选择"
|
|
172
|
+
:value="(item.candidateGroups?.users ?? []).map(user => user.name).join(',')">
|
|
173
|
+
</van-field>
|
|
174
|
+
<van-field @click="handleSelectPositionPopupShow(index)" label="候选岗位" readonly placeholder="点击选择"
|
|
175
|
+
:value="(item.candidateGroups?.positions ?? []).map(position => position.name).join(',')">
|
|
176
|
+
</van-field>
|
|
177
|
+
<van-field @click="handleSelectRolePopupShow(index)" label="候选角色" readonly placeholder="点击选择"
|
|
178
|
+
:value="(item.candidateGroups?.roles ?? []).map(role => role.name).join(',')">
|
|
179
|
+
</van-field>
|
|
180
|
+
<van-field @click="handleSelectOrganizePopupShow(index)" label="候选组织" readonly placeholder="点击选择"
|
|
181
|
+
:value="(item.candidateGroups?.organs ?? []).map(organ => organ.name).join(',')">
|
|
182
|
+
</van-field>
|
|
210
183
|
</div>
|
|
211
|
-
<
|
|
212
|
-
<
|
|
213
|
-
<
|
|
214
|
-
<div style="display: flex; align-items: center; margin-right: 16px;">
|
|
215
|
-
<van-stepper disable-input button-size="22" min="0" v-model="item.remainDay"/>
|
|
216
|
-
<span style="margin-left: 4px;">天</span>
|
|
217
|
-
</div>
|
|
184
|
+
<div v-if="handleButtons.includes('appointTimeoutTime')">
|
|
185
|
+
<van-cell center title="停留时间">
|
|
186
|
+
<template #default>
|
|
218
187
|
<div style="display: flex; align-items: center;">
|
|
219
|
-
<
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
<div style="display: flex; align-items: center;">
|
|
228
|
-
<div style="display: flex; align-items: center; margin-right: 16px;">
|
|
229
|
-
<van-stepper disable-input button-size="22" min="0" v-model="item.inAdvanceDay"/>
|
|
230
|
-
<span style="margin-left: 4px;">天</span>
|
|
188
|
+
<div style="display: flex; align-items: center; margin-right: 16px;">
|
|
189
|
+
<van-stepper disable-input button-size="22" min="0" v-model="item.remainDay"/>
|
|
190
|
+
<span style="margin-left: 4px;">天</span>
|
|
191
|
+
</div>
|
|
192
|
+
<div style="display: flex; align-items: center;">
|
|
193
|
+
<van-stepper disable-input button-size="22" min="0" v-model="item.remainTime"/>
|
|
194
|
+
<span style="margin-left: 4px;">小时</span>
|
|
195
|
+
</div>
|
|
231
196
|
</div>
|
|
197
|
+
</template>
|
|
198
|
+
</van-cell>
|
|
199
|
+
<van-cell title="任务提前">
|
|
200
|
+
<template #default>
|
|
232
201
|
<div style="display: flex; align-items: center;">
|
|
233
|
-
<
|
|
234
|
-
|
|
202
|
+
<div style="display: flex; align-items: center; margin-right: 16px;">
|
|
203
|
+
<van-stepper disable-input button-size="22" min="0" v-model="item.inAdvanceDay"/>
|
|
204
|
+
<span style="margin-left: 4px;">天</span>
|
|
205
|
+
</div>
|
|
206
|
+
<div style="display: flex; align-items: center;">
|
|
207
|
+
<van-stepper disable-input button-size="22" min="0" v-model="item.inAdvanceTime"/>
|
|
208
|
+
<span style="margin-left: 4px;">小时</span>
|
|
209
|
+
</div>
|
|
235
210
|
</div>
|
|
236
|
-
</
|
|
237
|
-
</
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
211
|
+
</template>
|
|
212
|
+
</van-cell>
|
|
213
|
+
<van-field
|
|
214
|
+
readonly
|
|
215
|
+
clickable
|
|
216
|
+
input-align="right"
|
|
217
|
+
name="picker"
|
|
218
|
+
:value="(handleTypeList.find(handleType => handleType.value === item.processing) || {}).label"
|
|
219
|
+
label="处理方式"
|
|
220
|
+
placeholder="点击选择处理方式"
|
|
221
|
+
@click="$set(showPicker, index, true)"
|
|
222
|
+
/>
|
|
223
|
+
</div>
|
|
249
224
|
<van-popup v-model="showPicker[index]" position="bottom">
|
|
250
225
|
<van-picker
|
|
251
226
|
show-toolbar
|
|
@@ -260,9 +235,25 @@
|
|
|
260
235
|
<div class="bar-item approve" @click="handleSelect('select')">确认</div>
|
|
261
236
|
</div>
|
|
262
237
|
</van-popup>
|
|
263
|
-
<van-popup v-model="selectHandlePopupShow" closeable round position="bottom"
|
|
238
|
+
<van-popup v-if="selectHandlePopupShow" v-model="selectHandlePopupShow" closeable round position="bottom"
|
|
264
239
|
:style="{ height: '80%' }" style="background: #f7f8fa">
|
|
265
|
-
<select-handle @selectHandle="handleSelectResult"></select-handle>
|
|
240
|
+
<select-handle title="指定办理人" :multi-select="false" :procType="procType" @selectHandle="handleSelectResult"></select-handle>
|
|
241
|
+
</van-popup>
|
|
242
|
+
<van-popup v-if="selectOrganizePopupShow" v-model="selectOrganizePopupShow" closeable round position="bottom"
|
|
243
|
+
:style="{ height: '80%' }">
|
|
244
|
+
<select-organize ref="selectOrganize" :all-organize="false" :organize-id-list="permissionsScope.O" @selectOrganizeHandle="selectOrganizeHandle" ></select-organize>
|
|
245
|
+
</van-popup>
|
|
246
|
+
<van-popup v-if="selectUserPopupShow" v-model="selectUserPopupShow" closeable round position="bottom"
|
|
247
|
+
:style="{ height: '80%' }">
|
|
248
|
+
<select-handle title="选择用户" :multi-select="true" :procType="procType" @selectHandle="selectUserHandle" ></select-handle>
|
|
249
|
+
</van-popup>
|
|
250
|
+
<van-popup v-if="selectPositionPopupShow" v-model="selectPositionPopupShow" closeable round position="bottom"
|
|
251
|
+
:style="{ height: '80%' }">
|
|
252
|
+
<select-normal-list title="选择岗位" :id-list="permissionsScope.P" @selectNormalListHandle="selectPositionHandle" :parse-function="parsePositionFunction"></select-normal-list>
|
|
253
|
+
</van-popup>
|
|
254
|
+
<van-popup v-if="selectRolePopupShow" v-model="selectRolePopupShow" closeable round position="bottom"
|
|
255
|
+
:style="{ height: '80%' }">
|
|
256
|
+
<select-normal-list title="选择角色" :id-list="permissionsScope.R" @selectNormalListHandle="selectRoleHandle" :parse-function="parseRoleFunction"></select-normal-list>
|
|
266
257
|
</van-popup>
|
|
267
258
|
<van-dialog v-model="nodeListDialogShow" @confirm="processJumpSpecifiedNode()" @close="nodeListDialogShowClose()"
|
|
268
259
|
:title="getAuditButtonStatus(auditResult)" show-cancel-button>
|
|
@@ -297,18 +288,26 @@
|
|
|
297
288
|
|
|
298
289
|
<script>
|
|
299
290
|
import {
|
|
300
|
-
audit,
|
|
291
|
+
audit,
|
|
292
|
+
config,
|
|
301
293
|
getAllPreNodes,
|
|
302
294
|
getAttachmentList,
|
|
303
295
|
getNextNodes,
|
|
304
296
|
getNodesBehind,
|
|
297
|
+
getPosition,
|
|
305
298
|
getPreNode,
|
|
306
|
-
getProcessHis
|
|
299
|
+
getProcessHis,
|
|
300
|
+
getProcessType, getRole
|
|
307
301
|
} from "../api";
|
|
308
302
|
import {Dialog, Toast} from "vant";
|
|
309
303
|
import UploadFile from '@lambo-design-mobile/upload-file';
|
|
310
304
|
import {flutterUtil} from "./utils/flutterUtil";
|
|
311
305
|
import SelectHandle from "./SelectHandle.vue";
|
|
306
|
+
import Tree from "./tree/Tree.vue";
|
|
307
|
+
import SelectOrganize from "./SelectOrganize.vue";
|
|
308
|
+
import SelectNormalList from "./SelectNormalList.vue";
|
|
309
|
+
import ApprovalNodeCell from "./ApprovalNodeCell.vue";
|
|
310
|
+
import {getAuditStatus} from "./js/global";
|
|
312
311
|
|
|
313
312
|
|
|
314
313
|
export default {
|
|
@@ -317,7 +316,7 @@ export default {
|
|
|
317
316
|
return config
|
|
318
317
|
}
|
|
319
318
|
},
|
|
320
|
-
components: {SelectHandle, UploadFile},
|
|
319
|
+
components: {ApprovalNodeCell, SelectNormalList, SelectOrganize, Tree, SelectHandle, UploadFile},
|
|
321
320
|
props: {
|
|
322
321
|
//业务表单保存方法
|
|
323
322
|
businessFormSave: {
|
|
@@ -340,6 +339,18 @@ export default {
|
|
|
340
339
|
processTraceRouterName: {
|
|
341
340
|
type: String,
|
|
342
341
|
required: true,
|
|
342
|
+
},
|
|
343
|
+
activeFirstTab: {
|
|
344
|
+
type: Boolean,
|
|
345
|
+
default: false,
|
|
346
|
+
},
|
|
347
|
+
offsetTop: {
|
|
348
|
+
type: Number,
|
|
349
|
+
default: 0
|
|
350
|
+
},
|
|
351
|
+
foldingApprovalComments: {
|
|
352
|
+
type: Boolean,
|
|
353
|
+
default: false
|
|
343
354
|
}
|
|
344
355
|
},
|
|
345
356
|
data() {
|
|
@@ -348,6 +359,7 @@ export default {
|
|
|
348
359
|
//初始化路由数据
|
|
349
360
|
taskNode: this.$route.query.taskNode,
|
|
350
361
|
procId: this.$route.query.procId,
|
|
362
|
+
procType: this.$route.query.procType,
|
|
351
363
|
instanceId: this.$route.query.instanceId,
|
|
352
364
|
applyId: this.$route.query.applyId,
|
|
353
365
|
formUrl: this.$route.query.formUrl,
|
|
@@ -360,13 +372,14 @@ export default {
|
|
|
360
372
|
handlingPersonnel: '',
|
|
361
373
|
nodeConfigMaps: '',
|
|
362
374
|
},
|
|
375
|
+
approvalError: false,
|
|
363
376
|
|
|
364
377
|
processHistory: [],
|
|
365
378
|
tableData: [],
|
|
366
379
|
|
|
367
380
|
bpmnViewer: null,
|
|
368
381
|
|
|
369
|
-
activeNames: [
|
|
382
|
+
activeNames: [],
|
|
370
383
|
popupShow: false,
|
|
371
384
|
|
|
372
385
|
nextNodePopupShow: false,
|
|
@@ -404,21 +417,59 @@ export default {
|
|
|
404
417
|
//给附件列表展示
|
|
405
418
|
files: [],
|
|
406
419
|
//文件上传列表
|
|
407
|
-
fileList: []
|
|
420
|
+
fileList: [],
|
|
421
|
+
|
|
422
|
+
permissionsScope: {},
|
|
423
|
+
selectOrganizePopupShow: false,
|
|
424
|
+
selectUserPopupShow: false,
|
|
425
|
+
selectRolePopupShow: false,
|
|
426
|
+
selectPositionPopupShow: false,
|
|
408
427
|
};
|
|
409
428
|
},
|
|
410
429
|
methods: {
|
|
430
|
+
getAuditStatus,
|
|
411
431
|
initData() {
|
|
412
432
|
this.getProcessHistory();
|
|
413
433
|
this.getNextNodes();
|
|
414
434
|
this.getAttachmentList();
|
|
435
|
+
this.getProcessTypeList();
|
|
415
436
|
//设置提示持续时间默认为500ms
|
|
416
437
|
Toast.setDefaultOptions({duration: 500});
|
|
417
438
|
},
|
|
439
|
+
|
|
440
|
+
// 计算有多少个可见的handleButtons
|
|
441
|
+
getVisibleButtonsCount() {
|
|
442
|
+
return ['auditTo70', 'auditTo40', 'auditTo90', 'auditTo80', 'auditTo82', 'auditTo50']
|
|
443
|
+
.filter(btn => this.handleButtons.includes(btn))
|
|
444
|
+
.length;
|
|
445
|
+
},
|
|
446
|
+
|
|
447
|
+
// 获取唯一按钮的文本
|
|
448
|
+
getSingleButtonText() {
|
|
449
|
+
const buttonIds = ['auditTo70', 'auditTo40', 'auditTo90', 'auditTo80', 'auditTo82', 'auditTo50'];
|
|
450
|
+
const singleButtonId = buttonIds.find(btn => this.handleButtons.includes(btn));
|
|
451
|
+
if (singleButtonId) {
|
|
452
|
+
const statusId = parseInt(singleButtonId.replace('auditTo', ''));
|
|
453
|
+
return this.getAuditButtonStatus(statusId);
|
|
454
|
+
}
|
|
455
|
+
return '';
|
|
456
|
+
},
|
|
457
|
+
|
|
458
|
+
// 处理唯一按钮的点击
|
|
459
|
+
handleSingleButton() {
|
|
460
|
+
const buttonIds = ['auditTo70', 'auditTo40', 'auditTo90', 'auditTo80', 'auditTo82', 'auditTo50'];
|
|
461
|
+
const singleButtonId = buttonIds.find(btn => this.handleButtons.includes(btn));
|
|
462
|
+
if (singleButtonId) {
|
|
463
|
+
const statusId = singleButtonId.replace('auditTo', '');
|
|
464
|
+
this.audit(statusId);
|
|
465
|
+
}
|
|
466
|
+
},
|
|
467
|
+
|
|
418
468
|
getProcessHistory() {
|
|
419
469
|
getProcessHis(this.applyId, this.instanceId, this.procId, this.taskId).then(resp => {
|
|
420
470
|
if (resp.data.code === '200') {
|
|
421
471
|
this.processHistory = resp.data.data
|
|
472
|
+
this.activeNames = this.processHistory.map((_, index) => index);
|
|
422
473
|
}
|
|
423
474
|
})
|
|
424
475
|
},
|
|
@@ -429,11 +480,82 @@ export default {
|
|
|
429
480
|
this.nextNodeProcessedData = this.processData(result.data);
|
|
430
481
|
this.approvalForm.nextNode = result.data.map(node => node.name).join(',');
|
|
431
482
|
this.approvalForm.handlingPersonnel = result.data
|
|
432
|
-
.map(node => node.assignee?.name || '
|
|
483
|
+
.map(node => node.assignee?.name || '候选人')
|
|
433
484
|
.join(',');
|
|
434
485
|
}
|
|
435
486
|
})
|
|
436
487
|
},
|
|
488
|
+
getProcessTypeList() {
|
|
489
|
+
getProcessType(this.procType).then(res => {
|
|
490
|
+
let permScope = res.data.data.rows[0].permScope;
|
|
491
|
+
this.permissionsScope = this.extractPermissions(permScope);
|
|
492
|
+
});
|
|
493
|
+
},
|
|
494
|
+
extractPermissions(permScope) {
|
|
495
|
+
const permissions = {};
|
|
496
|
+
|
|
497
|
+
// 使用正则分别匹配 O、U、P 和 R
|
|
498
|
+
const oMatch = permScope.match(/O:([^,]*)/);
|
|
499
|
+
const uMatch = permScope.match(/U:([^,]*)/);
|
|
500
|
+
const pMatch = permScope.match(/P:([^,]*)/);
|
|
501
|
+
const rMatch = permScope.match(/R:([^,]*)/);
|
|
502
|
+
|
|
503
|
+
// 分别解析 O、U、P 和 R 权限
|
|
504
|
+
permissions.O = oMatch && oMatch[1] ? oMatch[1].split(';') : [];
|
|
505
|
+
permissions.U = uMatch && uMatch[1] ? uMatch[1].split(';') : [];
|
|
506
|
+
permissions.P = pMatch && pMatch[1] ? pMatch[1].split(';') : [];
|
|
507
|
+
permissions.R = rMatch && rMatch[1] ? rMatch[1].split(';') : [];
|
|
508
|
+
|
|
509
|
+
return permissions;
|
|
510
|
+
},
|
|
511
|
+
async parsePositionFunction(idList) {
|
|
512
|
+
try {
|
|
513
|
+
// 并行调用 getPosition 方法
|
|
514
|
+
return await Promise.all(
|
|
515
|
+
idList.map(async (id) => {
|
|
516
|
+
const response = await getPosition(id);
|
|
517
|
+
const result = response.data; // 假设响应的主体包含在 data 中
|
|
518
|
+
|
|
519
|
+
// 返回 { id, name } 对象
|
|
520
|
+
return {
|
|
521
|
+
id: id,
|
|
522
|
+
name: result.data.positionName || `Unknown Name for ${id}`, // 使用返回数据中的 name,若无则提供默认值
|
|
523
|
+
};
|
|
524
|
+
})
|
|
525
|
+
); // 返回解析结果数组
|
|
526
|
+
} catch (error) {
|
|
527
|
+
console.error('Error fetching positions:', error);
|
|
528
|
+
// 在错误情况下返回默认结构
|
|
529
|
+
return idList.map((id) => ({
|
|
530
|
+
id: id,
|
|
531
|
+
name: `Unknown Name for ${id}`,
|
|
532
|
+
}));
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
async parseRoleFunction(idList) {
|
|
536
|
+
try {
|
|
537
|
+
// 并行调用 getPosition 方法
|
|
538
|
+
return await Promise.all(
|
|
539
|
+
idList.map(async (id) => {
|
|
540
|
+
const response = await getRole(id);
|
|
541
|
+
const result = response.data; // 假设响应的主体包含在 data 中
|
|
542
|
+
|
|
543
|
+
// 返回 { id, name } 对象
|
|
544
|
+
return {
|
|
545
|
+
id: id,
|
|
546
|
+
name: result.data.name || `Unknown Name for ${id}`, // 使用返回数据中的 name,若无则提供默认值
|
|
547
|
+
};
|
|
548
|
+
})
|
|
549
|
+
); // 返回解析结果数组
|
|
550
|
+
} catch (error) {
|
|
551
|
+
console.error('Error fetching positions:', error);
|
|
552
|
+
// 在错误情况下返回默认结构
|
|
553
|
+
return idList.map((id) => ({
|
|
554
|
+
id: id,
|
|
555
|
+
name: `Unknown Name for ${id}`,
|
|
556
|
+
}));
|
|
557
|
+
}
|
|
558
|
+
},
|
|
437
559
|
processData(data) {
|
|
438
560
|
return data.map(node => {
|
|
439
561
|
node.personType = node.assignee ? "assignee" : "candidate";
|
|
@@ -518,7 +640,7 @@ export default {
|
|
|
518
640
|
}, {});
|
|
519
641
|
this.approvalForm.nodeConfigMaps = JSON.stringify(params)
|
|
520
642
|
this.approvalForm.handlingPersonnel = this.nextNodeProcessedData
|
|
521
|
-
.map(node => node.assignee?.name
|
|
643
|
+
.map(node => node.personType === "assignee" ? node.assignee?.name : '候选人')
|
|
522
644
|
.join(',');
|
|
523
645
|
this.nextNodePopupShow = false;
|
|
524
646
|
} else {
|
|
@@ -527,6 +649,22 @@ export default {
|
|
|
527
649
|
this.nextNodePopupShow = false;
|
|
528
650
|
}
|
|
529
651
|
},
|
|
652
|
+
handleSelectOrganizePopupShow(index) {
|
|
653
|
+
this.nextNodeHandleIndex = index;
|
|
654
|
+
this.selectOrganizePopupShow=true;
|
|
655
|
+
},
|
|
656
|
+
handleSelectUserPopupShow(index) {
|
|
657
|
+
this.nextNodeHandleIndex = index;
|
|
658
|
+
this.selectUserPopupShow=true;
|
|
659
|
+
},
|
|
660
|
+
handleSelectRolePopupShow(index) {
|
|
661
|
+
this.nextNodeHandleIndex = index;
|
|
662
|
+
this.selectRolePopupShow = true;
|
|
663
|
+
},
|
|
664
|
+
handleSelectPositionPopupShow(index) {
|
|
665
|
+
this.nextNodeHandleIndex = index;
|
|
666
|
+
this.selectPositionPopupShow = true;
|
|
667
|
+
},
|
|
530
668
|
getAttachmentList() {
|
|
531
669
|
getAttachmentList(this.procId, this.applyId).then(resp => {
|
|
532
670
|
if (resp.data.code === '200') {
|
|
@@ -563,23 +701,7 @@ export default {
|
|
|
563
701
|
if (ext === 'pdf') return 'P';
|
|
564
702
|
return ext.charAt(0).toUpperCase();
|
|
565
703
|
},
|
|
566
|
-
|
|
567
|
-
const statusMap = {
|
|
568
|
-
'30': {text: '通过', icon: "tongguo", color: '#0d88ff', type: 'success'},
|
|
569
|
-
'40': {text: '驳回上一节点', icon: "bohui", color: '#ed4014', type: 'danger'},
|
|
570
|
-
'50': {text: '驳回到原点', icon: "bohui", color: '#ed4014', type: 'danger'},
|
|
571
|
-
'51': {text: '流程作废', icon: "liuchengzuofei", color: '#ed4014', type: 'danger'},
|
|
572
|
-
'60': {text: '撤回', icon: "chehui", color: '#ed4014', type: 'warning'},
|
|
573
|
-
'80': {text: '跳转指定节点', icon: "tiaozhuan", color: '#0d88ff', type: 'primary'},
|
|
574
|
-
'90': {text: '驳回指定节点', icon: "bohui", color: '#ed4014', type: 'primary'},
|
|
575
|
-
};
|
|
576
|
-
return {
|
|
577
|
-
text: (statusMap[auditResult] && statusMap[auditResult].text) || '待审批',
|
|
578
|
-
icon: (statusMap[auditResult] && statusMap[auditResult].icon) || 'daishenpi',
|
|
579
|
-
color: (statusMap[auditResult] && statusMap[auditResult].color) || '#ff9900',
|
|
580
|
-
type: (statusMap[auditResult] && statusMap[auditResult].type) || 'warning',
|
|
581
|
-
};
|
|
582
|
-
},
|
|
704
|
+
|
|
583
705
|
getAuditButtonStatus(auditResult) {
|
|
584
706
|
let statusMap = {
|
|
585
707
|
'30': '通过',
|
|
@@ -614,6 +736,8 @@ export default {
|
|
|
614
736
|
|
|
615
737
|
if (this.approvalForm.auditOpinion === '' || this.approvalForm.auditOpinion == null) {
|
|
616
738
|
if (!this.handleButtons || this.handleButtons.includes('auditOpinion')) {
|
|
739
|
+
this.updateActiveTab()
|
|
740
|
+
this.approvalError = true
|
|
617
741
|
Toast({message: '请输入审批意见', duration: '500'});
|
|
618
742
|
return
|
|
619
743
|
} else {
|
|
@@ -629,6 +753,9 @@ export default {
|
|
|
629
753
|
this.popupShow = false;
|
|
630
754
|
|
|
631
755
|
},
|
|
756
|
+
handleInputFocus() {
|
|
757
|
+
this.approvalError = false;
|
|
758
|
+
},
|
|
632
759
|
submit() {
|
|
633
760
|
let self = this;
|
|
634
761
|
self.auditParams = {
|
|
@@ -726,7 +853,7 @@ export default {
|
|
|
726
853
|
this.executionCompleted(true, result.data.processInstanceId, taskIds, auditResult, self.taskId);
|
|
727
854
|
}
|
|
728
855
|
} else {
|
|
729
|
-
this.executionCompleted(true, null, null);
|
|
856
|
+
this.executionCompleted(true, null, null, auditResult, self.taskId);
|
|
730
857
|
}
|
|
731
858
|
Toast.success(result.message);
|
|
732
859
|
} else if (result.code === '20002') {
|
|
@@ -823,14 +950,56 @@ export default {
|
|
|
823
950
|
}
|
|
824
951
|
self.selectHandlePopupShow = false;
|
|
825
952
|
},
|
|
953
|
+
selectOrganizeHandle(handle, checkedNodes) {
|
|
954
|
+
if (handle === 'select') {
|
|
955
|
+
this.nextNodeProcessedData[this.nextNodeHandleIndex].candidateGroups.organs =
|
|
956
|
+
checkedNodes.map(item => ({
|
|
957
|
+
name: item.node.title,
|
|
958
|
+
id: item.node.id,
|
|
959
|
+
}));
|
|
960
|
+
}
|
|
961
|
+
this.selectOrganizePopupShow = false
|
|
962
|
+
},
|
|
963
|
+
selectUserHandle(checkResult) {
|
|
964
|
+
this.nextNodeProcessedData[this.nextNodeHandleIndex].candidateGroups.users =
|
|
965
|
+
checkResult.map(item => ({
|
|
966
|
+
name: item.userName,
|
|
967
|
+
id: item.userId,
|
|
968
|
+
}));
|
|
969
|
+
this.selectUserPopupShow = false;
|
|
970
|
+
},
|
|
971
|
+
selectPositionHandle(handle, result) {
|
|
972
|
+
if (handle === 'select') {
|
|
973
|
+
this.nextNodeProcessedData[this.nextNodeHandleIndex].candidateGroups.positions =
|
|
974
|
+
result.map(item => ({
|
|
975
|
+
name: item.name,
|
|
976
|
+
id: item.id,
|
|
977
|
+
}));
|
|
978
|
+
}
|
|
979
|
+
this.selectPositionPopupShow = false
|
|
980
|
+
},
|
|
981
|
+
selectRoleHandle(handle, result) {
|
|
982
|
+
if (handle === 'select') {
|
|
983
|
+
this.nextNodeProcessedData[this.nextNodeHandleIndex].candidateGroups.roles =
|
|
984
|
+
result.map(item => ({
|
|
985
|
+
name: item.name,
|
|
986
|
+
id: item.id,
|
|
987
|
+
}));
|
|
988
|
+
}
|
|
989
|
+
this.selectRolePopupShow = false
|
|
990
|
+
},
|
|
826
991
|
},
|
|
827
992
|
activated() {
|
|
828
|
-
this.
|
|
993
|
+
if (!this.activeFirstTab) {
|
|
994
|
+
this.updateActiveTab();
|
|
995
|
+
}
|
|
829
996
|
},
|
|
830
997
|
mounted() {
|
|
831
998
|
this.initData()
|
|
832
999
|
// 默认选中最后一个tab页
|
|
833
|
-
this.
|
|
1000
|
+
if (!this.activeFirstTab) {
|
|
1001
|
+
this.updateActiveTab();
|
|
1002
|
+
}
|
|
834
1003
|
}
|
|
835
1004
|
|
|
836
1005
|
};
|
|
@@ -839,6 +1008,10 @@ export default {
|
|
|
839
1008
|
<style scoped>
|
|
840
1009
|
@import 'styles/global.css';
|
|
841
1010
|
|
|
1011
|
+
::v-deep .van-tabs__content {
|
|
1012
|
+
background: #f7f8fa;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
842
1015
|
::v-deep .van-collapse-item__content {
|
|
843
1016
|
padding: 0 0;
|
|
844
1017
|
}
|
|
@@ -855,6 +1028,7 @@ export default {
|
|
|
855
1028
|
::v-deep .van-tab--active .van-tab__text {
|
|
856
1029
|
color: #3478f6; /* 设置激活状态下的文字颜色为蓝色 */
|
|
857
1030
|
font-size: 16px; /* 增大激活状态下的字体大小 */
|
|
1031
|
+
font-weight: bold;
|
|
858
1032
|
}
|
|
859
1033
|
|
|
860
1034
|
::v-deep .van-tabs__line {
|
|
@@ -903,38 +1077,6 @@ export default {
|
|
|
903
1077
|
padding: 20px 10px;
|
|
904
1078
|
}
|
|
905
1079
|
|
|
906
|
-
.completed-icon {
|
|
907
|
-
width: 45px; /* 自定义宽度 */
|
|
908
|
-
height: 45px; /* 自定义高度 */
|
|
909
|
-
background-clip: padding-box; /* 使背景不填充边框 */
|
|
910
|
-
|
|
911
|
-
border-radius: 50%;
|
|
912
|
-
margin-right: 15px;
|
|
913
|
-
|
|
914
|
-
display: flex;
|
|
915
|
-
align-items: center;
|
|
916
|
-
justify-content: center;
|
|
917
|
-
|
|
918
|
-
background: linear-gradient(90deg, #0096FF, #1677FF);
|
|
919
|
-
border: 5px solid rgb(229, 244, 255); /* 半透明边框,颜色和背景色相同 */
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
.pending-icon {
|
|
923
|
-
width: 45px; /* 自定义宽度 */
|
|
924
|
-
height: 45px; /* 自定义高度 */
|
|
925
|
-
background-clip: padding-box; /* 使背景不填充边框 */
|
|
926
|
-
|
|
927
|
-
border-radius: 50%;
|
|
928
|
-
margin-right: 15px;
|
|
929
|
-
|
|
930
|
-
display: flex;
|
|
931
|
-
align-items: center;
|
|
932
|
-
justify-content: center;
|
|
933
|
-
|
|
934
|
-
background: linear-gradient(90deg, #FF7E00, #FFA200);
|
|
935
|
-
border: 5px solid rgb(255, 245, 229); /* 半透明边框,颜色和背景色相同 */
|
|
936
|
-
}
|
|
937
|
-
|
|
938
1080
|
.info-icon {
|
|
939
1081
|
display: inline-block;
|
|
940
1082
|
color: white; /* 自定义文字颜色 */
|