Browse Source

1.优化批量生成剧集的错误信息返回2.动漫对话全能模式接口新增主体非空判断和重试

lh 1 month ago
parent
commit
0aa7949af5
1 changed files with 75 additions and 26 deletions
  1. 75 26
      app/Services/DeepSeek/DeepSeekService.php

+ 75 - 26
app/Services/DeepSeek/DeepSeekService.php

@@ -10422,15 +10422,21 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
                 $validation_failed = true;
                 $validation_failed = true;
                 $validation_error_msg = '未生成分镜剧本相关的内容';
                 $validation_error_msg = '未生成分镜剧本相关的内容';
             } else {
             } else {
+                // 校验主体列表:不能为空主体(旁白不算)
+                $generated_roles = array_column($episode_arr['roles'] ?? [], 'role');
+                // 过滤掉"旁白"角色
+                $generated_roles = array_filter($generated_roles, function($role) {
+                    return $role !== '旁白';
+                });
+                if (empty($generated_roles)) {
+                    $validation_failed = true;
+                    $validation_error_msg = '生成的主体列表不能为空(旁白不算)';
+                }
+
                 // 仅当存在强制主体设定时校验主体列表
                 // 仅当存在强制主体设定时校验主体列表
-                if (!empty($extra_roles)) {
-                    $generated_roles = array_column($episode_arr['roles'], 'role');
-                    // 过滤掉"旁白"角色
-                    $generated_roles = array_filter($generated_roles, function($role) {
-                        return $role !== '旁白';
-                    });
+                if (!$validation_failed && !empty($extra_roles)) {
                     $expected_roles = array_keys($extra_roles);
                     $expected_roles = array_keys($extra_roles);
-                    
+
                     // 找出生成的主体中不在预期列表中的主体
                     // 找出生成的主体中不在预期列表中的主体
                     $invalid_roles = array_diff($generated_roles, $expected_roles);
                     $invalid_roles = array_diff($generated_roles, $expected_roles);
                     if (!empty($invalid_roles)) {
                     if (!empty($invalid_roles)) {
@@ -10470,6 +10476,17 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
             if (empty($episode_arr['acts'])) {
             if (empty($episode_arr['acts'])) {
                 $validation_failed = true;
                 $validation_failed = true;
                 $validation_error_msg = '未生成分镜剧本相关的内容';
                 $validation_error_msg = '未生成分镜剧本相关的内容';
+            } else {
+                // 校验主体列表:不能为空主体(旁白不算)
+                $generated_roles = array_column($episode_arr['roles'] ?? [], 'role');
+                // 过滤掉"旁白"角色
+                $generated_roles = array_filter($generated_roles, function($role) {
+                    return $role !== '旁白';
+                });
+                if (empty($generated_roles)) {
+                    $validation_failed = true;
+                    $validation_error_msg = '生成的主体列表不能为空(旁白不算)';
+                }
             }
             }
         }
         }
 
 
@@ -10497,10 +10514,12 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
             $retry_prompt = "生成的剧本存在问题:{$validation_error_msg}。\n\n请严格按照要求重新生成,确保:\n";
             $retry_prompt = "生成的剧本存在问题:{$validation_error_msg}。\n\n请严格按照要求重新生成,确保:\n";
             if ($anime_script_id) {
             if ($anime_script_id) {
                 $retry_prompt .= "1. 主体列表中的所有主体名称必须从【强制主体设定】中选择,不得使用其他主体名称\n";
                 $retry_prompt .= "1. 主体列表中的所有主体名称必须从【强制主体设定】中选择,不得使用其他主体名称\n";
-                $retry_prompt .= "2. 场景列表中的所有场景名称必须从【强制场景设定】中选择,不得使用其他场景名称\n";
-                $retry_prompt .= "3. 必须包含完整的分镜剧本内容\n";
+                $retry_prompt .= "2. 主体列表不能为空,必须至少包含一个非“旁白”的主体\n";
+                $retry_prompt .= "3. 场景列表中的所有场景名称必须从【强制场景设定】中选择,不得使用其他场景名称\n";
+                $retry_prompt .= "4. 必须包含完整的分镜剧本内容\n";
             } else {
             } else {
-                $retry_prompt .= "1. 必须包含完整的分镜剧本内容\n";
+                $retry_prompt .= "1. 主体列表不能为空,必须至少包含一个非“旁白”的主体\n";
+                $retry_prompt .= "2. 必须包含完整的分镜剧本内容\n";
             }
             }
 
 
             // 添加重试消息到messages
             // 添加重试消息到messages
@@ -10566,28 +10585,34 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
                         $validation_failed = true;
                         $validation_failed = true;
                         $validation_error_msg = '未生成分镜剧本相关的内容';
                         $validation_error_msg = '未生成分镜剧本相关的内容';
                     } else {
                     } else {
+                        // 校验主体列表:不能为空主体(旁白不算)
+                        $generated_roles = array_column($episode_arr['roles'] ?? [], 'role');
+                        // 过滤掉"旁白"角色
+                        $generated_roles = array_filter($generated_roles, function($role) {
+                            return $role !== '旁白';
+                        });
+                        if (empty($generated_roles)) {
+                            $validation_failed = true;
+                            $validation_error_msg = '生成的主体列表不能为空(旁白不算)';
+                        }
+
                         // 仅当存在强制主体设定时校验主体列表
                         // 仅当存在强制主体设定时校验主体列表
-                        if (!empty($extra_roles)) {
-                            $generated_roles = array_column($episode_arr['roles'], 'role');
-                            // 过滤掉"旁白"角色
-                            $generated_roles = array_filter($generated_roles, function($role) {
-                                return $role !== '旁白';
-                            });
+                        if (!$validation_failed && !empty($extra_roles)) {
                             $expected_roles = array_keys($extra_roles);
                             $expected_roles = array_keys($extra_roles);
                             $invalid_roles = array_diff($generated_roles, $expected_roles);
                             $invalid_roles = array_diff($generated_roles, $expected_roles);
-                            
+
                             if (!empty($invalid_roles)) {
                             if (!empty($invalid_roles)) {
                                 $validation_failed = true;
                                 $validation_failed = true;
                                 $validation_error_msg = '生成的主体列表包含不在【强制主体设定】中的主体:' . implode('、', $invalid_roles);
                                 $validation_error_msg = '生成的主体列表包含不在【强制主体设定】中的主体:' . implode('、', $invalid_roles);
                             }
                             }
                         }
                         }
-                        
+
                         // 仅当存在强制场景设定时校验场景列表
                         // 仅当存在强制场景设定时校验场景列表
                         if (!$validation_failed && !empty($extra_scenes)) {
                         if (!$validation_failed && !empty($extra_scenes)) {
                             $generated_scenes = array_column($episode_arr['scenes'], 'scene');
                             $generated_scenes = array_column($episode_arr['scenes'], 'scene');
                             $expected_scenes = array_keys($extra_scenes);
                             $expected_scenes = array_keys($extra_scenes);
                             $invalid_scenes = array_diff($generated_scenes, $expected_scenes);
                             $invalid_scenes = array_diff($generated_scenes, $expected_scenes);
-                            
+
                             if (!empty($invalid_scenes)) {
                             if (!empty($invalid_scenes)) {
                                 $validation_failed = true;
                                 $validation_failed = true;
                                 $validation_error_msg = '生成的场景列表包含不在【强制场景设定】中的场景:' . implode('、', $invalid_scenes);
                                 $validation_error_msg = '生成的场景列表包含不在【强制场景设定】中的场景:' . implode('、', $invalid_scenes);
@@ -10610,6 +10635,17 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
                     if (empty($episode_arr['acts'])) {
                     if (empty($episode_arr['acts'])) {
                         $validation_failed = true;
                         $validation_failed = true;
                         $validation_error_msg = '未生成分镜剧本相关的内容';
                         $validation_error_msg = '未生成分镜剧本相关的内容';
+                    } else {
+                        // 校验主体列表:不能为空主体(旁白不算)
+                        $generated_roles = array_column($episode_arr['roles'] ?? [], 'role');
+                        // 过滤掉"旁白"角色
+                        $generated_roles = array_filter($generated_roles, function($role) {
+                            return $role !== '旁白';
+                        });
+                        if (empty($generated_roles)) {
+                            $validation_failed = true;
+                            $validation_error_msg = '生成的主体列表不能为空(旁白不算)';
+                        }
                     }
                     }
                 }
                 }
 
 
@@ -10855,26 +10891,32 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
         // 验证必要字段
         // 验证必要字段
         $episode = $finalResult['episode'] ?? [];
         $episode = $finalResult['episode'] ?? [];
         
         
-        // 验证 roles
+        // 验证 roles(旁白不算主体,过滤后不能为空)
         if (empty($episode['roles']) || !is_array($episode['roles'])) {
         if (empty($episode['roles']) || !is_array($episode['roles'])) {
             return ['error' => '生成失败:主体列表(roles)为空或格式错误'];
             return ['error' => '生成失败:主体列表(roles)为空或格式错误'];
         }
         }
-        
+        $nonNarratorRoles = array_filter(array_column($episode['roles'], 'role'), function($role) {
+            return $role !== '旁白';
+        });
+        if (empty($nonNarratorRoles)) {
+            return ['error' => '生成失败:主体列表(roles)为空或格式错误(旁白不算)'];
+        }
+
         // 验证 scenes
         // 验证 scenes
         if (empty($episode['scenes']) || !is_array($episode['scenes'])) {
         if (empty($episode['scenes']) || !is_array($episode['scenes'])) {
             return ['error' => '生成失败:场景列表(scenes)为空或格式错误'];
             return ['error' => '生成失败:场景列表(scenes)为空或格式错误'];
         }
         }
-        
+
         // 验证 props(道具可以为空,但必须存在且为数组)
         // 验证 props(道具可以为空,但必须存在且为数组)
         if (!isset($episode['props']) || !is_array($episode['props'])) {
         if (!isset($episode['props']) || !is_array($episode['props'])) {
             $episode['props'] = [];
             $episode['props'] = [];
         }
         }
-        
+
         // 验证 acts(分镜剧本)
         // 验证 acts(分镜剧本)
         if (empty($episode['acts']) || !is_array($episode['acts'])) {
         if (empty($episode['acts']) || !is_array($episode['acts'])) {
             return ['error' => '生成失败:分镜剧本(acts)为空或格式错误'];
             return ['error' => '生成失败:分镜剧本(acts)为空或格式错误'];
         }
         }
-        
+
         // 更新验证后的 episode 数据
         // 更新验证后的 episode 数据
         $finalResult['episode'] = $episode;
         $finalResult['episode'] = $episode;
         
         
@@ -11077,7 +11119,8 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
         $processingCount = 0;
         $processingCount = 0;
         $completedCount = 0;
         $completedCount = 0;
         $failedCount = 0;
         $failedCount = 0;
-        
+        $failed_episodes = [];
+
         foreach ($tasks as $task) {
         foreach ($tasks as $task) {
             switch ($task['status']) {
             switch ($task['status']) {
                 case 'pending':
                 case 'pending':
@@ -11091,10 +11134,15 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
                     break;
                     break;
                 case 'failed':
                 case 'failed':
                     $failedCount++;
                     $failedCount++;
+                    // 组装失败分集对象(新对象):分集序号、错误原因
+                    $failed_episodes[] = [
+                        'episode_number' => $task['episode_number'],
+                        'error_message' => $task['error_message'] ?? ''
+                    ];
                     break;
                     break;
             }
             }
         }
         }
-        
+
         // 计算进度百分比
         // 计算进度百分比
         $progress = 0;
         $progress = 0;
         if ($totalCount > 0) {
         if ($totalCount > 0) {
@@ -11120,6 +11168,7 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
             'failed_count' => $failedCount,
             'failed_count' => $failedCount,
             'progress' => $progress,
             'progress' => $progress,
             'overall_status' => $overallStatus,
             'overall_status' => $overallStatus,
+            'failed_episodes' => $failed_episodes,
             'tasks' => $tasks
             'tasks' => $tasks
         ];
         ];
     }
     }