lh 2 miesięcy temu
rodzic
commit
4cda400ec5
1 zmienionych plików z 177 dodań i 0 usunięć
  1. 177 0
      app/Services/Anime/AnimeService.php

+ 177 - 0
app/Services/Anime/AnimeService.php

@@ -2480,6 +2480,9 @@ class AnimeService
             $table_name = 'mp_anime_episodes';
             $id_field = 'id';
             $id_value = $episode_id;
+            
+            // 获取剧集的anime_id用于继承全局数据
+            $anime_id = getProp($source, 'anime_id');
         } else {
             // 从动漫表获取
             $source = DB::table('mp_animes')->where('id', $anime_id)->where('is_deleted', 0)->first();
@@ -2492,6 +2495,11 @@ class AnimeService
         $source = (array)$source;
         $roles = json_decode(getProp($source, 'roles', '[]'), true) ?: [];
         $scenes = json_decode(getProp($source, 'scenes', '[]'), true) ?: [];
+        
+        // 如果是分集数据,需要处理继承和任务创建逻辑
+        if ($episode_id) {
+            $this->processEpisodeRolesAndScenes($episode_id, $anime_id, $roles, $scenes, $source);
+        }
 
         // 返回生成器函数,用于 SSE 流式输出
         return function() use ($roles, $scenes, $table_name, $id_field, $id_value) {
@@ -3809,6 +3817,175 @@ class AnimeService
     }
 
     /**
+     * 处理分集的角色和场景数据(继承全局数据或创建新任务)
+     * 
+     * @param int $episode_id 分集ID
+     * @param int $anime_id 动漫ID
+     * @param array $roles 分集角色数组(引用传递)
+     * @param array $scenes 分集场景数组(引用传递)
+     * @param array $episode 分集数据
+     */
+    private function processEpisodeRolesAndScenes($episode_id, $anime_id, &$roles, &$scenes, $episode) {
+        // 获取全局动漫的角色和场景数据
+        $anime = DB::table('mp_animes')->where('id', $anime_id)->first();
+        if (!$anime) return;
+        
+        $global_roles = json_decode(getProp($anime, 'roles'), true) ?: [];
+        $global_scenes = json_decode(getProp($anime, 'scenes'), true) ?: [];
+        
+        $roles_updated = false;
+        $scenes_updated = false;
+        
+        // 处理角色
+        foreach ($roles as &$role) {
+            $role_name = getProp($role, 'role');
+            $role_description = getProp($role, 'description');
+            $role_url = getProp($role, 'url');
+            $role_task_id = getProp($role, 'task_id');
+            
+            // 如果已有URL或已有任务ID,跳过
+            if (!empty($role_url) || !empty($role_task_id) || $role_name === '旁白') {
+                continue;
+            }
+            
+            $url_inherited = false;
+            
+            // 尝试从全局数据中继承
+            foreach ($global_roles as $global_role) {
+                $global_role_name = getProp($global_role, 'role');
+                $global_role_description = getProp($global_role, 'description');
+                $global_role_url = getProp($global_role, 'url');
+                $global_role_task_id = getProp($global_role, 'task_id');
+                $global_role_task_status = getProp($global_role, 'task_status');
+                
+                // 满足条件:角色名相同、描述相同、全局有URL
+                if ($role_name === $global_role_name 
+                    && $role_description === $global_role_description 
+                    && !empty($global_role_url)) {
+                    // 继承 task_id、task_status 和 url
+                    $role['task_id'] = $global_role_task_id;
+                    $role['task_status'] = $global_role_task_status;
+                    $role['url'] = $global_role_url;
+                    $roles_updated = true;
+                    $url_inherited = true;
+                    dLog('anime')->info("分集ID:{$episode_id} 角色:{$role_name} 继承全局数据");
+                    break;
+                }
+            }
+            
+            // 如果无法继承且没有任务ID,创建新任务
+            if (!$url_inherited && empty($role_task_id)) {
+                try {
+                    $art_style = getProp($episode, 'art_style');
+                    $description = $role_description;
+                    if ($art_style) {
+                        $description = "美术风格:\n{$art_style}\n主体描述:{$description}\n图片要求:图片侧重点在于主体人物信息,需要突出人物形象,不显示场景或背景信息";
+                    }
+                    
+                    $params = [
+                        'prompt' => $description,
+                        'ref_img_urls' => []
+                    ];
+                    
+                    $task = $this->aiImageGenerationService->createImageGenerationTask($params);
+                    $task_id = $task->id;
+                    
+                    if ($task_id) {
+                        $role['task_id'] = $task_id;
+                        $role['task_status'] = 'processing';
+                        $roles_updated = true;
+                        dLog('anime')->info("分集ID:{$episode_id} 角色:{$role_name} 创建图片生成任务,任务ID:{$task_id}");
+                    }
+                } catch (\Exception $e) {
+                    dLog('anime')->error("分集ID:{$episode_id} 角色:{$role_name} 创建图片生成任务失败: " . $e->getMessage());
+                }
+            }
+        }
+        
+        // 处理场景
+        foreach ($scenes as &$scene) {
+            $scene_name = getProp($scene, 'scene');
+            $scene_description = getProp($scene, 'description');
+            $scene_url = getProp($scene, 'url');
+            $scene_task_id = getProp($scene, 'task_id');
+            
+            // 如果已有URL或已有任务ID,跳过
+            if (!empty($scene_url) || !empty($scene_task_id)) {
+                continue;
+            }
+            
+            $url_inherited = false;
+            
+            // 尝试从全局数据中继承
+            foreach ($global_scenes as $global_scene) {
+                $global_scene_name = getProp($global_scene, 'scene');
+                $global_scene_description = getProp($global_scene, 'description');
+                $global_scene_url = getProp($global_scene, 'url');
+                $global_scene_task_id = getProp($global_scene, 'task_id');
+                $global_scene_task_status = getProp($global_scene, 'task_status');
+                
+                // 满足条件:场景名相同、描述相同、全局有URL
+                if ($scene_name === $global_scene_name 
+                    && $scene_description === $global_scene_description 
+                    && !empty($global_scene_url)) {
+                    // 继承 task_id、task_status 和 url
+                    $scene['task_id'] = $global_scene_task_id;
+                    $scene['task_status'] = $global_scene_task_status;
+                    $scene['url'] = $global_scene_url;
+                    $scenes_updated = true;
+                    $url_inherited = true;
+                    dLog('anime')->info("分集ID:{$episode_id} 场景:{$scene_name} 继承全局数据");
+                    break;
+                }
+            }
+            
+            // 如果无法继承且没有任务ID,创建新任务
+            if (!$url_inherited && empty($scene_task_id)) {
+                try {
+                    $art_style = getProp($episode, 'art_style');
+                    $description = $scene_description;
+                    if ($art_style) {
+                        $description = "美术风格:\n{$art_style}\n场景描述:{$description}\n图片要求: 图片侧重点是场景,生成的是场景环境图片,不要出现人物";
+                    }
+                    
+                    $params = [
+                        'prompt' => $description,
+                        'ref_img_urls' => []
+                    ];
+                    
+                    $task = $this->aiImageGenerationService->createImageGenerationTask($params);
+                    $task_id = $task->id;
+                    
+                    if ($task_id) {
+                        $scene['task_id'] = $task_id;
+                        $scene['task_status'] = 'processing';
+                        $scenes_updated = true;
+                        dLog('anime')->info("分集ID:{$episode_id} 场景:{$scene_name} 创建图片生成任务,任务ID:{$task_id}");
+                    }
+                } catch (\Exception $e) {
+                    dLog('anime')->error("分集ID:{$episode_id} 场景:{$scene_name} 创建图片生成任务失败: " . $e->getMessage());
+                }
+            }
+        }
+        
+        // 如果有更新,保存到数据库
+        if ($roles_updated || $scenes_updated) {
+            $update_data = ['updated_at' => date('Y-m-d H:i:s')];
+            
+            if ($roles_updated) {
+                $update_data['roles'] = json_encode($roles, JSON_UNESCAPED_UNICODE);
+            }
+            
+            if ($scenes_updated) {
+                $update_data['scenes'] = json_encode($scenes, JSON_UNESCAPED_UNICODE);
+            }
+            
+            DB::table('mp_anime_episodes')->where('id', $episode_id)->update($update_data);
+            dLog('anime')->info("分集ID:{$episode_id} 角色和场景数据已更新");
+        }
+    }
+
+    /**
      * 根据图片URL使用AI反推图片提示词
      * 
      * @param string $img_url 图片URL