@lambo-design-mobile/workflow-approve 1.0.0-beta.22 → 1.0.0-beta.24

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.
@@ -31,7 +31,7 @@
31
31
  <div v-if="approvalForm.nextNode!==''">
32
32
  <van-cell title="下一环节" :value="approvalForm.nextNode"/>
33
33
  <div v-if="handleButtons && handleButtons.includes('appointHandler')">
34
- <van-cell @click="nextNodePopupShow = true" title="办理人员" value-class="approvalForm-value"
34
+ <van-cell @click="handleNextNodePopupShow" title="办理人员" value-class="approvalForm-value"
35
35
  :value="approvalForm.handlingPersonnel">
36
36
  <template #right-icon>
37
37
  <van-icon name="friends-o" size="16" style="line-height: inherit;padding-left: 5px"/>
@@ -115,33 +115,16 @@
115
115
  <!-- 底部按钮 等其他内容 -->
116
116
  <div>
117
117
  <van-popup v-model="popupShow" style="padding-top: 40px" closeable round position="bottom">
118
- <div v-if="handleButtons && handleButtons.includes('auditTo70')" class="popup-option" @click="audit('70')">
119
- {{ getAuditButtonStatus(70) }}
120
- </div>
121
- <div v-if="handleButtons && handleButtons.includes('auditTo40')" class="popup-option highlighted"
122
- @click="audit('40')">
123
- {{ getAuditButtonStatus(40) }}
124
- </div>
125
- <div v-if="handleButtons && handleButtons.includes('auditTo90')" class="popup-option" @click="audit('90')">
126
- {{ getAuditButtonStatus(90) }}
127
- </div>
128
- <div v-if="handleButtons && handleButtons.includes('auditTo80')" class="popup-option" @click="audit('80')">
129
- {{ getAuditButtonStatus(80) }}
130
- </div>
131
- <div v-if="handleButtons && handleButtons.includes('auditTo82')" class="popup-option" @click="audit('82')">
132
- {{ getAuditButtonStatus(82) }}
133
- </div>
134
- <div v-if="handleButtons && handleButtons.includes('auditTo50')" class="popup-option" @click="audit('50')">
135
- {{ getAuditButtonStatus(50) }}
136
- </div>
118
+ <template v-for="(button, index) of operationButtons.moreOperations">
119
+ <div :class="button.class" @click="button.action">
120
+ {{ button.label }}
121
+ </div>
122
+ </template>
137
123
  </van-popup>
138
124
  <div class="custom-bottom-bar">
139
- <div v-if="!isDetail && getVisibleButtonsCount() > 1" class="bar-item" @click="onMore">更多</div>
140
- <div v-else-if="!isDetail && getVisibleButtonsCount() === 1" class="bar-item" @click="handleSingleButton()">
141
- {{ getSingleButtonText() }}
125
+ <div v-for="(button, index) of operationButtons.bottomButtons" :class="button.class" @click="button.action">
126
+ {{ button.label }}
142
127
  </div>
143
- <div class="bar-item" @click="onTrack">流程跟踪</div>
144
- <div v-if="!isDetail" class="bar-item approve" @click="audit('30')">{{ getAuditButtonStatus(30) }}</div>
145
128
  </div>
146
129
  </div>
147
130
  <van-popup @click-close-icon="handleSelect('cancel')" v-model="nextNodePopupShow"
@@ -156,29 +139,32 @@
156
139
  <van-field name="radio" label="人员类型" input-align="right">
157
140
  <template #input>
158
141
  <van-radio-group v-model="item.personType" direction="horizontal">
159
- <van-radio name="assignee">办理人</van-radio>
160
- <van-radio name="candidate">候选人</van-radio>
142
+ <van-radio v-if="!nextAssigneeSelectionType || nextAssigneeSelectionType === 'assignee'" name="assignee">办理人</van-radio>
143
+ <van-radio v-if="!nextAssigneeSelectionType || nextAssigneeSelectionType === 'candidate'" name="candidate">候选人</van-radio>
161
144
  </van-radio-group>
162
145
  </template>
163
146
  </van-field>
164
147
  <van-cell v-if="item.personType === 'assignee'" title="办理人"
165
148
  :value="(item.assignee.name ? item.assignee.name : '未指定') + ':' + (item.assignee.id ? item.assignee.id : '未指定')"
166
- @click="nextNodeHandleIndex=index;selectHandlePopupShow=true;">
149
+ @click="handleNextNodeAssigneeSelect(index, 'appointHandler')">
167
150
  </van-cell>
168
151
  <van-cell v-if="item.personType === 'candidate'" title="候选人" @click="toggleDetails(index)"
169
152
  :is-link="true" :arrow-direction="detailsVisible[index] ? 'down' : ''">
170
153
  </van-cell>
171
154
  <div v-if="detailsVisible[index] && item.personType === 'candidate'">
172
- <van-field @click="handleSelectUserPopupShow(index)" label="候选用户" readonly placeholder="点击选择"
155
+ <van-field v-if="useTransferUser" @click="handleNextNodeUserSelect(index, 'appointHandlerWithCandGroups')" label="候选用户" readonly placeholder="点击选择"
156
+ :value="(item.candidateGroups?.users ?? []).map(user => user.name).join(',')">
157
+ </van-field>
158
+ <van-field v-if="!useTransferUser && !useTransferOrgan" @click="handleCandUserSelect(index)" label="候选用户" readonly placeholder="点击选择"
173
159
  :value="(item.candidateGroups?.users ?? []).map(user => user.name).join(',')">
174
160
  </van-field>
175
- <van-field @click="handleSelectPositionPopupShow(index)" label="候选岗位" readonly placeholder="点击选择"
161
+ <van-field v-if="!useTransferUser && !useTransferOrgan" @click="handleSelectPositionPopupShow(index)" label="候选岗位" readonly placeholder="点击选择"
176
162
  :value="(item.candidateGroups?.positions ?? []).map(position => position.name).join(',')">
177
163
  </van-field>
178
- <van-field @click="handleSelectRolePopupShow(index)" label="候选角色" readonly placeholder="点击选择"
164
+ <van-field v-if="!useTransferUser && !useTransferOrgan" @click="handleSelectRolePopupShow(index)" label="候选角色" readonly placeholder="点击选择"
179
165
  :value="(item.candidateGroups?.roles ?? []).map(role => role.name).join(',')">
180
166
  </van-field>
181
- <van-field @click="handleSelectOrganizePopupShow(index)" label="候选组织" readonly placeholder="点击选择"
167
+ <van-field v-if="!useTransferUser" @click="handleSelectOrganizePopupShow(index)" label="候选组织" readonly placeholder="点击选择"
182
168
  :value="(item.candidateGroups?.organs ?? []).map(organ => organ.name).join(',')">
183
169
  </van-field>
184
170
  </div>
@@ -236,17 +222,19 @@
236
222
  <div class="bar-item approve" @click="handleSelect('select')">确认</div>
237
223
  </div>
238
224
  </van-popup>
239
- <van-popup v-if="selectHandlePopupShow" v-model="selectHandlePopupShow" closeable round position="bottom"
240
- :style="{ height: '80%' }" style="background: #f7f8fa">
241
- <select-handle title="指定办理人" :multi-select="false" :procType="procType" @selectHandle="handleSelectResult"></select-handle>
225
+ <van-popup v-if="selectUserPopupShow" v-model="selectUserPopupShow" closeable round position="bottom"
226
+ :style="{ height: '80%' }" :class="selectUserPopupParams.class">
227
+ <select-handle :title="selectUserPopupParams.title" :multi-select="selectUserPopupParams.multiSelect" :procType="procType" :organ-tree-type="selectUserPopupParams.organTreeType"
228
+ :org-list="selectUserPopupParams.orgList" :user-list="selectUserPopupParams.userList" @selectHandle="selectUserPopupParams.action"></select-handle>
242
229
  </van-popup>
243
230
  <van-popup v-if="selectOrganizePopupShow" v-model="selectOrganizePopupShow" closeable round position="bottom"
244
231
  :style="{ height: '80%' }">
245
- <select-organize ref="selectOrganize" :all-organize="false" :organize-id-list="permissionsScope.O" @selectOrganizeHandle="selectOrganizeHandle" ></select-organize>
232
+ <select-organize ref="selectOrganize" :treetype-id="orgTreeType" :all-organize="false" :organize-id-list="permissionsScope.O" @selectOrganizeHandle="selectOrganizeHandle" ></select-organize>
246
233
  </van-popup>
247
- <van-popup v-if="selectUserPopupShow" v-model="selectUserPopupShow" closeable round position="bottom"
234
+ <van-popup v-if="selectCandUserPopupShow" v-model="selectCandUserPopupShow" closeable round position="bottom"
248
235
  :style="{ height: '80%' }">
249
- <select-handle title="选择用户" :multi-select="true" :procType="procType" @selectHandle="selectUserHandle" ></select-handle>
236
+ <select-handle title="选择用户" :multi-select="true" :procType="procType" :organ-tree-type="selectUserPopupParams.organTreeType" :org-list="selectUserPopupParams.orgList"
237
+ :user-list="selectUserPopupParams.userList" @selectHandle="selectCandUserHandle"></select-handle>
250
238
  </van-popup>
251
239
  <van-popup v-if="selectPositionPopupShow" v-model="selectPositionPopupShow" closeable round position="bottom"
252
240
  :style="{ height: '80%' }">
@@ -256,7 +244,23 @@
256
244
  :style="{ height: '80%' }">
257
245
  <select-normal-list title="选择角色" :id-list="permissionsScope.R" @selectNormalListHandle="selectRoleHandle" :parse-function="parseRoleFunction"></select-normal-list>
258
246
  </van-popup>
259
- <van-dialog v-model="nodeListDialogShow" @confirm="processJumpSpecifiedNode()" @close="nodeListDialogShowClose()"
247
+ <van-popup v-if="selectReductionUserPopupShow" v-model="selectReductionUserPopupShow" closeable round position="bottom" :style="{ height: '80%' }">
248
+ <div id="reductionListContent" style="background: #f7f8fa">
249
+ <div class="van-nav-bar__content">
250
+ <div class="van-nav-bar__title">{{ getAuditButtonStatus(83) }}</div>
251
+ </div>
252
+ <van-list style="padding-top: 15px">
253
+ <select-handle-card ref="selectHandleCard" :multi-select="true" :person-list="unapprovedAssigneeList"
254
+ :result.sync="reductionUsers" :show-status="false">
255
+ </select-handle-card>
256
+ </van-list>
257
+ </div>
258
+ <div v-if="reductionUsers.length > 0" class="custom-bottom-bar">
259
+ <div class="bar-item" @click="handleReductionUserSelect('cancel')">取消</div>
260
+ <div class="bar-item approve" @click="handleReductionUserSelect('select')">选择</div>
261
+ </div>
262
+ </van-popup>
263
+ <van-dialog v-model="nodeListDialogShow" @confirm="processJumpSpecifiedNode()" @close="nodeListDialogShowClose()" :before-close="onBeforeClose"
260
264
  :title="getAuditButtonStatus(auditResult)" show-cancel-button>
261
265
  <van-radio-group v-model="radio">
262
266
  <van-cell-group>
@@ -267,7 +271,7 @@
267
271
  </div>
268
272
  <div class="table-row"
269
273
  v-for="(item, index) in nodeList" :key="index"
270
- @click="radio = index">
274
+ @click="selectNode(item, index)">
271
275
  <div>{{ item.taskName }}</div>
272
276
  <div>
273
277
  <van-tag v-if="item.auditResult" :type="getAuditStatus(item.auditResult).type">
@@ -281,9 +285,34 @@
281
285
  <van-radio :name='index'/>
282
286
  </div>
283
287
  </div>
288
+ <div v-if="showRejectToSelected" class="table-row">
289
+ <van-field @click="handleSelectRejectUser" label="选择驳回人员" readonly placeholder="点击选择" :value="rejectUsers.name"></van-field>
290
+ </div>
291
+ <div v-if="showProcessControl" class="reject-attribute">
292
+ <div>驳回的节点通过后:</div>
293
+ <van-radio-group v-model="rejectAttribute">
294
+ <van-radio v-for="(item, index) in rejectAttributeList" :key="index" :name="item.type">{{ item.name }}</van-radio>
295
+ </van-radio-group>
296
+ </div>
284
297
  </van-cell-group>
285
298
  </van-radio-group>
286
299
  </van-dialog>
300
+ <van-dialog v-model="rejectAttributesBoxShow" @confirm="processRejectNode()" @close="rejectAttributesDialogShowClose()"
301
+ title="驳回设置" show-cancel-button>
302
+ <div v-if="showProcessControl" class="reject-attribute">
303
+ <div>驳回的节点通过后:</div>
304
+ <van-radio-group v-model="rejectAttribute">
305
+ <van-radio v-for="(item, index) in rejectAttributeList" :key="index" :name="item.type">{{ item.name }}</van-radio>
306
+ </van-radio-group>
307
+ </div>
308
+ <div v-if="showRejectToSelected" class="reject-attribute">
309
+ <van-field @click="handleSelectRejectUser" label="选择驳回人员" readonly placeholder="点击选择" :value="rejectUsers.name"></van-field>
310
+ </div>
311
+ </van-dialog>
312
+ <van-popup v-if="selectRejectUserPopupShow" v-model="selectRejectUserPopupShow" closeable round position="bottom"
313
+ :style="{ height: '80%' }">
314
+ <select-handle title="选择驳回人员" :multi-select="true" :procType="procType" :user-list="rejectUserList" @selectHandle="selectRejectUserHandle"></select-handle>
315
+ </van-popup>
287
316
  </div>
288
317
  </template>
289
318
 
@@ -297,9 +326,16 @@ import {
297
326
  getNodesBehind,
298
327
  getPosition,
299
328
  getPreNode,
300
- getHandleButtons,
329
+ getNodeData,
301
330
  getProcessHis,
302
- getProcessType, getRole
331
+ getProcessType, getRole,
332
+ getTransferRange,
333
+ updateMultitaskInstance,
334
+ getUnapprovedListOfMultiNode,
335
+ getProcessTodoList,
336
+ getProcessAttributes,
337
+ listAll,
338
+ getDoneDetail
303
339
  } from "../api";
304
340
  import {Dialog, Toast} from "vant";
305
341
  import UploadFile from '@lambo-design-mobile/upload-file';
@@ -310,6 +346,8 @@ import SelectOrganize from "./SelectOrganize.vue";
310
346
  import SelectNormalList from "./SelectNormalList.vue";
311
347
  import ApprovalNodeCell from "./ApprovalNodeCell.vue";
312
348
  import {getAuditStatus} from "./js/global";
349
+ import {NodeType} from "./utils/const";
350
+ import SelectHandleCard from "./SelectHandleCard.vue";
313
351
 
314
352
 
315
353
  export default {
@@ -319,9 +357,178 @@ export default {
319
357
  },
320
358
  showAuditOpinion(){
321
359
  return this.handleButtons && (this.handleButtons.includes('auditOpinion') || this.handleButtons.includes('appointHandler') || this.handleButtons.includes('attachmentFile'))
360
+ },
361
+ operationButtons() {
362
+ // 流程跟踪按钮
363
+ const processTraceButton = {
364
+ id: 'processTrace',
365
+ label: '流程跟踪',
366
+ condition: this.handleButtons?.includes('processTrace'),
367
+ class: 'bar-item',
368
+ action: () => this.onTrack(),
369
+ }
370
+
371
+ // 审批按钮
372
+ const auditButtonDefinitions = [
373
+ {
374
+ id: 'auditTo30',
375
+ label: this.getAuditButtonStatus(30),
376
+ condition: this.handleButtons?.includes('auditTo30') && !this.isDetail && !this.revokeDelegateTask && !this.appointTask && !this.coSignVotingTask,
377
+ class: 'bar-item approve',
378
+ action: () => this.audit('30'),
379
+ },
380
+ {
381
+ id: 'auditTo62',
382
+ label: this.getAuditButtonStatus(62),
383
+ condition: !this.isDetail && this.revokeDelegateTask,
384
+ class: 'bar-item approve',
385
+ action: () => this.audit('62'),
386
+ },
387
+ {
388
+ id: 'auditTo61',
389
+ label: this.getAuditButtonStatus(61),
390
+ condition: !this.isDetail && this.appointTask,
391
+ class: 'bar-item approve',
392
+ action: () => this.audit('61'),
393
+ },
394
+ {
395
+ id: 'auditTo32',
396
+ label: this.getAuditButtonStatus(32),
397
+ condition: this.coSignVotingTask,
398
+ class: 'bar-item disagree',
399
+ action: () => this.audit('32'),
400
+ },
401
+ {
402
+ id: 'auditTo31',
403
+ label: this.getAuditButtonStatus(31),
404
+ condition: this.coSignVotingTask,
405
+ class: 'bar-item approve',
406
+ action: () => this.audit('31'),
407
+ },
408
+ ]
409
+
410
+ // 实际可以展示的审批按钮
411
+ const validAuditButtons = auditButtonDefinitions.filter(item => item.condition)
412
+ const showButtons = !this.appointTask && !this.rejectedTask && !this.revokeDelegateTask && !this.coSignVotingTask && !this.isDetail
413
+ const handleButtonsDefinitions = [
414
+ {
415
+ id: 'delegateTask',
416
+ label: this.getAuditButtonStatus(84),
417
+ condition: this.curNodeType === NodeType.UserTask &&
418
+ this.handleButtons?.includes('delegateTask') &&
419
+ showButtons,
420
+ class: 'popup-option',
421
+ barClass: 'bar-item approve',
422
+ action: () => this.audit('84'),
423
+ },
424
+ {
425
+ id: 'addMultitaskInstance',
426
+ label: this.getAuditButtonStatus(81),
427
+ condition: this.curNodeType === NodeType.MultiNode &&
428
+ this.handleButtons?.includes('addMultitaskInstance') &&
429
+ showButtons,
430
+ class: 'popup-option',
431
+ barClass: 'bar-item approve',
432
+ action: () => this.showUpdateMultitaskInstanceModal('81'),
433
+ },
434
+ {
435
+ id: 'reductionMultitaskInstance',
436
+ label: this.getAuditButtonStatus(83),
437
+ condition: this.curNodeType === NodeType.MultiNode &&
438
+ this.handleButtons?.includes('reductionMultitaskInstance') &&
439
+ showButtons,
440
+ class: 'popup-option',
441
+ barClass: 'bar-item disagree',
442
+ action: () => this.showUpdateMultitaskInstanceModal('83'),
443
+ },
444
+ {
445
+ id: 'auditTo70',
446
+ label: this.getAuditButtonStatus(70),
447
+ condition: this.handleButtons && this.handleButtons.includes('auditTo70') && showButtons,
448
+ class: 'popup-option',
449
+ barClass: 'bar-item disagree',
450
+ action: () => this.audit('70'),
451
+ },
452
+ {
453
+ id: 'auditTo40',
454
+ label: this.getAuditButtonStatus(40),
455
+ condition: this.handleButtons && this.handleButtons.includes('auditTo40') && showButtons,
456
+ class: 'popup-option highlighted',
457
+ barClass: 'bar-item disagree',
458
+ action: () => this.audit('40'),
459
+ },
460
+ {
461
+ id: 'auditTo90',
462
+ label: this.getAuditButtonStatus(90),
463
+ condition: this.handleButtons && this.handleButtons.includes('auditTo90') && showButtons,
464
+ class: 'popup-option',
465
+ barClass: 'bar-item disagree',
466
+ action: () => this.audit('90'),
467
+ },
468
+ {
469
+ id: 'auditTo80',
470
+ label: this.getAuditButtonStatus(80),
471
+ condition: this.handleButtons && this.handleButtons.includes('auditTo80') && showButtons,
472
+ class: 'popup-option',
473
+ barClass: 'bar-item approve',
474
+ action: () => this.audit('80'),
475
+ },
476
+ {
477
+ id: 'auditTo82',
478
+ label: this.getAuditButtonStatus(82),
479
+ condition: this.handleButtons && this.handleButtons.includes('auditTo82') && showButtons,
480
+ class: 'popup-option',
481
+ barClass: 'bar-item approve',
482
+ action: () => this.audit('82'),
483
+ },
484
+ {
485
+ id: 'auditTo50',
486
+ label: this.getAuditButtonStatus(50),
487
+ condition: this.handleButtons && this.handleButtons.includes('auditTo50') && showButtons,
488
+ class: 'popup-option',
489
+ barClass: 'bar-item disagree',
490
+ action: () => this.audit('50'),
491
+ },
492
+ ]
493
+
494
+ // 实际更多操作按钮
495
+ let moreOperations = handleButtonsDefinitions.filter(item => item.condition)
496
+
497
+ let moreButtons = []
498
+ let borrowedButton = null;
499
+ // 如果审批按钮为空,且更多操作里有按钮,则借调最后一个
500
+ if (validAuditButtons.length === 0 && moreOperations.length > 0) {
501
+ borrowedButton = moreOperations.pop();
502
+ borrowedButton.class = borrowedButton.barClass
503
+ }
504
+ if (!this.isDetail) {
505
+ if (moreOperations.length > 1) {
506
+ moreButtons.push({
507
+ id: 'onMore',
508
+ label: '更多',
509
+ condition: true,
510
+ class: 'bar-item',
511
+ action: () => this.onMore(),
512
+ })
513
+ } else if (moreOperations.length === 1) {
514
+ moreButtons.push({
515
+ id: moreOperations[0].id,
516
+ label: moreOperations[0].label,
517
+ condition: true,
518
+ class: 'bar-item',
519
+ action: () => moreOperations[0].action(),
520
+ })
521
+ }
522
+ }
523
+ const baseList = [...moreButtons, processTraceButton]
524
+ if (borrowedButton) {
525
+ baseList.splice(2, 0, borrowedButton);
526
+ }
527
+ const bottomButtons = [...baseList, ...validAuditButtons]
528
+ return { bottomButtons, moreOperations }
322
529
  }
323
530
  },
324
- components: {ApprovalNodeCell, SelectNormalList, SelectOrganize, Tree, SelectHandle, UploadFile},
531
+ components: {ApprovalNodeCell, SelectNormalList, SelectOrganize, Tree, SelectHandle, UploadFile, SelectHandleCard},
325
532
  props: {
326
533
  //业务表单保存方法
327
534
  businessFormSave: {
@@ -341,6 +548,18 @@ export default {
341
548
  required: false,
342
549
  default: false
343
550
  },
551
+ //审批人来源
552
+ auditGroup: {
553
+ type: String,
554
+ required: false,
555
+ default: '',
556
+ },
557
+ //默认审批意见
558
+ defaultAuditOpinion: {
559
+ type: String,
560
+ required: false,
561
+ default: '',
562
+ },
344
563
  processTraceRouterName: {
345
564
  type: String,
346
565
  required: true,
@@ -372,12 +591,13 @@ export default {
372
591
  handleButtons: this.$route.query.handleButtons,
373
592
 
374
593
  approvalForm: {
375
- auditOpinion: '',
594
+ auditOpinion: this.defaultAuditOpinion,
376
595
  nextNode: '',
377
596
  handlingPersonnel: '',
378
597
  nodeConfigMaps: '',
379
598
  },
380
599
  approvalError: false,
600
+ orgTreeType: '00',
381
601
 
382
602
  processHistory: [],
383
603
  tableData: [],
@@ -386,7 +606,15 @@ export default {
386
606
 
387
607
  activeNames: [],
388
608
  popupShow: false,
609
+ appointTask: false,
610
+ revokeDelegateTask: false,
611
+ rejectedTask: false,
612
+ coSignVotingTask: false,
613
+ curNodeType: NodeType.UserTask,
389
614
 
615
+ nextAssigneeSelectionType: '',
616
+ useTransferUser: false,
617
+ useTransferOrgan: false,
390
618
  nextNodePopupShow: false,
391
619
  nextNodeHandleIndex: 0,
392
620
  nextNodeProcessedData: [], // 用于存储处理下一节点的数据
@@ -411,6 +639,8 @@ export default {
411
639
  ],
412
640
  handleTypeValue: '',
413
641
  showPicker: {},
642
+ rejectName: '驳回',
643
+ passName: '通过',
414
644
 
415
645
  nodeListDialogShow: false,
416
646
  nodeList: [],
@@ -423,12 +653,40 @@ export default {
423
653
  files: [],
424
654
  //文件上传列表
425
655
  fileList: [],
656
+ // 可以减签的人员
657
+ unapprovedAssigneeList: [],
658
+ // 减签人员
659
+ reductionUsers: [],
426
660
 
427
661
  permissionsScope: {},
428
662
  selectOrganizePopupShow: false,
663
+ selectCandUserPopupShow: false,
664
+ selectRejectUserPopupShow: false,
429
665
  selectUserPopupShow: false,
430
666
  selectRolePopupShow: false,
667
+ selectReductionUserPopupShow: false,
431
668
  selectPositionPopupShow: false,
669
+ selectUserPopupParams: {
670
+ title: '选择用户',
671
+ class: '',
672
+ multiSelect: true,
673
+ userList: [],
674
+ orgList: [],
675
+ organTreeType: '',
676
+ action: (checkResult) => { console.log('未定义回调方法') },
677
+ },
678
+ showRejectToSelected: false,
679
+ showProcessControl: false,
680
+ rejectAttributesBoxShow: false,
681
+ rejectAttribute: 'inSequence',
682
+ rejectAttributeList: [],
683
+ taskAuditUserList: [],
684
+ rejectUserList: [],
685
+ targetTaskNodeProcessControl: '',
686
+ rejectUsers: {
687
+ name: '全部办理人',
688
+ id: 'all'
689
+ },
432
690
  };
433
691
  },
434
692
  methods: {
@@ -437,6 +695,7 @@ export default {
437
695
  if (!this.handleButtons){
438
696
  this.getHandleButtons();
439
697
  }
698
+ if (!this.isDetail) this.getTaskStatus();
440
699
  this.getProcessHistory();
441
700
  this.getNextNodes();
442
701
  this.getAttachmentList();
@@ -473,10 +732,42 @@ export default {
473
732
  }
474
733
  },
475
734
 
735
+ getTaskStatus() {
736
+ const self = this
737
+ let params = {
738
+ procId: self.procId,
739
+ applyId: self.applyId,
740
+ taskNode: self.taskNode,
741
+ taskId: self.taskId,
742
+ auditGroup: self.auditGroup,
743
+ }
744
+ getProcessTodoList(0, 10, params).then(resp => {
745
+ if (resp.data.code === '200') {
746
+ const todoData = resp.data.data.rows[0]
747
+ // 委派任务状态
748
+ self.revokeDelegateTask = todoData?.delegateStatus ? todoData.delegateStatus === '10' : false
749
+ self.appointTask = todoData?.delegateStatus ? todoData.delegateStatus === '20' : false
750
+ // 判断节点是否是被驳回的节点
751
+ const taskExtensionAttributes = todoData?.taskExtensionAttributes ? JSON.parse(todoData.taskExtensionAttributes) : ''
752
+ if (taskExtensionAttributes && taskExtensionAttributes.rejectAttributes) {
753
+ const rejectAttributes = taskExtensionAttributes.rejectAttributes
754
+ if (rejectAttributes && rejectAttributes.type && rejectAttributes.type != 'inSequence') self.rejectedTask = true
755
+ }
756
+ }
757
+ })
758
+ },
476
759
  getHandleButtons() {
477
- getHandleButtons(this.procId, this.taskNode).then(resp => {
760
+ getNodeData(this.procId, this.taskNode).then(resp => {
478
761
  if (resp.data.code === '200') {
479
- this.handleButtons = resp.data.data[0]?.handleButtons;
762
+ const data = resp.data.data[0]
763
+ this.handleButtons = data.handleButtons ? data.handleButtons : ["processTrace", "auditHistory", "auditOpinion", "attachmentFile", "auditTo30", "auditTo70", "auditTo40", "auditTo90", "auditTo80", "auditTo82", "auditTo50"];
764
+ this.coSignVotingTask = data.handleButtons && data.handleButtons.includes('coSignVoting')
765
+ this.nextAssigneeSelectionType = data.nextAssigneeSelectionType;
766
+ this.passName = data.handleName;
767
+ this.rejectName = data.rejectName;
768
+ if (data.hasOwnProperty('isSequential')) {
769
+ this.curNodeType = data.isSequential ? NodeType.SequentialMultiNode : NodeType.MultiNode;
770
+ }
480
771
  }
481
772
  })
482
773
  },
@@ -573,7 +864,7 @@ export default {
573
864
  },
574
865
  processData(data) {
575
866
  return data.map(node => {
576
- node.personType = node.assignee ? "assignee" : "candidate";
867
+ node.personType = this.nextAssigneeSelectionType ? this.nextAssigneeSelectionType : node.assignee ? "assignee" : "candidate";
577
868
  if (node.assignee) {
578
869
  node.candidateGroups = {
579
870
  organs: [],
@@ -610,7 +901,10 @@ export default {
610
901
  return node;
611
902
  });
612
903
  },
613
- toggleDetails(index) {
904
+ async toggleDetails(index) {
905
+ if (!this.detailsVisible[index]){
906
+ await this.fetchTransferRange('appointHandlerWithCandGroups')
907
+ }
614
908
  this.$set(this.detailsVisible, index, !this.detailsVisible[index]);
615
909
  },
616
910
  onHandleTypeConfirm(selectedLabel, selectedIndex, index) {
@@ -631,6 +925,13 @@ export default {
631
925
  // 拼接成目标格式
632
926
  return `O:${organIds},U:${userIds},P:${positionIds},R:${roleIds},RP:,T:`;
633
927
  },
928
+ handleReductionUserSelect(handle) {
929
+ if (handle === 'select') {
930
+ this.updateMultitaskInstance('83', this.reductionUsers.map(item => item.userId).join(','))
931
+ } else {
932
+ this.checkResult = [];
933
+ }
934
+ },
634
935
  handleSelect(handle) {
635
936
  if (handle === 'select') {
636
937
  //处理审批参数
@@ -666,11 +967,77 @@ export default {
666
967
  },
667
968
  handleSelectOrganizePopupShow(index) {
668
969
  this.nextNodeHandleIndex = index;
970
+ if (this.useTransferOrgan){
971
+ this.permissionsScope.O = this.selectUserPopupParams.orgList.map(item => item.orgCode)
972
+ }
669
973
  this.selectOrganizePopupShow=true;
670
974
  },
671
- handleSelectUserPopupShow(index) {
975
+ handleCandUserSelect(index){
672
976
  this.nextNodeHandleIndex = index;
673
- this.selectUserPopupShow=true;
977
+ this.selectUserPopupParams.userList = []
978
+ this.selectUserPopupParams.orgList = []
979
+ this.selectCandUserPopupShow = true
980
+ },
981
+ async handleNextNodePopupShow(){
982
+ // 指定下一环节选人为单/多选并且给出具体选人范围则直接弹出选人框
983
+ if (this.nextAssigneeSelectionType){
984
+ const actionType = this.nextAssigneeSelectionType === 'assignee' ? 'appointHandler' : 'appointHandlerWithCandGroups'
985
+ const action = this.nextAssigneeSelectionType === 'assignee' ? (checkResult) => this.handleAssigneeSelectResult(checkResult) : (checkResult) => this.selectCandUserHandle(checkResult)
986
+ await this.fetchTransferRange(actionType);
987
+ if (this.selectUserPopupParams.userList?.length > 0 || this.selectUserPopupParams.orgList?.length > 0){
988
+ this.handleSelectUserPopupShow('选择用户', this.nextAssigneeSelectionType === 'candidate', action, actionType)
989
+ return
990
+ }
991
+ }
992
+ this.nextNodePopupShow = true;
993
+ },
994
+ handleNextNodeAssigneeSelect(index, actionType){
995
+ this.nextNodeHandleIndex = index;
996
+ this.handleSelectUserPopupShow('选择用户', true, (checkResult) => this.handleAssigneeSelectResult(checkResult), actionType)
997
+ },
998
+ handleNextNodeUserSelect(index, actionType){
999
+ this.nextNodeHandleIndex = index;
1000
+ this.handleSelectUserPopupShow('选择用户', true, (checkResult) => this.selectCandUserHandle(checkResult), actionType)
1001
+ },
1002
+ async handleSelectUserPopupShow(title, multiSelect, action, actionType) {
1003
+ this.selectUserPopupParams.title = title
1004
+ this.selectUserPopupParams.multiSelect = multiSelect
1005
+ this.selectUserPopupParams.action = action
1006
+ const success = await this.fetchTransferRange(actionType);
1007
+ if (success) {
1008
+ this.selectUserPopupShow = true;
1009
+ }
1010
+ },
1011
+ async fetchTransferRange(actionType) {
1012
+ try {
1013
+ const params = {
1014
+ procType: this.procType,
1015
+ procId: this.procId,
1016
+ taskNode: this.taskNode,
1017
+ applyId: this.applyId,
1018
+ taskId: this.taskId,
1019
+ instanceId: this.instanceId,
1020
+ actionType: actionType,
1021
+ };
1022
+ const res = await getTransferRange(params);
1023
+ const result = res.data;
1024
+ if (result.code == 200) {
1025
+ this.selectUserPopupParams.organTreeType = result.data.organTreeType;
1026
+ this.selectUserPopupParams.userList = result.data.userList;
1027
+ this.selectUserPopupParams.orgList = result.data.orgList;
1028
+ if (actionType === 'appointHandlerWithCandGroups'){
1029
+ this.useTransferUser = result.data.userList?.length > 0
1030
+ this.useTransferOrgan = result.data.orgList?.length > 0
1031
+ }
1032
+ return true;
1033
+ } else {
1034
+ console.warn('获取选择人员范围失败,返回码:', result.code);
1035
+ return false;
1036
+ }
1037
+ } catch (err) {
1038
+ console.error('获取选择人员范围异常', err);
1039
+ return false;
1040
+ }
674
1041
  },
675
1042
  handleSelectRolePopupShow(index) {
676
1043
  this.nextNodeHandleIndex = index;
@@ -719,13 +1086,20 @@ export default {
719
1086
 
720
1087
  getAuditButtonStatus(auditResult) {
721
1088
  let statusMap = {
722
- '30': '通过',
723
- '40': '驳回上一节点',
1089
+ '30': `${this.passName}`,
1090
+ '31': '同意',
1091
+ '32': '不同意',
1092
+ '40': `${this.rejectName}上一节点`,
724
1093
  '50': '直接结束流程',
725
- '70': '驳回到原点',
1094
+ '61': '交回',
1095
+ '62': '撤回委派',
1096
+ '70': `${this.rejectName}到原点`,
726
1097
  '80': '跳转指定节点',
1098
+ '81': '加签',
727
1099
  '82': '指定他人处理',
728
- '90': '驳回指定节点',
1100
+ '83': '减签',
1101
+ '84': '委派',
1102
+ '90': `${this.rejectName}指定节点`,
729
1103
  };
730
1104
  return statusMap[auditResult];
731
1105
  },
@@ -743,20 +1117,55 @@ export default {
743
1117
  procId: this.procId,
744
1118
  instanceId: this.instanceId,
745
1119
  taskNode: this.taskNode,
1120
+ taskId: this.taskId,
1121
+ predictButtonEnabled: this.handleButtons && this.handleButtons.includes('predictiveRoute'),
746
1122
  }
747
1123
  })
748
1124
  },
1125
+ // 加减签
1126
+ showUpdateMultitaskInstanceModal(updateType){
1127
+ this.selectHandlePopupShow = true
1128
+ const self = this
1129
+ if (updateType === '81') {
1130
+ self.handleSelectUserPopupShow('加签', true, (checkResult) => this.updateMultitaskInstance('81', checkResult.map(item => item.userId).join(',')), 'addMultitaskInstance')
1131
+ } else if (updateType === '83') {
1132
+ getUnapprovedListOfMultiNode(self.taskId).then(res => {
1133
+ if (res.data.code === '200') {
1134
+ self.unapprovedAssigneeList = res.data.data.map(item => ({...item, userId: item.auditId, organName: item.auditUserOrgan ? item.auditUserOrgan.split(':')[1] : '未知部门'}))
1135
+ self.selectReductionUserPopupShow = true
1136
+ } else {
1137
+ Toast.fail(resp.data.message)
1138
+ }
1139
+ this.selectUserPopupShow = false;
1140
+ }).catch(err => {
1141
+ console.log(err)
1142
+ this.selectUserPopupShow = false;
1143
+ })
1144
+ }
1145
+ },
1146
+ updateMultitaskInstance(updateType, assignees) {
1147
+ const self = this
1148
+ updateMultitaskInstance(self.taskId, self.applyId, assignees, updateType).then(res => {
1149
+ res.data.code == 200 ? Toast.success(res.data.message) :Toast.fail(res.data.message)
1150
+ self.selectUserPopupShow = false;
1151
+ self.selectReductionUserPopupShow = false
1152
+ }).catch(err => {
1153
+ console.log(err)
1154
+ self.selectUserPopupShow = false;
1155
+ self.selectReductionUserPopupShow = false
1156
+ })
1157
+ },
749
1158
  audit(auditResult) {
750
1159
  console.log('点击了审批:', auditResult);
751
1160
 
752
1161
  if (this.approvalForm.auditOpinion === '' || this.approvalForm.auditOpinion == null) {
753
- if (!this.handleButtons || this.handleButtons.includes('auditOpinion')) {
1162
+ if (!this.handleButtons || (this.handleButtons.includes('auditOpinion') && auditResult != '30' && auditResult != '31')) {
754
1163
  this.updateActiveTab()
755
1164
  this.approvalError = true
756
1165
  Toast({message: '请输入审批意见', duration: '500'});
757
1166
  return
758
1167
  } else {
759
- this.auditParams.auditOpinion = this.getAuditButtonStatus(this.auditResult);
1168
+ this.approvalForm.auditOpinion = this.getAuditButtonStatus(auditResult);
760
1169
  }
761
1170
  }
762
1171
 
@@ -785,21 +1194,35 @@ export default {
785
1194
  //字段不清楚 暂不传递
786
1195
  params: null,
787
1196
  }
788
- self.businessFormSave ? self.businessFormSave(self.handleSaveResult) : self.handleSaveResult(true)
1197
+ let auditResult = {
1198
+ code: self.auditResult,
1199
+ name: self.getAuditButtonStatus(self.auditResult)
1200
+ }
1201
+ self.businessFormSave ? self.businessFormSave(self.handleSaveResult, auditResult) : self.handleSaveResult(true)
789
1202
  },
790
- handleSaveResult(saveResult) {
1203
+ handleSaveResult(saveResult, businessParams) {
791
1204
  if (saveResult) {
792
- this.executeButtonAction();
1205
+ this.executeButtonAction(businessParams);
793
1206
  } else {
794
1207
  console.error('保存失败');
795
1208
  }
796
1209
  },
797
1210
 
798
- executeButtonAction() {
1211
+ executeButtonAction(businessParams) {
799
1212
  const self = this;
1213
+ if (businessParams) {
1214
+ self.auditParams.params = JSON.stringify(businessParams)
1215
+ }
1216
+ let auditResult = {
1217
+ code: self.auditResult,
1218
+ name: self.getAuditButtonStatus(self.auditResult)
1219
+ }
800
1220
  if (self.auditResult === '82') {
801
1221
  // 处理转办逻辑
802
- this.selectHandlePopupShow = true;
1222
+ this.handleSelectUserPopupShow('指定办理人', false, (checkResult) => this.handleSelectResult(checkResult), 'auditTo82')
1223
+ } else if (self.auditResult === '84') {
1224
+ // 处理委派逻辑
1225
+ this.handleSelectUserPopupShow('委派', false, (checkResult) => this.handleDelegateTaskSelectResult(checkResult), 'delegateTaskTask')
803
1226
  } else if (self.auditResult === '80') {
804
1227
  // 处理调转到指定节点逻辑
805
1228
  self.getNodesBehind()
@@ -813,6 +1236,7 @@ export default {
813
1236
  // 处理驳回上一节点逻辑
814
1237
  getPreNode(self.auditParams).then(function (resp) {
815
1238
  let result = resp.data
1239
+ // 上一节点为原点
816
1240
  if (result.code === '30010') {
817
1241
  Dialog.confirm({
818
1242
  title: "提示",
@@ -823,8 +1247,31 @@ export default {
823
1247
  self.auditRequest(self.auditParams)
824
1248
  }).catch(() => {
825
1249
  })
1250
+ } else if (result.code == '30013' || result.code == '30014') {
1251
+ //前序节点为子流程或当前节点为子流程第一个节点不可驳回上一级节点
1252
+ const message = self.rejectName ? self.replaceName(result.message, '驳回', self.rejectName) : result.message
1253
+ Toast.fail(message)
1254
+ //避免未提示消息直接回调
1255
+ setTimeout(() => {
1256
+ self.executionCompleted(false, null, null, auditResult, self.taskId)
1257
+ }, 1000)
1258
+ } else if (result.code == '10012') {
1259
+ // 数据同步
1260
+ self.disable = false
1261
+ Toast.fail(result.message)
1262
+ setTimeout(() => {
1263
+ self.executionCompleted(true, null, null, auditResult, self.taskId)
1264
+ }, 1000)
826
1265
  } else {
827
- self.auditRequest(self.auditParams)
1266
+ // 前序节点只有一个会签节点才可选择驳回人员
1267
+ self.showRejectToSelected = result.data.length === 1 && result.data[0].handleButtons?.includes('rejectToSelected')
1268
+ self.nodeList = result.data
1269
+ self.radio = 0
1270
+ if (self.showRejectToSelected && !self.handleButtons?.includes('rejectProcessControl')) {
1271
+ self.rejectAttributesBoxShow = true
1272
+ } else {
1273
+ self.handleButtons && self.handleButtons.includes('rejectProcessControl') ? self.getProcessAttributes() : self.auditRequest(self.auditParams)
1274
+ }
828
1275
  }
829
1276
  })
830
1277
  }).catch(() => {
@@ -848,12 +1295,94 @@ export default {
848
1295
  message: message,
849
1296
  })
850
1297
  },
1298
+ getProcessAttributes(targetTaskNodeProcessControl){
1299
+ const self = this
1300
+ self.rejectAttributeList = []
1301
+ if (!targetTaskNodeProcessControl || targetTaskNodeProcessControl != 'jump') {
1302
+ self.rejectAttributeList.push({
1303
+ _checked: true,
1304
+ type: 'inSequence',
1305
+ name: '按顺序流转'
1306
+ })
1307
+ }
1308
+ getProcessAttributes(self.procId, self.taskNode).then(resp => {
1309
+ if (resp.data.code === '200') {
1310
+ if ((self.auditParams.auditResult == '70' && !resp.data.data.jumpFirstNode) || (self.auditParams.auditResult == '40' && (resp.data.data.multiNode || resp.data.data.preNodeGateway))) {
1311
+ if (self.showRejectToSelected) {
1312
+ self.rejectAttributesBoxShow = true
1313
+ return
1314
+ }
1315
+ self.auditRequest(self.auditParams)
1316
+ return
1317
+ } else {
1318
+ let param = {
1319
+ procId: self.procId,
1320
+ applyId: self.applyId,
1321
+ taskNode: self.taskNode,
1322
+ taskId: self.curTaskId,
1323
+ }
1324
+ listAll(self.procId, self.applyId, self.taskNode, self.taskId).then(todoResp => {
1325
+ if (todoResp.data.code === '200') {
1326
+ const rows = todoResp.data.data.rows
1327
+ self.taskAuditUserList = rows.map(item => item.auditName)
1328
+ const isMultiNode = resp.data.data.multiNode
1329
+ if (isMultiNode) {
1330
+ const parentExecutionId = String(rows[0].parentExecutionId).trim();
1331
+ const nodeDone = self.processHistory.filter(item => item[0].taskNode === self.taskNode && String(item[0].parentExecutionId).trim() === parentExecutionId)
1332
+ if (nodeDone) {
1333
+ const doneAuditName = nodeDone[0].flatMap(item => item.auditName);
1334
+ self.taskAuditUserList = new Set([...doneAuditName, ...self.taskAuditUserList])
1335
+ }
1336
+ }
1337
+ if (self.auditParams.auditResult == '40' || self.taskAuditUserList.length === 1) {
1338
+ self.rejectAttributeList.push(
1339
+ {
1340
+ type: 'returnToCurrentAuditUser',
1341
+ name: '返回我'
1342
+ }
1343
+ )
1344
+ } else {
1345
+ self.rejectAttributeList.push(
1346
+ {
1347
+ type: 'returnToCurrentNode',
1348
+ name: '返回本节点'
1349
+ }
1350
+ )
1351
+ if (!isMultiNode) {
1352
+ self.rejectAttributeList.push(
1353
+ {
1354
+ type: 'returnToCurrentAuditUser',
1355
+ name: '返回我'
1356
+ }
1357
+ )
1358
+ }
1359
+ }
1360
+ self.showProcessControl = self.rejectAttributeList.length > 0 && self.handleButtons && self.handleButtons.includes('rejectProcessControl')
1361
+ if (self.auditParams.auditResult == '70' || self.auditParams.auditResult == '40') {
1362
+ self.rejectAttributesBoxShow = self.rejectAttributeList.length > 0 && self.handleButtons && self.handleButtons.includes('rejectProcessControl')
1363
+ }
1364
+ }
1365
+ }).catch((err) => {
1366
+ console.log(err)
1367
+ })
1368
+ }
1369
+ } else {
1370
+ self.$Message.error(resp.data.message)
1371
+ }
1372
+ }).catch(err => {
1373
+ console.log(err);
1374
+ Toast.fail('获取流程配置失败')
1375
+ })
1376
+ },
851
1377
  auditRequest(auditParams) {
852
1378
  let self = this
853
1379
  let auditResult = {
854
1380
  code: self.auditResult,
855
1381
  name: self.getAuditStatus(self.auditResult).text
856
1382
  }
1383
+ if (self.rejectUsers.id !== 'all'){
1384
+ auditParams.rejectUsers = self.rejectUsers.id
1385
+ }
857
1386
  self.showToastLoading('处理审批中');
858
1387
  //确认执行审批逻辑
859
1388
  audit(auditParams).then((resp) => { // 使用箭头函数
@@ -879,6 +1408,7 @@ export default {
879
1408
  this.executionCompleted(false, null, null, auditResult, self.taskId)
880
1409
  Toast.fail(result.message);
881
1410
  }
1411
+ this.selectUserPopupShow = false;
882
1412
  })
883
1413
  },
884
1414
  getNodesBehind() {
@@ -914,12 +1444,81 @@ export default {
914
1444
  this.nodeListDialogShow = false
915
1445
  this.auditResult = '';
916
1446
  this.radio = '';
1447
+ this.rejectAttribute = 'inSequence';
1448
+ this.targetTaskNodeProcessControl = ''
1449
+ },
1450
+ onBeforeClose(action, done) {
1451
+ const self = this;
1452
+ if (action === 'confirm') {
1453
+ if (!self.nodeList[self.radio]) {
1454
+ Toast.fail('请选择驳回节点!');
1455
+ done(false);
1456
+ return;
1457
+ }
1458
+ done(true);
1459
+ } else {
1460
+ done(true);
1461
+ }
1462
+ },
1463
+ selectNode(currentRow, index) {
1464
+ this.radio = index
1465
+ this.targetTaskNodeProcessControl = currentRow.processControl
1466
+ this.rejectUsers = { name: '全部办理人', id: 'all' }
1467
+ this.showRejectToSelected = currentRow.rejectToSelected
917
1468
  },
918
1469
  processJumpSpecifiedNode() {
919
1470
  const self = this;
1471
+ if (!self.nodeList[self.radio]) return;
920
1472
  self.auditParams.targetTaskNode = self.nodeList[self.radio].taskNode;
1473
+ self.auditParams.rejectAttribute = self.rejectAttribute ? self.rejectAttribute : 'inSequence'
1474
+ self.auditRequest(self.auditParams)
1475
+ },
1476
+ processRejectNode() {
1477
+ const self = this;
1478
+ self.auditParams.rejectAttribute = self.rejectAttribute ? self.rejectAttribute : 'inSequence'
921
1479
  self.auditRequest(self.auditParams)
922
1480
  },
1481
+ handleSelectRejectUser() {
1482
+ let self = this
1483
+ getDoneDetail(self.nodeList[self.radio].taskNode, self.applyId).then(function (resp) {
1484
+ if (resp.data.code === '200') {
1485
+ const data = resp.data.data.rows
1486
+ const latestAudit = data.reduce((max, current) => {
1487
+ return current.auditDate > max.auditDate ? current : max;
1488
+ });
1489
+ const seenNames = new Set();
1490
+ self.rejectUserList = data.filter(item => {
1491
+ if (item.parentExecutionId && latestAudit.parentExecutionId && item.parentExecutionId !== latestAudit.parentExecutionId) {
1492
+ return false;
1493
+ }
1494
+ if (seenNames.has(item.auditName)) {
1495
+ return false;
1496
+ }
1497
+ seenNames.add(item.auditName);
1498
+ return true;
1499
+ }).map(item => {
1500
+ return {
1501
+ ...item,
1502
+ userName: item.auditName,
1503
+ userId: item.auditId,
1504
+ organName: item.auditUserOrgan?.split(':')[1]
1505
+ }
1506
+ });
1507
+ self.selectRejectUserPopupShow = true
1508
+ } else {
1509
+ Toast.fail(resp.data.message)
1510
+ }
1511
+ })
1512
+ },
1513
+ rejectAttributesDialogShowClose(){
1514
+ //重置
1515
+ this.showRejectToSelected = false
1516
+ this.showProcessControl = false
1517
+ this.rejectAttributesBoxShow = false
1518
+ this.auditResult = '';
1519
+ this.radio = '';
1520
+ this.rejectAttribute = 'inSequence';
1521
+ },
923
1522
 
924
1523
  showAuditDetail(auditComment) {
925
1524
  Dialog.alert({
@@ -951,6 +1550,21 @@ export default {
951
1550
  }
952
1551
  });
953
1552
  },
1553
+ handleDelegateTaskSelectResult(checkResult) {
1554
+ console.log('Selected result:', checkResult);
1555
+ if (!checkResult) {
1556
+ Toast('请选择委派人员')
1557
+ return
1558
+ }
1559
+ this.auditParams.selectedUserId = checkResult[0].userId
1560
+ Dialog.confirm({
1561
+ message: '确定执行:' + this.getAuditButtonStatus(this.auditResult) + ' ?',
1562
+ }).then(() => {
1563
+ this.auditRequest(this.auditParams)
1564
+ }).catch(() => {
1565
+ // on cancel
1566
+ });
1567
+ },
954
1568
  handleSelectResult(checkResult) {
955
1569
  console.log('Selected result:', checkResult);
956
1570
  const self = this;
@@ -963,7 +1577,16 @@ export default {
963
1577
  self.auditParams.selectedUserId = checkResult[0].userId;
964
1578
  self.auditRequest(self.auditParams);
965
1579
  }
966
- self.selectHandlePopupShow = false;
1580
+ self.selectUserPopupShow = false;
1581
+ },
1582
+ handleAssigneeSelectResult(checkResult) {
1583
+ console.log('Selected result:', checkResult);
1584
+ this.nextNodeProcessedData[this.nextNodeHandleIndex].assignee.id = checkResult[0].userId;
1585
+ this.nextNodeProcessedData[this.nextNodeHandleIndex].assignee.name = checkResult[0].userName;
1586
+ if (!this.nextNodePopupShow){
1587
+ this.handleSelect('select')
1588
+ }
1589
+ this.selectUserPopupShow = false;
967
1590
  },
968
1591
  selectOrganizeHandle(handle, checkedNodes) {
969
1592
  if (handle === 'select') {
@@ -975,13 +1598,22 @@ export default {
975
1598
  }
976
1599
  this.selectOrganizePopupShow = false
977
1600
  },
978
- selectUserHandle(checkResult) {
1601
+ selectCandUserHandle(checkResult) {
979
1602
  this.nextNodeProcessedData[this.nextNodeHandleIndex].candidateGroups.users =
980
1603
  checkResult.map(item => ({
981
1604
  name: item.userName,
982
1605
  id: item.userId,
983
1606
  }));
1607
+ if (!this.nextNodePopupShow){
1608
+ this.handleSelect('select')
1609
+ }
984
1610
  this.selectUserPopupShow = false;
1611
+ this.selectCandUserPopupShow = false;
1612
+ },
1613
+ selectRejectUserHandle(checkResult) {
1614
+ this.rejectUsers.name = checkResult.map(item => item.userName).join(',')
1615
+ this.rejectUsers.id = checkResult.map(item => item.userId).join(',')
1616
+ this.selectRejectUserPopupShow = false;
985
1617
  },
986
1618
  selectPositionHandle(handle, result) {
987
1619
  if (handle === 'select') {
@@ -1015,6 +1647,18 @@ export default {
1015
1647
  if (!this.activeFirstTab) {
1016
1648
  this.updateActiveTab();
1017
1649
  }
1650
+ },
1651
+ watch: {
1652
+ targetTaskNodeProcessControl(val) {
1653
+ const self = this
1654
+ if (self.handleButtons && self.handleButtons.includes('rejectProcessControl')) {
1655
+ if (val == 'inSequence') {
1656
+ self.showProcessControl = false
1657
+ return
1658
+ }
1659
+ self.getProcessAttributes(val)
1660
+ }
1661
+ },
1018
1662
  }
1019
1663
 
1020
1664
  };
@@ -1086,6 +1730,17 @@ export default {
1086
1730
  background-color: #1989fa;
1087
1731
  }
1088
1732
 
1733
+ .disagree {
1734
+ color: #fff;
1735
+ background: linear-gradient(90deg, #ff4d4f, #f5222d);
1736
+ border-radius: 9px;
1737
+ margin: 0 20px;
1738
+ }
1739
+
1740
+ .disagree:active {
1741
+ background-color: #ff7875;
1742
+ }
1743
+
1089
1744
  .title-info {
1090
1745
  font-weight: bold;
1091
1746
  font-size: 14px;
@@ -1158,7 +1813,7 @@ export default {
1158
1813
  font-size: 15px;
1159
1814
  }
1160
1815
 
1161
- .table-row {
1816
+ .table-row, .reject-attribute {
1162
1817
  display: flex;
1163
1818
  border-bottom: 1px solid #ebedf0;
1164
1819
  font-size: 14px;
@@ -1175,6 +1830,14 @@ export default {
1175
1830
  border-bottom: none;
1176
1831
  }
1177
1832
 
1833
+ .reject-attribute > div {
1834
+ padding: 10px 10px 10px 5px;
1835
+ }
1836
+ .reject-attribute .van-radio {
1837
+ padding: 5px;
1838
+ justify-content: flex-start !important;
1839
+ }
1840
+
1178
1841
  .van-radio {
1179
1842
  justify-content: center;
1180
1843
  }