From d4a23472b0c7ffc8f918de253d32f65ebed7f757 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 14 Oct 2025 14:16:12 +0800 Subject: [PATCH 01/89] =?UTF-8?q?style(flowEditor):=20=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E4=BA=A4=E4=BA=92=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - actionBar的按钮样式修改 - nodeEditModal取消自动聚焦 --- src/pages/flowEditor/components/actionBar.tsx | 1 + src/pages/flowEditor/components/nodeEditModal.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/src/pages/flowEditor/components/actionBar.tsx b/src/pages/flowEditor/components/actionBar.tsx index 0954743..99d9c88 100644 --- a/src/pages/flowEditor/components/actionBar.tsx +++ b/src/pages/flowEditor/components/actionBar.tsx @@ -67,6 +67,7 @@ const ActionBar: React.FC = ({ icon={} onClick={onUndo} disabled={!canUndo} + status='danger' style={{ padding: '0 8px', backgroundColor: '#fff' }} > 撤销 diff --git a/src/pages/flowEditor/components/nodeEditModal.tsx b/src/pages/flowEditor/components/nodeEditModal.tsx index 25630ca..2163ac9 100644 --- a/src/pages/flowEditor/components/nodeEditModal.tsx +++ b/src/pages/flowEditor/components/nodeEditModal.tsx @@ -98,6 +98,7 @@ const NodeEditModal: React.FC = ({ mask={false} maskClosable={false} footer={null} + focusLock={false} getPopupContainer={() => popupContainer?.current || document.body} onOk={handleSave} onCancel={isDelete ? handleClose : handleSave} From 1395bb735b4cc397f44dbf4926c92b8baf39aefd Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 14 Oct 2025 14:49:57 +0800 Subject: [PATCH 02/89] =?UTF-8?q?refactor(flowEditor)!:=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E7=BC=96=E8=BE=91=E5=99=A8=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 FlowEditorContent 组件拆分为独立的 FlowEditorMain 组件 - 提取状态管理逻辑到 useFlowEditorState 自定义 Hook - 提取回调函数到 useFlowCallbacks 自定义 Hook - 移除临时事件列表数据引用 - 优化组件间数据传递和事件处理 - 清理未使用的导入和组件引用 - 统一节点类型管理方式 BREAKING CHANGE: 整体结构重构,更新后的单文件逻辑不在使用,但整体业务逻辑不变 --- .../components/EventListenEditor.tsx | 3 +- .../components/EventSendEditor.tsx | 3 +- src/hooks/useFlowCallbacks.ts | 696 + src/hooks/useFlowEditorState.ts | 68 + src/pages/flowEditor/FlowEditorMain.tsx | 340 + src/pages/flowEditor/index.tsx | 1092 +- src/pages/flowEditor/test/exampleFlowData.ts | 20008 ---------------- 7 files changed, 1237 insertions(+), 20973 deletions(-) create mode 100644 src/hooks/useFlowCallbacks.ts create mode 100644 src/hooks/useFlowEditorState.ts create mode 100644 src/pages/flowEditor/FlowEditorMain.tsx delete mode 100644 src/pages/flowEditor/test/exampleFlowData.ts diff --git a/src/components/FlowEditor/nodeEditors/components/EventListenEditor.tsx b/src/components/FlowEditor/nodeEditors/components/EventListenEditor.tsx index ac880ea..b588a06 100644 --- a/src/components/FlowEditor/nodeEditors/components/EventListenEditor.tsx +++ b/src/components/FlowEditor/nodeEditors/components/EventListenEditor.tsx @@ -3,10 +3,9 @@ import { NodeEditorProps } from '@/components/FlowEditor/nodeEditors'; import { Typography } from '@arco-design/web-react'; import { IconUnorderedList } from '@arco-design/web-react/icon'; import EventSelect from './EventSelect'; -import { tempEventList } from '@/pages/flowEditor/test/exampleFlowData'; const EventListenEditor: React.FC = ({ nodeData, updateNodeData }) => { - const [eventList, setEventList] = useState(tempEventList); + const [eventList, setEventList] = useState(); return ( <> diff --git a/src/components/FlowEditor/nodeEditors/components/EventSendEditor.tsx b/src/components/FlowEditor/nodeEditors/components/EventSendEditor.tsx index d2e7220..8606ebf 100644 --- a/src/components/FlowEditor/nodeEditors/components/EventSendEditor.tsx +++ b/src/components/FlowEditor/nodeEditors/components/EventSendEditor.tsx @@ -3,10 +3,9 @@ import { NodeEditorProps } from '@/components/FlowEditor/nodeEditors'; import { Typography } from '@arco-design/web-react'; import { IconUnorderedList } from '@arco-design/web-react/icon'; import EventSelect from '@/components/FlowEditor/nodeEditors/components/EventSelect'; -import { tempEventList } from '@/pages/flowEditor/test/exampleFlowData'; const EventSendEditor: React.FC = ({ nodeData, updateNodeData }) => { - const [eventList, setEventList] = useState(tempEventList); + const [eventList, setEventList] = useState(); return ( <> 输入参数 diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts new file mode 100644 index 0000000..32f8f82 --- /dev/null +++ b/src/hooks/useFlowCallbacks.ts @@ -0,0 +1,696 @@ +import React, { useCallback } from 'react'; +import { + applyNodeChanges, + applyEdgeChanges, + addEdge, + reconnectEdge, + Node, + Edge +} from '@xyflow/react'; +import { setMainFlow } from '@/api/appRes'; +import { getUserToken } from '@/api/user'; +import { Message } from '@arco-design/web-react'; +import { nodeTypeMap, registerNodeType } from '@/components/FlowEditor/node'; +import { convertFlowData, revertFlowData } from '@/utils/convertFlowData'; +import { localNodeData } from '@/pages/flowEditor/sideBar/config/localNodeData'; +import { defaultNodeTypes } from '@/components/FlowEditor/node/types/defaultType'; +import useWebSocket from '@/hooks/useWebSocket'; +import { useAlignmentGuidelines } from '@/hooks/useAlignmentGuidelines'; +import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode'; +import BasicNode from '@/components/FlowEditor/node/basicNode/BasicNode'; +import { updateCanvasDataMap } from '@/store/ideContainer'; + +import { Dispatch } from 'redux'; + +export const useFlowCallbacks = ( + nodes: Node[], + setNodes: React.Dispatch>, + edges: Edge[], + setEdges: React.Dispatch>, + reactFlowInstance: any, + canvasDataMap: any, + dispatch: Dispatch, + updateCanvasDataMapDebounced: ( + dispatch: Dispatch, + canvasDataMap: any, + id: string, + nodes: Node[], + edges: Edge[] + ) => void, + initialData: any, + historyTimeoutRef: React.MutableRefObject, + setHistoryInitialized: React.Dispatch>, + editingNode: Node | null, + setEditingNode: React.Dispatch>, + setIsEditModalOpen: React.Dispatch>, + edgeForNodeAdd: Edge | null, + setEdgeForNodeAdd: React.Dispatch>, + positionForNodeAdd: { x: number, y: number } | null, + setPositionForNodeAdd: React.Dispatch>, + setIsDelete: React.Dispatch>, + setIsRunning: React.Dispatch> +) => { + const { getGuidelines, clearGuidelines } = useAlignmentGuidelines(); + + // 获取handle类型 (api或data) + const getHandleType = (handleId: string, nodeParams: any) => { + // 检查是否为api类型的handle + const apiOuts = nodeParams.apiOuts || []; + const apiIns = nodeParams.apiIns || []; + + if (apiOuts.some((api: any) => (api.name || api.id) === handleId) || + apiIns.some((api: any) => (api.name || api.id) === handleId)) { + return 'api'; + } + + // 检查是否为data类型的handle + const dataOuts = nodeParams.dataOuts || []; + const dataIns = nodeParams.dataIns || []; + + if (dataOuts.some((data: any) => (data.name || data.id) === handleId) || + dataIns.some((data: any) => (data.name || data.id) === handleId)) { + return 'data'; + } + + // 默认为data类型 + return 'data'; + }; + + // 验证数据类型是否匹配 + const validateDataType = (sourceNode: defaultNodeTypes, targetNode: defaultNodeTypes, sourceHandleId: string, targetHandleId: string) => { + const sourceParams = sourceNode.data?.parameters || {}; + const targetParams = targetNode.data?.parameters || {}; + + // 获取源节点的输出参数 + let sourceDataType = ''; + const sourceApiOuts = sourceParams.apiOuts || []; + const sourceDataOuts = sourceParams.dataOuts || []; + + // 查找源handle的数据类型 + const sourceApi = sourceApiOuts.find((api: any) => api.name === sourceHandleId); + const sourceData = sourceDataOuts.find((data: any) => data.name === sourceHandleId); + + if (sourceApi) { + sourceDataType = sourceApi.dataType || ''; + } + else if (sourceData) { + sourceDataType = sourceData.dataType || ''; + } + + // 获取目标节点的输入参数 + let targetDataType = ''; + const targetApiIns = targetParams.apiIns || []; + const targetDataIns = targetParams.dataIns || []; + + // 查找目标handle的数据类型 + const targetApi = targetApiIns.find((api: any) => api.name === targetHandleId); + const targetData = targetDataIns.find((data: any) => data.name === targetHandleId); + + if (targetApi) { + targetDataType = targetApi.dataType || ''; + } + else if (targetData) { + targetDataType = targetData.dataType || ''; + } + + // 如果任一数据类型为空,则允许连接 + if (!sourceDataType || !targetDataType) { + return true; + } + + // 比较数据类型是否匹配 + return sourceDataType === targetDataType; + }; + + // 修改 onNodesChange 函数,添加防抖机制 + const onNodesChange = useCallback( + (changes: any) => { + const newNodes = applyNodeChanges(changes, nodes); + setNodes(newNodes); + // 如果需要在节点变化时执行某些操作,可以在这里添加 + + // 只有当变化是节点位置变化时才不立即记录历史 + const isPositionChange = changes.some((change: any) => + change.type === 'position' && change.dragging === false + ); + + // 如果是位置变化结束或者不是位置变化,则记录历史 + if (isPositionChange || !changes.some((change: any) => change.type === 'position')) { + // 清除之前的定时器 + if (historyTimeoutRef.current) { + clearTimeout(historyTimeoutRef.current); + } + + // 设置新的定时器,延迟记录历史记录 + historyTimeoutRef.current = setTimeout(() => { + const event = new CustomEvent('takeSnapshot', { + detail: { nodes: [...newNodes], edges: [...edges] } + }); + document.dispatchEvent(event); + }, 100); + } + }, + [nodes, edges] + ); + + // 修改 onEdgesChange 函数 + const onEdgesChange = useCallback( + (changes: any) => { + const newEdges = applyEdgeChanges(changes, edges); + setEdges(newEdges); + // 如果需要在边变化时执行某些操作,可以在这里添加 + + // 边的变化立即记录历史 + const event = new CustomEvent('takeSnapshot', { + detail: { nodes: [...nodes], edges: [...newEdges] } + }); + document.dispatchEvent(event); + }, + [edges, nodes] + ); + + const onNodesDelete = useCallback((deletedNodes: any) => { + setIsDelete(true); + }, []); + + // 修改 onConnect 函数 + const onConnect = useCallback( + (params: any) => { + // 获取源节点和目标节点 + const sourceNode = nodes.find(node => node.id === params.source); + const targetNode = nodes.find(node => node.id === params.target); + + // 如果找不到节点,不创建连接 + if (!sourceNode || !targetNode) { + return; + } + + // 获取源节点和目标节点的参数信息 + const sourceParams = sourceNode.data?.parameters || {}; + const targetParams = targetNode.data?.parameters || {}; + console.log(sourceParams, targetParams, params); + + // 获取源handle和目标handle的类型 (api或data) + const sourceHandleType = getHandleType(params.sourceHandle, sourceParams); + const targetHandleType = getHandleType(params.targetHandle, targetParams); + + // 验证连接类型是否匹配 (api只能连api, data只能连data) + if (sourceHandleType !== targetHandleType) { + console.warn('连接类型不匹配: ', sourceHandleType, targetHandleType); + return; + } + + // 验证数据类型是否匹配 + if (!validateDataType(sourceNode, targetNode, params.sourceHandle, params.targetHandle)) { + console.warn('数据类型不匹配'); + return; + } + + // 如果验证通过,创建连接 + setEdges((edgesSnapshot: Edge[]) => { + const newEdges = addEdge({ ...params, type: 'custom' }, edgesSnapshot); + + // 连接建立后记录历史 + setTimeout(() => { + const event = new CustomEvent('takeSnapshot', { + detail: { nodes: [...nodes], edges: [...newEdges] } + }); + document.dispatchEvent(event); + }, 0); + + return newEdges; + }); + }, + [nodes] + ); + + // 边重新连接处理 + const onReconnect = useCallback( + (oldEdge: Edge, newConnection: any) => { + // 获取源节点和目标节点 + const sourceNode = nodes.find(node => node.id === newConnection.source); + const targetNode = nodes.find(node => node.id === newConnection.target); + + // 如果找不到节点,不创建连接 + if (!sourceNode || !targetNode) { + return; + } + + // 获取源节点和目标节点的参数信息 + const sourceParams = sourceNode.data?.parameters || {}; + const targetParams = targetNode.data?.parameters || {}; + + // 获取源handle和目标handle的类型 (api或data) + const sourceHandleType = getHandleType(newConnection.sourceHandle, sourceParams); + const targetHandleType = getHandleType(newConnection.targetHandle, targetParams); + + // 验证连接类型是否匹配 (api只能连api, data只能连data) + if (sourceHandleType !== targetHandleType) { + console.warn('连接类型不匹配: ', sourceHandleType, targetHandleType); + return; + } + + // 验证数据类型是否匹配 + if (!validateDataType(sourceNode, targetNode, newConnection.sourceHandle, newConnection.targetHandle)) { + console.warn('数据类型不匹配'); + return; + } + + // 如果验证通过,重新连接 + setEdges((els) => reconnectEdge(oldEdge, newConnection, els)); + }, + [nodes] + ); + + const onDragOver = useCallback((event: React.DragEvent) => { + event.preventDefault(); + event.dataTransfer.dropEffect = 'move'; + }, []); + + // 侧边栏节点实例 + // 修改 onDrop 函数 + const onDrop = useCallback( + (event: React.DragEvent) => { + event.preventDefault(); + + if (!reactFlowInstance) return; + + const callBack = event.dataTransfer.getData('application/reactflow'); + const nodeData = JSON.parse(callBack); + if (typeof nodeData.nodeType === 'undefined' || !nodeData.nodeType) { + return; + } + + const position = reactFlowInstance.screenToFlowPosition({ + x: event.clientX, + y: event.clientY + }); + + const newNode = { + id: `${nodeData.nodeType}-${Date.now()}`, + type: nodeData.nodeType, + position, + data: { ...nodeData.data, title: nodeData.nodeName, type: nodeData.nodeType } + }; + + // 将未定义的节点动态追加进nodeTypes + const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); + // 目前默认添加的都是系统组件/本地组件 + if (!nodeMap.includes(nodeData.nodeType)) { + registerNodeType(nodeData.nodeType, LocalNode, nodeData.nodeName); + } + + setNodes((nds: Node[]) => { + const newNodes = nds.concat(newNode); + + // 添加节点后记录历史 + setTimeout(() => { + const event = new CustomEvent('takeSnapshot', { + detail: { nodes: [...newNodes], edges: [...edges] } + }); + document.dispatchEvent(event); + }, 0); + + return newNodes; + }); + }, + [reactFlowInstance, edges] + ); + + const onNodeDrag = useCallback( + (_: any, node: Node) => { + // 获取对齐线 + getGuidelines(node, nodes); + }, + [nodes, getGuidelines] + ); + + // 节点拖拽结束处理 + const onNodeDragStop = useCallback(() => { + // 清除对齐线 + clearGuidelines(); + }, [clearGuidelines]); + + // 初始化画布数据 + const initializeCanvasData = useCallback(() => { + if (canvasDataMap[initialData?.id]) { + const { edges, nodes } = canvasDataMap[initialData?.id]; + setNodes(nodes); + setEdges(edges); + } + else { + // 首次进入 + const { nodes: convertedNodes, edges: convertedEdges } = convertFlowData(initialData); + // 为所有边添加类型 + const initialEdges: Edge[] = convertedEdges.map(edge => ({ + ...edge, + type: 'custom' + })); + + setNodes(convertedNodes); + setEdges(initialEdges); + + if (initialData?.id) { + dispatch(updateCanvasDataMap({ + ...canvasDataMap, + [initialData.id]: { nodes: convertedNodes, edges: initialEdges } + })); + } + } + + // 标记历史记录已初始化 + setHistoryInitialized(true); + }, [initialData, canvasDataMap]); + + // 实时更新 canvasDataMap + const updateCanvasDataMapEffect = useCallback(() => { + if (initialData?.id) { + updateCanvasDataMapDebounced(dispatch, canvasDataMap, initialData.id, nodes, edges); + } + + // 清理函数,在组件卸载时取消防抖 + return () => { + // 取消防抖函数 + }; + }, [nodes, edges, initialData?.id, dispatch, canvasDataMap]); + + // 关闭编辑弹窗 + const closeEditModal = useCallback(() => { + setIsEditModalOpen(false); + setEditingNode(null); + }, []); + + // 保存节点编辑 + const saveNodeEdit = useCallback((updatedData: any) => { + console.log('updatedData:', updatedData); + const updatedNodes = nodes.map((node) => { + if (node.id === editingNode?.id) { + return { + ...node, + data: { ...node.data, ...updatedData } + }; + } + return node; + }); + + setNodes(updatedNodes); + closeEditModal(); + + // TODO 如果需要在节点编辑后立即保存到服务器,可以调用保存函数 + // saveFlowDataToServer(); + }, [nodes, editingNode, closeEditModal]); + + // 修改删除节点函数 + const deleteNode = useCallback((node: Node) => { + setNodes((nds: Node[]) => nds.filter((n) => n.id !== node.id)); + setEdges((eds: Edge[]) => eds.filter((e) => e.source !== node.id && e.target !== node.id)); + + // 删除节点后记录历史 + setTimeout(() => { + const event = new CustomEvent('takeSnapshot', { + detail: { + nodes: [...nodes.filter((n) => n.id !== node.id)], + edges: [...edges.filter((e) => e.source !== node.id && e.target !== node.id)] + } + }); + document.dispatchEvent(event); + }, 0); + }, [nodes, edges]); + + // 修改删除边函数 + const deleteEdge = useCallback((edge: Edge) => { + setEdges((eds: Edge[]) => eds.filter((e) => e.id !== edge.id)); + + // 删除边后记录历史 + setTimeout(() => { + const event = new CustomEvent('takeSnapshot', { + detail: { + nodes: [...nodes], + edges: [...edges.filter((e) => e.id !== edge.id)] + } + }); + document.dispatchEvent(event); + }, 0); + }, [nodes, edges]); + + // 编辑节点 + const editNode = useCallback((node: Node) => { + setEditingNode(node); + setIsEditModalOpen(true); + }, []); + + // 编辑边 + const editEdge = useCallback((edge: Edge) => { + // 这里可以实现边编辑逻辑 + console.log('编辑边:', edge); + }, []); + + // 复制节点 + const copyNode = useCallback((node: Node) => { + // 这里可以实现节点复制逻辑 + console.log('复制节点:', node); + }, []); + + // 在边上添加节点的具体实现 + // 修改 addNodeOnEdge 函数 + const addNodeOnEdge = useCallback((nodeType: string, node: any) => { + if (!edgeForNodeAdd || !reactFlowInstance) return; + + // 查找节点定义 + const nodeDefinition = localNodeData.find(n => n.nodeType === nodeType) || node; + if (!nodeDefinition) return; + + // 获取源节点和目标节点 + const sourceNode = nodes.find(n => n.id === edgeForNodeAdd.source); + const targetNode = nodes.find(n => n.id === edgeForNodeAdd.target); + + if (!sourceNode || !targetNode) return; + + // 计算中点位置 + const position = { + x: (sourceNode.position.x + targetNode.position.x) / 2, + y: (sourceNode.position.y + targetNode.position.y) / 2 + }; + + // 创建新节点 + const newNode = { + id: `${nodeType}-${Date.now()}`, + type: nodeType, + position, + data: { + ...nodeDefinition.data, + title: nodeDefinition.nodeName, + type: nodeType + } + }; + + // 将未定义的节点动态追加进nodeTypes + const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); + if (!nodeMap.includes(nodeType)) { + registerNodeType(nodeType, nodeType === 'BASIC' ? BasicNode : LocalNode, nodeDefinition.nodeName); + } + + // 添加新节点 + setNodes((nds: Node[]) => [...nds, newNode]); + + // 删除旧边 + setEdges((eds: Edge[]) => eds.filter(e => e.id !== edgeForNodeAdd.id)); + + // 创建新边: source -> new node, new node -> target + const newEdges = [ + ...edges.filter(e => e.id !== edgeForNodeAdd.id), + { + id: `e${edgeForNodeAdd.source}-${newNode.id}`, + source: edgeForNodeAdd.source, + target: newNode.id, + type: 'custom' + }, + { + id: `e${newNode.id}-${edgeForNodeAdd.target}`, + source: newNode.id, + target: edgeForNodeAdd.target, + type: 'custom' + } + ]; + + setEdges(newEdges); + + // 关闭菜单 + setEdgeForNodeAdd(null); + setPositionForNodeAdd(null); + + // 添加节点后记录历史 + setTimeout(() => { + const event = new CustomEvent('takeSnapshot', { + detail: { + nodes: [...nodes, newNode], + edges: [...newEdges] + } + }); + document.dispatchEvent(event); + }, 0); + }, [edgeForNodeAdd, nodes, reactFlowInstance, edges]); + + // 在画布上添加节点 + // 修改 addNodeOnPane 函数 + const addNodeOnPane = useCallback((nodeType: string, position: { x: number; y: number }, node?: any) => { + if (!reactFlowInstance) return; + + // 查找节点定义 + const nodeDefinition = localNodeData.find(n => n.nodeType === nodeType) || node; + if (!nodeDefinition) return; + + // 创建新节点 + const newNode = { + id: `${nodeType}-${Date.now()}`, + type: nodeType, + position, + data: { + ...nodeDefinition.data, + title: nodeDefinition.nodeName, + type: nodeType + } + }; + + // 将未定义的节点动态追加进nodeTypes + const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); + // 目前默认添加的都是系统组件/本地组件 + if (!nodeMap.includes(nodeType)) { + registerNodeType(nodeType, nodeType === 'BASIC' ? BasicNode : LocalNode, nodeDefinition.nodeName); + } + + setNodes((nds: Node[]) => { + const newNodes = [...nds, newNode]; + + // 添加节点后记录历史 + setTimeout(() => { + const event = new CustomEvent('takeSnapshot', { + detail: { nodes: [...newNodes], edges: [...edges] } + }); + document.dispatchEvent(event); + }, 0); + + return newNodes; + }); + }, [reactFlowInstance, edges]); + + // 处理添加节点的统一方法 + const handleAddNode = useCallback((nodeType: string, node: any) => { + // 如果是通过边添加节点 + if (edgeForNodeAdd) { + addNodeOnEdge(nodeType, node); + } + // 如果是通过画布添加节点 + else if (positionForNodeAdd) { + addNodeOnPane(nodeType, positionForNodeAdd, node); + } + + // 清除状态 + setEdgeForNodeAdd(null); + setPositionForNodeAdd(null); + }, [edgeForNodeAdd, positionForNodeAdd, addNodeOnEdge, addNodeOnPane]); + + // 保存所有节点和边数据到服务器 + const saveFlowDataToServer = useCallback(async () => { + try { + // 转换会原始数据类型 + const revertedData = revertFlowData(nodes, edges); + console.log('initialData:', initialData); + + const res: any = await setMainFlow(revertedData, initialData.id); + if (res.code === 200) { + Message.success('保存成功'); + } + else { + Message.error(res.message); + } + } catch (error) { + console.error('Error saving flow data:', error); + Message.error('保存失败'); + } + }, [nodes, edges]); + + // 初始化WebSocket hook + const ws = useWebSocket({ + onOpen: () => { + console.log('WebSocket连接已建立'); + Message.success('运行已启动'); + }, + onClose: () => { + console.log('WebSocket连接已关闭'); + setIsRunning(false); + Message.info('运行已停止'); + }, + onError: (event) => { + console.error('WebSocket错误:', event); + setIsRunning(false); + Message.error('运行连接出错'); + }, + onMessage: (event) => { + console.log('收到WebSocket消息:', event.data); + // 这里可以处理从后端收到的消息,例如日志更新等 + } + }); + + // 修改运行处理函数 + const handleRun = useCallback(async (running: boolean) => { + if (running) { + // 启动运行 + const res = await getUserToken(); + const token = res.data; + const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'; + let wsApi = `${protocol}://${window.location.host}/ws/v1/bpms-runtime`; + if (window.location.host.includes('localhost')) { + // WS_API = `wss://${host}/ws/v1/bpms-runtime`; + wsApi = `ws://api.myserver.com:4121/ws/v1/bpms-runtime`; + } + const uri = `${wsApi}?x-auth0-token=${token}`; + ws.connect(uri); + setIsRunning(true); + } + else { + // 停止运行 + ws.disconnect(); + setIsRunning(false); + } + }, [initialData?.id, ws]); + + return { + // Event handlers + onNodesChange, + onEdgesChange, + onConnect, + onReconnect, + onDragOver, + onDrop, + onNodeDrag, + onNodeDragStop, + onNodesDelete, + + // Menu handlers + closeEditModal, + saveNodeEdit, + deleteNode, + deleteEdge, + editNode, + editEdge, + copyNode, + + // Node operations + addNodeOnEdge, + addNodeOnPane, + handleAddNode, + + // Initialization + initializeCanvasData, + updateCanvasDataMapEffect, + + // Actions + saveFlowDataToServer, + handleRun, + + // Utilities + getHandleType, + validateDataType + }; +}; \ No newline at end of file diff --git a/src/hooks/useFlowEditorState.ts b/src/hooks/useFlowEditorState.ts new file mode 100644 index 0000000..510a8f8 --- /dev/null +++ b/src/hooks/useFlowEditorState.ts @@ -0,0 +1,68 @@ +import { useState, useRef } from 'react'; +import { Node, Edge } from '@xyflow/react'; +import { debounce } from 'lodash'; +import { useSelector, useDispatch } from 'react-redux'; +import { updateCanvasDataMap } from '@/store/ideContainer'; + +export const useFlowEditorState = (initialData?: any) => { + const [nodes, setNodes] = useState([]); + const [edges, setEdges] = useState([]); + const { canvasDataMap } = useSelector((state: any) => state.ideContainer); + const dispatch = useDispatch(); + + // 添加编辑弹窗相关状态 + const [editingNode, setEditingNode] = useState(null); + const [isEditModalOpen, setIsEditModalOpen] = useState(false); + const [isDelete, setIsDelete] = useState(false); + + // 添加节点选择弹窗状态 + const [edgeForNodeAdd, setEdgeForNodeAdd] = useState(null); + const [positionForNodeAdd, setPositionForNodeAdd] = useState<{ x: number, y: number } | null>(null); + + // 添加运行状态 + const [isRunning, setIsRunning] = useState(false); + + // 在组件顶部添加历史记录相关状态 + const [historyInitialized, setHistoryInitialized] = useState(false); + const historyTimeoutRef = useRef(null); + + const updateCanvasDataMapDebounced = useRef( + debounce((dispatch: Function, canvasDataMap: any, id: string, nodes: Node[], edges: Edge[]) => { + dispatch(updateCanvasDataMap({ + ...canvasDataMap, + [id]: { nodes, edges } + })); + }, 500) + ).current; + + return { + // State values + nodes, + setNodes, + edges, + setEdges, + canvasDataMap, + editingNode, + setEditingNode, + isEditModalOpen, + setIsEditModalOpen, + isDelete, + setIsDelete, + edgeForNodeAdd, + setEdgeForNodeAdd, + positionForNodeAdd, + setPositionForNodeAdd, + isRunning, + setIsRunning, + historyInitialized, + setHistoryInitialized, + historyTimeoutRef, + updateCanvasDataMapDebounced, + + // Redux + dispatch, + + // Initial data + initialData: initialData + }; +}; \ No newline at end of file diff --git a/src/pages/flowEditor/FlowEditorMain.tsx b/src/pages/flowEditor/FlowEditorMain.tsx new file mode 100644 index 0000000..6ae58f1 --- /dev/null +++ b/src/pages/flowEditor/FlowEditorMain.tsx @@ -0,0 +1,340 @@ +import React, { useEffect } from 'react'; +import { + ReactFlow, + Background, + Panel, + SelectionMode, + ConnectionLineType, + Node, + Edge, + OnNodesChange, + OnEdgesChange, + OnConnect, + OnReconnect +} from '@xyflow/react'; +import '@xyflow/react/dist/style.css'; +import CustomEdge from './components/customEdge'; +import CustomConnectionLine from './components/customConnectionLine'; +import NodeContextMenu from './components/nodeContextMenu'; +import EdgeContextMenu from './components/edgeContextMenu'; +import PaneContextMenu from './components/paneContextMenu'; +import NodeEditModal from './components/nodeEditModal'; +import AddNodeMenu from './components/addNodeMenu'; +import ActionBar from './components/actionBar'; +import { useAlignmentGuidelines } from '@/hooks/useAlignmentGuidelines'; +import { useHistory } from './components/historyContext'; +import { NodeTypes } from '@xyflow/react'; + +const edgeTypes = { + custom: CustomEdge +}; + +interface FlowEditorMainProps { + nodes: Node[]; + edges: Edge[]; + nodeTypes: NodeTypes; + setNodes: React.Dispatch>; + setEdges: React.Dispatch>; + reactFlowInstance: any; + reactFlowWrapper: React.RefObject; + menu: any; + setMenu: React.Dispatch>; + editingNode: Node | null; + setEditingNode: React.Dispatch>; + isEditModalOpen: boolean; + setIsEditModalOpen: React.Dispatch>; + isDelete: boolean; + setIsDelete: React.Dispatch>; + edgeForNodeAdd: Edge | null; + setEdgeForNodeAdd: React.Dispatch>; + positionForNodeAdd: { x: number, y: number } | null; + setPositionForNodeAdd: React.Dispatch>; + isRunning: boolean; + setIsRunning: React.Dispatch>; + initialData: any; + canvasDataMap: any; + + // Callbacks + onNodesChange: OnNodesChange; + onEdgesChange: OnEdgesChange; + onConnect: OnConnect; + onReconnect: OnReconnect; + onDragOver: (event: React.DragEvent) => void; + onDrop: (event: React.DragEvent) => void; + onNodeDrag: (event: React.MouseEvent, node: Node) => void; + onNodeDragStop: () => void; + onNodeContextMenu: (event: React.MouseEvent, node: Node) => void; + onNodeDoubleClick: (event: React.MouseEvent, node: Node) => void; + onEdgeContextMenu: (event: React.MouseEvent, edge: Edge) => void; + onPaneContextMenu: (event: React.MouseEvent) => void; + onPaneClick: () => void; + closeEditModal: () => void; + saveNodeEdit: (updatedData: any) => void; + deleteNode: (node: Node) => void; + deleteEdge: (edge: Edge) => void; + editNode: (node: Node) => void; + editEdge: (edge: Edge) => void; + copyNode: (node: Node) => void; + addNodeOnEdge: (nodeType: string, node: any) => void; + addNodeOnPane: (nodeType: string, position: { x: number; y: number }, node?: any) => void; + handleAddNode: (nodeType: string, node: any) => void; + saveFlowDataToServer: () => void; + handleRun: (running: boolean) => void; +} + +const FlowEditorMain: React.FC = (props) => { + const { + nodes, + edges, + nodeTypes, + setNodes, + setEdges, + reactFlowInstance, + reactFlowWrapper, + menu, + setMenu, + editingNode, + setEditingNode, + isEditModalOpen, + setIsEditModalOpen, + isDelete, + setIsDelete, + edgeForNodeAdd, + setEdgeForNodeAdd, + positionForNodeAdd, + setPositionForNodeAdd, + isRunning, + initialData, + canvasDataMap, + onNodesChange, + onEdgesChange, + onConnect, + onReconnect, + onDragOver, + onDrop, + onNodeDrag, + onNodeDragStop, + onNodeContextMenu, + onNodeDoubleClick, + onEdgeContextMenu, + onPaneContextMenu, + onPaneClick, + closeEditModal, + saveNodeEdit, + deleteNode, + deleteEdge, + editNode, + editEdge, + copyNode, + addNodeOnEdge, + addNodeOnPane, + handleAddNode, + saveFlowDataToServer, + handleRun + } = props; + + const { getGuidelines, clearGuidelines, AlignmentGuides } = useAlignmentGuidelines(); + const { undo, redo, canUndo, canRedo } = useHistory(); + + // 监听键盘事件实现快捷键 + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + // Ctrl+Z 撤销 + if (e.ctrlKey && e.key === 'z' && !e.shiftKey && canUndo) { + e.preventDefault(); + undo(); + } + // Ctrl+Shift+Z 重做 + if (e.ctrlKey && e.shiftKey && e.key === 'Z' && canRedo) { + e.preventDefault(); + redo(); + } + // Ctrl+Y 重做 + if (e.ctrlKey && e.key === 'y' && canRedo) { + e.preventDefault(); + redo(); + } + }; + + document.addEventListener('keydown', handleKeyDown); + return () => { + document.removeEventListener('keydown', handleKeyDown); + }; + }, [undo, redo, canUndo, canRedo]); + + // 监听节点和边的变化以拍摄快照 + useEffect(() => { + // 获取 HistoryProvider 中的 takeSnapshot 方法 + const event = new CustomEvent('takeSnapshot', { + detail: { nodes: [...nodes], edges: [...edges] } + }); + document.dispatchEvent(event); + }, [nodes, edges]); + + return ( +
e.preventDefault()}> + { + setNodes((nds) => nds.filter((n) => !deleted.find((d) => d.id === n.id))); + }} + onNodesChange={onNodesChange} + onEdgesChange={onEdgesChange} + onConnect={onConnect} + onReconnect={onReconnect} + onDrop={onDrop} + onDragOver={onDragOver} + onNodeDrag={onNodeDrag} + connectionLineType={ConnectionLineType.SmoothStep} + connectionLineComponent={CustomConnectionLine} + onNodeDragStop={onNodeDragStop} + onNodeContextMenu={onNodeContextMenu} + onEdgeContextMenu={onEdgeContextMenu} + onNodeClick={onNodeDoubleClick} + onPaneClick={onPaneClick} + onPaneContextMenu={onPaneContextMenu} + onEdgeMouseEnter={(_event, edge) => { + setEdges((eds) => eds.map(e => { + if (e.id === edge.id) { + return { ...e, data: { ...e.data, hovered: true } }; + } + return e; + })); + }} + onEdgeMouseLeave={(_event, edge) => { + setEdges((eds) => eds.map(e => { + if (e.id === edge.id) { + return { ...e, data: { ...e.data, hovered: false } }; + } + return e; + })); + }} + fitView + selectionKeyCode={['Meta', 'Control']} + selectionMode={SelectionMode.Partial} + panOnDrag={[0, 1, 2]} // 支持多点触控平移 + zoomOnScroll={true} + zoomOnPinch={true} + panOnScrollSpeed={0.5} + > + + + + + + + + {/*节点右键上下文*/} + {menu && menu.type === 'node' && ( +
+ n.id === menu.id)!} + onDelete={deleteNode} + onEdit={editNode} + onCopy={copyNode} + /> +
+ )} + + {/*边右键上下文*/} + {menu && menu.type === 'edge' && ( +
+ e.id === menu.id)!} + onDelete={deleteEdge} + onEdit={editEdge} + onAddNode={(edge) => { + setEdgeForNodeAdd(edge); + setMenu(null); // 关闭上下文菜单 + }} + /> +
+ )} + + {/*画布右键上下文*/} + {menu && menu.type === 'pane' && ( +
+ { + addNodeOnPane(nodeType, position, node); + setMenu(null); // 关闭上下文菜单 + }} + /> +
+ )} + + {/*节点点击/节点编辑上下文*/} + + + {/*统一的添加节点菜单*/} + {(edgeForNodeAdd || positionForNodeAdd) && ( +
+ { + handleAddNode(nodeType, node); + // 关闭菜单 + setEdgeForNodeAdd(null); + setPositionForNodeAdd(null); + }} + position={positionForNodeAdd || undefined} + edgeId={edgeForNodeAdd?.id} + /> +
+ )} +
+ ); +}; + +export default FlowEditorMain; \ No newline at end of file diff --git a/src/pages/flowEditor/index.tsx b/src/pages/flowEditor/index.tsx index 327aaf1..50b4b7b 100644 --- a/src/pages/flowEditor/index.tsx +++ b/src/pages/flowEditor/index.tsx @@ -1,58 +1,23 @@ import React, { useState, useCallback, useRef, useEffect } from 'react'; import { - ReactFlow, - applyNodeChanges, - applyEdgeChanges, - addEdge, - reconnectEdge, - Background, - Controls, - Node, - Edge, ReactFlowProvider, useReactFlow, - EdgeTypes, - SelectionMode, useStoreApi, - Panel, - ConnectionLineType + Node, + Edge } from '@xyflow/react'; -import '@xyflow/react/dist/style.css'; import { useSelector, useDispatch } from 'react-redux'; -import { updateCanvasDataMap } from '@/store/ideContainer'; -import { debounce } from 'lodash'; -import { nodeTypeMap, nodeTypes, registerNodeType } from '@/components/FlowEditor/node'; +import { nodeTypes } from '@/components/FlowEditor/node'; import SideBar from './sideBar/sideBar'; -import { convertFlowData, revertFlowData } from '@/utils/convertFlowData'; -import { exampleFlowData } from '@/pages/flowEditor/test/exampleFlowData'; -import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode'; -import CustomEdge from './components/customEdge'; -import CustomConnectionLine from './components/customConnectionLine'; -import NodeContextMenu from './components/nodeContextMenu'; -import EdgeContextMenu from './components/edgeContextMenu'; -import PaneContextMenu from './components/paneContextMenu'; -import NodeEditModal from './components/nodeEditModal'; -import AddNodeMenu from './components/addNodeMenu'; -import ActionBar from './components/actionBar'; -import { defaultNodeTypes } from '@/components/FlowEditor/node/types/defaultType'; -import { localNodeData } from '@/pages/flowEditor/sideBar/config/localNodeData'; -import { useAlignmentGuidelines } from '@/hooks/useAlignmentGuidelines'; -import { setMainFlow } from '@/api/appRes'; -import { getUserToken } from '@/api/user'; -import { Message } from '@arco-design/web-react'; -import BasicNode from '@/components/FlowEditor/node/basicNode/BasicNode'; -import HistoryProvider, { useHistory } from './components/historyContext'; -import useWebSocket from '@/hooks/useWebSocket'; - -const edgeTypes: EdgeTypes = { - custom: CustomEdge -}; +import HistoryProvider from './components/historyContext'; +import FlowEditorMain from './FlowEditorMain'; +import { useFlowEditorState } from '@/hooks/useFlowEditorState'; +import { useFlowCallbacks } from '@/hooks/useFlowCallbacks'; const FlowEditorWithProvider: React.FC<{ initialData?: any, useDefault?: boolean }> = ({ initialData, useDefault }) => { return (
e.preventDefault()}> - {/**/}
@@ -60,9 +25,6 @@ const FlowEditorWithProvider: React.FC<{ initialData?: any, useDefault?: boolean }; const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean }> = ({ initialData, useDefault }) => { - const [nodes, setNodes] = useState([]); - const [edges, setEdges] = useState([]); - const { canvasDataMap } = useSelector(state => state.ideContainer); const reactFlowInstance = useReactFlow(); const reactFlowWrapper = useRef(null); const [menu, setMenu] = useState<{ @@ -73,385 +35,100 @@ const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean }> = ({ ini position?: { x: number; y: number }; } | null>(null); const store = useStoreApi(); - const dispatch = useDispatch(); - - // 添加编辑弹窗相关状态 - const [editingNode, setEditingNode] = useState(null); - const [isEditModalOpen, setIsEditModalOpen] = useState(false); - const [isDelete, setIsDelete] = useState(false); - - // 添加节点选择弹窗状态 - const [edgeForNodeAdd, setEdgeForNodeAdd] = useState(null); - const [positionForNodeAdd, setPositionForNodeAdd] = useState<{ x: number, y: number } | null>(null); - - const { getGuidelines, clearGuidelines, AlignmentGuides } = useAlignmentGuidelines(); - - const updateCanvasDataMapDebounced = useRef( - debounce((dispatch, canvasDataMap, id, nodes, edges) => { - dispatch(updateCanvasDataMap({ - ...canvasDataMap, - [id]: { nodes, edges } - })); - }, 500) - ).current; - - // 获取handle类型 (api或data) - const getHandleType = (handleId: string, nodeParams: any) => { - // 检查是否为api类型的handle - const apiOuts = nodeParams.apiOuts || []; - const apiIns = nodeParams.apiIns || []; - - if (apiOuts.some((api: any) => (api.name || api.id) === handleId) || - apiIns.some((api: any) => (api.name || api.id) === handleId)) { - return 'api'; - } - - // 检查是否为data类型的handle - const dataOuts = nodeParams.dataOuts || []; - const dataIns = nodeParams.dataIns || []; - - if (dataOuts.some((data: any) => (data.name || data.id) === handleId) || - dataIns.some((data: any) => (data.name || data.id) === handleId)) { - return 'data'; - } - - // 默认为data类型 - return 'data'; - }; - - // 验证数据类型是否匹配 - const validateDataType = (sourceNode: defaultNodeTypes, targetNode: defaultNodeTypes, sourceHandleId: string, targetHandleId: string) => { - const sourceParams = sourceNode.data?.parameters || {}; - const targetParams = targetNode.data?.parameters || {}; - - // 获取源节点的输出参数 - let sourceDataType = ''; - const sourceApiOuts = sourceParams.apiOuts || []; - const sourceDataOuts = sourceParams.dataOuts || []; - - // 查找源handle的数据类型 - const sourceApi = sourceApiOuts.find((api: any) => api.name === sourceHandleId); - const sourceData = sourceDataOuts.find((data: any) => data.name === sourceHandleId); - - if (sourceApi) { - sourceDataType = sourceApi.dataType || ''; - } - else if (sourceData) { - sourceDataType = sourceData.dataType || ''; - } - - // 获取目标节点的输入参数 - let targetDataType = ''; - const targetApiIns = targetParams.apiIns || []; - const targetDataIns = targetParams.dataIns || []; - - // 查找目标handle的数据类型 - const targetApi = targetApiIns.find((api: any) => api.name === targetHandleId); - const targetData = targetDataIns.find((data: any) => data.name === targetHandleId); - - if (targetApi) { - targetDataType = targetApi.dataType || ''; - } - else if (targetData) { - targetDataType = targetData.dataType || ''; - } - - // 如果任一数据类型为空,则允许连接 - if (!sourceDataType || !targetDataType) { - return true; - } - - // 比较数据类型是否匹配 - return sourceDataType === targetDataType; - }; - - // 在组件顶部添加历史记录相关状态 - const [historyInitialized, setHistoryInitialized] = useState(false); - const historyTimeoutRef = useRef(null); - - // 修改 onNodesChange 函数,添加防抖机制 - const onNodesChange = useCallback( - (changes: any) => { - const newNodes = applyNodeChanges(changes, nodes); - setNodes(newNodes); - // 如果需要在节点变化时执行某些操作,可以在这里添加 - onPaneClick(); - - // 只有当变化是节点位置变化时才不立即记录历史 - const isPositionChange = changes.some((change: any) => - change.type === 'position' && change.dragging === false - ); - - // 如果是位置变化结束或者不是位置变化,则记录历史 - if (isPositionChange || !changes.some((change: any) => change.type === 'position')) { - // 清除之前的定时器 - if (historyTimeoutRef.current) { - clearTimeout(historyTimeoutRef.current); - } - - // 设置新的定时器,延迟记录历史记录 - historyTimeoutRef.current = setTimeout(() => { - const event = new CustomEvent('takeSnapshot', { - detail: { nodes: [...newNodes], edges: [...edges] } - }); - document.dispatchEvent(event); - }, 100); - } - }, - [nodes, edges] - ); - - // 修改 onEdgesChange 函数 - const onEdgesChange = useCallback( - (changes: any) => { - const newEdges = applyEdgeChanges(changes, edges); - setEdges(newEdges); - // 如果需要在边变化时执行某些操作,可以在这里添加 - onPaneClick(); - - // 边的变化立即记录历史 - const event = new CustomEvent('takeSnapshot', { - detail: { nodes: [...nodes], edges: [...newEdges] } - }); - document.dispatchEvent(event); - }, - [edges, nodes] - ); - - const onNodesDelete = useCallback((deletedNodes) => { - setIsDelete(true); - closeEditModal(); - }, []); - - // 修改 onConnect 函数 - const onConnect = useCallback( - (params: any) => { - // 获取源节点和目标节点 - const sourceNode = nodes.find(node => node.id === params.source); - const targetNode = nodes.find(node => node.id === params.target); - - // 如果找不到节点,不创建连接 - if (!sourceNode || !targetNode) { - return; - } - - // 获取源节点和目标节点的参数信息 - const sourceParams = sourceNode.data?.parameters || {}; - const targetParams = targetNode.data?.parameters || {}; - console.log(sourceParams, targetParams, params); - - // 获取源handle和目标handle的类型 (api或data) - const sourceHandleType = getHandleType(params.sourceHandle, sourceParams); - const targetHandleType = getHandleType(params.targetHandle, targetParams); - - // 验证连接类型是否匹配 (api只能连api, data只能连data) - if (sourceHandleType !== targetHandleType) { - console.warn('连接类型不匹配: ', sourceHandleType, targetHandleType); - return; - } - - // 验证数据类型是否匹配 - if (!validateDataType(sourceNode, targetNode, params.sourceHandle, params.targetHandle)) { - console.warn('数据类型不匹配'); - return; - } - - // TODO 目前是临时定义,存在事件数据的时候才展示 - // params.data = { - // displayData: { - // label: '测试', - // value: '数据展示' - // } - // }; - - // 如果验证通过,创建连接 - setEdges((edgesSnapshot) => { - const newEdges = addEdge({ ...params, type: 'custom' }, edgesSnapshot); - - // 连接建立后记录历史 - setTimeout(() => { - const event = new CustomEvent('takeSnapshot', { - detail: { nodes: [...nodes], edges: [...newEdges] } - }); - document.dispatchEvent(event); - }, 0); - - return newEdges; - }); - }, - [nodes] - ); - - // 边重新连接处理 - const onReconnect = useCallback( - (oldEdge: Edge, newConnection: any) => { - // 获取源节点和目标节点 - const sourceNode = nodes.find(node => node.id === newConnection.source); - const targetNode = nodes.find(node => node.id === newConnection.target); - - // 如果找不到节点,不创建连接 - if (!sourceNode || !targetNode) { - return; - } - - // 获取源节点和目标节点的参数信息 - const sourceParams = sourceNode.data?.parameters || {}; - const targetParams = targetNode.data?.parameters || {}; - - // 获取源handle和目标handle的类型 (api或data) - const sourceHandleType = getHandleType(newConnection.sourceHandle, sourceParams); - const targetHandleType = getHandleType(newConnection.targetHandle, targetParams); - - // 验证连接类型是否匹配 (api只能连api, data只能连data) - if (sourceHandleType !== targetHandleType) { - console.warn('连接类型不匹配: ', sourceHandleType, targetHandleType); - return; - } - // 验证数据类型是否匹配 - if (!validateDataType(sourceNode, targetNode, newConnection.sourceHandle, newConnection.targetHandle)) { - console.warn('数据类型不匹配'); - return; - } - - // 如果验证通过,重新连接 - setEdges((els) => reconnectEdge(oldEdge, newConnection, els)); - }, - [nodes] - ); - - const onDragOver = useCallback((event: React.DragEvent) => { - event.preventDefault(); - event.dataTransfer.dropEffect = 'move'; - }, []); - - // 侧边栏节点实例 - // 修改 onDrop 函数 - const onDrop = useCallback( - (event: React.DragEvent) => { - event.preventDefault(); - - if (!reactFlowInstance) return; + // 使用自定义Hook管理状态 + const { + // State values + nodes, + setNodes, + edges, + setEdges, + canvasDataMap, + editingNode, + setEditingNode, + isEditModalOpen, + setIsEditModalOpen, + isDelete, + setIsDelete, + edgeForNodeAdd, + setEdgeForNodeAdd, + positionForNodeAdd, + setPositionForNodeAdd, + isRunning, + setIsRunning, + historyInitialized, + setHistoryInitialized, + historyTimeoutRef, + updateCanvasDataMapDebounced, - const callBack = event.dataTransfer.getData('application/reactflow'); - const nodeData = JSON.parse(callBack); - if (typeof nodeData.nodeType === 'undefined' || !nodeData.nodeType) { - return; - } + // Redux + dispatch, - const position = reactFlowInstance.screenToFlowPosition({ - x: event.clientX, - y: event.clientY - }); + // Initial data + initialData: stateInitialData + } = useFlowEditorState(initialData); - const newNode = { - id: `${nodeData.nodeType}-${Date.now()}`, - type: nodeData.nodeType, - position, - data: { ...nodeData.data, title: nodeData.nodeName, type: nodeData.nodeType } - }; + // 使用自定义Hook管理回调函数 + const { + // Event handlers + onNodesChange, + onEdgesChange, + onConnect, + onReconnect, + onDragOver, + onDrop, + onNodeDrag, + onNodeDragStop, + onNodesDelete, - // 将未定义的节点动态追加进nodeTypes - const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); - // 目前默认添加的都是系统组件/本地组件 - if (!nodeMap.includes(nodeData.nodeType)) registerNodeType(nodeData.nodeType, LocalNode, nodeData.nodeName); + // Menu handlers + closeEditModal, + saveNodeEdit, + deleteNode, + deleteEdge, + editNode, + editEdge, + copyNode, - setNodes((nds) => { - const newNodes = nds.concat(newNode); + // Node operations + addNodeOnEdge, + addNodeOnPane, + handleAddNode, - // 添加节点后记录历史 - setTimeout(() => { - const event = new CustomEvent('takeSnapshot', { - detail: { nodes: [...newNodes], edges: [...edges] } - }); - document.dispatchEvent(event); - }, 0); + // Initialization + initializeCanvasData, + updateCanvasDataMapEffect, - return newNodes; - }); - }, - [reactFlowInstance, edges] - ); + // Actions + saveFlowDataToServer, + handleRun, - const onNodeDrag = useCallback( - (_: any, node: Node) => { - // 获取对齐线 - getGuidelines(node, nodes); - }, - [nodes, getGuidelines] + // Utilities + getHandleType, + validateDataType + } = useFlowCallbacks( + nodes, + setNodes, + edges, + setEdges, + reactFlowInstance, + canvasDataMap, + dispatch, + updateCanvasDataMapDebounced, + initialData, + historyTimeoutRef, + setHistoryInitialized, + editingNode, + setEditingNode, + setIsEditModalOpen, + edgeForNodeAdd, + setEdgeForNodeAdd, + positionForNodeAdd, + setPositionForNodeAdd, + setIsDelete, + setIsRunning ); - // 节点拖拽结束处理 - const onNodeDragStop = useCallback(() => { - // 清除对齐线 - clearGuidelines(); - }, [clearGuidelines]); - - useEffect(() => { - if (canvasDataMap[initialData?.id]) { - const { edges, nodes } = canvasDataMap[initialData?.id]; - setNodes(nodes); - setEdges(edges); - } - else { - // 首次进入 - const { nodes: convertedNodes, edges: convertedEdges } = convertFlowData(initialData, useDefault); - // 为所有边添加类型- - const initialEdges: Edge[] = convertedEdges.map(edge => ({ - ...edge, - type: 'custom' - })); - - setNodes(convertedNodes); - setEdges(initialEdges); - - if (initialData?.id) { - dispatch(updateCanvasDataMap({ - ...canvasDataMap, - [initialData.id]: { convertedNodes, initialEdges } - })); - } - } - - // 标记历史记录已初始化 - setHistoryInitialized(true); - }, [initialData]); - - // 实时更新 canvasDataMap - useEffect(() => { - if (initialData?.id) { - updateCanvasDataMapDebounced(dispatch, canvasDataMap, initialData.id, nodes, edges); - } - - // 清理函数,在组件卸载时取消防抖 - return () => { - updateCanvasDataMapDebounced.cancel(); - }; - }, [nodes, edges, initialData?.id, dispatch, canvasDataMap]); - - // 监听边的变化,处理添加节点的触发 - useEffect(() => { - const edgeToAddNode = edges.find(edge => edge.data?.addNodeTrigger); - const pane = reactFlowWrapper.current?.getBoundingClientRect(); - if (edgeToAddNode) { - edgeToAddNode.data.y = (edgeToAddNode.data.clientY as number) - pane.top; - edgeToAddNode.data.x = (edgeToAddNode.data.clientX as number) - pane.left; - setEdgeForNodeAdd(edgeToAddNode); - - // 清除触发标志 - setEdges(eds => eds.map(edge => { - if (edge.id === edgeToAddNode.id) { - const { addNodeTrigger, ...restData } = edge.data || {}; - return { - ...edge, - data: restData - }; - } - return edge; - })); - } - }, [edges]); - // 节点右键菜单处理 const onNodeContextMenu = useCallback( (event: React.MouseEvent, node: Node) => { @@ -532,292 +209,38 @@ const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean }> = ({ ini setPositionForNodeAdd(null); }, [setMenu]); - // 关闭编辑弹窗 - const closeEditModal = useCallback(() => { - setIsEditModalOpen(false); - setEditingNode(null); - }, []); - - // 保存节点编辑 - const saveNodeEdit = useCallback((updatedData: any) => { - console.log('updatedData:', updatedData); - const updatedNodes = nodes.map((node) => { - if (node.id === editingNode?.id) { - return { - ...node, - data: { ...node.data, ...updatedData } - }; - } - return node; - }); - - setNodes(updatedNodes); - closeEditModal(); - - // TODO 如果需要在节点编辑后立即保存到服务器,可以调用保存函数 - // saveFlowDataToServer(); - }, [nodes, editingNode, closeEditModal]); - - // 修改删除节点函数 - const deleteNode = useCallback((node: Node) => { - setNodes((nds) => nds.filter((n) => n.id !== node.id)); - setEdges((eds) => eds.filter((e) => e.source !== node.id && e.target !== node.id)); - setMenu(null); - - // 删除节点后记录历史 - setTimeout(() => { - const event = new CustomEvent('takeSnapshot', { - detail: { - nodes: [...nodes.filter((n) => n.id !== node.id)], - edges: [...edges.filter((e) => e.source !== node.id && e.target !== node.id)] - } - }); - document.dispatchEvent(event); - }, 0); - }, [nodes, edges]); - - // 修改删除边函数 - const deleteEdge = useCallback((edge: Edge) => { - setEdges((eds) => eds.filter((e) => e.id !== edge.id)); - setMenu(null); - - // 删除边后记录历史 - setTimeout(() => { - const event = new CustomEvent('takeSnapshot', { - detail: { - nodes: [...nodes], - edges: [...edges.filter((e) => e.id !== edge.id)] - } - }); - document.dispatchEvent(event); - }, 0); - }, [nodes, edges]); - - // 编辑节点 - const editNode = useCallback((node: Node) => { - setMenu(null); - setEditingNode(node); - setIsEditModalOpen(true); - }, []); - - // 编辑边 - const editEdge = useCallback((edge: Edge) => { - // 这里可以实现边编辑逻辑 - console.log('编辑边:', edge); - setMenu(null); - }, []); - - // 复制节点 - const copyNode = useCallback((node: Node) => { - // 这里可以实现节点复制逻辑 - console.log('复制节点:', node); - setMenu(null); - }, []); - - // 在边上添加节点的具体实现 - // 修改 addNodeOnEdge 函数 - const addNodeOnEdge = useCallback((nodeType: string, node: any) => { - if (!edgeForNodeAdd || !reactFlowInstance) return; - - // 查找节点定义 - const nodeDefinition = localNodeData.find(n => n.nodeType === nodeType) || node; - if (!nodeDefinition) return; - - // 获取源节点和目标节点 - const sourceNode = nodes.find(n => n.id === edgeForNodeAdd.source); - const targetNode = nodes.find(n => n.id === edgeForNodeAdd.target); - - if (!sourceNode || !targetNode) return; - - // 计算中点位置 - const position = { - x: (sourceNode.position.x + targetNode.position.x) / 2, - y: (sourceNode.position.y + targetNode.position.y) / 2 - }; - - // 创建新节点 - const newNode = { - id: `${nodeType}-${Date.now()}`, - type: nodeType, - position, - data: { - ...nodeDefinition.data, - title: nodeDefinition.nodeName, - type: nodeType - } - }; - - // 将未定义的节点动态追加进nodeTypes - const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); - if (!nodeMap.includes(nodeType)) registerNodeType(nodeType, nodeType === 'BASIC' ? BasicNode : LocalNode, nodeDefinition.nodeName); - - // 添加新节点 - setNodes((nds) => [...nds, newNode]); - - // 删除旧边 - setEdges((eds) => eds.filter(e => e.id !== edgeForNodeAdd.id)); - - // 创建新边: source -> new node, new node -> target - const newEdges = [ - ...edges.filter(e => e.id !== edgeForNodeAdd.id), - { - id: `e${edgeForNodeAdd.source}-${newNode.id}`, - source: edgeForNodeAdd.source, - target: newNode.id, - type: 'custom' - }, - { - id: `e${newNode.id}-${edgeForNodeAdd.target}`, - source: newNode.id, - target: edgeForNodeAdd.target, - type: 'custom' - } - ]; - - setEdges(newEdges); - - // 关闭菜单 - setEdgeForNodeAdd(null); - setPositionForNodeAdd(null); + // 监听边的变化,处理添加节点的触发 + useEffect(() => { + const edgeToAddNode = edges.find(edge => edge.data?.addNodeTrigger); + const pane = reactFlowWrapper.current?.getBoundingClientRect(); + if (edgeToAddNode) { + edgeToAddNode.data.y = (edgeToAddNode.data.clientY as number) - pane.top; + edgeToAddNode.data.x = (edgeToAddNode.data.clientX as number) - pane.left; + setEdgeForNodeAdd(edgeToAddNode); - // 添加节点后记录历史 - setTimeout(() => { - const event = new CustomEvent('takeSnapshot', { - detail: { - nodes: [...nodes, newNode], - edges: [...newEdges] + // 清除触发标志 + setEdges((eds: Edge[]) => eds.map(edge => { + if (edge.id === edgeToAddNode.id) { + const { addNodeTrigger, ...restData } = edge.data || {}; + return { + ...edge, + data: restData + }; } - }); - document.dispatchEvent(event); - }, 0); - }, [edgeForNodeAdd, nodes, reactFlowInstance, edges]); - - // 在画布上添加节点 - // 修改 addNodeOnPane 函数 - const addNodeOnPane = useCallback((nodeType: string, position: { x: number; y: number }, node?: any) => { - setMenu(null); - - if (!reactFlowInstance) return; - - // 查找节点定义 - const nodeDefinition = localNodeData.find(n => n.nodeType === nodeType) || node; - if (!nodeDefinition) return; - - // 创建新节点 - const newNode = { - id: `${nodeType}-${Date.now()}`, - type: nodeType, - position, - data: { - ...nodeDefinition.data, - title: nodeDefinition.nodeName, - type: nodeType - } - }; - - // 将未定义的节点动态追加进nodeTypes - const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); - // 目前默认添加的都是系统组件/本地组件 - if (!nodeMap.includes(nodeType)) registerNodeType(nodeType, nodeType === 'BASIC' ? BasicNode : LocalNode, nodeDefinition.nodeName); - - setNodes((nds) => { - const newNodes = [...nds, newNode]; - - // 添加节点后记录历史 - setTimeout(() => { - const event = new CustomEvent('takeSnapshot', { - detail: { nodes: [...newNodes], edges: [...edges] } - }); - document.dispatchEvent(event); - }, 0); - - return newNodes; - }); - }, [reactFlowInstance, edges]); - - // 处理添加节点的统一方法 - const handleAddNode = useCallback((nodeType: string, node) => { - // 如果是通过边添加节点 - if (edgeForNodeAdd) { - addNodeOnEdge(nodeType, node); - } - // 如果是通过画布添加节点 - else if (positionForNodeAdd) { - addNodeOnPane(nodeType, positionForNodeAdd, node); - } - - // 清除状态 - setEdgeForNodeAdd(null); - setPositionForNodeAdd(null); - }, [edgeForNodeAdd, positionForNodeAdd, addNodeOnEdge, addNodeOnPane]); - - // 保存所有节点和边数据到服务器 - const saveFlowDataToServer = useCallback(async () => { - try { - // 转换会原始数据类型 - const revertedData = revertFlowData(nodes, edges); - console.log('initialData:', initialData); - - const res: any = await setMainFlow(revertedData, initialData.id); - if (res.code === 200) { - Message.success('保存成功'); - } - else { - Message.error(res.message); - } - } catch (error) { - console.error('Error saving flow data:', error); - Message.error(error); + return edge; + })); } - }, [nodes, edges]); - - // 添加运行状态 - const [isRunning, setIsRunning] = useState(false); + }, [edges]); - // 初始化WebSocket hook - const ws = useWebSocket({ - onOpen: () => { - console.log('WebSocket连接已建立'); - Message.success('运行已启动'); - }, - onClose: () => { - console.log('WebSocket连接已关闭'); - setIsRunning(false); - Message.info('运行已停止'); - }, - onError: (event) => { - console.error('WebSocket错误:', event); - setIsRunning(false); - Message.error('运行连接出错'); - }, - onMessage: (event) => { - console.log('收到WebSocket消息:', event.data); - // 这里可以处理从后端收到的消息,例如日志更新等 - } - }); + // 初始化画布数据 + useEffect(() => { + initializeCanvasData(); + }, [initialData]); - // 修改运行处理函数 - const handleRun = useCallback(async (running: boolean) => { - if (running) { - // 启动运行 - const res = await getUserToken(); - const token = res.data; - const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'; - let wsApi = `${protocol}://${window.location.host}/ws/v1/bpms-runtime`; - if (window.location.host.includes('localhost')) { - // WS_API = `wss://${host}/ws/v1/bpms-runtime`; - wsApi = `ws://api.myserver.com:4121/ws/v1/bpms-runtime`; - } - const uri = `${wsApi}?x-auth0-token=${token}`; - ws.connect(uri); - setIsRunning(true); - } - else { - // 停止运行 - ws.disconnect(); - setIsRunning(false); - } - }, [initialData?.id, ws]); + // 实时更新 canvasDataMap + useEffect(() => { + return updateCanvasDataMapEffect(); + }, [nodes, edges, initialData?.id, dispatch, canvasDataMap]); if (!historyInitialized) { return
Loading...
; @@ -827,22 +250,21 @@ const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean }> = ({ ini { + onHistoryChange={(newNodes: Node[], newEdges: Edge[]) => { setNodes(newNodes); setEdges(newEdges); }} > - = ({ ini setEdgeForNodeAdd={setEdgeForNodeAdd} positionForNodeAdd={positionForNodeAdd} setPositionForNodeAdd={setPositionForNodeAdd} - getGuidelines={getGuidelines} - clearGuidelines={clearGuidelines} - AlignmentGuides={AlignmentGuides} - updateCanvasDataMapDebounced={updateCanvasDataMapDebounced} - canvasDataMap={canvasDataMap} + isRunning={isRunning} + setIsRunning={setIsRunning} initialData={initialData} + canvasDataMap={canvasDataMap} + + // Event handlers onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} @@ -872,6 +294,8 @@ const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean }> = ({ ini onEdgeContextMenu={onEdgeContextMenu} onPaneContextMenu={onPaneContextMenu} onPaneClick={onPaneClick} + + // Menu handlers closeEditModal={closeEditModal} saveNodeEdit={saveNodeEdit} deleteNode={deleteNode} @@ -879,272 +303,18 @@ const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean }> = ({ ini editNode={editNode} editEdge={editEdge} copyNode={copyNode} + + // Node operations addNodeOnEdge={addNodeOnEdge} addNodeOnPane={addNodeOnPane} handleAddNode={handleAddNode} + + // Actions saveFlowDataToServer={saveFlowDataToServer} handleRun={handleRun} - isRunning={isRunning} /> ); }; -// 创建一个新的组件来包含 ReactFlow 和其他 UI 元素 -const FlowEditorContent: React.FC = (props) => { - const { - nodes, - edges, - setNodes, - setEdges, - reactFlowInstance, - reactFlowWrapper, - menu, - setMenu, - editingNode, - setEditingNode, - isEditModalOpen, - setIsEditModalOpen, - isDelete, - setIsDelete, - edgeForNodeAdd, - setEdgeForNodeAdd, - positionForNodeAdd, - setPositionForNodeAdd, - getGuidelines, - clearGuidelines, - AlignmentGuides, - initialData, - onNodesChange, - onEdgesChange, - onConnect, - onReconnect, - onDragOver, - onDrop, - onNodeDrag, - onNodeDragStop, - onNodeContextMenu, - onNodeDoubleClick, - onEdgeContextMenu, - onPaneContextMenu, - onPaneClick, - closeEditModal, - saveNodeEdit, - deleteNode, - deleteEdge, - editNode, - editEdge, - copyNode, - addNodeOnEdge, - addNodeOnPane, - handleAddNode, - saveFlowDataToServer, - handleRun, - isRunning - } = props; - - const { undo, redo, canUndo, canRedo } = useHistory(); - - // 监听键盘事件实现快捷键 - useEffect(() => { - const handleKeyDown = (e: KeyboardEvent) => { - // Ctrl+Z 撤销 - if (e.ctrlKey && e.key === 'z' && !e.shiftKey && canUndo) { - e.preventDefault(); - undo(); - } - // Ctrl+Shift+Z 重做 - if (e.ctrlKey && e.shiftKey && e.key === 'Z' && canRedo) { - e.preventDefault(); - redo(); - } - // Ctrl+Y 重做 - if (e.ctrlKey && e.key === 'y' && canRedo) { - e.preventDefault(); - redo(); - } - }; - - document.addEventListener('keydown', handleKeyDown); - return () => { - document.removeEventListener('keydown', handleKeyDown); - }; - }, [undo, redo, canUndo, canRedo]); - - // 监听节点和边的变化以拍摄快照 - useEffect(() => { - // 获取 HistoryProvider 中的 takeSnapshot 方法 - const event = new CustomEvent('takeSnapshot', { - detail: { nodes: [...nodes], edges: [...edges] } - }); - document.dispatchEvent(event); - }, [nodes, edges]); - - return ( -
e.preventDefault()}> - { - setNodes((nds) => nds.filter((n) => !deleted.find(d => d.id === n.id))); - }} - onNodesChange={onNodesChange} - onEdgesChange={onEdgesChange} - onConnect={onConnect} - onReconnect={onReconnect} - onDrop={onDrop} - onDragOver={onDragOver} - onNodeDrag={onNodeDrag} - connectionLineType={ConnectionLineType.SmoothStep} - connectionLineComponent={CustomConnectionLine} - onNodeDragStop={onNodeDragStop} - onNodeContextMenu={onNodeContextMenu} - onEdgeContextMenu={onEdgeContextMenu} - onNodeClick={onNodeDoubleClick} - onPaneClick={onPaneClick} - onPaneContextMenu={onPaneContextMenu} - onEdgeMouseEnter={(_event, edge) => { - setEdges(eds => eds.map(e => { - if (e.id === edge.id) { - return { ...e, data: { ...e.data, hovered: true } }; - } - return e; - })); - }} - onEdgeMouseLeave={(_event, edge) => { - setEdges(eds => eds.map(e => { - if (e.id === edge.id) { - return { ...e, data: { ...e.data, hovered: false } }; - } - return e; - })); - }} - fitView - selectionKeyCode={['Meta', 'Control']} - selectionMode={SelectionMode.Partial} - panOnDrag={[0, 1, 2]} // 支持多点触控平移 - zoomOnScroll={true} - zoomOnPinch={true} - panOnScrollSpeed={0.5} - > - - {/**/} - - - - - - - {/*节点右键上下文*/} - {menu && menu.type === 'node' && ( -
- n.id === menu.id)!} - onDelete={deleteNode} - onEdit={editNode} - onCopy={copyNode} - /> -
- )} - - {/*边右键上下文*/} - {menu && menu.type === 'edge' && ( -
- e.id === menu.id)!} - onDelete={deleteEdge} - onEdit={editEdge} - onAddNode={(edge) => { - setEdgeForNodeAdd(edge); - setMenu(null); // 关闭上下文菜单 - }} - /> -
- )} - - {/*画布右键上下文*/} - {menu && menu.type === 'pane' && ( -
- { - addNodeOnPane(nodeType, position, node); - setMenu(null); // 关闭上下文菜单 - }} - /> -
- )} - - {/*节点点击/节点编辑上下文*/} - - - {/*统一的添加节点菜单*/} - {(edgeForNodeAdd || positionForNodeAdd) && ( -
- { - handleAddNode(nodeType, node); - // 关闭菜单 - setEdgeForNodeAdd(null); - setPositionForNodeAdd(null); - }} - position={positionForNodeAdd || undefined} - edgeId={edgeForNodeAdd?.id} - /> -
- )} -
- ); -}; - export default FlowEditorWithProvider; \ No newline at end of file diff --git a/src/pages/flowEditor/test/exampleFlowData.ts b/src/pages/flowEditor/test/exampleFlowData.ts deleted file mode 100644 index 0caad84..0000000 --- a/src/pages/flowEditor/test/exampleFlowData.ts +++ /dev/null @@ -1,20008 +0,0 @@ -export const exampleFlowData = { - 'main': { - 'id': 'main', - 'lineConfigs': [ - // { - // 'id': '606f71c3-2051-4775-92a0-835d75b9ab91', - // 'lineType': 'API', - // 'next': { - // 'endpointId': 'start', - // 'nodeId': 'node_49' - // }, - // 'prev': { - // 'endpointId': 'start', - // 'nodeId': 'start' - // }, - // 'x6': '{"vertices":[]}' - // }, - // { - // 'id': '480b362e-45c6-4d9f-b55c-532703ff64ec', - // 'lineType': 'API', - // 'next': { - // 'endpointId': 'end', - // 'nodeId': 'end' - // }, - // 'prev': { - // 'endpointId': 'done', - // 'nodeId': 'node_49' - // }, - // 'x6': '{"vertices":[]}' - // } - ], - 'name': '', - 'nodeConfigs': [ - { - 'apiId': '', - 'component': null, - 'dataIns': [], - 'dataOfPrevNodeMap': {}, - 'dataOuts': [], - 'defaultValues': [], - 'description': '', - 'joinLines': {}, - 'nodeId': 'start', - 'nodeName': '', - 'x6': '{"position":{"x":-250,"y":0}}' - }, - { - 'apiId': '', - 'component': { - 'compIdentifier': 'admin_connect_test', - 'compInstanceIdentifier': 'admin_connect_test', - 'customDef': '', - 'type': 'BASIC' - }, - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOfPrevNodeMap': {}, - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '返回数据', - 'id': 'returnData' - } - ], - 'defaultValues': [], - 'description': '', - 'joinLines': {}, - 'nodeId': 'node_49', - 'nodeName': '连接test', - 'x6': '{"position":{"x":-90,"y":-60}}' - }, - { - 'apiId': '', - 'component': null, - 'dataIns': [], - 'dataOfPrevNodeMap': {}, - 'dataOuts': [], - 'defaultValues': [], - 'description': '', - 'joinLines': {}, - 'nodeId': 'end', - 'nodeName': '', - 'x6': '{"position":{"x":500,"y":0}}' - } - ] - } -}; - -export const mineList = [ - { - 'children': [ - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'contour' - }, - 'fieldIns': [ - 'imgPath', - 'standby' - ], - 'fieldOuts': [ - 'headArc', - 'tailArc', - 'leftLine', - 'rightLine', - 'outputimg' - ], - 'id': 'contour', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'imgPath' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '待用', - 'id': 'standby' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'headArc' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'leftLine' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'outputimg' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'rightLine' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tailArc' - } - ] - }, - 'description': 'djx\n', - 'id': '1926516475086848001', - 'identifier': 'admin_contour', - 'isDeleted': 0, - 'name': '车底盘轮廓识别(打磨)', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '车底盘轮廓识别(打磨)' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'image' - }, - 'fieldIns': [ - 'colorimage', - 'depthimage', - 'shape' - ], - 'fieldOuts': [ - 'pos1', - 'pos2' - ], - 'id': 'image', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'colorimage' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'depthimage' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': 'zhengfangxing,yuanxing,liubianxing', - 'id': 'shape' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '上方坐标', - 'id': 'pos1' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '铝块坐标', - 'id': 'pos2' - } - ] - }, - 'description': '', - 'id': '1926528848321396738', - 'identifier': 'admin_lvkuai', - 'isDeleted': 0, - 'name': '铝块识别', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '铝块识别' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'extractData' - }, - 'fieldIns': [ - 'input7', - 'selection' - ], - 'fieldOuts': [ - 'pos1', - 'pos2', - 'angles' - ], - 'id': 'extractData', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'input7' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'selection' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'angles' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '完整6d位姿', - 'id': 'pos1' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': 'z轴抬高的位姿', - 'id': 'pos2' - } - ] - }, - 'description': '可选任意一组。7个数据中取前6个。djx', - 'id': '1926535234551889922', - 'identifier': 'admin_extractdata2', - 'isDeleted': 0, - 'name': '数据7取6-可选', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '数据7取6-可选' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'centerPoint' - }, - 'fieldIns': [ - 'path', - 'carfront', - 'carback', - 'tireraised', - 'tireplaced' - ], - 'fieldOuts': [ - 'carfrontPoint', - 'carbackPoint', - 'tireraisedPoint', - 'tireplacedPoint', - 'imgPath' - ], - 'id': 'centerPoint', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'carback' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'carfront' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '图片路径', - 'id': 'path' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'tireplaced' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'tireraised' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'carbackPoint' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'carfrontPoint' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'imgPath' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tireplacedPoint' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tireraisedPoint' - } - ] - }, - 'description': '公司的机械臂要修改标定矩阵,所以多创一个。\ndjx', - 'id': '1926535238901383170', - 'identifier': 'admin_center33', - 'isDeleted': 0, - 'name': '小车零件中心点识别3-真实3', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '小车零件中心点识别3-真实3' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'detect' - }, - 'fieldIns': [ - 'imagePath' - ], - 'fieldOuts': [ - 'coordinates' - ], - 'id': 'detect', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '图片地址', - 'id': 'imagePath' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'STRING', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '坐标集', - 'id': 'coordinates' - } - ] - }, - 'description': '点胶路径识别组件', - 'id': '1926857005797466114', - 'identifier': 'admin_dispensing', - 'isDeleted': 0, - 'name': '点胶路径识别', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '点胶路径识别' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'centerPoint' - }, - 'fieldIns': [ - 'path', - 'depthpath', - 'carfront', - 'carback', - 'tireplaced', - 'tireraised' - ], - 'fieldOuts': [ - 'carfrontPoint', - 'carbackPoint', - 'tireplacedPoint', - 'tireraisedPoint', - 'imgPath' - ], - 'id': 'centerPoint', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'carback' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'carfront' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'depthpath' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'path' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'tireplaced' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'tireraised' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'carbackPoint' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'carfrontPoint' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'imgPath' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tireplacedPoint' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tireraisedPoint' - } - ] - }, - 'description': 'djx\n', - 'id': '1927211522822553601', - 'identifier': 'admin_center', - 'isDeleted': 0, - 'name': '真实小车零件中心点识别1', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '真实小车零件中心点识别1' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'centerPoint' - }, - 'fieldIns': [ - 'path', - 'depthpath', - 'carfront', - 'carback', - 'tireplaced', - 'tireraised' - ], - 'fieldOuts': [ - 'carfrontPoint', - 'carbackPoint', - 'tireplacedPoint', - 'tireraisedPoint', - 'imgPath' - ], - 'id': 'centerPoint', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'carback' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'carfront' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'depthpath' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'path' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'tireplaced' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'tireraised' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'carbackPoint' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'carfrontPoint' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'imgPath' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tireplacedPoint' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tireraisedPoint' - } - ] - }, - 'description': 'djx\n', - 'id': '1927283207684800514', - 'identifier': 'admin_center2', - 'isDeleted': 0, - 'name': '真实小车零件中心点识别2', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '真实小车零件中心点识别2' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'analyse' - }, - 'fieldIns': [ - 'imgpath', - 'thickness', - 'frontAngle', - 'reverseAngle' - ], - 'fieldOuts': [ - 'startpos1', - 'startpos2', - 'planningpath1', - 'planningpath2' - ], - 'id': 'analyse', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'frontAngle' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'imgpath' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'reverseAngle' - }, - { - 'arrayType': null, - 'dataType': 'DOUBLE', - 'defaultValue': null, - 'desc': '', - 'id': 'thickness' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'planningpath1' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'planningpath2' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'startpos1' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'startpos2' - } - ] - }, - 'description': '', - 'id': '1927608889875697665', - 'identifier': 'admin_sharpen_knife', - 'isDeleted': 0, - 'name': '刀具位置识别', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '刀具位置识别' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'passMsg' - }, - 'fieldIns': [ - 'file1', - 'file2', - 'file3', - 'file4', - 'file5' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'passMsg', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'file1' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'file2' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'file3' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'file4' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'file5' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'result' - } - ] - }, - 'description': '', - 'id': '1928322536741212161', - 'identifier': 'admin_pass_msg', - 'isDeleted': 0, - 'name': '瓶盖质检算法', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '瓶盖质检算法' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'sortPoints' - }, - 'fieldIns': [ - 'tailraised' - ], - 'fieldOuts': [ - 'outputPoints' - ], - 'id': 'sortPoints', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tailraised' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'outputPoints' - } - ] - }, - 'description': 'djx\n', - 'id': '1928412131506524162', - 'identifier': 'admin_carsort', - 'isDeleted': 0, - 'name': '小车轮胎排序', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '小车轮胎排序' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'extractData' - }, - 'fieldIns': [ - 'input7', - 'selection' - ], - 'fieldOuts': [ - 'pos1', - 'pos2', - 'angles' - ], - 'id': 'extractData', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'input7' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'selection' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'angles' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '完整6d位姿', - 'id': 'pos1' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': 'z轴抬高的位姿', - 'id': 'pos2' - } - ] - }, - 'description': '可选任意一组。7个数据中取前6个。djx', - 'id': '1928433685573406722', - 'identifier': 'admin_extractdata3', - 'isDeleted': 0, - 'name': '数据7取6-可选-轮子用', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '数据7取6-可选-轮子用' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'dsa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'dsa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1929790139983843329', - 'identifier': 'admin_py_test2', - 'isDeleted': 0, - 'name': 'Pytest', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'Pytest' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'passMsg' - }, - 'fieldIns': [ - 'file1', - 'file2', - 'file3', - 'file4', - 'file5' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'passMsg', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'file1' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'file2' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'file3' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'file4' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'file5' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'result' - } - ] - }, - 'description': '', - 'id': '1929836326141894658', - 'identifier': 'admin_image-to-vision', - 'isDeleted': 0, - 'name': '瓶盖识别算法', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '瓶盖识别算法' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'contour' - }, - 'fieldIns': [ - 'imgPath', - 'isDebug' - ], - 'fieldOuts': [ - 'startPoseRobot', - 'endPoseRobot', - 'planningPathRobot', - 'outputimg' - ], - 'id': 'contour', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'imgPath' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'isDebug' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'endPoseRobot' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'outputimg' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'planningPathRobot' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'startPoseRobot' - } - ] - }, - 'description': '', - 'id': '1930162893052436482', - 'identifier': 'admin_sharpen', - 'isDeleted': 0, - 'name': '磨刀识别', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '磨刀识别' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'camerainput' - }, - 'fieldIns': [ - 'shangfangUrl', - 'youshangUrl', - 'youxiaUrl', - 'zuoxiaUrl', - 'zuoshangUrl' - ], - 'fieldOuts': [ - 'shangfang', - 'youshang', - 'youxia', - 'zuoxia', - 'zuoshang' - ], - 'id': 'camerainput', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '输入对应相机图片', - 'id': 'shangfangUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youshangUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youxiaUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoshangUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoxiaUrl' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '如果没有问题,输出原url,如果有问题,输出质检后url', - 'id': 'shangfang' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youshang' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youxia' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoshang' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoxia' - } - ] - }, - 'description': '', - 'id': '1930426735050805249', - 'identifier': 'admin_car_detect', - 'isDeleted': 0, - 'name': '小车质检', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '小车质检' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'cameraInput' - }, - 'fieldIns': [ - 'shangfangUrl', - 'youshangUrl', - 'youxiaUrl', - 'zuoxiaUrl', - 'zuoshangUrl' - ], - 'fieldOuts': [ - 'judgement', - 'shangfang', - 'youshang', - 'youxia', - 'zuoshang', - 'zuoxia' - ], - 'id': 'cameraInput', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'shangfangUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youshangUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youxiaUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoshangUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoxiaUrl' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '如果产品有缺陷,输出false,无缺陷输出true', - 'id': 'judgement' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '如果无缺陷,输出原minio路径,如果有缺陷,输出缺陷minio', - 'id': 'shangfang' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youshang' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youxia' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoshang' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoxia' - } - ] - }, - 'description': '', - 'id': '1930587229694398465', - 'identifier': 'admin_judgement', - 'isDeleted': 0, - 'name': '小车质检(新)', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '小车质检(新)' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'inputUrl' - }, - 'fieldIns': [ - 'shangfangUrl', - 'youshangUrl', - 'youxiaUrl', - 'zuoxiaUrl', - 'zuoshangUrl' - ], - 'fieldOuts': [ - 'judgement', - 'shangfang', - 'youshang', - 'youxia', - 'zuoxia', - 'zuoshang' - ], - 'id': 'inputUrl', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'shangfangUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youshangUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youxiaUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoshangUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoxiaUrl' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '有缺陷输出false,无缺陷输出true', - 'id': 'judgement' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '有缺陷输出新url,无缺陷输出原url', - 'id': 'shangfang' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youshang' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youxia' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoshang' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoxia' - } - ] - }, - 'description': '', - 'id': '1930811783913771009', - 'identifier': 'admin_judge', - 'isDeleted': 0, - 'name': '瓶盖检测', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '瓶盖检测' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'planning' - }, - 'fieldIns': [ - 'startPoseRobot', - 'planningPathRobot', - 'endPoseRobot', - 'y', - 'rx', - 'ry', - 'rz' - ], - 'fieldOuts': [ - 'position', - 'midPosition', - 'targetPosition', - 'step', - 'flag' - ], - 'id': 'planning', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'reset' - }, - 'fieldIns': [ - 'step' - ], - 'fieldOuts': [ - 'step' - ], - 'id': 'reset', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'endPoseRobot' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'planningPathRobot' - }, - { - 'arrayType': null, - 'dataType': 'DOUBLE', - 'defaultValue': null, - 'desc': '', - 'id': 'rx' - }, - { - 'arrayType': null, - 'dataType': 'DOUBLE', - 'defaultValue': null, - 'desc': '', - 'id': 'ry' - }, - { - 'arrayType': null, - 'dataType': 'DOUBLE', - 'defaultValue': null, - 'desc': '', - 'id': 'rz' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'startPoseRobot' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - }, - { - 'arrayType': null, - 'dataType': 'DOUBLE', - 'defaultValue': null, - 'desc': '', - 'id': 'y' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'flag' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'midPosition' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'position' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'targetPosition' - } - ] - }, - 'description': 'djx', - 'id': '1931245671710560258', - 'identifier': 'admin_sharpenplanning2', - 'isDeleted': 0, - 'name': '磨刀路径规划-可调2', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '磨刀路径规划-可调2' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'test' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'test', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1932993903048069121', - 'identifier': 'admin_arm64py', - 'isDeleted': 0, - 'name': 'arm64Py', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'arm64Py' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'contour' - }, - 'fieldIns': [ - 'imgPath' - ], - 'fieldOuts': [ - 'headArc', - 'tailArc', - 'leftLine', - 'rightLine', - 'outputimg' - ], - 'id': 'contour', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'imgPath' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'headArc' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'leftLine' - }, - { - 'arrayType': null, - 'dataType': 'DOUBLE', - 'defaultValue': null, - 'desc': '', - 'id': 'outputimg' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'rightLine' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tailArc' - } - ] - }, - 'description': '', - 'id': '1933835980807507970', - 'identifier': 'admin_admin_contour', - 'isDeleted': 0, - 'name': '磨边ppt', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '磨边ppt' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'planning' - }, - 'fieldIns': [ - 'headArc', - 'tailArc', - 'leftLine', - 'rightLine' - ], - 'fieldOuts': [ - 'flag', - 'midPosition', - 'position', - 'step', - 'targetPosition' - ], - 'id': 'planning', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'reset' - }, - 'fieldIns': [ - 'step' - ], - 'fieldOuts': [ - 'step' - ], - 'id': 'reset', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'headArc' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'leftLine' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'rightLine' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tailArc' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'flag' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'midPosition' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'position' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'targetPosition' - } - ] - }, - 'description': '', - 'id': '1933908470699298817', - 'identifier': 'admin_carbackplanning_abc', - 'isDeleted': 0, - 'name': '小车底盘路径规划', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '小车底盘路径规划' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'a' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'a', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1934482624077475842', - 'identifier': 'admin_admin_admin_admin_contour', - 'isDeleted': 0, - 'name': '磨边', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '磨边' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'inputUrl' - }, - 'fieldIns': [ - 'shangfangUrl', - 'youshangUrl', - 'youxiaUrl', - 'zuoshangUrl', - 'zuoxiaUrl' - ], - 'fieldOuts': [ - 'judgement', - 'shangfang', - 'youshang', - 'youxia', - 'zuoshang', - 'zuoxia' - ], - 'id': 'inputUrl', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'shangfangUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youshangUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youxiaUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoshangUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoxiaUrl' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'judgement' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'shangfang' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youshang' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'youxia' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoshang' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'zuoxia' - } - ] - }, - 'description': '', - 'id': '1934883616096423938', - 'identifier': 'admin_judge_a', - 'isDeleted': 0, - 'name': '瓶盖质检', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '瓶盖质检' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '视觉AI组件', - 'createUser': '1930071310364372993', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1936329750598955010', - 'identifier': 'ichentang_cumtest', - 'isDeleted': 0, - 'name': '组件设计测试', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '组件设计测试' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'centerPoint' - }, - 'fieldIns': [ - 'path', - 'carfront', - 'carback', - 'tireraised', - 'tireplaced' - ], - 'fieldOuts': [ - 'carfrontPoint', - 'carbackPoint', - 'tireraisedPoint', - 'tireplacedPoint', - 'imgPath' - ], - 'id': 'centerPoint', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'carback' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'carfront' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '图片路径', - 'id': 'path' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'tireplaced' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'tireraised' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'carbackPoint' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'carfrontPoint' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'imgPath' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tireplacedPoint' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tireraisedPoint' - } - ] - }, - 'description': '给仿真小车加上旋转', - 'id': '1940965138418180097', - 'identifier': 'admin_center4_new', - 'isDeleted': 0, - 'name': '新小车零件中心点识别4-仿真', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '新小车零件中心点识别4-仿真' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'centerPoint' - }, - 'fieldIns': [ - 'path', - 'carfront', - 'carback', - 'tireraised', - 'tireplaced' - ], - 'fieldOuts': [ - 'carfrontPoint', - 'carbackPoint', - 'tireraisedPoint', - 'tireplacedPoint', - 'imgPath' - ], - 'id': 'centerPoint', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'carback' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'carfront' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '图片路径', - 'id': 'path' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'tireplaced' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'tireraised' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'carbackPoint' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'carfrontPoint' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'imgPath' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tireplacedPoint' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tireraisedPoint' - } - ] - }, - 'description': '给仿真小车加上旋转', - 'id': '1941027656478040066', - 'identifier': 'admin_center4', - 'isDeleted': 0, - 'name': '小车零件中心点识别4-仿真', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '小车零件中心点识别4-仿真' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'centerPoint' - }, - 'fieldIns': [ - 'path', - 'carfront', - 'carback', - 'tireraised', - 'tireplaced' - ], - 'fieldOuts': [ - 'carfrontPoint', - 'carbackPoint', - 'tireraisedPoint', - 'tireplacedPoint', - 'imgPath' - ], - 'id': 'centerPoint', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'carback' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'carfront' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '图片路径', - 'id': 'path' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'tireplaced' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'tireraised' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'carbackPoint' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'carfrontPoint' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'imgPath' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tireplacedPoint' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tireraisedPoint' - } - ] - }, - 'description': '', - 'id': '1941080442272030722', - 'identifier': 'admin_center1', - 'isDeleted': 0, - 'name': '小车零件中心点识别2', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '小车零件中心点识别2' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'input' - }, - 'fieldIns': [ - 'colorimage', - 'prompt' - ], - 'fieldOuts': [ - 'position2d' - ], - 'id': 'input', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'colorimage' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'prompt' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'position2d' - } - ] - }, - 'description': '', - 'id': '1952242455729721345', - 'identifier': 'admin_tuxiang', - 'isDeleted': 0, - 'name': '图像识别', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '图像识别' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'barcodeRecognition' - }, - 'fieldIns': [ - 'img' - ], - 'fieldOuts': [ - 'imgInfo' - ], - 'id': 'barcodeRecognition', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '条码图片', - 'id': 'img' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'OBJECT', - 'defaultValue': null, - 'desc': '条码信息(条码值和类型)', - 'id': 'imgInfo' - } - ] - }, - 'description': '', - 'id': '1952242460087603202', - 'identifier': 'admin_barcode', - 'isDeleted': 0, - 'name': '条码识别', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '条码识别' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'roIMod' - }, - 'fieldIns': [ - 'minioURL' - ], - 'fieldOuts': [ - 'outputUrl' - ], - 'id': 'roIMod', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'fullProcessModel' - }, - 'fieldIns': [ - 'minioUrl' - ], - 'fieldOuts': [ - 'outMinioUrl' - ], - 'id': 'fullProcessModel', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '从MinIO获取图像', - 'id': 'minioURL' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': 'minio图片url', - 'id': 'minioUrl' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '输出的minio图片url', - 'id': 'outMinioUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': 'MinIO输出地址', - 'id': 'outputUrl' - } - ] - }, - 'description': '', - 'id': '1952244936895418370', - 'identifier': 'admin_image_preprocessing', - 'isDeleted': 0, - 'name': 'OCR图像预处理', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': 'OCR图像预处理' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1956177312629698561', - 'identifier': 'admin_dsa-dsa', - 'isDeleted': 0, - 'name': 'da-', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'normal' - }, - 'label': 'da-' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'gestureRecognition' - }, - 'fieldIns': [ - 'var1' - ], - 'fieldOuts': [ - 'var2' - ], - 'id': 'gestureRecognition', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'recognizingGesture' - }, - 'fieldIns': [ - 'var1' - ], - 'fieldOuts': [], - 'id': 'recognizingGesture', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'var1' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'var2' - } - ] - }, - 'description': '', - 'id': '1958116009570648065', - 'identifier': 'admin_visua_recognition', - 'isDeleted': 0, - 'name': 'rknn视觉识别', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'loop' - }, - 'label': 'rknn视觉识别' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'attitudeDetection' - }, - 'fieldIns': [ - 'url' - ], - 'fieldOuts': [], - 'id': 'attitudeDetection', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'areaDetection' - }, - 'fieldIns': [ - 'url' - ], - 'fieldOuts': [], - 'id': 'areaDetection', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'url' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1958337039551610881', - 'identifier': 'admin_person_identification', - 'isDeleted': 0, - 'name': 'rknn_语音识别_new', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'loop' - }, - 'label': 'rknn_语音识别_new' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '视觉AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'areaDetection' - }, - 'fieldIns': [ - 'url', - 'type' - ], - 'fieldOuts': [], - 'id': 'areaDetection', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'attitudeDetection' - }, - 'fieldIns': [ - 'url', - 'type' - ], - 'fieldOuts': [], - 'id': 'attitudeDetection', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'safetyDetection' - }, - 'fieldIns': [ - 'url', - 'type' - ], - 'fieldOuts': [], - 'id': 'safetyDetection', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'type' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'url' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1958355063428005890', - 'identifier': 'admin_personnel_detection', - 'isDeleted': 0, - 'name': 'rknn_人员识别', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'loop' - }, - 'label': 'rknn_人员识别' - } - ], - 'label': '视觉AI组件' - }, - { - 'children': [ - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '监听组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'loopTest' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'loopTest', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'loop2' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'loop2', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1938075080539570178', - 'identifier': 'admin_loop_test3', - 'isDeleted': 0, - 'name': '自旋组件', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '自旋组件' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '监听组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'loopTest' - }, - 'fieldIns': [ - 'das' - ], - 'fieldOuts': [ - 'dsa' - ], - 'id': 'loopTest', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'das' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'dsa' - } - ] - }, - 'description': '', - 'id': '1938078774513688578', - 'identifier': 'admin_new_type_test', - 'isDeleted': 0, - 'name': '测试新类型', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试新类型' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '监听组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'aint' - }, - 'fieldIns': [ - 'int' - ], - 'fieldOuts': [ - 'out' - ], - 'id': 'aint', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'int' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'out' - } - ] - }, - 'description': '', - 'id': '1938098293483298818', - 'identifier': 'admin_pylooptest', - 'isDeleted': 0, - 'name': 'pyLoopTest', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'pyLoopTest' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '监听组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'autoLoop' - }, - 'fieldIns': [ - 'awd' - ], - 'fieldOuts': [ - 'aaa' - ], - 'id': 'autoLoop', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'awd' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'aaa' - } - ] - }, - 'description': '', - 'id': '1938149918851784706', - 'identifier': 'admin_autoloop', - 'isDeleted': 0, - 'name': 'autoLoop', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'autoLoop' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '监听组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'startModelDiscern' - }, - 'fieldIns': [ - 'rtspUrl', - 'uuid' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'startModelDiscern', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stopModelDiscern' - }, - 'fieldIns': [ - 'rtspUrl', - 'uuid' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'stopModelDiscern', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'getDiscernResult' - }, - 'fieldIns': [ - 'rtspUrl' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'getDiscernResult', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': 'rtsp视频流', - 'id': 'rtspUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '后续接口需要携带该uuid', - 'id': 'uuid' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': 'true: 成功 false:失败', - 'id': 'result' - } - ] - }, - 'description': '', - 'id': '1938153749794840577', - 'identifier': 'admin_rknn_discern_maket3_loop', - 'isDeleted': 0, - 'name': '视频识别-yolo_loop', - 'publishStatus': -1, - 'tags': '[]', - 'type': 'loop' - }, - 'label': '视频识别-yolo_loop' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '监听组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'newTest' - }, - 'fieldIns': [ - 'halohalo' - ], - 'fieldOuts': [], - 'id': 'newTest', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'halohalo' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940214246400647170', - 'identifier': 'admin_loop_test01', - 'isDeleted': 0, - 'name': '测试循环组件', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试循环组件' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '监听组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'test' - }, - 'fieldIns': [ - 'i1' - ], - 'fieldOuts': [ - 'o1' - ], - 'id': 'test', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'i1' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'o1' - } - ] - }, - 'description': '', - 'id': '1940582021376839681', - 'identifier': 'yuxing_nnn', - 'isDeleted': 0, - 'name': '测试自旋new', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试自旋new' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '监听组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'newnew' - }, - 'fieldIns': [ - 'n' - ], - 'fieldOuts': [ - 'q' - ], - 'id': 'newnew', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': 'q', - 'id': 'n' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': 'w', - 'id': 'q' - } - ] - }, - 'description': '', - 'id': '1940582985278230529', - 'identifier': 'yuxing_test_test', - 'isDeleted': 0, - 'name': '测试新组件', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试新组件' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '监听组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'halo' - }, - 'fieldIns': [ - 'asd' - ], - 'fieldOuts': [ - 'dsa' - ], - 'id': 'halo', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'asd' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'dsa' - } - ] - }, - 'description': '', - 'id': '1940590835647041537', - 'identifier': 'yuxing_new_test', - 'isDeleted': 0, - 'name': 'testtest', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'testtest' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '监听组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'newa' - }, - 'fieldIns': [ - 'new' - ], - 'fieldOuts': [ - 'newb' - ], - 'id': 'newa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'new' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'newb' - } - ] - }, - 'description': '', - 'id': '1940600873499623425', - 'identifier': 'yuxing_hl2', - 'isDeleted': 0, - 'name': 'halohalo2', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'halohalo2' - } - ], - 'label': '监听组件' - }, - { - 'children': [ - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '运动规划组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'planning' - }, - 'fieldIns': [ - 'coordinates' - ], - 'fieldOuts': [ - 'position', - 'midPosition', - 'targetPosition', - 'step', - 'flag' - ], - 'id': 'planning', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'reset' - }, - 'fieldIns': [ - 'step' - ], - 'fieldOuts': [ - 'step' - ], - 'id': 'reset', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'coordinates' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'flag' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'midPosition' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'position' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'targetPosition' - } - ] - }, - 'description': '', - 'id': '1927248942775451650', - 'identifier': 'admin_coord_planning', - 'isDeleted': 0, - 'name': '点胶路径规划', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '点胶路径规划' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '运动规划组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'planning' - }, - 'fieldIns': [ - 'headArc', - 'tailArc', - 'leftLine', - 'rightLine' - ], - 'fieldOuts': [ - 'flag', - 'midPosition', - 'position', - 'step', - 'targetPosition' - ], - 'id': 'planning', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'reset' - }, - 'fieldIns': [ - 'step' - ], - 'fieldOuts': [ - 'step' - ], - 'id': 'reset', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'headArc' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'leftLine' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'rightLine' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tailArc' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'flag' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'midPosition' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'position' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'targetPosition' - } - ] - }, - 'description': 'djx', - 'id': '1928025482550415362', - 'identifier': 'admin_carbackplanning', - 'isDeleted': 0, - 'name': '磨小车底盘路径规划', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '磨小车底盘路径规划' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '运动规划组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'reset' - }, - 'fieldIns': [ - 'step' - ], - 'fieldOuts': [ - 'step' - ], - 'id': 'reset', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'planning' - }, - 'fieldIns': [ - 'startPoseRobot', - 'endPoseRobot', - 'planningPathRobot' - ], - 'fieldOuts': [ - 'position', - 'midPosition', - 'targetPosition', - 'step', - 'flag' - ], - 'id': 'planning', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'endPoseRobot' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'planningPathRobot' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'startPoseRobot' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'flag' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'midPosition' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'position' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'targetPosition' - } - ] - }, - 'description': 'djx', - 'id': '1930182930382983169', - 'identifier': 'admin_knifeplanning', - 'isDeleted': 0, - 'name': '磨刀路径规划', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '磨刀路径规划' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '运动规划组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'planning' - }, - 'fieldIns': [ - 'startPoseRobot', - 'endPoseRobot', - 'planningPathRobot', - 'z', - 'rx', - 'ry', - 'rz' - ], - 'fieldOuts': [ - 'position', - 'midPosition', - 'targetPosition', - 'step', - 'flag' - ], - 'id': 'planning', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'reset' - }, - 'fieldIns': [ - 'step' - ], - 'fieldOuts': [ - 'step' - ], - 'id': 'reset', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'endPoseRobot' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'planningPathRobot' - }, - { - 'arrayType': null, - 'dataType': 'DOUBLE', - 'defaultValue': null, - 'desc': '', - 'id': 'rx' - }, - { - 'arrayType': null, - 'dataType': 'DOUBLE', - 'defaultValue': null, - 'desc': '', - 'id': 'ry' - }, - { - 'arrayType': null, - 'dataType': 'DOUBLE', - 'defaultValue': null, - 'desc': '', - 'id': 'rz' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'startPoseRobot' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - }, - { - 'arrayType': null, - 'dataType': 'DOUBLE', - 'defaultValue': null, - 'desc': '', - 'id': 'z' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'flag' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'midPosition' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'position' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'targetPosition' - } - ] - }, - 'description': 'djx。\n传入参数z实际上应该是机械臂的y。', - 'id': '1930520924878475265', - 'identifier': 'admin_knifeplanning2', - 'isDeleted': 0, - 'name': '磨刀路径规划-可调', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '磨刀路径规划-可调' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '运动规划组件', - 'createUser': '1930071310364372993', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'test' - }, - 'fieldIns': [ - 'arg' - ], - 'fieldOuts': [ - 'res' - ], - 'id': 'test', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '1', - 'id': 'arg' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '2', - 'id': 'res' - } - ] - }, - 'description': '', - 'id': '1936312325983744001', - 'identifier': 'ichentang_look', - 'isDeleted': 0, - 'name': '组件组价能', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '组件组价能' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '运动规划组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'planning' - }, - 'fieldIns': [ - 'headArc', - 'tailArc', - 'leftLine', - 'rightLine' - ], - 'fieldOuts': [ - 'flag', - 'midPosition', - 'position', - 'step', - 'targetPosition' - ], - 'id': 'planning', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'reset' - }, - 'fieldIns': [ - 'step' - ], - 'fieldOuts': [ - 'step' - ], - 'id': 'reset', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'headArc' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'leftLine' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'rightLine' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - }, - { - 'arrayType': 'OBJECT', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'tailArc' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'flag' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'midPosition' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'position' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'step' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'targetPosition' - } - ] - }, - 'description': 'djx,磨小车底盘路径规划是最原始的,不知道出什么问题了导致频繁抬升,所以复制一个2出来测试一下', - 'id': '1946527241462431745', - 'identifier': 'admin_carbackplanning2', - 'isDeleted': 0, - 'name': '磨小车底盘路径规划2', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '磨小车底盘路径规划2' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '运动规划组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'taskDivision' - }, - 'fieldIns': [ - 'instruction', - 'model', - 'apiKey', - 'baseUrl' - ], - 'fieldOuts': [ - 'taskList' - ], - 'id': 'taskDivision', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': 'API 密钥', - 'id': 'apiKey' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '基础域名', - 'id': 'baseUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '指令', - 'id': 'instruction' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '模型名称', - 'id': 'model' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'STRING', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '细分任务列表', - 'id': 'taskList' - } - ] - }, - 'description': '具身智能平台任务规划使用', - 'id': '1957686026581741569', - 'identifier': 'admin_embody_brain', - 'isDeleted': 0, - 'name': '具身智能大脑', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'normal' - }, - 'label': '具身智能大脑' - } - ], - 'label': '运动规划组件' - }, - { - 'children': [ - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '工艺知识服务组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'knifeTypeAnalyse' - }, - 'fieldIns': [ - 'imgpath' - ], - 'fieldOuts': [ - 'speed', - 'torque', - 'thickness', - 'frontTime', - 'reverseTime', - 'frontAngle', - 'reverseAngle' - ], - 'id': 'knifeTypeAnalyse', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'imgpath' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'frontAngle' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'frontTime' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'reverseAngle' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'reverseTime' - }, - { - 'arrayType': null, - 'dataType': 'DOUBLE', - 'defaultValue': null, - 'desc': '', - 'id': 'speed' - }, - { - 'arrayType': null, - 'dataType': 'DOUBLE', - 'defaultValue': null, - 'desc': '', - 'id': 'thickness' - }, - { - 'arrayType': null, - 'dataType': 'DOUBLE', - 'defaultValue': null, - 'desc': '', - 'id': 'torque' - } - ] - }, - 'description': '# 一、功能概述\n该组件可根据刀具图片获取刀具参数\n\n# 二、适用设备\n1. 与ur机械臂磨刀组件适配的刀具\n2. 与刀具识别算法适配使用\n\n# 三、接口描述\n|接口名称|描述|输入参数|输出参数|\n|-|-|-|-|-|\n|knifeTypeAnalyse|根据刀具图片获取刀具参数|imgPath|speed, torque, thickness, frontTime, reverseTime, frontAngle, reverseAngle|\n- imgPath: 刀具图片redisKey,值为二进制字节数组\n- speed:磨刀速度\n- torque:磨刀负载\n- thickness:刀刃厚度\n- frontTime:正面磨刀次数\n- reverseTime:反面磨刀次数\n- frontAngle:正面磨刀角度\n- reverseAngle:反面磨刀角度\n# 四、组件内部配置\n无\n\n# 五、部署配置\n无\n\n# 六、其他\n', - 'id': '1927629639357632514', - 'identifier': 'admin_knife-knowledge', - 'isDeleted': 0, - 'name': '刀具知识库', - 'publishStatus': 1, - 'tags': '', - 'type': '' - }, - 'label': '刀具知识库' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '工艺知识服务组件', - 'createUser': '1930071310364372993', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'testTest' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'testTest', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1931235966747217921', - 'identifier': 'ichentang_test_test', - 'isDeleted': 0, - 'name': '组件审核测试44', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '组件审核测试44' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '工艺知识服务组件', - 'createUser': '1930071310364372993', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'jjjjjj' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'jjjjjj', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1931242574298550273', - 'identifier': 'ichentang_jjjjjj', - 'isDeleted': 0, - 'name': '组件审核测试33', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '组件审核测试33' - } - ], - 'label': '工艺知识服务组件' - }, - { - 'children': [ - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photograph' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'minioPath' - ], - 'id': 'photograph', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'minioPath' - } - ] - }, - 'description': '', - 'id': '1920407654593728513', - 'identifier': 'admin_simulated-depth-camera0508-jy', - 'isDeleted': 0, - 'name': '仿真深度相机', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '仿真深度相机' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'testInput' - }, - 'fieldIns': [ - 'strLet', - 'intLet' - ], - 'fieldOuts': [], - 'id': 'testInput', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'intLet' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'strLet' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1921771526507524097', - 'identifier': 'yuxing_pytest', - 'isDeleted': 0, - 'name': '数据采集测试', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '数据采集测试' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'triggerInhalation' - }, - 'fieldIns': [ - 'trigger' - ], - 'fieldOuts': [], - 'id': 'triggerInhalation', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'trigger' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '修边位触发吸气,值为1时打开,0时关闭', - 'id': '1921866286987538434', - 'identifier': 'yuxing_trimming_position_inhale', - 'isDeleted': 0, - 'name': '修边位_触发吸气', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '修边位_触发吸气' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photographToRedis' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'colorKey', - 'depthKey' - ], - 'id': 'photographToRedis', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photographToMinio' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'colorUrl', - 'depthUrl' - ], - 'id': 'photographToMinio', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photographPointCloud' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'pointCloudUrl' - ], - 'id': 'photographPointCloud', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'colorKey' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'colorUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'depthKey' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'depthUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'pointCloudUrl' - } - ] - }, - 'description': '', - 'id': '1921894536996515842', - 'identifier': 'admin_hk-depth-camera', - 'isDeleted': 0, - 'name': '海康深度相机', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '海康深度相机' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'trigger' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'trigger', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '1是去检测位2是去上料位', - 'id': 'inputData' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '去检测位或者去上料位。\n1是检测位,2是上料位', - 'id': '1922119550790332418', - 'identifier': 'yuxing_detection_materials', - 'isDeleted': 0, - 'name': '去检测位_去上料位', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '去检测位_去上料位' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'triggerMark' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'triggerMark', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'inputData' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '激光位触发打标', - 'id': '1922169372163502082', - 'identifier': 'yuxing_laser_marking', - 'isDeleted': 0, - 'name': '激光位_触发打标', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '激光位_触发打标' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'trigger' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'trigger', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'inputData' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '激光位夹紧,1为夹紧。0为松开', - 'id': '1922221691830845441', - 'identifier': 'yuxing_laser_clamp', - 'isDeleted': 0, - 'name': '激光位_定位夹紧', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '激光位_定位夹紧' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'triggerPackage' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'triggerPackage', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'inputData' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '组装_触发夹紧. 1为夹紧,0为松开', - 'id': '1922460078340882433', - 'identifier': 'yuxing_package_clamp', - 'isDeleted': 0, - 'name': '组装_触发夹紧', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '组装_触发夹紧' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'triggerCompression' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'triggerCompression', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'inputData' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '螺丝位触发压紧,传入1时夹紧。0时张开', - 'id': '1922479023684894722', - 'identifier': 'yuxing_screw_compress', - 'isDeleted': 0, - 'name': '螺丝位_触发压紧', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '螺丝位_触发压紧' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'triggerTurn' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'triggerTurn', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'inputData' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '螺丝位_翻转', - 'id': '1922488365108740098', - 'identifier': 'yuxing_screw_turn', - 'isDeleted': 0, - 'name': '螺丝位_翻转', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '螺丝位_翻转' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'trigger' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'trigger', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'inputData' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '螺丝位_去取料位/去打螺丝位1/去打螺丝位2\n参数为1:去取料位', - 'id': '1922492536612503554', - 'identifier': 'yuxing_screw_materials_hitscrew', - 'isDeleted': 0, - 'name': '螺丝位_去取料位or去打螺丝位1or去打螺丝位2', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '螺丝位_去取料位or去打螺丝位1or去打螺丝位2' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'lineMove' - }, - 'fieldIns': [ - 'gpId', - 'isJoint', - 'ufNum', - 'utNum', - 'strPos', - 'isLinear', - 'config' - ], - 'fieldOuts': [], - 'id': 'lineMove', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'circleMove' - }, - 'fieldIns': [ - 'gpId', - 'ufNum', - 'utNum', - 'config', - 'strMidPos', - 'strEndPos', - 'isToMid', - 'isMidInt', - 'isEndJnt' - ], - 'fieldOuts': [], - 'id': 'circleMove', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '形态位', - 'id': 'config' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '组号', - 'id': 'gpId' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '末端点位是否为关节', - 'id': 'isEndJnt' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否关节点', - 'id': 'isJoint' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否直线', - 'id': 'isLinear' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '中间点位是否为关节', - 'id': 'isMidInt' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否到中间点', - 'id': 'isToMid' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '末端点位', - 'id': 'strEndPos' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '中间点位', - 'id': 'strMidPos' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '点数据', - 'id': 'strPos' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '工件号', - 'id': 'ufNum' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '工具号', - 'id': 'utNum' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1922919238548893697', - 'identifier': 'admin_huashu_robot_mot', - 'isDeleted': 0, - 'name': '华数机械臂移动', - 'publishStatus': 1, - 'tags': '', - 'type': '' - }, - 'label': '华数机械臂移动' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'suctionFlange' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'suctionFlange', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'gripperSwitch' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'gripperSwitch', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'grindingSwitch' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'grindingSwitch', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'inputData' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1923297764415492098', - 'identifier': 'yuxing_end_gripper', - 'isDeleted': 0, - 'name': '机械臂末端夹爪控制', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '机械臂末端夹爪控制' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photographToRedis' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'redisKey' - ], - 'id': 'photographToRedis', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photographToMinio' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'minioUrl' - ], - 'id': 'photographToMinio', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'minioUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'redisKey' - } - ] - }, - 'description': '# 一、功能概述\n该组件控制海康面阵相机拍照\n\n# 二、适用设备\n品牌:海康机器人\n型号:MV-CS050-60GC\n\n# 三、接口描述\n|接口名称|描述|输入参数|输出参数|\n|-|-|-|-|-|\n|photographToRedis|执行拍照并将图片存到redis|无|redisKey|\n|photographToMinio|执行拍照并将图片存到minio|无|minioUrl|\n- redisKey:图片的redisKey, 所存的值为二进制字节数组\n- minioUrl: 图片的minio路径\n\n# 四、组件内部配置\n|配置项|说明|\n|-|-|\n|camera.serialNumber|相机序列号|\n\n# 五、部署配置\n1. 在容器管理中部署该组件的线上实例时,需要选择host模式部署,容器才能检测到相机\n2. 相机的序列号是必须配置项\n3. 如在部署时配了相机序列号后还连接不上相机,可能是相机未配置ip,需要到MVS软件中将对应相机的ip配好方可使用\n\n# 六、其他\n \n', - 'id': '1923670214986813442', - 'identifier': 'admin_hk-area-camera', - 'isDeleted': 0, - 'name': '海康面阵相机', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '海康面阵相机' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'a' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'a', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1926829346753339393', - 'identifier': 'admin_py_test', - 'isDeleted': 0, - 'name': 'PyTest', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': 'PyTest' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'suctionFlange' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'suctionFlange', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'gripperSwitch' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'gripperSwitch', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'grindingSwitch' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'grindingSwitch', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'electricalTool' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'electricalTool', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'inputData' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': 'suctionFlange接口:吸取工具/放开工具\ngripperSwitch接口:打开/关闭夹爪\ngrindingSwitch接口:吸盘吸气/放下\nelectricalTool接口:电器工具开启关闭', - 'id': '1928328390408343554', - 'identifier': 'yuxing_end_gripper_control', - 'isDeleted': 0, - 'name': '机械臂末端控制', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '机械臂末端控制' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'lineMove' - }, - 'fieldIns': [ - 'ufNum', - 'utNum', - 'strPos' - ], - 'fieldOuts': [], - 'id': 'lineMove', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'circleMove' - }, - 'fieldIns': [ - 'ufNum', - 'utNum', - 'strMidPos', - 'strEndPos' - ], - 'fieldOuts': [], - 'id': 'circleMove', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '末端点位', - 'id': 'strEndPos' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '中间点位', - 'id': 'strMidPos' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '直线运动点位', - 'id': 'strPos' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '工件号', - 'id': 'ufNum' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '工具号', - 'id': 'utNum' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1928347365615800322', - 'identifier': 'yuxing_robot-move', - 'isDeleted': 0, - 'name': '机械臂移动', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '机械臂移动' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'lineMove' - }, - 'fieldIns': [ - 'ufNum', - 'utNum', - 'strPos' - ], - 'fieldOuts': [], - 'id': 'lineMove', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'circleMove' - }, - 'fieldIns': [ - 'ufNum', - 'utNum', - 'strMidPos', - 'strEndPos' - ], - 'fieldOuts': [], - 'id': 'circleMove', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '末端点位', - 'id': 'strEndPos' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '中间点位', - 'id': 'strMidPos' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '直线运动点位', - 'id': 'strPos' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '工件号', - 'id': 'ufNum' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '工具号', - 'id': 'utNum' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1928492227604557825', - 'identifier': 'yuxing_robot-move-mk3', - 'isDeleted': 0, - 'name': '机械臂移动_mk2', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '机械臂移动_mk2' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'trigger' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'trigger', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '1是去检测位2是去上料位', - 'id': 'inputData' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '去检测位或者去上料位。\n1是检测位,2是上料位', - 'id': '1929068875915132929', - 'identifier': 'admin_detection_materials', - 'isDeleted': 0, - 'name': '去检测位/去上料位', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '去检测位/去上料位' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'a' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'a', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1929741219762585601', - 'identifier': 'admin_a', - 'isDeleted': 0, - 'name': 'java_test', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'java_test' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'atest' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'atest', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930102437072928769', - 'identifier': 'admin_py', - 'isDeleted': 0, - 'name': 'PyBuildTest02', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': 'PyBuildTest02' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'test' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'test', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930157240057585666', - 'identifier': 'admin_compent_test', - 'isDeleted': 0, - 'name': '组件测试构建', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '组件测试构建' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'test' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'test', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930158022555328513', - 'identifier': 'ichentang_com_test', - 'isDeleted': 0, - 'name': '组件测试', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '组件测试' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'triggerMark' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'triggerMark', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'inputData' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '激光位触发打标', - 'id': '1930162411034632193', - 'identifier': 'admin_laser_marking', - 'isDeleted': 0, - 'name': '激光位_触发打标', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '激光位_触发打标' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'atest' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'atest', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930165190167879681', - 'identifier': 'yuxing_py', - 'isDeleted': 0, - 'name': 'PyBuildTest02', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'PyBuildTest02' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'atest' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'atest', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930165247604678657', - 'identifier': 'yuxing_pys', - 'isDeleted': 0, - 'name': 'PyBuildTest02', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'PyBuildTest02' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'dsa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'dsa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930170196229087234', - 'identifier': 'yuxing_submit_compoent_test', - 'isDeleted': 0, - 'name': '发布组件测试', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '发布组件测试' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'qwe' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'qwe', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930211503029542914', - 'identifier': 'admin_zujian_test', - 'isDeleted': 0, - 'name': '组件发布测试', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '组件发布测试' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'detect' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'formaldehyde', - 'pm25', - 'tvoc', - 'co2', - 'temperature', - 'humidity' - ], - 'id': 'detect', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'co2' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'formaldehyde' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'humidity' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'pm25' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'temperature' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'tvoc' - } - ] - }, - 'description': '# 一、功能概述\n该组件通过检测环境中的各项环境指数\n\n# 二、适用设备\n品牌:万图思睿\n型号:SD123-E60\n\n# 三、接口描述\n|接口名称|描述|输入参数|输出参数|\n|-|-|-|-|-|\n|detect|检测各项环境指数|无|formaldehyde, pm25, tvoc, co2, temperature, humidity|\n- formaldehyde: 甲醛浓度(单位ppm)\n- pm25: pm2.5浓度(单位ug/m^3)\n- tvoc: 异味tvoc浓度(单位ppm)\n- co2: 二氧化碳浓度(单位ppm)\n- temperature: 温度(单位°C)\n- humidity: 湿度(单位RH)\n\n# 四、组件内部配置\n无\n\n# 五、部署配置\n![](http://10.21.221.1:9000/camera-picture/Snipaste_2024-07-24_09-47-44.png)\n1. 新增实例时,需指定挂载的串口,**主机路径**指定连接到设备的串口,**容器路径**填写/dev/ttyUSB0即可\n\n# 六、其他\n无\n', - 'id': '1930429689187192833', - 'identifier': 'admin_rs485-air-quality-detection', - 'isDeleted': 0, - 'name': '空气质量传感器', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '空气质量传感器' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930570897951232002', - 'identifier': 'admin_sda', - 'isDeleted': 0, - 'name': 'test', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': 'test' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'aaa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'aaa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930804086617587714', - 'identifier': 'admin_b_t', - 'isDeleted': 0, - 'name': 'buildTest', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'buildTest' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'aaa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'aaa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930820961287053314', - 'identifier': 'admin_b_td', - 'isDeleted': 0, - 'name': 'buildTestd', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'buildTestd' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'asd' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'asd', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930823478913835009', - 'identifier': 'admin_asd', - 'isDeleted': 0, - 'name': 'java_build', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'java_build' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'lineMove' - }, - 'fieldIns': [ - 'gpId', - 'isJoint', - 'ufNum', - 'utNum', - 'strPos', - 'isLinear', - 'config' - ], - 'fieldOuts': [], - 'id': 'lineMove', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'circleMove' - }, - 'fieldIns': [ - 'gpId', - 'ufNum', - 'utNum', - 'config', - 'strMidPos', - 'strEndPos', - 'isToMid', - 'isMidInt', - 'isEndJnt' - ], - 'fieldOuts': [], - 'id': 'circleMove', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '形态位', - 'id': 'config' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '组号', - 'id': 'gpId' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '末端点位是否为关节', - 'id': 'isEndJnt' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否关节点', - 'id': 'isJoint' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否直线', - 'id': 'isLinear' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '中间点位是否为关节', - 'id': 'isMidInt' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否到中间点', - 'id': 'isToMid' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '末端点位', - 'id': 'strEndPos' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '中间点位', - 'id': 'strMidPos' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '点数据', - 'id': 'strPos' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '工件号', - 'id': 'ufNum' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '工具号', - 'id': 'utNum' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930833646573625345', - 'identifier': 'admin_huashu_robot_mot01', - 'isDeleted': 0, - 'name': '华数机械臂移动', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '华数机械臂移动' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'testInput' - }, - 'fieldIns': [ - 'strLet', - 'intLet' - ], - 'fieldOuts': [], - 'id': 'testInput', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'intLet' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'strLet' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930861013656444929', - 'identifier': 'admin_pytest04', - 'isDeleted': 0, - 'name': '数据采集测试', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '数据采集测试' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'testInput' - }, - 'fieldIns': [ - 'strLet', - 'intLet' - ], - 'fieldOuts': [], - 'id': 'testInput', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'intLet' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'strLet' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930862196093657090', - 'identifier': 'admin_pytests', - 'isDeleted': 0, - 'name': '数据采集测试', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '数据采集测试' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'triggerMark' - }, - 'fieldIns': [ - 'inputData' - ], - 'fieldOuts': [], - 'id': 'triggerMark', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'inputData' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '激光位触发打标', - 'id': '1930870816502812674', - 'identifier': 'admin_laser_markingds', - 'isDeleted': 0, - 'name': '激光位_触发打标', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '激光位_触发打标' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'aaa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'aaa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930873975338012674', - 'identifier': 'admin_build_market_test', - 'isDeleted': 0, - 'name': '组件市场测试', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '组件市场测试' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'aaa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'aaa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930884802039197698', - 'identifier': 'admin_test_market', - 'isDeleted': 0, - 'name': '测试发布市场', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试发布市场' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'aaa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'aaa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': 'test', - 'id': '1930889570908319745', - 'identifier': 'admin_test_commarkst_02', - 'isDeleted': 0, - 'name': 'test', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': 'test' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'startModelDiscern' - }, - 'fieldIns': [ - 'rtspUrl', - 'uuid' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'startModelDiscern', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stopModelDiscern' - }, - 'fieldIns': [ - 'rtspUrl', - 'uuid' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'stopModelDiscern', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'getDiscernResult' - }, - 'fieldIns': [ - 'rtspUrl' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'getDiscernResult', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': 'rtsp视频流', - 'id': 'rtspUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '后续接口需要携带该uuid', - 'id': 'uuid' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': 'true: 成功 false:失败', - 'id': 'result' - } - ] - }, - 'description': '', - 'id': '1930891104110981122', - 'identifier': 'admin_rknn_discern', - 'isDeleted': 0, - 'name': '视频识别-yolo模型', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '视频识别-yolo模型' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1930071310364372993', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'tomCom' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'tomCom', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1930935970761408513', - 'identifier': 'ichentang_tom_com', - 'isDeleted': 0, - 'name': '组件审核测试55', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '组件审核测试55' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'numerical' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '烟雾值', - 'id': 'numerical' - } - ] - }, - 'description': '', - 'id': '1931213503049678850', - 'identifier': 'admin_smoke_alarm2', - 'isDeleted': 0, - 'name': '烟雾传感器_汇川', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '烟雾传感器_汇川' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isOpen' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '(1为感应到)', - 'id': 'isOpen' - } - ] - }, - 'description': '', - 'id': '1931214429894393857', - 'identifier': 'admin_photoelectric_switch', - 'isDeleted': 0, - 'name': '光电开关_汇川', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '光电开关_汇川' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'open' - }, - 'fieldIns': [ - 'red', - 'green', - 'yellow', - 'beepAlarm' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'open', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'close' - }, - 'fieldIns': [ - 'red', - 'green', - 'yellow', - 'beepAlarm' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'close', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '蜂鸣报警', - 'id': 'beepAlarm' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '绿灯', - 'id': 'green' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '红灯', - 'id': 'red' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '黄灯', - 'id': 'yellow' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1931223940080381953', - 'identifier': 'admin_indicato_light', - 'isDeleted': 0, - 'name': '指示灯_汇川', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '指示灯_汇川' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'temperature', - 'humidity' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '湿度值(0.1%)', - 'id': 'humidity' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '温度值(0.1℃)', - 'id': 'temperature' - } - ] - }, - 'description': '', - 'id': '1931273372928159746', - 'identifier': 'admin_hygrothermoscope_new', - 'isDeleted': 0, - 'name': '温湿仪_汇川', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '温湿仪_汇川' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'numerical' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '数值(0.01m3)', - 'id': 'numerical' - } - ] - }, - 'description': '', - 'id': '1931275962432729090', - 'identifier': 'admin_water_meter_new', - 'isDeleted': 0, - 'name': '水表_汇川', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '水表_汇川' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'numerical' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '噪声值', - 'id': 'numerical' - } - ] - }, - 'description': '', - 'id': '1931277881108705281', - 'identifier': 'admin_noise_sensor_new', - 'isDeleted': 0, - 'name': '噪声传感器_汇川', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '噪声传感器_汇川' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'lineMove' - }, - 'fieldIns': [ - 'strPos' - ], - 'fieldOuts': [], - 'id': 'lineMove', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'circleMove' - }, - 'fieldIns': [ - 'strMidPos', - 'strEndPos' - ], - 'fieldOuts': [], - 'id': 'circleMove', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'strEndPos' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'strMidPos' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'strPos' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1931360682945593346', - 'identifier': 'admin_yuxing_robot-move_a', - 'isDeleted': 0, - 'name': '机械臂移动', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '机械臂移动' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'voltage', - 'electric', - 'energy' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '电流(A)', - 'id': 'electric' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '总有功电能(kw.h)', - 'id': 'energy' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '电压(V)', - 'id': 'voltage' - } - ] - }, - 'description': '', - 'id': '1931953418584043521', - 'identifier': 'admin_ammeter_new', - 'isDeleted': 0, - 'name': '电流表_汇川', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '电流表_汇川' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'display' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'clear' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'clear', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '测量显示值(KG)', - 'id': 'display' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1931981664994922497', - 'identifier': 'admin_weighing_cell', - 'isDeleted': 0, - 'name': '称重传感器_汇川', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '称重传感器_汇川' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'axisX', - 'axisY', - 'axisZ' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'clear' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'clear', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': 'X轴', - 'id': 'axisX' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': 'Y轴', - 'id': 'axisY' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': 'Z轴', - 'id': 'axisZ' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1931984683509682178', - 'identifier': 'admin_angle_sensor', - 'isDeleted': 0, - 'name': '倾斜角传感器_汇川', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '倾斜角传感器_汇川' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'aaa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'aaa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1932006576095834113', - 'identifier': 'admin_dsa', - 'isDeleted': 0, - 'name': '129测试环境', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '129测试环境' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'q' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'q', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1932252213097316354', - 'identifier': 'admin_sda1', - 'isDeleted': 0, - 'name': '129测试', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '129测试' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1930071310364372993', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'dfgdgerg' - }, - 'fieldIns': [ - 'arg' - ], - 'fieldOuts': [ - 'res' - ], - 'id': 'dfgdgerg', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'test' - }, - 'fieldIns': [ - 'arg1' - ], - 'fieldOuts': [ - 'dsa' - ], - 'id': 'test', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '1', - 'id': 'arg' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '12', - 'id': 'arg1' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '1212', - 'id': 'dsa' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '2', - 'id': 'res' - } - ] - }, - 'description': '', - 'id': '1932269848425971713', - 'identifier': 'ichentang_ioppoi', - 'isDeleted': 0, - 'name': '组件审核测试', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '组件审核测试' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'sa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'sa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1932282730677059586', - 'identifier': 'admin_test_a', - 'isDeleted': 0, - 'name': '新增组件测试', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '新增组件测试' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [ - 'speedSetting', - 'reverSetting' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stop' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'stop', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '正反转设定0-正传,1-反转', - 'id': 'reverSetting' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '速度设定(500 ~ 3000之间)', - 'id': 'speedSetting' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1932640739916328961', - 'identifier': 'admin_machinery_new', - 'isDeleted': 0, - 'name': '电机_汇川', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '电机_汇川' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stop' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'stop', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1932678774137630721', - 'identifier': 'admin_water_pump_new', - 'isDeleted': 0, - 'name': '水泵_汇川', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '水泵_汇川' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'voltage', - 'electric', - 'energy' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '电流(A)', - 'id': 'electric' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '总有功电能(kw.h)', - 'id': 'energy' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '电压(V)', - 'id': 'voltage' - } - ] - }, - 'description': '', - 'id': '1932683210520080386', - 'identifier': 'admin_ammeter_mts', - 'isDeleted': 0, - 'name': '电流表_三菱', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '电流表_三菱' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'temperature', - 'humidity' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '湿度值(%)', - 'id': 'humidity' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '温度值(℃)', - 'id': 'temperature' - } - ] - }, - 'description': '', - 'id': '1932691600464875521', - 'identifier': 'admin_hygrothermoscope_mts', - 'isDeleted': 0, - 'name': '温湿仪_三菱', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '温湿仪_三菱' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'display' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'clear' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'clear', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '测量显示值(KG)', - 'id': 'display' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1932692129207226369', - 'identifier': 'admin_weighing_cell_mts', - 'isDeleted': 0, - 'name': '称重传感器_三菱', - 'publishStatus': 1, - 'tags': '[]', - 'type': '' - }, - 'label': '称重传感器_三菱' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'numerical' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '水表数值(m3)', - 'id': 'numerical' - } - ] - }, - 'description': '', - 'id': '1932692846613565442', - 'identifier': 'admin_water_meter_mts', - 'isDeleted': 0, - 'name': '水表_三菱', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '水表_三菱' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stop' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'stop', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1932693221890527234', - 'identifier': 'admin_water_pump_mts', - 'isDeleted': 0, - 'name': '水泵_三菱', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '水泵_三菱' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [ - 'speedSetting', - 'reverSetting' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stop' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'stop', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '正反转设定0-正传,1-反转', - 'id': 'reverSetting' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '速度设定(500 ~ 3000之间)', - 'id': 'speedSetting' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1932693910859485186', - 'identifier': 'admin_machinery_mts', - 'isDeleted': 0, - 'name': '电机_三菱', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '电机_三菱' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'numerical' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '噪声值', - 'id': 'numerical' - } - ] - }, - 'description': '', - 'id': '1932694551090630658', - 'identifier': 'admin_noise_sensor_mts', - 'isDeleted': 0, - 'name': '噪声传感器_三菱', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '噪声传感器_三菱' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'numerical' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '烟雾值', - 'id': 'numerical' - } - ] - }, - 'description': '', - 'id': '1932694898337058818', - 'identifier': 'admin_smoke_alarm_mts', - 'isDeleted': 0, - 'name': '烟雾传感器_三菱', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '烟雾传感器_三菱' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isOpen' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '1为感应到', - 'id': 'isOpen' - } - ] - }, - 'description': '', - 'id': '1932695175622496258', - 'identifier': 'admin_photoelectric_switch_mts', - 'isDeleted': 0, - 'name': '光电开关_三菱', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '光电开关_三菱' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'open' - }, - 'fieldIns': [ - 'red', - 'green', - 'yellow', - 'beepAlarm' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'open', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'close' - }, - 'fieldIns': [ - 'red', - 'green', - 'yellow', - 'beepAlarm' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'close', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '蜂鸣报警', - 'id': 'beepAlarm' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '绿灯', - 'id': 'green' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '红灯', - 'id': 'red' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '黄灯', - 'id': 'yellow' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1932695491411644417', - 'identifier': 'admin_indicato_light_mts', - 'isDeleted': 0, - 'name': '指示灯_三菱', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '指示灯_三菱' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'dsa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'dsa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1932992768723718146', - 'identifier': 'admin_testarrm64', - 'isDeleted': 0, - 'name': 'arrm64Test', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'arrm64Test' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'qqq' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'qqq', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1932995651653406722', - 'identifier': 'admin_pyx86tesm', - 'isDeleted': 0, - 'name': 'pytest', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'pytest' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'aaa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'aaa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1933074255580950529', - 'identifier': 'admin_sdaa', - 'isDeleted': 0, - 'name': 'dsa', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'dsa' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photographToRedis' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'colorKey', - 'depthKey' - ], - 'id': 'photographToRedis', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photographToMinio' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'colorUrl', - 'depthUrl' - ], - 'id': 'photographToMinio', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photographPointCloud' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'pointCloudUrl' - ], - 'id': 'photographPointCloud', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'colorKey' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'colorUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'depthKey' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'depthUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'pointCloudUrl' - } - ] - }, - 'description': '', - 'id': '1933423539651076097', - 'identifier': 'admin_hk-depth-camera-train', - 'isDeleted': 0, - 'name': '海康深度相机_实训', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '海康深度相机_实训' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'lineMove' - }, - 'fieldIns': [ - 'strPos' - ], - 'fieldOuts': [], - 'id': 'lineMove', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'circleMove' - }, - 'fieldIns': [ - 'strEndPos', - 'strMidPos' - ], - 'fieldOuts': [], - 'id': 'circleMove', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'strEndPos' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'strMidPos' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '', - 'id': 'strPos' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1933429566962393090', - 'identifier': 'admin_robot-move', - 'isDeleted': 0, - 'name': '机械臂_实训', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '机械臂_实训' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'axisX', - 'axisY', - 'axisZ' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'clear' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'clear', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': 'X轴', - 'id': 'axisX' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': 'Y轴', - 'id': 'axisY' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': 'Z轴', - 'id': 'axisZ' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1935214245039120385', - 'identifier': 'admin_angle_sensor_mts', - 'isDeleted': 0, - 'name': '倾斜角传感器_三菱', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '倾斜角传感器_三菱' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'tttt' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'tttt', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1935172372994240513', - 'identifier': 'admin_qqq', - 'isDeleted': 0, - 'name': 'dsa', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'dsa' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'aa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'aa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1935276202876006402', - 'identifier': 'yuxing_test_url', - 'isDeleted': 0, - 'name': '测试url发布', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试url发布' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'aa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'aa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1935892422373978113', - 'identifier': 'admin_test_url_maket1', - 'isDeleted': 0, - 'name': '测试url发布', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试url发布' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'da' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'da', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1935936018145914881', - 'identifier': 'admin_test_publish', - 'isDeleted': 0, - 'name': '测试发布', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试发布' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'init' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'init', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'outData' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'outData', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1935970166373920769', - 'identifier': 'admin_self_circulation', - 'isDeleted': 0, - 'name': '测试自循环组件', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试自循环组件' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stopLoop' - }, - 'fieldIns': [ - 'initLoopTest' - ], - 'fieldOuts': [], - 'id': 'stopLoop', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stopLootComponent' - }, - 'fieldIns': [ - 'stop' - ], - 'fieldOuts': [], - 'id': 'stopLootComponent', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'initLoopTest' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'stop' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1936988836390809602', - 'identifier': 'admin_loop_component_test', - 'isDeleted': 0, - 'name': '自循环组件测试', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '自循环组件测试' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'temperature', - 'humidity' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '湿度值(%)', - 'id': 'humidity' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '温度值(℃)', - 'id': 'temperature' - } - ] - }, - 'description': '', - 'id': '1937065619014332418', - 'identifier': 'admin_hygrothermoscope_sms', - 'isDeleted': 0, - 'name': '温湿仪_西门子', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '温湿仪_西门子' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'numerical' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'clear' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'clear', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '称量显示值(KG)', - 'id': 'numerical' - } - ] - }, - 'description': '', - 'id': '1937076920897810434', - 'identifier': 'admin_weighing_cell_sms', - 'isDeleted': 0, - 'name': '称重传感器_西门子', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '称重传感器_西门子' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'voltage', - 'electric', - 'energy' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '电流(A)', - 'id': 'electric' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '总有功电能(kw.h)', - 'id': 'energy' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '电压(V)', - 'id': 'voltage' - } - ] - }, - 'description': '', - 'id': '1937408333653078017', - 'identifier': 'admin_ammeter_new_sms', - 'isDeleted': 0, - 'name': '电流表_西门子', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '电流表_西门子' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'numerical' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '水表数值(m3)', - 'id': 'numerical' - } - ] - }, - 'description': '', - 'id': '1937421355788398594', - 'identifier': 'admin_water_meter_sms', - 'isDeleted': 0, - 'name': '水表_西门子', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '水表_西门子' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stop' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'stop', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1937421934010953729', - 'identifier': 'admin_water_pump_sms', - 'isDeleted': 0, - 'name': '水泵_西门子', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '水泵_西门子' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'numerical' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '噪声值', - 'id': 'numerical' - } - ] - }, - 'description': '', - 'id': '1937423774411071489', - 'identifier': 'admin_noise_sensor_sms', - 'isDeleted': 0, - 'name': '噪声传感器_西门子', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '噪声传感器_西门子' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'numerical' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '烟雾值', - 'id': 'numerical' - } - ] - }, - 'description': '', - 'id': '1937424208894828546', - 'identifier': 'admin_smoke_alarm_sms', - 'isDeleted': 0, - 'name': '烟雾传感器_西门子', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '烟雾传感器_西门子' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isOpen' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '为1 感应到', - 'id': 'isOpen' - } - ] - }, - 'description': '', - 'id': '1937424655353323521', - 'identifier': 'admin_photoelectric_switch_sms', - 'isDeleted': 0, - 'name': '光电开关_西门子', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '光电开关_西门子' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'axisX', - 'axisY', - 'axisZ' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'clear' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'clear', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': 'X轴', - 'id': 'axisX' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': 'Y轴', - 'id': 'axisY' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': 'Z轴', - 'id': 'axisZ' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1937425068743925762', - 'identifier': 'admin_angle_sensor_sms', - 'isDeleted': 0, - 'name': '倾斜角传感器_西门子', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '倾斜角传感器_西门子' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'open' - }, - 'fieldIns': [ - 'red', - 'green', - 'yellow', - 'beepAlarm' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'open', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'close' - }, - 'fieldIns': [ - 'red', - 'green', - 'yellow', - 'beepAlarm' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'close', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '蜂鸣报警', - 'id': 'beepAlarm' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '绿灯', - 'id': 'green' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '红灯', - 'id': 'red' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '黄灯 ', - 'id': 'yellow' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1937425846669877250', - 'identifier': 'admin_indicato_light_sms', - 'isDeleted': 0, - 'name': '指示灯_西门子', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '指示灯_西门子' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'dataInsOne' - }, - 'fieldIns': [ - 'in' - ], - 'fieldOuts': [ - 'out' - ], - 'id': 'dataInsOne', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '入参测试', - 'id': 'in' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '出餐测试', - 'id': 'out' - } - ] - }, - 'description': '', - 'id': '1937436616128405505', - 'identifier': 'admin_loop_is', - 'isDeleted': 0, - 'name': '测试自旋节点流程1', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试自旋节点流程1' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [ - 'address' - ], - 'fieldOuts': [ - 'returnValue' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'write' - }, - 'fieldIns': [ - 'address', - 'writeValue' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'write', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '寄存器地址', - 'id': 'address' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '写入值', - 'id': 'writeValue' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '返回值', - 'id': 'returnValue' - } - ] - }, - 'description': '', - 'id': '1937784395127128066', - 'identifier': 'admin_general_component_hc', - 'isDeleted': 0, - 'name': '通用组件_汇川', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '通用组件_汇川' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [ - 'address' - ], - 'fieldOuts': [ - 'returnValue' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'write' - }, - 'fieldIns': [ - 'address', - 'writeValue' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'write', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '寄存器地址', - 'id': 'address' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '写入值', - 'id': 'writeValue' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '返回值', - 'id': 'returnValue' - } - ] - }, - 'description': '', - 'id': '1937795326217355265', - 'identifier': 'admin_general_component_sms', - 'isDeleted': 0, - 'name': '通用组件_西门子', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '通用组件_西门子' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stretch' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'stretch', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'retract' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'retract', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1935256865875214337', - 'identifier': 'admin_da', - 'isDeleted': 0, - 'name': '测试url组件', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试url组件' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [ - 'address' - ], - 'fieldOuts': [ - 'returnValue' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'write' - }, - 'fieldIns': [ - 'address', - 'writeValue' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'write', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '寄存器地址', - 'id': 'address' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '写入值', - 'id': 'writeValue' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '返回值', - 'id': 'returnValue' - } - ] - }, - 'description': '', - 'id': '1937814469708677121', - 'identifier': 'admin_general_component_mts', - 'isDeleted': 0, - 'name': '通用组件_三菱', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '通用组件_三菱' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [ - 'speedSetting', - 'reverSetting' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stop' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'stop', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '正反转设定0-正传,1-反转', - 'id': 'reverSetting' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '速度设定(500 ~ 3000)', - 'id': 'speedSetting' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1937820728885313538', - 'identifier': 'admin_machinery_new_sms', - 'isDeleted': 0, - 'name': '电机_西门子', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '电机_西门子' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1938074234456178689', - 'identifier': 'admin_loop_test', - 'isDeleted': 0, - 'name': '自循环测试组件', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '自循环测试组件' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'encodeBool' - }, - 'fieldIns': [ - 'trage' - ], - 'fieldOuts': [ - 'putTest' - ], - 'id': 'encodeBool', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'OBJECT', - 'defaultValue': null, - 'desc': '', - 'id': 'trage' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'putTest' - } - ] - }, - 'description': '', - 'id': '1939937150252146689', - 'identifier': 'admin_bool_test', - 'isDeleted': 0, - 'name': '接收布尔值测试', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '接收布尔值测试' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'a1' - }, - 'fieldIns': [ - 'aa' - ], - 'fieldOuts': [ - 'bb' - ], - 'id': 'a1', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'aa' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'bb' - } - ] - }, - 'description': '', - 'id': '1940598960244576258', - 'identifier': 'yuxing_aaa', - 'isDeleted': 0, - 'name': 'newTest', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'newTest' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1921771229133996034', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'aa' - }, - 'fieldIns': [ - 'a' - ], - 'fieldOuts': [ - 'd' - ], - 'id': 'aa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'a' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'd' - } - ] - }, - 'description': '', - 'id': '1940599117145100289', - 'identifier': 'yuxing_a', - 'isDeleted': 0, - 'name': 'newB', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'newB' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'tomCom' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'tomCom', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940953004498034689', - 'identifier': 'admin_tom_com_maket1', - 'isDeleted': 0, - 'name': '组件审核测试55', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '组件审核测试55' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'startModelDiscern' - }, - 'fieldIns': [ - 'rtspUrl', - 'uuid' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'startModelDiscern', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stopModelDiscern' - }, - 'fieldIns': [ - 'rtspUrl', - 'uuid' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'stopModelDiscern', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'getDiscernResult' - }, - 'fieldIns': [ - 'rtspUrl' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'getDiscernResult', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': 'rtsp视频流', - 'id': 'rtspUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '后续接口需要携带该uuid', - 'id': 'uuid' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': 'true: 成功 false:失败', - 'id': 'result' - } - ] - }, - 'description': '', - 'id': '1940955832637530114', - 'identifier': 'admin_rknn_discern_maket1', - 'isDeleted': 0, - 'name': '视频识别-yolo模型', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '视频识别-yolo模型' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'startModelDiscern' - }, - 'fieldIns': [ - 'rtspUrl', - 'uuid' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'startModelDiscern', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stopModelDiscern' - }, - 'fieldIns': [ - 'rtspUrl', - 'uuid' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'stopModelDiscern', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'getDiscernResult' - }, - 'fieldIns': [ - 'rtspUrl' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'getDiscernResult', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': 'rtsp视频流', - 'id': 'rtspUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '后续接口需要携带该uuid', - 'id': 'uuid' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': 'true: 成功 false:失败', - 'id': 'result' - } - ] - }, - 'description': '', - 'id': '1940956898947047426', - 'identifier': 'admin_rknn_discern_maket2', - 'isDeleted': 0, - 'name': '视频识别-yolo模型', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '视频识别-yolo模型' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'moveEnd' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'moveEnd', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'moveOrigin' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'moveOrigin', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940957013829033986', - 'identifier': 'admin_quality_detection_rail_new', - 'isDeleted': 0, - 'name': '新仿真质检滑轨', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '新仿真质检滑轨' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photograph' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'minioPath' - ], - 'id': 'photograph', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': 'minio图片地址', - 'id': 'minioPath' - } - ] - }, - 'description': '仿真相机,用于分拣产品', - 'id': '1940961276680544257', - 'identifier': 'admin_sorting_simulation_camera_new', - 'isDeleted': 0, - 'name': '新案例组件-分拣仿真相机', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '新案例组件-分拣仿真相机' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'punch' - }, - 'fieldIns': [ - 'enabled' - ], - 'fieldOuts': [], - 'id': 'punch', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '启用状态', - 'id': 'enabled' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940962144754671617', - 'identifier': 'admin_simulated_wheel_installation_n', - 'isDeleted': 0, - 'name': '新仿真车轮安装控制', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '新仿真车轮安装控制' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'driver1' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'driver1', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'driver2' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'driver2', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940963329549082625', - 'identifier': 'admin_simulated_lock_screw_new', - 'isDeleted': 0, - 'name': '新仿真锁丝机控制', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '新仿真锁丝机控制' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'marking' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'marking', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940963392547528706', - 'identifier': 'admin_simulated_laser_marking_new', - 'isDeleted': 0, - 'name': '新仿真激光打标', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '新仿真激光打标' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'punch' - }, - 'fieldIns': [ - 'enabled' - ], - 'fieldOuts': [], - 'id': 'punch', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'suck' - }, - 'fieldIns': [ - 'enabled' - ], - 'fieldOuts': [], - 'id': 'suck', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '启用状态', - 'id': 'enabled' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940963453855670273', - 'identifier': 'admin_grind_cylinder_control_new', - 'isDeleted': 0, - 'name': '新仿真打磨位气缸控制', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '新仿真打磨位气缸控制' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'punch' - }, - 'fieldIns': [ - 'enabled' - ], - 'fieldOuts': [], - 'id': 'punch', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'enabled' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940964259447250945', - 'identifier': 'admin_simulated_mark_cylinder_new', - 'isDeleted': 0, - 'name': '新仿真打标位气缸控制', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '新仿真打标位气缸控制' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'rotate' - }, - 'fieldIns': [ - 'enabled' - ], - 'fieldOuts': [], - 'id': 'rotate', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '翻转状态', - 'id': 'enabled' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940964356595720193', - 'identifier': 'admin_simulated_shell_rotate_new', - 'isDeleted': 0, - 'name': '新仿真车身翻转控制', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '新仿真车身翻转控制' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photograph' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'minioPath' - ], - 'id': 'photograph', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': 'minio图片地址', - 'id': 'minioPath' - } - ] - }, - 'description': '仿真相机,用于分拣产品', - 'id': '1940976877595598849', - 'identifier': 'admin_sorting_simulation_camera', - 'isDeleted': 0, - 'name': '案例组件-分拣仿真相机', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '案例组件-分拣仿真相机' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'punch' - }, - 'fieldIns': [ - 'enabled' - ], - 'fieldOuts': [], - 'id': 'punch', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '启用状态', - 'id': 'enabled' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940976886839844865', - 'identifier': 'admin_simulated_wheel_installation', - 'isDeleted': 0, - 'name': '仿真车轮安装控制', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '仿真车轮安装控制' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'rotate' - }, - 'fieldIns': [ - 'enabled' - ], - 'fieldOuts': [], - 'id': 'rotate', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '翻转状态', - 'id': 'enabled' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940976891717820418', - 'identifier': 'admin_simulated_shell_rotate', - 'isDeleted': 0, - 'name': '仿真车身翻转控制', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '仿真车身翻转控制' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'punch' - }, - 'fieldIns': [ - 'enabled' - ], - 'fieldOuts': [], - 'id': 'punch', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'enabled' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940976896444801026', - 'identifier': 'admin_simulated_mark_cylinder', - 'isDeleted': 0, - 'name': '仿真打标位气缸控制', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '仿真打标位气缸控制' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'punch' - }, - 'fieldIns': [ - 'enabled' - ], - 'fieldOuts': [], - 'id': 'punch', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'suck' - }, - 'fieldIns': [ - 'enabled' - ], - 'fieldOuts': [], - 'id': 'suck', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '启用状态', - 'id': 'enabled' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940976900932706305', - 'identifier': 'admin_grind_cylinder_control', - 'isDeleted': 0, - 'name': '仿真打磨位气缸控制', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '仿真打磨位气缸控制' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'marking' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'marking', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940976905529663489', - 'identifier': 'admin_simulated_laser_marking', - 'isDeleted': 0, - 'name': '仿真激光打标', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '仿真激光打标' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'driver1' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'driver1', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'driver2' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'driver2', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940976909942071297', - 'identifier': 'admin_simulated_lock_screw', - 'isDeleted': 0, - 'name': '仿真锁丝机控制', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '仿真锁丝机控制' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'moveEnd' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'moveEnd', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'moveOrigin' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'moveOrigin', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1940976914434170881', - 'identifier': 'admin_quality_detection_rail', - 'isDeleted': 0, - 'name': '仿真质检滑轨', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '仿真质检滑轨' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'move' - }, - 'fieldIns': [ - 'position' - ], - 'fieldOuts': [], - 'id': 'move', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'robotSuck' - }, - 'fieldIns': [ - 'suck' - ], - 'fieldOuts': [], - 'id': 'robotSuck', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'suckEnabled' - }, - 'fieldIns': [ - 'suck' - ], - 'fieldOuts': [], - 'id': 'suckEnabled', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'gripperEnabled' - }, - 'fieldIns': [ - 'enable' - ], - 'fieldOuts': [], - 'id': 'gripperEnabled', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'polishingEnabled' - }, - 'fieldIns': [ - 'enable' - ], - 'fieldOuts': [], - 'id': 'polishingEnabled', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否夹爪使能', - 'id': 'enable' - }, - { - 'arrayType': 'DOUBLE', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '6维坐标', - 'id': 'position' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '吸取或者放下', - 'id': 'suck' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '仿真机械臂', - 'id': '1941083850538295298', - 'identifier': 'admin_simulated-arm', - 'isDeleted': 0, - 'name': '案例组件-机械臂仿真', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '案例组件-机械臂仿真' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stretch' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'stretch', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'retract' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'retract', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1941374320652918786', - 'identifier': 'admin_screw_secondary_position', - 'isDeleted': 0, - 'name': '螺丝位_二次定位', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '螺丝位_二次定位' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stretch' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'stretch', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'retract' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'retract', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1941399305362677762', - 'identifier': 'admin_secondary_positioning', - 'isDeleted': 0, - 'name': '轮胎组装位_二次定位', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '轮胎组装位_二次定位' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'value' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'value' - } - ] - }, - 'description': '', - 'id': '1942481248669999106', - 'identifier': 'admin_test0708', - 'isDeleted': 0, - 'name': 'test1', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'test1' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'temperature', - 'humidity' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'humidity' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'temperature' - } - ] - }, - 'description': '', - 'id': '1943670542740930562', - 'identifier': 'admin_test', - 'isDeleted': 0, - 'name': '温湿仪传感器', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '温湿仪传感器' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'startModelDiscern' - }, - 'fieldIns': [ - 'rtspUrl', - 'uuid' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'startModelDiscern', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stopModelDiscern' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'stopModelDiscern', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'getDiscernResult' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'getDiscernResult', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'rtspUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'uuid' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'result' - } - ] - }, - 'description': '', - 'id': '1943684259574628353', - 'identifier': 'admin_test_', - 'isDeleted': 0, - 'name': '监控摄像头', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '监控摄像头' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'numerical' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'numerical' - } - ] - }, - 'description': '', - 'id': '1943690929436540930', - 'identifier': 'admin_tes', - 'isDeleted': 0, - 'name': '噪声传感器', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '噪声传感器' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'query' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'frequency', - 'ampltude' - ], - 'id': 'query', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'ampltude' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'frequency' - } - ] - }, - 'description': '', - 'id': '1943696394451075073', - 'identifier': 'admin_te', - 'isDeleted': 0, - 'name': '振动传感器', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '振动传感器' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photographToRedis' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'colorKey', - 'depthKey' - ], - 'id': 'photographToRedis', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photographToMinio' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'colorUrl', - 'depthUrl' - ], - 'id': 'photographToMinio', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'photographPointCloud' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'pointCloudUrl' - ], - 'id': 'photographPointCloud', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'colorKey' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'colorUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'depthKey' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'depthUrl' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'pointCloudUrl' - } - ] - }, - 'description': '', - 'id': '1946051467929174018', - 'identifier': 'admin_hk-depth-camera-new', - 'isDeleted': 0, - 'name': '海康深度相机new', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '海康深度相机new' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'extend' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'extend', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'shrink' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'shrink', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1947122167581589506', - 'identifier': 'admin_laser_position_cylinder', - 'isDeleted': 0, - 'name': '激光位_伸缩气缸', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '激光位_伸缩气缸' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'exten' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'exten', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'shrink' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'shrink', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1947125708077481986', - 'identifier': 'admin_loading_expansion', - 'isDeleted': 0, - 'name': '上料伸缩', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '上料伸缩' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'exten' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'exten', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'shrink' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'shrink', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1947213616390160385', - 'identifier': 'admin_laser_secondary_positioning', - 'isDeleted': 0, - 'name': '激光-二次定位', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '激光-二次定位' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'getPoint' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'point' - ], - 'id': 'getPoint', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'point' - } - ] - }, - 'description': '', - 'id': '1947824501462745090', - 'identifier': 'admin_get_robot_point', - 'isDeleted': 0, - 'name': '获取机械臂点位', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '获取机械臂点位' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 't1' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 't1', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1948666655621857281', - 'identifier': 'admin_zujian_kaifa', - 'isDeleted': 0, - 'name': '组件开发', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '组件开发' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1948668356965777410', - 'identifier': 'admin_biaozhun', - 'isDeleted': 0, - 'name': '组件标准化封装', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '组件标准化封装' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'testAbc' - }, - 'fieldIns': [ - 'cc' - ], - 'fieldOuts': [], - 'id': 'testAbc', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'cc' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1950133681697898497', - 'identifier': 'admin_test_bb', - 'isDeleted': 0, - 'name': 'abc', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'loop' - }, - 'label': 'abc' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'jiantin' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'jiantin', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1950795259215945729', - 'identifier': 'admin_jianting_test', - 'isDeleted': 0, - 'name': '简体测试', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'loop' - }, - 'label': '简体测试' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'inin' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'ouou' - ], - 'id': 'inin', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'ouou' - } - ] - }, - 'description': '', - 'id': '1950817677787602945', - 'identifier': 'admin_linster_test', - 'isDeleted': 0, - 'name': '监听测试', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'loop' - }, - 'label': '监听测试' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'jjjj' - }, - 'fieldIns': [ - 'halo' - ], - 'fieldOuts': [ - 'h' - ], - 'id': 'jjjj', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'halo' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'h' - } - ] - }, - 'description': '', - 'id': '1950835171815792642', - 'identifier': 'admin_j20', - 'isDeleted': 0, - 'name': 'j20', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'loop' - }, - 'label': 'j20' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'LOOP', - 'desc': '', - 'eventApi': { - 'topic': 'avc' - }, - 'fieldIns': [ - 'cc' - ], - 'fieldOuts': [ - 'c' - ], - 'id': 'avc', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'cc' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'c' - } - ] - }, - 'description': '', - 'id': '1950846484734357505', - 'identifier': 'admin_j50', - 'isDeleted': 0, - 'name': 'j50', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'loop' - }, - 'label': 'j50' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'aaa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'aaa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1951190154701783042', - 'identifier': 'admin_reso_test', - 'isDeleted': 0, - 'name': '资源优化', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'normal' - }, - 'label': '资源优化' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'getKeyword' - }, - 'fieldIns': [ - 'order' - ], - 'fieldOuts': [ - 'start', - 'end' - ], - 'id': 'getKeyword', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '用户语音文本', - 'id': 'order' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '释放的水果名', - 'id': 'end' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '起始夹取的水果名', - 'id': 'start' - } - ] - }, - 'description': '', - 'id': '1952192673158057985', - 'identifier': 'admin_get_keyword', - 'isDeleted': 0, - 'name': '关键词提取', - 'publishStatus': 0, - 'tags': '["ai"]', - 'type': '' - }, - 'label': '关键词提取' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'hello' - }, - 'fieldIns': [ - 'hello' - ], - 'fieldOuts': [], - 'id': 'hello', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'hello' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1953026515652489217', - 'identifier': 'admin_py_repo_test02', - 'isDeleted': 0, - 'name': '资源优化02', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'normal' - }, - 'label': '资源优化02' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'close' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'close', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1957344717860478978', - 'identifier': 'admin_clong2', - 'isDeleted': 0, - 'name': '创龙板子test2', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'normal' - }, - 'label': '创龙板子test2' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [ - 'inputAddress' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'close' - }, - 'fieldIns': [ - 'inputAddress' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'close', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '输入地址', - 'id': 'inputAddress' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1957371518473183233', - 'identifier': 'admin_clong3', - 'isDeleted': 0, - 'name': '创龙test3_输入', - 'publishStatus': -1, - 'tags': '[]', - 'type': 'normal' - }, - 'label': '创龙test3_输入' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [ - 'inputAddress' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stop' - }, - 'fieldIns': [ - 'inputAddress' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'stop', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '地址', - 'id': 'inputAddress' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1957626301893287937', - 'identifier': 'admin_chuanglong_output', - 'isDeleted': 0, - 'name': '创龙_输出_16', - 'publishStatus': -1, - 'tags': '[]', - 'type': 'normal' - }, - 'label': '创龙_输出_16' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'readValue' - }, - 'fieldIns': [ - 'inputAddress' - ], - 'fieldOuts': [ - 'returnData' - ], - 'id': 'readValue', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'inputAddress' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'returnData' - } - ] - }, - 'description': '', - 'id': '1957634721593663490', - 'identifier': 'admin_chuanglong_input', - 'isDeleted': 0, - 'name': '创龙_输入', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'normal' - }, - 'label': '创龙_输入' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'jk' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'jk', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1957684010769879041', - 'identifier': 'admin_kjh', - 'isDeleted': 0, - 'name': 'uui', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'normal' - }, - 'label': 'uui' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [ - 'inputAddress' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stop' - }, - 'fieldIns': [ - 'inputAddress' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'stop', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '地址', - 'id': 'inputAddress' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '是否成功', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1958336148371062786', - 'identifier': 'admin_chuanglong_output32', - 'isDeleted': 0, - 'name': '创龙_输出_32', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'normal' - }, - 'label': '创龙_输出_32' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [ - 'inputAddress' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'stop' - }, - 'fieldIns': [ - 'inputAddress' - ], - 'fieldOuts': [ - 'isSuccess' - ], - 'id': 'stop', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'inputAddress' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'isSuccess' - } - ] - }, - 'description': '', - 'id': '1958438863784820737', - 'identifier': 'admin_chuanglong_output_usb', - 'isDeleted': 0, - 'name': '创龙_输出_usb', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'normal' - }, - 'label': '创龙_输出_usb' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - }, - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'close' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'close', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1958772925707763713', - 'identifier': 'admin_clong211', - 'isDeleted': 0, - 'name': '创龙板子test2', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'normal' - }, - 'label': '创龙板子test2' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'aa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'aa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1958773389908164610', - 'identifier': 'admin_test_url_maket111', - 'isDeleted': 0, - 'name': '测试url发布', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试url发布' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'aa' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'aa', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1958773443238739970', - 'identifier': 'admin_test_url_maket111111', - 'isDeleted': 0, - 'name': '测试url发布', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试url发布' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'readValue' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'returnData' - ], - 'id': 'readValue', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'returnData' - } - ] - }, - 'description': '', - 'id': '1958797750630809601', - 'identifier': 'admin_chuanglong_vibration_sensor', - 'isDeleted': 0, - 'name': '创龙_振动传感器', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'normal' - }, - 'label': '创龙_振动传感器' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'start' - }, - 'fieldIns': [], - 'fieldOuts': [ - 'returnData' - ], - 'id': 'start', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '返回数据', - 'id': 'returnData' - } - ] - }, - 'description': '', - 'id': '1960246626338320385', - 'identifier': 'admin_connect_test', - 'isDeleted': 0, - 'name': '连接test', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'normal' - }, - 'label': '连接test' - }, - { - 'comp': { - 'codeLanguage': '', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': null, - 'description': '', - 'id': '1960608992428597249', - 'identifier': 'admin_aaaaaa', - 'isDeleted': 0, - 'name': 'aaaaaaa', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': 'aaaaaaa' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': null, - 'description': '', - 'id': '1960610210957795330', - 'identifier': 'admin_aaaaa11a', - 'isDeleted': 0, - 'name': 'aaaaa11aa', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': 'aaaaa11aa' - }, - { - 'comp': { - 'codeLanguage': '', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': null, - 'description': '', - 'id': '1960678406729539586', - 'identifier': 'admin_project_001', - 'isDeleted': 0, - 'name': '', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '' - }, - { - 'comp': { - 'codeLanguage': '', - 'componentClassify': '设备数采与控制交互组件', - 'createUser': '1123598821738675201', - 'def': null, - 'description': '', - 'id': '1960680605924761602', - 'identifier': 'admin_project123', - 'isDeleted': 0, - 'name': '', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '' - } - ], - 'label': '设备数采与控制交互组件' - }, - { - 'children': [ - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '测试组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'interface0425Puls' - }, - 'fieldIns': [ - 'plusInput' - ], - 'fieldOuts': [ - 'plusOutput' - ], - 'id': 'interface0425Puls', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'plusInput' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'plusOutput' - } - ] - }, - 'description': '', - 'id': '1915678768798150658', - 'identifier': 'admin_test0425_jy', - 'isDeleted': 0, - 'name': '测试0425', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '测试0425' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '测试组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': '' - }, - 'fieldIns': [ - 'text' - ], - 'fieldOuts': [ - 'text' - ], - 'id': '', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'text' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '', - 'id': 'text' - } - ] - }, - 'description': 'text', - 'id': '1930910536925450242', - 'identifier': 'admin_text', - 'isDeleted': 0, - 'name': 'text', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'text' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '测试组件', - 'createUser': '1930071310364372993', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'ooooo' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'ooooo', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1931249989920804866', - 'identifier': 'ichentang_ooooo', - 'isDeleted': 0, - 'name': '组件审核测试22', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '组件审核测试22' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '测试组件', - 'createUser': '1930071310364372993', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'ooooo' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'ooooo', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1931253478660235265', - 'identifier': 'ichentang_ooooo1', - 'isDeleted': 0, - 'name': '组件审核测试11', - 'publishStatus': -1, - 'tags': '[]', - 'type': '' - }, - 'label': '组件审核测试11' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '测试组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1949638813948919810', - 'identifier': 'admin_component_type', - 'isDeleted': 0, - 'name': 'componentType', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'componentType' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '测试组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1949648993573904386', - 'identifier': 'admin_component_type01', - 'isDeleted': 0, - 'name': 'componentType01', - 'publishStatus': 0, - 'tags': '[]', - 'type': 'normal' - }, - 'label': 'componentType01' - }, - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '测试组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1949660256971304961', - 'identifier': 'admiN_test111', - 'isDeleted': 0, - 'name': '测ll', - 'publishStatus': -1, - 'tags': '[]', - 'type': 'normal' - }, - 'label': '测ll' - } - ], - 'label': '测试组件' - }, - { - 'children': [ - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '文本数据AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'add1' - }, - 'fieldIns': [ - 'counter' - ], - 'fieldOuts': [ - 'addcounter' - ], - 'id': 'add1', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'counter' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'addcounter' - } - ] - }, - 'description': '', - 'id': '1927989396466622465', - 'identifier': 'admin_counter', - 'isDeleted': 0, - 'name': '计数器', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '计数器' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '文本数据AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'conditionTest' - }, - 'fieldIns': [ - 'counter', - 'targetNum' - ], - 'fieldOuts': [ - 'counter', - 'isDone' - ], - 'id': 'conditionTest', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'counter' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'targetNum' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': null, - 'desc': '', - 'id': 'counter' - }, - { - 'arrayType': null, - 'dataType': 'BOOLEAN', - 'defaultValue': null, - 'desc': '', - 'id': 'isDone' - } - ] - }, - 'description': '', - 'id': '1927989430897664001', - 'identifier': 'admin_counter-judge', - 'isDeleted': 0, - 'name': '计数器判断', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '计数器判断' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '文本数据AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'match' - }, - 'fieldIns': [ - 'minIoURL' - ], - 'fieldOuts': [ - 'outminIoURL' - ], - 'id': 'match', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '日志数据', - 'id': 'minIoURL' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '返回的可访问的URL', - 'id': 'outminIoURL' - } - ] - }, - 'description': '', - 'id': '1952212067271626753', - 'identifier': 'admin_keyword_matching', - 'isDeleted': 0, - 'name': '关键词匹配', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '关键词匹配' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '文本数据AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'classification' - }, - 'fieldIns': [ - 'keywords', - 'keyword' - ], - 'fieldOuts': [ - 'result' - ], - 'id': 'classification', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '关键词统计', - 'id': 'keyword' - }, - { - 'arrayType': 'STRING', - 'dataType': 'ARRAY', - 'defaultValue': null, - 'desc': '关键词列表', - 'id': 'keywords' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '标准ISDP响应', - 'id': 'result' - } - ] - }, - 'description': '', - 'id': '1952242447211089922', - 'identifier': 'admin_ruleclassification', - 'isDeleted': 0, - 'name': '规则分类', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '规则分类' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '文本数据AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'classification' - }, - 'fieldIns': [ - 'minIoUrl' - ], - 'fieldOuts': [ - 'outputUrl' - ], - 'id': 'classification', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '需要清洗的日志文件', - 'id': 'minIoUrl' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '返回可访问的url', - 'id': 'outputUrl' - } - ] - }, - 'description': '', - 'id': '1952242451468308481', - 'identifier': 'admin_log_classification', - 'isDeleted': 0, - 'name': '日志分类', - 'publishStatus': 0, - 'tags': '', - 'type': '' - }, - 'label': '日志分类' - }, - { - 'comp': { - 'codeLanguage': 'Python', - 'componentClassify': '文本数据AI组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'classification' - }, - 'fieldIns': [ - 'minIoUrl' - ], - 'fieldOuts': [ - 'outputUrl' - ], - 'id': 'classification', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '需要清洗的日志文件', - 'id': 'minIoUrl' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - }, - { - 'arrayType': null, - 'dataType': 'STRING', - 'defaultValue': null, - 'desc': '返回可访问的url', - 'id': 'outputUrl' - } - ] - }, - 'description': '', - 'id': '1952246315059826689', - 'identifier': 'admin_log_classification_maket1', - 'isDeleted': 0, - 'name': '日志分类组件生成', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': '日志分类组件生成' - } - ], - 'label': '文本数据AI组件' - }, - { - 'children': [ - { - 'comp': { - 'codeLanguage': 'Java', - 'componentClassify': '网络通信组件', - 'createUser': '1123598821738675201', - 'def': { - 'apiOut': { - 'desc': '', - 'id': 'done' - }, - 'apis': [ - { - 'apiType': 'EVENT', - 'desc': '', - 'eventApi': { - 'topic': 'res' - }, - 'fieldIns': [], - 'fieldOuts': [], - 'id': 'res', - 'restApi': { - 'headers': [], - 'inputType': '', - 'method': null, - 'outputType': '', - 'url': '' - }, - 'socketApi': null - } - ], - 'dataIns': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'input' - } - ], - 'dataOuts': [ - { - 'arrayType': null, - 'dataType': null, - 'defaultValue': null, - 'desc': '', - 'id': 'output' - } - ] - }, - 'description': '', - 'id': '1935945354595315714', - 'identifier': 'admin_rawr', - 'isDeleted': 0, - 'name': 'tt', - 'publishStatus': 0, - 'tags': '[]', - 'type': '' - }, - 'label': 'tt' - } - ], - 'label': '网络通信组件' - } -]; - -export const tempEventList = [ - { - "createBy": "1123598821738675201", - "createTime": 1752197919000, - "data": "{\"pubApps\": [], \"subApps\": [\"1943601642177236993\", \"1950799849741271042\", \"1948213415817437185\", \"1943213909198553090\"]}", - "description": "测试", - "id": "1943485051785117697", - "name": "事件测试", - "sceneId": "1943133286851096577", - "tenantId": "000000", - "topic": "testTopic01/scene_14", - "updateBy": "1123598821738675201", - "updateTime": 1754900639000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1752199434000, - "data": "{\"pubApps\": [\"1943484061488971778\"], \"subApps\": [\"1943484061488971778\"]}", - "description": "测试1", - "id": "1943491404054331393", - "name": "测试1", - "sceneId": "1930187368673484802", - "tenantId": "000000", - "topic": "test1/app_16", - "updateBy": "1123598821738675201", - "updateTime": 1752225281000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1752199546000, - "data": "{\"pubApps\": [], \"subApps\": []}", - "description": "测试2", - "id": "1943491874374221825", - "name": "测试2", - "sceneId": "1930187368673484802", - "tenantId": "000000", - "topic": "test2/app_16", - "updateBy": "1123598821738675201", - "updateTime": 1752202125000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1752393670000, - "data": "", - "description": "111", - "id": "1944306088012091393", - "name": "事件测试", - "sceneId": "1926533046308691969", - "tenantId": "000000", - "topic": "testopic1/scene_4", - "updateBy": "1123598821738675201", - "updateTime": 1752393670000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1752393815000, - "data": "{\"subApps\": [\"1926500839217160194\"]}", - "description": "111", - "id": "1944306697620623361", - "name": "testTopie", - "sceneId": "1922135918419456002", - "tenantId": "000000", - "topic": "testtopic1/app_1", - "updateBy": "1123598821738675201", - "updateTime": 1752393901000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1752393873000, - "data": "", - "description": "qwe", - "id": "1944306940089143298", - "name": "t1", - "sceneId": "1926533046308691969", - "tenantId": "000000", - "topic": "testtopic1/scene_4", - "updateBy": "1123598821738675201", - "updateTime": 1752393873000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1753068411000, - "data": "{\"pubApps\": [\"1947167301642137602\", \"1947173582788538370\", \"1950438244205387777\"]}", - "description": "螺丝装配完毕事件", - "id": "1947136156904894466", - "name": "螺丝装配完毕", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "screwAssembly/scene_15", - "updateBy": "1123598821738675201", - "updateTime": 1753864830000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1753068459000, - "data": "{\"pubApps\": [\"1947167301642137602\"], \"subApps\": [\"1947284188103356417\", \"1947243578403237889\", \"1947206991200038913\"]}", - "description": "轮胎装配完毕", - "id": "1947136358973878273", - "name": "轮胎装配完毕事件", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "tireAssembly/scene_15", - "updateBy": "1123598821738675201", - "updateTime": 1753345428000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1753076894000, - "data": "{\"pubApps\": [\"1947167301642137602\", \"1950008134922854402\", \"1950438244205387777\"], \"subApps\": [\"1947172396249296898\", \"1947173582788538370\"]}", - "description": "底盘车身放置完毕", - "id": "1947171738729230337", - "name": "底盘车身放置完毕", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "chassisCompleted/scene_15", - "updateBy": "1123598821738675201", - "updateTime": 1755684500000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1753094533000, - "data": "{\"pubApps\": [\"1947206991200038913\"]}", - "description": "", - "id": "1947245721264762881", - "name": "换夹爪完毕", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "jiazhuaok/app_4", - "updateBy": "1123598821738675201", - "updateTime": 1753094578000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1753094565000, - "data": "{\"pubApps\": [\"1947247574085971970\", \"1947206991200038913\"], \"subApps\": [\"1947206991200038913\"]}", - "description": "", - "id": "1947245855201472514", - "name": "夹爪放置完毕", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "fangzhiOK/app_4", - "updateBy": "1123598821738675201", - "updateTime": 1753095384000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1753094611000, - "data": "{\"subApps\": [\"1947247574085971970\", \"1947206991200038913\"]}", - "description": "", - "id": "1947246051025137665", - "name": "开始夹爪更换", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "beginjiazhua/app_4", - "updateBy": "1123598821738675201", - "updateTime": 1753095384000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1753108889000, - "data": "{\"pubApps\": [\"1947284188103356417\", \"1951085958320037889\"], \"subApps\": [\"1947218433047441409\"]}", - "description": "", - "id": "1947305934328082434", - "name": "车辆装配完毕", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "sendCar/app_4", - "updateBy": "1123598821738675201", - "updateTime": 1756190905000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1753109223000, - "data": "{\"pubApps\": [\"1947218433047441409\"], \"subApps\": [\"1947840123565682689\", \"1960181129977057282\", \"1947841090445029378\", \"1947228684962410498\", \"1947861173212983298\", \"1947226560178335745\"]}", - "description": "", - "id": "1947307336429383681", - "name": "打标完毕", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "senddabiao/app_5", - "updateBy": "1123598821738675201", - "updateTime": 1756187298000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1753345580000, - "data": "{\"pubApps\": [\"1947167301642137602\"], \"subApps\": [\"1947284188103356417\"]}", - "description": "lytai2", - "id": "1948298690581159937", - "name": "轮胎装配完毕2", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "lytai2/scene_15", - "updateBy": "1123598821738675201", - "updateTime": 1753345648000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1753347971000, - "data": "{\"pubApps\": [\"1947167301642137602\", \"1950008134922854402\"], \"subApps\": [\"1947284188103356417\", \"1951085958320037889\", \"1950832440820572161\"]}", - "description": "", - "id": "1948308718289608705", - "name": "轮胎3", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "luntai3/scene_15", - "updateBy": "1123598821738675201", - "updateTime": 1756190905000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1753862108000, - "data": "{\"pubApps\": [\"1950438244205387777\"], \"subApps\": [\"1950465070467252225\"]}", - "description": "ttt", - "id": "1950465166609088513", - "name": "测试接收", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "testLister/app_11", - "updateBy": "1123598821738675201", - "updateTime": 1753863106000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1754027176000, - "data": "{\"pubApps\": [\"1950832440820572161\"], \"subApps\": [\"1950832440820572161\"]}", - "description": "", - "id": "1951157510460862466", - "name": "测试事件4", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "test_Common/scene_15", - "updateBy": "1123598821738675201", - "updateTime": 1755674220000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1754556951000, - "data": "", - "description": "string", - "id": "1953379549169266690", - "name": "string", - "sceneId": "string", - "tenantId": "000000", - "topic": "string", - "updateBy": "1123598821738675201", - "updateTime": 1754556951000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1754557667000, - "data": "{\"pubApps\": [\"1950832440820572161\"], \"subApps\": [\"1950832440820572161\"], \"inputDataTypes\": [{\"id\": \"\", \"desc\": \"\", \"dataType\": \"INTEGER\", \"arrayType\": null, \"defaultValue\": null}], \"outputDataTypes\": [{\"id\": \"\", \"desc\": \"\", \"dataType\": \"INTEGER\", \"arrayType\": null, \"defaultValue\": null}]}", - "description": "string", - "id": "1953382553134157826", - "name": "string", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "string", - "updateBy": "1123598821738675201", - "updateTime": 1754640513000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1754620337000, - "data": "{\"inputDataTypes\": [{\"id\": \"dataInput\", \"desc\": \"dataInput\", \"dataType\": \"STRING\", \"arrayType\": null, \"defaultValue\": \"1\"}], \"outputDataTypes\": [{\"id\": \"dataOut\", \"desc\": \"dataOut\", \"dataType\": \"STRING\", \"arrayType\": null, \"defaultValue\": \"2\"}]}", - "description": "事件体测试", - "id": "1953645409743732737", - "name": "事件体测试", - "sceneId": "1943133286851096577", - "tenantId": "000000", - "topic": "事件体测试/scene_14", - "updateBy": "1123598821738675201", - "updateTime": 1754620337000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1754620788000, - "data": "{\"pubApps\": [\"1950832440820572161\"], \"subApps\": [\"1950832440820572161\"], \"inputDataTypes\": [{\"id\": \"aa\", \"desc\": \"aa\", \"dataType\": \"BOOLEAN\", \"arrayType\": null, \"defaultValue\": \"\"}], \"outputDataTypes\": [{\"id\": \"bb\", \"desc\": \"bb\", \"dataType\": \"ARRAY\", \"arrayType\": null, \"defaultValue\": \"\"}]}", - "description": "1", - "id": "1953647299357376513", - "name": "事件体测试", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "eventBodyTest/scene_15", - "updateBy": "1123598821738675201", - "updateTime": 1754640513000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1755692859000, - "data": "{\"pubApps\": [\"1947226560178335745\"], \"subApps\": [\"1947228684962410498\"]}", - "description": "", - "id": "1958143890057121794", - "name": "小车质检通过", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "passCar/app_6", - "updateBy": "1123598821738675201", - "updateTime": 1755692901000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1755740447000, - "data": "{\"pubApps\": [\"1947226560178335745\"], \"subApps\": [\"1947228684962410498\"]}", - "description": "", - "id": "1958343492081340418", - "name": "小车质检通过新", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "pscar/app_6", - "updateBy": "1123598821738675201", - "updateTime": 1755740472000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1755757721000, - "data": "{\"pubApps\": [\"1947226560178335745\"], \"subApps\": [\"1947228684962410498\"]}", - "description": "", - "id": "1958415943196790785", - "name": "小车质检6", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "passCar666/app_6", - "updateBy": "1123598821738675201", - "updateTime": 1755757736000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1755759103000, - "data": "{\"pubApps\": [\"1947226560178335745\"], \"subApps\": []}", - "description": "", - "id": "1958421737145421825", - "name": "小车质检7", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "passCar777/app_6", - "updateBy": "1123598821738675201", - "updateTime": 1755759159000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1755760052000, - "data": "{\"pubApps\": [\"1947226560178335745\"], \"subApps\": [\"1947228684962410498\"]}", - "description": "", - "id": "1958425718273921025", - "name": "小车质检8", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "zhijian8/app_6", - "updateBy": "1123598821738675201", - "updateTime": 1756172825000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1756171874000, - "data": "", - "description": "", - "id": "1960153024373772289", - "name": "事件后缀测试", - "sceneId": "1958050905957126145", - "tenantId": "000000", - "topic": "topicTest1/app_1", - "updateBy": "1123598821738675201", - "updateTime": 1756171874000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1756174123000, - "data": "{\"pubApps\": [\"1960181129977057282\", \"1947226560178335745\"], \"subApps\": [\"1960176336869052417\", \"1947228684962410498\"]}", - "description": "", - "id": "1960162457703206914", - "name": "小车质检pass", - "sceneId": "1947111285680418818", - "tenantId": "000000", - "topic": "carPass0826/scene_15", - "updateBy": "1123598821738675201", - "updateTime": 1756187298000 - }, - { - "createBy": "1123598821738675201", - "createTime": 1756794662000, - "data": "{\"subApps\": []}", - "description": "", - "id": "1962765190136659970", - "name": "test", - "sceneId": "1931196258454605825", - "tenantId": "000000", - "topic": "test/app_6", - "updateBy": "1123598821738675201", - "updateTime": 1756794736000 - } -] \ No newline at end of file From 6a21ce0d592c2f30201e593a8356965210ea4cf0 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 14 Oct 2025 14:51:46 +0800 Subject: [PATCH 03/89] =?UTF-8?q?pref(flowEditor):=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=9C=AA=E4=BD=BF=E7=94=A8=E7=9A=84=E7=BB=84=E4=BB=B6=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=EF=BC=8C=E4=BC=98=E5=8C=96redux=E4=B8=ADDispatch?= =?UTF-8?q?=E7=9A=84ts=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useFlowEditorState.ts | 4 +++- src/pages/flowEditor/index.tsx | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hooks/useFlowEditorState.ts b/src/hooks/useFlowEditorState.ts index 510a8f8..04220ca 100644 --- a/src/hooks/useFlowEditorState.ts +++ b/src/hooks/useFlowEditorState.ts @@ -4,6 +4,8 @@ import { debounce } from 'lodash'; import { useSelector, useDispatch } from 'react-redux'; import { updateCanvasDataMap } from '@/store/ideContainer'; +import { Dispatch } from 'redux'; + export const useFlowEditorState = (initialData?: any) => { const [nodes, setNodes] = useState([]); const [edges, setEdges] = useState([]); @@ -27,7 +29,7 @@ export const useFlowEditorState = (initialData?: any) => { const historyTimeoutRef = useRef(null); const updateCanvasDataMapDebounced = useRef( - debounce((dispatch: Function, canvasDataMap: any, id: string, nodes: Node[], edges: Edge[]) => { + debounce((dispatch: Dispatch, canvasDataMap: any, id: string, nodes: Node[], edges: Edge[]) => { dispatch(updateCanvasDataMap({ ...canvasDataMap, [id]: { nodes, edges } diff --git a/src/pages/flowEditor/index.tsx b/src/pages/flowEditor/index.tsx index 50b4b7b..e4ae4d5 100644 --- a/src/pages/flowEditor/index.tsx +++ b/src/pages/flowEditor/index.tsx @@ -6,9 +6,7 @@ import { Node, Edge } from '@xyflow/react'; -import { useSelector, useDispatch } from 'react-redux'; import { nodeTypes } from '@/components/FlowEditor/node'; -import SideBar from './sideBar/sideBar'; import HistoryProvider from './components/historyContext'; import FlowEditorMain from './FlowEditorMain'; import { useFlowEditorState } from '@/hooks/useFlowEditorState'; From 92b4a783deb0da3e21409a08d8d2bda7b0b146b4 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 14 Oct 2025 15:08:11 +0800 Subject: [PATCH 04/89] =?UTF-8?q?fix(flowEditor):=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E8=8F=9C=E5=8D=95=E5=85=B3=E9=97=AD=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E5=B9=B6=E4=BC=98=E5=8C=96=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 onCloseMenu 回调以在操作后关闭上下文菜单 - 更新节点类型检查逻辑以防止未定义错误 --- src/hooks/useFlowCallbacks.ts | 16 ++++++---------- src/pages/flowEditor/FlowEditorMain.tsx | 1 + .../flowEditor/components/nodeContextMenu.tsx | 11 ++++++++--- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index 32f8f82..6c11e7d 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -122,7 +122,7 @@ export const useFlowCallbacks = ( return sourceDataType === targetDataType; }; - // 修改 onNodesChange 函数,添加防抖机制 + // onNodesChange 函数,添加防抖机制 const onNodesChange = useCallback( (changes: any) => { const newNodes = applyNodeChanges(changes, nodes); @@ -153,7 +153,7 @@ export const useFlowCallbacks = ( [nodes, edges] ); - // 修改 onEdgesChange 函数 + // onEdgesChange 函数 const onEdgesChange = useCallback( (changes: any) => { const newEdges = applyEdgeChanges(changes, edges); @@ -173,7 +173,7 @@ export const useFlowCallbacks = ( setIsDelete(true); }, []); - // 修改 onConnect 函数 + // onConnect 函数 const onConnect = useCallback( (params: any) => { // 获取源节点和目标节点 @@ -268,7 +268,6 @@ export const useFlowCallbacks = ( }, []); // 侧边栏节点实例 - // 修改 onDrop 函数 const onDrop = useCallback( (event: React.DragEvent) => { event.preventDefault(); @@ -400,7 +399,7 @@ export const useFlowCallbacks = ( // saveFlowDataToServer(); }, [nodes, editingNode, closeEditModal]); - // 修改删除节点函数 + // 删除节点函数 const deleteNode = useCallback((node: Node) => { setNodes((nds: Node[]) => nds.filter((n) => n.id !== node.id)); setEdges((eds: Edge[]) => eds.filter((e) => e.source !== node.id && e.target !== node.id)); @@ -417,7 +416,7 @@ export const useFlowCallbacks = ( }, 0); }, [nodes, edges]); - // 修改删除边函数 + // 删除边函数 const deleteEdge = useCallback((edge: Edge) => { setEdges((eds: Edge[]) => eds.filter((e) => e.id !== edge.id)); @@ -452,7 +451,6 @@ export const useFlowCallbacks = ( }, []); // 在边上添加节点的具体实现 - // 修改 addNodeOnEdge 函数 const addNodeOnEdge = useCallback((nodeType: string, node: any) => { if (!edgeForNodeAdd || !reactFlowInstance) return; @@ -532,7 +530,6 @@ export const useFlowCallbacks = ( }, [edgeForNodeAdd, nodes, reactFlowInstance, edges]); // 在画布上添加节点 - // 修改 addNodeOnPane 函数 const addNodeOnPane = useCallback((nodeType: string, position: { x: number; y: number }, node?: any) => { if (!reactFlowInstance) return; @@ -632,7 +629,7 @@ export const useFlowCallbacks = ( } }); - // 修改运行处理函数 + // 运行处理函数 const handleRun = useCallback(async (running: boolean) => { if (running) { // 启动运行 @@ -641,7 +638,6 @@ export const useFlowCallbacks = ( const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'; let wsApi = `${protocol}://${window.location.host}/ws/v1/bpms-runtime`; if (window.location.host.includes('localhost')) { - // WS_API = `wss://${host}/ws/v1/bpms-runtime`; wsApi = `ws://api.myserver.com:4121/ws/v1/bpms-runtime`; } const uri = `${wsApi}?x-auth0-token=${token}`; diff --git a/src/pages/flowEditor/FlowEditorMain.tsx b/src/pages/flowEditor/FlowEditorMain.tsx index 6ae58f1..2c27956 100644 --- a/src/pages/flowEditor/FlowEditorMain.tsx +++ b/src/pages/flowEditor/FlowEditorMain.tsx @@ -254,6 +254,7 @@ const FlowEditorMain: React.FC = (props) => { onDelete={deleteNode} onEdit={editNode} onCopy={copyNode} + onCloseMenu={setMenu} /> )} diff --git a/src/pages/flowEditor/components/nodeContextMenu.tsx b/src/pages/flowEditor/components/nodeContextMenu.tsx index a2ce794..78c963e 100644 --- a/src/pages/flowEditor/components/nodeContextMenu.tsx +++ b/src/pages/flowEditor/components/nodeContextMenu.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { Menu, Dropdown } from '@arco-design/web-react'; import { Node } from '@xyflow/react'; @@ -8,24 +8,29 @@ interface NodeContextMenuProps { onDelete?: (node: Node) => void; onCopy?: (node: Node) => void; onEdit?: (node: Node) => void; + onCloseMenu?: (data: React.Dispatch>) => void; } const NodeContextMenu: React.FC = ({ node, onDelete, onCopy, - onEdit + onEdit, + onCloseMenu }) => { const handleDelete = () => { onDelete && onDelete(node); + onCloseMenu(null); }; const handleCopy = () => { onCopy && onCopy(node); + onCloseMenu(null); }; const handleEdit = () => { onEdit && onEdit(node); + onCloseMenu(null); }; return ( @@ -34,7 +39,7 @@ const NodeContextMenu: React.FC = ({ 编辑节点 - {(!['start', 'end'].includes(node.type)) && ( + {(!['start', 'end'].includes(node?.type)) && ( <> 复制节点 From efb1983ed1b19dd32a3086ba261c0664c17a4186 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 14 Oct 2025 15:18:05 +0800 Subject: [PATCH 05/89] =?UTF-8?q?feat(flowEditor):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E8=AE=B0=E5=BD=95=E5=BF=AB=E7=85=A7=E9=98=B2?= =?UTF-8?q?=E6=8A=96=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 引入 lodash 的 debounce 方法优化性能 - 对 takeSnapshot 事件处理函数进行防抖处理 - 设置防抖延迟时间为 100 毫秒 - 避免频繁触发快照导致的性能问题 --- src/pages/flowEditor/components/historyContext.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/flowEditor/components/historyContext.tsx b/src/pages/flowEditor/components/historyContext.tsx index 35bb9ca..00ba4b3 100644 --- a/src/pages/flowEditor/components/historyContext.tsx +++ b/src/pages/flowEditor/components/historyContext.tsx @@ -1,4 +1,5 @@ import React, { createContext, useContext, useState, useCallback, useRef, useEffect } from 'react'; +import { debounce } from 'lodash'; import { Node, Edge } from '@xyflow/react'; interface HistoryContextType { @@ -147,11 +148,11 @@ const HistoryProvider: React.FC = ({ // 监听 takeSnapshot 事件 useEffect(() => { - const handleTakeSnapshot = ((event: CustomEvent) => { + const handleTakeSnapshot = debounce((event: CustomEvent) => { const { nodes, edges } = event.detail; updateCurrentState(nodes, edges); takeSnapshot(); - }) as EventListener; + }, 100) as EventListener; document.addEventListener('takeSnapshot', handleTakeSnapshot); return () => { From eced9e27b4ed8ef8b5cac9a4e49271af53fb7ce4 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 14 Oct 2025 15:27:32 +0800 Subject: [PATCH 06/89] =?UTF-8?q?fix(flowEditor):=20=E5=85=B3=E9=97=AD?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E7=BC=96=E8=BE=91=E6=A8=A1=E6=80=81=E6=A1=86?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在节点删除、复制、编辑操作后关闭编辑模态框 - 在添加节点操作后关闭编辑模态框 - 更新节点上下文菜单组件属性定义 -优化上下文菜单操作后的模态框关闭逻辑 --- src/pages/flowEditor/FlowEditorMain.tsx | 4 ++++ src/pages/flowEditor/components/nodeContextMenu.tsx | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/pages/flowEditor/FlowEditorMain.tsx b/src/pages/flowEditor/FlowEditorMain.tsx index 2c27956..093ade5 100644 --- a/src/pages/flowEditor/FlowEditorMain.tsx +++ b/src/pages/flowEditor/FlowEditorMain.tsx @@ -184,6 +184,7 @@ const FlowEditorMain: React.FC = (props) => { snapGrid={[2, 2]} onNodesDelete={(deleted) => { setNodes((nds) => nds.filter((n) => !deleted.find((d) => d.id === n.id))); + setIsEditModalOpen(false); }} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} @@ -255,6 +256,7 @@ const FlowEditorMain: React.FC = (props) => { onEdit={editNode} onCopy={copyNode} onCloseMenu={setMenu} + onCloseOpenModal={setIsEditModalOpen} /> )} @@ -275,6 +277,7 @@ const FlowEditorMain: React.FC = (props) => { onEdit={editEdge} onAddNode={(edge) => { setEdgeForNodeAdd(edge); + setIsEditModalOpen(false); setMenu(null); // 关闭上下文菜单 }} /> @@ -295,6 +298,7 @@ const FlowEditorMain: React.FC = (props) => { position={menu.position!} onAddNode={(nodeType: string, position: { x: number, y: number }, node: any) => { addNodeOnPane(nodeType, position, node); + setIsEditModalOpen(false); setMenu(null); // 关闭上下文菜单 }} /> diff --git a/src/pages/flowEditor/components/nodeContextMenu.tsx b/src/pages/flowEditor/components/nodeContextMenu.tsx index 78c963e..b41ea2e 100644 --- a/src/pages/flowEditor/components/nodeContextMenu.tsx +++ b/src/pages/flowEditor/components/nodeContextMenu.tsx @@ -9,6 +9,7 @@ interface NodeContextMenuProps { onCopy?: (node: Node) => void; onEdit?: (node: Node) => void; onCloseMenu?: (data: React.Dispatch>) => void; + onCloseOpenModal?: (boolean: boolean) => void; } const NodeContextMenu: React.FC = ({ @@ -16,20 +17,24 @@ const NodeContextMenu: React.FC = ({ onDelete, onCopy, onEdit, - onCloseMenu + onCloseMenu, + onCloseOpenModal }) => { const handleDelete = () => { onDelete && onDelete(node); + onCloseOpenModal(false); onCloseMenu(null); }; const handleCopy = () => { onCopy && onCopy(node); + onCloseOpenModal(false); onCloseMenu(null); }; const handleEdit = () => { onEdit && onEdit(node); + onCloseOpenModal(false); onCloseMenu(null); }; From c6ad30b213e13d2bf7532734f2ae438ea63f5356 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 14 Oct 2025 16:19:24 +0800 Subject: [PATCH 07/89] =?UTF-8?q?fix(hooks):=20=E9=98=B2=E6=AD=A2=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E5=8F=98=E6=9B=B4=E6=97=B6=E4=BF=AE=E6=94=B9=E5=86=BB?= =?UTF-8?q?=E7=BB=93=E5=AF=B9=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 onNodesChange 中添加深度克隆逻辑 --- src/hooks/useFlowCallbacks.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index 6c11e7d..97db27b 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -125,7 +125,9 @@ export const useFlowCallbacks = ( // onNodesChange 函数,添加防抖机制 const onNodesChange = useCallback( (changes: any) => { - const newNodes = applyNodeChanges(changes, nodes); + // 深度克隆节点数组以避免修改冻结的对象 + const clonedNodes = JSON.parse(JSON.stringify(nodes)); + const newNodes = applyNodeChanges(changes, clonedNodes); setNodes(newNodes); // 如果需要在节点变化时执行某些操作,可以在这里添加 From da34978f6c1f617d681946fc97ca1970d56b18c1 Mon Sep 17 00:00:00 2001 From: ZLY Date: Wed, 15 Oct 2025 15:53:27 +0800 Subject: [PATCH 08/89] =?UTF-8?q?feat(flow):=20=E5=AE=9E=E7=8E=B0=E5=BE=AA?= =?UTF-8?q?=E7=8E=AF=E8=8A=82=E7=82=B9=E5=8A=9F=E8=83=BD=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=BC=96=E8=BE=91=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改节点类型获取逻辑,从 node.data.type 获取节点类型-为组件标识符添加默认空字符串处理- 在节点编辑器接口中添加索引签名以支持动态属性 - 阻止循环开始节点展示编辑框 - 更新本地节点编辑器以支持循环开始和结束节点类型 - 添加条件表格组件用于配置循环跳出条件- 在流程回调钩子中引入循环节点组件和相关处理逻辑 - 新增循环节点组件,包含开始和结束节点的视觉表示 - 实现添加循环节点时自动创建开始和结束节点及其连接边 - 优化数据转换逻辑以支持新的循环节点结构 --- .../FlowEditor/node/loopNode/LoopNode.tsx | 90 +++++ .../nodeEditors/LocalNodeEditor.tsx | 3 +- .../components/ConditionsTable.tsx | 341 ++++++++++++++++++ .../nodeEditors/components/LoopEditor.tsx | 19 +- .../FlowEditor/nodeEditors/index.tsx | 2 + src/hooks/useFlowCallbacks.ts | 122 ++++++- src/pages/flowEditor/index.tsx | 2 + src/utils/convertFlowData.ts | 6 +- 8 files changed, 574 insertions(+), 11 deletions(-) create mode 100644 src/components/FlowEditor/node/loopNode/LoopNode.tsx create mode 100644 src/components/FlowEditor/nodeEditors/components/ConditionsTable.tsx diff --git a/src/components/FlowEditor/node/loopNode/LoopNode.tsx b/src/components/FlowEditor/node/loopNode/LoopNode.tsx new file mode 100644 index 0000000..65e3117 --- /dev/null +++ b/src/components/FlowEditor/node/loopNode/LoopNode.tsx @@ -0,0 +1,90 @@ +import React from 'react'; +import { useStore } from '@xyflow/react'; +import styles from '@/components/FlowEditor/node/style/baseOther.module.less'; +import DynamicIcon from '@/components/DynamicIcon'; +import { Handle, Position } from '@xyflow/react'; + +// 循环节点组件,用于显示循环开始和循环结束节点 +const LoopNode = ({ data, id }: { data: any; id: string }) => { + const title = data.title || '循环节点'; + const isStartNode = data.type === 'LOOP_START'; + + // 获取节点选中状态 - 适配React Flow v12 API + const isSelected = useStore((state) => + state.nodeLookup.get(id)?.selected || false + ); + + // 设置图标 + const setIcon = () => { + if (isStartNode) { + return ; + } + else { + return ; + } + }; + + return ( +
+
+ {setIcon()} + {title} +
+ + {/* 左侧输入连接点 */} + + + {/* 右侧输出连接点 */} + + + {/* 顶部连接点,用于标识循环开始和结束节点是一组 */} + + + {/* 节点内容区域 */} +
+
+
+
+
+
+
+ ); +}; + +export default LoopNode; \ No newline at end of file diff --git a/src/components/FlowEditor/nodeEditors/LocalNodeEditor.tsx b/src/components/FlowEditor/nodeEditors/LocalNodeEditor.tsx index b9df0a5..baa192e 100644 --- a/src/components/FlowEditor/nodeEditors/LocalNodeEditor.tsx +++ b/src/components/FlowEditor/nodeEditors/LocalNodeEditor.tsx @@ -35,7 +35,8 @@ const LocalNodeEditor: React.FC = ({ return ; case 'WAIT': // 等待 return ; - case 'LOOP': // 循环 + case 'LOOP_START': // 循环 + case 'LOOP_END': // 循环 return ; case 'CYCLE': // 周期 return ; diff --git a/src/components/FlowEditor/nodeEditors/components/ConditionsTable.tsx b/src/components/FlowEditor/nodeEditors/components/ConditionsTable.tsx new file mode 100644 index 0000000..b6422b4 --- /dev/null +++ b/src/components/FlowEditor/nodeEditors/components/ConditionsTable.tsx @@ -0,0 +1,341 @@ +import React, { useState, useEffect } from 'react'; +import { Input, Select, Table, Button } from '@arco-design/web-react'; +import { IconDelete } from '@arco-design/web-react/icon'; + +interface TableDataItem { + key: number | string; + id: string; + apiOutId: string, + lftVal: string, + operator: string, + valueType: string, + rgtVal: string + + [key: string]: any; // 允许其他自定义字段 +} + + +interface ConditionsTableProps { + initialData: any; + nodeData: any; + onUpdateData: (data: any) => void; +} + +const dataTypeOptions = [ + { label: '字符串', value: 'string' }, + { label: '数字', value: 'number' }, + { label: '布尔值(真)', value: 'boolean-true' }, + { label: '布尔值(假)', value: 'boolean-false' }, + { label: '表达式', value: 'expression' } +]; + +const operationOptions = [ + { label: '==', value: '==' }, + { label: '!=', value: '!=' }, + { label: '>', value: '>' }, + { label: '<', value: '<' }, + { label: '>=', value: '>=' }, + { label: '<=', value: '<=' } + // { label: '包含', value: 'contains' }, + // { label: '不包含', value: 'notContains' }, + // { label: '匹配正则表达式', value: 'matchRegex' }, + // { label: '不匹配正则表达式', value: 'notMatchRegex' }, + // { label: '为空', value: 'isEmpty' }, + // { label: '不为空', value: 'isNotEmpty' }, + // { label: '为真', value: 'isTrue' }, + // { label: '为假', value: 'isFalse' }, + // { label: '为空或为假', value: 'isEmptyOrFalse' }, + // { label: '不为空或为真', value: 'isNotEmptyOrTrue' } +]; + +const ConditionsTable: React.FC = ({ + initialData, + nodeData, + onUpdateData + }) => { + const [data, setData] = useState([]); + const [apiOutsList, setApiOutsList] = useState([]); + const [leftList, setLeftList] = useState([]); + + const columns = [ + { + title: '序号', + dataIndex: 'index', + render: (_: any, record: TableDataItem, i) => ( + {i + 1} + ) + }, + { + title: '逻辑出口', + dataIndex: 'apiOutId', + render: (_: any, record: TableDataItem) => ( + handleSave({ ...record, apiOutId: value })} + placeholder="请输入逻辑出口" + /> + ) + }, + { + title: '左值', + dataIndex: 'lftVal', + render: (_: any, record: TableDataItem) => ( + handleSave({ ...record, operator: value })} + placeholder="请选择运算/比较符" + /> + ) + }, + { + title: '右值', + dataIndex: 'valueType', + render: (_: any, record: TableDataItem) => ( +
+ handleSave({ ...record, rgtVal: value })} + placeholder={'请输入'} + /> + ) : ()} +
+ ) + }, + { + title: '操作', + dataIndex: 'op', + render: (_: any, record: TableDataItem) => ( + + ) + } + ]; + + const convertData = (originData) => { + console.log('apiOutsList:', apiOutsList); + const apiOutIds = apiOutsList; + const conditions = originData.map(item => { + let expression = ''; + if (item.valueType.includes('boolean')) { + const splitStr = item.valueType.split('-')[1]; + expression = `$.${item.lftVal}${item.operator}${splitStr}`; + } + else expression = `$.${item.lftVal}${item.operator}${item.rgtVal}`; + if (item.apiOutId && !apiOutIds.includes(item.apiOutId)) { + apiOutIds.push(item.apiOutId); + } + return { + apiOutId: item.apiOutId, + valueType: item.valueType, + expression: expression + }; + }); + return { + type: nodeData.type, + customDef: JSON.stringify({ + apiOutIds, + conditions, + // 只需要动态添加开始节点的NodeId, 循环开始的节点不允许编辑信息的,所以接口需要的信息会在节点实例的时候配置 + loopStartNodeId: nodeData.component.loopStartNodeId + }) + }; + }; + + const getOperator = (expr: string) => { + let operator; + if (expr.includes('==')) { + operator = '=='; + } + else if (expr.includes('>=')) { + operator = '>='; + } + else if (expr.includes('<=')) { + operator = '<='; + } + else if (expr.includes('<')) { + operator = '<'; + } + else if (expr.includes('>')) { + operator = '>'; + } + else { + operator = '!='; + } + return operator; + }; + + // 反转结构的函数,将处理后的数据转回原始格式 + const reverseDataStructure = (processedData: any) => { + try { + const parsedCustomDef = JSON.parse(processedData.customDef); + if (!parsedCustomDef.conditions) { + return []; + } + + return parsedCustomDef.conditions.map((condition: any, index: number) => { + // 解析表达式以获取左值、操作符和右值 + let lftVal = ''; + let operator = ''; + let rgtVal = ''; + const valueType = condition.valueType || ''; + + if (condition.expression) { + // 处理布尔值表达式 + if (valueType.includes('boolean')) { + const splitStr = valueType.split('-')[1]; + operator = getOperator(condition.expression); + const pattern = new RegExp(`\\$\\.(.+)(${operator})${splitStr}`); + const match = condition.expression.match(pattern); + if (match) { + lftVal = match[1]; + operator = match[2]; + } + } + // 处理其他类型的表达式 + else { + // 简单的解析逻辑,可能需要根据实际表达式格式进行调整 + const match = condition.expression.match(/\$\.([^=!<>]+)(==|!=|>=|<=|>|<)(.+)/); + if (match) { + lftVal = match[1]; + operator = match[2]; + rgtVal = match[3]; + } + } + } + + return { + key: index, + id: Date.now(), + apiOutId: condition.apiOutId || '', + lftVal, + operator, + valueType, + rgtVal + }; + }); + } catch (e) { + console.error('Error parsing customDef:', e); + return []; + } + }; + + // 提取apiIns和apiOuts中的name属性,合并成一个一维数组 + const extractApiNames = () => { + const apiInsNames = nodeData.parameters?.apiIns?.map((item: any) => item.name) || []; + const apiOutsNames = nodeData.parameters?.apiOuts?.map((item: any) => item.name) || []; + return [...apiInsNames, ...apiOutsNames]; + }; + + // 提取dataIns中的属性,并构造成options结构 + const extractDataInsOptions = () => { + const dataInsOptions = nodeData.parameters?.dataIns?.map((item: any) => ({ + value: item.id, + label: item.id + })) || []; + return [...dataInsOptions]; + }; + + const handleSave = (row: TableDataItem) => { + const newData = [...data]; + const index = newData.findIndex((item) => row.key === item.key); + if (index >= 0) { + newData.splice(index, 1, { ...newData[index], ...row }); + } + else { + newData.push(row); + } + setData(newData); + // 重新构建数据结构 + const newComponentData = convertData(newData); + onUpdateData(newComponentData); + }; + + const removeRow = (key: number | string) => { + const newData = data.filter((item) => item.key !== key); + setData(newData); + // 重新构建数据结构 + const newComponentData = convertData(newData); + onUpdateData(newComponentData); + }; + + const addRow = () => { + const newKey = Date.now(); + const newRow = { + key: newKey, + id: '', + apiOutId: '', + lftVal: '', + operator: '', + valueType: '', + rgtVal: '' + }; + const newData = [...data, newRow]; + setData(newData); + // 重新构建数据结构 + const newComponentData = convertData(newData); + onUpdateData(newComponentData); + }; + + // 监听nodeData.parameters.dataIns的变化,更新leftList + useEffect(() => { + if (nodeData.parameters?.dataIns) { + setLeftList(extractDataInsOptions()); + } + }, [nodeData.parameters?.dataIns]); + + + useEffect(() => { + try { + console.log('nodeData:', nodeData); + setApiOutsList(extractApiNames()); + setLeftList(extractDataInsOptions()); + setData(reverseDataStructure(initialData)); + } catch (e) { + setApiOutsList([]); + setLeftList([]); + setData([]); + } + }, []); + + return ( + <> + + + + ); +}; + +export default ConditionsTable; \ No newline at end of file diff --git a/src/components/FlowEditor/nodeEditors/components/LoopEditor.tsx b/src/components/FlowEditor/nodeEditors/components/LoopEditor.tsx index b87aba5..b667b6e 100644 --- a/src/components/FlowEditor/nodeEditors/components/LoopEditor.tsx +++ b/src/components/FlowEditor/nodeEditors/components/LoopEditor.tsx @@ -1,8 +1,9 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { NodeEditorProps } from '@/components/FlowEditor/nodeEditors'; -import { Typography } from '@arco-design/web-react'; +import { Typography, Slider } from '@arco-design/web-react'; import { IconUnorderedList } from '@arco-design/web-react/icon'; -import ParamsTable from './ParamsTable'; +import ParamsTable from '@/components/FlowEditor/nodeEditors/components/ParamsTable'; +import ConditionsTable from '@/components/FlowEditor/nodeEditors/components/ConditionsTable'; const LoopEditor: React.FC = ({ nodeData, updateNodeData }) => { return ( @@ -17,6 +18,18 @@ const LoopEditor: React.FC = ({ nodeData, updateNodeData }) => }); }} /> + + + 跳出循环条件 + + { + updateNodeData('component', { + ...data + }); + }} /> ); }; diff --git a/src/components/FlowEditor/nodeEditors/index.tsx b/src/components/FlowEditor/nodeEditors/index.tsx index efe2ef4..efef826 100644 --- a/src/components/FlowEditor/nodeEditors/index.tsx +++ b/src/components/FlowEditor/nodeEditors/index.tsx @@ -10,6 +10,8 @@ export interface NodeEditorProps { node?: Node; nodeData: any; updateNodeData: (key: string, value: any) => void; + + [key: string]: any; } // 节点编辑器映射 diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index 97db27b..ec036c6 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -17,6 +17,7 @@ import { defaultNodeTypes } from '@/components/FlowEditor/node/types/defaultType import useWebSocket from '@/hooks/useWebSocket'; import { useAlignmentGuidelines } from '@/hooks/useAlignmentGuidelines'; import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode'; +import LoopNode from '@/components/FlowEditor/node/loopNode/LoopNode'; import BasicNode from '@/components/FlowEditor/node/basicNode/BasicNode'; import { updateCanvasDataMap } from '@/store/ideContainer'; @@ -59,7 +60,7 @@ export const useFlowCallbacks = ( const apiIns = nodeParams.apiIns || []; if (apiOuts.some((api: any) => (api.name || api.id) === handleId) || - apiIns.some((api: any) => (api.name || api.id) === handleId)) { + apiIns.some((api: any) => (api.name || api.id) === handleId) || (handleId.includes('loop'))) { return 'api'; } @@ -190,7 +191,6 @@ export const useFlowCallbacks = ( // 获取源节点和目标节点的参数信息 const sourceParams = sourceNode.data?.parameters || {}; const targetParams = targetNode.data?.parameters || {}; - console.log(sourceParams, targetParams, params); // 获取源handle和目标handle的类型 (api或data) const sourceHandleType = getHandleType(params.sourceHandle, sourceParams); @@ -287,6 +287,12 @@ export const useFlowCallbacks = ( y: event.clientY }); + // 特殊处理循环节点,添加开始和结束节点 + if (nodeData.nodeType === 'LOOP') { + addLoopNodeWithStartEnd(position, nodeData); + return; + } + const newNode = { id: `${nodeData.nodeType}-${Date.now()}`, type: nodeData.nodeType, @@ -318,6 +324,107 @@ export const useFlowCallbacks = ( [reactFlowInstance, edges] ); + // 添加循环节点及其开始和结束节点 + const addLoopNodeWithStartEnd = useCallback((position: { x: number, y: number }, nodeData: any) => { + // 创建循环开始节点 + const loopStartNode = { + id: `LOOP_START-${Date.now()}`, + type: 'LOOP', // 使用本地节点类型 + position: { x: position.x, y: position.y }, + data: { + title: '循环开始', + type: 'LOOP_START', + parameters: { + apiIns: [], + apiOuts: [{ name: 'loopStart', desc: '', dataType: '', defaultValue: '' }], + dataIns: [], + dataOuts: [] + }, + component: {} + } + + }; + + // 创建循环结束节点 + const loopEndNode = { + id: `LOOP_END-${Date.now()}`, + type: 'LOOP', // 使用本地节点类型 + position: { x: position.x + 400, y: position.y }, + data: { + title: '循环结束', + type: 'LOOP_END', + parameters: { + apiIns: [{ name: 'continue', desc: '', dataType: '', defaultValue: '' }], + apiOuts: [{ name: 'break', desc: '', dataType: '', defaultValue: '' }], + dataIns: [{ + 'arrayType': null, + 'dataType': 'INTEGER', + 'defaultValue': 10, + 'desc': '最大循环次数', + 'id': 'maxTime' + }], + dataOuts: [] + }, + component: { + type: 'LOOP_END', + customDef: '', + loopStartNodeId: loopStartNode.id // 这里的参数是为了提供在组件内部处理数据是使用,最后这个字段要序列化后放进customDef + } + } + }; + + loopStartNode.data.component = { + type: 'LOOP_START', + customDef: JSON.stringify({ loopEndNodeId: loopEndNode.id }) + }; + + // 创建连接边(连接循环开始和结束节点的顶部连接点) + const newEdges = [ + { + id: `${loopStartNode.id}-${loopEndNode.id}-group`, + source: loopStartNode.id, + target: loopEndNode.id, + sourceHandle: `${loopStartNode.id}-group`, + targetHandle: `${loopEndNode.id}-group`, + type: 'custom' + } + ]; + + // 将未定义的节点动态追加进nodeTypes + const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); + if (!nodeMap.includes('LOOP')) { + registerNodeType('LOOP', LoopNode, '循环'); + } + + setNodes((nds: Node[]) => { + const newNodes = [...nds, loopStartNode, loopEndNode]; + + // 添加节点后记录历史 + setTimeout(() => { + const event = new CustomEvent('takeSnapshot', { + detail: { nodes: [...newNodes], edges: [...edges, ...newEdges] } + }); + document.dispatchEvent(event); + }, 0); + + return newNodes; + }); + + setEdges((eds: Edge[]) => { + const updatedEdges = [...eds, ...newEdges]; + + // 添加边后记录历史 + setTimeout(() => { + const event = new CustomEvent('takeSnapshot', { + detail: { nodes: [...nodes, loopStartNode, loopEndNode], edges: [...updatedEdges] } + }); + document.dispatchEvent(event); + }, 0); + + return updatedEdges; + }); + }, [nodes, edges]); + const onNodeDrag = useCallback( (_: any, node: Node) => { // 获取对齐线 @@ -539,6 +646,12 @@ export const useFlowCallbacks = ( const nodeDefinition = localNodeData.find(n => n.nodeType === nodeType) || node; if (!nodeDefinition) return; + // 特殊处理循环节点,添加开始和结束节点 + if (nodeType === 'LOOP') { + addLoopNodeWithStartEnd(position, nodeDefinition); + return; + } + // 创建新节点 const newNode = { id: `${nodeType}-${Date.now()}`, @@ -571,7 +684,7 @@ export const useFlowCallbacks = ( return newNodes; }); - }, [reactFlowInstance, edges]); + }, [reactFlowInstance, edges, addLoopNodeWithStartEnd]); // 处理添加节点的统一方法 const handleAddNode = useCallback((nodeType: string, node: any) => { @@ -594,8 +707,9 @@ export const useFlowCallbacks = ( try { // 转换会原始数据类型 const revertedData = revertFlowData(nodes, edges); - console.log('initialData:', initialData); + console.log('revertedData:', revertedData); + // return; const res: any = await setMainFlow(revertedData, initialData.id); if (res.code === 200) { Message.success('保存成功'); diff --git a/src/pages/flowEditor/index.tsx b/src/pages/flowEditor/index.tsx index e4ae4d5..9d75c7e 100644 --- a/src/pages/flowEditor/index.tsx +++ b/src/pages/flowEditor/index.tsx @@ -150,6 +150,8 @@ const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean }> = ({ ini (event: React.MouseEvent, node: Node) => { // 不可编辑的类型 if (['AND', 'OR', 'JSON2STR', 'STR2JSON'].includes(node.type)) return; + // 循环开始的节点不展示编辑框 + if (['LOOP_START'].includes(node.data.type as string)) return; setEditingNode(node); setIsEditModalOpen(true); }, diff --git a/src/utils/convertFlowData.ts b/src/utils/convertFlowData.ts index 351ec0d..19bff39 100644 --- a/src/utils/convertFlowData.ts +++ b/src/utils/convertFlowData.ts @@ -172,7 +172,7 @@ export const revertFlowData = (nodes: any[], edges: any[]) => { const nodeName = node.data?.title || nodeId; // 确定节点类型 - let nodeType = node.type; + let nodeType = node.data.type; // 特殊处理 start 和 end 节点 if (nodeId === 'start') { nodeType = 'start'; @@ -197,8 +197,8 @@ export const revertFlowData = (nodes: any[], edges: any[]) => { if (node.data?.component) { nodeConfig.component = { type: nodeType, - compIdentifier: node.data.component.compIdentifier, - compInstanceIdentifier: node.data.component.compInstanceIdentifier + compIdentifier: node.data.component.compIdentifier || '', + compInstanceIdentifier: node.data.component.compInstanceIdentifier || '' }; if (node.data.component?.customDef) nodeConfig.component.customDef = node.data.component.customDef; } From e274937a19d515f56ed1ea7800825df5ec667e13 Mon Sep 17 00:00:00 2001 From: ZLY Date: Wed, 15 Oct 2025 15:53:42 +0800 Subject: [PATCH 09/89] =?UTF-8?q?refactor(components):=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E8=A1=A8=E6=A0=BC=E7=BB=84=E4=BB=B6=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E4=B8=8E=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 EndNodeTable 组件重命名为 ParamsTable -为 maxTime 参数项禁用编辑功能 -限制 maxTime 默认值输入类型为数字 - 隐藏 maxTime项的删除按钮 - 更新组件接口名称以匹配新用途 --- .../nodeEditors/components/ParamsTable.tsx | 74 ++++++++++++------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/src/components/FlowEditor/nodeEditors/components/ParamsTable.tsx b/src/components/FlowEditor/nodeEditors/components/ParamsTable.tsx index 9097c8f..8e6c57b 100644 --- a/src/components/FlowEditor/nodeEditors/components/ParamsTable.tsx +++ b/src/components/FlowEditor/nodeEditors/components/ParamsTable.tsx @@ -13,15 +13,15 @@ interface TableDataItem { [key: string]: any; // 允许其他自定义字段 } -interface EndNodeTableProps { +interface ParamsTableProps { initialData: TableDataItem[]; onUpdateData: (data: TableDataItem[]) => void; } -const EndNodeTable: React.FC = ({ - initialData, - onUpdateData - }) => { +const ParamsTable: React.FC = ({ + initialData, + onUpdateData + }) => { const [data, setData] = useState([]); useEffect(() => { @@ -52,23 +52,31 @@ const EndNodeTable: React.FC = ({ title: '标识', dataIndex: 'id', render: (_: any, record: TableDataItem) => ( - handleSave({ ...record, id: value })} - /> + record.id === 'maxTime' ? ( + {record.id} + ) : ( + handleSave({ ...record, id: value })} + /> + ) ) }, { title: '数据类型', dataIndex: 'dataType', render: (_: any, record: TableDataItem) => ( - handleSave({ ...record, dataType: value })} + placeholder="请选择数据类型" + /> + ) ) }, { @@ -92,27 +100,41 @@ const EndNodeTable: React.FC = ({ title: '描述', dataIndex: 'desc', render: (_: any, record: TableDataItem) => ( - handleSave({ ...record, desc: value })} - /> + record.id === 'maxTime' ? ( + {record.desc} + ) : ( + handleSave({ ...record, desc: value })} + /> + ) ) }, { title: '默认值', dataIndex: 'defaultValue', render: (_: any, record: TableDataItem) => ( - handleSave({ ...record, defaultValue: value })} - /> + record.id === 'maxTime' ? ( + handleSave({ ...record, defaultValue: value })} + /> + ) : ( + handleSave({ ...record, defaultValue: value })} + /> + ) ) }, { title: '操作', dataIndex: 'op', render: (_: any, record: TableDataItem) => ( - ) @@ -168,4 +190,4 @@ const EndNodeTable: React.FC = ({ ); }; -export default EndNodeTable; \ No newline at end of file +export default ParamsTable; \ No newline at end of file From 24bc2f392dba643fe9219e9b43d1ae259a7f91be Mon Sep 17 00:00:00 2001 From: ZLY Date: Wed, 15 Oct 2025 15:53:50 +0800 Subject: [PATCH 10/89] =?UTF-8?q?fix(FlowEditor):=20=E9=98=B2=E6=AD=A2?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=88=97=E8=A1=A8=E4=B8=BA=E7=A9=BA=E6=97=B6?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加了对 eventList 的空值检查- 避免在 eventList 未定义时调用 setOptions - 提高组件在数据加载前的稳定性 --- .../FlowEditor/nodeEditors/components/EventSelect.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/FlowEditor/nodeEditors/components/EventSelect.tsx b/src/components/FlowEditor/nodeEditors/components/EventSelect.tsx index 873bfe1..a3288b4 100644 --- a/src/components/FlowEditor/nodeEditors/components/EventSelect.tsx +++ b/src/components/FlowEditor/nodeEditors/components/EventSelect.tsx @@ -23,7 +23,7 @@ const EventSelect: React.FC = ({ eventList, type, onUpdateData const [showModal, setShowModal] = useState(false); useEffect(() => { - setOptions(eventList); + eventList && setOptions(eventList); }, [eventList]); const addItem = () => { From ae70967f86d144d69cca29884b5cd4c70d9fe2ba Mon Sep 17 00:00:00 2001 From: ZLY Date: Wed, 15 Oct 2025 16:10:20 +0800 Subject: [PATCH 11/89] =?UTF-8?q?feat(flow):=20=E6=94=AF=E6=8C=81=E5=BE=AA?= =?UTF-8?q?=E7=8E=AF=E8=8A=82=E7=82=B9=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E4=B8=8E=E6=B3=A8=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增对 LOOP_START 和 LOOP_END 组件类型的识别 - 在节点转换过程中构建循环开始和结束节点结构 - 为循环节点设置默认参数和位置信息 - 动态注册 LOOP 类型节点到编辑器中 - 更新节点类型判断逻辑以支持循环组件 - 序列化循环节点关联信息至 customDef 字段- 优化节点数据构造逻辑,确保组件标识正确附加 --- src/utils/convertFlowData.ts | 69 ++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/src/utils/convertFlowData.ts b/src/utils/convertFlowData.ts index 19bff39..4ab6371 100644 --- a/src/utils/convertFlowData.ts +++ b/src/utils/convertFlowData.ts @@ -1,5 +1,6 @@ import { nodeTypeMap, registerNodeType } from '@/components/FlowEditor/node'; import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode'; +import LoopNode from '@/components/FlowEditor/node/loopNode/LoopNode'; /** * 将提供的数据结构转换为适用于 flow editor 的 nodes 和 edges @@ -65,6 +66,9 @@ export const convertFlowData = (flowData: any, useDefault = true) => { else if (nodeConfig.nodeId === 'end') { nodeType = 'end'; } + else if (nodeConfig.component.type === 'LOOP_START' || nodeConfig.component.type === 'LOOP_END') { + nodeType = 'LOOP'; + } else { nodeType = nodeConfig.component.type; } @@ -78,6 +82,67 @@ export const convertFlowData = (flowData: any, useDefault = true) => { console.warn('Failed to parse position for node:', nodeConfig.nodeId); } + // 构建循环节点的默认参数和外壳 + if (nodeType === 'LOOP') { + // 创建循环开始节点 + const loopStartNode = { + id: `LOOP_START-${Date.now()}`, + type: 'LOOP', // 使用本地节点类型 + position: { x: position.x, y: position.y }, + data: { + title: '循环开始', + type: 'LOOP_START', + parameters: { + apiIns: [], + apiOuts: [{ name: 'loopStart', desc: '', dataType: '', defaultValue: '' }], + dataIns: [], + dataOuts: [] + }, + component: {} + } + + }; + + // 创建循环结束节点 + const loopEndNode = { + id: `LOOP_END-${Date.now()}`, + type: 'LOOP', // 使用本地节点类型 + position: { x: position.x + 400, y: position.y }, + data: { + title: '循环结束', + type: 'LOOP_END', + parameters: { + apiIns: [{ name: 'continue', desc: '', dataType: '', defaultValue: '' }], + apiOuts: [{ name: 'break', desc: '', dataType: '', defaultValue: '' }], + dataIns: [{ + 'arrayType': null, + 'dataType': 'INTEGER', + 'defaultValue': 10, + 'desc': '最大循环次数', + 'id': 'maxTime' + }], + dataOuts: [] + }, + component: { + type: 'LOOP_END', + customDef: '', + loopStartNodeId: loopStartNode.id // 这里的参数是为了提供在组件内部处理数据是使用,最后这个字段要序列化后放进customDef + } + } + }; + + loopStartNode.data.component = { + type: 'LOOP_START', + customDef: JSON.stringify({ loopEndNodeId: loopEndNode.id }) + }; + + // 将未定义的节点动态追加进nodeTypes + const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); + if (!nodeMap.includes('LOOP')) { + registerNodeType('LOOP', LoopNode, '循环'); + } + } + // 构造节点数据 const node: any = { id: nodeConfig.nodeId, @@ -111,11 +176,11 @@ export const convertFlowData = (flowData: any, useDefault = true) => { defaultValue: output.defaultValue })) || [] }, - type: nodeType + type: nodeType === 'LOOP' ? nodeConfig.component.type : nodeType } }; - // 如果是机械臂节点,添加组件标识信息 + // 添加组件标识信息 if (nodeConfig.component) { node.data.component = { compIdentifier: nodeConfig.component.compIdentifier, From 26fe3794fa4ece4df34a6aab98b45bf11d00371a Mon Sep 17 00:00:00 2001 From: ZLY Date: Wed, 15 Oct 2025 16:22:40 +0800 Subject: [PATCH 12/89] =?UTF-8?q?refactor(flow):=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E6=95=B0=E6=8D=AE=E5=A4=84=E7=90=86=E4=B8=8E?= =?UTF-8?q?=E5=BE=AA=E7=8E=AF=E7=BB=84=E4=BB=B6=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 完善输入输出数据结构,支持数组类型定义- 改进循环结束组件的自定义配置序列化逻辑 - 增强数据转换时的字段兼容性处理 --- .../nodeEditors/components/ConditionsTable.tsx | 1 - src/hooks/useFlowCallbacks.ts | 8 +++++++- src/utils/convertFlowData.ts | 10 ++++++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/components/FlowEditor/nodeEditors/components/ConditionsTable.tsx b/src/components/FlowEditor/nodeEditors/components/ConditionsTable.tsx index b6422b4..276819b 100644 --- a/src/components/FlowEditor/nodeEditors/components/ConditionsTable.tsx +++ b/src/components/FlowEditor/nodeEditors/components/ConditionsTable.tsx @@ -138,7 +138,6 @@ const ConditionsTable: React.FC = ({ ]; const convertData = (originData) => { - console.log('apiOutsList:', apiOutsList); const apiOutIds = apiOutsList; const conditions = originData.map(item => { let expression = ''; diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index ec036c6..eca0cd5 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -367,7 +367,11 @@ export const useFlowCallbacks = ( }, component: { type: 'LOOP_END', - customDef: '', + customDef: JSON.stringify({ + apiOutIds: ['continue', 'break'], + conditions: [], + loopStartNodeId: loopStartNode.id + }), loopStartNodeId: loopStartNode.id // 这里的参数是为了提供在组件内部处理数据是使用,最后这个字段要序列化后放进customDef } } @@ -510,6 +514,8 @@ export const useFlowCallbacks = ( // 删除节点函数 const deleteNode = useCallback((node: Node) => { + console.log('node:', node); + setNodes((nds: Node[]) => nds.filter((n) => n.id !== node.id)); setEdges((eds: Edge[]) => eds.filter((e) => e.source !== node.id && e.target !== node.id)); diff --git a/src/utils/convertFlowData.ts b/src/utils/convertFlowData.ts index 4ab6371..f0aeb9c 100644 --- a/src/utils/convertFlowData.ts +++ b/src/utils/convertFlowData.ts @@ -142,7 +142,7 @@ export const convertFlowData = (flowData: any, useDefault = true) => { registerNodeType('LOOP', LoopNode, '循环'); } } - + // 构造节点数据 const node: any = { id: nodeConfig.nodeId, @@ -280,10 +280,11 @@ export const revertFlowData = (nodes: any[], edges: any[]) => { // 处理 dataIns(输入数据) if (parameters.dataIns && parameters.dataIns.length > 0) { nodeConfig.dataIns = parameters.dataIns.map((input: any) => ({ - id: input.name, + id: input.name || input.id, desc: input.desc, dataType: input.dataType, - defaultValue: input.defaultValue + defaultValue: input.defaultValue, + arrayType: input.arrayType || null })); } @@ -293,7 +294,8 @@ export const revertFlowData = (nodes: any[], edges: any[]) => { id: output.name, desc: output.desc, dataType: output.dataType, - defaultValue: output.defaultValue + defaultValue: output.defaultValue, + arrayType: output.arrayType || null })); } From bba0197215da23f77a2cdce96da9a1a7ff835622 Mon Sep 17 00:00:00 2001 From: ZLY Date: Thu, 16 Oct 2025 11:38:59 +0800 Subject: [PATCH 13/89] =?UTF-8?q?feat(flow):=E4=BC=98=E5=8C=96=E5=BE=AA?= =?UTF-8?q?=E7=8E=AF=E8=8A=82=E7=82=B9=E9=85=8D=E7=BD=AE=E4=B8=8E=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 调整 LOOP_START 节点的 apiIns 和 apiOuts 参数结构 - 新增 buildNodeId 工具函数统一管理节点句柄 ID 生成逻辑- 在 convertFlowData 中增强 nodeId 获取逻辑,兼容 id与 name 字段 - LoopNode 组件新增状态管理,支持动态解析条件表达式并生成 apiOuts - 引入 NodeContentLoop 组件专门负责循环节点的内容渲染和句柄绘制 - 更新 useFlowCallbacks 中 LOOP_START 节点默认参数配置 - 新增 nodeContentLoop 组件实现节点内容与句柄的模块化渲染 --- .../FlowEditor/node/loopNode/LoopNode.tsx | 163 ++++++++++---- src/hooks/useFlowCallbacks.ts | 4 +- .../flowEditor/components/nodeContentLoop.tsx | 211 ++++++++++++++++++ src/utils/convertFlowData.ts | 33 ++- 4 files changed, 365 insertions(+), 46 deletions(-) create mode 100644 src/pages/flowEditor/components/nodeContentLoop.tsx diff --git a/src/components/FlowEditor/node/loopNode/LoopNode.tsx b/src/components/FlowEditor/node/loopNode/LoopNode.tsx index 65e3117..b54cacd 100644 --- a/src/components/FlowEditor/node/loopNode/LoopNode.tsx +++ b/src/components/FlowEditor/node/loopNode/LoopNode.tsx @@ -1,11 +1,14 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { useStore } from '@xyflow/react'; import styles from '@/components/FlowEditor/node/style/baseOther.module.less'; import DynamicIcon from '@/components/DynamicIcon'; import { Handle, Position } from '@xyflow/react'; +import NodeContentLoop from '@/pages/flowEditor/components/nodeContentLoop'; +import { defaultNodeTypes } from '@/components/FlowEditor/node/types/defaultType'; // 循环节点组件,用于显示循环开始和循环结束节点 -const LoopNode = ({ data, id }: { data: any; id: string }) => { +const LoopNode = ({ data, id }: { data: defaultNodeTypes; id: string }) => { + const [newData, setNewData] = useState([]); const title = data.title || '循环节点'; const isStartNode = data.type === 'LOOP_START'; @@ -24,6 +27,124 @@ const LoopNode = ({ data, id }: { data: any; id: string }) => { } }; + const getOperator = (expr: string) => { + let operator; + if (expr.includes('==')) { + operator = '=='; + } + else if (expr.includes('>=')) { + operator = '>='; + } + else if (expr.includes('<=')) { + operator = '<='; + } + else if (expr.includes('<')) { + operator = '<'; + } + else if (expr.includes('>')) { + operator = '>'; + } + else { + operator = '!='; + } + return operator; + }; + + const reverseDataStructure = (processedData: any) => { + try { + const parsedCustomDef = JSON.parse(processedData.customDef); + if (!parsedCustomDef.conditions) { + return []; + } + + return parsedCustomDef.conditions.map((condition: any, index: number) => { + // 解析表达式以获取左值、操作符和右值 + let lftVal = ''; + let operator = ''; + let rgtVal = ''; + const valueType = condition.valueType || ''; + + if (condition.expression) { + // 处理布尔值表达式 + if (valueType.includes('boolean')) { + const splitStr = valueType.split('-')[1]; + operator = getOperator(condition.expression); + const pattern = new RegExp(`\\$\\.(.+)(${operator})${splitStr}`); + const match = condition.expression.match(pattern); + if (match) { + lftVal = match[1]; + operator = match[2]; + } + } + // 处理其他类型的表达式 + else { + // 简单的解析逻辑,可能需要根据实际表达式格式进行调整 + const match = condition.expression.match(/\$\.([^=!<>]+)(==|!=|>=|<=|>|<)(.+)/); + if (match) { + lftVal = match[1]; + operator = match[2]; + rgtVal = match[3]; + } + } + } + + return { + key: index, + id: Date.now(), + apiOutId: condition.apiOutId || '', + lftVal, + operator, + valueType, + rgtVal + }; + }); + } catch (e) { + console.error('Error parsing customDef:', e); + return []; + } + }; + + useEffect(() => { + if (data) { + const reverseData = reverseDataStructure(data.component); + if (reverseData.length > 0) { + const list = reverseData.map(item => { + let expression = ''; + if (item.valueType.includes('boolean')) { + const splitStr = item.valueType.split('-')[1]; + expression = `$.${item.lftVal}${item.operator}${splitStr}`; + } + else expression = `$.${item.lftVal}${item.operator}${item.rgtVal}`; + return { + name: item.apiOutId, + id: item.apiOutId, + desc: '', + defaultValue: item.valueType, + dataType: expression + }; + }); + + // 合并list数组与data.parameters.apiOuts数组 + const apiOuts = data.parameters?.apiOuts || []; + const mergedApiOuts = [...apiOuts, ...list]; + setNewData(mergedApiOuts); + } + else { + // 如果没有reverseData,则直接使用原始apiOuts + setNewData(data.parameters?.apiOuts || []); + } + } + }, [data]); + + // 创建包含额外apiOuts的新data对象 + const modifiedData = { + ...data, + parameters: { + ...data.parameters, + apiOuts: newData + } + }; + return (
@@ -31,36 +152,6 @@ const LoopNode = ({ data, id }: { data: any; id: string }) => { {title}
- {/* 左侧输入连接点 */} - - - {/* 右侧输出连接点 */} - - {/* 顶部连接点,用于标识循环开始和结束节点是一组 */} { }} /> - {/* 节点内容区域 */} -
-
-
-
-
-
+
); }; diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index eca0cd5..4ebc6bb 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -335,8 +335,8 @@ export const useFlowCallbacks = ( title: '循环开始', type: 'LOOP_START', parameters: { - apiIns: [], - apiOuts: [{ name: 'loopStart', desc: '', dataType: '', defaultValue: '' }], + apiIns: [{ name: 'start', desc: '', dataType: '', defaultValue: '' }], + apiOuts: [{ name: 'done', desc: '', dataType: '', defaultValue: '' }], dataIns: [], dataOuts: [] }, diff --git a/src/pages/flowEditor/components/nodeContentLoop.tsx b/src/pages/flowEditor/components/nodeContentLoop.tsx new file mode 100644 index 0000000..b40d570 --- /dev/null +++ b/src/pages/flowEditor/components/nodeContentLoop.tsx @@ -0,0 +1,211 @@ +import React from 'react'; +import styles from '@/components/FlowEditor/node/style/baseOther.module.less'; +import { Handle, Position, useStore } from '@xyflow/react'; +import { deserializeValue } from '@/utils/common'; +import cronstrue from 'cronstrue/i18n'; + +interface NodeContentData { + parameters?: { + dataIns?: any[]; + dataOuts?: any[]; + apiIns?: any[]; + apiOuts?: any[]; + }; + showFooter?: boolean; + type?: string; + + [key: string]: any; +} + +// 定义通用的句柄样式 +const handleStyles = { + mainSource: { + background: '#2290f6', + width: '8px', + height: '8px', + border: '2px solid #fff', + boxShadow: '0 0 4px rgba(0,0,0,0.2)' + }, + mainTarget: { + background: '#2290f6', + width: '8px', + height: '8px', + border: '2px solid #fff', + boxShadow: '0 0 4px rgba(0,0,0,0.2)' + }, + data: { + background: '#555', + width: '6px', + height: '6px', + border: '1px solid #fff', + boxShadow: '0 0 2px rgba(0,0,0,0.2)' + } +}; + +// 渲染LOOP节点的句柄 +const renderRegularNodeHandles = (dataIns: any[], dataOuts: any[], apiIns: any[], apiOuts: any[]) => { + return ( + <> + {apiOuts.map((_, index) => ( + + ))} + {apiIns.map((_, index) => ( + + ))} + + {/* 输入参数连接端点 */} + {dataIns.map((_, index) => ( + + ))} + + {/* 输出参数连接端点 */} + {dataOuts.map((_, index) => ( + + ))} + + ); +}; + +const formatFooter = (data: any) => { + try { + switch (data.type) { + case 'WAIT': + const { duration } = deserializeValue(data.customDef); + const hours = Math.floor(duration / 3600); + const minutes = Math.floor((duration % 3600) / 60); + const seconds = Math.floor(duration % 60); + return `${hours}小时${minutes}分钟${seconds}秒`; + case 'CYCLE': + const { intervalSeconds } = deserializeValue(data.customDef); + return cronstrue.toString(intervalSeconds, { locale: 'zh_CN' }); + case 'EVENTSEND': + case 'EVENTLISTENE': + const { name } = data.customDef; + return `事件: ${name}`; + default: + return '这个类型还没开发'; + } + } catch (e) { + console.log(e); + } +}; + +const NodeContent = ({ data }: { data: NodeContentData }) => { + const apiIns = data.parameters?.apiIns || []; + const apiOuts = data.parameters?.apiOuts || []; + const dataIns = data.parameters?.dataIns || []; + const dataOuts = data.parameters?.dataOuts || []; + const showFooter = data?.component?.customDef || false; + const footerData = (showFooter && data.component) || {}; + + // 判断节点类型 + const isStartNode = data.type === 'start'; + const isEndNode = data.type === 'end'; + + return ( + <> + {/*content栏-api部分*/} +
+
+ {apiIns.length > 0 && ( +
+ {apiIns.map((input, index) => ( +
+ {data.type !== 'LOOP_START' ? input.desc || input.id : ''} +
+ ))} +
+ )} + + {apiOuts.length > 0 && ( +
+ {apiOuts.map((output, index) => ( +
+ {data.type !== 'LOOP_START' ? output.desc || output.id : ''} +
+ ))} +
+ )} +
+
+ {(dataIns.length > 0 || dataOuts.length > 0) && ( + <> + {/*分割*/} +
+ + {/*content栏-data部分*/} +
+
+ {dataIns.length > 0 && !isStartNode && ( +
+ {dataIns.map((input, index) => ( +
+ {input.id || `输入${index + 1}`} +
+ ))} +
+ )} + + {dataOuts.length > 0 && !isEndNode && ( +
+ {dataOuts.map((output, index) => ( +
+ {output.id || `输出${index + 1}`} +
+ ))} +
+ )} +
+
+ + )} + + {/*footer栏*/} + {/*{showFooter && (*/} + {/*
*/} + {/* {formatFooter(footerData)}*/} + {/*
*/} + {/*)}*/} + + {renderRegularNodeHandles(dataIns, dataOuts, apiIns, apiOuts)} + + ); +}; + +export default NodeContent; \ No newline at end of file diff --git a/src/utils/convertFlowData.ts b/src/utils/convertFlowData.ts index f0aeb9c..ba26d84 100644 --- a/src/utils/convertFlowData.ts +++ b/src/utils/convertFlowData.ts @@ -93,8 +93,8 @@ export const convertFlowData = (flowData: any, useDefault = true) => { title: '循环开始', type: 'LOOP_START', parameters: { - apiIns: [], - apiOuts: [{ name: 'loopStart', desc: '', dataType: '', defaultValue: '' }], + apiIns: [{ name: 'start', desc: '', dataType: '', defaultValue: '' }], + apiOuts: [{ name: 'done', desc: '', dataType: '', defaultValue: '' }], dataIns: [], dataOuts: [] }, @@ -143,6 +143,8 @@ export const convertFlowData = (flowData: any, useDefault = true) => { } } + console.log('nodeConfig:', nodeConfig); + // 构造节点数据 const node: any = { id: nodeConfig.nodeId, @@ -152,25 +154,29 @@ export const convertFlowData = (flowData: any, useDefault = true) => { title: nodeConfig.nodeName || nodeConfig.nodeId, parameters: { apiIns: [{ - name: 'start', + name: buildNodeId(nodeConfig.nodeId,'in'), + id: buildNodeId(nodeConfig.nodeId,'in'), desc: '', dataType: '', defaultValue: '' }], apiOuts: [{ - name: nodeConfig.nodeId === 'end' ? 'end' : 'done', + name: buildNodeId(nodeConfig.nodeId,'out'), + id: buildNodeId(nodeConfig.nodeId,'out'), desc: '', dataType: '', defaultValue: '' }], dataIns: nodeConfig.dataIns?.map((input: any) => ({ name: input.id, + id: input.id, desc: input.desc, dataType: input.dataType, defaultValue: input.defaultValue })) || [], dataOuts: nodeConfig.dataOuts?.map((output: any) => ({ name: output.id, + id: output.id, desc: output.desc, dataType: output.dataType, defaultValue: output.defaultValue @@ -233,7 +239,7 @@ export const revertFlowData = (nodes: any[], edges: any[]) => { if (nodes && nodes.length > 0) { flowData.nodeConfigs = nodes.map(node => { // 确定 nodeId 和 nodeName - const nodeId = node.id; + const nodeId = node.id || node.name; const nodeName = node.data?.title || nodeId; // 确定节点类型 @@ -343,3 +349,20 @@ export const revertFlowData = (nodes: any[], edges: any[]) => { return flowData; }; + + +// 通过nodeType先区分是否需要使用特殊nodeId,不需要就正常分类开始结束的句柄id +const buildNodeId = (nodeId, type) => { + if (nodeId.includes('LOOP_START')) { + if (type === 'in') return 'start'; + else return 'done'; + } + else if (nodeId.includes('LOOP_END')) { + if (type === 'in') return 'continue'; + else return 'break'; + } + else { + if (type === 'in') return 'start'; + else return nodeId === 'end' ? 'end' : 'done'; + } +}; From a024ba911d868d8519d04f0103d1b8520453f76d Mon Sep 17 00:00:00 2001 From: ZLY Date: Thu, 16 Oct 2025 11:39:10 +0800 Subject: [PATCH 14/89] =?UTF-8?q?feat(flowEditor):=E4=BC=98=E5=8C=96ReactF?= =?UTF-8?q?low=E5=AE=9E=E4=BE=8BID=E7=94=9F=E6=88=90=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 使用useMemo优化reactFlowId的生成,避免不必要的重复计算 - 统一ID生成逻辑,确保实例ID的唯一性和稳定性 - 修复addNodeOnPane函数中坐标类型定义的语法问题 - 提升组件性能,减少重复渲染 --- src/pages/flowEditor/FlowEditorMain.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/flowEditor/FlowEditorMain.tsx b/src/pages/flowEditor/FlowEditorMain.tsx index 093ade5..21b9252 100644 --- a/src/pages/flowEditor/FlowEditorMain.tsx +++ b/src/pages/flowEditor/FlowEditorMain.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { ReactFlow, Background, @@ -76,7 +76,7 @@ interface FlowEditorMainProps { editEdge: (edge: Edge) => void; copyNode: (node: Node) => void; addNodeOnEdge: (nodeType: string, node: any) => void; - addNodeOnPane: (nodeType: string, position: { x: number; y: number }, node?: any) => void; + addNodeOnPane: (nodeType: string, position: { x: number, y: number }, node?: any) => void; handleAddNode: (nodeType: string, node: any) => void; saveFlowDataToServer: () => void; handleRun: (running: boolean) => void; @@ -135,6 +135,7 @@ const FlowEditorMain: React.FC = (props) => { const { getGuidelines, clearGuidelines, AlignmentGuides } = useAlignmentGuidelines(); const { undo, redo, canUndo, canRedo } = useHistory(); + const reactFlowId = useMemo(() => new Date().getTime().toString(), []); // 监听键盘事件实现快捷键 useEffect(() => { @@ -175,7 +176,7 @@ const FlowEditorMain: React.FC = (props) => {
e.preventDefault()}> Date: Fri, 17 Oct 2025 10:29:36 +0800 Subject: [PATCH 15/89] =?UTF-8?q?feat(flow):=20=E9=87=8D=E6=9E=84=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E6=95=B0=E6=8D=AE=E8=BD=AC=E6=8D=A2=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=BB=A5=E6=94=AF=E6=8C=81=E6=96=B0=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 getAppInfoNew API 接口用于获取应用资源信息 - 重构 convertFlowData 工具函数以适配新的数据结构 - 改进节点和边的解析逻辑,支持更灵活的数据格式 - 添加对循环节点的特殊处理和支持 - 优化组件参数和连接线的构建方式 - 更新 Redux 状态管理中的数据流处理 -修复画布初始化时的数据映射问题 - 增强新节点添加时的自动连线功能 - 调整流程保存逻辑以匹配新的数据结构 - 更新 WebSocket 连接依赖的应用 ID 引用 --- src/api/appRes.ts | 6 + src/hooks/useFlowCallbacks.ts | 58 +++- src/pages/ideContainer/sideBar.tsx | 6 +- src/pages/orchestration/project/index.tsx | 7 +- src/utils/convertFlowData.ts | 402 ++++++++++++++-------- 5 files changed, 314 insertions(+), 165 deletions(-) diff --git a/src/api/appRes.ts b/src/api/appRes.ts index 58772ee..af9c356 100644 --- a/src/api/appRes.ts +++ b/src/api/appRes.ts @@ -9,6 +9,12 @@ export function getAppInfo(data: string) { return axios.get(`${urlPrefix}/appRes/${data}`); } +// 获取应用资源 +export function getAppInfoNew(data: string) { + return axios.get(`${urlPrefix}/appRes/${data}/new`); +} + + // 更新主流程 export function setMainFlow(data: FlowDefinition, appId: string) { return axios.post(`${urlPrefix}/appRes/${appId}/updateMain`, data); diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index 4ebc6bb..7502345 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -445,14 +445,16 @@ export const useFlowCallbacks = ( // 初始化画布数据 const initializeCanvasData = useCallback(() => { - if (canvasDataMap[initialData?.id]) { - const { edges, nodes } = canvasDataMap[initialData?.id]; + if (canvasDataMap[initialData?.appId]) { + const { edges, nodes } = canvasDataMap[initialData?.appId]; setNodes(nodes); setEdges(edges); } else { // 首次进入 - const { nodes: convertedNodes, edges: convertedEdges } = convertFlowData(initialData); + const { nodes: convertedNodes, edges: convertedEdges } = convertFlowData(initialData?.main.components, true); + + // return; // 为所有边添加类型 const initialEdges: Edge[] = convertedEdges.map(edge => ({ ...edge, @@ -462,10 +464,10 @@ export const useFlowCallbacks = ( setNodes(convertedNodes); setEdges(initialEdges); - if (initialData?.id) { + if (initialData?.appId) { dispatch(updateCanvasDataMap({ ...canvasDataMap, - [initialData.id]: { nodes: convertedNodes, edges: initialEdges } + [initialData.appId]: { nodes: convertedNodes, edges: initialEdges } })); } } @@ -476,15 +478,15 @@ export const useFlowCallbacks = ( // 实时更新 canvasDataMap const updateCanvasDataMapEffect = useCallback(() => { - if (initialData?.id) { - updateCanvasDataMapDebounced(dispatch, canvasDataMap, initialData.id, nodes, edges); + if (initialData?.appId) { + updateCanvasDataMapDebounced(dispatch, canvasDataMap, initialData.appId, nodes, edges); } // 清理函数,在组件卸载时取消防抖 return () => { // 取消防抖函数 }; - }, [nodes, edges, initialData?.id, dispatch, canvasDataMap]); + }, [nodes, edges, initialData?.appId, dispatch, canvasDataMap]); // 关闭编辑弹窗 const closeEditModal = useCallback(() => { @@ -593,7 +595,8 @@ export const useFlowCallbacks = ( data: { ...nodeDefinition.data, title: nodeDefinition.nodeName, - type: nodeType + type: nodeType, + compId: nodeDefinition.id } }; @@ -609,6 +612,29 @@ export const useFlowCallbacks = ( // 删除旧边 setEdges((eds: Edge[]) => eds.filter(e => e.id !== edgeForNodeAdd.id)); + // 确定新边的句柄 + // 对于第一条边 (source -> new node): 使用原始边的 sourceHandle,目标句柄根据节点类型确定 + // 对于第二条边 (new node -> target): 源句柄根据节点类型确定,使用原始边的 targetHandle + + // 获取新节点的默认句柄 + let newNodeSourceHandle = 'done'; // 默认源句柄 + let newNodeTargetHandle = 'start'; // 默认目标句柄 + + // 如果新节点有参数定义,尝试获取更准确的句柄信息 + if (newNode.data?.parameters) { + const { apiOuts, apiIns } = newNode.data.parameters; + + // 获取第一个api输出作为源句柄(如果存在) + if (apiOuts && apiOuts.length > 0) { + newNodeSourceHandle = apiOuts[0].name || apiOuts[0].id || newNodeSourceHandle; + } + + // 获取第一个api输入作为目标句柄(如果存在) + if (apiIns && apiIns.length > 0) { + newNodeTargetHandle = apiIns[0].name || apiIns[0].id || newNodeTargetHandle; + } + } + // 创建新边: source -> new node, new node -> target const newEdges = [ ...edges.filter(e => e.id !== edgeForNodeAdd.id), @@ -616,12 +642,16 @@ export const useFlowCallbacks = ( id: `e${edgeForNodeAdd.source}-${newNode.id}`, source: edgeForNodeAdd.source, target: newNode.id, + sourceHandle: edgeForNodeAdd.sourceHandle, + targetHandle: newNodeTargetHandle, type: 'custom' }, { id: `e${newNode.id}-${edgeForNodeAdd.target}`, source: newNode.id, target: edgeForNodeAdd.target, + sourceHandle: newNodeSourceHandle, + targetHandle: edgeForNodeAdd.targetHandle, type: 'custom' } ]; @@ -658,6 +688,7 @@ export const useFlowCallbacks = ( return; } + // 创建新节点 const newNode = { id: `${nodeType}-${Date.now()}`, @@ -666,7 +697,8 @@ export const useFlowCallbacks = ( data: { ...nodeDefinition.data, title: nodeDefinition.nodeName, - type: nodeType + type: nodeType, + compId: nodeDefinition.id } }; @@ -716,7 +748,7 @@ export const useFlowCallbacks = ( console.log('revertedData:', revertedData); // return; - const res: any = await setMainFlow(revertedData, initialData.id); + const res: any = await setMainFlow(revertedData, initialData.appId); if (res.code === 200) { Message.success('保存成功'); } @@ -727,7 +759,7 @@ export const useFlowCallbacks = ( console.error('Error saving flow data:', error); Message.error('保存失败'); } - }, [nodes, edges]); + }, [nodes, edges, initialData?.appId]); // 初始化WebSocket hook const ws = useWebSocket({ @@ -771,7 +803,7 @@ export const useFlowCallbacks = ( ws.disconnect(); setIsRunning(false); } - }, [initialData?.id, ws]); + }, [initialData?.appId, ws]); return { // Event handlers diff --git a/src/pages/ideContainer/sideBar.tsx b/src/pages/ideContainer/sideBar.tsx index caf2490..4b52f32 100644 --- a/src/pages/ideContainer/sideBar.tsx +++ b/src/pages/ideContainer/sideBar.tsx @@ -20,6 +20,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { updateMenuData, updateFlowData } from '@/store/ideContainer'; import { addApp, getProjectEnv, editApp, deleteApp } from '@/api/apps'; import _ from 'lodash'; +import { getAppInfoNew } from '@/api/appRes'; const TreeNode = Tree.Node; const FormItem = Form.Item; @@ -255,7 +256,8 @@ const SideBar: React.FC = ({ const parentKey = menu[activeKey]?.key; const currentMenu = _.cloneDeep(menuData[identity]); const index = currentMenu.findIndex(v => v.key === parentKey); - const res: any = await getProjectEnv(data.id); + // const res: any = await getProjectEnv(data.id); + const res: any = await getAppInfoNew(data.id); if (res.code === 200) { const children = currentMenu[index].children.find(v => v.id === data.id); children.children[0].children = res.data.events.map(item => { @@ -282,7 +284,7 @@ const SideBar: React.FC = ({ // 更新 menuData 中的数据 dispatch(updateMenuData({ ...menuData, [identity]: currentMenu })); // 更新 flowData 中的数据 - dispatch(updateFlowData({ [data.id]: res.data.app })); + dispatch(updateFlowData({ [data.id]: res.data })); // 同时更新本地 menu 状态以触发重新渲染 setMenu(prevMenu => { diff --git a/src/pages/orchestration/project/index.tsx b/src/pages/orchestration/project/index.tsx index 1b64813..561537b 100644 --- a/src/pages/orchestration/project/index.tsx +++ b/src/pages/orchestration/project/index.tsx @@ -4,14 +4,9 @@ import { useSelector } from 'react-redux'; const ProjectContainer = ({ selected }) => { const { flowData } = useSelector(state => state.ideContainer); - const [selectedFlowData, setSelectedFlowData] = useState({}); - - useEffect(() => { - setSelectedFlowData(flowData[selected.id]); - }, [selected]); return ( - + ); }; diff --git a/src/utils/convertFlowData.ts b/src/utils/convertFlowData.ts index ba26d84..6a673eb 100644 --- a/src/utils/convertFlowData.ts +++ b/src/utils/convertFlowData.ts @@ -1,6 +1,7 @@ import { nodeTypeMap, registerNodeType } from '@/components/FlowEditor/node'; import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode'; import LoopNode from '@/components/FlowEditor/node/loopNode/LoopNode'; +import store from '@/store/index'; /** * 将提供的数据结构转换为适用于 flow editor 的 nodes 和 edges @@ -11,8 +12,9 @@ import LoopNode from '@/components/FlowEditor/node/loopNode/LoopNode'; export const convertFlowData = (flowData: any, useDefault = true) => { const nodes: any[] = []; const edges: any[] = []; + const currentProjectCompData = getCurrentProjectStoreData(); - if (!flowData || Object.keys(flowData).length === 0 || flowData.main.nodeConfigs.length === 0) { + if (!flowData || Object.keys(flowData).length === 0) { // 如果useDefault为true且flowData为空,则返回默认的开始和结束节点 if (useDefault) { return { @@ -55,167 +57,157 @@ export const convertFlowData = (flowData: any, useDefault = true) => { return { nodes, edges }; } - // 处理节点配置 - const nodeConfigs = flowData.main?.nodeConfigs || []; - for (const nodeConfig of nodeConfigs) { + // 处理新格式的数据结构 + // 先处理所有节点 + const nodeEntries = Object.entries(flowData); + + for (const entry of nodeEntries) { + const nodeId: string = entry[0]; + const nodeConfig: any = entry[1]; + // 确定节点类型 let nodeType = 'BASIC'; - if (nodeConfig.nodeId === 'start') { + if (nodeId === 'start') { nodeType = 'start'; } - else if (nodeConfig.nodeId === 'end') { + else if (nodeId === 'end') { nodeType = 'end'; } - else if (nodeConfig.component.type === 'LOOP_START' || nodeConfig.component.type === 'LOOP_END') { + else if (nodeConfig.component?.type === 'LOOP_START' || nodeConfig.component?.type === 'LOOP_END') { nodeType = 'LOOP'; } else { - nodeType = nodeConfig.component.type; + nodeType = nodeConfig.component?.type || 'BASIC'; } // 解析位置信息 - let position = { x: 0, y: 0 }; - try { - const x6Data = JSON.parse(nodeConfig.x6); - position = x6Data.position || { x: 0, y: 0 }; - } catch (e) { - console.warn('Failed to parse position for node:', nodeConfig.nodeId); - } - - // 构建循环节点的默认参数和外壳 - if (nodeType === 'LOOP') { - // 创建循环开始节点 - const loopStartNode = { - id: `LOOP_START-${Date.now()}`, - type: 'LOOP', // 使用本地节点类型 - position: { x: position.x, y: position.y }, - data: { - title: '循环开始', - type: 'LOOP_START', - parameters: { - apiIns: [{ name: 'start', desc: '', dataType: '', defaultValue: '' }], - apiOuts: [{ name: 'done', desc: '', dataType: '', defaultValue: '' }], - dataIns: [], - dataOuts: [] - }, - component: {} - } - - }; - - // 创建循环结束节点 - const loopEndNode = { - id: `LOOP_END-${Date.now()}`, - type: 'LOOP', // 使用本地节点类型 - position: { x: position.x + 400, y: position.y }, - data: { - title: '循环结束', - type: 'LOOP_END', - parameters: { - apiIns: [{ name: 'continue', desc: '', dataType: '', defaultValue: '' }], - apiOuts: [{ name: 'break', desc: '', dataType: '', defaultValue: '' }], - dataIns: [{ - 'arrayType': null, - 'dataType': 'INTEGER', - 'defaultValue': 10, - 'desc': '最大循环次数', - 'id': 'maxTime' - }], - dataOuts: [] - }, - component: { - type: 'LOOP_END', - customDef: '', - loopStartNodeId: loopStartNode.id // 这里的参数是为了提供在组件内部处理数据是使用,最后这个字段要序列化后放进customDef - } - } - }; - - loopStartNode.data.component = { - type: 'LOOP_START', - customDef: JSON.stringify({ loopEndNodeId: loopEndNode.id }) - }; - - // 将未定义的节点动态追加进nodeTypes - const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); - if (!nodeMap.includes('LOOP')) { - registerNodeType('LOOP', LoopNode, '循环'); - } - } - - console.log('nodeConfig:', nodeConfig); + const position = nodeConfig.position || { x: 0, y: 0 }; // 构造节点数据 const node: any = { - id: nodeConfig.nodeId, + id: nodeId, type: nodeType, position, data: { - title: nodeConfig.nodeName || nodeConfig.nodeId, + title: nodeConfig.componentName || nodeId, parameters: { - apiIns: [{ - name: buildNodeId(nodeConfig.nodeId,'in'), - id: buildNodeId(nodeConfig.nodeId,'in'), - desc: '', - dataType: '', - defaultValue: '' - }], - apiOuts: [{ - name: buildNodeId(nodeConfig.nodeId,'out'), - id: buildNodeId(nodeConfig.nodeId,'out'), - desc: '', - dataType: '', - defaultValue: '' - }], - dataIns: nodeConfig.dataIns?.map((input: any) => ({ - name: input.id, - id: input.id, - desc: input.desc, - dataType: input.dataType, - defaultValue: input.defaultValue - })) || [], - dataOuts: nodeConfig.dataOuts?.map((output: any) => ({ - name: output.id, - id: output.id, - desc: output.desc, - dataType: output.dataType, - defaultValue: output.defaultValue - })) || [] + apiIns: getNodeApiIns(nodeId, nodeConfig, currentProjectCompData), + apiOuts: getNodeApiOuts(nodeId, nodeConfig, currentProjectCompData), + dataIns: nodeConfig.dataIns || [], + dataOuts: nodeConfig.dataOuts || [] }, - type: nodeType === 'LOOP' ? nodeConfig.component.type : nodeType + type: nodeConfig.component?.type || nodeType } }; // 添加组件标识信息 if (nodeConfig.component) { - node.data.component = { - compIdentifier: nodeConfig.component.compIdentifier, - compInstanceIdentifier: nodeConfig.component.compInstanceIdentifier, - customDef: nodeConfig.component?.customDef, - type: nodeConfig.component.type - }; + node.data.component = { ...nodeConfig.component }; + node.data.compId = nodeConfig.component.compId; } - // 将未定义的节点动态追加进nodeTypes + // 注册循环节点类型 + if (nodeType === 'LOOP') { + const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); + if (!nodeMap.includes('LOOP')) { + registerNodeType('LOOP', LoopNode, '循环'); + } + } + + // 注册其他节点类型 const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); - // 目前默认添加的都是系统组件/本地组件 - if (!nodeMap.includes(nodeType)) registerNodeType(nodeType, LocalNode, nodeConfig.nodeName); + if (!nodeMap.includes(nodeType) && nodeType !== 'start' && nodeType !== 'end' && nodeType !== 'LOOP') { + registerNodeType(nodeType, LocalNode, nodeConfig.componentName); + } nodes.push(node); } - // 处理连线配置 - const lineConfigs = flowData.main?.lineConfigs || []; - for (const lineConfig of lineConfigs) { - const edge: any = { - id: lineConfig.id, - source: lineConfig.prev.nodeId, - target: lineConfig.next.nodeId, - sourceHandle: lineConfig.prev.endpointId, - targetHandle: lineConfig.next.endpointId - }; + // 用于存储已添加的边,避免重复 + const addedEdges = new Set(); + + // 处理连接关系 - 只处理下游连接,避免重复创建连接线 + for (const entry of nodeEntries) { + const nodeId: string = entry[0]; + const nodeConfig: any = entry[1]; + + // 处理 API 下游连接 + if (nodeConfig.apiDownstream && Array.isArray(nodeConfig.apiDownstream)) { + nodeConfig.apiDownstream.forEach((targetArray: string[]) => { + // 确保 targetArray 是数组并且包含字符串元素 + if (Array.isArray(targetArray)) { + targetArray.forEach(target => { + if (typeof target === 'string' && target.includes('$$')) { + const [targetNodeId, targetHandle] = target.split('$$'); + + // 动态获取源句柄,而不是使用默认值 + const sourceNode = flowData[nodeId]; + // 统一旧版本逻辑,开始节点的输出句柄是start + let sourceHandle = sourceNode.id === 'start' ? 'start' : 'done'; // 默认值 + if (sourceNode && sourceNode.component && sourceNode.component.type) { + // 根据节点类型获取正确的源句柄 + sourceHandle = getNodeApiOutHandle(nodeId, sourceNode); + } + else if (sourceNode && sourceNode.data && sourceNode.data.parameters && + sourceNode.data.parameters.apiOuts && sourceNode.data.parameters.apiOuts.length > 0) { + // 从apiOuts中获取第一个句柄 + sourceHandle = sourceNode.data.parameters.apiOuts[0].name || + sourceNode.data.parameters.apiOuts[0].id || sourceHandle; + } + + // 创建边的唯一标识符 + const edgeId = `${nodeId}-${targetNodeId}-${sourceHandle}-${targetHandle}`; + + // 检查是否已添加此边 + if (!addedEdges.has(edgeId)) { + addedEdges.add(edgeId); + edges.push({ + id: `${edgeId}`, + source: nodeId, + target: targetNodeId, + sourceHandle, + targetHandle + }); + } + } + }); + } + }); + } - edges.push(edge); + // 处理数据下游连接 + if (nodeConfig.dataDownstream && Array.isArray(nodeConfig.dataDownstream)) { + nodeConfig.dataDownstream.forEach((connectionGroup: string[]) => { + // 确保 connectionGroup 是数组并且至少包含两个元素 + if (Array.isArray(connectionGroup) && connectionGroup.length >= 2) { + // 第一个元素是源节点和句柄信息 + const [sourceInfo, targetInfo] = connectionGroup; + + if (typeof sourceInfo === 'string' && sourceInfo.includes('@@') && + typeof targetInfo === 'string' && targetInfo.includes('@@')) { + + const [sourceNodeId, sourceHandle] = sourceInfo.split('@@'); + const [targetNodeId, targetHandle] = targetInfo.split('@@'); + + // 创建边的唯一标识符 + const edgeId = `${sourceNodeId}-${targetNodeId}-${sourceHandle}-${targetHandle}`; + + // 检查是否已添加此边 + if (!addedEdges.has(edgeId)) { + addedEdges.add(edgeId); + + edges.push({ + id: `${edgeId}`, + source: sourceNodeId, + target: targetNodeId, + sourceHandle: sourceHandle, + targetHandle: targetHandle + }); + } + } + } + }); + } } return { nodes, edges }; @@ -269,7 +261,8 @@ export const revertFlowData = (nodes: any[], edges: any[]) => { nodeConfig.component = { type: nodeType, compIdentifier: node.data.component.compIdentifier || '', - compInstanceIdentifier: node.data.component.compInstanceIdentifier || '' + compInstanceIdentifier: node.data.component.compInstanceIdentifier || '', + compId: node.data.compId || '' }; if (node.data.component?.customDef) nodeConfig.component.customDef = node.data.component.customDef; } @@ -279,6 +272,7 @@ export const revertFlowData = (nodes: any[], edges: any[]) => { type: nodeType }; } + if (['BASIC'].includes(nodeType)) nodeConfig.component.compId = node.data.compId || ''; // 处理参数信息 const parameters = node.data?.parameters || {}; @@ -297,7 +291,7 @@ export const revertFlowData = (nodes: any[], edges: any[]) => { // 处理 dataOuts(输出数据) if (parameters.dataOuts && parameters.dataOuts.length > 0) { nodeConfig.dataOuts = parameters.dataOuts.map((output: any) => ({ - id: output.name, + id: output.name || output.id, desc: output.desc, dataType: output.dataType, defaultValue: output.defaultValue, @@ -309,7 +303,7 @@ export const revertFlowData = (nodes: any[], edges: any[]) => { }); } -// 转换连线数据 + // 转换连线数据 if (edges && edges.length > 0) { flowData.lineConfigs = edges.map((edge, index) => { // 查找源节点和目标节点以确定连线类型 @@ -324,11 +318,11 @@ export const revertFlowData = (nodes: any[], edges: any[]) => { } // 判断是否为API类型的连线 else if (edge.sourceHandle && (edge.sourceHandle === 'apiOuts' || - sourceNode?.data?.parameters?.apiOuts?.some((out: any) => out.name === edge.sourceHandle))) { + sourceNode?.data?.parameters?.apiOuts?.some((out: any) => (out.name || out.id) === edge.sourceHandle))) { lineType = 'API'; } else if (edge.targetHandle && (edge.targetHandle === 'apiIns' || - targetNode?.data?.parameters?.apiIns?.some((inp: any) => inp.name === edge.targetHandle))) { + targetNode?.data?.parameters?.apiIns?.some((inp: any) => (inp.name || inp.id) === edge.targetHandle))) { lineType = 'API'; } @@ -350,19 +344,139 @@ export const revertFlowData = (nodes: any[], edges: any[]) => { return flowData; }; +// 获取节点的API输入参数 +const getNodeApiIns = (nodeId: string, nodeConfig: any, currentProjectCompData: any[]) => { + // 对于特定类型的节点使用预定义值 + if (nodeConfig.component?.type === 'LOOP_START') { + return [{ name: 'start', desc: '', dataType: '', defaultValue: '' }]; + } + else if (nodeConfig.component?.type === 'LOOP_END') { + return [{ name: 'continue', desc: '', dataType: '', defaultValue: '' }]; + } + else if (nodeId === 'end') { + return [{ name: 'end', desc: '', dataType: '', defaultValue: '' }]; + } + else { + const comp = currentProjectCompData.filter(item => item.id === nodeConfig?.component?.compId); + if (comp && comp.length > 0) { + return comp[0].def.apis.map(v => { + return { + ...v, + name: v.id, + desc: v.desc, + dataType: v?.dataType || '', + defaultValue: v?.defaultValue || '' + }; + }); + } + else { + return [{ name: 'start', desc: '', dataType: '', defaultValue: '' }]; + } + } +}; -// 通过nodeType先区分是否需要使用特殊nodeId,不需要就正常分类开始结束的句柄id -const buildNodeId = (nodeId, type) => { - if (nodeId.includes('LOOP_START')) { - if (type === 'in') return 'start'; - else return 'done'; +// 获取节点的API输出参数 +const getNodeApiOuts = (nodeId: string, nodeConfig: any, currentProjectCompData: any[]) => { + // 对于特定类型的节点使用预定义值 + if (nodeConfig.component?.type === 'LOOP_START') { + return [{ name: 'done', desc: '', dataType: '', defaultValue: '' }]; } - else if (nodeId.includes('LOOP_END')) { - if (type === 'in') return 'continue'; - else return 'break'; + else if (nodeConfig.component?.type === 'LOOP_END') { + return [{ name: 'break', desc: '', dataType: '', defaultValue: '' }]; + } + else if (nodeId === 'start') { + return [{ name: 'start', desc: '', dataType: '', defaultValue: '' }]; } else { - if (type === 'in') return 'start'; - else return nodeId === 'end' ? 'end' : 'done'; + const comp = currentProjectCompData.filter(item => item.id === nodeConfig?.component?.compId); + if (comp && comp.length > 0) { + return [{ + ...comp[0].def.apiOut, + dataType: '', + defaultValue: '' + }]; + } + else { + return [{ name: 'done', desc: '', dataType: '', defaultValue: '' }]; + } } + }; + +// 获取节点的API输出句柄名称 +const getNodeApiOutHandle = (nodeId: string, nodeConfig: any) => { + if (nodeConfig.component?.type === 'LOOP_START') { + return 'done'; + } + else if (nodeConfig.component?.type === 'LOOP_END') { + return 'break'; + } + else if (nodeId === 'start') { + return 'start'; + } + else if (nodeId === 'end') { + return 'end'; + } + return 'done'; +}; + +// 获取当前工程下组件列表并扁平化处理 +const getCurrentProjectStoreData = () => { + const { info, projectComponentData } = store.getState().ideContainer; + const compData = projectComponentData[info?.id] || {}; + + const result: any[] = []; + + // 处理projectCompDto中的数据 + if (compData.projectCompDto) { + const { mineComp = [], pubComp = [], teamWorkComp = [] } = compData.projectCompDto; + + // 添加mineComp数据 + mineComp.forEach((item: any) => { + result.push({ + ...item, + type: 'mineComp' + }); + }); + + // 添加pubComp数据 + pubComp.forEach((item: any) => { + result.push({ + ...item, + type: 'pubComp' + }); + }); + + // 添加teamWorkComp数据 + teamWorkComp.forEach((item: any) => { + result.push({ + ...item, + type: 'teamWorkComp' + }); + }); + } + + // 处理projectFlowDto中的数据 + if (compData.projectFlowDto) { + const { mineFlow = [], pubFlow = [] } = compData.projectFlowDto; + + // 添加mineFlow数据 + mineFlow.forEach((item: any) => { + result.push({ + ...item, + type: 'mineFlow' + }); + }); + + // 添加pubFlow数据 + pubFlow.forEach((item: any) => { + result.push({ + ...item, + type: 'pubFlow' + }); + }); + } + + return result; + +}; \ No newline at end of file From 0a70157262e3a765d3ed15057ee2b9cb91e78aaa Mon Sep 17 00:00:00 2001 From: ZLY Date: Fri, 17 Oct 2025 10:31:07 +0800 Subject: [PATCH 16/89] =?UTF-8?q?feat(flowEditor):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E5=AE=9A=E4=B9=89=E6=B3=A8=E9=87=8A=E5=B9=B6?= =?UTF-8?q?=E7=A6=81=E7=94=A8JSON=E7=9B=B8=E5=85=B3=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/flowEditor/sideBar/config/localNodeData.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/flowEditor/sideBar/config/localNodeData.ts b/src/pages/flowEditor/sideBar/config/localNodeData.ts index add0cbb..aaa78cd 100644 --- a/src/pages/flowEditor/sideBar/config/localNodeData.ts +++ b/src/pages/flowEditor/sideBar/config/localNodeData.ts @@ -47,7 +47,7 @@ const str2jsonParameters = { dataOuts: [] }; -// 定义节点基本信息 +// 定义节点基本信息 画布中添加的组件列表依赖这里 const nodeDefinitions = [ { nodeName: '条件选择', nodeType: 'CONDITION', nodeGroup: 'common', icon: 'IconBranch' }, { nodeName: '与门', nodeType: 'AND', nodeGroup: 'common', icon: 'IconShareAlt' }, @@ -57,9 +57,9 @@ const nodeDefinitions = [ { nodeName: '周期', nodeType: 'CYCLE', nodeGroup: 'common', icon: 'IconSchedule' }, { nodeName: '事件接收', nodeType: 'EVENTLISTENE', nodeGroup: 'common', icon: 'IconImport' }, { nodeName: '事件发送', nodeType: 'EVENTSEND', nodeGroup: 'common', icon: 'IconExport' }, - { nodeName: 'JSON转字符串', nodeType: 'JSON2STR', nodeGroup: 'common', icon: 'IconCodeBlock' }, - { nodeName: '字符串转JSON', nodeType: 'STR2JSON', nodeGroup: 'common', icon: 'IconCodeSquare' }, - { nodeName: 'JSON封装', nodeType: 'JSONCONVERT', nodeGroup: 'common', icon: 'IconTranslate' }, + // { nodeName: 'JSON转字符串', nodeType: 'JSON2STR', nodeGroup: 'common', icon: 'IconCodeBlock' }, + // { nodeName: '字符串转JSON', nodeType: 'STR2JSON', nodeGroup: 'common', icon: 'IconCodeSquare' }, + // { nodeName: 'JSON封装', nodeType: 'JSONCONVERT', nodeGroup: 'common', icon: 'IconTranslate' }, { nodeName: '结果展示', nodeType: 'RESULT', nodeGroup: 'common', icon: 'IconInteraction' }, { nodeName: '图片展示', nodeType: 'IMAGE', nodeGroup: 'common', icon: 'IconImage' }, { nodeName: '代码编辑器', nodeType: 'CODE', nodeGroup: 'common', icon: 'IconCode' }, From 4e594e1368f79183837d7849494f185bb69bdeb2 Mon Sep 17 00:00:00 2001 From: ZLY Date: Fri, 17 Oct 2025 15:17:31 +0800 Subject: [PATCH 17/89] =?UTF-8?q?feat(flow):=20=E5=AE=9E=E7=8E=B0=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E9=80=89=E6=8B=A9=E8=8A=82=E7=82=B9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增SwitchNode组件用于渲染条件选择节点- 新增nodeContentSwitch组件用于展示条件选择节点内容 - 修改LocalNode组件中的节点类型判断逻辑- 更新localNodeData配置文件,添加switchParameters配置 - 将ConditionEditor重命名为SwitchEditor并调整其内部实现 - 调整ConditionsTable组件以支持switch类型节点 -优化LoopNode和LoopEditor中参数更新逻辑 - 移除addNodeMenu中无用的日志输出 - 更新useFlowCallbacks中节点注册逻辑以支持SWITCH类型 - 调整节点句柄渲染逻辑以适配新结构 --- .../FlowEditor/node/localNode/LocalNode.tsx | 2 +- .../FlowEditor/node/loopNode/LoopNode.tsx | 2 +- .../FlowEditor/node/switchNode/SwitchNode.tsx | 157 ++++++++++++ .../nodeEditors/LocalNodeEditor.tsx | 6 +- .../components/ConditionEditor.tsx | 24 -- .../components/ConditionsTable.tsx | 227 ++++++++++++++++-- .../nodeEditors/components/LoopEditor.tsx | 6 +- .../nodeEditors/components/SwitchEditor.tsx | 43 ++++ src/hooks/useFlowCallbacks.ts | 11 +- .../flowEditor/components/addNodeMenu.tsx | 2 - .../flowEditor/components/nodeContentLoop.tsx | 32 --- .../components/nodeContentSwitch.tsx | 176 ++++++++++++++ .../sideBar/config/localNodeData.ts | 21 +- 13 files changed, 623 insertions(+), 86 deletions(-) create mode 100644 src/components/FlowEditor/node/switchNode/SwitchNode.tsx delete mode 100644 src/components/FlowEditor/nodeEditors/components/ConditionEditor.tsx create mode 100644 src/components/FlowEditor/nodeEditors/components/SwitchEditor.tsx create mode 100644 src/pages/flowEditor/components/nodeContentSwitch.tsx diff --git a/src/components/FlowEditor/node/localNode/LocalNode.tsx b/src/components/FlowEditor/node/localNode/LocalNode.tsx index 8d347bf..e694256 100644 --- a/src/components/FlowEditor/node/localNode/LocalNode.tsx +++ b/src/components/FlowEditor/node/localNode/LocalNode.tsx @@ -10,7 +10,7 @@ import NodeContentOther from '@/pages/flowEditor/components/nodeContentOther'; const setIcon = (nodeType: string) => { let type = 'IconApps'; switch (nodeType) { - case 'CONDITION': + case 'SWITCH': type = 'IconBranch'; break; case 'AND': diff --git a/src/components/FlowEditor/node/loopNode/LoopNode.tsx b/src/components/FlowEditor/node/loopNode/LoopNode.tsx index b54cacd..a698c70 100644 --- a/src/components/FlowEditor/node/loopNode/LoopNode.tsx +++ b/src/components/FlowEditor/node/loopNode/LoopNode.tsx @@ -126,7 +126,7 @@ const LoopNode = ({ data, id }: { data: defaultNodeTypes; id: string }) => { // 合并list数组与data.parameters.apiOuts数组 const apiOuts = data.parameters?.apiOuts || []; - const mergedApiOuts = [...apiOuts, ...list]; + const mergedApiOuts = [...apiOuts]; setNewData(mergedApiOuts); } else { diff --git a/src/components/FlowEditor/node/switchNode/SwitchNode.tsx b/src/components/FlowEditor/node/switchNode/SwitchNode.tsx new file mode 100644 index 0000000..541c3a6 --- /dev/null +++ b/src/components/FlowEditor/node/switchNode/SwitchNode.tsx @@ -0,0 +1,157 @@ +import React, { useEffect, useState } from 'react'; +import { useStore } from '@xyflow/react'; +import styles from '@/components/FlowEditor/node/style/baseOther.module.less'; +import DynamicIcon from '@/components/DynamicIcon'; +import { Handle, Position } from '@xyflow/react'; +import NodeContentSwitch from '@/pages/flowEditor/components/nodeContentSwitch'; +import { defaultNodeTypes } from '@/components/FlowEditor/node/types/defaultType'; + +// 循环节点组件,用于显示循环开始和循环结束节点 +const LoopNode = ({ data, id }: { data: defaultNodeTypes; id: string }) => { + const [newData, setNewData] = useState([]); + const title = data.title || '条件选择'; + + // 获取节点选中状态 - 适配React Flow v12 API + const isSelected = useStore((state) => + state.nodeLookup.get(id)?.selected || false + ); + + // 设置图标 + const setIcon = () => { + return ; + }; + + const getOperator = (expr: string) => { + let operator; + if (expr.includes('==')) { + operator = '=='; + } + else if (expr.includes('>=')) { + operator = '>='; + } + else if (expr.includes('<=')) { + operator = '<='; + } + else if (expr.includes('<')) { + operator = '<'; + } + else if (expr.includes('>')) { + operator = '>'; + } + else { + operator = '!='; + } + return operator; + }; + + const reverseDataStructure = (processedData: any) => { + if (!processedData) { + return []; + } + try { + const parsedCustomDef = JSON.parse(processedData?.customDef); + if (!parsedCustomDef.conditions) { + return []; + } + + return parsedCustomDef.conditions.map((condition: any, index: number) => { + // 解析表达式以获取左值、操作符和右值 + let lftVal = ''; + let operator = ''; + let rgtVal = ''; + const valueType = condition.valueType || ''; + + if (condition.expression) { + // 处理布尔值表达式 + if (valueType.includes('boolean')) { + const splitStr = valueType.split('-')[1]; + operator = getOperator(condition.expression); + const pattern = new RegExp(`\\$\\.(.+)(${operator})${splitStr}`); + const match = condition.expression.match(pattern); + if (match) { + lftVal = match[1]; + operator = match[2]; + } + } + // 处理其他类型的表达式 + else { + // 简单的解析逻辑,可能需要根据实际表达式格式进行调整 + const match = condition.expression.match(/\$\.([^=!<>]+)(==|!=|>=|<=|>|<)(.+)/); + if (match) { + lftVal = match[1]; + operator = match[2]; + rgtVal = match[3]; + } + } + } + + return { + key: index, + id: Date.now(), + apiOutId: condition.apiOutId || '', + lftVal, + operator, + valueType, + rgtVal + }; + }); + } catch (e) { + console.error('Error parsing customDef:', e); + return []; + } + }; + + useEffect(() => { + if (data) { + const reverseData = reverseDataStructure(data.component); + if (reverseData.length > 0) { + const list = reverseData.map(item => { + let expression = ''; + if (item.valueType.includes('boolean')) { + const splitStr = item.valueType.split('-')[1]; + expression = `$.${item.lftVal}${item.operator}${splitStr}`; + } + else expression = `$.${item.lftVal}${item.operator}${item.rgtVal}`; + return { + name: item.apiOutId, + id: item.apiOutId, + desc: '', + defaultValue: item.valueType, + dataType: expression + }; + }); + + // 合并list数组与data.parameters.apiOuts数组 + const apiOuts = data.parameters?.apiOuts || []; + const mergedApiOuts = [...apiOuts]; + setNewData(mergedApiOuts); + } + else { + // 如果没有reverseData,则直接使用原始apiOuts + setNewData(data.parameters?.apiOuts || []); + } + } + }, [data]); + + // 创建包含额外apiOuts的新data对象 + const modifiedData = { + ...data, + parameters: { + ...data.parameters, + apiOuts: newData + } + }; + + return ( +
+
+ {setIcon()} + {title} +
+ + +
+ ); +}; + +export default LoopNode; \ No newline at end of file diff --git a/src/components/FlowEditor/nodeEditors/LocalNodeEditor.tsx b/src/components/FlowEditor/nodeEditors/LocalNodeEditor.tsx index baa192e..4c0f918 100644 --- a/src/components/FlowEditor/nodeEditors/LocalNodeEditor.tsx +++ b/src/components/FlowEditor/nodeEditors/LocalNodeEditor.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { NodeEditorProps } from './index'; import { Form, Input } from '@arco-design/web-react'; -import ConditionEditor from './components/ConditionEditor'; +import SwitchEditor from './components/SwitchEditor'; import AndEditor from './components/AndEditor'; import OrEditor from './components/OrEditor'; import WaitEditor from './components/WaitEditor'; @@ -27,8 +27,8 @@ const LocalNodeEditor: React.FC = ({ const localNodeType = nodeData.type || ''; switch (localNodeType) { - case 'CONDITION': // 条件选择 - return ; + case 'SWITCH': // 条件选择 + return ; case 'AND': // 与门 return ; case 'OR': // 或门 diff --git a/src/components/FlowEditor/nodeEditors/components/ConditionEditor.tsx b/src/components/FlowEditor/nodeEditors/components/ConditionEditor.tsx deleted file mode 100644 index 02e8f7d..0000000 --- a/src/components/FlowEditor/nodeEditors/components/ConditionEditor.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; -import { NodeEditorProps } from '@/components/FlowEditor/nodeEditors'; -import { Typography } from '@arco-design/web-react'; -import { IconUnorderedList } from '@arco-design/web-react/icon'; -import ParamsTable from './ParamsTable'; - -const ConditionEditor: React.FC = ({ nodeData, updateNodeData }) => { - return ( - <> - 输入参数 - { - updateNodeData('parameters', { - ...nodeData.parameters, - dataIns: data - }); - }} - /> - - ); -}; - -export default ConditionEditor; \ No newline at end of file diff --git a/src/components/FlowEditor/nodeEditors/components/ConditionsTable.tsx b/src/components/FlowEditor/nodeEditors/components/ConditionsTable.tsx index 276819b..af646ae 100644 --- a/src/components/FlowEditor/nodeEditors/components/ConditionsTable.tsx +++ b/src/components/FlowEditor/nodeEditors/components/ConditionsTable.tsx @@ -19,6 +19,7 @@ interface ConditionsTableProps { initialData: any; nodeData: any; onUpdateData: (data: any) => void; + type?: string; } const dataTypeOptions = [ @@ -51,9 +52,11 @@ const operationOptions = [ const ConditionsTable: React.FC = ({ initialData, nodeData, - onUpdateData + onUpdateData, + type = 'LOOP' }) => { const [data, setData] = useState([]); + const [rowData, setRowData] = useState({}); const [apiOutsList, setApiOutsList] = useState([]); const [leftList, setLeftList] = useState([]); @@ -71,7 +74,29 @@ const ConditionsTable: React.FC = ({ render: (_: any, record: TableDataItem) => ( handleSave({ ...record, apiOutId: value })} + onChange={(value) => { + // 仅更新本地状态,不立即触发保存 + const newData = [...data]; + const index = newData.findIndex((item) => record.key === item.key); + if (index >= 0) { + newData.splice(index, 1, { ...newData[index], apiOutId: value }); + setData(newData); + } + }} + onBlur={() => { + // 失去焦点时才触发保存 + const currentRow = data.find(item => item.key === record.key); + if (currentRow) { + handleSave(currentRow); + } + }} + onPressEnter={() => { + // 按回车键时也触发保存 + const currentRow = data.find(item => item.key === record.key); + if (currentRow) { + handleSave(currentRow); + } + }} placeholder="请输入逻辑出口" /> ) @@ -84,7 +109,22 @@ const ConditionsTable: React.FC = ({ autoWidth={{ minWidth: 200, maxWidth: 500 }} options={leftList} value={record.lftVal} - onChange={(value) => handleSave({ ...record, lftVal: value })} + onChange={(value) => { + // 仅更新本地状态,不立即触发保存 + const newData = [...data]; + const index = newData.findIndex((item) => record.key === item.key); + if (index >= 0) { + newData.splice(index, 1, { ...newData[index], lftVal: value }); + setData(newData); + } + }} + onBlur={() => { + // 失去焦点时才触发保存 + const currentRow = data.find(item => item.key === record.key); + if (currentRow) { + handleSave(currentRow); + } + }} placeholder="请选择需要引用的出入参数" /> ) @@ -97,7 +137,22 @@ const ConditionsTable: React.FC = ({ autoWidth={{ minWidth: 200, maxWidth: 500 }} options={operationOptions} value={record.operator} - onChange={(value) => handleSave({ ...record, operator: value })} + onChange={(value) => { + // 仅更新本地状态,不立即触发保存 + const newData = [...data]; + const index = newData.findIndex((item) => record.key === item.key); + if (index >= 0) { + newData.splice(index, 1, { ...newData[index], operator: value }); + setData(newData); + } + }} + onBlur={() => { + // 失去焦点时才触发保存 + const currentRow = data.find(item => item.key === record.key); + if (currentRow) { + handleSave(currentRow); + } + }} placeholder="请选择运算/比较符" /> ) @@ -111,7 +166,27 @@ const ConditionsTable: React.FC = ({ autoWidth={{ minWidth: 200, maxWidth: 500 }} options={dataTypeOptions} value={record.valueType} - onChange={(value) => handleSave({ ...record, valueType: value })} + onChange={(value) => { + // 仅更新本地状态,不立即触发保存 + const newData = [...data]; + const index = newData.findIndex((item) => record.key === item.key); + if (index >= 0) { + newData.splice(index, 1, { + ...newData[index], + valueType: value, + // 如果类型不是string、number或expression,则清空rgtVal + rgtVal: ['string', 'number', 'expression'].includes(value) ? newData[index].rgtVal : '' + }); + setData(newData); + } + }} + onBlur={() => { + // 失去焦点时才触发保存 + const currentRow = data.find(item => item.key === record.key); + if (currentRow) { + handleSave(currentRow); + } + }} placeholder="请选择右值类型" /> {['string', 'number', 'expression'].includes(record.valueType) ? ( @@ -119,7 +194,29 @@ const ConditionsTable: React.FC = ({ style={{ marginTop: 8 }} autoWidth={{ minWidth: 200, maxWidth: 500 }} value={record.rgtVal} - onChange={(value) => handleSave({ ...record, rgtVal: value })} + onChange={(value) => { + // 仅更新本地状态,不立即触发保存 + const newData = [...data]; + const index = newData.findIndex((item) => record.key === item.key); + if (index >= 0) { + newData.splice(index, 1, { ...newData[index], rgtVal: value }); + setData(newData); + } + }} + onBlur={() => { + // 失去焦点时才触发保存 + const currentRow = data.find(item => item.key === record.key); + if (currentRow) { + handleSave(currentRow); + } + }} + onPressEnter={() => { + // 按回车键时也触发保存 + const currentRow = data.find(item => item.key === record.key); + if (currentRow) { + handleSave(currentRow); + } + }} placeholder={'请输入'} /> ) : ()} @@ -155,14 +252,16 @@ const ConditionsTable: React.FC = ({ expression: expression }; }); + const customDef = { + apiOutIds, + conditions + }; + // 只需要动态添加开始节点的NodeId, 循环开始的节点不允许编辑信息的,所以接口需要的信息会在节点实例的时候配置 + if (type === 'LOOP') customDef['loopStartNodeId'] = nodeData.component.loopStartNodeId; + return { type: nodeData.type, - customDef: JSON.stringify({ - apiOutIds, - conditions, - // 只需要动态添加开始节点的NodeId, 循环开始的节点不允许编辑信息的,所以接口需要的信息会在节点实例的时候配置 - loopStartNodeId: nodeData.component.loopStartNodeId - }) + customDef: JSON.stringify(customDef) }; }; @@ -248,7 +347,8 @@ const ConditionsTable: React.FC = ({ const extractApiNames = () => { const apiInsNames = nodeData.parameters?.apiIns?.map((item: any) => item.name) || []; const apiOutsNames = nodeData.parameters?.apiOuts?.map((item: any) => item.name) || []; - return [...apiInsNames, ...apiOutsNames]; + if (type === 'LOOP') return [...apiInsNames, ...apiOutsNames]; + else return [...apiOutsNames]; }; // 提取dataIns中的属性,并构造成options结构 @@ -260,6 +360,73 @@ const ConditionsTable: React.FC = ({ return [...dataInsOptions]; }; + const updateOriginData = (data) => { + // 获取现有的apiOuts数组,确保我们保留所有原始数据 + const existingApiOuts = nodeData.parameters?.apiOuts || []; + + // 创建一个Map来存储当前表格中的数据,便于快速查找 + const tableDataMap = new Map(); + data.forEach(item => { + if (item.apiOutId) { + tableDataMap.set(item.apiOutId, item); + } + }); + + // 更新现有的数据或标记需要删除的数据 + const updatedApiOuts = existingApiOuts.map(item => { + // 如果在表格数据中存在,则更新它 + if (item.id && tableDataMap.has(item.id)) { + const tableItem = tableDataMap.get(item.id); + let expression = ''; + if (tableItem.valueType.includes('boolean')) { + const splitStr = tableItem.valueType.split('-')[1]; + expression = `$.${tableItem.lftVal}${tableItem.operator}${splitStr}`; + } + else { + expression = `$.${tableItem.lftVal}${tableItem.operator}${tableItem.rgtVal}`; + } + + // 更新现有项,但保留原始属性 + return { + ...item, + name: tableItem.apiOutId, + id: tableItem.apiOutId, + desc: item.desc || '', + defaultValue: tableItem.valueType, + dataType: expression + }; + } + // 如果不在表格数据中,保持原样(可能是其他地方引用的数据) + return item; + }); + + // 添加表格中有但原始数据中没有的新项 + const existingIds = new Set(existingApiOuts.map(item => item.id)); + const newItems = data + .filter(item => item.apiOutId && !existingIds.has(item.apiOutId)) + .map(tableItem => { + let expression = ''; + if (tableItem.valueType.includes('boolean')) { + const splitStr = tableItem.valueType.split('-')[1]; + expression = `$.${tableItem.lftVal}${tableItem.operator}${splitStr}`; + } + else { + expression = `$.${tableItem.lftVal}${tableItem.operator}${tableItem.rgtVal}`; + } + + return { + name: tableItem.apiOutId, + id: tableItem.apiOutId, + desc: '', + defaultValue: tableItem.valueType, + dataType: expression + }; + }); + + // 合并更新后的数据和新增数据 + return [...updatedApiOuts, ...newItems]; + }; + const handleSave = (row: TableDataItem) => { const newData = [...data]; const index = newData.findIndex((item) => row.key === item.key); @@ -271,16 +438,32 @@ const ConditionsTable: React.FC = ({ } setData(newData); // 重新构建数据结构 + const newApiOuts = updateOriginData(newData); const newComponentData = convertData(newData); - onUpdateData(newComponentData); + onUpdateData({ + ...nodeData, + parameters: { + ...nodeData.parameters, + apiOuts: newApiOuts + }, + component: newComponentData + }); }; const removeRow = (key: number | string) => { const newData = data.filter((item) => item.key !== key); setData(newData); // 重新构建数据结构 + const newApiOuts = updateOriginData(newData); const newComponentData = convertData(newData); - onUpdateData(newComponentData); + onUpdateData({ + ...nodeData, + parameters: { + ...nodeData.parameters, + apiOuts: newApiOuts + }, + component: newComponentData + }); }; const addRow = () => { @@ -296,9 +479,17 @@ const ConditionsTable: React.FC = ({ }; const newData = [...data, newRow]; setData(newData); - // 重新构建数据结构 - const newComponentData = convertData(newData); - onUpdateData(newComponentData); + // 重新构建数据结构 添加新行时不更新 + // const newApiOuts = updateOriginData(newData); + // const newComponentData = convertData(newData); + // onUpdateData({ + // ...nodeData, + // parameters: { + // ...nodeData.parameters, + // apiOuts: newApiOuts + // }, + // component: newComponentData + // }); }; // 监听nodeData.parameters.dataIns的变化,更新leftList diff --git a/src/components/FlowEditor/nodeEditors/components/LoopEditor.tsx b/src/components/FlowEditor/nodeEditors/components/LoopEditor.tsx index b667b6e..ec42ab9 100644 --- a/src/components/FlowEditor/nodeEditors/components/LoopEditor.tsx +++ b/src/components/FlowEditor/nodeEditors/components/LoopEditor.tsx @@ -27,7 +27,11 @@ const LoopEditor: React.FC = ({ nodeData, updateNodeData }) => nodeData={nodeData || null} onUpdateData={(data) => { updateNodeData('component', { - ...data + ...data.component + }); + updateNodeData('parameters', { + ...nodeData.parameters, + apiOuts: data.parameters.apiOuts }); }} /> diff --git a/src/components/FlowEditor/nodeEditors/components/SwitchEditor.tsx b/src/components/FlowEditor/nodeEditors/components/SwitchEditor.tsx new file mode 100644 index 0000000..c31e203 --- /dev/null +++ b/src/components/FlowEditor/nodeEditors/components/SwitchEditor.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +import { NodeEditorProps } from '@/components/FlowEditor/nodeEditors'; +import { Typography } from '@arco-design/web-react'; +import { IconUnorderedList } from '@arco-design/web-react/icon'; +import ParamsTable from './ParamsTable'; +import ConditionsTable from '@/components/FlowEditor/nodeEditors/components/ConditionsTable'; + +const SwitchEditor: React.FC = ({ nodeData, updateNodeData }) => { + return ( + <> + 输入参数 + { + updateNodeData('parameters', { + ...nodeData.parameters, + dataIns: data + }); + }} + /> + + + 条件表达式 + + { + updateNodeData('component', { + ...data.component + }); + updateNodeData('parameters', { + ...nodeData.parameters, + apiOuts: data.parameters.apiOuts + }); + }} + type="switch" + /> + + ); +}; + +export default SwitchEditor; \ No newline at end of file diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index 7502345..f7361f4 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -19,6 +19,7 @@ import { useAlignmentGuidelines } from '@/hooks/useAlignmentGuidelines'; import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode'; import LoopNode from '@/components/FlowEditor/node/loopNode/LoopNode'; import BasicNode from '@/components/FlowEditor/node/basicNode/BasicNode'; +import SwitchNode from '@/components/FlowEditor/node/switchNode/SwitchNode'; import { updateCanvasDataMap } from '@/store/ideContainer'; import { Dispatch } from 'redux'; @@ -59,6 +60,8 @@ export const useFlowCallbacks = ( const apiOuts = nodeParams.apiOuts || []; const apiIns = nodeParams.apiIns || []; + console.log('123:', apiIns, apiOuts); + if (apiOuts.some((api: any) => (api.name || api.id) === handleId) || apiIns.some((api: any) => (api.name || api.id) === handleId) || (handleId.includes('loop'))) { return 'api'; @@ -192,6 +195,8 @@ export const useFlowCallbacks = ( const sourceParams = sourceNode.data?.parameters || {}; const targetParams = targetNode.data?.parameters || {}; + console.log('params:', params, sourceParams, targetParams); + // 获取源handle和目标handle的类型 (api或data) const sourceHandleType = getHandleType(params.sourceHandle, sourceParams); const targetHandleType = getHandleType(params.targetHandle, targetParams); @@ -603,7 +608,7 @@ export const useFlowCallbacks = ( // 将未定义的节点动态追加进nodeTypes const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); if (!nodeMap.includes(nodeType)) { - registerNodeType(nodeType, nodeType === 'BASIC' ? BasicNode : LocalNode, nodeDefinition.nodeName); + registerNodeType(nodeType, nodeType === 'BASIC' ? BasicNode : nodeType === 'SWITCH' ? SwitchNode : LocalNode, nodeDefinition.nodeName); } // 添加新节点 @@ -706,7 +711,7 @@ export const useFlowCallbacks = ( const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); // 目前默认添加的都是系统组件/本地组件 if (!nodeMap.includes(nodeType)) { - registerNodeType(nodeType, nodeType === 'BASIC' ? BasicNode : LocalNode, nodeDefinition.nodeName); + registerNodeType(nodeType, nodeType === 'BASIC' ? BasicNode : nodeType === 'SWITCH' ? SwitchNode : LocalNode, nodeDefinition.nodeName); } setNodes((nds: Node[]) => { @@ -745,7 +750,7 @@ export const useFlowCallbacks = ( try { // 转换会原始数据类型 const revertedData = revertFlowData(nodes, edges); - console.log('revertedData:', revertedData); + console.log('revertedData(中断):', revertedData); // return; const res: any = await setMainFlow(revertedData, initialData.appId); diff --git a/src/pages/flowEditor/components/addNodeMenu.tsx b/src/pages/flowEditor/components/addNodeMenu.tsx index b71580a..a5ddcd4 100644 --- a/src/pages/flowEditor/components/addNodeMenu.tsx +++ b/src/pages/flowEditor/components/addNodeMenu.tsx @@ -69,8 +69,6 @@ const AddNodeMenu: React.FC = ({ // } // }; // }); - - console.log(projectCompList, projectFlowList, initialGroupedNodes); } // 更新状态以触发重新渲染 diff --git a/src/pages/flowEditor/components/nodeContentLoop.tsx b/src/pages/flowEditor/components/nodeContentLoop.tsx index b40d570..d34bca6 100644 --- a/src/pages/flowEditor/components/nodeContentLoop.tsx +++ b/src/pages/flowEditor/components/nodeContentLoop.tsx @@ -102,37 +102,12 @@ const renderRegularNodeHandles = (dataIns: any[], dataOuts: any[], apiIns: any[] ); }; -const formatFooter = (data: any) => { - try { - switch (data.type) { - case 'WAIT': - const { duration } = deserializeValue(data.customDef); - const hours = Math.floor(duration / 3600); - const minutes = Math.floor((duration % 3600) / 60); - const seconds = Math.floor(duration % 60); - return `${hours}小时${minutes}分钟${seconds}秒`; - case 'CYCLE': - const { intervalSeconds } = deserializeValue(data.customDef); - return cronstrue.toString(intervalSeconds, { locale: 'zh_CN' }); - case 'EVENTSEND': - case 'EVENTLISTENE': - const { name } = data.customDef; - return `事件: ${name}`; - default: - return '这个类型还没开发'; - } - } catch (e) { - console.log(e); - } -}; - const NodeContent = ({ data }: { data: NodeContentData }) => { const apiIns = data.parameters?.apiIns || []; const apiOuts = data.parameters?.apiOuts || []; const dataIns = data.parameters?.dataIns || []; const dataOuts = data.parameters?.dataOuts || []; const showFooter = data?.component?.customDef || false; - const footerData = (showFooter && data.component) || {}; // 判断节点类型 const isStartNode = data.type === 'start'; @@ -196,13 +171,6 @@ const NodeContent = ({ data }: { data: NodeContentData }) => { )} - {/*footer栏*/} - {/*{showFooter && (*/} - {/*
*/} - {/* {formatFooter(footerData)}*/} - {/*
*/} - {/*)}*/} - {renderRegularNodeHandles(dataIns, dataOuts, apiIns, apiOuts)} ); diff --git a/src/pages/flowEditor/components/nodeContentSwitch.tsx b/src/pages/flowEditor/components/nodeContentSwitch.tsx new file mode 100644 index 0000000..4120a2c --- /dev/null +++ b/src/pages/flowEditor/components/nodeContentSwitch.tsx @@ -0,0 +1,176 @@ +import React from 'react'; +import styles from '@/components/FlowEditor/node/style/baseOther.module.less'; +import { Handle, Position, useStore } from '@xyflow/react'; + +interface NodeContentData { + parameters?: { + dataIns?: any[]; + dataOuts?: any[]; + apiIns?: any[]; + apiOuts?: any[]; + }; + showFooter?: boolean; + type?: string; + + [key: string]: any; +} + +// 定义通用的句柄样式 +const handleStyles = { + mainSource: { + background: '#2290f6', + width: '8px', + height: '8px', + border: '2px solid #fff', + boxShadow: '0 0 4px rgba(0,0,0,0.2)' + }, + mainTarget: { + background: '#2290f6', + width: '8px', + height: '8px', + border: '2px solid #fff', + boxShadow: '0 0 4px rgba(0,0,0,0.2)' + }, + data: { + background: '#555', + width: '6px', + height: '6px', + border: '1px solid #fff', + boxShadow: '0 0 2px rgba(0,0,0,0.2)' + } +}; + +// 渲染普通节点的句柄 +const renderRegularNodeHandles = (dataIns: any[], dataOuts: any[], apiIns: any[], apiOuts: any[]) => { + return ( + <> + {apiOuts.map((_, index) => ( + + ))} + {apiIns.map((_, index) => ( + + ))} + + {/* 输入参数连接端点 */} + {dataIns.map((_, index) => ( + + ))} + + {/* 输出参数连接端点 */} + {dataOuts.map((_, index) => ( + + ))} + + ); +}; + +const NodeContent = ({ data }: { data: NodeContentData }) => { + const apiIns = data.parameters?.apiIns || []; + const apiOuts = data.parameters?.apiOuts || []; + const dataIns = data.parameters?.dataIns || []; + const dataOuts = data.parameters?.dataOuts || []; + + // 判断节点类型 + const isStartNode = data.type === 'start'; + const isEndNode = data.type === 'end'; + + return ( + <> + {/*content栏-api部分*/} +
+
+ {apiIns.length > 0 && ( +
+ {apiIns.map((input, index) => ( +
+ {input.desc} +
+ ))} +
+ )} + + {apiOuts.length > 0 && ( +
+ {apiOuts.map((output, index) => ( +
+ {output.desc || output.id || output.name} +
+ ))} +
+ )} +
+
+ {(dataIns.length > 0 || dataOuts.length > 0) && ( + <> + {/*分割*/} +
+ + {/*content栏-data部分*/} +
+
+ {dataIns.length > 0 && !isStartNode && ( +
+ {dataIns.map((input, index) => ( +
+ {input.id || `输入${index + 1}`} +
+ ))} +
+ )} + + {dataOuts.length > 0 && !isEndNode && ( +
+ {dataOuts.map((output, index) => ( +
+ {output.id || `输出${index + 1}`} +
+ ))} +
+ )} +
+
+ + )} + + {renderRegularNodeHandles(dataIns, dataOuts, apiIns, apiOuts)} + + ); +}; + +export default NodeContent; \ No newline at end of file diff --git a/src/pages/flowEditor/sideBar/config/localNodeData.ts b/src/pages/flowEditor/sideBar/config/localNodeData.ts index aaa78cd..2d69939 100644 --- a/src/pages/flowEditor/sideBar/config/localNodeData.ts +++ b/src/pages/flowEditor/sideBar/config/localNodeData.ts @@ -46,10 +46,26 @@ const str2jsonParameters = { dataIns: [], dataOuts: [] }; +const switchParameters = { + apiIns: [{ + name: 'start', + desc: '', + dataType: '', + defaultValue: '' + }], + apiOuts: [{ + name: 'default', + desc: '', + dataType: '', + defaultValue: '' + }], + dataIns: [], + dataOuts: [] +}; // 定义节点基本信息 画布中添加的组件列表依赖这里 const nodeDefinitions = [ - { nodeName: '条件选择', nodeType: 'CONDITION', nodeGroup: 'common', icon: 'IconBranch' }, + { nodeName: '条件选择', nodeType: 'SWITCH', nodeGroup: 'common', icon: 'IconBranch' }, { nodeName: '与门', nodeType: 'AND', nodeGroup: 'common', icon: 'IconShareAlt' }, { nodeName: '或门', nodeType: 'OR', nodeGroup: 'common', icon: 'IconPause' }, { nodeName: '等待', nodeType: 'WAIT', nodeGroup: 'common', icon: 'IconClockCircle' }, @@ -77,6 +93,9 @@ export const localNodeData = nodeDefinitions.map(({ nodeName, nodeType, nodeGrou else if (nodeType === 'STR2JSON') { parameters = str2jsonParameters; } + else if (nodeType === 'SWITCH') { + parameters = switchParameters; + } return { nodeName, From e6f5f035bb269c67fdc458c618b7b92753071f1e Mon Sep 17 00:00:00 2001 From: ZLY Date: Fri, 17 Oct 2025 17:07:24 +0800 Subject: [PATCH 18/89] =?UTF-8?q?feat(flow):=E4=B8=BASWITCH=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E6=B7=BB=E5=8A=A0=E9=BB=98=E8=AE=A4component=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useFlowCallbacks.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index f7361f4..20b817d 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -60,8 +60,6 @@ export const useFlowCallbacks = ( const apiOuts = nodeParams.apiOuts || []; const apiIns = nodeParams.apiIns || []; - console.log('123:', apiIns, apiOuts); - if (apiOuts.some((api: any) => (api.name || api.id) === handleId) || apiIns.some((api: any) => (api.name || api.id) === handleId) || (handleId.includes('loop'))) { return 'api'; @@ -605,6 +603,15 @@ export const useFlowCallbacks = ( } }; + if (nodeType === 'SWITCH') { + newNode.data.component = { + customDef: JSON.stringify({ + apiOutIds: ['default'], + conditions: [] + }) + }; + } + // 将未定义的节点动态追加进nodeTypes const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); if (!nodeMap.includes(nodeType)) { @@ -707,6 +714,15 @@ export const useFlowCallbacks = ( } }; + if (nodeType === 'SWITCH') { + newNode.data.component = { + customDef: JSON.stringify({ + apiOutIds: ['default'], + conditions: [] + }) + }; + } + // 将未定义的节点动态追加进nodeTypes const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); // 目前默认添加的都是系统组件/本地组件 From bfe24c7dfc84e582070dc78439e18b0dc07adfe5 Mon Sep 17 00:00:00 2001 From: ZLY Date: Fri, 17 Oct 2025 17:08:06 +0800 Subject: [PATCH 19/89] =?UTF-8?q?refactor(flow):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E8=BE=B9=E7=AE=97=E6=B3=95=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0SWITCH=E8=8A=82=E7=82=B9=E7=9A=84=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/convertFlowData.ts | 235 ++++++++++++++++++++++++++++++----- 1 file changed, 203 insertions(+), 32 deletions(-) diff --git a/src/utils/convertFlowData.ts b/src/utils/convertFlowData.ts index 6a673eb..335d796 100644 --- a/src/utils/convertFlowData.ts +++ b/src/utils/convertFlowData.ts @@ -2,6 +2,7 @@ import { nodeTypeMap, registerNodeType } from '@/components/FlowEditor/node'; import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode'; import LoopNode from '@/components/FlowEditor/node/loopNode/LoopNode'; import store from '@/store/index'; +import SwitchNode from '@/components/FlowEditor/node/switchNode/SwitchNode'; /** * 将提供的数据结构转换为适用于 flow editor 的 nodes 和 edges @@ -117,7 +118,7 @@ export const convertFlowData = (flowData: any, useDefault = true) => { // 注册其他节点类型 const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); if (!nodeMap.includes(nodeType) && nodeType !== 'start' && nodeType !== 'end' && nodeType !== 'LOOP') { - registerNodeType(nodeType, LocalNode, nodeConfig.componentName); + registerNodeType(nodeType, nodeType === 'SWITCH' ? SwitchNode : LocalNode, nodeConfig.componentName); } nodes.push(node); @@ -126,47 +127,41 @@ export const convertFlowData = (flowData: any, useDefault = true) => { // 用于存储已添加的边,避免重复 const addedEdges = new Set(); - // 处理连接关系 - 只处理下游连接,避免重复创建连接线 + // 创建一个映射来存储所有连接信息 + const connections = new Map(); + + // 遍历所有节点,收集连接信息 for (const entry of nodeEntries) { const nodeId: string = entry[0]; const nodeConfig: any = entry[1]; - // 处理 API 下游连接 + // 处理 API 下游连接 - 确定目标节点信息 if (nodeConfig.apiDownstream && Array.isArray(nodeConfig.apiDownstream)) { nodeConfig.apiDownstream.forEach((targetArray: string[]) => { - // 确保 targetArray 是数组并且包含字符串元素 if (Array.isArray(targetArray)) { targetArray.forEach(target => { if (typeof target === 'string' && target.includes('$$')) { const [targetNodeId, targetHandle] = target.split('$$'); - - // 动态获取源句柄,而不是使用默认值 - const sourceNode = flowData[nodeId]; - // 统一旧版本逻辑,开始节点的输出句柄是start - let sourceHandle = sourceNode.id === 'start' ? 'start' : 'done'; // 默认值 - if (sourceNode && sourceNode.component && sourceNode.component.type) { - // 根据节点类型获取正确的源句柄 - sourceHandle = getNodeApiOutHandle(nodeId, sourceNode); + const connectionKey = `${nodeId}-${targetNodeId}`; + + // 存储连接信息 + if (connections.has(connectionKey)) { + // 如果连接已存在,更新目标句柄 + const existing = connections.get(connectionKey); + if (existing) { + connections.set(connectionKey, { + ...existing, + targetHandle: targetHandle + }); + } } - else if (sourceNode && sourceNode.data && sourceNode.data.parameters && - sourceNode.data.parameters.apiOuts && sourceNode.data.parameters.apiOuts.length > 0) { - // 从apiOuts中获取第一个句柄 - sourceHandle = sourceNode.data.parameters.apiOuts[0].name || - sourceNode.data.parameters.apiOuts[0].id || sourceHandle; - } - - // 创建边的唯一标识符 - const edgeId = `${nodeId}-${targetNodeId}-${sourceHandle}-${targetHandle}`; - - // 检查是否已添加此边 - if (!addedEdges.has(edgeId)) { - addedEdges.add(edgeId); - edges.push({ - id: `${edgeId}`, + else { + // 创建新的连接信息 + connections.set(connectionKey, { source: nodeId, target: targetNodeId, - sourceHandle, - targetHandle + sourceHandle: '', // 将根据节点信息填充 + targetHandle: targetHandle }); } } @@ -175,7 +170,132 @@ export const convertFlowData = (flowData: any, useDefault = true) => { }); } - // 处理数据下游连接 + // 处理 API 上游连接 - 确定源节点信息 + if (nodeConfig.apiUpstream && Array.isArray(nodeConfig.apiUpstream)) { + nodeConfig.apiUpstream.forEach((sourceArray: string[]) => { + if (Array.isArray(sourceArray)) { + sourceArray.forEach(source => { + if (typeof source === 'string' && source.includes('$$')) { + const [sourceNodeId, sourceHandle] = source.split('$$'); + const connectionKey = `${sourceNodeId}-${nodeId}`; + + // 存储连接信息 + if (connections.has(connectionKey)) { + // 如果连接已存在,更新源句柄 + const existing = connections.get(connectionKey); + if (existing) { + connections.set(connectionKey, { + ...existing, + sourceHandle: sourceHandle + }); + } + } + else { + // 创建新的连接信息 + connections.set(connectionKey, { + source: sourceNodeId, + target: nodeId, + sourceHandle: sourceHandle, + targetHandle: '' // 将根据节点信息填充 + }); + } + } + }); + } + }); + } + } + + // 根据收集的连接信息生成实际的边 + const connectionEntries = Array.from(connections.entries()); + for (const [connectionKey, connectionInfo] of connectionEntries) { + const { source, target, sourceHandle, targetHandle } = connectionInfo; + + // 获取源节点和目标节点 + const sourceNode = flowData[source]; + const targetNode = flowData[target]; + + // 确定最终的源句柄 + let finalSourceHandle = sourceHandle; + // 如果源句柄未指定,则根据源节点信息确定 + if (!finalSourceHandle) { + if (source === 'start') { + finalSourceHandle = 'start'; + } + else if (sourceNode && sourceNode.data && sourceNode.data.parameters && + sourceNode.data.parameters.apiOuts && sourceNode.data.parameters.apiOuts.length > 0) { + // 查找匹配的目标句柄 + const matchingApiOut = sourceNode.data.parameters.apiOuts.find( + (apiOut: any) => apiOut.name === targetHandle + ); + + if (matchingApiOut) { + finalSourceHandle = matchingApiOut.name; + } + else { + // 如果没有精确匹配,使用第一个apiOut + finalSourceHandle = sourceNode.data.parameters.apiOuts[0].name; + } + } + else if (sourceNode && sourceNode.component && sourceNode.component.type) { + // 根据节点类型获取正确的源句柄 + finalSourceHandle = getNodeApiOutHandle(source, sourceNode); + } + else { + // 默认句柄 + finalSourceHandle = 'done'; + } + } + + // 确定最终的目标句柄 + let finalTargetHandle = targetHandle; + // 如果目标句柄未指定,则根据目标节点信息确定 + if (!finalTargetHandle) { + if (target === 'end') { + finalTargetHandle = 'end'; + } + else if (targetNode && targetNode.data && targetNode.data.parameters && + targetNode.data.parameters.apiIns && targetNode.data.parameters.apiIns.length > 0) { + // 查找匹配的源句柄 + const matchingApiIn = targetNode.data.parameters.apiIns.find( + (apiIn: any) => apiIn.name === sourceHandle + ); + + if (matchingApiIn) { + finalTargetHandle = matchingApiIn.name; + } + else { + // 如果没有精确匹配,使用第一个apiIn + finalTargetHandle = targetNode.data.parameters.apiIns[0].name; + } + } + else { + // 默认句柄 + finalTargetHandle = 'start'; + } + } + + // 创建边的唯一标识符 + const edgeId = `${source}-${target}-${finalSourceHandle}-${finalTargetHandle}`; + + // 检查是否已添加此边 + if (!addedEdges.has(edgeId)) { + addedEdges.add(edgeId); + edges.push({ + id: `${edgeId}`, + source: source, + target: target, + sourceHandle: finalSourceHandle, + targetHandle: finalTargetHandle + }); + } + } + + // 处理数据下游连接 + for (const entry of nodeEntries) { + const nodeId: string = entry[0]; + const nodeConfig: any = entry[1]; + if (nodeConfig.dataDownstream && Array.isArray(nodeConfig.dataDownstream)) { nodeConfig.dataDownstream.forEach((connectionGroup: string[]) => { // 确保 connectionGroup 是数组并且至少包含两个元素 @@ -382,7 +502,58 @@ const getNodeApiOuts = (nodeId: string, nodeConfig: any, currentProjectCompData: return [{ name: 'done', desc: '', dataType: '', defaultValue: '' }]; } else if (nodeConfig.component?.type === 'LOOP_END') { - return [{ name: 'break', desc: '', dataType: '', defaultValue: '' }]; + // 从customDef中获取apiOutIds数组 + try { + const customDef = JSON.parse(nodeConfig.component?.customDef || '{}'); + const apiOutIds = customDef.apiOutIds || []; + + // 从"break"开始的所有项都应该作为apiOut返回 + const breakIndex = apiOutIds.indexOf('break'); + if (breakIndex !== -1) { + // 返回从"break"开始的所有项 + return apiOutIds.slice(breakIndex).map(id => ({ + name: id, + id: id, + desc: id, + dataType: '', + defaultValue: '' + })); + } + else { + // 如果没有找到"break",则返回默认值 + return [{ name: 'break', desc: '', dataType: '', defaultValue: '' }]; + } + } catch (e) { + // 解析失败时返回默认值 + return [{ name: 'break', desc: '', dataType: '', defaultValue: '' }]; + } + } + else if (nodeConfig.component?.type === 'SWITCH') { + // 从customDef中获取apiOutIds数组 + try { + const customDef = JSON.parse(nodeConfig.component?.customDef || '{}'); + const apiOutIds = customDef.apiOutIds || []; + + // 从"break"开始的所有项都应该作为apiOut返回 + const breakIndex = apiOutIds.indexOf('default'); + if (breakIndex !== -1) { + // 返回从"break"开始的所有项 + return apiOutIds.slice(breakIndex).map(id => ({ + name: id, + id: id, + desc: id, + dataType: '', + defaultValue: '' + })); + } + else { + // 如果没有找到"break",则返回默认值 + return [{ name: 'default', desc: '', dataType: '', defaultValue: '' }]; + } + } catch (e) { + // 解析失败时返回默认值 + return [{ name: 'done', desc: '', dataType: '', defaultValue: '' }]; + } } else if (nodeId === 'start') { return [{ name: 'start', desc: '', dataType: '', defaultValue: '' }]; @@ -400,11 +571,11 @@ const getNodeApiOuts = (nodeId: string, nodeConfig: any, currentProjectCompData: return [{ name: 'done', desc: '', dataType: '', defaultValue: '' }]; } } - }; // 获取节点的API输出句柄名称 const getNodeApiOutHandle = (nodeId: string, nodeConfig: any) => { + console.log('nodeConfig:', nodeConfig); if (nodeConfig.component?.type === 'LOOP_START') { return 'done'; } From d43d84143f85722a239c74a0b999132173c33fa5 Mon Sep 17 00:00:00 2001 From: ZLY Date: Sun, 19 Oct 2025 09:44:38 +0800 Subject: [PATCH 20/89] =?UTF-8?q?feat(ideContainer):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E5=BA=94=E7=94=A8=E6=95=B0=E6=8D=AE=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 ideContainer 状态中新增 currentAppData 字段用于存储当前选中的应用数据 - 添加 updateCurrentAppData action 用于更新当前应用数据 - 在页面组件中调用 dispatch 更新 currentAppData 状态 - 实现菜单项查找函数 findMenuItem用于定位当前应用数据 - 在侧边栏操作中同步更新当前应用数据状态 --- src/pages/ideContainer/index.tsx | 4 +++- src/pages/ideContainer/sideBar.tsx | 18 +++++++++++++++++- src/store/ideContainer.ts | 6 ++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/pages/ideContainer/index.tsx b/src/pages/ideContainer/index.tsx index df8a70b..ea3324c 100644 --- a/src/pages/ideContainer/index.tsx +++ b/src/pages/ideContainer/index.tsx @@ -6,7 +6,7 @@ import LogBar from './logBar'; import RightSideBar from './rightSideBar'; import NavBar, { NavBarRef } from './navBar'; import { Selected } from '@/pages/ideContainer/types'; -import { updateInfo, updateProjectComponentData } from '@/store/ideContainer'; +import { updateCurrentAppData, updateInfo, updateProjectComponentData } from '@/store/ideContainer'; import { useDispatch, useSelector } from 'react-redux'; import { getAppListBySceneId } from '@/api/apps'; import { getProjectComp } from '@/api/scene'; @@ -200,6 +200,8 @@ function IDEContainer() { const menuItems = menuData[urlParams.identity]; const menuItem = findMenuItem(menuItems, key); + dispatch(updateCurrentAppData({ ...menuItem })); + if (menuItem) { setSelected({ ...menuItem, diff --git a/src/pages/ideContainer/sideBar.tsx b/src/pages/ideContainer/sideBar.tsx index 4b52f32..9851514 100644 --- a/src/pages/ideContainer/sideBar.tsx +++ b/src/pages/ideContainer/sideBar.tsx @@ -17,7 +17,7 @@ import { menuData1, menuData2 } from './config/menuData'; import { IconSearch, IconPlus } from '@arco-design/web-react/icon'; import { Selected } from '@/pages/ideContainer/types'; import { useDispatch, useSelector } from 'react-redux'; -import { updateMenuData, updateFlowData } from '@/store/ideContainer'; +import { updateMenuData, updateFlowData, updateCurrentAppData } from '@/store/ideContainer'; import { addApp, getProjectEnv, editApp, deleteApp } from '@/api/apps'; import _ from 'lodash'; import { getAppInfoNew } from '@/api/appRes'; @@ -281,10 +281,26 @@ const SideBar: React.FC = ({ }; }); + const findMenuItem = (menuItems: any[], key: string): any => { + for (const item of menuItems) { + if (item.key === key) { + return item; + } + if (item.children) { + const found = findMenuItem(item.children, key); + if (found) return found; + } + } + return null; + }; + + // 更新 menuData 中的数据 dispatch(updateMenuData({ ...menuData, [identity]: currentMenu })); // 更新 flowData 中的数据 dispatch(updateFlowData({ [data.id]: res.data })); + // 更新 currentAppData 中的数据 + dispatch(updateCurrentAppData({ ...findMenuItem(menuData[identity], children.key) })); // 同时更新本地 menu 状态以触发重新渲染 setMenu(prevMenu => { diff --git a/src/store/ideContainer.ts b/src/store/ideContainer.ts index ef2cf8c..1bc7502 100644 --- a/src/store/ideContainer.ts +++ b/src/store/ideContainer.ts @@ -6,6 +6,7 @@ interface IDEContainerState { flowData: any; canvasDataMap: any; projectComponentData: any; + currentAppData: any; logBarStatus?: boolean; } @@ -15,6 +16,7 @@ const initialState: IDEContainerState = { flowData: {}, // 编排数据,即流程图的渲染数据 canvasDataMap: {}, // 每个画布的缓存信息 projectComponentData: {}, // 工程下的组件列表 + currentAppData: {}, // 当前选中的应用数据 logBarStatus: false }; @@ -37,6 +39,9 @@ const ideContainerSlice = createSlice({ updateProjectComponentData(state, action) { state.projectComponentData = { ...state.projectComponentData, ...action.payload }; }, + updateCurrentAppData(state, action) { + state.currentAppData = action.payload; + }, updateLogBarStatus(state, action) { state.logBarStatus = action.payload; } @@ -49,6 +54,7 @@ export const { updateFlowData, updateCanvasDataMap, updateProjectComponentData, + updateCurrentAppData, updateLogBarStatus } = ideContainerSlice.actions; From dcd1a0005965d13b4bd94d3c9d9457614fe81a98 Mon Sep 17 00:00:00 2001 From: ZLY Date: Sun, 19 Oct 2025 09:44:49 +0800 Subject: [PATCH 21/89] =?UTF-8?q?feat(flow):=20=E5=AE=9E=E7=8E=B0=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E7=9B=91=E5=90=AC=E4=B8=8E=E5=8F=91=E9=80=81=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E7=9A=84=E6=95=B0=E6=8D=AE=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/EventListenEditor.tsx | 15 +++++++- .../nodeEditors/components/EventSelect.tsx | 38 +++++++++++++++++-- .../components/EventSendEditor.tsx | 18 ++++++++- 3 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/components/FlowEditor/nodeEditors/components/EventListenEditor.tsx b/src/components/FlowEditor/nodeEditors/components/EventListenEditor.tsx index b588a06..648f196 100644 --- a/src/components/FlowEditor/nodeEditors/components/EventListenEditor.tsx +++ b/src/components/FlowEditor/nodeEditors/components/EventListenEditor.tsx @@ -1,11 +1,23 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { NodeEditorProps } from '@/components/FlowEditor/nodeEditors'; import { Typography } from '@arco-design/web-react'; import { IconUnorderedList } from '@arco-design/web-react/icon'; import EventSelect from './EventSelect'; +import { useDispatch, useSelector } from 'react-redux'; +import { queryEventItemBySceneId } from '@/api/event'; const EventListenEditor: React.FC = ({ nodeData, updateNodeData }) => { const [eventList, setEventList] = useState(); + const { currentAppData } = useSelector(state => state.ideContainer); + + const getEventList = async () => { + const res = await queryEventItemBySceneId(currentAppData.sceneId); + setEventList(res.data); + }; + + useEffect(() => { + getEventList(); + }, []); return ( <> @@ -13,6 +25,7 @@ const EventListenEditor: React.FC = ({ nodeData, updateNodeData { updateNodeData('component', { ...data diff --git a/src/components/FlowEditor/nodeEditors/components/EventSelect.tsx b/src/components/FlowEditor/nodeEditors/components/EventSelect.tsx index a3288b4..c179bc0 100644 --- a/src/components/FlowEditor/nodeEditors/components/EventSelect.tsx +++ b/src/components/FlowEditor/nodeEditors/components/EventSelect.tsx @@ -1,6 +1,9 @@ import React, { useEffect, useState } from 'react'; -import { Select, Divider, Modal, Button, Form, Input } from '@arco-design/web-react'; +import { Select, Divider, Modal, Button, Form, Input, Message } from '@arco-design/web-react'; import { IconPlus } from '@arco-design/web-react/icon'; +import { useDispatch, useSelector } from 'react-redux'; +import { addEventItem } from '@/api/event'; +import { AddEventParams } from '@/api/interface'; const FormItem = Form.Item; const TextArea = Input.TextArea; @@ -9,6 +12,7 @@ const Option = Select.Option; interface EventSelectProps { eventList: any[]; type: 'send' | 'listen'; + onRefresh: () => void; onUpdateData: (data) => void; } @@ -17,10 +21,11 @@ const typeMap = { listen: 'EVENTLISTENE' }; -const EventSelect: React.FC = ({ eventList, type, onUpdateData }) => { +const EventSelect: React.FC = ({ eventList, type, onRefresh, onUpdateData }) => { const [options, setOptions] = useState([]); const [form] = Form.useForm(); const [showModal, setShowModal] = useState(false); + const { currentAppData } = useSelector(state => state.ideContainer); useEffect(() => { eventList && setOptions(eventList); @@ -32,9 +37,22 @@ const EventSelect: React.FC = ({ eventList, type, onUpdateData const saveForm = async () => { try { - // TODO 需要对接事件新增的接口 await form.validate(); - console.log('form:', form.getFields()); + const formData = form.getFields(); + const params = { + ...formData, + sceneId: currentAppData.sceneId, + topic: formData.topic += `/${currentAppData.identify}` + }; + const res: any = await addEventItem(params as AddEventParams); + + if (res && res.code === 200) { + Message.success('添加成功'); + onRefresh(); + } + else { + Message.error(res.message); + } setShowModal(false); } catch (e) { } @@ -140,6 +158,18 @@ const EventSelect: React.FC = ({ eventList, type, onUpdateData