- 删除 src/platforms/painting/models/(9 个硬编码 JS) - 删除 src/utils/modelConfig.js(Video 旧远程 JSON 加载) 配置已全部迁移至后端 API。
5.8 KiB
5.8 KiB
模型参数后端化 — 前端适配设计
概述
将 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)
// 批量获取模型配置
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()+ 写入缓存 pendingRequestsMap 并发去重
新增 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 增强
- dimension.separator → 生成
parse/format函数(替代硬编码的 JS 函数) config.promptPlaceholder→ 同步到promptPlaceholder.value- 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 字段:
// 例如 { 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():逻辑不变