validate([ 'paper_id' => 'required|string', 'student_id' => 'required|string', 'answers' => 'required|array', 'answers.*.question_id' => 'required|string', 'answers.*.question_number' => 'nullable|string', 'answers.*.is_correct' => 'required|boolean', 'answers.*.student_answer' => 'nullable|string', 'answers.*.correct_answer' => 'nullable|string', 'answers.*.score' => 'nullable|numeric', 'answers.*.max_score' => 'nullable|numeric', 'answers.*.step_scores' => 'nullable|array', // 简答题步骤得分 'answers.*.knowledge_point' => 'nullable|string', 'answers.*.question_type' => 'nullable|string', 'answer_time' => 'nullable|timestamp', 'submit_time' => 'nullable|timestamp', 'source_system' => 'nullable|string', 'callback_url' => 'nullable|url', ]); try { // 使用TaskManager创建异步任务 $taskId = $this->taskManager->createTask( TaskManager::TASK_TYPE_ANALYSIS, array_merge($data, ['type' => 'answer_analysis']) ); Log::info('StudentAnswerAnalysisController: 收到作答结果', [ 'task_id' => $taskId, 'paper_id' => $data['paper_id'], 'student_id' => $data['student_id'], 'answer_count' => count($data['answers']), ]); // 触发后台分析处理 $this->processAnswerAnalysis($taskId, $data); return response()->json([ 'success' => true, 'message' => '作答结果已提交,正在分析中...', 'data' => [ 'task_id' => $taskId, 'paper_id' => $data['paper_id'], 'student_id' => $data['student_id'], 'status' => 'processing', 'created_at' => now()->toISOString(), ], ]); } catch (\Exception $e) { Log::error('提交作答结果失败', [ 'paper_id' => $data['paper_id'] ?? 'unknown', 'student_id' => $data['student_id'] ?? 'unknown', 'error' => $e->getMessage(), ]); return response()->json([ 'success' => false, 'message' => '提交失败:' . $e->getMessage(), ], 500); } } /** * 查询分析任务状态 */ public function getAnalysisStatus(string $taskId): JsonResponse { try { $task = $this->taskManager->getTaskStatus($taskId); if (!$task) { return response()->json([ 'success' => false, 'message' => '任务不存在', ], 404); } return response()->json([ 'success' => true, 'data' => $task, ]); } catch (\Exception $e) { Log::error('查询分析状态失败', [ 'task_id' => $taskId, 'error' => $e->getMessage(), ]); return response()->json([ 'success' => false, 'message' => '查询失败:' . $e->getMessage(), ], 500); } } /** * 处理作答分析(后台任务) */ private function processAnswerAnalysis(string $taskId, array $data): void { try { $this->taskManager->updateTaskProgress($taskId, 10, '正在保存作答记录...'); // 保存作答记录到数据库 $answerRecord = $this->answerAnalysisService->saveAnswerRecord($data); $this->taskManager->updateTaskProgress($taskId, 30, '正在分析每道题...'); // 使用本地AI分析服务分析每道题 $questionAnalyses = []; foreach ($data['answers'] as $answer) { // 获取题目内容(如果有) $questionText = $this->getQuestionText($answer['question_id']); // 构建分析数据 $analysisData = [ 'question_id' => $answer['question_id'], 'question_number' => $answer['question_number'] ?? null, 'question_text' => $questionText, 'student_answer' => $answer['student_answer'] ?? '', 'correct_answer' => $answer['correct_answer'] ?? '', 'score' => (float) ($answer['score'] ?? 0), 'max_score' => (float) ($answer['max_score'] ?? 10), 'kp_code' => $answer['knowledge_point'] ?? null, 'difficulty' => 0.5, // 默认难度 ]; // 调用AI分析 $analysisResult = $this->aiAnalysisService->analyzeAnswer($analysisData); if ($analysisResult['success']) { $questionAnalyses[] = array_merge($analysisData, $analysisResult['data']); } else { Log::warning('AI分析失败,使用规则分析', [ 'question_id' => $answer['question_id'], ]); $questionAnalyses[] = array_merge($analysisData, $analysisResult['data']); } } $this->taskManager->updateTaskProgress($taskId, 60, '正在保存分析结果...'); // 准备分析结果数据 $analysisData = [ 'question_results' => $questionAnalyses, 'total_questions' => count($questionAnalyses), 'correct_count' => count(array_filter($questionAnalyses, fn($q) => $q['correct'] ?? false)), 'wrong_count' => count(array_filter($questionAnalyses, fn($q) => !($q['correct'] ?? true))), 'model_used' => $questionAnalyses[0]['model_used'] ?? 'unknown', ]; // 保存分析结果 $this->answerAnalysisService->saveAnalysisResults($answerRecord, $analysisData, $questionAnalyses); $this->taskManager->updateTaskProgress($taskId, 80, '正在生成掌握度快照...'); // 生成掌握度快照 $masterySnapshot = $this->answerAnalysisService->createMasterySnapshot( $data['student_id'], $data['paper_id'], $answerRecord['record_id'] ); // 标记任务完成 $this->taskManager->markTaskCompleted($taskId, [ 'answer_record_id' => $answerRecord['record_id'], 'analysis_id' => 'analysis_' . uniqid(), 'mastery_snapshot_id' => $masterySnapshot['snapshot_id'] ?? null, 'correct_count' => $answerRecord['correct_count'], 'wrong_count' => $answerRecord['wrong_count'], 'overall_mastery' => $masterySnapshot['overall_mastery'] ?? null, ]); Log::info('作答分析完成', [ 'task_id' => $taskId, 'paper_id' => $data['paper_id'], 'student_id' => $data['student_id'], 'answer_record_id' => $answerRecord['record_id'], ]); // 发送回调通知 $this->taskManager->sendCallback($taskId); } catch (\Exception $e) { Log::error('作答分析失败', [ 'task_id' => $taskId, 'paper_id' => $data['paper_id'], 'student_id' => $data['student_id'], 'error' => $e->getMessage(), ]); $this->taskManager->markTaskFailed($taskId, $e->getMessage()); } } /** * 获取题目文本内容 */ private function getQuestionText(string $questionId): string { try { // 这里可以调用 QuestionBankService 获取题目内容 // 目前返回空字符串,让AI分析基于学生答案进行分析 return ''; } catch (\Exception $e) { Log::warning('获取题目文本失败', [ 'question_id' => $questionId, 'error' => $e->getMessage(), ]); return ''; } } /** * 获取学生学习历史 */ public function getStudentLearningHistory(string $studentId): JsonResponse { try { $history = $this->answerAnalysisService->getStudentLearningHistory($studentId); return response()->json([ 'success' => true, 'data' => $history, ]); } catch (\Exception $e) { Log::error('获取学习历史失败', [ 'student_id' => $studentId, 'error' => $e->getMessage(), ]); return response()->json([ 'success' => false, 'message' => '获取失败:' . $e->getMessage(), ], 500); } } }