From e8ef7263819e847d55cd35e006aa02635fd7b82e Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期三, 14 五月 2025 17:54:21 +0800
Subject: [PATCH] 2025-05-14

---
 src/tabviews/custom/components/chart/antv-X6/index.jsx | 1351 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 1,191 insertions(+), 160 deletions(-)

diff --git a/src/tabviews/custom/components/chart/antv-X6/index.jsx b/src/tabviews/custom/components/chart/antv-X6/index.jsx
index 3e2990b..ed4283f 100644
--- a/src/tabviews/custom/components/chart/antv-X6/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-X6/index.jsx
@@ -1,8 +1,8 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Spin, Tooltip, Empty, message, Modal, notification } from 'antd'
-import { VerticalAlignTopOutlined, VerticalAlignBottomOutlined, SaveOutlined, ZoomInOutlined, ZoomOutOutlined, OneToOneOutlined, DoubleLeftOutlined, DownloadOutlined } from '@ant-design/icons'
+import { Spin, Tooltip, message, Modal, notification, Switch, Button } from 'antd'
+import { UndoOutlined, RedoOutlined, VerticalAlignTopOutlined, VerticalAlignBottomOutlined, ZoomInOutlined, ZoomOutOutlined, OneToOneOutlined, QuestionCircleOutlined, ClearOutlined } from '@ant-design/icons'
 import { Graph, Shape } from '@antv/x6'
 import { Stencil } from '@antv/x6-plugin-stencil'
 import { Transform } from '@antv/x6-plugin-transform'
@@ -14,12 +14,14 @@
 import { Export } from '@antv/x6-plugin-export'
 
 import Api from '@/api'
-import UtilsDM from '@/utils/utils-datamanage.js'
 import MKEmitter from '@/utils/events.js'
 import asyncComponent from '@/utils/asyncComponent'
 import NormalHeader from '@/tabviews/custom/components/share/normalheader'
+// import lanes from '@/menu/components/chart/antv-X6/lane.json'
+// import xflows from '@/menu/components/chart/antv-X6/xflow.json'
 import './index.scss'
 
+const { confirm } = Modal
 const NodeUpdate = asyncComponent(() => import('./nodeupdate'))
 
 const groups = {
@@ -136,8 +138,8 @@
   'mk-rect',
   {
     inherit: 'rect',
-    width: 66,
-    height: 36,
+    width: 100,
+    height: 32,
     attrs: {
       body: {
         strokeWidth: 1,
@@ -166,8 +168,8 @@
   'mk-polygon',
   {
     inherit: 'polygon',
-    width: 66,
-    height: 36,
+    width: 100,
+    height: 32,
     attrs: {
       body: {
         strokeWidth: 1,
@@ -196,8 +198,8 @@
   'mk-paral',
   {
     inherit: 'polygon',
-    width: 66,
-    height: 36,
+    width: 100,
+    height: 32,
     attrs: {
       body: {
         strokeWidth: 1,
@@ -224,8 +226,8 @@
   'mk-circle',
   {
     inherit: 'circle',
-    width: 36,
-    height: 36,
+    width: 40,
+    height: 40,
     attrs: {
       body: {
         strokeWidth: 1,
@@ -254,8 +256,8 @@
   'mk-ellipse',
   {
     inherit: 'ellipse',
-    width: 66,
-    height: 36,
+    width: 100,
+    height: 32,
     attrs: {
       body: {
         strokeWidth: 1,
@@ -284,8 +286,8 @@
   'mk-star',
   {
     inherit: 'polygon',
-    width: 36,
-    height: 36,
+    width: 40,
+    height: 40,
     points: '100,10 40,198 190,78 10,78 160,198',
     attrs: {
       body: {
@@ -315,41 +317,84 @@
 Graph.registerNode(
   'mk-text',
   {
-    inherit: 'rect',
-    width: 66,
-    height: 36,
+    inherit: 'text-block',
+    width: 100,
+    height: 50,
+    text: '鏂囨湰鍩�',
     attrs: {
       body: {
-        strokeWidth: 0,
-        fill: 'transparent'
-      },
-      text: {
-        fontSize: 12,
-        fill: '#262626'
+        fill: '#ffffff',
+        stroke: '#000000',
+        strokeWidth: 1,
+        rx: 0,
+        ry: 0
       }
     }
   },
   true
 )
 
+const styles = {
+  blue: '#1890ff',
+  red: '#f5222d',
+  orange_red: '#fa541c',
+  orange: '#fa8c16',
+  orange_yellow: '#faad14',
+  yellow: '#fadb14',
+  yellow_green: '#a0d911',
+  green: '#52c41a',
+  cyan: '#13c2c2',
+  blue_purple: '#3860f4',
+  purple: '#722ed1',
+  magenta: '#eb2f96',
+  grass_green: '#aeb303',
+  deep_red: '#c32539',
+  deep_blue: '#1d3661',
+  blue1: '#e6f7ff',
+  red1: '#fff1f0',
+  orange_red1: '#fff2e8',
+  orange1: '#fff7e6',
+  orange_yellow1: '#fffbe6',
+  yellow1: '#feffe6',
+  yellow_green1: '#fcffe6',
+  green1: '#f6ffed',
+  cyan1: '#e6fffb',
+  blue_purple1: '#f0f5ff',
+  purple1: '#f9f0ff',
+  magenta1: '#fff0f6',
+  grass_green1: '#f2efda',
+  deep_red1: '#fff0f0',
+  deep_blue1: '#eff1f4'
+}
+
+let sysColor = '#1890ff'
+let lightColor = '#e6f7ff'
+if (window.GLOB.style) {
+  let type = window.GLOB.style.replace(/bg_black_style_|bg_white_style_/, '')
+  sysColor = styles[type] || '#1890ff'
+  lightColor = styles[type + '1'] || '#e6f7ff'
+}
+
 class antvX6Chart extends Component {
   static propTpyes = {
-    config: PropTypes.object,
-    mainSearch: PropTypes.any
+    config: PropTypes.object
   }
 
   state = {
     config: null,
-    toolunfold: true,
-    nodeunfold: true,
     editing: false,
     node: null,
-    arr_field: 'id,cells',
-    loading: false
+    loading: false,
+    status: 0,
+    flowname: '',
+    flowcode: '',
+    orgs: [],
+    empty: true
   }
 
   selectNode = null
   mkGraph = null
+  cells = []
 
   UNSAFE_componentWillMount () {
     const { config } = this.props
@@ -358,27 +403,38 @@
     let BID = ''
     let BData = ''
 
-    if (config.setting.supModule) {
-      BData = window.GLOB.CacheData.get(config.setting.supModule)
+    _config.setting.supModule = ''
+
+    if (_config.plot.supModule && _config.plot.supModule.length > 0) {
+      _config.setting.supModule = _config.plot.supModule.pop()
+    }
+
+    if (_config.setting.supModule) {
+      BData = window.GLOB.CacheData.get(_config.setting.supModule)
     } else {
       BData = window.GLOB.CacheData.get(config.$pageId)
     }
     if (BData) {
       BID = BData.$BID || ''
     }
-    
+
     this.setState({
       config: _config,
       BID: BID || '',
       BData: BData || '',
       plot: _config.plot
     }, () => {
-      if (config.setting.onload === 'true') {
-        setTimeout(() => {
-          this.loadData()
-        }, _config.setting.delay || 0)
+      this.loadData()
+
+      if (_config.plot.function === 'edit') {
+        this.getorganizations()
       }
     })
+  }
+
+  componentDidMount () {
+    MKEmitter.addListener('reloadData', this.reloadData)
+    MKEmitter.addListener('resetSelectLine', this.resetParentParam)
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -392,24 +448,156 @@
     this.setState = () => {
       return
     }
+
+    MKEmitter.removeListener('reloadData', this.reloadData)
+    MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
+  }
+
+  reloadData = (menuId) => {
+    const { config } = this.state
+
+    if (config.uuid !== menuId) return
+
+    this.loadData()
+  }
+
+  resetParentParam = (MenuID, id) => {
+    const { config } = this.state
+
+    if (!config.setting.supModule || config.setting.supModule !== MenuID) return
+    if (id !== this.state.BID || id !== '') {
+      this.setState({ BID: id }, () => {
+        this.loadData()
+      })
+    }
+  }
+
+  getorganizations = () => {
+    Api.genericInterface({func: 's_get_organizations_v1'}).then(res => {
+      if (!res.status) {
+        notification.error({
+          top: 92,
+          message: res.message,
+          duration: 10
+        })
+        return
+      }
+
+      let orgs = []
+      res.organizations && res.organizations.forEach(com => {
+        let _com = {
+          key: com.OrgCode,
+          title: com.OrgName,
+          shortName: com.ShortName,
+          checkable: false,
+          selectable: false,
+          children: []
+        }
+        let _works = []
+
+        com.departments.forEach(dep => {
+          let _dep = {
+            key: dep.co_pro_code,
+            title: dep.co_pro_name,
+            checkable: false,
+            selectable: false,
+            children: []
+          }
+
+          dep.jobs.forEach(job => {
+            let _job = {
+              key: job.jobcode,
+              title: job.jobname,
+              checkable: false,
+              selectable: false,
+              children: []
+            }
+  
+            job.work_group.forEach(group => {
+              if (group.work_group === 'normal') {
+                group.workers.forEach(work => {
+                  let _work = {
+                    key: work.worker_id,
+                    title: work.workername,
+                    email: work.email || '',
+                    images: work.images || '',
+                    mob: work.mob || '',
+                    sex: work.sex || '',
+                    work_grade: work.work_grade || '',
+                    worker_id: work.worker_id || '',
+                    workercode: work.workercode || '',
+                    workername: work.workername || '',
+                    job_type: job.job_type || '',
+                    parentIds: [com.OrgCode, dep.co_pro_code, job.jobcode],
+                    parentNames: [com.OrgName, dep.co_pro_name, job.jobname]
+                  }
+  
+                  _job.children.push(_work)
+                })
+              } else {
+                let _group = {
+                  key: group.work_group,
+                  title: group.work_group,
+                  checkable: false,
+                  selectable: false,
+                  children: []
+                }
+
+                group.workers.forEach(work => {
+                  let _work = {
+                    key: work.worker_id,
+                    title: work.workername,
+                    email: work.email || '',
+                    images: work.images || '',
+                    mob: work.mob || '',
+                    sex: work.sex || '',
+                    work_grade: work.work_grade || '',
+                    worker_id: work.worker_id || '',
+                    workercode: work.workercode || '',
+                    workername: work.workername || '',
+                    job_type: job.job_type || '',
+                    parentIds: [com.OrgCode, dep.co_pro_code, job.jobcode, group.work_group],
+                    parentNames: [com.OrgName, dep.co_pro_name, job.jobname, group.work_group]
+                  }
+  
+                  _group.children.push(_work)
+                })
+
+                if (_group.children.length > 0) {
+                  _job.children.push(_group)
+                }
+              }
+            })
+
+            if (_job.children.length > 0) {
+              _dep.children.push(_job)
+            }
+          })
+
+          if (_dep.children.length > 0) {
+            _com.children.push(_dep)
+          }
+        })
+
+        if (_com.children.length > 0) {
+          _com.works = _works
+          orgs.push(_com)
+        }
+      })
+
+      this.setState({orgs: orgs})
+    })
   }
 
   async loadData () {
-    const { mainSearch } = this.props
-    const { config, arr_field, BID } = this.state
+    const { BID } = this.state
 
-    if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
+    if (!BID) {
+      this.cells = []
       if (!is(fromJS(this.data), fromJS([]))) {
-        this.data = []
         this.handleData()
       }
-      return
-    }
-
-    let searches = config.setting.useMSearch && mainSearch ? mainSearch : []
-
-    let requireFields = searches.filter(item => item.required && item.value === '')
-    if (requireFields.length > 0) {
+      this.setState({empty: true})
       return
     }
 
@@ -417,23 +605,31 @@
       loading: true
     })
 
-    let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID)
+    let param = {
+      func: 's_get_works_flow_local_param_v6',
+      ID: BID
+    }
 
     let result = await Api.genericInterface(param)
     if (result.status) {
-      if (config.$cache && config.setting.onload !== 'false') {
-        Api.writeCacheConfig(config.uuid, result.data || '')
+      let item = result.data && result.data[0] ? result.data[0] : null
+      let cells = []
+
+      if (item && item.long_param) {
+        let long_param = JSON.parse(window.decodeURIComponent(window.atob(item.long_param)))
+        cells = long_param.cells || []
       }
+
+      this.cells = cells
+      this.handleData()
 
       this.setState({
-        loading: false
+        status: item.status || 0,
+        flowname: item.works_flow_name || '',
+        flowcode: item.works_flow_code || '',
+        loading: false,
+        empty: cells.length === 0
       })
-
-      if (!is(fromJS(this.data), fromJS(result.data || []))) {
-        this.data = result.data || []
-        this.handleData()
-      }
 
       if (result.message) {
         if (result.ErrCode === 'Y') {
@@ -486,10 +682,139 @@
   viewrender = () => {
     const { plot } = this.state
 
-    if (plot.subtype === 'xflow') {
-      this.xflowrender()
-    } else if (plot.subtype === 'lane') {
-      this.lanerender()
+    if (plot.function === 'show') {
+      if (plot.subtype === 'xflow') {
+        this.xflowSrender()
+      } else if (plot.subtype === 'lane') {
+        this.laneSrender()
+      }
+    } else {
+      if (plot.subtype === 'xflow') {
+        this.xflowrender()
+      } else if (plot.subtype === 'lane') {
+        this.lanerender()
+      }
+    }
+  }
+
+  xflowSrender = () => {
+    const { config } = this.state
+
+    const graph = new Graph({
+      container: document.getElementById(config.uuid + 'container'),
+      grid: config.plot.grid,
+      scaling: {
+        min: 0.5,
+        max: 2
+      },
+      autoResize: true,
+      interacting: false,
+      panning: true,
+      background: {
+        color: config.plot.backgroundColor || 'transparent'
+      },
+      mousewheel: {
+        enabled: true,
+        zoomAtMousePosition: true,
+        modifiers: 'ctrl'
+      },
+      connecting: {
+        router: 'manhattan',
+        connector: {
+          name: 'rounded',
+          args: {
+            radius: 8
+          }
+        },
+        anchor: 'center',
+        connectionPoint: 'anchor',
+        allowBlank: false,
+        snap: {
+          radius: 20
+        }
+      }
+    })
+
+    if (this.cells.length > 0) {
+      let cells = []
+      this.cells.forEach((item) => {
+        if (item.shape === 'edge') {
+          cells.push(graph.createEdge(item))
+        } else {
+          cells.push(graph.createNode(item))
+        }
+      })
+      graph.resetCells(cells)
+      graph.positionContent('center')
+    }
+
+    if (config.plot.click) {
+      graph.on('cell:click', ({ node }) => {
+        this.checkNode(graph, node)
+      })
+  
+      graph.on('blank:click', () => {
+        this.checkNode(graph)
+      })
+    }
+  }
+
+  laneSrender = () => {
+    const { config } = this.state
+
+    const graph = new Graph({
+      container: document.getElementById(config.uuid + 'container'),
+      scaling: {
+        min: 0.5,
+        max: 2
+      },
+      interacting: false,
+      autoResize: true,
+      panning: true,
+      background: { color: '#ffffff' },
+      mousewheel: {
+        enabled: true,
+        zoomAtMousePosition: true,
+        modifiers: 'ctrl'
+      },
+      connecting: {
+        router: 'manhattan',
+        connector: {
+          name: 'rounded',
+          args: {
+            radius: 8
+          }
+        },
+        anchor: 'center',
+        connectionPoint: 'anchor',
+        allowBlank: false,
+        snap: {
+          radius: 20
+        }
+      }
+    })
+
+    if (this.cells.length > 0) {
+      let cells = []
+      this.cells.forEach((item) => {
+        if (item.shape === 'edge') {
+          cells.push(graph.createEdge(item))
+        } else {
+          cells.push(graph.createNode(item))
+        }
+      })
+      graph.resetCells(cells)
+      graph.positionContent('top')
+    }
+
+    if (config.plot.click) {
+      graph.on('cell:click', ({ node }) => {
+        this.checkNode(graph, node)
+      })
+  
+      graph.on('blank:click', () => {
+        this.checkNode(graph)
+      })
     }
   }
 
@@ -560,7 +885,6 @@
       }
     })
 
-    // #region 浣跨敤鎻掍欢
     graph
       .use(new Transform({
         resizing: true,
@@ -573,21 +897,21 @@
       .use(new History())
       .use(new Export())
 
-    // #region 鍒濆鍖� stencil
     const stencil = new Stencil({
       title: '娴佺▼鍥�',
       target: graph,
-      stencilGraphWidth: 180,
+      stencilGraphWidth: 230,
       stencilGraphHeight: 180,
       groups: [
         {
           title: '閫氱敤鑺傜偣',
-          name: 'group1'
+          name: 'group1',
+          graphHeight: 150
         },
         {
           title: '鑷畾涔�',
           name: 'group2',
-          graphHeight: 150,
+          graphHeight: 300,
           layoutOptions: {
             rowHeight: 70
           }
@@ -595,14 +919,13 @@
       ],
       layoutOptions: {
         columns: 2,
-        columnWidth: 80,
+        columnWidth: 110,
         rowHeight: 55
       }
     })
 
     document.getElementById(config.uuid + 'stencil').appendChild(stencil.container)
 
-    // #region 蹇嵎閿笌浜嬩欢
     graph.bindKey(['meta+c', 'ctrl+c'], () => {
       const cells = graph.getSelectedCells()
       if (cells.length) {
@@ -624,7 +947,6 @@
       return false
     })
 
-    // undo redo
     graph.bindKey(['meta+z', 'ctrl+z'], () => {
       if (graph.canUndo()) {
         graph.undo()
@@ -638,7 +960,6 @@
       return false
     })
 
-    // 鍒犻櫎鍏冪礌
     graph.bindKey(['backspace', 'delete'], () => {
       const cells = graph.getSelectedCells()
       if (cells.length) {
@@ -665,72 +986,195 @@
       showPorts(ports, false)
     })
 
-    graph.on('node:click', ({ e, x, y, node, view }) => {
+    graph.on('node:click', ({ node }) => {
       this.selectNode = node
       
       this.setState({node: node.store.data})
     })
-    graph.on('edge:click', ({ e, x, y, edge, view }) => {
+    graph.on('edge:click', ({ edge }) => {
       this.selectNode = edge
-      
+
       this.setState({node: edge.store.data})
 
       graph.clearTransformWidgets()
     })
-    graph.on('blank:click', ({ e, x, y }) => {
+
+    graph.on('node:dblclick', () => {
+      setTimeout(() => {
+        MKEmitter.emit('mk-x6-dbclick')
+      }, 100)
+    })
+    graph.on('edge:dblclick', () => {
+      setTimeout(() => {
+        MKEmitter.emit('mk-x6-dbclick')
+      }, 100)
+    })
+
+    graph.on('blank:click', () => {
       this.selectNode = null
       
       this.setState({node: null})
     })
+    graph.on('edge:connected', ({ isNew, edge }) => {
+      if (!isNew) return
+
+      let target = edge.getTargetCell()
+      let source = edge.getSourceCell()
+
+      if (!target || !source) return
+
+      if (source.prop('mknode') === 'end') {
+        notification.warning({
+          top: 92,
+          message: '缁撴潫鑺傜偣涓嶅彲娣诲姞鍒嗘敮锛�',
+          duration: 2
+        })
+        graph.removeCells([edge])
+        return
+      }
+
+      let mkdata = target.prop('mkdata')
+
+      if (source.prop('mknode') === 'start' && target.prop('mknode') === 'end') {
+        edge.prop('mknode', 'throughEdge')
+      } else if (target.prop('mknode') === 'end') {
+        edge.prop('mknode', 'endEdge')
+      } else if (target.prop('mknode') === 'start') {
+        edge.prop('mknode', 'startEdge')
+      } else if (source.prop('mknode') === 'start') {
+        edge.prop('mknode', 'firstEdge')
+      }
+      if (mkdata) {
+        edge.prop('mkdata', {status: mkdata.status, statusName: mkdata.statusName})
+      }
+    })
     
     const r1 = graph.createNode({
       shape: 'mk-rect',
-      label: '寮�濮�',
+      mknode: 'start',
+      mkdata: {status: 0, statusName: '鏈彁浜�'},
       attrs: {
         body: {
-          rx: 20,
-          ry: 26
+          rx: 0,
+          ry: 0,
+          fill: '#000000',
+          stroke: '#000000'
+        },
+        text: {
+          fill: '#ffffff',
+          text: '寮�濮�'
         }
       }
     })
+    
+    const r4 = graph.createNode({
+      shape: 'mk-rect',
+      attrs: {
+        body: {
+          rx: 0,
+          ry: 0,
+          fill: '#ffffff',
+          stroke: '#757575'
+        },
+        text: {
+          fill: '#000000',
+          text: '鑺傜偣'
+        }
+      }
+    })
+
+    const r5 = graph.createNode({
+      shape: 'mk-polygon',
+      attrs: {
+        body: {
+          refPoints: '0,10 10,0 20,10 10,20',
+          fill: '#ffffff',
+          stroke: '#757575'
+        },
+        text: {
+          fill: '#000000',
+          text: '鍐崇瓥'
+        }
+      }
+    })
+
+    const r8 = graph.createNode({
+      shape: 'mk-rect',
+      mknode: 'end',
+      mkdata: {status: 888, statusName: '宸插畬鎴�'},
+      attrs: {
+        body: {
+          rx: 0,
+          ry: 0,
+          fill: '#000000',
+          stroke: '#000000'
+        },
+        text: {
+          fill: '#ffffff',
+          text: '缁撴潫'
+        }
+      }
+    })
+    
+    stencil.load([r1, r4, r5, r8], 'group1')
+    
     const r2 = graph.createNode({
       shape: 'mk-rect',
-      label: '杩囩▼'
+      attrs: {
+        body: {
+          rx: 20,
+          ry: 26,
+          fill: '#ffffff',
+          stroke: '#757575'
+        },
+        text: {
+          fill: '#000000',
+          text: '杩囩▼'
+        }
+      }
     })
     const r3 = graph.createNode({
       shape: 'mk-rect',
       attrs: {
         body: {
           rx: 6,
-          ry: 6
+          ry: 6,
+          fill: '#ffffff',
+          stroke: '#757575'
+        },
+        text: {
+          fill: '#000000',
+          text: '鍙�夎繃绋�'
         }
-      },
-      label: '鍙�夎繃绋�'
+      }
     })
-    const r4 = graph.createNode({
-      shape: 'mk-polygon',
-      attrs: {
-        body: {
-          refPoints: '0,10 10,0 20,10 10,20'
-        }
-      },
-      label: '鍐崇瓥'
-    })
-    const r5 = graph.createNode({
+    const r6 = graph.createNode({
       shape: 'mk-paral',
       attrs: {
         body: {
-          refPoints: '10,0 40,0 30,20 0,20'
+          refPoints: '10,0 40,0 30,20 0,20',
+          fill: '#ffffff',
+          stroke: '#757575'
+        },
+        text: {
+          fill: '#000000',
+          text: '鏁版嵁'
         }
-      },
-      label: '鏁版嵁'
+      }
     })
-    const r6 = graph.createNode({
+    const r7 = graph.createNode({
       shape: 'mk-circle',
-      label: '杩炴帴'
+      attrs: {
+        body: {
+          fill: '#ffffff',
+          stroke: '#757575'
+        },
+        text: {
+          fill: '#000000',
+          text: '杩炴帴'
+        }
+      }
     })
-    
-    stencil.load([r1, r2, r3, r4, r5, r6], 'group1')
     
     const p1 = graph.createNode({
       shape: 'mk-ellipse',
@@ -742,11 +1186,23 @@
     })
 
     const p3 = graph.createNode({
-      shape: 'mk-text',
-      label: '鏂囨湰'
+      shape: 'mk-text'
     })
     
-    stencil.load([p1, p2, p3], 'group2')
+    stencil.load([r2, r3, r6, r7, p1, p2, p3], 'group2')
+
+    if (this.cells.length > 0) {
+      let cells = []
+      this.cells.forEach((item) => {
+        if (item.shape === 'edge') {
+          cells.push(graph.createEdge(item))
+        } else {
+          cells.push(graph.createNode(item))
+        }
+      })
+      graph.resetCells(cells)
+      graph.positionContent('center')
+    }
     
     this.mkGraph = graph
   }
@@ -835,18 +1291,24 @@
     })
 
     graph
+      .use(new Transform({
+        resizing: true,
+        rotating: true
+      }))
       .use(new Selection())
-      .use(new Snapline())
+      .use(new Snapline({
+        enabled: true,
+        filter: (Graph) => Graph.prop('shape') !== 'lane'
+      }))
       .use(new Keyboard())
       .use(new Clipboard())
       .use(new History())
       .use(new Export())
 
-    // #region 鍒濆鍖� stencil
     const stencil = new Stencil({
       title: '娴佺▼鍥�',
       target: graph,
-      stencilGraphWidth: 180,
+      stencilGraphWidth: 230,
       stencilGraphHeight: 180,
       groups: [
         {
@@ -872,25 +1334,28 @@
       ],
       layoutOptions: {
         columns: 2,
-        columnWidth: 80,
+        columnWidth: 110,
         rowHeight: 55
       }
     })
 
     document.getElementById(config.uuid + 'stencil').appendChild(stencil.container)
 
-    // #region 蹇嵎閿笌浜嬩欢
     graph.bindKey(['meta+c', 'ctrl+c'], () => {
       const cells = graph.getSelectedCells()
       if (cells.length) {
-        graph.copy(cells)
+        if (cells[0].prop('shape') !== 'lane' && cells[0].prop('shape') !== 'edge') {
+          graph.copy(cells)
+        }
       }
       return false
     })
     graph.bindKey(['meta+x', 'ctrl+x'], () => {
       const cells = graph.getSelectedCells()
       if (cells.length) {
-        graph.cut(cells)
+        if (cells[0].prop('shape') !== 'lane' && cells[0].prop('shape') !== 'edge') {
+          graph.cut(cells)
+        }
       }
       return false
     })
@@ -914,17 +1379,25 @@
       return false
     })
 
-    // 鍒犻櫎鍏冪礌
     graph.bindKey(['backspace', 'delete'], () => {
       const cells = graph.getSelectedCells()
       if (cells.length) {
-        graph.removeCells(cells)
         this.selectNode = null
         this.setState({node: null})
+        
+        if (cells[0].prop('shape') === 'lane') {
+          graph.startBatch('delete-lane')
+
+          graph.removeCells(cells)
+          this.deleteLane(cells[0], graph)
+
+          graph.stopBatch('delete-lane')
+        } else {
+          graph.removeCells(cells)
+        }
       }
     })
 
-    // 鎺у埗杩炴帴妗╂樉绀�/闅愯棌
     const showPorts = (ports, show) => {
       for (let i = 0, len = ports.length; i < len; i += 1) {
         ports[i].style.visibility = show ? 'visible' : 'hidden'
@@ -943,8 +1416,10 @@
       showPorts(ports, false)
     })
 
-    graph.on('node:added', ({ cell, index, options }) => {
+    graph.on('node:added', ({ cell }) => {
       if (cell.prop('shape') === 'lane') {
+        if (cell.prop('zIndex') === 0) return
+
         graph.startBatch('add-lane')
 
         this.addLane(cell, graph)
@@ -956,22 +1431,26 @@
         if (num <= 1) {
           message.warning('璇锋坊鍔犳吵閬擄紒')
           graph.removeCells([cell])
-        } else {
+        } else if (!cell.prop('parent')) {
           this.addNode(cell, graph)
         }
       }
     })
-    graph.on('node:click', ({ e, x, y, node, view }) => {
+    graph.on('node:click', ({ node }) => {
       this.selectNode = node
       this.setState({node: node.store.data})
+
+      if (node.prop('shape') === 'lane') {
+        graph.clearTransformWidgets()
+      }
     })
-    graph.on('edge:click', ({ e, x, y, edge, view }) => {
+    graph.on('edge:click', ({ edge }) => {
       this.selectNode = edge
       this.setState({node: edge.store.data})
 
       graph.clearTransformWidgets()
     })
-    graph.on('blank:click', ({ e, x, y }) => {
+    graph.on('blank:click', () => {
       this.selectNode = null
       
       this.setState({node: null})
@@ -1036,8 +1515,7 @@
     })
 
     const p3 = graph.createNode({
-      shape: 'mk-text',
-      label: '鏂囨湰'
+      shape: 'mk-text'
     })
     
     stencil.load([p1, p2, p3], 'group2')
@@ -1049,17 +1527,18 @@
     
     stencil.load([g1], 'group3')
 
-    // let data = [{"id":"1","shape":"lane","width":260,"height":500,"position":{"x":0,"y":0},"label":"闃舵1", preId: '', nextId: '2'},{"id":"2","shape":"lane","width":200,"height":500,"position":{"x":260,"y":0},"label":"<Function>", preId: '1', nextId: '3'},{"id":"3","shape":"lane","width":200,"height":500,"position":{"x":460,"y":0},"label":"<Function>", preId: '2', nextId: '4'},{"id":"4","shape":"lane","width":200,"height":500,"position":{"x":660,"y":0},"label":"<Function>", preId: '3', nextId: ''}]
-    // let cells = []
-    // data.forEach((item) => {
-    //   if (item.shape === 'edge') {
-    //     cells.push(graph.createEdge(item))
-    //   } else {
-    //     cells.push(graph.createNode(item))
-    //   }
-    // })
-    // graph.resetCells(cells)
-    // graph.zoomToFit({ padding: 10, maxScale: 1 })
+    if (this.cells.length > 0) {
+      let cells = []
+      this.cells.forEach((item) => {
+        if (item.shape === 'edge') {
+          cells.push(graph.createEdge(item))
+        } else {
+          cells.push(graph.createNode(item))
+        }
+      })
+      graph.resetCells(cells)
+      graph.positionContent('top')
+    }
 
     this.mkGraph = graph
   }
@@ -1078,11 +1557,25 @@
       return
     }
 
-    // let cells = this.mkGraph.getCells()
     this.selectNode.toBack()
   }
 
-  // zoom() 鍙幏鍙栨垨鑰呰缃缉鏀炬瘮渚�
+  setback = () => {
+    if (this.mkGraph.canUndo()) {
+      this.mkGraph.undo()
+    } else {
+      message.warning('鏃犲彲鎾ら攢璁板綍锛�')
+    }
+  }
+
+  setprev = () => {
+    if (this.mkGraph.canRedo()) {
+      this.mkGraph.redo()
+    } else {
+      message.warning('鏃犲彲鍓嶈繘璁板綍锛�')
+    }
+  }
+
   setZoomIn = () => {
     this.mkGraph.zoom(0.1)
   }
@@ -1095,13 +1588,203 @@
     this.mkGraph.zoomTo(1)
   }
 
-  save = () => {
-    // let nodes = this.mkGraph.toJSON()
+  close = () => {
+    const { config } = this.state
+
+    let nodes = this.mkGraph.toJSON()
+
+    if (!is(fromJS(nodes.cells), fromJS(this.cells))) {
+      confirm({
+        title: '娴佺▼鍥惧凡淇敼锛岀‘瀹氬叧闂悧?',
+        okText: '纭畾',
+        cancelText: '鍙栨秷',
+        onOk() {
+          MKEmitter.emit('closeTabView', config.$pageId)
+        },
+        onCancel() {}
+      })
+    } else {
+      MKEmitter.emit('closeTabView', config.$pageId)
+    }
   }
 
-  savePicture = () => {
-    const { config } = this.state
-    this.mkGraph.exportPNG(config.name, {padding: 20})
+  save = () => {
+    const { BID, plot, status, flowname, flowcode } = this.state
+
+    if (!BID) {
+      Modal.error({
+        title: '鏈幏鍙栧埌娴佺▼ID锛屼笉鍙繚瀛橈紒',
+      })
+      return
+    }
+
+    let nodes = this.mkGraph.toJSON()
+    let _status = status
+
+    if (plot.subtype === 'xflow' && status === 10) {
+      let start_num = 0
+      let end_num = 0
+      let unvalid = false
+      let map = new Map()
+      let appMap = new Map()
+      
+      nodes.cells.forEach(item => {
+        if (item.shape === 'mk-text' || item.shape === 'lane') return
+
+        if (!item.mkdata) {
+          unvalid = true
+        } else if (item.mknode === 'start') {
+          start_num++
+        } else if (item.mknode === 'end') {
+          end_num++
+        } else if (item.shape === 'edge') {
+          if (item.mknode === 'throughEdge') {
+            if (!item.mkdata.seniorbers || item.mkdata.seniorbers.length === 0) {
+              unvalid = true
+            }
+          } else if (item.mkdata.seniorCondition === 'open') {
+
+          } else if (item.mknode !== 'endEdge' && item.mknode !== 'startEdge' && (!item.mkdata.members || item.mkdata.members.length === 0)) {
+            unvalid = true
+          } else if (item.mknode === 'startEdge' || item.mkdata.flowType === 'reject') {
+            if (map.has(item.source.cell)) {
+              unvalid = true
+            } else {
+              map.set(item.source.cell, true)
+            }
+          } else if (item.mkdata.flowType === 'approval' || item.mknode === 'endEdge') {
+            let val = ''
+            if (item.mkdata.execCondition === 'open') {
+              val = item.mkdata.match + item.mkdata.matchVal
+            }
+            if (appMap.has(item.source.cell + val)) {
+              unvalid = true
+            } else {
+              appMap.set(item.source.cell + val, true)
+            }
+          }
+        }
+      })
+
+      if (start_num !== 1 || end_num === 0 || unvalid) {
+        _status = 0
+      }
+    }
+
+    this.setState({
+      loading: true
+    })
+
+    this.mkGraph.toPNG((dataUri) => {
+      let param = {
+        func: 's_works_flow_param_upt_v6',
+        long_param: window.btoa(window.encodeURIComponent(JSON.stringify(nodes))),
+        flow_image: dataUri,
+        status: status,
+        ID: BID,
+        BID: ''
+      }
+
+      let ssoParam = {
+        func: 's_works_flow_param_sso_upt_v6',
+        status: status,
+        ID: BID,
+        works_flow_code: flowcode,
+        works_flow_name: flowname,
+        long_param: window.btoa(window.encodeURIComponent(JSON.stringify(nodes)))
+      }
+  
+      Api.genericInterface(param).then(res => {
+        if (res.status) {
+          if (plot.subtype === 'xflow') {
+            Api.getSystemConfig(ssoParam).then(result => {
+              if (result.status) {
+                notification.success({
+                  top: 92,
+                  message: '淇濆瓨鎴愬姛锛�',
+                  duration: 2
+                })
+                this.setState({
+                  loading: false,
+                  status: _status
+                })
+                this.cells = nodes.cells
+              } else {
+                notification.error({
+                  top: 92,
+                  message: result.message,
+                  duration: 10
+                })
+                this.setState({
+                  loading: false
+                })
+              }
+            })
+          } else {
+            notification.success({
+              top: 92,
+              message: '淇濆瓨鎴愬姛锛�',
+              duration: 2
+            })
+            this.setState({
+              loading: false,
+              status: _status
+            })
+            this.cells = nodes.cells
+          }
+        } else {
+          notification.error({
+            top: 92,
+            message: res.message,
+            duration: 10
+          })
+          this.setState({
+            loading: false
+          })
+        }
+      })
+    }, {padding: 20})
+  }
+
+  clearNode = () => {
+    let cells = this.mkGraph.getCells()
+    const that = this
+
+    if (cells.length === 0) {
+      message.warning('灏氭湭娣诲姞鍏冪礌锛�')
+      return
+    }
+
+    confirm({
+      title: '纭畾娓呯┖鍏冪礌鍚�?',
+      content: '娓呯┖鍚庝笉鍙仮澶嶃��',
+      okText: '纭畾',
+      cancelText: '鍙栨秷',
+      onOk() {
+        that.mkGraph.removeCells(cells)
+        that.mkGraph.cleanHistory()
+      },
+      onCancel() {}
+    })
+  }
+
+  deleteLane = (cell, graph) => {
+    let id = cell.id
+
+    let nodes = graph.getNodes()
+    let cells = []
+
+    nodes.forEach(item => {
+      if (item.prop('shape') === 'lane') return
+
+      if (item.prop('parent') === id) {
+        cells.push(item)
+      }
+    })
+
+    graph.removeCells(cells)
+
+    this.resetlane(cell.id, cell.prop('position/x'), -cell.prop('size/width'))
   }
 
   addLane = (cell, graph) => {
@@ -1138,6 +1821,7 @@
     }
 
     let height = 400
+
     if (typeof(config.plot.height) === 'number' || /px/.test(config.plot.height)) {
       height = parseInt(config.plot.height)
     }
@@ -1226,22 +1910,61 @@
     }
   }
 
+  delCell = () => {
+    const { node } = this.state
+
+    let cell = this.mkGraph.getCellById(node.id)
+
+    this.mkGraph.removeCells([cell])
+
+    this.setState({node: null})
+  }
+
   changeProps = (value, key) => {
     const { node } = this.state
 
     if (node.shape === 'edge') {
+      let labels = this.selectNode.prop('labels')
+      if (!labels || labels.length === 0) {
+        labels = [{
+          attrs: {label: { text: '' }}
+        }]
+      }
+
       if (key === 'title') {
-        this.selectNode.setLabels(value)
+        labels = JSON.parse(JSON.stringify(labels))
+        labels[0].attrs.label.text = value
+        this.selectNode.setLabels(labels)
       } else if (key === 'stroke') {
         this.selectNode.attr('line/stroke', value)
       } else if (key === 'strokeWidth') {
         this.selectNode.attr('line/strokeWidth', value)
+      } else if (key === 'fontSize') {
+        labels = JSON.parse(JSON.stringify(labels))
+        labels[0].attrs.label.fontSize = value
+        this.selectNode.setLabels(labels)
+      } else if (key === 'fontFill') {
+        labels = JSON.parse(JSON.stringify(labels))
+        labels[0].attrs.label.fill = value
+        this.selectNode.setLabels(labels)
       } else if (key === 'lineType') {
         if (value === 'dash') {
           this.selectNode.attr('line/strokeDasharray', 5)
         } else {
           this.selectNode.attr('line/strokeDasharray', 0)
         }
+      } else if (key === 'mkdata') {
+        if (!node.mkdata) {
+          if (node.target && node.target.cell) {
+            let cell = this.mkGraph.getCellById(node.target.cell)
+
+            if (cell) {
+              cell.prop('mkdata', {status: value.status, statusName: value.statusName || ''})
+            }
+          }
+        }
+
+        this.selectNode.prop('mkdata', value)
       }
     } else if (node.shape === 'lane') {
       if (key === 'title') {
@@ -1267,6 +1990,18 @@
 
         this.mkGraph.stopBatch('width-change')
       }
+    } else if (node.shape === 'mk-text') {
+      if (key === 'title') {
+        this.selectNode.attr('label/text', value)
+      } else if (key === 'fill') {
+        this.selectNode.attr('body/fill', value)
+      } else if (key === 'stroke') {
+        this.selectNode.attr('body/stroke', value)
+      } else if (key === 'fontSize') {
+        this.selectNode.attr('label/style/fontSize', value)
+      } else if (key === 'fontFill') {
+        this.selectNode.attr('label/style/color', value)
+      }
     } else {
       if (key === 'title') {
         this.selectNode.attr('text/text', value)
@@ -1278,9 +2013,278 @@
         this.selectNode.attr('text/fontSize', value)
       } else if (key === 'fontFill') {
         this.selectNode.attr('text/fill', value)
-      } else if (key === 'mksign') {
-        this.selectNode.prop('mksign', value)
+      } else if (key === 'mkdata') {
+        this.selectNode.prop('mkdata', value)
       }
+    }
+  }
+
+  checkNode = (graph, node) => {
+    const { plot, config } = this.state
+
+    let nodes = graph.getNodes()
+
+    nodes.forEach(item => {
+      if (item.prop('shape') === 'lane') return
+
+      if (item.prop('oristyle')) {
+        let style = item.prop('oristyle')
+
+        item.prop('attrs/body/fill', style.fill)
+        item.prop('attrs/body/stroke', style.stroke)
+        item.prop('attrs/text/fill', style.text)
+      }
+    })
+
+    if (!node || ['lane', 'mk-text', 'edge'].includes(node.prop('shape'))) {
+      MKEmitter.emit('resetSelectLine', config.uuid, '', '')
+      return
+    }
+
+    if (!node.prop('oristyle')) {
+      node.prop('oristyle', {
+        fill: node.prop('attrs/body/fill'),
+        stroke: node.prop('attrs/body/stroke'),
+        text: node.prop('attrs/text/fill')
+      })
+    }
+
+    node.prop('attrs/body/fill', lightColor)
+    node.prop('attrs/body/stroke', sysColor)
+    node.prop('attrs/text/fill', sysColor)
+
+    let sign = node.prop('mksign') || ''
+
+    if (plot.click === 'menus') {
+      let menu = null
+      
+      if (plot.menus && plot.menus.length > 0) {
+        plot.menus.forEach(m => {
+          if (sign !== m.sign) return
+          menu = m
+        })
+      }
+      if (!menu || !menu.MenuID) return
+
+      let newtab = {
+        MenuID: menu.MenuID,
+        MenuName: menu.MenuName,
+        MenuNo: menu.MenuNo || '',
+        type: menu.tabType,
+        param: {$BID: sign}
+      }
+
+      MKEmitter.emit('modifyTabs', newtab, true)
+    } else if (plot.click === 'menu') {
+      let menuId = plot.menu.slice(-1)[0]
+      let menu = null
+
+      if (window.GLOB.mkThdMenus.has(menuId)) {
+        menu = {...window.GLOB.mkThdMenus.get(menuId)}
+      } else if (plot.MenuID) {
+        menu = {
+          MenuID: plot.MenuID,
+          MenuName: plot.MenuName,
+          type: plot.tabType
+        }
+      }
+
+      if (!menu) return
+
+      menu.param = {$BID: sign}
+
+      MKEmitter.emit('modifyTabs', menu, true)
+    } else {
+      MKEmitter.emit('resetSelectLine', config.uuid, sign, {})
+    }
+  }
+
+  changeStatus = () => {
+    const { plot, status } = this.state
+
+    let _status = status === 10 ? 0 : 10
+    
+    if (plot.subtype === 'xflow' && _status === 10) {
+      let nodes = this.mkGraph.toJSON()
+
+      let start_num = 0
+      let end_num = 0
+      let unvalidId = ''
+      let emptyNode = null
+      let emptyEdge = null
+      let map = new Map()
+      let appMap = new Map()
+      let rejectId = ''
+      let approvalId = ''
+
+      nodes.cells.forEach(item => {
+        if (item.shape === 'mk-text' || item.shape === 'lane') return
+
+        if (!item.mkdata) {
+          if (item.shape !== 'edge') {
+            if (!emptyNode) {
+              emptyNode = item
+            }
+          } else {
+            if (!emptyEdge) {
+              emptyEdge = item
+            }
+          }
+        } else if (item.mknode === 'start') {
+          start_num++
+        } else if (item.mknode === 'end') {
+          end_num++
+        } else if (item.shape === 'edge' && !unvalidId && !rejectId && !approvalId) {
+          if (item.mknode === 'throughEdge') {
+            if (!item.mkdata.seniorbers || item.mkdata.seniorbers.length === 0) {
+              unvalidId = item.id
+            }
+          } else if (item.mkdata.seniorCondition === 'open') {
+
+          } else if (item.mknode !== 'endEdge' && item.mknode !== 'startEdge' && (!item.mkdata.members || item.mkdata.members.length === 0)) {
+            unvalidId = item.id
+          } else if (item.mknode === 'startEdge' || item.mkdata.flowType === 'reject') {
+            if (map.has(item.source.cell)) {
+              rejectId = item.source.cell
+            } else {
+              map.set(item.source.cell, true)
+            }
+          } else if (item.mkdata.flowType === 'approval' || item.mknode === 'endEdge') {
+            let val = ''
+            if (item.mkdata.execCondition === 'open') {
+              val = item.mkdata.match + item.mkdata.matchVal
+            }
+            if (appMap.has(item.source.cell + val)) {
+              approvalId = item.source.cell
+            } else {
+              appMap.set(item.source.cell + val, item)
+            }
+          }
+        }
+      })
+
+      if (start_num === 0) {
+        notification.warning({
+          top: 92,
+          message: '璇锋坊鍔犲紑濮嬭妭鐐癸紒',
+          duration: 2
+        })
+      } else if (start_num > 1) {
+        notification.warning({
+          top: 92,
+          message: '寮�濮嬭妭鐐逛笉鍙坊鍔犲涓紒',
+          duration: 2
+        })
+      } else if (end_num === 0) {
+        notification.warning({
+          top: 92,
+          message: '璇锋坊鍔犵粨鏉熻妭鐐癸紒',
+          duration: 2
+        })
+      // } else if (end_num > 1) {
+      //   notification.warning({
+      //     top: 92,
+      //     message: '缁撴潫鑺傜偣涓嶅彲娣诲姞澶氫釜锛�',
+      //     duration: 2
+      //   })
+      } else if (emptyNode) {
+        let errmsg = '閮ㄥ垎鑺傜偣鏈缃熀鏈俊鎭��'
+        if (emptyNode.attrs && emptyNode.attrs.text && emptyNode.attrs.text.text) {
+          errmsg = '鑺傜偣銆�' + emptyNode.attrs.text.text + '銆嬫湭璁剧疆鍩烘湰淇℃伅銆�'
+        }
+        notification.warning({
+          top: 92,
+          message: errmsg,
+          duration: 2
+        })
+      } else if (emptyEdge) {
+        let errmsg = '閮ㄥ垎杩炵嚎鏈缃熀鏈俊鎭��'
+
+        let edge = this.mkGraph.getCellById(emptyEdge.id)
+        let target = edge.getTargetCell()
+
+        let t_label = ''
+        if (target.attrs && target.attrs.text && target.attrs.text.text) {
+          t_label = target.attrs.text.text
+        }
+
+        let source = edge.getSourceCell()
+
+        let s_label = ''
+        if (source.attrs && source.attrs.text && source.attrs.text.text) {
+          s_label = source.attrs.text.text
+        }
+
+        if (t_label && s_label) {
+          errmsg = '鑺傜偣銆�' + s_label + '銆嬩笌鑺傜偣銆�' + t_label + '銆嬮棿杩炵嚎鏈缃熀鏈俊鎭��'
+        }
+
+        notification.warning({
+          top: 92,
+          message: errmsg,
+          duration: 2
+        })
+      } else if (rejectId) {
+        let node = this.mkGraph.getCellById(rejectId)
+
+        let title = ''
+        if (node.attrs && node.attrs.text && node.attrs.text.text) {
+          title = '鑺傜偣銆�' + node.attrs.text.text + '銆�'
+        } else if (node.mkdata) {
+          title = '鐘舵�侊細' + node.mkdata.status + ' - ' + node.mkdata.statusName
+        }
+
+        notification.warning({
+          top: 92,
+          message: title + ' 涓嶅彲璁剧疆涓ゆ潯椹冲洖杩炵嚎锛�',
+          duration: 2
+        })
+      } else if (approvalId) {
+        let node = this.mkGraph.getCellById(approvalId)
+
+        let title = ''
+        if (node.attrs && node.attrs.text && node.attrs.text.text) {
+          title = '鑺傜偣銆�' + node.attrs.text.text + '銆�'
+        } else if (node.mkdata) {
+          title = '鐘舵�侊細' + node.mkdata.status + ' - ' + node.mkdata.statusName
+        }
+
+        notification.warning({
+          top: 92,
+          message: title + ' 鍚庣殑瀹℃壒鍒嗘敮鎵ц鏉′欢閲嶅锛�',
+          duration: 2
+        })
+      } else if (unvalidId) {
+        let edge = this.mkGraph.getCellById(unvalidId)
+
+        let node = edge.getTargetCell()
+
+        let title = ''
+        if (node.attrs && node.attrs.text && node.attrs.text.text) {
+          title = node.attrs.text.text
+        } else if (node.mkdata) {
+          title = '鐘舵�侊細' + node.mkdata.status + ' - ' + node.mkdata.statusName
+        }
+
+        let source = edge.getSourceCell()
+
+        let s_label = ''
+        if (source.attrs && source.attrs.text && source.attrs.text.text) {
+          s_label = source.attrs.text.text
+        } else if (source.mkdata) {
+          s_label = '鐘舵�侊細' + source.mkdata.status + ' - ' + source.mkdata.statusName
+        }
+
+        notification.warning({
+          top: 92,
+          message: '鑺傜偣銆�' + s_label + '銆嬩笌銆�' + title + '銆嬮棿杩炵嚎鏈缃鎵逛汉锛�',
+          duration: 2
+        })
+      } else {
+        this.setState({status: _status})
+      }
+    } else {
+      this.setState({status: _status})
     }
   }
 
@@ -1299,7 +2303,32 @@
   }
 
   render() {
-    const { loading, config, empty, toolunfold, nodeunfold, node } = this.state
+    const { loading, config, node, orgs, status, flowname, empty } = this.state
+
+    let style = {...config.style}
+
+    if (config.plot.function === 'show') {
+      if (config.plot.empty === 'hidden' && empty) {
+        style.position = 'absolute'
+        style.width = '100%'
+        style.zIndex = -1
+      }
+
+      return (
+        <div className="custom-x6-plot-box" id={'anchor' + config.uuid} style={style}>
+          {loading ?
+            <div className="loading-mask">
+              <div className="ant-spin-blur"></div>
+              <Spin />
+            </div> : null
+          }
+          <NormalHeader config={config} />
+          <div className={'canvas only-show' + (config.plot.click ? ' switchable' : '')} style={{width: '100%', minHeight: config.plot.height, height: config.plot.height}} id={config.uuid + 'canvas'}>
+            <div id={config.uuid + 'container'} className="mk-container"></div>
+          </div>
+        </div>
+      )
+    }
 
     return (
       <div className="custom-x6-plot-box" id={'anchor' + config.uuid} style={config.style}>
@@ -1310,7 +2339,6 @@
           </div> : null
         }
         <NormalHeader config={config} />
-        {empty ? <Empty description={false}/> : null}
         <div className="mk-toolbar">
           <div className="left-tool">
             {config.plot.subtype === 'xflow' ? <Tooltip title="缃墠">
@@ -1319,14 +2347,6 @@
             {config.plot.subtype === 'xflow' ? <Tooltip title="缃悗">
               <VerticalAlignBottomOutlined onClick={this.setBottom}/>
             </Tooltip> : null}
-            <Tooltip title="淇濆瓨">
-              <SaveOutlined onClick={this.save}/>
-            </Tooltip>
-            {config.plot.export === 'png' ? <Tooltip title="瀵煎嚭鍥剧墖">
-              <DownloadOutlined onClick={this.savePicture}/>
-            </Tooltip> : null}
-          </div>
-          <div className="right-tool">
             <Tooltip title="鏀惧ぇ">
               <ZoomInOutlined onClick={this.setZoomIn}/>
             </Tooltip>
@@ -1336,21 +2356,32 @@
             <Tooltip title="1:1">
               <OneToOneOutlined onClick={this.setZoomInt}/>
             </Tooltip>
+            <Tooltip title="鍚庨��">
+              <UndoOutlined onClick={this.setback}/>
+            </Tooltip>
+            <Tooltip title="鍓嶈繘">
+              <RedoOutlined onClick={this.setprev}/>
+            </Tooltip>
+            <Tooltip title="娓呯┖">
+              <ClearOutlined onClick={this.clearNode}/>
+            </Tooltip>
+            <Tooltip overlayStyle={{maxWidth: 310}} title="蹇嵎閿細澶嶅埗锛坈trl+c锛夈�佸壀鍒囷紙ctrl+x锛夈�佺矘璐达紙ctrl+v锛夈�佸悗閫�锛坈trl+z锛夈�佸墠杩涳紙ctrl+shift+z锛夈�佸垹闄わ紙backspace 鎴� delete锛夛紱鍙屽嚮鑺傜偣鎴栬繛绾垮彲缂栬緫鑷畾涔変俊鎭��">
+              <QuestionCircleOutlined />
+            </Tooltip>
+          </div>
+          <div className="flow-name">{flowname}</div>
+          <div className="right-tool">
+            <Switch size="large" checked={status === 10} checkedChildren="鍚�" unCheckedChildren="鍋�" onChange={this.changeStatus} />
+            <Button className="save" onClick={this.save}>淇濆瓨</Button>
+            <Button className="close" onClick={this.close}>鍏抽棴</Button>
           </div>
         </div>
         <div className="canvas" style={{width: '100%', minHeight: config.plot.height, height: config.plot.height}} id={config.uuid + 'canvas'}>
-          <div id={config.uuid + 'stencil'} className={'mk-stencil ' + (toolunfold ? '' : 'merge')}>
-            <div className="tool-control" onClick={() => this.setState({toolunfold: !toolunfold})}>
-              <DoubleLeftOutlined />
-            </div>
-          </div>
+          <div id={config.uuid + 'stencil'} className="mk-stencil"></div>
           <div id={config.uuid + 'container'} className="mk-container"></div>
-          <div className={'mk-node-edit ' + (nodeunfold ? '' : 'merge')}>
-            <div className="tool-control" onClick={() => this.setState({nodeunfold: !nodeunfold})}>
-              <DoubleLeftOutlined />
-            </div>
+          <div className="mk-node-edit">
             <div className="header">璁剧疆</div>
-            {!node ? <div className="empty">鏈�変腑</div> : <NodeUpdate node={node} onChange={this.changeProps}/>}
+            {!node ? <div className="empty">鏈�変腑</div> : <NodeUpdate node={node} orgs={orgs} onChange={this.changeProps} onDel={this.delCell}/>}
           </div>
         </div>
       </div>

--
Gitblit v1.8.0