|
|
@@ -6474,21 +6474,26 @@ class AnimeService
|
|
|
if (!$id) Utils::throwError('20003:ID不能为空');
|
|
|
|
|
|
// 检查是否存在且属于当前用户
|
|
|
- $role = DB::table('mp_products')
|
|
|
+ $product = DB::table('mp_products')
|
|
|
->where('id', $id)
|
|
|
->where('cpid', $cpid)
|
|
|
->where('type', 1)->first();
|
|
|
- if (!$role) Utils::throwError('20003:记录不存在');
|
|
|
+ if (!$product) Utils::throwError('20003:资产不存在');
|
|
|
|
|
|
$prompt = trim(getProp($data, 'prompt', '基于参考图生成主体的标准正面、侧面、后面三视图,主体完整。在最左侧添加主体正视图的特写,主体清晰完整。背景修改成纯白色,整体保持与参考图一致的美术风格和色彩搭配。画面无说明文字'));
|
|
|
$ref_img_url = trim(getProp($data, 'ref_img_url'));
|
|
|
if (!$ref_img_url) {
|
|
|
// 如果没有传入参考图,使用角色表中的图片
|
|
|
- $ref_img_url = $role->url ?? '';
|
|
|
+ $ref_img_url = $product->url ?? '';
|
|
|
if (!$ref_img_url) {
|
|
|
Utils::throwError('20003:参考图不能为空');
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ $pic_prompt = getProp($product, 'pic_prompt');
|
|
|
+ if ($pic_prompt) {
|
|
|
+ $prompt .= '\n参考图原始提示词: '.$pic_prompt;
|
|
|
+ }
|
|
|
|
|
|
// 检查参考图是否是正确的图片格式
|
|
|
$allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'];
|
|
|
@@ -6509,6 +6514,56 @@ class AnimeService
|
|
|
if (!DB::table('mp_image_models')->where('model', $model)->where('is_enabled', 1)->exists()) {
|
|
|
Utils::throwError('20003:该模型已不可用,请更换!');
|
|
|
}
|
|
|
+ $ratio = getProp($data, 'ratio', '16:9');
|
|
|
+ $resolution = getProp($data, 'resolution', '2k');
|
|
|
+
|
|
|
+ // 定义分辨率和宽高比对应的尺寸映射表
|
|
|
+ $sizeMap = [
|
|
|
+ '2k' => [
|
|
|
+ '1:1' => ['width' => 2048, 'height' => 2048],
|
|
|
+ '4:3' => ['width' => 2304, 'height' => 1728],
|
|
|
+ '3:4' => ['width' => 1728, 'height' => 2304],
|
|
|
+ '16:9' => ['width' => 2848, 'height' => 1600],
|
|
|
+ '9:16' => ['width' => 1600, 'height' => 2848],
|
|
|
+ '3:2' => ['width' => 2496, 'height' => 1664],
|
|
|
+ '2:3' => ['width' => 1664, 'height' => 2496],
|
|
|
+ '21:9' => ['width' => 3136, 'height' => 1344],
|
|
|
+ ],
|
|
|
+ '3k' => [
|
|
|
+ '1:1' => ['width' => 3072, 'height' => 3072],
|
|
|
+ '4:3' => ['width' => 3456, 'height' => 2592],
|
|
|
+ '3:4' => ['width' => 2592, 'height' => 3456],
|
|
|
+ '16:9' => ['width' => 4096, 'height' => 2304],
|
|
|
+ '9:16' => ['width' => 2304, 'height' => 4096],
|
|
|
+ '2:3' => ['width' => 2496, 'height' => 3744],
|
|
|
+ '3:2' => ['width' => 3744, 'height' => 2496],
|
|
|
+ '21:9' => ['width' => 4704, 'height' => 2016],
|
|
|
+ ],
|
|
|
+ '4k' => [
|
|
|
+ '1:1' => ['width' => 4096, 'height' => 4096],
|
|
|
+ '3:4' => ['width' => 3520, 'height' => 4704],
|
|
|
+ '4:3' => ['width' => 4704, 'height' => 3520],
|
|
|
+ '16:9' => ['width' => 5504, 'height' => 3040],
|
|
|
+ '9:16' => ['width' => 3040, 'height' => 5504],
|
|
|
+ '2:3' => ['width' => 3328, 'height' => 4992],
|
|
|
+ '3:2' => ['width' => 4992, 'height' => 3328],
|
|
|
+ '21:9' => ['width' => 6240, 'height' => 2656],
|
|
|
+ ],
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 参数验证
|
|
|
+ $resolution = strtolower($resolution);
|
|
|
+ if (!isset($sizeMap[$resolution])) {
|
|
|
+ Utils::throwError('20003:分辨率参数错误,仅支持 2k、3k、4k');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!isset($sizeMap[$resolution][$ratio])) {
|
|
|
+ Utils::throwError('20003:宽高比参数错误,该分辨率下不支持 ' . $ratio . ' 比例');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据 ratio 和 resolution 确定宽高
|
|
|
+ $width = $sizeMap[$resolution][$ratio]['width'];
|
|
|
+ $height = $sizeMap[$resolution][$ratio]['height'];
|
|
|
|
|
|
try {
|
|
|
// 创建图片生成任务
|
|
|
@@ -6516,8 +6571,8 @@ class AnimeService
|
|
|
'prompt' => $prompt,
|
|
|
'model' => $model,
|
|
|
'ref_img_urls' => [$ref_img_url],
|
|
|
- 'width' => 1600,
|
|
|
- 'height' => 2848
|
|
|
+ 'width' => $width,
|
|
|
+ 'height' => $height
|
|
|
];
|
|
|
|
|
|
$task = $this->aiImageGenerationService->createImageGenerationTask($params);
|
|
|
@@ -6526,62 +6581,42 @@ class AnimeService
|
|
|
if (!$task_id) {
|
|
|
Utils::throwError('20003:创建图片生成任务失败');
|
|
|
}
|
|
|
-
|
|
|
- // 检查任务模型类型
|
|
|
- $isVolcModel = in_array($model, \App\Consts\BaseConst::VOLC_PIC_MODELS);
|
|
|
- $isGptModel = in_array($model, \App\Consts\BaseConst::GPT_IMAGE2_MODELS);
|
|
|
- $isSyncModel = $isVolcModel || $isGptModel;
|
|
|
|
|
|
- // 轮询获取结果(5分钟超时,每3秒查询一次)
|
|
|
+ // 轮询获取结果
|
|
|
+ // 只查询数据库,不调用API,不更新任务表
|
|
|
$start_time = time();
|
|
|
- $timeout = 300; // 5分钟
|
|
|
+ $timeout = 1800;
|
|
|
$img_url = '';
|
|
|
|
|
|
while (time() - $start_time < $timeout) {
|
|
|
- sleep(3);
|
|
|
+ sleep(5);
|
|
|
|
|
|
- // 火山API和GPT-Image2 API是同步返回结果的,直接检查任务状态
|
|
|
- if ($isSyncModel) {
|
|
|
- // 刷新任务状态
|
|
|
- $task = MpGeneratePicTask::where('id', $task_id)->first();
|
|
|
-
|
|
|
- if ($task->status === 'success' && $task->result_url) {
|
|
|
- $result_urls = is_array($task->result_url) ? $task->result_url : json_decode($task->result_url, true);
|
|
|
- $img_url = is_array($result_urls) ? $result_urls[0] : $task->result_url;
|
|
|
- break;
|
|
|
- } elseif ($task->status === 'failed') {
|
|
|
- Utils::throwError('20003:三视图生成失败,' . ($task->error_message ?? '未知错误'));
|
|
|
- }
|
|
|
- } else {
|
|
|
- $task = MpGeneratePicTask::where('id', $task_id)->first();
|
|
|
- $statusInfo = $this->aiImageGenerationService->queryTaskStatus($task);
|
|
|
-
|
|
|
- if ($statusInfo['status'] === 'success') {
|
|
|
- $task->updateStatus('success', [
|
|
|
- 'result_url' => $statusInfo['result_url'],
|
|
|
- 'result_json' => $statusInfo['result_json'] ?? []
|
|
|
- ]);
|
|
|
-
|
|
|
- $img_url = $statusInfo['result_url'][0];
|
|
|
- break;
|
|
|
- } elseif ($statusInfo['status'] === 'failed') {
|
|
|
- $task->updateStatus('failed', [
|
|
|
- 'error_message' => $statusInfo['error_message'],
|
|
|
- 'result_json' => $statusInfo['result_json'] ?? []
|
|
|
- ]);
|
|
|
- dLog('anime')->error('三视图生成失败', [
|
|
|
- 'error' => $statusInfo['error_message'] ?? '未知错误'
|
|
|
- ]);
|
|
|
- Utils::throwError('20003:三视图生成失败,' . ($statusInfo['error_message'] ?? '未知错误'));
|
|
|
- }
|
|
|
+ // 只查询数据库中的任务状态,不调用API,不更新任务表
|
|
|
+ $task = DB::table('mp_generate_pic_tasks')
|
|
|
+ ->where('id', $task_id)
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ if (!$task) {
|
|
|
+ Utils::throwError('20003:任务不存在');
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($task->status === 'success' && $task->result_url) {
|
|
|
+ $result_urls = is_string($task->result_url)
|
|
|
+ ? json_decode($task->result_url, true)
|
|
|
+ : $task->result_url;
|
|
|
+ $img_url = is_array($result_urls) ? $result_urls[0] : $task->result_url;
|
|
|
+ break;
|
|
|
+ } elseif ($task->status === 'failed') {
|
|
|
+ Utils::throwError('20003:三视图生成失败,' . ($task->error_message ?? '未知错误'));
|
|
|
}
|
|
|
+ // 其他状态继续轮询
|
|
|
}
|
|
|
|
|
|
if (empty($img_url)) {
|
|
|
Utils::throwError('20003:三视图生成超时,请稍后重试');
|
|
|
}
|
|
|
|
|
|
- // 保存三视图到 mp_products 表
|
|
|
+ // 更新 mp_products 表(不是任务表)
|
|
|
DB::table('mp_products')
|
|
|
->where('id', $id)
|
|
|
->where('cpid', $cpid)
|