# 模型参数后端化 — 前端适配设计 ## 概述 将 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()`:逻辑不变