docs: 重写模型参数后端化方案,对齐新平台架构

更新文档以反映平台重构后的架构变化:
- 新增当前架构(Platform Descriptor 模式)概述
- 新增目标架构与数据流设计
- 新增模型配置 API 格式规范(含 ui 字段映射表)
- 新增分阶段迁移步骤
- 保留 RunningHub API 参考作为附录
This commit is contained in:
王佑琳 2026-06-09 12:57:45 +08:00
parent 73f7bd888e
commit 3d5d356700

View File

@ -1,190 +1,279 @@
# 欢迎使用 RunningHub API轻松调用 RunningHub 标准模型API
# 模型参数后端化方案
## 开始使用
## 一、当前架构(平台重构后)
### 注册用户
平台重构已采用 **Platform Descriptor 模式**Painting 和 Video 统一走扁平 `modelParams`
先注册成为RunningHub网站的用户并充值钱包。标准模型API仅支持企业级-共享API Key
```
src/platforms/
├── registry.js # 注册表registerPlatform() + createPlatform()
├── painting/
│ ├── index.js # Painting descriptorcontrols, state, loadConfig 等)
│ ├── modelSelector.vue
│ ├── imageUploader.vue
│ ├── models/ # 模型参数 schema本地 JS 文件,待后端化)
│ │ ├── index.js # getModelConfig(modelName) → 查找本地 config
│ │ └── flux-2.js # 单个模型的 params 定义
│ └── controls/
│ ├── proportion.vue
│ ├── dimension.vue
│ ├── quality.vue
│ └── quantity.vue
└── video/
├── index.js # Video descriptor仍用 fetchModelConfig 拉远程 JSON
├── modelSelector.vue
├── imageUploader.vue
└── controls/
├── pattern.vue
├── proportion.vue
└── time.vue
```
### 获取您的 API Key
**核心数据流(两个平台统一):**
RunningHub 为每位用户自动生成一个独特的 32 位 API KEY
1. 用户选择模型 → `dialogBox` 调用 `platform.loadConfig(modelName, modelType)`
2. `loadConfig` 获取参数 schema → 驱动 `controls` 数组渲染对应 UI 控件
3. 用户点击发送 → `platform.buildTaskBody({ prompt, referenceImages })` 返回扁平 `modelParams`
4. `createTask.js` 透传 `data.body`(不再做任何转换)
5. POST `/suanli/v1/tasks`,携带 `X-Session-Id` header
请妥善保存您的 API KEY不要外泄后续步骤将依赖此密钥进行操作
**当前参数配置来源(待统一):**
### 提交请求
| 平台 | 参数配置来源 | 位置 |
|------|-------------|------|
| Painting | 本地 JS 文件(硬编码) | `src/platforms/painting/models/*.js` |
| Video | 远程静态 JSON每日 localStorage 缓存) | `fetchModelConfig()``resources.xueai.art/AIGC/static/public/Platform/Video/workflows/...` |
提交 API 请求。RunningHub API 已为您处理 API Key您只需提交请求即可
两个平台的 `buildTaskBody()` 均已返回扁平 `modelParams`,不再构造 `{ workflowId, nodeInfoList }` 格式。
---
## 二、目标架构
将模型参数配置从**前端代码**迁移到**后端 API**,实现:
- 新增模型/修改参数无需前端发版
- Painting 和 Video 使用统一的 API 获取配置
- 前端只保留 UI 控件库,参数 schema 完全由后端驱动
```
后端 API
├── GET /api/v1/platforms/:code/models # 模型列表(已有)
│ └── 响应: [{ id, display_name, tags, config? }]
├── GET /api/v1/models/:id/config # 模型参数配置(新增)
│ └── 响应: { params: [...], inputType, maxImages, ... }
└── POST /api/v1/tasks # 创建任务(已有)
└── 请求体: 扁平 modelParams与 RunningHub API 格式对齐)
```
**改造后的数据流:**
```
用户选择模型
→ platform.loadConfig(modelName)
→ GET /api/v1/models/:id/config
→ 返回 { params: [{ name, ui, default, options, ... }] }
→ 前端根据 ui 字段渲染对应控件
→ 用户填写参数
→ buildTaskBody() 返回扁平 { aspectRatio, resolution, ... }
→ POST /api/v1/tasks
```
---
## 三、模型配置 API 格式
### 3.1 请求
```
GET /api/v1/models/:modelId/config
```
`modelId` 来自模型列表接口返回的 `id` 字段UUID
### 3.2 响应格式
```json
{
"code": 0,
"data": {
"inputType": "text",
"maxImages": 4,
"promptPlaceholder": "描述你想生成的画面和动作。",
"params": [
{
"name": "prompt",
"ui": "textarea",
"label": "提示词",
"required": true,
"default": ""
},
{
"name": "aspectRatio",
"ui": "proportion",
"label": "比例",
"default": "1:1",
"options": ["1:1", "3:4", "4:3", "9:16", "16:9", "custom"]
},
{
"name": "resolution",
"ui": "resolution",
"label": "分辨率",
"default": "2k",
"options": ["1k", "2k", "4k"]
},
{
"name": "size",
"ui": "dimension",
"label": "尺寸",
"default": "1024*1024",
"dimension": {
"width": { "min": 256, "max": 6197 },
"height": { "min": 256, "max": 4096 }
}
},
{
"name": "quality",
"ui": "select",
"label": "画质",
"default": "medium",
"options": ["low", "medium", "high"]
},
{
"name": "quantity",
"ui": "quantity",
"label": "生成数量",
"default": 1,
"options": [1, 2, 3, 4]
},
{
"name": "imageUrl",
"ui": "imageUpload",
"label": "参考图",
"maxCount": 4
}
]
}
}
```
### 3.3 `ui` 字段与前端控件映射
| `ui` 值 | 前端控件 | 说明 |
|---------|---------|------|
| `textarea` | Sender 内置 textarea | 提示词输入框,不需要额外渲染控件 |
| `proportion` | `PaintingProportion` / `VideoProportion` | 比例选择 Popover`options` 含 `custom` 时允许自定义宽高 |
| `resolution` | `proportion` 控件内部 | 分辨率子选项,与 proportion 共用 Popover |
| `dimension` | `DimensionInput` | **组合模式**:单字段 `"W*H"` 格式,通过 `dimension.parse/format` 序列化 |
| `dimensionWidth` + `dimensionHeight` | `DimensionInput` | **拆分模式**:两个独立字段,共享同一个 Popover 和比例锁 |
| `select` | `Select` | 通用下拉选择(如 quality |
| `quantity` | `Quantity` | 生成数量,上限由 `options` 最大值派生 |
| `imageUpload` | `ImageUploader` | 参考图上传,`maxCount` 控制数量上限 |
| `hidden` | 无 | 静默写入默认值,不渲染控件 |
### 3.4 条件显示
```json
{
"name": "customWidth",
"ui": "dimensionWidth",
"showWhen": { "aspectRatio": "custom" }
}
```
`showWhen` 字段使参数仅在指定条件满足时显示。当前支持的条件:`aspectRatio` 值为 `custom`
---
## 四、迁移步骤
### 阶段一:后端实现模型配置 API
- [ ] 设计并实现 `GET /api/v1/models/:id/config` 接口
- [ ] 将 Painting 的 9 个模型配置(`src/platforms/painting/models/*.js`)迁移到数据库/配置文件
- [ ] 将 Video 的 workflow 配置(`resources.xueai.art/AIGC/static/public/Platform/Video/workflows/...`)迁移到同一接口
- [ ] 响应格式对齐 3.2 节的 schema
### 阶段二:前端适配
- [ ] `src/platforms/painting/models/` 目录删除,`getModelConfig()` 改为调用 API
- [ ] `src/utils/modelConfig.js`Video 旧架构遗留删除Video descriptor 改为调用同一 API
- [ ] `src/utils/createTask.js`(当前仅透传)删除,`dialogBox` 直接使用 `buildTaskBody()` 返回值
- [ ] Painting descriptor 的 `loadConfig()` 改为 `fetch` API + 本地缓存30s TTL与模型列表一致
### 阶段三:清理
- [ ] 删除 `src/utils/modelConfig.js`
- [ ] 删除 `src/utils/createTask.js`
- [ ] 确认前端不再包含任何硬编码的模型参数
---
## 五、与 RunningHub API 的关系
后端创建任务的请求体格式应**直接对齐 RunningHub 标准模型 API**,前端 `buildTaskBody()` 返回的扁平 `modelParams` 即是 API body
```json
{
"prompt": "...",
"resolution": "720p",
"aspectRatio": "16:9",
"duration": 5
}
```
不再需要中间层转换(旧架构的 `src/config/runninghub/` 已删除)。
---
## 附录RunningHub API 参考
以下为 RunningHub 标准模型 API 的原始文档,作为后端任务创建接口的设计参考。
### A.1 提交任务
```curl
curl --location --request POST 'https://www.runninghub.cn/openapi/v2/rhart-video/ltx-2.3/text-to-video' \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${RUNNINGHUB_API_KEY}" \
--data-raw '{
"prompt": "第一视角无人机跟拍视角主体为一只自由飞翔的鸟镜头快速划过城市上空与飞鸟同步高速飞行沉浸式第一视角流畅丝滑运镜低空急速掠过楼宇街道强烈速度感与飞行沉浸感电影级动态光影稳定不抖动4K 超清画质,飞鸟为主视觉,城市背景虚化,氛围感拉满。",
"prompt": "...",
"resolution": "720p",
"aspectRatio": "16:9",
"duration": 5
}'
```
#### 请求参数说明
| 参数说明 | 类型 | 必填/可选 | AI 应用程序生成的结果。 |
| 参数 | 类型 | 必填/可选 | 说明 |
| --- | --- | --- | --- |
| `prompt` | String | 必填 | |
| `prompt` | String | 必填 | 提示词 |
| `resolution` | String | 必填 | 枚举值: [1080p, 720p, 480p] |
| `aspectRatio` | String | 必填 | 枚举值: [16:9, 9:16] |
| `duration` | Int | 必填 | 输入范围值: 5 - 15 |
#### 响应示例
```json
{
"taskId": "2013508786110730241",
"status": "RUNNING",
"errorCode": "",
"errorMessage": "",
"results": null,
"clientId": "f828b9af25161bc066ef152db7b29ccc",
"promptTips": "{\"result\": true, \"error\": null, \"outputs_to_execute\": [\"4\"], \"node_errors\": {}}"
}
```
#### 响应字段说明
| 参数说明 | 类型 | AI 应用程序生成的结果。 |
| --- | --- | --- |
| `taskId` | String | 任务ID用于后续查询任务状态 |
| `status` | String | 当前任务状态常见状态QUEUED (排队中), RUNNING (运行中), SUCCESS (成功), FAILED (失败) |
| `errorCode` | String | 错误码,仅在失败时返回 |
| `errorMessage` | String | 错误具体信息 |
| `results` | List | 生成结果(提交时为 null |
| ├ `url` | String | 重要提醒:该链接有效期仅为 24 小时。任务生成结束后,请务必在此时间窗口内将视频文件下载或转存至您的服务器。逾期后链接将永久失效且无法恢复。 |
| ├ `nodeId` | String | 生成该结果的工作流节点 ID |
| ├ `outputType` | String | 文件扩展名 (如 png, mp4, txt) |
| └ `text` | String | 如果输出是纯文本,内容将显示在此字段 |
| `clientId` | String | 客户端会话ID用于标识本次连接 |
| `promptTips` | String (JSON) | ComfyUI 后端的校验信息包含需执行的节点ID等调试信息 |
### 查询结果与 Webhook
如果在提交时添加了 "webhookUrl": "https://example.com/webhook" 请求体参数RunningHub 会在任务完成时向您的URL发送POST请求
#### 请求示例
### A.2 查询结果
```curl
curl --location --request POST 'https://www.runninghub.cn/openapi/v2/query' \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${RUNNINGHUB_API_KEY}" \
--data-raw '{
"taskId": "${RUNNINGHUB_TASKID}"
}'
--data-raw '{"taskId": "${RUNNINGHUB_TASKID}"}'
```
#### 响应示例
响应字段:
```json
{
"taskId": "2013508786110730241",
"status": "SUCCESS",
"errorCode": "",
"errorMessage": "",
"failedReason": {},
"usage": {
"consumeMoney": null,
"consumeCoins": null,
"taskCostTime": "0",
"thirdPartyConsumeMoney": null
},
"results": [
{
"url": "https://rh-images-1252422369.cos.ap-beijing.myqcloud.com/b04e28cad0ee39193921a30a2eb4dc00/output/ComfyUI_00001_plhjr_1768892915.png",
"nodeId": "2",
"outputType": "png",
"text": null
}
],
"clientId": "",
"promptTips": ""
}
```
#### 响应字段说明
| 参数说明 | 类型 | AI 应用程序生成的结果。 |
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `taskId` | String | 任务 ID |
| `status` | String | 任务最终状态SUCCESS 表示生成成功 |
| `results` | List | 生成结果列表,包含图片、视频或文本等输出 |
| ├ `url` | String | 重要提醒:该链接有效期仅为 24 小时。任务生成结束后,请务必在此时间窗口内将视频文件下载或转存至您的服务器。逾期后链接将永久失效且无法恢复。 |
| ├ `nodeId` | String | 生成该结果的工作流节点 ID |
| ├ `outputType` | String | 文件扩展名 (如 png, mp4, txt) |
| └ `text` | String | 如果输出是纯文本,内容将显示在此字段 |
| `errorCode` | String | 错误码 (如有) |
| `errorMessage` | String | 错误信息 (如有) |
| `failedReason` | Object | ComfyUI 相关的失败原因 |
| `usage` | Object | 任务消耗信息 |
| ├ `thirdPartyConsumeMoney` | String | 三方API消费金额 |
| ├ `consumeMoney` | String | 运行时长消耗金额 |
| ├ `consumeCoins` | String | 运行消耗的RH币 |
| └ `taskCostTime` | String | 运行耗时ComfyUI 工作流运行时长) |
### 文件上传
| `status` | String | QUEUED / RUNNING / SUCCESS / FAILED |
| `results` | List | 生成结果列表 |
| `results[].url` | String | 结果 URL24 小时有效) |
| `results[].nodeId` | String | 工作流节点 ID |
| `results[].outputType` | String | 文件扩展名 (png, mp4, txt) |
| `results[].text` | String | 纯文本输出内容 |
资源文件(如 imageUrls参数支持传入文件 URL 或 Base64 Data URI。
### A.3 文件上传
#### 公共 URL
直接传递可公开访问的 URL
```json
{
"imageUrls": [
"https://example.com/image.png"
]
}
```
#### Base64 data URI
以 Base64 格式嵌入图片:
```json
{
"images": [
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
]
}
```
#### RH 上传接口
上传本地文件以获取一个 URL。
**Endpoint:** `https://www.runninghub.cn/openapi/v2/media/upload/binary`
**请求**
```curl
curl --location --request POST 'https://www.runninghub.cn/openapi/v2/media/upload/binary' \
--header 'Authorization: Bearer [Your API KEY]' \
--form 'file=@/path/to/image.png'
```
**响应**
```json
{
"code": 0,
"message": "success",
"data": {
"type": "image",
"download_url": "xxxx.png",
"fileName": "openapi/xxxx.png",
"size": "3490"
}
}
```
**备注:** 上传后获得的链接有效期为 1 天,超期将无法通过 URL 直接访问。
**上传接口:** `POST https://www.runninghub.cn/openapi/v2/media/upload/binary`
支持 `imageUrls`(公共 URL、Base64 Data URI、RH 上传接口三种方式传入图片。