| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Modal, Button, notification, Spin } from 'antd' |
| | | import { Modal, Button, notification, Spin, Input } from 'antd' |
| | | import { ForkOutlined } from '@ant-design/icons' |
| | | |
| | | import Api from '@/api' |
| | | import G6 from "@antv/g6" |
| | | import Utils from '@/utils/utils.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import './index.scss' |
| | | |
| | | const { Search } = Input |
| | | |
| | | class TableNodes extends Component { |
| | | static propTpyes = { |
| | |
| | | state = { |
| | | visible: false, |
| | | loading: false, |
| | | nodes: null, |
| | | empty: false |
| | | } |
| | | |
| | |
| | | |
| | | trigger = () => { |
| | | const { config } = this.props |
| | | |
| | | if (!config) return |
| | | |
| | | this.setState({visible: true, loading: true, empty: false}, () => { |
| | | let param = { |
| | |
| | | }) |
| | | } |
| | | |
| | | if (ptbs.length) { |
| | | ptbs.forEach((item, i) => { |
| | | if (result.tb_list) { |
| | | result.tb_list.sort((a, b) => a.tbname > b.tbname ? 1 : -1) |
| | | result.tb_list.forEach((item, i) => { |
| | | let cell = { |
| | | label: item, |
| | | id: 'menu' + i, |
| | | label: item.tbname, |
| | | name: item.tbname.toLowerCase(), |
| | | id: 'table' + i, |
| | | direction: 'right', |
| | | color: '#1890ff', |
| | | // children: [] |
| | | children: [] |
| | | } |
| | | |
| | | if (item[item.tbname]) { |
| | | item[item.tbname].forEach((m, i) => { |
| | | if (m.debug_url) { |
| | | let _param = JSON.parse(window.decodeURIComponent(window.atob(m.debug_url))) |
| | | cell.children.push({ |
| | | label: _param.MenuName, |
| | | id: item.tbname + 'menu' + i, |
| | | direction: 'right', |
| | | color: '#1890ff', |
| | | param: _param |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | data.children.push(cell) |
| | |
| | | if (data.children.length === 0) { |
| | | this.setState({empty: true, loading: false}) |
| | | } else { |
| | | this.setState({loading: false}) |
| | | this.setState({loading: false, nodes: data}) |
| | | this.getForks(data) |
| | | } |
| | | }) |
| | |
| | | } |
| | | |
| | | changeMenu = (menu) => { |
| | | if (menu.depth === 0) return |
| | | if (menu.direction !== 'right') return |
| | | |
| | | MKEmitter.emit('changeEditMenu', menu) |
| | | if (menu.depth === 1) { |
| | | window.open('#/hs') |
| | | } else if (menu.param) { |
| | | if (menu.param.type === 'admin') { |
| | | if (menu.param.MenuType === 'custom') { |
| | | let _param = {...menu.param} |
| | | delete _param.type |
| | | _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param))) |
| | | window.open(`#/menudesign/${_param}`) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | resetNodes = (key) => { |
| | | let data = fromJS(this.state.nodes).toJS() |
| | | key = key ? key.toLowerCase() : '' |
| | | |
| | | data.children.forEach(cell => { |
| | | if (cell.direction === 'right') { |
| | | cell.fontcolor = '' |
| | | if (key && cell.name.indexOf(key) > -1) { |
| | | cell.fontcolor = 'orange' |
| | | } |
| | | } |
| | | }) |
| | | let _element = document.getElementById('mkTableNode') |
| | | if (_element) { |
| | | _element.innerHTML = '' |
| | | } |
| | | |
| | | this.setState({}, () => { |
| | | this.getForks(data) |
| | | }) |
| | | } |
| | | |
| | | getForks = (data) => { |
| | |
| | | return ` |
| | | <group> |
| | | <rect draggable="true" style={{width: ${width}, height: 26, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, fill: 'transparent' }}> |
| | | <text style={{ fontSize: 12, fill: black, cursor: ${cfg.direction !== 'left' ? 'pointer' : 'default'}, marginLeft: 12, marginTop: 6 }}>${cfg.label}</text> |
| | | <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> |
| | |
| | | }; |
| | | |
| | | const tree = new G6.TreeGraph({ |
| | | container: 'mountNode', |
| | | container: 'mkTableNode', |
| | | width: this.wrap.offsetWidth, |
| | | height: this.wrap.offsetHeight, |
| | | fitView: true, |
| | |
| | | footer={[]} |
| | | destroyOnClose |
| | | > |
| | | <div className="header">页面关系图</div> |
| | | <div className="header">表关系图</div> |
| | | <Search className="tb-search" placeholder="请输入表名" onSearch={value => this.resetNodes(value)} enterButton /> |
| | | <div className="wrap"> |
| | | {loading ? <Spin size="large" /> : null} |
| | | {empty ? <div className="empty">未查询到页面关联菜单。</div> : null} |
| | | <div className="mountNode" id="mountNode" ref={ref => this.wrap = ref}></div> |
| | | {empty ? <div className="empty">未查询到表名信息。</div> : null} |
| | | <div className="mountNode" id="mkTableNode" ref={ref => this.wrap = ref}></div> |
| | | </div> |
| | | <div className="footer"> |
| | | <Button key="cancel" onClick={() => { this.setState({ visible: false })}}>关闭</Button> |