|  |  | 
 |  |  | import React, { useRef, useEffect } from "react"; | 
 |  |  | import React, { useRef, useEffect, useState } from "react"; | 
 |  |  | import { Button, message, Modal, Divider, List, Typography, Input, Popconfirm } from 'antd'; | 
 |  |  | import { DeleteFilled, ApiOutlined } from '@ant-design/icons'; | 
 |  |  | import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; | 
 |  |  | import { solarizedlight } from 'react-syntax-highlighter/dist/esm/styles/prism'; | 
 |  |  | import { exportDataToServer, getFlowList, deleteFlowById, updateFlowStatus, mockRun } from "../../services/flow/api"; | 
 |  |  | import './css/GraphTools.less' | 
 |  |  | import { flow, remove } from "lodash"; | 
 |  |  | import { find } from "lodash"; | 
 |  |  |  | 
 |  |  | export const GraphTools = ({ graphRef,isReady }) => { | 
 |  |  | export const GraphTools = ({ graphRef, isReady }) => { | 
 |  |  |  | 
 |  |  |     const exportData = () => { | 
 |  |  |     const [isModalOpen, setIsModalOpen] = useState(false); | 
 |  |  |     const [saveIsModalOpen, setSaveIsModalOpen] = useState(false); | 
 |  |  |     const [preCode, setPreCode] = useState(null); | 
 |  |  |     const [flowListData, setFlowListData] = useState([]); | 
 |  |  |     const [currentFlow, setCurrentFlow] = useState(null); | 
 |  |  |     const [flowName, setFlowName] = useState(null); | 
 |  |  |     const [flowMemo, setFlowMemo] = useState(null); | 
 |  |  |  | 
 |  |  |     let flowId = -1; | 
 |  |  |  | 
 |  |  |     const handleOk = () => { | 
 |  |  |         setIsModalOpen(false); | 
 |  |  |     }; | 
 |  |  |  | 
 |  |  |     const handleCancel = () => { | 
 |  |  |         setIsModalOpen(false); | 
 |  |  |         setSaveIsModalOpen(false); | 
 |  |  |     }; | 
 |  |  |  | 
 |  |  |     const flowNameInputChange = (e) => { | 
 |  |  |         setFlowName(e.target.value) | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const memoInputChange = (e) => { | 
 |  |  |         setFlowMemo(e.target.value) | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const saveData = () => { | 
 |  |  |         if (currentFlow == null) { | 
 |  |  |             flowId = -1; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         setSaveIsModalOpen(true); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     //预览代码 | 
 |  |  |     const prewCode = () => { | 
 |  |  |         const graph = graphRef.current; | 
 |  |  |         if (graph) { | 
 |  |  |         if (isReady) { | 
 |  |  |             const data = graph.toJSON(); | 
 |  |  |             console.log(data); | 
 |  |  |             // 这里你可以将数据发送到服务器或保存到本地 | 
 |  |  |  | 
 |  |  |             const edges = []; | 
 |  |  |             const nodes = []; | 
 |  |  |             let rootNode = null; | 
 |  |  |             data.cells.forEach((item) => { | 
 |  |  |                 if (item.shape == "edge") { | 
 |  |  |                     edges.push(item) | 
 |  |  |                 } else { | 
 |  |  |                     nodes.push(item) | 
 |  |  |                     if (item.data.root) { | 
 |  |  |                         rootNode = item; | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |             }) | 
 |  |  |  | 
 |  |  |             if (rootNode == null) { | 
 |  |  |                 message.warning('请设置程序入口组件'); | 
 |  |  |                 return; | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             const codeContent = transCode(rootNode, nodes, graph) | 
 |  |  |             console.log(codeContent); | 
 |  |  |  | 
 |  |  |             setPreCode(codeContent); | 
 |  |  |             setIsModalOpen(true); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     return <button onClick={exportData}>导出数据</button>; | 
 |  |  |     const exportData = () => { | 
 |  |  |         const graph = graphRef.current; | 
 |  |  |         if (isReady) { | 
 |  |  |             const data = graph.toJSON(); | 
 |  |  |             console.log(data); | 
 |  |  |             // 这里你可以将数据发送到服务器或保存到本地 | 
 |  |  |  | 
 |  |  |             const edges = []; | 
 |  |  |             const nodes = []; | 
 |  |  |             let rootNode = null; | 
 |  |  |             data.cells.forEach((item) => { | 
 |  |  |                 if (item.shape == "edge") { | 
 |  |  |                     edges.push(item) | 
 |  |  |                 } else { | 
 |  |  |                     nodes.push(item) | 
 |  |  |                     if (item.data.root) { | 
 |  |  |                         rootNode = item; | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |             }) | 
 |  |  |  | 
 |  |  |             if (rootNode == null) { | 
 |  |  |                 message.warning('请设置程序入口组件'); | 
 |  |  |                 return; | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             let id = null; | 
 |  |  |             if (currentFlow != null) { | 
 |  |  |                 id = currentFlow.id; | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             let result = sortNodes(rootNode, nodes, graph); | 
 |  |  |             let targetResult = setResult(edges, result) | 
 |  |  |             console.log(targetResult); | 
 |  |  |             exportDataToServer({ | 
 |  |  |                 originData: JSON.stringify(data), | 
 |  |  |                 data: result, | 
 |  |  |                 name: flowName, | 
 |  |  |                 memo: flowMemo, | 
 |  |  |                 id: id | 
 |  |  |             }).then((res) => { | 
 |  |  |                 if (res.code == 200) { | 
 |  |  |                     message.success('保存成功'); | 
 |  |  |                     updateFlowList(); | 
 |  |  |                 } else { | 
 |  |  |                     message.warning(res.msg); | 
 |  |  |                 } | 
 |  |  |                 setSaveIsModalOpen(false); | 
 |  |  |             }) | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const sortNodes = (rootNode, nodes, graph) => { | 
 |  |  |         let values = nodeDFS(rootNode, nodes, graph); | 
 |  |  |         const searchNode = { | 
 |  |  |             id: 1, | 
 |  |  |             parent: null, | 
 |  |  |             logicBool: true | 
 |  |  |         }; | 
 |  |  |  | 
 |  |  |         let cpValues = JSON.parse(JSON.stringify(values)) | 
 |  |  |  | 
 |  |  |         let searchIndex = 0; | 
 |  |  |         cpValues.forEach((value) => { | 
 |  |  |             if (value.data.isLogic) { | 
 |  |  |                 value.data.searchLogicId = searchNode.id; | 
 |  |  |                 value.data.searchLogicBool = searchNode.logicBool; | 
 |  |  |                 value.data.searchIndex = searchIndex++; | 
 |  |  |  | 
 |  |  |                 let tmpSearchNode = JSON.parse(JSON.stringify(searchNode)) | 
 |  |  |                 searchNode.parent = tmpSearchNode; | 
 |  |  |                 searchNode.id = value.id; | 
 |  |  |                 searchNode.logicBool = null; | 
 |  |  |                 searchIndex = 0; | 
 |  |  |             } else { | 
 |  |  |                 let id = searchNode.id; | 
 |  |  |                 let logicBool = searchNode.logicBool; | 
 |  |  |  | 
 |  |  |                 const connectedEdges = graph.getConnectedEdges(value);//取边 | 
 |  |  |                 connectedEdges.forEach((edge) => { | 
 |  |  |                     let tmpSearchNode = JSON.parse(JSON.stringify(searchNode)); | 
 |  |  |                     while (tmpSearchNode.parent != null) { | 
 |  |  |                         if (edge.source.cell == tmpSearchNode.id) { | 
 |  |  |                             logicBool = edge.data.logicBool;//更新方向 | 
 |  |  |                             searchNode.logicBool = edge.data.logicBool; | 
 |  |  |                             id = tmpSearchNode.id; | 
 |  |  |                             break; | 
 |  |  |                         } | 
 |  |  |                         tmpSearchNode = tmpSearchNode.parent; | 
 |  |  |                     } | 
 |  |  |                 }) | 
 |  |  |  | 
 |  |  |                 value.data.searchLogicId = id; | 
 |  |  |                 value.data.searchLogicBool = logicBool; | 
 |  |  |                 value.data.searchIndex = searchIndex++; | 
 |  |  |             } | 
 |  |  |         }) | 
 |  |  |  | 
 |  |  |         return cpValues; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const setResult = (edges, result) => { | 
 |  |  |         console.log(edges, result); | 
 |  |  |         result.forEach((item) => { | 
 |  |  |             let find = findEdge(edges, item.id) | 
 |  |  |  | 
 |  |  |             item.nextTrue = ""; | 
 |  |  |             item.nextFalse = ""; | 
 |  |  |  | 
 |  |  |             find.forEach((edge) => { | 
 |  |  |                 if (edge.data.logicBool == true) { | 
 |  |  |                     item.nextTrue = edge.target.cell; | 
 |  |  |                 } else { | 
 |  |  |                     item.nextFalse = edge.target.cell; | 
 |  |  |                 } | 
 |  |  |             }) | 
 |  |  |         }) | 
 |  |  |  | 
 |  |  |         return result; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const findEdge = (edges, parentId) => { | 
 |  |  |         let list = []; | 
 |  |  |         edges.forEach((edge) => { | 
 |  |  |             if (edge.source.cell == parentId) { | 
 |  |  |                 list.push(edge); | 
 |  |  |             } | 
 |  |  |         }) | 
 |  |  |  | 
 |  |  |         return list; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const transCode = (rootNode, nodes, graph) => { | 
 |  |  |         let codeContent = ""; | 
 |  |  |  | 
 |  |  |         let values = nodeDFS(rootNode, nodes, graph); | 
 |  |  |         const searchNode = { | 
 |  |  |             id: 1, | 
 |  |  |             parent: null, | 
 |  |  |             logicBool: true | 
 |  |  |         }; | 
 |  |  |  | 
 |  |  |         let cpValues = JSON.parse(JSON.stringify(values)) | 
 |  |  |  | 
 |  |  |         let searchIndex = 0; | 
 |  |  |         cpValues.forEach((value) => { | 
 |  |  |             if (value.data.isLogic) { | 
 |  |  |                 value.data.searchLogicId = searchNode.id; | 
 |  |  |                 value.data.searchLogicBool = searchNode.logicBool; | 
 |  |  |                 value.data.searchIndex = searchIndex++; | 
 |  |  |  | 
 |  |  |                 let tmpSearchNode = JSON.parse(JSON.stringify(searchNode)) | 
 |  |  |                 searchNode.parent = tmpSearchNode; | 
 |  |  |                 searchNode.id = value.id; | 
 |  |  |                 searchNode.logicBool = null; | 
 |  |  |                 searchIndex = 0; | 
 |  |  |             } else { | 
 |  |  |                 let id = searchNode.id; | 
 |  |  |                 let logicBool = searchNode.logicBool; | 
 |  |  |  | 
 |  |  |                 const connectedEdges = graph.getConnectedEdges(value);//取边 | 
 |  |  |                 connectedEdges.forEach((edge) => { | 
 |  |  |                     let tmpSearchNode = JSON.parse(JSON.stringify(searchNode)); | 
 |  |  |                     while (tmpSearchNode.parent != null) { | 
 |  |  |                         if (edge.source.cell == tmpSearchNode.id) { | 
 |  |  |                             logicBool = edge.data.logicBool;//更新方向 | 
 |  |  |                             searchNode.logicBool = edge.data.logicBool; | 
 |  |  |                             id = tmpSearchNode.id; | 
 |  |  |                             break; | 
 |  |  |                         } | 
 |  |  |                         tmpSearchNode = tmpSearchNode.parent; | 
 |  |  |                     } | 
 |  |  |                 }) | 
 |  |  |  | 
 |  |  |                 value.data.searchLogicId = id; | 
 |  |  |                 value.data.searchLogicBool = logicBool; | 
 |  |  |                 value.data.searchIndex = searchIndex++; | 
 |  |  |             } | 
 |  |  |         }) | 
 |  |  |         console.log(cpValues); | 
 |  |  |         console.log(searchNode); | 
 |  |  |  | 
 |  |  |         let tmp = {} | 
 |  |  |         let tmpList = [] | 
 |  |  |         let tmpIndex = 0; | 
 |  |  |         for (let i = cpValues.length - 1; i >= 0; i--) { | 
 |  |  |             let item = cpValues[i]; | 
 |  |  |             if (tmp[item.data.searchLogicId] == null) { | 
 |  |  |                 tmpList[tmpIndex] = [item]; | 
 |  |  |                 tmp[item.data.searchLogicId] = { | 
 |  |  |                     index: tmpIndex, | 
 |  |  |                     code: "", | 
 |  |  |                     codeTrue: "", | 
 |  |  |                     codeFalse: "", | 
 |  |  |                     condition: "" | 
 |  |  |                 }; | 
 |  |  |                 tmpIndex++; | 
 |  |  |             } else { | 
 |  |  |                 tmpList[tmp[item.data.searchLogicId].index].push(item); | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         console.log(tmp, tmpList); | 
 |  |  |  | 
 |  |  |         tmpList.forEach((item) => { | 
 |  |  |             item.forEach((val) => { | 
 |  |  |                 let originCode = tmp[val.data.searchLogicId].codeTrue; | 
 |  |  |                 if (!val.data.searchLogicBool) { | 
 |  |  |                     originCode = tmp[val.data.searchLogicId].codeFalse; | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 let codeContent = val.data.codeContent; | 
 |  |  |  | 
 |  |  |                 if (val.data.isLogic) { | 
 |  |  |                     codeContent = val.id + "_logic_tag"; | 
 |  |  |                     console.log(val.data); | 
 |  |  |                     tmp[val.id].condition = val.data.codeContent; | 
 |  |  |                 } else { | 
 |  |  |                     codeContent = ` | 
 |  |  |                     //**********${val.attrs.text.text}-start**********// | 
 |  |  |                     ${codeContent} | 
 |  |  |                     //**********${val.attrs.text.text}-start**********// | 
 |  |  |                     `; | 
 |  |  |                 } | 
 |  |  |                 let newCode = ` | 
 |  |  |                     ${codeContent} | 
 |  |  |  | 
 |  |  |                     ${originCode} | 
 |  |  |                 `; | 
 |  |  |  | 
 |  |  |                 console.log(newCode); | 
 |  |  |                 if (val.data.searchLogicBool) { | 
 |  |  |                     tmp[val.data.searchLogicId].codeTrue = newCode; | 
 |  |  |                 } else { | 
 |  |  |                     tmp[val.data.searchLogicId].codeFalse = newCode; | 
 |  |  |                 } | 
 |  |  |             }) | 
 |  |  |         }) | 
 |  |  |  | 
 |  |  |         let sortTmp = []; | 
 |  |  |         for (var key in tmp) { | 
 |  |  |             let obj = tmp[key]; | 
 |  |  |             obj.id = key; | 
 |  |  |             sortTmp[tmp[key].index] = obj; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         console.log(sortTmp); | 
 |  |  |  | 
 |  |  |         // 合并True和False | 
 |  |  |         sortTmp.forEach((item) => { | 
 |  |  |             let nestedIfCode = ""; | 
 |  |  |             if (item.condition == "") { | 
 |  |  |                 nestedIfCode = ` | 
 |  |  |                 ${item.codeTrue} | 
 |  |  |                 ${item.codeFalse} | 
 |  |  |                 `; | 
 |  |  |             } else { | 
 |  |  |                 nestedIfCode = ` | 
 |  |  |                 if(${item.condition}){ | 
 |  |  |                     // 逻辑TRUE | 
 |  |  |                     ${item.codeTrue} | 
 |  |  |                 }else { | 
 |  |  |                     // 逻辑FALSE | 
 |  |  |                     ${item.codeFalse} | 
 |  |  |                 } | 
 |  |  |             `; | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             item.code = nestedIfCode; | 
 |  |  |         }) | 
 |  |  |  | 
 |  |  |         console.log(sortTmp); | 
 |  |  |  | 
 |  |  |         let finalTmp = {}; | 
 |  |  |         let sortTmpCopy = JSON.parse(JSON.stringify(sortTmp)); | 
 |  |  |         sortTmpCopy.forEach((item) => { | 
 |  |  |             if (item.id != "1") { | 
 |  |  |                 let codeContent = item.code; | 
 |  |  |                 sortTmp.forEach((val) => { | 
 |  |  |                     codeContent = codeContent.replace(val.id + "_logic_tag", val.code); | 
 |  |  |                     console.log(item, val.id, codeContent); | 
 |  |  |                 }) | 
 |  |  |                 finalTmp[item.id] = { | 
 |  |  |                     code: codeContent | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |         }) | 
 |  |  |  | 
 |  |  |         console.log(sortTmpCopy); | 
 |  |  |         console.log(finalTmp); | 
 |  |  |  | 
 |  |  |         sortTmpCopy.forEach((item) => { | 
 |  |  |             if (item.id == "1") { | 
 |  |  |                 let finalCode = item.code; | 
 |  |  |                 for (var key in finalTmp) { | 
 |  |  |                     let obj = finalTmp[key]; | 
 |  |  |                     finalCode = finalCode.replace(key + "_logic_tag", obj.code); | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 codeContent = finalCode; | 
 |  |  |             } | 
 |  |  |         }) | 
 |  |  |  | 
 |  |  |         codeContent = formatJavaCode(codeContent) | 
 |  |  |         return codeContent; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const formatJavaCode = (codeString) => { | 
 |  |  |         let baseIndentation = "    ";  //用四个空格表示一个缩进 | 
 |  |  |         let indentationLevel = 0;  //增加这行代码来初始化indentationLevel | 
 |  |  |  | 
 |  |  |         let formattedCode = codeString | 
 |  |  |             .replace(/^\s+/mg, '') // 移除每行前面的空白 | 
 |  |  |             .replace(/(\{|\})/g, ' $& ') // 让大括号周围都有空格 | 
 |  |  |             // 上面的.replace(/^\s+/mg, '')可能会在括号周围插入多余的空格,所以下面这行代码会移除开头或末尾的空格 | 
 |  |  |             .replace(/^\s+|\s+$/mg, '') | 
 |  |  |             // 用了.split('\n')后,每一行都是数组中的一个元素,所以可以通过减少或增加行开头的空格数来添加或删除缩进 | 
 |  |  |             .split('\n').reduce((formattedCode, currentLine) => { | 
 |  |  |                 if (currentLine.includes('}')) { | 
 |  |  |                     // 如果一行中包含右大括号,我们要减少一个缩进 | 
 |  |  |                     indentationLevel--; | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 let indentation = baseIndentation.repeat(indentationLevel); | 
 |  |  |                 let indentedLine = indentation + currentLine; | 
 |  |  |  | 
 |  |  |                 if (currentLine.includes('{')) { | 
 |  |  |                     // 如果一行中包含左大括号,那个大括号后面的代码需要额外的一个缩进 | 
 |  |  |                     indentationLevel++; | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 return formattedCode + '\n' + indentedLine; | 
 |  |  |             }, ''); | 
 |  |  |  | 
 |  |  |         return formattedCode; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const nodeDFS = (node, nodes, graph) => { | 
 |  |  |         let values = []; | 
 |  |  |         if (graph) { | 
 |  |  |             const connectedEdges = graph.getConnectedEdges(node); | 
 |  |  |             const children = []; | 
 |  |  |  | 
 |  |  |             // console.log(node); | 
 |  |  |             connectedEdges.forEach((edge) => { | 
 |  |  |                 nodes.forEach((item) => { | 
 |  |  |                     if (item.id === edge.target.cell && item.id != node.id) { | 
 |  |  |                         children.push(item); | 
 |  |  |                     } | 
 |  |  |                 }) | 
 |  |  |             }); | 
 |  |  |  | 
 |  |  |             // console.log(connectedEdges); | 
 |  |  |             if (children.length != 0) { | 
 |  |  |                 // console.log(children); | 
 |  |  |                 children.forEach((node) => { | 
 |  |  |                     // console.log(node); | 
 |  |  |                     values.push(node); | 
 |  |  |                     values = values.concat(nodeDFS(node, nodes, graph)) | 
 |  |  |                 }) | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         return values; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const setFlowActive = () => { | 
 |  |  |         if (currentFlow == null) { | 
 |  |  |             message.warning("请选择要激活使用的流程图!"); | 
 |  |  |             return; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         const status = currentFlow.status == 1 ? 0 : 1; | 
 |  |  |         updateFlowStatus(currentFlow.id, status).then((res) => { | 
 |  |  |             if (res.code == 200) { | 
 |  |  |                 message.success(status == 1 ? "激活成功" : "已取消激活"); | 
 |  |  |                 currentFlow.status = status; | 
 |  |  |             } else { | 
 |  |  |                 message.warning(res.msg); | 
 |  |  |             } | 
 |  |  |             updateFlowList(); | 
 |  |  |         }) | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const removeFlow = () => { | 
 |  |  |         if (currentFlow == null) { | 
 |  |  |             message.warning("请选择要删除的流程图!"); | 
 |  |  |             return; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         deleteFlowById(currentFlow.id).then((res) => { | 
 |  |  |             if (res.code == 200) { | 
 |  |  |                 message.success("删除成功"); | 
 |  |  |             } else { | 
 |  |  |                 message.warning(res.msg); | 
 |  |  |             } | 
 |  |  |             updateFlowList(); | 
 |  |  |         }) | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const updateFlowList = () => { | 
 |  |  |         getFlowList().then((res) => { | 
 |  |  |             setFlowListData(res.data); | 
 |  |  |         }) | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const createNewBlank = () => { | 
 |  |  |         const graph = graphRef.current; | 
 |  |  |         if (graph) { | 
 |  |  |             graph.clearCells(); | 
 |  |  |             setCurrentFlow(null); | 
 |  |  |             setFlowName(null); | 
 |  |  |             setFlowMemo(null); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const switchFlowBlank = (flow) => { | 
 |  |  |         const graph = graphRef.current; | 
 |  |  |         if (graph) { | 
 |  |  |             graph.fromJSON(JSON.parse(flow.originData)); | 
 |  |  |             setCurrentFlow(flow) | 
 |  |  |             setFlowName(flow.name); | 
 |  |  |             setFlowMemo(flow.memo); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     const testRun = () => {//模拟运行 | 
 |  |  |         if (currentFlow == null) { | 
 |  |  |             message.warning("请选择流程图"); | 
 |  |  |             return; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         mockRun(currentFlow.id).then((res) => { | 
 |  |  |             if (res.code == 200) { | 
 |  |  |                 message.success("运行成功"); | 
 |  |  |             } else { | 
 |  |  |                 message.warning(res.msg); | 
 |  |  |             } | 
 |  |  |         }) | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     useEffect(() => { | 
 |  |  |         updateFlowList(); | 
 |  |  |     }, []) | 
 |  |  |  | 
 |  |  |     return ( | 
 |  |  |         <> | 
 |  |  |             <div> | 
 |  |  |                 <div className="container"> | 
 |  |  |                     <div className="containerButton"> | 
 |  |  |                         <Button type="primary" onClick={createNewBlank}> | 
 |  |  |                             新建 | 
 |  |  |                         </Button> | 
 |  |  |                     </div> | 
 |  |  |  | 
 |  |  |                     <div className="containerButton"> | 
 |  |  |                         <Button type="primary" onClick={saveData}> | 
 |  |  |                             保存 | 
 |  |  |                         </Button> | 
 |  |  |                     </div> | 
 |  |  |  | 
 |  |  |                     <div className="containerButton"> | 
 |  |  |                         <Button type="primary" onClick={setFlowActive}> | 
 |  |  |                             激活使用 | 
 |  |  |                         </Button> | 
 |  |  |                     </div> | 
 |  |  |  | 
 |  |  |                     <div className="containerButton"> | 
 |  |  |                         <Button type="primary" onClick={prewCode}> | 
 |  |  |                             预览代码 | 
 |  |  |                         </Button> | 
 |  |  |                     </div> | 
 |  |  |  | 
 |  |  |                     <div className="containerButton"> | 
 |  |  |                         <Button type="primary" onClick={testRun}> | 
 |  |  |                             模拟运行 | 
 |  |  |                         </Button> | 
 |  |  |                     </div> | 
 |  |  |                 </div> | 
 |  |  |  | 
 |  |  |                 <div className="flowList"> | 
 |  |  |                     <List | 
 |  |  |                         header={ | 
 |  |  |                             <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> | 
 |  |  |                                 <div><Typography.Text mark>[数据]</Typography.Text> 流程图列表</div> | 
 |  |  |                                 <div> | 
 |  |  |                                     <Button type="primary" size="small" onClick={updateFlowList}> | 
 |  |  |                                         刷新 | 
 |  |  |                                     </Button> | 
 |  |  |  | 
 |  |  |                                     <Popconfirm | 
 |  |  |                                         title="删除流程图" | 
 |  |  |                                         description="确认删除?" | 
 |  |  |                                         okText="删除" | 
 |  |  |                                         cancelText="取消" | 
 |  |  |                                         onConfirm={removeFlow} | 
 |  |  |                                     > | 
 |  |  |                                         <Button style={{ marginLeft: '5px' }} type="primary" danger size="small"> | 
 |  |  |                                             <DeleteFilled /> | 
 |  |  |                                         </Button> | 
 |  |  |                                     </Popconfirm> | 
 |  |  |  | 
 |  |  |                                 </div> | 
 |  |  |                             </div> | 
 |  |  |                         } | 
 |  |  |                         dataSource={flowListData} | 
 |  |  |                         renderItem={(item) => ( | 
 |  |  |                             <List.Item> | 
 |  |  |                                 <Button type={currentFlow != null && item.id == currentFlow.id ? 'primary' : 'dashed'} style={{ width: '100%' }} onClick={() => switchFlowBlank(item)}> | 
 |  |  |                                     <div style={{ display: 'flex', justifyContent: 'space-between' }}> | 
 |  |  |                                         <div>{item.name}</div> | 
 |  |  |                                         {item.status == 1 ? <div><ApiOutlined /></div> : ''} | 
 |  |  |                                     </div> | 
 |  |  |                                 </Button> | 
 |  |  |                             </List.Item> | 
 |  |  |                         )} | 
 |  |  |                     /> | 
 |  |  |                 </div> | 
 |  |  |             </div> | 
 |  |  |  | 
 |  |  |             <Modal title="预览代码" open={isModalOpen} onOk={handleOk} onCancel={handleCancel}> | 
 |  |  |                 <SyntaxHighlighter language="java" style={solarizedlight}> | 
 |  |  |                     {preCode} | 
 |  |  |                 </SyntaxHighlighter> | 
 |  |  |             </Modal> | 
 |  |  |  | 
 |  |  |             <Modal title="保存流程图" open={saveIsModalOpen} onOk={exportData} onCancel={handleCancel}> | 
 |  |  |                 <div style={{ marginTop: '10px' }}> | 
 |  |  |                     <Input placeholder="流程图名称" value={flowName} onChange={flowNameInputChange} /> | 
 |  |  |                 </div> | 
 |  |  |                 <div style={{ marginTop: '10px' }}> | 
 |  |  |                     <Input placeholder="备注" value={flowMemo} onChange={memoInputChange} /> | 
 |  |  |                 </div> | 
 |  |  |             </Modal> | 
 |  |  |         </> | 
 |  |  |     ); | 
 |  |  | } |