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