# 角色/场景/道具详情编辑 API 对接 **日期**: 2026-02-09 **类型**: 功能实现 + Bug修复 **影响范围**: 前端 - 预览面板 ## 概述 1. 实现角色、场景、道具详情编辑功能与后端 API 的对接 2. 修复详情面板字段显示问题(从 meta_data 正确读取字段) ## 变更内容 ### 1. 新增 API Hooks **文件**: `client/src/hooks/api/useProjectElements.ts` (新建) - `useUpdateCharacter()` - 更新角色信息 - `useUpdateLocation()` - 更新场景信息 - `useUpdateProp()` - 更新道具信息 ### 2. 修复字段显示问题 ✅ **问题**:详情面板无法正确显示角色的 `gender`、`visual_age`、`personality`、`appearance` 等字段 **根本原因**: 1. ❌ 误以为后端将这些字段放在 `meta_data` 中 2. ✅ 实际上后端直接将这些字段放在响应的**顶层** **实际后端响应结构**: ```json { "character_id": "...", "name": "前妻", "description": "...", "role_type": "main", // 字符串,不是数字 "is_offscreen": true, "gender": null, // 顶层字段 "visual_age": "35岁", // 顶层字段 "personality": null, // 顶层字段 "appearance": null, // 顶层字段 "tags": [...] } ``` **修复内容**: 1. **更新接口定义** (`project-elements.ts`) - 在 `CharacterDetailResponse` 中添加顶层字段:`gender`, `visual_age`, `personality`, `appearance` 2. **修复字段读取** (`usePreviewData.ts`) - 从 `characterDetail.gender` 等顶层字段读取(而非 `meta_data.gender`) - 添加 `role_type` 映射:`"main"` → `"protagonist"` 3. **修复字段保存** (`usePreviewActions.ts`) - 将 `gender`, `visual_age`, `personality`, `appearance` 直接放在 payload 顶层 - 修复 `role_type` 映射:`"protagonist"` → `"main"`(字符串,不是数字) - 移除错误的 `meta_data` 封装 ### 3. 字段映射规则 #### 角色 (Character) **顶层字段**: - `name` - 角色名称 - `description` - 详细描述 - `role_type` - 角色类型(字符串:`"main"`, `"supporting"`, `"extra"`) - `is_offscreen` - 是否为画外音 - `gender` - 性别 - `visual_age` - 视觉年龄 - `personality` - 性格描述 - `appearance` - 外貌描述 **前端 ↔ 后端映射**: - `roleType: "protagonist"` ↔ `role_type: "main"` - `roleType: "supporting"` ↔ `role_type: "supporting"` - `roleType: "extra"` ↔ `role_type: "extra"` #### 场景 (Location) **顶层字段**: - `name` - 场景名称 - `description` - 详细描述 - `location` - 场景布景 (前端字段 `setting`) **meta_data 字段**: - `location_type` - 景别 (外景/内景) - `time_of_day` - 时间 - `weather` - 天气 - `atmosphere` - 氛围 - `real_world_location` - 现实取景地参考 #### 道具 (Prop) **顶层字段**: - `name` - 道具名称 - `description` - 详细描述 **meta_data 字段**: - `prop_type` - 道具类型 - `usage` - 使用方法/关键功能 ### 3. 更新 usePreviewActions **文件**: `client/src/components/features/preview/hooks/usePreviewActions.ts` 新增三个更新方法: - `handleUpdateCharacter` - 处理角色信息更新 - `handleUpdateLocation` - 处理场景信息更新 - `handleUpdateProp` - 处理道具信息更新 ### 4. 更新组件传递链 **文件**: `client/src/components/features/preview/PreviewPanel.tsx` - 在两处 `SingleViewPlayer` 调用中添加 `onUpdate` prop - 根据资源类型 (type: 1/2/3) 传递对应的更新方法 **文件**: `client/src/components/features/preview/SingleViewPlayer.tsx` - 已有 `onUpdate` prop 并传递给 `PreviewInfoPanel`(无需修改) **文件**: `client/src/components/features/preview/PreviewInfoPanel.tsx` - 已有 `onUpdate` 回调并在 `handleSaveInfo` 中调用(无需修改) ### 5. UI 优化 **文件**: `client/src/components/features/preview/PreviewInfoPanel.tsx` - 场景名称和景别放在同一行显示 - 移除道具的"数量"和"尺寸"字段 - "空间类型" 改为 "景别",placeholder 改为 "外景/内景" ## API 端点 ``` PUT /api/v1/projects/{project_id}/characters/{character_id} PUT /api/v1/projects/{project_id}/locations/{location_id} PUT /api/v1/projects/{project_id}/props/{prop_id} ``` ## 测试建议 1. **角色编辑测试** - 修改角色名称、描述、角色类型 - 修改性别、视觉年龄、性格、外貌 - 切换画外音开关 - 验证保存后数据正确存储到 meta_data 2. **场景编辑测试** - 修改场景名称、描述、布景 - 修改景别、时间、天气、氛围 - 验证字段映射正确 (locationType → location_type) 3. **道具编辑测试** - 修改道具名称、描述、类型 - 修改使用方法 - 确认数量和尺寸字段已移除 4. **错误处理测试** - 测试网络错误时的 toast 提示 - 测试缺少 projectId 的异常情况 - 验证缓存刷新机制 ## 注意事项 1. **字段命名统一**:前端和后端统一使用 `visual_age`(不再使用 `age`) 2. **字段位置**:角色的 `gender`, `visual_age`, `personality`, `appearance` 在响应的**顶层**,不在 `meta_data` 中 3. **角色类型映射**:前端使用字符串枚举,后端也使用字符串(`"main"`, `"supporting"`, `"extra"`) 4. **缓存更新**:成功保存后自动 invalidate 相关查询缓存 5. **Toast 提示**:成功/失败都有明确的用户反馈 ## 相关文档 - API 定义: `client/src/services/api/project-elements.ts` - 后端路由: `server/app/api/v1/routes/characters.py`, `locations.py`, `props.py`