feat: Video 平台接入模型配置 API

This commit is contained in:
王佑琳 2026-06-09 18:05:02 +08:00
parent 308581e2e4
commit fe1ce00f66

View File

@ -1,12 +1,12 @@
import { ref, markRaw } from 'vue'
import { fetchModelConfig } from '@/utils/modelConfig'
import { fetchPlatformModels, getPlatformCode } from '@/utils/modelApi'
import VideoModelSelector from './modelSelector.vue'
import { markRaw, reactive, ref } from 'vue'
import { fetchPlatformModels, getModelConfig, getModelId, getPlatformCode, preloadModelConfigs } from '@/utils/modelApi'
import { syncDefaults as _syncDefaults, syncParamValues as _syncParamValues } from '@/utils/modelConfigHelper.js'
import { registerPlatform } from '../registry.js'
import Pattern from './controls/pattern.vue'
import VideoProportion from './controls/proportion.vue'
import Time from './controls/time.vue'
import VideoImageUploader from './imageUploader.vue'
import { registerPlatform } from '../registry.js'
import VideoModelSelector from './modelSelector.vue'
export function defineVideoPlatform() {
const model = ref('LTX2.0')
@ -19,7 +19,7 @@ export function defineVideoPlatform() {
const resolutionOptions = ref([
{ value: '1k', label: '标清 1K' },
{ value: '2k', label: '高清 2K' },
{ value: '4k', label: '超清 4K' },
{ value: '4k', label: '超清 4K' }
])
const proportionOptions = ref([
{ value: '智能', label: '智能' },
@ -28,42 +28,55 @@ export function defineVideoPlatform() {
{ value: '4:3', label: '4:3' },
{ value: '1:1', label: '1:1' },
{ value: '3:4', label: '3:4' },
{ value: '9:16', label: '9:16' },
{ value: '9:16', label: '9:16' }
])
const durationOptions = ref([])
const modelDisplayConfig = ref(null)
const promptPlaceholder = ref('描述你想生成的画面和动作。')
// params 驱动(与 Painting 统一)
const paramValues = reactive({})
const modelConfig = ref(null)
const quality = ref('medium')
const customWidth = ref(1024)
const customHight = ref(1024)
const dimWidth = ref(1024)
const dimHeight = ref(1024)
const quantity = ref(1)
const state = {
model, modelType,
proportion, resolution,
duration, videoPattern,
resolutionOptions, proportionOptions, durationOptions,
modelDisplayConfig,
model,
modelType,
proportion,
resolution,
duration,
videoPattern,
resolutionOptions,
proportionOptions,
durationOptions,
modelConfig,
paramValues
}
async function loadInternalConfig(modelName, modelTypeVal) {
const config = await fetchModelConfig('Video', modelName, modelTypeVal)
modelDisplayConfig.value = config
if (config?.display) {
const d = config.display
if (d.resolution) {
resolution.value = d.resolution.default || '1k'
resolutionOptions.value = d.resolution.options || []
}
if (d.proportion) {
proportion.value = d.proportion.default || '16:9'
proportionOptions.value = d.proportion.options || []
}
if (d.duration) {
duration.value = d.duration.default || 5
durationOptions.value = d.duration.options || []
}
if (d.promptPlaceholder) {
promptPlaceholder.value = d.promptPlaceholder.default || '描述你想生成的画面和动作。'
}
}
return config
const paintingCompatState = {
modelConfig,
paramValues,
proportion,
resolution,
quantity,
quality,
customWidth,
customHight,
dimWidth,
dimHeight,
promptPlaceholder
}
function syncDefaults(config) {
_syncDefaults(config, paintingCompatState)
}
function syncParamValues() {
_syncParamValues(modelConfig.value, paintingCompatState)
}
const controls = [
@ -72,33 +85,33 @@ export function defineVideoPlatform() {
component: markRaw(Pattern),
show: () => true,
props: () => ({
modelValue: videoPattern.value,
'onUpdate:modelValue': (v) => { videoPattern.value = v },
}),
'modelValue': videoPattern.value,
'onUpdate:modelValue': (v) => { videoPattern.value = v }
})
},
{
name: 'proportion',
component: markRaw(VideoProportion),
show: () => true,
props: () => ({
modelValue: proportion.value,
'modelValue': proportion.value,
'onUpdate:modelValue': (v) => { proportion.value = v },
resolution: resolution.value,
'resolution': resolution.value,
'onUpdate:resolution': (v) => { resolution.value = v },
proportionOptions: proportionOptions.value,
resolutionOptions: resolutionOptions.value,
}),
'proportionOptions': proportionOptions.value,
'resolutionOptions': resolutionOptions.value
})
},
{
name: 'time',
component: markRaw(Time),
show: () => true,
props: () => ({
modelValue: duration.value,
'modelValue': duration.value,
'onUpdate:modelValue': (v) => { duration.value = v },
options: durationOptions.value,
}),
},
'options': durationOptions.value
})
}
]
const platform = {
@ -111,16 +124,25 @@ export function defineVideoPlatform() {
state,
model,
modelType,
modelDisplayConfig,
modelConfig,
promptPlaceholder,
async loadModels() {
const code = getPlatformCode('Video')
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, modelTypeVal) {
return loadInternalConfig(modelName, modelTypeVal)
async loadConfig(modelName, _modelType) {
const modelId = await getModelId('Video', modelName)
if (!modelId) return null
const config = await getModelConfig(modelId)
syncDefaults(config)
return config
},
getDefaultModel() {
@ -139,25 +161,23 @@ export function defineVideoPlatform() {
},
showImageUploader() {
return modelType.value !== 'text'
return modelConfig.value?.inputType === 'image' || modelConfig.value?.inputType === 'both'
},
imageUploadLimit() {
return modelDisplayConfig.value?.display?.images || 1
if (!modelConfig.value) return 4
const imageParam = modelConfig.value.params.find((p) => p.ui === 'imageUpload')
return imageParam?.maxCount || modelConfig.value.maxImages || 4
},
isImageRequired() {
return modelType.value !== 'text'
return !!(modelConfig.value?.params?.find((p) => p.ui === 'imageUpload'))
},
buildTaskBody(shared) {
const modelParams = {
prompt: shared.prompt.value,
proportion: proportion.value,
resolution: resolution.value,
duration: duration.value,
videoPattern: videoPattern.value,
}
syncParamValues()
const modelParams = { ...paramValues }
if (shared.prompt.value) modelParams.prompt = shared.prompt.value
return modelParams
},
@ -168,7 +188,7 @@ export function defineVideoPlatform() {
if (resultData.resolution !== undefined) resolution.value = resultData.resolution
if (resultData.duration !== undefined) duration.value = resultData.duration
if (resultData.videoPattern !== undefined) videoPattern.value = resultData.videoPattern
},
}
}
return platform