- 删除 src/platforms/painting/models/(9 个硬编码 JS) - 删除 src/utils/modelConfig.js(Video 旧远程 JSON 加载) 配置已全部迁移至后端 API。
148 lines
5.8 KiB
Markdown
148 lines
5.8 KiB
Markdown
# 模型参数后端化 — 前端适配设计
|
||
|
||
## 概述
|
||
|
||
将 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)`:
|
||
|
||
- 优先读 localStorage(key: `model_config_{modelId}`,TTL 60 秒)
|
||
- 未命中调 `requestModelConfig()` + 写入缓存
|
||
- `pendingRequests` Map 并发去重
|
||
|
||
新增 `preloadModelConfigs(modelIds)`:
|
||
|
||
- 调用 `requestModelConfigsBatch(modelIds)`
|
||
- 逐条写入 localStorage 缓存
|
||
|
||
## 三、共享工具函数
|
||
|
||
新建 `src/utils/modelConfigHelper.js`:
|
||
|
||
| 导出函数 | 说明 |
|
||
|---------|------|
|
||
| `syncDefaults(config, state)` | params → paramValues + 专用 ref(proportion/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]`(reactive),Vue 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.vue):UI 不变
|
||
- `buildTaskBody()` / `fillFromResult()`:逻辑不变
|