浏览代码

1.动漫对话(全能模式)接口新增道具列表的生成2.同步调整公共解析方法及保存方法、生图方法和数据继承方法

lh 2 天之前
父节点
当前提交
9d87827ef6
共有 3 个文件被更改,包括 614 次插入0 次删除
  1. 148 0
      MODIFICATION_GUIDE.md
  2. 90 0
      addChatForAce_modifications.md
  3. 376 0
      docs/批量生成分集功能说明.md

+ 148 - 0
MODIFICATION_GUIDE.md

@@ -0,0 +1,148 @@
+# addChatForAce 方法完整修改指南
+
+## 已完成的修改
+
+### ✅ 1. 道具提示词构建 (行5966-6004)
+已在 `addChatForAce` 方法中添加了道具列表的生成逻辑:
+- 新增 `$extra_prop_prompt` 变量
+- 在 foreach 循环中添加 product === 3 的道具处理
+- 添加道具强制设定提示词
+
+##未完成的修改
+
+### 📝 2. 修改单剧集 systemPrompt (行6006附近)
+
+需要将板块列表从:
+```
+<故事梗概><剧本亮点><人物关系><核心矛盾><主体列表><美术风格><场景列表><分段剧本>
+```
+
+改为:
+```
+<故事梗概><剧本亮点><人物关系><核心矛盾><主体列表><美术风格><场景列表><道具列表><分段剧本>
+```
+
+并在场景列表相关说明后添加道具列表说明:
+```
+4.<道具列表>与场景列表同理,需尽可能的对道具环境进行详细描述,必须严格注意不要出现任何角色和人物。
+    4.1<道具列表>分以下两部分(强制格式):道具描述和道具提示词,格式必须为:道具名:道具描述{道具提示词}
+    4.2<道具列表>的道具描述是分析在整部剧中出现过的道具,道具描述尽量简洁贴合原文。
+    4.3<道具列表>的道具提示词用于视觉呈现的道具描述,该道具需包含材质特征、颜色、尺寸比例、细节装饰、视觉风格等,描述需具有镜头感与画面表现力,适合直接用于AI图像生成模型,避免抽象词汇,强调具体可视化细节与整体视觉一致性,同时保证风格统一且符合剧情设定。该提示词在道具描述后用{}框起来。
+    {$extra_prop_prompt}
+```
+
+### 📝 3. 在示例格式中添加道具列表 (行6100附近)
+
+在场景列表示例后(###场景列表之后,###分段剧本之前)添加:
+```
+###道具列表
+神秘药瓶:一个古朴的玉质小瓶,装有救命的阴阳球。{特写镜头,古朴的玉质小瓶,瓶身呈半透明的青白色玉质,高约8厘米,直径3厘米,瓶口用红绳系着精致的翠绿色玉塞。瓶身雕刻有精细的云纹图案,在灯光下泛着温润的光泽。无人物。}
+```
+
+### 📝 4. 更新 table_data 保存逻辑 (行6300附近)
+
+在以下代码中:
+```php
+$table_data = [
+    'user_id' => $uid,
+    'anime_name' => $anime_name,
+    ...
+    'scenes' => isset($script_arr['scenes']) && is_array($script_arr['scenes']) ? json_encode($script_arr['scenes'], 256) : '[]',
+    'status' => '解析完成',
+```
+
+添加 props 字段:
+```php
+    'scenes' => isset($script_arr['scenes']) && is_array($script_arr['scenes']) ? json_encode($script_arr['scenes'], 256) : '[]',
+    'props' => isset($script_arr['props']) && is_array($script_arr['props']) ? json_encode($script_arr['props'], 256) : '[]',
+    'status' => '解析完成',
+```
+
+### 📝 5. 更新 saveEpisodeVersionData 调用 (行6400附近)
+
+找到:
+```php
+$saveResult = $this->saveEpisodeVersionData(
+    $anime_id,
+    1,
+    $episode_arr,
+    is_array(getProp($script_arr, 'roles')) ? getProp($script_arr, 'roles') : [],
+    is_array(getProp($script_arr, 'scenes')) ? getProp($script_arr, 'scenes') : [],
+```
+
+改为:
+```php
+$saveResult = $this->saveEpisodeVersionData(
+    $anime_id,
+    1,
+    $episode_arr,
+    is_array(getProp($script_arr, 'roles')) ? getProp($script_arr, 'roles') : [],
+    is_array(getProp($script_arr, 'scenes')) ? getProp($script_arr, 'scenes') : [],
+    is_array(getProp($script_arr, 'props')) ? getProp($script_arr, 'props') : [],
+```
+
+### 📝 6. 更新返回数据 (行6500附近)
+
+找到:
+```php
+$table_data['roles'] = json_decode($table_data['roles'], true);
+$table_data['scenes'] = json_decode($table_data['scenes'], true);
+```
+
+改为:
+```php
+$table_data['roles'] = json_decode($table_data['roles'], true);
+$table_data['scenes'] = json_decode($table_data['scenes'], true);
+$table_data['props'] = json_decode($table_data['props'], true);
+```
+
+### 📝 7. 更新 mp_animes 表同步逻辑 (行6420附近)
+
+找到:
+```php
+$boolen5 = DB::table('mp_animes')->where('id', $anime_id)->update([
+    'roles' => json_encode($saveResult['merged_roles'], 256),
+    'scenes' => json_encode($saveResult['merged_scenes'], 256),
+    'updated_at' => $now
+]);
+```
+
+改为:
+```php
+$boolen5 = DB::table('mp_animes')->where('id', $anime_id)->update([
+    'roles' => json_encode($saveResult['merged_roles'], 256),
+    'scenes' => json_encode($saveResult['merged_scenes'], 256),
+    'props' => json_encode($saveResult['merged_props'], 256),
+    'updated_at' => $now
+]);
+```
+
+并更新后续代码:
+```php
+$table_data['roles'] = json_encode($saveResult['merged_roles'], 256);
+$table_data['scenes'] = json_encode($saveResult['merged_scenes'], 256);
+$table_data['props'] = json_encode($saveResult['merged_props'], 256);
+```
+
+## 参考 chatForAce 方法
+
+chatForAce 方法中已经有完整的道具列表处理逻辑,可以参考:
+- 行7490附近的 chatForAce 方法
+- 包含道具的强制提示词设定
+- 道具列表的格式要求
+- 分镜中道具的使用说明
+
+## 测试要点
+
+完成所有修改后,需要测试:
+1. 单剧集模式是否能正确生成道具列表
+2. 道具数据是否正确保存到 mp_animes 和 mp_anime_episodes 表
+3. 道具提示词格式是否符合要求
+4. 与 chatForAce 方法的输出结果一致性
+
+## 注意事项
+
+1. 所有修改都只针对 addChatForAce 方法(行5851开始)
+2. 不要修改 addChat 方法(行6762附近)
+3. 确保 systemPrompt 的格式与 chatForAce 完全一致
+4. 道具提示词的编号应为 4.x,不要与场景的 3.x 冲突

文件差异内容过多而无法显示
+ 90 - 0
addChatForAce_modifications.md


+ 376 - 0
docs/批量生成分集功能说明.md

@@ -0,0 +1,376 @@
+# 批量生成分集功能说明
+
+## 功能概述
+
+该功能允许用户批量生成多个剧集,支持从当前集数自动往后生成指定数量的剧集。使用队列机制实现异步处理,提升用户体验。
+
+## 核心特性
+
+1. **队列异步处理**: 任务放入队列异步执行,前端无需长时间等待
+2. **进度跟踪**: 提供实时任务状态查询接口
+3. **完全复用逻辑**: 批量生成完全使用 `chatForAce` 方法的逻辑,包括资产库应用、提示词等
+4. **错误容错**: 单集失败不影响其他集的生成
+5. **防重复执行**: 同一剧集同时只能有一个批量任务执行
+
+## 技术架构
+
+### 1. 数据库表结构
+
+#### mp_batch_episode_generation_tasks (批量生成任务主表)
+- `id`: 主键
+- `anime_id`: 动漫ID
+- `uid`: 用户ID
+- `cpid`: 公司ID
+- `start_episode`: 起始集数
+- `end_episode`: 结束集数
+- `total_episodes`: 总集数
+- `current_episode`: 当前处理的集数
+- `completed_episodes`: 已完成集数
+- `status`: 任务状态 (pending/processing/completed/failed)
+- `request_data`: 请求数据JSON
+- `error_message`: 错误信息
+- `completed_at`: 完成时间
+- `created_at`: 创建时间
+- `updated_at`: 更新时间
+
+#### mp_batch_episode_generation_details (批量生成详情表)
+- `id`: 主键
+- `task_id`: 任务ID
+- `episode_number`: 集数
+- `status`: 状态 (processing/completed/failed)
+- `result_data`: 结果数据JSON
+- `error_message`: 错误信息
+- `created_at`: 创建时间
+- `updated_at`: 更新时间
+
+### 2. 核心类文件
+
+#### ProcessBatchEpisodeGenerationJob (队列任务类)
+**位置**: `app/Jobs/ProcessBatchEpisodeGenerationJob.php`
+
+**职责**:
+- 处理批量生成任务
+- 逐集调用 `chatForAceNonStream` 方法
+- 更新任务进度
+- 记录每集的生成结果
+
+**关键参数**:
+- `$taskId`: 批量任务ID
+- `$animeId`: 动漫ID
+- `$startEpisodeNumber`: 起始集数
+- `$totalEpisodes`: 总共生成集数
+- `$requestData`: 请求数据
+- `$uid`: 用户ID
+- `$cpid`: 公司ID
+
+#### DeepSeekService 新增方法
+
+##### chatForAceNonStream
+**功能**: `chatForAce` 的非流式版本,用于队列任务调用
+
+**实现方式**: 
+- 调用 `chatForAce` 流式方法
+- 收集所有数据块
+- 返回最终结果
+
+**返回值**: 与 `chatForAce` 的 `done` 类型数据一致
+
+##### batchGenerateEpisodes
+**功能**: 创建批量生成任务
+
+**参数**:
+- `anime_id`: 动漫ID (必填)
+- `generate_episode_number`: 要生成的集数 (必填)
+- `episode_number`: 起始集数 (可选,默认从当前最大集数+1开始)
+- 其他与 `chatForAce` 相同的参数
+
+**流程**:
+1. 验证参数
+2. 检查是否为多剧集模式
+3. 计算起始和结束集数
+4. 检查是否超过总集数限制
+5. 检查是否已有进行中的任务
+6. 创建任务记录
+7. 分发到队列
+
+**返回值**:
+```json
+{
+    "task_id": 1,
+    "anime_id": 123,
+    "start_episode": 2,
+    "end_episode": 6,
+    "total_episodes": 5,
+    "status": "processing",
+    "message": "已创建批量生成任务,将生成第2集到第6集,共5集"
+}
+```
+
+##### getBatchGenerationTaskStatus
+**功能**: 查询批量生成任务状态
+
+**参数**:
+- `task_id`: 任务ID (与 `anime_id` 二选一)
+- `anime_id`: 动漫ID (与 `task_id` 二选一,返回最新任务)
+
+**返回值**:
+```json
+{
+    "task_id": 1,
+    "anime_id": 123,
+    "start_episode": 2,
+    "end_episode": 6,
+    "total_episodes": 5,
+    "current_episode": 3,
+    "completed_episodes": 2,
+    "progress": 40.00,
+    "status": "processing",
+    "error_message": null,
+    "details": [
+        {
+            "episode_number": 2,
+            "status": "completed",
+            "error_message": null,
+            "created_at": "2026-01-29 10:00:00",
+            "updated_at": "2026-01-29 10:05:00"
+        },
+        {
+            "episode_number": 3,
+            "status": "processing",
+            "error_message": null,
+            "created_at": "2026-01-29 10:05:00",
+            "updated_at": "2026-01-29 10:05:00"
+        }
+    ],
+    "created_at": "2026-01-29 10:00:00",
+    "updated_at": "2026-01-29 10:05:00",
+    "completed_at": null
+}
+```
+
+### 3. API 接口
+
+#### 创建批量生成任务
+**接口**: `POST /api/anime/batchGenerateEpisodes`
+
+**请求参数**:
+```json
+{
+    "anime_id": 123,
+    "generate_episode_number": 5,
+    "episode_number": 2,  // 可选,指定起始集数
+    "file": null,
+    "content": "",
+    "bid": 0,
+    "script_id": 0,
+    "prompt": "确认分镜大纲",
+    "products": [],
+    "art_style": "",
+    "model": ""
+}
+```
+
+**响应示例**:
+```json
+{
+    "code": 0,
+    "msg": "success",
+    "data": {
+        "task_id": 1,
+        "anime_id": 123,
+        "start_episode": 2,
+        "end_episode": 6,
+        "total_episodes": 5,
+        "status": "processing",
+        "message": "已创建批量生成任务,将生成第2集到第6集,共5集"
+    }
+}
+```
+
+#### 查询任务状态
+**接口**: `GET /api/anime/getBatchGenerationTaskStatus`
+
+**请求参数**:
+```
+task_id=1
+或
+anime_id=123
+```
+
+**响应示例**: (见上方 getBatchGenerationTaskStatus 返回值)
+
+## 使用流程
+
+### 前端调用流程
+
+1. **发起批量生成请求**
+```javascript
+// 用户输入要生成5集,当前是第2集
+const response = await fetch('/api/anime/batchGenerateEpisodes', {
+    method: 'POST',
+    headers: {
+        'Content-Type': 'application/json',
+        'Authorization': 'Bearer <token>'
+    },
+    body: JSON.stringify({
+        anime_id: 123,
+        generate_episode_number: 5,
+        // 其他参数与 chatForAce 一致
+    })
+});
+
+const result = await response.json();
+const taskId = result.data.task_id;
+```
+
+2. **轮询查询任务状态**
+```javascript
+const checkStatus = async () => {
+    const response = await fetch(`/api/anime/getBatchGenerationTaskStatus?task_id=${taskId}`);
+    const result = await response.json();
+    
+    // 更新UI显示进度
+    updateProgressBar(result.data.progress);
+    updateEpisodeList(result.data.details);
+    
+    // 如果任务未完成,继续轮询
+    if (result.data.status === 'processing') {
+        setTimeout(checkStatus, 3000); // 每3秒查询一次
+    } else if (result.data.status === 'completed') {
+        showSuccessMessage('批量生成完成!');
+    } else if (result.data.status === 'failed') {
+        showErrorMessage(result.data.error_message);
+    }
+};
+
+// 开始轮询
+checkStatus();
+```
+
+3. **防止重复操作**
+```javascript
+// 在发起新任务前,先检查是否有进行中的任务
+const checkExistingTask = async () => {
+    const response = await fetch(`/api/anime/getBatchGenerationTaskStatus?anime_id=${animeId}`);
+    const result = await response.json();
+    
+    if (result.data && ['pending', 'processing'].includes(result.data.status)) {
+        alert('已有批量生成任务正在进行中,请等待完成后再试');
+        return false;
+    }
+    return true;
+};
+
+// 创建任务前先检查
+if (await checkExistingTask()) {
+    // 创建新任务
+}
+```
+
+### 前端 UI 建议
+
+1. **任务状态显示**
+   - 显示整体进度条
+   - 显示当前正在生成的集数
+   - 显示已完成集数/总集数
+
+2. **详细列表**
+   - 显示每集的状态(等待中/处理中/已完成/失败)
+   - 失败的集显示错误原因
+   - 已完成的集提供预览入口
+
+3. **操作按钮**
+   - 禁用"开始生成"按钮当有任务进行中
+   - 提供"查看任务详情"按钮
+   - 提供"取消任务"按钮(未来扩展)
+
+## 迁移数据库
+
+运行以下命令创建所需数据表:
+
+```bash
+php artisan migrate
+```
+
+如果需要手动创建,执行:
+
+```sql
+-- 见 database/migrations/2026_01_29_000001_create_batch_episode_generation_tables.php
+```
+
+## 队列配置
+
+确保 Laravel 队列已正确配置并运行:
+
+1. 配置队列驱动 (`.env`):
+```
+QUEUE_CONNECTION=database
+```
+
+2. 运行队列监听:
+```bash
+php artisan queue:work
+```
+
+或使用 Supervisor 进行持久化监听。
+
+## 注意事项
+
+1. **性能考虑**
+   - 批量生成会占用较多AI接口资源
+   - 建议限制单次生成的集数上限(如最多10集)
+   - 合理设置队列worker数量
+
+2. **错误处理**
+   - 单集失败不会中断整个任务
+   - 所有错误信息都会记录到详情表
+   - 建议提供"重试失败集数"功能(未来扩展)
+
+3. **用户体验**
+   - 前端应该定期轮询任务状态(建议3-5秒)
+   - 任务完成后应通知用户(可使用浏览器通知API)
+   - 提供任务历史记录查询
+
+4. **资源管理**
+   - 定期清理已完成的旧任务记录
+   - 监控队列任务堆积情况
+   - 合理设置任务超时时间
+
+## 未来扩展
+
+1. **取消任务**: 允许用户取消正在进行的批量生成
+2. **重试机制**: 自动或手动重试失败的集数
+3. **优先级队列**: 支持任务优先级设置
+4. **通知系统**: 任务完成后发送邮件或站内通知
+5. **并行生成**: 支持多集并行生成(需注意资源占用)
+
+## 测试建议
+
+1. **单元测试**
+   - 测试 `chatForAceNonStream` 方法
+   - 测试 `batchGenerateEpisodes` 参数验证
+   - 测试任务状态查询
+
+2. **集成测试**
+   - 测试完整的批量生成流程
+   - 测试错误处理机制
+   - 测试并发任务冲突
+
+3. **性能测试**
+   - 测试大批量生成(如20集)
+   - 测试多用户同时批量生成
+   - 监控内存和CPU使用
+
+## 常见问题
+
+### Q: 如何取消正在进行的批量任务?
+A: 当前版本不支持取消任务,可以通过停止队列worker来中断,但已提交的任务会在重启后继续执行。
+
+### Q: 任务失败后如何重试?
+A: 可以使用相同的参数重新创建批量任务,系统会自动从已完成的集数继续生成。
+
+### Q: 批量生成会影响手动生成吗?
+A: 不会。批量生成使用独立的队列任务,不影响用户手动操作。
+
+### Q: 如何查看队列任务执行日志?
+A: 查看 `storage/logs/laravel.log` 文件,搜索 `batch_episode_generation` 关键字。