|
|
@@ -2875,47 +2875,109 @@ class AnimeController extends BaseController
|
|
|
$videoResolution = !empty($episode->video_resolution) ? $episode->video_resolution : '720p';
|
|
|
$generate_audio = getProp($data, 'generate_audio', 1);
|
|
|
|
|
|
- // 合并角色、场景和道具作为products,统一字段名为product_name
|
|
|
+ // 合并角色、场景、道具、extra_products和当前集mappings作为products,统一字段名为product_name
|
|
|
+ // 优先级:mappings > extra_products > 剧集中的roles/scenes/props
|
|
|
$products = [];
|
|
|
$roles = json_decode(getProp($episode, 'roles'), true) ?: [];
|
|
|
$scenes = json_decode(getProp($episode, 'scenes'), true) ?: [];
|
|
|
$props = json_decode(getProp($episode, 'props'), true) ?: [];
|
|
|
-
|
|
|
- // 处理角色数组
|
|
|
+ $extra_products = json_decode(getProp($episode, 'extra_products', '[]'), true) ?: [];
|
|
|
+
|
|
|
+ $normalizeProductName = function($name) {
|
|
|
+ return trim(preg_replace(
|
|
|
+ '/^[\s*\[\]【】[]{}{}\x{3000}]+|[\s*\[\]【】[]{}{}\x{3000}]+$/u',
|
|
|
+ '',
|
|
|
+ trim((string)$name)
|
|
|
+ ));
|
|
|
+ };
|
|
|
+
|
|
|
+ // 最低优先级:roles/scenes/props
|
|
|
foreach ($roles as $role) {
|
|
|
+ $role_name = getProp($role, 'role');
|
|
|
+ if (!$role_name) continue;
|
|
|
+
|
|
|
$product = $role;
|
|
|
- // 将role字段重命名为product_name
|
|
|
- if (isset($product['role'])) {
|
|
|
- $product['product_name'] = $product['role'];
|
|
|
- unset($product['role']);
|
|
|
- }
|
|
|
+ $product['product_name'] = $role_name;
|
|
|
+ unset($product['role']);
|
|
|
$product['product'] = 1; // 标记类型为角色
|
|
|
- $products[] = $product;
|
|
|
+ $products[$normalizeProductName($role_name)] = $product;
|
|
|
}
|
|
|
-
|
|
|
- // 处理场景数组
|
|
|
+
|
|
|
foreach ($scenes as $scene) {
|
|
|
+ $scene_name = getProp($scene, 'scene');
|
|
|
+ if (!$scene_name) continue;
|
|
|
+
|
|
|
$product = $scene;
|
|
|
- // 将scene字段重命名为product_name
|
|
|
- if (isset($product['scene'])) {
|
|
|
- $product['product_name'] = $product['scene'];
|
|
|
- unset($product['scene']);
|
|
|
- }
|
|
|
+ $product['product_name'] = $scene_name;
|
|
|
+ unset($product['scene']);
|
|
|
$product['product'] = 2; // 标记类型为场景
|
|
|
- $products[] = $product;
|
|
|
+ $products[$normalizeProductName($scene_name)] = $product;
|
|
|
}
|
|
|
-
|
|
|
- // 处理道具数组
|
|
|
+
|
|
|
foreach ($props as $prop) {
|
|
|
+ $prop_name = getProp($prop, 'prop');
|
|
|
+ if (!$prop_name) continue;
|
|
|
+
|
|
|
$product = $prop;
|
|
|
- // 将prop字段重命名为product_name
|
|
|
- if (isset($product['prop'])) {
|
|
|
- $product['product_name'] = $product['prop'];
|
|
|
- unset($product['prop']);
|
|
|
- }
|
|
|
+ $product['product_name'] = $prop_name;
|
|
|
+ unset($product['prop']);
|
|
|
$product['product'] = 3; // 标记类型为道具
|
|
|
- $products[] = $product;
|
|
|
+ $products[$normalizeProductName($prop_name)] = $product;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 中间优先级:extra_products(覆盖roles/scenes/props中的同名资产)
|
|
|
+ // 使用array_merge保留原资产的voice_prompt、description等extra_products没有的字段
|
|
|
+ foreach ($extra_products as $extra_product) {
|
|
|
+ $extra_name = getProp($extra_product, 'product_name');
|
|
|
+ if (!$extra_name) continue;
|
|
|
+
|
|
|
+ $normalized_extra_name = $normalizeProductName($extra_name);
|
|
|
+ $products[$normalized_extra_name] = array_merge(
|
|
|
+ isset($products[$normalized_extra_name]) ? $products[$normalized_extra_name] : [],
|
|
|
+ $extra_product
|
|
|
+ );
|
|
|
}
|
|
|
+
|
|
|
+ // 暂不确定是否启用,先保留
|
|
|
+ // // 最高优先级:当前集对应的mp_script_product_mappings(关联mp_products获取资产库最新数据)
|
|
|
+ // $script_id = (int)DB::table('mp_animes')->where('id', $animeId)->value('script_id');
|
|
|
+ // if ($script_id) {
|
|
|
+ // $mapping_items = DB::table('mp_script_product_mappings as mapping')
|
|
|
+ // ->join('mp_products as product', 'mapping.product_id', '=', 'product.id')
|
|
|
+ // ->where('mapping.script_id', $script_id)
|
|
|
+ // ->where('mapping.episode_number', $episodeNumber)
|
|
|
+ // ->where('product.is_deleted', 0)
|
|
|
+ // ->select(
|
|
|
+ // 'mapping.product_id',
|
|
|
+ // 'product.product_name',
|
|
|
+ // 'product.product',
|
|
|
+ // 'product.pic_prompt',
|
|
|
+ // 'product.url',
|
|
|
+ // 'product.three_view_image_url',
|
|
|
+ // )
|
|
|
+ // ->get();
|
|
|
+
|
|
|
+ // foreach ($mapping_items as $mapping_item) {
|
|
|
+ // $mapping_name = $normalizeProductName($mapping_item->product_name);
|
|
|
+ // if ($mapping_name === '') continue;
|
|
|
+
|
|
|
+ // $mapping_product = [
|
|
|
+ // 'product_id' => (int)$mapping_item->product_id,
|
|
|
+ // 'product_name' => $mapping_item->product_name,
|
|
|
+ // 'product' => (int)$mapping_item->product,
|
|
|
+ // 'pic_prompt' => $mapping_item->pic_prompt ?? '',
|
|
|
+ // 'url' => $mapping_item->url ?? '',
|
|
|
+ // 'three_view_image_url' => $mapping_item->three_view_image_url ?? '',
|
|
|
+ // ];
|
|
|
+
|
|
|
+ // $products[$mapping_name] = array_merge(
|
|
|
+ // isset($products[$mapping_name]) ? $products[$mapping_name] : [],
|
|
|
+ // $mapping_product
|
|
|
+ // );
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+ $products = array_values($products);
|
|
|
|
|
|
// 处理视频模型(在循环外统一处理)
|
|
|
// $model = getProp($data, 'model');
|