yemeishu пре 5 дана
родитељ
комит
3d4d1659ed

+ 15 - 1
app/Http/Controllers/Api/IntelligentExamController.php

@@ -133,9 +133,23 @@ class IntelligentExamController extends Controller
                 ]);
 
                 if (empty($result['success'])) {
+                    $errorMsg = $result['message'] ?? '智能出卷失败';
+                    Log::error('智能出卷失败', [
+                        'student_id' => $data['student_id'],
+                        'error' => $result
+                    ]);
+
+                    // 提供更详细的错误信息
+                    if (strpos($errorMsg, '超时') !== false) {
+                        $errorMsg = '服务响应超时,请稍后重试';
+                    } elseif (strpos($errorMsg, '连接') !== false) {
+                        $errorMsg = '依赖服务连接失败,请检查服务状态';
+                    }
+
                     return response()->json([
                         'success' => false,
-                        'message' => $result['message'] ?? '智能出卷失败',
+                        'message' => $errorMsg,
+                        'details' => $result['details'] ?? null,
                     ], 400);
                 }
 

+ 47 - 6
app/Services/LearningAnalyticsService.php

@@ -1504,14 +1504,32 @@ class LearningAnalyticsService
 
         // 4. 如果题目过多,按权重排序后截取
         if (count($selectedQuestions) > $totalQuestions) {
+            Log::info('开始按权重排序题目', [
+                'before_sort_count' => count($selectedQuestions),
+                'target_count' => $totalQuestions
+            ]);
+
+            $startTime = microtime(true);
             usort($selectedQuestions, function ($a, $b) use ($kpWeights) {
                 $weightA = $kpWeights[$a['kp_code']] ?? 1.0;
                 $weightB = $kpWeights[$b['kp_code']] ?? 1.0;
                 return $weightB <=> $weightA;
             });
+            $sortTime = (microtime(true) - $startTime) * 1000;
+
+            Log::info('权重排序完成', [
+                'sort_time_ms' => round($sortTime, 2),
+                'after_sort_count' => count($selectedQuestions)
+            ]);
+
             $selectedQuestions = array_slice($selectedQuestions, 0, $totalQuestions);
         }
 
+        Log::info('开始题型配比调整', [
+            'input_count' => count($selectedQuestions),
+            'target_count' => $totalQuestions
+        ]);
+
         // 5. 按题型和难度进行微调
         return $this->adjustQuestionsByRatio($selectedQuestions, $questionTypeRatio, $difficultyRatio, $totalQuestions);
     }
@@ -1549,6 +1567,9 @@ class LearningAnalyticsService
             'type_ratio' => $typeRatio
         ]);
 
+        // 缓存题目类型,避免重复计算
+        $questionTypeCache = [];
+
         // 按题型分桶
         $buckets = [
             'choice' => [],
@@ -1556,7 +1577,17 @@ class LearningAnalyticsService
             'answer' => [],
         ];
         foreach ($questions as $q) {
-            $type = $this->determineQuestionType($q);
+            $qid = $q['id'] ?? $q['question_id'] ?? null;
+
+            if ($qid && isset($questionTypeCache[$qid])) {
+                $type = $questionTypeCache[$qid];
+            } else {
+                $type = $this->determineQuestionType($q);
+                if ($qid) {
+                    $questionTypeCache[$qid] = $type;
+                }
+            }
+
             if (!isset($buckets[$type])) {
                 $type = 'answer';
             }
@@ -1626,14 +1657,24 @@ class LearningAnalyticsService
         // 截断至目标数
         $selected = array_slice($selected, 0, $targetCount);
 
+        // 使用缓存统计题型分布
+        $selectedCounts = ['choice' => 0, 'fill' => 0, 'answer' => 0];
+        foreach ($selected as $q) {
+            $qid = $q['id'] ?? $q['question_id'] ?? null;
+            if ($qid && isset($questionTypeCache[$qid])) {
+                $type = $questionTypeCache[$qid];
+            } else {
+                $type = $this->determineQuestionType($q);
+            }
+            if (isset($selectedCounts[$type])) {
+                $selectedCounts[$type]++;
+            }
+        }
+
         Log::info('题型配比调整完成', [
             'target_count' => $targetCount,
             'targets' => $targets,
-            'selected_counts' => [
-                'choice' => count(array_filter($selected, fn($q) => $this->determineQuestionType($q) === 'choice')),
-                'fill' => count(array_filter($selected, fn($q) => $this->determineQuestionType($q) === 'fill')),
-                'answer' => count(array_filter($selected, fn($q) => $this->determineQuestionType($q) === 'answer')),
-            ],
+            'selected_counts' => $selectedCounts,
             'final_selected_count' => count($selected)
         ]);
 

+ 18 - 0
routes/api.php

@@ -502,6 +502,7 @@ Route::get('/mistake-book/{mistakeId}', [MistakeBookController::class, 'getMista
         'auth:sanctum',
         'auth:api',
     ])
+    ->whereNumber('mistakeId')
     ->name('api.mistake-book.detail');
 
 // 获取错题统计概要
@@ -958,6 +959,7 @@ Route::get('/student-answers/history/{studentId}', [StudentAnswerAnalysisControl
 
 use App\Http\Controllers\Api\ExamAnswerAnalysisController;
 use App\Http\Controllers\Api\PaperSubmitAnalysisController;
+use App\Http\Controllers\Api\HealthCheckController;
 
 // 分析考试答题数据
 Route::post('/exam-answer-analysis', [ExamAnswerAnalysisController::class, 'analyze'])
@@ -1076,3 +1078,19 @@ Route::get('/paper-submit-analysis/{paperId}', [PaperSubmitAnalysisController::c
         'auth:api',
     ])
     ->name('api.paper-submit-analysis.result');
+
+/*
+|--------------------------------------------------------------------------
+| 健康检查 API 路由
+|--------------------------------------------------------------------------
+*/
+
+// 检查系统健康状态
+Route::get('/health', [HealthCheckController::class, 'index'])
+    ->withoutMiddleware([
+        Authenticate::class,
+        'auth',
+        'auth:sanctum',
+        'auth:api',
+    ])
+    ->name('api.health.index');