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 { markRaw, reactive, ref } from 'vue'
|
||||||
import { fetchPlatformModels, getPlatformCode } from '@/utils/modelApi'
|
import { fetchPlatformModels, getModelConfig, getModelId, getPlatformCode, preloadModelConfigs } from '@/utils/modelApi'
|
||||||
import { getModelConfig } from './models/index.js'
|
import { syncDefaults as _syncDefaults, syncParamValues as _syncParamValues, checkShowWhen, getDimConfig } from '@/utils/modelConfigHelper.js'
|
||||||
import PaintingModelSelector from './modelSelector.vue'
|
import { registerPlatform } from '../registry.js'
|
||||||
import PaintingProportion from './controls/proportion.vue'
|
|
||||||
import DimensionInput from './controls/dimension.vue'
|
import DimensionInput from './controls/dimension.vue'
|
||||||
|
import PaintingProportion from './controls/proportion.vue'
|
||||||
import QualitySelect from './controls/quality.vue'
|
import QualitySelect from './controls/quality.vue'
|
||||||
import Quantity from './controls/quantity.vue'
|
import Quantity from './controls/quantity.vue'
|
||||||
import ImageUploader from './imageUploader.vue'
|
import ImageUploader from './imageUploader.vue'
|
||||||
import { registerPlatform } from '../registry.js'
|
import PaintingModelSelector from './modelSelector.vue'
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
export function definePaintingPlatform() {
|
export function definePaintingPlatform() {
|
||||||
const model = ref('Flux 2')
|
const model = ref('Flux 2')
|
||||||
@ -35,142 +25,118 @@ export function definePaintingPlatform() {
|
|||||||
const paramValues = reactive({})
|
const paramValues = reactive({})
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
model, modelType,
|
model,
|
||||||
proportion, resolution,
|
modelType,
|
||||||
customWidth, customHight,
|
proportion,
|
||||||
dimWidth, dimHeight,
|
resolution,
|
||||||
quantity, quality,
|
customWidth,
|
||||||
paramValues, modelConfig,
|
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) {
|
function syncDefaults(config) {
|
||||||
modelConfig.value = config
|
_syncDefaults(config, paintingState)
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncParamValues() {
|
function syncParamValues() {
|
||||||
const ratioParam = modelConfig.value?.params?.find(p => p.ui === 'proportion')
|
_syncParamValues(modelConfig.value, paintingState)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const controls = [
|
const controls = [
|
||||||
{
|
{
|
||||||
name: 'proportion',
|
name: 'proportion',
|
||||||
component: markRaw(PaintingProportion),
|
component: markRaw(PaintingProportion),
|
||||||
show: (config) => !!config?.params?.find(p => p.ui === 'proportion'),
|
show: (config) => !!config?.params?.find((p) => p.ui === 'proportion'),
|
||||||
props: (config) => {
|
props: (config) => {
|
||||||
const ratioParam = config?.params?.find(p => p.ui === 'proportion')
|
const ratioParam = config?.params?.find((p) => p.ui === 'proportion')
|
||||||
const resParam = config?.params?.find(p => p.ui === 'resolution')
|
const resParam = config?.params?.find((p) => p.ui === 'resolution')
|
||||||
return {
|
return {
|
||||||
modelValue: proportion.value,
|
'modelValue': proportion.value,
|
||||||
'onUpdate:modelValue': (v) => { proportion.value = v },
|
'onUpdate:modelValue': (v) => { proportion.value = v },
|
||||||
resolution: resolution.value,
|
'resolution': resolution.value,
|
||||||
'onUpdate:resolution': (v) => { resolution.value = v },
|
'onUpdate:resolution': (v) => { resolution.value = v },
|
||||||
width: customWidth.value,
|
'width': customWidth.value,
|
||||||
'onUpdate:width': (v) => { customWidth.value = v },
|
'onUpdate:width': (v) => { customWidth.value = v },
|
||||||
height: customHight.value,
|
'height': customHight.value,
|
||||||
'onUpdate:height': (v) => { customHight.value = v },
|
'onUpdate:height': (v) => { customHight.value = v },
|
||||||
proportionOptions: ratioParam?.options
|
'proportionOptions': ratioParam?.options
|
||||||
?.filter(o => o !== 'custom')
|
?.filter((o) => o !== 'custom')
|
||||||
.map(o => ({ value: o, label: o })) || [],
|
.map((o) => ({ value: o, label: o })) || [],
|
||||||
resolutionOptions: resParam?.options
|
'resolutionOptions': resParam?.options
|
||||||
?.map(o => ({ value: o, label: o.toUpperCase() })) || [],
|
?.map((o) => ({ value: o, label: o.toUpperCase() })) || [],
|
||||||
allowCustom: ratioParam?.options?.includes('custom') || false,
|
'allowCustom': ratioParam?.options?.includes('custom') || false
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'dimension',
|
name: 'dimension',
|
||||||
component: markRaw(DimensionInput),
|
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) => {
|
props: (config) => {
|
||||||
const dc = getDimConfig(config)
|
const dc = getDimConfig(config)
|
||||||
return {
|
return {
|
||||||
width: dimWidth.value,
|
'width': dimWidth.value,
|
||||||
'onUpdate:width': (v) => { dimWidth.value = v },
|
'onUpdate:width': (v) => { dimWidth.value = v },
|
||||||
height: dimHeight.value,
|
'height': dimHeight.value,
|
||||||
'onUpdate:height': (v) => { dimHeight.value = v },
|
'onUpdate:height': (v) => { dimHeight.value = v },
|
||||||
minW: dc?.config?.width?.min || dc?.wParam?.min || 256,
|
'minW': dc?.config?.width?.min || dc?.wParam?.min || 256,
|
||||||
maxW: dc?.config?.width?.max || dc?.wParam?.max || 6197,
|
'maxW': dc?.config?.width?.max || dc?.wParam?.max || 6197,
|
||||||
minH: dc?.config?.height?.min || dc?.hParam?.min || 256,
|
'minH': dc?.config?.height?.min || dc?.hParam?.min || 256,
|
||||||
maxH: dc?.config?.height?.max || dc?.hParam?.max || 4096,
|
'maxH': dc?.config?.height?.max || dc?.hParam?.max || 4096
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'quality',
|
name: 'quality',
|
||||||
component: markRaw(QualitySelect),
|
component: markRaw(QualitySelect),
|
||||||
show: (config) => !!config?.params?.find(p => p.name === 'quality'),
|
show: (config) => !!config?.params?.find((p) => p.name === 'quality'),
|
||||||
props: (config) => {
|
props: (config) => {
|
||||||
const q = config?.params?.find(p => p.name === 'quality')
|
const q = config?.params?.find((p) => p.name === 'quality')
|
||||||
return {
|
return {
|
||||||
modelValue: quality.value,
|
'modelValue': quality.value,
|
||||||
'onUpdate:modelValue': (v) => { quality.value = v },
|
'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',
|
name: 'quantity',
|
||||||
component: markRaw(Quantity),
|
component: markRaw(Quantity),
|
||||||
show: (config) => !!config?.params?.find(p => p.ui === 'quantity'),
|
show: (config) => !!config?.params?.find((p) => p.ui === 'quantity'),
|
||||||
props: (config) => {
|
props: (config) => {
|
||||||
const qtyParam = config?.params?.find(p => p.ui === 'quantity')
|
const qtyParam = config?.params?.find((p) => p.ui === 'quantity')
|
||||||
return {
|
return {
|
||||||
modelValue: quantity.value,
|
'modelValue': quantity.value,
|
||||||
'onUpdate:modelValue': (v) => { quantity.value = v },
|
'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 = {
|
const platform = {
|
||||||
@ -188,11 +154,18 @@ export function definePaintingPlatform() {
|
|||||||
|
|
||||||
async loadModels() {
|
async loadModels() {
|
||||||
const code = getPlatformCode('Painting')
|
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) {
|
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)
|
syncDefaults(config)
|
||||||
return config
|
return config
|
||||||
},
|
},
|
||||||
@ -216,12 +189,12 @@ export function definePaintingPlatform() {
|
|||||||
|
|
||||||
imageUploadLimit() {
|
imageUploadLimit() {
|
||||||
if (!modelConfig.value) return 4
|
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
|
return imageParam?.maxCount || modelConfig.value.maxImages || 4
|
||||||
},
|
},
|
||||||
|
|
||||||
isImageRequired() {
|
isImageRequired() {
|
||||||
return !!(modelConfig.value?.params?.find(p => p.ui === 'imageUpload'))
|
return !!(modelConfig.value?.params?.find((p) => p.ui === 'imageUpload'))
|
||||||
},
|
},
|
||||||
|
|
||||||
buildTaskBody(shared) {
|
buildTaskBody(shared) {
|
||||||
@ -252,7 +225,7 @@ export function definePaintingPlatform() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (paramValues.quality !== undefined) quality.value = paramValues.quality
|
if (paramValues.quality !== undefined) quality.value = paramValues.quality
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return platform
|
return platform
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user