|
@@ -0,0 +1,100 @@
|
|
|
|
|
+<?php
|
|
|
|
|
+
|
|
|
|
|
+namespace App\Jobs;
|
|
|
|
|
+
|
|
|
|
|
+use App\Services\ExamAnswerAnalysisService;
|
|
|
|
|
+use App\Services\TaskManager;
|
|
|
|
|
+use Illuminate\Bus\Queueable;
|
|
|
|
|
+use Illuminate\Contracts\Queue\ShouldQueue;
|
|
|
|
|
+use Illuminate\Foundation\Bus\Dispatchable;
|
|
|
|
|
+use Illuminate\Queue\InteractsWithQueue;
|
|
|
|
|
+use Illuminate\Queue\SerializesModels;
|
|
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
|
|
+use Throwable;
|
|
|
|
|
+
|
|
|
|
|
+class ProcessExamAnswerAnalysisJob implements ShouldQueue
|
|
|
|
|
+{
|
|
|
|
|
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
|
|
|
+
|
|
|
|
|
+ public int $tries = 2;
|
|
|
|
|
+ public int $timeout = 300;
|
|
|
|
|
+ public array $backoff = [5, 15];
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @param array<string,mixed> $examData
|
|
|
|
|
+ */
|
|
|
|
|
+ public function __construct(
|
|
|
|
|
+ public string $taskId,
|
|
|
|
|
+ public array $examData
|
|
|
|
|
+ ) {
|
|
|
|
|
+ $this->onQueue('pdf');
|
|
|
|
|
+ $this->afterCommit();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function handle(ExamAnswerAnalysisService $analysisService, TaskManager $taskManager): void
|
|
|
|
|
+ {
|
|
|
|
|
+ try {
|
|
|
|
|
+ $taskManager->updateTaskProgress($this->taskId, 10, '正在分析考试答题...');
|
|
|
|
|
+
|
|
|
|
|
+ Log::warning('ProcessExamAnswerAnalysisJob: 开始处理考试答题分析', [
|
|
|
|
|
+ 'task_id' => $this->taskId,
|
|
|
|
|
+ 'paper_id' => $this->examData['paper_id'] ?? null,
|
|
|
|
|
+ 'student_id' => $this->examData['student_id'] ?? null,
|
|
|
|
|
+ 'question_count' => count($this->examData['questions'] ?? []),
|
|
|
|
|
+ 'attempt' => $this->attempts(),
|
|
|
|
|
+ 'memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $result = $analysisService->analyzeExamAnswers($this->examData);
|
|
|
|
|
+
|
|
|
|
|
+ $taskManager->markTaskCompleted($this->taskId, [
|
|
|
|
|
+ 'paper_id' => $this->examData['paper_id'] ?? null,
|
|
|
|
|
+ 'student_id' => $this->examData['student_id'] ?? null,
|
|
|
|
|
+ 'analysis_status' => 'completed',
|
|
|
|
|
+ 'pdf_status' => 'queued',
|
|
|
|
|
+ 'analyzed_knowledge_points' => count($result['knowledge_point_analysis'] ?? []),
|
|
|
|
|
+ 'result_url' => isset($this->examData['student_id'], $this->examData['paper_id'])
|
|
|
|
|
+ ? route('api.exam-answer-analysis.result', [
|
|
|
|
|
+ 'student_id' => $this->examData['student_id'],
|
|
|
|
|
+ 'paper_id' => $this->examData['paper_id'],
|
|
|
|
|
+ ])
|
|
|
|
|
+ : null,
|
|
|
|
|
+ 'pdf_lookup_url' => isset($this->examData['paper_id'])
|
|
|
|
|
+ ? route('api.exam-analysis.pdf', ['paper_id' => $this->examData['paper_id']])
|
|
|
|
|
+ : null,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ $taskManager->sendCallback($this->taskId);
|
|
|
|
|
+
|
|
|
|
|
+ Log::warning('ProcessExamAnswerAnalysisJob: 考试答题分析完成', [
|
|
|
|
|
+ 'task_id' => $this->taskId,
|
|
|
|
|
+ 'paper_id' => $this->examData['paper_id'] ?? null,
|
|
|
|
|
+ 'student_id' => $this->examData['student_id'] ?? null,
|
|
|
|
|
+ 'memory_peak_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
|
|
|
|
|
+ ]);
|
|
|
|
|
+ } catch (Throwable $e) {
|
|
|
|
|
+ $taskManager->markTaskFailed($this->taskId, $e->getMessage());
|
|
|
|
|
+ $taskManager->sendCallback($this->taskId);
|
|
|
|
|
+
|
|
|
|
|
+ Log::error('ProcessExamAnswerAnalysisJob: 考试答题分析失败', [
|
|
|
|
|
+ 'task_id' => $this->taskId,
|
|
|
|
|
+ 'paper_id' => $this->examData['paper_id'] ?? null,
|
|
|
|
|
+ 'student_id' => $this->examData['student_id'] ?? null,
|
|
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
|
|
+ 'exception' => get_class($e),
|
|
|
|
|
+ 'memory_peak_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ throw $e;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function failed(Throwable $exception): void
|
|
|
|
|
+ {
|
|
|
|
|
+ Log::error('ProcessExamAnswerAnalysisJob: 队列任务最终失败', [
|
|
|
|
|
+ 'task_id' => $this->taskId,
|
|
|
|
|
+ 'paper_id' => $this->examData['paper_id'] ?? null,
|
|
|
|
|
+ 'student_id' => $this->examData['student_id'] ?? null,
|
|
|
|
|
+ 'error' => $exception->getMessage(),
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|