Files
JuYou/文档/接口文档.md
T
2026-08-25 17:59:42 +08:00

1043 lines
36 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# JuYouAI HTTP 接口文档
## 1. 基础约定
### 1.1 服务地址
| 环境 | 地址 |
| --- | --- |
| 本地联调 | `http://127.0.0.1:8123`,以实际 `SERVER_ADDRESS` 为准 |
| 生产环境 | `https://部署域名`,由 Nginx 转发到 `127.0.0.1:8123` |
接口分为两个前缀:
```text
/api/web 用户端接口
/api/admin 管理端接口
```
### 1.2 请求格式
- 普通写接口使用 `Content-Type: application/json`
- 文件上传使用 `Content-Type: multipart/form-data`
- GET 查询参数放在 URL Query 中。
- 所有 `project_id``episode_id``storyboard_id``asset_id``task_id``output_id``media_id``script_id` 和资源 `id` 均为 UUID。
- 时间使用 ISO 8601/RFC 3339 字符串,例如 `2026-07-31T10:00:00+08:00`
- 金额和积分字段通常使用十进制字符串返回,调用方不要用二进制浮点数直接结算。
### 1.3 用户端认证
除登录、刷新、退出和健康检查外,WEB 接口需要:
```http
Authorization: Bearer <web_access_token>
```
### 1.4 管理端认证
除登录、刷新、退出和健康检查外,ADMIN 接口需要:
```http
Authorization: Bearer <admin_access_token>
```
创建兑换码批次还需要管理员二次认证:
```http
X-Admin-Reauth-Token: <reauth_token>
```
### 1.5 成功响应
大多数查询、创建和更新接口使用统一数据包:
```json
{
"data": {}
}
```
分页响应:
```json
{
"data": {
"items": [],
"total": 0,
"page": 1,
"page_size": 20
}
}
```
删除、退出和部分更新成功时返回 `204 No Content`,没有响应体。
### 1.6 错误响应
```json
{
"code": "invalid_request",
"message": "参数说明",
"trace_id": "请求追踪 UUID"
}
```
常见状态码:
| 状态码 | 说明 |
| --- | --- |
| `200` | 查询或更新成功 |
| `201` | 资源创建成功 |
| `202` | 异步任务已接受 |
| `204` | 操作成功,无响应体 |
| `400` | 参数或业务状态不符合要求 |
| `401` | 未登录、Access Token 失效或登录凭证错误 |
| `403` | 缺少或失效的管理员二次认证 |
| `404` | 资源不存在、无权访问或路由不允许 |
| `413` | 请求体超过限制,通常由上传限制触发 |
| `500` | 服务端执行失败 |
| `503` | PostgreSQL、Redis、COS 等依赖不可用 |
服务会在响应头返回:
```http
X-Request-ID: <请求追踪 UUID>
```
调用方也可以主动发送 `X-Request-ID`,后端将复用该值。
## 2. 公共数据结构
### 2.1 TokenPair
用户登录和管理员登录返回相同的 Token 基础字段:
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `access_token` | string | 用于 Authorization 的短期访问令牌 |
| `refresh_token` | string | 用于刷新登录态;每次刷新后应替换旧值 |
| `expires_at` | datetime | Access Token 到期时间 |
| `user` | object | 仅 WEB 返回的用户摘要 |
| `admin` | object | 仅 ADMIN 返回的管理员摘要 |
### 2.2 分页参数
| 参数 | 位置 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| `page` | Query | integer | `1` | 小于 1 时按 1 处理 |
| `page_size` | Query | integer | `20` | 最大 100 |
| `keyword` | Query | string | 空 | 模糊搜索关键词,是否生效取决于接口 |
### 2.3 GenerationTask 摘要
任务列表和创建任务通常返回以下主要字段:
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | UUID | 任务 ID |
| `request_id` | string | 幂等和上游请求追踪标识 |
| `task_type` | string | 任务类型 |
| `status` | string | 当前状态 |
| `project_id` | UUID/null | 所属项目 |
| `episode_id` | UUID/null | 所属剧集 |
| `storyboard_id` | UUID/null | 所属分镜 |
| `estimated_points` | string | 预估积分 |
| `prepaid_points` | string | 已预扣积分 |
| `actual_points` | string/null | 最终积分 |
| `error_code` | string | 失败错误码 |
| `error_message` | string | 失败原因 |
| `created_at` | datetime | 创建时间 |
| `submitted_at` | datetime/null | 提交上游时间 |
| `finished_at` | datetime/null | 终态时间 |
常见任务状态:`pending_submission``submitting``submit_unknown``submitted``processing``result_ready``downloading``succeeded``failed``cancel_requested``cancelled`
### 2.4 MediaAsset
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | UUID | 媒体 ID |
| `public_url` | string | COS 公开访问地址 |
| `original_name` | string | 原始文件名 |
| `display_name` | string | 业务显示名称 |
| `mime_type` | string | MIME 类型 |
| `size_bytes` | integer | 文件字节数 |
| `sha256` | string | 文件摘要 |
| `width``height` | integer/null | 图片或视频尺寸 |
| `duration_ms` | integer/null | 音视频时长 |
| `created_at` | datetime | 创建时间 |
## 3. 健康检查
### 3.1 接口列表
| 方法 | 路径 | 认证 | 作用 |
| --- | --- | --- | --- |
| GET | `/health` | 否 | 系统级健康检查 |
| GET | `/api/web/health` | 否 | WEB 前缀健康检查 |
| GET | `/api/admin/health` | 否 | ADMIN 前缀健康检查 |
三个接口参数和响应一致,同时 Ping PostgreSQL 和 Redis。
成功示例:
```json
{
"status": "ok",
"services": {
"postgresql": "ok",
"redis": "ok"
}
}
```
任一依赖失败时返回 `503``status``degraded`,对应服务值为 `unavailable`
## 4. WEB 用户认证与账户
### 4.1 接口总表
| 方法 | 路径 | 认证 | 作用 | 参数 |
| --- | --- | --- | --- | --- |
| POST | `/api/web/auth/login` | 否 | 用户登录 | JSON`account``password`,均必填 |
| POST | `/api/web/auth/refresh` | 否 | 刷新并轮换 Token | JSON`refresh_token`,必填 |
| POST | `/api/web/auth/logout` | 否 | 注销 Refresh Token | JSON`refresh_token`,可空 |
| GET | `/api/web/account` | 是 | 获取账户、积分等完整信息 | 无 |
| PATCH | `/api/web/account/profile` | 是 | 修改用户显示名 | JSON:`username`,必填 |
| POST | `/api/web/account/avatar` | 是 | 上传或替换头像 | multipart`file` |
| PUT | `/api/web/account/password` | 是 | 修改用户密码 | JSON:`original_password``new_password` |
| GET | `/api/web/usage/30-days` | 是 | 获取最近 30 天消耗数据 | 无 |
| GET | `/api/web/usage/consumption-records` | 是 | 获取最近消费记录 | 无;后端固定最多 100 条 |
| POST | `/api/web/redemption/redeem` | 是 | 使用兑换码增加积分 | JSON:`code`,必填 |
### 4.2 登录
请求:
```json
{
"account": "user001",
"password": "用户密码"
}
```
成功返回 `TokenPair`,其中 `user` 包含 `id``uid``account``username``avatar_url` 等用户摘要。账号不存在、密码错误或账号被禁用返回 `401`
### 4.3 更新资料
```json
{
"username": "新的显示名称"
}
```
用户名格式不正确或已存在时返回 `400 profile_invalid`
### 4.4 修改密码
```json
{
"original_password": "原密码",
"new_password": "新密码"
}
```
原密码错误或新密码不满足 8 至 128 字符限制时返回 `400 password_invalid`。成功返回 `204`
### 4.5 上传头像
| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `file` | file | 是 | JPEG、PNG 或 WebP;大小不超过 `COS_MAX_IMAGE_SIZE_MB` |
后端同时校验声明的 MIME 和文件头。成功返回:
```json
{
"data": {
"avatar_url": "https://媒体域名/users/..."
}
}
```
替换成功后会删除旧头像对象。
## 5. WEB 提示词与模型配置
### 5.1 接口列表
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| GET | `/api/web/user/prompts/{prompt_type}` | 列出指定类型的系统提示词、用户自定义提示词和当前选择 | Path:`prompt_type` |
| PUT | `/api/web/user/prompts/{prompt_type}/select` | 选择或关闭某类提示词 | JSON:`prompt_id`UUID 或 `null` |
| POST | `/api/web/user/custom-prompts` | 新建用户提示词 | JSON`name``type``content` |
| PUT | `/api/web/user/custom-prompts/{id}` | 修改本人提示词 | Path`id`JSON`name``content``type` 可选 |
| DELETE | `/api/web/user/custom-prompts/{id}` | 删除本人提示词并清理选择关系 | Path:`id` |
| GET | `/api/web/creative/options` | 获取可用风格、模型、价格和能力信息 | 无 |
| GET | `/api/web/user/model-configs/{scope}` | 获取用户级模型偏好 | 当前 `scope` 只接受 `script_analysis` |
| PUT | `/api/web/user/model-configs/{scope}/{model_type}` | 保存用户级模型偏好 | 当前只接受 `scope=script_analysis``model_type=text`JSON`model_id` |
### 5.2 提示词列表响应
```json
{
"data": {
"prompts": [
{
"id": "UUID",
"name": "提示词名称",
"type": "提示词类型",
"content": "内容",
"scope": "system",
"editable": false
}
],
"selected_id": "UUID"
}
}
```
`scope``system``user`。平台代码内固定的短剧解析提示词不允许用户选择或自定义。
### 5.3 保存模型偏好
```json
{
"model_id": "模型 UUID"
}
```
模型及所属渠道必须启用。成功返回 `204`
## 6. WEB 剧本分析
所有接口均需要用户认证。
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| GET | `/api/web/script-analyses` | 获取本人剧本分析列表 | 无 |
| POST | `/api/web/script-analyses` | 创建空白剧本分析 | 无;默认名称为“未命名剧本” |
| GET | `/api/web/script-analyses/import-projects` | 获取可导入的剧本反推项目 | 无 |
| GET | `/api/web/script-analyses/{script_id}` | 获取剧本、分析结果和角色列表 | Path:`script_id` |
| PUT | `/api/web/script-analyses/{script_id}` | 保存剧本名称、源内容或人工结果内容 | JSON:`name``source_content``result_content` |
| POST | `/api/web/script-analyses/{script_id}/import-project` | 从本人反推项目导入已完成剧本 | JSON:`project_id` |
| POST | `/api/web/script-analyses/{script_id}/import-file` | 从文件替换剧本源内容 | multipart`file` |
| POST | `/api/web/script-analyses/{script_id}/analyze` | 创建异步剧本分析任务 | 无;返回 `202` |
| POST | `/api/web/script-analyses/{script_id}/cancel` | 请求取消当前分析任务 | 无 |
| DELETE | `/api/web/script-analyses/{script_id}` | 软删除剧本分析 | 无 |
### 6.1 更新剧本
```json
{
"name": "剧本名称",
"source_content": "待分析的完整剧本",
"result_content": "可选的人工整理结果"
}
```
剧本正在分析时,部分源内容替换操作会被拒绝。
### 6.2 文件导入
| 参数 | 类型 | 限制 |
| --- | --- | --- |
| `file` | file | 仅 `.txt``.doc`,有效内容不超过 3 MiB;整个 multipart 请求不超过 4 MiB |
导入会使用文件名作为剧本名称,并清空旧分析结果和角色数据。
### 6.3 剧本分析主要返回字段
| 字段 | 说明 |
| --- | --- |
| `id``name` | 剧本标识和名称 |
| `source_content` | 原始剧本内容 |
| `result_content` | 人工或展示用结果文本 |
| `analysis_result` | JSON 结构化分析结果 |
| `analysis_status` | `idle``queued``running``succeeded``failed` |
| `analysis_message` | 进度或错误说明 |
| `characters` | 角色名称、阵营、传记、动机和关系 |
## 7. WEB 项目管理
### 7.1 接口列表
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| GET | `/api/web/projects` | 获取本人项目列表 | Query:`project_type``keyword` |
| POST | `/api/web/projects` | 创建项目 | JSONProjectInput |
| GET | `/api/web/projects/{project_id}` | 获取项目、模型配置和剧集详情 | Path:`project_id` |
| PUT | `/api/web/projects/{project_id}` | 修改项目基础信息 | JSONProjectInput |
| DELETE | `/api/web/projects/{project_id}` | 删除项目及关联数据库和 COS 对象 | Path:`project_id` |
| PUT | `/api/web/projects/{project_id}/model-configs` | 保存项目的文本、图片和视频配置 | JSON:模型配置映射 |
### 7.2 项目列表查询参数
| 参数 | 类型 | 说明 |
| --- | --- | --- |
| `project_type` | string | 可空;常用值 `video_redraw``premium_drama` |
| `keyword` | string | 按项目名称模糊搜索 |
### 7.3 ProjectInput
```json
{
"project_type": "premium_drama",
"name": "项目名称",
"style_id": "风格 UUID",
"era_type": "modern_city",
"custom_era": null,
"aspect_ratio": "16:9",
"localization": "china",
"short_drama_type": "短剧类型",
"play_count": "播放量文本",
"audience_profile": "受众说明",
"producer": "制作方",
"cast_members": [
{
"name": "演员名",
"follower_count": "粉丝数文本"
}
]
}
```
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `project_type` | 创建时建议填写 | `video_redraw``premium_drama` |
| `name` | 是 | 项目名称 |
| `style_id` | 短剧项目是 | 风格 UUID;反推项目未填时后端尝试使用第一个可用风格 |
| `era_type` | 是 | 时代类型;自定义时代使用 `other` 配合 `custom_era` |
| `custom_era` | 否 | 自定义时代文本 |
| `aspect_ratio` | 是 | 项目画面比例 |
| `localization` | 视项目而定 | 本地化区域代码 |
| 其他字段 | 否 | 短剧运营和演员信息 |
### 7.4 项目模型配置
接口接受按模型类型或用途命名的对象。推荐格式:
```json
{
"text": {
"model_id": "文本模型 UUID",
"settings": {
"prompt": "可选附加提示"
}
},
"image": {
"model_id": "图片模型 UUID",
"settings": {}
},
"video": {
"model_id": "视频模型 UUID",
"settings": {
"resolution": "720p"
}
}
}
```
也兼容 `prompt_reverse``image_generation``video_generation` 作为键。`resolution` 允许 `480p``720p``1080p`,无效值回退为 `480p`。图片比例由业务固定,不从模型配置保存。
## 8. WEB 剧集、导入与短剧解析
### 8.1 剧集接口
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| POST | `/api/web/projects/{project_id}/episodes` | 新建剧集 | JSON`episode_no``name`,均可省略使用默认值 |
| PUT | `/api/web/projects/{project_id}/episodes/{episode_id}` | 修改剧集名称 | JSON`name` |
| DELETE | `/api/web/projects/{project_id}/episodes/{episode_id}` | 删除剧集及其媒体、分镜和任务数据 | 无请求体 |
| GET | `/api/web/projects/{project_id}/episodes/{episode_id}/workbench` | 获取项目、剧集、资产和分镜工作台数据 | 无 |
| POST | `/api/web/projects/{project_id}/episodes/{episode_id}/storyboards` | 手动新增 5 秒空白分镜 | 无 |
### 8.2 小说或剧本导入
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| POST | `/api/web/projects/{project_id}/episodes/import/preview` | 解析上传文件或粘贴文本,生成章节预览和一次性导入令牌 | multipart`file``raw_text` 至少一个 |
| POST | `/api/web/projects/{project_id}/episodes/import/confirm` | 使用预览令牌正式创建剧集 | JSON:见下方 |
预览限制:整个请求不超过 4 MiB,文件读取上限为 3 MiB。文件和 `raw_text` 同时提供时优先使用文件。
确认请求:
```json
{
"import_token": "预览返回的 UUID",
"chapters_per_episode": 2,
"start_episode_no": 1,
"treat_as_single_episode": false
}
```
| 字段 | 说明 |
| --- | --- |
| `import_token` | 必填,一次性导入会话 UUID |
| `chapters_per_episode` | 每集包含的章节数 |
| `start_episode_no` | 起始集号 |
| `treat_as_single_episode` | 无章节或希望合并时按单集导入 |
### 8.3 剧集文本源和解析
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| GET | `/api/web/projects/{project_id}/episodes/{episode_id}/text-source` | 获取待解析的剧集文本 | 无 |
| PUT | `/api/web/projects/{project_id}/episodes/{episode_id}/text-source` | 保存剧集标题和原始正文 | JSON:`title``raw_content` |
| POST | `/api/web/projects/{project_id}/episodes/{episode_id}/parse` | 创建短剧文本解析任务 | 无;返回 `202` |
| POST | `/api/web/projects/{project_id}/episodes/{episode_id}/reparse` | 清理旧分析产物并重新解析 | 无;需要 COS 可用 |
| GET | `/api/web/projects/{project_id}/parse-tasks` | 获取项目解析任务 | Query:可选 `episode_id` |
| POST | `/api/web/projects/{project_id}/parse-tasks/{task_id}/cancel` | 取消解析任务 | 无 |
保存文本请求:
```json
{
"title": "本集标题",
"raw_content": "本集完整正文"
}
```
## 9. WEB 反推与媒体分析
### 9.1 工作台和任务接口
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| GET | `/api/web/projects/{project_id}/redraw-workbench` | 获取项目级反推工作台 | 无 |
| GET | `/api/web/projects/{project_id}/episodes/{episode_id}/redraw-workbench` | 获取剧集级反推工作台 | 无 |
| POST | `/api/web/projects/{project_id}/redraw-analyze` | 分析项目级原视频 | 无;返回 `202` |
| POST | `/api/web/projects/{project_id}/redraw-reanalyze` | 删除旧分析并重新分析项目原视频 | 无;返回 `202` |
| POST | `/api/web/projects/{project_id}/redraw-script` | 生成项目级完整反推剧本 | 无;返回 `202` |
| POST | `/api/web/projects/{project_id}/episodes/{episode_id}/redraw-script` | 生成剧集级反推剧本 | 无;返回 `202` |
| PUT | `/api/web/projects/{project_id}/episodes/{episode_id}/redraw-script` | 保存修改后的剧集级反推剧本 | JSON:`content` |
| POST | `/api/web/projects/{project_id}/episodes/{episode_id}/analyze` | 分析剧集原视频 | 无;返回 `202` |
| POST | `/api/web/projects/{project_id}/episodes/{episode_id}/reanalyze` | 清理并重新分析剧集原视频 | 无;返回 `202` |
| POST | `/api/web/projects/{project_id}/episodes/{episode_id}/storyboards/{storyboard_id}/reinfer` | 重新反推指定短剧分镜 | 无;返回 `202` |
| POST | `/api/web/projects/{project_id}/storyboards/{storyboard_id}/redraw-reinfer` | 重新反推指定项目级分镜 | 无;返回 `202` |
### 9.2 分析设置
| 方法 | 路径 | 作用 |
| --- | --- | --- |
| PUT | `/api/web/projects/{project_id}/redraw-analysis-settings` | 保存项目级台词来源和源语言 |
| PUT | `/api/web/projects/{project_id}/episodes/{episode_id}/analysis-settings` | 保存剧集级台词来源和源语言 |
请求:
```json
{
"audio_source": "video_audio",
"source_language": "zh"
}
```
`audio_source` 只允许:
- `video_audio`:从视频中提取音频识别;
- `subtitle_file`:使用上传字幕。
剧集级 `source_language` 最长 16 字符;项目级允许空值表示自动或未指定。
### 9.3 原视频和字幕上传
| 方法 | 路径 | multipart 参数 |
| --- | --- | --- |
| POST | `/api/web/projects/{project_id}/redraw-source` | `file`:项目原视频 |
| POST | `/api/web/projects/{project_id}/redraw-subtitle` | `file`:项目字幕 |
| POST | `/api/web/projects/{project_id}/episodes/{episode_id}/source` | `file`:剧集原视频 |
| POST | `/api/web/projects/{project_id}/episodes/{episode_id}/subtitle` | `file`:剧集字幕 |
视频限制:
- MIME`video/mp4``video/webm``video/quicktime``video/x-m4v`
- 扩展名:`.mp4``.webm``.mov``.m4v`
- 最大 50 MiB。
字幕限制:扩展名 `.srt``.vtt``.txt`,最大 2 MiB。
替换原视频会重置已有分析产物;替换字幕不会自动触发分析。
## 10. WEB 资产管理
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| POST | `/api/web/projects/{project_id}/assets` | 创建资产 | JSON`asset_type``name` |
| PUT | `/api/web/projects/{project_id}/assets/{asset_id}` | 修改资产 | JSON:允许字段见下方 |
| DELETE | `/api/web/projects/{project_id}/assets/{asset_id}` | 删除资产及媒体和输出 | 无 |
| POST | `/api/web/projects/{project_id}/assets/{asset_id}/image` | 上传资产参考图 | multipart`file` |
| DELETE | `/api/web/projects/{project_id}/assets/{asset_id}/image` | 移除当前参考图 | 无 |
| POST | `/api/web/projects/{project_id}/assets/{asset_id}/audio` | 上传参考音频 | multipart`file`、可选 `duration_ms` |
| GET | `/api/web/projects/{project_id}/assets/{asset_id}/outputs` | 获取资产图片生成历史 | 无 |
| PUT | `/api/web/projects/{project_id}/assets/{asset_id}/outputs/{output_id}/activate` | 将历史输出设为当前资产图 | 无 |
| DELETE | `/api/web/projects/{project_id}/assets/{asset_id}/outputs/{output_id}` | 删除资产历史输出和 COS 对象 | 无 |
创建资产:
```json
{
"asset_type": "character",
"name": "资产名称"
}
```
`asset_type` 允许 `character``scene``prop``custom`。同一项目内同类型资产名称不能重复。
修改资产允许字段:
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `name` | string | 非空;重命名时同步更新分镜引用 |
| `description` | string | 资产描述 |
| `image_prompt` | string | 资产图片提示词 |
| `appearances` | array | 出场信息 |
剧本反推项目中的解析资产只允许修改 `name`
参考图只接受 JPEG、PNG、WebP,大小不超过 `COS_MAX_IMAGE_SIZE_MB`,后端会解析真实图片尺寸。音频必须为 `audio/*`,大小不超过 `COS_MAX_AUDIO_SIZE_MB``duration_ms` 必须是大于等于 0 的整数。
## 11. WEB 分镜、生成与输出
### 11.1 分镜编辑
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| PUT | `/api/web/projects/{project_id}/storyboards/{storyboard_id}` | 修改分镜 | JSON:允许字段见下方 |
| POST | `/api/web/projects/{project_id}/storyboards/{storyboard_id}/insert` | 在目标分镜前或后插入空白分镜 | JSON:`position` |
| DELETE | `/api/web/projects/{project_id}/storyboards/{storyboard_id}` | 删除分镜及关联输出 | 无 |
允许修改的分镜字段:
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `title` | string | 分镜标题 |
| `script_content` | string | 分镜剧本内容 |
| `source_excerpt` | string | 来源文本片段 |
| `prompt_content` | string | 生成提示词 |
| `dialogue` | array/object | 以 JSONB 保存的台词结构 |
| `asset_refs` | array | 资产引用结构 |
| `locked` | boolean | 是否锁定 |
| `active_output_id` | UUID/null | 当前活动输出 |
| `duration_seconds` | integer | 5 至 15 秒 |
插入请求:
```json
{
"position": "after"
}
```
`position` 只允许 `before``after`
### 11.2 创建生成任务
```text
POST /api/web/projects/{project_id}/episodes/{episode_id}/storyboards/{storyboard_id}/generate
```
请求:
```json
{
"task_type": "image_generation",
"input": {
"prompt": "生成提示词",
"size": "16:9",
"duration": 5,
"resolution": "720p",
"image_urls": [],
"audio_urls": [],
"video_urls": []
}
}
```
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `task_type` | string | 只允许 `image_generation``video_generation` |
| `input` | object | 任务输入;根据任务类型使用提示词、画面比例、时长、清晰度和参考媒体 URL 等字段 |
后端会结合项目模型配置、分镜、资产引用和渠道能力重新校验,不应把 `input` 当作可任意透传第三方的对象。成功返回 `202` 和 GenerationTask。
### 11.3 任务接口
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| GET | `/api/web/projects/{project_id}/tasks` | 获取项目任务列表 | Query:可选 `episode_id` |
| POST | `/api/web/projects/{project_id}/tasks/{task_id}/cancel` | 取消排队任务或请求取消上游任务 | 无 |
取消已进入终态的任务不会重新改变结果。不同项目类型的取消和退款规则不同,以后端返回为准。
### 11.4 分镜输出历史
| 方法 | 路径 | 作用 |
| --- | --- | --- |
| GET | `/api/web/projects/{project_id}/storyboards/{storyboard_id}/outputs` | 获取分镜生成历史 |
| PUT | `/api/web/projects/{project_id}/storyboards/{storyboard_id}/outputs/{output_id}/activate` | 设置当前输出 |
| PUT | `/api/web/projects/{project_id}/storyboards/{storyboard_id}/outputs/{output_id}/candidate` | 标记候选输出 |
| DELETE | `/api/web/projects/{project_id}/storyboards/{storyboard_id}/outputs/{output_id}/candidate` | 取消候选标记 |
| DELETE | `/api/web/projects/{project_id}/storyboards/{storyboard_id}/outputs/{output_id}` | 删除输出和 COS 对象 |
输出列表主要返回 `id``task_id``media_asset_id``output_type``public_url``mime_type``size_bytes``active``candidate`、积分和创建时间。
### 11.5 受保护媒体读取
```text
GET /api/web/media/{media_id}
```
后端先校验媒体属于当前用户,再从 COS 流式返回原始二进制。响应 `Content-Type` 使用媒体 MIME`Cache-Control``private, max-age=3600`。该接口不是 JSON 响应。
## 12. ADMIN 管理员认证
| 方法 | 路径 | 认证 | 作用 | 参数 |
| --- | --- | --- | --- | --- |
| POST | `/api/admin/auth/login` | 否 | 管理员登录 | JSON:`username``password` |
| POST | `/api/admin/auth/refresh` | 否 | 刷新管理员 Token | JSON`refresh_token` |
| POST | `/api/admin/auth/logout` | 否 | 注销 Refresh Token | JSON:可选 `refresh_token` |
| POST | `/api/admin/auth/reauth` | Admin JWT | 使用当前密码取得 5 分钟二次认证令牌 | JSON:`password` |
| PUT | `/api/admin/auth/password` | Admin JWT | 修改管理员密码 | JSON`current_password``new_password``confirm_password` |
二次认证成功:
```json
{
"data": {
"reauth_token": "短期 JWT",
"expires_at": "2026-07-31T10:05:00+08:00"
}
}
```
新管理员密码必须与确认密码一致,并满足 8 至 128 字符限制。修改成功返回 `204`
## 13. ADMIN 用户管理
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| GET | `/api/admin/users` | 分页查询用户 | Query`keyword``enabled``page``page_size` |
| POST | `/api/admin/users` | 创建单个用户 | JSON`account``password``daily_limit` |
| POST | `/api/admin/users/batch` | 按前缀和序号批量创建用户 | JSON:见下方 |
| PATCH | `/api/admin/users/batch` | 批量调整日限额或启停 | JSON:`ids`、可选 `daily_limit`、可选 `enabled``reason` |
| DELETE | `/api/admin/users/batch` | 批量软删除用户 | JSON`ids``reason` |
单用户创建:
```json
{
"account": "user001",
"password": "初始密码",
"daily_limit": "100.00"
}
```
批量创建:
```json
{
"prefix": "user",
"start_sequence": "001",
"end_sequence": "010",
"password": "统一初始密码",
"daily_limit": "100.00"
}
```
`start_sequence``end_sequence` 使用字符串以保留前导零。批量更新至少应提供 `daily_limit``enabled` 之一。
## 14. ADMIN 模型管理
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| GET | `/api/admin/models` | 分页查询模型和价格 | Query:`keyword``model_type``channel_id``page``page_size` |
| POST | `/api/admin/models` | 创建模型配置 | JSONModelBody |
| PUT | `/api/admin/models/{id}` | 更新模型并整体替换价格 | JSONModelBody |
ModelBody
```json
{
"channel_id": "渠道 UUID",
"name": "渠道侧标识",
"model_type": "text",
"multimodal": false,
"text_billing_mode": "per_request",
"enabled": true,
"prices": [
{
"price_key": "default",
"unit": "次",
"price": "0.50"
}
]
}
```
| 字段 | 说明 |
| --- | --- |
| `channel_id` | 所属渠道 UUID |
| `name` | 渠道请求使用的标识 |
| `model_type` | `text``image``video` |
| `multimodal` | 文本类型是否支持多模态输入 |
| `text_billing_mode` | 文本类型只允许 `per_request``per_token` |
| `enabled` | 是否允许新任务选择 |
| `prices` | 更新时整体替换原价格列表 |
文本按次计费必须且只能提供 `price_key=default`;按 Token 计费必须同时提供 `input``output`,单位由后端规范化。
模型启停和删除目前没有独立 `/models/{id}` 路由,前端代码虽然尝试使用通用资源路由,但服务器通用资源白名单当前只允许 `styles``channels`。直接调用 `/api/admin/resources/models/...` 会返回 `404 route_not_found`
## 15. ADMIN 提示词管理
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| GET | `/api/admin/prompts` | 查询系统提示词 | Query`keyword``type``page``page_size` |
| POST | `/api/admin/prompts` | 创建并立即生效系统提示词 | JSON:`name``type``content` |
| PUT | `/api/admin/prompts/{id}` | 修改并立即生效系统提示词 | JSON:`name``type``content` |
| DELETE | `/api/admin/prompts/{id}` | 删除系统提示词 | Path`id` |
| POST | `/api/admin/prompts/{id}/actions` | 兼容占位接口 | 当前忽略请求体并返回 `204` |
| GET | `/api/admin/prompts/{id}/history` | 兼容占位接口 | 当前固定返回空数组 |
请求示例:
```json
{
"name": "提示词名称",
"type": "提示词类型",
"content": "完整提示词内容"
}
```
`name``type``content` 不能为空。后端代码内固定的短剧解析提示词不会出现在列表,也不允许通过该接口维护。
注意:当前 ADMIN 页面删除操作使用 `/resources/prompts/{id}`,但通用资源白名单不允许 `prompts`;对接方应以本节已注册的 `DELETE /api/admin/prompts/{id}` 为准。
## 16. ADMIN 兑换码
| 方法 | 路径 | 作用 | 参数 |
| --- | --- | --- | --- |
| GET | `/api/admin/redemption-codes` | 分页查询兑换码 | Query`keyword``status``page``page_size` |
| POST | `/api/admin/redemption-batches` | 创建一批兑换码 | Admin JWT + `X-Admin-Reauth-Token`JSON:见下方 |
查询:
- `keyword` 匹配兑换码、兑换码掩码、批次名或用户 UID;
- `status``unused``redeemed``expired` 等状态过滤;
- 过期但仍标记 unused 的记录会动态显示为 expired。
创建请求:
```json
{
"name": "活动批次名称",
"points": "50",
"quantity": 10,
"expires_at": "2026-08-07T23:59:59+08:00"
}
```
| 字段 | 限制 |
| --- | --- |
| `name` | 批次名称 |
| `points` | 单码 1 至 100 积分 |
| `quantity` | 1 至 10 个 |
| `expires_at` | 可空;为空时默认当前时间后 7 天 |
成功响应中的 `codes` 是完整明文兑换码;管理后台列表也会返回 `code` 字段供查看和复制。
## 17. ADMIN 风格图片和排序
### 17.1 上传风格图片
```text
POST /api/admin/uploads/style-images
```
multipart 参数:`file`
限制:
- JPEG、PNG 或 GIF
- 大小不超过 `COS_MAX_IMAGE_SIZE_MB`
- 宽高均为 64 至 8192 像素。
返回 `image_key``image_url``image_mime``image_size``image_width``image_height`,随后把这些字段传给风格创建或更新接口。
### 17.2 风格排序
```text
PUT /api/admin/resources/styles/reorder
```
请求:
```json
{
"ids": ["风格 UUID 1", "风格 UUID 2"]
}
```
`ids` 必须包含当前所有未删除风格,不能缺少、重复或包含无效 UUID。数组顺序就是最终 `sort_order`
## 18. ADMIN 通用资源接口
通用资源路由形式如下:
| 方法 | 路径 | 作用 |
| --- | --- | --- |
| GET | `/api/admin/resources/{resource}` | 分页查询资源 |
| POST | `/api/admin/resources/{resource}` | 创建资源 |
| PUT | `/api/admin/resources/{resource}/{id}` | 更新资源 |
| PATCH | `/api/admin/resources/{resource}/{id}/enabled` | 启用或停用资源 |
| DELETE | `/api/admin/resources/{resource}/{id}` | 软删除资源 |
服务器路由白名单当前只允许:
```text
styles
channels
```
其他 `{resource}` 值直接返回 `404 route_not_found`
### 18.1 通用查询参数
| 参数 | 说明 |
| --- | --- |
| `page``page_size` | 分页;默认 1/20,最大 100 |
| `keyword` | 渠道按名称或基础网址搜索;风格当前不使用关键词 |
| `enabled` | 渠道启停过滤 |
| `channel_type` | 渠道类型过滤 |
### 18.2 风格资源
创建或更新 JSON
```json
{
"name": "风格名称",
"image_key": "styles/2026/07/UUID.png",
"image_url": "https://媒体域名/...",
"image_mime": "image/png",
"image_size": 102400,
"image_width": 1024,
"image_height": 1024
}
```
允许字段仅为以上字段。创建时后端自动把新风格放在当前排序末尾。
### 18.3 渠道资源
创建或更新 JSON
```json
{
"name": "渠道名称",
"base_url": "https://api.example.com/v1",
"api_key": "渠道 API Key",
"warning_threshold": "10.00",
"channel_points_per_cny": "100.00",
"max_concurrency": 500,
"max_user_concurrency": 10,
"enabled": true
}
```
| 字段 | 创建 | 更新 | 说明 |
| --- | --- | --- | --- |
| `name` | 必填 | 可改 | 渠道显示名 |
| `base_url` | 必填 | 可改 | 请求基础网址,不要带具体任务路径 |
| `api_key` | 必填 | 可省略 | 更新时省略表示保留原密钥;提供时加密替换 |
| `warning_threshold` | 建议填写 | 可改 | 余额预警阈值 |
| `channel_points_per_cny` | 必填 | 必填 | 大于 0,表示每人民币对应渠道积分 |
| `max_concurrency` | 可省略 | 可改 | 默认 500,范围 1 至 5000 |
| `max_user_concurrency` | 可省略 | 可改 | 默认 10,范围 1 至 500,且不超过总并发 |
| `enabled` | 可选 | 可改 | 是否启用 |
创建时后端强制 `channel_type=relay`。列表响应不会返回密文或完整 API Key,而是返回 `api_key_masked`。读取渠道列表会异步触发一次余额同步。
### 18.4 启停和删除
启停请求:
```json
{
"enabled": false,
"reason": "调整原因"
}
```
停用渠道时会同步停用该渠道下的模型。删除使用软删除,可选请求体:
```json
{
"reason": "删除原因"
}
```
## 19. 接口调用示例
### 19.1 用户登录并查询项目
```bash
curl -X POST "https://部署域名/api/web/auth/login" \
-H "Content-Type: application/json" \
-d '{"account":"user001","password":"用户密码"}'
```
```bash
curl "https://部署域名/api/web/projects?project_type=video_redraw&page=1" \
-H "Authorization: Bearer WEB_ACCESS_TOKEN"
```
`/api/web/projects` 当前不使用分页参数,示例中的 `page` 会被忽略;项目列表直接返回数组。
### 19.2 上传原视频
```bash
curl -X POST "https://部署域名/api/web/projects/PROJECT_UUID/redraw-source" \
-H "Authorization: Bearer WEB_ACCESS_TOKEN" \
-F "file=@source.mp4"
```
### 19.3 创建生成任务
```bash
curl -X POST "https://部署域名/api/web/projects/PROJECT_UUID/episodes/EPISODE_UUID/storyboards/STORYBOARD_UUID/generate" \
-H "Authorization: Bearer WEB_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"task_type":"image_generation","input":{"prompt":"画面描述","size":"16:9"}}'
```
### 19.4 管理员创建渠道
```bash
curl -X POST "https://部署域名/api/admin/resources/channels" \
-H "Authorization: Bearer ADMIN_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name":"渠道名称",
"base_url":"https://api.example.com/v1",
"api_key":"渠道密钥",
"warning_threshold":"10",
"channel_points_per_cny":"100",
"max_concurrency":500,
"max_user_concurrency":10,
"enabled":true
}'
```
## 20. 对接注意事项
- 前端和第三方调用方应以 HTTP 状态码和 `code` 判断结果,不要只比较中文 `message`
- 收到 401 后最多刷新并重放一次原请求,避免 Refresh Token 失效时形成循环。
- 任务创建返回 202 只表示已经进入任务系统,不表示第三方任务完成。
- 任务真实状态以 PostgreSQL 返回的接口数据为准,不以 Redis 队列长度为准。
- 删除项目、剧集、资产、分镜或输出会同时清理 COS;COS 不可用时接口可能返回 503。
- 文件上传不要手工伪造 MIME;后端会同时检查扩展名、MIME、文件头或可解析性。
- 渠道 API Key、COS SecretKey、JWT Secret 和数据库密码不能传给 WEB 或 ADMIN 前端。
- 当前没有 OpenAPI/Swagger 自动生成路由;修改 `server.go`、Handler 参数或返回结构后,应同步更新本文档。