where($where) ->field($field) ->order($order) ->page($page, $limit) ->select() ->toArray(); $count = (new SchoolApprovalProcess())->where($where)->count(); return [ 'list' => $list, 'count' => $count ]; } /** * 获取审批流程详情 * @param int $id * @return array */ public function getInfo(int $id): array { $info = (new SchoolApprovalProcess())->with(['participants'])->where(['id' => $id])->find(); if (empty($info)) { return []; } return $info->toArray(); } /** * 创建审批流程 * @param array $data * @param int $config_id 审批配置ID * @return int * @throws \Exception */ public function create(array $data, int $config_id): int { Db::startTrans(); try { // 获取审批配置详情 $config_info = (new SchoolApprovalConfigService())->getInfo($config_id); if (empty($config_info)) { throw new Exception('审批配置不存在'); } // 创建审批流程 $process = [ 'process_name' => $data['process_name'], 'applicant_id' => $data['applicant_id'], 'application_time' => time(), 'current_approver_id' => 0, // 初始时为0,后面会更新 'approval_status' => SchoolApprovalProcess::STATUS_PENDING, 'remarks' => $data['remarks'] ?? '' ]; $process_id = (new SchoolApprovalProcess())->insertGetId($process); // 创建审批参与人 $participants = []; foreach ($config_info['nodes'] as $sequence => $node) { $approver_ids = explode(',', $node['approver_ids']); foreach ($approver_ids as $approver_id) { $participants[] = [ 'process_id' => $process_id, 'participant_id' => $approver_id, 'sequence' => $node['sequence'], 'status' => SchoolApprovalParticipants::STATUS_PENDING, 'sign_type' => $node['sign_type'] ]; } } if (!empty($participants)) { (new SchoolApprovalParticipants())->insertAll($participants); // 更新当前审批人为第一个审批人 $first_participant = (new SchoolApprovalParticipants()) ->where(['process_id' => $process_id]) ->order('sequence', 'asc') ->find(); if (!empty($first_participant)) { (new SchoolApprovalProcess())->where(['id' => $process_id]) ->update(['current_approver_id' => $first_participant['participant_id']]); } } Db::commit(); return $process_id; } catch (\Exception $e) { Db::rollback(); throw new Exception($e->getMessage()); } } /** * 审批 * @param int $process_id 流程ID * @param int $approver_id 审批人ID * @param string $status 审批状态 * @param string $remarks 备注 * @return bool * @throws \Exception */ public function approve(int $process_id, int $approver_id, string $status, string $remarks = ''): bool { Db::startTrans(); try { // 获取审批流程 $process_info = (new SchoolApprovalProcess())->where(['id' => $process_id])->find(); if (empty($process_info)) { throw new Exception('审批流程不存在'); } // 检查是否当前审批人 if ($process_info['current_approver_id'] != $approver_id) { throw new Exception('您不是当前审批人'); } // 检查流程状态 if ($process_info['approval_status'] != SchoolApprovalProcess::STATUS_PENDING) { throw new Exception('该审批流程已完成'); } // 获取当前审批节点 $current_participant = (new SchoolApprovalParticipants()) ->where([ 'process_id' => $process_id, 'participant_id' => $approver_id, 'status' => SchoolApprovalParticipants::STATUS_PENDING ]) ->find(); if (empty($current_participant)) { throw new Exception('审批节点信息错误'); } // 更新当前审批人状态 (new SchoolApprovalParticipants())->where(['id' => $current_participant['id']]) ->update([ 'status' => $status, 'remarks' => $remarks ]); // 如果拒绝,直接更新整个流程状态为拒绝 if ($status == SchoolApprovalParticipants::STATUS_REJECTED) { (new SchoolApprovalProcess())->where(['id' => $process_id]) ->update([ 'approval_status' => SchoolApprovalProcess::STATUS_REJECTED, 'approval_time' => time(), 'remarks' => $remarks ]); Db::commit(); return true; } // 检查当前节点是否需要会签 $same_sequence_participants = (new SchoolApprovalParticipants()) ->where([ 'process_id' => $process_id, 'sequence' => $current_participant['sequence'], 'status' => SchoolApprovalParticipants::STATUS_PENDING ]) ->select(); // 如果是会签且还有其他人未审批,则等待 if ($current_participant['sign_type'] == SchoolApprovalParticipants::SIGN_TYPE_AND && !$same_sequence_participants->isEmpty()) { // 不做任何处理,等待其他人审批 Db::commit(); return true; } // 获取下一个审批节点 $next_participant = (new SchoolApprovalParticipants()) ->where([ 'process_id' => $process_id, 'status' => SchoolApprovalParticipants::STATUS_PENDING ]) ->order('sequence', 'asc') ->find(); if (empty($next_participant)) { // 没有下一个审批人,流程结束,标记为已通过 (new SchoolApprovalProcess())->where(['id' => $process_id]) ->update([ 'approval_status' => SchoolApprovalProcess::STATUS_APPROVED, 'approval_time' => time() ]); } else { // 更新当前审批人为下一个审批人 (new SchoolApprovalProcess())->where(['id' => $process_id]) ->update(['current_approver_id' => $next_participant['participant_id']]); } Db::commit(); return true; } catch (\Exception $e) { Db::rollback(); throw new Exception($e->getMessage()); } } /** * 撤销审批流程 * @param int $process_id 流程ID * @param int $applicant_id 申请人ID * @return bool * @throws \Exception */ public function cancel(int $process_id, int $applicant_id): bool { Db::startTrans(); try { // 获取审批流程 $process_info = (new SchoolApprovalProcess())->where(['id' => $process_id])->find(); if (empty($process_info)) { throw new Exception('审批流程不存在'); } // 检查是否申请人 if ($process_info['applicant_id'] != $applicant_id) { throw new Exception('您不是该流程的申请人'); } // 检查流程状态 if ($process_info['approval_status'] != SchoolApprovalProcess::STATUS_PENDING) { throw new Exception('该审批流程已完成,无法撤销'); } // 更新流程状态为已拒绝(撤销) (new SchoolApprovalProcess())->where(['id' => $process_id]) ->update([ 'approval_status' => SchoolApprovalProcess::STATUS_REJECTED, 'approval_time' => time(), 'remarks' => '申请人撤销' ]); // 更新所有待审批节点为已拒绝 (new SchoolApprovalParticipants())->where([ 'process_id' => $process_id, 'status' => SchoolApprovalParticipants::STATUS_PENDING ])->update([ 'status' => SchoolApprovalParticipants::STATUS_REJECTED, 'remarks' => '申请人撤销' ]); Db::commit(); return true; } catch (\Exception $e) { Db::rollback(); throw new Exception($e->getMessage()); } } }