api.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. use App\Services\QuestionServiceApi;
  3. use Illuminate\Support\Facades\Route;
  4. use Illuminate\Support\Facades\Log;
  5. /*
  6. |--------------------------------------------------------------------------
  7. | 题库管理 API 路由
  8. |--------------------------------------------------------------------------
  9. */
  10. // 接收题目生成回调
  11. Route::post('/questions/callback', function () {
  12. try {
  13. $data = request()->all();
  14. Log::info('Received question generation callback', $data);
  15. // 验证回调数据
  16. if (!isset($data['task_id']) || !isset($data['status'])) {
  17. return response()->json(['error' => 'Invalid callback data'], 400);
  18. }
  19. // 存储回调结果到 session 或缓存中,供前端查询
  20. session(['question_gen_callback_' . $data['task_id'] => $data]);
  21. // 广播实时通知到前端
  22. if ($data['status'] === 'completed') {
  23. $kpCode = $data['result']['kp_code'] ?? '未知';
  24. $total = $data['result']['total'] ?? 0;
  25. // 广播成功事件
  26. // event(new \App\Events\QuestionGenerationCompleted($data['task_id'], $kpCode, $total));
  27. } elseif ($data['status'] === 'failed') {
  28. $error = $data['error'] ?? '未知错误';
  29. $kpCode = $data['result']['kp_code'] ?? '未知';
  30. // 广播失败事件
  31. // event(new \App\Events\QuestionGenerationFailed($data['task_id'], $kpCode, $error));
  32. }
  33. return response()->json(['success' => true, 'message' => 'Callback received']);
  34. } catch (\Exception $e) {
  35. Log::error('Callback processing failed: ' . $e->getMessage());
  36. return response()->json(['error' => $e->getMessage()], 500);
  37. }
  38. })->name('api.questions.callback');
  39. // 获取题目生成回调结果
  40. Route::get('/questions/callback/{taskId}', function (string $taskId) {
  41. $callbackData = session('question_gen_callback_' . $taskId);
  42. if ($callbackData) {
  43. // 清除已读取的回调数据
  44. session()->forget('question_gen_callback_' . $taskId);
  45. return response()->json($callbackData);
  46. }
  47. return response()->json(['status' => 'pending'], 202);
  48. })->name('api.questions.callback.get');
  49. // 题目相关 API
  50. Route::get('/questions', function (QuestionServiceApi $service) {
  51. try {
  52. $page = (int) request()->get('page', 1);
  53. $perPage = (int) request()->get('per_page', 25);
  54. $filters = [
  55. 'kp_code' => request()->get('kp_code'),
  56. 'difficulty' => request()->get('difficulty'),
  57. 'search' => request()->get('search'),
  58. ];
  59. $response = $service->listQuestions($page, $perPage, $filters);
  60. return response()->json($response);
  61. } catch (\Exception $e) {
  62. \Log::error('Failed to fetch questions: ' . $e->getMessage());
  63. return response()->json([
  64. 'data' => [],
  65. 'meta' => [
  66. 'page' => 1,
  67. 'per_page' => 25,
  68. 'total' => 0,
  69. 'total_pages' => 0,
  70. ],
  71. 'error' => $e->getMessage(),
  72. ], 500);
  73. }
  74. });
  75. // 获取题目统计信息
  76. Route::get('/questions/statistics', function (QuestionServiceApi $service) {
  77. try {
  78. $stats = $service->getStatistics();
  79. return response()->json($stats);
  80. } catch (\Exception $e) {
  81. \Log::error('Failed to get question statistics: ' . $e->getMessage());
  82. return response()->json(['error' => $e->getMessage()], 500);
  83. }
  84. });
  85. // 语义搜索题目
  86. Route::post('/questions/search', function (QuestionServiceApi $service) {
  87. try {
  88. $data = request()->only(['query', 'limit']);
  89. $results = $service->searchQuestions($data['query'], $data['limit'] ?? 20);
  90. return response()->json($results);
  91. } catch (\Exception $e) {
  92. \Log::error('Question search failed: ' . $e->getMessage());
  93. return response()->json(['error' => $e->getMessage()], 500);
  94. }
  95. });
  96. // 获取单个题目详情
  97. Route::get('/questions/{id}', function (int $id, QuestionServiceApi $service) {
  98. try {
  99. $question = $service->getQuestionById($id);
  100. if (!$question) {
  101. return response()->json(['error' => 'Question not found'], 404);
  102. }
  103. return response()->json($question);
  104. } catch (\Exception $e) {
  105. \Log::error("Failed to get question {$id}: " . $e->getMessage());
  106. return response()->json(['error' => $e->getMessage()], 500);
  107. }
  108. });
  109. // AI 生成题目
  110. Route::post('/questions/generate', function (QuestionServiceApi $service) {
  111. try {
  112. $data = request()->only(['kp_code', 'keyword', 'count', 'strategy']);
  113. $result = $service->generateQuestions($data);
  114. return response()->json($result);
  115. } catch (\Exception $e) {
  116. \Log::error('Question generation failed: ' . $e->getMessage());
  117. return response()->json([
  118. 'success' => false,
  119. 'message' => $e->getMessage(),
  120. ], 500);
  121. }
  122. });
  123. // 删除题目
  124. Route::delete('/questions/{id}', function (int $id, QuestionServiceApi $service) {
  125. try {
  126. $deleted = $service->deleteQuestion($id);
  127. return response()->json([
  128. 'success' => $deleted,
  129. 'message' => $deleted ? 'Question deleted' : 'Failed to delete',
  130. ]);
  131. } catch (\Exception $e) {
  132. \Log::error("Failed to delete question {$id}: " . $e->getMessage());
  133. return response()->json([
  134. 'success' => false,
  135. 'message' => $e->getMessage(),
  136. ], 500);
  137. }
  138. });
  139. // 获取知识点选项
  140. Route::get('/knowledge-points', function (QuestionServiceApi $service) {
  141. try {
  142. $points = $service->getKnowledgePointOptions();
  143. return response()->json($points);
  144. } catch (\Exception $e) {
  145. \Log::error('Failed to get knowledge points: ' . $e->getMessage());
  146. return response()->json([], 500);
  147. }
  148. });
  149. /*
  150. |--------------------------------------------------------------------------
  151. | MathRecSys 集成 API 路由
  152. |--------------------------------------------------------------------------
  153. */
  154. use App\Http\Controllers\Api\StudentController;
  155. // 健康检查
  156. Route::get('/mathrecsys/health', [StudentController::class, 'checkServiceHealth'])->name('api.mathrecsys.health');
  157. // 学生相关 API
  158. Route::prefix('mathrecsys/students')->name('api.mathrecsys.students.')->group(function () {
  159. // 获取学生完整信息
  160. Route::get('{studentId}', [StudentController::class, 'show'])->name('show');
  161. // 获取个性化推荐
  162. Route::get('{studentId}/recommendations', [StudentController::class, 'getRecommendations'])->name('recommendations');
  163. // 获取学习轨迹
  164. Route::get('{studentId}/trajectory', [StudentController::class, 'getTrajectory'])->name('trajectory');
  165. // 获取学习建议
  166. Route::get('{studentId}/suggestions', [StudentController::class, 'getSuggestions'])->name('suggestions');
  167. // 智能分析题目
  168. Route::post('{studentId}/analyze', [StudentController::class, 'analyzeQuestion'])->name('analyze');
  169. // 更新掌握度
  170. Route::put('{studentId}/mastery', [StudentController::class, 'updateMastery'])->name('update-mastery');
  171. });
  172. // 班级分析 API
  173. Route::prefix('mathrecsys/classes')->name('api.mathrecsys.classes.')->group(function () {
  174. Route::get('{classId}/analysis', [StudentController::class, 'classAnalysis'])->name('analysis');
  175. });
  176. // 测试 API
  177. Route::get('/mathrecsys/test', function () {
  178. return response()->json([
  179. 'success' => true,
  180. 'message' => 'MathRecSys API integration is working',
  181. 'timestamp' => now()->toISOString()
  182. ]);
  183. })->name('api.mathrecsys.test');