Files
admin-ui/src/views/settings/workflow/component/ModelParamsForm.vue
T
2910410219andClaude 68bdc63231 首页工作流节点引用多选与保存回显完善:isMultiParameter 全链路透传 + valueSource 数组化/label + 旧 DSL 兼容
- isMultiParameter 节点级开关从节点库透传至引用下拉,支持多选勾选/去重/逐条删除/清空
- valueSource 契约统一为数组并补 label(节点名.字段中文名),覆盖用户引用、表单展示标记与旧 DSL 单对象
- ModelField 递归透传 multi,object/array 嵌套子字段同样支持多选
- 保存/回显兼容旧 DSL 单对象 valueSource,重开自动升级为数组
- modelRequestParamsPath 每项新增 label 字段,后端按 path 重组请求参数

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-19 19:53:06 +08:00

93 lines
2.4 KiB
Vue

<template>
<div class="model-params-form">
<div v-if="!hasParams" class="mpf-empty">
<el-empty description="该模型无请求参数配置" :image-size="80" />
</div>
<div v-else>
<div class="mpf-count">
{{ fieldCount }} 个参数<el-divider direction="vertical" />点击字段名旁图标查看说明
</div>
<div class="mpf-fields">
<ModelField
v-for="(def, key) in localParams"
:key="key"
:field-def="def"
:path="key"
:upstream-nodes="upstreamNodes"
:multi="multi"
/>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue';
import ModelField from './ModelField.vue';
import { deepClone, normalizeModelParams, stripReadonlyFields } from './modelParamUtils';
// 前驱节点的可引用输出字段(供「引用上级节点输出」)
interface UpstreamNodeInfo {
id: string;
label: string;
nodeCode: string;
outputFields: { field: string; label: string }[];
}
const props = defineProps<{ modelRequestParams: Record<string, any> | null; upstreamNodes?: UpstreamNodeInfo[]; multi?: boolean }>();
const emit = defineEmits<{ 'update:modelRequestParams': [Record<string, any> | null] }>();
const localParams = ref<Record<string, any>>({});
let internalSync = false; // 由 props 同步触发,避免 emit 循环
// props → 本地:深拷贝 + defaultValue 预填,避免直接改动父级引用
watch(
() => props.modelRequestParams,
(val) => {
internalSync = true;
// 剔除 isForm=false 的只读字段:不显示、不参与编辑与保存
localParams.value = stripReadonlyFields(normalizeModelParams(deepClone(val || {})));
nextTick(() => {
internalSync = false;
});
},
{ immediate: true, deep: true }
);
// 本地 → 父级:就地修改的叶子 value 会触发深度 watch
watch(
localParams,
(val) => {
if (internalSync) return;
emit('update:modelRequestParams', deepClone(val));
},
{ deep: true }
);
const hasParams = computed(() => Object.keys(localParams.value).length > 0);
const fieldCount = computed(() => Object.keys(localParams.value).length);
</script>
<style scoped lang="scss">
.model-params-form {
width: 100%;
.mpf-empty {
padding: 8px 0;
}
.mpf-count {
font-size: 12px;
color: #94a3b8;
margin-bottom: 10px;
line-height: 1.4;
}
.mpf-fields {
max-height: 420px;
overflow-y: auto;
padding-right: 4px;
}
}
</style>