AIGatewayService.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <?php
  2. namespace app\service;
  3. use think\Db;
  4. use think\Queue;
  5. class AIGatewayService{
  6. /**
  7. * 接口访问配置
  8. *
  9. * 每个模块包含:
  10. * - api_key:API 调用密钥(Bearer Token)
  11. * - api_url:对应功能的服务端地址
  12. */
  13. protected $config = [
  14. //图生文
  15. 'imgtotxt' => [
  16. 'api_key' => 'sk-scyWT2YPrPOIzralcb6WzCeFdAZvl91rh1JcuuaNMrhEJNDZ',
  17. 'api_url' => 'https://niubi.zeabur.app/v1/chat/completions'
  18. ],
  19. //文生文
  20. 'txttotxt' => [
  21. 'api_key' => 'sk-Bhos1lXTRpZiAAmN06624a219a874eCd91Dc068b902a3e73',
  22. 'api_url' => 'https://one.opengptgod.com/v1/chat/completions'
  23. ],
  24. //文生图
  25. 'txttoimg' => [
  26. 'api_key' => 'sk-e0JuPjMntkbgi1BoMjrqyyzMKzAxILkQzyGMSy3xiMupuoWY',
  27. 'api_url' => 'https://niubi.zeabur.app/v1/images/generations'
  28. ]
  29. ];
  30. /**
  31. * 图生文
  32. * @param string $imageUrl 图像 URL,支持公网可访问地址
  33. * @param string $prompt 对图像的提问内容或提示文本
  34. */
  35. public function callGptApi($imageUrl, $prompt)
  36. {
  37. $data = [
  38. "model" => "gemini-2.5-pro-preview-05-06",
  39. "messages" => [[
  40. "role" => "user",
  41. "content" => [
  42. ["type" => "text", "text" => $prompt],
  43. ["type" => "image_url", "image_url" => [
  44. "url" => $imageUrl,
  45. "detail" => "auto"
  46. ]]
  47. ]
  48. ]],
  49. "max_tokens" => 1000
  50. ];
  51. return $this->callApi($this->config['imgtotxt']['api_url'], $this->config['imgtotxt']['api_key'], $data);
  52. }
  53. // public function callGptApi($imageUrl, $prompt)
  54. // {
  55. // $data = [
  56. // "model" => "gpt-4-vision-preview",
  57. // "messages" => [[
  58. // "role" => "user",
  59. // "content" => [
  60. // ["type" => "text", "text" => $prompt],
  61. // ["type" => "image_url", "image_url" => [
  62. // "url" => $imageUrl,
  63. // "detail" => "auto"
  64. // ]]
  65. // ]
  66. // ]],
  67. // "max_tokens" => 1000
  68. // ];
  69. // return $this->callApi($this->config['imgtotxt']['api_url'], $this->config['imgtotxt']['api_key'], $data);
  70. // }
  71. /**
  72. * 文生文
  73. * @param string $prompt 用户输入的文本提示内容
  74. */
  75. public function txtGptApi($prompt)
  76. {
  77. $data = [
  78. 'prompt' => $prompt,
  79. 'model' => 'gpt-4',
  80. 'session_id' => null,
  81. 'context_reset' => true
  82. ];
  83. return $this->callApi(
  84. $this->config['txttotxt']['api_url'],
  85. $this->config['txttotxt']['api_key'],
  86. $data
  87. );
  88. }
  89. /**
  90. * 文生图
  91. * @param string $prompt 提示文本,用于指导图像生成
  92. * @param string $selectedOption 模型名称,例如 'dall-e-3' 或其他兼容模型
  93. */
  94. public function callDalleApi($prompt,$selectedOption)
  95. {
  96. if($selectedOption == 'dall-e-3'){
  97. $data = [
  98. 'prompt' => $prompt,
  99. 'model' => $selectedOption,
  100. 'n' => 1,
  101. 'size' => '1024x1024',
  102. 'quality' => 'standard',
  103. 'style' => 'vivid',
  104. 'response_format' => 'url',
  105. 'session_id' => null,
  106. 'context_reset' => true
  107. ];
  108. }else{
  109. $data = [
  110. 'prompt' => $prompt,
  111. 'model' => $selectedOption,
  112. 'n' => 1,
  113. 'size' => '1024x1024',
  114. 'quality' => 'hd',
  115. 'style' => 'vivid',
  116. 'response_format' => 'url',
  117. 'session_id' => null,
  118. 'context_reset' => true
  119. ];
  120. }
  121. return $this->callApi($this->config['txttoimg']['api_url'], $this->config['txttoimg']['api_key'], $data);
  122. }
  123. /**
  124. * 通用 API 调用方法(支持重试机制)
  125. *
  126. * @param string $url 接口地址
  127. * @param string $apiKey 授权密钥(Bearer Token)
  128. * @param array $data 请求数据(JSON 格式)
  129. *
  130. * 功能说明:
  131. * - 使用 cURL 发送 POST 请求到指定 API 接口
  132. * - 设置请求头和超时时间等参数
  133. * - 支持最多重试 2 次,当接口调用失败时自动重试
  134. * - 返回成功时解析 JSON 响应为数组
  135. *
  136. * 异常处理:
  137. * - 若全部重试失败,将抛出异常并包含最后一次错误信息
  138. *
  139. * @return array 接口响应数据(成功时返回解析后的数组)
  140. * @throws \Exception 接口请求失败时抛出异常
  141. */
  142. public function callApi($url, $apiKey, $data)
  143. {
  144. $maxRetries = 2; // 最多重试次数
  145. $attempt = 0; // 当前尝试次数
  146. $lastError = ''; // 最后一次错误信息
  147. while ($attempt <= $maxRetries) {
  148. $ch = curl_init();
  149. curl_setopt_array($ch, [
  150. CURLOPT_URL => $url,
  151. CURLOPT_RETURNTRANSFER => true,
  152. CURLOPT_POST => true,
  153. CURLOPT_POSTFIELDS => json_encode($data),
  154. CURLOPT_HTTPHEADER => [
  155. 'Content-Type: application/json',
  156. 'Authorization: Bearer ' . $apiKey
  157. ],
  158. CURLOPT_TIMEOUT => 120,
  159. CURLOPT_SSL_VERIFYPEER => false,
  160. CURLOPT_SSL_VERIFYHOST => 0,
  161. CURLOPT_TCP_KEEPALIVE => 1,
  162. CURLOPT_FORBID_REUSE => false
  163. ]);
  164. $response = curl_exec($ch);
  165. $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  166. $curlError = curl_error($ch);
  167. curl_close($ch);
  168. if ($response !== false && $httpCode === 200) {
  169. $result = json_decode($response, true);
  170. return $result;
  171. }
  172. $lastError = $curlError ?: "HTTP错误:{$httpCode}";
  173. $attempt++;
  174. sleep(1);
  175. }
  176. throw new \Exception("请求失败(重试{$maxRetries}次):{$lastError}");
  177. }
  178. }