| | |
| | | |
| | | WebApiUrl: { |
| | | MainUrl: 'https://widev.cpolar.top/ai_dev/', |
| | | // MainUrl: 'http://192.168.1.58:8080/', |
| | | |
| | | AuthUrl: 'http://47.100.245.85:8190/', |
| | | }, |
| | | SoftWareInfo: { |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '/@/utils/request'; |
| | | |
| | | const convertJson = (res: any) => { |
| | | const json = JSON.parse(res.json_url); |
| | | |
| | | return { |
| | | json_ok: res.json_ok, |
| | | values: json, |
| | | }; |
| | | }; |
| | | |
| | | export const GetN8nWorkflowList = async (params, req: any = request) => { |
| | | const res = await req({ |
| | | url: '/n8n/connectionN8nList', |
| | | method: 'POST', |
| | | data: params, |
| | | headers: { |
| | | 'Content-Type': 'application/x-www-form-urlencoded', |
| | | }, |
| | | }); |
| | | |
| | | return convertJson(res); |
| | | }; |
| | |
| | | <div class="relative h-full w-full" id="main-canvas" @drop="handleOnDrop" @dragover="handleOnDragOver"> |
| | | <VueFlow v-model="elements" :node-types="nodeTypes" :connection-mode="ConnectionMode.Strict"> |
| | | <template #node-start="startNodeProps"> |
| | | <StartNode ref="nodeRef" v-bind="startNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(startNodeProps.id, ref)" /> |
| | | <StartNode |
| | | ref="nodeRef" |
| | | v-bind="startNodeProps" |
| | | :isViewMode="isViewMode" |
| | | @register="(ref) => registerNodeRef(startNodeProps.id, ref)" |
| | | /> |
| | | </template> |
| | | <template #node-condition="conditionNodeProps"> |
| | | <ConditionNode ref="nodeRef" v-bind="conditionNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(conditionNodeProps.id, ref)" /> |
| | | <ConditionNode |
| | | ref="nodeRef" |
| | | v-bind="conditionNodeProps" |
| | | :isViewMode="isViewMode" |
| | | @register="(ref) => registerNodeRef(conditionNodeProps.id, ref)" |
| | | /> |
| | | </template> |
| | | <template #node-output_msg="outputNodeProps"> |
| | | <OutputNode ref="nodeRef" v-bind="outputNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(outputNodeProps.id, ref)" /> |
| | | <OutputNode |
| | | ref="nodeRef" |
| | | v-bind="outputNodeProps" |
| | | :isViewMode="isViewMode" |
| | | @register="(ref) => registerNodeRef(outputNodeProps.id, ref)" |
| | | /> |
| | | </template> |
| | | |
| | | <template #node-end="endNodeProps"> |
| | |
| | | </template> |
| | | |
| | | <template #node-agent="agentNodeProps"> |
| | | <AgentNode ref="nodeRef" v-bind="agentNodeProps" :agentNames="agentNames" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(agentNodeProps.id, ref)" /> |
| | | <AgentNode |
| | | ref="nodeRef" |
| | | v-bind="agentNodeProps" |
| | | :agentNames="agentNames" |
| | | :isViewMode="isViewMode" |
| | | @register="(ref) => registerNodeRef(agentNodeProps.id, ref)" |
| | | /> |
| | | </template> |
| | | <template #node-func="funcNodeProps"> |
| | | <FuncNode ref="nodeRef" v-bind="funcNodeProps" :funcNames="funcNames" :isViewMode="isViewMode" /> |
| | | </template> |
| | | |
| | | <template #node-code="codeNodeProps"> |
| | | <CodeNode ref="nodeRef" v-bind="codeNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(codeNodeProps.id, ref)" /> |
| | | <CodeNode |
| | | ref="nodeRef" |
| | | v-bind="codeNodeProps" |
| | | :isViewMode="isViewMode" |
| | | @register="(ref) => registerNodeRef(codeNodeProps.id, ref)" |
| | | /> |
| | | </template> |
| | | <template #node-python_code="pythonCodeNodeProps"> |
| | | <PythonCodeNode ref="nodeRef" v-bind="pythonCodeNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(pythonCodeNodeProps.id, ref)" /> |
| | | <PythonCodeNode |
| | | ref="nodeRef" |
| | | v-bind="pythonCodeNodeProps" |
| | | :isViewMode="isViewMode" |
| | | @register="(ref) => registerNodeRef(pythonCodeNodeProps.id, ref)" |
| | | /> |
| | | </template> |
| | | <template #node-n8n="n8nNodeProps"> |
| | | <N8nNode |
| | | :workflowList="n8nWorkflowList" |
| | | ref="nodeRef" |
| | | v-bind="n8nNodeProps" |
| | | :isViewMode="isViewMode" |
| | | @register="(ref) => registerNodeRef(n8nNodeProps.id, ref)" |
| | | /> |
| | | </template> |
| | | <template #node-text_resource="textResourceNodeProps"> |
| | | <TextResourceNode ref="nodeRef" v-bind="textResourceNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(textResourceNodeProps.id, ref)" /> |
| | | <TextResourceNode |
| | | ref="nodeRef" |
| | | v-bind="textResourceNodeProps" |
| | | :isViewMode="isViewMode" |
| | | @register="(ref) => registerNodeRef(textResourceNodeProps.id, ref)" |
| | | /> |
| | | </template> |
| | | |
| | | <template #node-analysis="analysisNodeProps"> |
| | |
| | | import TextResourceNode from './ui/nodes/TextResourceNode.vue'; |
| | | import { NodeType, nodeTypeMap } from './vueFlowEnum'; |
| | | import { VueFlowHelper } from './VueFlowHelper'; |
| | | |
| | | import N8nNode from './ui/nodes/N8nNode.vue'; |
| | | import { GetN8nWorkflowList } from '/@/api/n8n'; |
| | | const props = defineProps(['flowJson', 'agentNames', 'funcNames', 'llmInfoList', 'isViewMode']); |
| | | |
| | | const n8nWorkflowList = ref([]); |
| | | const getN8nWorkflowList = async () => { |
| | | const res = await GetN8nWorkflowList({ |
| | | active: true, |
| | | }); |
| | | n8nWorkflowList.value = res.values?.data ?? []; |
| | | }; |
| | | |
| | | const nodeTypes = {}; |
| | | const elements = ref<Elements>(); |
| | |
| | | |
| | | setInteractive(!props.isViewMode); |
| | | }; |
| | | onMounted(() => { |
| | | onMounted(async () => { |
| | | getN8nWorkflowList(); |
| | | setTimeout(() => { |
| | | initFlowStatus(); |
| | | }, 30); |
| | |
| | | key: 'code', |
| | | type: 'code', |
| | | required: true, |
| | | value: "var recs = args.querySQL(\n \" SELECT * FROM guangming_data.tc_hzl_v4\"\n + \" WHERE otime >={start_time}::timestamp + '-1 months' AND otime < {end_time}::timestamp + '1 days'\", {\n start_time : args.getArg(\"start_time\"),\n end_time : args.getArg(\"end_time\")\n});\n\nvar resultText = \"æ¶é´,æ°´ååï¼èçµé,åºå£æµé\\n\";\nfor(var recIndex in recs)\n{\n var rec = recs[recIndex];\n resultText += rec[\"OTIME\"] + \",\" + rec[\"FACT_NAME\"] + \",\" + rec[\"VPOWER\"] + \",\" + rec[\"VFLOW\"] + \"\\n\";\n}\nargs.setArg(\"RECORD_LIST\", resultText);\n\nargs.sendTableToClent({\n title : \"æµé\",\n columns : [\n {\"title\":\"æ¶é´\", \"name\":\"OTIME\"},\n {\"title\":\"æ°´å\", \"name\":\"FACT_NAME\"},\n {\"title\":\"æµé\", \"name\":\"VFLOW\"}\n ],\n\n recs : recs\n});\n\nargs.sendChartToClient({\n title : \"çµé\",\n col_time : \"OTIME\",\n col_name : \"FACT_NAME\",\n col_value: \"VPOWER\",\n recs : recs\n});\nargs.sendKnowledgeToClient({\n result : args.getArg(\"num1\") + \" + \" + args.getArg(\"num2\") + \"=\" + args.getArg(\"V\")\n});", |
| | | value: |
| | | 'var recs = args.querySQL(\n " SELECT * FROM guangming_data.tc_hzl_v4"\n + " WHERE otime >={start_time}::timestamp + \'-1 months\' AND otime < {end_time}::timestamp + \'1 days\'", {\n start_time : args.getArg("start_time"),\n end_time : args.getArg("end_time")\n});\n\nvar resultText = "æ¶é´,æ°´ååï¼èçµé,åºå£æµé\\n";\nfor(var recIndex in recs)\n{\n var rec = recs[recIndex];\n resultText += rec["OTIME"] + "," + rec["FACT_NAME"] + "," + rec["VPOWER"] + "," + rec["VFLOW"] + "\\n";\n}\nargs.setArg("RECORD_LIST", resultText);\n\nargs.sendTableToClent({\n title : "æµé",\n columns : [\n {"title":"æ¶é´", "name":"OTIME"},\n {"title":"æ°´å", "name":"FACT_NAME"},\n {"title":"æµé", "name":"VFLOW"}\n ],\n\n recs : recs\n});\n\nargs.sendChartToClient({\n title : "çµé",\n col_time : "OTIME",\n col_name : "FACT_NAME",\n col_value: "VPOWER",\n recs : recs\n});\nargs.sendKnowledgeToClient({\n result : args.getArg("num1") + " + " + args.getArg("num2") + "=" + args.getArg("V")\n});', |
| | | language: ['text', 'javascript'], |
| | | defaultLanguage: 'javascript', |
| | | }, |
| | |
| | | ], |
| | | }; |
| | | break; |
| | | |
| | | case NodeType.N8n: |
| | | data = { |
| | | ...data, |
| | | description: 'æ§è¡n8n工使µã', |
| | | [VueFlowConstant.GROUP_PARAMS_KEY]: [ |
| | | { |
| | | name: '工使µID', |
| | | [VueFlowConstant.PARAMS_KEY]: [ |
| | | { |
| | | key: 'n8n_flow_id', |
| | | type: 'n8n_flow_id', |
| | | required: true, |
| | | value: { type: 'input', label: '', value: '' }, |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | name: 'å
¥å', |
| | | [VueFlowConstant.PARAMS_KEY]: [ |
| | | { |
| | | key: 'n8n_input', |
| | | type: 'n8n_input', |
| | | value: { |
| | | type: 'json', |
| | | value: {}, |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | { |
| | | name: 'åºå', |
| | | [VueFlowConstant.PARAMS_KEY]: [ |
| | | { |
| | | key: 'n8n_output', |
| | | type: 'n8n_output', |
| | | required: true, |
| | | value: { type: 'input', label: '', value: '' }, |
| | | }, |
| | | ], |
| | | }, |
| | | // { |
| | | // name: 'æ§è¡ä»£ç ', |
| | | // [VueFlowConstant.PARAMS_KEY]: [ |
| | | // { |
| | | // key: 'code', |
| | | // type: 'code', |
| | | // required: true, |
| | | // value: `from lib.system import *\n\nargJson = readArgJson()\nrestult = argJson['num1'] + argJson['num2']\nwriteResultText(str(restult))`, |
| | | // language: ['python'], |
| | | // defaultLanguage: 'python', |
| | | // }, |
| | | // ], |
| | | // }, |
| | | ], |
| | | }; |
| | | break; |
| | | case NodeType.TextResource: |
| | | data = { |
| | | ...data, |
| | |
| | | class: 'bg-[#0062be] !p-1', |
| | | }, |
| | | ], |
| | | |
| | | [ |
| | | NodeType.TextResource, |
| | | { |
| | |
| | | class: 'bg-[#98fb98] ', |
| | | }, |
| | | ], |
| | | |
| | | [ |
| | | NodeType.N8n, |
| | | { |
| | | type: NodeType.N8n, |
| | | title: nodeTypeMap[NodeType.N8n], |
| | | icon: 'didaima', |
| | | fontSize: '18', |
| | | class: 'bg-[#0062be] !p-1', |
| | | }, |
| | | ], |
| | | ]); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <NodeBasicLayout |
| | | v-model:title="data.title" |
| | | :type="NodeType.N8n" |
| | | :style="{ width: '320px' }" |
| | | :showOffset="false" |
| | | :description="data.description" |
| | | :isViewMode="isViewMode" |
| | | > |
| | | <Handle :id="targetHandleId" type="target" :position="Position.Left" /> |
| | | <el-form ref="formRef" :model="data" :rules="formRules" label-position="right" label-width="60px" :show-message="false"> |
| | | <FieldLayout :title="workflow.name" required> |
| | | <!-- codeInput.params[0].value --> |
| | | <el-form-item prop="group_params.0.params.0.value.value" labelWidth="0"> |
| | | <el-select |
| | | class="!w-[220px] flex-0" |
| | | filterable |
| | | :disabled="isViewMode" |
| | | placeholder="工使µID" |
| | | v-model="workflow.params[0].value.value" |
| | | @change="workflowValueChange" |
| | | > |
| | | <el-option v-for="item in workflowList" :key="item.id" :value="item.id" :label="item.name"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </FieldLayout> |
| | | <FieldLayout :title="flowInput.name" v-if="Object.keys(flowInput.params[0].value.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> |
| | | </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-input |
| | | filterable |
| | | class="w-[120px] flex-0" |
| | | v-model="flowOutput.params[0].value.value" |
| | | placeholder="åæ°å" |
| | | :readonly="isViewMode" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </FieldLayout> |
| | | </el-form> |
| | | <Handle :id="sourceHandleId" type="source" :position="Position.Right" /> |
| | | </NodeBasicLayout> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import type { NodeProps } from '@vue-flow/core'; |
| | | 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 CodeEditDialog from './components/CodeEditDlg.vue'; |
| | | 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; |
| | | workflowList: any[]; |
| | | } |
| | | >(); |
| | | |
| | | const getFlowByID = (id: string) => { |
| | | return props.workflowList.find((item) => item.id === id); |
| | | }; |
| | | |
| | | 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 = {}; |
| | | if (!webhookNode) { |
| | | return; |
| | | } |
| | | |
| | | // Get path parameter from webhook node |
| | | const path = webhookNode?.parameters?.path; |
| | | if (path) { |
| | | // Parse path parameters from path string |
| | | const pathParams = path.match(/\/:([^\/]+)/g)?.map((p) => p.substring(2)) || []; |
| | | console.log('ð ~ pathParams:', pathParams); |
| | | // 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<{ |
| | | (e: 'register', data: { validateForm: () => Promise<{ isValid: boolean; invalidFields?: any }> }): void; |
| | | }>(); |
| | | const node = useNode(); |
| | | const targetHandleId = ref(VueFlowHelper.getHandleId(node.node, 'target')); |
| | | const sourceHandleId = ref(VueFlowHelper.getHandleId(node.node, 'source')); |
| | | const data = ref(node.node.data); |
| | | const workflow = ref(VueFlowHelper.getGroupParam(data.value, 0)); |
| | | const flowInput = ref(VueFlowHelper.getGroupParam(data.value, 1)); |
| | | const flowOutput = ref(VueFlowHelper.getGroupParam(data.value, 2)); |
| | | |
| | | const formRef = ref(); |
| | | const formRules = ref({ |
| | | 'group_params.0.params.0.value.value': [{ required: true, message: 'è¯·éæ©å·¥ä½æµ', trigger: 'blur' }], |
| | | // 'group_params.1.params.0.value.value': [{ required: true, message: '请è¾å
¥åºå', trigger: 'blur' }], |
| | | // 'group_params.2.params.0.value': [{ required: true, message: '请è¾å
¥æ§è¡ä»£ç ', trigger: 'blur' }], |
| | | }); |
| | | |
| | | // 注åèç¹å®ä¾ |
| | | onMounted(() => { |
| | | emit('register', { |
| | | validateForm: validateForm(formRef) as any, |
| | | }); |
| | | }); |
| | | </script> |
| | |
| | | Func = 'func', |
| | | Code = 'code', |
| | | PythonCode = 'python_code', |
| | | N8n = 'n8n', |
| | | |
| | | TextResource = 'text_resource', |
| | | Analysis = 'analysis', |
| | |
| | | [NodeType.Func]: 'æ§è¡åè½', |
| | | [NodeType.Code]: '代ç ', |
| | | [NodeType.PythonCode]: 'python代ç ', |
| | | |
| | | [NodeType.N8n]: 'n8nèç¹', |
| | | [NodeType.TextResource]: 'ææ¬èµæº', |
| | | [NodeType.Analysis]: 'åæ', |
| | | }; |