From 3d5d356700aea5e1ad5c5b19d118bda4b2945fe8 Mon Sep 17 00:00:00 2001 From: WangLeo <690854599@qq.com> Date: Tue, 9 Jun 2026 12:57:45 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E9=87=8D=E5=86=99=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=90=8E=E7=AB=AF=E5=8C=96=E6=96=B9=E6=A1=88?= =?UTF-8?q?=EF=BC=8C=E5=AF=B9=E9=BD=90=E6=96=B0=E5=B9=B3=E5=8F=B0=E6=9E=B6?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新文档以反映平台重构后的架构变化: - 新增当前架构(Platform Descriptor 模式)概述 - 新增目标架构与数据流设计 - 新增模型配置 API 格式规范(含 ui 字段映射表) - 新增分阶段迁移步骤 - 保留 RunningHub API 参考作为附录 --- docs/模型参数后端化方案.md | 393 +++++++++++++++++++++++-------------- 1 file changed, 241 insertions(+), 152 deletions(-) diff --git a/docs/模型参数后端化方案.md b/docs/模型参数后端化方案.md index da7121d..82b6630 100644 --- a/docs/模型参数后端化方案.md +++ b/docs/模型参数后端化方案.md @@ -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 descriptor(controls, 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 | 结果 URL(24 小时有效) | +| `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 上传接口三种方式传入图片。