king
2023-07-03 902ee517e0a3223ff2543924abe12df77376fb81
2023-07-03
13个文件已修改
5个文件已添加
1935 ■■■■■ 已修改文件
src/api/index.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tabview/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/calendar/index.jsx 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/calendar/index.scss 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/calendar/options.jsx 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/actionform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/options.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modulesource/option.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/tabs/antv-tabs/index.jsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/popview/index.jsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/newpagebutton/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/updatetable/index.jsx 135 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/treepageconfig/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/treepageconfig/updatetable/index.jsx 1227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/treepageconfig/updatetable/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editTable/index.jsx 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js
@@ -42,6 +42,7 @@
      Modal.destroyAll()
      Modal.error({
        title: response.data.message,
        okText: '知道了',
        onOk: () => {
          window.GLOB.$error = false
          sessionStorage.clear()
src/components/tabview/index.jsx
@@ -22,6 +22,7 @@
const Iframe = asyncComponent(() => import('@/tabviews/iframe'))
const RoleManage = asyncComponent(() => import('@/tabviews/rolemanage'))
const FormTab = asyncComponent(() => import('@/tabviews/formtab'))
// const Calendar = asyncComponent(() => import('@/tabviews/calendar'))
class TabViews extends Component {
  static propTpyes = {
@@ -210,6 +211,7 @@
    } else if (view.type === 'iframe') {
      return (<Iframe MenuID={view.MenuID} title={view.MenuName} url={view.src}/>)
    } else {
      // return (<Calendar MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} param={view.param}/>)
      return (<NotFount />)
    }
  }
src/menu/components/calendar/index.jsx
New file
@@ -0,0 +1,187 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, message } from 'antd'
import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import getWrapForm from './options'
import './index.scss'
const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
class NormalCalendarComponent extends Component {
  static propTpyes = {
    card: PropTypes.object,
    deletecomponent: PropTypes.func,
    updateConfig: PropTypes.func,
  }
  state = {
    card: null
  }
  UNSAFE_componentWillMount () {
    const { card } = this.props
    if (card.isNew) {
      let _card = {
        uuid: card.uuid,
        type: card.type,
        format: 'array',    // 组件属性 - 数据格式
        pageable: false,    // 组件属性 - 是否可分页
        switchable: false,  // 组件属性 - 数据是否可切换
        width: card.width || 24,
        name: card.name,
        subtype: card.subtype,
        setting: { interType: 'system' },
        wrap: { title: '', name: card.name, width: card.width || 24 },
        style: { marginLeft: '0px', marginRight: '0px', marginTop: '0px', marginBottom: '0px' },
        headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
        columns: [],
        scripts: [],
      }
      if (card.config) {
        let config = fromJS(card.config).toJS()
        _card.wrap = config.wrap
        _card.wrap.name = card.name
        _card.style = config.style
        _card.setting = config.setting
        _card.columns = config.columns
        _card.scripts = config.scripts
      }
      this.updateComponent(_card)
    } else {
      this.setState({
        card: fromJS(card).toJS()
      })
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
  }
  /**
   * @description 卡片行外层信息更新(数据源,样式等)
   */
  updateComponent = (card) => {
    card.width = card.wrap.width
    card.name = card.wrap.name
    if (!window.GLOB.styling || !card.errors) { // 样式修改时不做筛查
      card.$c_ds = true
      card.$c_sc = true
      card.errors = checkComponent(card)
      if (card.errors.length === 0) {
        card.$tables = getTables(card)
      }
    }
    this.setState({
      card: card
    })
    this.props.updateConfig(card)
  }
  changeStyle = () => {
    const { card } = this.state
    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear', 'minHeight'], card.style, this.getStyle)
  }
  getStyle = (style) => {
    let _card = {...this.state.card, style}
    this.updateComponent(_card)
  }
  getWrapForms = () => {
    const { card } = this.state
    return getWrapForm(card.wrap, card.columns)
  }
  updateWrap = (res) => {
    delete res.quick
    if (res.hmode) {
      res.mode = res.hmode
      delete res.hmode
    }
    this.updateComponent({...this.state.card, wrap: res})
  }
  render() {
    const { card } = this.state
    let _style = resetStyle(card.style)
    return (
      <div className="menu-calendar-edit-box" style={_style} id={card.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <NormalForm title="日历设置" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="calendar" card={card}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <UserComponent config={card}/>
            <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)} />
            <SettingComponent config={card} updateConfig={this.updateComponent} />
          </div>
        } trigger="hover">
          <ToolOutlined />
        </Popover>
        <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
        <div className="component-name">
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
              document.body.removeChild(oInput)
              message.success('复制成功。')
            }}>{card.name}</div>
            <div className="content">
              {card.errors && card.errors.map((err, index) => {
                if (err.level === 0) {
                  return <span key={index} className="error">{err.detail}</span>
                } else {
                  return <span key={index} className="waring">{err.detail};</span>
                }
              })}
            </div>
          </div>
        </div>
      </div>
    )
  }
}
export default NormalCalendarComponent
src/menu/components/calendar/index.scss
New file
@@ -0,0 +1,53 @@
.menu-calendar-edit-box {
  position: relative;
  box-sizing: border-box;
  background: #ffffff;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 50px;
  .model-menu-card-cell-list {
    flex: 1;
  }
  >.anticon-tool {
    position: absolute;
    z-index: 2;
    font-size: 16px;
    right: 1px;
    top: 1px;
    cursor: pointer;
    padding: 5px;
    background: rgba(255, 255, 255, 0.55);
  }
  .card-item {
    overflow: hidden;
    position: relative;
    background-color: #ffffff;
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
    min-height: 20px;
  }
  .card-item:hover {
    box-shadow: 0px 0px 2px #1890ff;
  }
  .model-menu-card-cell-list .card-detail-row > .anticon-plus {
    position: absolute;
    right: -30px;
    font-size: 16px;
  }
}
.menu-calendar-edit-box::after {
  display: block;
  content: ' ';
  clear: both;
}
.menu-calendar-edit-box:hover {
  z-index: 1;
  box-shadow: 0px 0px 4px #1890ff;
}
src/menu/components/calendar/options.jsx
New file
@@ -0,0 +1,201 @@
/**
 * @description Wrap表单配置信息
 */
export default function (wrap, columns) {
  let roleList = sessionStorage.getItem('sysRoles')
  let appType = sessionStorage.getItem('appType')
  if (roleList) {
    try {
      roleList = JSON.parse(roleList)
    } catch (e) {
      roleList = []
    }
  } else {
    roleList = []
  }
  const balconyWrapForm = [
    {
      type: 'text',
      field: 'title',
      label: '标题',
      initval: wrap.title || '',
      required: false
    },
    {
      type: 'text',
      field: 'name',
      label: '组件名称',
      initval: wrap.name || '',
      tooltip: '用于组件间的区分。',
      required: true
    },
    {
      type: 'number',
      field: 'width',
      label: '宽度',
      initval: wrap.width || 24,
      tooltip: '栅格布局,每行等分为24列。',
      min: 1,
      max: 24,
      precision: 0,
      required: true
    },
    {
      type: 'radio',
      field: 'direction',
      label: '轴线方向',
      initval: wrap.direction || 'vertical',
      required: false,
      options: [
        {value: 'vertical', label: '纵向'},
        {value: 'horizontal', label: '横向'},
      ],
      controlFields: [
        {field: 'mode', values: ['vertical']},
        {field: 'hmode', values: ['horizontal']},
        {field: 'label', values: ['vertical']},
        {field: 'iconSize', values: ['horizontal']},
        {field: 'dotSign', values: ['horizontal']},
      ]
    },
    {
      type: 'radio',
      field: 'mode',
      label: '轴线位置',
      initval: ['left', 'alternate', 'right'].includes(wrap.mode) ? wrap.mode : 'left',
      required: false,
      options: [
        {value: 'left', label: '左侧'},
        {value: 'alternate', label: '中间'},
        {value: 'right', label: '右侧'},
      ]
    },
    {
      type: 'radio',
      field: 'hmode',
      label: '轴线位置',
      initval: ['up', 'down'].includes(wrap.mode) ? wrap.mode : 'up',
      required: false,
      options: [
        {value: 'up', label: '上侧'},
        {value: 'down', label: '下侧'}
      ]
    },
    // {
    //   type: 'radio',
    //   field: 'reverse',
    //   label: '排序',
    //   initval: wrap.reverse || 'false',
    //   required: false,
    //   options: [
    //     {value: 'false', label: '正序'},
    //     {value: 'true', label: '倒序'},
    //   ]
    // },
    {
      type: 'color',
      field: 'color',
      label: '节点颜色',
      initval: wrap.color || '#1890ff',
      tooltip: '节点默认颜色。',
      required: false
    },
    {
      type: 'radio',
      field: 'line',
      label: '连线颜色',
      initval: wrap.line || '',
      required: false,
      options: [
        {value: '', label: '默认'},
        {value: 'system', label: '系统色'},
      ]
    },
    {
      type: 'radio',
      field: 'dotSign',
      label: '节点渲染',
      initval: wrap.dotSign || 'background',
      tooltip: '节点的渲染方式,在节点组中设置的颜色渲染图标还是渲染背景色。',
      required: false,
      options: [
        {value: 'background', label: '背景色'},
        {value: 'icon', label: '图标'},
      ]
    },
    {
      type: 'select',
      field: 'iconSize',
      label: '图标大小',
      initval: wrap.iconSize || '',
      tooltip: '图标可在节点组中添加。',
      required: false,
      options: [
        {value: '', label: '默认(14px)'},
        {value: 'size16', label: '16px'},
        {value: 'size18', label: '18px'},
        {value: 'size20', label: '20px'},
        {value: 'size22', label: '22px'},
        {value: 'size24', label: '24px'},
        {value: 'adaptive', label: '自适应'},
      ]
    },
    {
      type: 'select',
      field: 'label',
      label: '标签',
      initval: wrap.label || '',
      tooltip: '在内容对面单独展示。',
      required: false,
      options: columns,
      forbid: !appType
    },
    {
      type: 'select',
      field: 'node',
      label: '节点控制',
      initval: wrap.node || '',
      tooltip: '选择自定义节点的控制字段后,在节点组中添加节点样式。',
      required: false,
      options: columns
    },
    {
      type: 'radio',
      field: 'permission',
      label: '权限验证',
      initval: wrap.permission || (!appType ? 'true' : 'false'),
      required: false,
      options: [
        {value: 'true', label: '启用'},
        {value: 'false', label: '禁用'},
      ],
      forbid: sessionStorage.getItem('editMenuType') === 'popview'
    },
    {
      type: 'radio',
      field: 'empty',
      label: '空值隐藏',
      initval: wrap.empty || 'show',
      tooltip: '当查询数据为空时,隐藏该组件。',
      required: false,
      skip: true,
      options: [
        {value: 'show', label: '否'},
        {value: 'hidden', label: '是'},
      ],
    },
    {
      type: 'multiselect',
      field: 'blacklist',
      label: '黑名单',
      initval: wrap.blacklist || [],
      required: false,
      options: roleList,
      forbid: !!appType
    },
  ]
  return balconyWrapForm
}
src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -413,7 +413,7 @@
        reTooltip.linkmenu = ''
      } else if (this.record.pageTemplate === 'billprint') {
        shows.push('printTemp')
        reOptions.Ot = requireOptions.filter(op => ['notRequired', 'requiredSgl', 'required'].includes(op.value))
        reOptions.Ot = requireOptions
      } else if (this.record.pageTemplate === 'pay') {
        reOptions.Ot = requireOptions.filter(op => op.value === 'requiredSgl')
      }
src/menu/components/tabs/antv-tabs/options.jsx
@@ -39,7 +39,7 @@
      field: 'controlVal',
      label: '隐藏标记',
      initval: tab.controlVal || '',
      tooltip: '当禁用字段值与隐藏标记相等时,标签页会隐藏。注:多个值请用逗号分隔。',
      tooltip: '当禁用字段值与隐藏标记相等时,标签页会隐藏。注:1、多个值请用逗号分隔,2、@pass@值表示忽略此设置(始终显示),2、@pass_empty@值表示忽略空值,即未获取上级组件信息时显示(可与其他值拼接)。',
      required: false,
    },
    {
@@ -209,7 +209,7 @@
      field: 'controlField',
      label: '禁用字段',
      initval: setting.controlField || '',
      tooltip: '用于控制标签隐藏的字段,在标签中填入隐藏标记。',
      tooltip: '用于控制标签隐藏的字段,在标签中填入隐藏标记。注:树形组件中不同层级会自动生成mk_floor(层级字段1、2、3...)。',
      required: true,
    },
    {
src/menu/modulesource/option.jsx
@@ -50,6 +50,7 @@
  { type: 'menu', url: NormalTable, component: 'table', subtype: 'normaltable', title: '常用表', width: 24 },
  { type: 'menu', url: NormalTable, component: 'table', subtype: 'editable', title: '表格(可编辑)', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: timeline, component: 'timeline', subtype: 'timeline', title: '时间轴', width: 12 },
  { type: 'menu', url: timeline, component: 'calendar', subtype: 'calendar', title: '日历', width: 24 },
  { type: 'menu', url: tree, component: 'tree', subtype: 'normaltree', title: '树形列表', width: 12, forbid: ['billPrint'] },
  { type: 'menu', url: line, component: 'line', subtype: 'line', title: '折线图', width: 24 },
  { type: 'menu', url: bar, component: 'bar', subtype: 'bar', title: '柱状图', width: 24 },
src/tabviews/custom/components/tabs/antv-tabs/index.jsx
@@ -40,12 +40,15 @@
          }
        })
        _tabs.subtabs = config.subtabs.filter(tab => {
          if (tab.controlVal === val) {
            return false
          } else if (/,/ig.test(tab.controlVal)) {
            return !tab.controlVal.split(',').includes(val)
          }
          return true
          if (tab.$pass) return true
          return !tab.controlVals.includes(val)
        })
      } else {
        _tabs.subtabs = config.subtabs.filter(tab => {
          if (tab.$pass) return true
          return tab.controlVals.includes('@pass_empty@')
        })
      }
    }
@@ -90,7 +93,11 @@
    if (tabs.setting.supModule === MenuID) {
      if (!data) {
        this.setState({
          tabs: {...tabs, subtabs: []}
          tabs: {...tabs, subtabs: this.props.config.subtabs.filter(tab => {
            if (tab.$pass) return true
            return tab.controlVals.includes('@pass_empty@')
          })}
        })
      } else {
        let val = ''
@@ -101,12 +108,9 @@
        })
        this.setState({
          tabs: {...tabs, subtabs: this.props.config.subtabs.filter(tab => {
            if (tab.controlVal === val) {
              return false
            } else if (/,/ig.test(tab.controlVal)) {
              return !tab.controlVal.split(',').includes(val)
            }
            return true
            if (tab.$pass) return true
            return !tab.controlVals.includes(val)
          })}
        })
      }
src/tabviews/custom/index.jsx
@@ -359,6 +359,13 @@
          return false
        }
        if (item.setting.supModule) {
          let pid = item.setting.supModule.pop()
          item.setting.supModule = pid || ''
        } else {
          item.setting.supModule = ''
        }
        item.subtabs = item.subtabs.filter(tab => {
          if (
            tab.blacklist && tab.blacklist.length > 0 &&
@@ -368,12 +375,19 @@
          } else if (tab.hide === 'true') {
            return false
          }
          return true
        })
        if (item.setting.supModule) {
          let pid = item.setting.supModule.pop()
          item.setting.supModule = pid || ''
            if (tab.controlVal === '@pass@') {
              tab.$pass = true
            } else if (/,/ig.test(tab.controlVal)) {
              tab.controlVals = tab.controlVal.split(',')
            } else {
              tab.controlVals = [(tab.controlVal || '')]
            }
          }
          return true
        })
          if (item.setting.supModule) {
            item.setting.controlField = item.setting.controlField.toLowerCase()
@@ -388,15 +402,10 @@
              })
  
              item.subtabs = item.subtabs.filter(tab => {
                if (tab.controlVal === val) {
                  return false
                } else if (/,/ig.test(tab.controlVal)) {
                  return !tab.controlVal.split(',').includes(val)
                }
              if (tab.$pass) return true
      
                return true
              return !tab.controlVals.includes(val)
              })
            }
          }
        }
src/tabviews/custom/popview/index.jsx
@@ -201,6 +201,13 @@
          return false
        }
        if (item.setting.supModule) {
          let pid = item.setting.supModule.pop()
          item.setting.supModule = pid || ''
        } else {
          item.setting.supModule = ''
        }
        item.subtabs = item.subtabs.filter(tab => {
          if (
            tab.blacklist && tab.blacklist.length > 0 &&
@@ -210,12 +217,19 @@
          } else if (tab.hide === 'true') {
            return false
          }
          return true
        })
        if (item.setting.supModule) {
          let pid = item.setting.supModule.pop()
          item.setting.supModule = pid || ''
            if (tab.controlVal === '@pass@') {
              tab.$pass = true
            } else if (/,/ig.test(tab.controlVal)) {
              tab.controlVals = tab.controlVal.split(',')
            } else {
              tab.controlVals = [(tab.controlVal || '')]
            }
          }
          return true
        })
          if (item.setting.supModule) {
            item.setting.controlField = item.setting.controlField.toLowerCase()
@@ -230,15 +244,10 @@
              })
  
              item.subtabs = item.subtabs.filter(tab => {
                if (tab.controlVal === val) {
                  return false
                } else if (/,/ig.test(tab.controlVal)) {
                  return !tab.controlVal.split(',').includes(val)
                }
              if (tab.$pass) return true
      
                return true
              return !tab.controlVals.includes(val)
              })
            }
          }
        }
src/tabviews/zshare/actionList/newpagebutton/index.jsx
@@ -161,6 +161,10 @@
          let url = '#/billprint/' + window.btoa(window.encodeURIComponent(JSON.stringify({ id: _id, tempId: btn.printTemp, dataM: sessionStorage.getItem('dataM') })))
          window.open(url)
        })
      } else if (btn.Ot === 'requiredOnce' && data && data.length > 0) {
        Id = data.map(item => item.$$uuid).filter(Boolean).join(',')
        window.open('#/billprint/' + window.btoa(window.encodeURIComponent(JSON.stringify({ id: Id, tempId: btn.printTemp, dataM: sessionStorage.getItem('dataM') }))))
      } else {
        window.open('#/billprint/' + window.btoa(window.encodeURIComponent(JSON.stringify({ id: Id, tempId: btn.printTemp, dataM: sessionStorage.getItem('dataM') }))))
      }
src/templates/comtableconfig/updatetable/index.jsx
@@ -87,14 +87,13 @@
    let formActions = []
    let popActions = []
    let errors = []
    let formTabs = []
    let mainTb = {name: '主表', uuid: Utils.getuuid(), useMSearch: 'false', isMain: true}
    let oldtabs = {
      mainTable: mainTb.uuid
    }
    let tbl = this.getTable(config, mainTb, errors, formActions, formTabs, popActions, oldtabs)
    let tbl = this.getTable(config, mainTb, errors, formActions, popActions, oldtabs)
    if (config.autoMatic && config.autoMatic.enable === 'true') {
      if (tbl.action.filter(item => item.uuid === config.autoMatic.action && (['pop', 'prompt', 'exec'].includes(item.OpenType) || (item.OpenType === 'funcbutton' && item.funcType === 'print'))).length === 0) {
@@ -191,7 +190,7 @@
        _config.components = _config.components.map(item => {
          if (item.type === 'tabs') {
            item.subtabs = item.subtabs.map(tab => {
              tab.components[0] = this.getTable(menus[tab.components[0].linkTab], tab.components[0], errors, formActions, formTabs, popActions, oldtabs)
              tab.components[0] = this.getTable(menus[tab.components[0].linkTab], tab.components[0], errors, formActions, popActions, oldtabs)
              return tab
            })
@@ -199,14 +198,14 @@
          return item
        })
        this.setPopView(_resolve, _config, formActions, formTabs, popActions, errors)
        this.setPopView(_resolve, _config, formActions, popActions, errors)
      })
    } else {
      this.setPopView(_resolve, _config, formActions, formTabs, popActions, errors)
      this.setPopView(_resolve, _config, formActions, popActions, errors)
    }
  }
  setPopView = (_resolve, _config, formActions, formTabs, popActions, errors) => {
  setPopView = (_resolve, _config, formActions, popActions, errors) => {
    if (popActions.length > 0) {
      let defers = popActions.map((item, i) => {
        return new Promise((resolve) => {
@@ -267,7 +266,7 @@
                      MenuName: btn.label,
                      tables: _config.tables || [],
                      Template: 'BaseTable',
                      components: [this.getTable(menus[btn.uuid], mainTb, errors, formActions, formTabs)],
                      components: [this.getTable(menus[btn.uuid], mainTb, errors, formActions)],
                      viewType: 'popview',
                      style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
                    }
@@ -293,7 +292,7 @@
                        MenuName: btn.label,
                        tables: _config.tables || [],
                        Template: 'BaseTable',
                        components: [this.getTable(menus[btn.uuid], mainTb, errors, formActions, formTabs)],
                        components: [this.getTable(menus[btn.uuid], mainTb, errors, formActions)],
                        viewType: 'popview',
                        style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
                      }
@@ -319,7 +318,7 @@
                    MenuName: btn.label,
                    tables: _config.tables || [],
                    Template: 'BaseTable',
                    components: [this.getTable(menus[btn.uuid], mainTb, errors, formActions, formTabs)],
                    components: [this.getTable(menus[btn.uuid], mainTb, errors, formActions)],
                    viewType: 'popview',
                    style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
                  }
@@ -345,7 +344,7 @@
                      MenuName: btn.label,
                      tables: _config.tables || [],
                      Template: 'BaseTable',
                      components: [this.getTable(menus[btn.uuid], mainTb, errors, formActions, formTabs)],
                      components: [this.getTable(menus[btn.uuid], mainTb, errors, formActions)],
                      viewType: 'popview',
                      style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
                    }
@@ -360,10 +359,10 @@
          }
        })
        this.setPopForm(_resolve, _config, formActions, formTabs, errors)
        this.setPopForm(_resolve, _config, formActions, errors)
      })
    } else {
      this.setPopForm(_resolve, _config, formActions, formTabs, errors)
      this.setPopForm(_resolve, _config, formActions, errors)
    }
  }
@@ -386,7 +385,7 @@
    return enabled
  }
  setPopForm = (_resolve, _config, formActions, formTabs, errors) => {
  setPopForm = (_resolve, _config, formActions, errors) => {
    if (formActions.length > 0) {
      let defers = formActions.map((item, i) => {
        return new Promise((resolve) => {
@@ -512,10 +511,10 @@
          }
        })
        this.saveConfig(_resolve, _config, errors, formTabs)
        this.saveConfig(_resolve, _config, errors)
      })
    } else {
      this.saveConfig(_resolve, _config, errors, formTabs)
      this.saveConfig(_resolve, _config, errors)
    }
  }
@@ -554,7 +553,7 @@
    })
  }
  saveConfig = (_resolve, _config, errors, formTabs) => {
  saveConfig = (_resolve, _config, errors) => {
    let err = errors.join(';')
    let _this = this
@@ -565,17 +564,17 @@
        content: '',
        onOk() {
          return new Promise(resolve => {
            _this.saveNewMenu(resolve, _config, formTabs)
            _this.saveNewMenu(resolve, _config)
          })
        },
        onCancel() {}
      })
    } else {
      this.saveNewMenu(_resolve, _config, formTabs)
      this.saveNewMenu(_resolve, _config)
    }
  }
  saveNewMenu = (_resolve, _config, formTabs) => {
  saveNewMenu = (_resolve, _config) => {
    _config.components.forEach(item => {
      if (item.type === 'tabs') {
        item.subtabs.forEach(tab => {
@@ -616,82 +615,7 @@
      }
    })
    // if (formTabs.length > 0) {
    //   this.transformTabs(_resolve, _config, formTabs)
    // } else {
      this.submitConfig(_resolve, _config)
    // }
  }
  transformTabs = (_resolve, _config, formTabs) => {
    let tab = formTabs.shift()
    Api.getSystemConfig({
      func: 'sPC_Get_LongParam',
      MenuID: tab.uuid
    }).then(res => {
      if (res.status) {
        let _LongParam = ''
        if (res.LongParam) {
          try {
            _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
          } catch (e) {
            console.warn('Parse Failure')
            _LongParam = ''
          }
        }
        if (_LongParam && (_LongParam.type === 'FormTab' || _LongParam.Template === 'FormTab') && _LongParam.enabled) {
          if (!_LongParam.tabgroups) {
            _LongParam.tabgroups = []
          } else if (typeof(_LongParam.tabgroups[0]) === 'string') {
            let _tabgroups = []
            _LongParam.tabgroups.forEach(groupId => {
              let _group = {
                uuid: groupId,
                sublist: fromJS(_LongParam[groupId]).toJS()
              }
              delete _LongParam[groupId]
              _tabgroups.push(_group)
            })
            _LongParam.tabgroups = _tabgroups
          }
          _LongParam.tabgroups = _LongParam.tabgroups.filter(group => group.sublist.length > 0)
          _LongParam.tabgroups.forEach(group => {
            group.sublist = group.sublist.map(tab => {
              if (tab.supMenu === 'mainTable') {
                tab.supMenu = ''
              }
              return tab
            })
          })
          _LongParam.action = _LongParam.action.map(item => {
            if (item.intertype === 'inner' && !item.innerFunc) {
              item.intertype = 'system'
            }
            return item
          })
          delete _LongParam.funcs
          delete _LongParam.tables
        } else {
          _config.components[0].action = _config.components[0].action.filter(btn => btn.uuid !== tab.uuid)
        }
      } else {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        _resolve()
      }
    })
  }
  checkBtns = (card) => {
@@ -854,7 +778,7 @@
    })
  }
  getTable = (config, newCon, errors, formActions, formTabs, popActions, oldtabs) => {
  getTable = (config, newCon, errors, formActions, popActions, oldtabs) => {
    let _card = {
      uuid: newCon.uuid,
      type: 'table',
@@ -1155,27 +1079,6 @@
        if (btn.tabTemplate === 'FormTab') {
          errors.push(newCon.name + '中按钮《' + btn.label + '》不在支持')
          return
          // if (newCon.isMain !== true) {
          //   errors.push(newCon.name + '中按钮《' + btn.label + '》不在支持')
          //   return
          // }
          // delete _btn.tabTemplate
          // _btn.MenuID = 'tab' + md5(btn.uuid).substr(3)
          // _btn.MenuName = this.baseMsg.MenuName + '-' + btn.label
          // _btn.MenuNo = this.baseMsg.MenuNo + '_' + _btn.MenuID.substr(-4).toUpperCase()
          // _btn.hidden = _btn.hidden || 'false'
          // _btn.tabType = 'CustomPage'
          // _btn.linkmenu = [this.baseMsg.fstMenuId, this.baseMsg.parentId, _btn.MenuID]
          // let _tab = {...btn}
          // _tab.MenuID = _btn.MenuID
          // _tab.MenuNo = _btn.MenuNo
          // _tab.MenuName = _btn.MenuName
          // formTabs.push(_tab)
        } else if (!btn.linkmenu || btn.linkmenu.length !== 3) {
          errors.push(newCon.name + '中按钮《' + btn.label + '》不在支持')
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -839,7 +839,7 @@
              清空Excel列
            </Button>
            <Col style={{fontSize: '12px', color: '#757575', paddingLeft: '10px'}} span={24}>注:数值类型(int 或 decimal),内容为必填;最大值和最小值在类型为数值时有效。</Col>
            <EditTable actions={['edit', 'move', 'copy', 'del']} type="excelcolumn" data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/>
            <EditTable actions={['edit', 'move', 'copy', 'del', 'extra:required:是否必填']} type="excelcolumn" data={verify.columns} columns={excelColumns} onChange={this.changeColumns}/>
          </TabPane>
          {card.intertype === 'system' ? <TabPane tab={
            <span>
src/templates/treepageconfig/index.jsx
@@ -19,6 +19,8 @@
const { Panel } = Collapse
const { confirm } = Modal
const { TreeNode } = Tree
const UpdateTable = asyncComponent(() => import('./updatetable'))
const TreeSettingComponent = asyncComponent(() => import('@/templates/sharecomponent/treesettingcomponent'))
const TabsComponent = asyncComponent(() => import('@/templates/sharecomponent/tabscomponent'))
@@ -68,6 +70,7 @@
    _config.MenuName = menu.MenuName || ''
    _config.MenuNo = menu.MenuNo || ''
    _config.OpenType = menu.PageParam ? menu.PageParam.OpenType : ''
    _config.MenuID = menu.MenuID || ''
    // 配置默认值,兼容
    _config.Template = 'TreePage'
@@ -715,6 +718,7 @@
              </div>
            } bordered={false} extra={
              <div>
                <UpdateTable config={config}/>
                <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={this.state.config.enabled} onChange={this.onEnabledChange} />
                <Button type="primary" id="save-config" onClick={this.submitConfig} loading={this.state.menuloading}>保存</Button>
                <Button onClick={this.cancelConfig}>关闭</Button>
src/templates/treepageconfig/updatetable/index.jsx
New file
@@ -0,0 +1,1227 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Modal, Button, notification } from 'antd'
import { ArrowUpOutlined } from '@ant-design/icons'
import moment from 'moment'
import md5 from 'md5'
import { colorTransform } from '@/utils/option.js'
import { getTables } from '@/utils/utils-custom.js'
import Api from '@/api'
import Utils from '@/utils/utils.js'
// import './index.scss'
const { confirm } = Modal
class UpdateTable extends Component {
  static propTpyes = {
    config: PropTypes.object
  }
  state = {}
  delButtons = []
  baseMsg = {}
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  trigger = () => {
    const { config } = this.props
    const _this = this
    if (!config.enabled) {
      notification.warning({
        top: 92,
        message: '未启用菜单不可升级!',
        duration: 5
      })
      return
    }
    confirm({
      title: '确定升级当前菜单吗?',
      content: '',
      onOk() {
        return new Promise(resolve => {
          _this.execUpdate(resolve)
        })
      },
      onCancel() {}
    })
  }
  execUpdate = (_resolve) => {
    const config = fromJS(this.props.config).toJS()
    this.delButtons = []
    this.baseMsg = {
      fstMenuId: config.fstMenuId,
      parentId: config.ParentId,
      MenuName: config.MenuName,
      MenuNo: config.MenuNo,
    }
    let _config = {
      version: 1.0,
      uuid: config.MenuID,
      MenuID: config.MenuID,
      fstMenuId: config.fstMenuId,
      parentId: config.ParentId,
      Template: 'CustomPage',
      easyCode: config.easyCode,
      enabled: false,
      MenuName: config.MenuName,
      MenuNo: config.MenuNo,
      OpenType: 'newtab',
      tables: config.tables || [],
      urlFields: config.urlFields || [],
      hidden: config.hidden || 'false',
      Remark: config.Remark || '',
      components: [],
      viewType: 'menu',
      style: { backgroundColor: '#ffffff', paddingTop: '16px', paddingBottom: '80px', paddingLeft: '16px', paddingRight: '16px'},
    }
    let formActions = []
    let popActions = []
    let errors = []
    let mainTr = {
      uuid: Utils.getuuid(),
      type: 'tree',
      format: 'array',    // 组件属性 - 数据格式
      pageable: false,    // 组件属性 - 是否可分页
      switchable: true,   // 组件属性 - 数据是否可切换
      width: config.setting.width || 5,
      name: config.setting.title || '结构树',
      subtype: 'normaltree',
      setting: {},
      wrap: { name: config.setting.title || '结构树', title: config.setting.title || '', width: config.setting.width || 5, showIcon: config.setting.showIcon || 'false', showLine: config.setting.showLine || 'false', searchable: config.setting.searchable || 'false' },
      style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
      headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
      columns: [],
      scripts: [],
      action: [],
    }
    mainTr.setting = {
      interType: config.setting.interType || 'system',
      innerFunc: config.setting.innerFunc || '',
      interface: config.setting.interface || '',
      dataresource: config.setting.dataresource || '',
      tableName: config.setting.tableName || '',
      order: config.setting.order || '',
      execute: config.setting.default || 'true',
      primaryKey: config.setting.valueField || '',
      supModule: ['empty'],
      sync: 'false',
      onload: 'true'
    }
    mainTr.wrap.valueField = config.setting.valueField || ''
    mainTr.wrap.labelField = config.setting.labelField || ''
    mainTr.wrap.parentField = config.setting.parentField || ''
    mainTr.wrap.mark = config.setting.mark || ''
    mainTr.scripts = config.setting.scripts || []
    let fields = [mainTr.wrap.valueField, mainTr.wrap.labelField, mainTr.wrap.parentField]
    fields.forEach(col => {
      mainTr.columns.push({
        datatype: `Nvarchar(50)`,
        field: col,
        fieldlength: 50,
        label: col,
        type: 'text',
        uuid: Utils.getuuid()
      })
    })
    let oldtabs = {
      mainTable: mainTr.uuid
    }
    _config.components.push(mainTr)
    let _tbs = []
    if (config.tabgroups && config.tabgroups.length > 0) {
      config.tabgroups.forEach((m, i) => {
        if (!m.sublist || m.sublist.length === 0) return
        let tabs = {
          uuid: Utils.getuuid(),
          type: 'tabs',
          subtype: 'tabs',
          name: '标签组' + (i + 1),
          width: 24 - mainTr.width,
          setting: {supModule: [mainTr.uuid], controlField: 'mk_floor', name: '标签组' + (i + 1), width: 24 - mainTr.width, position: 'top'},
          style: {},
          subtabs: m.sublist.map(n => {
            let level = ''
            if (n.level === 0) {
              level = '@pass_empty@,1,2,3,4,5'
            } else if (!n.level) {
              level = '@pass@'
            } else {
              if (n.level === 1) {
                level = '2,3,4,5'
              } else if (n.level === 2) {
                level = '1,3,4,5'
              } else if (n.level === 3) {
                level = '1,2,4,5'
              } else if (n.level === 4) {
                level = '1,2,3,5'
              } else if (n.level === 5) {
                level = '1,2,3,4'
              }
            }
            let tab = { uuid: Utils.getuuid(), controlVal: level, label: n.label, icon: n.icon, permission: 'false', components: [
              {
                uuid: Utils.getuuid(),
                linkTab: n.linkTab,
                name: n.label,
                useMSearch: 'false',
                supModule: n.supMenu || '',
                equalTab: n.equalTab && n.equalTab.length > 0 ? n.equalTab[0] : ''
              }
            ]}
            this.delButtons.push(n.linkTab)
            oldtabs[n.uuid] = tab.components[0].uuid
            _tbs.push(tab.components[0])
            return tab
          })
        }
        _config.components.push(tabs)
      })
    }
    if (_tbs.length > 0) {
      let defers = _tbs.map((item, i) => {
        return new Promise((resolve) => {
          setTimeout(() => {
            Api.getSystemConfig({
              func: 'sPC_Get_LongParam',
              MenuID: item.linkTab
            }).then(res => {
              if (res.status) {
                let _LongParam = ''
                if (res.LongParam) {
                  try {
                    _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
                  } catch (e) {
                    console.warn('Parse Failure')
                    _LongParam = ''
                  }
                }
                if (_LongParam) {
                  _LongParam.uuid = item.linkTab
                  resolve(_LongParam)
                } else {
                  resolve({uuid: item.linkTab, $empty: true})
                }
              } else {
                notification.warning({
                  top: 92,
                  message: res.message,
                  duration: 5
                })
                resolve({uuid: item.linkTab, $empty: true})
              }
            })
          }, i * 50)
        })
      })
      Promise.all(defers).then(res => {
        let menus = {}
        res.forEach(item => {
          if (item && !item.$empty) {
            menus[item.uuid] = item
          }
        })
        _config.components = _config.components.map(item => {
          if (item.type === 'tabs') {
            item.subtabs = item.subtabs.map(tab => {
              tab.components[0] = this.getTable(menus[tab.components[0].linkTab], tab.components[0], errors, formActions, popActions, oldtabs)
              return tab
            })
          }
          return item
        })
        this.setPopView(_resolve, _config, formActions, popActions, errors)
      })
    } else {
      this.setPopView(_resolve, _config, formActions, popActions, errors)
    }
  }
  setPopView = (_resolve, _config, formActions, popActions, errors) => {
    if (popActions.length > 0) {
      let defers = popActions.map((item, i) => {
        return new Promise((resolve) => {
          setTimeout(() => {
            Api.getSystemConfig({
              func: 'sPC_Get_LongParam',
              MenuID: item.linkTab
            }).then(res => {
              if (res.status) {
                let _LongParam = ''
                if (res.LongParam) {
                  try {
                    _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
                  } catch (e) {
                    console.warn('Parse Failure')
                    _LongParam = ''
                  }
                }
                if (_LongParam) {
                  _LongParam.uuid = item.uuid
                  resolve(_LongParam)
                } else {
                  resolve({uuid: item.uuid, $empty: true})
                }
              } else {
                notification.warning({
                  top: 92,
                  message: res.message,
                  duration: 5
                })
                resolve({uuid: item.uuid, $empty: true})
              }
            })
          }, i * 50)
        })
      })
      Promise.all(defers).then(res => {
        let menus = {}
        res.forEach(item => {
          if (item && !item.$empty) {
            menus[item.uuid] = item
          }
        })
        _config.components.forEach(item => {
          if (item.type === 'tabs') {
            item.subtabs.forEach(tab => {
              tab.components[0].action.forEach(btn => {
                if (btn.OpenType === 'popview') {
                  if (menus[btn.uuid]) {
                    let mainTb = {name: '主表', uuid: Utils.getuuid(), useMSearch: 'false'}
                    btn.config = {
                      uuid: btn.uuid,
                      MenuID: btn.uuid,
                      ParentId: tab.components[0].uuid,
                      MenuName: btn.label,
                      tables: _config.tables || [],
                      Template: 'CustomPage',
                      components: [this.getTable(menus[btn.uuid], mainTb, errors, formActions)],
                      viewType: 'popview',
                      style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
                    }
                    btn.config.enabled = this.setEnabled(btn.config)
                  } else {
                    errors.push(tab.label + '中按钮《' + btn.label + '》配置信息丢失')
                  }
                }
              })
              tab.components[0].cols.forEach(col => {
                if (col.type !== 'custom') return
                col.elements.forEach(btn => {
                  if (btn.eleType !== 'button') return
                  if (btn.OpenType === 'popview') {
                    if (menus[btn.uuid]) {
                      let mainTb = {name: '主表', uuid: Utils.getuuid(), useMSearch: 'false'}
                      btn.config = {
                        uuid: btn.uuid,
                        MenuID: btn.uuid,
                        ParentId: tab.components[0].uuid,
                        MenuName: btn.label,
                        tables: _config.tables || [],
                        Template: 'CustomPage',
                        components: [this.getTable(menus[btn.uuid], mainTb, errors, formActions)],
                        viewType: 'popview',
                        style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
                      }
                      btn.config.enabled = this.setEnabled(btn.config)
                    } else {
                      errors.push(tab.label + '中按钮《' + btn.label + '》配置信息丢失')
                    }
                  }
                })
              })
            })
          } else if (item.type !== 'tree') {
            item.action.forEach(btn => {
              if (btn.OpenType === 'popview') {
                if (menus[btn.uuid]) {
                  let mainTb = {name: '主表', uuid: Utils.getuuid(), useMSearch: 'false'}
                  btn.config = {
                    uuid: btn.uuid,
                    MenuID: btn.uuid,
                    ParentId: item.uuid,
                    MenuName: btn.label,
                    tables: _config.tables || [],
                    Template: 'CustomPage',
                    components: [this.getTable(menus[btn.uuid], mainTb, errors, formActions)],
                    viewType: 'popview',
                    style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
                  }
                  btn.config.enabled = this.setEnabled(btn.config)
                } else {
                  errors.push('主表中按钮《' + btn.label + '》配置信息丢失')
                }
              }
            })
            item.cols.forEach(col => {
              if (col.type !== 'custom') return
              col.elements.forEach(btn => {
                if (btn.eleType !== 'button') return
                if (btn.OpenType === 'popview') {
                  if (menus[btn.uuid]) {
                    let mainTb = {name: '主表', uuid: Utils.getuuid(), useMSearch: 'false'}
                    btn.config = {
                      uuid: btn.uuid,
                      MenuID: btn.uuid,
                      ParentId: item.uuid,
                      MenuName: btn.label,
                      tables: _config.tables || [],
                      Template: 'CustomPage',
                      components: [this.getTable(menus[btn.uuid], mainTb, errors, formActions)],
                      viewType: 'popview',
                      style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
                    }
                    btn.config.enabled = this.setEnabled(btn.config)
                  } else {
                    errors.push('主表中按钮《' + btn.label + '》配置信息丢失')
                  }
                }
              })
            })
          }
        })
        this.setPopForm(_resolve, _config, formActions, errors)
      })
    } else {
      this.setPopForm(_resolve, _config, formActions, errors)
    }
  }
  setEnabled = (config) => {
    let enabled = true
    config.components.forEach(item => {
      if (item.type === 'tabs') {
        item.subtabs.forEach(tab => {
          if (tab.components[0].errors.length > 0) {
            enabled = false
          }
        })
      } else {
        if (item.errors.length > 0) {
          enabled = false
        }
      }
    })
    return enabled
  }
  setPopForm = (_resolve, _config, formActions, errors) => {
    if (formActions.length > 0) {
      let defers = formActions.map((item, i) => {
        return new Promise((resolve) => {
          setTimeout(() => {
            Api.getSystemConfig({
              func: 'sPC_Get_LongParam',
              MenuID: item.origin
            }).then(res => {
              if (res.status) {
                let _LongParam = ''
                if (res.LongParam) {
                  try {
                    _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
                  } catch (e) {
                    console.warn('Parse Failure')
                    _LongParam = ''
                  }
                }
                if (_LongParam) {
                  _LongParam.uuid = item.uuid
                  resolve(_LongParam)
                } else {
                  resolve({uuid: item.uuid, $empty: true})
                }
              } else {
                notification.warning({
                  top: 92,
                  message: res.message,
                  duration: 5
                })
                resolve({uuid: item.uuid, $empty: true})
              }
            })
          }, i * 50)
        })
      })
      Promise.all(defers).then(res => {
        let menus = {}
        res.forEach(item => {
          if (item && !item.$empty) {
            menus[item.uuid] = item
          }
        })
        _config.components.forEach(item => {
          if (item.type === 'tabs') {
            item.subtabs.forEach(tab => {
              tab.components[0].action.forEach(btn => {
                if (btn.OpenType === 'popview' && btn.config && btn.config.components[0]) {
                  this.setTbForm(btn.config.components[0], menus, errors, tab.components[0].name + '-' + btn.label)
                } else if (btn.OpenType === 'pop' || (btn.OpenType === 'funcbutton' && btn.funcType === 'print' && btn.execMode === 'pop')) {
                  if (menus[btn.uuid]) {
                    btn.modal = {
                      setting: menus[btn.uuid].setting,
                      tables: [],
                      groups: [],
                      fields: menus[btn.uuid].fields || []
                    }
                  } else {
                    errors.push(tab.label + '中按钮《' + btn.label + '》配置信息丢失')
                  }
                }
              })
              tab.components[0].cols.forEach(col => {
                if (col.type !== 'custom') return
                col.elements.forEach(btn => {
                  if (btn.eleType !== 'button') return
                  if (btn.OpenType === 'popview' && btn.config && btn.config.components[0]) {
                    this.setTbForm(btn.config.components[0], menus, errors, tab.components[0].name + '-' + btn.label)
                  } else if (btn.OpenType === 'pop' || (btn.OpenType === 'funcbutton' && btn.funcType === 'print' && btn.execMode === 'pop')) {
                    if (menus[btn.uuid]) {
                      btn.modal = {
                        setting: menus[btn.uuid].setting,
                        tables: [],
                        groups: [],
                        fields: menus[btn.uuid].fields || []
                      }
                    } else {
                      errors.push(tab.label + '中按钮《' + btn.label + '》配置信息丢失')
                    }
                  }
                })
              })
            })
          } else if (item.type !== 'tree') {
            item.action.forEach(btn => {
              if (btn.OpenType === 'popview' && btn.config && btn.config.components[0]) {
                this.setTbForm(btn.config.components[0], menus, errors, item.name + '-' + btn.label)
              } else if (btn.OpenType === 'pop' || (btn.OpenType === 'funcbutton' && btn.funcType === 'print' && btn.execMode === 'pop')) {
                if (menus[btn.uuid]) {
                  btn.modal = {
                    setting: menus[btn.uuid].setting,
                    tables: [],
                    groups: [],
                    fields: menus[btn.uuid].fields || []
                  }
                } else {
                  errors.push('主表中按钮《' + btn.label + '》配置信息丢失')
                }
              }
            })
            item.cols.forEach(col => {
              if (col.type !== 'custom') return
              col.elements.forEach(btn => {
                if (btn.eleType !== 'button') return
                if (btn.OpenType === 'popview' && btn.config && btn.config.components[0]) {
                  this.setTbForm(btn.config.components[0], menus, errors, item.name + '-' + btn.label)
                } else if (btn.OpenType === 'pop' || (btn.OpenType === 'funcbutton' && btn.funcType === 'print' && btn.execMode === 'pop')) {
                  if (menus[btn.uuid]) {
                    btn.modal = {
                      setting: menus[btn.uuid].setting,
                      tables: [],
                      groups: [],
                      fields: menus[btn.uuid].fields || []
                    }
                  } else {
                    errors.push('主表中按钮《' + btn.label + '》配置信息丢失')
                  }
                }
              })
            })
          }
        })
        this.saveConfig(_resolve, _config, errors)
      })
    } else {
      this.saveConfig(_resolve, _config, errors)
    }
  }
  setTbForm = (item, menus, errors, name) => {
    item.action.forEach(btn => {
      if (btn.OpenType === 'pop' || (btn.OpenType === 'funcbutton' && btn.funcType === 'print' && btn.execMode === 'pop')) {
        if (menus[btn.uuid]) {
          btn.modal = {
            setting: menus[btn.uuid].setting,
            tables: [],
            groups: [],
            fields: menus[btn.uuid].fields || []
          }
        } else {
          errors.push(name + '中按钮《' + btn.label + '》配置信息丢失')
        }
      }
    })
    item.cols.forEach(col => {
      if (col.type !== 'custom') return
      col.elements.forEach(btn => {
        if (btn.eleType !== 'button') return
        if (btn.OpenType === 'pop' || (btn.OpenType === 'funcbutton' && btn.funcType === 'print' && btn.execMode === 'pop')) {
          if (menus[btn.uuid]) {
            btn.modal = {
              setting: menus[btn.uuid].setting,
              tables: [],
              groups: [],
              fields: menus[btn.uuid].fields || []
            }
          } else {
            errors.push(name + '中按钮《' + btn.label + '》配置信息丢失')
          }
        }
      })
    })
  }
  saveConfig = (_resolve, _config, errors) => {
    let err = errors.join(';')
    let _this = this
    if (err) {
      _resolve()
      confirm({
        title: err + ',确定升级当前菜单吗?',
        content: '',
        onOk() {
          return new Promise(resolve => {
            _this.saveNewMenu(resolve, _config)
          })
        },
        onCancel() {}
      })
    } else {
      this.saveNewMenu(_resolve, _config)
    }
  }
  saveNewMenu = (_resolve, _config) => {
    _config.components.forEach(item => {
      if (item.type === 'tabs') {
        item.subtabs.forEach(tab => {
          tab.components[0].action.forEach(btn => {
            if (btn.OpenType === 'popview' && btn.config) {
              btn.config.$tables = getTables(btn.config.components[0])
            }
          })
          tab.components[0].cols.forEach(col => {
            if (col.type !== 'custom') return
            col.elements.forEach(btn => {
              if (btn.eleType !== 'button') return
              if (btn.OpenType === 'popview' && btn.config) {
                btn.config.$tables = getTables(btn.config.components[0])
              }
            })
          })
          tab.components[0].$tables = getTables(tab.components[0])
        })
      } else {
        item.$tables = getTables(item)
      }
    })
    this.submitConfig(_resolve, _config)
  }
  checkBtns = (card) => {
    card.action.forEach(cell => {
      if (cell.hidden === 'true') return
      if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
        if (!cell.modal || cell.modal.fields.length === 0) {
          card.errors.push({ level: 0, detail: `按钮“${cell.label}”中表单尚未添加`})
        }
      } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
        card.errors.push({ level: 0, detail: `按钮“${cell.label}”中导入列未设置!`})
      } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
        card.errors.push({ level: 0, detail: `按钮“${cell.label}”中导出列未设置!`})
      }
    })
    card.cols.forEach(col => {
      if (col.type !== 'custom') return
      col.elements.forEach(cell => {
        if (cell.hidden === 'true' || cell.eleType !== 'button') return
        if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
          if (!cell.modal || cell.modal.fields.length === 0) {
            card.errors.push({ level: 0, detail: `按钮“${cell.label}”中表单尚未添加`})
          }
        } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
          card.errors.push({ level: 0, detail: `按钮“${cell.label}”中导入列未设置!`})
        } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
          card.errors.push({ level: 0, detail: `按钮“${cell.label}”中导出列未设置!`})
        }
      })
    })
  }
  submitConfig = (_resolve, config) => {
    let tbs = []
    config.components.forEach(item => {
      if (item.type === 'tabs') {
        item.subtabs.forEach(tab => {
          if (tab.components[0].$tables) {
            tbs.push(...tab.components[0].$tables)
          }
          this.checkBtns(tab.components[0])
        })
      } else {
        if (item.$tables) {
          tbs.push(...item.$tables)
        }
      }
    })
    let arr = []
    tbs = tbs.filter(tb => {
      let _tb = tb.toLowerCase()
      if (arr.includes(_tb)) return false
      arr.push(_tb)
      return true
    })
    tbs.sort()
    if (tbs.length && sessionStorage.getItem('mk_tb_names')) {
      let names = sessionStorage.getItem('mk_tb_names')
      tbs = tbs.filter(tb => names.indexOf(',' + tb.toLowerCase() + ',') > -1)
    }
    tbs = tbs.map(tb => `'${tb}'`).join(';')
    let key = md5(config.uuid + tbs.toLowerCase())
    let urlparam = {
      FstId: config.fstMenuId,
      ParentId: config.parentId,
      MenuID: config.uuid,
      MenuName: config.MenuName,
      MenuNo: config.MenuNo,
      EasyCode: config.easyCode,
      type: 'admin',
      OpenType: config.OpenType,
      PageParam: {Template: 'CustomPage', OpenType: 'newtab', hidden: config.hidden},
      MenuType: 'CustomPage'
    }
    let url = window.btoa(window.encodeURIComponent(JSON.stringify(urlparam)))
    config.tbkey = key
    let param = {
      func: 'sPC_TrdMenu_AddUpt',
      FstID: config.fstMenuId || '',
      SndID: config.parentId,
      ParentID: config.parentId,
      MenuID: config.uuid,
      MenuNo: config.MenuNo || '',
      EasyCode: config.easyCode || '',
      Template: 'CustomPage',
      MenuName: config.MenuName || '',
      PageParam: JSON.stringify({Template: 'CustomPage', OpenType: config.OpenType, hidden: config.hidden}),
      open_edition: '',
      debug_md5: key,
      debug_url: url,
      debug_list: window.btoa(tbs),
      LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(config)))
    }
    param.LText = Utils.formatOptions(param.LText)
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    let save = false
    new Promise(resolve => {
      Api.getSystemConfig(param).then(res => {
        resolve(res)
      })
    }).then(res => { // 删除原菜单
      if (!res || !res.status) return res
      save = true
      localStorage.setItem('menuUpdate', new Date().getTime() + ',' + config.uuid)
      if (this.delButtons.length === 0) return res
      return Api.getSystemConfig({
        func: 'sPC_MainMenu_Del',
        up_type: 'Y',
        MenuID: this.delButtons.join(',')
      })
    }).then(res => {
      if (!res) return
      _resolve()
      if (res.status) {
        delete urlparam.type
        delete urlparam.MenuType
        let _param = window.btoa(window.encodeURIComponent(JSON.stringify(urlparam)))
        window.history.replaceState(null, null, window.location.href.split('#')[0] + `#/menudesign/${_param}`)
        window.location.reload()
      } else {
        Modal.warning({
          title: res.message,
          okText: '知道了',
          onOk: () => {
            if (save) {
              delete urlparam.type
              delete urlparam.MenuType
              let _param = window.btoa(window.encodeURIComponent(JSON.stringify(urlparam)))
              window.history.replaceState(null, null, window.location.href.split('#')[0] + `#/menudesign/${_param}`)
              window.location.reload()
            } else {
              window.location.reload()
            }
          }
        })
      }
    })
  }
  getTable = (config, newCon, errors, formActions, popActions, oldtabs) => {
    let _card = {
      uuid: newCon.uuid,
      type: 'table',
      name: newCon.name,
      format: 'array',
      pageable: true,
      switchable: true,
      search: [],
      action: [],
      subtype: 'normaltable',
      setting: { useMSearch: 'false', sync: 'false', onload: 'true' },
      wrap: {},
      style: {},
      headerStyle: {},
      columns: [],
      cols: [],
      scripts: []
    }
    if (!config) {
      errors.push(newCon.name + '配置信息丢失')
      return _card
    }
    if (oldtabs && newCon.supModule && oldtabs[newCon.supModule]) {
      _card.setting.supModule = [oldtabs[newCon.supModule]]
    } else {
      _card.setting.supModule = ['empty']
    }
    _card.search = config.search.map(item => {
      item.uuid = Utils.getuuid()
      return item
    })
    let _cols = {}
    let _colspan = []
    let lineMarks = []
    config.columns.forEach(col => {
      if (col.type === 'colspan') {
        _colspan.push(...col.subfield.split(', '))
      }
      if (!col.field) return
      let _col = fromJS(col).toJS()
      if (_col.marks) {
        _col.marks = []
        col.marks.forEach(m => {
          if (m.signType === 'card') return
          let field = []
          field.push(m.field)
          field.push(m.contrastType)
          if (m.contrastField) {
            field.push(m.contrastField)
          }
          let color = '#1890ff'
          if (m.color && m.color[1]) {
            color = colorTransform[m.color[1]]
          }
          let signType = ['font']
          if (m.signType === 'background') {
            signType = ['background']
          } else if (m.signType === 'icon') {
            if (m.position === 'back') {
              signType = ['iconback']
            } else {
              signType = ['iconfront']
            }
            signType.push(m.iconType)
            signType.push(m.icon)
          }
          if (m.signType === 'line') {
            lineMarks.push({
              $index: lineMarks.length + 1,
              uuid: Utils.getuuid(),
              field: field,
              color: color,
              contrastValue: m.contrastValue || '',
              match: m.match,
              signType: ['background']
            })
          } else {
            _col.marks.push({
              $index: _col.marks.length + 1,
              uuid: Utils.getuuid(),
              field: field,
              color: color,
              contrastValue: m.contrastValue || '',
              match: m.match,
              signType: signType
            })
          }
        })
      }
      _cols[col.field] = _col
    })
    config.columns.forEach(col => {
      if (col.type === 'index') {
        _card.cols.push(fromJS(col).toJS())
      } else if (col.field && _cols[col.field]) {
        let _col = fromJS(_cols[col.field]).toJS()
        if (_colspan.includes(col.field)) {
          _col.Hide = 'true'
        }
        _card.cols.push(_col)
      }
      if (col.type === 'colspan') {
        let ucol = {
          Align: col.Align,
          Hide: col.Hide,
          label: col.label,
          marks: [],
          isSub: false,
          uuid: col.uuid,
          blacklist: []
        }
        if (col.unfold === 'true') {
          ucol.type = 'colspan'
          ucol.subcols = []
          col.subfield.split(', ').forEach(sub => {
            if (_cols[sub]) {
              let _col = fromJS(_cols[sub]).toJS()
              _col.Hide = 'false'
              _col.isSub = true
              _col.uuid = Utils.getuuid()
              ucol.subcols.push(_col)
            }
          })
          if (ucol.subcols.length > 0) {
            _card.cols.push(ucol)
          }
        } else {
          ucol.Width = 120
          ucol.type = 'custom'
          ucol.elements = []
          ucol.style = {paddingTop: '12px', paddingLeft: '8px', paddingBottom: '12px', paddingRight: '8px'}
          col.subfield.split(', ').forEach(sub => {
            if (_cols[sub]) {
              let _col = {
                copyable: 'false',
                datatype: 'dynamic',
                eleType: _cols[sub].type !== 'number' ? 'text' : 'number',
                field: sub,
                height: '',
                innerHeight: 'auto',
                marks: _cols[sub].marks || null,
                noValue: 'show',
                prefix: _cols[sub].prefix || '',
                postfix: _cols[sub].postfix || '',
                style: {},
                width: 24,
                uuid: Utils.getuuid()
              }
              ucol.elements.push(_col)
            }
          })
          if (ucol.elements.length > 0) {
            _card.cols.push(ucol)
          }
        }
      }
    })
    _card.lineMarks = lineMarks
    _card.columns = []
    _card.absFields = []
    _card.cols.forEach(col => {
      if (!col.field) return
      if (['text', 'picture', 'video', 'textarea'].includes(col.type)) {
        _card.columns.push({
          datatype: `Nvarchar(${col.fieldlength || 50})`,
          field: col.field,
          fieldlength: col.fieldlength || 50,
          label: col.label,
          type: 'text',
          uuid: col.uuid
        })
      } else if (col.type === 'link') {
        _card.columns.push({
          datatype: `Nvarchar(${col.fieldlength || 50})`,
          field: col.field,
          fieldlength: col.fieldlength || 50,
          label: col.label,
          type: 'text',
          uuid: col.uuid
        })
        if (col.nameField) {
          _card.columns.push({
            datatype: `Nvarchar(${col.fieldlength || 50})`,
            field: col.nameField,
            fieldlength: col.fieldlength || 50,
            label: col.label + '(名称)',
            type: 'text',
            uuid: col.uuid + 'name'
          })
        }
      } else if (col.type === 'number') {
        _card.columns.push({
          datatype: `Decimal(18,${col.decimal || 0})`,
          field: col.field,
          decimal: col.decimal || 0,
          label: col.label,
          type: 'number',
          uuid: col.uuid
        })
        if (col.format === 'abs') {
          _card.absFields.push(col.field)
        }
      }
    })
    if (_card.absFields.length) {
      _card.absFields = Array.from(new Set(_card.absFields))
    } else {
      _card.absFields = null
    }
    let colbtns = []
    let colors = { primary: '#1890ff', yellow: '#c49f47', orange: 'orange', danger: '#ff4d4f', green: '#26C281', dgreen: '#32c5d2', purple: '#8E44AD', cyan: '#13c2c2', gray: '#E7E7EF', default: 'rgba(0, 0, 0, 0.65)' }
    let uuids = {}
    config.action.forEach(btn => {
      let _c = btn.class ? btn.class.replace('border-', '') : ''
      let color = colors[_c] || '#1890ff'
      let _btn = fromJS(btn).toJS()
      delete _btn.position
      delete _btn.linkTab
      if (_btn.intertype === 'inner' && !_btn.innerFunc) {
        _btn.intertype = 'system'
      }
      if ((_btn.intertype === 'outer' || _btn.intertype === 'custom') && !_btn.procMode) { // 兼容外部函数直传类型
        _btn.procMode = !_btn.innerFunc ? 'none' : 'inner'
      }
      if (_btn.funcType === 'print' && _btn.execMode) {
        _btn.OpenType = 'funcbutton'
      } else if (_btn.OpenType === 'blank') {
        _btn.OpenType = 'tab'
      }
      this.delButtons.push(btn.uuid)
      _btn.show = 'button'
      if (_btn.execSuccess === 'equaltab') {
        _btn.execSuccess = 'grid'
        _btn.syncComponent = []
        if (newCon.equalTab && oldtabs && oldtabs[newCon.equalTab]) {
          _btn.syncComponent.push(oldtabs[newCon.equalTab])
        }
      } else if (_btn.execSuccess === 'maingrid') {
        _btn.execSuccess = 'mainline'
      }
      if (_btn.execError === 'equaltab') {
        _btn.execError = 'grid'
      } else if (_btn.execError === 'maingrid') {
        _btn.execError = 'mainline'
      }
      if (_btn.popClose === 'equaltab') {
        _btn.popClose = 'grid'
        _btn.syncComponent = []
        if (newCon.equalTab && oldtabs && oldtabs[newCon.equalTab]) {
          _btn.syncComponent.push(oldtabs[newCon.equalTab])
        }
      } else if (_btn.popClose === 'maingrid') {
        _btn.popClose = 'mainline'
      }
      if (_btn.OpenType === 'pop' || (_btn.OpenType === 'funcbutton' && _btn.funcType === 'print' && _btn.execMode === 'pop')) {
        formActions.push({origin: btn.uuid, uuid: _btn.uuid, name: newCon.name, label: btn.label})
      } else if (_btn.OpenType === 'popview') {
        if (!popActions) return
        popActions.push({origin: btn.uuid, linkTab: btn.linkTab || '', uuid: _btn.uuid, name: newCon.name, label: btn.label})
      } else if (_btn.OpenType === 'tab') {
        if (btn.tabTemplate === 'FormTab') {
          errors.push(newCon.name + '中按钮《' + btn.label + '》不在支持')
          return
        } else if (!btn.linkmenu || btn.linkmenu.length !== 3) {
          errors.push(newCon.name + '中按钮《' + btn.label + '》不在支持')
          return
        }
      }
      uuids[btn.uuid] = true
      if (_btn.tabType === 'CommonTable' || _btn.tabType === 'SubTable') {
        _btn.tabType = 'BaseTable'
      }
      if (btn.position === 'grid') {
        _btn.eleType = 'button'
        _btn.width = 24
        _btn.style = {color: color, backgroundColor: 'transparent', borderColor: 'transparent'}
        colbtns.push(_btn)
      } else {
        if (btn.class === 'default') {
          _btn.style = {color: 'rgba(0, 0, 0, 0.65)', backgroundColor: '#fff', borderColor: '#d9d9d9', marginRight: '15px'}
        } else if (btn.class.indexOf('border') > -1) {
          _btn.style = {color: color, backgroundColor: '#fff', borderColor: color, marginRight: '15px'}
        } else {
          _btn.style = {color: btn.class === 'gray' ? 'rgba(0, 0, 0, 0.65)' : '#fff', backgroundColor: color, borderColor: color, marginRight: '15px'}
        }
        _card.action.push(_btn)
      }
    })
    if (colbtns.length > 0) {
      _card.cols.push({
        Align: 'left',
        label: '操作',
        marks: [],
        isSub: false,
        uuid: Utils.getuuid(),
        type: 'custom',
        Width: 120,
        elements: colbtns,
        style: {paddingTop: '12px', paddingLeft: '8px', paddingBottom: '12px', paddingRight: '8px'}
      })
    }
    let sets = ['tableName', 'interType', 'sysInterface', 'innerFunc', 'interface', 'proInterface', 'outerFunc', 'dataresource', ['queryType', 'query'], 'primaryKey', 'order', 'execute', ['laypage', 'true'], ['pageSize', 10], ['onload', 'true']]
    let wraps = ['tableType', ['bordered', 'true'], 'actionfixed', ['size', 'middle'], ['selected', 'false'], ['tableMode', 'compatible'], ['mask', 'show'], ['borderColor', '#e8e8e8'], 'height', 'controlField', 'controlVal']
    _card.scripts = config.setting.scripts || []
    sets.forEach(n => {
      if (n === 'interType') {
        if (!['system', 'inner', 'outer'].includes(config.setting.interType)) {
          _card.setting.interType = 'system'
        } else if (config.setting.interType === 'inner' && !config.setting.innerFunc) {
          _card.setting.interType = 'system'
        } else {
          _card.setting.interType = config.setting.interType
        }
      } else if (typeof(n) === 'string') {
        _card.setting[n] = config.setting[n] || ''
      } else {
        _card.setting[n[0]] = config.setting[n[0]] || n[1]
      }
    })
    wraps.forEach(w => {
      if (typeof(w) === 'string') {
        _card.wrap[w] = config.setting[w] || ''
      } else {
        _card.wrap[w[0]] = config.setting[w[0]] || w[1]
      }
    })
    _card.wrap.doubleClick = config.setting.doubleClick || ''
    if (_card.wrap.doubleClick && !uuids[_card.wrap.doubleClick]) {
      _card.wrap.doubleClick = ''
    }
    _card.errors = []
    let columns = _card.columns.map(c => c.field)
    if (_card.setting.interType === 'system' && _card.setting.execute !== 'false' && !_card.setting.dataresource) {
      _card.errors.push({ level: 0, detail: '未设置数据源!'})
    } else if (_card.setting.interType === 'system' && _card.setting.execute === 'false' && _card.scripts.filter(script => script.status !== 'false').length === 0) {
      _card.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
    } else if (!_card.setting.primaryKey) {
      _card.errors.push({ level: 0, detail: '未设置主键!'})
    } else if (!columns.includes(_card.setting.primaryKey)) {
      _card.errors.push({ level: 0, detail: '主键已失效!'})
    } else if (!_card.setting.supModule) {
      _card.errors.push({ level: 0, detail: '未设置上级组件!'})
    }
    return _card
  }
  render() {
    return (
      <Button className="mk-border-purple" onClick={this.trigger}><ArrowUpOutlined /> 升级</Button>
    )
  }
}
export default UpdateTable
src/templates/treepageconfig/updatetable/index.scss
src/templates/zshare/editTable/index.jsx
@@ -180,6 +180,15 @@
    const { data, actions } = this.props
    let columns = fromJS(this.props.columns).toJS()
    let operation = null
    let extra = null
    if (actions) {
      actions.forEach(item => {
        if (/^extra/.test(item)) {
          extra = item.split(':')
        }
      })
    }
    if (actions && (actions.includes('edit') || actions.includes('copy') || actions.includes('del'))) {
      let _operation = null
@@ -217,9 +226,10 @@
            </div>
          ) : (
            <div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')} style={{minWidth: '110px', whiteSpace: 'nowrap'}}>
              {actions.includes('edit') ? <span className="primary" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><EditOutlined /></span> : null}
              {actions.includes('copy') ? <span className="copy" onClick={() => {editingKey === '' && this.copy(record)}}><CopyOutlined /></span> : null}
              {actions.includes('status') ? <span className="status" onClick={() => {editingKey === '' && this.handleStatus(record)}}><SwapOutlined /></span> : null}
              {actions.includes('edit') ? <span className="primary" title="编辑" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><EditOutlined /></span> : null}
              {extra ? <span className="status" title={extra[2]} onClick={() => {editingKey === '' && this.handleStatus(record, extra[1])}}><SwapOutlined /></span> : null}
              {actions.includes('status') ? <span className="status" title="是否启用" onClick={() => {editingKey === '' && this.handleStatus(record, 'status')}}><SwapOutlined /></span> : null}
              {actions.includes('copy') ? <span className="copy" title="复制" onClick={() => {editingKey === '' && this.copy(record)}}><CopyOutlined /></span> : null}
              {actions.includes('del') && editingKey === '' ? <Popconfirm
                overlayClassName="popover-confirm"
                title="确定删除吗?"
@@ -474,10 +484,10 @@
    message.success('粘贴成功。')
  }
  handleStatus = (record) => {
  handleStatus = (record, type) => {
    const { data } = this.state
    record.status = record.status === 'false' ? 'true' : 'false'
    record[type] = record[type] === 'false' ? 'true' : 'false'
    let newData = data.map(item => {
      if (record.uuid === item.uuid) return record