@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.
@@ -1,6 +1,9 @@
1
1
  <template>
2
2
  <div>
3
- <van-tabs ref="tabs" style="padding-bottom: 60px" v-model="active" @click="onTabClick" animated>
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
- <van-cell @click="nextNodePopupShow = true" title="办理人员" value-class="approvalForm-value"
28
- :value="approvalForm.handlingPersonnel">
29
- <template #right-icon>
30
- <van-icon name="friends-o" size="16" style="line-height: inherit;padding-left: 5px"/>
31
- </template>
32
- </van-cell>
33
- <div class="van-hairline--bottom"></div>
34
- </div>
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
- <van-cell center>
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-cell @click="clickCandidateGroup()" title-style="padding-left:10px" title="候选用户"
199
- :value="(item.candidateGroups?.users ?? []).map(user => user.name).join(',')">
200
- </van-cell>
201
- <van-cell @click="clickCandidateGroup()" title-style="padding-left:10px" title="候选岗位"
202
- :value="(item.candidateGroups?.positions ?? []).map(position => position.name).join(',')">
203
- </van-cell>
204
- <van-cell @click="clickCandidateGroup()" title-style="padding-left:10px" title="候选角色"
205
- :value="(item.candidateGroups?.roles ?? []).map(role => role.name).join(',')">
206
- </van-cell>
207
- <van-cell @click="clickCandidateGroup()" title-style="padding-left:10px" title="候选组织"
208
- :value="(item.candidateGroups?.organs ?? []).map(organ => organ.name).join(',')">
209
- </van-cell>
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
- <van-cell center title="停留时间">
212
- <template #default>
213
- <div style="display: flex; align-items: center;">
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
- <van-stepper disable-input button-size="22" min="0" v-model="item.remainTime"/>
220
- <span style="margin-left: 4px;">小时</span>
221
- </div>
222
- </div>
223
- </template>
224
- </van-cell>
225
- <van-cell title="任务提前">
226
- <template #default>
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
- <van-stepper disable-input button-size="22" min="0" v-model="item.inAdvanceTime"/>
234
- <span style="margin-left: 4px;">小时</span>
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
- </div>
237
- </template>
238
- </van-cell>
239
- <van-field
240
- readonly
241
- clickable
242
- input-align="right"
243
- name="picker"
244
- :value="(handleTypeList.find(handleType => handleType.value === item.processing) || {}).label"
245
- label="处理方式"
246
- placeholder="点击选择处理方式"
247
- @click="$set(showPicker, index, true)"
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, config,
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: [0],
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
- getAuditStatus(auditResult) {
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.updateActiveTab();
993
+ if (!this.activeFirstTab) {
994
+ this.updateActiveTab();
995
+ }
829
996
  },
830
997
  mounted() {
831
998
  this.initData()
832
999
  // 默认选中最后一个tab页
833
- this.updateActiveTab();
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; /* 自定义文字颜色 */