# Storyboard Mock 数据 API 字段对齐 > **日期**:2026-02-01 > **类型**:数据规范化 > **影响范围**:Mock 数据 --- ## 变更概述 对齐 `client/src/mocks/storyboards.ts` Mock 数据与后端 API 文档字段规范,确保前端开发时使用的 Mock 数据结构与真实 API 响应一致。 --- ## 主要变更 ### 1. 字段命名规范化 #### 主键和外键字段 - ✅ 保持 `id` (前端 camelCase) ← API `storyboard_id` (snake_case) - ✅ 保持 `projectId` ← API `project_id` #### 新增必填字段 - ✅ **shotNumber**: 镜号(如 "001", "002"),自动生成 - ✅ **shotSize**: 景别(SMALLINT 1-8) - ✅ **cameraMovement**: 运镜(SMALLINT 1-9) - ✅ **estimatedDuration**: 预估时长(秒) - ✅ **actualDuration**: 实际时长(秒) #### 字段类型调整 - ✅ **dialogue**: 从数组改为单个字符串(API 规范) - ✅ **cameraMovement**: 从字符串改为枚举数字(1-9) - ✅ **resources**: 结构从 `{ resourceId, displayOrder }` 改为 `{ id, name }` ### 2. 枚举类型定义 #### 景别枚举(ShotSize) ```typescript export enum ShotSize { EXTREME_WIDE_SHOT = 1, // 大远景 WIDE_SHOT = 2, // 远景 FULL_SHOT = 3, // 全景 MEDIUM_SHOT = 4, // 中景 MEDIUM_CLOSE_UP = 5, // 中近景 CLOSE_UP = 6, // 特写 EXTREME_CLOSE_UP = 7, // 大特写 OVER_SHOULDER = 8, // 过肩镜头 } ``` #### 运镜枚举(CameraMovement) ```typescript export enum CameraMovement { STATIC = 1, // 固定 PAN = 2, // 摇镜 TILT = 3, // 俯仰 DOLLY = 4, // 推拉 ZOOM = 5, // 变焦 TRACKING = 6, // 跟踪 ARC = 7, // 环绕 CRANE = 8, // 升降 HANDHELD = 9, // 手持 } ``` ### 3. 资源关联结构 #### API 格式 ```json { "resources": { "characters": [{ "id": "uuid", "name": "角色名" }], "scenes": [{ "id": "uuid", "name": "场景名" }], "props": [{ "id": "uuid", "name": "道具名" }] } } ``` #### Mock 格式(前端使用 locations) ```typescript { resources: { characters: [{ id: "uuid", name: "角色名" }], locations: [{ id: "uuid", name: "场景名" }], // 对应 API 的 scenes props: [{ id: "uuid", name: "道具名" }] } } ``` ### 4. UI 扩展字段 以下字段仅用于前端 UI,不在 API 中: - `dialogues`: 对白数组(前端扩展) - `prompt`: AI 生成提示词 - `status`: 生成状态 - `angle`: 拍摄角度 - `isFinalized`: 是否已定稿 - `imageUrl`: 图片 URL - `videoUrl`: 视频 URL - `order`: 兼容字段(等同于 orderIndex) - `duration`: 兼容字段(计算值) --- ## 文件变更 ### 修改的文件 - `client/src/mocks/storyboards.ts` - 更新 Mock 数据结构 ### 新增的文件 - `client/src/mocks/storyboards-api-mapping.md` - 字段映射文档 - `client/src/mocks/generate-storyboards.py` - 数据生成脚本 - `client/src/mocks/storyboards-generated.txt` - 生成的示例代码 --- ## API 文档参考 - [Storyboard Service 文档](../../requirements/backend/04-services/project/storyboard-service.md) - [ADR-004: 景别和运镜标准化](../../architecture/adrs/004-shot-size-camera-movement-standardization.md) --- ## 数据示例 ### 更新前(旧格式) ```typescript { id: '018e1234-5678-7abc-8def-300000000001', projectId: '018e1234-5678-7abc-8def-100000000001', title: '五行山全景', description: '...', orderIndex: 1, startTime: 0, endTime: 4, cameraMovement: 'crane_down', // ❌ 字符串 resources: { locations: [{ resourceId: 'uuid', displayOrder: 0 }] // ❌ 旧结构 } } ``` ### 更新后(新格式) ```typescript { id: '018e1234-5678-7abc-8def-300000000001', projectId: '018e1234-5678-7abc-8def-100000000001', shotNumber: '001', // ✅ 新增 title: '五行山全景', description: '...', dialogue: undefined, // ✅ 单个字符串 shotSize: ShotSize.EXTREME_WIDE_SHOT, // ✅ 枚举数字 cameraMovement: CameraMovement.CRANE, // ✅ 枚举数字 estimatedDuration: 4.0, // ✅ 新增 actualDuration: 4.0, // ✅ 新增 orderIndex: 1, startTime: 0, endTime: 4, metadata: { // ✅ 扩展字段 lighting: '自然光', weather: '阴天', time_of_day: '傍晚' }, resources: { locations: [{ id: 'uuid', name: '五行山' }] // ✅ 新结构 } } ``` --- ## 后续工作 ### 类型定义更新 - [ ] 更新 `client/src/types/storyboard.ts` 类型定义 - [ ] 添加 `ShotSize` 和 `CameraMovement` 枚举导出 - [ ] 更新 `StoryboardWithUI` 接口 ### 组件适配 - [ ] 更新使用分镜数据的组件(PreviewPanel, Timeline 等) - [ ] 适配新的 `resources` 结构 - [ ] 处理 `dialogue` 字符串与 `dialogues` 数组的转换 ### API 集成 - [ ] 创建 API 响应转换函数(snake_case → camelCase) - [ ] 实现枚举值的双向转换(数字 ↔ 字符串) - [ ] 添加 API 响应类型定义 --- ## 测试建议 1. **类型检查**:运行 `npm run type-check` 确保类型正确 2. **组件测试**:测试使用分镜数据的所有组件 3. **数据转换**:测试 API 响应转换逻辑 4. **枚举映射**:验证景别和运镜枚举的正确性 --- ## 参考资料 - [Storyboard Service API 文档](../../requirements/backend/04-services/project/storyboard-service.md) - [国际影视行业标准](https://www.filmdaft.com/shot-sizes/) - [PostgreSQL SMALLINT 枚举设计](../../architecture/adrs/005-variant-to-tag-system-refactor.md)