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, int $uid, string $action, string $comment = '') { if (!in_array($action, ['1','2'], true)) { //审批动作:1通过 2驳回 throw new BusinessException("无效的审批操作"); } return Db::transaction(function () use ($requisitionId, $approverId, $uid, $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 !== 10 && $requisition->status !== 11) { return ['status' => 'noop', 'msg' => '实例未处理']; } //审批流程 $flow = Db::table('approval_flows')->where('type', 'inv_requisition')->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('id', $approverId) ->where('action', 0) ->lockForUpdate() ->first(); if (!$pendingRecord) { // 已处理过? $anyRecord = Db::table('inv_requisition_approve') ->where('requisition_id', $requisitionId) ->where('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' => '无待处理记录']; } // else{ // if ($pendingRecord->approver_id == $uid) { // return ['status' => 'noop', 'msg' => '无审核权限']; // } // } $now = time(); // 1) 更新当前人的审批记录 Db::table('inv_requisition_approve')->where('id', $pendingRecord->id)->update([ 'action' => $action, 'comment' => $comment, 'action_at' => $now, 'updated_at' => $now, ]); // 2) 已通过步骤与总步数相等则结束审核流程 $pass = Db::table('inv_requisition_approve') ->where('requisition_id', $requisitionId) ->where('action', 1) ->count(); if($action == 1){ if(count($steps) == $pass){ $requisitionItem = Db::table('inv_requisition_item') ->where('requisition_id', $requisition->id) ->where('is_consumable_snap', 0) ->get(); if($requisitionItem){ Db::table('inv_requisition')->where('id', $requisition->id)->update(['status'=>12]); }else{ Db::table('inv_requisition')->where('id', $requisition->id)->update(['status'=>19]); } // $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){ Db::table('inv_requisition')->where('id', $requisition->id)->update(['status'=>12]); // $requisition->status = 13; // $requisition->save(); return ['status' => 'complete', 'msg' => '拒绝']; } } // 4) 通过 => 进入下一步或结束 $requisitionItem = Db::table('inv_requisition_item')->where('requisition_id', $requisitionId)->first(); $item_id = Db::table('inv_item')->where('id', $requisitionItem->item_id)->first(); $formData = ['manage_user_id'=>$item_id->manage_user_id]; $nextIndex = $pass; $nextStep = $steps[$nextIndex]; $service = new \app\common\utils\approval\service\ApprovalFlowService(); $instance = (object)[ 'initiator_id' => $requisition->applicant_id, //申请人id 'form_data'=>json_encode($formData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ]; $approverIds = $service->StetApprovers($nextStep, $instance, true); // if($approverIds == "manage_user_id"){ //物品管理人审核步骤查询管理人 // $requisitionItem = Db::table('inv_requisition_item')->where('id', $requisitionId)->first(); // $invItem = Db::table('inv_requisition_item')->where('id', $requisitionItem->item_id)->first(); // // if(empty($invItem)){ // return ['status' => 'noop', 'msg' => '未查询到物品管理人']; // } // $approverIds = [$invItem->manage_user_id]; // } $approver = User::where('id', array_pop($approverIds))->first(); Db::table('inv_requisition_approve')->insertGetId([ 'requisition_id' => $requisitionId, //申请单ID 'node_type' => $nextStep['approvers'][0]['value'], '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; } }