import React, { useState, useEffect } from 'react';
import { Button, Modal, notification, Spin, Tooltip } from 'antd';
import lodash from 'lodash';
import { SaveNodeChange, GetFlowNode } from '@/services/workflow/workflow';

import { ExclamationCircleOutlined } from '@ant-design/icons';
import { Prompt } from 'react-router-dom';
import * as go from 'gojs';
import styles from '../workflow.less';
import NodeModal from './flowChartComponents/NodeModal';
import LineModal from './flowChartComponents/LineModal';
import imgUrl from '@/assets/images/icons/closeBlue.png';
import nodeEnd from '@/assets/images/workFlow/nodeEnd.png';
import nodeGeneral from '@/assets/images/workFlow/nodeGeneral.png';
import nodeStart from '@/assets/images/workFlow/nodeStart.png';
// import cc from '@/assets/images/workFlow/cc.png';
import gatewayCondition from '@/assets/images/workFlow/gatewayCondition.png';
import gatewayParallel from '@/assets/images/workFlow/gatewayParallel.png';
import gatewayJoin from '@/assets/images/workFlow/gatewayJoin.png';
const { confirm } = Modal;
let diagram = null;
const nodeTypeList = [
  { nodeTypeName: '开始节点', NodeType: '1', src: nodeStart },
  { nodeTypeName: '普通节点', NodeType: '0', src: nodeGeneral },
  { nodeTypeName: '结束节点', NodeType: '2', src: nodeEnd },
];
const gatewayList = [
  { nodeTypeName: '条件网关', NodeType: '20', src: gatewayCondition },
  { nodeTypeName: '并行网关', NodeType: '22', src: gatewayParallel },
  { nodeTypeName: '汇合网关', NodeType: '21', src: gatewayJoin },
];
const FlowChart = props => {
  const { flowData, flowID, chartLoading, leaveCallBack } = props;
  const [visible, setVisible] = useState(false);
  const [lineVisible, setLineVisible] = useState(false);
  const [editMsg, setEditMsg] = useState({}); // 编辑节点的信息
  const [lineMsg, setLineMsg] = useState({});
  const [modalType, setModalType] = useState(''); // 存入弹窗是编辑还是新增
  const [lineId, setLineId] = useState(''); //  存入编辑线id
  const [nodeKey, setNodeKey] = useState(''); // 存入编辑节点的key
  const [DeleteNodes, setDeleteNodes] = useState([]); // 删除节点数组
  const [DeleteLines, setDeleteLines] = useState([]); // 删除线数组
  const [deleteLine, setDeleteLine] = useState(); // 删除的线id
  const [deleteNode, setDeleteNode] = useState(); // 删除的节点id
  const [AddNodes, setAddNodes] = useState([]); // 新增数组
  const [initFlowData, setInitFlowData] = useState({}); // 初始数据，用来比对是否有修改流程图
  const [currentFlowData, setCurrentFlowData] = useState({
    Nodes: [],
    Lines: [],
  }); // 组件内得流程图数据
  const [showLeaveTip, setShowLeaveTip] = useState(false); // 离开路由是否又提醒
  const [newSerialNo, setNewSerialNo] = useState(0);
  const [nodeLength, setNodeLength] = useState();
  const [buttonLoading, setButtonLoading] = useState(); // 发布按钮保存loading
  const objGo = go.GraphObject.make;
  // 监听删除，给删除数组里添加删除id
  useEffect(() => {
    if (deleteLine) {
      setDeleteLines([...DeleteLines, deleteLine]);
    }
  }, [deleteLine]);
  useEffect(() => {
    if (deleteNode) {
      setDeleteNodes([...DeleteNodes, deleteNode]);
    }
  }, [deleteNode]);
  // 初始化
  useEffect(() => {
    // 初始化流程图
    init();
    // 监听节点或线的删除事件
    diagram.addDiagramListener('SelectionDeleted', e => {
      e.subject.each(n => {
        // 如果删除得节点不是新增得就给id放入到删除节点数组中
        if (n.data.NodeId && !AddNodes.some(item => item === n.data.NodeId)) {
          setTimeout(() => {
            setDeleteNode(n.data.NodeId);
          }, 0);
        }
        if (n.data.LineId) {
          setTimeout(() => {
            setDeleteLine(n.data.LineId);
          }, 0);
        }
      });
    });
    // 监听节点或线的删除前事件
    diagram.commandHandler.canDeleteSelection = () =>
      // 用例获取选中的节点或线
      diagram.selection.all(() => {
        // 判断是否存在不允许删除的节点或线
        showDeleteConfirm();
        return false;
      });
    // diagram.addDiagramListener('SelectionDeleted', e => {

    // });
    console.log(diagram.model, 'diagram.model');
    // 监听复制事件并修改复制内容
    // setTimeout(() => {}, 1200);
  }, []);
  useEffect(() => {
    if (flowData) {
      // 每次切换时清空删除得id数组跟新增得id数组
      setDeleteNodes([]);
      setDeleteLines([]);
      setAddNodes([]);
      setDeleteNode('');
      setDeleteLine('');
      setCurrentFlowData(JSON.parse(JSON.stringify(flowData)));
      setShowLeaveTip(false);
    }
  }, [flowData]);
  // 存入在树形流程中选择得流程数据
  useEffect(() => {
    let nodeDataArray;
    if (currentFlowData.Nodes.length === 0) {
      nodeDataArray = [];
    } else {
      // 处理老数据，让老数据可以正常展示
      nodeDataArray = currentFlowData.Nodes.map((item, index) => {
        let obj;
        obj = item;
        obj.key = item.NodeId;
        if (obj.points === '') {
          if (obj.NodeType === '1') {
            obj.points = `${(index * 200).toString()}" 100"`;
          } else {
            obj.points = `${(index * 200).toString()}" -22"`;
          }
        }
        return obj;
      });
    }
    // 保存初始数据
    setInitFlowData(
      JSON.parse(
        JSON.stringify({
          Nodes: nodeDataArray,
          Lines: currentFlowData.Lines,
        }),
      ),
    );
    diagram.model = go.Model.fromJson({
      linkFromPortIdProperty: 'fromPort', // 所需信息：
      linkToPortIdProperty: 'toPort', // 标识数据属性名称
      nodeDataArray,
      linkDataArray: currentFlowData.Lines,
    });
    // 修改复制后节点内容
    diagram.model.copyNodeDataFunction = (obj, model) => {
      let copyObj = JSON.parse(JSON.stringify(obj));
      delete copyObj.ActivityId;
      return copyObj;
    };
    // 修改复制后线内容
    diagram.model.copyLinkDataFunction = (obj, model) => {
      let copyObj = lodash.cloneDeep(obj);
      delete copyObj.LineId;
      return copyObj;
    };
    // diagram.model.linkKeyProperty = 'LineId';
    // diagram.model.makeUniqueLinkKeyFunction = (model, data) => {
    //   let i = model.linkDataArray.length * 2 + 2;
    //   while (model.findLinkDataForKey(i) !== null) i += 2;
    //   return i;
    // };
  }, [currentFlowData]);
  // 删除提醒
  const showDeleteConfirm = () => {
    confirm({
      title: '确定要删除所选中的节点吗？',
      icon: <ExclamationCircleOutlined />,
      content: '',
      okText: '是',
      okType: 'danger',
      cancelText: '否',
      onOk() {
        delNode();
      },
      onCancel() {},
    });
  };
  // 删除节点
  const delNode = () => {
    setShowLeaveTip(true);
    leaveCallBack(true);
    diagram.commandHandler.deleteSelection();
  };
  // 流程图初始化
  const init = () => {
    diagram = objGo(go.Diagram, 'myDiagramDiv', {
      'undoManager.isEnabled': true,
      allowDragOut: false,
      'dragSelectingTool.isEnabled': false, // 禁止多选
      allowCopy: true, // 禁止复制
      // nodeSelectionAdornmentTemplate: objGo(
      //   go.Adornment,
      //   'Auto',
      //   objGo(go.Shape, 'Rectangle', { fill: 'white', stroke: null }),
      // ), // 去掉节点点击时的边框颜色
      scale: '0.8',
    });
    // 节点配置
    diagram.nodeTemplate = objGo(
      go.Node,
      'Auto',
      new go.Binding('location', 'points', go.Point.parse).makeTwoWay(go.Point.stringify),
      // 节点样式配置
      objGo(
        go.Panel,
        nodeBoxStyle('width'),
        nodeBoxStyle('height'),
        objGo(
          go.Picture,
          new go.Binding('source', 'NodeType', v => {
            switch (v) {
              case '1':
                return nodeStart;
              case '2':
                return nodeEnd;
              case '0':
                return nodeGeneral;
              // case '4':
              //   return cc;
              case '20':
                return gatewayCondition;
              case '21':
                return gatewayJoin;
              case '22':
                return gatewayParallel;
              default:
                return null;
            }
          }),
          nodeBoxStyle('width'),
          nodeBoxStyle('height'),
        ),
        objGo(
          go.Panel,
          'Horizontal',
          nodeBoxStyle('height'),
          { alignment: go.Spot.Center },
          objGo(
            go.Panel,
            'Vertical', // 节点文案

            nodeBoxStyle('width'),
            objGo(
              go.TextBlock,
              {
                maxSize: new go.Size(120, NaN),
                maxLines: 1,
                alignment: go.Spot.Center,
                margin: new go.Margin(0, 10, 0, 10),
                overflow: go.TextBlock.OverflowEllipsis,
                font: 'normal 12pt serif',
              },
              new go.Binding('text', 'nodeDetail', v => {
                const obj = JSON.parse(v);
                if (obj.NodeType === '20' || obj.NodeType === '21' || obj.NodeType === '22') {
                  return '';
                }
                return obj.NodeName;
              }),
              nodeBoxStyle('stroke', 'nodeStyle'),
            ),
            objGo(
              go.TextBlock,

              {
                alignment: go.Spot.Center,
                maxLines: 2,
                overflow: go.TextBlock.OverflowEllipsis,
                font: 'normal 12pt serif',
              },
              new go.Binding('spacingAbove', 'roleList', v => (v?.length > 0 ? 10 : 0)),
              new go.Binding('height', 'roleList', v => (v?.length > 0 ? 20 : 0)),
              new go.Binding('margin', 'roleList', v =>
                v?.length > 0 ? new go.Margin(10, 10, 0, 10) : 0,
              ),
              new go.Binding('text', 'nodeDetail', v => {
                const obj = JSON.parse(v);
                if (obj.NodeType === '20' || obj.NodeType === '21' || obj.NodeType === '22') {
                  return '';
                }
                if (obj.roleList?.length === 0) {
                  return '';
                }
                return obj.roleList.map(item => item.roleName).join(',');
              }),
              nodeBoxStyle('stroke', 'roleStyle'),
            ),
          ),
        ),
      ),

      // 我们的小命名端口，每侧一个：
      makePort('T', go.Spot.Top),
      makePort('L', go.Spot.Left),
      makePort('R', go.Spot.Right),
      makePort('B', go.Spot.Bottom),
      {
        // 节点之间线得连接
        linkValidation(fromnode, fromport, tonode, toport, thisLink) {
          // console.log(fromnode.data, tonode.data, 'aaaaaa');
          if (fromnode.data.NodeType === '22' && tonode.data.NodeType === '21') {
            return false;
          }
          return true;
        },
        // 处理鼠标进入/离开事件以显示/隐藏端口
        mouseEnter(e, node) {
          showSmallPorts(node, true);
        },
        mouseLeave(e, node) {
          showSmallPorts(node, false);
        },
        // 处理双击
        doubleClick(e, node) {
          // 双击事件
          handlerDC(e, node); // 双击执行的方法
        },
        toolTip: objGo(
          'ToolTip',
          objGo(
            go.TextBlock,
            { margin: 4 },
            new go.Binding('text', 'nodeDetail', v => {
              const obj = JSON.parse(v);
              return `节点名称:${obj.NodeName}\n${
                obj.roleList.length > 0 ? '承办:' : ''
              }${obj.roleList.map(item => item.roleName).join(',')}`;
            }),
          ),
        ),
      },
    );
    // 链接设置
    diagram.linkTemplate = objGo(
      go.Link,
      {
        routing: go.Link.Orthogonal,
        curve: go.Link.JumpOver,
        corner: 5,
        toShortLength: 4,
        selectionAdornmentTemplate: objGo(
          go.Adornment,
          objGo(go.Shape, { isPanelMain: true, stroke: '#faad14', strokeWidth: 2 }), // 修改线颜色和大小
          objGo(go.Shape, { toArrow: 'Standard', fill: '#faad14', stroke: '#faad14' }), // 修改线箭头的颜色和大小
        ),
      },
      new go.Binding('points').makeTwoWay(),
      objGo(
        go.Shape, // 链接路径形状
        {
          isPanelMain: true,
          strokeWidth: 2,
        },

        new go.Binding('stroke', 'from', v => lineStyle(v, 'stroke')),
        new go.Binding('strokeDashArray', 'from', v => lineStyle(v, 'strokeDashArray')),
      ),
      objGo(
        go.Shape, // 箭头
        { toArrow: 'Standard' },
        new go.Binding('stroke', 'from', v => lineStyle(v, 'stroke')),
        new go.Binding('fill', 'from', v => lineStyle(v, 'stroke')),
      ),
      // {
      //   // 处理双击
      //   doubleClick(e, node) {
      //     addLineMsg(e, node);
      //     // 双击事件
      //     // handlerDC(e, node); // 双击执行的方法
      //   },
      // },
    );
    // 初始化流程的节点数组
    diagram.model = objGo(go.GraphLinksModel, {
      linkFromPortIdProperty: 'fromPort', // 所需信息：
      linkToPortIdProperty: 'toPort', // 标识数据属性名称
      nodeDataArray: currentFlowData.Nodes,
      linkDataArray: currentFlowData.Lines,
    });
  };

  // 线的样式
  const lineStyle = (v, styleName) => {
    const msg = diagram.model.findNodeDataForKey(v);
    switch (styleName) {
      case 'strokeDashArray':
        if (msg.NodeType === '20') {
          return [6, 3];
        }
        return null;
      case 'stroke':
        return '#1685FF';
      default:
        return null;
    }
  };
  // 是否显示端口
  const showSmallPorts = (node, show) => {
    node.ports.each(port => {
      if (port.portId !== '') {
        // 不要更改默认端口，这是大形状
        port.fill = show ? 'rgba(5,135,224,.3)' : null;
      }
    });
  };
  // 创建节点端口
  const makePort = (name, spot) =>
    // 端口基本上只是一个小的透明 方块
    objGo(
      go.Shape,
      'Circle',
      {
        fill: null, // 默认情况下不可见； 由 showSmallPorts 设置为半透明灰色，定义如下
        stroke: null,
        desiredSize: new go.Size(8, 8),
        alignment: spot, // 对齐主要形状上的端口
        alignmentFocus: spot, // 就在形状里面
        portId: name, // 将此对象声明为“端口”
        fromSpot: spot,
        toSpot: spot, // 声明链接可以在此端口连接的位置
        cursor: 'pointer', // 显示不同的光标以指示潜在的链接点
      },
      new go.Binding('fromLinkable', 'NodeType', v => v !== '2'), // 是否允许用户绘制的链接到这里
      new go.Binding('toLinkable', 'NodeType', v => v !== '1'), // 声明用户是否可以从这里绘制链接
    );
  const nodeBoxStyle = (atr, classname) => {
    switch (atr) {
      case 'width':
        return new go.Binding('width', 'NodeType', v => {
          switch (v) {
            case '1':
              return 150;
            case '2':
              return 150;
            case '0':
              return 210;
            case '4':
              return 210;
            case '20':
              return 55;
            case '21':
              return 55;
            case '22':
              return 55;
            default:
              return null;
          }
        });
      case 'height':
        return new go.Binding('height', 'NodeType', v => {
          switch (v) {
            case '1':
              return 150;
            case '2':
              return 150;
            case '0':
              return 110;
            case '4':
              return 110;
            case '20':
              return 55;
            case '21':
              return 55;
            case '22':
              return 55;
            default:
              return null;
          }
        });
      case 'stroke':
        return new go.Binding('stroke', 'NodeType', v => {
          switch (v) {
            case '1':
              return classname === 'roleStyle' ? '#BCBCBC' : '#1685FF';
            case '2':
              return classname === 'roleStyle' ? '#BCBCBC' : '#51C21A';
            case '0':
              return classname === 'roleStyle' ? '#BCBCBC' : '#1685FF';
            case '4':
              return '#9850F6';
            default:
              return null;
          }
        });
      default:
        return null;
    }
  };
  // 双击节点
  const handlerDC = (e, node) => {
    setNodeKey(node.part.data.key);
    setEditMsg(node.part.data);
    setModalType('edit');
    setVisible(true);
  };
  // 双击线
  const addLineMsg = (e, node) => {
    // setLineId(node.part.data.__gohashid);
    setLineMsg(node.part.data);
    setLineVisible(true);
  };
  // 新增节点
  const addNode = type => {
    const list = JSON.parse(diagram.model.toJson()).nodeDataArray;
    console.log(list, 'list');
    let newNum;
    let newKey;

    if (list.length > 0) {
      // eslint-disable-next-line prefer-spread
      newNum = Math.max.apply(Math, list.map(item => item.SerialNo)) + 1;
      // eslint-disable-next-line prefer-spread
      newKey = Math.max.apply(Math, list.map(item => item.key)) + 1;
    } else {
      newKey = 1;
      newNum = 1;
    }
    let NodeName = '';
    switch (type) {
      case '1':
        NodeName = `开始节点${newNum}`;
        break;
      case '0':
        NodeName = `普通节点${newNum}`;
        break;
      case '2':
        NodeName = `结束节点${newNum}`;
        break;
      case '20':
        NodeName = `条件网关${newNum}`;
        break;
      case '21':
        NodeName = `汇合网关${newNum}`;
        break;
      case '22':
        NodeName = `并行网关${newNum}`;
        break;
      default:
        break;
    }
    setNodeLength(list.length);
    console.log(newNum, newKey);
    setNewSerialNo(newNum);
    // 新增节点
    // 新增得key比最大得key值+1
    let obj = {
      key: newKey,
      NodeId: newKey,
      NodeType: type,
      SerialNo: newNum,
      NodeName,
      aheadHandle: 1,
      NodeHandling: 1,
      RuleList: [],
      roleList: [],
    };
    diagram.model.addNodeData({ ...obj, nodeDetail: JSON.stringify(obj) });
    setAddNodes([...AddNodes, newKey]);
    // 关闭时进行数据比对看数据是否改变
    leaveTip();
  };
  // 节点配置回调
  const nodeCallBack = obj => {
    console.log(obj, 'obj');
    let nameIsRepeat;
    let { nodes } = diagram;
    let keyArr = [];
    // 遍历输出节点对象
    nodes.each(node => {
      keyArr = [...keyArr, Number(node.data.key)];
      if (obj.NodeName === node.data.NodeName) {
        nameIsRepeat = true;
        if (modalType === 'edit' && obj.NodeName === editMsg.NodeName) {
          nameIsRepeat = false;
        }
      }
    });
    if (nameIsRepeat) {
      notification.error({
        message: '提示',
        duration: 3,
        description: '节点名称不能重复',
      });
      return;
    }
    if (modalType === 'add') {
      // 新增节点
      // 新增得key比最大得key值+1
      let newKey;
      if (keyArr.length === 0) {
        newKey = 1;
      } else {
        newKey = keyArr.reduce((num1, num2) => (num1 > num2 ? num1 : num2)) + 1;
      }
      diagram.model.addNodeData({
        key: newKey,
        NodeId: newKey,
        ...obj,
      });
      setAddNodes([...AddNodes, newKey]);
    }
    if (modalType === 'edit') {
      // 编辑节点
      let nodeData = diagram.model.findNodeDataForKey(nodeKey);
      const {
        NodeName,
        NodeType,
        roleList,
        SerialNo,
        aheadHandle,
        NodeHandling,
        nodeDetail,
        RuleList,
      } = obj;
      nodeData.NodeName = NodeName;
      nodeData.NodeType = NodeType;
      nodeData.NodeId = nodeKey;
      nodeData.roleList = roleList;
      nodeData.SerialNo = SerialNo;
      nodeData.aheadHandle = aheadHandle;
      nodeData.NodeHandling = NodeHandling;
      nodeData.nodeDetail = nodeDetail;
      nodeData.RuleList = RuleList;
      diagram.model.updateTargetBindings(nodeData);
    }
    // 关闭时进行数据比对看数据是否改变
    leaveTip();
    setVisible(false);
  };
  const leaveTip = () => {
    // 关闭时进行数据比对看数据是否改变
    let diagramObj = JSON.parse(diagram.model.toJson());
    let stageJson = {
      Nodes: diagramObj.nodeDataArray,
      Lines: diagramObj.linkDataArray,
    };
    if (JSON.stringify(stageJson.Nodes) === JSON.stringify(initFlowData.Nodes)) {
      setShowLeaveTip(false);
      leaveCallBack(false);
    } else {
      leaveCallBack(true);
      setShowLeaveTip(true);
    }
  };
  // 线配置回调函数
  const lineCallBack = obj => {
    console.log(obj, 'obj');
    console.log(lineId, 'lineId');
    let node = diagram.findLinkDataForKey(lineId);
    console.log(node, 'linkemsg');
    // 关闭时进行数据比对看数据是否改变
    let diagramObj = JSON.parse(diagram.model.toJson());
    let stageJson = {
      Nodes: diagramObj.nodeDataArray,
      Lines: diagramObj.linkDataArray,
    };

    if (JSON.stringify(stageJson.Nodes) === JSON.stringify(initFlowData.Nodes)) {
      setShowLeaveTip(false);
      leaveCallBack(false);
    } else {
      leaveCallBack(true);
      setShowLeaveTip(true);
    }
    setLineVisible(false);
  };
  // 获取保存后的流程数据
  const getFlowData = () => {
    GetFlowNode({ flowID }).then(res => {
      if (res.code === 0) {
        // 保存后离开不用提醒要修改数据了
        setShowLeaveTip(false);
        leaveCallBack(false);
        res.data.Nodes.forEach(item => {
          item.nodeDetail = JSON.stringify(item);
        });
        setCurrentFlowData(res.data);
      } else {
        notification.error({
          title: '提示',
          duration: 3,
          description: res.msg,
        });
      }
    });
  };
  const isRepeat = (arr, key) => {
    let obj = {};
    for (let i = 0; i < arr.length; i++) {
      if (obj[arr[i][key]]) {
        return false;
      }
      obj[arr[i][key]] = arr[i];
    }
    return obj;
  };

  // 保存流程
  const saveFlow = () => {
    setButtonLoading(true);
    let diagramObj = JSON.parse(diagram.model.toJson());
    // let list = isRepeat(diagramObj.nodeDataArray, 'SerialNo');

    // if (!list) {
    //   notification.error({
    //     message: '提示',
    //     duration: 3,
    //     description: '请检查序号是否重复',
    //   });
    //   return;
    // }
    SaveNodeChange({
      FlowId: flowID,
      DeleteNodes,
      DeleteLines,
      Lines: diagramObj.linkDataArray,
      Nodes: diagramObj.nodeDataArray,
    })
      .then(res => {
        setButtonLoading(false);
        if (res.code === 0) {
          setDeleteNodes([]);
          setDeleteLines([]);
          setAddNodes([]);
          setDeleteNode('');
          setDeleteLine('');
          getFlowData();
          notification.success({
            message: '提示',
            duration: 3,
            description: '保存成功',
          });
        } else {
          notification.error({
            message: '提示',
            duration: 8,
            description: res.msg,
          });
        }
      })
      .catch(() => {
        setButtonLoading(false);
        notification.error({
          message: '提示',
          duration: 3,
          description: '网络异常请稍后重试',
        });
      });
  };
  return (
    <>
      <Prompt message="编辑的内容还未保存，确定要离开该页面吗?" when={showLeaveTip} />
      <div className={styles.control}>
        <div className={styles.nodeList}>
          {nodeTypeList.map(item => (
            <Tooltip placement="topLeft" title="点击插入节点" key={item.NodeType}>
              <div className={styles.nodeBox} onClick={() => addNode(item.NodeType)}>
                <div className={styles.nodeImg}>
                  <img src={item.src} alt="" />
                </div>
                <div className={styles.nodeTypeName}>{item.nodeTypeName}</div>
              </div>
            </Tooltip>
          ))}
          <div className={styles.lineBox} />
          {gatewayList.map(item => (
            <Tooltip placement="topLeft" title="点击插入网关" key={item.NodeType}>
              <div className={styles.nodeBox} onClick={() => addNode(item.NodeType)}>
                <div className={styles.nodeImg}>
                  <img src={item.src} alt="" />
                </div>
                <div className={styles.nodeTypeName}>{item.nodeTypeName}</div>
              </div>
            </Tooltip>
          ))}
        </div>
        <div className={styles.buttonList}>
          <Button
            type="link"
            onClick={() => {
              window.open(
                'https://www.yuque.com/docs/share/da224db9-b8d1-49d2-838f-a23fcd15f0da?#%20%E3%80%8A%E6%B5%81%E7%A8%8B%E8%AE%BE%E8%AE%A1%E3%80%8B',
              );
            }}
          >
            说明文档
          </Button>
          <Button type="primary" onClick={() => saveFlow()} loading={buttonLoading}>
            发布
          </Button>
        </div>
      </div>
      <div className={styles.chartBox}>
        <Spin spinning={chartLoading}>
          <div
            id="myDiagramDiv"
            className={styles.myDiagramDiv}
            style={{ backgroundColor: '#EFF8FA' }}
          />
        </Spin>
      </div>
      <NodeModal
        flowID={flowID}
        visible={visible}
        editMsg={editMsg}
        newSerialNo={newSerialNo}
        nodeNum={nodeLength}
        modalType={modalType}
        handleCancel={() => setVisible(false)}
        onSubumit={obj => nodeCallBack(obj)}
        flowData={diagram ? JSON.parse(diagram.model.toJson()) : {}}
      />
      {/* <LineModal
        visible={lineVisible}
        lineMsg={lineMsg}
        handleCancel={() => setLineVisible(false)}
        onSubumit={obj => lineCallBack(obj)}
      /> */}
    </>
  );
};

export default FlowChart;
