wujingjing
2025-03-20 37535ab838b1d8d1a4b61db41afb3b77d2101311
添加 RPA 节点
已修改4个文件
114 ■■■■■ 文件已修改
src/components/vue-flow/VueFlowHelper.ts 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/vue-flow/ui/nodes/N8nNode.vue 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/vue-flow/ui/nodes/PythonCodeNode.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/vue-flow/vueFlowEnum.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/vue-flow/VueFlowHelper.ts
@@ -217,16 +217,17 @@
            case NodeType.N8n:
                data = {
                    ...data,
                    description: '执行n8n工作流。',
                    description: '执行RPA操作。',
                    [VueFlowConstant.GROUP_PARAMS_KEY]: [
                        {
                            name: '工作流ID',
                            name: '工作流',
                            [VueFlowConstant.PARAMS_KEY]: [
                                {
                                    key: 'n8n_flow_id',
                                    type: 'n8n_flow_id',
                                    required: true,
                                    value: { type: 'input', label: '', value: '' },
                                    // type: 'var'
                                    value: { type: 'select', label: '', value: '' },
                                },
                            ],
                        },
@@ -236,10 +237,7 @@
                                {
                                    key: 'n8n_input',
                                    type: 'n8n_input',
                                    value: {
                                        type: 'json',
                                        value: {},
                                    },
                                    value: [],
                                },
                            ],
                        },
@@ -249,8 +247,7 @@
                                {
                                    key: 'n8n_output',
                                    type: 'n8n_output',
                                    required: true,
                                    value: { type: 'input', label: '', value: '' },
                                    value: { type: 'macro', label: '' },
                                },
                            ],
                        },
src/components/vue-flow/ui/nodes/N8nNode.vue
@@ -13,7 +13,7 @@
                <!-- codeInput.params[0].value -->
                <el-form-item prop="group_params.0.params.0.value.value" labelWidth="0">
                    <el-select
                        class="!w-[220px] flex-0"
                        class="!w-full flex-0"
                        filterable
                        :disabled="isViewMode"
                        placeholder="工作流"
@@ -24,29 +24,38 @@
                    </el-select>
                </el-form-item>
            </FieldLayout>
            <FieldLayout :title="flowInput.name" v-if="Object.keys(flowInput.params[0].value.value).length > 0">
            <FieldLayout :title="flowInput.name" v-if="flowInput.params[0].value.length > 0">
                <!-- codeInput.params[0].value -->
                <FieldLayout level="2" :title="item" v-for="(item, index) in Object.keys(flowInput.params[0].value.value)" :key="index">
                    <el-form-item :prop="`group_params.1.params.0.value.value.${item}`" labelWidth="0">
                        <el-input
                            filterable
                            class="w-[120px] flex-0"
                            v-model="flowInput.params[0].value.value[item]"
                            :readonly="isViewMode"
                            placeholder="参数名"
                        ></el-input>
                <FieldLayout level="2" :title="item.key" v-for="(item, index) in flowInput.params[0].value" :key="index">
                    <template #right>
                        <el-radio-group
                            v-model="item.type"
                            :disabled="isViewMode"
                            @change="handleTypeChange(item)"
                            size="small"
                            class="input-type-radio"
                        >
                            <el-radio-button label="input">输入</el-radio-button>
                            <el-radio-button label="macro">宏</el-radio-button>
                        </el-radio-group>
                    </template>
                    <el-form-item v-if="item.type === 'input'" :prop="`group_params.1.params.0.value.${index}.value`" labelWidth="0">
                        <el-input filterable class="w-full flex-0" v-model="item.value" :readonly="isViewMode" placeholder="值"></el-input>
                    </el-form-item>
                    <el-form-item v-if="item.type === 'macro'" :prop="`group_params.1.params.0.value.${index}.value`" labelWidth="0">
                        <el-input filterable class="w-full flex-0" v-model="item.label" :readonly="isViewMode" placeholder="宏"></el-input>
                    </el-form-item>
                </FieldLayout>
            </FieldLayout>
            <FieldLayout :title="flowOutput.name">
                <!-- codeOutput.params[0].value -->
                <el-form-item prop="group_params.2.params.0.value.value" labelWidth="0">
                <el-form-item prop="group_params.2.params.0.value.label" labelWidth="0">
                    <el-input
                        filterable
                        class="w-[120px] flex-0"
                        v-model="flowOutput.params[0].value.value"
                        placeholder="参数名"
                        class="w-full flex-0"
                        v-model="flowOutput.params[0].value.label"
                        placeholder="宏"
                        :readonly="isViewMode"
                    ></el-input>
                </el-form-item>
@@ -61,14 +70,14 @@
import { Handle, Position, useNode } from '@vue-flow/core';
import { onMounted, ref } from 'vue';
import { VueFlowHelper } from '../../VueFlowHelper';
import { NodeType, ParameterType } from '../../vueFlowEnum';
import CodeEditor from '/@/components/input/codeEditor/index.vue';
import { NodeType } from '../../vueFlowEnum';
// import CodeEditDialog from './components/CodeEditDlg.vue';
import item from 'element-plus/es/components/space/src/item';
import FieldLayout from './components/FieldLayout.vue';
import NodeBasicLayout from './components/NodeBasicLayout.vue';
import type { LLMNodeData, LLMNodeEvents } from './index';
import { validateForm } from './utils';
import { textTypeMap } from '/@/components/input/codeEditor/types';
const props = defineProps<
    NodeProps<LLMNodeData, LLMNodeEvents> & {
        isViewMode?: boolean;
@@ -81,13 +90,10 @@
};
const workflowValueChange = (value: string) => {
    console.log('🚀 ~ workflowValueChange ~ workflow:', value);
    const flow = getFlowByID(value);
    console.log('🚀 ~ workflowValueChange ~ flow:', flow);
    const nodes = flow.nodes;
    const webhookNode = nodes.find((item) => item.type === 'n8n-nodes-base.webhook');
    console.log('🚀 ~ workflowValueChange ~ webhookNode:', webhookNode);
    flowInput.value.params[0].value.value = {};
    flowInput.value.params[0].value = [];
    if (!webhookNode) {
        return;
    }
@@ -97,18 +103,15 @@
    if (path) {
        // Parse path parameters from path string
        const pathParams = path.match(/\/:([^\/]+)/g)?.map((p) => p.substring(2)) || [];
        console.log('🚀 ~ pathParams:', pathParams);
        flowInput.value.params[0].value = pathParams.map((item) => {
            return {
                key: item,
                type: 'macro',
                label: '',
                value: '',
            };
        });
        // Update input parameters with path params
        if (pathParams.length > 0) {
            const inputValue = flowInput.value.params[0].value.value || {};
            pathParams.forEach((param) => {
                if (!inputValue[param]) {
                    inputValue[param] = '';
                }
            });
            flowInput.value.params[0].value.value = inputValue;
        }
        console.log('🚀 ~ flowInput.value.params[0].value.value:', flowInput.value.params[0].value.value);
    }
};
const emit = defineEmits<{
@@ -135,4 +138,28 @@
        validateForm: validateForm(formRef) as any,
    });
});
const handleTypeChange = (item: any) => {
    // 清空之前的输入值
    if (item.type === 'macro') {
        item.value = ''; // 切换到变量模式时清空输入值
    } else {
        item.label = ''; // 切换到输入模式时清空变量值
    }
};
</script>
<style scoped>
.input-type-radio {
    margin: 0 8px;
}
:deep(.el-radio-button__inner) {
    padding: 2px 8px;
}
:deep(.el-radio-button__original-radio:checked + .el-radio-button__inner) {
    background-color: var(--el-color-primary);
    border-color: var(--el-color-primary);
}
</style>
src/components/vue-flow/ui/nodes/PythonCodeNode.vue
@@ -14,7 +14,7 @@
                <el-form-item prop="group_params.0.params.0.value.value" labelWidth="0">
                    <el-input
                        filterable
                        class="w-[120px] flex-0"
                        class="w-full flex-0"
                        v-model="codeInput.params[0].value.value"
                        placeholder="参数名"
                        :readonly="isViewMode"
@@ -27,7 +27,7 @@
                <el-form-item prop="group_params.1.params.0.value.value" labelWidth="0">
                    <el-input
                        filterable
                        class="w-[120px] flex-0"
                        class="w-full flex-0"
                        v-model="codeOutput.params[0].value.value"
                        placeholder="参数名"
                        :readonly="isViewMode"
src/components/vue-flow/vueFlowEnum.ts
@@ -38,7 +38,7 @@
    [NodeType.Func]: '执行功能',
    [NodeType.Code]: '代码',
    [NodeType.PythonCode]: 'python代码',
    [NodeType.N8n]: 'n8n节点',
    [NodeType.N8n]: 'RPA',
    [NodeType.TextResource]: '文本资源',
    [NodeType.Analysis]: '分析',
};