|
|
@@ -251,16 +251,35 @@ class AIImageGenerationService
|
|
|
$isEditMode = true;
|
|
|
}
|
|
|
|
|
|
+ dLog('generate')->info('开始调用GPT-Image2 API', ['task_id' => $task->task_id, 'mode' => $isEditMode ? 'edit' : 'generation']);
|
|
|
+ logDB('generate', 'info', '开始调用GPT-Image2 API', ['task_id' => $task->task_id, 'mode' => $isEditMode ? 'edit' : 'generation']);
|
|
|
+
|
|
|
+ // 创建专用客户端,设置更长的超时时间(图片生成可能需要较长时间)
|
|
|
+ $gptClient = new Client([
|
|
|
+ 'timeout' => 600, // 10分钟超时
|
|
|
+ 'connect_timeout' => 30, // 连接超时30秒
|
|
|
+ 'read_timeout' => 600, // 读取超时10分钟
|
|
|
+ 'http_errors' => false, // 不自动抛出HTTP错误,手动处理
|
|
|
+ ]);
|
|
|
+
|
|
|
// 根据是否有参考图选择不同的请求方式
|
|
|
if ($isEditMode) {
|
|
|
// 使用 multipart/form-data 格式
|
|
|
$imageUrl = is_array($task->ref_img_url) ? $task->ref_img_url[0] : $task->ref_img_url;
|
|
|
|
|
|
+ dLog('generate')->info('下载参考图片', ['image_url' => $imageUrl]);
|
|
|
+
|
|
|
// 下载图片到临时文件
|
|
|
- $imageContent = file_get_contents($imageUrl);
|
|
|
+ $imageContent = @file_get_contents($imageUrl);
|
|
|
+ if ($imageContent === false) {
|
|
|
+ throw new \Exception('下载参考图片失败: ' . $imageUrl);
|
|
|
+ }
|
|
|
+
|
|
|
$tempFile = tempnam(sys_get_temp_dir(), 'gpt_image_');
|
|
|
file_put_contents($tempFile, $imageContent);
|
|
|
|
|
|
+ dLog('generate')->info('参考图片已保存到临时文件', ['temp_file' => $tempFile, 'size' => filesize($tempFile)]);
|
|
|
+
|
|
|
$multipart = [
|
|
|
[
|
|
|
'name' => 'image',
|
|
|
@@ -285,11 +304,14 @@ class AIImageGenerationService
|
|
|
];
|
|
|
}
|
|
|
|
|
|
- dLog('generate')->info('GPT-Image2 API参数(编辑模式): ', ['api_url' => $api_url, 'prompt' => $task->prompt, 'image_url' => $imageUrl]);
|
|
|
- logDB('generate', 'info', 'GPT-Image2任务提交(编辑模式)', ['task_id' => $task->task_id, 'api_url' => $api_url, 'image_url' => $imageUrl]);
|
|
|
+ dLog('generate')->info('GPT-Image2 API参数(编辑模式)', ['api_url' => $api_url, 'prompt' => $task->prompt, 'image_url' => $imageUrl, 'size' => ($task->width . 'x' . $task->height)]);
|
|
|
+ logDB('generate', 'info', 'GPT-Image2任务提交(编辑模式)', ['task_id' => $task->task_id, 'api_url' => $api_url, 'image_url' => $imageUrl, 'prompt' => $task->prompt]);
|
|
|
+
|
|
|
+ dLog('generate')->info('开始发送multipart请求到GPT-Image2 API');
|
|
|
+ $startTime = microtime(true);
|
|
|
|
|
|
// 调用GPT-Image2 API (multipart/form-data)
|
|
|
- $response = $this->httpClient->post($api_url, [
|
|
|
+ $response = $gptClient->post($api_url, [
|
|
|
'headers' => [
|
|
|
'Authorization' => 'Bearer ' . $apiKey,
|
|
|
'Accept' => 'application/json',
|
|
|
@@ -297,6 +319,9 @@ class AIImageGenerationService
|
|
|
'multipart' => $multipart,
|
|
|
]);
|
|
|
|
|
|
+ $elapsed = round(microtime(true) - $startTime, 2);
|
|
|
+ dLog('generate')->info('GPT-Image2 API请求完成', ['elapsed' => $elapsed . 's', 'status_code' => $response->getStatusCode()]);
|
|
|
+
|
|
|
// 删除临时文件
|
|
|
@unlink($tempFile);
|
|
|
} else {
|
|
|
@@ -311,21 +336,45 @@ class AIImageGenerationService
|
|
|
$apiParams['size'] = $task->width . 'x' . $task->height;
|
|
|
}
|
|
|
|
|
|
- dLog('generate')->info('GPT-Image2 API参数: ', $apiParams);
|
|
|
+ dLog('generate')->info('GPT-Image2 API参数', $apiParams);
|
|
|
logDB('generate', 'info', 'GPT-Image2任务提交', ['task_id' => $task->task_id, 'api_url' => $api_url, 'params' => $apiParams]);
|
|
|
|
|
|
+ dLog('generate')->info('开始发送JSON请求到GPT-Image2 API');
|
|
|
+ $startTime = microtime(true);
|
|
|
+
|
|
|
// 调用GPT-Image2 API
|
|
|
- $response = $this->httpClient->post($api_url, [
|
|
|
+ $response = $gptClient->post($api_url, [
|
|
|
'headers' => [
|
|
|
'Authorization' => 'Bearer ' . $apiKey,
|
|
|
'Content-Type' => 'application/json',
|
|
|
],
|
|
|
'json' => $apiParams,
|
|
|
]);
|
|
|
+
|
|
|
+ $elapsed = round(microtime(true) - $startTime, 2);
|
|
|
+ dLog('generate')->info('GPT-Image2 API请求完成', ['elapsed' => $elapsed . 's', 'status_code' => $response->getStatusCode()]);
|
|
|
}
|
|
|
-
|
|
|
- $responseData = json_decode($response->getBody()->getContents(), true);
|
|
|
- dLog('generate')->info('GPT-Image2 API响应: ', $responseData);
|
|
|
+
|
|
|
+ // 获取响应状态码
|
|
|
+ $statusCode = $response->getStatusCode();
|
|
|
+ dLog('generate')->info('GPT-Image2 API HTTP状态码: ' . $statusCode);
|
|
|
+
|
|
|
+ // 读取响应内容
|
|
|
+ $responseBody = $response->getBody()->getContents();
|
|
|
+ dLog('generate')->info('GPT-Image2 API响应原始数据长度: ' . strlen($responseBody));
|
|
|
+
|
|
|
+ if (empty($responseBody)) {
|
|
|
+ throw new \Exception('API返回空响应,HTTP状态码: ' . $statusCode);
|
|
|
+ }
|
|
|
+
|
|
|
+ $responseData = json_decode($responseBody, true);
|
|
|
+
|
|
|
+ if (json_last_error() !== JSON_ERROR_NONE) {
|
|
|
+ dLog('generate')->error('JSON解析失败', ['error' => json_last_error_msg(), 'body' => substr($responseBody, 0, 500)]);
|
|
|
+ throw new \Exception('JSON解析失败: ' . json_last_error_msg());
|
|
|
+ }
|
|
|
+
|
|
|
+ dLog('generate')->info('GPT-Image2 API响应', $responseData);
|
|
|
logDB('generate', 'info', 'GPT-Image2 API响应', ['task_id' => $task->task_id, 'response' => $responseData]);
|
|
|
|
|
|
if (isset($responseData['error'])) {
|
|
|
@@ -337,12 +386,21 @@ class AIImageGenerationService
|
|
|
]);
|
|
|
} else {
|
|
|
// 任务提交成功,直接处理结果
|
|
|
+ dLog('generate')->info('开始处理GPT-Image2响应结果');
|
|
|
$this->processGptImage2ApiResponse($task, $responseData);
|
|
|
}
|
|
|
} catch (\Exception $e) {
|
|
|
// 记录错误
|
|
|
- dLog('generate')->error('GPT-Image2 API请求失败: ' . $e->getMessage());
|
|
|
- logDB('generate', 'error', 'GPT-Image2任务异常', ['task_id' => $task->task_id, 'error' => $e->getMessage()]);
|
|
|
+ dLog('generate')->error('GPT-Image2 API请求失败: ' . $e->getMessage(), [
|
|
|
+ 'task_id' => $task->task_id,
|
|
|
+ 'trace' => $e->getTraceAsString()
|
|
|
+ ]);
|
|
|
+ logDB('generate', 'error', 'GPT-Image2任务异常', [
|
|
|
+ 'task_id' => $task->task_id,
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
+ 'file' => $e->getFile(),
|
|
|
+ 'line' => $e->getLine()
|
|
|
+ ]);
|
|
|
$task->updateStatus(MpGeneratePicTask::STATUS_FAILED, [
|
|
|
'error_message' => 'API请求失败: ' . $e->getMessage()
|
|
|
]);
|