feat: 新增 modelConfigHelper 共享工具函数

This commit is contained in:
王佑琳 2026-06-09 17:55:51 +08:00
parent 025ce0de9f
commit af7debd54c

View File

@ -0,0 +1,160 @@
// 模型配置共享工具函数
// 供 Painting / Video descriptor 使用
/**
* 检测 dimension 配置模式
* @param {object | null} config - 模型配置对象
* @returns {object | null}
* - combined: { type: 'combined', config: dimension子对象, paramName: string }
* - split: { type: 'split', wParam: 宽度参数, hParam: 高度参数 }
* - null: dimension 参数
*/
export function getDimConfig(config) {
if (!config) return null
const dimParam = config.params.find((p) => p.ui === 'dimension')
if (dimParam) return { type: 'combined', config: dimParam.dimension, paramName: dimParam.name }
const wParam = config.params.find((p) => p.ui === 'dimensionWidth')
const hParam = config.params.find((p) => p.ui === 'dimensionHeight')
if (wParam && hParam) return { type: 'split', wParam, hParam }
return null
}
/**
* 检查 showWhen 条件是否满足
* @param {object} param - 参数定义可能含 showWhen
* @param {object} paramValues - 当前所有参数值
* @returns {boolean}
*/
export function checkShowWhen(param, paramValues) {
if (!param.showWhen) return true
return Object.entries(param.showWhen).every(([key, expected]) => {
return paramValues[key] === expected
})
}
/**
* API 返回的 config 同步到响应式 state
*
* state 对象需包含以下属性均为 ref reactive
* modelConfig, paramValues, proportion, resolution, quantity, quality,
* customWidth, customHight, dimWidth, dimHeight, promptPlaceholder
*/
export function syncDefaults(config, state) {
const {
modelConfig,
paramValues,
proportion,
resolution,
quantity,
quality,
customWidth,
customHight,
dimWidth,
dimHeight,
promptPlaceholder
} = state
modelConfig.value = config
if (!config) return
// 1. dimension.separator → 生成 parse/format在遍历 params 之前完成)
config.params.forEach((p) => {
if (p.ui === 'dimension' && p.dimension?.separator && !p.dimension.parse) {
const sep = p.dimension.separator
p.dimension.parse = (val) => {
const parts = (val || '').split(sep)
return { width: Number.parseInt(parts[0]) || 0, height: Number.parseInt(parts[1]) || 0 }
}
p.dimension.format = (w, h) => `${w}${sep}${h}`
}
})
// 2. 初始化 paramValues已存在的 key 保留,避免切换模型时丢失值)
config.params.forEach((p) => {
if (!(p.name in paramValues)) {
paramValues[p.name] = p.default ?? (p.name === 'outputFormat' ? 'png' : '')
}
})
// 3. 同步专用 ref
const ratioParam = config.params.find((p) => p.ui === 'proportion')
if (ratioParam) proportion.value = ratioParam.default || '1:1'
const resParam = config.params.find((p) => p.ui === 'resolution')
if (resParam) resolution.value = resParam.default || '2k'
const qtyParam = config.params.find((p) => p.ui === 'quantity')
if (qtyParam) quantity.value = qtyParam.default || 1
const cwParam = config.params.find((p) => p.name === 'customWidth')
if (cwParam) customWidth.value = cwParam.default || 1024
const chParam = config.params.find((p) => p.name === 'customHight')
if (chParam) customHight.value = chParam.default || 1024
const qualityParam = config.params.find((p) => p.name === 'quality')
if (qualityParam) quality.value = qualityParam.default || 'medium'
// 4. dimension 初始化
const dc = getDimConfig(config)
if (dc?.type === 'split') {
dimWidth.value = dc.wParam.default || 1024
dimHeight.value = dc.hParam.default || 1024
} else if (dc?.type === 'combined') {
const dimParam = config.params.find((p) => p.name === dc.paramName)
const raw = dimParam?.default || ''
const parsed = dc.config.parse(raw)
dimWidth.value = parsed.width
dimHeight.value = parsed.height
}
// 5. promptPlaceholder 同步
if (config.promptPlaceholder) {
promptPlaceholder.value = config.promptPlaceholder
}
}
/**
* 将专用 ref 的当前值回写到 paramValues
* buildTaskBody 之前调用
*/
export function syncParamValues(config, state) {
const {
paramValues,
proportion,
resolution,
quantity,
customWidth,
customHight,
dimWidth,
dimHeight,
quality
} = state
const ratioParam = config?.params?.find((p) => p.ui === 'proportion')
if (ratioParam) paramValues[ratioParam.name] = proportion.value
const resParam = config?.params?.find((p) => p.ui === 'resolution')
if (resParam) paramValues[resParam.name] = resolution.value
const qtyParam = config?.params?.find((p) => p.ui === 'quantity')
if (qtyParam) paramValues[qtyParam.name] = quantity.value
if (config?.params?.find((p) => p.name === 'customWidth')) {
paramValues.customWidth = customWidth.value
}
if (config?.params?.find((p) => p.name === 'customHight')) {
paramValues.customHight = customHight.value
}
if (config?.params?.find((p) => p.name === 'quality')) {
paramValues.quality = quality.value
}
const dc = getDimConfig(config)
if (dc?.type === 'split') {
paramValues[dc.wParam.name] = dimWidth.value
paramValues[dc.hParam.name] = dimHeight.value
} else if (dc?.type === 'combined') {
paramValues[dc.paramName] = dc.config.format(dimWidth.value, dimHeight.value)
}
}