feat: Painting 平台接入模型配置 API
将模型配置从代码内硬编码切换为后端 API 动态加载,使用 modelConfigHelper 共享工具函数。
This commit is contained in:
parent
33094e675c
commit
308581e2e4
@ -1,23 +1,13 @@
|
||||
import { ref, reactive, markRaw } from 'vue'
|
||||
import { fetchPlatformModels, getPlatformCode } from '@/utils/modelApi'
|
||||
import { getModelConfig } from './models/index.js'
|
||||
import PaintingModelSelector from './modelSelector.vue'
|
||||
import PaintingProportion from './controls/proportion.vue'
|
||||
import { markRaw, reactive, ref } from 'vue'
|
||||
import { fetchPlatformModels, getModelConfig, getModelId, getPlatformCode, preloadModelConfigs } from '@/utils/modelApi'
|
||||
import { syncDefaults as _syncDefaults, syncParamValues as _syncParamValues, checkShowWhen, getDimConfig } from '@/utils/modelConfigHelper.js'
|
||||
import { registerPlatform } from '../registry.js'
|
||||
import DimensionInput from './controls/dimension.vue'
|
||||
import PaintingProportion from './controls/proportion.vue'
|
||||
import QualitySelect from './controls/quality.vue'
|
||||
import Quantity from './controls/quantity.vue'
|
||||
import ImageUploader from './imageUploader.vue'
|
||||
import { registerPlatform } from '../registry.js'
|
||||
|
||||
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
|
||||
}
|
||||
import PaintingModelSelector from './modelSelector.vue'
|
||||
|
||||
export function definePaintingPlatform() {
|
||||
const model = ref('Flux 2')
|
||||
@ -35,142 +25,118 @@ export function definePaintingPlatform() {
|
||||
const paramValues = reactive({})
|
||||
|
||||
const state = {
|
||||
model, modelType,
|
||||
proportion, resolution,
|
||||
customWidth, customHight,
|
||||
dimWidth, dimHeight,
|
||||
quantity, quality,
|
||||
paramValues, modelConfig,
|
||||
model,
|
||||
modelType,
|
||||
proportion,
|
||||
resolution,
|
||||
customWidth,
|
||||
customHight,
|
||||
dimWidth,
|
||||
dimHeight,
|
||||
quantity,
|
||||
quality,
|
||||
paramValues,
|
||||
modelConfig
|
||||
}
|
||||
|
||||
// state 对象供 helper 函数使用
|
||||
const paintingState = {
|
||||
modelConfig,
|
||||
paramValues,
|
||||
proportion,
|
||||
resolution,
|
||||
quantity,
|
||||
quality,
|
||||
customWidth,
|
||||
customHight,
|
||||
dimWidth,
|
||||
dimHeight,
|
||||
promptPlaceholder
|
||||
}
|
||||
|
||||
function syncDefaults(config) {
|
||||
modelConfig.value = config
|
||||
if (!config) return
|
||||
config.params.forEach(p => {
|
||||
if (!(p.name in paramValues)) {
|
||||
paramValues[p.name] = p.default ?? (p.name === 'outputFormat' ? 'png' : '')
|
||||
}
|
||||
})
|
||||
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'
|
||||
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
|
||||
}
|
||||
_syncDefaults(config, paintingState)
|
||||
}
|
||||
|
||||
function syncParamValues() {
|
||||
const ratioParam = modelConfig.value?.params?.find(p => p.ui === 'proportion')
|
||||
if (ratioParam) paramValues[ratioParam.name] = proportion.value
|
||||
const resParam = modelConfig.value?.params?.find(p => p.ui === 'resolution')
|
||||
if (resParam) paramValues[resParam.name] = resolution.value
|
||||
const qtyParam = modelConfig.value?.params?.find(p => p.ui === 'quantity')
|
||||
if (qtyParam) paramValues[qtyParam.name] = quantity.value
|
||||
if (modelConfig.value?.params?.find(p => p.name === 'customWidth')) {
|
||||
paramValues.customWidth = customWidth.value
|
||||
}
|
||||
if (modelConfig.value?.params?.find(p => p.name === 'customHight')) {
|
||||
paramValues.customHight = customHight.value
|
||||
}
|
||||
if (modelConfig.value?.params?.find(p => p.name === 'quality')) {
|
||||
paramValues.quality = quality.value
|
||||
}
|
||||
const dc = getDimConfig(modelConfig.value)
|
||||
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)
|
||||
}
|
||||
_syncParamValues(modelConfig.value, paintingState)
|
||||
}
|
||||
|
||||
const controls = [
|
||||
{
|
||||
name: 'proportion',
|
||||
component: markRaw(PaintingProportion),
|
||||
show: (config) => !!config?.params?.find(p => p.ui === 'proportion'),
|
||||
show: (config) => !!config?.params?.find((p) => p.ui === 'proportion'),
|
||||
props: (config) => {
|
||||
const ratioParam = config?.params?.find(p => p.ui === 'proportion')
|
||||
const resParam = config?.params?.find(p => p.ui === 'resolution')
|
||||
const ratioParam = config?.params?.find((p) => p.ui === 'proportion')
|
||||
const resParam = config?.params?.find((p) => p.ui === 'resolution')
|
||||
return {
|
||||
modelValue: proportion.value,
|
||||
'modelValue': proportion.value,
|
||||
'onUpdate:modelValue': (v) => { proportion.value = v },
|
||||
resolution: resolution.value,
|
||||
'resolution': resolution.value,
|
||||
'onUpdate:resolution': (v) => { resolution.value = v },
|
||||
width: customWidth.value,
|
||||
'width': customWidth.value,
|
||||
'onUpdate:width': (v) => { customWidth.value = v },
|
||||
height: customHight.value,
|
||||
'height': customHight.value,
|
||||
'onUpdate:height': (v) => { customHight.value = v },
|
||||
proportionOptions: ratioParam?.options
|
||||
?.filter(o => o !== 'custom')
|
||||
.map(o => ({ value: o, label: o })) || [],
|
||||
resolutionOptions: resParam?.options
|
||||
?.map(o => ({ value: o, label: o.toUpperCase() })) || [],
|
||||
allowCustom: ratioParam?.options?.includes('custom') || false,
|
||||
'proportionOptions': ratioParam?.options
|
||||
?.filter((o) => o !== 'custom')
|
||||
.map((o) => ({ value: o, label: o })) || [],
|
||||
'resolutionOptions': resParam?.options
|
||||
?.map((o) => ({ value: o, label: o.toUpperCase() })) || [],
|
||||
'allowCustom': ratioParam?.options?.includes('custom') || false
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'dimension',
|
||||
component: markRaw(DimensionInput),
|
||||
show: (config) => !!config?.params?.find(p => p.ui === 'dimension' || p.ui === 'dimensionWidth'),
|
||||
show: (config) => {
|
||||
const hasDim = config?.params?.find((p) =>
|
||||
(p.ui === 'dimension' || p.ui === 'dimensionWidth') && checkShowWhen(p, paramValues)
|
||||
)
|
||||
return !!hasDim
|
||||
},
|
||||
props: (config) => {
|
||||
const dc = getDimConfig(config)
|
||||
return {
|
||||
width: dimWidth.value,
|
||||
'width': dimWidth.value,
|
||||
'onUpdate:width': (v) => { dimWidth.value = v },
|
||||
height: dimHeight.value,
|
||||
'height': dimHeight.value,
|
||||
'onUpdate:height': (v) => { dimHeight.value = v },
|
||||
minW: dc?.config?.width?.min || dc?.wParam?.min || 256,
|
||||
maxW: dc?.config?.width?.max || dc?.wParam?.max || 6197,
|
||||
minH: dc?.config?.height?.min || dc?.hParam?.min || 256,
|
||||
maxH: dc?.config?.height?.max || dc?.hParam?.max || 4096,
|
||||
'minW': dc?.config?.width?.min || dc?.wParam?.min || 256,
|
||||
'maxW': dc?.config?.width?.max || dc?.wParam?.max || 6197,
|
||||
'minH': dc?.config?.height?.min || dc?.hParam?.min || 256,
|
||||
'maxH': dc?.config?.height?.max || dc?.hParam?.max || 4096
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'quality',
|
||||
component: markRaw(QualitySelect),
|
||||
show: (config) => !!config?.params?.find(p => p.name === 'quality'),
|
||||
show: (config) => !!config?.params?.find((p) => p.name === 'quality'),
|
||||
props: (config) => {
|
||||
const q = config?.params?.find(p => p.name === 'quality')
|
||||
const q = config?.params?.find((p) => p.name === 'quality')
|
||||
return {
|
||||
modelValue: quality.value,
|
||||
'modelValue': quality.value,
|
||||
'onUpdate:modelValue': (v) => { quality.value = v },
|
||||
options: q?.options?.map(o => ({ value: o, label: o })) || [],
|
||||
'options': q?.options?.map((o) => ({ value: o, label: o })) || []
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'quantity',
|
||||
component: markRaw(Quantity),
|
||||
show: (config) => !!config?.params?.find(p => p.ui === 'quantity'),
|
||||
show: (config) => !!config?.params?.find((p) => p.ui === 'quantity'),
|
||||
props: (config) => {
|
||||
const qtyParam = config?.params?.find(p => p.ui === 'quantity')
|
||||
const qtyParam = config?.params?.find((p) => p.ui === 'quantity')
|
||||
return {
|
||||
modelValue: quantity.value,
|
||||
'modelValue': quantity.value,
|
||||
'onUpdate:modelValue': (v) => { quantity.value = v },
|
||||
max: qtyParam?.options?.length ? Math.max(...qtyParam.options) : 4,
|
||||
'max': qtyParam?.options?.length ? Math.max(...qtyParam.options) : 4
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const platform = {
|
||||
@ -188,11 +154,18 @@ export function definePaintingPlatform() {
|
||||
|
||||
async loadModels() {
|
||||
const code = getPlatformCode('Painting')
|
||||
return fetchPlatformModels(code)
|
||||
const models = await fetchPlatformModels(code)
|
||||
if (models?.length) {
|
||||
const modelIds = models.map((m) => m.id)
|
||||
await preloadModelConfigs(modelIds)
|
||||
}
|
||||
return models
|
||||
},
|
||||
|
||||
async loadConfig(modelName, _modelType) {
|
||||
const config = getModelConfig(modelName)
|
||||
const modelId = await getModelId('Painting', modelName)
|
||||
if (!modelId) return null
|
||||
const config = await getModelConfig(modelId)
|
||||
syncDefaults(config)
|
||||
return config
|
||||
},
|
||||
@ -216,12 +189,12 @@ export function definePaintingPlatform() {
|
||||
|
||||
imageUploadLimit() {
|
||||
if (!modelConfig.value) return 4
|
||||
const imageParam = modelConfig.value.params.find(p => p.ui === 'imageUpload')
|
||||
const imageParam = modelConfig.value.params.find((p) => p.ui === 'imageUpload')
|
||||
return imageParam?.maxCount || modelConfig.value.maxImages || 4
|
||||
},
|
||||
|
||||
isImageRequired() {
|
||||
return !!(modelConfig.value?.params?.find(p => p.ui === 'imageUpload'))
|
||||
return !!(modelConfig.value?.params?.find((p) => p.ui === 'imageUpload'))
|
||||
},
|
||||
|
||||
buildTaskBody(shared) {
|
||||
@ -252,7 +225,7 @@ export function definePaintingPlatform() {
|
||||
}
|
||||
}
|
||||
if (paramValues.quality !== undefined) quality.value = paramValues.quality
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return platform
|
||||
|
||||
Loading…
Reference in New Issue
Block a user