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