validator; } /** * @param string $flowType * @param string $bizType * @param string $bizId * @param array $formData ['manage_user_id'=>23]//物品管理员 * @param int $initiatorId //申请人id * @return array */ public function start(string $flowType, string $bizType, string $bizId, array $formData, int $initiatorId): array { return Db::transaction(function () use ($flowType, $bizType, $bizId, $formData, $initiatorId) { $flow = Db::table('approval_flows')->where('type', $flowType)->where('is_active', 1)->first(); if (!$flow) throw new BusinessException("审批流程未找到或已停用: {$flowType}"); $steps = json_decode($flow->steps, true); if (!is_array($steps) || empty($steps)) throw new BusinessException("流程步骤配置错误"); // 找首个有效步骤索引(考虑条件) $firstIndex = $this->getNextStepIndex($steps, $formData, -1); if ($firstIndex === null) throw new BusinessException("未找到可执行的审批步骤"); $firstStep = $steps[$firstIndex]; //$now = date('Y-m-d H:i:s'); $now = time(); $service = new \app\common\utils\approval\service\ApprovalFlowService(); // 解析首步审批人(支持 role_id 或 roles.name) $instance = (object)[ 'initiator_id' => $initiatorId, 'form_data'=>json_encode($formData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ]; $approverIds = $service->StetApprovers($firstStep, $instance, true); if(empty($approverIds)){ throw new BusinessException('未解析到任何审批人'); } $uid = array_shift($approverIds); $approver = User::where('id', $uid)->first(); $approveId = Db::table('inv_requisition_approve')->insertGetId([ 'requisition_id' => $bizId, //申请单ID 'node_type' => $bizType, 'approver_id' => $approver->id, 'approver_name' => $approver->name, 'action' => 0, 'comment' => '', 'created_at' => $now, 'updated_at' => $now, ]); // foreach ($approverIds as $uid) { // $this->insertApprovalRecord($instance, $firstIndex, $uid); // } return ['instance_id' => $approveId]; }); } /** 执行审批 */ public function approve(int $requisitionId, int $approverId, string $action, string $comment = '') { if (!in_array($action, ['1','2'], true)) { //审批动作:1通过 2驳回 throw new BusinessException("无效的审批操作"); } return Db::transaction(function () use ($requisitionId, $approverId, $action, $comment) { // $instance = Db::table('approval_instances')->where('id', $instanceId)->lockForUpdate()->first(); $requisition = Db::table('inv_requisition')->where('id', $requisitionId)->lockForUpdate()->first(); if (!$requisition) throw new BusinessException("审批实例未找到"); if ($requisition->status !== 'processing') { return ['status' => 'noop', 'msg' => '实例未处理']; } //审批流程 $flow = Db::table('approval_flows')->where('type', $requisition->flow_type)->first(); if (!$flow) throw new BusinessException("审批流程定义未找到"); $steps = json_decode($flow->steps, true); //$idx = (int)$requisition->current_step; //$step = $steps[$idx] ?? null; //if (!$step) throw new BusinessException("当前步骤配置错误"); // 找到该用户在本步的 pending 记录(加锁) $pendingRecord = Db::table('inv_requisition_approve') ->where('requisition_id', $requisitionId) ->where('approver_id', $approverId) ->where('action', 0) ->lockForUpdate() ->first(); if (!$pendingRecord) { // 已处理过? $anyRecord = Db::table('inv_requisition_approve') ->where('requisition_id', $requisitionId) ->where('approver_id', $approverId) ->first(); if ($anyRecord && $anyRecord->action > 0) { return ['status' => 'noop', 'msg' => '已处理']; } // 步骤已推进 // if ((int)$requisition->current_step !== $idx) { // return ['status' => 'noop', 'msg' => '非当前审批']; // } return ['status' => 'noop', 'msg' => '无待处理记录']; } $now = date('Y-m-d H:i:s'); // 1) 更新当前人的审批记录 Db::table('inv_requisition_approve')->where('id', $pendingRecord->id)->update([ 'action' => $action, 'comment' => $comment, 'approved_at' => $now, 'updated_at' => $now, ]); // 2) 已通过步骤与总步数相等则结束审核流程 $pass = Db::table('inv_requisition_approve') ->where('requisition_id', $requisitionId) ->where('approver_id', $approverId) ->where('action', 1) ->count(); if($action == 1){ if(count($steps) == $pass){ $requisition->status = 12; $requisition->save(); return ['status' => 'complete', 'msg' => '已通过']; } } // 3) 拒绝 => 结束 if($action == 2){ Db::table('inv_requisition_approve')->where('id', $pendingRecord->id)->update([ 'action' => $action, 'comment' => $comment, 'approved_at' => $now, 'updated_at' => $now, ]); if(count($steps) == $pass){ $requisition->status = 13; $requisition->save(); return ['status' => 'complete', 'msg' => '拒绝']; } } // 4) 通过 => 进入下一步或结束 $formData = ['manage_user_id'=>'']; $nextIndex = $pass; $nextStep = $steps[$nextIndex]; $service = new \app\common\utils\approval\service\ApprovalFlowService(); $instance = (object)[ 'form_data'=>json_encode($formData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ]; $approverIds = $service->StetApprovers($nextStep, $instance, true); $approver = User::where('id', array_pop($approverIds))->first(); Db::table('inv_requisition_approve')->insertGetId([ 'requisition_id' => $requisitionId, //申请单ID 'node_type' => $nextStep['approvers']['initiator_leader'], 'approver_id' => $approver->id, 'approver_name' => $approver->name, 'action' => 0, 'comment' => '', 'created_at' => $now, 'updated_at' => $now, ]);; }); } // public function insertApprovalRecord() // { // } /** 获取下一个有效步骤索引 */ private function getNextStepIndex(array $steps, array $formData, int $currentStepIndex): ?int { for ($i = $currentStepIndex + 1; $i < count($steps); $i++) { $s = $steps[$i]; if (empty($s['condition'])) { return $i; } } return null; } }