|
@@ -8370,13 +8370,15 @@ class AnimeService
|
|
|
}
|
|
}
|
|
|
$roles = json_decode(getProp($episode, 'roles'), true) ?: [];
|
|
$roles = json_decode(getProp($episode, 'roles'), true) ?: [];
|
|
|
$scenes = json_decode(getProp($episode, 'scenes'), true) ?: [];
|
|
$scenes = json_decode(getProp($episode, 'scenes'), true) ?: [];
|
|
|
|
|
+ $props = json_decode(getProp($episode, 'props'), true) ?: [];
|
|
|
|
|
|
|
|
// 获取所有片段数据
|
|
// 获取所有片段数据
|
|
|
$acts = DB::table('mp_episode_segments')->where('episode_id', $episode_id)->orderBy('act_number')->get();
|
|
$acts = DB::table('mp_episode_segments')->where('episode_id', $episode_id)->orderBy('act_number')->get();
|
|
|
|
|
|
|
|
- // 构建角色和场景名称数组
|
|
|
|
|
|
|
+ // 构建角色、场景和道具名称数组
|
|
|
$role_names = [];
|
|
$role_names = [];
|
|
|
$scene_names = [];
|
|
$scene_names = [];
|
|
|
|
|
+ $prop_names = [];
|
|
|
|
|
|
|
|
foreach ($roles as $role) {
|
|
foreach ($roles as $role) {
|
|
|
$role_name = getProp($role, 'role');
|
|
$role_name = getProp($role, 'role');
|
|
@@ -8392,6 +8394,13 @@ class AnimeService
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ foreach ($props as $prop) {
|
|
|
|
|
+ $prop_name = getProp($prop, 'prop');
|
|
|
|
|
+ if ($prop_name) {
|
|
|
|
|
+ $prop_names[] = $prop_name;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 按照字符长度降序排序,确保先匹配长的名称(避免部分匹配问题)
|
|
// 按照字符长度降序排序,确保先匹配长的名称(避免部分匹配问题)
|
|
|
usort($role_names, function($a, $b) {
|
|
usort($role_names, function($a, $b) {
|
|
|
return mb_strlen($b) - mb_strlen($a);
|
|
return mb_strlen($b) - mb_strlen($a);
|
|
@@ -8399,6 +8408,9 @@ class AnimeService
|
|
|
usort($scene_names, function($a, $b) {
|
|
usort($scene_names, function($a, $b) {
|
|
|
return mb_strlen($b) - mb_strlen($a);
|
|
return mb_strlen($b) - mb_strlen($a);
|
|
|
});
|
|
});
|
|
|
|
|
+ usort($prop_names, function($a, $b) {
|
|
|
|
|
+ return mb_strlen($b) - mb_strlen($a);
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
DB::beginTransaction();
|
|
DB::beginTransaction();
|
|
@@ -8432,12 +8444,32 @@ class AnimeService
|
|
|
}, $processed_content);
|
|
}, $processed_content);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 再匹配角色名称(只在"画面:"部分)
|
|
|
|
|
|
|
+ // 匹配道具(在"道具:"后面,逻辑与场景一致)
|
|
|
|
|
+ foreach ($prop_names as $prop_name) {
|
|
|
|
|
+ // 转义特殊字符
|
|
|
|
|
+ $escaped_prop = preg_quote($prop_name, '/');
|
|
|
|
|
+ // 匹配道具:后面的道具名称(可能换行,也可能不换行)
|
|
|
|
|
+ $pattern = '/(道具:[\s\r\n]*)(' . $escaped_prop . ')/u';
|
|
|
|
|
+
|
|
|
|
|
+ $processed_content = preg_replace_callback($pattern, function($matches) use (&$marked_positions) {
|
|
|
|
|
+ $full_match = $matches[0];
|
|
|
|
|
+ $prefix = $matches[1];
|
|
|
|
|
+ $prop_name = $matches[2];
|
|
|
|
|
+
|
|
|
|
|
+ // 检查是否已经被标记
|
|
|
|
|
+ if (strpos($prop_name, '{') === false && strpos($prop_name, '}') === false) {
|
|
|
|
|
+ return $prefix . '{' . $prop_name . '}';
|
|
|
|
|
+ }
|
|
|
|
|
+ return $full_match;
|
|
|
|
|
+ }, $processed_content);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 再匹配角色名称(在"画面:"部分和"角色:"部分)
|
|
|
foreach ($role_names as $role_name) {
|
|
foreach ($role_names as $role_name) {
|
|
|
// 转义特殊字符
|
|
// 转义特殊字符
|
|
|
$escaped_role = preg_quote($role_name, '/');
|
|
$escaped_role = preg_quote($role_name, '/');
|
|
|
|
|
|
|
|
- // 只匹配"画面:"开始到换行之前的内容
|
|
|
|
|
|
|
+ // 1. 匹配"画面:"开始到换行之前的内容
|
|
|
$pattern = '/(画面:[^\n]*)/u';
|
|
$pattern = '/(画面:[^\n]*)/u';
|
|
|
$processed_content = preg_replace_callback($pattern, function($matches) use ($escaped_role) {
|
|
$processed_content = preg_replace_callback($pattern, function($matches) use ($escaped_role) {
|
|
|
$line = $matches[1]; // 整行"画面:xxxxx"
|
|
$line = $matches[1]; // 整行"画面:xxxxx"
|
|
@@ -8451,6 +8483,84 @@ class AnimeService
|
|
|
|
|
|
|
|
return $new_line;
|
|
return $new_line;
|
|
|
}, $processed_content);
|
|
}, $processed_content);
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 匹配"角色:"或"出场角色:"这一整行内的角色名称
|
|
|
|
|
+ $pattern = '/((?:出场)?角色:[^\n]*)/u';
|
|
|
|
|
+ $processed_content = preg_replace_callback($pattern, function($matches) use ($escaped_role) {
|
|
|
|
|
+ $line = $matches[1]; // 整行"角色:xxxxx"或"出场角色:xxxxx"
|
|
|
|
|
+
|
|
|
|
|
+ // 在这一行中匹配所有角色名(避免重复标记)
|
|
|
|
|
+ $new_line = preg_replace(
|
|
|
|
|
+ '/(?<![{])(' . $escaped_role . ')(?![}])/u',
|
|
|
|
|
+ '{$1}',
|
|
|
|
|
+ $line
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ return $new_line;
|
|
|
|
|
+ }, $processed_content);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 匹配道具名称(在"画面:"部分,逻辑与角色一致)
|
|
|
|
|
+ foreach ($prop_names as $prop_name) {
|
|
|
|
|
+ // 转义特殊字符
|
|
|
|
|
+ $escaped_prop = preg_quote($prop_name, '/');
|
|
|
|
|
+
|
|
|
|
|
+ // 匹配"画面:"开始到换行之前的内容
|
|
|
|
|
+ $pattern = '/(画面:[^\n]*)/u';
|
|
|
|
|
+ $processed_content = preg_replace_callback($pattern, function($matches) use ($escaped_prop) {
|
|
|
|
|
+ $line = $matches[1]; // 整行"画面:xxxxx"
|
|
|
|
|
+
|
|
|
|
|
+ // 在这一行中匹配所有道具名(避免重复标记)
|
|
|
|
|
+ $new_line = preg_replace(
|
|
|
|
|
+ '/(?<![{])(' . $escaped_prop . ')(?![}])/u',
|
|
|
|
|
+ '{$1}',
|
|
|
|
|
+ $line
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ return $new_line;
|
|
|
|
|
+ }, $processed_content);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 匹配角色名称(在"运镜:"部分)
|
|
|
|
|
+ foreach ($role_names as $role_name) {
|
|
|
|
|
+ // 转义特殊字符
|
|
|
|
|
+ $escaped_role = preg_quote($role_name, '/');
|
|
|
|
|
+
|
|
|
|
|
+ // 匹配"运镜:"开始到换行之前的内容
|
|
|
|
|
+ $pattern = '/(运镜:[^\n]*)/u';
|
|
|
|
|
+ $processed_content = preg_replace_callback($pattern, function($matches) use ($escaped_role) {
|
|
|
|
|
+ $line = $matches[1]; // 整行"运镜:xxxxx"
|
|
|
|
|
+
|
|
|
|
|
+ // 在这一行中匹配所有角色名(避免重复标记)
|
|
|
|
|
+ $new_line = preg_replace(
|
|
|
|
|
+ '/(?<![{])(' . $escaped_role . ')(?![}])/u',
|
|
|
|
|
+ '{$1}',
|
|
|
|
|
+ $line
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ return $new_line;
|
|
|
|
|
+ }, $processed_content);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 匹配道具名称(在"运镜:"部分)
|
|
|
|
|
+ foreach ($prop_names as $prop_name) {
|
|
|
|
|
+ // 转义特殊字符
|
|
|
|
|
+ $escaped_prop = preg_quote($prop_name, '/');
|
|
|
|
|
+
|
|
|
|
|
+ // 匹配"运镜:"开始到换行之前的内容
|
|
|
|
|
+ $pattern = '/(运镜:[^\n]*)/u';
|
|
|
|
|
+ $processed_content = preg_replace_callback($pattern, function($matches) use ($escaped_prop) {
|
|
|
|
|
+ $line = $matches[1]; // 整行"运镜:xxxxx"
|
|
|
|
|
+
|
|
|
|
|
+ // 在这一行中匹配所有道具名(避免重复标记)
|
|
|
|
|
+ $new_line = preg_replace(
|
|
|
|
|
+ '/(?<![{])(' . $escaped_prop . ')(?![}])/u',
|
|
|
|
|
+ '{$1}',
|
|
|
|
|
+ $line
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ return $new_line;
|
|
|
|
|
+ }, $processed_content);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 处理【镜头X】或【分镜X】重新编号为从1开始的连续整数【镜头X】
|
|
// 处理【镜头X】或【分镜X】重新编号为从1开始的连续整数【镜头X】
|
|
@@ -8494,8 +8604,8 @@ class AnimeService
|
|
|
// 重新查询更新后的片段数据
|
|
// 重新查询更新后的片段数据
|
|
|
$acts = DB::table('mp_episode_segments')->where('episode_id', $episode_id)->orderBy('act_number')->get();
|
|
$acts = DB::table('mp_episode_segments')->where('episode_id', $episode_id)->orderBy('act_number')->get();
|
|
|
|
|
|
|
|
- // 合并角色、场景和extra_products作为products,统一字段名为product_name
|
|
|
|
|
- // extra_products优先级更高,会覆盖同名的roles和scenes
|
|
|
|
|
|
|
+ // 合并角色、场景、道具和extra_products作为products,统一字段名为product_name
|
|
|
|
|
+ // extra_products优先级更高,会覆盖同名的roles、scenes和props
|
|
|
$products = [];
|
|
$products = [];
|
|
|
|
|
|
|
|
// 先处理角色数组
|
|
// 先处理角色数组
|
|
@@ -8522,6 +8632,18 @@ class AnimeService
|
|
|
$products[$product['product_name']] = $product; // 使用product_name作为key便于后续覆盖
|
|
$products[$product['product_name']] = $product; // 使用product_name作为key便于后续覆盖
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 处理道具数组(逻辑与场景一致)
|
|
|
|
|
+ foreach ($props as $prop) {
|
|
|
|
|
+ $product = $prop;
|
|
|
|
|
+ // 将prop字段重命名为product_name
|
|
|
|
|
+ if (isset($product['prop'])) {
|
|
|
|
|
+ $product['product_name'] = $product['prop'];
|
|
|
|
|
+ unset($product['prop']);
|
|
|
|
|
+ }
|
|
|
|
|
+ $product['product'] = 3; // 标记类型为道具
|
|
|
|
|
+ $products[$product['product_name']] = $product; // 使用product_name作为key便于后续覆盖
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// extra_products优先级更高,直接覆盖同名的roles和scenes
|
|
// extra_products优先级更高,直接覆盖同名的roles和scenes
|
|
|
$extra_products = json_decode(getProp($episode, 'extra_products', '[]'), true) ?: [];
|
|
$extra_products = json_decode(getProp($episode, 'extra_products', '[]'), true) ?: [];
|
|
|
foreach ($extra_products as $extra_product) {
|
|
foreach ($extra_products as $extra_product) {
|