From 8110b1e5e642ffe0656e83c5b9f0330c67542ff3 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 26 Feb 2026 09:44:44 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8F=91=E8=B5=B7=E4=BA=BA=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=AE=A1=E6=89=B9=E9=80=9A=E8=BF=87=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 当发起人在审批人列表中时,提交时自动创建审批通过记录 - 根据节点类型判断是否完成: - 单人审批(approver):发起人审批后节点完成 - 或签(or_approve):发起人审批后节点完成 - 会签(and_approve):需要所有审批人审批才完成 - 节点完成后自动移动到下一节点或完成审批 - 更新 PROJECT_ISSUES.md 记录问题和解决方案 业务逻辑说明: - 如果发起人选择自己作为唯一审批人,提交后申请直接完成 - 如果有其他审批人,需要其他审批人继续审批 Co-Authored-By: Claude Opus 4.6 --- PROJECT_ISSUES.md | 70 +++++++++++++++++++++ backend/app/service/BusinessTripService.php | 54 ++++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/PROJECT_ISSUES.md b/PROJECT_ISSUES.md index c38c63e..d490cd8 100644 --- a/PROJECT_ISSUES.md +++ b/PROJECT_ISSUES.md @@ -441,6 +441,76 @@ navigate('/approval') // 改为跳转到审批列表 **相关文件**:`frontend/src/pages/business-trip/apply.tsx` +### 23. 发起人自动审批通过逻辑 + +**需求**:当发起人选择的审批人中包含自己时,提交时自动标记为已审批 + +**实现逻辑**: +1. 检查发起人是否在审批人列表中 +2. 如果是,自动创建审批通过记录 +3. 根据节点类型判断是否完成: + - 单人审批(approver):发起人审批后节点完成 + - 或签(or_approve):发起人审批后节点完成 + - 会签(and_approve):需要所有审批人审批才完成 +4. 节点完成后移动到下一节点或完成审批 + +**解决方案**: +```php +// 如果发起人在审批人列表中,自动标记为已审批 +if (in_array($userId, $approverIds)) { + ApprovalRecord::create([ + 'order_id' => $approvalOrder->id, + 'node_id' => $node->id, + 'node_type' => $node->type, + 'approver_id' => $userId, + 'action' => 'approve', + 'comment' => '发起人自动审批通过', + ]); + + // 判断节点是否完成 + $nodeCompleted = false; + + if ($node->type === 'approver') { + // 单人审批:发起人即完成 + $nodeCompleted = true; + } elseif ($node->type === 'or_approve') { + // 或签:任一人通过即可 + $nodeCompleted = true; + } elseif ($node->type === 'and_approve') { + // 会签:需要所有人通过 + $approvedCount = ApprovalRecord::where('order_id', $approvalOrder->id) + ->where('node_id', $node->id) + ->where('action', 'approve') + ->count(); + + if ($approvedCount >= count($approverIds)) { + $nodeCompleted = true; + } + } + + // 如果节点完成,移动到下一节点 + if ($nodeCompleted) { + $nextNodes = ApprovalNode::where('flow_id', $flow->id) + ->where('order', '>', 0) + ->orderBy('order') + ->get(); + + if ($nextNodes->isEmpty()) { + // 审批完成 + $approvalOrder->status = ApprovalOrder::STATUS_APPROVED; + $approvalOrder->current_nodes = []; + } else { + // 移动到下一节点 + $approvalOrder->current_nodes = $nextNodes->pluck('id')->toArray(); + } + + $approvalOrder->save(); + } +} +``` + +**相关文件**:`backend/app/service/BusinessTripService.php` + --- ## 文件修改记录 diff --git a/backend/app/service/BusinessTripService.php b/backend/app/service/BusinessTripService.php index a96cc14..133a7c9 100644 --- a/backend/app/service/BusinessTripService.php +++ b/backend/app/service/BusinessTripService.php @@ -215,6 +215,60 @@ class BusinessTripService 'comment' => null, ]); + // 如果发起人在审批人列表中,自动标记为已审批 + if (in_array($userId, $approverIds)) { + ApprovalRecord::create([ + 'order_id' => $approvalOrder->id, + 'node_id' => $node->id, + 'node_type' => $node->type, + 'approver_id' => $userId, + 'action' => 'approve', + 'comment' => '发起人自动审批通过', + ]); + + // 判断节点是否完成 + $nodeCompleted = false; + + if ($node->type === 'approver') { + // 单人审批:发起人即完成 + $nodeCompleted = true; + } elseif ($node->type === 'or_approve') { + // 或签:任一人通过即可 + $nodeCompleted = true; + } elseif ($node->type === 'and_approve') { + // 会签:需要所有人通过 + $approvedCount = ApprovalRecord::where('order_id', $approvalOrder->id) + ->where('node_id', $node->id) + ->where('action', 'approve') + ->count(); + + if ($approvedCount >= count($approverIds)) { + $nodeCompleted = true; + } + } + + // 如果节点完成,移动到下一节点 + if ($nodeCompleted) { + $nextNodes = ApprovalNode::where('flow_id', $flow->id) + ->where('order', '>', 0) + ->orderBy('order') + ->get(); + + if ($nextNodes->isEmpty()) { + // 没有后续节点,审批完成 + $approvalOrder->status = ApprovalOrder::STATUS_APPROVED; + $approvalOrder->current_nodes = []; + $businessTrip->status = BusinessTrip::STATUS_APPROVED; + } else { + // 移动到下一节点 + $approvalOrder->current_nodes = $nextNodes->pluck('id')->toArray(); + } + + $approvalOrder->save(); + $businessTrip->save(); + } + } + return $businessTrip->fresh(['itineraries', 'approvalOrder']); }); }