db = Db::connection(); } /** * 提交审批 */ public function submit(array $data): ApprovalOrder { return $this->db->transaction(function () use ($data) { // 1. 获取审批流程 $flow = ApprovalFlow::active() ->byBusinessType($data['business_type']) ->with('nodes') ->findOrFail($data['flow_id']); // 2. 创建审批单 $order = ApprovalOrder::create([ 'business_type' => $data['business_type'], 'business_id' => $data['business_id'], 'title' => $data['title'], 'applicant_id' => $data['applicant_id'], 'status' => ApprovalOrder::STATUS_PENDING, 'current_nodes' => $this->getFirstNodeIds($flow), 'flow_id' => $flow->id, 'form_data' => $data['form_data'] ?? [], 'attachments' => $data['attachments'] ?? [], ]); // 3. 记录提交操作 ApprovalRecord::create([ 'order_id' => $order->id, 'node_id' => $flow->nodes->first()->id ?? 0, 'node_type' => 'submit', 'approver_id' => $data['applicant_id'], 'action' => ApprovalRecord::ACTION_SUBMIT, 'comment' => $data['comment'] ?? null, ]); return $order->load(['flow', 'applicant']); }); } /** * 审批通过 */ public function approve(int $orderId, int $approverId, ?string $comment = null): ApprovalOrder { return $this->db->transaction(function () use ($orderId, $approverId, $comment) { $order = ApprovalOrder::with(['flow.nodes'])->findOrFail($orderId); if (!$order->canApprove()) { throw new \Exception('当前状态无法审批'); } $currentNodeIds = $order->current_nodes ?? []; $currentNode = ApprovalNode::whereIn('id', $currentNodeIds)->first(); if (!$currentNode) { throw new \Exception('当前节点不存在'); } // 记录审批操作 ApprovalRecord::create([ 'order_id' => $order->id, 'node_id' => $currentNode->id, 'node_type' => $currentNode->type, 'approver_id' => $approverId, 'action' => ApprovalRecord::ACTION_APPROVE, 'comment' => $comment, ]); // 判断节点是否完成 if ($this->isNodeCompleted($order->id, $currentNode->id)) { // 移动到下一节点 $nextNodes = $this->getNextNodes($order->flow, $currentNode->order); if (empty($nextNodes)) { // 审批完成 $order->status = ApprovalOrder::STATUS_APPROVED; $order->current_nodes = []; } else { $order->current_nodes = collect($nextNodes)->pluck('id')->toArray(); } $order->save(); } return $order->fresh(['flow', 'applicant', 'records']); }); } /** * 审批拒绝 */ public function reject(int $orderId, int $approverId, ?string $comment = null): ApprovalOrder { return $this->db->transaction(function () use ($orderId, $approverId, $comment) { $order = ApprovalOrder::findOrFail($orderId); if (!$order->canApprove()) { throw new \Exception('当前状态无法审批'); } $currentNodeIds = $order->current_nodes ?? []; $currentNode = ApprovalNode::whereIn('id', $currentNodeIds)->first(); // 记录拒绝操作 ApprovalRecord::create([ 'order_id' => $order->id, 'node_id' => $currentNode->id ?? 0, 'node_type' => $currentNode->type ?? 'unknown', 'approver_id' => $approverId, 'action' => ApprovalRecord::ACTION_REJECT, 'comment' => $comment, ]); // 更新状态为已拒绝 $order->status = ApprovalOrder::STATUS_REJECTED; $order->current_nodes = []; $order->save(); return $order->fresh(['flow', 'applicant', 'records']); }); } /** * 撤销申请 */ public function cancel(int $orderId, int $userId): ApprovalOrder { $order = ApprovalOrder::findOrFail($orderId); if ($order->applicant_id !== $userId) { throw new \Exception('只有申请人可以撤销'); } if (!$order->canEdit() && !$order->canApprove()) { throw new \Exception('当前状态无法撤销'); } // 记录撤销操作 ApprovalRecord::create([ 'order_id' => $order->id, 'node_id' => 0, 'node_type' => 'cancel', 'approver_id' => $userId, 'action' => ApprovalRecord::ACTION_CANCEL, 'comment' => '申请人撤销', ]); $order->status = ApprovalOrder::STATUS_CANCELLED; $order->current_nodes = []; $order->save(); return $order->fresh(['flow', 'applicant', 'records']); } /** * 获取审批列表 */ public function getList(int $userId, string $type = 'my', int $page = 1, int $pageSize = 20): array { $query = ApprovalOrder::with(['flow', 'applicant']); switch ($type) { case 'my': $query->where('applicant_id', $userId); break; case 'pending': // 获取用户待审批的订单 $pendingOrderIds = $this->getPendingOrderIds($userId); $query->whereIn('id', $pendingOrderIds); break; case 'approved': // 获取用户已审批的订单 $approvedOrderIds = ApprovalRecord::where('approver_id', $userId) ->where('action', '!=', ApprovalRecord::ACTION_SUBMIT) ->pluck('order_id') ->unique() ->toArray(); $query->whereIn('id', $approvedOrderIds); break; } $total = $query->count(); $list = $query->orderBy('created_at', 'desc') ->offset(($page - 1) * $pageSize) ->limit($pageSize) ->get(); return [ 'list' => $list, 'total' => $total, 'page' => $page, 'page_size' => $pageSize, ]; } /** * 获取第一个节点ID列表 */ private function getFirstNodeIds(ApprovalFlow $flow): array { return $flow->nodes ->where('order', 0) ->pluck('id') ->toArray(); } /** * 判断节点是否完成 */ private function isNodeCompleted(int $orderId, int $nodeId): bool { $node = ApprovalNode::findOrFail($nodeId); $records = ApprovalRecord::where('order_id', $orderId) ->where('node_id', $nodeId) ->where('action', 'approve') ->get(); $approvers = $node->approvers ?? []; if ($node->type === ApprovalNode::TYPE_AND_APPROVE) { // 会签:需要所有人通过 return count($records) >= count($approvers); } elseif ($node->type === ApprovalNode::TYPE_OR_APPROVE) { // 或签:任一人通过即可 return count($records) >= 1; } else { // 单人审批:需要一人通过 return count($records) >= 1; } } /** * 获取下一节点 */ private function getNextNodes(ApprovalFlow $flow, int $currentOrder): array { return $flow->nodes ->where('order', '>', $currentOrder) ->sortBy('order') ->values() ->toArray(); } /** * 获取用户待审批的订单ID列表 */ private function getPendingOrderIds(int $userId): array { // 获取用户参与的待审批订单 $pendingOrders = ApprovalOrder::where('status', ApprovalOrder::STATUS_PENDING) ->whereNotNull('current_nodes') ->get(); $result = []; foreach ($pendingOrders as $order) { $currentNodeIds = $order->current_nodes ?? []; $nodes = ApprovalNode::whereIn('id', $currentNodeIds)->get(); foreach ($nodes as $node) { $approvers = $node->approvers ?? []; if (in_array($userId, $approvers)) { // 检查是否已审批 $hasApproved = ApprovalRecord::where('order_id', $order->id) ->where('node_id', $node->id) ->where('approver_id', $userId) ->exists(); if (!$hasApproved) { $result[] = $order->id; break; } } } } return $result; } }