TextToTextJob.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. namespace app\job;
  3. use think\Db;
  4. use think\queue\Job;
  5. use think\Queue;
  6. class TextToTextJob
  7. {
  8. protected $config = [
  9. 'gpt' => [
  10. 'api_key' => 'sk-Bhos1lXTRpZiAAmN06624a219a874eCd91Dc068b902a3e73',
  11. 'api_url' => 'https://one.opengptgod.com/v1/chat/completions'
  12. ],
  13. 'dalle' => [
  14. 'api_key' => 'sk-e0JuPjMntkbgi1BoMjrqyyzMKzAxILkQzyGMSy3xiMupuoWY',
  15. 'api_url' => 'https://niubi.zeabur.app/v1/images/generations'
  16. ]
  17. ];
  18. /**
  19. * 文生文
  20. */
  21. public function fire(Job $job, $data)
  22. {
  23. $logId = $data['log_id'] ?? null;
  24. echo "━━━━━━━━━━ ▶ 文生文任务开始处理━━━━━━━━━━\n";
  25. try {
  26. $startTime = date('Y-m-d H:i:s');
  27. if ($logId) {
  28. Db::name('image_task_log')->where('id', $logId)->update([
  29. 'status' => 1,
  30. 'log' => '文生文处理中',
  31. 'update_time' => date('Y-m-d H:i:s')
  32. ]);
  33. }
  34. $fullPath = rtrim($data['sourceDir'], '/') . '/' . ltrim($data['file_name'], '/');
  35. $list = Db::name("text_to_image")
  36. ->where('old_image_url', $fullPath)
  37. ->where('img_name', '<>', '')
  38. ->where('status', 0)
  39. ->select();
  40. if (!empty($list)) {
  41. foreach ($list as $index => $row) {
  42. $currentTime = date('Y-m-d H:i:s');
  43. echo "处理时间:{$currentTime}\n";
  44. echo "👉 正在处理第 " . ($index + 1) . " 条,ID: {$row['id']}\n";
  45. $result = $this->textToTxt($row['id']);
  46. echo $result;
  47. echo "✅ 处理结果:完成\n";
  48. echo "完成时间:" . date('Y-m-d H:i:s') . "\n";
  49. echo "Processed: " . static::class . "\n\n";
  50. }
  51. // 更新日志为成功
  52. if ($logId) {
  53. Db::name('image_task_log')->where('id', $logId)->update([
  54. 'status' => 2,
  55. 'log' => '文生文执行成功',
  56. 'update_time' => date('Y-m-d H:i:s')
  57. ]);
  58. }
  59. echo "处理完成\n";
  60. } else {
  61. echo "⚠ 未找到可处理的数据,跳过执行\n";
  62. if ($logId) {
  63. Db::name('image_task_log')->where('id', $logId)->update([
  64. 'status' => 2,
  65. 'log' => '无数据可处理,已跳过',
  66. 'update_time' => date('Y-m-d H:i:s')
  67. ]);
  68. }
  69. }
  70. } catch (\Exception $e) {
  71. echo "❌ 错误信息: " . $e->getMessage() . "\n";
  72. echo "📄 文件: " . $e->getFile() . ",第 " . $e->getLine() . " 行\n";
  73. if ($logId) {
  74. Db::name('image_task_log')->where('id', $logId)->update([
  75. 'status' => -1,
  76. 'log' => '文生文失败:' . $e->getMessage(),
  77. 'update_time' => date('Y-m-d H:i:s')
  78. ]);
  79. }
  80. }
  81. $job->delete();
  82. }
  83. /**
  84. * 文生文接口
  85. */
  86. public function textToTxt($id)
  87. {
  88. $template = Db::name('template')
  89. ->field('id,english_content')
  90. ->where('ids',1)
  91. ->find();
  92. $record = Db::name('text_to_image')
  93. ->field('id,english_description')
  94. ->where('id',$id)
  95. ->order('id desc')
  96. ->find();
  97. if (!$record) {return '没有找到匹配的图像记录';}
  98. // 调用文生文
  99. $gptRes = $this->TxtGptApi($template['english_content'].$record['english_description']);
  100. $gptText = trim($gptRes['choices'][0]['message']['content'] ?? '');
  101. // 更新数据库记录
  102. Db::name('text_to_image')->where('id', $record['id'])->update([
  103. 'english_description' => $gptText
  104. ]);
  105. return 0;
  106. }
  107. /**
  108. * 文升文模型
  109. */
  110. public function TxtGptApi($prompt)
  111. {
  112. $data = [
  113. 'prompt' => $prompt,
  114. 'model' => 'gpt-4',
  115. 'session_id' => null,
  116. 'context_reset' => true
  117. ];
  118. return $this->callApi($this->config['gpt']['api_url'],$this->config['gpt']['api_key'],$data);
  119. }
  120. /**
  121. * 通用API调用方法
  122. */
  123. public function callApi($url, $apiKey, $data)
  124. {
  125. $maxRetries = 2;
  126. $attempt = 0;
  127. $lastError = '';
  128. while ($attempt <= $maxRetries) {
  129. $ch = curl_init();
  130. curl_setopt_array($ch, [
  131. CURLOPT_URL => $url,
  132. CURLOPT_RETURNTRANSFER => true,
  133. CURLOPT_POST => true,
  134. CURLOPT_POSTFIELDS => json_encode($data),
  135. CURLOPT_HTTPHEADER => [
  136. 'Content-Type: application/json',
  137. 'Authorization: Bearer ' . $apiKey
  138. ],
  139. CURLOPT_TIMEOUT => 120,
  140. CURLOPT_SSL_VERIFYPEER => false,
  141. CURLOPT_SSL_VERIFYHOST => 0,
  142. CURLOPT_TCP_KEEPALIVE => 1,
  143. CURLOPT_FORBID_REUSE => false
  144. ]);
  145. $response = curl_exec($ch);
  146. $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  147. $curlError = curl_error($ch);
  148. curl_close($ch);
  149. if ($response !== false && $httpCode === 200) {
  150. $result = json_decode($response, true);
  151. return $result;
  152. }
  153. $lastError = $curlError ?: "HTTP错误:{$httpCode}";
  154. $attempt++;
  155. sleep(1);
  156. }
  157. throw new \Exception("请求失败(重试{$maxRetries}次):{$lastError}");
  158. }
  159. }