Ver código fonte

修改流程的审批同意接口

huanglc 2 semanas atrás
pai
commit
0a19d5afa2

+ 4 - 4
bpm-client-http/src/main/java/com/srm/bpm/facde/oa/WebServiceRequestInfo.java

@@ -3,17 +3,17 @@ package com.srm.bpm.facde.oa;
3 3
 public class WebServiceRequestInfo {
4 4
 
5 5
 
6
-     //正式
6
+/*     //正式
7 7
     public static final String oaRequestAddress = "http://172.16.0.36"; //正式环境
8 8
 // public static final String oaRequestAddress = "http://172.16.0.37:8081"; //测试环境
9 9
 
10
-    public static final String oaEtenAddress="http://uoa.jqh.cc:20600";
10
+    public static final String oaEtenAddress="http://uoa.jqh.cc:20600";*/
11 11
 
12
-/*    //测试
12
+    //测试
13 13
 //public static final String oaRequestAddress = "http://172.16.0.36"; //E8正式环境
14 14
 public static final String oaRequestAddress = "http://172.16.1.36"; //E8假环境
15 15
 // public static final String oaRequestAddress = "http://172.16.0.37:8081"; //(失效)测试环境
16 16
 
17 17
 //public static final String oaEtenAddress="http://uoa.jqh.cc:20600";//E10正式环境
18
-public static final String oaEtenAddress="http://172.16.0.59:20666/";//E10测试环境*/
18
+public static final String oaEtenAddress="http://172.16.0.59:20666/";//E10测试环境
19 19
 }

+ 324 - 39
bpm-core/src/main/java/com/srm/bpm/logic/service/impl/BillBpmnLogicImpl.java

@@ -28,6 +28,7 @@ import com.srm.bpm.logic.constant.BillAction;
28 28
 import com.srm.bpm.logic.constant.BillStatus;
29 29
 import com.srm.bpm.logic.constant.BillTaskStatus;
30 30
 import com.srm.bpm.logic.constant.BpmnConst;
31
+import com.srm.bpm.logic.constant.Const;
31 32
 import com.srm.bpm.logic.constant.NodeLinkType;
32 33
 import com.srm.bpm.logic.constant.StringPool;
33 34
 import com.srm.bpm.logic.context.BillDataContext;
@@ -206,10 +207,10 @@ public class BillBpmnLogicImpl implements BillBpmnLogic {
206 207
         variables.put(BpmnConst.VAR_FORM_DATA, formDataParam);
207 208
         variables.put(BpmnConst.VAR_BILL_CONTEXT, varDataContext);
208 209
         variables.put(BpmnConst.VAR_APPLY_PROCESS, processDetail.getId());
209
-        variables.put(BpmnConst.VAR_APPLY_EMPLOYEE, authenticatedUserId);
210
-        variables.put(BpmnConst.VAR_APPROVER_EMPLOYEE, authenticatedUserId);
210
+        variables.put(BpmnConst.VAR_APPLY_EMPLOYEE, authenticatedUserId);//申请人
211
+        variables.put(BpmnConst.VAR_APPROVER_EMPLOYEE, authenticatedUserId);//审批人
211 212
         variables.put(BpmnConst.VAR_ACTION, BillAction.submit.name());
212
-        variables.put(BpmnConst.VAR_NEXT_APPROVER, nextApprover);
213
+        variables.put(BpmnConst.VAR_NEXT_APPROVER, nextApprover);//下一个审批人
213 214
         variables.put(BpmnConst.VAR_AGREE_DATA, Maps.newHashMap());
214 215
         final ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery()
215 216
                 .processInstanceBusinessKey(businessKey).active();
@@ -494,33 +495,78 @@ public class BillBpmnLogicImpl implements BillBpmnLogic {
494 495
         taskService.complete(taskId, variables);
495 496
         return true;*/
496 497
 
497
-        // 先检查运行时任务是否存在
498
+        // 查询【当前流程】对应的【处理中】的【任务节点】信息
498 499
         final Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
500
+
501
+        // 如果流程没有【处理中】的节点,就查询【已处理】的节点
499 502
         if (task == null) {
500
-            // 检查历史任务,看是否已经完成
501 503
             final org.activiti.engine.history.HistoricTaskInstance historicTask = historyService
502 504
                     .createHistoricTaskInstanceQuery()
503 505
                     .taskId(taskId)
504 506
                     .singleResult();
507
+
508
+            // 【已处理】节点不为空
505 509
             if (historicTask != null) {
506
-                log.warn("任务已经完成,跳过完成操作。taskId: {}, billId: {}, 完成时间: {}",
507
-                        taskId, bill != null ? bill.getId() : null, historicTask.getEndTime());
508
-                // 检查归档条件并触发回调
510
+
511
+                /*// 判断是否是自动审批
512
+                final boolean isAutoAgree = Const.AUTO_AGREE_OPTION.equals(opinion);
513
+
514
+                // 默认是最后一个节点
515
+                boolean isLastNode = true;
516
+                if (bill != null && bill.getId() != null) {
517
+                    final String processInstanceId = bill.getProcessInstanceId();
518
+                    if (!Strings.isNullOrEmpty(processInstanceId)) {
519
+
520
+                        // 查询该【流程实例】的活跃节点,
521
+                        // 【有活跃任务】 --> 不是最后一个节点
522
+                        // 【无活跃任务】 --> 是最后一个节点
523
+                        final List<Task> activeTasks = taskService.createTaskQuery()
524
+                                .processInstanceId(processInstanceId)
525
+                                .active()
526
+                                .list();
527
+                        isLastNode = CollectionUtil.isEmpty(activeTasks);
528
+                    }
529
+                }
530
+
531
+
532
+                log.warn("任务已经完成,跳过完成操作。taskId: {}, billId: {}, 完成时间: {}, isAutoAgree: {}, isLastNode: {}",
533
+                        taskId, bill != null ? bill.getId() : null, historicTask.getEndTime(), isAutoAgree, isLastNode);*/
534
+                
535
+                // 如果 toa_bill 的 status 为 1【审批中】,且 bill_task 的最后一个节点为【归档节点】,则触发回调
509 536
                 checkAndTriggerArchiveCallback(bill, taskId);
510
-                // 检查流程是否应该结束
537
+                
538
+                // 如果是自动审批且是最后一个节点,直接触发完成逻辑(重复触发了)
539
+                /*if (isAutoAgree && isLastNode) {
540
+                    log.info("任务已完成,自动审批最后一个节点,直接触发审批单完成逻辑和回调。billId: {}, taskId: {}",
541
+                            bill != null ? bill.getId() : null, taskId);
542
+                    triggerBillCompleteCallback(bill);
543
+                    return true;
544
+                }*/
545
+
546
+                // 如果没有【审批待办】了,但还不是【归档】状态,二次触发【回调】
511 547
                 checkAndCompleteBillIfNeeded(bill);
512 548
                 return true;
513 549
             } else {
514
-                log.warn("Activiti任务不存在,可能已经被删除。taskId: {}, billId: {},跳过完成操作。业务数据已更新。",
515
-                        taskId, bill != null ? bill.getId() : null);
550
+                log.warn("Activiti任务不存在,可能已经被删除。taskId: {}, billId: {},跳过完成操作。业务数据已更新。", taskId, bill != null ? bill.getId() : null);
551
+                
516 552
                 // 检查归档条件并触发回调
517 553
                 checkAndTriggerArchiveCallback(bill, taskId);
554
+                
555
+                /*// 如果是自动审批且是最后一个节点,直接触发完成逻辑
556
+                if (isAutoAgree && isLastNode) {
557
+                    log.info("任务不存在,自动审批最后一个节点,直接触发审批单完成逻辑和回调。billId: {}, taskId: {}",
558
+                            bill != null ? bill.getId() : null, taskId);
559
+                    triggerBillCompleteCallback(bill);
560
+                    return true;
561
+                }*/
562
+                
518 563
                 // 检查流程是否应该结束
519 564
                 checkAndCompleteBillIfNeeded(bill);
520 565
                 return true; // 业务数据已更新,返回成功
521 566
             }
522 567
         }
523 568
 
569
+        // 如果能查询到【当前流程】对应的【处理中】的【任务节点】信息
524 570
         Map<String, Object> variables = Maps.newHashMap();
525 571
         variables.put(BpmnConst.VAR_OPINION, opinion);
526 572
         variables.put(BpmnConst.VAR_APPROVER_EMPLOYEE, userCode);
@@ -542,33 +588,257 @@ public class BillBpmnLogicImpl implements BillBpmnLogic {
542 588
         }
543 589
 
544 590
         try {
591
+            // 判断是否是自动审批
592
+            final boolean isAutoAgree = Const.AUTO_AGREE_OPTION.equals(opinion);
593
+
594
+            // 设置task_bill表数据
545 595
             taskService.complete(taskId, variables);
546 596
 
547
-            // 任务完成后,先检查归档条件并触发回调
597
+            // 如果是自动审批,需要判断是否是最后一个节点
598
+            if (isAutoAgree) {
599
+                // 检查是否有下一个节点(通过检查运行时待办任务)
600
+                // taskService.complete() 会同步触发 CreateTaskListener,所以这里检查时下一个节点应该已经创建
601
+                boolean isLastNode = true;
602
+                if (bill != null && bill.getId() != null) {
603
+                    final String processInstanceId = bill.getProcessInstanceId();
604
+                    if (!Strings.isNullOrEmpty(processInstanceId)) {
605
+                        final List<Task> activeTasks = taskService.createTaskQuery()
606
+                                .processInstanceId(processInstanceId)
607
+                                .active()
608
+                                .list();
609
+                        isLastNode = CollectionUtil.isEmpty(activeTasks);
610
+                    }
611
+                }
612
+
613
+                // 当前节点是最后一个节点,执行检查和回调方法
614
+                if (isLastNode) {
615
+                    log.info("自动审批完成,当前节点是最后一个节点,执行检查和回调方法。billId: {}, taskId: {}", bill != null ? bill.getId() : null, taskId);
616
+
617
+                    // 如果 toa_bill 的 status 为 1【审批中】,且 bill_task 的最后一个节点为【归档节点】,则触发回调
618
+                    checkAndTriggerArchiveCallback(bill, taskId);
619
+                    
620
+                    /*// 再检查流程是否应该结束(无论是否是归档节点,都要检查)
621
+                    // 因为最后一个节点可能不是归档节点,但流程已经结束,需要完成审批单
622
+                    final String processInstanceId = bill != null ? bill.getProcessInstanceId() : null;
623
+                    boolean shouldTriggerComplete = false;
624
+                    
625
+                    if (!Strings.isNullOrEmpty(processInstanceId)) {
626
+                        // 检查是否有运行时待办任务
627
+                        final List<Task> activeTasks = taskService.createTaskQuery()
628
+                                .processInstanceId(processInstanceId)
629
+                                .active()
630
+                                .list();
631
+                        
632
+                        if (CollectionUtil.isEmpty(activeTasks)) {
633
+                            // 没有运行时待办任务,检查历史流程实例是否已结束
634
+                            final org.activiti.engine.history.HistoricProcessInstance historicProcessInstance = historyService
635
+                                    .createHistoricProcessInstanceQuery()
636
+                                    .processInstanceId(processInstanceId)
637
+                                    .singleResult();
638
+                            
639
+                            if (historicProcessInstance != null && historicProcessInstance.getEndTime() != null) {
640
+                                // 流程已结束,立即触发完成逻辑和回调
641
+                                log.info("自动审批完成,最后一个节点,流程已结束(历史流程实例已结束)。立即触发审批单完成逻辑和回调。billId: {}, taskId: {}",
642
+                                        bill != null ? bill.getId() : null, taskId);
643
+                                shouldTriggerComplete = true;
644
+                            } else {
645
+                                // 流程实例可能还没有完全结束(endTime 可能还是 null),但没有运行时待办任务
646
+                                // 说明流程实际上已经结束,只是 Activiti 还没有更新历史流程实例
647
+                                // 此时也应该触发完成逻辑
648
+                                log.info("自动审批完成,最后一个节点,没有运行时待办任务,流程应该已结束(即使历史流程实例 endTime 为 null)。立即触发审批单完成逻辑和回调。billId: {}, taskId: {}",
649
+                                        bill != null ? bill.getId() : null, taskId);
650
+                                shouldTriggerComplete = true;
651
+                            }
652
+                        }
653
+                    } else {
654
+                        // 流程实例ID为空,但所有任务都已完成,应该完成审批单
655
+                        log.info("自动审批完成,最后一个节点,流程实例ID为空,但所有任务都已完成。立即触发审批单完成逻辑和回调。billId: {}, taskId: {}",
656
+                                bill != null ? bill.getId() : null, taskId);
657
+                        shouldTriggerComplete = true;
658
+                    }
659
+                    
660
+                    if (shouldTriggerComplete) {
661
+                        // 触发完成逻辑和回调
662
+                        triggerBillCompleteCallback(bill);
663
+                        return true;
664
+                    }*/
665
+                    
666
+                    // 如果流程实例还没有结束,检查是否应该结束(兜底机制)
667
+                    checkAndCompleteBillIfNeeded(bill);
668
+                    return true;
669
+                }/*else {
670
+                    // todo 如果是自动审批节点,但不是最后一个节点,则需要处理完当前节点,再新建下一个节点
671
+                    // 下一个节点的自动审批会在 saveBillApprover() 中递归处理
672
+                    log.info("自动审批完成,当前节点不是最后一个节点,等待下一个节点处理。billId: {}, taskId: {}", bill != null ? bill.getId() : null, taskId);
673
+                    return true;
674
+                }*/
675
+
676
+            }
677
+
678
+            // 【手动审批】 || 【自动审批】但不是【最后一个节点】:任务完成后,先检查归档条件并触发回调
548 679
             checkAndTriggerArchiveCallback(bill, taskId);
549 680
 
550
-            // 任务完成后,立即检查流程是否结束,如果结束则触发回调
681
+            // 手动审批场景:判断下一个节点是否是自动审批节点
682
+            // 步骤一:先完成本节点审批事件,生成下一个节点的审批信息(已完成,通过 taskService.complete())
683
+            // 步骤二:判断下一个节点是否是自动审批节点,如果是,则自动调用审批通过的方法
551 684
             if (bill != null && bill.getId() != null) {
552 685
                 final String processInstanceId = bill.getProcessInstanceId();
553 686
                 if (!Strings.isNullOrEmpty(processInstanceId)) {
554
-                    // 先检查运行时流程实例是否还有待办任务
687
+                    // 检查是否有下一个节点
555 688
                     final List<Task> activeTasks = taskService.createTaskQuery()
556 689
                             .processInstanceId(processInstanceId)
557 690
                             .active()
558 691
                             .list();
559 692
 
560
-                    // 如果没有待办任务,检查流程是否已结束
561
-                    if (CollectionUtil.isEmpty(activeTasks)) {
693
+
694
+                    // 有下一个节点
695
+                    if (CollectionUtil.isNotEmpty(activeTasks)) {
696
+                        final Task nextTask = activeTasks.get(0);
697
+                        final String nextTaskNodeId = nextTask.getTaskDefinitionKey();
698
+                        final Long processId = bill.getProcessId();
699
+                        
700
+                        if (processId != null && !Strings.isNullOrEmpty(nextTaskNodeId)) {
701
+                            // 获取下一个节点的配置
702
+                            final Optional<ProcessNodeExtendEntity> nextNodeExtendOpt = nodeExtendService
703
+                                    .findByNodeIdAndProcessId(processId, nextTaskNodeId);
704
+                            
705
+                            if (nextNodeExtendOpt.isPresent()) {
706
+                                final ProcessNodeExtendEntity nextNodeExtend = nextNodeExtendOpt.get();
707
+                                final String nextNodeAutoAgree = nextNodeExtend.getAutoAgree();
708
+                                
709
+                                // 判断下一个节点是否配置了自动审批
710
+                                if (!Strings.isNullOrEmpty(nextNodeAutoAgree)) {
711
+                                    // 下一个节点是自动审批节点,需要检查是否满足自动审批条件
712
+                                    // 这里需要查询下一个节点的 bill_task,检查是否满足自动审批条件
713
+                                    final List<BillTaskEntity> nextNodeTasks = billTaskService.list(
714
+                                            com.baomidou.mybatisplus.core.toolkit.Wrappers.lambdaQuery(BillTaskEntity.class)
715
+                                                    .eq(BillTaskEntity::getBillId, bill.getId())
716
+                                                    .eq(BillTaskEntity::getTaskId, nextTask.getId())
717
+                                                    .eq(BillTaskEntity::getIsDeleted, 0)
718
+                                    );
719
+                                    
720
+                                    if (CollectionUtil.isNotEmpty(nextNodeTasks)) {
721
+                                        // 检查下一个节点的任务是否满足自动审批条件
722
+                                        final BillTaskLogic billTaskLogic = SpringContextHolder.getBean(BillTaskLogic.class);
723
+                                        
724
+                                        // 获取上一个节点的任务ID(用于判断是否是同一个处理人)
725
+                                        // 使用当前完成的 taskId 作为 lastTaskId
726
+                                        final String nextNodeLastTaskId = taskId;
727
+                                        
728
+                                        // 检查是否满足自动审批条件
729
+                                        final BillTaskEntity autoAgreeTask = billTaskLogic.autoAgree(
730
+                                                nextNodeExtend, nextNodeTasks, nextNodeLastTaskId, bill.getId());
731
+
732
+                                        // 有下一个节点,且下一个节点满足自动审批条件,自动调用审批通过的方法
733
+                                        if (autoAgreeTask != null) {
734
+                                            log.info("手动审批完成,下一个节点是自动审批节点且满足条件,自动调用审批通过的方法。billId: {}, nextTaskId: {}, nextNodeKey: {}",
735
+                                                    bill.getId(), nextTask.getId(), nextTaskNodeId);
736
+                                            
737
+                                            // 会签判断
738
+                                            final BillLogic billLogic = SpringContextHolder.getBean(BillLogic.class);
739
+                                            final boolean goFlag = billLogic.agreeIsGoOn(autoAgreeTask);
740
+                                            if (goFlag) {
741
+                                                // 自动审批下一个节点
742
+                                                // 使用当前完成的 taskId 作为 lastTaskId
743
+                                                this.complete(bill, nextTask.getId(), Const.AUTO_AGREE_OPTION, 
744
+                                                        autoAgreeTask.getUserCode(), "", "", 
745
+                                                        nextTaskNodeId, nextNodeLastTaskId);
746
+                                                
747
+                                                // 删除待审批的信息
748
+                                                billTaskService.deleteApproval(bill.getId(), nextTask.getId(), 
749
+                                                        BillTaskStatus.APPROVAL.getStatus());
750
+                                            }
751
+                                            /*else {
752
+                                                //todo 转办操作
753
+                                                transfer(billTasks, billId);
754
+                                                final List<BillTaskEntity> approvingByBillAndTaskId = this.billTaskService.findApprovingByBillAndTaskId(billId, taskId);
755
+                                                msgLogic.sendMsg(approvingByBillAndTaskId);
756
+                                                return approvingByBillAndTaskId;
757
+                                            }*/
758
+                                        }else {
759
+                                            /*//todo 转办操作
760
+                                            transfer(billTasks, billId);
761
+                                            final List<BillTaskEntity> approvingByBillAndTaskId = this.billTaskService.findApprovingByBillAndTaskId(billId, taskId);
762
+                                            msgLogic.sendMsg(approvingByBillAndTaskId);
763
+                                            return approvingByBillAndTaskId;*/
764
+                                        }
765
+                                    }
766
+                                }else {
767
+                                    // 下一个节点是手动审批节点
768
+                                    log.info("手动审批完成,下一个节点是手动审批节点,等待审批人处理。billId: {}, nextTaskId: {}, nextNodeKey: {}", bill.getId(), nextTask.getId(), nextTaskNodeId);
769
+
770
+                                    // 查询下一个节点的 bill_task 记录
771
+                                    final List<BillTaskEntity> nextNodeTasks = billTaskService.list(
772
+                                            com.baomidou.mybatisplus.core.toolkit.Wrappers.lambdaQuery(BillTaskEntity.class)
773
+                                                    .eq(BillTaskEntity::getBillId, bill.getId())
774
+                                                    .eq(BillTaskEntity::getTaskId, nextTask.getId())
775
+                                                    .eq(BillTaskEntity::getIsDeleted, 0)
776
+                                    );
777
+
778
+                                    if (CollectionUtil.isNotEmpty(nextNodeTasks)) {
779
+                                        // 使用当前完成的 taskId 作为 lastTaskId
780
+                                        final String nextNodeLastTaskId = taskId;
781
+
782
+                                        // 检查并更新 lastTaskId,确保正确关联到当前完成的节点
783
+                                        boolean needUpdate = false;
784
+                                        for (BillTaskEntity nextNodeTask : nextNodeTasks) {
785
+                                            // 如果 lastTaskId 不正确,需要更新
786
+                                            if (!Objects.equals(nextNodeTask.getLastTaskId(), nextNodeLastTaskId)) {
787
+                                                nextNodeTask.setLastTaskId(nextNodeLastTaskId);
788
+                                                nextNodeTask.setLastNodeKey(lastTaskNodeId); // 同时更新 lastNodeKey
789
+                                                needUpdate = true;
790
+                                            }
791
+                                        }
792
+
793
+                                        if (needUpdate) {
794
+                                            log.info("手动审批完成,更新下一个手动审批节点的 lastTaskId。billId: {}, nextTaskId: {}, lastTaskId: {} -> {}",
795
+                                                    bill.getId(), nextTask.getId(), nextNodeTasks.get(0).getLastTaskId(), nextNodeLastTaskId);
796
+                                            billTaskService.updateBatchById(nextNodeTasks);
797
+                                        } else {
798
+                                            log.info("手动审批完成,下一个手动审批节点的 lastTaskId 已正确关联。billId: {}, nextTaskId: {}, lastTaskId: {}",
799
+                                                    bill.getId(), nextTask.getId(), nextNodeLastTaskId);
800
+                                        }
801
+                                    } else {
802
+                                        log.warn("手动审批完成,下一个节点是手动审批节点,但未找到对应的 bill_task 记录。billId: {}, nextTaskId: {}, nextNodeKey: {}",
803
+                                                bill.getId(), nextTask.getId(), nextTaskNodeId);
804
+                                    }
805
+                                }
806
+
807
+                            }
808
+                        }
809
+                    } else {
810
+                        // 没有下一个节点,当前节点是最后一个节点了(【手动审批】)
811
+
562 812
                         // 检查历史流程实例是否已结束
563 813
                         final org.activiti.engine.history.HistoricProcessInstance historicProcessInstance = historyService
564 814
                                 .createHistoricProcessInstanceQuery()
565 815
                                 .processInstanceId(processInstanceId)
566 816
                                 .singleResult();
567 817
 
818
+                        // 流程正常已结束,立即触发完成逻辑和回调
568 819
                         if (historicProcessInstance != null && historicProcessInstance.getEndTime() != null) {
569
-                            // 流程已结束,立即触发完成逻辑和回调
570
-                            log.info("任务完成后,检测到流程已结束(没有待办任务且历史流程实例已结束)。立即触发审批单完成逻辑和回调。billId: {}, taskId: {}",
571
-                                    bill.getId(), taskId);
820
+                            log.info("任务完成后,检测到流程已结束(没有待办任务且历史流程实例已结束)。立即触发审批单完成逻辑和回调。billId: {}, taskId: {}", bill.getId(), taskId);
821
+
822
+                            // 如果 toa_bill 的 status 为 1【审批中】,且 bill_task 的最后一个节点为【归档节点】,则触发回调
823
+                            checkAndTriggerArchiveCallback(bill, taskId);
824
+                            triggerBillCompleteCallback(bill);
825
+                            return true;
826
+
827
+                        }else if(historicProcessInstance != null && historicProcessInstance.getEndTime() == null) {
828
+                            // 流程实例可能还没有完全结束(endTime 可能还是 null),但没有运行时待办任务
829
+                            // 说明流程实际上已经结束,只是 Activiti 还没有更新历史流程实例
830
+                            // 此时也应该触发完成逻辑
831
+                            log.info("自动审批完成,最后一个节点,没有运行时待办任务,流程应该已结束(即使历史流程实例 endTime 为 null)。立即触发审批单完成逻辑和回调。billId: {}, taskId: {}",
832
+                                    bill != null ? bill.getId() : null, taskId);
833
+                            checkAndTriggerArchiveCallback(bill, taskId);
834
+                            triggerBillCompleteCallback(bill);
835
+                            return true;
836
+
837
+                        }else if(historicProcessInstance == null){
838
+                            // 流程实例ID为空,但所有任务都已完成,应该完成审批单
839
+                            log.info("手动审批完成,最后一个节点,流程实例ID为空,但所有任务都已完成。立即触发审批单完成逻辑和回调。billId: {}, taskId: {}", bill != null ? bill.getId() : null, taskId);
840
+                            // 如果 toa_bill 的 status 为 1【审批中】,且 bill_task 的最后一个节点为【归档节点】,则触发回调
841
+                            checkAndTriggerArchiveCallback(bill, taskId);
572 842
                             triggerBillCompleteCallback(bill);
573 843
                             return true;
574 844
                         }
@@ -576,7 +846,7 @@ public class BillBpmnLogicImpl implements BillBpmnLogic {
576 846
                 }
577 847
             }
578 848
 
579
-            // 如果流程未结束,检查是否应该结束(用于处理没有Activiti任务但业务任务已完成的情况)
849
+            // 如果流程未结束,检查是否应该结束(用于处理没有Activiti任务但业务任务已完成的情况)【二次确认归档】
580 850
             checkAndCompleteBillIfNeeded(bill);
581 851
             return true;
582 852
         } catch (org.activiti.engine.ActivitiObjectNotFoundException e) {
@@ -593,7 +863,7 @@ public class BillBpmnLogicImpl implements BillBpmnLogic {
593 863
 
594 864
     /**
595 865
      * 检查归档条件并触发回调
596
-     * 如果 toa_bill 的 status 为 1(审批中)且 bill_task 的最后一个节点审批状态为 2(已同意),则触发回调
866
+     * 如果 toa_bill 的 status 为 1【审批中】,且 bill_task 的最后一个节点为【归档节点】,则触发回调
597 867
      *
598 868
      * @param bill 审批单实体
599 869
      * @param taskId 任务ID
@@ -658,6 +928,8 @@ public class BillBpmnLogicImpl implements BillBpmnLogic {
658 928
                 // 检查最后一个任务是否是归档节点
659 929
                 final Long processId = latestBill.getProcessId();
660 930
                 if (processId != null && !Strings.isNullOrEmpty(lastTask.getTaskNodeKey())) {
931
+
932
+                    // 查询【当前节点】的【流程节点配置表元数据】
661 933
                     final Optional<ProcessNodeExtendEntity> nodeExtendOpt = nodeExtendService
662 934
                             .findByNodeIdAndProcessId(processId, lastTask.getTaskNodeKey());
663 935
 
@@ -713,7 +985,10 @@ public class BillBpmnLogicImpl implements BillBpmnLogic {
713 985
     }
714 986
 
715 987
     /**
716
-     * 检查审批单是否应该完成,如果是最后一个节点且没有待审批任务,则完成审批单
988
+     * 如果没有【审批待办】了,但还不是【归档】状态,触发【回调】
989
+     *  有流程实例,且是最后一个节点就要归档(如果有流程实例,但不是最后一个节点,目前不管。)
990
+     *  不能查到流程实例,也要归档(可能最后一个节点当时没有【归档】就结束任务了,重新触发【归档】)
991
+     *
717 992
      * 
718 993
      * @param bill 审批单实体
719 994
      */
@@ -721,31 +996,42 @@ public class BillBpmnLogicImpl implements BillBpmnLogic {
721 996
         if (bill == null || bill.getId() == null) {
722 997
             return;
723 998
         }
999
+
1000
+        final ToaBillEntity latestBill = billService.getById(bill.getId());
1001
+        if (latestBill == null) {
1002
+            return;
1003
+        }
724 1004
         
725 1005
         try {
726 1006
             // 先检查是否有待审批的bill_task
727 1007
             final List<BillTaskEntity> approvalTasks = billTaskService.list(
728 1008
                     com.baomidou.mybatisplus.core.toolkit.Wrappers.lambdaQuery(BillTaskEntity.class)
729
-                            .eq(BillTaskEntity::getBillId, bill.getId())
1009
+                            .eq(BillTaskEntity::getBillId, latestBill.getId())
730 1010
                             .eq(BillTaskEntity::getNodeStatus, BillTaskStatus.APPROVAL.getStatus())
731 1011
                             .eq(BillTaskEntity::getIsDeleted, 0)
732 1012
             );
733 1013
             
734
-            // 如果没有待审批任务,说明所有任务都已完成
735
-            if (CollectionUtil.isEmpty(approvalTasks)) {
1014
+            // 如果没有待审批任务,但是流程不是【归档】状态,需要触发回调
1015
+            if (CollectionUtil.isEmpty(approvalTasks) && latestBill.getStatus() != BillStatus.COMPLETE.getStatus()) {
1016
+
736 1017
                 // 检查流程实例状态
737
-                final String processInstanceId = bill.getProcessInstanceId();
1018
+                final String processInstanceId = latestBill.getProcessInstanceId();
738 1019
                 boolean shouldComplete = false;
739
-                
1020
+
740 1021
                 if (!Strings.isNullOrEmpty(processInstanceId)) {
741
-                    // 检查运行时流程实例是否还有待办任务
1022
+
1023
+                    // 查询该【流程实例】的活跃节点,
1024
+                    // 【有活跃任务】 --> 不是最后一个节点
1025
+                    // 【无活跃任务】 --> 是最后一个节点
742 1026
                     final List<Task> activeTasks = taskService.createTaskQuery()
743 1027
                             .processInstanceId(processInstanceId)
744 1028
                             .active()
745 1029
                             .list();
746
-                    
1030
+
1031
+                    // 所有任务都完成了,且现在是最后一个节点了
747 1032
                     if (CollectionUtil.isEmpty(activeTasks)) {
748
-                        // 没有运行时待办任务,检查历史流程实例是否已结束
1033
+
1034
+                        // 如果流程没有【处理中】的节点,就查询【已处理】的节点
749 1035
                         final org.activiti.engine.history.HistoricProcessInstance historicProcessInstance = historyService
750 1036
                                 .createHistoricProcessInstanceQuery()
751 1037
                                 .processInstanceId(processInstanceId)
@@ -753,29 +1039,28 @@ public class BillBpmnLogicImpl implements BillBpmnLogic {
753 1039
                         
754 1040
                         if (historicProcessInstance != null && historicProcessInstance.getEndTime() != null) {
755 1041
                             // 流程已结束
756
-                            log.info("流程实例已结束,但审批单状态未更新。billId: {}, processInstanceId: {}", bill.getId(), processInstanceId);
1042
+                            log.info("流程实例已结束,但审批单状态未更新。billId: {}, processInstanceId: {}", latestBill.getId(), processInstanceId);
757 1043
                             shouldComplete = true;
758 1044
                         } else {
759 1045
                             // 流程实例不存在或未结束,但也没有待办任务和待审批任务,应该完成
760
-                            log.info("没有待办任务和待审批任务,流程应该结束。billId: {}, processInstanceId: {}", bill.getId(), processInstanceId);
1046
+                            log.info("没有待办任务和待审批任务,流程应该结束。billId: {}, processInstanceId: {}", latestBill.getId(), processInstanceId);
761 1047
                             shouldComplete = true;
762 1048
                         }
763 1049
                     }
764 1050
                 } else {
765
-                    // 流程实例ID为空,但所有bill_task都已完成,应该完成审批单
766
-                    log.info("流程实例ID为空,但所有任务都已完成,应该完成审批单。billId: {}", bill.getId());
1051
+                    // 流程实例ID为空,但是没有待办任务了,也应该要归档
1052
+                    log.info("流程实例ID为空,但所有任务都已完成,应该完成审批单。billId: {}", latestBill.getId());
767 1053
                     shouldComplete = true;
768 1054
                 }
769 1055
                 
770
-                if (shouldComplete && bill.getStatus() != BillStatus.COMPLETE.getStatus()) {
1056
+                if (shouldComplete) {
771 1057
                     // 审批单状态不是完成,需要触发完成逻辑和回调
772
-                    log.info("检测到流程应该结束,但审批单状态未更新。手动触发审批单完成逻辑和回调。billId: {}, 当前状态: {}", 
773
-                            bill.getId(), bill.getStatus());
774
-                    triggerBillCompleteCallback(bill);
1058
+                    log.info("检测到流程应该结束,但审批单状态未更新。手动触发审批单完成逻辑和回调。billId: {}, 当前状态: {}", latestBill.getId(), latestBill.getStatus());
1059
+                    triggerBillCompleteCallback(latestBill);//调用归档接口
775 1060
                 }
776 1061
             }
777 1062
         } catch (Exception e) {
778
-            log.error("检查审批单完成状态时发生异常。billId: {}, 错误: {}", bill.getId(), e.getMessage(), e);
1063
+            log.error("检查审批单完成状态时发生异常。billId: {}, 错误: {}", latestBill.getId(), e.getMessage(), e);
779 1064
             // 设置事务回滚,确保异常不会导致事务提交
780 1065
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
781 1066
             throw new RuntimeException("检查审批单完成状态时发生异常: " + e.getMessage(), e);

+ 18 - 5
bpm-core/src/main/java/com/srm/bpm/logic/service/impl/BillTaskLogicImpl.java

@@ -292,20 +292,33 @@ public class BillTaskLogicImpl implements BillTaskLogic {
292 292
                     }
293 293
                 }
294 294
                 if (CollectionUtil.isNotEmpty(billTasks)) {
295
+                    // 先保存节点任务到数据库,确保节点任务已经被创建
295 296
                     this.billTaskService.saveBatch(billTasks, 300);
297
+                    
298
+                    // 检查是否需要自动审批
296 299
                     final BillTaskEntity billTaskEntity = autoAgree(nodeExtend, billTasks, lastTaskId, billId);
297 300
                     if (!Objects.isNull(billTaskEntity)) {
298 301
                         //需要增加会签判断
299 302
                         final boolean goFlag = billLogic.agreeIsGoOn(billTaskEntity);
300 303
                         if (goFlag) {
301
-                            this.billBpmnLogic.complete(billService.getById(billId), billTaskEntity.getTaskId(), Const.AUTO_AGREE_OPTION, billTaskEntity.getUserCode(), "", "", billTaskEntity.getTaskNodeKey(), billTaskEntity.getTaskId());
302
-
303
-                            //todo 修改后
304
-                            // this.billBpmnLogic.complete(billService.getById(billId), billTaskEntity.getTaskId(), Const.AUTO_AGREE_OPTION, billTaskEntity.getUserCode(), "", "", billTaskEntity.getTaskNodeKey(), billTaskEntity.getLastTaskId());
304
+                            // 自动审批场景:
305
+                            // 步骤一:先完成本节点审批事件,生成下一个节点的审批信息
306
+                            // 步骤二:然后在 complete() 中判断是否是最后一个节点,如果不是,继续递归处理
307
+                            log.info("节点满足自动审批条件,执行自动审批。billId: {}, taskId: {}, nodeKey: {}", 
308
+                                    billId, billTaskEntity.getTaskId(), billTaskEntity.getTaskNodeKey());
309
+                            
310
+                            // 执行自动审批,这会触发下一个节点的创建
311
+                            // 使用 lastTaskId 作为参数,确保能正确关联上一个节点
312
+                            this.billBpmnLogic.complete(billService.getById(billId), billTaskEntity.getTaskId(), 
313
+                                    Const.AUTO_AGREE_OPTION, billTaskEntity.getUserCode(), "", "", 
314
+                                    billTaskEntity.getTaskNodeKey(), billTaskEntity.getLastTaskId());
305 315
 
306 316
                             //删除待审批的信息
307
-                            this.billTaskService.deleteApproval(billId, billTaskEntity.getTaskId(), BillTaskStatus.APPROVAL.getStatus());
317
+                            this.billTaskService.deleteApproval(billId, billTaskEntity.getTaskId(), 
318
+                                    BillTaskStatus.APPROVAL.getStatus());
308 319
                             
320
+                            // 返回已创建的节点任务列表(即使已经自动审批,也要返回,确保节点信息被记录)
321
+                            return billTasks;
309 322
                         } else {
310 323
                             //转办操作
311 324
                             transfer(billTasks, billId);