king
2022-10-26 fb64bcf1fab18b33d21470c83f28d4cda8d309ce
2022-10-26
60个文件已修改
2个文件已添加
1839 ■■■■■ 已修改文件
src/menu/components/card/cardcellcomponent/index.jsx 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.jsx 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/prop-card/index.jsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/table-card/index.jsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/data-card/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/prop-card/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/simple-form/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/step-form/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/tab-form/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/groupcomponents/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/groupcomponents/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/paste/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/copycomponent/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/pastebasetable/index.jsx 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/pastebasetable/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/pastecomponent/index.jsx 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/index.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/index.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/options.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/paste/index.jsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/tabcomponents/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/tabcomponents/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/table-tabs/index.jsx 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/menushell/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/menushell/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modulesource/option.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/pastecontroller/index.jsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/tablenodes/index.jsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/antv-tabs/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/antv-tabs/options.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/tabcomponents/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/tabcomponents/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/mobshell/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/mobshell/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/modalconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/modulesource/option.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/menushell/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/menushell/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/group/normal-group/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/tabtransfer/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/pageMessage/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/settingcomponent/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/index.jsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/sqlFormatter.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-custom.js 172 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/billprint/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/interface/history/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 613 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.scss 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/popview/index.jsx 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.jsx 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/index.jsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/index.jsx
@@ -324,15 +324,11 @@
   * @description 取消保存,如果元素为新添元素,则从序列中删除
   */
  editModalCancel = () => {
    const { card, elements, appType } = this.state
    const { card, elements } = this.state
    let _elements = null
    if (card.focus) {
      _elements = elements.filter(item => item.uuid !== card.uuid)
      if (card.OpenType === 'popview' && appType !== 'mob') { // 弹窗标签按钮,从复制列表中删除
        MKEmitter.emit('delButtons', [card.uuid])
      }
    } else {
      _elements = elements
    }
@@ -468,30 +464,19 @@
   * @description 按钮删除
   */
  deleteElement = (card) => {
    const { cardCell, side } = this.props
    const { elements, appType } = this.state
    const { elements } = this.state
    let _this = this
    confirm({
      content: '确定删除元素吗?',
      onOk() {
        let _elements = elements.filter(item => item.uuid !== card.uuid)
        if (card.OpenType === 'popview' || card.verify || card.modal) {
          card.$parentId = cardCell.uuid
          card.$side = side || ''
        }
        _this.setState({
          elements: _elements
        }, () => {
          _this.props.updateElement(_elements)
        })
        if (card.eleType !== 'button') return
        if (appType === 'mob' || (appType === 'pc' && card.OpenType !== 'popview')) return
        MKEmitter.emit('delButtons', [card.uuid])
      },
      onCancel() {}
    })
src/menu/components/card/cardcomponent/index.jsx
@@ -239,12 +239,6 @@
    
    if (element.copyType === 'action') {
      element.eleType = 'button'
      if (element.OpenType === 'popview') { // 弹窗标签复制
        let _cell = fromJS(element).toJS()
        _cell.$originUuid = element.uuid
        _cell.uuid = _uuid
        MKEmitter.emit('copyButtons', [_cell])
      }
    }
    element.uuid = _uuid
src/menu/components/card/data-card/index.jsx
@@ -276,7 +276,6 @@
   * @description 单个卡片信息更新
   */
  deleteCard = (cell) => {
    const { appType } = this.state
    let card = fromJS(this.state.card).toJS()
    let _this = this
@@ -286,25 +285,6 @@
        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
        _this.updateComponent(card)
        if (appType === 'mob') return
        let uuids = []
        cell.elements && cell.elements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        cell.backElements && cell.backElements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
@@ -512,7 +492,6 @@
      res.$cardType = 'extendCard'
      res.setting.width = res.setting.width || 6
      let copyBtns = []
      let mobtypes = ['pop', 'prompt', 'exec', 'innerpage', 'funcbutton']
      let elements = []
@@ -527,16 +506,7 @@
        } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
          return
        } else {
          let _uuid = Utils.getuuid()
          if (cell.OpenType === 'popview') {
            let _cell = fromJS(cell).toJS()
            _cell.$originUuid = _cell.uuid
            _cell.uuid = _uuid
            copyBtns.push(_cell)
          }
          cell.uuid = _uuid
          cell.uuid = Utils.getuuid()
          elements.push(cell)
        }
      })
@@ -557,26 +527,13 @@
          } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
            return
          } else {
            let _uuid = Utils.getuuid()
            if (cell.OpenType === 'popview') {
              let _cell = fromJS(cell).toJS()
              _cell.$originUuid = _cell.uuid
              _cell.uuid = _uuid
              copyBtns.push(_cell)
            }
            cell.uuid = _uuid
            cell.uuid = Utils.getuuid()
            backElements.push(cell)
          }
        })
      }
      res.backElements = backElements
      if (copyBtns.length > 0) {
        MKEmitter.emit('copyButtons', copyBtns)
      }
      resolve({status: true})
@@ -613,19 +570,9 @@
      if (appType === 'mob' && !['pop', 'prompt', 'exec', 'innerpage'].includes(res.OpenType)) {
        resolve({status: false, message: '移动端不支持此类型的按钮。'})
      } else {
        let _uuid = Utils.getuuid()
        if (res.OpenType === 'popview') {
          let _cell = fromJS(res).toJS()
          _cell.$originUuid = _cell.uuid
          _cell.uuid = _uuid
          MKEmitter.emit('copyButtons', [_cell])
        }
        resolve({status: true})
    
        res.uuid = _uuid
        res.uuid = Utils.getuuid()
        this.addButton(res)
      }
    }
src/menu/components/card/prop-card/index.jsx
@@ -287,7 +287,6 @@
   * @description 单个卡片信息更新
   */
  deleteCard = (cell) => {
    const { appType } = this.state
    let card = fromJS(this.state.card).toJS()
    let _this = this
@@ -297,25 +296,6 @@
        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
        _this.updateComponent(card)
        if (appType === 'mob') return
        let uuids = []
        cell.elements && cell.elements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        cell.backElements && cell.backElements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
@@ -401,7 +381,6 @@
    res.setting = res.setting || {}
    res.setting.width = res.setting.width || 6
    let copyBtns = []
    let mobtypes = ['pop', 'prompt', 'exec', 'innerpage', 'funcbutton']
    let elements = []
@@ -412,16 +391,7 @@
      } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
        return
      } else {
        let _uuid = Utils.getuuid()
        if (cell.OpenType === 'popview') {
          let _cell = fromJS(cell).toJS()
          _cell.$originUuid = _cell.uuid
          _cell.uuid = _uuid
          copyBtns.push(_cell)
        }
        cell.uuid = _uuid
        cell.uuid = Utils.getuuid()
        elements.push(cell)
      }
    })
@@ -438,26 +408,13 @@
        } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
          return
        } else {
          let _uuid = Utils.getuuid()
          if (cell.OpenType === 'popview') {
            let _cell = fromJS(cell).toJS()
            _cell.$originUuid = _cell.uuid
            _cell.uuid = _uuid
            copyBtns.push(_cell)
          }
          cell.uuid = _uuid
          cell.uuid = Utils.getuuid()
          backElements.push(cell)
        }
      })
    }
    res.backElements = backElements
    if (copyBtns.length > 0) {
      MKEmitter.emit('copyButtons', copyBtns)
    }
    resolve({status: true})
src/menu/components/card/table-card/index.jsx
@@ -237,7 +237,6 @@
   * @description 单个卡片信息更新
   */
  deleteCard = (cell) => {
    const { appType } = this.state
    let card = fromJS(this.state.card).toJS()
    let _this = this
@@ -247,20 +246,6 @@
        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
        _this.updateComponent(card)
        if (appType === 'mob') return
        let uuids = []
        cell.elements && cell.elements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
@@ -374,7 +359,6 @@
      res.setting = res.setting || {}
      res.setting.width = res.setting.width || 6
      let copyBtns = []
      let mobtypes = ['pop', 'prompt', 'exec', 'innerpage', 'funcbutton']
      let elements = []
@@ -385,16 +369,7 @@
        } else if (appType === 'mob' && !mobtypes.includes(cell.OpenType)) {
          return
        } else {
          let _uuid = Utils.getuuid()
          if (cell.OpenType === 'popview') {
            let _cell = fromJS(cell).toJS()
            _cell.$originUuid = _cell.uuid
            _cell.uuid = _uuid
            copyBtns.push(_cell)
          }
          cell.uuid = _uuid
          cell.uuid = Utils.getuuid()
          elements.push(cell)
        }
      })
@@ -403,10 +378,6 @@
      delete res.$cardType
      delete res.backElements
      if (copyBtns.length > 0) {
        MKEmitter.emit('copyButtons', copyBtns)
      }
      resolve({status: true})
src/menu/components/carousel/data-card/index.jsx
@@ -29,7 +29,6 @@
  }
  state = {
    appType: sessionStorage.getItem('appType'),
    card: null,
    back: false
  }
@@ -179,7 +178,6 @@
   * @description 单个卡片信息更新
   */
  deleteCard = (cell) => {
    const { appType } = this.state
    let card = fromJS(this.state.card).toJS()
    let _this = this
@@ -189,20 +187,6 @@
        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
        _this.updateComponent(card)
        if (appType === 'mob') return
        let uuids = []
        cell.elements && cell.elements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
src/menu/components/carousel/prop-card/index.jsx
@@ -30,7 +30,6 @@
  }
  state = {
    appType: sessionStorage.getItem('appType'),
    card: null,
    back: false
  }
@@ -199,7 +198,6 @@
   * @description 单个卡片信息更新
   */
  deleteCard = (cell) => {
    const { appType } = this.state
    let card = fromJS(this.state.card).toJS()
    let _this = this
@@ -209,20 +207,6 @@
        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
        _this.updateComponent(card)
        if (appType === 'mob') return
        let uuids = []
        cell.elements && cell.elements.forEach(c => {
          if (c.eleType !== 'button' || (appType === 'pc' && c.OpenType !== 'popview')) return
          uuids.push(c.uuid)
        })
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
src/menu/components/form/simple-form/index.jsx
@@ -429,7 +429,7 @@
      standardform,
      visible: true,
      editform: _form,
      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields)
      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields, card.columns)
    })
  }
src/menu/components/form/step-form/index.jsx
@@ -530,7 +530,7 @@
      standardform,
      visible: true,
      editform: _form,
      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields)
      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields, card.columns)
    })
  }
src/menu/components/form/tab-form/index.jsx
@@ -536,7 +536,7 @@
      standardform,
      visible: true,
      editform: _form,
      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields)
      formlist: getModalForm(_form, _inputfields, _tabfields, _linkableFields, _linksupFields, card.columns)
    })
  }
src/menu/components/group/groupcomponents/card.jsx
@@ -79,7 +79,7 @@
      return (<DataCard card={card} updateConfig={updateConfig} deletecomponent={delCard} />)
    } else if (card.type === 'card' && card.subtype === 'propcard') {
      return (<PropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'tablecard') {
    } else if (card.type === 'card' && card.subtype === 'tablecard') {
      return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'normaltable') {
      return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
src/menu/components/group/groupcomponents/index.jsx
@@ -5,8 +5,6 @@
import { Empty, Modal } from 'antd'
import Utils from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import MenuUtils from '@/utils/utils-custom.js'
import Card from './card'
import './index.scss'
@@ -39,16 +37,10 @@
  const deleteCard = (id) => {
    const { card } = findCard(id)
    let uuids = MenuUtils.getDelButtonIds(card)
    confirm({
      title: `确定删除《${card.name}》吗?`,
      onOk() {
        handleList({...config, components: cards.filter(item => item.uuid !== card.uuid)})
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
src/menu/components/group/paste/index.jsx
@@ -4,7 +4,6 @@
import { SnippetsOutlined } from '@ant-design/icons'
import MenuUtils from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
// import './index.scss'
@@ -24,6 +23,7 @@
  }
  pasteSubmit = () => {
    let appType = sessionStorage.getItem('appType')
    let options = ['datacard', 'propcard', 'balcony', 'timeline', 'simpleform', 'stepform', 'tabform', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter', 'chart']
    let types = {
      login: '登录',
@@ -34,6 +34,10 @@
      mainsearch: '搜索',
      group: '分组',
      menubar: '菜单'
    }
    if (appType !== 'mob') {
      options.push('editable')
    }
    this.pasteFormRef.handleConfirm().then(res => {
@@ -53,19 +57,11 @@
        return
      }
      let copyBtns = new Map()
      res = MenuUtils.resetComponentConfig(res, copyBtns)
      res = MenuUtils.resetComponentConfig(res)
      delete res.copyType
      
      this.props.insert(res)
      copyBtns = [...copyBtns.values()]
      if (copyBtns.length > 0) {
        MKEmitter.emit('copyButtons', copyBtns)
      }
      this.setState({visible: false})
src/menu/components/share/actioncomponent/index.jsx
@@ -316,7 +316,6 @@
   */
  deleteElement = (card) => {
    const { config } = this.props
    const { appType } = this.state
    let _this = this
    confirm({
@@ -331,11 +330,6 @@
        }, () => {
          _this.props.updateaction({...config, action: _actionlist})
        })
        if (card.origin || appType === 'mob') return
        if (appType === 'pc' && card.OpenType !== 'popview') return
        MKEmitter.emit('delButtons', [card.uuid])
      },
      onCancel() {}
    })
@@ -461,7 +455,7 @@
    let btn = null
    let _col = null
    if (config.subtype === 'normaltable' || config.subtype === 'editable' || config.subtype === 'basetable') {
    if (config.type === 'table') {
      config.cols.forEach(col => {
        if (col.type !== 'action') return
src/menu/components/share/copycomponent/index.jsx
@@ -39,6 +39,11 @@
          _val.subMenus.push(cell)
        }
      } else if (['normaltable', 'editable', 'basetable'].includes(type)) {
        _val.action = _val.action.filter(item => !item.origin)
        _val.cols = _val.cols.filter(item => !item.origin)
        _val.search = _val.search.filter(item => !item.origin)
        delete _val.isNew
      }
      _val = window.btoa(window.encodeURIComponent(JSON.stringify(_val)))
src/menu/components/share/pastebasetable/index.jsx
New file
@@ -0,0 +1,135 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Modal, notification, Button } from 'antd'
import { SnippetsOutlined } from '@ant-design/icons'
import Utils from '@/utils/utils.js'
import asyncComponent from '@/utils/asyncComponent'
// import './index.scss'
const PasteForm = asyncComponent(() => import('@/templates/zshare/pasteform'))
class PasteBaseTable extends Component {
  static propTpyes = {
    type: PropTypes.any,
    insert: PropTypes.func
  }
  state = {
    visible: false
  }
  handleMenuClick = () => {
    this.setState({visible: true})
  }
  pasteSubmit = () => {
    this.pasteFormRef.handleConfirm().then(res => {
      if (res.copyType !== 'basetable') {
        notification.warning({
          top: 92,
          message: '配置信息格式错误!',
          duration: 5
        })
        return
      }
      delete res.copyType
      res.uuid = Utils.getuuid()
      res.search = res.search.map(cell => {
        cell.uuid = Utils.getuuid()
        return cell
      })
      let loopCol = (col) => {
        col.subcols = col.subcols.map(c => {
          c.uuid = Utils.getuuid()
          if (c.type === 'colspan' && c.subcols) {
            c = loopCol(c)
          } else if (c.type === 'custom' && c.elements) {
            c.elements = c.elements.map(cell => {
              cell.uuid = Utils.getuuid()
              return cell
            })
          }
          return c
        })
        return col
      }
      res.cols = res.cols.map(col => {
        col.uuid = Utils.getuuid()
        if (col.type === 'colspan' && col.subcols) {
          col = loopCol(col)
        } else if (col.type === 'custom' && col.elements) {
          col.elements = col.elements.map(cell => {
            cell.uuid = Utils.getuuid()
            return cell
          })
        } else if (col.type === 'action' && col.elements) {
          col.elements = col.elements.map(cell => {
            cell.uuid = Utils.getuuid()
            return cell
          })
        }
        return col
      })
      let oriUids = {}
      res.action = res.action.map(cell => {
        let _uuid = Utils.getuuid()
        oriUids[cell.uuid] = _uuid
        cell.uuid = _uuid
        return cell
      })
      res.setting.supModule = ''
      if (res.wrap && res.wrap.doubleClick) {
        res.wrap.doubleClick = oriUids[res.wrap.doubleClick] || ''
      }
      this.props.insert(res)
      this.setState({visible: false})
      notification.success({
        top: 92,
        message: '粘贴成功!',
        duration: 2
      })
    })
  }
  render() {
    const { type } = this.props
    const { visible } = this.state
    return (
      <div style={{display: 'inline-block'}}>
        {type === 'page' ? <Button icon="snippets" style={{color: '#1890ff', borderColor: '#1890ff'}} onClick={() => {this.setState({visible: true})}} >粘贴</Button> : <SnippetsOutlined style={{color: 'purple'}} onClick={() => {this.setState({visible: true})}} />}
        <Modal
          title="粘贴"
          visible={visible}
          width={600}
          maskClosable={false}
          onOk={this.pasteSubmit}
          onCancel={() => {this.setState({visible: false})}}
          destroyOnClose
        >
          <PasteForm wrappedComponentRef={(inst) => this.pasteFormRef = inst} inputSubmit={this.pasteSubmit}/>
        </Modal>
      </div>
    )
  }
}
export default PasteBaseTable
src/menu/components/share/pastebasetable/index.scss
src/menu/components/share/pastecomponent/index.jsx
@@ -25,15 +25,8 @@
    this.setState({visible: true})
  }
  resetconfig = (item, copyBtns, config) => {
  resetconfig = (item, config) => {
    let _uuid = Utils.getuuid()
    if (item.OpenType === 'popview') {
      let _cell = fromJS(item).toJS()
      _cell.$originUuid = _cell.uuid
      _cell.uuid = _uuid
      copyBtns.set(_uuid, _cell)
    }
    if (item.uuid) {
      item.uuid = _uuid
@@ -109,14 +102,7 @@
          })
        } else if (_item.type === 'action' && _item.elements) {
          _item.elements = _item.elements.map(cell => {
            let _uuid = Utils.getuuid()
            if (cell.OpenType === 'popview') {
              let _cell = fromJS(cell).toJS()
              _cell.$originUuid = _cell.uuid
              _cell.uuid = _uuid
              copyBtns.set(_uuid, _cell)
            }
            cell.uuid = _uuid
            cell.uuid = Utils.getuuid()
            return cell
          })
        }
@@ -138,25 +124,15 @@
      let type = res.copyType
      let config = fromJS(this.props.config).toJS()
      let copyBtns = new Map()
      res = this.resetconfig(res, copyBtns, config)
      res = this.resetconfig(res, config)
      delete res.copyType
      copyBtns = [...copyBtns.values()]
      if (copyBtns.length > 0) {
        MKEmitter.emit('copyButtons', copyBtns)
      }
      if (config.type === 'form') {
        this.props.updateConfig(res)
        this.setState({visible: false})
        return
      } else if (type === 'action') {
        config.action = config.action || []
        config.action = config.action.filter(item => !item.origin)
        if (['line', 'bar', 'scatter'].includes(config.type) && !['excelOut', 'excelIn'].includes(res.OpenType)) {
          notification.warning({ top: 92, message: '图表中不支持此类按钮!', duration: 5 })
          return
src/menu/components/table/base-table/columns/index.jsx
@@ -435,19 +435,6 @@
    }, () => {
      this.props.updatecolumn({...this.props.config, cols: _columns})
    })
    if (col.type !== 'action') return
    let uuids = []
    col.elements && col.elements.forEach(c => {
      if (c.OpenType !== 'popview') return
      uuids.push(c.uuid)
    })
    if (uuids.length === 0) return
    MKEmitter.emit('delButtons', uuids)
  }
  updateLineMarks = (vals) => {
src/menu/components/table/base-table/index.jsx
@@ -359,7 +359,7 @@
            <NormalForm title="表格设置" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="normaltable" card={card}/>
            <CopyComponent type="basetable" card={card}/>
            <PasteComponent config={card} options={options} updateConfig={this.updateComponent} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <SettingComponent config={card} updateConfig={this.updateComponent} />
src/menu/components/table/edit-table/columns/index.jsx
@@ -181,7 +181,6 @@
  }
  state = {
    appType: sessionStorage.getItem('appType'),
    tableId: '',
    data: [{uuid: Utils.getuuid()}],
    refresh: false,    // 强制刷新
@@ -400,7 +399,6 @@
  }
  deleteCol = (col) => {
    const { appType } = this.state
    let _columns = fromJS(this.state.columns).toJS()
    _columns = _columns.filter(column => column.uuid !== col.uuid)
@@ -410,19 +408,6 @@
    }, () => {
      this.props.updatecolumn({...this.props.config, cols: _columns})
    })
    if (col.type !== 'action' || appType === 'mob') return
    let uuids = []
    col.elements && col.elements.forEach(c => {
      if (appType === 'pc' && c.OpenType !== 'popview') return
      uuids.push(c.uuid)
    })
    if (uuids.length === 0) return
    MKEmitter.emit('delButtons', uuids)
  }
  updateLineMarks = (vals) => {
src/menu/components/table/edit-table/index.jsx
@@ -390,7 +390,7 @@
            <NormalForm title="表格设置" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="normaltable" card={card}/>
            <CopyComponent type="editable" card={card}/>
            <PasteComponent config={card} options={['action', 'search', 'form', 'cols']} updateConfig={this.updateComponent} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <UserComponent config={card}/>
src/menu/components/table/normal-table/columns/index.jsx
@@ -429,7 +429,6 @@
  }
  deleteCol = (col) => {
    const { appType } = this.state
    let _columns = fromJS(this.state.columns).toJS()
    _columns = this.loopDelCol(_columns, col)
@@ -439,19 +438,6 @@
    }, () => {
      this.props.updatecolumn({...this.props.config, cols: _columns})
    })
    if (col.type !== 'action' || appType === 'mob') return
    let uuids = []
    col.elements && col.elements.forEach(c => {
      if (appType === 'pc' && c.OpenType !== 'popview') return
      uuids.push(c.uuid)
    })
    if (uuids.length === 0) return
    MKEmitter.emit('delButtons', uuids)
  }
  updateLineMarks = (vals) => {
src/menu/components/tabs/antv-tabs/index.jsx
@@ -10,7 +10,6 @@
import MkIcon from '@/components/mk-icon'
import DraggableTabs from './dragabletabs'
import { resetStyle } from '@/utils/utils-custom.js'
import MenuUtils from '@/utils/utils-custom.js'
import Utils from '@/utils/utils.js'
import { getTabForm, getTabsSetForm } from './options'
import './index.scss'
@@ -31,7 +30,6 @@
  }
  state = {
    appType: sessionStorage.getItem('appType'),
    tabs: null,
    editab: null,
    defaultActiveKey: ''
@@ -153,18 +151,12 @@
    tabs.subtabs = tabs.subtabs.filter(t => t.uuid !== tab.uuid)
    let uuids = MenuUtils.getDelButtonIds({...tab, type: 'group'})
    confirm({
      title: '确定删除标签?',
      content: '',
      onOk() {
        _this.setState({tabs})
        _this.props.updateConfig(tabs)
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
@@ -227,7 +219,6 @@
    editab.label = res.label
    editab.icon = res.icon
    // editab.hasSearch = res.hasSearch || ''
    editab.hide = res.hide || 'false'
    editab.backgroundColor = res.backgroundColor
    editab.controlVal = res.controlVal || ''
src/menu/components/tabs/antv-tabs/options.jsx
@@ -34,19 +34,6 @@
      required: false,
      allowClear: true,
    },
    // {
    //   type: 'radio',
    //   field: 'hasSearch',
    //   label: '搜索',
    //   initval: tab.hasSearch || 'false',
    //   required: false,
    //   options: [
    //     {value: 'false', label: '无'},
    //     {value: 'icon', label: '有'},
    //   ],
    //   forbid: appType !== 'mob' || setting.position !== 'top' || setting.display !== 'inline-block',
    //   span: 22
    // },
    {
      type: 'text',
      field: 'controlVal',
src/menu/components/tabs/paste/index.jsx
@@ -4,7 +4,6 @@
import { SnippetsOutlined } from '@ant-design/icons'
import MenuUtils from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
// import './index.scss'
@@ -24,7 +23,7 @@
    this.setState({visible: true})
  }
  resetconfig = (item, copyBtns, uuids = {}) => {
  resetconfig = (item, uuids = {}) => {
    if (item.type === 'tabs') {
      uuids[item.uuid] = MenuUtils.getuuid()
      item.uuid = uuids[item.uuid]
@@ -36,7 +35,7 @@
        tab.uuid = uuids[tab.uuid]
        tab.components = tab.components.map(cell => {
          cell = this.resetconfig(cell, copyBtns, uuids)
          cell = this.resetconfig(cell, uuids)
          return cell
        })
      })
@@ -47,12 +46,12 @@
      item.name = item.setting.name
      item.components = item.components.map(cell => {
        cell = MenuUtils.resetComponentConfig(cell, copyBtns, uuids)
        cell = MenuUtils.resetComponentConfig(cell, uuids)
        return cell
      })
    } else {
      item = MenuUtils.resetComponentConfig(item, copyBtns, uuids)
      item = MenuUtils.resetComponentConfig(item, uuids)
    }
    return item
@@ -60,6 +59,7 @@
  pasteSubmit = () => {
    const { Tab } = this.props
    let appType = sessionStorage.getItem('appType')
    let options = ['tabs', 'group', 'datacard', 'propcard', 'timeline', 'balcony', 'normaltable', 'mainsearch', 'simpleform', 'stepform', 'tabform', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter', 'chart']
    let types = {
      login: '登录',
@@ -67,8 +67,10 @@
      topbar: '导航栏'
    }
    if (sessionStorage.getItem('appType') === 'mob') {
    if (appType === 'mob') {
      options.push('menubar')
    } else {
      options.push('editable')
    }
    this.pasteFormRef.handleConfirm().then(res => {
@@ -88,19 +90,11 @@
        return
      }
      let copyBtns = new Map()
      res = this.resetconfig(res, copyBtns, {})
      res = this.resetconfig(res, {})
      delete res.copyType
      
      this.props.insert(res, Tab)
      copyBtns = [...copyBtns.values()]
      if (copyBtns.length > 0) {
        MKEmitter.emit('copyButtons', copyBtns)
      }
      this.setState({visible: false})
src/menu/components/tabs/tabcomponents/card.jsx
@@ -90,7 +90,7 @@
      return (<CarouselDataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'carousel' && card.subtype === 'propcard') {
      return (<CarouselPropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'tablecard') {
    } else if (card.type === 'card' && card.subtype === 'tablecard') {
      return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'normaltable') {
      return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
src/menu/components/tabs/tabcomponents/index.jsx
@@ -5,8 +5,6 @@
import { Empty, notification, Modal } from 'antd'
import Utils from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import MenuUtils from '@/utils/utils-custom.js'
import Card from './card'
import './index.scss'
@@ -48,17 +46,11 @@
      })
    }
    let uuids = MenuUtils.getDelButtonIds(card)
    confirm({
      title: `确定删除《${card.name}》吗?`,
      content: hasComponent ? '当前组件中含有子组件!' : '',
      onOk() {
        handleList({...config, components: cards.filter(item => item.uuid !== card.uuid)})
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
src/menu/components/tabs/table-tabs/index.jsx
@@ -4,19 +4,16 @@
import { Tabs, Popover, Modal } from 'antd'
import { PlusOutlined, CloseOutlined, EditOutlined, DeleteOutlined, ToolOutlined } from '@ant-design/icons'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import MkIcon from '@/components/mk-icon'
import DraggableTabs from './dragabletabs'
import MenuUtils from '@/utils/utils-custom.js'
import Utils from '@/utils/utils.js'
import { getTabForm } from './options'
import './index.scss'
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
// const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('../paste'))
const PasteBaseTable = asyncIconComponent(() => import('@/menu/components/share/pastebasetable'))
const BaseTable = asyncComponent(() => import('@/menu/components/table/base-table'))
const { TabPane } = Tabs
@@ -80,18 +77,12 @@
    tabs.subtabs = tabs.subtabs.filter(t => t.uuid !== tab.uuid)
    let uuids = MenuUtils.getDelButtonIds({...tab, type: 'group'})
    confirm({
      title: '确定删除标签?',
      content: '',
      onOk() {
        _this.setState({tabs})
        _this.props.updateConfig(tabs)
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
@@ -149,16 +140,36 @@
    }
  }
  insert = (item, tab) => {
  plusTable = () => {
    let tabs = fromJS(this.state.tabs).toJS()
    let name = '子表' + (tabs.subtabs.length + 1)
    let tab = { uuid: Utils.getuuid(), label: name, icon: '', components: [{uuid: Utils.getuuid(), type: 'table', name: name, subtype: 'basetable', isNew: true}]}
    tabs.subtabs.push(tab)
    this.setState({tabs}, () => {
      setTimeout(() => {
        let node = document.getElementById(tab.uuid)
        node && node.click()
      }, 200)
    })
    this.props.updateConfig(tabs)
  }
  insert = (item) => {
    let tabs = fromJS(this.state.tabs).toJS()
    tabs.subtabs.forEach(stab => {
      if (stab.uuid === tab.uuid) {
        stab.components.push(item)
      }
    })
    let name = item.name || ('子表' + (tabs.subtabs.length + 1))
    let tab = { uuid: Utils.getuuid(), label: name, icon: '', components: [item]}
    this.setState({tabs})
    tabs.subtabs.push(tab)
    this.setState({tabs}, () => {
      setTimeout(() => {
        let node = document.getElementById(tab.uuid)
        node && node.click()
      }, 200)
    })
    this.props.updateConfig(tabs)
  }
@@ -246,8 +257,8 @@
        </DraggableTabs>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <PlusOutlined className="plus" title="添加子表"/>
            <PasteComponent insert={this.insert} />
            <PlusOutlined className="plus" title="添加子表" onClick={this.plusTable}/>
            <PasteBaseTable insert={this.insert} />
            <DeleteOutlined className="close" onClick={() => this.props.deletecomponent(tabs.uuid)} />
          </div>
        } trigger="hover">
src/menu/menushell/card.jsx
@@ -91,7 +91,7 @@
      return (<CarouselDataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'carousel' && card.subtype === 'propcard') {
      return (<CarouselPropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'tablecard') {
    } else if (card.type === 'card' && card.subtype === 'tablecard') {
      return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'normaltable') {
      return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
src/menu/menushell/index.jsx
@@ -4,8 +4,6 @@
import { Empty, notification, Modal } from 'antd'
import Utils from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import MenuUtils from '@/utils/utils-custom.js'
import Card from './card'
import './index.scss'
@@ -50,8 +48,6 @@
      })
    }
    let uuids = MenuUtils.getDelButtonIds(card)
    confirm({
      title: `确定删除《${card.name}》吗?`,
      content: hasComponent ? '当前组件中含有子组件!' : '',
@@ -59,10 +55,6 @@
        const _cards = cards.filter(item => item.uuid !== card.uuid)
        handleList({...menu, components: _cards})
        setCards(_cards)
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
src/menu/modalconfig/index.jsx
@@ -206,7 +206,7 @@
      standardform,
      visible: true,
      card: card,
      formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields)
      formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields, componentConfig.columns)
    })
  }
src/menu/modulesource/option.jsx
@@ -40,9 +40,9 @@
  { type: 'menu', url: tabForm, component: 'form', subtype: 'tabform', title: '表单(tab页)', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: Carousel, component: 'carousel', subtype: 'datacard', title: '轮播-动态数据', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: Carousel1, component: 'carousel', subtype: 'propcard', title: '轮播-静态数据', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: TableCard, component: 'card', subtype: 'tablecard', title: '表格(卡片)', width: 12 },
  { 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: TableCard, component: 'table', subtype: 'tablecard', title: '表格(卡片)', width: 12 },
  { type: 'menu', url: timeline, component: 'timeline', subtype: 'timeline', title: '时间轴', width: 12 },
  { type: 'menu', url: tree, component: 'tree', subtype: 'normaltree', title: '树形列表', width: 12, forbid: ['billPrint'] },
  { type: 'menu', url: line, component: 'line', subtype: 'line', title: '折线图', width: 24 },
src/menu/pastecontroller/index.jsx
@@ -4,7 +4,6 @@
import { SnippetsOutlined } from '@ant-design/icons'
import MenuUtils from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
// import './index.scss'
@@ -19,7 +18,7 @@
    visible: false
  }
  resetconfig = (item, copyBtns, uuids = {}) => {
  resetconfig = (item, uuids = {}) => {
    let appType = sessionStorage.getItem('appType')
    
    if (item.type === 'tabs') {
@@ -37,7 +36,7 @@
        }
        tab.components = tab.components.map(cell => {
          cell = this.resetconfig(cell, copyBtns, uuids)
          cell = this.resetconfig(cell, uuids)
          return cell
        })
      })
@@ -48,28 +47,28 @@
      item.name = item.setting.name
      item.components = item.components.map(cell => {
        cell = MenuUtils.resetComponentConfig(cell, copyBtns, uuids)
        cell = MenuUtils.resetComponentConfig(cell, uuids)
        return cell
      })
    } else {
      item = MenuUtils.resetComponentConfig(item, copyBtns, uuids)
      item = MenuUtils.resetComponentConfig(item, uuids)
    }
    return item
  }
  pasteSubmit = () => {
    let options = ['tabs', 'menubar', 'topbar', 'timeline', 'datacard', 'propcard', 'mainsearch', 'simpleform', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter']
    let appType = sessionStorage.getItem('appType')
    let options = ['tabs', 'timeline', 'datacard', 'propcard', 'mainsearch', 'simpleform', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter']
    if (appType === 'mob') {
      options.push('menubar', 'topbar')
    } else {
      options.push('editable')
    }
    this.pasteFormRef.handleConfirm().then(res => {
      if ((res.copyType === 'menubar' || res.copyType === 'topbar') && sessionStorage.getItem('appType') !== 'mob') {
        notification.warning({
          top: 92,
          message: '当前系统不支持菜单组件!',
          duration: 5
        })
        return
      } else if (!options.includes(res.copyType)) {
      if (!options.includes(res.copyType)) {
        notification.warning({
          top: 92,
          message: '配置信息格式错误!',
@@ -78,19 +77,11 @@
        return
      }
      let copyBtns = new Map()
      res = this.resetconfig(res)
      res = this.resetconfig(res, copyBtns)
      delete res.copyType
      // delete res.copyType
      
      this.props.insert(res)
      copyBtns = [...copyBtns.values()]
      if (copyBtns.length > 0) {
        MKEmitter.emit('copyButtons', copyBtns)
      }
      this.setState({visible: false})
    })
src/menu/tablenodes/index.jsx
@@ -87,6 +87,23 @@
      })
    } else {
      traversal(config.components)
      if (config.interfaces) {
        config.interfaces.forEach(item => {
          if (item.$tables) {
            ptbs.push(...item.$tables)
            item.$tables.forEach(tb => {
              tbs.push({
                label: item.name,
                table: tb,
                color: '#5AD8A6',
                id: Utils.getuuid(),
                direction: 'left'
              })
            })
          }
        })
      }
    }
    return {tbs, ptbs}
src/mob/components/tabs/antv-tabs/index.jsx
@@ -9,7 +9,6 @@
import asyncIconComponent from '@/utils/asyncIconComponent'
import DraggableTabs from './dragabletabs'
import { resetStyle } from '@/utils/utils-custom.js'
import MenuUtils from '@/utils/utils-custom.js'
import Utils from '@/utils/utils.js'
import { getTabForm, getTabsSetForm } from './options'
import MkIcon from '@/components/mk-icon'
@@ -174,18 +173,12 @@
    tabs.subtabs = tabs.subtabs.filter(t => t.uuid !== tab.uuid)
    let uuids = MenuUtils.getDelButtonIds({...tab, type: 'group'})
    confirm({
      title: '确定删除标签?',
      content: '',
      onOk() {
        _this.setState({tabs})
        _this.props.updateConfig(tabs)
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
@@ -257,7 +250,6 @@
    editab.label = res.label
    editab.icon = res.icon
    // editab.hasSearch = res.hasSearch || ''
    editab.hide = res.hide || 'false'
    editab.backgroundColor = res.backgroundColor
    editab.controlVal = res.controlVal || ''
src/mob/components/tabs/antv-tabs/options.jsx
@@ -34,19 +34,6 @@
      required: false,
      allowClear: true,
    },
    // {
    //   type: 'radio',
    //   field: 'hasSearch',
    //   label: '搜索',
    //   initval: tab.hasSearch || 'false',
    //   required: false,
    //   options: [
    //     {value: 'false', label: '无'},
    //     {value: 'icon', label: '有'},
    //   ],
    //   forbid: appType !== 'mob' || setting.display !== 'inline-block',
    //   span: 22
    // },
    {
      type: 'text',
      field: 'controlVal',
src/mob/components/tabs/tabcomponents/card.jsx
@@ -89,7 +89,7 @@
      return (<CarouselDataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'carousel' && card.subtype === 'propcard') {
      return (<CarouselPropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'tablecard') {
    } else if (card.type === 'card' && card.subtype === 'tablecard') {
      return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'normaltable') {
      return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
src/mob/components/tabs/tabcomponents/index.jsx
@@ -5,8 +5,6 @@
import { Empty, Modal } from 'antd'
import Utils from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import MenuUtils from '@/utils/utils-custom.js'
import Card from './card'
import './index.scss'
@@ -48,17 +46,11 @@
      })
    }
    let uuids = MenuUtils.getDelButtonIds(card)
    confirm({
      title: `确定删除《${card.name}》吗?`,
      content: hasComponent ? '当前组件中含有子组件!' : '',
      onOk() {
        handleList({...config, components: cards.filter(item => item.uuid !== card.uuid)})
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
src/mob/mobshell/card.jsx
@@ -109,7 +109,7 @@
      return (<CarouselDataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'carousel' && card.subtype === 'propcard') {
      return (<CarouselPropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'tablecard') {
    } else if (card.type === 'card' && card.subtype === 'tablecard') {
      return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'normaltable') {
      return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
src/mob/mobshell/index.jsx
@@ -4,8 +4,6 @@
import { Empty, notification, Modal } from 'antd'
import Utils from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import MenuUtils from '@/utils/utils-custom.js'
import Card from './card'
import './index.scss'
@@ -50,8 +48,6 @@
      })
    }
    let uuids = MenuUtils.getDelButtonIds(card)
    confirm({
      title: `确定删除${card.name ? `《${card.name}》` : '组件'}吗?`,
      content: hasComponent ? '当前组件中含有子组件!' : '',
@@ -59,10 +55,6 @@
        const _cards = cards.filter(item => item.uuid !== card.uuid)
        handleList({...menu, components: _cards})
        setCards(_cards)
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
src/mob/modalconfig/index.jsx
@@ -223,7 +223,7 @@
      standardform,
      visible: true,
      card: card,
      formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields)
      formlist: getModalForm(card, _inputfields, _tabfields, _linkableFields, _linksupFields, componentConfig.columns)
    })
  }
src/mob/modulesource/option.jsx
@@ -44,8 +44,8 @@
  { type: 'menu', url: tabForm, component: 'form', subtype: 'tabform', title: '表单(tab页)', width: 24 },
  { type: 'menu', url: Carousel, component: 'carousel', subtype: 'datacard', title: '轮播-动态数据', width: 24 },
  { type: 'menu', url: Carousel1, component: 'carousel', subtype: 'propcard', title: '轮播-静态数据', width: 24 },
  { type: 'menu', url: TableCard, component: 'card', subtype: 'tablecard', title: '表格(卡片)', width: 24 },
  { type: 'menu', url: NormalTable, component: 'table', subtype: 'normaltable', title: '常用表', width: 24 },
  { type: 'menu', url: TableCard, component: 'table', subtype: 'tablecard', title: '表格(卡片)', width: 24 },
  { type: 'menu', url: timeline, component: 'timeline', subtype: 'timeline', title: '时间轴', width: 24 },
  { type: 'menu', url: line, component: 'line', subtype: 'line', title: '折线图', width: 24 },
  { type: 'menu', url: line1, component: 'line', subtype: 'line1', title: '阶梯折线图', width: 24 },
src/pc/menushell/card.jsx
@@ -111,7 +111,7 @@
      return (<CarouselDataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'carousel' && card.subtype === 'propcard') {
      return (<CarouselPropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'tablecard') {
    } else if (card.type === 'card' && card.subtype === 'tablecard') {
      return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
    } else if (card.type === 'table' && card.subtype === 'normaltable') {
      return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
src/pc/menushell/index.jsx
@@ -4,8 +4,6 @@
import { Empty, notification, Modal } from 'antd'
import Utils from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import MenuUtils from '@/utils/utils-custom.js'
import Card from './card'
import './index.scss'
@@ -50,8 +48,6 @@
      })
    }
    let uuids = MenuUtils.getDelButtonIds(card)
    confirm({
      title: `确定删除${card.name ? `《${card.name}》` : '组件'}吗?`,
      content: hasComponent ? '当前组件中含有子组件!' : '',
@@ -59,10 +55,6 @@
        const _cards = cards.filter(item => item.uuid !== card.uuid)
        handleList({...menu, components: _cards})
        setCards(_cards)
        if (uuids.length === 0) return
        MKEmitter.emit('delButtons', uuids)
      },
      onCancel() {}
    })
src/tabviews/custom/components/group/normal-group/index.jsx
@@ -205,7 +205,7 @@
            <PropCard config={item} data={data} mainSearch={mainSearch}/>
          </Col>
        )
      } else if (item.type === 'table' && item.subtype === 'tablecard') {
      } else if (item.type === 'card' && item.subtype === 'tablecard') {
        return (
          <Col span={item.width} key={item.uuid}>
            <TableCard config={item} data={data} mainSearch={mainSearch}/>
src/tabviews/custom/components/share/tabtransfer/index.jsx
@@ -233,7 +233,7 @@
            <CarouselPropCard config={item} data={data} mainSearch={mainSearch}/>
          </Col>
        )
      } else if (item.type === 'table' && item.subtype === 'tablecard') {
      } else if (item.type === 'card' && item.subtype === 'tablecard') {
        return (
          <Col span={item.width} key={item.uuid}>
            <TableCard config={item} data={data} mainSearch={mainSearch}/>
src/tabviews/custom/index.jsx
@@ -409,12 +409,16 @@
        }
      }
      if (item.subtype === 'tablecard') { // 兼容
        item.type = 'card'
      }
      // 搜索条件初始化
      if (item.search && item.search.length > 0) {
        item.search = Utils.initSearchVal(item.search)
      }
      if (item.type === 'table' && (item.subtype === 'normaltable' || item.subtype === 'editable')) {
      if (item.type === 'table') {
        let statFields = []
        let getCols = (cols) => {
          return cols.filter(col => {
@@ -519,7 +523,7 @@
        })
      }
      if (item.type === 'card') {
      if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
        item.subcards && item.subcards.forEach(card => {
          if (card.style.boxShadow) {
            delete card.style.hShadow
@@ -566,6 +570,9 @@
            return cell.eleType !== 'button' || skip || permAction[cell.uuid]
          })
          if (!card.backElements || card.backElements.length === 0) return
          card.backElements = card.backElements.filter(cell => {
            if (cell.eleType === 'button') {
              if (cell.hidden === 'true') return false
@@ -646,47 +653,7 @@
          return cell.eleType !== 'button' || skip || permAction[cell.uuid]
        })
      } else if ((item.type === 'table' && item.subtype === 'tablecard') || item.type === 'carousel' || item.type === 'timeline') {
        item.subcards && item.subcards.forEach(card => {
          card.elements = card.elements.filter(cell => {
            if (cell.eleType === 'button') {
              if (cell.hidden === 'true') return false
              cell.logLabel = item.$menuname + '-' + cell.label
              cell.Ot = cell.Ot || 'requiredSgl'
              cell.ContainerId = this.state.ContainerId
              cell.syncComponentId = cell.syncComponent ? (cell.syncComponent.pop() || '') : ''
              cell.$menuId = item.uuid
              cell.$MenuID = this.props.MenuID
              cell.$tabId = tabId
              cell.$view = 'CustomPage'
              if (cell.syncComponentId === item.setting.supModule) {
                cell.syncComponentId = ''
              }
              if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 打印机设置
                cell = this.getPrinter(cell, item.uuid)
              }
              if (card.btnstyle) { // 兼容
                card.style = card.style || {}
                card.style = {...card.style, ...card.btnstyle}
              }
            } else if (['text', 'number', 'formula'].includes(cell.eleType)) {
              if (!cell.height) {
                cell.innerHeight = 'auto'
              }
              if (cell.eleType === 'number' && typeof(cell.decimal) === 'number') {
                cell.round = Math.pow(10, cell.decimal)
                if (cell.format === 'percent') {
                  cell.decimal = cell.decimal > 2 ? cell.decimal - 2 : 0
                }
              }
            }
            return cell.eleType !== 'button' || skip || permAction[cell.uuid]
          })
        })
      } else if (item.type === 'table' && (item.subtype === 'normaltable' || item.subtype === 'editable')) {
      } else if (item.type === 'table') {
        item.cols = item.cols.filter(col => {
          if (col.type !== 'action') return true
          col.elements = col.elements.filter(cell => {
@@ -1215,7 +1182,7 @@
            <CarouselPropCard config={item} data={data} mainSearch={mainSearch}/>
          </Col>
        )
      } else if (item.type === 'table' && item.subtype === 'tablecard') {
      } else if (item.type === 'card' && item.subtype === 'tablecard') {
        return (
          <Col span={item.width} key={item.uuid}>
            <TableCard config={item} data={data} mainSearch={mainSearch}/>
src/tabviews/zshare/pageMessage/index.jsx
@@ -142,7 +142,7 @@
        })
      }
      if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) {
      if (item.type === 'card') {
        item.subcards.forEach(card => {
          card.elements && card.elements.forEach(cell => {
            if (cell.eleType === 'button') {
@@ -157,7 +157,7 @@
            }
          })
        })
      } else if (item.type === 'table' && item.subtype === 'normaltable') {
      } else if (item.type === 'table') {
        item.cols.forEach(col => {
          if (col.type !== 'action') return
          col.elements && col.elements.forEach(cell => {
src/tabviews/zshare/settingcomponent/index.jsx
@@ -98,7 +98,7 @@
          _comp.action.push({...cell, ...(userConfig[cell.uuid] || {})})
        })
        
        if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) {
        if (item.type === 'card') {
          item.subcards.forEach(card => {
            card.elements && card.elements.forEach(cell => {
              if (cell.eleType !== 'button') return
@@ -143,7 +143,7 @@
              _comp.action.push({...cell, ...(userConfig[cell.uuid] || {})})
            })
          })
        } else if (item.type === 'table' && item.subtype === 'normaltable') {
        } else if (item.type === 'table') {
          item.cols && item.cols.forEach(col => {
            if (col.type !== 'action') return
            col.elements && col.elements.forEach(cell => {
src/tabviews/zshare/topSearch/index.jsx
@@ -81,7 +81,7 @@
      if (config.type === 'search') {
        _setting.float = config.wrap.float || 'left'
        _setting.style = config.style
      } else if (config.type === 'table' && config.subtype !== 'tablecard') {
      } else if (config.type === 'table') {
        _setting.float = 'left'
      } else {
        _setting.float = 'right'
src/templates/zshare/formconfig.jsx
@@ -2379,7 +2379,7 @@
 * @param {*} linkableFields  // 可关联表单
 * @param {*} linksupFields   // 上级表单
 */
export function getModalForm (card, inputfields = [], tabfields = [], linkableFields, linksupFields) {
export function getModalForm (card, inputfields = [], tabfields = [], linkableFields, linksupFields, columns = []) {
  let appType = sessionStorage.getItem('appType')
  let roleList = sessionStorage.getItem('sysRoles')
  if (roleList) {
@@ -2578,7 +2578,8 @@
      label: '字段',
      initVal: card.field || '',
      required: true,
      readonly: false
      readonly: false,
      options: columns
    },
    {
      type: 'select',
src/templates/zshare/modalform/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Form, Row, Col, Input, Select, Radio, notification, InputNumber, Tooltip, Checkbox } from 'antd'
import { Form, Row, Col, Input, Select, Radio, notification, InputNumber, Tooltip, Checkbox, AutoComplete } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons'
import { formRule } from '@/utils/option.js'
@@ -565,6 +565,12 @@
    this.props.form.setFieldsValue({dataSource: resource})
  }
  complete = (key, option) => {
    let label = option.props.label
    this.props.form.setFieldsValue({label: label})
  }
  getFields() {
    const { getFieldDecorator } = this.props.form
    const { transfield } = this.state
@@ -613,7 +619,20 @@
          })
        }
        content = <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />
        if (item.key === 'field' && item.options && item.options.length > 0) {
          content = <AutoComplete
            dataSource={item.options.map((cell) => <AutoComplete.Option label={cell.label} value={cell.field} key={cell.uuid}>
              {cell.field}
            </AutoComplete.Option>)}
            filterOption={(input, option) => option.props.children.indexOf(input) > -1}
            onSelect={this.complete}
            placeholder=""
          >
            <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />
          </AutoComplete>
        } else {
          content = <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />
        }
      } else if (item.type === 'number') {
        rules = [
          { required: item.required, message: '请输入' + item.label + '!' }
src/utils/sqlFormatter.js
@@ -242,7 +242,6 @@
 
        Formatter.prototype.format = function format(query) {
                    this.tokens = this.tokenizer.tokenize(query);
                    console.log(this.tokens)
            var formattedQuery = this.getFormattedQueryFromTokens();
            return formattedQuery.trim();
        };
src/utils/utils-custom.js
@@ -342,73 +342,6 @@
  }
  /**
   * @description 获取删除按钮Id
   * @return {String}  name
   */
  static getDelButtonIds (card) {
    let appType = sessionStorage.getItem('appType')
    let uuids = []
    if (appType === 'mob') return uuids
    const getUuids = (item) => {
      if (item.type === 'tabs') {
        item.subtabs.forEach(tab => {
          tab.components.forEach(c => {
            getUuids(c)
          })
        })
      } else if (item.type === 'group') {
        item.components.forEach(c => {
          getUuids(c)
        })
      } else {
        item.action && item.action.forEach(act => {
          if (act.origin || (appType === 'pc' && act.OpenType !== 'popview')) return
          uuids.push(act.uuid)
        })
        if (['card', 'carousel', 'timeline'].includes(item.type) || (item.type === 'table' && item.subtype === 'tablecard')) {
          item.subcards.forEach(_card => {
            _card.elements && _card.elements.forEach(cell => {
              if (cell.eleType !== 'button') return
              if (appType === 'pc' && cell.OpenType !== 'popview') return
              uuids.push(cell.uuid)
            })
            _card.backElements && _card.backElements.forEach(cell => {
              if (cell.eleType !== 'button') return
              if (appType === 'pc' && cell.OpenType !== 'popview') return
              uuids.push(cell.uuid)
            })
          })
        } else if (item.type === 'table' && (item.subtype === 'normaltable' || item.subtype === 'editable')) {
          item.cols && item.cols.forEach(col => {
            if (col.type !== 'action') return
            col.elements && col.elements.forEach(cell => {
              if (appType === 'pc' && cell.OpenType !== 'popview') return
              uuids.push(cell.uuid)
            })
          })
        } else if (item.type === 'balcony') {
          item.elements && item.elements.forEach(cell => {
            if (appType === 'pc' && cell.OpenType !== 'popview') return
            uuids.push(cell.uuid)
          })
        }
      }
    }
    getUuids(card)
    return uuids
  }
  /**
   * @description 生成32位uuid string + 时间
   * @return {String}  uuid
   */
@@ -433,6 +366,10 @@
        return item
      }
      if (item.subtype === 'tablecard') { // 兼容
        item.type = 'card'
      }
      uuids[item.uuid] = this.getuuid()
      item.uuid = uuids[item.uuid]
@@ -454,7 +391,7 @@
          }
          return cell
        })
      } else if (['card', 'carousel', 'timeline'].includes(item.type) || (item.type === 'table' && item.subtype === 'tablecard')) {
      } else if (['card', 'carousel', 'timeline'].includes(item.type)) {
        if (item.wrap.datatype === 'public' && uuids[item.wrap.publicId]) {
          item.wrap.publicId = uuids[item.wrap.publicId]
        }
@@ -514,7 +451,7 @@
            return cell
          })
        }
      } else if (item.type === 'table' && (item.subtype === 'normaltable' || item.subtype === 'editable') && item.cols) {
      } else if (item.type === 'table' && item.cols) {
        let loopCol = (col) => {
          col.subcols = col.subcols.map(c => {
            c.uuid = this.getuuid()
@@ -678,9 +615,13 @@
  * @description 重置组件配置
  * @return {String}  item 组件信息
  */
  static resetComponentConfig = (item, copyBtns, uuids = {}) => {
  static resetComponentConfig = (item, uuids = {}) => {
    if (item.type === 'navbar') {
      return item
    }
    if (item.subtype === 'tablecard') { // 兼容
      item.type = 'card'
    }
    let _uuid = this.getuuid()
@@ -707,7 +648,7 @@
        cell.uuid = this.getuuid()
        return cell
      })
    } else if (['card', 'carousel', 'timeline'].includes(item.type) || (item.type === 'table' && item.subtype === 'tablecard')) {
    } else if (['card', 'carousel', 'timeline'].includes(item.type)) {
      item.subcards.forEach(card => {
        card.uuid = this.getuuid()
        if (card.elements) {
@@ -715,14 +656,7 @@
            card.elements = card.elements.filter(b => b.OpenType !== 'popview' && b.OpenType !== 'funcbutton')
          }
          card.elements = card.elements.map(cell => {
            let _uuid = this.getuuid()
            if (cell.OpenType === 'popview' && copyBtns) {
              let _cell = JSON.parse(JSON.stringify(cell))
              _cell.$originUuid = _cell.uuid
              _cell.uuid = _uuid
              copyBtns.set(_uuid, _cell)
            }
            cell.uuid = _uuid
            cell.uuid = this.getuuid()
            return cell
          })
        }
@@ -731,14 +665,7 @@
            card.elements = card.elements.filter(b => b.OpenType !== 'popview' && b.OpenType !== 'funcbutton')
          }
          card.backElements = card.backElements.map(cell => {
            let _uuid = this.getuuid()
            if (cell.OpenType === 'popview' && copyBtns) {
              let _cell = JSON.parse(JSON.stringify(cell))
              _cell.$originUuid = _cell.uuid
              _cell.uuid = _uuid
              copyBtns.set(_uuid, _cell)
            }
            cell.uuid = _uuid
            cell.uuid = this.getuuid()
            return cell
          })
        }
@@ -749,18 +676,11 @@
          item.elements = item.elements.filter(b => b.OpenType !== 'popview' && b.OpenType !== 'funcbutton')
        }
        item.elements = item.elements.map(cell => {
          let _uuid = this.getuuid()
          if (cell.OpenType === 'popview' && copyBtns) {
            let _cell = JSON.parse(JSON.stringify(cell))
            _cell.$originUuid = _cell.uuid
            _cell.uuid = _uuid
            copyBtns.set(_uuid, _cell)
          }
          cell.uuid = _uuid
          cell.uuid = this.getuuid()
          return cell
        })
      }
    } else if (item.type === 'table' && (item.subtype === 'normaltable' || item.subtype === 'editable') && item.cols) {
    } else if (item.type === 'table' && item.cols) {
      let loopCol = (col) => {
        col.subcols = col.subcols.map(c => {
          c.uuid = this.getuuid()
@@ -798,14 +718,7 @@
            col.elements = col.elements.filter(c => c.OpenType !== 'popview' && c.OpenType !== 'funcbutton')
          }
          col.elements = col.elements.map(cell => {
            let _uuid = this.getuuid()
            if (cell.OpenType === 'popview' && copyBtns) {
              let _cell = JSON.parse(JSON.stringify(cell))
              _cell.$originUuid = _cell.uuid
              _cell.uuid = _uuid
              copyBtns.set(_uuid, _cell)
            }
            cell.uuid = _uuid
            cell.uuid = this.getuuid()
            return cell
          })
        }
@@ -833,9 +746,7 @@
      })
    }
    if (item.btnlog) {
      item.btnlog = null
    }
    delete item.btnlog
    let oriUids = {}
    if (item.action) {
@@ -846,13 +757,6 @@
        let _uuid = this.getuuid()
        oriUids[cell.uuid] = _uuid
        if (cell.OpenType === 'popview' && copyBtns) {
          let _cell = JSON.parse(JSON.stringify(cell))
          _cell.$originUuid = _cell.uuid
          _cell.uuid = _uuid
          copyBtns.set(_uuid, _cell)
        }
        cell.uuid = _uuid
@@ -976,8 +880,12 @@
        if (cell.eleType !== 'button') return
        if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
          action.push(cell)
        } else if (pops && cell.OpenType === 'popview') {
          pops.push({...cell, parentId: config.uuid})
        } else if (cell.OpenType === 'popview') {
          if (pops) {
            pops.push({...cell, parentId: config.uuid})
          } else if (cell.config && cell.config.$tables) {
            tables.push(...cell.config.$tables)
          }
        }
      })
  
@@ -986,8 +894,12 @@
          if (cell.eleType !== 'button') return
          if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
            action.push(cell)
          } else if (pops && cell.OpenType === 'popview') {
            pops.push({...cell, parentId: config.uuid})
          } else if (cell.OpenType === 'popview') {
            if (pops) {
              pops.push({...cell, parentId: config.uuid})
            } else if (cell.config && cell.config.$tables) {
              tables.push(...cell.config.$tables)
            }
          }
        })
      }
@@ -998,8 +910,12 @@
      col.elements.forEach(cell => {
        if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
          action.push(cell)
        } else if (pops && cell.OpenType === 'popview') {
          pops.push({...cell, parentId: config.uuid})
        } else if (cell.OpenType === 'popview') {
          if (pops) {
            pops.push({...cell, parentId: config.uuid})
          } else if (cell.config && cell.config.$tables) {
            tables.push(...cell.config.$tables)
          }
        }
      })
    }
@@ -1009,16 +925,24 @@
    if (cell.eleType !== 'button') return
    if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
      action.push(cell)
    } else if (pops && cell.OpenType === 'popview') {
      pops.push({...cell, parentId: config.uuid})
    } else if (cell.OpenType === 'popview') {
      if (pops) {
        pops.push({...cell, parentId: config.uuid})
      } else if (cell.config && cell.config.$tables) {
        tables.push(...cell.config.$tables)
      }
    }
  })
  config.action && config.action.forEach(cell => {
    if (['pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
      action.push(cell)
    } else if (pops && cell.OpenType === 'popview') {
      pops.push({...cell, parentId: config.uuid})
    } else if (cell.OpenType === 'popview') {
      if (pops) {
        pops.push({...cell, parentId: config.uuid})
      } else if (cell.config && cell.config.$tables) {
        tables.push(...cell.config.$tables)
      }
    }
  })
src/views/billprint/index.jsx
@@ -262,7 +262,11 @@
          if (component.search) component.search = []
          component.data = [] // 初始化数据为空
          if (component.type === 'table' && component.subtype === 'normaltable') {
          if (component.subtype === 'tablecard') { // 兼容
            component.type = 'card'
          }
          if (component.type === 'table') {
            let getColumns = (cols) => {
              return cols.map(item => {
                if (item.type === 'colspan') {
@@ -720,7 +724,7 @@
            <PropCard config={item} initdata={item.data} mainSearch={[]} />
          </Col>
        )
      } else if (item.type === 'table' && item.subtype === 'tablecard') {
      } else if (item.type === 'card' && item.subtype === 'tablecard') {
        return (
          <Col span={item.width} key={item.uuid}>
            <TableCard config={item} initdata={item.data} mainSearch={[]}/>
src/views/interface/history/index.jsx
@@ -222,7 +222,7 @@
      interface: window.GLOB.baseurl + 'webapi/dostars',
      method: 'POST',
      params: [],
      raw: "{\n \"func\":\"******\",\n \"LoginUID\":\"******\",\n \"UserID\":\"******\",\n \"nonc\":\"" + Utils.getguid() + "\",\n \"t\":" + parseInt(new Date().getTime() / 1000) + "\n}",
      raw: "{\n \"func\":\"******\",\n \"LoginUID\":\"" + (sessionStorage.getItem('LoginUID') || "******") + "\",\n \"UserID\":\"" + (sessionStorage.getItem('UserID') || "******") + "\",\n \"nonc\":\"" + Utils.getguid() + "\",\n \"t\":" + parseInt(new Date().getTime() / 1000) + "\n}",
      uuid: 'dologon'
    }
    MKEmitter.emit('useInterface', m)
src/views/menudesign/index.jsx
@@ -14,7 +14,7 @@
import Utils, { setGLOBFuncs } from '@/utils/utils.js'
import antdZhCN from 'antd/es/locale/zh_CN'
import MKEmitter from '@/utils/events.js'
import MenuUtils, { getTables } from '@/utils/utils-custom.js'
import { getTables } from '@/utils/utils-custom.js'
import asyncComponent from '@/utils/asyncComponent'
import '@/assets/css/design.scss'
@@ -59,8 +59,6 @@
    MenuName: '',
    MenuNo: '',
    delButtons: [],
    copyButtons: [],
    activeKey: 'basedata',
    menuloading: false,
    oriConfig: null,
    config: null,
@@ -70,6 +68,7 @@
    eyeopen: false,
    view: '',
    popConfig: null,
    needUpdate: false
  }
  UNSAFE_componentWillMount() {
@@ -106,8 +105,6 @@
  }
  componentDidMount () {
    MKEmitter.addListener('delButtons', this.delButtons)
    MKEmitter.addListener('copyButtons', this.copyButtons)
    MKEmitter.addListener('changePopview', this.initPopview)
    MKEmitter.addListener('triggerMenuSave', this.triggerMenuSave)
    MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent)
@@ -187,15 +184,38 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('delButtons', this.delButtons)
    MKEmitter.removeListener('copyButtons', this.copyButtons)
    MKEmitter.removeListener('changePopview', this.initPopview)
    MKEmitter.removeListener('triggerMenuSave', this.triggerMenuSave)
    MKEmitter.removeListener('updateCustomComponent', this.updateCustomComponent)
  }
  triggerMenuSave = () => {
    if (this.state.view === 'popview') return
    this.submitConfig()
  }
  submitPopConfig = (btnconfig) => {
    let parents = {[btnconfig.ParentId]: true}
    let popbtns = {[btnconfig.uuid]: fromJS(btnconfig).toJS()}
    let config = fromJS(this.state.config).toJS()
    config.components = this.setPopView(config.components, parents, popbtns)
    this.setState({ config }, () => {
      this.submitConfig()
    })
  }
  closePop = () => {
    const {config} = this.state
    sessionStorage.setItem('editMenuType', 'menu')
    window.GLOB.urlFields = config.urlFields || []
    window.GLOB.customMenu = config
    this.setState({view: '', popConfig: null})
  }
  getPrintTemp = () => {
@@ -327,16 +347,17 @@
    this.setState({customComponents: coms})
  }
  delButtons = (items) => {
    this.setState({ delButtons: [...this.state.delButtons, ...items] })
  }
  copyButtons = (items) => {
    this.setState({copyButtons: [...this.state.copyButtons, ...items]})
  }
  initPopview = (card, btn) => {
    const { config } = this.state
    if (!this.checkBase()) {
      notification.warning({
        top: 92,
        message: '请完善基本信息!',
        duration: 5
      })
      return
    }
    let _btn = fromJS(btn).toJS()
@@ -344,13 +365,14 @@
      _btn.config.uuid = _btn.uuid
      _btn.config.MenuID = _btn.uuid
      _btn.config.ParentId = card.uuid
      _btn.config.MenuName = _btn.label
    } else {
      _btn.config = {
        uuid: _btn.uuid,
        MenuID: _btn.uuid,
        ParentId: card.uuid,
        enabled: false,
        MenuName: btn.label,
        MenuName: _btn.label,
        tables: config.tables || [],
        Template: 'CustomPage',
        components: [],
@@ -451,19 +473,20 @@
        config.open_edition = result.open_edition || ''
        window.GLOB.urlFields = config.urlFields || []
        // if (config.version !== 2.0) {
        //   this.setState({
        //     oriConfig: fromJS(config).toJS(),
        //     comloading: true
        //   })
        //   this.updatePage(config)
        // } else {
        if (config.version !== 2.0) {
          this.setState({
            oriConfig: fromJS(config).toJS(),
            comloading: true,
            needUpdate: true
          })
          this.updatePage(config)
        } else {
          this.setState({
            oriConfig: fromJS(config).toJS(),
            config: config
          })
          window.GLOB.customMenu = config
        // }
        }
      } else {
        notification.warning({
          top: 92,
@@ -474,28 +497,180 @@
    })
  }
  collectTB = (components, popBtns) => {
    return components.map(item => {
      if (item.type === 'tabs') {
        item.subtabs.forEach(tab => {
          delete tab.floor
          delete tab.hasSearch
          delete tab.parentId
          tab.components = this.collectTB(tab.components, popBtns)
        })
      } else if (item.type === 'group') {
        item.components = this.collectTB(item.components, popBtns)
      } else if (item.type !== 'search') {
        item.$tables = getTables(item, popBtns)
      }
      if (item.subtype === 'tablecard') { // 兼容
        item.type = 'card'
      }
      delete item.tabId
      delete item.parentId
      delete item.btnlog
      delete item.floor
      delete item.dataName
      return item
    })
  }
  setPopView = (components, parents, popbtns) => {
    return components.map(item => {
      if (item.type === 'tabs') {
        item.subtabs.forEach(tab => {
          tab.components = this.setPopView(tab.components, parents, popbtns)
        })
      } else if (item.type === 'group') {
        item.components = this.setPopView(item.components, parents, popbtns)
      } else if (parents[item.uuid]) {
        this.setpopConfig(item, popbtns)
      }
      return item
    })
  }
  setpopConfig = (config, popbtns) => {
    config.subcards && config.subcards.forEach(item => {
      item.elements.forEach(cell => {
        if (cell.eleType !== 'button') return
        if (cell.OpenType === 'popview' && popbtns[cell.uuid]) {
          cell.config = popbtns[cell.uuid]
        }
      })
    })
    config.cols && config.cols.forEach(col => {
      if (col.type === 'action') {
        col.elements.forEach(cell => {
          if (cell.OpenType === 'popview' && popbtns[cell.uuid]) {
            cell.config = popbtns[cell.uuid]
          }
        })
      }
    })
    config.elements && config.elements.forEach(cell => {
      if (cell.eleType !== 'button') return
      if (cell.OpenType === 'popview' && popbtns[cell.uuid]) {
        cell.config = popbtns[cell.uuid]
      }
    })
    config.action && config.action.forEach(cell => {
      if (cell.OpenType === 'popview' && popbtns[cell.uuid]) {
        cell.config = popbtns[cell.uuid]
      }
    })
    config.$tables = getTables(config)
  }
  updatePage = (config) => {
    let popBtns = []
    let traversal = (components) => {
      components.forEach(item => {
        if (item.type === 'tabs') {
          item.subtabs.forEach(tab => {
            traversal(tab.components)
          })
        } else if (item.type === 'group') {
          traversal(item.components)
        } else if (item.type !== 'search') {
          item.$tables = getTables(item, popBtns)
        }
    config.components = this.collectTB(config.components, popBtns)
    if (popBtns.length === 0) {
      this.setState({
        config: config,
        comloading: false,
        needUpdate: true
      })
      return
    }
    traversal(config.components)
    Promise.all(popBtns.map((pop, i) => {
      return new Promise(resolve => {
        let param = {
          func: 'sPC_Get_LongParam',
          MenuID: pop.uuid
        }
        setTimeout(() => {
          Api.getSystemConfig(param).then(res => {
            let _config = null
            try {
              _config = res.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(res.LongParam))) : null
            } catch (e) {
              console.warn('Parse Failure')
              _config = null
            }
            if (_config && _config.Template !== 'CustomPage') {
              _config = null
            }
            if (_config) {
              _config.uuid = pop.uuid
              _config.MenuID = pop.uuid
              _config.ParentId = pop.parentId
              _config.MenuName = pop.label
              delete _config.MenuNo
              delete _config.open_edition
              delete _config.version
              _config.components = this.collectTB(_config.components)
            } else {
              _config = {
                uuid: pop.uuid,
                MenuID: pop.uuid,
                ParentId: pop.parentId,
                enabled: false,
                MenuName: pop.label,
                tables: config.tables || [],
                Template: 'CustomPage',
                components: [],
                viewType: 'popview',
                style: { backgroundColor: '#ffffff', backgroundImage: '', paddingTop: '16px', paddingBottom: '40px', paddingLeft: '16px', paddingRight: '16px' }
              }
            }
            resolve(_config)
          })
        }, i * 40)
      })
    })).then(results => {
      let bts = []
      results = results.map(res => {
        let tbs = []
        bts.push(...this.getMenuMessage(res, tbs))
        res.$tables = Array.from(new Set(tbs))
        return res
      })
      bts = bts.map(bt => bt.replace(/select\s'/, '').replace(/'\sas.*/, ''))
      bts.push(...popBtns.map(pop => pop.uuid))
      let parents = {}
      let popbtns = {}
      results.forEach(item => {
        parents[item.ParentId] = true
        popbtns[item.uuid] = item
      })
      config.components = this.setPopView(config.components, parents, popbtns)
      this.setState({ delButtons: bts, config, comloading: false })
    })
  }
  getMenuMessage = (delButtons, tbs) => {
    const { config } = this.state
  getMenuMessage = (config, tbs) => {
    let buttons = []
    let _sort = 1
@@ -504,89 +679,47 @@
        if (item.$tables) {
          tbs.push(...item.$tables)
        }
        if (item.action && item.action.length > 0) {
          item.action.forEach(btn => {
            if (btn.hidden === 'true') return
            buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort, '${config.uuid}' as parentid, 40 as Type`)
            _sort++
          })
        }
        if (item.type === 'tabs') {
          item.subtabs.forEach(tab => {
            traversal(tab.components)
          })
        } else if (item.type === 'group') {
          traversal(item.components)
        } else if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) {
          item.action && item.action.forEach(btn => {
            if (btn.hidden === 'true') {
              delButtons.push(btn.uuid)
              return
            }
            buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
            _sort++
          })
        } else if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
          item.subcards.forEach(card => {
            card.elements && card.elements.forEach(cell => {
              if (cell.eleType !== 'button') return
              if (cell.hidden === 'true') {
                delButtons.push(cell.uuid)
                return
              }
              buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`)
              if (cell.hidden === 'true') return
              buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort, '${config.uuid}' as parentid, 40 as Type`)
              _sort++
            })
            card.backElements && card.backElements.forEach(cell => {
              if (cell.eleType !== 'button') return
              if (cell.hidden === 'true') {
                delButtons.push(cell.uuid)
                return
              }
              buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`)
              _sort++
            })
          })
        } else if (item.type === 'carousel' || item.type === 'timeline') {
          item.subcards.forEach(card => {
            card.elements && card.elements.forEach(cell => {
              if (cell.eleType !== 'button') return
              if (cell.hidden === 'true') {
                delButtons.push(cell.uuid)
                return
              }
              buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`)
              if (cell.hidden === 'true') return
              buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort, '${config.uuid}' as parentid, 40 as Type`)
              _sort++
            })
          })
        } else if (item.type === 'balcony') {
          item.elements && item.elements.forEach(cell => {
            if (cell.eleType !== 'button') return
            if (cell.hidden === 'true') {
              delButtons.push(cell.uuid)
              return
            }
            buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`)
            if (cell.hidden === 'true') return
            buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort, '${config.uuid}' as parentid, 40 as Type`)
            _sort++
          })
        } else if (item.type === 'line' || item.type === 'bar' || item.type === 'chart') {
          item.action && item.action.forEach(btn => {
            if (btn.hidden === 'true') {
              delButtons.push(btn.uuid)
              return
            }
            buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
            _sort++
          })
        } else if (item.type === 'table' && (item.subtype === 'normaltable' || item.subtype === 'editable')) {
          item.action && item.action.forEach(btn => {
            if (btn.hidden === 'true') {
              delButtons.push(btn.uuid)
              return
            }
            buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
            _sort++
          })
        } else if (item.type === 'table') {
          item.cols && item.cols.forEach(col => {
            if (col.type !== 'action') return
            col.elements.forEach(btn => {
              if (btn.hidden === 'true') {
                delButtons.push(btn.uuid)
                return
              }
              buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`)
              if (btn.hidden === 'true') return
              buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort, '${config.uuid}' as parentid, 40 as Type`)
              _sort++
            })
          })
@@ -596,31 +729,38 @@
    traversal(config.components)
    if (config.interfaces) {
      config.interfaces.forEach(item => {
        if (item.$tables) {
          tbs.push(...item.$tables)
        }
      })
    }
    return buttons
  }
  submitConfig = () => {
    const { MenuType, copyButtons } = this.state
    let config = fromJS(this.state.config).toJS()
  checkBase = () => {
    const { MenuType, config } = this.state
    if (MenuType === 'billPrint' && config.printPage === 'page' && !config.everyPCount) {
      return false
    } else if (MenuType === 'home' && (config.cacheUseful === 'true' && !config.cacheTime)) {
      return false
    } else if (MenuType === 'custom' && (!config.MenuName || !config.MenuNo || !config.fstMenuId || !config.parentId || (config.cacheUseful === 'true' && !config.cacheTime))) {
      return false
    }
    return true
  }
  submitConfig = () => {
    const { MenuType } = this.state
    let config = fromJS(this.state.config).toJS()
    if (!this.checkBase()) {
      notification.warning({
        top: 92,
        message: '请完善基本信息!',
        duration: 5
      })
      return
    } else if (MenuType === 'home' && (config.cacheUseful === 'true' && !config.cacheTime)) {
      notification.warning({
        top: 92,
        message: '请完善菜单基本信息!',
        duration: 5
      })
      return
    } else if (MenuType === 'custom' && (!config.MenuName || !config.MenuNo || !config.fstMenuId || !config.parentId || (config.cacheUseful === 'true' && !config.cacheTime))) {
      notification.warning({
        top: 92,
        message: '请完善菜单基本信息!',
        duration: 5
      })
      return
@@ -636,8 +776,7 @@
      }
      let tbs = []
      let delButtons = fromJS(this.state.delButtons).toJS()
      let btns = this.getMenuMessage(delButtons, tbs)
      let btns = this.getMenuMessage(config, tbs)
      let arr = []
      tbs = tbs.filter(tb => {
        let _tb = tb.toLowerCase()
@@ -696,24 +835,15 @@
        ParentID: config.uuid,
        MenuNo: config.MenuNo,
        Template: 'CustomPage',
        PageParam: '',
        LongParam: '',
        LText: []
        button_proc_edition: 'Y'
      }
      let btnIds = '' // 用于复制按钮的过滤
      if (MenuType !== 'billPrint') {
        btnParam.LText = btns
        btnParam.LText = btnParam.LText.join(' union all ')
      btnParam.LText = btns.join(' union all ')
        btnIds = btnParam.LText
        btnParam.LText = Utils.formatOptions(btnParam.LText)
        btnParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        btnParam.secretkey = Utils.encrypt(btnParam.LText, btnParam.timestamp)
      } else {
        btnParam.LText = ''
      }
      btnParam.LText = Utils.formatOptions(btnParam.LText)
      btnParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      btnParam.secretkey = Utils.encrypt(btnParam.LText, btnParam.timestamp)
      new Promise(resolve => {
        if (MenuType === 'billPrint') { // 打印生成页面效果图
@@ -737,206 +867,89 @@
                  Remark: '',
                  temp_type: 'billprint',
                }).then(response => {
                  if (response.status) {
                    resolve(true)
                  } else {
                    notification.warning({
                      top: 92,
                      message: response.message,
                      duration: 5
                    })
                    resolve(false)
                  }
                  resolve(response)
                })
              } else {
                notification.warning({
                  top: 92,
                  message: result.ErrMesg,
                  duration: 5
                })
                resolve(false)
                resolve(result)
              }
            })
          })
        } else {
          resolve(true)
          resolve({status: true})
        }
      }).then(res => { // 按钮删除
        if (!res) return
      }).then(res => { // 页面保存
        if (!res || !res.status) return res
        if (delButtons.length === 0) {
        return Api.getSystemConfig(param)
      }).then(res => { // 按钮删除
        if (!res || !res.status) return res
        if (MenuType !== 'billPrint') { // 基本信息改变时,通知菜单列表更新
          let ori = this.state.oriConfig
          if (config.MenuName !== ori.MenuName || config.MenuNo !== ori.MenuNo || config.parentId !== ori.parentId) {
            localStorage.setItem('menuUpdate', new Date().getTime())
          }
        }
        config.open_edition = res.open_edition || ''
        this.setState({
          config,
          oriConfig: fromJS(config).toJS(),
          needUpdate: false
        })
        if (this.state.delButtons.length === 0) {
          return {
            status: true
          }
        } else {
          let _param = {
            func: 'sPC_MainMenu_Del',
            MenuID: delButtons.join(',')
            MenuID: this.state.delButtons.join(',')
          }
          return Api.getSystemConfig(_param)
        }
      }).then(res => { // 页面保存
        if (!res) return
        if (res.status) {
          return Api.getSystemConfig(param)
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
          return false
        }
      }).then(res => { // 页面按钮关系保存
        if (!res) return
        if (!res || !res.status) return res
        if (res.status) {
          if (MenuType !== 'billPrint') { // 基本信息改变时,通知菜单列表更新
            let ori = this.state.oriConfig
            if (config.MenuName !== ori.MenuName || config.MenuNo !== ori.MenuNo || config.parentId !== ori.parentId) {
              localStorage.setItem('menuUpdate', new Date().getTime())
            }
          }
          config.open_edition = res.open_edition || ''
          this.setState({
            config,
            oriConfig: fromJS(config).toJS(),
          })
        this.setState({
          delButtons: []
        })
          if (btnParam.LText) {
            return Api.getSystemConfig(btnParam)
          } else {
            return {
              status: true
            }
          }
        if (MenuType !== 'billPrint') {
          return Api.getSystemConfig(btnParam)
        } else {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
          return false
        }
      }).then(res => { // 按钮复制
        if (!res) return
        if (!res.status) {
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
          return false
        }
        if (copyButtons.length === 0) {
          return {
            status: true
          }
        } else {
          return new Promise(resolve => {
            let deffers = copyButtons.map(item => {
              return new Promise(resolve => {
                if (btnIds.indexOf(item.uuid) === -1) { // 复制的按钮已删除
                  resolve({
                    status: true
                  })
                  return
                }
                Api.getSystemConfig({
                  func: 'sPC_Get_LongParam',
                  MenuID: item.$originUuid
                }).then(result => {
                  if (result.status) {
                    let _conf = ''
                    try {
                      _conf = result.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) : ''
                    } catch (e) {
                      console.warn('Parse Failure')
                      _conf = ''
                    }
                    if (_conf) {
                      _conf.components = MenuUtils.resetConfig(_conf.components)
                      _conf.uuid = item.uuid
                      _conf.MenuID = item.uuid
                      _conf.Template = 'CustomPage'
                      _conf.enabled = false
                    } else {
                      resolve({
                        status: true
                      })
                      return
                    }
                    let _param = {
                      func: 'sPC_ButtonParam_AddUpt',
                      ParentID: config.uuid,
                      MenuID: item.uuid,
                      MenuNo: '',
                      Template: 'CustomPage',
                      MenuName: item.label,
                      PageParam: JSON.stringify({Template: 'CustomPage'}),
                      LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(_conf)))
                    }
                    Api.getSystemConfig(_param).then(response => {
                      resolve(response)
                    })
                  }
                })
              })
            })
            Promise.all(deffers).then(result => {
              let error = null
              result.forEach(response => {
                if (!response.status) {
                  error = response
                }
              })
              if (error) {
                notification.warning({
                  top: 92,
                  message: error.message,
                  duration: 5
                })
                resolve(false)
              } else {
                resolve({
                  status: true
                })
              }
            })
          })
        }
      }).then(res => {
        if (res && res.status) {
          this.setState({
            delButtons: [],
            copyButtons: [],
            menuloading: false
          })
        this.setState({
          menuloading: false
        })
        if (!res) return
        if (res.status) {
          notification.success({
            top: 92,
            message: '保存成功',
            duration: 2
          })
          MKEmitter.emit('completeSave')
        } else {
          this.setState({
            menuloading: false
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
        }
        MKEmitter.emit('completeSave')
      })
    }, 300 + (+sessionStorage.getItem('mkDelay')))
  }
  getRoleFields = () => {
    if (sessionStorage.getItem('sysRoles') || sessionStorage.getItem('permFuncField')) return
    if (sessionStorage.getItem('sysRoles')) return
    Api.getSystemConfig({func: 'sPC_Get_Roles_sModular'}).then(res => {
      if (res.status) {
        let _permFuncField = []
@@ -1096,19 +1109,19 @@
  }
  render () {
    const { view, activeKey, comloading, MenuType, MenuId, config, settingshow, ParentId, menuloading, customComponents, eyeopen } = this.state
    const { view, comloading, MenuType, MenuId, config, settingshow, ParentId, menuloading, customComponents, eyeopen, needUpdate } = this.state
    return (
      <ConfigProvider locale={_locale}>
        {view !== 'popview' ? <div className={'pc-menu-view ' + (MenuType || '')}>
          <Header />
          <DndProvider backend={HTML5Backend}>
        <Header />
        <DndProvider backend={HTML5Backend}>
          {view !== 'popview' ? <div className={'pc-menu-view ' + (MenuType || '')}>
            <div className="menu-body">
              <div className={'menu-setting ' + (!settingshow ? 'hidden' : '')}>
                <div className="draw">
                  {settingshow ? <DoubleLeftOutlined onClick={this.changeSetting}/> : <DoubleRightOutlined onClick={this.changeSetting}/>}
                </div>
                <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
                <Collapse accordion defaultActiveKey="basedata" bordered={false}>
                  {/* 基本信息 */}
                  <Panel header="基本信息" key="basedata">
                    {/* 菜单信息 */}
@@ -1163,7 +1176,7 @@
                    <StyleCombControlButton menu={config} />
                    <PasteController insert={this.insert} />
                    <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config && config.enabled} onChange={this.onEnabledChange} />
                    <Button type="primary" id="save-config" onClick={this.submitConfig} loading={menuloading}>保存</Button>
                    <Button type="primary" id="save-config" className={needUpdate ? 'update-tip' : ''} onClick={this.submitConfig} loading={menuloading}>保存</Button>
                    <Button type="default" onClick={this.closeView}>关闭</Button>
                  </div>
                } style={{ width: '100%' }}>
@@ -1171,8 +1184,8 @@
                </Card>
              </div>
            </div>
          </DndProvider>
        </div> : <PopView btn={this.state.popConfig}/>}
          </div> : <PopView btn={this.state.popConfig} save={this.submitPopConfig} cancel={this.closePop}/>}
        </DndProvider>
        <ModalController />
        <StyleController />
        <StyleCombController />
src/views/menudesign/index.scss
@@ -17,6 +17,17 @@
      text-decoration: line-through!important;
    }
  }
  .update-tip::after {
    content: ' ';
    display: inline-block;
    position: absolute;
    top: -4px;
    right: -4px;
    width: 8px;
    height: 8px;
    background-color: red;
    border-radius: 8px;
  }
  .eye-open {
    .component-name {
      display: block;
src/views/menudesign/popview/index.jsx
@@ -1,8 +1,6 @@
import React, { Component } from 'react'
import { DndProvider } from 'react-dnd'
import { is, fromJS } from 'immutable'
import PropTypes from 'prop-types'
import HTML5Backend from 'react-dnd-html5-backend'
import { notification, Modal, Collapse, Card, Switch, Button } from 'antd'
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'
@@ -15,7 +13,6 @@
const { confirm } = Modal
const MenuForm = asyncComponent(() => import('./menuform'))
const Header = asyncComponent(() => import('@/menu/header'))
const SourceWrap = asyncComponent(() => import('@/menu/modulesource'))
const Modulecell = asyncComponent(() => import('@/menu/modulecell'))
const MenuShell = asyncComponent(() => import('@/menu/menushell'))
@@ -28,12 +25,11 @@
class PopViewDesign extends Component {
  static propTpyes = {
    btn: PropTypes.object,
    updateConfig: PropTypes.func
    save: PropTypes.func,
    cancel: PropTypes.func
  }
  state = {
    MenuId: '',
    activeKey: 'basedata',
    menuloading: false,
    oriConfig: null,
    config: null,
@@ -54,6 +50,7 @@
  }
  componentDidMount () {
    MKEmitter.addListener('completeSave', this.completeSave)
    MKEmitter.addListener('triggerMenuSave', this.submitConfig)
  }
@@ -68,6 +65,7 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('completeSave', this.completeSave)
    MKEmitter.removeListener('triggerMenuSave', this.submitConfig)
  }
@@ -75,21 +73,23 @@
    const { oriConfig, config } = this.state
    if (!is(fromJS(oriConfig), fromJS(config))) {
      const _this = this
      confirm({
        title: '配置已修改,放弃保存吗?',
        content: '',
        onOk() {
          // window.history.back()
          _this.props.cancel()
        },
        onCancel() {}
      })
    } else {
      // window.history.back()
      this.props.cancel()
    }
  }
  getMenuMessage = (tbs) => {
    const { config } = this.state
  getMenuMessage = (config) => {
    let tbs = []
    let traversal = (components) => {
      components.forEach(item => {
@@ -107,6 +107,14 @@
    }
    traversal(config.components)
    config.$tables = Array.from(new Set(tbs))
  }
  completeSave = () => {
    this.setState({
      menuloading: false
    })
  }
  submitConfig = () => {
@@ -125,9 +133,16 @@
      config.enabled = false
    }
    this.getMenuMessage(config)
    this.setState({
      config: config,
      menuloading: true
    })
    window.GLOB.customMenu = config
    this.props.save(config)
  }
  onEnabledChange = () => {
@@ -218,6 +233,7 @@
    config.components.push(item)
    this.setState({config})
    window.GLOB.customMenu = config
    
    notification.success({
@@ -228,53 +244,50 @@
  }
  render () {
    const { activeKey, comloading, config, menuloading, eyeopen } = this.state
    const { comloading, config, menuloading, eyeopen } = this.state
    return (
      <div className="pc-poper-view">
        <Header />
        <DndProvider backend={HTML5Backend}>
          <div className="menu-body">
            <div className="menu-setting">
              <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
                {/* 基本信息 */}
                <Panel header="基本信息" key="basedata">
                  {/* 菜单信息 */}
                  <MenuForm config={config} updateConfig={this.updateConfig}/>
                  {/* 表名添加 */}
                  <TableComponent config={config} updatetable={this.updatetable}/>
                </Panel>
                {/* 组件添加 */}
                <Panel header="组件" key="component">
                  <SourceWrap MenuType="" />
                </Panel>
                <Panel header="元素" key="element">
                  <Modulecell />
                </Panel>
                <Panel header="页面样式" key="background">
                  <BgController config={config} updateConfig={this.updateConfig} />
                </Panel>
              </Collapse>
            </div>
            <div className={'menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}>
              <Card title={
                <div> {config.MenuName} </div>
              } bordered={false} extra={
                <div>
                  <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button>
                  <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                  <StyleCombControlButton menu={config} />
                  <PasteController insert={this.insert} />
                  <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config.enabled} onChange={this.onEnabledChange} />
                  <Button type="primary" id="save-pop-config" onClick={this.submitConfig} loading={menuloading}>保存</Button>
                  <Button type="default" onClick={this.closeView}>返回</Button>
                </div>
              } style={{ width: '100%' }}>
                {!comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
              </Card>
            </div>
        <div className="menu-body">
          <div className="menu-setting">
            <Collapse accordion defaultActiveKey="basedata" bordered={false}>
              {/* 基本信息 */}
              <Panel header="基本信息" key="basedata">
                {/* 菜单信息 */}
                <MenuForm config={config} updateConfig={this.updateConfig}/>
                {/* 表名添加 */}
                <TableComponent config={config} updatetable={this.updatetable}/>
              </Panel>
              {/* 组件添加 */}
              <Panel header="组件" key="component">
                <SourceWrap MenuType="" />
              </Panel>
              <Panel header="元素" key="element">
                <Modulecell />
              </Panel>
              <Panel header="页面样式" key="background">
                <BgController config={config} updateConfig={this.updateConfig} />
              </Panel>
            </Collapse>
          </div>
        </DndProvider>
          <div className={'menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}>
            <Card title={
              <div> {config.MenuName} </div>
            } bordered={false} extra={
              <div>
                <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button>
                <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                <StyleCombControlButton menu={config} />
                <PasteController insert={this.insert} />
                <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config.enabled} onChange={this.onEnabledChange} />
                <Button type="primary" id="save-pop-config" onClick={this.submitConfig} loading={menuloading}>保存</Button>
                <Button type="default" onClick={this.closeView}>返回</Button>
              </div>
            } style={{ width: '100%' }}>
              {!comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
            </Card>
          </div>
        </div>
      </div>
    )
  }
src/views/pcdesign/index.jsx
@@ -59,8 +59,6 @@
    MenuId: '',
    MenuName: '',
    MenuNo: '',
    delButtons: [],
    copyButtons: [],
    activeKey: 'basedata',
    menuloading: false,
    oriConfig: null,
@@ -125,8 +123,6 @@
      document.getElementById('mk-pc-design-view').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh; height: 100vh; background: #fff;">本应用没有PC端页面的编辑权限,请联系管理员!</div>'
      return
    }
    MKEmitter.addListener('delButtons', this.delButtons)
    MKEmitter.addListener('copyButtons', this.copyButtons)
    MKEmitter.addListener('changePopview', this.initPopview)
    MKEmitter.addListener('changeEditMenu', this.changeEditMenu)
    MKEmitter.addListener('triggerMenuSave', this.triggerMenuSave)
@@ -210,8 +206,6 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('delButtons', this.delButtons)
    MKEmitter.removeListener('copyButtons', this.copyButtons)
    MKEmitter.removeListener('changePopview', this.initPopview)
    MKEmitter.removeListener('changeEditMenu', this.changeEditMenu)
    MKEmitter.removeListener('triggerMenuSave', this.triggerMenuSave)
@@ -484,14 +478,6 @@
      })
    })
    this.setState({customComponents: coms})
  }
  delButtons = (items) => {
    this.setState({ delButtons: [...this.state.delButtons, ...items] })
  }
  copyButtons = (items) => {
    this.setState({copyButtons: [...this.state.copyButtons, ...items]})
  }
  initPopview = (card, btn) => {
@@ -1145,7 +1131,6 @@
  }
  submitConfig = () => {
    const { delButtons, copyButtons } = this.state
    let config = fromJS(this.state.config).toJS()
    if (!config.MenuName || !config.MenuNo || (config.cacheUseful === 'true' && !config.cacheTime)) {
@@ -1414,15 +1399,6 @@
      }).then(res => { // 按钮或菜单删除
        if (!res) return
        if (delButtons.length === 0) {
          return { status: true, nonexec: true }
        } else {
          let _param = {
            func: 'sPC_MainMenu_Del',
            MenuID: delButtons.join(',')
          }
          return Api.getSystemConfig(_param)
        }
      }).then(res => { // 页面保存
        if (!res) return
@@ -1468,99 +1444,9 @@
          })
          return false
        }
        if (copyButtons.length === 0) {
          return {
            status: true
          }
        } else {
          return new Promise(resolve => {
            let deffers = copyButtons.map(item => {
              return new Promise(resolve => {
                if (delButtons.includes(item.uuid)) { // 复制的按钮已删除
                  resolve({
                    status: true
                  })
                  return
                }
                Api.getSystemConfig({
                  func: 'sPC_Get_LongParam',
                  MenuID: item.$originUuid,
                  TypeCharOne: sessionStorage.getItem('kei_no'),
                  typename: 'pc',
                }).then(result => {
                  if (result.status) {
                    let _conf = ''
                    try {
                      _conf = result.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) : ''
                    } catch (e) {
                      console.warn('Parse Failure')
                      _conf = ''
                    }
                    if (_conf) {
                      _conf.components = MenuUtils.resetConfig(_conf.components)
                      _conf.uuid = item.uuid
                      _conf.MenuID = item.uuid
                      _conf.Template = 'webPage'
                      _conf.enabled = false
                    } else {
                      resolve({
                        status: true
                      })
                      return
                    }
                    let _param = {
                      func: 'sPC_ButtonParam_AddUpt',
                      ParentID: config.uuid,
                      MenuID: item.uuid,
                      MenuNo: '',
                      Template: 'webPage',
                      MenuName: item.label,
                      PageParam: JSON.stringify({Template: 'webPage'}),
                      LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(_conf))),
                      TypeCharOne: sessionStorage.getItem('kei_no'),
                      Typename: 'pc',
                    }
                    Api.getSystemConfig(_param).then(response => {
                      resolve(response)
                    })
                  }
                })
              })
            })
            Promise.all(deffers).then(result => {
              let error = null
              result.forEach(response => {
                if (!response.status) {
                  error = response
                }
              })
              if (error) {
                notification.warning({
                  top: 92,
                  message: error.message,
                  duration: 5
                })
                resolve(false)
              } else {
                resolve({
                  status: true
                })
              }
            })
          })
        }
      }).then(res => {
        if (res && res.status) {
          this.setState({
            delButtons: [],
            copyButtons: [],
            menuloading: false
          })
          notification.success({
src/views/tabledesign/index.jsx
@@ -37,6 +37,7 @@
const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent'))
const ModalController = asyncComponent(() => import('@/menu/modalconfig/controller'))
const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
const PasteBaseTable = asyncComponent(() => import('@/menu/components/share/pastebasetable'))
sessionStorage.setItem('isEditState', 'true')
sessionStorage.setItem('appType', '')          // 应用类型
@@ -626,16 +627,22 @@
  insert = (item) => {
    let config = fromJS(this.state.config).toJS()
    config.components.push(item)
    let tabs = {
      uuid: Utils.getuuid(),
      type: 'tabs',
      subtype: 'tabletabs',
      width: 24,
      setting: {},
      style: {},
      subtabs: [
        { uuid: Utils.getuuid(), label: item.name || '子表1', icon: '', components: [item] },
      ]
    }
    config.components.push(tabs)
    this.setState({config})
    window.GLOB.customMenu = config
    notification.success({
      top: 92,
      message: '粘贴成功!',
      duration: 2
    })
  }
  changeSetting = () => {
@@ -701,6 +708,7 @@
                    <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''}/>
                    <TableNodes config={config} />
                    <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                    <PasteBaseTable type="page" insert={this.insert}/>
                    <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config && config.enabled} onChange={this.onEnabledChange} />
                    <Button type="primary" id="save-config" onClick={this.submitConfig} loading={menuloading}>保存</Button>
                    <Button type="default" onClick={this.closeView}>关闭</Button>