king
2024-10-11 6ca240a14ccf55d4e0a94fff77e95f64db2cdfcc
src/menu/tablenodes/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Modal, Button, notification, Spin, Input } from 'antd'
import { Modal, Button, notification, Spin, Input, message } from 'antd'
import { ForkOutlined } from '@ant-design/icons'
import Api from '@/api'
@@ -109,6 +109,293 @@
    return {tbs, ptbs}
  }
  getFuncAndInterface = (config) => {
    let ptbs = []
    let filterBtn = (cell, tbs) => {
      if (cell.intertype === 'inner') {
        tbs.push({
          label: cell.innerFunc + ' (' + cell.label + ')',
          color: 'orange',
          id: Utils.getuuid(),
          direction: 'left'
        })
      } else if (cell.intertype === 'outer' || cell.intertype === 'custom') {
        if (cell.innerFunc) {
          tbs.push({
            label: cell.innerFunc + ' (' + cell.label + ')',
            color: 'orange',
            id: Utils.getuuid(),
            direction: 'left'
          })
        }
        if (cell.outerFunc) {
          tbs.push({
            label: cell.outerFunc + ' (' + cell.label + ')',
            color: 'orange',
            id: Utils.getuuid(),
            direction: 'left'
          })
        }
        if (cell.interface && cell.sysInterface !== 'true') {
          tbs.push({
            label: cell.interface + ' (' + cell.label + ')',
            color: 'orange',
            id: Utils.getuuid(),
            direction: 'left'
          })
        }
        if (cell.proInterface) {
          tbs.push({
            label: cell.proInterface + ' (' + cell.label + ')',
            color: 'orange',
            id: Utils.getuuid(),
            direction: 'left'
          })
        }
        if (cell.exInterface) {
          let url = ''
          try {
            url = JSON.parse(cell.exInterface).url
          } catch(e) {
            url = ''
          }
          if (url) {
            tbs.push({
              label: url + ' (' + cell.label + ')',
              color: 'orange',
              id: Utils.getuuid(),
              direction: 'left'
            })
          }
        }
        if (cell.exProInterface) {
          let url = ''
          try {
            url = JSON.parse(cell.exProInterface).url
          } catch(e) {
            url = ''
          }
          if (url) {
            tbs.push({
              label: url + ' (' + cell.label + ')',
              color: 'orange',
              id: Utils.getuuid(),
              direction: 'left'
            })
          }
        }
        if (cell.callbackFunc) {
          tbs.push({
            label: cell.callbackFunc + ' (' + cell.label + ')',
            color: 'orange',
            id: Utils.getuuid(),
            direction: 'left'
          })
        }
      }
    }
    let filterSetting = (item, tbs) => {
      if (!item.setting) return
      if (item.setting.interType === 'inner') {
        tbs.push({
          label: item.setting.innerFunc + ' (数据源)',
          color: 'orange',
          id: Utils.getuuid(),
          direction: 'left'
        })
      } else if (item.setting.interType === 'outer') {
        if (item.setting.outerFunc) {
          tbs.push({
            label: item.setting.outerFunc + ' (数据源)',
            color: 'orange',
            id: Utils.getuuid(),
            direction: 'left'
          })
        }
        if (item.setting.interface && item.setting.sysInterface !== 'true') {
          tbs.push({
            label: item.setting.interface + ' (数据源)',
            color: 'orange',
            id: Utils.getuuid(),
            direction: 'left'
          })
        }
        if (item.setting.proInterface) {
          tbs.push({
            label: item.setting.proInterface + ' (数据源)',
            color: 'orange',
            id: Utils.getuuid(),
            direction: 'left'
          })
        }
        if (item.setting.exInterface) {
          let url = ''
          try {
            url = JSON.parse(item.setting.exInterface).url
          } catch(e) {
            url = ''
          }
          if (url) {
            tbs.push({
              label: url + ' (数据源)',
              color: 'orange',
              id: Utils.getuuid(),
              direction: 'left'
            })
          }
        }
        if (item.setting.exProInterface) {
          let url = ''
          try {
            url = JSON.parse(item.setting.exProInterface).url
          } catch(e) {
            url = ''
          }
          if (url) {
            tbs.push({
              label: url + ' (数据源)',
              color: 'orange',
              id: Utils.getuuid(),
              direction: 'left'
            })
          }
        }
      }
    }
    let traversal = (components, extra) => {
      components.forEach(item => {
        if (item.type === 'tabs') {
          item.subtabs.forEach(tab => {
            traversal(tab.components, extra)
          })
        } else if (item.type === 'group') {
          traversal(item.components, extra)
        } else {
          let tbs = []
          filterSetting(item, tbs)
          if (item.action) {
            item.action.forEach(cell => {
              if (cell.OpenType === 'popview') {
                if (cell.config.components) {
                  traversal(cell.config.components, `-${cell.label}(弹窗)`)
                }
              } else {
                filterBtn(cell, tbs)
              }
            })
          }
          if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
            item.subcards.forEach(card => {
              card.elements && card.elements.forEach(cell => {
                if (cell.eleType !== 'button') return
                if (cell.OpenType === 'popview') {
                  if (cell.config.components) {
                    traversal(cell.config.components, `-${cell.label}(弹窗)`)
                  }
                } else {
                  filterBtn(cell, tbs)
                }
              })
              card.backElements && card.backElements.forEach(cell => {
                if (cell.eleType !== 'button') return
                if (cell.OpenType === 'popview') {
                  if (cell.config.components) {
                    traversal(cell.config.components, `-${cell.label}(弹窗)`)
                  }
                } else {
                  filterBtn(cell, tbs)
                }
              })
            })
          } else if (item.type === 'balcony') {
            item.elements && item.elements.forEach(cell => {
              if (cell.eleType !== 'button') return
              if (cell.OpenType === 'popview') {
                if (cell.config.components) {
                  traversal(cell.config.components, `-${cell.label}(弹窗)`)
                }
              } else {
                filterBtn(cell, tbs)
              }
            })
          } else if (item.type === 'table') {
            let loopCol = (cols) => {
              cols.forEach(col => {
                if (col.type === 'colspan') {
                  loopCol(col.subcols)
                } else if (col.type === 'custom') {
                  col.elements.forEach(cell => {
                    if (cell.eleType !== 'button') return
                    if (cell.OpenType === 'popview') {
                      if (cell.config.components) {
                        traversal(cell.config.components, `-${cell.label}(弹窗)`)
                      }
                    } else {
                      filterBtn(cell, tbs)
                    }
                  })
                }
              })
            }
            loopCol(item.cols)
          } else if (item.type === 'form') {
            item.subcards.forEach(group => {
              filterBtn(group.subButton, tbs)
            })
          }
          if (tbs.length) {
            ptbs.push({
              label: item.name + extra,
              id: Utils.getuuid(),
              direction: 'left',
              color: 'orange',
              children: tbs
            })
          }
        }
      })
    }
    if (config.interfaces) {
      config.interfaces.forEach(item => {
        let tbs = []
        filterSetting(item, tbs)
        if (tbs.length) {
          ptbs.push({
            label: item.name,
            id: Utils.getuuid(),
            direction: 'left',
            color: 'orange',
            children: tbs
          })
        }
      })
    }
    traversal(config.components, '')
    return ptbs
  }
  trigger = () => {
    const { config } = this.props
@@ -122,7 +409,7 @@
        MenuID: config.uuid
      }
      Api.getSystemConfig(param).then(result => {
      Api.getCloudConfig(param).then(result => {
        if (!result.status) {
          notification.warning({
            top: 92,
@@ -158,6 +445,7 @@
              id: 'par' + i,
              direction: 'left',
              color: '#5AD8A6',
              node: 'table',
              children: []
            }
@@ -171,8 +459,15 @@
          })
        }
        let funcs = this.getFuncAndInterface(config)
        if (funcs.length) {
          data.children.push(...funcs)
        }
        if (result.tb_list) {
          result.tb_list.sort((a, b) => a.tbname > b.tbname ? 1 : -1)
          let length = result.tb_list.length
          result.tb_list.forEach((item, i) => {
            let cell = {
              label: item.tbname,
@@ -180,6 +475,8 @@
              id: 'table' + i,
              direction: 'right',
              color: '#1890ff',
              collapsed: false,
              collable: true,
              children: []
            }
@@ -188,9 +485,12 @@
                if (m.debug_url) {
                  let _param = JSON.parse(window.decodeURIComponent(window.atob(m.debug_url)))
                  let label = _param.MenuName
                  _param.lang = _param.lang || 'zh-CN'
                  if (_param && _param.type === 'app') {
                    label += ` (${_param.kei_no} | ${_param.typename}${param.lang !== 'zh-CN' ? ' | ' + param.lang : ''})`
                    label += ` (${_param.kei_no} | ${_param.typename}${_param.lang !== 'zh-CN' ? ' | ' + _param.lang : ''})`
                  } else if (_param && _param.lang && _param.lang !== 'zh-CN') {
                    label += ` (${_param.lang})`
                  }
                  cell.children.push({
@@ -198,10 +498,17 @@
                    id: item.tbname + 'menu' + i,
                    direction: 'right',
                    color: '#1890ff',
                    type: 'dice-mind-map-leaf',
                    param: _param
                  })
                }
              })
            }
            if (cell.children.length > 5 && length > 1) {
              cell.collapsed = true
            } else if (cell.children.length === 0) {
              cell.collable = false
            }
            data.children.push(cell)
@@ -222,10 +529,15 @@
    if (menu.direction !== 'right') return
    if (menu.depth === 1) {
      sessionStorage.setItem('mk-table-node', menu.label)
      window.open('#/hs')
      setTimeout(() => {
        sessionStorage.removeItem('mk-table-node')
      }, 50)
    } else if (menu.param) {
      if (menu.param.type === 'admin') {
        if (menu.param.MenuType === 'custom') {
        if (['custom', 'home', 'billPrint'].includes(menu.param.MenuType)) {
          let _param = {...menu.param}
          delete _param.type
          _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
@@ -284,12 +596,12 @@
          const stroke = cfg.style.stroke || '#096dd9';
    
          return `
          <group>
            <rect draggable="true" style={{width: ${width}, height: 30, stroke: ${stroke}, radius: 4}} keyshape>
              <text style={{ fontSize: 14, marginLeft: 6, marginTop: 6 }}>${cfg.label}</text>
            </rect>
          </group>
        `;
            <group>
              <rect draggable="true" style={{width: ${width}, height: 30, stroke: ${stroke}, radius: 4}} keyshape>
                <text style={{ fontSize: 14, marginLeft: 6, marginTop: 6 }}>${cfg.label}</text>
              </rect>
            </group>
          `;
        },
        getAnchorPoints() {
          return [
@@ -308,13 +620,13 @@
          const color = cfg.color;
    
          return `
          <group>
            <rect draggable="true" style={{width: ${width}, height: 26, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, fill: 'transparent' }}>
              <text style={{ fontSize: 12, fill: ${cfg.fontcolor ? cfg.fontcolor : 'black'}, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, marginLeft: 12, marginTop: 6 }}>${cfg.label}</text>
            </rect>
            <rect style={{ fill: ${color}, width: ${width}, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, height: 2, x: 0, y: 32 }} />
          </group>
        `;
            <group>
              <rect draggable="true" style={{width: ${width}, height: 26, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, fill: 'transparent' }}>
                <text style={{ fontSize: 12, fill: ${cfg.fontcolor ? cfg.fontcolor : 'black'}, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, marginLeft: 12, marginTop: 6 }}>${cfg.label} ${cfg.collable ? '+' : ''}</text>
              </rect>
              <rect style={{ fill: ${color}, width: ${width}, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, height: 2, x: 0, y: 32 }} />
            </group>
          `;
        },
        getAnchorPoints() {
          return [
@@ -334,6 +646,35 @@
      editNode(evt) {
        const item = evt.item;
        const model = item.get('model');
        // 选中节点
        this.graph.getNodes().forEach(node => {
          let _model = node.get('model')
          if (_model.fontcolor === '#1890ff') {
            _model.fontcolor = ''
            this.graph.updateItem(node, _model, false)
          }
        })
        if (model.direction === 'left') {
          if (model.node === 'table') {
            model.fontcolor = '#1890ff'
            this.graph.updateItem(item, model, false)
            let oInput = document.createElement('input')
            oInput.value = model.label
            document.body.appendChild(oInput)
            oInput.select()
            document.execCommand('Copy')
            document.body.removeChild(oInput)
            message.success('表名复制成功。')
          }
          return
        }
        model.fontcolor = '#1890ff'
        this.graph.updateItem(item, model, false)
        
        that.changeMenu(model)
      }
@@ -394,7 +735,7 @@
          data.color = color;
        }
    
        if (d.children) {
        if (d.children && !d.collapsed) {
          data.children = d.children.map((child) => changeData(child, level + 1, data.color));
        }
        return data;
@@ -435,9 +776,21 @@
          lineWidth: 2,
        },
      },
      minZoom: 0.5,
      minZoom: 0.3,
      modes: {
        default: ['drag-canvas', 'zoom-canvas', 'dice-mindmap'],
        default: [
          {
            type: 'collapse-expand',
            trigger: 'click',
            shouldBegin: (e, self) => {
              if (e.item && e.item.getModel().collable) return true;
              return false;
            },
          },
          'drag-canvas',
          'zoom-canvas',
          'dice-mindmap'
        ],
      },
    });
    
@@ -450,7 +803,7 @@
    const { visible, loading, empty } = this.state
    return (
      <div style={{display: 'inline-block'}}>
      <>
        <Button style={{borderColor: '#8E44AD', color: '#8E44AD'}} onClick={this.trigger}><ForkOutlined /> 表关系图</Button>
        <Modal
          title=""
@@ -471,9 +824,10 @@
          </div>
          <div className="footer">
            <Button key="cancel" onClick={() => { this.setState({ visible: false })}}>关闭</Button>
            <span className="tip">注:点击表名(右侧)可展开/收起菜单,左侧橙色标注为接口或函数名。</span>
          </div>
        </Modal>
      </div>
      </>
    )
  }
}