ソースを参照

优化片段确认分镜接口的逻辑执行顺序

lh 1 週間 前
コミット
00ffb2909e
1 ファイル変更95 行追加111 行削除
  1. 95 111
      app/Services/Anime/AnimeService.php

+ 95 - 111
app/Services/Anime/AnimeService.php

@@ -9863,117 +9863,8 @@ class AnimeService
         // 获取所有片段数据
         $acts = DB::table('mp_episode_segments')->where('episode_id', $episode_id)->orderBy('act_number')->get();
         
-        // 收集所有资产名称(角色、场景、道具)
-        $product_names = [];
-        
-        // 收集角色名称
-        foreach ($roles as $role) {
-            $role_name = getProp($role, 'role');
-            if ($role_name && $role_name != '旁白') {
-                $product_names[] = $role_name;
-            }
-        }
-        
-        // 收集场景名称
-        foreach ($scenes as $scene) {
-            $scene_name = getProp($scene, 'scene');
-            if ($scene_name) {
-                $product_names[] = $scene_name;
-            }
-        }
-        
-        // 收集道具名称
-        foreach ($props as $prop) {
-            $prop_name = getProp($prop, 'prop');
-            if ($prop_name) {
-                $product_names[] = $prop_name;
-            }
-        }
-        
-        // 去重并按长度降序排序(避免短名称先匹配到长名称的一部分)
-        $product_names = array_unique($product_names);
-        usort($product_names, function($a, $b) {
-            return mb_strlen($b) - mb_strlen($a);
-        });
-
-        try {
-            DB::beginTransaction();
-            // 处理每个片段
-            foreach ($acts as $act) {
-                $act_content = getProp($act, 'act_content');
-                if (!$act_content) continue;
-                
-                $processed_content = $act_content;
-                
-                // 统一替换所有资产名称为 {资产名} 格式
-                // 使用占位符避免嵌套替换问题
-                $placeholder_map = [];
-                $placeholder_index = 0;
-                
-                foreach ($product_names as $product_name) {
-                    // 转义特殊字符
-                    $escaped_product = preg_quote($product_name, '/');
-                    
-                    // 检查是否匹配且未被 {} 包裹
-                    $processed_content = preg_replace_callback(
-                        '/(?<![{])(' . $escaped_product . ')(?![}])/u',
-                        function($matches) use (&$placeholder_map, &$placeholder_index) {
-                            // 使用唯一占位符
-                            $placeholder = '<<<PLACEHOLDER_' . $placeholder_index . '>>>';
-                            $placeholder_map[$placeholder] = '{' . $matches[1] . '}';
-                            $placeholder_index++;
-                            return $placeholder;
-                        },
-                        $processed_content
-                    );
-                }
-                
-                // 将所有占位符替换回实际内容
-                foreach ($placeholder_map as $placeholder => $replacement) {
-                    $processed_content = str_replace($placeholder, $replacement, $processed_content);
-                }
-                
-                // 处理【镜头X】或【分镜X】重新编号为从1开始的连续整数【镜头X】
-                $shot_counter = 0;
-                $processed_content = preg_replace_callback(
-                    '/【(?:镜头|分镜)(\d+)】/u',
-                    function($matches) use (&$shot_counter) {
-                        $shot_counter++;
-                        return '【镜头' . $shot_counter . '】';
-                    },
-                    $processed_content
-                );
-                
-                // 更新数据库
-                $boolen = DB::table('mp_episode_segments')
-                    ->where('id', $act->id)
-                    ->update([
-                        'act_show_content' => $processed_content,
-                        'updated_at' => date('Y-m-d H:i:s')
-                    ]);
-                if (!$boolen) {
-                    Utils::throwError('20003:片段处理失败');
-                }
-            }
-        }catch (\Exception $e) {
-            DB::rollBack();
-            Utils::throwError('20003:'.$e->getMessage());
-        }
-        
-        $boolen1 = DB::table('mp_anime_episodes')->where('id', $episode_id)->update([
-            'is_generated'  => 1,
-            'updated_at'    => date('Y-m-d H:i:s')
-        ]);
-        if (!$boolen1) {
-            DB::rollBack();
-            Utils::throwError('20003:分集处理失败!');
-        }
-
-        DB::commit();
-
-        // 重新查询更新后的片段数据
-        $acts = DB::table('mp_episode_segments')->where('episode_id', $episode_id)->orderBy('act_number')->get();
-
+        // 先构建完整的 products(角色、场景、道具、extra_products,并用资产库映射覆盖),
+        // 再处理每个片段的 act_content,避免 extra_products 等资产名未被格式化为 {资产名}
         // 合并角色、场景、道具和extra_products作为products,统一字段名为product_name
         // extra_products优先级更高,会覆盖同名的roles、scenes和props
         $products = [];
@@ -10094,6 +9985,99 @@ class AnimeService
         // 重新索引数组(去除key)
         $products = array_values($products);
         
+        // 基于构建完成的 products 收集所有资产名称(含 extra_products 中的资产)
+        $product_names = [];
+        foreach ($products as $product) {
+            $product_name = getProp($product, 'product_name');
+            if ($product_name && $product_name !== '旁白') {
+                $product_names[] = $product_name;
+            }
+        }
+        
+        // 去重并按长度降序排序(避免短名称先匹配到长名称的一部分)
+        $product_names = array_unique($product_names);
+        usort($product_names, function($a, $b) {
+            return mb_strlen($b) - mb_strlen($a);
+        });
+
+        try {
+            DB::beginTransaction();
+            // 处理每个片段
+            foreach ($acts as $act) {
+                $act_content = getProp($act, 'act_content');
+                if (!$act_content) continue;
+                
+                $processed_content = $act_content;
+                
+                // 统一替换所有资产名称为 {资产名} 格式
+                // 使用占位符避免嵌套替换问题
+                $placeholder_map = [];
+                $placeholder_index = 0;
+                
+                foreach ($product_names as $product_name) {
+                    // 转义特殊字符
+                    $escaped_product = preg_quote($product_name, '/');
+                    
+                    // 检查是否匹配且未被 {} 包裹
+                    $processed_content = preg_replace_callback(
+                        '/(?<![{])(' . $escaped_product . ')(?![}])/u',
+                        function($matches) use (&$placeholder_map, &$placeholder_index) {
+                            // 使用唯一占位符
+                            $placeholder = '<<<PLACEHOLDER_' . $placeholder_index . '>>>';
+                            $placeholder_map[$placeholder] = '{' . $matches[1] . '}';
+                            $placeholder_index++;
+                            return $placeholder;
+                        },
+                        $processed_content
+                    );
+                }
+                
+                // 将所有占位符替换回实际内容
+                foreach ($placeholder_map as $placeholder => $replacement) {
+                    $processed_content = str_replace($placeholder, $replacement, $processed_content);
+                }
+                
+                // 处理【镜头X】或【分镜X】重新编号为从1开始的连续整数【镜头X】
+                $shot_counter = 0;
+                $processed_content = preg_replace_callback(
+                    '/【(?:镜头|分镜)(\d+)】/u',
+                    function($matches) use (&$shot_counter) {
+                        $shot_counter++;
+                        return '【镜头' . $shot_counter . '】';
+                    },
+                    $processed_content
+                );
+                
+                // 更新数据库
+                $boolen = DB::table('mp_episode_segments')
+                    ->where('id', $act->id)
+                    ->update([
+                        'act_show_content' => $processed_content,
+                        'updated_at' => date('Y-m-d H:i:s')
+                    ]);
+                if (!$boolen) {
+                    Utils::throwError('20003:片段处理失败');
+                }
+            }
+        }catch (\Exception $e) {
+            DB::rollBack();
+            Utils::throwError('20003:'.$e->getMessage());
+        }
+        
+        $boolen1 = DB::table('mp_anime_episodes')->where('id', $episode_id)->update([
+            'is_generated'  => 1,
+            'updated_at'    => date('Y-m-d H:i:s')
+        ]);
+        if (!$boolen1) {
+            DB::rollBack();
+            Utils::throwError('20003:分集处理失败!');
+        }
+
+        DB::commit();
+
+        // 重新查询更新后的片段数据
+        $acts = DB::table('mp_episode_segments')->where('episode_id', $episode_id)->orderBy('act_number')->get();
+
         // 构建返回的acts数组
         $return_acts = [];
         foreach ($acts as $act) {