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.
9.6 KiB
9.6 KiB
项目资源服务实现总结
日期: 2026-02-02
类型: 功能实现
影响范围: 后端 - 项目资源管理、子项目功能
概述
完整实现了项目资源服务(ProjectResourceService)和子项目功能,支持项目专属素材管理(角色、场景、道具、实拍)和分镜素材关联。
实现内容
1. 数据模型
ProjectResource 模型 (server/app/models/project_resource.py)
- 支持 4 种素材类型:角色(1)、场景(2)、道具(3)、实拍(4)
- 文件信息:URL、缩略图、尺寸、MIME 类型、校验和
- 标签关联:
element_tag_id、element_name、tag_label(冗余字段) - AI 生成:
ai_job_id、extra_data(JSONB) - 使用统计:
usage_count(引用计数) - 软删除:
deleted_at
StoryboardResource 关联模型
- 多对多关联:分镜 ↔ 素材
- 类型标记:
resource_type(冗余存储) - 自动维护
usage_count
Project 模型扩展
parent_project_id: 父项目 ID(子项目功能)screenplay_id: 关联剧本 IDis_subproject属性:判断是否为子项目
2. 仓储层
ProjectResourceRepository (server/app/repositories/project_resource_repository.py)
create(): 创建素材get_by_id(): 获取单个素材get_by_project(): 获取项目素材列表(支持类型、标签、搜索过滤)update(): 更新素材delete(): 软删除素材get_by_checksum(): 通过校验和查找(去重)increment_usage()/decrement_usage(): 维护使用计数
ProjectRepository 扩展
create_subproject(): 创建子项目get_subprojects(): 获取子项目列表count_subprojects(): 统计子项目数量
3. Schema 定义
请求 Schema (server/app/schemas/project_resource.py)
ProjectResourceCreate: 创建素材(上传)ProjectResourceUpdate: 更新素材AIGenerateRequest: AI 生成素材请求
响应 Schema
ProjectResourceResponse: 素材详情ProjectResourceListResponse: 素材列表(分页)ResourceUsageResponse: 使用统计
4. 服务层
ProjectResourceService (server/app/services/project_resource_service.py)
-
素材上传:
upload_image(): 上传图片素材upload_video(): 上传视频素材(支持 ffmpeg 处理)- 自动生成缩略图
- 文件去重(基于 SHA256)
-
AI 生成:
generate_resource(): AI 生成素材- 支持角色、场景、道具生成
- 自动关联 AI 任务
-
素材管理:
get_resource(): 获取素材详情list_resources(): 获取素材列表(支持过滤、搜索、分页)update_resource(): 更新素材delete_resource(): 删除素材get_usage_stats(): 获取使用统计
-
权限检查:
_check_project_permission(): 检查项目权限
StoryboardResourceService (server/app/services/storyboard_resource_service.py)
add_resource_to_storyboard(): 添加素材到分镜remove_resource_from_storyboard(): 从分镜移除素材get_storyboard_resources(): 获取分镜的所有素材get_resource_storyboards(): 获取素材关联的分镜batch_add_resources(): 批量添加素材batch_remove_resources(): 批量移除素材- 自动维护
usage_count字段
ProjectService 扩展
create_subproject(): 创建子项目get_subprojects(): 获取子项目列表(分页)
5. API 路由
ProjectResourcesRouter (server/app/api/v1/project_resources.py)
POST /api/v1/projects/{project_id}/resources/upload/image # 上传图片
POST /api/v1/projects/{project_id}/resources/upload/video # 上传视频
POST /api/v1/projects/{project_id}/resources/generate # AI 生成
GET /api/v1/projects/{project_id}/resources # 获取列表
GET /api/v1/projects/{project_id}/resources/{resource_id} # 获取详情
PUT /api/v1/projects/{project_id}/resources/{resource_id} # 更新素材
DELETE /api/v1/projects/{project_id}/resources/{resource_id} # 删除素材
GET /api/v1/projects/{project_id}/resources/{resource_id}/usage # 使用统计
ProjectsRouter 扩展 (server/app/api/v1/projects.py)
GET /api/v1/projects/{parent_project_id}/subprojects # 获取子项目列表
6. 数据库迁移
迁移脚本 (server/alembic/versions/20260202_1600_add_project_resources_and_subprojects.py)
project_resources 表:
-
主键:
project_resource_id(UUID v7) -
索引:
idx_project_resources_project_id(project_id, WHERE deleted_at IS NULL)idx_project_resources_type(type, WHERE deleted_at IS NULL)idx_project_resources_created_by(created_by, WHERE deleted_at IS NULL)idx_project_resources_checksum(checksum) - 去重idx_project_resources_element_tag_id(element_tag_id, WHERE NOT NULL)idx_project_resources_ai_job_id(ai_job_id, WHERE NOT NULL)idx_project_resources_usage_count(usage_count, WHERE deleted_at IS NULL)idx_project_resources_extra_data_gin(extra_data) - GIN 索引idx_project_resources_name_trgm(name) - 全文搜索idx_project_resources_element_name_trgm(element_name) - 全文搜索idx_project_resources_tag_label_trgm(tag_label) - 全文搜索
-
约束:
usage_count >= 0- 实拍素材不能有标签关联
storyboard_resources 表:
- 主键:
id(UUID v7) - 索引:
idx_storyboard_resources_storyboard_ididx_storyboard_resources_project_resource_ididx_storyboard_resources_type
- 唯一约束:
(storyboard_id, project_resource_id)
projects 表扩展:
- 新增字段:
parent_project_id(UUID, nullable)screenplay_id(UUID, nullable)
- 索引:
idx_projects_parent_project_ididx_projects_screenplay_id
- 约束:子项目必须有
screenplay_id
7. Docker 配置
Dockerfile 更新 (server/Dockerfile)
- 添加
ffmpeg依赖(视频处理)
技术亮点
1. 文件去重
- 基于 SHA256 校验和
- 避免重复上传相同文件
- 节省存储空间
2. 使用计数维护
- 自动维护
usage_count字段 - 通过
StoryboardResourceService统一管理 - 支持批量操作
3. 冗余字段设计
element_name、tag_label冗余存储- 减少 JOIN 查询
- 提升列表查询性能
4. 全文搜索
- 使用 pg_trgm 扩展
- 支持模糊搜索素材名称、元素名称、标签
- GIN 索引优化 JSONB 查询
5. 权限控制
- 继承项目权限
- 支持 viewer/editor/owner 角色
- 应用层校验(无物理外键)
6. 软删除
deleted_at字段- 索引过滤
WHERE deleted_at IS NULL - 保留历史数据
数据流程
上传素材流程
1. 用户上传文件 → API 接收
2. 计算 SHA256 校验和
3. 检查是否已存在(去重)
4. 上传到文件存储服务
5. 生成缩略图(图片/视频)
6. 创建 ProjectResource 记录
7. 返回素材信息
AI 生成素材流程
1. 用户提交生成请求 → API 接收
2. 检查项目权限
3. 调用 AI 服务生成素材
4. 下载生成的文件
5. 上传到文件存储
6. 创建 ProjectResource 记录(关联 ai_job_id)
7. 返回素材信息
分镜关联素材流程
1. 用户添加素材到分镜
2. 创建 StoryboardResource 关联
3. 增加 ProjectResource.usage_count
4. 返回成功
移除时:
1. 删除 StoryboardResource 关联
2. 减少 ProjectResource.usage_count
3. 返回成功
待实现功能
1. 分镜素材关联 API
- 需要在
storyboards路由中添加:POST /api/v1/storyboards/{storyboard_id}/resources- 添加素材DELETE /api/v1/storyboards/{storyboard_id}/resources/{resource_id}- 移除素材GET /api/v1/storyboards/{storyboard_id}/resources- 获取素材列表
2. 视频处理优化
- 当前为同步处理,大文件可能超时
- 建议改为异步任务(Celery)
- 支持进度查询
3. 缩略图生成优化
- 支持多种尺寸
- 支持自定义裁剪
- 异步生成
4. 素材库集成
- 从素材库导入到项目
- 支持批量导入
- 自动关联标签
5. 测试
- 单元测试
- 集成测试
- API 测试
注意事项
1. 字段命名变更
- ⚠️ 原设计中的
metadata字段改为extra_data - 原因:
metadata是 SQLAlchemy 保留字段名 - 影响:迁移脚本、模型定义、索引名称
2. ffmpeg 依赖
- 需要重新构建 Docker 镜像:
docker compose build app docker compose up -d app
3. 权限检查
- 所有操作都需要检查项目权限
- 使用
ProjectService._check_permission()方法 - 支持 viewer/editor/owner 角色
4. 文件存储
- 依赖
FileStorageService - 支持本地存储和 S3
- 自动生成唯一文件名
相关文档
- 需求文档:
docs/requirements/backend/04-services/project/project-resource-service.md - 项目服务文档:
docs/requirements/backend/04-services/project/project-service.md - 数据库设计:
docs/requirements/database-design.md - API 设计:
docs/requirements/api-design-specification.md
验证清单
- 数据库迁移成功执行
- API 路由注册成功
- 模型定义正确
- 仓储层实现完整
- 服务层实现完整
- Schema 定义完整
- 子项目功能实现
- 分镜素材关联服务实现
- ffmpeg 依赖安装(需要重新构建镜像)
- API 端点测试
- 权限检查测试
- 文件上传测试
- AI 生成测试
下一步
- 重新构建 Docker 镜像(安装 ffmpeg)
- 实现分镜素材关联 API
- 编写测试用例
- 性能优化(异步任务、缓存)
- 前端集成