StudentController.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. <?php
  2. namespace App\Http\Controllers\Api;
  3. use App\Http\Controllers\Controller;
  4. use App\Services\MathRecSysService;
  5. use Illuminate\Http\Request;
  6. use Illuminate\Http\JsonResponse;
  7. class StudentController extends Controller
  8. {
  9. protected MathRecSysService $mathRecSys;
  10. public function __construct(MathRecSysService $mathRecSys)
  11. {
  12. $this->mathRecSys = $mathRecSys;
  13. }
  14. /**
  15. * 获取学生完整信息(集成MathRecSys数据)
  16. *
  17. * @param string $studentId 学生ID
  18. * @return JsonResponse
  19. */
  20. public function show(string $studentId): JsonResponse
  21. {
  22. try {
  23. // 获取Laravel本地数据
  24. $localStudent = $this->getLocalStudent($studentId);
  25. // 获取MathRecSys能力画像
  26. $mathRecSysProfile = $this->mathRecSys->getStudentProfile($studentId);
  27. // 获取薄弱知识点
  28. $weakPoints = $this->mathRecSys->getWeakPoints($studentId);
  29. // 合并数据
  30. $studentData = [
  31. 'basic_info' => $localStudent,
  32. 'ability_profile' => $mathRecSysProfile['data'] ?? [],
  33. 'mastery_levels' => $this->formatMasteryLevels($mathRecSysProfile),
  34. 'weak_points' => $weakPoints['data'] ?? [],
  35. 'learning_progress' => $mathRecSysProfile['progress'] ?? [],
  36. 'recommendations' => $this->getStudentRecommendations($studentId),
  37. 'last_updated' => now()->toISOString()
  38. ];
  39. return response()->json([
  40. 'success' => true,
  41. 'data' => $studentData
  42. ]);
  43. } catch (\Exception $e) {
  44. \Log::error('获取学生信息失败', [
  45. 'student_id' => $studentId,
  46. 'error' => $e->getMessage()
  47. ]);
  48. return response()->json([
  49. 'success' => false,
  50. 'message' => '获取学生信息失败: ' . $e->getMessage()
  51. ], 500);
  52. }
  53. }
  54. /**
  55. * 获取班级整体分析
  56. *
  57. * @param string $classId 班级ID
  58. * @return JsonResponse
  59. */
  60. public function classAnalysis(string $classId): JsonResponse
  61. {
  62. try {
  63. $analysis = $this->mathRecSys->getClassAnalysis($classId);
  64. return response()->json([
  65. 'success' => true,
  66. 'data' => $analysis['data'] ?? []
  67. ]);
  68. } catch (\Exception $e) {
  69. \Log::error('获取班级分析失败', [
  70. 'class_id' => $classId,
  71. 'error' => $e->getMessage()
  72. ]);
  73. return response()->json([
  74. 'success' => false,
  75. 'message' => '获取班级分析失败'
  76. ], 500);
  77. }
  78. }
  79. /**
  80. * 获取学生个性化推荐
  81. *
  82. * @param string $studentId 学生ID
  83. * @param Request $request
  84. * @return JsonResponse
  85. */
  86. public function getRecommendations(string $studentId, Request $request): JsonResponse
  87. {
  88. try {
  89. $options = $request->only(['count', 'difficulty', 'focus_kp']);
  90. $recommendations = $this->mathRecSys->getRecommendations($studentId, $options);
  91. return response()->json([
  92. 'success' => true,
  93. 'data' => $recommendations['data'] ?? []
  94. ]);
  95. } catch (\Exception $e) {
  96. \Log::error('获取推荐失败', [
  97. 'student_id' => $studentId,
  98. 'error' => $e->getMessage()
  99. ]);
  100. return response()->json([
  101. 'success' => false,
  102. 'message' => '获取推荐失败'
  103. ], 500);
  104. }
  105. }
  106. /**
  107. * 智能分析题目
  108. *
  109. * @param Request $request
  110. * @param string $studentId 学生ID
  111. * @return JsonResponse
  112. */
  113. public function analyzeQuestion(Request $request, string $studentId): JsonResponse
  114. {
  115. $request->validate([
  116. 'question' => 'required|string',
  117. 'student_answer' => 'required|string',
  118. 'correct_answer' => 'required|string',
  119. 'focus_kp' => 'nullable|string',
  120. 'question_type' => 'nullable|string',
  121. 'difficulty' => 'nullable|numeric|min:0|max:1',
  122. ]);
  123. try {
  124. $analysisData = [
  125. 'student_id' => $studentId,
  126. 'question' => $request->question,
  127. 'student_answer' => $request->student_answer,
  128. 'correct_answer' => $request->correct_answer,
  129. 'focus_kp' => $request->focus_kp,
  130. 'question_type' => $request->question_type ?? '计算题',
  131. 'difficulty' => $request->difficulty ?? 0.5,
  132. ];
  133. $analysis = $this->mathRecSys->smartAnalyze($analysisData);
  134. return response()->json([
  135. 'success' => true,
  136. 'data' => $analysis['data'] ?? []
  137. ]);
  138. } catch (\Exception $e) {
  139. \Log::error('题目分析失败', [
  140. 'student_id' => $studentId,
  141. 'error' => $e->getMessage()
  142. ]);
  143. return response()->json([
  144. 'success' => false,
  145. 'message' => '题目分析失败'
  146. ], 500);
  147. }
  148. }
  149. /**
  150. * 获取学习轨迹
  151. *
  152. * @param string $studentId 学生ID
  153. * @param Request $request
  154. * @return JsonResponse
  155. */
  156. public function getTrajectory(string $studentId, Request $request): JsonResponse
  157. {
  158. try {
  159. $startDate = $request->input('start_date');
  160. $endDate = $request->input('end_date');
  161. $trajectory = $this->mathRecSys->getLearningTrajectory($studentId, $startDate, $endDate);
  162. return response()->json([
  163. 'success' => true,
  164. 'data' => $trajectory['data'] ?? []
  165. ]);
  166. } catch (\Exception $e) {
  167. \Log::error('获取学习轨迹失败', [
  168. 'student_id' => $studentId,
  169. 'error' => $e->getMessage()
  170. ]);
  171. return response()->json([
  172. 'success' => false,
  173. 'message' => '获取学习轨迹失败'
  174. ], 500);
  175. }
  176. }
  177. /**
  178. * 获取学习建议
  179. *
  180. * @param string $studentId 学生ID
  181. * @return JsonResponse
  182. */
  183. public function getSuggestions(string $studentId): JsonResponse
  184. {
  185. try {
  186. $suggestions = $this->mathRecSys->getLearningSuggestions($studentId);
  187. return response()->json([
  188. 'success' => true,
  189. 'data' => $suggestions['data'] ?? []
  190. ]);
  191. } catch (\Exception $e) {
  192. \Log::error('获取学习建议失败', [
  193. 'student_id' => $studentId,
  194. 'error' => $e->getMessage()
  195. ]);
  196. return response()->json([
  197. 'success' => false,
  198. 'message' => '获取学习建议失败'
  199. ], 500);
  200. }
  201. }
  202. /**
  203. * 更新学生掌握度
  204. *
  205. * @param Request $request
  206. * @param string $studentId 学生ID
  207. * @return JsonResponse
  208. */
  209. public function updateMastery(Request $request, string $studentId): JsonResponse
  210. {
  211. $request->validate([
  212. 'mastery_data' => 'required|array',
  213. 'mastery_data.*.kp' => 'required|string',
  214. 'mastery_data.*.level' => 'required|numeric|min:0|max:1',
  215. ]);
  216. try {
  217. $result = $this->mathRecSys->updateMastery($studentId, $request->mastery_data);
  218. return response()->json([
  219. 'success' => true,
  220. 'data' => $result['data'] ?? []
  221. ]);
  222. } catch (\Exception $e) {
  223. \Log::error('更新掌握度失败', [
  224. 'student_id' => $studentId,
  225. 'error' => $e->getMessage()
  226. ]);
  227. return response()->json([
  228. 'success' => false,
  229. 'message' => '更新掌握度失败'
  230. ], 500);
  231. }
  232. }
  233. /**
  234. * 检查MathRecSys服务状态
  235. *
  236. * @return JsonResponse
  237. */
  238. public function checkServiceHealth(): JsonResponse
  239. {
  240. $isHealthy = $this->mathRecSys->isHealthy();
  241. return response()->json([
  242. 'success' => true,
  243. 'healthy' => $isHealthy,
  244. 'timestamp' => now()->toISOString()
  245. ]);
  246. }
  247. /**
  248. * 从本地数据库获取学生基本信息
  249. *
  250. * @param string $studentId
  251. * @return array
  252. */
  253. private function getLocalStudent(string $studentId): array
  254. {
  255. // 这里应该从Laravel数据库查询学生信息
  256. // 示例返回数据,实际应该查询数据库
  257. return [
  258. 'id' => $studentId,
  259. 'name' => '学生_' . substr($studentId, -3),
  260. 'class' => '五年级一班',
  261. 'grade' => '五年级',
  262. 'created_at' => now()->subMonths(6)->toISOString(),
  263. ];
  264. }
  265. /**
  266. * 格式化掌握度数据
  267. *
  268. * @param array $profile
  269. * @return array
  270. */
  271. private function formatMasteryLevels(array $profile): array
  272. {
  273. $masteryData = $profile['data']['mastery'] ?? $profile['mastery'] ?? [];
  274. return array_map(function ($item) {
  275. return [
  276. 'kp' => $item['kp'] ?? $item['kp_id'] ?? '',
  277. 'level' => floatval($item['level'] ?? $item['mastery_level'] ?? 0),
  278. 'practice_count' => $item['practice_count'] ?? 0,
  279. 'success_rate' => floatval($item['success_rate'] ?? 0),
  280. 'last_practice' => $item['last_practice'] ?? null
  281. ];
  282. }, $masteryData);
  283. }
  284. /**
  285. * 获取推荐(内部方法)
  286. *
  287. * @param string $studentId
  288. * @return array
  289. */
  290. private function getStudentRecommendations(string $studentId): array
  291. {
  292. try {
  293. $recommendations = $this->mathRecSys->getRecommendations($studentId, ['count' => 5]);
  294. return $recommendations['data'] ?? [];
  295. } catch (\Exception $e) {
  296. \Log::warning('获取推荐失败', ['error' => $e->getMessage()]);
  297. return [];
  298. }
  299. }
  300. }