refactor: dialogBox 重构为通用平台编排壳,委托所有平台特定逻辑

This commit is contained in:
王佑琳 2026-06-09 11:51:29 +08:00
parent 615afbc211
commit ec81dce28a
2 changed files with 129 additions and 533 deletions

View File

@ -1,91 +1,60 @@
<template>
<Transition name="slide-up">
<div class="input-container" :class="{ generate : !props.isGenerate }" @click="handleContainerClick">
<div v-if="!props.isGenerate && props.type === 'Painting'" class="title">AI绘画2026</div>
<div v-if="!props.isGenerate && props.type === 'Video'" class="title">AI视频2026</div>
<div v-if="!props.isGenerate" class="title">{{ platform.label }}</div>
<div class="sender-top">
<div v-if="useDisplay.Sender_variant === 'default'" class="scroll-to-bottom-text" @click.stop="handleScrollToBottom">回到底部<img src="@/assets/dialog/ArrowDown.svg"></div>
<div v-if="useDisplay.Sender_variant === 'default'" class="scroll-to-bottom-text" @click.stop="handleScrollToBottom">
回到底部<img src="@/assets/dialog/ArrowDown.svg">
</div>
<div v-show="showImageUploader" class="upload-img-container">
<div v-show="showUploader" class="upload-img-container">
<div class="reference-diagram">
<ImageUploader
v-if="props.type === 'Painting'"
<component
v-if="platform.ImageUploader"
:is="platform.ImageUploader"
ref="referenceDiagramRef"
v-model="referenceImages"
:limit="imageUploadLimit"
@open-canvas="handleOpenCanvas"
/>
<VideoImageUploader
v-else-if="props.type === 'Video'"
ref="referenceDiagramRef"
v-model="referenceImages"
:model-type="modelType"
:images-count="modelDisplayConfig?.display?.images || 1"
v-bind="uploaderBindings"
/>
</div>
</div>
</div>
<Sender :key="useDisplay.Sender_variant" v-model="prompt" :variant="useDisplay.Sender_variant" :placeholder="promptPlaceholder" :submit-btn-disabled="isgerenate.value" :auto-size="autoSizeConfig">
<template #prefix>
<div v-if="useDisplay.Sender_variant !== 'default' && props.type === 'Painting'" class="prefix-self-wrap">
<paintingModel v-model="model" v-model:typeValue="modelType" />
<paintingProportion
v-if="showProportion"
v-model="proportion"
v-model:resolution="resolution"
v-model:width="customWidth"
v-model:height="customHight"
:proportion-options="paintingProportionOpts"
:resolution-options="paintingResolutionOpts"
:allow-custom="hasCustomSize"
<Sender
v-model="prompt"
:variant="useDisplay.Sender_variant"
:placeholder="platform.promptPlaceholder.value"
:submit-btn-disabled="isgerenate"
:auto-size="autoSizeConfig"
>
<template v-if="useDisplay.Sender_variant !== 'default'" #prefix>
<div class="prefix-self-wrap">
<component
:is="platform.ModelSelector"
:modelValue="platform.model.value"
@update:modelValue="platform.model.value = $event"
:typeValue="platform.modelType.value"
@update:typeValue="platform.modelType.value = $event"
v-bind="(platform.modelSelectorProps && platform.modelSelectorProps()) || {}"
/>
<DimensionInput
v-if="showDimension"
v-model:width="dimWidth"
v-model:height="dimHeight"
:min-w="dimMinW"
:max-w="dimMaxW"
:min-h="dimMinH"
:max-h="dimMaxH"
/>
<Select
v-if="showQuality"
v-model="qualityValue"
:options="qualityOpts"
width="auto"
class="quality-select"
>
<template #prefix>
<span class="quality-label">画质</span>
</template>
</Select>
<Quantity v-if="showQuantity" v-model="quantity" :max="quantityMax" />
</div>
<div v-if="useDisplay.Sender_variant !== 'default' && props.type === 'Video'" class="prefix-self-wrap">
<Pattern v-model="videoPattern" />
<videoModel v-model="model" v-model:typeValue="modelType" :video-pattern="videoPattern" />
<videoProportion
v-model="proportion"
v-model:resolution="resolution"
:proportion-options="proportionOptions"
:resolution-options="resolutionOptions"
/>
<Time v-model="duration" :options="durationOptions" />
<template v-for="ctrl in visibleControls" :key="ctrl.name">
<component
:is="ctrl.component"
v-bind="ctrl.props(getCurrentConfig())"
/>
</template>
</div>
</template>
<template #action-list>
<div style="display: flex; align-items: center; gap: 8px; height: 100%;">
<el-button v-if="isgerenate" round color="#626aef">
<i-ep-loading style="animation: spin 1s linear infinite;" />
<i-ep-loading style="animation: spin 1s linear infinite;" />
</el-button>
<div v-else class="gerenate" :class="{ isprompt: prompt }" @click="handleStart">
<img v-if="!prompt" src="@/assets/dialog/darkArrow.svg" alt="" />
<img v-else src="@/assets/dialog/writerArrow.svg" alt="" />
<img v-if="!prompt" src="@/assets/dialog/darkArrow.svg" alt="">
<img v-else src="@/assets/dialog/writerArrow.svg" alt="">
<div v-show="useDisplay.Sender_variant !== 'default'">发送</div>
</div>
</div>
@ -97,415 +66,117 @@
</template>
<script setup>
import videoProportion from './proportion/video.vue'
import paintingModel from './model/painting.vue'
import videoModel from './model/video.vue'
import Pattern from './pattern/index.vue'
import ImageUploader from './imageUploader/index.vue'
import VideoImageUploader from './videoImageUploader/index.vue'
import Time from './Time/index.vue'
import paintingProportion from './proportion/painting.vue'
import Quantity from './quantity/index.vue'
import DimensionInput from './dimension/index.vue'
import Select from '@/components/Select/index.vue'
import { Sender } from 'vue-element-plus-x'
import { useDisplayStore } from '@/stores'
import { generate } from '@/utils/taskPolling'
import { useRouter } from 'vue-router'
import { getModelId, fetchPlatformModels, getPlatformCode } from '@/utils/modelApi'
import { fetchModelConfig } from '@/utils/modelConfig'
import { getModelConfig } from '@/config/models/index.js'
import { createPlatform } from '@/platforms/registry.js'
import { getModelId } from '@/utils/modelApi'
//
import '@/platforms/painting/index.js'
import '@/platforms/video/index.js'
const props = defineProps({
isGenerate: {
type: Boolean,
default: false
},
generate: {
type: Boolean,
default: false
},
type: {
type: String,
default: 'Painting'
}
isGenerate: { type: Boolean, default: false },
generate: { type: Boolean, default: false },
type: { type: String, default: 'Painting' },
})
const router = useRouter()
const useDisplay = useDisplayStore()
const isgerenate = ref(false)
const model = ref() //
const modelType = ref('text')
//
const modelConfig = computed(() => {
return props.type === 'Painting' ? getModelConfig(model.value) : null
})
//
const paramValues = reactive({})
const showImageUploader = computed(() => {
if (props.type === 'Video') return modelType.value !== 'text'
return modelType.value !== 'text' || modelConfig.value?.inputType === 'image' || modelConfig.value?.inputType === 'both'
})
// imageNum
const showQuantity = computed(() => {
if (props.type !== 'Painting') return false
return !!modelConfig.value?.params?.find(p => p.ui === 'quantity')
})
// 使 proportion aspectRatio
const showProportion = computed(() => {
return !!modelConfig.value?.params?.find(p => p.ui === 'proportion')
})
// aspectRatio 'custom'
const hasCustomSize = computed(() => {
const ratioParam = modelConfig.value?.params?.find(p => p.ui === 'proportion')
return ratioParam?.options?.includes('custom') || false
})
// DimensionInput
const dimWidth = ref(1024)
const dimHeight = ref(1024)
const qualityValue = ref('medium')
const showDimension = computed(() => {
return !!modelConfig.value?.params?.find(p => p.ui === 'dimension' || p.ui === 'dimensionWidth')
})
const dimConfig = computed(() => {
if (!modelConfig.value) return null
const dimParam = modelConfig.value.params.find(p => p.ui === 'dimension')
if (dimParam) return { type: 'combined', config: dimParam.dimension, paramName: dimParam.name }
const wParam = modelConfig.value.params.find(p => p.ui === 'dimensionWidth')
const hParam = modelConfig.value.params.find(p => p.ui === 'dimensionHeight')
if (wParam && hParam) return { type: 'split', wParam, hParam }
return null
})
const dimMinW = computed(() => dimConfig.value?.config?.width?.min || dimConfig.value?.wParam?.min || 256)
const dimMaxW = computed(() => dimConfig.value?.config?.width?.max || dimConfig.value?.wParam?.max || 6197)
const dimMinH = computed(() => dimConfig.value?.config?.height?.min || dimConfig.value?.hParam?.min || 256)
const dimMaxH = computed(() => dimConfig.value?.config?.height?.max || dimConfig.value?.hParam?.max || 4096)
const showQuality = computed(() => {
return !!modelConfig.value?.params?.find(p => p.name === 'quality')
})
const qualityOpts = computed(() => {
const q = modelConfig.value?.params?.find(p => p.name === 'quality')
if (q?.options) return q.options.map(o => ({ value: o, label: o }))
return []
})
// 退
const paintingProportionOpts = computed(() => {
const ratioParam = modelConfig.value?.params?.find(p => p.ui === 'proportion')
if (ratioParam?.options) {
return ratioParam.options
.filter(o => o !== 'custom')
.map(o => ({ value: o, label: o }))
}
return proportionOptions.value
})
// resolution
const paintingResolutionOpts = computed(() => {
const resParam = modelConfig.value?.params?.find(p => p.ui === 'resolution')
if (resParam?.options) {
return resParam.options.map(o => ({ value: o, label: o.toUpperCase() }))
}
return []
})
const imageUploadLimit = computed(() => {
if (!modelConfig.value) return 4
const imageParam = modelConfig.value.params.find(p => p.ui === 'imageUpload')
return imageParam?.maxCount || modelConfig.value.maxImages || 4
})
const promptPlaceholder = ref('描述你想生成的画面和动作。') //
const prompt = ref('') //
const proportion = ref('16:9') // Video
const resolution = ref('1k') // Video
const prompt = ref('')
const referenceImages = ref([])
//
const quantity = ref(1) //
const customWidth = ref(1024) //
const customHight = ref(1024) //
const platform = computed(() => createPlatform(props.type))
const quantityMax = computed(() => {
const qtyParam = modelConfig.value?.params?.find(p => p.ui === 'quantity')
if (qtyParam?.options?.length) return Math.max(...qtyParam.options)
return 4
const getCurrentConfig = () => {
return platform.value.modelConfig?.value ?? platform.value.modelDisplayConfig?.value ?? null
}
const visibleControls = computed(() => {
const config = getCurrentConfig()
return platform.value.controls.filter(c => c.show(config))
})
// paramValues UI refs
watch(modelConfig, (config) => {
if (!config) return
config.params.forEach(p => {
if (!(p.name in paramValues)) {
if (p.name === 'outputFormat') {
paramValues[p.name] = 'png'
} else {
paramValues[p.name] = p.default ?? ''
}
}
})
// UI
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
// dimension quality
const qualityParam = config.params.find(p => p.name === 'quality')
if (qualityParam) qualityValue.value = qualityParam.default || 'medium'
const dc = dimConfig.value
if (dc?.type === 'split') {
dimWidth.value = dc.wParam.default || 1024
dimHeight.value = dc.hParam.default || 1024
} else if (dc?.type === 'combined') {
const raw = paramValues[dc.paramName] || config.params.find(p => p.name === dc.paramName)?.default || ''
const parsed = dc.config.parse(raw)
dimWidth.value = parsed.width
dimHeight.value = parsed.height
const showUploader = computed(() => {
return platform.value.showImageUploader()
})
const uploaderBindings = computed(() => {
const p = platform.value
if (p.id === 'painting') {
return { limit: p.imageUploadLimit() }
}
}, { immediate: true })
// UI refs paramValues
watch(proportion, (val) => {
const p = modelConfig.value?.params?.find(param => param.ui === 'proportion')
if (p) paramValues[p.name] = val
})
watch(resolution, (val) => {
const p = modelConfig.value?.params?.find(param => param.ui === 'resolution')
if (p) paramValues[p.name] = val
})
watch(quantity, (val) => {
const p = modelConfig.value?.params?.find(param => param.ui === 'quantity')
if (p) paramValues[p.name] = val
})
watch(customWidth, (val) => {
if (modelConfig.value?.params?.find(p => p.name === 'customWidth')) {
paramValues.customWidth = val
if (p.id === 'video') {
return { modelType: p.modelType.value, imagesCount: p.imageUploadLimit() }
}
return {}
})
watch(customHight, (val) => {
if (modelConfig.value?.params?.find(p => p.name === 'customHight')) {
paramValues.customHight = val
}
})
watch([dimWidth, dimHeight], ([w, h]) => {
const dc = dimConfig.value
if (!dc) return
if (dc.type === 'split') {
paramValues[dc.wParam.name] = w
paramValues[dc.hParam.name] = h
} else if (dc.type === 'combined') {
paramValues[dc.paramName] = dc.config.format(w, h)
}
})
watch(qualityValue, (val) => {
if (modelConfig.value?.params?.find(p => p.name === 'quality')) {
paramValues.quality = val
}
})
// paramValues
watch(referenceImages, (imgs) => {
const imageParam = modelConfig.value?.params?.find(p => p.ui === 'imageUpload')
if (imageParam) {
paramValues[imageParam.name] = imgs.map(img => img.url)
}
}, { deep: true })
//
const duration = ref(5) //
const videoPattern = ref('文生视频') // ''
const resolutionOptions = ref([
{ value: '1k', label: '标清 1K' },
{ value: '2k', label: '高清 2K' },
{ value: '4k', label: '超清 4K' },
])
const proportionOptions = ref([
{ value: '智能', label: '智能' },
{ value: '21:9', label: '21:9' },
{ value: '16:9', label: '16:9' },
{ value: '4:3', label: '4:3' },
{ value: '1:1', label: '1:1' },
{ value: '3:4', label: '3:4' },
{ value: '9:16', label: '9:16' },
])
const durationOptions = ref([])
const isInitialized = ref(false)
const autoSizeConfig = computed(() => {
if (useDisplay.Sender_variant !== 'default') {
return { minRows: 5, maxRows: 9 }
} else {
return { minRows: 1, maxRows: 1 }
}
return { minRows: 1, maxRows: 1 }
})
const modelDisplayConfig = ref(null)
// Video: workflow
const loadVideoModelConfig = async (modelName, currentModelType) => {
try {
const config = await fetchModelConfig(props.type, modelName, currentModelType)
modelDisplayConfig.value = config
if (config.display) {
const display = config.display
if (display.promptPlaceholder) {
promptPlaceholder.value = display.promptPlaceholder.default || '描述你想生成的画面和动作。'
}
if (display.prompt && !isInitialized.value) {
prompt.value = display.prompt.default || ''
}
if (display.resolution) {
resolution.value = display.resolution.default || '1k'
resolutionOptions.value = display.resolution.options || []
}
if (display.proportion) {
proportion.value = display.proportion.default || '16:9'
proportionOptions.value = display.proportion.options || []
}
if (display.duration) {
duration.value = display.duration.default || 5
durationOptions.value = display.duration.options || []
}
}
isInitialized.value = true
} catch (error) {
console.error('加载视频模型配置失败:', error)
}
}
const handleStart = async () => {
const currentType = props.type
let currentModelType = modelType.value
const p = platform.value
if(model.value === 'Seedance 2.0') {
if (props.type === 'Video' && p.model.value === 'Seedance 2.0') {
ElMessage.primary('敬请期待 Seedance 2.0')
return
}
if (!props.isGenerate) {
router.push({ name: 'home', query: { loading: false, Generate: true, type: currentType } })
router.push({ name: 'home', query: { loading: false, Generate: true, type: props.type } })
}
if (!prompt.value) {
// eslint-disable-next-line no-undef
ElMessage.error('请输入提示词')
return
}
if (showImageUploader.value && !referenceImages.value.length){
if (showUploader.value && p.isImageRequired() && !referenceImages.value.length) {
ElMessage.warning('请上传图片')
return
}
isgerenate.value = true
console.log('生成开始', isgerenate.value)
const imgs = []
referenceImages.value.forEach((img, index) => {
imgs.push({ name: `image_${index + 1}`, url: img.url })
})
// Painting
const modelParams = { ...paramValues }
if (prompt.value) modelParams.prompt = prompt.value
const modelId = await getModelId(props.type, p.model.value)
// modelParams
const body = await p.buildTaskBody({ prompt, referenceImages })
const generateData = {
model: model.value,
modelType: currentModelType,
model: p.model.value,
modelType: p.modelType.value,
prompt: prompt.value,
proportion: proportion.value,
referenceImages: referenceImages.value,
quantity: quantity.value,
resolution: resolution.value,
customWidth: customWidth.value,
customHight: customHight.value,
duration: duration.value,
videoPattern: videoPattern.value,
modelParams,
modelParams: body,
}
const modelId = await getModelId(currentType, model.value)
// Painting Video params
const isPainting = currentType === 'Painting'
const data = {
type: currentType,
modelType: currentModelType,
AIGC: currentType,
platform: 'runninghub',
modelName: model.value,
type: props.type,
modelType: p.modelType.value,
modelName: p.model.value,
modelId: modelId || '',
modelParams: isPainting ? modelParams : {},
params: isPainting ? [] : [
{ name: 'prompt', data: prompt.value },
{ name: 'quantity', data: quantity.value },
{ name: 'proportion', data: proportion.value },
{ name: 'resolution', data: resolution.value },
{ name: 'duration', data: duration.value },
],
imgs,
request: JSON.stringify(generateData)
body,
request: JSON.stringify(generateData),
}
await generate(data, generateData)
console.log('生成中', isgerenate.value)
}
const fillParamsFromResult = (resultData) => {
if (!resultData) return
if (resultData.model !== undefined) model.value = resultData.model
if (resultData.modelType !== undefined) modelType.value = resultData.modelType
platform.value.fillFromResult(resultData)
if (resultData.prompt !== undefined) prompt.value = resultData.prompt
if (resultData.proportion !== undefined) proportion.value = resultData.proportion
if (resultData.referenceImages !== undefined) referenceImages.value = resultData.referenceImages
if (resultData.quantity !== undefined) quantity.value = resultData.quantity
if (resultData.resolution !== undefined) resolution.value = resultData.resolution
if (resultData.customWidth !== undefined) customWidth.value = resultData.customWidth
if (resultData.customHight !== undefined) customHight.value = resultData.customHight
if (resultData.duration !== undefined) duration.value = resultData.duration
if (resultData.videoPattern !== undefined) videoPattern.value = resultData.videoPattern
if (resultData.modelParams !== undefined) Object.assign(paramValues, resultData.modelParams)
// modelParams dimension/quality UI refs
nextTick(() => {
const dc = dimConfig.value
if (dc?.type === 'split') {
if (paramValues[dc.wParam.name] !== undefined) dimWidth.value = paramValues[dc.wParam.name]
if (paramValues[dc.hParam.name] !== undefined) dimHeight.value = paramValues[dc.hParam.name]
} else if (dc?.type === 'combined') {
if (paramValues[dc.paramName]) {
const parsed = dc.config.parse(paramValues[dc.paramName])
dimWidth.value = parsed.width
dimHeight.value = parsed.height
}
}
if (paramValues.quality !== undefined) qualityValue.value = paramValues.quality
})
}
defineExpose({
fillParamsFromResult,
handleStart
})
defineExpose({ fillParamsFromResult, handleStart })
const handleContainerClick = () => {
if (useDisplay.Sender_variant === 'default') {
@ -514,46 +185,33 @@ const handleContainerClick = () => {
}
const handleScrollToBottom = () => {
console.log('点击回到底部按钮')
useDisplay.scrollToBottom()
}
const handleOpenCanvas = (data) => {
useDisplay.openCanvas(data)
}
watch(() => useDisplay.isSubGerenate, (v) => { isgerenate.value = v }, { immediate: true })
watch(() => useDisplay.isSubGerenate, (newValue) => {
console.log('生成状态', newValue)
isgerenate.value = newValue
}, { immediate: true })
watch([() => model.value, () => modelType.value], async ([newModel, newModelType]) => {
console.log('模型或类型改变:', newModel, newModelType)
if (!newModel) return
if (props.type !== 'Painting') {
await loadVideoModelConfig(newModel, newModelType)
}
})
// ""
const prefetchModels = () => {
const code = getPlatformCode(props.type)
fetchPlatformModels(code)
}
//
watch(
[() => platform.value.model.value, () => platform.value.modelType.value],
async ([newModel, newModelType]) => {
if (!newModel) return
if (platform.value.id === 'video') {
await platform.value.loadConfig(newModel, newModelType)
} else {
platform.value.loadConfig(newModel)
}
},
)
// +
watch(() => props.type, (newType) => {
if (newType === 'Video') {
model.value = 'LTX2.0'
} else {
model.value = 'flux'
}
prefetchModels()
const p = createPlatform(newType)
p.model.value = p.getDefaultModel()
p.loadModels()
}, { immediate: true })
</script>
<style lang="less" scoped>
/* 输入区域 */
.input-container {
width: 50%;
max-width: 880px;
@ -591,20 +249,14 @@ watch(() => props.type, (newType) => {
justify-content: center;
gap: 5px;
&:active {
transform: scale(0.95);
}
&:hover {
background-color: #F0F1F2;
}
&:active { transform: scale(0.95); }
&:hover { background-color: #F0F1F2; }
}
//
.upload-img-container{
.upload-img-container {
position: absolute;
bottom: 0;
left: 0;
width: 80%;
width: 100%;
display: flex;
justify-content: start;
@ -620,35 +272,31 @@ watch(() => props.type, (newType) => {
}
}
.generate{
.generate {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
// gap: 40px;
position: relative;
border: none;
box-shadow: none;
:deep(.el-sender){
:deep(.el-sender) {
border: none;
box-shadow: none;
}
}
.prefix-self-wrap{
.prefix-self-wrap {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
gap: 5px;
img{
height: 50px;
border-radius: 4px;
}
img { height: 50px; border-radius: 4px; }
}
.title{
.title {
background-color: #FFF;
color: #333;
text-align: center;
@ -659,27 +307,28 @@ watch(() => props.type, (newType) => {
line-height: normal;
margin-bottom: 106px;
}
:deep(.el-sender){
:deep(.el-sender) {
background-color: #F5F6F7;
border: none;
border-radius: 20px;
}
:deep(.el-sender:focus-within){
:deep(.el-sender:focus-within) {
box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.1);
}
:deep(.el-popover.el-popper){
:deep(.el-popover.el-popper) {
border-radius: 20px;
}
//
.select{
.select {
background: #ffffff;
border-radius: 10px;
border: 1px solid rgba(0, 0, 0, 0.10);
}
//
.upload-btn{
.upload-btn {
display: flex;
height: 40px;
padding: 0 15px;
@ -692,10 +341,9 @@ watch(() => props.type, (newType) => {
cursor: pointer;
position: relative;
}
.upload-btn:hover{
background: #E5E7EB;
}
/* 圆形按钮 */
.upload-btn:hover { background: #E5E7EB; }
.circle-btn {
position: absolute;
right: 0px;
@ -711,18 +359,10 @@ watch(() => props.type, (newType) => {
transition: all 0.3s ease;
color: rgb(0, 0, 0);
font-size: 20px;
&:hover {
transform: scale(1.1);
// box-shadow: 0 6px 16px rgba(98, 106, 239, 0.6);
}
&:active {
transform: scale(0.95);
}
&:hover { transform: scale(1.1); }
&:active { transform: scale(0.95); }
}
/* 过渡动画 */
.slide-up-enter-active,
.slide-up-leave-active {
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
@ -738,7 +378,7 @@ watch(() => props.type, (newType) => {
transform: translate(-50%, 100%);
}
.gerenate{
.gerenate {
display: inline-flex;
height: 40px;
padding: 0 20px;
@ -748,7 +388,6 @@ watch(() => props.type, (newType) => {
border-radius: 10px;
background: rgba(0, 15, 51, 0.10);
cursor: pointer;
color: #000F33;
text-align: center;
font-family: "Microsoft YaHei";
@ -757,35 +396,9 @@ watch(() => props.type, (newType) => {
font-weight: 700;
line-height: normal;
}
.isprompt{
.isprompt {
color: #ffffff;
background-color: #000F33;
}
// .gerenate:hover{
// background: rgba(0, 15, 51, 0.20);
// }
//
.quality-select {
:deep(.select-header) {
height: 40px;
padding: 0 15px;
border-radius: 10px;
border: 1px solid #E8E9EB;
background: #f5f6f7;
&:hover {
background: #e9eaeb;
}
}
:deep(.select-text) {
font-size: 14px;
}
}
.quality-label {
font-family: "Microsoft YaHei";
font-size: 12px;
color: #999;
}
</style>

View File

@ -1,22 +1,5 @@
import outPlatform from '@/config/index'
// 构造任务 body
// 所有平台 descriptor 的 buildTaskBody() 已直接返回扁平 modelParams
// 此文件仅做透传,后续可直接移除
export async function createTask(data) {
// Painting 使用新架构:直接使用动态模型参数
if (data.type === 'Painting') {
return data.modelParams || {}
}
// Video 继续使用旧 workflow 适配器
const payload = await outPlatform[data.platform].Playload(data)
return payload
}
// 获取结果
export async function getTask(result) {
if (result.code === 0 && result.msg === 'success' && Array.isArray(result.data) && result.data.length > 0) {
const urls = result.data.map(item => item.fileUrl)
return { type: true, urls: urls }
}
return { type: false, message: result.data.exception_message || '生成失败' }
return data.body
}