king
2022-07-22 0c439ced2c97905cb2b02f5f689a37b19369fb8a
src/templates/treepageconfig/index.jsx
@@ -1,10 +1,10 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { is, fromJS } from 'immutable'
import { DndProvider } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import { Button, Card, Modal, Collapse, notification, Spin, Icon, Switch, Tooltip, Row, Col, Tree } from 'antd'
import { Button, Card, Modal, Collapse, notification, Spin, Switch, Tooltip, Row, Col, Tree } from 'antd'
import { QuestionCircleOutlined, RedoOutlined, SearchOutlined, FileOutlined, FolderOpenOutlined } from '@ant-design/icons'
import moment from 'moment'
import Api from '@/api'
@@ -12,10 +12,9 @@
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import MenuForm from '@/templates/comtableconfig/menuform'
import EditComponent from '@/templates/zshare/editcomponent'
import SourceElement from '@/templates/zshare/dragsource'
import Source from './source'
import './index.scss'
@@ -29,13 +28,12 @@
class ComTableConfig extends Component {
  static propTpyes = {
    menu: PropTypes.any,
    optionLibs: PropTypes.any,
    reloadmenu: PropTypes.func,
    handleView: PropTypes.func
  }
  state = {
    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    config: null,            // 页面配置
    formlist: null,          // 搜索条件、按钮、显示列表单字段
    menuloading: false,      // 菜单保存中
@@ -46,10 +44,9 @@
    originMenu: null,        // 原始菜单
    delTabs: [],             // 删除标签列表
    tabviews: [],            // 所有标签页
    optionLibs: null,        // 自定义下拉选项库
    activeKey: '0',          // 默认展开基本信息
    pasteContent: null,      // 粘贴配置信息
    openEdition: ''          // 编辑版本标记,防止多人操作
    openEdition: '',         // 编辑版本标记,防止多人操作
    modalStatus: false       // 弹窗是否开启,判断ctrl+s是否可用
  }
  /**
@@ -58,7 +55,7 @@
   * 2、设置操作类型、原始菜单信息(每次保存后重置)、已使用表及基本信息表单
   */
  UNSAFE_componentWillMount () {
    const { menu, optionLibs } = this.props
    const { menu } = this.props
    let _LongParam = menu.LongParam
    let _config = ''
@@ -105,7 +102,6 @@
      config: _config,
      openEdition: menu.open_edition || '',
      activeKey: menu.activeKey || '0',
      optionLibs: optionLibs,
      originMenu: fromJS(_config).toJS()
    })
  }
@@ -115,6 +111,42 @@
   */
  componentDidMount () {
    this.reloadTab(false)
    document.onkeydown = (event) => {
      let e = event || window.event
      let keyCode = e.keyCode || e.which || e.charCode
      let preKey = ''
      if (e.ctrlKey) {
        preKey = 'ctrl'
      }
      if (e.shiftKey) {
        preKey = 'shift'
      } else if (e.altKey) {
        preKey = 'alt'
      }
      if (!preKey || !keyCode) return
      let _shortcut = `${preKey}+${keyCode}`
      if (_shortcut === 'ctrl+83') {
        if (this.state.modalStatus) {
          notification.warning({
            top: 92,
            message: '请保存' + this.state.modalStatus,
            duration: 5
          })
          return false
        }
        let node = document.getElementById('save-config')
        if (node && node.click) {
          node.click()
        }
        return false
      }
    }
    MKEmitter.addListener('modalStatus', this.modalStatus)
  }
  /**
@@ -124,6 +156,12 @@
    this.setState = () => {
      return
    }
    document.onkeydown = () => {}
    MKEmitter.removeListener('modalStatus', this.modalStatus)
  }
  modalStatus = (val) => {
    this.setState({modalStatus: val})
  }
  /**
@@ -169,30 +207,6 @@
    })
  }
  getFuncNames = (data, funcNames, tableNames) => {
    data.forEach(item => {
      if (item.subfuncs) {
        this.getFuncNames(item.subfuncs, funcNames, tableNames)
      } else {
        if (item.tableName) {
          tableNames.push(item.tableName)
        }
        if (item.innerFunc) {
          funcNames.push({func: item.innerFunc, label: item.label || ''})
        }
        if (item.callbackFunc) {
          funcNames.push({func: item.callbackFunc, label: item.label || ''})
        }
      }
    })
    return {
      func: funcNames,
      table: tableNames
    }
  }
  /**
   * @description 三级菜单保存
   */
@@ -236,31 +250,6 @@
      _config.enabled = false
    }
    _config.funcs = [] // 页面及子页面存储过程集
    _config.funcs.push({
      type: 'view',
      subtype: 'view',
      uuid: menu.MenuID,
      intertype: _config.setting.interType || 'inner',
      interface: _config.setting.interface || '',
      tableName: _config.setting.tableName || '',
      innerFunc: _config.setting.innerFunc || '',
      outerFunc: _config.setting.outerFunc || ''
    })
    _config.tabgroups.forEach(group => {
      group.sublist.forEach(tab => {
        _config.funcs.push({
          type: 'tab',
          subtype: 'tab',
          uuid: tab.uuid,
          label: tab.label,
          linkTab: tab.linkTab
        })
      })
    })
    if (this.state.closeVisible) { // 显示关闭对话框时,模态框中保存按钮,显示保存中状态
      this.setState({
        menucloseloading: true
@@ -271,254 +260,224 @@
      })
    }
    new Promise(resolve => {
      let deffers = []
      _config.funcs.forEach(item => {
        if (item.type === 'tab') {
          let deffer = new Promise(resolve => {
            Api.getSystemConfig({
              func: 'sPC_Get_LongParam',
              MenuID: item.linkTab
            }).then(result => {
              if (result.status && result.LongParam) {
                let _LongParam = ''
                if (result.LongParam) {
                  try {
                    _LongParam = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
                  } catch (e) {
                    console.warn('Parse Failure')
                    _LongParam = ''
                  }
                }
    // 保存时删除配置类型,system 、user
    delete _config.type
    delete _config.isAdd
    let _LongParam = ''
    try {
      _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(_config)))
    } catch (e) {
      notification.warning({
        top: 92,
        message: '编译错误',
        duration: 5
      })
      this.setState({
        menucloseloading: false,
        menuloading: false
      })
      return
    }
    let _sort = 0
    let btntabs = []
    
                if (_LongParam) {
                  item.menuNo = _LongParam.tabNo || ''
                  item.subfuncs = _LongParam.funcs || []
                }
              }
              resolve()
    let tabParam = { // 添加菜单tab页
      func: 'sPC_sMenusTab_AddUpt',
      MenuID: menu.MenuID
    }
    let _LText = []
    btntabs.forEach(item => {
      _LText.push(`select '${item.uuid}' as MenuID ,'${item.linkTab}' as Tabid,'${item.label}' as TabName ,'${item.sort * 10}' as Sort`)
    })
    _config.tabgroups.forEach(group => {
      group.sublist.forEach(item => {
        _sort++
        _LText.push(`select '${menu.MenuID}' as MenuID ,'${item.linkTab}' as Tabid,'${item.label}' as TabName ,'${_sort * 10}' as Sort`)
      })
    })
    _LText = _LText.join(' union all ')
    tabParam.LText = Utils.formatOptions(_LText)
    tabParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    tabParam.secretkey = Utils.encrypt(tabParam.LText, tabParam.timestamp)
    let _funcs = []
    let _tables = []
    if (_config.setting.tableName) {
      _tables.push(_config.setting.tableName)
    }
    if (_config.setting.innerFunc) {
      _funcs.push({func: _config.setting.innerFunc, label: _config.MenuName || ''})
    }
    if (_config.setting.outerFunc) {
      _funcs.push({func: _config.setting.outerFunc, label: _config.MenuName || ''})
    }
    let param = {
      func: 'sPC_TrdMenu_AddUpt',
      FstID: _config.fstMenuId,
      SndID: _config.ParentId,
      ParentID: _config.ParentId,
      MenuID: menu.MenuID,
      MenuNo: _config.MenuNo,
      EasyCode: _config.easyCode,
      Template: _config.Template,
      MenuName: _config.MenuName,
      PageParam: JSON.stringify({...menu.PageParam, Template: _config.Template, OpenType: _config.OpenType}),
      LongParam: _LongParam,
      LText: _funcs.map(item => `select '${menu.MenuID}' as MenuID,'${item.func}' as ProcName,'${item.label}' as MenuName`),
      LTexttb: _tables.map(item => `select '${menu.MenuID}' as MenuID,'${item}' as tbName`)
    }
    if (menu.menuSort) { // 菜单新建时设置排序
      param.Sort = menu.menuSort
    }
    param.LText = param.LText.join(' union all ')
    param.LText = Utils.formatOptions(param.LText)
    param.LTexttb = param.LTexttb.join(' union all ')
    param.LTexttb = Utils.formatOptions(param.LTexttb)
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    if (openEdition) { // 版本管理
      param.open_edition = openEdition
    }
    // 有按钮或标签删除时,先进行删除操作
    // 删除成功后,保存页面配置
    new Promise(resolve => {
      if (delTabs.length > 0) {
        let deffers = delTabs.map(item => {
          let _param = {
            func: 'sPC_MainMenu_Del',
            MenuID: item.uuid
          }
          return new Promise(resolve => {
            Api.getSystemConfig(_param).then(response => {
              resolve(response)
            })
          })
          deffers.push(deffer)
        }
      })
      if (deffers.length === 0) {
        resolve()
      } else {
        Promise.all(deffers).then(() => {
          resolve()
        })
      }
    }).then(() => {
      // 保存时删除配置类型,system 、user
      delete _config.type
      delete _config.isAdd
      let _LongParam = ''
      try {
        _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(_config)))
      } catch (e) {
        notification.warning({
          top: 92,
          message: '编译错误',
          duration: 5
        })
        this.setState({
          menucloseloading: false,
          menuloading: false
        })
        return
      }
      let _sort = 0
      let btntabs = []
      let tabParam = { // 添加菜单tab页
        func: 'sPC_sMenusTab_AddUpt',
        MenuID: menu.MenuID
      }
      let _LText = []
      btntabs.forEach(item => {
        _LText.push(`select '${item.uuid}' as MenuID ,'${item.linkTab}' as Tabid,'${item.label}' as TabName ,'${item.sort * 10}' as Sort`)
      })
      _config.tabgroups.forEach(group => {
        group.sublist.forEach(item => {
          _sort++
          _LText.push(`select '${menu.MenuID}' as MenuID ,'${item.linkTab}' as Tabid,'${item.label}' as TabName ,'${_sort * 10}' as Sort`)
        })
      })
      _LText = _LText.join(' union all ')
      tabParam.LText = Utils.formatOptions(_LText)
      tabParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      tabParam.secretkey = Utils.encrypt(tabParam.LText, tabParam.timestamp)
      let _vals = this.getFuncNames(_config.funcs, [], [])
      let _tables = Array.from(new Set(_vals.table))
      let param = {
        func: 'sPC_TrdMenu_AddUpt',
        FstID: _config.fstMenuId,
        SndID: _config.ParentId,
        ParentID: _config.ParentId,
        MenuID: menu.MenuID,
        MenuNo: _config.MenuNo,
        EasyCode: _config.easyCode,
        Template: _config.Template,
        MenuName: _config.MenuName,
        PageParam: JSON.stringify({...menu.PageParam, Template: _config.Template, OpenType: _config.OpenType}),
        LongParam: _LongParam,
        LText: _vals.func.map(item => `select '${menu.MenuID}' as MenuID,'${item.func}' as ProcName,'${item.label}' as MenuName`),
        LTexttb: _tables.map(item => `select '${menu.MenuID}' as MenuID,'${item}' as tbName`)
      }
      if (menu.menuSort) { // 菜单新建时设置排序
        param.Sort = menu.menuSort
      }
      param.LText = param.LText.join(' union all ')
      param.LText = Utils.formatOptions(param.LText)
      param.LTexttb = param.LTexttb.join(' union all ')
      param.LTexttb = Utils.formatOptions(param.LTexttb)
      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      param.secretkey = Utils.encrypt(param.LText, param.timestamp)
      if (openEdition) { // 版本管理
        param.open_edition = openEdition
      }
      // 有按钮或标签删除时,先进行删除操作
      // 删除成功后,保存页面配置
      new Promise(resolve => {
        if (delTabs.length > 0) {
          let deffers = delTabs.map(item => {
            let _param = {
              func: 'sPC_MainMenu_Del',
              MenuID: item.uuid
            }
            return new Promise(resolve => {
              Api.getSystemConfig(_param).then(response => {
                resolve(response)
              })
            })
          })
          Promise.all(deffers).then(result => {
            let error = null
            result.forEach(response => {
              if (!response.status) {
                error = response
              }
            })
            if (error) {
              this.setState({
                menuloading: false,
                menucloseloading: false
              })
              notification.warning({
                top: 92,
                message: error.message,
                duration: 5
              })
              resolve(false)
            } else {
              this.setState({
                delTabs: []
              })
              resolve(true)
        Promise.all(deffers).then(result => {
          let error = null
          result.forEach(response => {
            if (!response.status) {
              error = response
            }
          })
        } else if (delTabs.length === 0) {
          resolve(true)
        }
      }).then(resp => {
        if (resp === false) return
        let localParam = fromJS(param).toJS()
        Api.getSystemConfig(param).then(response => {
          if (response.status) {
            this.setState({
              config: _config,
              openEdition: response.open_edition || '',
              originMenu: fromJS(_config).toJS()
            })
            this.props.reloadmenu()
            // 存在标签页时
            if (tabParam.LText) {
              Api.getSystemConfig(tabParam).then(result => {
                if (result.status) {
                  notification.success({
                    top: 92,
                    message: '保存成功',
                    duration: 2
                  })
                  if (this.state.closeVisible) {
                    this.props.handleView()
                  } else {
                    this.setState({
                      menuloading: false,
                      menucloseloading: false
                    })
                  }
                } else {
                  notification.warning({
                    top: 92,
                    message: result.message,
                    duration: 5
                  })
                  this.setState({
                    menuloading: false,
                    menucloseloading: false
                  })
                }
              })
            } else {
              notification.success({
                top: 92,
                message: '保存成功',
                duration: 2
              })
              if (this.state.closeVisible) {
                this.props.handleView()
              } else {
                this.setState({
                  menuloading: false,
                  menucloseloading: false
                })
              }
            }
            localParam.func = 'sPC_TrdMenu_AddUpt_For_Local'
            delete localParam.LongParam
            delete localParam.PageParam
            delete localParam.Template
            delete localParam.Sort
            delete localParam.EasyCode
            delete localParam.open_edition
            Api.getLocalConfig(localParam)
          } else {
          if (error) {
            this.setState({
              menuloading: false,
              menucloseloading: false
            })
            notification.warning({
              top: 92,
              message: response.message,
              message: error.message,
              duration: 5
            })
            resolve(false)
          } else {
            this.setState({
              delTabs: []
            })
            resolve(true)
          }
        })
      } else if (delTabs.length === 0) {
        resolve(true)
      }
    }).then(resp => {
      if (resp === false) return
      let localParam = fromJS(param).toJS()
      localParam.func = 'sPC_TrdMenu_AddUpt_For_Local'
      delete localParam.LongParam
      delete localParam.PageParam
      delete localParam.Template
      delete localParam.Sort
      delete localParam.EasyCode
      delete localParam.open_edition
      Api.getSystemConfig(param).then(response => {
        if (response.status) {
          this.setState({
            config: _config,
            openEdition: response.open_edition || '',
            originMenu: fromJS(_config).toJS()
          })
          // 存在标签页时
          if (tabParam.LText) {
            Api.getSystemConfig(tabParam).then(result => {
              if (result.status) {
                notification.success({
                  top: 92,
                  message: '保存成功',
                  duration: 2
                })
                this.props.reloadmenu()
                Api.getLocalConfig(localParam)
                if (this.state.closeVisible) {
                  this.props.handleView()
                } else {
                  this.setState({
                    menuloading: false,
                    menucloseloading: false
                  })
                }
              } else {
                notification.warning({
                  top: 92,
                  message: result.message,
                  duration: 5
                })
                this.setState({
                  menuloading: false,
                  menucloseloading: false
                })
              }
            })
          } else {
            notification.success({
              top: 92,
              message: '保存成功',
              duration: 2
            })
            this.props.reloadmenu()
            Api.getLocalConfig(localParam)
            if (this.state.closeVisible) {
              this.props.handleView()
            } else {
              this.setState({
                menuloading: false,
                menucloseloading: false
              })
            }
          }
        } else {
          this.setState({
            menuloading: false,
            menucloseloading: false
          })
          notification.warning({
            top: 92,
            message: response.message,
            duration: 5
          })
        }
      })
    })
  }
@@ -554,7 +513,7 @@
   */
  setSubConfig = (item) => {
    const { menu } = this.props
    const { config, originMenu, optionLibs, activeKey, openEdition } = this.state
    const { config, originMenu, activeKey, openEdition } = this.state
    if (config.isAdd) { // menuID不存在时,为新建菜单,提示菜单尚未保存
      notification.warning({
@@ -585,6 +544,7 @@
      }
      let submenu = menu.fstMenuList.filter(item => item.MenuID === config.fstMenuId)[0]
      let _Menu = {
        ...menu,
        LongParam: config,
@@ -593,14 +553,13 @@
        MenuNo: config.MenuNo,
        ParentId: config.ParentId,
        fstMenuId: config.fstMenuId,
        supMenuList: submenu ? submenu.options : []
        supMenuList: submenu ? submenu.children : []
      }
      _Menu.activeKey = activeKey       // 保存当前打开页签
      _Menu.open_edition = openEdition  // 更新版本号
      let param = {
        optionLibs: optionLibs,
        editMenu: _Menu,
        editTab: item,
        tabConfig: null,
@@ -710,21 +669,6 @@
  }
  /**
   * @description 编辑功能完成更新,包括解冻按钮、粘贴、替换等
   */
  editConfig = (res) => {
    if (res.type === 'paste') {
      this.setState({
        pasteContent: res.content
      }, () => {
        this.setState({
          pasteContent: null
        })
      })
    }
  }
  /**
   * @description 更新标签配置信息
   */
  updatetabs = (config, delcards) => {
@@ -780,9 +724,9 @@
                {configTabs.length > 0 ?
                  <p className="config-btn-title">
                    <Tooltip placement="topLeft" title="点击按钮,可完成或查看标签配置信息。">
                      <Icon type="question-circle" />
                      <QuestionCircleOutlined className="mk-form-tip" />
                    </Tooltip>
                    {this.state.dict['header.menu.tab.configurable']}
                    标签配置
                  </p> : null
                }
                {configTabs.map((item, index) => {
@@ -803,14 +747,13 @@
          <div className="setting">
            <Card title={
              <div>
                {this.state.dict['header.menu.page.configurable']}
                <Icon type="redo" style={{marginLeft: '10px'}} title="刷新标签列表" onClick={() => this.reloadTab(true)} />
                页面配置
                <RedoOutlined style={{marginLeft: '10px'}} title="刷新标签列表" onClick={() => this.reloadTab(true)} />
              </div>
            } bordered={false} extra={
              <div>
                <EditComponent dict={this.state.dict} type="TreePage" config={this.state.config} MenuID={this.props.menu.MenuID} refresh={this.editConfig}/>
                <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={this.state.config.enabled} onChange={this.onEnabledChange} />
                <Button type="primary" onClick={this.submitConfig} loading={this.state.menuloading}>{this.state.dict['model.save']}</Button>
                <Button type="primary" id="save-config" onClick={this.submitConfig} loading={this.state.menuloading}>{this.state.dict['model.save']}</Button>
                <Button onClick={this.cancelConfig}>{this.state.dict['model.back']}</Button>
              </div>
            } style={{ width: '100%' }}>
@@ -819,7 +762,6 @@
                  <TreeSettingComponent
                    config={config}
                    MenuID={this.props.menu.MenuID}
                    permFuncField={this.props.permFuncField}
                    updatesetting={this.updateconfig}
                  />
                  <Card
@@ -827,7 +769,7 @@
                    title={
                      <span className="tree-title">
                        <span className="title">{config.setting.title}</span>
                        {config.setting.searchable !== 'false' ? <span className="ant-input-search ant-input-affix-wrapper"><span className="ant-input-suffix"><Icon type="search" /></span></span> : null}
                        {config.setting.searchable !== 'false' ? <span className="ant-input-search ant-input-affix-wrapper"><span className="ant-input-suffix"><SearchOutlined /></span></span> : null}
                      </span>
                    }
                    bordered={false}
@@ -839,13 +781,13 @@
                        showIcon={config.setting.showIcon === 'true'}
                        showLine={config.setting.showLine === 'true'}
                      >
                        <TreeNode icon={<Icon type="folder-open" />} title="parent 0" key="0-0">
                          <TreeNode icon={<Icon type="file" />} title="leaf 0-0" key="0-0-0" isLeaf />
                          <TreeNode icon={<Icon type="file" />} title="leaf 0-1" key="0-0-1" isLeaf />
                        <TreeNode icon={<FolderOpenOutlined />} title="parent 0" key="0-0">
                          <TreeNode icon={<FileOutlined />} title="leaf 0-0" key="0-0-0" isLeaf />
                          <TreeNode icon={<FileOutlined />} title="leaf 0-1" key="0-0-1" isLeaf />
                        </TreeNode>
                        <TreeNode icon={<Icon type="folder-open" />} title="parent 1" key="0-1">
                          <TreeNode icon={<Icon type="file" />} title="leaf 1-0" key="0-1-0" isLeaf />
                          <TreeNode icon={<Icon type="file" />} title="leaf 1-1" key="0-1-1" isLeaf />
                        <TreeNode icon={<FolderOpenOutlined />} title="parent 1" key="0-1">
                          <TreeNode icon={<FileOutlined />} title="leaf 1-0" key="0-1-0" isLeaf />
                          <TreeNode icon={<FileOutlined />} title="leaf 1-1" key="0-1-1" isLeaf />
                        </TreeNode>
                      </Tree>
                    </div>
@@ -886,16 +828,4 @@
  }
}
const mapStateToProps = (state) => {
  return {
    sysRoles: state.sysRoles,
    permFuncField: state.permFuncField,
    memberLevel: state.memberLevel
  }
}
const mapDispatchToProps = () => {
  return {}
}
export default connect(mapStateToProps, mapDispatchToProps)(ComTableConfig)
export default ComTableConfig