# 修复项目 API 响应序列化问题 **日期**: 2026-01-21 **类型**: Bug 修复 **影响范围**: 后端 API - 项目模块 ## 问题描述 创建项目时前端收到的响应数据格式不正确,导致: 1. 前端无法正确获取项目 ID 2. 导航到项目详情页时使用了错误的 ID(undefined 或错误值) 3. 后端尝试将非 UUID 字符串转换为 UUID 时抛出 500 错误 ## 根本原因 `Project` 模型的 `id` 字段定义了 `alias="project_id"`,但 `ProjectResponse` schema 期望字段名为 `id`。FastAPI 在序列化时使用了 alias,导致前端收到的字段名不一致。 ```python # 模型定义 class Project(SQLModel, table=True): id: UUID = Field( sa_column=Column(...), alias="project_id" # ❌ 这导致了序列化问题 ) ``` ## 解决方案 在所有返回 `Project` 对象的 API 端点中,手动构建响应字典,确保字段名使用 camelCase 格式: ```python @router.post("", response_model=ProjectResponse, summary="创建项目") async def create_project(...): service = ProjectService(session) project = await service.create_project(...) # 手动构建响应 return { "id": str(project.id), # ✅ 使用正确的字段名 "name": project.name, "type": project.type_str, "ownerId": str(project.owner_id), "folderId": str(project.folder_id) if project.folder_id else None, # ... 其他字段 } ``` ## 修改的端点 1. `POST /api/v1/projects` - 创建项目 2. `GET /api/v1/projects` - 获取项目列表 3. `GET /api/v1/projects/{id}` - 获取项目详情 4. `PUT /api/v1/projects/{id}` - 更新项目 5. `POST /api/v1/projects/{id}/move` - 移动项目 6. `PUT /api/v1/projects/{id}/order` - 更新项目顺序 ## 测试验证 - [x] 创建项目返回正确的 UUID - [x] 项目列表返回正确的字段名 - [x] 项目详情返回正确的字段名 - [x] 更新项目返回正确的字段名 - [x] 前端可以正确导航到项目详情页 ## 后续优化建议 考虑以下方案避免手动构建响应: 1. **移除 alias**:修改 `Project` 模型,移除 `alias="project_id"` 2. **自定义序列化器**:实现自定义的 Pydantic 序列化器 3. **使用 model_dump**:在 service 层返回字典而非模型实例 ## 相关文件 - `server/app/api/v1/projects.py` - 修改了 6 个端点 - `server/app/models/project.py` - 问题根源(未修改) - `server/app/schemas/project.py` - Response schema 定义 ## 影响 - ✅ 修复了创建项目后无法跳转的问题 - ✅ 修复了 500 错误(UUID 转换失败) - ✅ 统一了前后端字段命名(camelCase) - ⚠️ 增加了代码重复(每个端点都需要手动构建响应)