You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

5.1 KiB

Changelog: 解析状态接口增强 - 包含 AI 任务状态

日期: 2026-02-11
类型: 功能增强
影响范围: 后端 API - 剧本解析状态查询
关联接口: GET /api/v1/screenplays/{screenplay_id}/parse-status


变更概述

修改 /parse-status 接口,同时返回文件解析状态和 AI 解析任务状态,只有当两者都完成时才返回 completed,避免前端过早查询 storyboards 导致数据为空。

问题背景

原有流程问题

前端流程:
1. POST /parse → 触发解析
2. 轮询 GET /parse-status → 等待 "completed"
3. 收到 "completed" → 立即调用 GET /storyboards
4. ❌ 问题:此时 AI 解析可能还未完成,storyboards 为空

根本原因

  • /parse-status 原本只返回文件解析状态(提取文本内容)
  • 但 storyboards 是由 AI 解析任务创建的(提取角色/场景/道具/分镜)
  • 两者是异步的,存在时间差
  • 前端收到 completed 时,AI 任务可能还在进行中

技术实现

修改文件

  1. server/app/schemas/screenplay.py - 增强 ParseStatusResponse
  2. server/app/api/v1/screenplays.py - 修改 get_parse_status 接口

核心变更

1. Schema 增强

class ParseStatusResponse(BaseModel):
    # 原有字段
    screenplay_id: UUID
    parsing_status: str  # 综合状态
    progress: int
    message: str
    
    # ✨ 新增字段
    ai_job_id: Optional[UUID]      # AI 任务 ID
    ai_status: Optional[str]        # AI 任务状态
    ai_progress: Optional[int]      # AI 任务进度

2. 状态综合判断逻辑

# 只有当文件解析完成 AND AI 任务完成时,才返回 completed
if parsing_status == COMPLETED:
    if ai_status == 'pending':
        final_status = 'parsing'
        final_message = '等待 AI 解析...'
    elif ai_status == 'processing':
        final_status = 'parsing'
        final_message = 'AI 正在提取角色、场景和道具...'
    elif ai_status == 'completed':
        final_status = 'completed'  # ✅ 真正完成
        final_message = '解析完成'

进度映射

阶段 进度 状态 说明
未开始 0% idle 初始状态
等待解析 10% pending 文件上传完成
解析文件 30% parsing 提取文本内容
等待 AI 40% parsing 文件解析完成,等待 AI
AI 解析中 40-90% parsing AI 提取角色/场景/道具
完成 100% completed 文件 + AI 都完成
失败 0% failed 任一步骤失败

API 响应示例

解析中(AI 任务进行中)

{
  "success": true,
  "data": {
    "screenplayId": "xxx",
    "parsingStatus": "parsing",
    "progress": 65,
    "message": "AI 正在提取角色、场景和道具...",
    "aiJobId": "yyy",
    "aiStatus": "processing",
    "aiProgress": 50
  }
}

解析完成(AI 任务也完成)

{
  "success": true,
  "data": {
    "screenplayId": "xxx",
    "parsingStatus": "completed",
    "progress": 100,
    "message": "解析完成",
    "wordCount": 356,
    "fileUrl": "https://...",
    "aiJobId": "yyy",
    "aiStatus": "completed",
    "aiProgress": 100
  }
}

业务价值

1. 避免前端查询空数据

前端现在可以安全地等待 parsingStatus === 'completed' 后再查询 storyboards,确保数据已准备好。

2. 更准确的进度反馈

用户可以看到完整的解析流程:

  • 文件解析(0-40%)
  • AI 解析(40-90%)
  • 完成(100%)

3. 更好的错误处理

可以区分文件解析失败和 AI 解析失败,提供更精确的错误信息。

向后兼容性

完全兼容 - 新增字段为可选,不影响现有前端

前端可以:

  • 简单模式:只检查 parsingStatus === 'completed'
  • 详细模式:同时检查 aiStatus 获取更多信息

测试验证

验证步骤

  1. 上传并解析一个剧本
  2. 轮询 /parse-status 接口
  3. 观察状态变化:pendingparsingcompleted
  4. 确认只有在 AI 任务完成后才返回 completed
  5. 查询 /storyboards 确认数据存在

预期结果

# 文件解析完成,但 AI 还在进行
GET /parse-status
→ parsingStatus: "parsing"
→ message: "AI 正在提取角色、场景和道具..."
→ aiStatus: "processing"

# AI 任务完成
GET /parse-status
→ parsingStatus: "completed"
→ message: "解析完成"
→ aiStatus: "completed"

# 此时查询 storyboards 有数据
GET /storyboards?project_id=xxx
→ 返回分镜列表 ✅

注意事项

  1. AI 任务查询:通过 input_data->>'screenplay_id' 查询最近的 AI 任务
  2. 纯文本剧本:如果没有 AI 任务,文件解析完成即视为完成
  3. 进度计算:AI 进度映射到 40-90% 区间,避免进度倒退

后续优化

  • 考虑在 screenplays 表增加 ai_job_id 字段,避免每次查询
  • 增加 WebSocket 推送,实时通知前端状态变化
  • 支持批量查询多个剧本的解析状态

变更人: AI Assistant
审核人: 待审核
状态: 已实施