taskId = $taskId; $this->paperId = $paperId; } public function handle( ExamPdfExportService $pdfExportService, QuestionBankService $questionBankService, PaperPayloadService $paperPayloadService, TaskManager $taskManager ): void { try { Log::info('开始处理PDF生成队列任务', [ 'task_id' => $this->taskId, 'paper_id' => $this->paperId, 'attempt' => $this->attempts(), ]); // 【修复】首先检查试卷是否存在 $paperModel = Paper::with('questions')->find($this->paperId); if (!$paperModel) { Log::error('PDF生成队列任务失败:试卷不存在', [ 'task_id' => $this->taskId, 'paper_id' => $this->paperId, 'attempt' => $this->attempts(), ]); // 如果试卷不存在,判断是否需要重试 if ($this->attempts() < $this->maxAttempts) { Log::info('试卷不存在,将在2秒后重试', [ 'task_id' => $this->taskId, 'paper_id' => $this->paperId, 'attempt' => $this->attempts(), 'next_attempt' => $this->attempts() + 1, ]); // 延迟2秒后重试(缩短间隔,减少对回调的影响) $this->release(2); return; } else { Log::error('试卷不存在且已达到最大重试次数,标记任务失败', [ 'task_id' => $this->taskId, 'paper_id' => $this->paperId, 'attempts' => $this->attempts(), ]); $taskManager->markTaskFailed($this->taskId, "试卷不存在: {$this->paperId}"); return; } } // 检查试卷是否有题目 if ($paperModel->questions->isEmpty()) { Log::error('PDF生成队列任务失败:试卷没有题目数据', [ 'task_id' => $this->taskId, 'paper_id' => $this->paperId, 'question_count' => 0, ]); if ($this->attempts() < $this->maxAttempts) { Log::info('试卷没有题目,将在1秒后重试', [ 'task_id' => $this->taskId, 'paper_id' => $this->paperId, 'attempt' => $this->attempts(), ]); // 延迟1秒后重试(更短间隔) $this->release(1); return; } else { $taskManager->markTaskFailed($this->taskId, "试卷没有题目数据: {$this->paperId}"); return; } } $taskManager->updateTaskProgress($this->taskId, 10, '开始生成试卷PDF...'); // 生成试卷PDF $pdfUrl = $pdfExportService->generateExamPdf($this->paperId) ?? $questionBankService->exportExamToPdf($this->paperId) ?? route('filament.admin.auth.intelligent-exam.pdf', ['paper_id' => $this->paperId, 'answer' => 'false']); $taskManager->updateTaskProgress($this->taskId, 50, '试卷PDF生成完成,开始生成判卷PDF...'); // 生成判卷PDF $gradingPdfUrl = $pdfExportService->generateGradingPdf($this->paperId) ?? route('filament.admin.auth.intelligent-exam.pdf', ['paper_id' => $this->paperId, 'answer' => 'true']); // 构建完整的试卷内容 $examContent = $paperPayloadService->buildExamContent($paperModel); // 标记任务完成 $taskManager->markTaskCompleted($this->taskId, [ 'exam_content' => $examContent, 'pdfs' => [ 'exam_paper_pdf' => $pdfUrl, 'grading_pdf' => $gradingPdfUrl, ], ]); Log::info('PDF生成队列任务完成', [ 'task_id' => $this->taskId, 'paper_id' => $this->paperId, 'pdf_url' => $pdfUrl, 'grading_pdf_url' => $gradingPdfUrl, 'question_count' => $paperModel->questions->count(), ]); // 发送回调通知 $taskManager->sendCallback($this->taskId); } catch (\Exception $e) { Log::error('PDF生成队列任务失败', [ 'task_id' => $this->taskId, 'paper_id' => $this->paperId, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), ]); // 如果是第一次失败且试卷可能还在创建中,等待后重试 if ($this->attempts() < $this->maxAttempts && strpos($e->getMessage(), '不存在') !== false) { Log::info('检测到试卷不存在错误,将在2秒后重试', [ 'task_id' => $this->taskId, 'paper_id' => $this->paperId, 'attempt' => $this->attempts(), ]); $this->release(2); return; } $taskManager->markTaskFailed($this->taskId, $e->getMessage()); } } }