Преглед изворни кода

1.新增剧本详情2.优化剧本角色和场景数据结构

lh пре 4 месеци
родитељ
комит
16d3a5467a

+ 9 - 0
app/Http/Controllers/DeepSeek/DeepSeekController.php

@@ -251,6 +251,15 @@ class DeepSeekController extends BaseController
         return $this->success($result, [new DeepSeekTransformer(), 'newBuildScriptList']);
     }
 
+    // 剧本详情
+    public function scriptInfo(Request $request) {
+        $data = $request->all();
+
+        $result = $this->deepseekService->scriptInfo($data);
+        return $this->success($result);
+
+    }
+
     /**
      * 创建剧本
      *

+ 86 - 2
app/Libs/Helpers.php

@@ -2153,7 +2153,8 @@ function handleScriptContent($originalContent) {
         
     // 提取主体列表
     preg_match('/###主体列表\s*\n(.*?)(?=\n###|$)/s', $originalContent, $subjectsMatch);
-    $parts['roles'] = isset($subjectsMatch[1]) ? trim($subjectsMatch[1]) : '';
+    $rolesText = isset($subjectsMatch[1]) ? trim($subjectsMatch[1]) : '';
+    $parts['roles'] = parseRolesFromText($rolesText);
         
     // 提取美术风格
     preg_match('/###美术风格\s*\n(.*?)(?=\n###|$)/s', $originalContent, $artStyleMatch);
@@ -2161,7 +2162,8 @@ function handleScriptContent($originalContent) {
         
     // 提取场景列表
     preg_match('/###场景列表\s*\n(.*?)(?=\n###|$)/s', $originalContent, $scenesMatch);
-    $parts['scenes'] = isset($scenesMatch[1]) ? trim($scenesMatch[1]) : '';
+    $scenesText = isset($scenesMatch[1]) ? trim($scenesMatch[1]) : '';
+    $parts['scenes'] = parseScenesFromText($scenesText);
         
     // 提取分集剧本并按分集拆分
     preg_match('/###分集剧本\s*\n(.*)/s', $originalContent, $storyboardMatch);
@@ -2501,3 +2503,85 @@ function safeDestroyImage(&$img)
 
 //     return null;
 // }
+
+/**
+ * 将主体列表文本拆分为主体数组
+ * 
+ * @param string $rolesText 主体列表文本内容
+ * @return array 主体名称数组
+ */
+function parseRolesFromText(string $rolesText): array
+{
+    if (empty($rolesText)) {
+        return [];
+    }
+    
+    $roles = [];
+    
+    // 按行分割文本
+    $lines = explode("\n", $rolesText);
+    
+    foreach ($lines as $line) {
+        $line = trim($line);
+        if (empty($line)) {
+            continue;
+        }
+        
+        // 匹配格式:角色名-描述:详细信息
+        // 例如:许芸-重生者:18岁少女,原许家假千金...
+        if (preg_match('/^([^::]+)[::]/', $line, $matches)) {
+            $roleName = trim($matches[1]);
+            
+            // 如果角色名包含"-",取"-"前面的部分作为主要角色名
+            if (strpos($roleName, '-') !== false) {
+                $parts = explode('-', $roleName);
+                $mainRole = trim($parts[0]);
+                if (!empty($mainRole) && !in_array($mainRole, $roles)) {
+                    $roles[] = $mainRole;
+                }
+            } else {
+                if (!in_array($roleName, $roles)) {
+                    $roles[] = $roleName;
+                }
+            }
+        }
+    }
+    
+    return $roles;
+}
+
+/**
+ * 将场景列表文本拆分为场景数组
+ * 
+ * @param string $scenesText 场景列表文本内容
+ * @return array 场景名称数组
+ */
+function parseScenesFromText(string $scenesText): array
+{
+    if (empty($scenesText)) {
+        return [];
+    }
+    
+    $scenes = [];
+    
+    // 按行分割文本
+    $lines = explode("\n", $scenesText);
+    
+    foreach ($lines as $line) {
+        $line = trim($line);
+        if (empty($line)) {
+            continue;
+        }
+        
+        // 匹配格式:场景名:描述信息
+        // 例如:徐家馄饨店:老旧街边小店,锅炉、案板杂乱...
+        if (preg_match('/^([^::]+)[::]/', $line, $matches)) {
+            $sceneName = trim($matches[1]);
+            if (!empty($sceneName) && !in_array($sceneName, $scenes)) {
+                $scenes[] = $sceneName;
+            }
+        }
+    }
+    
+    return $scenes;
+}

+ 21 - 2
app/Services/DeepSeek/DeepSeekService.php

@@ -808,6 +808,25 @@ class DeepSeekService
         return $query->orderBy('created_at', 'desc')->paginate(12);
     }
 
+    public function scriptInfo($data) {
+        $script_id = getProp($data, 'script_id');
+        $script = DB::table('mp_scripts')->where('id', $script_id)->where('is_deleted', 0)
+        ->selectRaw('id as script_id, script_name, intro, highlights, roles, role_relationship, core_contradiction, art_style, scenes, status, start_episode_sequence, end_episode_sequence, episode_num, remark, created_at')->first();
+        if (!!$script) Utils::throwError('20003:该剧本不存在!');
+        $script = (array)$script;
+        $script['roles'] = json_decode($script['roles']);
+        $script['scenes'] = json_decode($script['scenes']);
+
+        // 获取分集信息
+        $episodes = DB::table('mp_script_episodes')->where('script_id', $script_id)->orderBy('episode_number')
+        ->select('script_id', 'episode_number', 'title', 'content')
+        ->get()->map(function ($value) {
+            return (array)$value;
+        })->toArray();
+        $script['episodes'] = $episodes;
+        return $script;
+    }
+
     public function createScript($data) {
         $script_name = getProp($data, 'script_name');
         $uid = Site::getUid(); // 获取当前用户ID
@@ -1220,9 +1239,9 @@ class DeepSeekService
                 'highlights' => isset($script_arr['highlights']) ? $script_arr['highlights'] : '',
                 'role_relationship' => isset($script_arr['role_relationship']) ? $script_arr['role_relationship'] : '',
                 'core_contradiction' => isset($script_arr['core_contradiction']) ? $script_arr['core_contradiction'] : '',
-                'roles' => isset($script_arr['roles']) ? $script_arr['roles'] : '',
+                'roles' => isset($script_arr['roles']) ? json_encode($script_arr['roles'], true) : '',
                 'art_style' => isset($script_arr['art_style']) ? $script_arr['art_style'] : '',
-                'scenes' => isset($script_arr['scenes']) ? $script_arr['scenes'] : '',
+                'scenes' => isset($script_arr['scenes']) ? json_encode($script_arr['scenes'], true) : '',
                 'status' => 3,
                 'start_episode_sequence' => $start_episode_sequence,
                 'end_episode_sequence' => $start_episode_sequence + count($script_arr['episodes']) - 1,

+ 1 - 0
routes/api.php

@@ -88,6 +88,7 @@ Route::group(['middleware' => ['bindToken', 'bindExportToken', 'checkLogin']], f
 
         // 剧本管理
         Route::get('scriptList', [DeepSeekController::class, 'scriptList']);
+        Route::get('scriptInfo', [DeepSeekController::class, 'scriptInfo']);
         Route::get('createScript', [DeepSeekController::class, 'createScript']);
         Route::post('chatWithFile', [DeepSeekController::class, 'chatWithFile']);
         Route::post('saveScript', [DeepSeekController::class, 'saveScript']);