king
2021-07-25 10e2b76a5b403c17da448d8e043c42966b14e657
2021-07-25
8个文件已修改
688 ■■■■ 已修改文件
src/mob/components/menubar/normal-menubar/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/menubar/normal-menubar/menucomponent/index.jsx 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/menubar/normal-menubar/menucomponent/settingform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/navbar/normal-navbar/menusetting/menutable/index.jsx 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx 86 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/index.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/rolemanage/index.jsx 473 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/menubar/normal-menubar/index.jsx
@@ -180,12 +180,14 @@
      setting: { type: 'menu', width: 6, sign: 'icon', icon: 'user', name: '客户', url: '', color: '#ffffff', iconFont: 20, padding: 12, background: '#1890ff', imgWidth: '' },
      style: {
        paddingTop: '15px', paddingBottom: '15px'
      }
      },
      isnew: true
    }
    if (card.subMenus.length > 0) {
      newcard = fromJS(card.subMenus.slice(-1)[0]).toJS()
      newcard.uuid = Utils.getuuid()
      newcard.isnew = true
    }
    card.subMenus.push(newcard)
src/mob/components/menubar/normal-menubar/menucomponent/index.jsx
@@ -6,11 +6,13 @@
import asyncIconComponent from '@/utils/asyncIconComponent'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import Utils from '@/utils/utils.js'
import SettingForm from './settingform'
import { resetStyle } from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import './index.scss'
const { confirm } = Modal
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
class MenuBoxComponent extends Component {
@@ -25,14 +27,11 @@
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    card: null,            // 卡片信息,包括正反面
    formlist: null,        // 设置表单信息
    visible: false,        // 模态框控制
    card: null,
    formlist: null,
    visible: false
  }
  /**
   * @description 搜索条件初始化
   */
  UNSAFE_componentWillMount () {
    const { card } = this.props
@@ -42,7 +41,14 @@
  }
  componentDidMount () {
    const { card } = this.props
    MKEmitter.addListener('submitStyle', this.getStyle)
    if (card.isnew) {
      this.setState({
        visible: true
      })
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -91,13 +97,39 @@
    const { card } = this.state
    this.settingRef.handleConfirm().then(res => {
      this.setState({
        visible: false,
        card: {...card, setting: res}
      })
      let _card = {...card, setting: res}
      this.props.updateElement({...card, setting: res})
      if (!card.isnew && card.setting.type === 'menu' && _card.setting.type !== 'menu') {
        const _this = this
        confirm({
          content: '菜单属性由“菜单”切换至其他类型时,菜单将被重置,即解除之前菜单的绑定关系,确定修改吗?',
          onOk() {
            _card.uuid = Utils.getuuid()
            _this.setState({ visible: false, card: _card })
            _this.props.updateElement(_card)
          },
          onCancel() {}
        })
      } else {
        delete _card.isnew
        this.setState({ visible: false, card: _card })
        this.props.updateElement(_card)
      }
    })
  }
  cancel = () => {
    const { card } = this.state
    if (card.isnew) {
      let _card = fromJS(card).toJS()
      delete _card.isnew
      this.setState({ visible: false, card: _card })
      this.props.updateElement(_card)
    } else {
      this.setState({ visible: false })
    }
  }
  changeMenu = () => {
@@ -167,7 +199,7 @@
          maskClosable={false}
          okText={dict['model.submit']}
          onOk={this.settingSubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          onCancel={this.cancel}
          destroyOnClose
        >
          <SettingForm
src/mob/components/menubar/normal-menubar/menucomponent/settingform/index.jsx
@@ -125,7 +125,7 @@
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item label="类型">
              <Form.Item label="菜单属性">
                {getFieldDecorator('type', {
                  initialValue: type,
                  rules: [
@@ -137,8 +137,8 @@
                })(
                  <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => this.setState({type: e.target.value})}>
                    <Radio value="menu">菜单</Radio>
                    <Radio value="link">链接</Radio>
                    <Radio value="linkmenu">关联菜单</Radio>
                    <Radio value="link">链接</Radio>
                  </Radio.Group>
                )}
              </Form.Item>
src/mob/components/navbar/normal-navbar/menusetting/menutable/index.jsx
@@ -111,22 +111,39 @@
    this.menuRef.handleConfirm().then(res => {
      let _menu = {...editMenu, ...res}
      let _data = fromJS(data).toJS()
      if (!_menu.MenuID) {
        _menu.MenuID = Utils.getuuid()
        this.setState({data: [...data, _menu], editMenu: null, visible: false})
        _data.push(_menu)
      } else {
        this.setState({
          editMenu: null,
          visible: false,
          data: data.map(item => {
            if (item.MenuID === _menu.MenuID) {
              return _menu
            } else {
              return item
            }
          })
        _data = _data.map(item => {
          if (item.MenuID === _menu.MenuID) {
            return _menu
          } else {
            return item
          }
        })
      }
      if (editMenu.MenuID && editMenu.property === 'menu' && _menu.property !== 'menu') {
        const _this = this
        confirm({
          content: '菜单属性由“菜单”切换至其他类型时,菜单将被重置,即解除之前菜单的绑定关系,确定修改吗?',
          onOk() {
            _data = _data.map(item => {
              if (item.MenuID === _menu.MenuID) {
                item.MenuID = Utils.getuuid()
              }
              return item
            })
            _this.setState({data: _data, editMenu: null, visible: false})
          },
          onCancel() {}
        })
      } else {
        this.setState({data: _data, editMenu: null, visible: false})
      }
    })
  }
src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx
@@ -123,7 +123,7 @@
    this.menuRef.handleConfirm().then(res => {
      let _menu = {...editMenu, ...res}
      let _data = this.state.data
      let _data = fromJS(this.state.data).toJS()
      if (!_menu.MenuID) {
        _menu.MenuID = Utils.getuuid()
        _data.push(_menu)
@@ -136,8 +136,26 @@
          }
        })
      }
      this.setState({data: _data, editMenu: null, visible: false})
      this.props.menuUpdate({...menu, sublist: _data})
      if (editMenu.MenuID && editMenu.property === 'menu' && _menu.property !== 'menu') {
        const _this = this
        confirm({
          content: '菜单属性由“菜单”切换至其他类型时,菜单将被重置,即解除之前菜单的绑定关系,确定修改吗?',
          onOk() {
            _data = _data.map(item => {
              if (item.MenuID === _menu.MenuID) {
                item.MenuID = Utils.getuuid()
              }
              return item
            })
            _this.setState({data: _data, editMenu: null, visible: false})
            _this.props.menuUpdate({...menu, sublist: _data})
          },
          onCancel() {}
        })
      } else {
        this.setState({data: _data, editMenu: null, visible: false})
        this.props.menuUpdate({...menu, sublist: _data})
      }
    })
  }
@@ -288,7 +306,7 @@
    this.menuRef.handleConfirm().then(res => {
      let _menu = {...editMenu, ...res}
      let _data = this.state.data
      let _data = fromJS(this.state.data).toJS()
      if (!_menu.MenuID) {
        _menu.MenuID = Utils.getuuid()
        _data.push(_menu)
@@ -301,8 +319,26 @@
          }
        })
      }
      this.setState({data: _data, editMenu: null, visible: false})
      this.props.menuUpdate({...menu, sublist: _data})
      if (editMenu.MenuID && editMenu.property === 'menu' && _menu.property !== 'menu') {
        const _this = this
        confirm({
          content: '菜单属性由“菜单”切换至其他类型时,菜单将被重置,即解除之前菜单的绑定关系,确定修改吗?',
          onOk() {
            _data = _data.map(item => {
              if (item.MenuID === _menu.MenuID) {
                item.MenuID = Utils.getuuid()
              }
              return item
            })
            _this.setState({data: _data, editMenu: null, visible: false})
            _this.props.menuUpdate({...menu, sublist: _data})
          },
          onCancel() {}
        })
      } else {
        this.setState({data: _data, editMenu: null, visible: false})
        this.props.menuUpdate({...menu, sublist: _data})
      }
    })
  }
@@ -462,22 +498,38 @@
    this.menuRef.handleConfirm().then(res => {
      let _menu = {...editMenu, ...res}
      let _data = fromJS(data).toJS()
      if (!_menu.MenuID) {
        _menu.MenuID = Utils.getuuid()
        this.setState({data: [...data, _menu], editMenu: null, visible: false})
        _data.push(_menu)
      } else {
        this.setState({
          editMenu: null,
          visible: false,
          data: data.map(item => {
            if (item.MenuID === _menu.MenuID) {
              return _menu
            } else {
              return item
            }
          })
        _data = _data.map(item => {
          if (item.MenuID === _menu.MenuID) {
            return _menu
          } else {
            return item
          }
        })
      }
      if (editMenu.MenuID && editMenu.property === 'menu' && _menu.property !== 'menu') {
        const _this = this
        confirm({
          content: '菜单属性由“菜单”切换至其他类型时,菜单将被重置,即解除之前菜单的绑定关系,确定修改吗?',
          onOk() {
            _data = _data.map(item => {
              if (item.MenuID === _menu.MenuID) {
                item.MenuID = Utils.getuuid()
              }
              return item
            })
            _this.setState({data: _data, editMenu: null, visible: false})
          },
          onCancel() {}
        })
      } else {
        this.setState({data: _data, editMenu: null, visible: false})
      }
    })
  }
src/views/mobdesign/index.jsx
@@ -847,15 +847,14 @@
        config.enabled = false
      }
      let parMenuId = sessionStorage.getItem('kei_no') + 'pc' + sessionStorage.getItem('lang')
      let roleParam = {type: 'view', key: config.uuid, title: config.MenuName, children: []}
      roleParam.children = this.getMenuMessage()
      let param = {
        func: 'sPC_TrdMenu_AddUpt',
        FstID: parMenuId,
        SndID: parMenuId,
        ParentID: parMenuId,
        FstID: 'mk_app',
        SndID: 'mk_app',
        ParentID: 'mk_app',
        MenuID: config.uuid,
        MenuNo: config.MenuNo || '',
        EasyCode: '',
@@ -918,9 +917,9 @@
              let _param = {
                func: 'sPC_TrdMenu_AddUpt',
                FstID: parMenuId,
                SndID: parMenuId,
                ParentID: parMenuId,
                FstID: 'mk_app',
                SndID: 'mk_app',
                ParentID: 'mk_app',
                MenuID: item.uuid,
                MenuNo: item.wrap.MenuNo || Utils.getuuid(),
                EasyCode: '',
src/views/pcdesign/index.jsx
@@ -939,14 +939,13 @@
        config.enabled = false
      }
      let parMenuId = sessionStorage.getItem('kei_no') + 'pc' + sessionStorage.getItem('lang')
      let roleParam = this.getMenuMessage()
      let param = {
        func: 'sPC_TrdMenu_AddUpt',
        FstID: parMenuId,
        SndID: parMenuId,
        ParentID: parMenuId,
        FstID: 'mk_app',
        SndID: 'mk_app',
        ParentID: 'mk_app',
        MenuID: config.uuid,
        MenuNo: config.MenuNo || '',
        EasyCode: '',
@@ -1026,9 +1025,9 @@
              let _param = {
                func: 'sPC_TrdMenu_AddUpt',
                FstID: parMenuId,
                SndID: parMenuId,
                ParentID: parMenuId,
                FstID: 'mk_app',
                SndID: 'mk_app',
                ParentID: 'mk_app',
                MenuID: item.uuid,
                MenuNo: item.wrap.MenuNo || Utils.getuuid(),
                EasyCode: '',
src/views/rolemanage/index.jsx
@@ -2,7 +2,7 @@
import { fromJS } from 'immutable'
import { Spin, notification, Button, Table, Modal, ConfigProvider, Tree, Input, Empty } from 'antd'
import moment from 'moment'
// import md5 from 'md5'
import md5 from 'md5'
import enUS from 'antd/es/locale/en_US'
import zhCN from 'antd/es/locale/zh_CN'
@@ -46,17 +46,19 @@
    thawmenulist: [],
    confirmLoading: false,
    targetKeys: [],
    trees: [],
    trees: null,
    expandedKeys: [],
    searchkey: ''
  }
  oriTrees = null
  UNSAFE_componentWillMount() {
    let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
    this.setState({app: param}, () => {
      this.getTreeList()
      this.getMenuList()
      this.getThawMenulist()
    })
  }
@@ -69,7 +71,7 @@
    }
  }
  getMenuList = () => {
  getMenuList = (reset) => {
    const { app } = this.state
    let param = {
      func: 's_get_app_menus',
@@ -89,7 +91,6 @@
    Api.getCloudConfig(param).then(result => {
      if (result.status) {
        this.setState({
          loading: false,
          menulist: result.menus.map(item => {
            item.nodes = ''
            item.type = 'view'
@@ -108,7 +109,12 @@
            return item
          })
        }, () => {
          this.initMenutree()
          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 +129,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 +275,26 @@
      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
    }).then(res => {
      if (res.status) {
        this.setState({
@@ -206,18 +316,21 @@
  }
  deleteMenu = (record) => {
    // const { app } = this.state
    const { app } = this.state
    const _this = 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
    }
    if (app.typename === 'pc' && record.nodes && record.nodes.popviews && record.nodes.popviews.length > 0) {
      param.MenuID = param.MenuID + ',' + record.nodes.popviews.join(',')
    }
    confirm({
      content: '确定删除该菜单吗?',
      onOk() {
@@ -229,7 +342,7 @@
                message: '操作成功!',
                duration: 3
              })
              _this.getMenuList()
              _this.getMenuList(true)
            } else {
              notification.warning({
                top: 92,
@@ -248,7 +361,7 @@
  }
  thawSubmit = () => {
    const { targetKeys } = this.state
    const { targetKeys, app } = this.state
    if (targetKeys.length === 0) {
      notification.warning({
@@ -263,46 +376,117 @@
      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.getSystemConfig({
      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 === 'navbar') {
                      item.type = 'navbar'
                    }
                  } catch {
                    item.nodes = ''
                  }
                }
                if (targetKeys.includes(item.MenuID) && item.nodes && item.nodes.popviews && item.nodes.popviews.length > 0) {
                  list = [...list, ...item.nodes.popviews]
                }
                return item
              })
            }, () => {
              if (!this.oriTrees || this.oriTrees.length === 0) {
                this.initMenutree()
              }
            })
            if (app.typename === 'pc' && list.length > 0) {
              Api.getSystemConfig({
                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) => {
@@ -373,30 +557,189 @@
    confirm({
      content: '初始化会根据菜单重置权限树,确定执行吗?',
      onOk() {
        _this.initMenutree()
        return new Promise(resolve => {
          _this.initMenutree(resolve)
        })
      },
      onCancel() {}
    })
  }
  syncTree = () => {
    const _this = this
    confirm({
      content: '同步会根据菜单删除或新增节点,确定执行吗?',
      onOk() {
        return new Promise(resolve => {
          _this.syncMenutree(resolve)
        })
      },
      onCancel() {}
    })
  }
  saveTree = () => {
    const { trees } = this.state
    const _this = this
    if (!trees || trees.length === 0) {
      notification.warning({
        top: 92,
        message: '未获取到权限信息!',
        duration: 5
      })
      return
    }
    confirm({
      content: '确定执行吗?',
      onOk() {
        return new Promise(resolve => {
          _this.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: [] })
  }
  render () {
@@ -420,7 +763,7 @@
            <div className="left-view">
              <div className="app-table">
                <div className="app-action">
                  <Button className="mk-green" onClick={() => this.setState({ visible: true, targetKeys: [] })}>解冻菜单</Button>
                  <Button className="mk-green" onClick={this.triggerThaw}>解冻菜单</Button>
                  <Search placeholder="综合搜索" onSearch={value => this.setState({ searchkey: value })} enterButton />
                </div>
                <Table
@@ -437,7 +780,7 @@
                <Button className="mk-purple" onClick={this.syncTree}>同步</Button>
                <Button className="mk-green save" onClick={this.saveTree}>保存</Button>
              </div>
              {trees.length ? <Tree
              {trees && trees.length ? <Tree
                className="draggable-tree"
                defaultExpandedKeys={this.state.expandedKeys}
                // showLine