king
2024-11-07 fa2c99a6ed8574878c1bdefae5dcb839fc4ebcf8
src/views/rolemanage/index.jsx
@@ -1,10 +1,9 @@
import React, {Component} from 'react'
import { fromJS } from 'immutable'
import { Spin, notification, Button, Table, Modal, ConfigProvider, Tree, Input, Empty } from 'antd'
import { Spin, notification, Button, Table, Modal, Tree, Input, Empty } from 'antd'
import moment from 'moment'
// import md5 from 'md5'
import enUS from 'antd/es/locale/en_US'
import zhCN from 'antd/es/locale/zh_CN'
import md5 from 'md5'
import { ApiOutlined, SoundOutlined, DatabaseOutlined } from '@ant-design/icons'
import Api from '@/api'
import Utils from '@/utils/utils.js'
@@ -13,29 +12,56 @@
const { confirm } = Modal
const { TreeNode } = Tree
// const { Paragraph } = Typography
const { Search } = Input
const _locale = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
const Header = asyncComponent(() => import('./header'))
const TransferForm = asyncComponent(() => import('@/templates/zshare/basetransferform'))
sessionStorage.setItem('isEditState', 'true')
class RoleManage extends Component {
  state = {
    app: null,
    loading: false,
    menulist: [],
    sortType: '',
    columns: [
      { title: '菜单名称', dataIndex: 'MenuName', key: 'MenuName', align: 'center' },
      {
        title: '菜单名称', dataIndex: 'MenuName', key: 'MenuName', align: 'center', render: (text, record) => {
          let className = window.backend && record.backend !== 'level1' ? 'unbackend' : ''
          if (record.extra || this.state.appKeys.includes(record.MenuID)) {
            return <span className={className} style={{color: '#1890ff'}}>{text}</span>
          } else if (record.interfaces === 'true' || record.msg === 'true' || record.pds === 'true') {
            return <span className={className}>{record.interfaces === 'true' ? <ApiOutlined style={{color: 'orange', marginRight: '5px'}} title="菜单中使用了外部接口" /> : null}{record.msg === 'true' ? <SoundOutlined style={{color: 'orange', marginRight: '5px'}} title="菜单中发送了消息" /> : null}{text}{record.pds === 'true' ? <DatabaseOutlined style={{marginLeft: '5px'}} title="菜单中使用了公共数据源" /> : null}</span>
          }
          return <span className={className}>{text}</span>
        }
      },
      {
        title: '菜单参数', dataIndex: 'MenuNo', key: 'MenuNo', align: 'center'
      },
      {
        title: '修改时间', dataIndex: 'modifydate', key: 'modifydate', align: 'center', sorter: true, render: (text, record) => {
          if (window.GLOB.upStatus && record.up_action === 'Y') {
            return <span style={{color: 'orange'}}>{text}</span>
          }
          return text
        }
      },
      {
        title: '操作',
        key: 'action',
        align: 'center',
        render: (text, record) => (
          <div>
            <Button type="link" onClick={() => this.deleteMenu(record)} style={{color: '#ff4d4f'}}>删除</Button>
          <div style={{minWidth: '125px'}}>
            {record.type !== 'none' ?
              <Button type="link" onClick={() => this.deleteMenu(record)} style={{color: '#ff4d4f'}}>删除</Button> :
              <Button type="link" onClick={() => {
                notification.warning({
                  top: 92,
                  message: '当前系统菜单尚未创建。',
                  duration: 5
                })
              }} style={{color: '#ff4d4f', opacity: '0.5'}}>删除</Button>}
            <Button type="link" onClick={() => this.jumpApp(record)} style={{color: '#1890ff', marginLeft: '5px'}}>编辑</Button>
          </div>
        ),
      },
@@ -46,17 +72,27 @@
    thawmenulist: [],
    confirmLoading: false,
    targetKeys: [],
    trees: [],
    trees: null,
    expandedKeys: [],
    searchkey: ''
    searchkey: '',
    appViewList: [],
    appKeys: []
  }
  oriTrees = null
  UNSAFE_componentWillMount() {
    document.body.className = ''
    let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
    if (param.lang) {
      sessionStorage.setItem('lang', param.lang)
    }
    this.setState({app: param}, () => {
      this.getTreeList()
      this.getMenuList()
      this.getThawMenulist()
      this.getAppViewList()
    })
  }
@@ -69,7 +105,28 @@
    }
  }
  getMenuList = () => {
  getAppViewList = () => {
    const { app } = this.state
    Api.getCloudConfig({
      func: 's_get_keyids',
      bid: app.ID
    }).then(result => {
      if (!result.status) {
        notification.warning({
          top: 92,
          message: result.message,
          duration: 5
        })
        return
      }
      let data = result.data || []
      this.setState({appViewList: data, appKeys: data.map(item => item.keys_id)})
    })
  }
  getMenuList = (reset, resolve) => {
    const { app } = this.state
    let param = {
      func: 's_get_app_menus',
@@ -82,33 +139,81 @@
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    this.setState({
      loading: true
    })
    if (!resolve) {
      this.setState({
        loading: true
      })
    }
    Api.getCloudConfig(param).then(result => {
      if (result.status) {
        this.setState({
          loading: false,
          menulist: result.menus.map(item => {
            item.nodes = ''
            item.type = 'view'
            if (item.menus_rolelist) {
              try {
                let pageParam = JSON.parse(window.decodeURIComponent(window.atob(item.menus_rolelist)))
                item.nodes = pageParam
                if (pageParam.type === 'navbar') {
                  item.type = 'navbar'
                }
              } catch {
        let ub = app.user_binding === 'true' && app.userbind ? false : true
        let im = app.instantMessage ? false : true
        let menus = result.menus.map(item => {
          item.nodes = ''
          item.type = 'view'
          if (item.menus_rolelist) {
            try {
              let pageParam = JSON.parse(window.decodeURIComponent(window.atob(item.menus_rolelist)))
              item.nodes = pageParam
              item.interfaces = pageParam.interfaces || 'false'
              item.msg = pageParam.msg || 'false'
              item.pds = pageParam.pds || 'false'
              item.backend = pageParam.backend || ''
              if (pageParam.type) {
                item.type = pageParam.type
              }
              if (item.type === 'navbar' || item.type === 'im') {
                item.backend = 'level1'
              }
              if (pageParam.version !== '1.0') {
                item.nodes = ''
              } else if (pageParam.login || pageParam.pass) {
                item.nodes = ''
              } else if (pageParam.type === 'im') {
                item.nodes = ''
              }
            } catch (e) {
              item.nodes = ''
            }
            return item
          })
            delete item.menus_rolelist
          }
          if (app.userbind === item.MenuID) {
            item.extra = true
            ub = true
          }
          if (app.instantMessage === item.MenuID) {
            item.extra = true
            im = true
          }
          return item
        })
        if (!im) {
          menus.push({nodes: '', type: 'none', backend: 'level1', extra: true, MenuID: app.instantMessage, MenuName: '即时通信'})
        }
        if (!ub) {
          menus.push({nodes: '', type: 'none', backend: 'level1', extra: true, MenuID: app.userbind, MenuName: '用户绑定'})
        }
        this.setState({
          menulist: menus
        }, () => {
          this.initMenutree()
          if (resolve) {
            this.initMenutree(resolve)
          } else if (reset && (!this.oriTrees || this.oriTrees.length === 0)) {
            this.initMenutree()
          } else if (!reset && this.oriTrees && this.oriTrees.length === 0) {
            this.initMenutree()
          }
          this.setState({loading: false})
        })
      } else {
        this.setState({
@@ -123,8 +228,114 @@
    })
  }
  initMenutree = () => {
  getTreeList = () => {
    const { app } = this.state
    let param = {
      func: 's_get_menus_roles_tree',
      typecharone: app.kei_no,
      lang: app.lang
    }
    param.upid = md5(window.GLOB.appkey + app.kei_no + app.typename + app.lang)
    Api.getCloudConfig(param).then(result => {
      if (result.status) {
        if (!result.data || result.data.length === 0) {
          this.oriTrees = []
          if (this.state.menulist.length > 0) {
            this.initMenutree()
          }
          this.setState({trees: [], loading: false})
        } else {
          this.oriTrees = result.data
          this.initTrees(result.data)
          this.setState({loading: false})
        }
      } else {
        this.setState({
          loading: false
        })
        notification.warning({
          top: 92,
          message: result.message,
          duration: 5
        })
      }
    })
  }
  initTrees = (data) => {
    let trees = []
    let map = new Map()
    let _data = data.sort((a, b) => {
      return a.sort - b.sort
    })
    _data.forEach(menu => {
      if (menu.ParentID === 'top') {
        trees.push({
          key: menu.MenuID,
          title: menu.MenuName,
          children: []
        })
      } else {
        map.set(menu.MenuID, menu)
      }
    })
    let reset = (m) => {
      return m.map(n => {
        [...map.keys()].forEach(key => {
          if (map.get(key).ParentID === n.key) {
            let c = map.get(key)
            n.children.push({
              key: c.MenuID,
              title: c.MenuName,
              children: []
            })
            map.delete(key)
          }
        })
        if (n.children.length > 0) {
          n.children = reset(n.children)
        }
        return n
      })
    }
    trees = reset(trees)
    let expandedKeys = this.getExpandedKeys(trees, 0, [])
    this.setState({trees, expandedKeys})
  }
  getExpandedKeys = (trees, i, keys) => {
    if (i >= 3 || !trees[0]) return keys
    keys.push(trees[0].key)
    i++
    if (trees[0].children && trees[0].children.length > 0) {
      keys = this.getExpandedKeys(trees[0].children, i, keys)
    }
    return keys
  }
  initMenutree = (resolve) => {
    const { menulist } = this.state
    if (!menulist || menulist.length === 0) {
      this.setState({trees: [], expandedKeys: []}, () => {
        if (resolve) {
          this.execSave(resolve)
        }
      })
      return
    }
    let navbars = []
    let map = new Map()
@@ -163,28 +374,27 @@
      data = [...data, ...map.values()]
    }
    let expandedKeys = []
    if (data[0]) {
      expandedKeys.push(data[0].key)
      if (data[0].children && data[0].children[0]) {
        expandedKeys.push(data[0].children[0].key)
        if (data[0].children[0].children && data[0].children[0].children[0]) {
          expandedKeys.push(data[0].children[0].children[0].key)
        }
      }
    }
    let expandedKeys = this.getExpandedKeys(data, 0, [])
    this.setState({trees: [], expandedKeys: []}, () => {
      this.setState({trees: data, expandedKeys})
      this.setState({trees: data, expandedKeys}, () => {
        if (resolve) {
          this.execSave(resolve)
        }
      })
    })
  }
  getThawMenulist = () => {
    const { app } = this.state
    Api.getCloudConfig({
      func: 'sPC_Get_FrozenMenu',
      ParentID: '0',
      TYPE: 10
      ParentID: 'mk_app',
      TypeCharOne: app.kei_no,
      typename: app.typename,
      lang: app.lang,
      TYPE: 30
    }).then(res => {
      if (res.status) {
        this.setState({
@@ -206,18 +416,37 @@
  }
  deleteMenu = (record) => {
    // const { app } = this.state
    const _this = this
    const { app, appViewList } = this.state
    const that = this
    let param = {
      func: 'sPC_MainMenu_Del',
      MenuID: record.MenuID,
      // ID: app.ID,
      // TypeCharOne: app.kei_no,
      // typename: app.typename,
      // lang: app.lang
      TypeCharOne: app.kei_no,
      typename: app.typename,
      lang: app.lang
    }
    let _param = {
      func: 's_kei_link_keyids_addupt',
      BID: app.ID,
      exec_type: 'x',
      LText: ''
    }
    let _appViewList = appViewList.filter(item => item.keys_id !== record.MenuID)
    if (appViewList.length !== _appViewList.length) {
      _param.LText = _appViewList.map(item => `select '${item.keys_id}','${item.keys_type}','${item.kei_no}','${item.appkey}','${item.bid}','${sessionStorage.getItem('CloudUserID')}','${item.remark}'`)
      _param.LText = _param.LText.join(' union all ')
      _param.LText = Utils.formatOptions(_param.LText, 'x')
      _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      _param.secretkey = Utils.encrypt('', _param.timestamp)
    } else {
      _param = null
    }
    confirm({
      content: '确定删除该菜单吗?',
      onOk() {
@@ -229,7 +458,21 @@
                message: '操作成功!',
                duration: 3
              })
              _this.getMenuList()
              that.getMenuList(true)
              if (_param) {
                Api.getCloudConfig(_param).then(res => {
                  if (!res.status) {
                    notification.warning({
                      top: 92,
                      message: res.message,
                      duration: 5
                    })
                  } else {
                    that.setState({appViewList: _appViewList})
                  }
                })
              }
            } else {
              notification.warning({
                top: 92,
@@ -248,7 +491,7 @@
  }
  thawSubmit = () => {
    const { targetKeys } = this.state
    const { targetKeys, app } = this.state
    if (targetKeys.length === 0) {
      notification.warning({
@@ -263,46 +506,124 @@
      confirmLoading: true
    })
    let defers = targetKeys.map(item => {
      return new Promise((resolve) => {
        // Api.getCloudConfig({
        //   func: 'sPC_MainMenu_ReDel',
        //   MenuID: item
        // }).then(res => {
        //   if (res.status) {
        //     resolve('')
        //   } else {
        //     resolve(res.message)
        //   }
        // })
        resolve('')
      })
    })
    Promise.all(defers).then(res => {
      let msg = res.filter(Boolean)[0]
      if (msg) {
        notification.error({
    Api.getCloudConfig({
      func: 'sPC_MainMenu_ReDel',
      MenuID: targetKeys.join(','),
      TypeCharOne: app.kei_no,
      typename: app.typename,
      lang: app.lang
    }).then(res => {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: msg,
          duration: 10
          message: res.message,
          duration: 2
        })
        this.setState({
          confirmLoading: false
        })
      } else {
        this.setState({
          confirmLoading: false,
          visible: false,
          targetKeys: [],
          thawmenulist: this.state.thawmenulist.filter(item => !targetKeys.includes(item.key))
        let param = {
          func: 's_get_app_menus',
          TypeCharOne: app.kei_no,
          typename: app.typename,
          LText: `select '${window.GLOB.appkey}'`,
          timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
          lang: app.lang
        }
        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
        Api.getCloudConfig(param).then(result => {
          if (result.status) {
            let list = []
            this.setState({
              menulist: result.menus.map(item => {
                item.nodes = ''
                item.type = 'view'
                if (item.menus_rolelist) {
                  try {
                    let pageParam = JSON.parse(window.decodeURIComponent(window.atob(item.menus_rolelist)))
                    item.nodes = pageParam
                    if (pageParam.type) {
                      item.type = pageParam.type
                    }
                    if (pageParam.version !== '1.0') {
                      item.nodes = ''
                    } else if (pageParam.login || pageParam.pass) {
                      item.nodes = ''
                    } else if (pageParam.type === 'im') {
                      item.nodes = ''
                    }
                  } catch (e) {
                    item.nodes = ''
                  }
                  delete item.menus_rolelist
                }
                return item
              })
            }, () => {
              if (!this.oriTrees || this.oriTrees.length === 0) {
                this.initMenutree()
              }
            })
            if (app.typename === 'pc' && list.length > 0) {
              Api.getCloudConfig({
                func: 'sPC_MainMenu_ReDel',
                MenuID: list.join(','),
                TypeCharOne: app.kei_no,
                typename: app.typename,
                lang: app.lang
              }).then(response => {
                if (!response.status) {
                  notification.warning({
                    top: 92,
                    message: response.message,
                    duration: 2
                  })
                  this.setState({
                    confirmLoading: false
                  })
                } else {
                  this.setState({
                    confirmLoading: false,
                    visible: false,
                    targetKeys: []
                  })
                }
              })
            } else {
              this.setState({
                confirmLoading: false,
                visible: false,
                targetKeys: []
              })
            }
          } else {
            this.setState({
              confirmLoading: false
            })
            notification.warning({
              top: 92,
              message: result.message,
              duration: 5
            })
          }
        })
        this.getMenuList()
      }
    })
  }
  onDrop = info => {
    const dropKey = info.node.props.eventKey;
    const dragKey = info.dragNode.props.eventKey;
    const dropPos = info.node.props.pos.split('-');
    const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
    const dropKey = info.node.props.eventKey
    const dragKey = info.dragNode.props.eventKey
    const dropPos = info.node.props.pos.split('-')
    const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1])
    const loop = (data, key, callback) => {
      data.forEach((item, index, arr) => {
@@ -369,100 +690,299 @@
  }
  initTree = () => {
    const _this = this
    const that = this
    confirm({
      content: '初始化会根据菜单重置权限树,确定执行吗?',
      content: '权限树会重新生成,确定执行吗?',
      onOk() {
        _this.initMenutree()
        return new Promise(resolve => {
          that.getMenuList(true, resolve)
        })
      },
      onCancel() {}
    })
  }
  syncTree = () => {
    const that = this
    confirm({
      content: '同步会根据菜单删除或新增节点,确定执行吗?',
      onOk() {
        return new Promise(resolve => {
          that.syncMenutree(resolve)
        })
      },
      onCancel() {}
    })
  }
  saveTree = () => {
    // const { trees } = this.state
    const that = this
    // if (!trees || trees.length === 0) {
    //   notification.warning({
    //     top: 92,
    //     message: '未获取到权限信息!',
    //     duration: 5
    //   })
    //   return
    // }
    confirm({
      content: '确定执行吗?',
      onOk() {
        return new Promise(resolve => {
          that.execSave(resolve)
        })
      },
      onCancel() {}
    })
  }
  syncMenutree = (resolve) => {
    const { menulist } = this.state
    if (menulist.length === 0) {
      this.setState({trees: [], expandedKeys: []}, () => {
        this.execSave(resolve)
      })
      return
    }
    let navbars = []
    let map = new Map()
    fromJS(menulist).toJS().forEach(menu => {
      if (!menu.nodes) return
      if (menu.type === 'navbar') {
        navbars.push(menu.nodes)
      } else {
        map.set(menu.MenuID, menu.nodes)
      }
    })
    let re = {}
    this.oriTrees && this.oriTrees.forEach(item => {
      if (item.ParentID === 'top') return
      if (!re[item.ParentID]) {
        re[item.ParentID] = []
      }
      re[item.ParentID].push(item.MenuID)
    })
    let data = []
    if (navbars.length === 0) {
      data = [...map.values()]
    } else {
      let reset = (m) => {
        return m.map(n => {
          if (n.children && n.children.length > 0) {
            n.children = reset(n.children)
          } else if (map.has(n.key)) {
            let p = map.get(n.key)
            if (p.children && p.children.length > 0) {
              n.children = reset(p.children)
            }
            map.delete(n.key)
          }
          if (re[n.key]) {
            n.children = n.children || []
            re[n.key].forEach(c => {
              if (map.has(c)) {
                let p = map.get(c)
                if (p.children && p.children.length > 0) {
                  p.children = reset(p.children)
                }
                map.delete(c)
                n.children.push(p)
              }
            })
          }
          return n
        })
      }
      data = reset(navbars)
      data = [...data, ...map.values()]
    }
    let expandedKeys = this.getExpandedKeys(data, 0, [])
    this.setState({trees: [], expandedKeys: []}, () => {
      this.setState({trees: data, expandedKeys}, () => {
        this.execSave(resolve)
      })
    })
  }
  execSave = (resolve) => {
    const { trees, app } = this.state
    let lines = []
    let i = 0
    let reset = (m) => {
      m.children.forEach(n => {
        lines.push(`'${n.key}','${n.title}','${m.key}',${i}`)
        i++
        if (n.children) {
          reset(n)
        }
      })
    }
    trees.forEach(g => {
      lines.push(`'${g.key}','${g.title}','top',${i}`)
      i++
      if (g.children) {
        reset(g)
      }
    })
    let param = {
      func: 's_menus_roles_tree_adduptdel',
      typecharone: app.kei_no,
      typename: app.typename,
      lang: app.lang
    }
    lines = lines.join(';')
    param.upid = md5(window.GLOB.appkey + param.typecharone + param.typename + param.lang)
    param.menus_roles_longtext = window.btoa(window.encodeURIComponent(lines))
    Api.getCloudConfig(param).then(result => {
      if (result.status) {
        notification.success({
          top: 92,
          message: '操作成功!',
          duration: 3
        })
      } else {
        notification.warning({
          top: 92,
          message: result.message,
          duration: 5
        })
      }
      resolve()
    }, () => {
      resolve()
    })
  }
  triggerThaw = () => {
    this.getThawMenulist()
    this.setState({ visible: true, targetKeys: [] })
  }
  jumpApp = (item) => {
    const { app } = this.state
    let route = 'mobdesign'
    if (app.typename === 'pc') {
      route = 'pcdesign'
    }
    if (item.type === 'navbar') {
      notification.warning({
        top: 92,
        message: '导航栏不可单独编辑,请在含有导航栏的页面中修改。',
        duration: 5
      })
      return
    }
    if (app.instantMessage && item.MenuID === app.instantMessage) {
      route = 'imdesign'
    }
    window.open(window.location.href.replace(/#.+/ig, `#/${route}/${window.btoa(window.encodeURIComponent(JSON.stringify({...app, MenuID: item.MenuID, type: 'app'})))}`))
  }
  changeTable = (pagination, filters, sorter) => {
    this.setState({sortType: sorter.order || ''})
  }
  render () {
    const { app, loading, columns, menulist, trees, searchkey } = this.state
    let _menulist = menulist
    const { app, loading, columns, menulist, trees, searchkey, sortType } = this.state
    let _menulist = fromJS(menulist).toJS()
    if (searchkey) {
      _menulist = _menulist.filter(item => item.MenuName.toLowerCase().indexOf(searchkey.toLowerCase()) > -1)
    }
    if (sortType === 'ascend') {
      _menulist.sort((a, b) => {
        if (a.modifydate > b.modifydate) return 1
        if (a.modifydate < b.modifydate) return -1
        return 0
      })
    } else if (sortType === 'descend') {
      _menulist.sort((a, b) => {
        if (a.modifydate < b.modifydate) return 1
        if (a.modifydate > b.modifydate) return -1
        return 0
      })
    }
    return (
      <div className="mk-role-manage">
        <ConfigProvider locale={_locale}>
          <Header app={app} />
          {loading ?
            <div className="loading-mask">
              <Spin size="large" />
            </div> : null
          }
          <div className="view-wrap">
            <div className="left-view">
              <div className="app-table">
                <div className="app-action">
                  <Button className="mk-green" onClick={() => this.setState({ visible: true, targetKeys: [] })}>解冻菜单</Button>
                  <Search placeholder="综合搜索" onSearch={value => this.setState({ searchkey: value })} enterButton />
                </div>
                <Table
                  rowKey="MenuID"
                  columns={columns}
                  dataSource={_menulist}
                  pagination={false}
                />
              </div>
            </div>
            <div className="right-view">
        <Header app={app} />
        {loading ?
          <div className="loading-mask">
            <Spin size="large" />
          </div> : null
        }
        <div className="view-wrap">
          <div className="left-view">
            <div className="app-table">
              <div className="app-action">
                <Button className="mk-primary" onClick={this.initTree}>初始化</Button>
                <Button className="mk-purple" onClick={this.syncTree}>同步</Button>
                <Button className="mk-green save" onClick={this.saveTree}>保存</Button>
                <Button className="mk-green" onClick={this.triggerThaw}>解冻菜单</Button>
                <Search placeholder="综合搜索" onSearch={value => this.setState({ searchkey: value })} enterButton />
              </div>
              {trees.length ? <Tree
                className="draggable-tree"
                defaultExpandedKeys={this.state.expandedKeys}
                // showLine
                draggable
                blockNode
                onDrop={this.onDrop}
              >
                {this.renderNode(trees)}
              </Tree> : <div className="empty">
                <Empty />
              </div>}
              <Table
                rowKey="MenuID"
                columns={columns}
                dataSource={_menulist}
                pagination={false}
                onChange={this.changeTable}
              />
            </div>
          </div>
          <Modal
            title="解除冻结"
            visible={this.state.visible}
            width={600}
            onOk={this.thawSubmit}
            confirmLoading={this.state.confirmLoading}
            onCancel={() => this.setState({visible: false, targetKeys: []})}
            destroyOnClose
          >
            <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={this.state.thawmenulist}/>
          </Modal>
        </ConfigProvider>
          <div className="right-view">
            <div className="app-action">
              <Button className="mk-primary" onClick={this.initTree}>重置</Button>
              {/* <Button className="mk-purple" onClick={this.syncTree}>同步</Button> */}
              <Button className="mk-green save" onClick={this.saveTree}>保存</Button>
            </div>
            {trees && trees.length ? <Tree
              className="draggable-tree"
              defaultExpandedKeys={this.state.expandedKeys}
              // showLine
              draggable
              blockNode
              onDrop={this.onDrop}
            >
              {this.renderNode(trees)}
            </Tree> : <div className="empty">
              <Empty />
            </div>}
          </div>
        </div>
        <Modal
          title="解除冻结"
          visible={this.state.visible}
          width={600}
          onOk={this.thawSubmit}
          confirmLoading={this.state.confirmLoading}
          onCancel={() => this.setState({visible: false, targetKeys: []})}
          destroyOnClose
        >
          <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={this.state.thawmenulist}/>
        </Modal>
      </div>
    )
  }