AI_Painting_V2.0/src/components/ParamGroup/index.vue
WangLeo b8ff25a8d7 feat: Video 平台控件配置驱动化 + UUID 模型标识 + 首尾帧双图上传
- Video 控件(proportion/time/ParamGroup)改为 config 驱动,根据 API 参数 schema 动态渲染选项
- 模型选择器改用 UUID(m.id)作为内部标识,避免同名 display_name 冲突导致错误模型配置
- getModelId 查找优先级:id → name → display_name,向下兼容
- imageUploadLimit 累加所有 imageUpload 参数 maxCount,支持首尾帧等双图模型
- buildTaskBody 将 referenceImages 按索引映射到 imageUpload 参数名
- 新增 ParamGroup(动态参数容器)+ SwitchControl(纯 CSS 开关)共享组件
- modelConfigHelper 扩展 resolution/duration 同步支持
- Select 组件 dropdown-item 添加 flex-shrink:0 防止 flex 压缩
- dialogBox 支持 beforeModel 控件分组渲染
2026-06-10 15:07:37 +08:00

70 lines
2.1 KiB
Vue

<template>
<template v-for="param in dynamicParams" :key="param.name">
<Select
v-if="param.ui === 'select' || param.type === 'select'"
:model-value="paramValues[param.name]"
:options="(param.options || []).map(o => (typeof o === 'object' ? o : { value: o, label: String(o) }))"
class="param-select"
position="top"
@update:model-value="(v) => paramValues[param.name] = v"
>
<template #prefix>
<span class="param-label">{{ param.label || param.name }}</span>
</template>
</Select>
<SwitchControl
v-else-if="param.ui === 'switch' || param.type === 'boolean' || param.type === 'Boolean'"
:model-value="paramValues[param.name] === true || paramValues[param.name] === 'true'"
:label="param.label || param.name"
@update:model-value="(v) => paramValues[param.name] = v"
/>
</template>
</template>
<script setup>
import Select from '@/components/Select/index.vue'
import SwitchControl from '@/components/SwitchControl/index.vue'
const props = defineProps({
config: { type: Object, default: null },
paramValues: { type: Object, default: () => ({}) },
excludeNames: { type: Array, default: () => [] }
})
const handledUis = ['textarea', 'proportion', 'resolution', 'dimension', 'dimensionWidth', 'dimensionHeight', 'quantity', 'imageUpload', 'hidden', 'number']
const dynamicParams = computed(() => {
if (!props.config?.params) return []
return props.config.params.filter((p) => {
if (handledUis.includes(p.ui)) return false
if (props.excludeNames.includes(p.name)) return false
return true
})
})
</script>
<style lang="less" scoped>
.param-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; }
:deep(.dropdown-menu) { min-width: 136px; }
:deep(.dropdown-item) {
min-width: 80px;
justify-content: center;
}
}
.param-label {
font-family: "Microsoft YaHei";
font-size: 12px;
color: #999;
white-space: nowrap;
}
</style>