1. 上游节点输出引用(核心功能)
- 新增 upstreamNodes computed:遍历当前选中节点的前驱链路,仅 model / http / form 三类节点被识别为有输出的节点
- 新增 getNodeOutputFields,按节点类型提取可引用字段:
- form → formConfig 的字段
- http → response schema 的叶子字段
- model → modelResponseBodyMapping(模型返回参数)的 key
- 开始节点 → runFormFields(运行表单字段),从而让下游节点能引用"用户填的运行表单"作为输出
2. 开始节点运行表单字段聚合
- syncRunFormFields + 深监听:开始节点 formConfig 变化时自动聚合字段,存为 runFormFields,作为开始节点自身可被下游引用的输出
3. 模型返回参数
- handleModelConfirm 用 stripReadonlyFields 清理 requestBodyMapping 冗余字段,同时保存 modelResponseBodyMapping 供下游引用
- 保存时 collectExposedFields 提取对外暴露字段存 modelFormFields
4. 提示词 / 反向提示词
- 保存 prompt、negativePrompt、runFormFields 到节点 DSL
5. 其他
- nodeTypes 用 markRaw 包裹 FlowNode,修复 Vue 警告
- buildNodeFormConfigFromDsl 的 responseType 匹配改为兼容 key/value 两种取值
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
<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"
|
||||
/>
|
||||
</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[] }>();
|
||||
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>
|
||||
Reference in New Issue
Block a user