king
2021-09-07 da9942cd74b890c8533f475e7b333105c2358f0a
2021-09-07
14个文件已修改
4个文件已删除
5个文件已添加
1165 ■■■■■ 已修改文件
src/menu/components/form/normal-form/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/tab-form/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/groupcomponents/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/groupsetting/index.jsx 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/groupsetting/index.scss 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/groupsetting/settingform/index.jsx 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/groupsetting/settingform/index.scss 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/normal-group/index.jsx 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/normal-group/options.jsx 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/paste/index.jsx 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/paste/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/paste/index.jsx 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/paste/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/pastecontroller/index.jsx 233 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/popview/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/versions/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/versions/index.scss 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/antv-tabs/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-custom.js 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/normal-form/index.jsx
@@ -650,7 +650,7 @@
            <NormalForm title="表单设置" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
              <Icon type="edit" style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="propcard" card={card}/>
            <CopyComponent type="stepform" card={card}/>
            <PasteComponent config={card} options={['form']} updateConfig={this.pasteForm} />
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <UserComponent config={card}/>
src/menu/components/form/tab-form/index.jsx
@@ -642,7 +642,7 @@
            <NormalForm title="表单设置" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
              <Icon type="edit" style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="propcard" card={card}/>
            <CopyComponent type="tabform" card={card}/>
            <PasteComponent config={card} options={['form']} updateConfig={this.pasteForm} />
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <UserComponent config={card}/>
src/menu/components/group/groupcomponents/index.jsx
@@ -59,7 +59,7 @@
    drop(item) {
      if (item.hasOwnProperty('originalIndex') || item.added) {
        return
      } else if (['login', 'navbar', 'topbar', 'tabs', 'search', 'group'].includes(item.component)) {
      } else if (['login', 'navbar', 'topbar', 'tabs', 'search', 'group', 'menubar'].includes(item.component)) {
        return
      }
src/menu/components/group/groupsetting/index.jsx
File was deleted
src/menu/components/group/groupsetting/index.scss
File was deleted
src/menu/components/group/groupsetting/settingform/index.jsx
File was deleted
src/menu/components/group/groupsetting/settingform/index.scss
File was deleted
src/menu/components/group/normal-group/index.jsx
@@ -7,13 +7,14 @@
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { resetStyle } from '@/utils/utils-custom.js'
import getSettingForm from './options'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
import './index.scss'
const SettingComponent = asyncIconComponent(() => import('../groupsetting'))
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteController = asyncIconComponent(() => import('@/menu/pastecontroller'))
const PasteComponent = asyncIconComponent(() => import('../paste'))
const GroupComponents = asyncComponent(() => import('../groupcomponents'))
class NormalGroup extends Component {
@@ -146,10 +147,23 @@
  insert = (item) => {
    let group = fromJS(this.state.group).toJS()
    item.floor = group.floor || 1
    item.parentId = group.parentId
    group.components.push(item)
    this.setState({group})
    this.props.updateConfig(group)
  }
  getWrapForms = () => {
    const { setting } = this.state.group
    return getSettingForm(setting)
  }
  updateWrap = (res) => {
    this.updateComponent({...this.state.group, setting: res})
  }
  clickComponent = (e) => {
@@ -172,9 +186,11 @@
      <div className={'menu-group-edit-box' + (paddingTop ? ' padding' : '')} style={_style} onClick={this.clickComponent} id={group.uuid}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <SettingComponent config={group} updateConfig={this.updateComponent} />
            <NormalForm title="分组设置" width={700} update={this.updateWrap} getForms={this.getWrapForms}>
              <Icon type="edit" style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="tabs" card={group}/>
            <PasteController type="tab" Tab={group} insert={this.insert} />
            <PasteComponent insert={this.insert} />
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(group.uuid)} />
          </div>
src/menu/components/group/normal-group/options.jsx
New file
@@ -0,0 +1,93 @@
/**
 * @description Wrap表单配置信息
 */
export default function (setting) {
  let roleList = sessionStorage.getItem('sysRoles')
  let appType = sessionStorage.getItem('appType')
  if (roleList) {
    try {
      roleList = JSON.parse(roleList)
    } catch (e) {
      roleList = []
    }
  } else {
    roleList = []
  }
  const settingForm = [
    {
      type: 'text',
      field: 'name',
      label: '组件名称',
      initval: setting.name || '',
      tooltip: '用于组件间的区分。',
      required: true
    },
    {
      type: 'number',
      field: 'width',
      label: '宽度',
      initval: setting.width || 24,
      tooltip: '栅格布局,每行等分为24列。',
      min: 1,
      max: 24,
      precision: 0,
      required: true
    },
    {
      type: 'radio',
      field: 'print',
      label: '打印按钮',
      initval: setting.print || 'false',
      required: false,
      options: [
        {value: 'true', label: '显示'},
        {value: 'false', label: '隐藏'},
      ],
      controlFields: [
        {field: 'pageSize', values: ['true']},
        {field: 'pageLayout', values: ['true']},
        {field: 'syncModule', values: ['true']},
        {field: 'checkAll', values: ['true']},
      ],
      forbid: appType === 'mob'
    },
    {
      type: 'radio',
      field: 'pageSize',
      label: '打印尺寸',
      initval: setting.pageSize || 'A4',
      required: true,
      options: [
        {value: 'A3', label: 'A3'},
        {value: 'A4', label: 'A4'},
        {value: 'A5', label: 'A5'},
      ],
      forbid: appType === 'mob'
    },
    {
      type: 'radio',
      field: 'pageLayout',
      label: '打印布局',
      initval: setting.pageLayout || 'vertical',
      required: true,
      options: [
        {value: 'vertical', label: '纵向'},
        {value: 'horizontal', label: '横向'},
      ],
      forbid: appType === 'mob'
    },
    {
      type: 'multiselect',
      field: 'blacklist',
      label: '黑名单',
      initval: setting.blacklist || [],
      required: false,
      options: roleList,
      forbid: !!appType
    },
  ]
  return settingForm
}
src/menu/components/group/paste/index.jsx
New file
@@ -0,0 +1,101 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Icon, Modal, notification } from 'antd'
import MenuUtils from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
const PasteForm = asyncComponent(() => import('@/templates/zshare/pasteform'))
class PasteGroup extends Component {
  static propTpyes = {
    insert: PropTypes.func
  }
  state = {
    visible: false
  }
  handleMenuClick = () => {
    this.setState({visible: true})
  }
  pasteSubmit = () => {
    let options = ['datacard', 'propcard', 'balcony', 'stepform', 'tabform', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter']
    let types = {
      login: '登录',
      navbar: '导航栏',
      topbar: '导航栏',
      tabs: '标签页',
      search: '搜索',
      mainsearch: '搜索',
      group: '分组',
      menubar: '菜单'
    }
    this.pasteFormRef.handleConfirm().then(res => {
      if (res.copyType && types[res.copyType]) {
        notification.warning({
          top: 92,
          message: '分组中不可添加《' + types[res.copyType] + '》组件!',
          duration: 5
        })
        return
      } else if (!options.includes(res.copyType)) {
        notification.warning({
          top: 92,
          message: '配置信息格式错误!',
          duration: 5
        })
        return
      }
      let copyBtns = new Map()
      res = MenuUtils.resetComponentConfig(res, copyBtns)
      delete res.copyType
      this.props.insert(res)
      copyBtns = [...copyBtns.values()]
      if (copyBtns.length > 0) {
        MKEmitter.emit('copyButtons', copyBtns)
      }
      this.setState({visible: false})
      notification.success({
        top: 92,
        message: '粘贴成功!',
        duration: 2
      })
    })
  }
  render() {
    const { visible } = this.state
    return (
      <div style={{display: 'inline-block'}}>
        <Icon type="snippets" 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 PasteGroup
src/menu/components/group/paste/index.scss
New file
@@ -0,0 +1,4 @@
.menu-config-paste {
  border-color: #40a9ff;
  color: #40a9ff;
}
src/menu/components/tabs/antv-tabs/index.jsx
@@ -17,7 +17,7 @@
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteController = asyncIconComponent(() => import('@/menu/pastecontroller'))
const PasteComponent = asyncIconComponent(() => import('../paste'))
const TabComponents = asyncComponent(() => import('../tabcomponents'))
const { TabPane } = Tabs
@@ -370,7 +370,7 @@
                  <NormalForm title="标签编辑" width={600} update={this.updateTab} getForms={() => this.getTabForms(tab)}>
                    <Icon type="edit" style={{color: '#1890ff'}} title="编辑"/>
                  </NormalForm>
                  <PasteController type="tab" Tab={tab} insert={this.insert} />
                  <PasteComponent Tab={tab} insert={this.insert} />
                  <Icon className="close" title="delete" type="close" onClick={() => this.delTab(tab)} />
                </div>
              } trigger="hover">
src/menu/components/tabs/paste/index.jsx
New file
@@ -0,0 +1,146 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Icon, Modal, notification } from 'antd'
import MenuUtils from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
const PasteForm = asyncComponent(() => import('@/templates/zshare/pasteform'))
class PasteGroup extends Component {
  static propTpyes = {
    Tab: PropTypes.any,         // 标签
    insert: PropTypes.func
  }
  state = {
    visible: false
  }
  handleMenuClick = () => {
    this.setState({visible: true})
  }
  resetconfig = (item, Tab, copyBtns) => {
    item.floor = Tab.floor + 1
    item.tabId = Tab.uuid
    item.parentId = Tab.parentId
    if (item.type === 'tabs') {
      item.uuid = MenuUtils.getuuid()
      item.setting.name = item.setting.name + MenuUtils.getdataName().toUpperCase().substr(-4)
      item.name = item.setting.name
      item.subtabs.forEach(tab => {
        tab.uuid = MenuUtils.getuuid()
        tab.parentId = item.uuid
        if (item.floor >= 3) {
          tab.components = tab.components.filter(cell => cell.type !== 'tabs')
        }
        tab.components = tab.components.map(cell => {
          cell = this.resetconfig(cell, tab, copyBtns)
          return cell
        })
      })
    } else if (item.type === 'group') {
      item.uuid = MenuUtils.getuuid()
      item.setting.name = item.setting.name + MenuUtils.getdataName().toUpperCase().substr(-4)
      item.name = item.setting.name
      item.components = item.components.map(cell => {
        cell.floor = Tab.floor + 1
        cell.tabId = Tab.uuid
        cell.parentId = Tab.parentId
        cell = MenuUtils.resetComponentConfig(cell, copyBtns)
        return cell
      })
    } else {
      item = MenuUtils.resetComponentConfig(item, copyBtns)
    }
    return item
  }
  pasteSubmit = () => {
    const { Tab } = this.props
    let options = ['tabs', 'group', 'datacard', 'propcard', 'balcony', 'normaltable', 'mainsearch', 'stepform', 'tabform', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter']
    let types = {
      login: '登录',
      navbar: '导航栏',
      topbar: '导航栏'
    }
    if (sessionStorage.getItem('appType') === 'mob') {
      options.push('menubar')
    }
    this.pasteFormRef.handleConfirm().then(res => {
      if (res.copyType && types[res.copyType]) {
        notification.warning({
          top: 92,
          message: '分组中不可添加《' + types[res.copyType] + '》组件!',
          duration: 5
        })
        return
      } else if (!options.includes(res.copyType)) {
        notification.warning({
          top: 92,
          message: '配置信息格式错误!',
          duration: 5
        })
        return
      }
      let copyBtns = new Map()
      res = this.resetconfig(res, Tab, copyBtns)
      delete res.copyType
      this.props.insert(res, Tab)
      copyBtns = [...copyBtns.values()]
      if (copyBtns.length > 0) {
        MKEmitter.emit('copyButtons', copyBtns)
      }
      this.setState({visible: false})
      notification.success({
        top: 92,
        message: '粘贴成功!',
        duration: 2
      })
    })
  }
  render() {
    const { visible } = this.state
    return (
      <div style={{display: 'inline-block'}}>
        <Icon type="snippets" 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 PasteGroup
src/menu/components/tabs/paste/index.scss
New file
@@ -0,0 +1,4 @@
.menu-config-paste {
  border-color: #40a9ff;
  color: #40a9ff;
}
src/menu/pastecontroller/index.jsx
@@ -1,9 +1,8 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Icon, Modal, Button, notification } from 'antd'
import { Modal, Button, notification } from 'antd'
import Utils from '@/utils/utils.js'
import MenuUtils from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
@@ -12,8 +11,6 @@
class PasteController extends Component {
  static propTpyes = {
    type: PropTypes.any,        // 组件类型
    Tab: PropTypes.any,         // 标签,添加菜单组件时为空
    insert: PropTypes.func
  }
@@ -25,220 +22,68 @@
    this.setState({visible: true})
  }
  resetconfig = (item, Tab, isgroup, copyBtns) => {
    item.uuid = Utils.getuuid()
    item.floor = Tab ? (Tab.floor + 1) : 1
    if (Tab && !isgroup) {
      item.tabId = Tab.uuid
      item.parentId = Tab.parentId
    } else if (Tab) {
      item.floor = Tab.floor || 1
      item.parentId = Tab.parentId
    }
    if (item.dataName) {
      item.dataName = Utils.getdataName()
    }
  resetconfig = (item, copyBtns) => {
    let appType = sessionStorage.getItem('appType')
    if (item.type === 'tabs') {
      item.uuid = MenuUtils.getuuid()
      item.setting.name = item.setting.name + MenuUtils.getdataName().toUpperCase().substr(-4)
      item.name = item.setting.name
      item.subtabs.forEach(tab => {
        tab.uuid = Utils.getuuid()
        tab.uuid = MenuUtils.getuuid()
        tab.parentId = item.uuid
        if (item.floor >= 3) {
          tab.components = tab.components.filter(cell => cell.type !== 'tabs')
        if (appType !== 'mob') {
          tab.components = tab.components.filter(cell => cell.type !== 'menubar')
        }
        tab.components = tab.components.map(cell => {
          cell = this.resetconfig(cell, tab, false, copyBtns)
          cell.floor = tab.floor + 1
          cell.tabId = tab.uuid
          cell.parentId = tab.parentId
          cell = this.resetconfig(cell, copyBtns)
          return cell
        })
      })
    } else if (item.type === 'group') {
      item.uuid = MenuUtils.getuuid()
      item.setting.name = item.setting.name + MenuUtils.getdataName().toUpperCase().substr(-4)
      item.name = item.setting.name
      if (appType !== 'mob') {
        item.components = item.components.filter(cell => cell.type !== 'menubar')
      }
      item.components = item.components.map(cell => {
        cell = this.resetconfig(cell, item, true, copyBtns)
        cell.floor = item.floor
        cell.tabId = item.tabId || ''
        cell.parentId = item.parentId || ''
        cell = MenuUtils.resetComponentConfig(cell, copyBtns)
        return cell
      })
    } else if (item.type === 'menubar') {
      item.subMenus = item.subMenus.map(cell => {
        cell.uuid = Utils.getuuid()
        return cell
      })
    } else if (item.type === 'balcony') {
      item.elements = item.elements.map(cell => {
        cell.uuid = Utils.getuuid()
        return cell
      })
    } else if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) {
      item.subcards && item.subcards.forEach(card => {
        card.uuid = Utils.getuuid()
        if (card.elements) {
          if (sessionStorage.getItem('editMenuType') === 'popview') {
            card.elements = card.elements.filter(b => b.OpenType !== 'popview' && b.OpenType !== 'funcbutton')
          }
          card.elements = card.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
            return cell
          })
        }
        if (card.backElements) {
          if (sessionStorage.getItem('editMenuType') === 'popview') {
            card.elements = card.elements.filter(b => b.OpenType !== 'popview' && b.OpenType !== 'funcbutton')
          }
          card.backElements = card.backElements.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
            return cell
          })
        }
      })
    } else if (item.type === 'table' && item.subtype === 'normaltable' && item.cols) {
      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
      }
      item.cols = item.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) {
          if (sessionStorage.getItem('editMenuType') === 'popview') {
            col.elements = col.elements.filter(c => c.OpenType !== 'popview' && c.OpenType !== 'funcbutton')
          }
          col.elements = col.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
            return cell
          })
        }
        return col
      })
    } else if (item.type === 'form') {
      item.subcards = item.subcards.map(cell => {
        cell.uuid = Utils.getuuid()
        cell.fields = cell.fields.map(m => {
          m.uuid = Utils.getuuid()
          return m
        })
        return cell
      })
    }
    if (item.btnlog) {
      item.btnlog = []
    }
    let oriUids = {}
    if (item.action) {
      if (sessionStorage.getItem('editMenuType') === 'popview') {
        item.action = item.action.filter(c => c.OpenType !== 'popview' && c.OpenType !== 'funcbutton')
      }
      item.action = item.action.map(cell => {
        let _uuid = Utils.getuuid()
        oriUids[cell.uuid] = _uuid
        if (cell.OpenType === 'popview') {
          let _cell = fromJS(cell).toJS()
          _cell.$originUuid = _cell.uuid
          _cell.uuid = _uuid
          copyBtns.set(_uuid, _cell)
        }
        cell.uuid = _uuid
        return cell
      })
    }
    if (item.search) {
      item.search = item.search.map(cell => {
        cell.uuid = Utils.getuuid()
        return cell
      })
    }
    if (item.columns) {
      item.columns = item.columns.map(cell => {
        cell.uuid = Utils.getuuid()
        return cell
      })
    }
    if (item.setting && item.setting.supModule) {
      item.setting.supModule = ''
    }
    if (item.wrap && item.wrap.doubleClick) {
      item.wrap.doubleClick = oriUids[item.wrap.doubleClick] || ''
    } else {
      item = MenuUtils.resetComponentConfig(item, copyBtns)
    }
    return item
  }
  pasteSubmit = () => {
    const { Tab } = this.props
    let isgroup = Tab && Tab.type === 'group' ? true : false
    let options = ['tabs', 'datacard', 'propcard', 'mainsearch', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter']
    if (sessionStorage.getItem('appType') === 'mob') {
      options.push('menubar')
    }
    if (isgroup) {
      options = options.filter(item => !['tabs', 'mainsearch', 'group'].includes(item))
    }
    let options = ['tabs', 'menubar', 'datacard', 'propcard', 'mainsearch', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter']
    this.pasteFormRef.handleConfirm().then(res => {
      if (!options.includes(res.copyType)) {
      if (res.copyType === 'menubar' && sessionStorage.getItem('appType') !== 'mob') {
        notification.warning({
          top: 92,
          message: '配置信息格式错误!',
          message: '当前系统不支持菜单组件!',
          duration: 5
        })
        return
      } else if (Tab && Tab.floor === 3 && res.type === 'tabs') {
      } else if (!options.includes(res.copyType)) {
        notification.warning({
          top: 92,
          message: '标签页最多为三重结构!',
          message: '配置信息格式错误!',
          duration: 5
        })
        return
@@ -246,11 +91,11 @@
      let copyBtns = new Map()
      res = this.resetconfig(res, Tab, isgroup, copyBtns)
      res = this.resetconfig(res, copyBtns)
      delete res.copyType
      
      this.props.insert(res, Tab)
      this.props.insert(res)
      copyBtns = [...copyBtns.values()]
@@ -269,13 +114,11 @@
  }
  render() {
    const { type } = this.props
    const { visible } = this.state
    return (
      <div style={{display: 'inline-block'}}>
        {type !== 'menu' ? <Icon type="snippets" style={{color: 'purple'}} onClick={() => {this.setState({visible: true})}} /> : null}
        {type === 'menu' ? <Button className="menu-config-paste" icon="snippets" onClick={() => {this.setState({visible: true})}}>粘贴</Button> : null}
        <Button className="menu-config-paste" icon="snippets" onClick={() => {this.setState({visible: true})}}>粘贴</Button>
        <Modal
          title="粘贴"
          visible={visible}
src/menu/popview/index.jsx
@@ -608,7 +608,7 @@
                  <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''} updateConfig={this.refreshConfig}/>
                  <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                  <StyleCombControlButton menu={config} />
                  <PasteController type="menu" Tab={null} insert={this.insert} />
                  <PasteController insert={this.insert} />
                  {config ? <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                  <Button type="primary" onClick={this.submitConfig} loading={menuloading}>{dict['mob.save']}</Button>
                  <Button type="default" onClick={this.closeView}>{dict['mob.return']}</Button>
src/menu/versions/index.jsx
@@ -64,7 +64,7 @@
        notification.success({
          top: 92,
          message: '执行成功。',
          duration: 2
          duration: 1
        })
        if (updateConfig) {
@@ -72,7 +72,7 @@
        } else {
          setTimeout(() => {
            window.location.reload()
          }, 2000)
          }, 1000)
        }
      }
    })
@@ -110,7 +110,7 @@
        notification.success({
          top: 92,
          message: '执行成功。',
          duration: 2
          duration: 1
        })
        
        if (updateConfig) {
@@ -118,7 +118,7 @@
        } else {
          setTimeout(() => {
            window.location.reload()
          }, 2000)
          }, 1000)
        }
      }
    })
@@ -143,9 +143,9 @@
          <div className="header"><Icon type="question-circle"/>版本切换</div>
          <div className="detail">请选择需要切换的版本,或点击取消关闭弹窗。</div>
          <div className="footer">
            <Button key="cancel" onClick={() => { this.setState({ visible: false })}}>取消</Button>
            <Button key="pre" type="primary" loading={preconfirming} onClick={this.preVersion}>上一版本</Button>
            <Button key="next" type="primary" loading={nextconfirming} onClick={this.nextVersion}>下一版本</Button>
            <Button key="cancel" onClick={() => { this.setState({ visible: false })}}>取消</Button>
          </div>
        </Modal>
      </div>
src/menu/versions/index.scss
@@ -6,7 +6,7 @@
    display: none;
  }
  .header {
    color: rgba(0,0,0,.85);
    color: rgba(0, 0, 0, 0.85);
    font-weight: 500;
    font-size: 16px;
    .anticon {
@@ -18,7 +18,7 @@
  .detail {
    margin-top: 8px;
    margin-bottom: 24px;
    color: rgba(0,0,0,.65);
    color: rgba(0, 0, 0, 0.5);
    font-size: 14px;
  }
  .footer {
src/mob/components/tabs/antv-tabs/index.jsx
@@ -17,8 +17,7 @@
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteController = asyncIconComponent(() => import('@/menu/pastecontroller'))
// const TabLabelComponent = asyncComponent(() => import('@/menu/components/tabs/tablabelform'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/tabs/paste'))
const TabComponents = asyncComponent(() => import('../tabcomponents'))
const { TabPane } = Tabs
@@ -393,7 +392,7 @@
                  <NormalForm title="标签编辑" width={600} update={this.updateTab} getForms={() => this.getTabForms(tab)}>
                    <Icon type="edit" style={{color: '#1890ff'}} title="编辑"/>
                  </NormalForm>
                  <PasteController type="tab" Tab={tab} insert={this.insert} />
                  <PasteComponent Tab={tab} insert={this.insert} />
                  <Icon className="style" title="调整样式" onClick={this.changeTabStyle} type="font-colors" />
                  <Icon className="close" title="delete" type="close" onClick={() => this.delTab(tab)} />
                </div>
src/utils/utils-custom.js
@@ -327,7 +327,7 @@
  }
  /**
   * @description 重置菜单配置
   * @description 重置菜单配置,页面整体复制
   * @return {String}  components 配置信息
   */
  static resetConfig = (components) => {
@@ -432,9 +432,14 @@
        item.btnlog = []
      }
  
      let oriUids = {}
      if (item.action) {
        item.action = item.action.map(cell => {
          cell.uuid = this.getuuid()
          let _uuid = this.getuuid()
          oriUids[cell.uuid] = _uuid
          cell.uuid = _uuid
          return cell
        })
      }
@@ -467,10 +472,240 @@
          return cell
        })
      }
      if (item.wrap && item.wrap.doubleClick) {
        item.wrap.doubleClick = oriUids[item.wrap.doubleClick] || ''
      }
  
      return item
    })
  }
  /**
   * @description 数据源名称,用于统一查询
   * @return {String}  name
   */
  static getdataName () {
    let name = []
    let _options = 'abcdefghigklmnopqrstuvwxyz'
    for (let i = 0; i < 6; i++) {
      name.push(_options.substr(Math.floor(Math.random() * 26), 1))
    }
    name.splice(3, 0, new Date().getTime())
    return name.join('')
  }
  /**
  * @description 重置组件配置
  * @return {String}  item 组件信息
  */
  static resetComponentConfig = (item, copyBtns) => {
    if (item.type === 'navbar') {
      return item
    }
    item.uuid = this.getuuid()
    if (item.dataName) {
      item.dataName = this.getdataName()
    }
    // 重置组件名称
    let sign = this.getdataName().toUpperCase().substr(-4)
    if (item.plot) { // 图表
      item.plot.name = item.plot.name + sign
      item.name = item.plot.name
    } else if (item.wrap) { // 通用
      item.wrap.name = item.wrap.name + sign
      item.name = item.wrap.name
    } else if (item.setting) { // 分组、标签页等
      item.setting.name = item.setting.name + sign
      item.name = item.setting.name
    }
    if (item.type === 'menubar') {
      item.subMenus = item.subMenus.map(cell => {
        cell.uuid = this.getuuid()
        return cell
      })
    } else if (item.type === 'card' || item.type === 'carousel' || (item.type === 'table' && item.subtype === 'tablecard')) {
      item.subcards.forEach(card => {
        card.uuid = this.getuuid()
        if (card.elements) {
          if (sessionStorage.getItem('editMenuType') === 'popview') {
            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
            return cell
          })
        }
        if (card.backElements) {
          if (sessionStorage.getItem('editMenuType') === 'popview') {
            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
            return cell
          })
        }
      })
    } else if (item.type === 'balcony') {
      if (item.elements) {
        if (sessionStorage.getItem('editMenuType') === 'popview') {
          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
          return cell
        })
      }
    } else if (item.type === 'table' && item.subtype === 'normaltable' && item.cols) {
      let loopCol = (col) => {
        col.subcols = col.subcols.map(c => {
          c.uuid = this.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 = this.getuuid()
              return cell
            })
          }
          return c
        })
        return col
      }
      item.cols = item.cols.map(col => {
        col.uuid = this.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 = this.getuuid()
            return cell
          })
        } else if (col.type === 'action' && col.elements) {
          if (sessionStorage.getItem('editMenuType') === 'popview') {
            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
            return cell
          })
        }
        return col
      })
    } else if (item.type === 'form') {
      item.subcards = item.subcards.map(cell => {
        cell.uuid = this.getuuid()
        cell.fields = cell.fields.map(m => {
          m.uuid = this.getuuid()
          return m
        })
        return cell
      })
    }
    if (item.btnlog) {
      item.btnlog = []
    }
    let oriUids = {}
    if (item.action) {
      if (sessionStorage.getItem('editMenuType') === 'popview') {
        item.action = item.action.filter(c => c.OpenType !== 'popview' && c.OpenType !== 'funcbutton')
      }
      item.action = item.action.map(cell => {
        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
        return cell
      })
    }
    if (item.type === 'topbar') {
      if (item.search && item.search.fields) {
        item.search.fields = item.search.fields.map(cell => {
          cell.uuid = this.getuuid()
          return cell
        })
      }
      if (item.search && item.search.groups) {
        item.search.groups = item.search.groups.map(cell => {
          cell.uuid = this.getuuid()
          cell.fields = cell.fields.map(m => {
            m.uuid = this.getuuid()
            return m
          })
          return cell
        })
      }
    } else if (item.search) {
      item.search = item.search.map(cell => {
        cell.uuid = this.getuuid()
        return cell
      })
    }
    if (item.columns) {
      item.columns = item.columns.map(cell => {
        cell.uuid = this.getuuid()
        return cell
      })
    }
    if (item.setting && item.setting.supModule) {
      item.setting.supModule = ''
    }
    if (item.wrap && item.wrap.doubleClick) {
      item.wrap.doubleClick = oriUids[item.wrap.doubleClick] || ''
    }
    return item
  }
}
/**
src/views/menudesign/index.jsx
@@ -984,7 +984,7 @@
                    <SysInterface config={config} updateConfig={this.updateConfig}/>
                    <PictureController/>
                    <StyleCombControlButton menu={config} />
                    <PasteController type="menu" Tab={null} insert={this.insert} />
                    <PasteController insert={this.insert} />
                    <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config && config.enabled} onChange={this.onEnabledChange} />
                    <Button type="primary" onClick={this.submitConfig} loading={menuloading}>{dict['mob.save']}</Button>
                    <Button type="default" onClick={this.closeView}>关闭</Button>
src/views/mobdesign/index.jsx
@@ -1351,7 +1351,7 @@
                <Button type="primary" onClick={this.submitConfig} loading={menuloading}>{dict['mob.save']}</Button>
                <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config && config.enabled} onChange={this.onEnabledChange} />
                <CreateView resetmenu={this.getAppMenus} />
                <PasteController type="menu" Tab={null} insert={this.insert} />
                <PasteController insert={this.insert} />
                <StyleCombControlButton menu={config} />
                <SysInterface config={config} updateConfig={this.updateConfig}/>
                <PictureController/>
src/views/pcdesign/index.jsx
@@ -1589,7 +1589,7 @@
                <Button type="primary" onClick={this.submitConfig} loading={menuloading}>{dict['mob.save']}</Button>
                <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config && config.enabled} onChange={this.onEnabledChange} />
                <CreateView resetmenu={this.getAppMenus} />
                <PasteController type="menu" Tab={null} insert={this.insert} />
                <PasteController insert={this.insert} />
                <StyleCombControlButton menu={config} />
                <SysInterface config={config} updateConfig={this.updateConfig}/>
                <PictureController/>