# 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 ``` ### 1.4 管理端认证 除登录、刷新、退出和健康检查外,ADMIN 接口需要: ```http Authorization: Bearer ``` 创建兑换码批次还需要管理员二次认证: ```http X-Admin-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` | 创建项目 | JSON:ProjectInput | | GET | `/api/web/projects/{project_id}` | 获取项目、模型配置和剧集详情 | Path:`project_id` | | PUT | `/api/web/projects/{project_id}` | 修改项目基础信息 | JSON:ProjectInput | | 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` | 创建模型配置 | JSON:ModelBody | | PUT | `/api/admin/models/{id}` | 更新模型并整体替换价格 | JSON:ModelBody | 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 参数或返回结构后,应同步更新本文档。