king
2023-05-09 7b0dbecd1d6155d26ec67be0a47a16264c738c85
src/menu/modalconfig/index.jsx
@@ -1,32 +1,29 @@
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 moment from 'moment'
import { Button, Card, Modal, Collapse, notification, Icon, Empty, Popover } from 'antd'
import { Button, Card, Modal, Collapse, notification, Switch, message } from 'antd'
import { SettingOutlined, CopyOutlined } from '@ant-design/icons'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import { getModalForm } from '@/templates/zshare/formconfig'
import ModalForm from '@/templates/zshare/modalform'
import DragElement from '@/templates/modalconfig/dragelement'
import SourceElement from '@/templates/modalconfig/dragelement/source'
import SettingForm from '@/templates/modalconfig/settingform'
import GroupForm from '@/templates/modalconfig/groupform'
import EditCard from '@/templates/modalconfig/editcard'
import asyncComponent from '@/utils/asyncComponent'
import { SearchItems } from '@/templates/modalconfig/source'
import MKEmitter from '@/utils/events.js'
import './index.scss'
const { Panel } = Collapse
const { confirm } = Modal
const CommonDict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
const EditComponent = asyncComponent(() => import('@/templates/zshare/editcomponent'))
const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
const PasteForms = asyncComponent(() => import('@/menu/components/share/pasteforms'))
const DragElement = asyncComponent(() => import('@/templates/modalconfig/dragelement'))
const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
class ComModalConfig extends Component {
  static propTpyes = {
@@ -36,26 +33,16 @@
  }
  state = {
    menu: null,            // 上级菜单,三级菜单或标签
    dict: CommonDict,      // 字典
    config: null,          // 页面配置,包括模板类型、模态框设置、添加表名、表单列表
    visible: false,        // 表单编辑模态框,显示控制
    tableVisible: false,   // 数据表字段列表模态框,显示控制
    tableColumns: [],      // 表格字段名列表
    fields: null,          // 表单,可选字段(去重后)
    formlist: null,        // 表单编辑模态框,可编辑字段
    card: null,            // 编辑元素
    closeloading: false,   // 菜单保存中
    settingVisible: false, // 全局配置模态框
    closeVisible: false,   // 关闭模态框
    tables: [],            // 可用表名
    selectedTables: [],    // 已选表名
    originConfig: null,    // 原始菜单
    groupVisible: false,   // 全局配置模态框
    curgroup: null,        // 当前组,新建或编辑
    sources: null,         // 表单类型
    sqlVerifing: false,    // sql验证
    openEdition: ''        // 编辑版本标记,防止多人操作
    showField: false,      // 显示表单字段值
    standardform: null,
    saving: false
  }
  /**
@@ -65,6 +52,7 @@
    const { btn } = this.props
    let _config = btn.modal
    _config.version = '1.0'
    this.setState({
      config: _config,
@@ -72,13 +60,9 @@
    })
  }
  /**
   * @description 获取数据表信息
   * 1、获取系统中全部表名
   * 2、根据已选表名,获取表格字段列表
   */
  componentDidMount () {
    MKEmitter.addListener('completeSave', this.completeSave)
    MKEmitter.addListener('submitStyle', this.getStyle)
  }
  /**
@@ -88,6 +72,8 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('completeSave', this.completeSave)
    MKEmitter.removeListener('submitStyle', this.getStyle)
  }
  /**
@@ -96,78 +82,20 @@
   * 2、表单移动后,保存移动后的顺序
   * 3、新增表单时,直接打开编辑框
   */
  handleList = (list, group, elementId, newcard) => {
  handleList = (list, newcard) => {
    let _config = fromJS(this.state.config).toJS()
    if (!group && !elementId) {
      // 没有分组时(拖拽添加)
      if (list.length > _config.fields.length) {
        _config.fields = list.filter(item => !item.origin)
        this.setState({
          config: _config
        }, () => {
          this.handleForm(newcard)
        })
      } else {
        _config.fields = list
        this.setState({config: _config})
      }
    } else if (group && !elementId) {
      // 存在分组时,拖拽添加
      if (list.length > group.sublist.length) {
        group.sublist = list
        _config.groups = _config.groups.map(item => {
          if (item.uuid === group.uuid) {
            return group
          } else {
            return item
          }
        })
        this.setState({
          config: _config
        }, () => {
          this.handleForm(newcard)
        })
      } else {
        group.sublist = list
        _config.groups = _config.groups.map(item => {
          if (item.uuid === group.uuid) {
            return group
          } else {
            return item
          }
        })
        this.setState({config: _config})
      }
    } else if (group && elementId) {
      // 修改已有元素的分组
      let element = null
      _config.groups.forEach(item => {
        item.sublist = item.sublist.filter(cell => {
          if (cell.uuid !== elementId) {
            return true
          } else {
            element = cell
            return false
          }
        })
      })
      group.sublist.push(element)
      _config.groups = _config.groups.map(item => {
        if (item.uuid === group.uuid) {
          return group
        } else {
          return item
        }
      })
    if (list.length > _config.fields.length) {
      _config.fields = list
      this.setState({
        config: _config
      }, () => {
        this.handleForm(newcard)
      })
    } else {
      _config.fields = list
      this.setState({config: _config})
    }
  }
@@ -178,56 +106,79 @@
   * 3、设置编辑参数项-formlist
   */
  handleForm = (_card) => {
    const { componentConfig } = this.props
    const { componentConfig, btn } = this.props
    const { config } = this.state
    let card = fromJS(_card).toJS()
    let _inputfields = []
    let _tabfields = []
    let _linkableFields = []
    let _linksupFields = [{
      value: '',
      text: '空'
    }]
    let _formfields = []
    // 设置下拉菜单可关联字段(上级与下级)
    if (config.groups.length > 0) {
      config.groups.forEach(group => {
        _formfields = [..._formfields, ...group.sublist]
      })
    } else {
      _formfields = config.fields
    }
    _inputfields = _formfields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color')
    _tabfields = _formfields.filter(item => card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type))
    _tabfields.unshift({field: '', text: '原表单'})
    let _linksupFields = []
    let standardform = null
    let uniq = new Map()
    let index = null
    uniq.set(card.field, true)
    _formfields.forEach(item => {
      if (item.type !== 'select' && item.type !== 'link' && item.type !== 'radio') return
    config.fields.forEach((item, i) => {
      if (card.uuid === item.uuid) {
        index = i
      }
      if (['text', 'number', 'textarea', 'color'].includes(item.type) && card.field !== item.field) {
        _inputfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (card.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
        _tabfields.push({
          field: item.field,
          label: item.label
        })
      }
      if (item.type === 'switch' || item.type === 'check') {
        _linksupFields.push({
          field: item.field,
          label: item.label
        })
      }
      if (!['select', 'link', 'radio', 'checkcard'].includes(item.type)) return
      if (item.type === 'checkcard' && item.multiple === 'true') return // 选项卡多选
      if (item.field && !uniq.has(item.field)) {
        uniq.set(item.field, true)
        _linkableFields.push({
          value: item.field,
          text: item.label + ' (表单)'
          field: item.field,
          label: item.label + '-表单'
        })
        _linksupFields.push({
          value: item.field,
          text: item.label
          field: item.field,
          label: item.label
        })
      }
    })
    if (index !== null) {
      if (index === 0) {
        standardform = config.fields[index + 1] || null
      } else {
        standardform = config.fields[index - 1] || null
      }
    }
    componentConfig.columns.forEach(col => {
    let columns = componentConfig.columns
    if (btn.$sub) {
      columns = componentConfig.subColumns || []
    }
    columns.forEach(col => {
      if (col.field && !uniq.has(col.field)) {
        uniq.set(col.field, true)
        _linkableFields.push({
          value: col.field,
          text: col.label + ' (显示列)'
          field: col.field,
          label: col.label + '-显示列'
        })
      }
    })
@@ -237,10 +188,37 @@
      card.linkSubField = card.linkSubField.filter(item => fields.includes(item))
    }
    if (!card.span && standardform && standardform.span) {
      card.span = standardform.span
      card.labelwidth = standardform.labelwidth
    } else if (!card.span) {
      card.span = 12
      card.labelwidth = 33.3
    }
    this.setState({
      standardform,
      visible: true,
      card: card,
      formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields, !!this.props.editTab)
      formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields, columns)
    })
  }
  getStyle = (comIds, style) => {
    const { config } = this.state
    if (comIds[0] !== 'form') return
    let Index = config.fields.findIndex(n => n.uuid === comIds[1])
    if (Index === -1) return
    let _config = fromJS(config).toJS()
    _config.fields[Index].style = style
    this.setState({
      config: _config
    })
  }
@@ -254,39 +232,23 @@
    this.formRef.handleConfirm().then(res => {
      let _config = fromJS(this.state.config).toJS()
      let fieldrepet = false // 字段重复
      let labelrepet = false // 提示文字重复
      if (_config.groups.length > 0) {
        _config.groups.forEach(group => {
          group.sublist = group.sublist.map(item => {
            if (item.uuid !== res.uuid && item.field.toLowerCase() === res.field.toLowerCase()) {
              fieldrepet = true
            } else if (item.uuid !== res.uuid && item.label === res.label) {
              labelrepet = true
            }
      _config.fields = _config.fields.map(item => {
        if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
          fieldrepet = true
        }
            if (item.uuid === res.uuid) {
              return res
            } else {
              return item
            }
          })
        })
      } else {
        _config.fields = _config.fields.map(item => {
          if (item.uuid !== res.uuid && item.field.toLowerCase() === res.field.toLowerCase()) {
            fieldrepet = true
          } else if (item.uuid !== res.uuid && item.label === res.label) {
            labelrepet = true
        delete item.focus
        if (item.uuid === res.uuid) {
          if (item.style) {
            res.style = item.style
          }
          if (item.uuid === res.uuid) {
            return res
          } else {
            return item
          }
        })
      }
          return res
        } else {
          return item
        }
      })
      if (fieldrepet) {
        notification.warning({
@@ -295,18 +257,11 @@
          duration: 10
        })
        return
      } else if (labelrepet) {
        notification.warning({
          top: 92,
          message: '名称已存在!',
          duration: 10
        })
        return
      }
      _config.fields = _config.fields.filter(item => !item.origin)
      window.GLOB.formId = res.uuid
      if ((res.type === 'select' || res.type === 'multiselect' || res.type === 'link') && res.resourceType === '1' && /\s/.test(res.dataSource)) {
      if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) {
        this.setState({
          sqlVerifing: true
        })
@@ -314,20 +269,22 @@
        let param = {
          func: 's_debug_sql',
          exec_type: 'y',
          LText: res.dataSource
          LText: `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)
            ${res.dataSource}`
        }
        param.LText = param.LText.replace(/@\$|\$@/ig, '')
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
        param.LText = param.LText.replace(/\n/g, ' ')
        
        param.LText = Utils.formatOptions(param.LText)
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        param.secretkey = Utils.encrypt('', param.timestamp)
        if (window.GLOB.mainSystemApi && res.database === 'sso') {
          param.rduri = window.GLOB.mainSystemApi
        }
        
        Api.getLocalConfig(param).then(result => {
        Api.genericInterface(param).then(result => {
          if (result.status) {
            this.setState({
              sqlVerifing: false,
@@ -360,17 +317,10 @@
    let _this = this
    confirm({
      content: `确定删除<<${card.label}>>吗?`,
      content: `确定删除${card.label ? `<<${card.label}>>` : ''}吗?`,
      onOk() {
        let _config = fromJS(_this.state.config).toJS()
        if (_config.groups.length > 0) {
          _config.groups.forEach(group => {
            group.sublist = group.sublist.filter(item => !(item.uuid === card.uuid))
          })
        } else {
          _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid))
        }
        _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid))
        _this.setState({
          config: _config,
@@ -383,186 +333,46 @@
  submitConfig = () => {
    const { config } = this.state
    this.setState({originConfig: fromJS(config).toJS(), saving: true})
    this.props.handleSave(config)
    setTimeout(() => {
      MKEmitter.emit('triggerMenuSave')
    }, 100)
  }
  clearConfig = () => {
    const _this = this
    let _config = {...this.state.config, fields: []}
    confirm({
      content: '确定清空表单吗?',
      onOk() {
        _this.setState({ config: _config })
      },
      onCancel() {}
    })
  }
  completeSave = () => {
    this.setState({saving: false})
  }
  cancelConfig = () => {
    const { config, originConfig } = this.state
    if (!is(fromJS(config), fromJS(originConfig))) {
      this.setState({
        closeVisible: true
      let _this = this
      confirm({
        content: '配置信息未保存,确定返回吗?',
        onOk() {
          _this.props.handleBack()
        },
        onCancel() {}
      })
    } else {
      this.props.handleBack()
    }
  }
  /**
   * @description 通过表字段添加表单
   * 1、检查是否已选表名,为选时警告提示
   * 2、表字段名通过map去重
   * 3、检查表单中的已选字段,并标记已选
   */
  queryField = () => {
    const { config } = this.state
    if (window.GLOB.tableFields.length === 0) {
      notification.warning({
        top: 92,
        message: '请选择表名!',
        duration: 10
      })
      return
    }
    let columns = new Map()
    window.GLOB.tableFields.forEach(table => {
      table.columns.forEach(column => {
        columns.set(column.field, column)
      })
    })
    if (config.groups.length > 1) {
      config.groups.forEach(group => {
        group.sublist.forEach(item => {
          if (columns.has(item.field)) {
            columns.set(item.field, {...item, selected: true})
          }
        })
      })
    } else {
      config.fields.forEach(item => {
        if (columns.has(item.field)) {
          columns.set(item.field, {...item, selected: true})
        }
      })
    }
    this.setState({
      tableVisible: true,
      fields: [...columns.values()]
    })
  }
  /**
   * @description 选择字段后提交
   * 1、没有可选字段时,直接关闭
   * 2、获取已选字段
   * 3、与已有字段对比
   * 4、添加新增字段
   */
  addFieldSubmit = () => {
    if (!this.state.fields || this.state.fields.length === 0) {
      this.setState({
        tableVisible: false
      })
    }
    let _config = fromJS(this.state.config).toJS()
    let cards = this.refs.searchcard.state.selectCards
    let columns = new Map()
    cards.forEach(card => {
      columns.set(card.field, card)
    })
    if (_config.groups.length > 1) {
      _config.groups.forEach(group => {
        let items = []
        group.sublist.forEach(item => {
          if (columns.has(item.field)) {
            let cell = columns.get(item.field)
            if (cell.selected && cell.type === item.type) { // 数据选择状态及类型未修改时,直接添加
              items.push(item)
            } else if (cell.selected) {                     // 数据类型修改时,重置类型及初始值
              item.type = cell.type
              item.initval = ''
              items.push(item)
            }
            columns.delete(item.field)
          } else if (!item.origin) {                        // 过滤示例项
            items.push(item)
          }
        })
        group.sublist = items
      })
      let _columns = [...columns.values()]
      let _additems = _columns.map(item => { // 循环添加新增字段
        return {
          uuid: Utils.getuuid(),
          label: item.label,
          field: item.field,
          initval: '',
          type: item.type,
          resourceType: '0',
          setAll: 'false',
          options: [],
          orderType: 'asc',
          decimal: 0,
          min: '',
          max: '',
          readonly: 'false',
          required: 'true'
        }
      })
      _config.groups[_config.groups.length - 1].sublist = [..._config.groups.slice(-1)[0].sublist, ..._additems]
    } else {
      let items = []
      _config.fields.forEach(item => {
        if (columns.has(item.field)) {
          let cell = columns.get(item.field)
          if (cell.selected && cell.type === item.type) { // 数据选择状态及类型未修改时,直接添加
            items.push(item)
          } else if (cell.selected) {                     // 数据类型修改时,重置类型及初始值
            item.type = cell.type
            item.initval = ''
            items.push(item)
          }
          columns.delete(item.field)
        } else if (!item.origin) {                        // 过滤示例项
          items.push(item)
        }
      })
      let _columns = [...columns.values()]
      _columns.forEach(item => { // 循环添加新增字段
        if (item.selected) {
          let newcard = {
            uuid: Utils.getuuid(),
            label: item.label,
            field: item.field,
            initval: '',
            type: item.type,
            resourceType: '0',
            setAll: 'false',
            options: [],
            orderType: 'asc',
            readonly: 'false',
            required: 'true'
          }
          items.push(newcard)
        }
      })
      _config.fields = items
    }
    this.setState({
      config: _config
    })
    notification.success({
      top: 92,
      message: '添加成功',
      duration: 2
    })
  }
  /**
@@ -587,115 +397,12 @@
    })
  }
  handleGroup = (group) => {
    let curgroup = ''
    if (group) {
      curgroup = group
    } else {
      curgroup = {
        isnew: true,
        label: '',
        default: false,
        uuid: Utils.getuuid(),
        sublist: []
      }
    }
    this.setState({
      groupVisible: true,
      curgroup: curgroup
    })
  }
  closeGroup = (group) => {
    let _this = this
    confirm({
      content: `确定删除分组<<${group.label}>>吗?`,
      onOk() {
        let _config = fromJS(_this.state.config).toJS()
        _config.groups = _config.groups.filter(item => !(item.uuid === group.uuid))
        let _length = _config.groups.length
        if (_length === 1) {
          _config.fields = [...group.sublist, ..._config.groups[0].sublist]
          _config.groups = []
        } else {
          _config.groups[_length - 1].sublist = [...group.sublist, ..._config.groups[_length - 1].sublist]
        }
        _this.setState({
          config: _config
        })
      },
      onCancel() {}
    })
  }
  handleGroupSave = () => {
    let _group = fromJS(this.state.curgroup).toJS()
    let config = fromJS(this.state.config).toJS()
    this.groupRef.handleConfirm().then(res => {
      _group = {..._group, ...res.target}
      if (_group.isnew) {
        delete _group.isnew
        config.groups.unshift(_group)
        if (config.groups.length > 1) {
          config.groups = config.groups.map(item => {
            if (item.default) {
              return res.default
            } else {
              return item
            }
          })
        } else {
          config.groups.push(res.default)
        }
      } else {
        config.groups = config.groups.map(item => {
          if (item.uuid === _group.uuid) {
            return _group
          } else if (item.default) {
            return res.default
          } else {
            return item
          }
        })
      }
      config.fields = []
      config.groups = config.groups.sort((a, b) => {
        return a.sort - b.sort
      })
      this.setState({
        groupVisible: false,
        curgroup: '',
        config: config
      })
    })
  }
  editModalCancel = () => {
    const { config, card } = this.state
    if (card.focus) {
      let _config = null
      if (config.groups.length > 0) {
        let _groups = config.groups.map(group => {
          group.sublist = group.sublist.filter(item => item.uuid !== card.uuid)
          return group
        })
        _config = {...config, groups: _groups}
      } else {
        let _fields = config.fields.filter(item => item.uuid !== card.uuid)
        _config = {...config, fields: _fields}
      }
      let _fields = config.fields.filter(item => item.uuid !== card.uuid)
      let _config = {...config, fields: _fields}
      this.setState({
        card: null,
@@ -711,100 +418,162 @@
  }
  /**
   * @description 编辑功能完成更新,包括解冻按钮、粘贴、替换等
   * @description 更新
   */
  updateConfig = (res) => {
    if (res.type === 'paste') {
      this.setState({
        config: res.config
      })
  updateConfig = (config) => {
    this.setState({
      config
    })
  }
  changecols = (type) => {
    let config = fromJS(this.state.config).toJS()
    let _this = this
    config.fields = config.fields.map(item => {
      item.labelwidth = 33.3
      item.span = 24
      if (['textarea','split','hint','checkcard','brafteditor'].includes(item.type)) {
        if (type === 2) {
          item.labelwidth = 16.3
        } else if (type === 3) {
          item.labelwidth = 10.5
        } else if (type === 4) {
          item.labelwidth = 8.3
        }
      } else if (type === 2) {
        item.span = 12
      } else if (type === 3) {
        item.span = 8
      } else if (type === 4) {
        item.span = 6
      }
      return item
    })
    confirm({
      content: `确定切换为${type}列吗?`,
      onOk() {
        _this.setState({config})
      },
      onCancel() {}
    })
  }
  plusFields = (items) => {
    let _config = fromJS(this.state.config).toJS()
    _config.fields.push(...items)
    this.setState({
      config: _config
    }, () => {
      if (items.length === 1 && items[0].focus) {
        this.handleForm(items[0])
      }
    })
  }
  pasteFields = (items) => {
    let _config = fromJS(this.state.config).toJS()
    _config.fields = items
    this.setState({
      config: _config
    })
  }
  triggerCopy = () => {
    const { config } = this.state
    let val = {
      copyType: 'forms',
      fields: config.fields || []
    }
    if (val.fields.length === 0) {
      message.warning('表单元素不可为空!')
      return
    }
    try {
      val = window.btoa(window.encodeURIComponent(JSON.stringify(val)))
    } catch (e) {
      console.warn(e)
      message.warning('复制失败,请重试!')
      val = ''
    }
    if (val) {
      let oInput = document.createElement('input')
      oInput.value = val
      document.body.appendChild(oInput)
      oInput.select()
      document.execCommand('Copy')
      document.body.removeChild(oInput)
      message.success('复制成功。')
    }
  }
  render () {
    const { config } = this.state
    const { btn } = this.props
    const { config, saving, card } = this.state
    return (
      <div className="modal-form-board">
        <DndProvider backend={HTML5Backend}>
          <div className="tools">
            <Collapse accordion defaultActiveKey="1" bordered={false}>
              <Panel header={this.state.dict['header.menu.form']} key="1">
              <Panel header="表单" key="1">
                <div className="search-element">
                  {SearchItems.map((item, index) => {
                    return (<SourceElement key={index} content={item}/>)
                  })}
                </div>
                <Button type="primary" block onClick={() => this.queryField()}>{this.state.dict['model.batchAdd']}</Button>
                <Button type="primary" block onClick={() => this.handleGroup()}>{this.state.dict['header.menu.group.add']}</Button>
                <FieldsComponent config={config} type="form" plusFields={this.plusFields}/>
              </Panel>
            </Collapse>
          </div>
          <div className="setting">
            <Card title={this.state.dict['header.menu.form.configurable']} bordered={false} extra={
            <Card title="表单配置" bordered={false} extra={
              <div>
                <EditComponent dict={this.state.dict} options={['form']} config={this.state.config} refresh={this.updateConfig}/>
                <Button type="primary" onClick={this.submitConfig}>{this.state.dict['model.confirm']}</Button>
                <Button onClick={this.cancelConfig}>{this.state.dict['model.cancel']}</Button>
                <Button type="danger" onClick={this.clearConfig}>清空</Button>
                <PasteForms type="toolbar" config={config} update={this.pasteFields}/>
                <Button type="primary" id="save-modal-config" loading={saving} onClick={this.submitConfig}>保存</Button>
                <Button onClick={this.cancelConfig}>返回</Button>
              </div>
            } style={{ width: '100%' }}>
              <Icon type="setting" onClick={this.changeSetting} />
              <div className="ant-modal-content" style={{width: config.setting.width + '%'}}>
                <button type="button" className="ant-modal-close">
                  <span className="ant-modal-close-x"><Icon type="close"/></span>
                </button>
              <SettingOutlined onClick={this.changeSetting} />
              <div className="ant-modal-content" style={{width: config.setting.width > 100 ? config.setting.width : config.setting.width + '%'}}>
                <div className="ant-modal-header">
                  <div className="ant-modal-title">{config.setting.title}</div>
                  <div className="ant-modal-title">{btn.label}</div>
                  <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1列</Button>
                  <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2列</Button>
                  <Button className="mk-cols-change" onClick={() => this.changecols(3)}>3列</Button>
                  <Button className="mk-cols-change" onClick={() => this.changecols(4)}>4列</Button>
                  <CopyOutlined title="复制" onClick={this.triggerCopy} />
                  <Switch checkedChildren="开" unCheckedChildren="关" defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
                </div>
                <div className="ant-modal-body">
                  <div className="modal-form">
                    {config.groups.length > 0 &&
                      config.groups.map(group => {
                        return (
                          <div key={group.uuid}>
                            <div className="group-title">
                              {!group.default ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
                                <div className="mk-popover-control">
                                  <Icon className="edit" type="edit" onClick={() => {this.handleGroup(group)}} />
                                  <Icon className="edit close" type="close" onClick={() => {this.closeGroup(group)}} />
                                </div>
                              } trigger="hover">
                                <span>{group.label}</span>
                              </Popover> : null}
                              {group.default ? <span style={{color: '#bcbcbc'}}>{group.label}</span> : null}
                            </div>
                            <DragElement
                              group={group}
                              list={group.sublist}
                              setting={config.setting}
                              placeholder={this.state.dict['header.form.modal.placeholder']}
                              handleList={this.handleList}
                              handleForm={this.handleForm}
                              closeForm={this.closeForm}
                            />
                          </div>
                        )
                      })
                    }
                    {config.groups.length === 0 ?
                      <DragElement
                        list={config.fields}
                        setting={config.setting}
                        placeholder={this.state.dict['header.form.modal.placeholder']}
                        handleList={this.handleList}
                        handleForm={this.handleForm}
                        closeForm={this.closeForm}
                      /> : null
                    }
                    <DragElement
                      list={config.fields}
                      setting={config.setting}
                      showField={this.state.showField}
                      handleList={this.handleList}
                      handleForm={this.handleForm}
                      closeForm={this.closeForm}
                    />
                  </div>
                </div>
                <div className="ant-modal-footer">
                  <div>
                    <button type="button" className="ant-btn">
                      <span>{this.state.dict['model.cancel']}</span>
                      <span>取消</span>
                    </button>
                    <button type="button" className="ant-btn ant-btn-primary">
                      <span>{this.state.dict['model.confirm']}</span>
                      <span>确定</span>
                    </button>
                  </div>
                  <div className="action-mask"></div>
@@ -814,45 +583,27 @@
          </div>
        </DndProvider>
        <Modal
          title={this.state.dict['model.edit']}
          title={card && card.$copy ? '复制' : '编辑'}
          visible={this.state.visible}
          width={850}
          width={950}
          maskClosable={false}
          onCancel={this.editModalCancel}
          onOk={this.handleSubmit}
          confirmLoading={this.state.sqlVerifing}
          destroyOnClose
        >
          <ModalForm
            dict={this.state.dict}
            card={this.state.card}
            card={card}
            formlist={this.state.formlist}
            inputSubmit={this.handleSubmit}
            standardform={this.state.standardform}
            wrappedComponentRef={(inst) => this.formRef = inst}
          />
        </Modal>
        <Modal
          wrapClassName="modal-fields"
          title={this.state.dict['model.edit']}
          visible={this.state.tableVisible}
          width={'65vw'}
          maskClosable={false}
          style={{minWidth: '900px', maxWidth: '1200px'}}
          onOk={this.addFieldSubmit}
          cancelText={this.state.dict['model.close']}
          onCancel={() => { this.setState({ tableVisible: false }) }}
          destroyOnClose
        >
          {this.state.fields && this.state.fields.length > 0 ?
            <EditCard data={this.state.fields} ref="searchcard" type="search" /> : null
          }
          {(!this.state.fields || this.state.fields.length === 0) &&
            <Empty />
          }
        </Modal>
        <Modal
          title={this.state.dict['model.edit']}
          title="编辑"
          visible={this.state.settingVisible}
          width={700}
          width={850}
          maskClosable={false}
          onOk={this.settingSave}
          onCancel={() => { this.setState({ settingVisible: false }) }}
@@ -860,42 +611,9 @@
        >
          <SettingForm
            config={config}
            dict={this.state.dict}
            isSubTab={!!this.props.editTab}
            inputSubmit={this.settingSave}
            wrappedComponentRef={(inst) => this.settingRef = inst}
          />
        </Modal>
        <Modal
          bodyStyle={{textAlign: 'center', color: '#000000', fontSize: '16px'}}
          closable={false}
          maskClosable={false}
          visible={this.state.closeVisible}
          onCancel={() => { this.setState({closeVisible: false}) }}
          footer={[
            <Button key="save" className="mk-btn mk-green" loading={this.state.closeloading} onClick={this.submitConfig}>{this.state.dict['model.save']}</Button>,
            <Button key="confirm" className="mk-btn mk-yellow" onClick={this.props.handleBack}>{this.state.dict['model.notsave']}</Button>,
            <Button key="cancel" onClick={() => { this.setState({closeVisible: false}) }}>{this.state.dict['model.cancel']}</Button>
          ]}
          destroyOnClose
        >
          {this.state.dict['header.menu.config.placeholder']}
        </Modal>
        <Modal
          title={this.state.dict['header.menu.group.manage']}
          visible={this.state.groupVisible}
          width={700}
          maskClosable={false}
          onOk={this.handleGroupSave}
          onCancel={() => { this.setState({ groupVisible: false }) }}
          destroyOnClose
        >
          <GroupForm
            config={config}
            dict={this.state.dict}
            group={this.state.curgroup}
            inputSubmit={this.handleGroupSave}
            wrappedComponentRef={(inst) => this.groupRef = inst}
          />
        </Modal>
      </div>
@@ -903,14 +621,4 @@
  }
}
const mapStateToProps = (state) => {
  return {
    menu: state.customMenu
  }
}
const mapDispatchToProps = () => {
  return {}
}
export default connect(mapStateToProps, mapDispatchToProps)(ComModalConfig)
export default ComModalConfig