Sfoglia il codice sorgente

完善三视图生成接口

lh 2 mesi fa
parent
commit
0d6c923765

+ 4 - 0
app/Http/Controllers/Anime/AnimeController.php

@@ -2280,6 +2280,10 @@ class AnimeController extends BaseController
 
     // 生成三视图
     public function generateThreeView(Request $request) {
+        // 忽略所有超时限制
+        set_time_limit(0);
+        ini_set('max_execution_time', '0');
+
         $data = $request->all();
         $result = $this->AnimeService->generateThreeView($data);
         return $this->success($result);

+ 83 - 48
app/Services/Anime/AnimeService.php

@@ -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)