Преглед изворни кода

Merge branch 'main' of https://git.shalu.com/Shalu/shalu-agent-workflow

jiaxing.liao пре 4 дана
родитељ
комит
9409aefb11

+ 1 - 0
apps/web/components.d.ts

@@ -66,6 +66,7 @@ declare module 'vue' {
     ElTabs: typeof import('element-plus/es')['ElTabs']
     ElTag: typeof import('element-plus/es')['ElTag']
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
+    ErrorHandling: typeof import('./src/components/SetterCommon/Code/ErrorHandling.vue')['default']
     ExecutionChart: typeof import('./src/components/Chart/ExecutionChart.vue')['default']
     HttpSetter: typeof import('./src/components/setter/HttpSetter.vue')['default']
     InputVariables: typeof import('./src/components/SetterCommon/Code/InputVariables.vue')['default']

+ 132 - 138
apps/web/src/components/SetterCommon/Code/CodeEditor.vue

@@ -6,39 +6,39 @@ import * as monaco from 'monaco-editor'
 import { IconButton } from '@repo/ui'
 
 const props = withDefaults(
-	defineProps<{
-		allowFullscreen?: boolean
-		autoToggleTheme?: boolean
-		bordered?: boolean
-		config?: editor.IStandaloneEditorConstructionOptions
-		language?: string
-		lineNumbers?: 'off' | 'on'
-		modelValue?: any
-		readOnly?: boolean
-		theme?: 'hc-black' | 'vs-dark' | 'vs-light'
-		valueFormat?: string
-		height?: string
-		appendTo?: string | HTMLElement
-	}>(),
-	{
-		allowFullscreen: true,
-		config: () => ({
-			minimap: {
-				enabled: false
-			},
-			selectOnLineNumbers: true
-		}),
-		autoToggleTheme: true,
-		language: 'json',
-		lineNumbers: 'on',
-		readOnly: false,
-		theme: 'vs-light',
-		valueFormat: 'string',
-		height: '120px'
-	}
+    defineProps<{
+        allowFullscreen?: boolean
+        autoToggleTheme?: boolean
+        bordered?: boolean
+        config?: editor.IStandaloneEditorConstructionOptions
+        language?: string
+        lineNumbers?: 'off' | 'on'
+        modelValue?: any
+        readOnly?: boolean
+        theme?: 'hc-black' | 'vs-dark' | 'vs-light'
+        valueFormat?: string
+        height?: string
+        appendTo?: string | HTMLElement
+    }>(),
+    {
+        allowFullscreen: true,
+        config: () => ({
+            minimap: {
+                enabled: false
+            },
+            selectOnLineNumbers: true
+        }),
+        autoToggleTheme: true,
+        language: 'json',
+        lineNumbers: 'on',
+        readOnly: false,
+        theme: 'vs-light',
+        valueFormat: 'string',
+        height: '120px'
+    }
 )
 
-// todo 动态切换主题
+// 动态切换主题
 const theme = ref('dark')
 
 const emit = defineEmits(['update:modelValue', 'update:language'])
@@ -47,7 +47,7 @@ const isFullScreen = ref(false)
 
 const fullScreenStyle = `position: fixed;
   top: 0;
-  left: 0;
+  left: 0;      
   right: 0;
   bottom: 0;
   z-index: 2999;`
@@ -61,7 +61,7 @@ let monacoEditor: monaco.editor.IStandaloneCodeEditor | null = null
  * @param text
  */
 function setValue(text: string) {
-	monacoEditor?.setValue(text || '')
+    monacoEditor?.setValue(text || '')
 }
 
 /**
@@ -69,124 +69,118 @@ function setValue(text: string) {
  * @param text
  */
 function insertText(text: string) {
-	// 获取光标位置
-	const position = monacoEditor?.getPosition()
-	// 未获取到光标位置信息
-	if (!position) {
-		return
-	}
-	// 插入
-	monacoEditor?.executeEdits('', [
-		{
-			range: new monaco.Range(
-				position.lineNumber,
-				position.column,
-				position.lineNumber,
-				position.column
-			),
-			text
-		}
-	])
-	// 设置新的光标位置
-	monacoEditor?.setPosition({
-		...position,
-		column: position.column + text.length
-	})
-	// 重新聚焦
-	monacoEditor?.focus()
+    // 获取光标位置
+    const position = monacoEditor?.getPosition()
+    // 未获取到光标位置信息
+    if (!position) {
+        return
+    }
+    // 插入
+    monacoEditor?.executeEdits('', [
+        {
+            range: new monaco.Range(
+                position.lineNumber,
+                position.column,
+                position.lineNumber,
+                position.column
+            ),
+            text
+        }
+    ])
+    // 设置新的光标位置
+    monacoEditor?.setPosition({
+        ...position,
+        column: position.column + text.length
+    })
+    // 重新聚焦
+    monacoEditor?.focus()
 }
 
 onMounted(() => {
-	monacoEditor = monaco.editor.create(editContainer.value as HTMLElement, {
-		value: getValue(),
-		...props.config,
-		automaticLayout: true,
-		language: props.language,
-		lineNumbers: props.lineNumbers,
-		readOnly: props.readOnly,
-		scrollBeyondLastLine: false,
-		theme: props.theme
-	})
-
-	function handleToggleTheme() {
-		if (theme.value === 'dark') {
-			monaco.editor.setTheme('vs-dark')
-		} else {
-			monaco.editor.setTheme('vs-light')
-		}
-	}
-
-	// 自动切换主题
-	if (props.autoToggleTheme) {
-		watch(
-			() => theme,
-			() => {
-				nextTick(() => handleToggleTheme())
-			},
-			{
-				immediate: true
-			}
-		)
-	}
-
-	// 获取值
-	function getValue() {
-		// valueFormat 为json 格式,需要转换处理
-		if (props.valueFormat === 'json' && props.modelValue) {
-			return JSON.stringify(props.modelValue, null, 2)
-		}
-		return props.modelValue ?? ''
-	}
-
-	// 监听值变化
-	monacoEditor.onDidChangeModelContent(() => {
-		const currenValue = monacoEditor?.getValue()
-
-		// valueFormat 为json 格式,需要转换处理
-		if (props.valueFormat === 'json' && currenValue) {
-			emit('update:modelValue', JSON.parse(currenValue))
-			return
-		}
-
-		emit('update:modelValue', currenValue ?? '')
-	})
+    monacoEditor = monaco.editor.create(editContainer.value as HTMLElement, {
+        value: getValue(),
+        ...props.config,
+        automaticLayout: true,
+        language: props.language,
+        lineNumbers: props.lineNumbers,
+        readOnly: props.readOnly,
+        scrollBeyondLastLine: false,
+        theme: props.theme
+    })
+
+    function handleToggleTheme() {
+        if (theme.value === 'dark') {
+            monaco.editor.setTheme('vs-dark')
+        } else {
+            monaco.editor.setTheme('vs-light')
+        }
+    }
+
+    // 自动切换主题
+    if (props.autoToggleTheme) {
+        watch(
+            () => theme,
+            () => {
+                nextTick(() => handleToggleTheme())
+            },
+            {
+                immediate: true
+            }
+        )
+    }
+
+    // 获取值
+    function getValue() {
+        // valueFormat 为json 格式,需要转换处理
+        if (props.valueFormat === 'json' && props.modelValue) {
+            return JSON.stringify(props.modelValue, null, 2)
+        }
+        return props.modelValue ?? ''
+    }
+
+    // 监听值变化
+    monacoEditor.onDidChangeModelContent(() => {
+        const currenValue = monacoEditor?.getValue()
+
+        // valueFormat 为json 格式,需要转换处理
+        if (props.valueFormat === 'json' && currenValue) {
+            emit('update:modelValue', JSON.parse(currenValue))
+            return
+        }
+
+        emit('update:modelValue', currenValue ?? '')
+    })
 })
 
 defineExpose({
-	insertText,
-	setValue
+    insertText,
+    setValue
 })
 </script>
 <template>
-	<Teleport :disabled="!appendTo" :to="appendTo">
-		<div
-			ref="editContainer"
-			:class="{ bordered: props.bordered }"
-			:style="isFullScreen ? fullScreenStyle : { height: props.height }"
-			class="code-editor w-full h-full relative"
-		>
-			<div
-				class="z-999 text-$epic-text-helper absolute right-4 top-2 cursor-pointer text-xl"
-				@click="isFullScreen = !isFullScreen"
-				v-if="props.allowFullscreen"
-			>
-				<IconButton v-if="!isFullScreen" icon="lucide:fullscreen" link />
-				<IconButton v-else icon="material-symbols-light:fullscreen-exit-rounded" link />
-			</div>
-		</div>
-	</Teleport>
+    <Teleport :disabled="!appendTo" :to="appendTo">
+        <div ref="editContainer" :class="{ bordered: props.bordered }"
+            :style="isFullScreen ? fullScreenStyle : { height: props.height }"
+            class="code-editor w-full h-full relative">
+            <div class="z-999 text-$epic-text-helper absolute right-4 top-2 cursor-pointer text-xl"
+                @click="isFullScreen = !isFullScreen" v-if="props.allowFullscreen">
+                <IconButton v-if="!isFullScreen" icon="lucide:fullscreen" link />
+                <IconButton v-else icon="material-symbols-light:fullscreen-exit-rounded" link />
+            </div>
+        </div>
+    </Teleport>
 </template>
 <style lang="less" scoped>
 .code-editor {
-	width: 100%;
-	min-height: 150px;
+    width: 100%;
+    min-height: 150px;
 
-	:deep(.monaco-editor) {
-		height: 100%;
-	}
+    :deep(.monaco-editor) {
+        height: 100%;
+    }
 
-	&.bordered {
-		border: 1px solid var(--epic-border-color);
-	}
+    &.bordered {
+        border: 1px solid var(--epic-border-color);
+    }
 }
 </style>

+ 65 - 0
apps/web/src/components/SetterCommon/Code/ErrorHandling.vue

@@ -0,0 +1,65 @@
+<template>
+    <!-- 异常处理 -->
+    <div class="space-y-2 flex items-center justify-between">
+        <label class="text-sm font-medium text-gray-700 flex items-center gap-1">
+            异常处理
+            <Icon icon="lucide:info" :height="14" :width="14" class="text-gray-400" />
+        </label>
+        <ElSelect v-model="config.errorHandling" @change="handleConfigChange" size="default"
+            class="!w-[120px] text-sm bg-white !mt-0">
+            <el-option value="none" label="无"></el-option>
+            <el-option value="default" label="默认值"></el-option>
+            <el-option value="errBranch" label="异常分支"></el-option>
+        </ElSelect>
+    </div>
+    <div class="!mt-0">
+        <div v-if="config.errorHandling === 'default'">
+            <p class="text-sm text-gray-600 m-0 mb-1">当发生异常时,指定默认输出内容。</p>
+            <!-- 代码编辑器 -->
+            <CodeEditor v-model="config.errorCodeReturn" v-model:language="config.language" value-format="javascript" />
+        </div>
+        <div v-else-if="config.errorHandling === 'errBranch'">
+            <p class="text-sm m-0 mb-1 text-gray-600">在画布自定义失败分支逻辑。</p>
+            <p class="text-sm text-gray-400 m-0">当节点发生异常时,将自动执行失败分支。失败分支允许您灵活地提供错误消息、报告、修复或跳过操作。</p>
+        </div>
+    </div>
+</template>
+<script lang="ts" setup>
+import { ref, watch } from "vue"
+import { Icon } from '@iconify/vue'
+import CodeEditor from '@/components/SetterCommon/Code/CodeEditor.vue'
+interface ErrorHandlerConfig {
+    errorHandling: string
+    errorCodeReturn: string
+    language: string
+}
+interface Props {
+    modelValue: ErrorHandlerConfig
+}
+
+interface Emits {
+    (e: 'update:modelValue', value: ErrorHandlerConfig): void
+}
+const props = defineProps<Props>()
+const emit = defineEmits<Emits>()
+
+watch(
+    () => props.modelValue,
+    (newVal) => {
+        config.value = newVal || {
+            errorHandling: 'none',
+            errorCodeReturn: '',
+            language: 'javascript',
+        }
+    }
+)
+const config = ref<ErrorHandlerConfig>(props.modelValue || {
+    errorHandling: 'none',
+    errorCodeReturn: '',
+    language: 'javascript',
+})
+
+const handleConfigChange = () => {
+    emit('update:modelValue', config.value)
+}
+</script>

+ 14 - 6
apps/web/src/components/SetterCommon/Code/InputVariables.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="space-y-3">
-        <div class="flex items-center justify-between">
+        <div class="flex items-center justify-between beautify">
             <label class="text-sm font-medium text-gray-700">输入变量</label>
             <ElButton @click="addVariable" class="p-1  rounded bg-gray-100 transition-colors" title="添加变量">
                 <Icon icon="lucide:plus" :height="16" :width="16" class="text-gray-600" />
@@ -10,7 +10,7 @@
         <div class="space-y-2">
             <div v-for="(variable, index) in variables" :key="variable.name" class="flex items-center gap-2 group">
                 <ElInput v-model="variable.id" type="text" placeholder="变量名"
-                    class="w-1/3 px-3 py-2 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
+                    class="w-1/3 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                     @input="handleVariableChange" />
                 <ElInput class="w-1/3" v-model="variable.name" placeholder="设置变量值" />
 
@@ -22,7 +22,7 @@
             </div>
 
             <div v-if="variables.length === 0" class="text-sm text-gray-400 text-center py-4">
-                <Icon icon="lucide:circle-off" :height="24" :width="25"></Icon>
+                <Icon icon="lucide:variable" :height="24" :width="25"></Icon>
                 <p class="m-1">暂无输入变量</p>
             </div>
         </div>
@@ -57,16 +57,17 @@ watch(
         variables.value = newVal || []
     }
 )
-
+// 添加变量
 const addVariable = () => {
     const newVariable: Variable = {
-        id: `var_${Date.now()}`,
-        name: `arg${variables.value.length + 1}`
+        id: '',
+        name: ''
     }
     variables.value.push(newVariable)
     handleVariableChange()
 }
 
+// 删除变量
 const removeVariable = (index: number) => {
     variables.value.splice(index, 1)
     handleVariableChange()
@@ -76,3 +77,10 @@ const handleVariableChange = () => {
     emit('update:modelValue', variables.value)
 }
 </script>
+
+<style lang="less" scoped>
+.beautify {
+    padding-bottom: 10px;
+    border-bottom: 1px solid #eee;
+}
+</style>

+ 13 - 13
apps/web/src/components/SetterCommon/Code/OutputVariables.vue

@@ -1,13 +1,6 @@
-<!--
- * @Author: liuJie
- * @Date: 2026-01-27 14:38:32
- * @LastEditors: liuJie
- * @LastEditTime: 2026-01-28 17:18:55
- * @Describe: file describe
--->
 <template>
-    <div class="">
-        <div class="flex items-center justify-between">
+    <div class="space-y-3">
+        <div class="flex items-center justify-between beautify">
             <label class="text-sm font-medium text-gray-700">
                 输出变量
                 <span class="text-red-500">*</span>
@@ -20,10 +13,10 @@
         <div class="space-y-2">
             <div v-for="(output, index) in outputs" :key="output.id" class="flex items-center gap-2 group">
                 <ElInput v-model="output.name" type="text" placeholder="result"
-                    class="w-1/3 px-3 py-2 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
+                    class="w-1/3 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                     @input="handleOutputChange" />
                 <ElSelect v-model="output.type" @change="handleOutputChange"
-                    class="w-1/3 px-3 py-2 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white min-w-[100px]">
+                    class="w-1/3 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white min-w-[100px]">
                     <el-option value="String">String</el-option>
                     <el-option value="Number">Number</el-option>
                     <el-option value="Boolean">Boolean</el-option>
@@ -38,7 +31,7 @@
             </div>
 
             <div v-if="outputs.length === 0" class="text-sm text-gray-400 text-center py-4">
-                <Icon icon="lucide:circle-off" :height="24" :width="25"></Icon>
+                <Icon icon="lucide:variable" :height="24" :width="25"></Icon>
                 <p class="m-1">请添加至少一个输出变量</p>
             </div>
         </div>
@@ -79,7 +72,7 @@ const addOutput = () => {
     const newOutput: OutputVariable = {
         id: `output_${Date.now()}`,
         name: 'result',
-        type: 'String'
+        type: 'Array'
     }
     outputs.value.push(newOutput)
     handleOutputChange()
@@ -94,3 +87,10 @@ const handleOutputChange = () => {
     emit('update:modelValue', outputs.value)
 }
 </script>
+
+<style lang="less" scoped>
+.beautify {
+    padding-bottom: 10px;
+    border-bottom: 1px solid #eee;
+}
+</style>

+ 17 - 29
apps/web/src/components/SetterCommon/Code/TestConfig.vue

@@ -1,47 +1,31 @@
 <template>
-    <div class="space-y-4">
+    <div class="space-y-3">
         <!-- 失败时重试 -->
         <div class="space-y-2">
-            <div class="flex items-center justify-between">
+            <div class="flex items-center justify-between beautify">
                 <label class="text-sm font-medium text-gray-700">失败时重试</label>
                 <el-switch v-model="retryState" @change="toggleRetry" />
             </div>
             <div class="space-y-2" v-if="config.retryEnabled">
-                <div class="pl-[22px]">
-                    <p class="m-0 text-sm text-gray-600">最大重试次数</p>
-                    <el-slider v-model="config.maxRetries" show-input />
+                <div class="pl-[10px] flex item-center justify-between">
+                    <p class="m-0 text-sm text-gray-600 w-1/2">最大重试次数</p>
+                    <el-slider v-model="config.maxRetries" class="w-1/2" show-input :min="0" :max="10" size="default" />
                 </div>
-                <div class="pl-[22px]">
-                    <p class="m-0 text-sm text-gray-600">重试间隔</p>
-                    <el-slider v-model="config.retryInterval" show-input />
+                <div class="pl-[10px] flex item-center justify-between">
+                    <p class="m-0 text-sm text-gray-600 w-1/2">重试间隔(ms)</p>
+                    <el-slider v-model="config.retryInterval" class="w-1/2" :min="100" :max="5000" show-input
+                        size="default" />
                 </div>
             </div>
         </div>
-
-        <!-- 异常处理 -->
-        <div class="space-y-2">
-            <label class="text-sm font-medium text-gray-700 flex items-center gap-1">
-                异常处理
-                <Icon icon="lucide:info" :height="14" :width="14" class="text-gray-400" />
-            </label>
-            <ElSelect v-model="config.errorHandling" @change="handleConfigChange"
-                class="w-full px-3 py-2 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white">
-                <el-option value="none" label="无"></el-option>
-                <el-option value="stop" label="停止执行"></el-option>
-                <el-option value="continue" label="继续执行"></el-option>
-                <el-option value="retry" label="重试"></el-option>
-            </ElSelect>
-        </div>
     </div>
 </template>
 
 <script setup lang="ts">
 import { ref, watch } from 'vue'
-import { Icon } from '@iconify/vue'
 
 interface TestConfig {
     retryEnabled: boolean
-    errorHandling: string,
     maxRetries?: number
     retryInterval?: number
 }
@@ -60,9 +44,8 @@ const emit = defineEmits<Emits>()
 const retryState = ref(false)
 const config = ref<TestConfig>(props.modelValue || {
     retryEnabled: false,
-    errorHandling: 'none',
-    maxRetries: 3,
-    retryInterval: 1000
+    maxRetries: 0,
+    retryInterval: 100
 })
 
 watch(
@@ -70,7 +53,6 @@ watch(
     (newVal) => {
         config.value = newVal || {
             retryEnabled: false,
-            errorHandling: 'none'
         }
     }
 )
@@ -84,3 +66,9 @@ const handleConfigChange = () => {
     emit('update:modelValue', config.value)
 }
 </script>
+<style lang="less" scoped>
+.beautify {
+    padding-bottom: 6px;
+    border-bottom: 1px solid #eee;
+}
+</style>

+ 10 - 14
apps/web/src/components/SetterCommon/condition/ConditionBuilder.vue

@@ -3,25 +3,21 @@
         <!-- 条件行 -->
         <div v-for="(condition, index) in conditions" :key="condition.id" class="flex items-center gap-1">
             <!-- 左侧变量选择 -->
-            <div class="relative w-3/4">
-                <ElSelect placeholder="选择变量" v-model="condition.leftValue">
-                    <ElOption v-for="variable in availableVariables" :key="variable.id" :value="variable.name"
-                        :label="variable.name" />
-                </ElSelect>
-            </div>
+            <ElSelect placeholder="选择变量" class="w-1/4" v-model="condition.leftValue" @change="handleConditionChange">
+                <ElOption v-for="variable in availableVariables" :key="variable.id" :value="variable.name"
+                    :label="variable.name + `  (${variable.type})`" />
+            </ElSelect>
+
+            <!-- 右侧值输入 -->
+            <ElInput v-model="condition.rightValue" type="text" placeholder="输入值" @input="handleConditionChange"
+                class="w-1/4 text-sm bg-white" />
 
             <!-- 运算符选择 -->
-            <ElSelect v-model="condition.operator" @change="handleConditionChange"
-                class="w-1/4 text-sm border border-gray-200 rounded-lg  bg-white ">
+            <ElSelect placeholder="选择条件" v-model="condition.operator" @change="handleConditionChange"
+                class="w-1/4 text-sm bg-white">
                 <ElOption v-for="li in operators" :key="li.value" :value="li.value" :label="li.label" />
             </ElSelect>
 
-            <!-- 右侧值输入 -->
-            <div class="relative w-3/4">
-                <ElInput v-model="condition.rightValue" type="text" placeholder="输入值" @input="handleConditionChange"
-                    class="w-full text-sm border border-gray-200 rounded-lg" />
-            </div>
-
             <!-- 删除按钮 -->
             <ElButton v-if="conditions.length > 1" @click="removeCondition(index)"
                 class="p-2 w-1/4 opacity-50 hover:opacity-100 hover:bg-red-50 rounded transition-all" title="删除条件">

+ 60 - 49
apps/web/src/components/setter/CodeSetter.vue

@@ -1,28 +1,28 @@
 <template>
-	<div class="bg-white w-full">
-		<div class="w-full">
-			<!-- Content -->
-			<div class="p-4">
-				<div class="space-y-6">
-					<!-- 输入变量 -->
-					<InputVariables v-model="formData.inputVariables" />
+    <div class="bg-white w-full">
+        <div class="w-full">
+            <!-- Content -->
+            <div class="p-4">
+                <div class="space-y-6">
+                    <!-- 输入变量 -->
+                    <InputVariables v-model="formData.inputVariables" />
 
-					<!-- 代码编辑器 -->
-					<CodeEditor
-						v-model="formData.code"
-						v-model:language="formData.language"
-						value-format="javascript"
-					/>
+                    <!-- 代码编辑器 -->
+                    <CodeEditor v-model="formData.code" v-model:language="formData.language"
+                        value-format="javascript" />
 
-					<!-- 输出变量 -->
-					<OutputVariables v-model="formData.outputVariables" />
+                    <!-- 输出变量 -->
+                    <OutputVariables v-model="formData.outputVariables" />
 
-					<!-- 测试配置 -->
-					<TestConfig v-model="formData.testConfig" />
-				</div>
-			</div>
-		</div>
-	</div>
+                    <!-- 测试配置 -->
+                    <TestConfig v-model="formData.testConfig" />
+
+                    <!-- 异常处理 -->
+                    <ErrorHandling v-model="formData.errorHandler" />
+                </div>
+            </div>
+        </div>
+    </div>
 </template>
 
 <script setup lang="ts">
@@ -31,21 +31,28 @@ import InputVariables from '@/components/SetterCommon/Code/InputVariables.vue'
 import CodeEditor from '@/components/SetterCommon/Code/CodeEditor.vue'
 import OutputVariables from '@/components/SetterCommon/Code/OutputVariables.vue'
 import TestConfig from '@/components/SetterCommon/Code/TestConfig.vue'
-
+import ErrorHandling from '@/components/SetterCommon/Code/ErrorHandling.vue'
 interface Variable {
-	id: string
-	name: string
+    id: string
+    name: string
 }
 
 interface OutputVariable {
-	id: string
-	name: string
-	type: string
+    id: string
+    name: string
+    type: string
 }
 
 interface TestConfigData {
-	retryEnabled: boolean
-	errorHandling: string
+    retryEnabled: boolean
+    maxRetries: number
+    retryInterval: number
+}
+
+interface ErrorHandler {
+    errorHandling: string
+    errorCodeReturn: string,
+    language: string
 }
 
 // const props = withDefaults(defineProps<{
@@ -56,25 +63,29 @@ interface TestConfigData {
 // }>()
 
 const formData = reactive({
-	// 输入变量, 变量默认值
-	inputVariables: [
-		// { id: 'var_1', name: 'arg1' },
-	] as Variable[],
-	// 代码内容
-	code: `function main(arg1, arg2) {
-            return {
-                "result": arg1 + arg2,
-}}`,
-	// 编程语言
-	language: 'javascript',
-	// 输出变量
-	outputVariables: [
-		// { id: 'output_1', name: 'result', type: 'String' }
-	] as OutputVariable[],
-	// 测试配置
-	testConfig: {
-		retryEnabled: false,
-		errorHandling: 'none'
-	} as TestConfigData
+    // 输入变量, 变量默认值
+    inputVariables: [
+        // { id: 'var_1', name: 'arg1' },
+    ] as Variable[],
+    // 代码内容
+    code: ``,
+    // 编程语言
+    language: 'javascript',
+    // 输出变量
+    outputVariables: [
+        // { id: 'output_1', name: 'result', type: 'String' }
+    ] as OutputVariable[],
+    // 测试配置
+    testConfig: {
+        retryEnabled: false,
+        maxRetries: 0,
+        retryInterval: 100,
+    } as TestConfigData,
+    // 错误补救
+    errorHandler: {
+        errorHandling: 'none',
+        errorCodeReturn: '',
+        language: 'javascript',
+    } as ErrorHandler
 })
 </script>

+ 3 - 3
apps/web/src/components/setter/ConditionSetter.vue

@@ -76,7 +76,7 @@ const branches = reactive({
     if: {
         id: 'if_1',
         type: 'if' as const,
-        label: 'CASE 1',
+        label: '条件 1',
         description: '选择变量名称,设置条件和值',
         conditions: [
             {
@@ -91,7 +91,7 @@ const branches = reactive({
     else: {
         id: 'else_1',
         type: 'else' as const,
-        label: 'ELSE',
+        label: '条件',
         description: '当if条件不满足且没有匹配的逻辑时。',
         conditions: [
             {
@@ -114,7 +114,7 @@ const addElifBranch = () => {
     const newElif: Branch = {
         id: `elif_${Date.now()}`,
         type: 'elif',
-        label: `CASE ${branches.elifs.length + 2}`,
+        label: `条件 ${branches.elifs.length + 2}`,
         description: '条件未设置',
         conditions: [
             {