QuestionBankService.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <?php
  2. namespace App\Services;
  3. use Illuminate\Support\Facades\Http;
  4. use Illuminate\Support\Facades\Log;
  5. class QuestionBankService
  6. {
  7. protected string $baseUrl;
  8. public function __construct()
  9. {
  10. // 从配置文件读取base_url
  11. $this->baseUrl = config('services.question_bank.base_url', env('QUESTION_BANK_API_BASE', 'http://fa.test/api.questions.callback'));
  12. $this->baseUrl = rtrim($this->baseUrl, '/');
  13. }
  14. /**
  15. * 获取题目列表
  16. */
  17. public function listQuestions(int $page = 1, int $perPage = 50, array $filters = []): array
  18. {
  19. try {
  20. $response = Http::timeout(10)
  21. ->get($this->baseUrl . '/questions', [
  22. 'page' => $page,
  23. 'per_page' => $perPage,
  24. ...$filters
  25. ]);
  26. if ($response->successful()) {
  27. return $response->json();
  28. }
  29. Log::warning('题库API调用失败', [
  30. 'status' => $response->status()
  31. ]);
  32. } catch (\Exception $e) {
  33. Log::error('获取题目列表失败', [
  34. 'error' => $e->getMessage()
  35. ]);
  36. }
  37. return ['data' => [], 'meta' => ['total' => 0]];
  38. }
  39. /**
  40. * 智能生成题目(异步模式)
  41. */
  42. public function generateIntelligentQuestions(array $params, ?string $callbackUrl = null): array
  43. {
  44. try {
  45. // 添加回调 URL
  46. if ($callbackUrl) {
  47. $params['callback_url'] = $callbackUrl;
  48. }
  49. $response = Http::timeout(10)
  50. ->post($this->baseUrl . '/generate-intelligent-questions', $params);
  51. if ($response->successful()) {
  52. return $response->json();
  53. }
  54. Log::warning('题目生成API调用失败', [
  55. 'status' => $response->status()
  56. ]);
  57. } catch (\Exception $e) {
  58. Log::error('题目生成异常', [
  59. 'error' => $e->getMessage()
  60. ]);
  61. }
  62. return ['success' => false, 'message' => '生成失败'];
  63. }
  64. /**
  65. * 获取任务状态
  66. */
  67. public function getTaskStatus(string $taskId): ?array
  68. {
  69. try {
  70. $response = Http::timeout(10)
  71. ->get($this->baseUrl . '/tasks/' . $taskId);
  72. if ($response->successful()) {
  73. return $response->json();
  74. }
  75. Log::warning('获取任务状态失败', [
  76. 'task_id' => $taskId,
  77. 'status' => $response->status()
  78. ]);
  79. } catch (\Exception $e) {
  80. Log::error('获取任务状态异常', [
  81. 'task_id' => $taskId,
  82. 'error' => $e->getMessage()
  83. ]);
  84. }
  85. return null;
  86. }
  87. /**
  88. * 获取任务列表
  89. */
  90. public function listTasks(?string $status = null, int $page = 1, int $perPage = 10): array
  91. {
  92. try {
  93. $params = [
  94. 'page' => $page,
  95. 'per_page' => $perPage
  96. ];
  97. if ($status) {
  98. $params['status'] = $status;
  99. }
  100. $response = Http::timeout(10)
  101. ->get($this->baseUrl . '/tasks', $params);
  102. if ($response->successful()) {
  103. return $response->json();
  104. }
  105. Log::warning('获取任务列表失败', [
  106. 'status' => $response->status()
  107. ]);
  108. } catch (\Exception $e) {
  109. Log::error('获取任务列表异常', [
  110. 'error' => $e->getMessage()
  111. ]);
  112. }
  113. return ['data' => [], 'meta' => ['total' => 0]];
  114. }
  115. /**
  116. * 获取题目统计信息
  117. */
  118. public function getStatistics(): array
  119. {
  120. try {
  121. $response = Http::timeout(10)
  122. ->get($this->baseUrl . '/questions/statistics');
  123. if ($response->successful()) {
  124. return $response->json();
  125. }
  126. Log::warning('获取题目统计失败', [
  127. 'status' => $response->status()
  128. ]);
  129. } catch (\Exception $e) {
  130. Log::error('获取题目统计异常', [
  131. 'error' => $e->getMessage()
  132. ]);
  133. }
  134. return [
  135. 'total' => 0,
  136. 'by_difficulty' => [],
  137. 'by_kp' => [],
  138. 'by_source' => []
  139. ];
  140. }
  141. /**
  142. * 根据知识点获取题目
  143. */
  144. public function getQuestionsByKpCode(string $kpCode, int $limit = 100): array
  145. {
  146. try {
  147. $response = Http::timeout(10)
  148. ->get($this->baseUrl . '/questions', [
  149. 'kp_code' => $kpCode,
  150. 'limit' => $limit
  151. ]);
  152. if ($response->successful()) {
  153. return $response->json();
  154. }
  155. } catch (\Exception $e) {
  156. Log::error('根据知识点获取题目失败', [
  157. 'kp_code' => $kpCode,
  158. 'error' => $e->getMessage()
  159. ]);
  160. }
  161. return [];
  162. }
  163. /**
  164. * 删除题目
  165. */
  166. public function deleteQuestion(string $questionCode): bool
  167. {
  168. try {
  169. $response = Http::timeout(10)
  170. ->delete($this->baseUrl . "/questions/{$questionCode}");
  171. // 只有返回204(删除成功)才返回true,404(不存在)返回false
  172. if ($response->status() === 204) {
  173. return true;
  174. }
  175. if ($response->status() === 404) {
  176. Log::warning('尝试删除不存在的题目', ['question_code' => $questionCode]);
  177. return false;
  178. }
  179. return false;
  180. } catch (\Exception $e) {
  181. Log::error('删除题目失败', [
  182. 'question_code' => $questionCode,
  183. 'error' => $e->getMessage()
  184. ]);
  185. return false;
  186. }
  187. }
  188. /**
  189. * 检查服务健康状态
  190. */
  191. public function checkHealth(): bool
  192. {
  193. try {
  194. $response = Http::timeout(5)
  195. ->get($this->baseUrl . '/health');
  196. return $response->successful();
  197. } catch (\Exception $e) {
  198. Log::error('题库服务健康检查失败', [
  199. 'error' => $e->getMessage()
  200. ]);
  201. return false;
  202. }
  203. }
  204. }