ny
23 小时以前 b6f169fe43a2b13f351aefc152374fc7f0bc8cb7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
package jnpf.flowable.util;
 
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.ImmutableList;
import jnpf.base.UserInfo;
import jnpf.base.model.base.SystemBaeModel;
import jnpf.base.model.systemconfig.SysConfigModel;
import jnpf.constant.MsgCode;
import jnpf.exception.WorkFlowException;
import jnpf.flowable.entity.*;
import jnpf.flowable.enums.*;
import jnpf.flowable.mapper.*;
import jnpf.flowable.model.flowable.FlowAbleUrl;
import jnpf.flowable.model.flowable.FlowableNodeModel;
import jnpf.flowable.model.flowable.NextOrPrevFo;
import jnpf.flowable.model.operator.AddSignModel;
import jnpf.flowable.model.task.FlowMethod;
import jnpf.flowable.model.task.FlowModel;
import jnpf.flowable.model.templatenode.ButtonModel;
import jnpf.flowable.model.templatenode.TaskNodeModel;
import jnpf.flowable.model.templatenode.nodejson.FileConfig;
import jnpf.flowable.model.templatenode.nodejson.NodeModel;
import jnpf.flowable.model.templatenode.nodejson.PrintConfig;
import jnpf.flowable.model.templatenode.nodejson.ProperCond;
import jnpf.flowable.model.util.FlowNature;
import jnpf.permission.model.authorize.AuthorizeVO;
import jnpf.util.JsonUtil;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import java.util.*;
import java.util.stream.Collectors;
 
/**
 * 类的描述
 *
 * @author JNPF@YinMai Info. Co., Ltd
 * @version 5.0.x
 * @since 2024/5/16 17:35
 */
@Component
public class ButtonUtil {
 
    @Autowired
    private FlowAbleUrl flowAbleUrl;
    @Autowired
    private ServiceUtil serviceUtil;
    @Autowired
    private OperatorMapper operatorMapper;
    @Autowired
    private TaskMapper taskMapper;
    @Autowired
    private RevokeMapper revokeMapper;
    @Autowired
    private FlowUtil flowUtil;
    @Autowired
    private EventLogMapper eventLogMapper;
    @Autowired
    private TriggerRecordMapper triggerRecordMapper;
    @Autowired
    private RecordMapper recordMapper;
    @Autowired
    private TemplateMapper templateMapper;
 
    /**
     * 按钮控制
     *
     * @param flowModel 参数
     */
    public ButtonModel handleButton(FlowModel flowModel) throws WorkFlowException {
        String opType = flowModel.getOpType();
        TaskEntity taskEntity = flowModel.getTaskEntity();
        OperatorEntity operatorEntity = flowModel.getOperatorEntity();
        RecordEntity recordEntity = flowModel.getRecordEntity();
        Map<String, Object> formData = flowModel.getFormData();
        List<TaskNodeModel> nodeList = flowModel.getNodeList();
        TemplateEntity template = flowModel.getTemplateEntity();
        UserInfo userInfo = flowModel.getUserInfo() == null ? UserProvider.getUser() : flowModel.getUserInfo();
        String userId = userInfo.getUserId();
 
        List<TemplateNodeEntity> nodeEntityList = flowModel.getNodeEntityList();
        Map<String, NodeModel> nodes = new HashMap<>();
        for (TemplateNodeEntity nodeEntity : nodeEntityList) {
            nodes.put(nodeEntity.getNodeCode(), JsonUtil.getJsonToBean(nodeEntity.getNodeJson(), NodeModel.class));
        }
        flowModel.setNodes(nodes);
        RevokeEntity revokeEntity = revokeMapper.getRevokeTask(taskEntity.getId());
 
        // 全局节点
        NodeModel global = nodes.get(NodeEnum.global.getType());
 
        ButtonModel model = new ButtonModel();
        FlowMethod flowMethod = new FlowMethod();
        flowMethod.setNodes(nodes);
        flowMethod.setTaskEntity(taskEntity);
        flowMethod.setFormData(formData);
        flowMethod.setPrintNodeList(nodeList);
        OpTypeEnum type = OpTypeEnum.getType(opType);
        switch (type) {
            case LaunchCreate: // 我发起的新建/编辑
//                List<Integer> templateStatus = ImmutableList.of(1, 2);
//                if (!templateStatus.contains(template.getStatus())) {
//                    break;
//                }
                // 是否是退回撤回的任务
                List<Integer> taskStatus = ImmutableList.of(TaskStatusEnum.BACKED.getCode(), TaskStatusEnum.RECALL.getCode());
                boolean isBack = taskStatus.contains(taskEntity.getStatus());
                if (isBack) {
                    // 是否是委托的任务
                    boolean isDelegate = StringUtil.isNotBlank(taskEntity.getDelegateUserId());
                    if (isDelegate) {
                        if (ObjectUtil.equals(taskEntity.getParentId(), FlowNature.ParentId)) {
                            model.setHasDelegateSubmitBtn(this.checkDelegateSubmit(userId, template));
                        }
                    }
                } else {
                    // 委托发起
                    if (null == taskEntity.getId()) {
                        model.setHasDelegateSubmitBtn(this.checkDelegateSubmit(userId, template));
                    } else {
                        if (ObjectUtil.equals(taskEntity.getParentId(), FlowNature.ParentId)) {
                            model.setHasDelegateSubmitBtn(this.checkDelegateSubmit(userId, template));
                        }
                    }
                }
 
                //暂存和发起按钮
                boolean commonUser = serviceUtil.isCommonUser(userId);
                if (commonUser) {
                    if (null == taskEntity.getId() || ObjectUtil.equals(taskEntity.getParentId(), FlowNature.ParentId)) {
                        AuthorizeVO authorizeByUser = serviceUtil.getAuthorizeByUser();
                        List<String> systemIdList = authorizeByUser.getSystemList().stream().filter(t -> !Objects.equals(t.getIsMain(), 1)).map(SystemBaeModel::getId).collect(Collectors.toList());
                        if (!systemIdList.isEmpty()) {
                            QueryWrapper<TemplateEntity> queryWrapper = new QueryWrapper<>();
                            queryWrapper.lambda().in(TemplateEntity::getSystemId, systemIdList)
                                    .eq(TemplateEntity::getVisibleType, FlowNature.All);
                            queryWrapper.lambda().select(TemplateEntity::getId);
                            List<TemplateEntity> list = templateMapper.selectList(queryWrapper);
                            List<String> permissionList = list.stream().map(TemplateEntity::getId).collect(Collectors.toList());
                            permissionList.addAll(authorizeByUser.getFlowIdList());
                            if (permissionList.contains(template.getId())) {
                                model.setHasSubmitBtn(true);
                                model.setHasSaveBtn(true);
                            }
                        }
                    } else {
                        model.setHasSubmitBtn(true);
                        model.setHasSaveBtn(true);
                    }
                } else {
                    model.setHasSubmitBtn(true);
                    model.setHasSaveBtn(true);
                }
                break;
            case LaunchDetail: // 我发起的详情
                // 打印
                TemplateNodeEntity start = nodeEntityList.stream().filter(e -> e.getNodeType().equals(NodeEnum.start.getType())).findFirst().orElse(null);
                if (null != start) {
                    NodeModel startNode = JsonUtil.getJsonToBean(start.getNodeJson(), NodeModel.class);
                    flowMethod.setNodeModel(startNode);
                    model.setHasPrintBtn(this.checkPrint(flowMethod));
                }
                // 催办
                List<Integer> statusList = ImmutableList.of(TaskStatusEnum.RUNNING.getCode(), TaskStatusEnum.REVOKING.getCode());
                if (global.getHasInitiatorPressOverdueNode() && statusList.contains(taskEntity.getStatus())) {
                    QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
                    queryWrapper.lambda().eq(OperatorEntity::getTaskId, taskEntity.getId()).eq(OperatorEntity::getCompletion, FlowNature.Normal)
                            .ne(OperatorEntity::getStatus, OperatorStateEnum.Futility.getCode())
                            .isNull(OperatorEntity::getHandleStatus).isNotNull(OperatorEntity::getDuedate);
                    List<OperatorEntity> operatorList = operatorMapper.selectList(queryWrapper);
                    if (!operatorList.isEmpty()) {
                        model.setHasPressBtn(true);
                    }
                }
                // 撤回
                if (null == revokeEntity) {
                    flowModel.setFlag(FlowNature.InitiateFlag);
                    if (this.checkRecall(flowModel)) {
                        model.setHasRecallLaunchBtn(true);
                    }
                }
                // 撤销,全局属性开启 且 同意状态的任务才能撤销 且不是子流程
                if (global.getHasRevoke() && Objects.equals(taskEntity.getStatus(), TaskStatusEnum.PASSED.getCode())
                        && Objects.equals(taskEntity.getParentId(), FlowNature.ParentId)) {
                    Boolean isExist = revokeMapper.checkExist(taskEntity.getId());
                    if (null == revokeEntity && isExist) {
                        model.setHasRevokeBtn(true);
                    }
                }
                break;
            case Sign: // 待签事宜
                if (Objects.equals(taskEntity.getStatus(), TaskStatusEnum.PAUSED.getCode())) {
                    break;
                }
                model.setHasSignBtn(true);
                if (null != operatorEntity) {
                    model.setProxyMark(!ObjectUtil.equals(operatorEntity.getHandleId(), userId));
                    NodeModel nodeModel = nodes.get(operatorEntity.getNodeCode());
                    if (this.checkViewStartForm(global, nodeModel)) {
                        model.setHasViewStartFormBtn(true);
                    }
                }
                break;
            case Todo: // 待办事宜
                if (Objects.equals(taskEntity.getStatus(), TaskStatusEnum.PAUSED.getCode())) {
                    break;
                }
                if (global.getHasSignFor()) {
                    model.setHasReduceSignBtn(true);
                }
                model.setHasTransactBtn(true);
                if (null != operatorEntity) {
                    NodeModel nodeModel = nodes.get(operatorEntity.getNodeCode());
                    if (this.checkViewStartForm(global, nodeModel)) {
                        model.setHasViewStartFormBtn(true);
                    }
                }
                break;
            case Doing: // 在办事宜
                if (Objects.equals(taskEntity.getStatus(), TaskStatusEnum.PAUSED.getCode())) {
                    break;
                }
                if (null == operatorEntity) {
                    break;
                }
                // 待办的opType传的也是3,所以待办的代理标识需要再在办判断
                model.setProxyMark(!ObjectUtil.equals(operatorEntity.getHandleId(), userId));
                if (null != revokeEntity) {
                    model.setHasAuditBtn(true);
                    model.setHasRejectBtn(true);
                    break;
                }
                NodeModel nodeModel = nodes.get(operatorEntity.getNodeCode());
                if (null == nodeModel) {
                    break;
                }
                if (this.checkViewStartForm(global, nodeModel)) {
                    model.setHasViewStartFormBtn(true);
                }
                // 协办状态的经办 只有协办保存按钮
                if (OperatorStateEnum.Assist.getCode().equals(operatorEntity.getStatus())) {
                    model.setHasAssistSaveBtn(true);
                    break;
                }
                // 打印
                flowMethod.setNodeModel(nodeModel);
                model.setHasPrintBtn(this.checkPrint(flowMethod));
                if (nodeModel.getHasAuditBtn()) {
                    model.setHasAuditBtn(true);
                }
                if (nodeModel.getHasRejectBtn() && ObjectUtil.equals(operatorEntity.getIsProcessing(), FlowNature.NotProcessing)) {
                    model.setHasRejectBtn(true);
                }
                if (nodeModel.getHasBackBtn() && taskEntity.getRejectDataId() == null) {
                    model.setHasBackBtn(true);
                }
                if (nodeModel.getHasSaveAuditBtn()) {
                    model.setHasSaveAuditBtn(true);
                }
                List<Integer> operatorState = ImmutableList.of(OperatorStateEnum.AddSign.getCode(), OperatorStateEnum.Transfer.getCode());
                if (nodeModel.getHasFreeApproverBtn()) {
                    if (!ObjectUtil.equals(operatorEntity.getStatus(), OperatorStateEnum.Transfer.getCode())) {
                        model.setHasFreeApproverBtn(this.checkAddSign(operatorEntity, null, false));
                    }
                }
                if (nodeModel.getHasTransferBtn()) {
                    if (!operatorState.contains(operatorEntity.getStatus()) && ObjectUtil.equals(operatorEntity.getParentId(), FlowNature.ParentId)) {
                        model.setHasTransferBtn(true);
                    }
                }
                if (nodeModel.getHasAssistBtn()) {
                    model.setHasAssistBtn(true);
                }
                break;
            case Done: // 已办事宜
                if (null == operatorEntity || operatorEntity.getId() == null) {
                    break;
                }
                // 减签
                NodeModel node = nodes.get(operatorEntity.getNodeCode());
                // 节点属性开启、经办存在加签信息、记录是加签操作
                if (node != null) {
                    if (null != recordEntity) {
                        if (node.getHasReduceApproverBtn() && null != operatorEntity.getHandleParameter()
                                && recordEntity.getHandleType().equals(RecordEnum.addSign.getCode())) {
                            QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
                            queryWrapper.lambda().eq(OperatorEntity::getTaskId, operatorEntity.getTaskId())
                                    .eq(OperatorEntity::getParentId, operatorEntity.getId())
                                    .ne(OperatorEntity::getStatus, OperatorStateEnum.Futility.getCode())
                                    .ne(OperatorEntity::getStatus, OperatorStateEnum.Assist.getCode())
                                    .eq(OperatorEntity::getCompletion, FlowNature.Normal).isNull(OperatorEntity::getHandleStatus);
                            List<OperatorEntity> list = operatorMapper.selectList(queryWrapper);
                            if (CollectionUtil.isNotEmpty(list)) {
                                model.setHasReduceApproverBtn(true);
                            }
                        }
                        // 审批撤回
                        List<Integer> handleTypes = ImmutableList.of(RecordEnum.audit.getCode(), RecordEnum.reject.getCode());
                        if (handleTypes.contains(recordEntity.getHandleType())) {
                            flowModel.setFlag(FlowNature.ApprovalFlag);
                            if (this.checkRecall(flowModel)) {
                                model.setHasRecallAuditBtn(true);
                            }
                        }
                    }
                    flowMethod.setNodeModel(node);
                    // 打印
                    model.setHasPrintBtn(this.checkPrint(flowMethod));
                    if (this.checkViewStartForm(global, node)) {
                        model.setHasViewStartFormBtn(true);
                    }
                }
                break;
            case Circulate: // 抄送事宜
                if (null != operatorEntity) {
                    NodeModel node1 = nodes.get(operatorEntity.getNodeCode());
                    if (this.checkViewStartForm(global, node1)) {
                        model.setHasViewStartFormBtn(true);
                    }
                }
                break;
            case Monitor: // 流程监控
                // 终止状态下只有复活
                if (ObjectUtil.equals(taskEntity.getStatus(), TaskStatusEnum.CANCEL.getCode())
                        && ObjectUtil.equals(taskEntity.getParentId(), FlowNature.ParentId) && ObjectUtil.equals(template.getStatus(), TemplateStatueEnum.up.getCode())) {
                    List<TriggerRecordEntity> triggerRecordList = triggerRecordMapper.getListByTaskId(taskEntity.getId());
                    long count = triggerRecordList.stream().filter(e -> ObjectUtil.equals(e.getStatus(), TriggerRecordEnum.EXCEPTION.getCode())).count();
                    if (count == 0) {
                        model.setHasActivateBtn(true);
                    }
                }
                // 挂起状态下只有恢复
                if (ObjectUtil.equals(taskEntity.getStatus(), TaskStatusEnum.PAUSED.getCode())) {
                    if (!ObjectUtil.equals(taskEntity.getIsRestore(), FlowNature.NotRestore)) {
                        model.setHasRebootBtn(true);
                    }
                }
                // 运行状态下,终止、挂起
                if (ObjectUtil.equals(taskEntity.getStatus(), TaskStatusEnum.RUNNING.getCode())) {
                    // 子流程不允许终止
                    if (ObjectUtil.equals(taskEntity.getParentId(), FlowNature.ParentId)) {
                        model.setHasCancelBtn(true);
                    }
                    model.setHasPauseBtn(true);
                    if (this.checkAssign(taskEntity, nodes)) {
                        model.setHasAssignBtn(true);
                    }
                }
                // 归档按钮
                FileConfig config = global.getFileConfig();
                if (config.getOn() && StringUtil.isNotBlank(config.getTemplateId())) {
                    if (ObjectUtil.isNotEmpty(taskEntity.getEndTime()) || ObjectUtil.equals(taskEntity.getStatus(), TaskStatusEnum.CANCEL.getCode())) {
                        if (serviceUtil.checkFlowFile(taskEntity.getId())) {
                            model.setHasFileBtn(true);
                        }
                    }
                }
                break;
        }
        return model;
    }
 
    // 判断指派,当前节点全是子流程,就隐藏
    public boolean checkAssign(TaskEntity taskEntity, Map<String, NodeModel> nodes) {
        String currentNodeCode = taskEntity.getCurrentNodeCode();
        if (StringUtil.isNotBlank(currentNodeCode)) {
            List<String> currentNodeList = Arrays.stream(currentNodeCode.split(",")).collect(Collectors.toList());
            for (String nodeCode : currentNodeList) {
                NodeModel nodeModel = nodes.get(nodeCode);
                if (null != nodeModel && !Objects.equals(nodeModel.getType(), NodeEnum.subFlow.getType())) {
                    return true;
                }
            }
        }
        return false;
    }
 
    // 委托发起按钮
    public boolean checkDelegateSubmit(String userId, TemplateEntity template) {
        List<DelegateEntity> delegateList = flowUtil.getByToUserId(userId, 0);
        if (CollectionUtil.isNotEmpty(delegateList) && ObjectUtil.equals(template.getStatus(), TemplateStatueEnum.up.getCode())) {
            for (DelegateEntity delegateEntity : delegateList) {
                String flowId = delegateEntity.getFlowId();
                if (StringUtil.isNotBlank(flowId)) {
                    if (flowId.contains(template.getId())) {
                        if (ObjectUtil.equals(template.getVisibleType(), FlowNature.All)) {
                            return true;
                        }
                        List<String> launchPermission = serviceUtil.getPermission(delegateEntity.getUserId());
                        if (launchPermission.contains(template.getId())) {
                            return true;
                        }
                    }
                } else {
                    // 全部流程
                    if (ObjectUtil.equals(template.getVisibleType(), FlowNature.All)) {
                        return true;
                    }
                    List<String> launchPermission = serviceUtil.getPermission(delegateEntity.getUserId());
                    if (launchPermission.contains(template.getId())) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
 
    /**
     * 查看发起表单
     */
    public boolean checkViewStartForm(NodeModel global, NodeModel nodeModel) {
        if (null != nodeModel) {
            if (global.getHasAloneConfigureForms() && StringUtil.isNotBlank(nodeModel.getFormId())) {
                return true;
            }
        }
        return false;
    }
 
    /**
     * 判断撤回
     *
     * @param flowModel 参数
     */
    public boolean checkRecall(FlowModel flowModel) throws WorkFlowException {
        String deploymentId = flowModel.getDeploymentId();
        String currentNodeCode = flowModel.getNodeEntity().getNodeCode();
        TaskEntity taskEntity = flowModel.getTaskEntity();
        RecordEntity recordEntity = flowModel.getRecordEntity();
        Map<String, NodeModel> nodes = flowModel.getNodes();
        // 判断撤回的标识  1.发起撤回  2.审批撤回
        int flag = flowModel.getFlag();
        boolean isException = flowModel.getIsException();
 
        NodeModel global = nodes.get(NodeEnum.global.getType());
        Integer recallRule = global.getRecallRule();
 
        // 全局撤回配置为1 直接不允许撤回 (流程撤回规则  1: 不允许撤回  2: 发起节点允许撤回  3:所有节点允许撤回)
        if (recallRule == null || Objects.equals(recallRule, FlowNature.NotAllowed)) {
            return false;
        }
 
        // 不是进行中的任务、存在退回冻结数据
        if (!Objects.equals(TaskStatusEnum.RUNNING.getCode(), taskEntity.getStatus()) || null != taskEntity.getRejectDataId()) {
            if (isException) {
                throw new WorkFlowException(MsgCode.WF036.get());
            }
            return false;
        }
        // 经办未审批 说明是已撤回的,不允许撤回
        OperatorEntity operator = operatorMapper.getInfo(recordEntity.getOperatorId());
        if (null != operator) {
            if (!ObjectUtil.equals(operator.getParentId(), FlowNature.ParentId)) {
                if (isException) {
                    throw new WorkFlowException(MsgCode.WF077.get());
                }
                return false;
            }
            // 判断依次审批
            boolean inTurn = this.checkInTurn(operator, isException);
            if (!inTurn && !isException) {
                return false;
            }
            //判断逐级审批
            boolean inStep = this.checkStep(operator, isException);
            if (!inStep && !isException) {
                return false;
            }
            if (operator.getHandleStatus() == null) {
                if (isException) {
                    throw new WorkFlowException(MsgCode.WF006.get());
                }
                return false;
            } else if (null == operator.getHandleTime()) {
                // 后加签的同意未真正审批,不允许撤回
                List<OperatorEntity> childList = operatorMapper.getChildList(operator.getId());
                if (CollectionUtil.isNotEmpty(childList)) {
                    if (isException) {
                        throw new WorkFlowException(MsgCode.WF006.get());
                    }
                    return false;
                }
            }
        } else {
            // 发起撤回的校验
            QueryWrapper<RecordEntity> recordWrapper = new QueryWrapper<>();
            recordWrapper.lambda().eq(RecordEntity::getTaskId, taskEntity.getId()).ne(RecordEntity::getStatus, FlowNature.Invalid);
            List<RecordEntity> recordList = recordMapper.selectList(recordWrapper);
            if (CollectionUtil.isNotEmpty(recordList)) {
                RecordEntity submit = recordList.stream().filter(e -> ObjectUtil.equals(e.getHandleType(), RecordEnum.submit.getCode())).findFirst().orElse(null);
                if (null != submit) {
                    recordList = recordList.stream().filter(e -> !ObjectUtil.equals(e.getNodeCode(), submit.getNodeCode())).collect(Collectors.toList());
                }
                if (!recordList.isEmpty()) {
                    if (isException) {
                        throw new WorkFlowException(MsgCode.WF006.get());
                    }
                    return false;
                }
            }
 
            //外部节点
            List<EventLogEntity> eventLogList = eventLogMapper.getList(taskEntity.getId()).stream().filter(e -> Objects.equals(FlowNature.Success, e.getStatus())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(eventLogList)) {
                if (!eventLogList.isEmpty()) {
                    if (isException) {
                        throw new WorkFlowException(MsgCode.WF006.get());
                    }
                    return false;
                }
            }
        }
        // 获取节点的下一级节点,判断撤回
        NextOrPrevFo fo = new NextOrPrevFo();
        fo.setDeploymentId(deploymentId);
        fo.setTaskKey(currentNodeCode);
        List<FlowableNodeModel> nextModels = flowAbleUrl.getNext(fo);
        List<String> nextCodes = nextModels.stream().map(FlowableNodeModel::getId).collect(Collectors.toList());
        // 审批撤回需要用到下一级节点
        flowModel.setNextCodes(nextCodes);
 
        if (CollectionUtil.isNotEmpty(nextCodes)) {
            QueryWrapper<TaskEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(TaskEntity::getParentId, taskEntity.getId())
                    .in(TaskEntity::getSubCode, nextCodes);
            List<TaskEntity> list = taskMapper.selectList(queryWrapper);
            if (CollectionUtil.isNotEmpty(list)) {
                // 异步子流程,不允许撤回
                long asyncCount = list.stream().filter(e -> Objects.equals(e.getIsAsync(), FlowNature.ChildAsync)).count();
                if (asyncCount > 0) {
                    return false;
                }
                long count = list.stream().filter(e -> !Objects.equals(e.getStatus(), TaskStatusEnum.TO_BE_SUBMIT.getCode())).count();
                if (count > 0) {
                    if (isException) {
                        throw new WorkFlowException(MsgCode.WF036.get());
                    }
                    return false;
                }
            }
 
            //外部节点只要有成功数据,不允许撤回
            List<EventLogEntity> eventLogList = eventLogMapper.getList(taskEntity.getId(), nextCodes).stream().filter(e -> Objects.equals(FlowNature.Success, e.getStatus())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(eventLogList)) {
                if (!eventLogList.isEmpty()) {
                    if (isException) {
                        throw new WorkFlowException(MsgCode.WF006.get());
                    }
                    return false;
                }
            }
        }
 
        if (Objects.equals(flag, FlowNature.ApprovalFlag) && Objects.equals(recallRule, FlowNature.StartAllowed)) {
            return false;
        }
        if (CollectionUtil.isEmpty(nextCodes)) {
            return true;
        }
        // 存在已办理的经办,撤回后可以重新提交(下个审批节点只进行了签收 此时还可以撤回)
        QueryWrapper<OperatorEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(OperatorEntity::getTaskId, taskEntity.getId());
        if (CollectionUtil.isNotEmpty(nextCodes)) {
            wrapper.lambda().in(OperatorEntity::getNodeCode, nextCodes);
        }
        wrapper.lambda().orderByDesc(OperatorEntity::getCreatorTime);
        List<OperatorEntity> list = operatorMapper.selectList(wrapper);
        boolean mark = this.checkDraftAndRecord(list);
        if (mark) {
            if (isException) {
                throw new WorkFlowException(MsgCode.WF077.get());
            }
            return false;
        }
 
        //todo 2025-01-23 加签和被加签人不能撤回
        if (operator != null) {
            if (!Objects.equals(operator.getParentId(), FlowNature.ParentId)) {
                return false;
            }
            if (StringUtil.isNotEmpty(operator.getHandleParameter())) {
                return false;
            }
        }
        return true;
    }
 
    // 依次审批的撤回判断
    public boolean checkInTurn(OperatorEntity operator, boolean isException) throws WorkFlowException {
        if (StringUtil.isNotBlank(operator.getHandleAll())) {
            List<String> handleIds = Arrays.stream(operator.getHandleAll().split(",")).collect(Collectors.toList());
            int index = handleIds.indexOf(operator.getHandleId());
            if (index != -1 && index < handleIds.size() - 1) {
                String nextHandleId = handleIds.get(index + 1);
                QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().eq(OperatorEntity::getHandleId, nextHandleId).eq(OperatorEntity::getParentId, operator.getParentId())
                        .eq(OperatorEntity::getNodeId, operator.getNodeId()).orderByDesc(OperatorEntity::getCreatorTime);
                List<OperatorEntity> list = operatorMapper.selectList(queryWrapper);
                if (CollectionUtil.isNotEmpty(list)) {
                    OperatorEntity nextOperator = list.get(0);
                    if (StringUtil.isNotEmpty(nextOperator.getDraftData())) {
                        if (isException) {
                            throw new WorkFlowException(MsgCode.WF036.get());
                        }
                        return false;
                    }
                    QueryWrapper<RecordEntity> recordWrapper = new QueryWrapper<>();
                    recordWrapper.lambda().eq(RecordEntity::getOperatorId, nextOperator.getId()).ne(RecordEntity::getStatus, FlowNature.Invalid);
                    List<RecordEntity> recordList = recordMapper.selectList(recordWrapper);
                    if (CollectionUtil.isNotEmpty(recordList)) {
                        if (isException) {
                            throw new WorkFlowException(MsgCode.WF036.get());
                        }
                        return false;
                    }
                }
            }
        }
        return true;
    }
 
    // 逐级审批的撤回判断
    public boolean checkStep(OperatorEntity operator, boolean isException) throws WorkFlowException {
        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperatorEntity::getTaskId, operator.getTaskId());
        List<OperatorEntity> operatorList = operatorMapper.selectList(queryWrapper);
        List<OperatorEntity> list = operatorList.stream().filter(e -> Objects.equals(e.getHandleAll(), operator.getId())).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(list)) {
            OperatorEntity nextOperator = list.get(0);
            if (StringUtil.isNotEmpty(nextOperator.getDraftData())) {
                if (isException) {
                    throw new WorkFlowException(MsgCode.WF036.get());
                }
                return false;
            }
            QueryWrapper<RecordEntity> recordWrapper = new QueryWrapper<>();
            recordWrapper.lambda().eq(RecordEntity::getOperatorId, nextOperator.getId()).ne(RecordEntity::getStatus, FlowNature.Invalid);
            List<RecordEntity> recordList = recordMapper.selectList(recordWrapper);
            if (CollectionUtil.isNotEmpty(recordList)) {
                if (isException) {
                    throw new WorkFlowException(MsgCode.WF036.get());
                }
                return false;
            }
        }
        return true;
    }
 
    public boolean checkDraftAndRecord(List<OperatorEntity> list) {
        return this.checkDraftAndRecord(list, false);
    }
 
    // 判断草稿、操作记录
    public boolean checkDraftAndRecord(List<OperatorEntity> list, boolean filterAddSign) {
        list = list.stream().filter(e -> !ObjectUtil.equals(e.getStatus(), OperatorStateEnum.Futility.getCode())).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(list)) {
            return false;
        }
//        if (CollectionUtil.isNotEmpty(list)) {
//            // 回流的处理
//            OperatorEntity first = list.get(0);
//            list = list.stream().filter(e -> ObjectUtil.equals(first.getNodeId(), e.getNodeId())).collect(Collectors.toList());
//        }
        // 只要有操作就不让撤回,草稿数据(暂存)
        long draftCount = list.stream().filter(e -> StringUtil.isNotEmpty(e.getDraftData())).count();
        boolean mark = false;
        // 不存在草稿数据,继续根据记录判断
        if (draftCount == 0) {
            List<String> collect = list.stream().map(OperatorEntity::getId).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(collect)) {
                QueryWrapper<RecordEntity> recordWrapper = new QueryWrapper<>();
                recordWrapper.lambda().in(RecordEntity::getOperatorId, collect).ne(RecordEntity::getStatus, FlowNature.Invalid);
                List<RecordEntity> recordList = recordMapper.selectList(recordWrapper);
                if (filterAddSign) {
                    List<Integer> status = ImmutableList.of(RecordEnum.addSign.getCode(), RecordEnum.subtractSign.getCode());
                    recordList = recordList.stream().filter(e -> !status.contains(e.getHandleType())).collect(Collectors.toList());
                }
                mark = !recordList.isEmpty();
            }
        } else {
            mark = true;
        }
        return mark;
    }
 
    /**
     * 判断打印
     */
    public boolean checkPrint(FlowMethod flowMethod) {
        NodeModel nodeModel = flowMethod.getNodeModel();
        TaskEntity taskEntity = flowMethod.getTaskEntity();
        Map<String, Object> formData = flowMethod.getFormData();
        List<TaskNodeModel> nodeList = flowMethod.getPrintNodeList();
 
        // 发起除了草稿状态都显示
        if (Objects.equals(taskEntity.getStatus(), TaskStatusEnum.TO_BE_SUBMIT.getCode())) {
            return false;
        }
        PrintConfig printConfig = nodeModel.getPrintConfig();
        if (printConfig.getOn()) {
            // 打印没有选择模版,按钮不显示
            if (CollectionUtil.isEmpty(printConfig.getPrintIds())) {
                return false;
            }
            switch (PrintEnum.getPrint(printConfig.getConditionType())) {
                case none:
                    // 不限制
                    return true;
                case nodeEnd:
                    // 节点结束
                    // 开始节点直接返回true,除草稿状态
                    if (nodeModel.getType().equals(NodeEnum.start.getType())
                            && !taskEntity.getStatus().equals(TaskStatusEnum.TO_BE_SUBMIT.getCode())) {
                        return true;
                    }
                    TaskNodeModel taskNode = nodeList.stream().filter(e -> e.getNodeCode().equals(nodeModel.getNodeId())).findFirst().orElse(null);
                    if (null != taskNode && taskNode.getType().equals(NodeTypeEnum.pass.getType())) {
                        return true;
                    }
                    break;
                case flowEnd:
                    // 流程结束
                    List<Integer> status = ImmutableList.of(TaskStatusEnum.PASSED.getCode(), TaskStatusEnum.REJECTED.getCode());
                    if (status.contains(taskEntity.getStatus())) {
                        return true;
                    }
                    break;
                case conditions:
                    // 条件设置
                    List<ProperCond> conditions = printConfig.getConditions();
                    String matchLogic = printConfig.getMatchLogic();
                    UserInfo userInfo = UserProvider.getUser();
                    flowMethod.setUserInfo(userInfo);
                    flowMethod.setUserEntity(serviceUtil.getUserInfo(userInfo.getUserId()));
                    flowMethod.setConditions(conditions);
                    flowMethod.setMatchLogic(matchLogic);
                    if (FlowJsonUtil.nodeConditionDecide(flowMethod)) {
                        return true;
                    }
                    break;
            }
        }
        return false;
    }
 
    /**
     * 判断加签
     */
    public void checkAddSign(OperatorEntity operator, AddSignModel parameter) throws WorkFlowException {
        this.checkAddSign(operator, parameter, true);
    }
 
    public boolean checkAddSign(OperatorEntity operator, AddSignModel parameter, Boolean isException) throws WorkFlowException {
        int level = 1;
        if (!ObjectUtil.equals(operator.getParentId(), FlowNature.ParentId)) {
            OperatorEntity parent = operatorMapper.selectById(operator.getParentId());
            if (null != parent) {
                String handleParameter = parent.getHandleParameter() == null ? operator.getHandleParameter() : parent.getHandleParameter();
                AddSignModel jsonToBean = JsonUtil.getJsonToBean(handleParameter, AddSignModel.class);
                level = jsonToBean.getLevel() + 1;
            }
        }
        SysConfigModel sysConfig = serviceUtil.getSysConfig();
        Integer addSignLevel = sysConfig.getAddSignLevel();
        if (level > addSignLevel) {
            if (isException) {
                throw new WorkFlowException(MsgCode.WF143.get());
            }
            return false;
        }
        if (null != parameter) {
            parameter.setLevel(level);
        }
        return true;
    }
}