AI_Painting_V2.0/docs/superpowers/specs/2026-06-09-模型参数后端化-前端适配-design.md
WangLeo 5c24de354b refactor: 删除旧模型配置文件
- 删除 src/platforms/painting/models/(9 个硬编码 JS)
- 删除 src/utils/modelConfig.js(Video 旧远程 JSON 加载)
配置已全部迁移至后端 API。
2026-06-09 18:09:25 +08:00

148 lines
5.8 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.

# 模型参数后端化 — 前端适配设计
## 概述
将 Painting/Video 平台的模型参数配置从**前端代码硬编码**迁移至**后端 API 获取**,实现新增模型或修改参数无需前端发版。
方案 A最小改动只替换配置来源保持现有架构不变。
## 一、数据流
```
页面加载 → platform.loadModels()
→ fetchPlatformModels(code) // 已有
→ 提取所有 modelId
→ POST /suanli/v1/models/configs // 新增,批量获取
→ 返回 { "uuid1": { config }, ... }
→ 逐条写入 60s localStorage 缓存
用户切换模型 → platform.loadConfig(modelName)
→ getModelId(type, modelName) // 已有
→ getModelConfig(modelId) // 新增,优先缓存 → fallback 单条 API
→ syncDefaults(config)
→ modelConfig.value = config
→ 遍历 params 初始化 paramValues + 专用 ref
→ dimension.separator → 生成 parse/format
→ promptPlaceholder 同步
→ visibleControls 更新(含 showWhen 条件判断)
→ 用户填写参数 → buildTaskBody() → 扁平 modelParams → POST 创建任务
```
## 二、API 层
### 新增 API 函数(`src/apis/display/index.js`
```js
// 批量获取模型配置
export function requestModelConfigsBatch(modelIds) {
return service.post('/suanli/v1/models/configs', { modelIds })
}
// 单条查询(缓存未命中 fallback
export function requestModelConfig(modelId) {
return service.get(`/suanli/v1/models/${modelId}/config`)
}
```
### 缓存层(`src/utils/modelApi.js`
新增 `getModelConfig(modelId)`
- 优先读 localStoragekey: `model_config_{modelId}`TTL 60 秒)
- 未命中调 `requestModelConfig()` + 写入缓存
- `pendingRequests` Map 并发去重
新增 `preloadModelConfigs(modelIds)`
- 调用 `requestModelConfigsBatch(modelIds)`
- 逐条写入 localStorage 缓存
## 三、共享工具函数
新建 `src/utils/modelConfigHelper.js`
| 导出函数 | 说明 |
|---------|------|
| `syncDefaults(config, state)` | params → paramValues + 专用 refproportion/resolution/quantity/dimension/quality |
| `syncParamValues(config, state)` | 专用 ref 回写到 paramValues |
| `getDimConfig(config)` | 检测 combined/split 模式,返回 dimension 配置 |
| `checkShowWhen(param, paramValues)` | 检查 showWhen 条件是否满足 |
### `syncDefaults` 增强
1. dimension.separator → 生成 `parse/format` 函数(替代硬编码的 JS 函数)
2. `config.promptPlaceholder` → 同步到 `promptPlaceholder.value`
3. customWidth/customHight 继续通过 `p.name` 查找(保持现有硬编码兼容)
## 四、Painting 平台改造
`src/platforms/painting/index.js`
- `loadConfig()` 改为 `getModelId()` + `getModelConfig()` API 调用
- `syncDefaults`/`syncParamValues`/`getDimConfig` 改为从 helper 导入
- 移除 `import { getModelConfig } from './models/index.js'`
- controls 的 `show()` 加入 `checkShowWhen` 判断
## 五、Video 平台改造
`src/platforms/video/index.js`
| 项目 | 当前 | 改造后 |
|------|------|--------|
| 配置来源 | `modelConfig.js` → 远程 JSON | 统一 API |
| 配置存储 | `modelDisplayConfig` | 统一 `modelConfig` |
| 数据结构 | `config.display.*` | 统一 `params[]` 数组 |
| `loadConfig` | `loadInternalConfig` | 改为 API + `syncDefaults` |
| `buildTaskBody` | 硬编码 5 字段 | 改为 params 驱动(与 Painting 一致) |
| `showImageUploader` | `modelType !== 'text'` | 改为 `config.inputType` 驱动 |
| controls | pattern/proportion/time | 改为按 `params[]``ui` 驱动 |
Video 现有的 pattern/time 控件对应的 ui 值暂未定义,保留占位,等后端配置数据就绪后再适配。
## 六、showWhen 条件显示
`checkShowWhen(param, paramValues)` 检查 param 的 `showWhen` 字段:
```js
// 例如 { aspectRatio: 'custom' } → 仅在 paramValues.aspectRatio === 'custom' 时显示
showWhen 为空 总是显示
showWhen 存在 所有 key-value 匹配才显示
```
controls 的 `show()` 中调用,因为直接读取 `paramValues[key]`reactiveVue computed 自动追踪依赖。
## 七、文件清理
| 路径 | 操作 |
|------|------|
| `src/utils/modelConfigHelper.js` | **新建** |
| `src/platforms/painting/models/`9 文件) | **删除** |
| `src/utils/modelConfig.js` | **删除** |
| `src/utils/createTask.js` | **删除** |
删除前需确认 `createTask.js` 无其他文件 import。
## 八、API 验证发现
已用 token 实测 Painting 全部 8 个模型,结论:
| 发现 | 结论 |
|------|------|
| 单条 API | `GET /suanli/v1/models/:id/config``data` 直接返回 config |
| 批量 API | `POST /suanli/v1/models/configs``data``{ modelId: config, ... }`,不存在的 ID 返回空 `{}` |
| `dimension.separator` | 字符串 `"*"`,需前端 `syncDefaults` 生成 parse/format |
| `dimensionWidth/Height``min/max` | 在 param 根层,与硬编码结构一致,`getDimConfig` 直接兼容 |
| `imageUpload``maxCount` | 在 param 根层,`imageUploadLimit()` 直接兼容 |
| `number` 类型的 `min/max` | 在 param 根层,与 dimensionWidth 一致 |
| customWidth/customHight | `ui: 'number'``showWhen: {"aspectRatio": "custom"}` |
| hidden 参数 | 不返回 `options` 字段(与硬编码不同),不影响功能 |
| `type` 字段 | API 不返回,前端 `syncDefaults` 不依赖,无影响 |
| Video 平台 | 模型列表为空,改造后无 fallback 将不可用 |
## 九、不改动的部分
- `src/components/dialogBox/index.vue`:通过 `platform.loadConfig()` 多态调用,改动仅在 descriptor 内部
- `src/utils/modelApi.js``getModelId()`/`fetchPlatformModels()` 保持不变,新增两个函数
- controls 组件proportion.vue / dimension.vue / quality.vue / quantity.vueUI 不变
- `buildTaskBody()` / `fillFromResult()`:逻辑不变