king
2020-10-23 407c0f1765c7d085218a91ad8842784977383d05
src/templates/formtabconfig/index.jsx
@@ -8,42 +8,43 @@
import { Button, Card, Modal, Collapse, notification, Spin, Select, List, Icon, Empty, Switch, Tooltip } from 'antd'
import Api from '@/api'
import zhCN from '@/locales/zh-CN/comtable.js'
import enUS from '@/locales/en-US/comtable.js'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import Utils from '@/utils/utils.js'
import { getModalForm, getActionForm } from '@/templates/tableshare/formconfig'
import DevUtils from '@/utils/devutils.js'
import { getModalForm, getActionForm } from '@/templates/zshare/formconfig'
import { queryTableSql } from '@/utils/option.js'
import ModalForm from '@/templates/ushare/modalform'
import TabsComponent from '@/templates/sharecomponent/tabscomponent'
import ModalForm from '@/templates/zshare/modalform'
import PasteForm from '@/templates/zshare/pasteform'
import ActionForm from './actionform'
import SettingForm from './settingform'
import DragElement from './dragelement'
import GroupForm from './groupform'
import TabForm from '@/templates/tableshare/tabform'
import EditCard from '@/templates/tableshare/editcard'
import VerifyCard from '@/templates/tableshare/verifycard'
import MenuForm from '@/templates/tableshare/menuform'
import TabDragElement from '@/templates/tableshare/tabdragelement'
import SourceElement from '@/templates/tableshare/dragelement/source'
import EditCard from '@/templates/zshare/editcard'
import VerifyCard from '@/templates/zshare/verifycard'
import MenuForm from '@/templates/zshare/menuform'
import SourceElement from '@/templates/zshare/dragsource'
import CreateFunc from '@/templates/zshare/createfunc'
import Source from './source'
import './index.scss'
const { Panel } = Collapse
const { Option } = Select
const { confirm } = Modal
const CommonDict = (!localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS
class ComTableConfig extends Component {
  static propTpyes = {
    menu: PropTypes.any,
    optionLibs: PropTypes.any,
    btnTab: PropTypes.object,
    config: PropTypes.any,
    handleView: PropTypes.func
  }
  state = {
    dict: CommonDict,        // 字典
    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,        // 字典
    config: null,            // 页面配置
    modaltype: '',           // 模态框类型,控制模态框显示
    tableVisible: false,     // 数据表字段模态框
@@ -61,12 +62,14 @@
    selectedTables: [],      // 已选表名
    originMenu: null,        // 原始菜单
    delActions: [],          // 删除按钮列表
    funcLoading: false,      // 存储过程创建中
    tabviews: [],            // 所有标签页
    profileVisible: false,   // 验证信息模态框
    editgroup: null,         // 当前编辑组
    groupVisible: false,     // 编辑组模态框
    optionLibs: null         // 自定义下拉选项库
    activeKey: '0',          // 默认展开基本信息
    pasteVisible: false,     // 粘贴模态框
    sqlVerifing: false,      // sql验证
    openEdition: ''          // 编辑版本标记,防止多人操作
  }
  /**
@@ -75,7 +78,7 @@
   * 2、设置操作类型、原始菜单信息(每次保存后重置)、已使用表及基本信息表单
   */
  UNSAFE_componentWillMount () {
    const { menu, btnTab, config, optionLibs } = this.props
    const { menu, btnTab, config } = this.props
    let _config = ''
    let columns = []
@@ -99,33 +102,43 @@
      if (menu && menu.LongParam && menu.LongParam.setting) {
        _config.setting.primaryKey = menu.LongParam.setting.primaryKey
      }
    }
      _config.groups.forEach(group => {
        group.sublist.forEach(item => {
          if (
            (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') &&
            item.resourceType === '0' &&
            item.options && item.options.length > 0
          ) {
            optionLibs.set(btnTab.uuid + item.uuid, {
              uuid: btnTab.uuid + item.uuid,
              label: item.label,
              parname: btnTab.label,
              type: 'Modal',
              options: item.options
            })
          }
        })
    if (!_config.tabgroups) {
      _config.tabgroups = [{ uuid: 'tabs', sublist: [] }]
    } else if (typeof(_config.tabgroups[0]) === 'string') {
      let _tabgroups = []
      _config.tabgroups.forEach(groupId => {
        let _group = {
          uuid: groupId,
          sublist: fromJS(_config[groupId]).toJS()
        }
        delete _config[groupId]
        _tabgroups.push(_group)
      })
      _config.tabgroups = _tabgroups
    }
    if (menu && menu.LongParam && menu.LongParam.columns) {
      columns = menu.LongParam.columns
    }
    // 配置默认值,兼容
    _config.Template = 'FormTab'
    _config.action = _config.action.map(item => {
      if (item.intertype === 'inner' && !item.innerFunc) {
        item.intertype = 'system'
      }
      return item
    })
    this.setState({
      config: _config,
      optionLibs: optionLibs,
      activeKey: btnTab.activeKey || '0',
      openEdition: btnTab.open_edition || '',
      columns: columns,
      originMenu: JSON.parse(JSON.stringify(_config)),
      selectedTables: _config.tables,
@@ -133,7 +146,7 @@
        {
          type: 'text',
          key: 'menuName',
          label: this.state.dict['header.menu.menuName'],
          label: this.state.dict['model.menu'] + this.state.dict['model.name'],
          initVal: menu.MenuName,
          readonly: true
        },
@@ -163,8 +176,10 @@
    }
    param.LText = Utils.formatOptions(param.LText)
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp) // 云端数据验证
    Api.getSystemConfig(param).then(res => {
      if (res.status) {
@@ -175,7 +190,7 @@
        notification.warning({
          top: 92,
          message: res.message,
          duration: 10
          duration: 5
        })
      }
    })
@@ -237,7 +252,7 @@
          notification.warning({
            top: 92,
            message: res.message,
            duration: 10
            duration: 5
          })
        }
      })
@@ -260,6 +275,12 @@
            }
          })
        })
      } else {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      }
    })
  }
@@ -272,6 +293,46 @@
      return
    }
  }
  /**
   * @description 加载或刷新标签信息
   */
  reloadTab = () => {
    this.setState({
      loading: true,
      tabviews: []
    })
    Api.getSystemConfig({func: 'sPC_Get_UserTemp', TypeCharTwo: 'tab'}).then(res => {
      if (res.status) {
        this.setState({
          loading: false,
          tabviews: res.UserTemp.map(temp => {
            return {
              uuid: temp.MenuID,
              value: temp.MenuID,
              text: temp.MenuName,
              type: temp.Template,
              MenuNo: temp.MenuNo
            }
          })
        })
        notification.success({
          top: 92,
          message: '刷新成功。',
          duration: 2
        })
      } else {
        this.setState({
          loading: false
        })
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      }
    })
  }
  // 页面返回
  handleViewBack = () => {
@@ -279,7 +340,6 @@
    let _tabview = menu ? menu.LongParam.Template : ''
    let param = {
      editMenu: menu,
      optionLibs: this.state.optionLibs,
      editTab: null,
      tabConfig: null,
      editSubTab: null,
@@ -297,15 +357,7 @@
  handleList = (type, list, card, groupId, elementId) => {
    const { config } = this.state
    if (type === 'tabs') { // 标签页调整顺序或添加元素
      if (list.length > config[card.groupId].length) {
        list = list.filter(item => !item.origin)
        this.handleTab(card)
      }
      this.setState({config: {...config, [card.groupId]: list}})
    } else if (type === 'action') {
    if (type === 'action') {
      if (list.length > config.action.length) {
  
        this.handleAction(card)
@@ -426,18 +478,34 @@
      })
    }
    let roleList = []
    if (this.props.sysRoles && this.props.sysRoles.length > 0) {
      roleList = this.props.sysRoles.map(role => {
        return {
          uuid: role.uuid,
          field: role.value,
          label: role.text
        }
      })
    }
    this.setState({
      modaltype: 'search',
      card: card,
      formlist: getModalForm(card, _inputfields, _linkableFields, _linksupFields)
      formlist: getModalForm(card, _inputfields, _linkableFields, _linksupFields, false, roleList).map(item => {
        if (item.key === 'type') {
          item.options = item.options.filter(option => !['switch', 'checkbox', 'radio', 'checkcard', 'hint'].includes(option.value))
        }
        return item
      })
    })
  }
  handleAction = (card) => {
    let ableField = this.props.permFuncField.join(', ')
    let functip = <div>
      <p style={{marginBottom: '5px'}}>{this.state.dict['header.modal.func.innerface'].replace('@ableField', ableField)}</p>
      <p>{this.state.dict['header.modal.func.outface']}</p>
      <p style={{marginBottom: '5px'}}>{this.state.dict['model.tooltip.func.innerface'].replace('@ableField', ableField)}</p>
      <p>{this.state.dict['model.tooltip.func.outface']}</p>
    </div>
    this.setState({
@@ -447,118 +515,6 @@
    })
  }
  handleTab = (card) => {
    const { config } = this.state
    let menus = [
      {value: '', text: '空'},
      {value: 'mainTable', text: '主数据'}
    ]
    let equalTabs = []
    let supMenu = card.supMenu || ''
    let equalTab = card.equalTab || []
    let isuptab = true
    let equalTabIds = []
    config.tabgroups.forEach((groupId, i) => {
      if (groupId === card.groupId) {
        isuptab = false
        config[card.groupId].forEach(tab => { // 可关联的同级标签
          if (tab.uuid === card.uuid) return
          equalTabIds.push(tab.uuid)
          equalTabs.push(tab)
        })
      } else if (isuptab) {
        config[groupId].forEach(tab => {
          menus.push({
            value: tab.uuid,
            text: tab.label
          })
        })
      }
    })
    if (supMenu && menus.filter(menu => menu.value === supMenu).length === 0) {
      supMenu = ''
    }
    if (equalTab.length > 0) {
      equalTab = equalTab.filter(tabId => equalTabIds.includes(tabId))
    }
    this.setState({
      modaltype: 'tabs',
      card: card,
      formlist: [
        {
          type: 'text',
          key: 'label',
          label: this.state.dict['header.menu.tabName'],
          initVal: card.label || '',
          required: true
        },
        {
          type: 'select',
          key: 'type',
          label: this.state.dict['header.form.tabType'],
          initVal: card.type || 'SubTable',
          required: true,
          options: [{
            value: 'SubTable',
            text: this.state.dict['header.menu.tab.subtable']
          }]
        },
        {
          type: 'select',
          key: 'linkTab',
          label: '关联标签',
          initVal: card.linkTab || '',
          required: false,
          options: []
        },
        {
          type: 'select',
          key: 'icon',
          label: this.state.dict['header.menu.icon'],
          initVal: card.icon || '',
          required: false,
          options: [{
            value: '',
            text: this.state.dict['header.form.empty']
          }, {
            value: 'table',
            text: 'table'
          }, {
            value: 'bar-chart',
            text: 'bar-chart'
          }, {
            value: 'pie-chart',
            text: 'pie-chart'
          }, {
            value: 'line-chart',
            text: 'line-chart'
          }]
        },
        {
          type: 'select',
          key: 'supMenu',
          label: this.state.dict['header.form.supTab'],
          initVal: supMenu,
          required: false,
          options: menus
        },
        {
          type: 'mutilselect',
          key: 'equalTab',
          label: this.state.dict['header.form.equalTab'],
          initVal: equalTab,
          required: false,
          options: equalTabs
        }
      ]
    })
  }
  /**
   * @description 搜索、按钮、显示列修改后提交保存
@@ -567,38 +523,27 @@
   * 3、添加或编辑列,保存时,如按钮位置设置为表格,则修改操作列显示状态
   */
  handleSubmit = () => {
    const { btnTab } = this.props
    const { config, modaltype, optionLibs, card } = this.state
    const { config, modaltype, card } = this.state
    if (modaltype === 'search') {
      this.modalFormRef.handleConfirm().then(res => {
        if (config.setting.primaryKey && config.setting.primaryKey.toLowerCase() === res.field.toLowerCase()) {
        let _config = JSON.parse(JSON.stringify(config))
        if (_config.setting.primaryKey && _config.setting.primaryKey.toLowerCase() === res.field.toLowerCase()) {
          notification.warning({
            top: 92,
            message: '表单中字段名不可与主键重复!',
            duration: 10
            duration: 5
          })
          return
        }
        if ( // 更新下拉字典
          (res.type === 'select' || res.type === 'multiselect' || res.type === 'link') &&
          res.resourceType === '0' &&
          res.options && res.options.length > 0
        ) {
          optionLibs.set(btnTab.uuid + res.uuid, {
            uuid: btnTab.uuid + res.uuid,
            label: res.label,
            parname: btnTab.label,
            type: 'Modal',
            options: res.options
          })
        }
        let _groups = null
        let fieldrepet = false // 字段重复
        let fieldrepet = false  // 字段重复
        let labelrepeat = false // 提示文字重复
        if (card.iscopy) {
          _groups = config.groups.map(group => {
          _groups = _config.groups.map(group => {
            let _index = null
            group.sublist.forEach((item, index) => {
              if (item.uuid === card.originUuid) {
@@ -607,6 +552,8 @@
              if (item.uuid !== res.uuid && item.field === res.field) {
                fieldrepet = true
              } else if (item.uuid !== res.uuid && item.label === res.label) {
                labelrepeat = true
              }
            })
@@ -620,10 +567,12 @@
            return group
          })
        } else {
          _groups = config.groups.map(group => {
          _groups = _config.groups.map(group => {
            group.sublist = group.sublist.map(item => {
              if (item.uuid !== res.uuid && item.field === res.field) {
                fieldrepet = true
              } else if (item.uuid !== res.uuid && item.label === res.label) {
                labelrepeat = true
              }
              if (item.uuid === res.uuid) {
@@ -642,17 +591,60 @@
        if (fieldrepet) {
          notification.warning({
            top: 92,
            message: '字段名重复!',
            duration: 10
            message: '字段已存在!',
            duration: 5
          })
          return
        } else if (labelrepeat) {
          notification.warning({
            top: 92,
            message: '名称已存在!',
            duration: 5
          })
          return
        }
        this.setState({
          config: {...config, groups: _groups},
          optionLibs: optionLibs,
          modaltype: ''
        })
        if ((res.type === 'select' || res.type === 'multiselect' || res.type === 'link') && res.resourceType === '1' && /\s/.test(res.dataSource)) {
          this.setState({
            sqlVerifing: true
          })
          let param = {
            func: 's_debug_sql',
            LText: res.dataSource
          }
          param.LText = param.LText.replace(/@\$|\$@/ig, '')
          param.LText = Utils.formatOptions(param.LText)
          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
          param.secretkey = Utils.encrypt(param.LText, param.timestamp)
          if (window.GLOB.mainSystemApi && res.database === 'sso') {
            param.rduri = window.GLOB.mainSystemApi
          }
          Api.getLocalConfig(param).then(result => {
            if (result.status) {
              this.setState({
                sqlVerifing: false,
                config: {..._config, groups: _groups},
                modaltype: ''
              })
            } else {
              this.setState({sqlVerifing: false})
              Modal.error({
                title: result.message
              })
            }
          })
        } else {
          this.setState({
            config: {..._config, groups: _groups},
            modaltype: ''
          })
        }
      })
    } else if (modaltype === 'actionEdit') {
      this.actionFormRef.handleConfirm().then(res => {
@@ -666,22 +658,6 @@
        this.setState({
          config: {...config, action: _action},
          modaltype: ''
        })
      })
    } else if (modaltype === 'tabs') {
      this.tabsFormRef.handleConfirm().then(res => {
        let _tabgroup = config[res.groupId].map(item => {
          if (item.uuid === res.uuid) {
            return res
          } else {
            return item
          }
        })
        _tabgroup = _tabgroup.filter(item => !item.origin)
        this.setState({
          config: {...config, [res.groupId]: _tabgroup},
          modaltype: ''
        })
      })
@@ -702,9 +678,6 @@
      } else if (modaltype === 'actionEdit') {
        let _action = config.action.filter(item => item.uuid !== card.uuid)
        _config = {...config, action: _action}
      } else if (modaltype === 'tabs') {
        let _tabgroup = config[card.groupId].filter(item => item.uuid !== card.uuid)
        _config = {...config, [card.groupId]: _tabgroup}
      } else {
        _config = config
      }
@@ -729,276 +702,37 @@
    const { menu } = this.props
    let _config = JSON.parse(JSON.stringify(this.state.config))
    this.formRef.handleConfirm().then(res => {
      let btn = res.values  // 按钮信息
    this.actionFormRef.handleConfirm().then(res => {
      let btn = res         // 按钮信息
      let newLText = ''     // 创建存储过程sql
      let DelText = ''      // 删除存储过程sql
      let isExit = false    // 存储过程是否存在
      let sysTVPText = ''   // 已有的存储过程语句(云端)
      let localTVPText = '' // 已有的存储过程语句(本地)
      // 创建存储过程,必须填写内部函数名
      if (!btn.innerFunc) {
        notification.warning({
          top: 92,
          message: '请填写内部函数!',
          duration: 10
          duration: 5
        })
        return
      }
      // 创建中
      this.setState({
        funcLoading: true
      let fields = []
      _config.groups.forEach(group => {
        fields = [...fields, ...group.sublist]
      })
      new Promise(resolve => {
        // 弹窗(表单)类按钮,先获取按钮配置信息,如果尚未配置按钮则会报错并终止。
        // 获取信息后生成删除和创建存储过程的语句
        if (btn.OpenType === 'pop') {
          Api.getSystemConfig({
            func: 'sPC_Get_LongParam',
            MenuID: btn.uuid
          }).then(res => {
            let _LongParam = ''
            if (res.status && res.LongParam) {
              try {
                _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
              } catch (e) {
                console.warn('Parse Failure')
                _LongParam = ''
              }
            }
      let _param = {
        funcName: btn.innerFunc,
        name: _config.setting.tableName || '',
        fields: fields,
        menuNo: menu.MenuNo
      }
            if (_LongParam) {
              let fields = []
              if (_LongParam.groups.length > 0) {
                _LongParam.groups.forEach(group => {
                  fields = [...fields, ...group.sublist]
                })
              } else {
                fields = _LongParam.fields
              }
      newLText = Utils.formatOptions(DevUtils.getfunc(_param, btn, menu, _config))
      DelText = Utils.formatOptions(DevUtils.dropfunc(_param.funcName))
              let _param = {
                funcName: btn.innerFunc,
                name: _config.setting.tableName || '',
                fields: fields,
                menuNo: menu.MenuNo
              }
              newLText = Utils.formatOptions(Utils.getfunc(_param, btn, menu, _config))
              DelText = Utils.formatOptions(Utils.dropfunc(_param.funcName))
              resolve(true)
            } else {
              resolve(false)
              notification.warning({
                top: 92,
                message: '弹窗(表单)按钮,请先配置表单信息!',
                duration: 10
              })
            }
          })
        } else {
          let _param = {
            funcName: btn.innerFunc,
            name: _config.setting.tableName || '',
            fields: '',
            menuNo: menu.MenuNo
          }
          newLText = Utils.formatOptions(Utils.getfunc(_param, btn, menu, _config))
          DelText = Utils.formatOptions(Utils.dropfunc(_param.funcName))
          resolve(true)
        }
      }).then(res => {
        // 获取云端及本地,是否已存在该存储过程的信息
        if (res === false) return res
        let sysDefer = new Promise(resolve => {
          Api.getSystemConfig({
            func: 'sPC_Get_TVP', // 云端获取存储结果
            TVPName: btn.innerFunc
          }).then(result => {
            resolve(result)
          })
        })
        let localDefer = new Promise(resolve => {
          let _param = { // 获取本地存储过程信息
            func: 's_get_userproc',
            LText: btn.innerFunc
          }
          _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
          _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
          Api.getLocalConfig(_param).then(result => {
            resolve(result)
          })
        })
        return Promise.all([sysDefer, localDefer])
      }).then(res => {
        // 云端结果与新语句不同时,更新云端信息
        if (res === false) return res
        let isError = false
        res.forEach((result, index) => {
          if (!result.status) {
            notification.warning({
              top: 92,
              message: result.message,
              duration: 10
            })
            isError = true
          } else if (index === 0) {
            sysTVPText = result.TVPText
          } else {
            if (result.Ltext) { // 本地存储过程是否存在
              isExit = true
            }
            localTVPText = Utils.formatOptions(result.Ltext)
          }
        })
        if (isError) return false
        if ((newLText === localTVPText) && (newLText === sysTVPText)) {
          return 'drop'
        } else if (!localTVPText || (localTVPText === sysTVPText)) {
          // 本地存储过程不存在,将新的存储过程更新至云端
          return Api.getSystemConfig({
            func: 'sPC_TVP_InUp',
            TVPName: btn.innerFunc,
            TVPText: newLText,
            TypeName: 'P'
          })
        } else {
          return new Promise(resolve => {
            Api.getSystemConfig({ // 添加现有的本地存储过程至云端
              func: 'sPC_TVP_InUp',
              TVPName: btn.innerFunc,
              TVPText: localTVPText,
              TypeName: 'P'
            }).then(result => {
              if (result.status) {
                Api.getSystemConfig({
                  func: 'sPC_TVP_InUp', // 添加最新的存储过程至云端
                  TVPName: btn.innerFunc,
                  TVPText: newLText,
                  TypeName: 'P'
                }).then(response => {
                  resolve(response)
                })
              } else {
                resolve(result)
              }
            })
          })
        }
      }).then(res => {
        // 云端信息更新后,判断是删除或是直接新建存储过程
        if (res === false || res === 'drop') return res
        if (!res.status) {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 10
          })
          return false
        } else if (isExit) {
          return 'drop'
        } else {
          return 'create'
        }
      }).then(res => {
        // 删除存储过程
        if (res === false || res === 'create') return res
        let _param = {
          func: 'sPC_TableData_InUpDe',
          LText: DelText,
          TypeCharOne: 'proc' // 删除或创建存储过程
        }
        _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
        _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
        return Api.getLocalConfig(_param)
      }).then(res => {
        // 根据上述操作结果,判断是否新建存储过程
        if (res === false || res === 'create') return res
        if (!res.status) {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 10
          })
          return false
        } else {
          return 'create'
        }
      }).then(res => {
        // 新建存储过程
        if (res === false) return res
        let _param = {
          func: 'sPC_TableData_InUpDe',
          LText: newLText,
          TypeCharOne: 'proc' // 删除或创建存储过程
        }
        _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
        _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
        return Api.getLocalConfig(_param)
      }).then(res => {
        // 处理新建结果
        if (res === false) return res
        if (!res.status) {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 10
          })
          return false
        } else {
          notification.success({
            top: 92,
            message: '创建成功',
            duration: 2
          })
          return true
        }
      }).then(res => {
        // 新建成功后,更新页面按钮信息
        if (res === false) {
          this.setState({
            funcLoading: false
          })
          return
        }
        let isupdate = false
        _config.action = _config.action.map(item => {
          if (item.uuid === btn.uuid) {
            isupdate = true
            return btn
          } else {
            return item
          }
        })
        if (!isupdate) { // 操作不是修改,添加元素至列表
          _config.action.push(btn)
        }
        this.setState({
          config: _config,
          funcLoading: false
        })
      })
      this.refs.btnCreatFunc.exec(btn.innerFunc, newLText, DelText)
    })
  }
@@ -1007,15 +741,15 @@
   */
  tableCreatFunc = () => {
    const { menu } = this.props
    let config = JSON.parse(JSON.stringify(this.state.config))
    const { config } = this.state
    this.settingRef.handleConfirm().then(res => {
      const setting = res
    this.settingRef.handleConfirm().then(setting => {
      if (!(setting.interType === 'inner') || !setting.innerFunc) {
        notification.warning({
          top: 92,
          message: '接口类型为-内部,且存在内部函数时,才可以创建存储过程!',
          duration: 10
          duration: 5
        })
        return
      }
@@ -1028,197 +762,22 @@
        }
        param.LText = Utils.formatOptions(param.LText)
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
        Api.getLocalConfig(param)
      }
      this.setState({
        funcLoading: true
      })
      let _config = {...config, setting: setting}
      let newLText = Utils.formatOptions(DevUtils.getTableFunc(setting, menu, _config)) // 创建存储过程sql
      let DelText = Utils.formatOptions(DevUtils.dropfunc(setting.innerFunc))          // 删除存储过程sql
      let newLText = Utils.formatOptions(Utils.getTableFunc(setting, menu, config)) // 创建存储过程sql
      let DelText = Utils.formatOptions(Utils.dropfunc(setting.innerFunc))          // 删除存储过程sql
      new Promise(resolve => {
        let sysDefer = new Promise(resolve => {
          Api.getSystemConfig({
            func: 'sPC_Get_TVP', // 云端获取存储结果
            TVPName: setting.innerFunc
          }).then(result => {
            if (!result.status) {
              notification.warning({
                top: 92,
                message: result.message,
                duration: 10
              })
              resolve(false)
            } else {
              resolve(result)
            }
          })
        })
        let localDefer = new Promise(resolve => {
          let _param = { // 获取本地存储过程信息
            func: 's_get_userproc',
            LText: setting.innerFunc
          }
          _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
          _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
          Api.getLocalConfig(_param).then(result => {
            if (!result.status) {
              notification.warning({
                top: 92,
                message: result.message,
                duration: 10
              })
              resolve(false)
            } else {
              resolve(result)
            }
          })
        })
        Promise.all([sysDefer, localDefer]).then(result => {
          resolve(result)
        })
      }).then(res => {
        // 获取云端及本地,是否已存在该存储过程的信息
        if (res === false) return res
        if (res[0] === false || res[1] === false) return false
        let cloudfunc = ''
        let localfunc = ''
        res.forEach((item, index) => {
          if (index === 0 && item.TVPText) {
            cloudfunc = item.TVPText
          } else if (index === 1 && item.Ltext) {
            localfunc = Utils.formatOptions(item.Ltext)
          }
        })
        if ((newLText === localfunc) && (newLText === cloudfunc)) {
          return 'drop'
        } else if (!localfunc || (cloudfunc === localfunc)) {
          // 本地存储过程不存在,或云端和本地存储过程一致时,将新的存储过程更新至云端
          return Api.getSystemConfig({
            func: 'sPC_TVP_InUp',
            TVPName: setting.innerFunc,
            TVPText: newLText,
            TypeName: 'P'
          })
        } else {
          return new Promise(resolve => {
            Api.getSystemConfig({ // 添加现有的本地存储过程至云端
              func: 'sPC_TVP_InUp',
              TVPName: setting.innerFunc,
              TVPText: localfunc,
              TypeName: 'P'
            }).then(result => {
              if (result.status) {
                Api.getSystemConfig({
                  func: 'sPC_TVP_InUp', // 添加最新的存储过程至云端
                  TVPName: setting.innerFunc,
                  TVPText: newLText,
                  TypeName: 'P'
                }).then(response => {
                  resolve(response)
                })
              } else {
                resolve(result)
              }
            })
          })
        }
      }).then(res => {
        // 云端信息更新后,判断是删除或是直接新建存储过程
        if (res === false || res === 'drop') return res
        if (!res.status) {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 10
          })
          return false
        } else {
          return 'create'
        }
      }).then(res => {
        // 删除存储过程
        if (res === false || res === 'create') return res
        let _param = {
          func: 'sPC_TableData_InUpDe',
          LText: DelText,
          TypeCharOne: 'proc' // 删除或创建存储过程
        }
        _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
        _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
        return Api.getLocalConfig(_param)
      }).then(res => {
        // 根据上述操作结果,判断是否新建存储过程
        if (res === false || res === 'create') return res
        if (!res.status) {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 10
          })
          return false
        } else {
          return 'create'
        }
      }).then(res => {
        // 新建存储过程
        if (res === false) return res
        let _param = {
          func: 'sPC_TableData_InUpDe',
          LText: newLText,
          TypeCharOne: 'proc' // 删除或创建存储过程
        }
        _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
        _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
        return Api.getLocalConfig(_param)
      }).then(res => {
        // 处理新建结果
        if (res === false) return res
        if (!res.status) {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 10
          })
          return false
        } else {
          notification.success({
            top: 92,
            message: '创建成功',
            duration: 2
          })
          return true
        }
      }).then(res => {
        // 新建成功后,更新页面按钮信息
        if (res === false) {
      this.refs.tableCreatFunc.exec(setting.innerFunc, newLText, DelText).then(result => {
        if (result === 'success') {
          this.setState({
            funcLoading: false
            config: _config
          })
          return
        }
        this.setState({
          config: {...config, setting: setting}
        })
      })
    })
  }
@@ -1227,22 +786,11 @@
    let _this = this
    confirm({
      content: `确定删除<<${element.card.label}>>吗?`,
      okText: this.state.dict['header.confirm'],
      cancelText: this.state.dict['header.cancel'],
      onOk() {
        let _config = JSON.parse(JSON.stringify(_this.state.config))
        let _delActions = _this.state.delActions
        if (element.type === 'tabs') {
          _config[element.card.groupId] = _config[element.card.groupId].filter(item => {
            if (item.uuid === element.card.uuid) {
              return false
            } else {
              return true
            }
          })
          _delActions.push(element.card.uuid)
        } else if (element.type === 'search') {
        if (element.type === 'search') {
          _config.groups = _config.groups.map(group => {
            group.sublist = group.sublist.filter(item => item.uuid !== element.card.uuid)
            return group
@@ -1283,20 +831,21 @@
  verifySubmit = () => {
    const { card } = this.state
    let config = JSON.parse(JSON.stringify(this.state.config))
    let _verify = this.verifyRef.state.verify
    config.action = config.action.map(item => {
      if (item.uuid === card.uuid) {
        item.verify = _verify
      }
      return item
    })
    this.setState({
      profileVisible: false,
      config: config,
      card: '',
    this.verifyRef.handleConfirm().then(res => {
      config.action = config.action.map(item => {
        if (item.uuid === card.uuid) {
          item.verify = res
        }
        return item
      })
      this.setState({
        profileVisible: false,
        config: config,
        card: ''
      })
    })
  }
@@ -1305,19 +854,27 @@
   */
  submitConfig = () => {
    const { menu, btnTab } = this.props
    const { delActions } = this.state
    const { delActions, openEdition } = this.state
    let config = JSON.parse(JSON.stringify(this.state.config))
    this.menuformRef.handleConfirm().then(res => {
      if (config.isAdd) {
        if (config.groups[0] && config.groups[0].sublist[0] && config.groups[0].sublist[0].origin) {
          config.groups[0].sublist = config.groups[0].sublist.filter(item => !item.origin)
        }
        if (config.tabs[0] && config.tabs[0].origin) {
          config.tabs = config.tabs.filter(item => !item.origin)
        }
        config.tabgroups[0].sublist = config.tabgroups[0].sublist.filter(item => !item.origin)
      }
      let btnNames = config.action.map(item => item.label)
      btnNames = Array.from(new Set(btnNames))
      if (btnNames.length < config.action.length) {
        notification.warning({
          top: 92,
          message: '按钮名称不可相同!',
          duration: 5
        })
        return
      }
      let _LongParam = ''
@@ -1332,8 +889,8 @@
      // 标签不合法时,启用状态为false
      if (_config.tabgroups.length > 1) {
        _config.tabgroups.forEach(groupId => {
          if (_config[groupId].length === 0) {
        _config.tabgroups.forEach(group => {
          if (group.sublist.length === 0) {
            _config.enabled = false
          }
        })
@@ -1386,10 +943,8 @@
        }
      })
      _config.tabgroups.forEach(groupId => {
        if (_config[groupId].length === 0) return
        _config[groupId].forEach(tab => {
      _config.tabgroups.forEach(group => {
        group.sublist.forEach(tab => {
          _config.funcs.push({
            type: 'tab',
            subtype: 'tab',
@@ -1462,7 +1017,7 @@
          notification.warning({
            top: 92,
            message: '编译错误',
            duration: 10
            duration: 5
          })
          this.setState({
@@ -1490,7 +1045,7 @@
  
        btnParam.LText = btnParam.LText.join(' union all ')
        btnParam.LText = Utils.formatOptions(btnParam.LText)
        btnParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
        btnParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        btnParam.secretkey = Utils.encrypt(btnParam.LText, btnParam.timestamp)
        
        let tabParam = { // 添加菜单tab页
@@ -1500,8 +1055,8 @@
        
        let _LText = []
        config.tabgroups.forEach(groupId => {
          config[groupId].forEach(item => {
        config.tabgroups.forEach(group => {
          group.sublist.forEach(item => {
            _sort++
            _LText.push(`select '${btnTab.uuid}' as MenuID ,'${item.linkTab}' as Tabid,'${item.label}' as TabName ,'${_sort * 10}' as Sort`)
          })
@@ -1511,7 +1066,7 @@
        tabParam.LText = Utils.formatOptions(_LText)
        tabParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
        tabParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        tabParam.secretkey = Utils.encrypt(tabParam.LText, tabParam.timestamp)
  
        let param = {
@@ -1523,6 +1078,10 @@
          MenuName: btnTab.label,
          PageParam: JSON.stringify({Template: 'FormTab'}),
          LongParam: _LongParam
        }
        if (openEdition) {
          param.open_edition = openEdition
        }
        // 有按钮或标签删除时,先进行删除操作
@@ -1556,7 +1115,7 @@
                notification.warning({
                  top: 92,
                  message: error.message,
                  duration: 10
                  duration: 5
                })
                resolve(false)
              } else {
@@ -1575,6 +1134,7 @@
          Api.getSystemConfig(param).then(response => {
            if (response.status) {
              this.setState({
                openEdition: response.open_edition || '',
                config: _config,
                originMenu: _config
              })
@@ -1588,7 +1148,7 @@
              notification.warning({
                top: 92,
                message: response.message,
                duration: 10
                duration: 5
              })
            }
          })
@@ -1597,8 +1157,8 @@
    }, () => {
      notification.warning({
        top: 92,
        message: this.state.dict['header.menu.basemsg'],
        duration: 10
        message: this.state.dict['model.menu.basemsg'],
        duration: 5
      })
    })
  }
@@ -1643,7 +1203,7 @@
            notification.warning({
              top: 92,
              message: error.message,
              duration: 10
              duration: 5
            })
            resolve(false)
          } else {
@@ -1683,8 +1243,6 @@
    if (config.isAdd) {
      confirm({
        content: '按钮配置尚未提交,确定放弃保存吗?',
        okText: this.state.dict['header.confirm'],
        cancelText: this.state.dict['header.cancel'],
        onOk() {
          _this.handleViewBack()
        },
@@ -1710,7 +1268,7 @@
      notification.warning({
        top: 92,
        message: '请选择表名!',
        duration: 10
        duration: 5
      })
      return
    }
@@ -1856,7 +1414,7 @@
          notification.warning({
            top: 92,
            message: res.message,
            duration: 10
            duration: 5
          })
        }
      })
@@ -1896,16 +1454,49 @@
        }
        param.LText = Utils.formatOptions(param.LText)
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
        Api.getLocalConfig(param)
      }
      this.setState({
        config: {...config, setting: res},
        settingVisible: false,
      })
      if (res.interType === 'inner' && !res.innerFunc && res.dataresource && /\s/.test(res.dataresource)) {
        this.setState({
          sqlVerifing: true
        })
        let param = {
          func: 's_debug_sql',
          LText: res.dataresource
        }
        param.LText = param.LText.replace(/@\$|\$@/ig, '')
        param.LText = Utils.formatOptions(param.LText)
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
        Api.getLocalConfig(param).then(result => {
          if (result.status) {
            this.setState({
              sqlVerifing: false,
              config: {...config, setting: res},
              settingVisible: false
            })
          } else {
            this.setState({sqlVerifing: false})
            Modal.error({
              title: result.message
            })
          }
        })
      } else {
        this.setState({
          config: {...config, setting: res},
          settingVisible: false
        })
      }
    })
  }
@@ -1914,13 +1505,13 @@
   */
  setSubConfig = (btn) => {
    const {menu, btnTab} = this.props
    const { config, originMenu } = this.state
    const { config, originMenu, activeKey, openEdition } = this.state
    if (config.isAdd) {
      notification.warning({
        top: 92,
        message: '菜单尚未保存,请保存菜单配置!',
        duration: 10
        duration: 5
      })
    } else {
      this.menuformRef.handleConfirm().then(res => {
@@ -1930,16 +1521,18 @@
          notification.warning({
            top: 92,
            message: '菜单配置已修改,请保存!',
            duration: 10
            duration: 5
          })
        } else {
          this.setState({
            loading: true
          })
          btnTab.activeKey = activeKey       // 保存当前打开页签
          btnTab.open_edition = openEdition  // 更新版本号
          let param = {
            editMenu: menu,
            optionLibs: this.state.optionLibs,
            editTab: btn,
            tabConfig: null,
            editSubTab: null,
@@ -1973,6 +1566,10 @@
                param.subConfig = _LongParam
              }
              if (param.editTab) {
                param.editTab.open_edition = res.open_edition || ''
              }
              this.props.handleView(param)
            } else {
              this.setState({
@@ -1981,7 +1578,7 @@
              notification.warning({
                top: 92,
                message: res.message,
                duration: 10
                duration: 5
              })
            }
          })
@@ -1990,7 +1587,7 @@
        notification.warning({
          top: 92,
          message: '菜单基本信息已修改,请保存!',
          duration: 10
          duration: 5
        })
      })
    }
@@ -2002,7 +1599,7 @@
    let tabinvalid = true
    if (config.tabgroups.length > 1) {
      config.tabgroups.forEach(group => {
        if (config[group].length === 0) {
        if (group.sublist.length === 0) {
          tabinvalid = false
        }
      })
@@ -2031,31 +1628,31 @@
      notification.warning({
        top: 92,
        message: '尚未设置数据源,不可启用!',
        duration: 10
        duration: 5
      })
    } else if (config.setting.datatype === 'query' && !config.setting.primaryKey) {
      notification.warning({
        top: 92,
        message: '尚未设置主键,不可启用!',
        duration: 10
        duration: 5
      })
    } else if (!tabinvalid) {
      notification.warning({
        top: 92,
        message: '存在多余标签组,不可启用!',
        duration: 10
        duration: 5
      })
    } else if (!forminvalid) {
      notification.warning({
        top: 92,
        message: '存在多余空表单组,不可启用!',
        duration: 10
        duration: 5
      })
    } else if (primaryrepeat) {
      notification.warning({
        top: 92,
        message: '表单字段与主键重复,不可启用!',
        duration: 10
        duration: 5
      })
    } else {
      this.setState({
@@ -2064,48 +1661,7 @@
    }
  }
  addTabGroup = () => {
    let _this = this
    let _config = JSON.parse(JSON.stringify(this.state.config))
    confirm({
      content: `确定新建标签组吗?`,
      okText: this.state.dict['header.confirm'],
      cancelText: this.state.dict['header.cancel'],
      onOk() {
        let newgroup = 'tabs' + Utils.getuuid()
        _config.tabgroups.push(newgroup)
        _config[newgroup] = []
        _this.setState({
          config: _config,
        })
      },
      onCancel() {}
    })
  }
  delTabGroup = (groupId) => {
    let _this = this
    let _config = JSON.parse(JSON.stringify(this.state.config))
    confirm({
      content: `确定删除标签组吗?`,
      okText: this.state.dict['header.confirm'],
      cancelText: this.state.dict['header.cancel'],
      onOk() {
        _config.tabgroups = _config.tabgroups.filter(group => group !== groupId)
        delete _config[groupId]
        _this.setState({
          config: _config
        })
      },
      onCancel() {}
    })
  }
  handleGroup = (group) => {
    let editgroup = {
@@ -2131,8 +1687,6 @@
    confirm({
      content: `确定删除分组<<${group.label}>>吗?`,
      okText: this.state.dict['header.confirm'],
      cancelText: this.state.dict['header.cancel'],
      onOk() {
        let groups = config.groups.filter(item => !(item.uuid === group.uuid))
        groups = groups.map(item => {
@@ -2174,33 +1728,62 @@
    })
  }
  handleTabGroup = (index, type) => {
    let config = JSON.parse(JSON.stringify(this.state.config))
    if (type === 'up') {
      config.tabgroups.splice(index, 0, config.tabgroups.splice(index - 1, 1)[0])
    } else {
      config.tabgroups.splice(index, 0, config.tabgroups.splice(index + 1, 1)[0])
    }
  pasteSubmit = () => {
    let _config = JSON.parse(JSON.stringify(this.state.config))
    this.pasteFormRef.handleConfirm().then(res => {
      if (res.copyType === 'form') {
        _config.groups.forEach(group => {
          if (group.isDefault) {
            group.sublist.push(res)
          }
        })
        if (res.type === 'linkMain') {
          notification.warning({
            top: 92,
            message: '不支持此表单类型!',
            duration: 5
          })
          return
        }
        this.setState({
          config: _config,
          pasteVisible: null
        }, () => {
          this.handleSearch(res)
        })
      } else {
        notification.warning({
          top: 92,
          message: '配置信息格式错误!',
          duration: 5
        })
      }
    })
  }
  /**
   * @description 更新标签配置信息
   */
  updatetabs = (config, delcards) => {
    const { delActions } = this.state
    this.setState({
      config: config
    })
    notification.success({
      top: 92,
      message: '调整成功',
      duration: 2
      config: config,
      delActions: delcards ? [...delActions, ...delcards.map(item => item.uuid)] : delActions
    })
  }
  render () {
    const { config, modaltype } = this.state
    const { config, modaltype, activeKey } = this.state
    let _length = config.groups.length
    let configTabs = []
    this.state.config.tabgroups.forEach(group => {
      configTabs.push(...this.state.config[group])
    config.tabgroups.forEach(group => {
      configTabs.push(...group.sublist)
    })
    return (
@@ -2208,9 +1791,9 @@
        <DndProvider backend={HTML5Backend}>
          {/* 工具栏 */}
          <div className="tools">
            <Collapse accordion defaultActiveKey="0" bordered={false}>
            <Collapse accordion defaultActiveKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
              {/* 基本信息 */}
              <Panel header={this.state.dict['header.menu.basedata']} key="0" id="common-basedata">
              <Panel forceRender={true} header={this.state.dict['header.menu.basedata']} key="0" id="common-basedata">
                {/* 菜单信息 */}
                <MenuForm
                  dict={this.state.dict}
@@ -2303,11 +1886,16 @@
            </Collapse>
          </div>
          <div className="setting">
            <Card title={this.state.dict['header.menu.page.configurable']} bordered={false} extra={
            <Card title={
              <div>
                {this.state.dict['header.menu.page.configurable']}
                <Icon type="redo" style={{marginLeft: '10px'}} title="刷新标签列表" onClick={this.reloadTab} />
              </div>
            } bordered={false} extra={
              <div>
                <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['header.save']}</Button>
                <Button onClick={this.cancelConfig}>{this.state.dict['header.return']}</Button>
                <Button type="primary" 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%' }}>
              <Icon type="setting" onClick={this.changeSetting} />
@@ -2335,6 +1923,7 @@
                      />
                    </span>
                  )}>
                    {group.isDefault ? <Icon type="snippets" title={this.state.dict['header.form.paste']} onClick={() => {this.setState({pasteVisible: true})}} /> : null}
                    <DragElement
                      type="search"
                      groupId={group.uuid}
@@ -2363,29 +1952,12 @@
                />
              </div>
              {/* 标签组 */}
              {this.state.config.tabgroups.map((groupId, index) => {
                return (
                  <div key={index} className="tab-list">
                    {index === 0 ? <Tooltip placement="bottomLeft" overlayClassName="middle" title="在左侧工具栏《标签页》中,选择对应类型的标签页拖至此处添加。">
                      <Icon type="question-circle" />
                    </Tooltip> : null}
                    {index !== (this.state.config.tabgroups.length - 1) ?
                      <Icon type="arrow-down" onClick={() => {this.handleTabGroup(index, 'down')}} /> : null
                    }
                    {index !== 0 ? <Icon type="arrow-up" onClick={() => {this.handleTabGroup(index, 'up')}} /> : null}
                    {index === 0 ? <Icon type="plus" onClick={this.addTabGroup} /> : null}
                    {index !== 0 ? <Icon type="delete" onClick={() => {this.delTabGroup(groupId)}} /> : null}
                    <TabDragElement
                      type="tabs"
                      groupId={groupId}
                      list={this.state.config[groupId]}
                      handleList={this.handleList}
                      handleMenu={this.handleTab}
                      deleteMenu={this.deleteElement}
                      placeholder={this.state.dict['header.form.tab.placeholder']}
                    />
                  </div>)
              })}
              <TabsComponent
                config={config}
                tabs={this.state.tabviews}
                setSubConfig={(item) => this.setSubConfig(item, 'tab')}
                updatetabs={this.updatetabs}
              />
            </Card>
          </div>
        </DndProvider>
@@ -2396,6 +1968,7 @@
          width={700}
          maskClosable={false}
          onOk={this.handleSubmit}
          confirmLoading={this.state.sqlVerifing}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
@@ -2404,22 +1977,21 @@
            card={this.state.card}
            formlist={this.state.formlist}
            inputSubmit={this.handleSubmit}
            optionLibs={this.state.optionLibs}
            wrappedComponentRef={(inst) => this.modalFormRef = inst}
          />
        </Modal>
        {/* 编辑按钮:复制、编辑 */}
        <Modal
          title={this.state.dict['header.modal.action.edit']}
          title={this.state.dict['model.action'] + '-' + this.state.dict['model.edit']}
          visible={modaltype === 'actionEdit'}
          width={700}
          maskClosable={false}
          onCancel={this.editModalCancel}
          footer={[
            this.state.card && this.state.card.btnType !== 'cancel' ?
            <Button key="delete" className="mk-btn mk-purple" onClick={this.creatFunc} loading={this.state.funcLoading}>{this.state.dict['header.menu.func.create']}</Button> : null,
            <Button key="cancel" onClick={this.editModalCancel}>{this.state.dict['header.cancel']}</Button>,
            <Button key="confirm" type="primary" onClick={this.handleSubmit}>{this.state.dict['header.confirm']}</Button>
            <CreateFunc key="create" dict={this.state.dict} ref="btnCreatFunc" trigger={this.creatFunc}/> : null,
            <Button key="cancel" onClick={this.editModalCancel}>{this.state.dict['model.cancel']}</Button>,
            <Button key="confirm" type="primary" onClick={this.handleSubmit}>{this.state.dict['model.confirm']}</Button>
          ]}
          destroyOnClose
        >
@@ -2432,35 +2004,15 @@
            wrappedComponentRef={(inst) => this.actionFormRef = inst}
          />
        </Modal>
        {/* 标签编辑 */}
        <Modal
          title={this.state.dict['header.modal.tabs.edit']}
          visible={modaltype === 'tabs'}
          width={700}
          maskClosable={false}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <TabForm
            type="tabs"
            dict={this.state.dict}
            card={this.state.card}
            tabs={this.state.tabviews}
            formlist={this.state.formlist}
            inputSubmit={this.handleSubmit}
            wrappedComponentRef={(inst) => this.tabsFormRef = inst}
          />
        </Modal>
        {/* 根据字段名添加显示列及搜索条件 */}
        <Modal
          wrapClassName="common-table-fields-modal"
          title={this.state.dict['header.edit']}
          title={this.state.dict['model.edit']}
          visible={this.state.tableVisible}
          width={'65vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          cancelText={this.state.dict['header.close']}
          cancelText={this.state.dict['model.close']}
          onOk={this.addFieldSubmit}
          onCancel={() => { // 取消添加
            this.setState({
@@ -2484,6 +2036,7 @@
          width={'75vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          okText={this.state.dict['model.submit']}
          onOk={this.verifySubmit}
          onCancel={() => { this.setState({ profileVisible: false }) }}
          destroyOnClose
@@ -2499,7 +2052,7 @@
        </Modal>
        {/* 设置全局配置及列表数据源 */}
        <Modal
          title={this.state.dict['header.edit']}
          title={this.state.dict['model.edit']}
          visible={this.state.settingVisible}
          width={700}
          maskClosable={false}
@@ -2509,9 +2062,9 @@
            })
          }}
          footer={[
            <Button key="delete" className="mk-btn mk-purple" onClick={this.tableCreatFunc} loading={this.state.funcLoading}>{this.state.dict['header.menu.func.create']}</Button>,
            <Button key="cancel" onClick={() => { this.setState({ settingVisible: false }) }}>{this.state.dict['header.cancel']}</Button>,
            <Button key="confirm" type="primary" onClick={this.settingSave}>{this.state.dict['header.confirm']}</Button>
            <CreateFunc key="create" dict={this.state.dict} ref="tableCreatFunc" trigger={this.tableCreatFunc}/>,
            <Button key="cancel" onClick={() => { this.setState({ settingVisible: false }) }}>{this.state.dict['model.cancel']}</Button>,
            <Button key="confirm" type="primary" loading={this.state.sqlVerifing} onClick={this.settingSave}>{this.state.dict['model.confirm']}</Button>
          ]}
          destroyOnClose
        >
@@ -2531,9 +2084,9 @@
          visible={this.state.closeVisible}
          onCancel={() => { this.setState({closeVisible: false}) }}
          footer={[
            <Button key="save" className="mk-btn mk-green" loading={this.state.menucloseloading} onClick={this.submitConfig}>{this.state.dict['header.save']}</Button>,
            <Button key="confirm" className="mk-btn mk-yellow" onClick={this.handleViewBack}>{this.state.dict['header.notsave']}</Button>,
            <Button key="cancel" onClick={() => { this.setState({closeVisible: false}) }}>{this.state.dict['header.cancel']}</Button>
            <Button key="save" className="mk-btn mk-green" loading={this.state.menucloseloading} onClick={this.submitConfig}>{this.state.dict['model.save']}</Button>,
            <Button key="confirm" className="mk-btn mk-yellow" onClick={this.handleViewBack}>{this.state.dict['model.notsave']}</Button>,
            <Button key="cancel" onClick={() => { this.setState({closeVisible: false}) }}>{this.state.dict['model.cancel']}</Button>
          ]}
          destroyOnClose
        >
@@ -2556,6 +2109,21 @@
            wrappedComponentRef={(inst) => this.groupRef = inst}
          />
        </Modal>
        {/* 按钮配置信息粘贴复制 */}
        <Modal
          title={this.state.dict['header.form.paste']}
          visible={this.state.pasteVisible}
          width={600}
          maskClosable={false}
          onOk={this.pasteSubmit}
          onCancel={() => {this.setState({pasteVisible: null})}}
          destroyOnClose
        >
          <PasteForm
            dict={this.state.dict}
            wrappedComponentRef={(inst) => this.pasteFormRef = inst}
          />
        </Modal>
        {this.state.loading && <Spin size="large" />}
      </div>
    )
@@ -2564,6 +2132,7 @@
const mapStateToProps = (state) => {
  return {
    sysRoles: state.sysRoles,
    permFuncField: state.permFuncField
  }
}