From 5154395edba5564a7dca18b809f6916e2bb8be1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?API=E6=96=87=E6=A1=A3=E7=BB=B4=E6=8A=A4?= Date: Mon, 29 Jun 2026 10:53:32 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20API=20=E5=8F=82=E8=80=83=E6=96=87?= =?UTF-8?q?=E6=A1=A3=20v0.1.88=20+=20CHANGELOG=20=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 API 参考文档(v0.1.88),覆盖 17 个模块、50+ 端点 - 更新 CHANGELOG,记录 v0.1.77 ~ v0.1.88 的全部变更 - 重点更新:查重 API、订阅 API、标题库 API、配音库 API 变更内容: - 认证 API:7 个端点 - 项目 API:3 个端点 - 任务中心 API:2 个端点 - 素材诊断 API:1 个端点 - 素材库 API:2 个端点 - 素材 API:3 个端点 - 导入/分类任务 API:4 个端点 - 上传 API:3 个端点 - 分片上传 API:4 个端点 - 生成任务 API:3 个端点 - 成片 API:4 个端点 - 标题库 API:5 个端点 - 配音库 API:5 个端点 - 查重 API:5 个端点 - 订阅 API:5 个端点 --- CHANGELOG.md | 221 ++++- docs/API-REFERENCE-v0.1.88.md | 1688 +++++++++++++++++++++++++++++++++ 2 files changed, 1898 insertions(+), 11 deletions(-) create mode 100644 docs/API-REFERENCE-v0.1.88.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a46e975f..d8e383e22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,19 +1,218 @@ -# Changelog +## [v0.1.88] - 2026-06-29 -All notable changes to this project will be documented in this file. +### Phase 2 前端优化 - 完成 ✅ -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +**前端交互全面优化:** + +- 素材上传添加 project_id 参数 +- Drager 组件显示上传列表 +- 按钮防重复提交 +- 前端交互状态反馈补充(P0 第一批) + +--- + +## [v0.1.87] - 2026-06-29 + +### Bug 修复 + +- Docker compose 修复 mem_limit 冲突 + +--- + +## [v0.1.86] - 2026-06-29 + +### CI/CD 优化 + +- CI 优化 + +--- + +## [v0.1.85] - 2026-06-29 + +### CI/CD 优化 + +- CI 优化 + +--- + +## [v0.1.84] - 2026-06-29 + +### CI/CD 优化 + +- CI runner label 匹配修复 + +--- + +## [v0.1.83] - 2026-06-29 + +### CI/CD 优化 + +- CI SSH debug 修正 + +--- + +## [v0.1.82] - 2026-06-29 + +### CI/CD 优化 + +- CI SSH debug 修正 + +--- + +## [v0.1.81] - 2026-06-29 + +### CI/CD 优化 + +- CI runner label 匹配修复 + +--- + +## [v0.1.80] - 2026-06-28 + +### Bug 修复 + +- 修复 redirect_slashes + 标题字段匹配 + +--- + +## [v0.1.79] - 2026-06-28 + +### Deployment + +- Re-trigger deployment + +--- + +## [v0.1.78] - 2026-06-28 + +### Bug 修复 + +- 修复 500 错误 +- CORS 配置修复 +- redirect_slashes 禁用 + +--- + +## [v0.1.77] - 2026-06-28 + +### Bug 修复 + +- 修复标题库新建/编辑 — 前后端字段名不匹配导致 422 + +--- + +### Phase 2 功能合并(v0.1.77 ~ v0.1.88) + +**新增功能 PR:** + +- PR#74: Phase 1 核心重构 — 标题库 API、配音库 API、去 Project 层清理 +- PR#75: Phase 2 查重功能前端页面 +- PR#76: Phase 2 查重功能后端 API(5 个端点) +- PR#77: Phase 2 订阅管理前端页面 +- PR#78: Phase 2 订阅管理后端 API(5 个端点) +- PR#79: 修复一键生成页面废弃 API 调用 +- PR#80: 回退域对象 extra_meta → metadata +- PR#81: 删除查重 API 错误的 204 返回 +- PR#82: 查重上传接口错误信息不再泄露内部异常(安全审计) +- PR#83: 订阅 + 查重单元测试(63 用例) +- PR#84: 订阅管理前端对接真实 API +- PR#85: 禁用 redirect_slashes 修复 307 重定向 +- PR#90: 标题库字段名修复 +- PR#91: 标题/配音创建 500 修复 + CORS +- PR#94: 素材库新建自动获取默认 project_id +- PR#97: 前端交互状态反馈全面补充 + +--- + + +- Docker compose 修复 mem_limit 冲突 + +--- + +## [v0.1.86] - 2026-06-29 + +### CI/CD 优化 + +- CI 优化 + +--- + +## [v0.1.85] - 2026-06-29 + +### CI/CD 优化 + +- CI 优化 + +--- + +## [v0.1.84] - 2026-06-29 + +### CI/CD 优化 + +- CI runner label 匹配修复 + +--- + +## [v0.1.83] - 2026-06-29 + +### CI/CD 优化 + +- CI SSH debug 修正 + +--- + +## [v0.1.82] - 2026-06-29 + +### CI/CD 优化 + +- CI SSH debug 修正 + +--- + +## [v0.1.81] - 2026-06-29 + +### CI/CD 优化 + +- CI runner label 匹配修复 + +--- + +## [v0.1.80] - 2026-06-28 + +### Bug 修复 + +- 修复 redirect_slashes + 标题字段匹配 + +--- + +## [v0.1.79] - 2026-06-28 + +### Deployment + +- Re-trigger deployment + +--- + +## [v0.1.78] - 2026-06-28 + +### Bug 修复 + +- 修复 500 错误 +- CORS 配置修复 +- redirect_slashes 禁用 + +--- + +## [v0.1.77] - 2026-06-28 + +### Bug 修复 + +- 修复标题库新建/编辑 — 前后端字段名不匹配导致 422 + +--- ## [Unreleased] -## [1.2.0] - 2026-06-19 - -### Phase 7: 核心视频剪辑业务 - 完成 ✅ - -**完成进度:** 100% -**状态:** 已完成并验证 - #### Added **素材管理:** diff --git a/docs/API-REFERENCE-v0.1.88.md b/docs/API-REFERENCE-v0.1.88.md new file mode 100644 index 000000000..308c504d6 --- /dev/null +++ b/docs/API-REFERENCE-v0.1.88.md @@ -0,0 +1,1688 @@ +# 小虾 SaaS API 参考文档 + +**版本**: v0.1.88 +**更新日期**: 2026-06-29 +**基础 URL**: `/api/v1` + +--- + +## 目录 + +1. [认证 (Auth)](#1-认证-auth) +2. [项目 (Project)](#2-项目-project) +3. [任务中心 (TaskCenter)](#3-任务中心-taskcenter) +4. [素材诊断 (AssetDiagnosis)](#4-素材诊断-assetdiagnosis) +5. [素材库 (AssetLibrary)](#5-素材库-assetlibrary) +6. [素材 (Asset)](#6-素材-asset) +7. [导入任务 (IngestJob)](#7-导入任务-ingestjob) +8. [分类任务 (ClassificationJob)](#8-分类任务-classificationjob) +9. [上传 (Upload)](#9-上传-upload) +10. [分片上传 (ChunkedUpload)](#10-分片上传-chunkedupload) +11. [生成任务 (Generation)](#11-生成任务-generation) +12. [生成视频 (GeneratedVideo)](#12-生成视频-generatedvideo) +13. [标题库 (TitleLibrary)](#13-标题库-titlelibrary) +14. [配音库 (VoiceLibrary)](#14-配音库-voicelibrary) +15. [查重 (Duplication)](#15-查重-duplication) +16. [订阅 (Subscription)](#16-订阅-subscription) + +--- + +## 通用说明 + +### 认证方式 + +除特别说明外,所有 API 端点均需要认证。认证通过以下方式: + +**请求头**: +``` +Authorization: Bearer +``` + +获取 access_token 请参见 [登录接口](#post-apiv1autologin)。 + +### 错误响应格式 + +```json +{ + "detail": "错误描述信息" +} +``` + +### HTTP 状态码 + +| 状态码 | 说明 | +|--------|------| +| 200 | 请求成功 | +| 201 | 资源创建成功 | +| 204 | 请求成功(无返回内容) | +| 400 | 请求参数错误 | +| 401 | 未认证或 token 无效 | +| 403 | 无权限访问 | +| 404 | 资源不存在 | +| 409 | 资源冲突 | +| 413 | 文件过大 | +| 415 | 不支持的文件类型 | +| 422 | 请求格式正确但无法处理 | +| 429 | 配额超限 | +| 500 | 服务器内部错误 | +| 503 | 服务暂不可用 | + +--- + +## 1. 认证 (Auth) + +**基础路径**: `/api/v1/auth` + +### POST /register + +用户注册。 + +**认证**: 否 + +**请求 Body**: +```json +{ + "email": "user@example.com", + "password": "your_password", + "username": "username", + "display_name": "显示名称" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| email | string | 是 | 邮箱地址 | +| password | string | 是 | 密码(建议至少 8 位) | +| username | string | 是 | 用户名(唯一) | +| display_name | string | 否 | 显示名称,默认同 username | + +**响应** `201 Created`: +```json +{ + "user_id": "用户ID", + "email": "user@example.com", + "username": "username", + "display_name": "显示名称", + "message": "注册成功!" +} +``` + +--- + +### POST /login + +用户登录。 + +**认证**: 否 + +**请求 Body**: +```json +{ + "email": "user@example.com", + "password": "your_password" +} +``` + +**响应** `200 OK`: +```json +{ + "access_token": "eyJhbGciOiJIUzI1NiIs...", + "refresh_token": "eyJhbGciOiJIUzI1NiIs...", + "token_type": "bearer", + "user_id": "用户ID", + "email": "user@example.com", + "username": "username", + "display_name": "显示名称", + "expires_in": 3600 +} +``` + +--- + +### POST /refresh + +刷新访问令牌。 + +**认证**: 否 + +**请求 Body**: +```json +{ + "refresh_token": "eyJhbGciOiJIUzI1NiIs..." +} +``` + +**响应** `200 OK`: 同登录响应 + +--- + +### GET /verify-email + +验证邮箱(通过链接点击)。 + +**认证**: 否 + +**查询参数**: +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| token | string | 是 | 邮箱验证 token | + +**响应** `200 OK`: +```json +{ + "message": "邮箱验证成功" +} +``` + +--- + +### POST /verify-email + +验证邮箱(通过 API)。 + +**认证**: 否 + +**请求 Body**: +```json +{ + "token": "邮箱验证 token" +} +``` + +**响应** `200 OK`: +```json +{ + "message": "邮箱验证成功" +} +``` + +--- + +### POST /password/forgot + +请求密码重置。 + +**认证**: 否 + +**请求 Body**: +```json +{ + "email": "user@example.com" +} +``` + +**响应** `202 Accepted`: +```json +{ + "message": "如果账户存在,密码重置邮件已发送" +} +``` + +--- + +### POST /password/reset + +重置密码。 + +**认证**: 否 + +**请求 Body**: +```json +{ + "token": "密码重置 token", + "new_password": "new_password123" +} +``` + +**响应** `200 OK`: +```json +{ + "message": "密码重置成功" +} +``` + +--- + +### GET /me + +获取当前登录用户信息。 + +**认证**: 是 + +**响应** `200 OK`: +```json +{ + "user_id": "用户ID", + "email": "user@example.com", + "username": "username", + "display_name": "显示名称", + "email_verified": true +} +``` + +--- + +## 2. 项目 (Project) + +**基础路径**: `/api/v1/projects` + +### GET / + +获取用户的所有项目列表。 + +**认证**: 是 + +**响应** `200 OK`: +```json +{ + "items": [ + { + "id": "项目ID", + "owner_user_id": "拥有者ID", + "name": "项目名称", + "description": "项目描述", + "shared_users": [] + } + ] +} +``` + +--- + +### POST / + +创建新项目。 + +**认证**: 是 + +**请求 Body**: +```json +{ + "name": "项目名称", + "description": "项目描述(可选)" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| name | string | 是 | 项目名称(1-100字符) | +| description | string | 否 | 项目描述(最多500字符) | + +**响应** `200 OK`: +```json +{ + "id": "项目ID", + "owner_user_id": "拥有者ID", + "name": "项目名称", + "description": "项目描述", + "shared_users": [] +} +``` + +--- + +### GET /{project_id} + +获取指定项目详情。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| project_id | string | 项目 ID | + +**响应** `200 OK`: +```json +{ + "id": "项目ID", + "owner_user_id": "拥有者ID", + "name": "项目名称", + "description": "项目描述", + "shared_users": [] +} +``` + +--- + +## 3. 任务中心 (TaskCenter) + +**基础路径**: `/api/v1` + +### GET /projects/{project_id}/tasks + +获取项目的所有任务(导入任务 + 生成任务)。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| project_id | string | 项目 ID | + +**响应** `200 OK`: +```json +{ + "items": [ + { + "id": "task:任务ID", + "task_type": "ingest 或 generation", + "project_id": "项目ID", + "status": "pending | processing | completed | failed", + "progress": 0.0, + "current_step": "当前步骤描述", + "error_message": "", + "user_message": "", + "retryable": false, + "source_id": "原始任务ID", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z" + } + ] +} +``` + +--- + +### POST /tasks/{task_type}/{source_id}/retry + +重试失败的任务。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| task_type | string | 任务类型:`ingest` 或 `generation` | +| source_id | string | 原始任务 ID | + +**响应** `200 OK`: 返回重试后的任务信息(同上) + +--- + +## 4. 素材诊断 (AssetDiagnosis) + +**基础路径**: `/api/v1` + +### GET /projects/{project_id}/asset-diagnosis + +获取项目的素材健康度诊断。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| project_id | string | 项目 ID | + +**响应** `200 OK`: +```json +{ + "project_id": "项目ID", + "readiness_score": 75, + "readiness_label": "素材充足", + "total_assets": 10, + "ready_assets": 8, + "video_assets": 5, + "image_assets": 2, + "voice_assets": 1, + "total_duration_seconds": 120.5, + "estimated_video_count": 3, + "used_assets": 2, + "unused_assets": 6, + "pending_review_assets": 0, + "smart_views": [ + { + "key": "recommended", + "label": "推荐素材", + "count": 5, + "description": "已导入完成、可参与生成的视频素材" + } + ], + "gaps": [ + { + "key": "missing_voice", + "severity": "info", + "message": "暂未配置配音素材", + "recommendation": "如果本项目需要口播/旁白,请上传配音素材" + } + ] +} +``` + +--- + +## 5. 素材库 (AssetLibrary) + +**基础路径**: `/api/v1/asset-libraries` + +### GET / + +获取素材库列表。 + +**认证**: 是 + +**查询参数**: +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| project_id | string | 否 | 按项目 ID 筛选 | + +**响应** `200 OK`: +```json +{ + "items": [ + { + "id": "素材库ID", + "project_id": "项目ID", + "name": "素材库名称", + "kind": "video | voice | image", + "asset_count": 10, + "total_size": 104857600 + } + ] +} +``` + +--- + +### POST / + +创建素材库。 + +**认证**: 是 + +**请求 Body**: +```json +{ + "project_id": "项目ID", + "name": "素材库名称", + "kind": "video" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| project_id | string | 是 | 所属项目 ID | +| name | string | 是 | 素材库名称(1-100字符) | +| kind | string | 是 | 类型:`video`、`voice` 或 `image` | + +**响应** `200 OK`: +```json +{ + "id": "素材库ID", + "project_id": "项目ID", + "name": "素材库名称", + "kind": "video", + "asset_count": 0, + "total_size": 0 +} +``` + +--- + +## 6. 素材 (Asset) + +**基础路径**: `/api/v1/assets` + +### GET / + +获取素材列表。 + +**认证**: 是 + +**查询参数**: +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| library_id | string | 是 | 素材库 ID | + +**响应** `200 OK`: +```json +{ + "items": [ + { + "id": "素材ID", + "project_id": "项目ID", + "library_id": "素材库ID", + "name": "素材名称.mp4", + "storage_key": "uploads/xxx/素材名称.mp4", + "mime_type": "video/mp4", + "metadata": {}, + "file_size": 10485760, + "thumbnail_url": "https://...", + "duration": 120.5, + "width": 1920, + "height": 1080, + "fps": 30.0, + "codec": "h264", + "status": "ready", + "classification_status": "completed", + "quality_score": 85.0, + "uploaded_by_user_id": "用户ID" + } + ] +} +``` + +--- + +### POST / + +创建素材记录(通常由上传流程自动调用)。 + +**认证**: 是 + +**请求 Body**: +```json +{ + "project_id": "项目ID", + "library_id": "素材库ID", + "name": "素材名称.mp4", + "storage_key": "uploads/xxx/素材名称.mp4", + "mime_type": "video/mp4", + "metadata": {}, + "file_size": 10485760, + "thumbnail_url": "https://...", + "duration": 120.5, + "width": 1920, + "height": 1080, + "fps": 30.0, + "codec": "h264", + "status": "uploading", + "classification_status": "pending", + "quality_score": 85.0 +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| project_id | string | 是 | 项目 ID | +| library_id | string | 是 | 素材库 ID | +| name | string | 是 | 素材名称(1-100字符) | +| storage_key | string | 是 | 存储路径 | +| mime_type | string | 是 | MIME 类型 | +| metadata | object | 否 | 元数据 | +| file_size | integer | 否 | 文件大小(字节) | +| thumbnail_url | string | 否 | 缩略图 URL | +| duration | float | 否 | 时长(秒) | +| width | integer | 否 | 宽度 | +| height | integer | 否 | 高度 | +| fps | float | 否 | 帧率 | +| codec | string | 否 | 编码格式 | +| status | string | 否 | 状态(默认 uploading) | +| classification_status | string | 否 | 分类状态(默认 pending) | +| quality_score | float | 否 | 质量分数(0-100) | + +**响应** `200 OK`: 返回创建的素材对象 + +--- + +### PATCH /{asset_id}/review + +更新素材审核状态。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| asset_id | string | 素材 ID | + +**请求 Body**: +```json +{ + "review_status": "pending_review | approved | rejected" +} +``` + +**响应** `200 OK`: 返回更新的素材对象 + +--- + +## 7. 导入任务 (IngestJob) + +**基础路径**: `/api/v1/ingest-jobs` + +### GET /{job_id} + +获取导入任务详情。 + +**认证**: 否(内部 API) + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| job_id | string | 任务 ID | + +**响应** `200 OK`: +```json +{ + "id": "任务ID", + "project_id": "项目ID", + "library_id": "素材库ID", + "storage_key": "uploads/xxx/file.mp4", + "status": "completed", + "error_message": "", + "result_asset_id": "素材ID" +} +``` + +--- + +### POST / + +提交新的导入任务。 + +**认证**: 否(内部 API) + +**请求 Body**: +```json +{ + "project_id": "项目ID", + "library_id": "素材库ID", + "storage_key": "uploads/xxx/file.mp4" +} +``` + +**响应** `200 OK`: 返回创建的任务对象 + +--- + +## 8. 分类任务 (ClassificationJob) + +**基础路径**: `/api/v1/classification-jobs` + +### GET /{job_id} + +获取分类任务详情。 + +**认证**: 否(内部 API) + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| job_id | string | 任务 ID | + +**响应** `200 OK`: +```json +{ + "id": "任务ID", + "project_id": "项目ID", + "asset_id": "素材ID", + "status": "completed", + "classification": "video", + "confidence": 0.95, + "error_message": "" +} +``` + +--- + +### POST / + +提交新的分类任务。 + +**认证**: 否(内部 API) + +**请求 Body**: +```json +{ + "project_id": "项目ID", + "asset_id": "素材ID" +} +``` + +**响应** `200 OK`: 返回创建的任务对象 + +--- + +## 9. 上传 (Upload) + +**基础路径**: `/api/v1/upload` + +### POST /direct/prepare + +准备直传 OSS(获取表单签名)。 + +**认证**: 是 + +**请求 Body**: +```json +{ + "project_id": "项目ID", + "library_id": "素材库ID", + "filename": "video.mp4", + "content_type": "video/mp4", + "file_size": 104857600 +} +``` + +**响应** `200 OK`: +```json +{ + "upload_url": "https://oss.example.com/...", + "method": "POST", + "storage_key": "uploads/xxx/video.mp4", + "expires_at": "2024-01-01T12:00:00Z", + "fields": { + "OSSAccessKeyId": "...", + "policy": "...", + "signature": "...", + "key": "uploads/xxx/video.mp4" + }, + "max_size_bytes": 104857600 +} +``` + +--- + +### POST /direct/complete + +确认直传完成并创建导入任务。 + +**认证**: 是 + +**请求 Body**: +```json +{ + "project_id": "项目ID", + "library_id": "素材库ID", + "storage_key": "uploads/xxx/video.mp4" +} +``` + +**响应** `200 OK`: +```json +{ + "storage_key": "uploads/xxx/video.mp4", + "ingest_job_id": "导入任务ID" +} +``` + +--- + +### POST / + +上传素材文件(multipart/form-data)。 + +**认证**: 是 + +**表单字段**: +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| project_id | string | 是 | 项目 ID | +| library_id | string | 是 | 素材库 ID | +| file | file | 是 | 上传的文件 | + +**响应** `200 OK`: +```json +{ + "storage_key": "uploads/xxx/video.mp4", + "ingest_job_id": "导入任务ID", + "url": "https://oss.example.com/uploads/xxx/video.mp4" +} +``` + +**支持的文件类型**: +- 视频: `video/mp4`, `video/mpeg`, `video/quicktime`, `video/x-msvideo`, `video/webm`, `video/x-matroska`, `video/3gpp` +- 音频: `audio/mpeg`, `audio/wav`, `audio/ogg`, `audio/flac`, `audio/aac`, `audio/mp3`, `audio/x-m4a` +- 图片: `image/jpeg`, `image/png`, `image/gif`, `image/webp`, `image/bmp`, `image/svg+xml`, `image/tiff` + +--- + +## 10. 分片上传 (ChunkedUpload) + +**基础路径**: `/api/v1/upload/chunk` + +适用于大文件上传(最大 2GB)。 + +### POST /init + +初始化分片上传。 + +**认证**: 是 + +**请求 Body**: +```json +{ + "filename": "large_video.mp4", + "file_size": 1073741824, + "total_chunks": 200, + "content_type": "video/mp4", + "project_id": "项目ID", + "library_id": "素材库ID" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| filename | string | 是 | 文件名(1-255字符) | +| file_size | integer | 是 | 文件大小(最大 2GB) | +| total_chunks | integer | 是 | 分片总数 | +| content_type | string | 否 | 文件 MIME 类型 | +| project_id | string | 是 | 项目 ID | +| library_id | string | 是 | 素材库 ID | + +**响应** `200 OK`: +```json +{ + "upload_id": "上传ID", + "chunk_size": 5242880, + "total_chunks": 200, + "filename": "large_video.mp4", + "expires_at": "2024-01-02T00:00:00Z" +} +``` + +--- + +### POST /{upload_id}/{chunk_index} + +上传单个分片。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| upload_id | string | 上传 ID | +| chunk_index | integer | 分片索引(从 0 开始) | + +**请求体**: 二进制文件数据 + +**响应** `200 OK`: +```json +{ + "message": "Chunk uploaded successfully", + "chunk_index": 0, + "uploaded_chunks": 1, + "total_chunks": 200 +} +``` + +--- + +### GET /{upload_id}/status + +获取上传状态(支持断点续传)。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| upload_id | string | 上传 ID | + +**响应** `200 OK`: +```json +{ + "upload_id": "上传ID", + "filename": "large_video.mp4", + "file_size": 1073741824, + "total_chunks": 200, + "uploaded_chunks": [0, 1, 2, 3], + "status": "uploading", + "created_at": "2024-01-01T00:00:00Z", + "expires_at": "2024-01-02T00:00:00Z" +} +``` + +--- + +### POST /{upload_id}/complete + +完成分片上传,合并文件并创建导入任务。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| upload_id | string | 上传 ID | + +**请求 Body**: +```json +{ + "project_id": "项目ID", + "library_id": "素材库ID" +} +``` + +**响应** `200 OK`: +```json +{ + "storage_key": "uploads/xxx/large_video.mp4", + "ingest_job_id": "导入任务ID", + "url": "https://oss.example.com/uploads/xxx/large_video.mp4" +} +``` + +--- + +## 11. 生成任务 (Generation) + +**基础路径**: `/api/v1/generation` + +### POST /tasks + +创建视频生成任务。 + +**认证**: 是 + +**请求 Body**: +```json +{ + "project_id": "项目ID", + "asset_library_id": "素材库ID", + "strategy_id": "", + "voice_library_id": "" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| project_id | string | 是 | 项目 ID | +| asset_library_id | string | 是 | 素材库 ID | +| strategy_id | string | 否 | 生成策略 ID | +| voice_library_id | string | 否 | 配音库 ID | + +**响应** `200 OK`: +```json +{ + "id": "任务ID", + "project_id": "项目ID", + "asset_library_id": "素材库ID", + "strategy_id": "", + "voice_library_id": "", + "status": "pending", + "progress": 0.0, + "result_count": 0, + "error_message": "" +} +``` + +--- + +### GET /tasks/{task_id} + +获取生成任务详情。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| task_id | string | 任务 ID | + +**响应** `200 OK`: 返回任务详情(同上) + +--- + +### GET /tasks/{task_id}/results + +获取生成任务的成片列表。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| task_id | string | 任务 ID | + +**响应** `200 OK`: +```json +{ + "items": [ + { + "id": "成片ID", + "project_id": "项目ID", + "generation_task_id": "任务ID", + "name": "成片名称.mp4", + "file_url": "uploads/xxx/output.mp4", + "file_size": 5242880, + "duration": 30.0, + "thumbnail_url": "https://...", + "width": 1920, + "height": 1080, + "fps": 30.0, + "status": "completed", + "review_status": "pending_review", + "generation_params": {}, + "download_url": "https://..." + } + ] +} +``` + +--- + +## 12. 生成视频 (GeneratedVideo) + +**基础路径**: `/api/v1/generated-videos` + +### GET / + +获取成片列表。 + +**认证**: 是 + +**查询参数**: +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| project_id | string | 否 | 按项目 ID 筛选 | + +**响应** `200 OK`: +```json +{ + "items": [ + { + "id": "成片ID", + "project_id": "项目ID", + "generation_task_id": "任务ID", + "name": "成片名称.mp4", + "file_url": "uploads/xxx/output.mp4", + "file_size": 5242880, + "duration": 30.0, + "thumbnail_url": "https://...", + "width": 1920, + "height": 1080, + "fps": 30.0, + "status": "completed", + "review_status": "pending_review", + "generation_params": {}, + "download_url": "https://..." + } + ] +} +``` + +--- + +### GET /{video_id} + +获取成片详情。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| video_id | string | 成片 ID | + +**响应** `200 OK`: 返回成片详情 + +--- + +### PATCH /{video_id}/review + +更新成片审核状态。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| video_id | string | 成片 ID | + +**请求 Body**: +```json +{ + "review_status": "pending_review | approved | rejected" +} +``` + +**响应** `200 OK`: 返回更新后的成片对象 + +--- + +### GET /{video_id}/download-url + +获取成片下载链接。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| video_id | string | 成片 ID | + +**响应** `200 OK`: +```json +{ + "video_id": "成片ID", + "download_url": "https://oss.example.com/..." +} +``` + +--- + +## 13. 标题库 (TitleLibrary) + +**基础路径**: `/api/v1/titles` + +### GET / + +获取标题列表。 + +**认证**: 是 + +**查询参数**: +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| category | string | 否 | 按分类筛选 | +| skip | integer | 否 | 跳过数量(默认 0) | +| limit | integer | 否 | 返回数量(默认 50,最大 200) | + +**响应** `200 OK`: +```json +{ + "items": [ + { + "id": "标题ID", + "user_id": "用户ID", + "name": "标题名称", + "text": "标题文本内容", + "category": "default", + "description": "描述", + "tags": ["标签1", "标签2"], + "usage_count": 5, + "is_active": true, + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z" + } + ], + "total": 100 +} +``` + +--- + +### GET /{title_id} + +获取标题详情。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| title_id | string | 标题 ID | + +**响应** `200 OK`: 返回标题详情 + +--- + +### POST / + +创建标题。 + +**认证**: 是 + +**请求 Body**: +```json +{ + "name": "标题名称", + "text": "标题文本内容", + "category": "default", + "description": "描述", + "tags": ["标签1", "标签2"] +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| name | string | 是 | 标题名称(1-255字符) | +| text | string | 是 | 标题文本(1-500字符) | +| category | string | 否 | 分类(默认 default) | +| description | string | 否 | 描述 | +| tags | array | 否 | 标签列表 | + +**响应** `201 Created`: 返回创建的标题对象 + +**配额限制**: +- free: 10 条 +- standard: 50 条 +- pro: 200 条 +- enterprise: 无限制 + +--- + +### PUT /{title_id} + +更新标题。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| title_id | string | 标题 ID | + +**请求 Body**: +```json +{ + "name": "新标题名称", + "text": "新标题文本", + "category": "new_category", + "description": "新描述", + "tags": ["新标签"] +} +``` + +**响应** `200 OK`: 返回更新后的标题对象 + +--- + +### DELETE /{title_id} + +删除标题。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| title_id | string | 标题 ID | + +**响应** `204 No Content` + +--- + +## 14. 配音库 (VoiceLibrary) + +**基础路径**: `/api/v1/voices` + +### GET / + +获取配音列表。 + +**认证**: 是 + +**查询参数**: +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| status | string | 否 | 按状态筛选 | +| skip | integer | 否 | 跳过数量(默认 0) | +| limit | integer | 否 | 返回数量(默认 50,最大 200) | + +**响应** `200 OK`: +```json +{ + "items": [ + { + "id": "配音ID", + "user_id": "用户ID", + "name": "配音名称", + "text": "配音文本", + "voice_provider": "elevenlabs", + "voice_id": "voice_xxx", + "voice_name": "中文男声", + "audio_url": "https://...", + "duration": 10.5, + "file_size": 102400, + "status": "completed", + "project_id": null, + "tags": ["旁白"], + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z" + } + ], + "total": 20 +} +``` + +--- + +### GET /{voice_id} + +获取配音详情。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| voice_id | string | 配音 ID | + +**响应** `200 OK`: 返回配音详情 + +--- + +### POST / + +创建配音。 + +**认证**: 是 + +**请求 Body**: +```json +{ + "name": "配音名称", + "text": "配音文本内容", + "voice_provider": "elevenlabs", + "voice_id": "voice_xxx", + "voice_name": "中文男声", + "audio_url": "https://...", + "duration": 10.5, + "file_size": 102400, + "status": "completed", + "project_id": null, + "tags": ["旁白"] +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| name | string | 是 | 配音名称(1-255字符) | +| text | string | 否 | 配音文本 | +| voice_provider | string | 否 | 语音服务商 | +| voice_id | string | 否 | 语音 ID | +| voice_name | string | 否 | 语音名称 | +| audio_url | string | 否 | 音频 URL | +| duration | float | 否 | 时长(秒) | +| file_size | integer | 否 | 文件大小 | +| status | string | 否 | 状态(默认 completed) | +| project_id | string | 否 | 关联项目 ID | +| tags | array | 否 | 标签列表 | + +**响应** `201 Created`: 返回创建的配音对象 + +--- + +### PUT /{voice_id} + +更新配音。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| voice_id | string | 配音 ID | + +**请求 Body**: 同创建(所有字段可选) + +**响应** `200 OK`: 返回更新后的配音对象 + +--- + +### DELETE /{voice_id} + +删除配音。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| voice_id | string | 配音 ID | + +**响应** `204 No Content` + +--- + +## 15. 查重 (Duplication) + +**基础路径**: `/api/v1/duplication` + +### POST /upload + +上传视频进行查重检测。 + +**认证**: 是 + +**请求**: multipart/form-data + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| file | file | 是 | 视频文件 | + +**响应** `200 OK`: +```json +{ + "id": "查重记录ID", + "status": "pending", + "message": "文件 \"video.mp4\" 已上传,正在查重中..." +} +``` + +**限制**: +- 仅支持视频文件: `mp4`, `mpeg`, `mov`, `avi`, `webm`, `mkv`, `3gp` +- 最大文件大小: 100MB + +--- + +### GET /records + +获取查重记录列表。 + +**认证**: 是 + +**响应** `200 OK`: +```json +[ + { + "id": "记录ID", + "filename": "video.mp4", + "file_size": 5242880, + "duration_seconds": 30.0, + "status": "completed", + "duplicate_rate": 0.15, + "duplicate_count": 2, + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:01:00Z" + } +] +``` + +--- + +### GET /records/{record_id} + +获取查重记录详情(含重复片段)。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| record_id | string | 查重记录 ID | + +**响应** `200 OK`: +```json +{ + "id": "记录ID", + "filename": "video.mp4", + "file_size": 5242880, + "duration_seconds": 30.0, + "status": "completed", + "duplicate_rate": 0.15, + "duplicate_count": 2, + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:01:00Z", + "segments": [ + { + "id": "片段ID", + "source_start": 5.0, + "source_end": 10.5, + "matched_video_id": "视频ID", + "matched_video_name": "匹配视频名称", + "matched_start": 0.0, + "matched_end": 5.5, + "similarity": 0.95 + } + ] +} +``` + +--- + +### DELETE /records/{record_id} + +删除查重记录。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| record_id | string | 查重记录 ID | + +**响应** `204 No Content` + +--- + +### POST /records/{record_id}/retry + +重新提交查重。 + +**认证**: 是 + +**路径参数**: +| 参数 | 类型 | 说明 | +|------|------|------| +| record_id | string | 查重记录 ID | + +**响应** `200 OK`: +```json +{ + "id": "记录ID", + "status": "pending", + "message": "已重新提交查重" +} +``` + +--- + +## 16. 订阅 (Subscription) + +**基础路径**: `/api/v1/subscription` + +### GET /current + +获取当前订阅信息。 + +**认证**: 是 + +**响应** `200 OK`: +```json +{ + "id": "sub-xxx", + "plan_id": "pro", + "plan_name": "专业版", + "status": "active", + "billing_cycle": "monthly", + "current_period_start": "2024-01-01T00:00:00Z", + "current_period_end": "2024-02-01T00:00:00Z", + "amount": 299.0, + "auto_renew": true, + "created_at": "2024-01-01T00:00:00Z" +} +``` + +--- + +### GET /billing-records + +获取账单记录列表。 + +**认证**: 是 + +**响应** `200 OK`: +```json +[] +``` + +--- + +### POST /change-plan + +变更订阅套餐(升级/降级)。 + +**认证**: 是 + +**请求 Body**: +```json +{ + "target_plan_id": "pro", + "billing_cycle": "monthly" +} +``` + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| target_plan_id | string | 是 | 目标套餐: `free`, `standard`, `pro`, `enterprise` | +| billing_cycle | string | 是 | 计费周期: `monthly`, `yearly` | + +**响应** `200 OK`: +```json +{ + "success": true, + "message": "套餐已成功变更为 专业版", + "new_subscription": { ... } +} +``` + +--- + +### POST /cancel + +取消订阅。 + +**认证**: 是 + +**响应** `200 OK`: +```json +{ + "success": true, + "message": "订阅已取消,当前周期结束后停止服务" +} +``` + +--- + +### POST /toggle-auto-renew + +切换自动续费。 + +**认证**: 是 + +**请求 Body**: +```json +{ + "enabled": false +} +``` + +**响应** `200 OK`: +```json +{ + "success": true, + "message": "已关闭自动续费" +} +``` + +--- + +## 附录 A: 套餐配额 + +| 套餐 | 最大项目数 | 存储空间 | 标题库配额 | 配音库配额 | +|------|-----------|----------|-----------|-----------| +| free | 3 | 10 GB | 10 条 | 5 条 | +| standard | 10 | 50 GB | 50 条 | 20 条 | +| pro | 无限制 | 100 GB | 200 条 | 100 条 | +| enterprise | 无限制 | 1000 GB | 无限制 | 无限制 | + +--- + +## 附录 B: 套餐价格 + +| 套餐 | 月付 | 年付 | +|------|------|------| +| free | ¥0 | ¥0 | +| standard | ¥99 | ¥999 | +| pro | ¥299 | ¥2999 | +| enterprise | ¥999 | ¥9999 | + +--- + +*文档版本: v0.1.88 | 更新于: 2026-06-29*