diff --git a/src/i18n/lang/en.ts b/src/i18n/lang/en.ts
index bc98748d4d4662698a676c2f823e60f6e9833e3c..b95893f564964292eea73b234c63df90b7d86479 100644
--- a/src/i18n/lang/en.ts
+++ b/src/i18n/lang/en.ts
@@ -389,6 +389,7 @@ export default {
choose_flow: 'Select a workflow.',
debug: 'Debug',
enterWorkflowName: 'Enter a workflow name.',
+ enterWorkflowDesc: 'Enter a workflow Description.',
default: '',
success: 'Workflow succeeded',
error: 'Workflow failed',
@@ -415,4 +416,45 @@ export default {
scaleTo150: 'Zoom to 150%',
scaleTo200: 'Zoom to 200%',
},
+ yaml: {
+ else: 'else',
+ if: 'if',
+ else_if: 'else if',
+ please_select: 'Please select',
+ please_select_condition: 'Please select the condition.',
+ parameter_value: 'Input or reference parameter value',
+ add_conditional_branches: 'Add conditional branches',
+ and: 'and',
+ or: 'or',
+ add: 'Add',
+ input_type_error: 'Input type error',
+ please_improve_the_conditions: 'Please improve the conditions.',
+ },
+ opertion: {
+ api: 'HTTP request',
+ mcp: 'MCP',
+ sql: 'SQL query',
+ gcraph: 'Chart',
+ llm: 'Large model',
+ rag: 'Knowledge base',
+ suggestion: 'Question recommendation',
+ equal: 'Equal',
+ not_equal: 'Not equal',
+ contains: 'Contains',
+ does_not_contain: 'Does not contain',
+ starts_with: 'Starts with',
+ ends_with: 'Ends with',
+ length_equal: 'Length equal',
+ length_greater_than: 'Length greater than',
+ length_greater_than_or_equal: 'Length greater than or equal',
+ length_less_than: 'Length less than',
+ length_less_than_or_equal: 'Length less than or equal',
+ regex_match: 'Regex match',
+ greater_than: 'Greater than',
+ less_than: 'Less than',
+ greater_than_or_equal: 'Greater than or equal',
+ less_than_or_equal: 'Less than or equal',
+ contains_key: 'Contains key',
+ does_not_contain_key: 'Does not contain key',
+ }
};
diff --git a/src/i18n/lang/zh-cn.ts b/src/i18n/lang/zh-cn.ts
index 18e226d75c5986050724446680a91d239ceef71b..497a64695700e1b44ee083205a782d7f1995f25b 100644
--- a/src/i18n/lang/zh-cn.ts
+++ b/src/i18n/lang/zh-cn.ts
@@ -420,6 +420,7 @@ export default {
choose_flow: '请选择工作流',
debug: '调试',
enterWorkflowName: '请输入工作流名称',
+ enterWorkflowDesc: '请输入工作流名称',
default: '',
success: '运行成功',
error: '运行失败',
@@ -446,4 +447,45 @@ export default {
scaleTo150: '缩放到150%',
scaleTo200: '缩放到200%',
},
+ yaml: {
+ else: '否则',
+ if: '如果',
+ else_if: '否则如果',
+ please_select: '请选择',
+ please_select_condition: '请选择条件',
+ parameter_value: '输入或引用参数值',
+ add_conditional_branches: '添加条件分支',
+ and: '且',
+ or: '或',
+ add: '新增',
+ input_type_error: '输入类型错误',
+ please_improve_the_conditions: '请完善条件',
+ },
+ opertion: {
+ api: 'HTTP请求',
+ mcp: 'MCP',
+ sql: 'SQL查询',
+ gcraph: '图表',
+ llm: '大模型',
+ rag: '知识库',
+ suggestion: '问题推荐',
+ equal: '等于',
+ not_equal: '不等于',
+ contains: '包含',
+ does_not_contain: '不包含',
+ starts_with: '起始等于',
+ ends_with: '结束等于',
+ length_equal: '长度等于',
+ length_greater_than: '长度大于',
+ length_greater_than_or_equal: '长度大于等于',
+ length_less_than: '长度小于',
+ length_less_than_or_equal: '长度小于等于',
+ regex_match: '正则匹配',
+ greater_than: '大于',
+ less_than: '小于',
+ greater_than_or_equal: '大于等于',
+ less_than_or_equal: '小于等于',
+ contains_key: '包含键',
+ does_not_contain_key: '不包含键',
+ }
};
diff --git a/src/views/createapp/components/AgentAppConfig.vue b/src/views/createapp/components/AgentAppConfig.vue
index 6a69f199912336e4451c8126eedfbf794afd49e5..8a76760f07a2d9c02d2d4ee8fe3c21f6c3ecbec9 100644
--- a/src/views/createapp/components/AgentAppConfig.vue
+++ b/src/views/createapp/components/AgentAppConfig.vue
@@ -99,7 +99,7 @@ async function queryAgentConfig() {
createAppFormRef.value?.clearValidate();
if (res) {
- const { name, description, permission, icon, mcpService, dialogRounds } =
+ const { name, description, permission, icon, mcpService, dialogRounds, llm } =
res.result;
createAppForm.icon = icon || '';
createAppForm.name = name;
@@ -107,6 +107,8 @@ async function queryAgentConfig() {
createAppForm.mcps = mcpService?.map((item) => item.id) || [];
createAppForm.dialogRounds = dialogRounds || 3;
createAppForm.permission = permission || createAppForm.permission;
+ // 如果有模型
+ createAppForm.model = llm?.llmId;
}
loading.value = false;
}
diff --git a/src/views/createapp/components/types.ts b/src/views/createapp/components/types.ts
index ab038d34617c75d5665193049859dcc483945724..539b183c19c015309db711bcf5529d8178040f7d 100644
--- a/src/views/createapp/components/types.ts
+++ b/src/views/createapp/components/types.ts
@@ -30,6 +30,8 @@ import TASK_CHOICE from '@/assets/svgs/taskChoice.svg';
import USER_CODE from '@/assets/svgs/userCode.svg';
import USER_DATABASE_CLASS from '@/assets/svgs/userDatabaseClass.svg';
import USER_DOCUMENT_CLASS from '@/assets/svgs/userDatabaseClass.svg';
+import i18n from 'src/i18n';
+
// 工具类型
export type LinkType = 'redirect' | 'action';
@@ -77,14 +79,14 @@ export const nodeTypeToIcon = {
// 这里是对应的图标
export const iconTypeList = [
- { name: 'HTTP请求', value: 'API', icon: API, class: 'otherNode' },
- { name: 'MCP', value: 'MCP', icon: API, class: 'otherNode' },
- { name: 'SQL查询', value: 'SQL', icon: API, class: 'otherNode' },
- { name: '图表', value: 'Graph', icon: API, class: 'otherNode' },
- { name: '大模型', value: 'LLM', icon: LLM, class: 'systemNode' },
- { name: '知识库', value: 'RAG', icon: KENOWLEDGE_BASE, class: 'systemNode' },
+ { name: i18n.global.t('opertion.api'), value: 'API', icon: API, class: 'otherNode' },
+ { name: i18n.global.t('opertion.mcp'), value: 'MCP', icon: API, class: 'otherNode' },
+ { name: i18n.global.t('opertion.sql'), value: 'SQL', icon: API, class: 'otherNode' },
+ { name: i18n.global.t('opertion.gcraph'), value: 'Graph', icon: API, class: 'otherNode' },
+ { name: i18n.global.t('opertion.llm'), value: 'LLM', icon: LLM, class: 'systemNode' },
+ { name: i18n.global.t('opertion.rag'), value: 'RAG', icon: KENOWLEDGE_BASE, class: 'systemNode' },
{
- name: '问题推荐',
+ name: i18n.global.t('opertion.suggestion'),
value: 'Suggestion',
icon: get_CVE_DETAIL,
class: 'aposNode',
@@ -148,47 +150,47 @@ export interface ListItem {
const opertionList = [
// Number operations
- {value: 'number_equal', label: '等于', str: '='},
- {value: 'number_not_equal', label: '不等于', str: '≠'},
- {value: 'number_greater_than', label: '大于', str: '>'},
- {value: 'number_less_than', label: '小于', str: '<'},
- {value: 'number_greater_than_or_equal', label: '大于等于', str: '≥'},
- {value: 'number_less_than_or_equal', label: '小于等于', str: '≤'},
+ {value: 'number_equal', label: i18n.global.t('opertion.equal'), str: '='},
+ {value: 'number_not_equal', label: i18n.global.t('opertion.not_equal'), str: '≠'},
+ {value: 'number_greater_than', label: i18n.global.t('opertion.greater_than'), str: '>'},
+ {value: 'number_less_than', label: i18n.global.t('opertion.less_than'), str: '<'},
+ {value: 'number_greater_than_or_equal', label: i18n.global.t('opertion.greater_than_or_equal'), str: '≥'},
+ {value: 'number_less_than_or_equal', label: i18n.global.t('opertion.less_than_or_equal'), str: '≤'},
// String operations
- {value: 'string_equal', label: '等于', str: '='},
- {value: 'string_not_equal', label: '不等于', str: '≠'},
- {value: 'string_contains', label: '包含', str: ''},
- {value: 'string_not_contains', label: '不包含', str: ''},
- {value: 'string_starts_with', label: '起始等于', str: '='},
- {value: 'string_ends_with', label: '结束等于', str: '='},
- {value: 'string_length_equal', label: '长度等于', str: '|...|='},
- {value: 'string_length_greater_than', label: '长度大于', str: '|...|>'},
- {value: 'string_length_greater_than_or_equal', label: '长度大于等于', str: '|...|≥'},
- {value: 'string_length_less_than', label: '长度小于', str: '|...|<'},
- {value: 'string_length_less_than_or_equal', label: '长度小于等于', str: '|...|≤'},
- {value: 'string_regex_match', label: '正则匹配', str: '\\+'},
+ {value: 'string_equal', label: i18n.global.t('opertion.equal'), str: '='},
+ {value: 'string_not_equal', label: i18n.global.t('opertion.not_equal'), str: '≠'},
+ {value: 'string_contains', label: i18n.global.t('opertion.contains'), str: ''},
+ {value: 'string_not_contains', label: i18n.global.t('opertion.does_not_contain'), str: ''},
+ {value: 'string_starts_with', label: i18n.global.t('opertion.starts_with'), str: '='},
+ {value: 'string_ends_with', label: i18n.global.t('opertion.ends_with'), str: '='},
+ {value: 'string_length_equal', label: i18n.global.t('opertion.length_equal'), str: '|...|='},
+ {value: 'string_length_greater_than', label: i18n.global.t('opertion.length_greater_than'), str: '|...|>'},
+ {value: 'string_length_greater_than_or_equal', label: i18n.global.t('opertion.length_greater_than_or_equal'), str: '|...|≥'},
+ {value: 'string_length_less_than', label: i18n.global.t('opertion.length_less_than'), str: '|...|<'},
+ {value: 'string_length_less_than_or_equal', label: i18n.global.t('opertion.length_less_than_or_equal'), str: '|...|≤'},
+ {value: 'string_regex_match', label: i18n.global.t('opertion.regex_match'), str: '\\+'},
// List operations
- {value: 'list_equal', label: '等于', str: '='},
- {value: 'list_not_equal', label: '不等于', str: '≠'},
- {value: 'list_contains', label: '包含', str: ''},
- {value: 'list_not_contains', label: '不包含', str: ''},
- {value: 'list_length_equal', label: '长度等于', str: '|...|='},
- {value: 'list_length_greater_than', label: '长度大于', str: '|...|>'},
- {value: 'list_length_greater_than_or_equal', label: '长度大于等于', str: '|...|≥'},
- {value: 'list_length_less_than', label: '长度小于', str: '|...|<'},
- {value: 'list_length_less_than_or_equal', label: '长度小于等于', str: '|...|≤'},
+ {value: 'list_equal', label: i18n.global.t('opertion.equal'), str: '='},
+ {value: 'list_not_equal', label: i18n.global.t('opertion.not_equal'), str: '≠'},
+ {value: 'list_contains', label: i18n.global.t('opertion.contains'), str: ''},
+ {value: 'list_not_contains', label: i18n.global.t('opertion.does_not_contain'), str: ''},
+ {value: 'list_length_equal', label: i18n.global.t('opertion.length_equal'), str: '|...|='},
+ {value: 'list_length_greater_than', label: i18n.global.t('opertion.length_greater_than'), str: '|...|>'},
+ {value: 'list_length_greater_than_or_equal', label: i18n.global.t('opertion.length_greater_than_or_equal'), str: '|...|≥'},
+ {value: 'list_length_less_than', label: i18n.global.t('opertion.length_less_than'), str: '|...|<'},
+ {value: 'list_length_less_than_or_equal', label: i18n.global.t('opertion.length_less_than_or_equal'), str: '|...|≤'},
// Boolean operations
- {value: 'bool_equal', label: '等于', str: '='},
- {value: 'bool_not_equal', label: '不等于', str: '≠'},
+ {value: 'bool_equal', label: i18n.global.t('opertion.equal'), str: '='},
+ {value: 'bool_not_equal', label: i18n.global.t('opertion.not_equal'), str: '≠'},
// Dictionary operations
- {value: 'dict_equal', label: '等于', str: '='},
- {value: 'dict_not_equal', label: '不等于', str: '≠'},
- {value: 'dict_contains_key', label: '包含键', str: ''},
- {value: 'dict_not_contains_key', label: '不包含键', str: ''}
+ {value: 'dict_equal', label: i18n.global.t('opertion.equal'), str: '='},
+ {value: 'dict_not_equal', label: i18n.global.t('opertion.not_equal'), str: '≠'},
+ {value: 'dict_contains_key', label: i18n.global.t('opertion.contains_key'), str: ''},
+ {value: 'dict_not_contains_key', label: i18n.global.t('opertion.does_not_contain_key'), str: ''}
]
export const opertionListMap = new Map(opertionList.map(item => [item.value, item]));
diff --git a/src/views/createapp/components/workFlow.vue b/src/views/createapp/components/workFlow.vue
index a0beef6d7d4df8738f9a7cbff26e3095d52157aa..fde4d27c838dd5943438d98f88dc85dfbe31b65f 100644
--- a/src/views/createapp/components/workFlow.vue
+++ b/src/views/createapp/components/workFlow.vue
@@ -345,7 +345,7 @@ const nodesChange = (nodes) => {
removeSelectedNodes([getSelectedNodes.value[0]]);
}
if (nodes?.[0]?.type === 'remove') {
- delNode(nodes[0].id);
+ // delNode(nodes[0].id);
// 节点增加删除时直接将工作流debug状态置为false
emits('updateFlowsDebug', false);
nodeAndLineConnection();
diff --git a/src/views/createapp/components/workFlowConfig/BranchNode.vue b/src/views/createapp/components/workFlowConfig/BranchNode.vue
index 58d0e0466b2455c00ebd7e665112d997e73c02e4..6fe71ab8f99dc276510c0a72d8c45a7c38ef94c6 100644
--- a/src/views/createapp/components/workFlowConfig/BranchNode.vue
+++ b/src/views/createapp/components/workFlowConfig/BranchNode.vue
@@ -3,6 +3,9 @@ import { Position, Handle } from '@vue-flow/core';
import { ref, watch } from 'vue';
import { getSrcIcon, opertionListMap } from '../types';
import NodeMirrorText from '../codeMirror/nodeMirrorText.vue';
+import i18n from 'src/i18n';
+
+const { t } = i18n.global;
const props = defineProps({
id: {
type: String,
@@ -177,25 +180,25 @@ const getHandleStyle = (index, total) => {
- 否则
+ {{$t('yaml.else')}}
- 如果
+ {{$t('yaml.if')}}
- 否则如果
+ {{$t('yaml.else_if')}}
-
- {{ condition.left.value }}
+
+ {{ condition.left.name }}
{{ opertionListMap.get(condition.operate)?.str || opertionListMap.get(condition.operate)?.label }}
-
- {{ condition.right.value }}
+
+ {{ condition.right.name }}
diff --git a/src/views/createapp/components/workFlowConfig/yamlEditDrawer.vue b/src/views/createapp/components/workFlowConfig/yamlEditDrawer.vue
index 9a19e68c303eb2c80a736114dd2ff22ffd464c89..8f9e93851b71e43cad6db994fad073d53e138140 100644
--- a/src/views/createapp/components/workFlowConfig/yamlEditDrawer.vue
+++ b/src/views/createapp/components/workFlowConfig/yamlEditDrawer.vue
@@ -8,155 +8,282 @@
class="flowDrawer"
:before-close="closeDrawer"
>
-
+
-
+
- {{ $t('添加条件分支') }}
+ {{ $t('yaml.add_conditional_branches') }}
-
+
-
- 否则
+
+ {{ $t('yaml.else') }}
- 如果
+ {{ $t('yaml.if') }}
- 否则如果
+ {{ $t('yaml.else_if') }}
-
+
-
+
+
-
- {{ logicObj[item.logic] }}
-
-
-
-
+
+ {{ logicObj[item.logic] }}
+
+
+
+
-
+
+
onSelectOperateOption(value, index, cIndex)"
+ :placeholder="
+ i18n.global.t('yaml.please_select_condition')
+ "
+ @change="
+ (value) => onSelectOperateOption(value, index, cIndex)
+ "
>
-
- {{ opertionListMap.get(condition.operate)?.str }}
- {{ opertionListMap.get(condition.operate)?.label }}
-
-
- {{ opertionListMap.get(item.operate)?.str }}
- {{ opertionListMap.get(item.operate)?.label }}
-
+
+ {{ opertionListMap.get(condition.operate)?.str }}
+ {{ opertionListMap.get(condition.operate)?.label }}
+
+
+ {{ opertionListMap.get(item.operate)?.str }}
+ {{ opertionListMap.get(item.operate)?.label }}
+
+
onSelectOption(value, index, cIndex)"
+ :style="
+ item.conditions.length > 1
+ ? { minWidth: '345px' }
+ : { minWidth: '460px' }
+ "
+ @change="
+ (value) => onSelectOption(value, index, cIndex)
+ "
>
-
-
+
+
+
- {{ item.name }}
+ {{ item.name }}
-
-
+
+
-
-
+
+
- {{ item.name }}
-
- {{ item.paramType }}
-
+ {{ item.name }}
+
+ {{ item.paramType }}
+
+
-
{{ condition.right.type ?? 'string' }}
+
+ {{ condition.right.type ?? '' }}
+
onSelectInputOption(value, index, cIndex)"
+ :value="condition.right.name || ''"
+ @change="
+ (value) =>
+ onSelectInputOption(value, index, cIndex, 'input')
+ "
>
-
- onSelectInputOption(value, index, cIndex)"
- :popper-options="{ modifiers: [{ name: 'offset', options: { offset: [-150, 10] } }] }"
- >
-
-
-
-
- {{ item.name }}
-
-
-
-
-
-
-
-
-
-
-
- {{ item.name }}
-
- {{ item.paramType }}
-
-
+
+
+ onSelectInputOption(
+ value,
+ index,
+ cIndex,
+ 'select',
+ )
+ "
+ :popper-options="{
+ modifiers: [
+ {
+ name: 'offset',
+ options: { offset: [-150, 10] },
+ },
+ ],
+ }"
+ >
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+
+ {{ item.paramType }}
+
+
+
-
-
-
-
-
+
+
+
+
-
+
- 新增
+
+ {{ $t('yaml.add') }}
+
-
+
import { onMounted, ref, watch } from 'vue';
import MirrorText from '../codeMirror/mirrorTextArea.vue';
-import { IconCaretDown, IconCaretRight, IconCaretUp, IconMinimize, IconPlusCircle } from '@computing/opendesign-icons';
+import {
+ IconCaretDown,
+ IconCaretRight,
+ IconCaretUp,
+ IconMinimize,
+ IconPlusCircle,
+} from '@computing/opendesign-icons';
import yaml from 'js-yaml';
import { ElMessage } from 'element-plus';
import MonacoEditor from 'src/components/monaco/MonacoEditor.vue';
@@ -264,7 +397,14 @@ const yamlInputCode = ref();
const yamlOutputCode = ref();
const yamlNodeName = ref();
const yamlNodeId = ref();
-const choicesList = ref>([]);
+const choicesList = ref<
+ Array<{
+ is_default: boolean;
+ branch_id: string;
+ conditions: any[];
+ logic: string;
+ }>
+>([]);
const infoDisabled = ref(true);
const yamlExpress = ref([
{
@@ -287,9 +427,19 @@ const yamlExpress = ref([
},
]);
const yamlBaseInfoRule = ref({
- name: [{ required: true, message: '请输入工作流名称', trigger: 'blur' }],
+ name: [
+ {
+ required: true,
+ message: i18n.global.t('flow.enterWorkflowName'),
+ trigger: 'blur',
+ },
+ ],
description: [
- { required: true, message: '请输入工作流描述', trigger: 'blur' },
+ {
+ required: true,
+ message: i18n.global.t('flow.enterWorkflowDesc'),
+ trigger: 'blur',
+ },
],
});
const activeName = ref([
@@ -312,117 +462,192 @@ interface Props {
const props = defineProps();
const emits = defineEmits(['closeDrawer', 'saveNode']);
-const logicObj ={
- and: '且',
- or: '或',
-}
+const logicObj = {
+ and: i18n.global.t('yaml.and'),
+ or: i18n.global.t('yaml.or'),
+};
const leftOptions = ref([]);
-const paramoperateList = ref([])
+const paramoperateList = ref([]);
-const handleGroupClick = (item: any, isVisible: boolean) => {
+const handleGroupClick = (item: any, isVisible: boolean, cIndex: number) => {
item.childVisible = isVisible;
- leftOptions.value.forEach(option => {
- if(option.stepId === item.stepId && !Object.hasOwn(option, 'isGroup')){
+ leftOptions.value.forEach((option) => {
+ if (option.stepId === item.stepId) {
option.visible = isVisible;
}
- })
-}
-const onSelectOption = (option: any,index:number, cIndex:number) => {
- const curOption = leftOptions.value.find(op => {
+ });
+};
+
+// 左值选择操作
+const onSelectOption = (option: any, index: number, cIndex: number) => {
+ const curOption = leftOptions.value.find((op) => {
return op.paramPath === option;
});
+ // 清空操作符
choicesList.value[index].conditions[cIndex].operate = null;
- choicesList.value[index].conditions[cIndex].right={
- step_id: null, type: null, value: null,name:null
- }
- choicesList.value[index].conditions[cIndex].left={
- step_id: curOption.stepId, type: curOption.paramType, value: option,name:curOption.pathName
- }
+ // 清空右值
+ choicesList.value[index].conditions[cIndex].right = {
+ step_id: null,
+ type: null,
+ value: null,
+ name: null,
+ };
+ // 重新赋值左值
+ let value = curOption.stepId + curOption.pathName;
+ choicesList.value[index].conditions[cIndex].left = {
+ step_id: curOption.stepId,
+ type: curOption.paramType,
+ value: value,
+ name: curOption.paramPath,
+ };
api
- .queryParameterOperate({ParamType:curOption.paramType})
- .then((res)=>{
- paramoperateList.value = res?.[1]?.result;
+ .queryParameterOperate({ ParamType: curOption.paramType })
+ .then((res) => {
+ if (paramoperateList.value[index].length < cIndex) {
+ paramoperateList.value[index][cIndex] = res?.[1]?.result;
+ } else {
+ paramoperateList.value[index].push(res?.[1]?.result);
+ }
})
- .catch((err)=>[
- console.error(err)
- ])
-}
-
+ .catch((err) => [console.error(err)]);
+};
-const onSelectOperateOption = (option: any,index:number, cIndex:number) => {
+// 操作符选择操作
+const onSelectOperateOption = (option: any, index: number, cIndex: number) => {
choicesList.value[index].conditions[cIndex].operate = option;
- const curBindType = paramoperateList.value.find(op => {
+ const curBindType = paramoperateList.value[index][cIndex].find((op) => {
return op.operate === option;
})?.bind_type;
+ // 切换当前绑定类型
choicesList.value[index].conditions[cIndex].right.type = curBindType;
+ // 清空右值
choicesList.value[index].conditions[cIndex].right.value = null;
-}
+ choicesList.value[index].conditions[cIndex].right.name = null;
+};
-const onSelectInputOption = (option: any, index:number, cIndex:number) => {
+// 右值选择操作
+const onSelectInputOption = (
+ option: any,
+ index: number,
+ cIndex: number,
+ type: string,
+) => {
const targetType = choicesList.value[index].conditions[cIndex].right.type;
let isValid = true;
- // 类型检查逻辑
- switch (targetType) {
- case 'number':
- isValid = !isNaN(Number(option));
- break;
- case 'boolean':
- isValid = option === 'true' || option === 'false' || option === true || option === false;
- break;
- case 'list':
- if (typeof option === 'string') {
- try {
- const parsed = JSON.parse(option);
- isValid = Array.isArray(parsed);
- } catch {
- isValid = false;
+ const curOption = leftOptions.value.find((op) => {
+ return op.paramPath === option;
+ });
+ // 类型检查逻辑,两种情况:1输入,2选择
+ if (type === 'input') {
+ switch (targetType) {
+ case 'number':
+ isValid = !isNaN(Number(option));
+ break;
+ case 'boolean':
+ isValid =
+ option === 'true' ||
+ option === 'false' ||
+ option === true ||
+ option === false;
+ break;
+ case 'list':
+ if (typeof option === 'string') {
+ try {
+ const parsed = JSON.parse(option);
+ isValid = Array.isArray(parsed);
+ } catch {
+ isValid = false;
+ }
}
- }
- break;
- case 'dict':
- if (typeof option === 'string') {
- try {
- const parsed = JSON.parse(option);
- isValid = typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed);
- } catch {
- isValid = false;
+ break;
+ case 'dict':
+ if (typeof option === 'string') {
+ try {
+ const parsed = JSON.parse(option);
+ isValid =
+ typeof parsed === 'object' &&
+ parsed !== null &&
+ !Array.isArray(parsed);
+ } catch {
+ isValid = false;
+ }
}
- }
- break;
- case 'string':
- default:
- isValid = typeof option === 'string';
- break;
+ break;
+ case 'string':
+ default:
+ isValid = typeof option === 'string';
+ break;
+ }
+ } else {
+ isValid = curOption.paramType === targetType;
}
+
if (isValid) {
- choicesList.value[index].conditions[cIndex].right.value = option;
+ choicesList.value[index].conditions[cIndex].right.name = option;
} else {
- ElMessage.error(i18n.global.t('输入类型错误'));
+ ElMessage.error(i18n.global.t('yaml.input_type_error'));
+ return;
}
- const curOption = leftOptions.value.find(op => {
- return op.paramPath === option;
- });
- if(curOption?.stepId){
- choicesList.value[index].conditions[cIndex].right.step_id = curOption?.stepId ?? null;
- choicesList.value[index].conditions[cIndex].right.name = curOption?.pathName ?? null;
+
+ // 赋值右值信息-选择的情况
+ if (curOption?.stepId) {
+ choicesList.value[index].conditions[cIndex].right.step_id =
+ curOption?.stepId ?? null;
+ let value = curOption?.stepId + curOption?.pathName;
+ choicesList.value[index].conditions[cIndex].right.value = value ?? null;
+ } else {
+ // 输入的情况
+ choicesList.value[index].conditions[cIndex].right.value = option;
}
-}
+};
watch(
() => [props.yamlContent, props.nodeName, props.nodeDesc, props.nodeId],
() => {
+ // 这里初始化左边条件选择
yamlInputCode.value = yaml.dump(props.yamlContent.input_parameters);
yamlOutputCode.value = yaml.dump(props.yamlContent.output_parameters);
yamlNodeName.value = props.nodeName;
yamlNodeId.value = props.nodeId;
- choicesList.value = JSON.parse(JSON.stringify(props.yamlContent?.input_parameters?.choices || [])).reverse();
+ choicesList.value = JSON.parse(
+ JSON.stringify(props.yamlContent?.input_parameters?.choices || []),
+ ).reverse();
yamlExpress.value[0].name = props.nodeName;
yamlExpress.value[0].description = props.nodeDesc;
yamlExpress.value[1].yamlCode = yaml.dump(
props.yamlContent.input_parameters,
);
yamlExpress.value[2].yamlCode = props.yamlContent.output_parameters;
+
+ // 获取需要处理的 choices(倒序、过滤掉 is_default 为 true 的、只保留有条件的)
+ const processedChoices = props.yamlContent.input_parameters.choices
+ .slice()
+ .reverse()
+ .filter((choice) => !choice.is_default && choice.conditions.length > 0);
+
+ // 初始化 paramoperateList.value,为每个需要处理的 choice 预先创建一个空数组
+ // 这样后续异步回调中就能通过索引安全地访问和 push
+ paramoperateList.value = processedChoices.map(() => []);
+
+ // 如果input_parameters有值,则初始化 左值,paramoperateList选择项添加
+ processedChoices.forEach((item, index) => {
+ if (!item.is_default) {
+ if (item.conditions.length > 0) {
+ item.conditions.forEach((conditionItem, conditionIndex) => {
+ let paramType = conditionItem.left.type;
+ if (paramType) {
+ api
+ .queryParameterOperate({ ParamType: paramType })
+ .then((res) => {
+ paramoperateList.value[index].push(res?.[1]?.result);
+ })
+ .catch((err) => [console.error(err)]);
+ }
+ });
+ }
+ }
+ });
},
{ deep: true, immediate: true },
);
@@ -450,23 +675,30 @@ const updateNodeYaml = () => {
let transResult;
let choiceHasEmpty = false;
try {
- if(yamlNodeId.value === 'Choice'){
- choicesList.value.forEach(item => {
- if(!item.is_default){
- item.conditions.forEach(condition => {
- if(!condition.left.value || !condition.right.value || !condition.operate){
+ if (yamlNodeId.value === 'Choice') {
+ choicesList.value.forEach((item) => {
+ if (!item.is_default) {
+ item.conditions.forEach((condition) => {
+ if (
+ !condition.left.value ||
+ !condition.right.value ||
+ !condition.operate
+ ) {
choiceHasEmpty = true;
return;
}
- })
+ });
}
- })
+ });
}
- if(yamlNodeId.value === 'Choice' && choiceHasEmpty){
- ElMessage.error(i18n.global.t('请完善条件'));
+ if (yamlNodeId.value === 'Choice' && choiceHasEmpty) {
+ ElMessage.error(i18n.global.t('yaml.please_improve_the_conditions'));
return;
}
- transResult = yamlNodeId.value === 'Choice'? JSON.parse(JSON.stringify(choicesList.value.reverse())) :yaml.load(yamlExpress.value[1].yamlCode ?? '');
+ transResult =
+ yamlNodeId.value === 'Choice'
+ ? JSON.parse(JSON.stringify(choicesList.value.reverse()))
+ : yaml.load(yamlExpress.value[1].yamlCode ?? '');
// 调用接口并更新--根据id包含更新后的yamlCode, name, desc
emits(
'saveNode',
@@ -483,7 +715,8 @@ const updateNodeYaml = () => {
const handleAddChoice = () => {
// 处理 pop() 可能返回 undefined 的情况
- const last = choicesList.value.length > 0 ? choicesList.value.pop() : undefined;
+ const last =
+ choicesList.value.length > 0 ? choicesList.value.pop() : undefined;
choicesList.value.push({
is_default: false,
branch_id: crypto.randomUUID(),
@@ -499,6 +732,8 @@ const handleAddChoice = () => {
if (last !== undefined) {
choicesList.value.push(last);
}
+ // 新增之后需要push空
+ paramoperateList.value.push([]);
};
const handleDelChoice = (index: number, branchItem: any) => {
// 添加类型注解
@@ -506,17 +741,16 @@ const handleDelChoice = (index: number, branchItem: any) => {
ElMessage.error(i18n.global.t('semantic.choiceMin'));
return;
}
-
+
// 删除当前分支的边
if (props.getEdges) {
- console.log(props.getEdges, branchItem);
props.getEdges?.forEach((item) => {
- if(item.branchId === branchItem.branch_id && props.removeEdges){
- props.removeEdges([item.id])
+ if (item.branchId === branchItem.branch_id && props.removeEdges) {
+ props.removeEdges([item.id]);
}
- })
+ });
}
-
+
choicesList.value.splice(index, 1);
};
const handleAddCondition = (index: number) => {
@@ -531,54 +765,65 @@ const handleAddCondition = (index: number) => {
};
const handleDelCondition = (index: number, cIndex: number) => {
// 添加类型注解和边界检查
- if (index >= 0 && index < choicesList.value.length && choicesList.value[index].conditions.length <= 1) {
+ if (
+ index >= 0 &&
+ index < choicesList.value.length &&
+ choicesList.value[index].conditions.length <= 1
+ ) {
ElMessage.error(i18n.global.t('semantic.conditionMin'));
return;
}
- if (index >= 0 && index < choicesList.value.length && cIndex >= 0 && cIndex < choicesList.value[index].conditions.length) {
+ if (
+ index >= 0 &&
+ index < choicesList.value.length &&
+ cIndex >= 0 &&
+ cIndex < choicesList.value[index].conditions.length
+ ) {
choicesList.value[index].conditions.splice(cIndex, 1);
}
};
-onMounted(()=>{
+onMounted(() => {
+ // 1、页面加载时,获取Choice节点内参数
api
.queryParameter({
appId: route.query?.appId as string,
flowId: props.flowId,
- stepId: props.nodeYamlId
+ stepId: props.nodeYamlId,
})
.then((res) => {
- if(Array.isArray(res[1]?.result)){
- res[1]?.result?.forEach(item => {
+ if (Array.isArray(res[1]?.result)) {
+ res[1]?.result?.forEach((item) => {
leftOptions.value.push({
- stepId:item.stepId,
- name:item.name,
- paramPath:item.name,
- isGroup:true,
- visible:true,
- childVisible:false
+ stepId: item.stepId,
+ name: item.name,
+ paramPath: item.name,
+ isGroup: true,
+ visible: true,
+ childVisible: false,
+ paramType: item.paramsNode.paramType,
+ pathName: `/${item.name}`,
});
- if(item?.paramsNode?.subParams){
- item?.paramsNode?.subParams.forEach(param => {
+ if (item?.paramsNode?.subParams) {
+ item?.paramsNode?.subParams.forEach((param) => {
leftOptions.value.push({
...param,
- name:param.paramName,
- stepId:item.stepId,
- visible:false,
- paramPath:`${item.name}${param.paramPath.replace(/\//, '.')}`,
- pathName:param.paramPath,
- })
- })
+ name: param.paramName,
+ stepId: item.stepId,
+ visible: false,
+ paramPath: `${item.name}${param.paramPath.replace(/\//, '.')}`,
+ pathName: param.paramPath,
+ });
+ });
}
- })
-
+ });
}
})
.catch((err) => {
console.error('Error fetching parameters:', err);
leftOptions.value = [];
- })
-})
+ });
+});