新增参数结构配置功能,支持动态添加和删除参数字段,优化表单逻辑和样式
This commit is contained in:
@@ -91,6 +91,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<template v-if="isParameterConversionNode">
|
||||||
|
<el-divider content-position="left">参数结构</el-divider>
|
||||||
|
<div class="output-config-list">
|
||||||
|
<div v-for="(item, index) in outputConfigFields" :key="index" class="output-config-card">
|
||||||
|
<div class="output-config-inline-row">
|
||||||
|
<el-input v-model="item.field" placeholder="参数名" class="output-config-inline-input" />
|
||||||
|
<el-input v-model="item.value" placeholder="参数说明" class="output-config-inline-input" />
|
||||||
|
<el-button type="danger" :icon="Delete" circle size="small" @click="removeOutputConfigField(index)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-button type="primary" link :icon="Plus" class="add-pair-btn" @click="addOutputConfigField">添加参数结构</el-button>
|
||||||
|
</template>
|
||||||
<!-- 基础表单 + 模型表单 -->
|
<!-- 基础表单 + 模型表单 -->
|
||||||
<el-form-item v-for="fieldItem in visibleFormFields" :key="fieldItem.field" :label="fieldItem.label">
|
<el-form-item v-for="fieldItem in visibleFormFields" :key="fieldItem.field" :label="fieldItem.label">
|
||||||
<!-- 下拉选择框 -->
|
<!-- 下拉选择框 -->
|
||||||
@@ -260,7 +273,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<el-button type="primary" link class="w100" @click="addCustomField">+ 添加自定义字段</el-button>
|
<el-button type="primary" link class="w100" @click="addCustomField">+ 添加自定义字段</el-button>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
@@ -874,6 +887,7 @@ const customFields = ref<
|
|||||||
maxFileCount?: number;
|
maxFileCount?: number;
|
||||||
}>
|
}>
|
||||||
>([]);
|
>([]);
|
||||||
|
const outputConfigFields = ref<Array<{ field: string; value: string }>>([]);
|
||||||
const selectedParentParam = ref('');
|
const selectedParentParam = ref('');
|
||||||
const selectedModel = ref('');
|
const selectedModel = ref('');
|
||||||
const showSkillSelector = ref(false);
|
const showSkillSelector = ref(false);
|
||||||
@@ -1092,6 +1106,7 @@ const visibleFormFields = computed<NodeLibraryFormItem[]>(() => {
|
|||||||
return returnType === 'callback' || returnType === '等候回调' || returnType === '等待回调';
|
return returnType === 'callback' || returnType === '等候回调' || returnType === '等待回调';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
const isParameterConversionNode = computed(() => String(formState.nodeCode || '').toLowerCase() === 'data_conversion_model');
|
||||||
// 获取可用的上级节点参数
|
// 获取可用的上级节点参数
|
||||||
const availableParentParams = computed(() => {
|
const availableParentParams = computed(() => {
|
||||||
if (!selectedElement.value) return [];
|
if (!selectedElement.value) return [];
|
||||||
@@ -1327,6 +1342,7 @@ const workflowDsl = computed(() => ({
|
|||||||
modelResponse: n.properties.modelConfig?.modelResponse || n.properties?.modelResponse || null,
|
modelResponse: n.properties.modelConfig?.modelResponse || n.properties?.modelResponse || null,
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
|
outputConfig: Array.isArray(n.properties?.outputConfig) ? n.properties.outputConfig : null,
|
||||||
isSaveFile: n.properties?.isSaveFileEnabled ?? null,
|
isSaveFile: n.properties?.isSaveFileEnabled ?? null,
|
||||||
promptContent: n.properties?.promptData?.prompt || null,
|
promptContent: n.properties?.promptData?.prompt || null,
|
||||||
outputResult: null,
|
outputResult: null,
|
||||||
@@ -2503,6 +2519,12 @@ const addCustomField = () => {
|
|||||||
maxFileCount: undefined,
|
maxFileCount: undefined,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
const addOutputConfigField = () => {
|
||||||
|
outputConfigFields.value.push({ field: '', value: '' });
|
||||||
|
};
|
||||||
|
const removeOutputConfigField = (index: number) => {
|
||||||
|
outputConfigFields.value.splice(index, 1);
|
||||||
|
};
|
||||||
// 删除自定义字段
|
// 删除自定义字段
|
||||||
const removeCustomField = (index: number) => {
|
const removeCustomField = (index: number) => {
|
||||||
customFields.value.splice(index, 1);
|
customFields.value.splice(index, 1);
|
||||||
@@ -2940,6 +2962,18 @@ const updateKeyValueFieldFromPairs = (field: string) => {
|
|||||||
// 保存为JSON字符串
|
// 保存为JSON字符串
|
||||||
dynamicFormValues[field] = Object.keys(obj).length > 0 ? JSON.stringify(obj) : '';
|
dynamicFormValues[field] = Object.keys(obj).length > 0 ? JSON.stringify(obj) : '';
|
||||||
};
|
};
|
||||||
|
const buildOutputConfigPayload = () =>
|
||||||
|
outputConfigFields.value
|
||||||
|
.map((item) => {
|
||||||
|
const fieldName = String(item.field || '').trim();
|
||||||
|
if (!fieldName) return null;
|
||||||
|
return {
|
||||||
|
field: fieldName,
|
||||||
|
label: fieldName,
|
||||||
|
value: String(item.value || '').trim(),
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter(Boolean) as Array<{ field: string; label: string; value: string }>;
|
||||||
// 存储字段的文件列表
|
// 存储字段的文件列表
|
||||||
const fieldFileLists = reactive<Record<string, any[]>>({});
|
const fieldFileLists = reactive<Record<string, any[]>>({});
|
||||||
// 存储字段的上传key(用于重置上传组件)
|
// 存储字段的上传key(用于重置上传组件)
|
||||||
@@ -3221,6 +3255,7 @@ watch(
|
|||||||
Object.keys(fieldUploadKeys).forEach((k) => delete fieldUploadKeys[k]);
|
Object.keys(fieldUploadKeys).forEach((k) => delete fieldUploadKeys[k]);
|
||||||
currentHttpBodyField.value = '';
|
currentHttpBodyField.value = '';
|
||||||
showHttpBodyDialog.value = false;
|
showHttpBodyDialog.value = false;
|
||||||
|
outputConfigFields.value = [];
|
||||||
|
|
||||||
// 重置 dynamicFormValues(不删除固定字段键,动态 expand 键按节点切换清理)
|
// 重置 dynamicFormValues(不删除固定字段键,动态 expand 键按节点切换清理)
|
||||||
for (const key in dynamicFormValues) {
|
for (const key in dynamicFormValues) {
|
||||||
@@ -3294,6 +3329,12 @@ watch(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (Array.isArray(e?.properties?.outputConfig)) {
|
||||||
|
outputConfigFields.value = e.properties.outputConfig.map((item: any) => ({
|
||||||
|
field: String(item?.field || item?.label || '').trim(),
|
||||||
|
value: String(item?.value || ''),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化模型选择和模型相关数据(从 modelConfig)
|
// 初始化模型选择和模型相关数据(从 modelConfig)
|
||||||
const modelConfig = e?.properties?.modelConfig;
|
const modelConfig = e?.properties?.modelConfig;
|
||||||
@@ -3534,6 +3575,7 @@ const applySelected = () => {
|
|||||||
|
|
||||||
// 保存 formConfig(包含基础字段 + 自定义字段,不包含模型字段)
|
// 保存 formConfig(包含基础字段 + 自定义字段,不包含模型字段)
|
||||||
const formConfig: Array<any> = [];
|
const formConfig: Array<any> = [];
|
||||||
|
const outputConfig = buildOutputConfigPayload();
|
||||||
|
|
||||||
// 1. 添加基础表单字段(非模型字段)
|
// 1. 添加基础表单字段(非模型字段)
|
||||||
// 重用上面的 modelFieldNames
|
// 重用上面的 modelFieldNames
|
||||||
@@ -3590,6 +3632,12 @@ const applySelected = () => {
|
|||||||
} else {
|
} else {
|
||||||
delete p.formConfig;
|
delete p.formConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (outputConfig.length > 0) {
|
||||||
|
p.outputConfig = outputConfig;
|
||||||
|
} else {
|
||||||
|
delete p.outputConfig;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -3929,6 +3977,7 @@ const loadWorkflowFromDsl = (dsl: any) => {
|
|||||||
skillName: n.skillName || null,
|
skillName: n.skillName || null,
|
||||||
formConfig: n.formConfig || null,
|
formConfig: n.formConfig || null,
|
||||||
modelConfig: n.modelConfig || null,
|
modelConfig: n.modelConfig || null,
|
||||||
|
outputConfig: n.outputConfig || null,
|
||||||
inputSource: n.inputSource || null,
|
inputSource: n.inputSource || null,
|
||||||
// 加载提示词和保存文件配置
|
// 加载提示词和保存文件配置
|
||||||
isSaveFileEnabled: n.isSaveFile ?? false,
|
isSaveFileEnabled: n.isSaveFile ?? false,
|
||||||
@@ -5413,6 +5462,30 @@ onBeforeUnmount(() => {
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.output-config-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-config-card {
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-config-inline-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) auto;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-config-inline-input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.selected-panel {
|
.selected-panel {
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
Reference in New Issue
Block a user