ExamAnalysisApiController.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <?php
  2. namespace App\Http\Controllers\Api;
  3. use App\Http\Controllers\Controller;
  4. use App\Services\ExamAnalysisService;
  5. use App\Services\TaskManager;
  6. use Illuminate\Http\JsonResponse;
  7. use Illuminate\Http\Request;
  8. use Illuminate\Support\Facades\Log;
  9. class ExamAnalysisApiController extends Controller
  10. {
  11. public function __construct(
  12. private readonly ExamAnalysisService $examAnalysisService,
  13. private readonly TaskManager $taskManager
  14. ) {}
  15. /**
  16. * 生成学情报告(异步模式)
  17. * 立即返回任务ID,PDF生成在后台进行
  18. */
  19. public function store(Request $request): JsonResponse
  20. {
  21. $data = $request->validate([
  22. 'paper_id' => 'required|string',
  23. 'student_id' => 'nullable|string',
  24. 'record_id' => 'nullable|string',
  25. 'callback_url' => 'nullable|url',
  26. ]);
  27. $paperId = $data['paper_id'];
  28. $studentId = $data['student_id'] ?? null;
  29. $recordId = $data['record_id'] ?? null;
  30. try {
  31. // 如果没有提供student_id,尝试从paper_id获取
  32. if (!$studentId) {
  33. $studentId = $this->getStudentIdFromPaper($paperId);
  34. }
  35. if (!$studentId) {
  36. return response()->json([
  37. 'success' => false,
  38. 'message' => '缺少 student_id',
  39. ], 422);
  40. }
  41. // 使用ExamAnalysisService生成报告
  42. $taskId = $this->examAnalysisService->generateReport($paperId, $studentId, $recordId);
  43. // 构建返回数据
  44. $payload = [
  45. 'success' => true,
  46. 'message' => '学情报告任务已创建,正在后台生成PDF...',
  47. 'data' => [
  48. 'task_id' => $taskId,
  49. 'paper_id' => $paperId,
  50. 'student_id' => $studentId,
  51. 'record_id' => $recordId,
  52. 'status' => 'processing',
  53. 'analysis_url' => route('filament.admin.pages.exam-analysis', [
  54. 'paperId' => $paperId,
  55. 'studentId' => $studentId,
  56. 'recordId' => $recordId,
  57. ]),
  58. 'pdf_url' => null, // 稍后生成
  59. 'created_at' => now()->toISOString(),
  60. ],
  61. ];
  62. return response()->json($payload, 200, [], JSON_UNESCAPED_SLASHES);
  63. } catch (\Exception $e) {
  64. Log::error('学情报告API失败', [
  65. 'paper_id' => $paperId,
  66. 'student_id' => $studentId,
  67. 'record_id' => $recordId,
  68. 'error' => $e->getMessage(),
  69. ]);
  70. return response()->json([
  71. 'success' => false,
  72. 'message' => '服务异常:' . $e->getMessage(),
  73. ], 500);
  74. }
  75. }
  76. /**
  77. * 轮询任务状态
  78. */
  79. public function status(string $taskId): JsonResponse
  80. {
  81. try {
  82. $task = $this->taskManager->getTaskStatus($taskId);
  83. if (!$task) {
  84. return response()->json([
  85. 'success' => false,
  86. 'message' => '任务不存在',
  87. ], 404);
  88. }
  89. return response()->json([
  90. 'success' => true,
  91. 'data' => $task,
  92. ]);
  93. } catch (\Exception $e) {
  94. Log::error('查询学情报告任务状态失败', [
  95. 'task_id' => $taskId,
  96. 'error' => $e->getMessage(),
  97. ]);
  98. return response()->json([
  99. 'success' => false,
  100. 'message' => '查询失败:' . $e->getMessage(),
  101. ], 500);
  102. }
  103. }
  104. /**
  105. * 从试卷ID获取学生ID
  106. */
  107. private function getStudentIdFromPaper(string $paperId): ?string
  108. {
  109. try {
  110. $paper = \App\Models\Paper::find($paperId);
  111. return $paper?->student_id;
  112. } catch (\Exception $e) {
  113. Log::warning('获取试卷学生ID失败', [
  114. 'paper_id' => $paperId,
  115. 'error' => $e->getMessage(),
  116. ]);
  117. return null;
  118. }
  119. }
  120. }