From 37733cc39c04b863a0b997c7fa3d9ac6a24e08be Mon Sep 17 00:00:00 2001
From: zjj <3272660260@qq.com>
Date: 星期三, 19 六月 2024 15:58:19 +0800
Subject: [PATCH] #
---
zy-asrs-flow/src/components/Flow/GraphTools.jsx | 603 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 599 insertions(+), 4 deletions(-)
diff --git a/zy-asrs-flow/src/components/Flow/GraphTools.jsx b/zy-asrs-flow/src/components/Flow/GraphTools.jsx
index 60d5d83..dddb705 100644
--- a/zy-asrs-flow/src/components/Flow/GraphTools.jsx
+++ b/zy-asrs-flow/src/components/Flow/GraphTools.jsx
@@ -1,7 +1,82 @@
import React, { useRef, useEffect, useState } from "react";
-import { Button } from 'antd';
+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 }) => {
+
+ 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);
+ }
+
+ //棰勮浠g爜
+ const prewCode = () => {
+ const graph = graphRef.current;
+ if (isReady) {
+ const data = graph.toJSON();
+
+ 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('璇疯缃▼搴忓叆鍙g粍浠�');
+ return;
+ }
+
+ const codeContent = transCode(rootNode, nodes, graph)
+ console.log(codeContent);
+
+ setPreCode(codeContent);
+ setIsModalOpen(true);
+ }
+ }
const exportData = () => {
const graph = graphRef.current;
@@ -9,14 +84,534 @@
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('璇疯缃▼搴忓叆鍙g粍浠�');
+ 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鍜孎alse
+ 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; //澧炲姞杩欒浠g爜鏉ュ垵濮嬪寲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 (
<>
- <Button type="primary" onClick={exportData}>
- 瀵煎嚭鏁版嵁
- </Button>
+ <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}>
+ 棰勮浠g爜
+ </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="棰勮浠g爜" 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>
</>
);
}
\ No newline at end of file
--
Gitblit v1.9.1