lh 2 месяцев назад
Родитель
Сommit
baf2422288
2 измененных файлов с 94 добавлено и 158 удалено
  1. 14 0
      app/Consts/BaseConst.php
  2. 80 158
      app/Services/Anime/AnimeService.php

+ 14 - 0
app/Consts/BaseConst.php

@@ -92,4 +92,18 @@ class BaseConst
         'doubao-seedream-4-5-251128'        => 'ep-20260422092419-6lvp9',
         'doubao-seedance-1-5-pro-251215'    => 'ep-20260422091940-g4knb'
     ];
+
+    /**
+     * 画面比例配置
+     */
+    const IMAGE_RATIOS = [
+        '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],
+    ];
 }

+ 80 - 158
app/Services/Anime/AnimeService.php

@@ -2,6 +2,7 @@
 
 namespace App\Services\Anime;
 
+use App\Consts\BaseConst;
 use App\Consts\ErrorConst;
 use App\Facade\Site;
 use App\Libs\Utils;
@@ -42,6 +43,29 @@ class AnimeService
         ];
     }
 
+    /**
+     * 验证画面比例是否有效
+     * @param string $ratio 画面比例
+     * @return bool
+     */
+    private function validateRatio($ratio) {
+        return isset(BaseConst::IMAGE_RATIOS[$ratio]);
+    }
+
+    /**
+     * 获取画面比例对应的宽高
+     * @param string $ratio 画面比例
+     * @return array ['width' => int, 'height' => int]
+     * @throws \Exception
+     */
+    private function getRatioDimensions($ratio) {
+        if ($ratio && !$this->validateRatio($ratio)) {
+            $validRatios = implode('、', array_keys(BaseConst::IMAGE_RATIOS));
+            Utils::throwError("1002:画面比例选择不正确,只支持{$validRatios}");
+        }
+        return isset(BaseConst::IMAGE_RATIOS[$ratio]) ? BaseConst::IMAGE_RATIOS[$ratio] : ['width' => 2048, 'height' => 2048];
+    }
+
     public function createAnime($data) {
         $uid = Site::getUid();
         $input_art_style = getProp($data, 'art_style');
@@ -753,37 +777,18 @@ class AnimeService
             $prompt = getProp($segment, 'segment_content');
         }
 
-        $ratio = getProp($data, 'ratio');
-        if (!in_array($ratio, ['1:1', '4:3', '3:2', '16:9', '21:9'])) {
-            Utils::throwError('1002:画面比例选择不正确');
-        }
+        $anime_id = getProp($segment, 'anime_id');
+        $episode_id = getProp($segment, 'episode_id');
+        $episode_number = getProp($segment, 'episode_number');
 
-        // 根据画面比例给宽高赋值
-        switch ($ratio) {
-            case '1:1':
-                $width = 2048;
-                $height = 2048;
-                break;
-            case '4:3':
-                $width = 2304;
-                $height = 1728;
-                break;
-            case '3:2':
-                $width = 2496;
-                $height = 1664;
-                break;
-            case '16:9':
-                $width = 2560;
-                $height = 1440;
-                break;
-            case '21:9':
-                $width = 3024;
-                $height = 1296;
-                break;
-            default:
-                $width = 2048;
-                $height = 2048;
+        $ratio = getProp($data, 'ratio');
+        if (!$ratio) {
+            $ratio = DB::table('mp_anime_episodes')->where('id', $episode_id)->value('ratio');
+            if (!$ratio) $ratio = '1:1';
         }
+        $dimensions = $this->getRatioDimensions($ratio);
+        $width = $dimensions['width'];
+        $height = $dimensions['height'];
 
         try {
             $params = [
@@ -819,48 +824,39 @@ class AnimeService
             $uid = Site::getUid();
             $now = date('Y-m-d H:i:s');
             
-            // 获取segment的anime_id和episode_number
-            $segmentInfo = DB::table('mp_episode_segments as es')
-                ->join('mp_anime_episodes as ae', 'es.episode_id', '=', 'ae.id')
-                ->where('es.segment_id', $segment_id)
-                ->select('ae.anime_id', 'ae.episode_number')
-                ->first();
             
-            if ($segmentInfo) {
-                $anime_id = getProp($segmentInfo, 'anime_id');
-                $episode_number = getProp($segmentInfo, 'episode_number');
-                
-                // 使用AI反推图片提示词
-                $pic_prompt = $this->generateImagePromptFromUrl($img_url);
-                
-                // 保存对话记录
-                $records = [
-                    [
-                        'uid'           => $uid,
-                        'anime_id'      => $anime_id,
-                        'sequence'      => $episode_number,
-                        'role'          => 'user',
-                        'content'       => $prompt,
-                        'segment_id'    => $segment_id,
-                        'image_url'     => '',
-                        'created_at'    => $now,
-                        'updated_at'    => $now
-                    ],
-                    [
-                        'uid'           => $uid,
-                        'anime_id'      => $anime_id,
-                        'sequence'      => $episode_number,
-                        'role'          => 'assistant',
-                        'content'       => $pic_prompt,
-                        'segment_id'    => $segment_id,
-                        'image_url'     => $img_url,
-                        'created_at'    => $now,
-                        'updated_at'    => $now
-                    ]
-                ];
+            
+            // 使用AI反推图片提示词
+            $pic_prompt = $this->generateImagePromptFromUrl($img_url);
                 
-                DB::table('mp_anime_records')->insert($records);
-            }
+            // 保存对话记录
+            $records = [
+                [
+                    'uid'           => $uid,
+                    'anime_id'      => $anime_id,
+                    'sequence'      => $episode_number,
+                    'role'          => 'user',
+                    'content'       => $prompt,
+                    'segment_id'    => $segment_id,
+                    'image_url'     => '',
+                    'created_at'    => $now,
+                    'updated_at'    => $now
+                ],
+                [
+                    'uid'           => $uid,
+                    'anime_id'      => $anime_id,
+                    'sequence'      => $episode_number,
+                    'role'          => 'assistant',
+                    'content'       => $pic_prompt,
+                    'segment_id'    => $segment_id,
+                    'image_url'     => $img_url,
+                    'created_at'    => $now,
+                    'updated_at'    => $now
+                ]
+            ];
+            
+            DB::table('mp_anime_records')->insert($records);
+            
         } catch (\Exception $e) {
             // 记录日志但不影响主流程
             dLog('anime')->error('保存对话记录失败: ' . $e->getMessage(), [
@@ -1151,9 +1147,9 @@ class AnimeService
         $anime_id = getProp($data, 'anime_id');
         $episode_id = getProp($data, 'episode_id');
         $ratio = getProp($data, 'ratio');
-        if (!in_array($ratio, ['1:1', '4:3', '3:2', '16:9', '21:9'])) {
-            Utils::throwError('1002:画面比例选择不正确,只支持1:1、4:3、3:2、16:9、21:9');
-        }
+        $dimensions = $this->getRatioDimensions($ratio);
+        $width = $dimensions['width'];
+        $height = $dimensions['height'];
         
         if (!$anime_id || !$episode_id) {
             Utils::throwError('1002:请选择剧集');
@@ -1171,33 +1167,6 @@ class AnimeService
             Utils::throwError('20003:该剧集不存在');
         }
 
-        // 根据画面比例给宽高赋值
-        switch ($ratio) {
-            case '1:1':
-                $width = 2048;
-                $height = 2048;
-                break;
-            case '4:3':
-                $width = 2304;
-                $height = 1728;
-                break;
-            case '3:2':
-                $width = 2496;
-                $height = 1664;
-                break;
-            case '16:9':
-                $width = 2560;
-                $height = 1440;
-                break;
-            case '21:9':
-                $width = 3024;
-                $height = 1296;
-                break;
-            default:
-                $width = 2048;
-                $height = 2048;
-        }
-
         // 获取动漫的角色信息(包含参考图)
         $anime = DB::table('mp_animes')
             ->where('id', $anime_id)
@@ -1253,6 +1222,9 @@ class AnimeService
             Utils::throwError('20003:所有分镜图片已完成或正在生成中');
         }
 
+        // 保存图片比例
+        DB::table('mp_anime_episodes')->where('id', $episode_id)->update(['ratio' => $ratio, 'updated_at' => date('Y-m-d H:i:s')]);
+
         $updated_segments = [];
         $failed_segments = [];
 
@@ -1437,9 +1409,13 @@ class AnimeService
         $episode_number = getProp($segment, 'episode_number');
         $segment_content = getProp($data, 'segment_content');
         $ratio = getProp($data, 'ratio');
-        if (!in_array($ratio, ['1:1', '4:3', '3:2', '16:9', '21:9'])) {
-            Utils::throwError('1002:画面比例选择不正确');
+        if (!$ratio) {
+            $ratio = DB::table('mp_anime_episodes')->where('id', $episode_id)->value('ratio');
+            if (!$ratio) $ratio = '1:1';
         }
+        $dimensions = $this->getRatioDimensions($ratio);
+        $width = $dimensions['width'];
+        $height = $dimensions['height'];
         
         if (!$anime_id || !$episode_id) {
             Utils::throwError('1002:请选择分镜');
@@ -1450,33 +1426,6 @@ class AnimeService
             $segment_content = $this->parseSegmentContentWithAI($segment_content);
         }
 
-        // 根据画面比例给宽高赋值
-        switch ($ratio) {
-            case '1:1':
-                $width = 2048;
-                $height = 2048;
-                break;
-            case '4:3':
-                $width = 2304;
-                $height = 1728;
-                break;
-            case '3:2':
-                $width = 2496;
-                $height = 1664;
-                break;
-            case '16:9':
-                $width = 2560;
-                $height = 1440;
-                break;
-            case '21:9':
-                $width = 3024;
-                $height = 1296;
-                break;
-            default:
-                $width = 2048;
-                $height = 2048;
-        }
-
         // 获取动漫的角色信息(包含参考图)
         $anime = DB::table('mp_animes')
             ->where('id', $anime_id)
@@ -1764,9 +1713,9 @@ class AnimeService
         $img_url = getProp($data, 'img_url');
         $video_url = getProp($data, 'video_url');
         $ratio = getProp($data, 'ratio');
-        if (!in_array($ratio, ['1:1', '4:3', '3:2', '16:9', '21:9'])) {
-            Utils::throwError('1002:画面比例选择不正确');
-        }
+        $dimensions = $this->getRatioDimensions($ratio);
+        $width = $dimensions['width'];
+        $height = $dimensions['height'];
         
         if (!$anime_id || !$episode_id) {
             Utils::throwError('1002:请选择分镜');
@@ -1777,33 +1726,6 @@ class AnimeService
             $segment_content = $this->parseSegmentContentWithAI($segment_content);
         }
 
-        // 根据画面比例给宽高赋值
-        switch ($ratio) {
-            case '1:1':
-                $width = 2048;
-                $height = 2048;
-                break;
-            case '4:3':
-                $width = 2304;
-                $height = 1728;
-                break;
-            case '3:2':
-                $width = 2496;
-                $height = 1664;
-                break;
-            case '16:9':
-                $width = 2560;
-                $height = 1440;
-                break;
-            case '21:9':
-                $width = 3024;
-                $height = 1296;
-                break;
-            default:
-                $width = 2048;
-                $height = 2048;
-        }
-
         // 获取动漫的角色信息(包含参考图)
         $anime = DB::table('mp_animes')
             ->where('id', $anime_id)