|
|
@@ -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);
|