# ProjectPage 剧本检测和自动弹窗功能 **日期**: 2026-02-06 **类型**: Feature Enhancement **影响范围**: ProjectPage, ParseFlowDialogContainer ## 概述 完成 ProjectPage 与后端剧本 API 的完整对接,实现项目剧本检测和智能弹窗功能。 ## 变更内容 ### 1. ParseFlowDialogContainer 增强 **文件**: `client/src/components/features/storyboard/ParseFlowDialogContainer.tsx` **新增功能**: - 从 `useAppStore` 获取当前项目 ID - 使用 `useScreenplays` hook 查询项目的剧本列表 - 自动将第一个剧本的 ID 传递给 `ParseFlowDialog` 作为 `initialSelectedId` **实现逻辑**: ```typescript const currentProjectId = useAppStore((state) => state.currentProjectId); const { data: screenplaysData } = useScreenplays(currentProjectId, { page: 1, pageSize: 20 }); const firstScreenplayId = screenplaysData?.items?.[0]?.screenplayId || null; ``` ### 2. ProjectPage 剧本检测逻辑 **文件**: `client/src/pages/ProjectPage.tsx` **已实现功能**: - 使用 `useScreenplays` hook 查询项目剧本列表 - 自动检测项目是否有剧本 - 根据剧本存在情况决定弹窗模式: - 有剧本 → `preview` 模式(显示剧本内容) - 无剧本 → `upload` 模式(显示上传界面) **实现逻辑**: ```typescript const { data: screenplaysData, isLoading: isScreenplaysLoading } = useScreenplays( currentProjectId, { page: 1, pageSize: 20 } ); // 自动弹窗逻辑 if (storyboards.length === 0) { const hasScreenplays = screenplaysData.items && screenplaysData.items.length > 0; const mode = hasScreenplays ? 'preview' : 'upload'; setScreenplayParseDialogOpen(true, mode); } ``` ### 3. ParseFlowDialog 类型修复 **文件**: `client/src/components/features/storyboard/ParseFlowDialog.tsx` **修复内容**: - 移除 `parseStatusData` 的类型断言,使用正确的 `ParseStatusResponse` 类型 - 修复 `parsingStatus` 的类型转换问题 ## 功能流程 ### 场景 1: 项目无剧本 1. 用户打开项目 2. ProjectPage 检测到无分镜且无剧本 3. 自动弹出智能分镜工作台,显示 `upload` 模式 4. 用户可以上传剧本文件 ### 场景 2: 项目有剧本 1. 用户打开项目 2. ProjectPage 检测到无分镜但有剧本 3. 自动弹出智能分镜工作台,显示 `preview` 模式 4. ParseFlowDialogContainer 自动加载第一个剧本 5. ParseFlowDialog 通过 `useScreenplay` hook 自动查询并显示剧本内容 ### 场景 3: 项目有分镜 1. 用户打开项目 2. ProjectPage 检测到有分镜 3. 不自动弹窗,正常显示编辑器界面 ## 技术细节 ### React Query 数据流 ``` ProjectPage ├─ useScreenplays(projectId) → 获取剧本列表 └─ 决定弹窗模式 (preview/upload) ParseFlowDialogContainer ├─ useScreenplays(projectId) → 获取剧本列表 └─ 传递 firstScreenplayId 给 ParseFlowDialog ParseFlowDialog ├─ 接收 initialSelectedId (firstScreenplayId) ├─ 设置 activeScreenplayId └─ useScreenplay(activeScreenplayId) → 自动查询剧本详情 ``` ### 数据优先级 剧本内容显示优先级: 1. `activeScreenplayData?.content` (API 返回的详情数据) 2. `screenplayList.find(s => s.id === activeScreenplayId)?.content` (本地列表数据) 3. `''` (空字符串) ## 测试建议 ### 手动测试清单 - [ ] 测试无剧本项目:应显示 upload 模式 - [ ] 测试有剧本项目:应显示 preview 模式并加载剧本内容 - [ ] 测试剧本切换:切换不同剧本时内容正确更新 - [ ] 测试有分镜项目:不应自动弹窗 - [ ] 测试剧本上传:上传后自动切换到 preview 模式 - [ ] 测试异步解析:DOCX/PDF 文件上传后显示解析进度 ## 相关文件 - `client/src/pages/ProjectPage.tsx` - `client/src/components/features/storyboard/ParseFlowDialogContainer.tsx` - `client/src/components/features/storyboard/ParseFlowDialog.tsx` - `client/src/hooks/api/useScreenplays.ts` - `client/src/types/screenplay.ts` ## 后续优化 1. 添加剧本切换的过渡动画 2. 优化剧本列表的加载状态显示 3. 添加剧本内容的搜索和高亮功能 4. 支持多剧本对比查看