king
2022-11-07 af6486b3629d23e426ce85b87dbc20dfa15b1afe
2022-11-07
21个文件已修改
2个文件已添加
1269 ■■■■■ 已修改文件
src/menu/components/card/cardcellcomponent/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/dragaction/card.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/formconfig.jsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/index.scss 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/table-tabs/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/transfer/index.jsx 264 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/transfer/index.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/basetable/index.jsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalTable/index.jsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/base-table/index.jsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/base-table/index.scss 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/normal-table/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/normal-table/index.scss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/popview/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/debugtable/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/settingcomponent/index.jsx 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/settingcomponent/index.scss 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/updatetable/index.jsx 736 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/index.jsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/index.jsx
@@ -413,7 +413,7 @@
   */
  handleActionSubmit = () => {
    const { elements } = this.state
    let color = { primary: '#1890ff', yellow: '#c49f47', orange: 'orange', danger: '#ff4d4f', green: '#26C281', dgreen: '#32c5d2', purple: '#8E44AD', cyan: '#13c2c2', gray: '#666666' }
    let color = { primary: '#1890ff', yellow: '#c49f47', orange: 'orange', danger: '#ff4d4f', green: '#26C281', dgreen: '#32c5d2', purple: '#8E44AD', cyan: '#13c2c2', gray: '#666666', default: 'rgba(0, 0, 0, 0.65)' }
    this.actionFormRef.handleConfirm().then(res => {
      let _elements = elements.map(cell => {
src/menu/components/share/actioncomponent/dragaction/card.jsx
@@ -1,7 +1,7 @@
import React from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { Button, Popover } from 'antd'
import { CopyOutlined, EditOutlined, FontColorsOutlined, CloseOutlined, ProfileOutlined, WarningOutlined } from '@ant-design/icons'
import { CopyOutlined, EditOutlined, FontColorsOutlined, CloseOutlined, ProfileOutlined, WarningOutlined, DisconnectOutlined } from '@ant-design/icons'
import MkIcon from '@/components/mk-icon'
import { resetStyle } from '@/utils/utils-custom.js'
@@ -31,10 +31,17 @@
  const opacity = isDragging ? 0.5 : 1
  let hasProfile = false
  let forbidSql = false
  if (['pop', 'prompt', 'exec'].includes(card.OpenType)) {
    hasProfile = true
    if (card.verify && card.verify.default === 'false') {
      forbidSql = true
    }
  } else if (card.OpenType === 'excelIn' || card.OpenType === 'excelOut') {
    hasProfile = true
    if (card.verify && card.verify.default === 'false') {
      forbidSql = true
    }
  } else if (card.funcType === 'print') {
    hasProfile = true
  } else if (card.funcType === 'megvii') {
@@ -56,6 +63,8 @@
  let warning = null
  if (card.OpenType === 'innerpage' && !card.pageTemplate) {
    warning = <WarningOutlined style={{color: 'orange', marginLeft: '5px'}}/>
  } else if (forbidSql) {
    warning = <DisconnectOutlined className="mk-disconnect"/>
  }
  if (show === 'icon') {
src/menu/components/share/actioncomponent/formconfig.jsx
@@ -1464,6 +1464,23 @@
      required: true
    },
    {
      type: 'radio',
      key: 'show',
      label: '显示为',
      initVal: card.show || 'button',
      required: true,
      options: [{
        value: 'icon',
        text: '图标'
      }, {
        value: 'button',
        text: '图标+文字'
      }, {
        value: 'link',
        text: '文字+图标'
      }]
    },
    {
      type: 'icon',
      key: 'icon',
      label: '图标',
src/menu/components/share/actioncomponent/index.jsx
@@ -257,7 +257,7 @@
   */
  handleSubmit = () => {
    const { config } = this.props
    let color = { primary: '#1890ff', yellow: '#c49f47', orange: 'orange', danger: '#ff4d4f', green: '#26C281', dgreen: '#32c5d2', purple: '#8E44AD', cyan: '#13c2c2', gray: '#666666', default: '#333333' }
    let color = { primary: '#1890ff', yellow: '#c49f47', orange: 'orange', danger: '#ff4d4f', green: '#26C281', dgreen: '#32c5d2', purple: '#8E44AD', cyan: '#13c2c2', gray: '#666666', default: 'rgba(0, 0, 0, 0.65)' }
    let _actionlist = fromJS(this.state.actionlist).toJS()
    
    this.actionFormRef.handleConfirm().then(btn => {
@@ -272,7 +272,9 @@
        if (item.uuid === btn.uuid) {
          if (config.subtype === 'basetable') {
            let _c = btn.class.replace('border-', '')
            if (btn.class.indexOf('border') > -1 || btn.class === 'default') {
            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[_c], backgroundColor: '#fff', borderColor: color[_c], marginRight: '15px'}
            } else {
              btn.style = {color: '#fff', backgroundColor: color[_c], borderColor: color[_c], marginRight: '15px'}
src/menu/components/share/actioncomponent/index.scss
@@ -29,6 +29,12 @@
        text-decoration: inherit;
        font-weight: inherit;
      }
      .mk-disconnect {
        font-size: 10px;
        position: absolute;
        right: 1px;
        top: 0px;
      }
    }
    .swiper {
      margin-left: 10px;
src/menu/components/tabs/table-tabs/index.jsx
@@ -40,7 +40,6 @@
        uuid: tabs.uuid,
        type: tabs.type,
        subtype: 'tabletabs',
        width: 24,
        setting: {},
        style: {},
        subtabs: [
src/menu/transfer/index.jsx
New file
@@ -0,0 +1,264 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Modal, Button, notification } from 'antd'
import moment from 'moment'
import md5 from 'md5'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import { getTables } from '@/utils/utils-custom.js'
// import MKEmitter from '@/utils/events.js'
import './index.scss'
const { confirm } = Modal
class Transfer extends Component {
  static propTpyes = {
    config: PropTypes.object,
    updateConfig: PropTypes.func
  }
  state = {}
  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) => {
    let _config = fromJS(this.props.config).toJS()
    _config.permission = 'true'
    _config.Template = 'CustomPage'
    _config.version = 2.0
    _config.enabled = false
    delete _config.autoMatic
    let useMSearch = false
    _config.components.forEach((item, i) => {
      if (item.type === 'tabs') {
        item.name = '标签组' + i
        item.width = 24
        item.subtype = 'tabs'
        item.setting = {autoSwitch: 'false', blacklist: [], name: item.name, position: 'top', supModule: [], tabStyle: 'line', width: 24}
        item.subtabs.forEach(tab => {
          tab.components[0].subtype = 'normaltable'
          tab.components[0].width = 24
          tab.components[0].wrap.width = 24
          tab.components[0].wrap.name = tab.components[0].name
          if (tab.components[0].setting.useMSearch === 'true') {
            useMSearch = true
          }
          tab.components[0].action.forEach(btn => {
            if (btn.OpenType === 'popview' && btn.config) {
              btn.config.Template = 'CustomPage'
              if (btn.config.components[0]) {
                btn.config.components[0].subtype = 'normaltable'
              }
            }
          })
          tab.components[0].cols.forEach(col => {
            if (col.type !== 'action') return
            col.elements.forEach(btn => {
              if (btn.OpenType === 'popview' && btn.config) {
                btn.config.Template = 'CustomPage'
                if (btn.config.components[0]) {
                  btn.config.components[0].subtype = 'normaltable'
                }
              }
            })
          })
        })
      } else {
        item.subtype = 'normaltable'
        item.width = 24
        item.wrap.width = 24
        item.wrap.name = item.name
        item.action.forEach(btn => {
          if (btn.OpenType === 'popview' && btn.config) {
            btn.config.Template = 'CustomPage'
            if (btn.config.components[0]) {
              btn.config.components[0].subtype = 'normaltable'
            }
          }
        })
        item.cols.forEach(col => {
          if (col.type !== 'action') return
          col.elements.forEach(btn => {
            if (btn.OpenType === 'popview' && btn.config) {
              btn.config.Template = 'CustomPage'
              if (btn.config.components[0]) {
                btn.config.components[0].subtype = 'normaltable'
              }
            }
          })
        })
      }
    })
    if (useMSearch) {
      let cell = {
        uuid: Utils.getuuid(),
        type: 'search',
        width: 24,
        subtype: 'mainsearch',
        name: '搜索',
        search: _config.components[0].search || [],
        style: {borderBottomColor: '#f0f0f0', borderBottomWidth: '1px'},
        wrap: {float: 'left', blacklist: [], name: '搜索', width: 24}
      }
      cell.wrap.advanceType = _config.components[0].wrap.advanceType || 'modal'
      cell.wrap.advanceWidth = _config.components[0].wrap.advanceWidth || 1000
      cell.wrap.searchLwidth = _config.components[0].wrap.searchLwidth || 33.3
      cell.wrap.searchRatio = _config.components[0].wrap.searchRatio || 6
      cell.wrap.show = _config.components[0].wrap.show || 'true'
      if (cell.wrap.advanceType === 'drawer') {
        cell.wrap.drawerPlacement = _config.components[0].wrap.drawerPlacement || 'left'
      }
      _config.components[0].search = []
      _config.components[0].setting.useMSearch = 'true'
      _config.components.unshift(cell)
      _config.components[0].$tables = getTables(_config.components[0])
      _config.components[1].$tables = getTables(_config.components[1])
    }
    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)
          }
        })
      } 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: 'custom'
    }
    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 || 'newtab', hidden: _config.hidden || 'false'}),
      open_edition: _config.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)
    Api.getSystemConfig(param).then(res => {
      _resolve()
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        return
      }
      localStorage.setItem('menuUpdate', new Date().getTime())
      notification.success({
        top: 92,
        message: '切换成功。',
        duration: 2
      })
      delete urlparam.type
      let _param = window.btoa(window.encodeURIComponent(JSON.stringify(urlparam)))
      setTimeout(() => {
        window.history.replaceState(null, null, window.location.href.split('#')[0] + `#/menudesign/${_param}`)
        window.location.reload()
      }, 2000)
    })
  }
  render() {
    return (
      <div className="mk-replace-field" style={{display: 'inline-block'}}>
        <Button className="mk-border-green" icon="retweet" onClick={this.trigger}>模板切换</Button>
      </div>
    )
  }
}
export default Transfer
src/menu/transfer/index.scss
New file
@@ -0,0 +1,9 @@
.replace-field-modal {
  .ant-modal {
    top: 70px;
  }
  .ant-modal-body {
    min-height: 150px;
    padding-top: 40px;
  }
}
src/tabviews/basetable/index.jsx
@@ -17,6 +17,7 @@
const MkBaseTable = asyncComponent(() => import('@/tabviews/custom/components/table/base-table'))
const SettingComponent = asyncComponent(() => import('@/tabviews/zshare/settingcomponent'))
const TableNodes = asyncComponent(() => import('@/tabviews/zshare/tablenodes'))
const AutoMatic = asyncComponent(() => import('@/tabviews/zshare/automatic'))
const DebugTable = asyncComponent(() => import('@/tabviews/debugtable'))
class BasePage extends Component {
@@ -42,7 +43,8 @@
    data: null,           // 列表数据集
    loading: false,       // 列表数据加载中
    visible: false,       // 标签页控制
    shortcuts: null       // 快捷键
    shortcuts: null,      // 快捷键
    autoMatic: null
  }
  /**
@@ -155,6 +157,20 @@
      }
      config.components = this.filterComponent(config.components, roleId, window.GLOB.mkActions, skip, param, MenuID)
      let autoMatic = null
      if (config.autoMatic && config.autoMatic.enable === 'true') {
        config.components[0].action.forEach(item => {
          if (item.uuid === config.autoMatic.action) {
            autoMatic = config.autoMatic
            autoMatic.OpenType = item.execMode || item.OpenType
            config.components[0].wrap.selected = 'false'
            config.components[0].MenuID = config.components[0].uuid
            config.components[0].autoMatic = true
            item.autoMatic = true
          }
        })
      }
      
      // 获取主搜索条件
      let mainSearch = []
@@ -181,6 +197,7 @@
        BID: BID,
        shortcuts: shortcuts.length > 0 ? shortcuts : null,
        config,
        autoMatic,
        mainSearch
      }, () => {
        setTimeout(() => { // 延时加载状态
@@ -266,6 +283,9 @@
        item.subtabs = item.subtabs.map(tab => {
          tab.components[0].name = tab.label
          if (tab.permission !== 'true') { // 权限未开启不做权限控制
            skip = true
          }
          tab.components = this.filterComponent(tab.components, roleId, permAction, skip, urlparam, pageId)
          return tab
        })
@@ -586,13 +606,14 @@
  }
  render() {
    const { loadingview, viewlost, config, loading, shortcuts } = this.state
    const { loadingview, viewlost, config, loading, shortcuts, autoMatic } = this.state
    return (
      <div className={'custom-page-wrap ' + (loadingview || loading ? 'loading' : '')} id={this.state.ContainerId} style={config ? config.style : null}>
        {(loadingview || loading) ? <Spin className="view-spin" size="large" /> : null}
        <Row className="component-wrap">{this.getComponents()}</Row>
        {config && window.GLOB.breakpoint ? <DebugTable /> : null}
        {!window.GLOB.mkHS && config && autoMatic ? <AutoMatic autoMatic={autoMatic} config={config.components[0]} /> : null}
        {!window.GLOB.mkHS && window.GLOB.systemType !== 'production' ? <TableNodes config={config} /> : null}
        {!window.GLOB.mkHS && config ? <SettingComponent config={config} dict={this.state.dict} shortcuts={shortcuts || []}/> : null}
        {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
src/tabviews/custom/components/share/normalTable/index.jsx
@@ -409,6 +409,7 @@
    loading: PropTypes.bool,         // 表格加载中
    refreshdata: PropTypes.func,     // 表格中排序列、页码的变化时刷新
    chgSelectData: PropTypes.func,   // 数据切换
    autoMatic: PropTypes.any
  }
  state = {
@@ -548,9 +549,17 @@
  }
  componentDidMount () {
    MKEmitter.addListener('mkCheckTopLine', this.mkCheckTopLine)
    const { autoMatic } = this.props
    MKEmitter.addListener('mkCheckAll', this.mkCheckAll)
    MKEmitter.addListener('resetTable', this.resetTable)
    if (autoMatic === true) {
      MKEmitter.addListener('autoQueryData', this.autoQueryData)
      MKEmitter.addListener('autoSelectData', this.autoSelectData)
    }
    MKEmitter.addListener('mkCheckTopLine', this.mkCheckTopLine)
  }
  /**
@@ -560,9 +569,50 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('mkCheckTopLine', this.mkCheckTopLine)
    MKEmitter.removeListener('mkCheckAll', this.mkCheckAll)
    MKEmitter.removeListener('resetTable', this.resetTable)
    MKEmitter.removeListener('autoQueryData', this.autoQueryData)
    MKEmitter.removeListener('autoSelectData', this.autoSelectData)
    MKEmitter.removeListener('mkCheckTopLine', this.mkCheckTopLine)
  }
  autoSelectData = (id, index) => {
    if (id !== this.props.MenuID) return
    const { pageSize, pageIndex } = this.state
    let i = index - (pageIndex - 1) * pageSize - 1
    if (this.props.data[i]) {
      this.changeRow(this.props.data[i], i)
      MKEmitter.emit('autoTransSelectData', this.props.MenuID, this.props.data[i])
    } else {
      MKEmitter.emit('autoMaticOver', this.props.MenuID)
    }
  }
  autoQueryData = (id, index) => {
    if (id !== this.props.MenuID) return
    const { total } = this.props
    const { pageSize } = this.state
    if (index !== 1 && (!total || index > total)) {
      MKEmitter.emit('autoMaticOver', this.props.MenuID)
      return
    }
    console.clear()
    let pageIndex = Math.ceil(index / pageSize)
    this.setState({
      pageIndex: pageIndex,
      selectedRowKeys: [],
      activeIndex: null
    })
    this.props.refreshdata({pageIndex})
  }
  mkCheckTopLine = (menuId, id) => {
src/tabviews/custom/components/table/base-table/index.jsx
@@ -206,10 +206,22 @@
        total: result.total,
        loading: false
      })
      if (config.autoMatic) {
        if (result.data && result.data.length > 0) {
          MKEmitter.emit('autoGetData', config.MenuID)
        } else {
          MKEmitter.emit('autoMaticOver', config.MenuID)
        }
      }
    } else {
      this.setState({
        loading: false
      })
      if (config.autoMatic) {
        MKEmitter.emit('autoMaticError', config.MenuID)
      }
      
      if (result.ErrCode === 'N') {
        Modal.error({
@@ -405,21 +417,29 @@
   * @description 表格条件改变时重置数据(分页或排序)
   */
  refreshbytable = (pagination, filters, sorter) => {
    if (sorter.order) {
      let _chg = {
        ascend: 'asc',
        descend: 'desc'
    if (!sorter) { // 无人值守
      this.setState({
        pageIndex: pagination.pageIndex
      }, () => {
        this.loadmaindata()
      })
    } else {
      if (sorter.order) {
        let _chg = {
          ascend: 'asc',
          descend: 'desc'
        }
        sorter.order = _chg[sorter.order]
      }
      sorter.order = _chg[sorter.order]
      this.setState({
        pageIndex: pagination.current,
        pageSize: pagination.pageSize,
        orderBy: (sorter.field && sorter.order) ? `${sorter.field} ${sorter.order}` : ''
      }, () => {
        this.loadmaindata()
      })
    }
    this.setState({
      pageIndex: pagination.current,
      pageSize: pagination.pageSize,
      orderBy: (sorter.field && sorter.order) ? `${sorter.field} ${sorter.order}` : ''
    }, () => {
      this.loadmaindata()
    })
  }
  /**
@@ -558,20 +578,20 @@
  render() {
    const { BID, setting, actions, config, columns, selectedData, BData, data } = this.state
    return (
      <div className="custom-base-table" style={config.style}>
        {config.search.length ?
          <MainSearch BID={BID} config={config} refreshdata={this.refreshbysearch}/> : null
        }
        {actions.length ? <MainAction
        {actions.length > 0 ? <MainAction
          BID={BID}
          setting={setting}
          actions={actions}
          BData={BData}
          columns={config.columns}
          selectedData={selectedData}
        /> : <div style={{height: '15px'}}></div>}
        /> : <div style={{height: '25px'}}></div>}
        <div className="main-table-box">
          <MainTable
            data={data}
@@ -580,6 +600,7 @@
            MenuID={config.uuid}
            fields={config.columns}
            total={this.state.total}
            autoMatic={config.autoMatic}
            lineMarks={config.lineMarks}
            loading={this.state.loading}
            refreshdata={this.refreshbytable}
src/tabviews/custom/components/table/base-table/index.scss
@@ -9,8 +9,7 @@
    border-bottom: 1px solid #efefef;
  }
  >.button-list.toolbar-button {
    padding: 5px 0px;
    line-height: 45px;
    min-height: 60px;
    padding-right: 60px;
    button {
      margin-right: 0px;
src/tabviews/custom/components/table/normal-table/index.jsx
@@ -706,15 +706,15 @@
            {config.search && config.search.length ?
              <MainSearch BID={BID} config={config} refreshdata={this.refreshbysearch}/> : null
            }
            <MainAction
            {actions.length > 0 ? <MainAction
              BID={BID}
              setting={setting}
              actions={actions}
              BData={BData}
              columns={config.columns}
              selectedData={selectedData}
            />
            <div className={'main-table-box ' + (!actions || actions.length === 0 ? 'no-action' : '')}>
            /> : <div style={{height: '25px'}}></div>}
            <div className="main-table-box">
              <MainTable
                setting={setting}
                columns={columns}
@@ -735,14 +735,14 @@
          {config.search && config.search.length ?
            <MainSearch BID={BID} config={config} refreshdata={this.refreshbysearch}/> : null
          }
          <MainAction
          {actions.length > 0 ? <MainAction
            BID={BID}
            setting={setting}
            actions={actions}
            BData={BData}
            columns={config.columns}
            selectedData={selectedData}
          />
          /> : <div style={{height: '15px'}}></div>}
          <div className={'main-table-box ' + (!actions || actions.length === 0 ? 'no-action' : '')}>
            <MainTable
              setting={setting}
src/tabviews/custom/components/table/normal-table/index.scss
@@ -9,8 +9,7 @@
    border-bottom: 1px solid #efefef;
  }
  >.button-list.toolbar-button {
    padding: 0;
    line-height: 45px;
    min-height: 60px;
    padding-right: 60px;
    button {
      margin-right: 0px;
@@ -43,15 +42,6 @@
    }
    >.async-spin {
      line-height: 150px!important;
    }
  }
  .no-action.main-table-box {
    .main-pickup {
      position: relative;
      right: 0px;
      top: 0px;
      z-index: 2;
      float: right;
    }
  }
  .ant-collapse {
src/tabviews/custom/popview/index.jsx
@@ -996,7 +996,7 @@
    const { viewlost, config, loading } = this.state
    return (
      <div className={'pop-page-wrap ' + (loading ? 'loading' : '')} style={config.style}>
      <div className={'pop-page-wrap ' + (loading ? 'loading' : '')} style={config ? config.style : null}>
        {loading ? <Spin className="view-spin" size="large" /> : null}
        <Row className="component-wrap">{this.getComponents()}</Row>
        {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
src/tabviews/debugtable/index.jsx
@@ -26,6 +26,7 @@
    setting: {
      interType: 'system',
      execute: true,
      laypage: true,
      dataresource: '(select * from s_debug_value_log where createuserid=@userid@) tb'
    },
    arr_field: 'ID,Sort,CDefine1,CDefine2,CDefine3,CDefine4,CDefine5,CDefine6,CDefine7,createdate'
@@ -41,7 +42,7 @@
      loading: true
    })
    let param = UtilsDM.getQueryDataParams(setting, arr_field, [], 'sort', 1, 9999, '')
    let param = UtilsDM.getQueryDataParams(setting, arr_field, [], 'sort', 1, 50, '')
    let result = await Api.genericInterface(param)
src/tabviews/zshare/settingcomponent/index.jsx
@@ -41,7 +41,7 @@
    if (config.Template === 'CommonTable' || config.Template === 'TreePage') {
      this.getPageConfig()
    } else if (config.Template === 'CustomPage') {
    } else if (config.Template === 'CustomPage' || config.Template === 'BaseTable') {
      this.getCustomPageConfig()
    } else {
      notification.warning({
@@ -82,7 +82,7 @@
          if (cell.OpenType === 'funcbutton' && cell.funcType === 'print') {
            cell.$port = cell.verify ? cell.verify.linkUrl : ''
            if (cell.verify && cell.verify.printerTypeList) {
            if (cell.verify && cell.verify.printerTypeList && cell.verify.printerTypeList.length > 0) {
              cell.verify.printerTypeList = cell.verify.printerTypeList.map(_cell => {
                _cell.uuid = _cell.uuid || _cell.key
                _cell.parentId = cell.uuid
@@ -106,7 +106,7 @@
              if (cell.OpenType === 'funcbutton' && cell.funcType === 'print') {
                cell.$port = cell.verify ? cell.verify.linkUrl : ''
                if (cell.verify && cell.verify.printerTypeList) {
                if (cell.verify && cell.verify.printerTypeList && cell.verify.printerTypeList.length > 0) {
                  cell.verify.printerTypeList = cell.verify.printerTypeList.map(_cell => {
                    _cell.uuid = _cell.uuid || _cell.key
                    _cell.parentId = cell.uuid
@@ -119,7 +119,7 @@
                printbtns.push(cell)
              }
              _comp.action.push({...cell, ...(userConfig[cell.uuid] || {})})
              _comp.action.push({...cell, $line: true, ...(userConfig[cell.uuid] || {})})
            })
            card.backElements && card.backElements.forEach(cell => {
              if (cell.eleType !== 'button') return
@@ -127,7 +127,7 @@
              if (cell.OpenType === 'funcbutton' && cell.funcType === 'print') {
                cell.$port = cell.verify ? cell.verify.linkUrl : ''
                if (cell.verify && cell.verify.printerTypeList) {
                if (cell.verify && cell.verify.printerTypeList && cell.verify.printerTypeList.length > 0) {
                  cell.verify.printerTypeList = cell.verify.printerTypeList.map(_cell => {
                    _cell.uuid = _cell.uuid || _cell.key
                    _cell.parentId = cell.uuid
@@ -140,7 +140,7 @@
                printbtns.push(cell)
              }
              _comp.action.push({...cell, ...(userConfig[cell.uuid] || {})})
              _comp.action.push({...cell, $line: true, ...(userConfig[cell.uuid] || {})})
            })
          })
        } else if (item.type === 'table') {
@@ -151,7 +151,7 @@
              if (cell.OpenType === 'funcbutton' && cell.funcType === 'print') {
                cell.$port = cell.verify ? cell.verify.linkUrl : ''
                if (cell.verify && cell.verify.printerTypeList) {
                if (cell.verify && cell.verify.printerTypeList && cell.verify.printerTypeList.length > 0) {
                  cell.verify.printerTypeList = cell.verify.printerTypeList.map(_cell => {
                    _cell.uuid = _cell.uuid || _cell.key
                    _cell.parentId = cell.uuid
@@ -164,7 +164,7 @@
                printbtns.push(cell)
              }
              _comp.action.push({...cell, ...(userConfig[cell.uuid] || {})})
              _comp.action.push({...cell, $line: true, ...(userConfig[cell.uuid] || {})})
            })
          })
        } 
@@ -269,7 +269,7 @@
              item.printer = _item ? (_item.printer || '') : ''
              item.$port = item.verify ? item.verify.linkUrl : ''
              if (item.verify && item.verify.printerTypeList) {
              if (item.verify && item.verify.printerTypeList && item.verify.printerTypeList.length > 0) {
                item.verify.printerTypeList = item.verify.printerTypeList.map(cell => {
                  cell.uuid = cell.uuid || cell.key
                  cell.parentId = item.uuid
@@ -424,7 +424,7 @@
    components.forEach(com => {
      com.action.forEach(item => {
        if (item.shortcut && item.shortcut.length > 0) {
        if (item.shortcut && item.shortcut.length > 0 && !item.$line) {
          _LongParam.action.push({uuid: item.uuid, parentId: com.uuid, shortcut: item.shortcut, $shortcut: item.shortcut.join('+')})
        }
        if (item.funcType === 'print' && (item.printer || item.verify.printerTypeList)) {
@@ -531,6 +531,7 @@
          ]}
          destroyOnClose
        >
          <div className="tip">注:行级按钮快捷键设置无效。</div>
          {components && components.length > 0 ? components.map(item => (
            <div key={item.uuid}>
              <p className="component-title">{item.title}</p>
src/tabviews/zshare/settingcomponent/index.scss
@@ -29,6 +29,12 @@
      padding-top: 0px;
      position: relative;
      .tip {
        float: right;
        margin-top: 10px;
        color: #b6b6b6;
      }
      .ant-spin {
        position: absolute;
        left: calc(50% - 22px);
src/templates/comtableconfig/index.jsx
@@ -28,7 +28,7 @@
const Versions = asyncComponent(() => import('@/menu/versions'))
const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
// const UpdateTable = asyncComponent(() => import('./updatetable'))
const UpdateTable = asyncComponent(() => import('./updatetable'))
const Unattended = asyncComponent(() => import('@/templates/zshare/unattended'))
const EditComponent = asyncComponent(() => import('@/templates/zshare/editcomponent'))
const SettingComponent = asyncComponent(() => import('@/templates/sharecomponent/settingcomponent'))
@@ -1268,7 +1268,7 @@
                <Versions MenuId={menu.MenuID} open_edition={openEdition} updateConfig={this.refreshConfig}/>
                <ReplaceField type="table" config={config} updateConfig={this.updateconfig}/>
                <EditComponent type="table" options={['search', 'form', 'action', 'columns']} config={this.state.config} MenuID={this.props.menu.MenuID} thawButtons={this.state.thawButtons} refresh={this.editConfig}/>
                {/* <UpdateTable config={config}/> */}
                <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/comtableconfig/updatetable/index.jsx
@@ -3,10 +3,12 @@
import { is, fromJS } from 'immutable'
import { Modal, Button, notification } from 'antd'
import { ArrowUpOutlined } from '@ant-design/icons'
// import moment from 'moment'
import moment from 'moment'
import md5 from 'md5'
import { colorTransform } from '@/utils/option.js'
// import Api from '@/api'
import { getTables } from '@/utils/utils-custom.js'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import './index.scss'
@@ -51,21 +53,27 @@
  execUpdate = (_resolve) => {
    const { config } = this.props
    let uuid = config.uuid
    let trail = md5(uuid).slice(-10) + 'mk'
    uuid = uuid.replace(/.{12}$/, trail)
    let _config = {
      version: 1.0,
      uuid: config.uuid,
      MenuID: config.uuid,
      uuid: uuid,
      MenuID: uuid,
      fstMenuId: config.fstMenuId,
      parentId: config.ParentId,
      Template: 'BaseTable',
      easyCode: config.easyCode,
      enabled: false,
      MenuName: config.MenuName,
      MenuNo: config.MenuNo,
      MenuName: config.MenuName + '_new',
      MenuNo: config.MenuNo + '_new',
      OpenType: 'newtab',
      tables: config.tables || [],
      urlFields: config.urlFields || [],
      hidden: config.hidden,
      hidden: config.hidden || 'false',
      autoMatic: {},
      Remark: config.Remark,
      Remark: config.Remark || '',
      components: [],
      viewType: 'menu',
      style: { backgroundColor: '#ffffff', paddingTop: '16px', paddingBottom: '80px', paddingLeft: '16px', paddingRight: '16px'},
@@ -75,46 +83,663 @@
    let formActions = []
    let popActions = []
    let errors = []
    let mainTb = {name: '主表', uuid: Utils.getuuid(), useMSearch: 'false'}
    let tbl = this.getTable(config, uuids, errors, formActions, popActions, '主表')
    let oldtabs = {
      mainTable: mainTb.uuid
    }
    let tbl = this.getTable(config, mainTb, uuids, errors, formActions, popActions, oldtabs)
    if (config.autoMatic && config.autoMatic.enable === 'true' && uuids[config.autoMatic.action]) {
      _config.autoMatic = {...config.autoMatic}
      _config.autoMatic.action = uuids[config.autoMatic.action]
      if (tbl.action.filter(item => item.uuid === _config.autoMatic.action && (['pop', 'prompt', 'exec'].includes(item.OpenType) || (item.OpenType === 'funcbutton' && item.funcType === 'print'))).length === 0) {
        _config.autoMatic = {enable: 'false'}
      }
    } else {
      _config.autoMatic = {enable: 'false'}
    }
    _config.components.push(tbl)
    let _tbs = []
    if (config.tabgroups && config.tabgroups.length > 0) {
      config.tabgroups.forEach(m => {
        if (!m.sublist || m.sublist.length === 0) return
        let tabs = {
          uuid: Utils.getuuid(),
          type: 'tabs',
          subtype: 'tabletabs',
          setting: {},
          style: {},
          subtabs: m.sublist.map(n => {
            let tab = { uuid: Utils.getuuid(), label: n.label, icon: n.icon, permission: 'false', components: [
              {
                uuid: Utils.getuuid(),
                linkTab: n.linkTab,
                name: n.label,
                useMSearch: n.searchPass === 'true' ? 'true' : 'false',
                supModule: n.supMenu || '',
                equalTab: n.equalTab && n.equalTab.length > 0 ? n.equalTab[0] : ''
              }
            ]}
            oldtabs[n.uuid] = tab.components[0].uuid
            _tbs.push(tab.components[0])
            return tab
          })
        }
        _config.components.push(tabs)
      })
    }
    console.log(config)
    console.log(_config)
    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
          }
        })
    setTimeout(() => {
      _resolve()
    }, 5000)
        _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], uuids, errors, formActions, popActions, oldtabs)
              return tab
            })
          }
          return item
        })
        this.setPopView(_resolve, _config, formActions, popActions, errors)
      })
    } else {
      this.setPopView(_resolve, _config, formActions, popActions, errors)
    }
  }
  getTable = (config, uuids, errors, formActions, popActions, name) => {
  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,
                      enabled: false,
                      MenuName: btn.label,
                      tables: _config.tables || [],
                      Template: 'BaseTable',
                      components: [this.getTable(menus[btn.uuid], mainTb, {}, errors, formActions)],
                      viewType: 'popview',
                      style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
                    }
                  } else {
                    errors.push(tab.label + '中按钮《' + btn.label + '》配置信息丢失')
                  }
                }
              })
              tab.components[0].cols.forEach(col => {
                if (col.type !== 'action') return
                col.elements.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,
                        enabled: false,
                        MenuName: btn.label,
                        tables: _config.tables || [],
                        Template: 'BaseTable',
                        components: [this.getTable(menus[btn.uuid], mainTb, {}, errors, formActions)],
                        viewType: 'popview',
                        style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
                      }
                    } else {
                      errors.push(tab.label + '中按钮《' + btn.label + '》配置信息丢失')
                    }
                  }
                })
              })
            })
          } else {
            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,
                    enabled: false,
                    MenuName: btn.label,
                    tables: _config.tables || [],
                    Template: 'BaseTable',
                    components: [this.getTable(menus[btn.uuid], mainTb, {}, errors, formActions)],
                    viewType: 'popview',
                    style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
                  }
                } else {
                  errors.push('主表中按钮《' + btn.label + '》配置信息丢失')
                }
              }
            })
            item.cols.forEach(col => {
              if (col.type !== 'action') return
              col.elements.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,
                      enabled: false,
                      MenuName: btn.label,
                      tables: _config.tables || [],
                      Template: 'BaseTable',
                      components: [this.getTable(menus[btn.uuid], mainTb, {}, errors, formActions)],
                      viewType: 'popview',
                      style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
                    }
                  } else {
                    errors.push('主表中按钮《' + btn.label + '》配置信息丢失')
                  }
                }
              })
            })
          }
        })
        this.setPopForm(_resolve, _config, formActions, errors)
      })
    } else {
      this.setPopForm(_resolve, _config, formActions, errors)
    }
  }
  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 !== 'action') return
                col.elements.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 + '》配置信息丢失')
                    }
                  }
                })
              })
            })
          } else {
            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 !== 'action') return
              col.elements.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 + '》配置信息丢失')
                  }
                }
              })
            })
          }
        })
        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 !== 'action') return
      col.elements.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 + '》配置信息丢失')
          }
        }
      })
    })
  }
  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 !== 'action') return
            col.elements.forEach(btn => {
              if (btn.OpenType === 'popview' && btn.config) {
                btn.config.$tables = getTables(btn.config.components[0])
              }
            })
          })
          tab.components[0].$tables = getTables(tab.components[0])
        })
      } else {
        item.action.forEach(btn => {
          if (btn.OpenType === 'popview' && btn.config) {
            btn.config.$tables = getTables(btn.config.components[0])
          }
        })
        item.cols.forEach(col => {
          if (col.type !== 'action') return
          col.elements.forEach(btn => {
            if (btn.OpenType === 'popview' && btn.config) {
              btn.config.$tables = getTables(btn.config.components[0])
            }
          })
        })
        item.$tables = getTables(item)
      }
    })
    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)
          }
          tab.components[0].errors = []
          let columns = tab.components[0].columns.map(c => c.field)
          if (tab.components[0].setting.interType === 'system' && tab.components[0].setting.execute !== 'false' && !tab.components[0].setting.dataresource) {
            tab.components[0].errors.push({ level: 0, detail: '未设置数据源!'})
          } else if (tab.components[0].setting.interType === 'system' && tab.components[0].setting.execute === 'false' && tab.components[0].scripts.filter(script => script.status !== 'false').length === 0) {
            tab.components[0].errors.push({ level: 0, detail: '数据源中无可用脚本!'})
          } else if (!tab.components[0].setting.primaryKey) {
            tab.components[0].errors.push({ level: 0, detail: '未设置主键!'})
          } else if (!columns.includes(tab.components[0].setting.primaryKey)) {
            tab.components[0].errors.push({ level: 0, detail: '主键已失效!'})
          } else if (!tab.components[0].setting.supModule) {
            tab.components[0].errors.push({ level: 0, detail: '未设置上级组件!'})
          }
        })
      } else {
        if (item.$tables) {
          tbs.push(...item.$tables)
        }
        item.errors = []
        let columns = item.columns.map(c => c.field)
        if (item.setting.interType === 'system' && item.setting.execute !== 'false' && !item.setting.dataresource) {
          item.errors.push({ level: 0, detail: '未设置数据源!'})
        } else if (item.setting.interType === 'system' && item.setting.execute === 'false' && item.scripts.filter(script => script.status !== 'false').length === 0) {
          item.errors.push({ level: 0, detail: '数据源中无可用脚本!'})
        } else if (!item.setting.primaryKey) {
          item.errors.push({ level: 0, detail: '未设置主键!'})
        } else if (!columns.includes(item.setting.primaryKey)) {
          item.errors.push({ level: 0, detail: '主键已失效!'})
        } else if (!item.setting.supModule) {
          item.errors.push({ level: 0, detail: '未设置上级组件!'})
        }
      }
    })
    this.submitConfig(_resolve, _config, tbs)
  }
  submitConfig = (_resolve, config, tbs) => {
    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: 'BaseTable', OpenType: 'newtab', hidden: config.hidden},
      MenuType: 'BaseTable'
    }
    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: 'BaseTable',
      MenuName: config.MenuName || '',
      PageParam: JSON.stringify({Template: 'BaseTable', 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)
    new Promise(resolve => {
      Api.getSystemConfig(param).then(res => {
        resolve(res)
      })
    // }).then(res => { // 删除原菜单
    //   if (!res || !res.status) return res
    //   return Api.getSystemConfig({
    //     func: 'sPC_MainMenu_Del',
    //     MenuID: this.props.config.uuid
    //   })
    }).then(res => {
      if (!res) return
      _resolve()
      if (res.status) {
        localStorage.setItem('menuUpdate', new Date().getTime())
        notification.success({
          top: 92,
          message: '升级成功',
          duration: 2
        })
        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] + `#/tabledesign/${_param}`)
        // window.location.reload()
        window.open(`#/tabledesign/${_param}`)
      } else {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
      }
    })
  }
  getTable = (config, newCon, uuids, errors, formActions, popActions, oldtabs) => {
    let _card = {
      uuid: Utils.getuuid(),
      uuid: newCon.uuid,
      type: 'table',
      name: name,
      name: newCon.name,
      format: 'array',
      pageable: true,
      switchable: true,
      search: config.search.map(item => {
        item.uuid = Utils.getuuid()
        return item
      }),
      search: [],
      action: [],
      subtype: 'basetable',
      setting: { },
      wrap: { },
      setting: { useMSearch: newCon.useMSearch },
      wrap: {},
      style: {},
      headerStyle: {},
      columns: [],
@@ -122,12 +747,28 @@
      scripts: []
    }
    if (!config) {
      errors.push(newCon.name + '配置信息丢失')
      return _card
    }
    if (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(', '))
        _colspan.push(...col.subfield.split(', '))
      }
      if (!col.field) return
@@ -317,7 +958,7 @@
    }
    let colbtns = []
    let colors = { primary: '#1890ff', yellow: '#c49f47', orange: 'orange', danger: '#ff4d4f', green: '#26C281', dgreen: '#32c5d2', purple: '#8E44AD', cyan: '#13c2c2', gray: '#666666', default: '#333333' }
    let colors = { primary: '#1890ff', yellow: '#c49f47', orange: 'orange', danger: '#ff4d4f', green: '#26C281', dgreen: '#32c5d2', purple: '#8E44AD', cyan: '#13c2c2', gray: '#666666', default: 'rgba(0, 0, 0, 0.65)' }
    config.action.forEach(btn => {
      let _c = btn.class ? btn.class.replace('border-', '') : ''
@@ -327,23 +968,54 @@
      delete _btn.position
      delete _btn.linkTab
      _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'
      }
      uuids[btn.uuid] = _btn.uuid
      if (btn.OpenType === 'pop' || (btn.OpenType === 'funcbutton' && btn.funcType === 'print' && btn.execMode === 'pop')) {
        formActions.push({origin: btn.uuid, uuid: _btn.uuid, name: name, label: btn.label})
        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: name, label: btn.label})
        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' || !btn.linkmenu || btn.linkmenu.length !== 3) {
          errors.push(name + '中按钮《' + btn.label + '》不在支持')
          errors.push(newCon.name + '中按钮《' + btn.label + '》不在支持')
          return
        }
      }
      if (_btn.tabType === 'CommonTable') {
      if (_btn.tabType === 'CommonTable' || _btn.tabType === 'SubTable') {
        _btn.tabType = 'BaseTable'
      }
@@ -353,7 +1025,9 @@
        _btn.style = {color: color, backgroundColor: 'transparent', borderColor: 'transparent'}
        colbtns.push(_btn)
      } else {
        if (btn.class.indexOf('border') > -1 || btn.class === 'default') {
        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: '#fff', backgroundColor: color, borderColor: color, marginRight: '15px'}
@@ -378,7 +1052,7 @@
    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']
    // useMSearch supModule
    _card.scripts = config.setting.scripts || []
    sets.forEach(n => {
src/views/menudesign/index.jsx
@@ -64,7 +64,7 @@
    config: null,
    customComponents: [],
    comloading: false,
    settingshow: true,
    settingshow: sessionStorage.getItem('settingshow') !== 'false',
    eyeopen: false,
    view: '',
    popConfig: null,
@@ -84,7 +84,7 @@
      this.setState({
        MenuType: param.MenuType,
        MenuId: param.MenuId,
        MenuId: param.MenuId || param.MenuID,
        ParentId: param.ParentId || '',
        MenuName: param.MenuName || '',
        MenuNo: param.MenuNo || '',
@@ -1106,6 +1106,7 @@
  changeSetting = () => {
    this.setState({settingshow: !this.state.settingshow})
    sessionStorage.setItem('settingshow', '' + !this.state.settingshow)
    setTimeout(() => {
      MKEmitter.emit('tabsChange', 'all')
src/views/tabledesign/index.jsx
@@ -35,6 +35,7 @@
const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const Versions = asyncComponent(() => import('@/menu/versions'))
const Transfer = asyncComponent(() => import('@/menu/transfer'))
const Unattended = asyncComponent(() => import('@/templates/zshare/unattended'))
const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent'))
const ModalController = asyncComponent(() => import('@/menu/modalconfig/controller'))
@@ -56,7 +57,7 @@
    oriConfig: null,
    config: null,
    comloading: false,
    settingshow: true,
    settingshow: sessionStorage.getItem('settingshow') !== 'false',
    view: null,
    popConfig: null
  }
@@ -688,6 +689,18 @@
      }
    })
    if (!error && config.autoMatic && config.autoMatic.enable === 'true') {
      let pass = false
      config.components[0].action.forEach(item => {
        if (item.uuid === config.autoMatic.action && (['pop', 'prompt', 'exec'].includes(item.OpenType) || (item.OpenType === 'funcbutton' && item.funcType === 'print'))) {
          pass = true
        }
      })
      if (!pass) {
        error = '无人值守设置无效!'
      }
    }
    if (show && error) {
      notification.warning({
        top: 92,
@@ -742,6 +755,7 @@
  changeSetting = () => {
    this.setState({settingshow: !this.state.settingshow})
    sessionStorage.setItem('settingshow', '' + !this.state.settingshow)
  }
  render () {
@@ -799,6 +813,7 @@
                  <div style={{paddingLeft: '15px'}}> {config && config.MenuName} </div>
                } bordered={false} extra={
                  <div>
                    {config ? <Transfer config={config}/> : null}
                    {config ? <Unattended config={config} updateConfig={this.updateConfig}/> : null}
                    <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''}/>
                    <TableNodes config={config} />
src/views/tabledesign/index.scss
@@ -140,7 +140,7 @@
          .ant-card-extra {
            padding: 5px 0;
            button {
              margin-left: 10px;
              margin-left: 15px;
            }
            >div >div >button, .style-control-button {
              padding: 0px 7px;