king
2023-12-24 3e13e3e61854671fce6aac45679e1b7252126105
Merge branch 'master' into positec
88个文件已修改
4个文件已删除
2377 ■■■■■ 已修改文件
src/components/normalform/modalform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/mkTable/index.jsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/calendar/options.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/elementform/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/options.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.jsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/options.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/double-data-card/index.jsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/double-data-card/options.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/data-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/prop-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-scatter/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/chart-custom/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/dragtitle/card.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/groupcomponents/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/normal-group/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/paste/index.jsx 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/paste/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/actionform/index.jsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/formconfig.jsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/pastecomponent/index.jsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/editColumn/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/options.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/editColumn/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/tableIn/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/options.jsx 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/index.jsx 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/antv-tabs/options.jsx 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/paste/index.jsx 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/paste/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tabs/tabcomponents/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/debug/index.jsx 224 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/pastecontroller/index.jsx 346 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/antv-tabs/index.jsx 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/antv-tabs/options.jsx 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/tabs/tabcomponents/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/topbar/normal-navbar/options.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/login/normal-login/options.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/basetable/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardcellList/index.jsx 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/data-card/index.jsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/double-data-card/index.jsx 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/prop-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/interfaces/interItem/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/base-table/index.jsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/normal-table/index.jsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/popview/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/rolemanage/index.jsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtable/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/excelInbutton/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkCheck/index.jsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkSwitch/index.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/actionform/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/formconfig.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/columnform/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/columnform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/formconfig.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/tabscomponent/formconfig.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/tabscomponent/tabform/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editTable/index.jsx 71 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editTable/index.scss 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/index.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 178 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.scss 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-custom.js 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basedesign/updateFormTab/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/billprint/index.jsx 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/sidemenu/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/popview/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/index.jsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/popview/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemfunc/sidemenu/index.jsx 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/index.jsx
@@ -282,7 +282,7 @@
      let label = item.tooltip ? <Tooltip placement="topLeft" title={item.tooltip}><QuestionCircleOutlined className="mk-form-tip" />{item.label}</Tooltip> : item.label
    
      if (item.type === 'text') {
        content = (<MKEInput config={item} onChange={(val, defer) => !defer && this.recordChange({[item.field]: val})} onSubmit={this.props.inputSubmit} />)
        content = (<MKEInput config={item} onChange={(val, defer) => !defer && this.recordChange({[item.field]: val}, item)} onSubmit={this.props.inputSubmit} />)
      } else if (item.type === 'number') {
        content = (<MKNumberInput config={item} onChange={(val, defer) => !defer && this.recordChange({[item.field]: val})} onSubmit={this.props.inputSubmit} />)
      } else if (item.type === 'select' || item.type === 'multiselect') {
@@ -306,7 +306,7 @@
      } else if (item.type === 'source') {
        content = (<SourceComponent type="" placement="right"/>)
      } else if (item.type === 'table') {
        content = (<MKTable tip={item.tip || ''} fixed={item.fixed === true} columns={item.columns || []} actions={item.actions || []}/>)
        content = (<MKTable tip={item.tip || ''} columns={item.columns || []} actions={item.actions || []}/>)
      } else if (item.type === 'hint') {
        fields.push(
          <Col span={24} key={index}>
src/components/normalform/modalform/mkTable/index.jsx
@@ -153,8 +153,9 @@
class EditTable extends Component {
  static propTpyes = {
    columns: PropTypes.array,       // 显示列
    onChange: PropTypes.func        // 数据变化
    actions: PropTypes.array,
    columns: PropTypes.array,
    onChange: PropTypes.func
  }
  state = {
@@ -166,7 +167,7 @@
  }
  UNSAFE_componentWillMount () {
    let actions = this.props.actions || []
    const { actions } = this.props
    let columns = fromJS(this.props.columns).toJS()
    let operation = {
@@ -189,16 +190,16 @@
          </div>
        ) : (
          <div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')} style={{minWidth: '110px', whiteSpace: 'nowrap'}}>
            <span className="primary" onClick={() => {editingKey === '' && this.edit(record)}}><EditOutlined /></span>
            {editingKey === '' ? <Popconfirm
            {actions.includes('edit') ? <span className="primary" onClick={() => {editingKey === '' && this.edit(record)}}><EditOutlined /></span> : null}
            {actions.includes('del') && editingKey === '' ? <Popconfirm
              overlayClassName="popover-confirm"
              title="确定删除吗?"
              onConfirm={() => this.handleDelete(record.uuid)
            }>
              <span className="danger"><DeleteOutlined /></span>
            </Popconfirm> : null}
            {editingKey !== '' ? <span className="danger"><DeleteOutlined /></span> : null}
            {actions.includes('view') ? <span className="copy" onClick={() => {editingKey === '' && this.changeMenu(record.menu)}}><ArrowRightOutlined /></span> : null}
            {actions.includes('del') && editingKey !== '' ? <span className="danger"><DeleteOutlined /></span> : null}
            {actions.includes('view') ? <span className="copy" onClick={() => {editingKey === '' && this.changeMenu(record)}}><ArrowRightOutlined /></span> : null}
          </div>
        )
      }
@@ -217,7 +218,8 @@
  //   return !is(fromJS(this.state), fromJS(nextState))
  // }
  changeMenu = (MenuId) => {
  changeMenu = (record) => {
    let MenuId = record.menu
    if (MenuId === 'IM') {
      if (!sessionStorage.getItem('instantMessage')) return
@@ -231,7 +233,7 @@
  
      MKEmitter.emit('changeEditMenu', {routerUrl: '/imdesign/' + param})
    } else {
      MKEmitter.emit('changeEditMenu', {MenuID: MenuId})
      MKEmitter.emit('changeEditMenu', { ...record, MenuID: MenuId})
    }
  }
@@ -392,7 +394,7 @@
  }
  render() {
    const { fixed } = this.props
    const { actions } = this.props
    let components = {
      body: {
        cell: EditableCell
@@ -401,8 +403,11 @@
    let moveprops = {}
    components.body.row = DragableBodyRow
    moveprops.moveAble = !this.state.editingKey
    moveprops.moveRow = this.moveRow
    if (actions.includes('move')) {
      moveprops.moveAble = !this.state.editingKey
      moveprops.moveRow = this.moveRow
    }
    
    let  columns = this.state.columns.map(col => {
      if (col.copy) {
@@ -437,7 +442,7 @@
    return (
      <EditableContext.Provider value={this.props.form}>
        <div className="modal-editable-table">
          {!fixed ? <Button disabled={!!this.state.editingKey} type="link" onClick={this.addline}><PlusOutlined style={{}}/></Button> : null}
          {actions.includes('add') ? <Button disabled={!!this.state.editingKey} type="link" onClick={this.addline}><PlusOutlined style={{}}/></Button> : null}
          <DndProvider>
            <Table
              bordered
src/menu/components/calendar/options.jsx
@@ -195,6 +195,7 @@
      label: '颜色标识',
      initval: wrap.signs || [],
      required: false,
      actions: ['edit', 'del', 'add', 'move'],
      span: 24,
      columns: [
        {
@@ -224,7 +225,7 @@
      initval: wrap.menus || [],
      required: true,
      span: 24,
      actions: ['view'],
      actions: ['edit', 'del', 'add', 'move', 'view'],
      forbid: isprint,
      columns: [
        {
src/menu/components/card/cardcellcomponent/elementform/index.scss
@@ -43,7 +43,7 @@
  .ant-popover-inner-content {
    div {
      max-width: 750px;
      word-break: break-all;
      word-break: normal;
    }
  }
}
src/menu/components/card/cardcellcomponent/index.jsx
@@ -310,8 +310,9 @@
        supId = ''
      }
    }
    let menu = window.GLOB.customMenu
    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, cards.uuid, supId, true)
    let modules = MenuUtils.getSubModules(menu.components, cards.uuid, supId, menu.interfaces || null)
    if (cards.subtype === 'basetable') {
      this.setState({
@@ -320,7 +321,7 @@
        formlist: getBaseTableActionForm(card, functip, cards, usefulFields, modules)
      })
    } else {
      let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, cards.uuid) || []
      let anchors = MenuUtils.getAnchors(menu.components, cards.uuid) || []
      this.setState({
        actvisible: true,
src/menu/components/card/cardcomponent/options.jsx
@@ -67,7 +67,7 @@
      required: false,
      options: [
        {value: 'card', label: '属性卡'},
        {value: 'header', label: '表格头'},
        {value: 'header', label: '表格头(可排序)'},
      ],
      controlFields: [
        {field: 'type', values: ['card']},
@@ -286,7 +286,7 @@
      initval: menus,
      required: true,
      span: 24,
      actions: ['view'],
      actions: ['edit', 'del', 'add', 'move', 'view'],
      columns: [
        {
          title: '标识',
src/menu/components/card/data-card/index.jsx
@@ -341,8 +341,30 @@
  getWrapForms = () => {
    const { card } = this.state
    let buttons = []
    card.action && card.action.forEach(n => {
      buttons.push({
        value: n.uuid,
        label: n.label
      })
    })
    card.subcards.forEach(m => {
      if (m.$cardType !== 'extendCard') return
      m.elements.forEach(n => {
        if (n.eleType === 'button') {
          buttons.push({
            value: n.uuid,
            label: n.label
          })
        }
      })
    })
    
    return getWrapForm(card.wrap, card.subtype, card.columns, card.uuid, card.supNodes, card.setting)
    return getWrapForm(card.wrap, card.subtype, card.columns, card.uuid, card.supNodes, card.setting, buttons)
  }
  updateWrap = (res) => {
src/menu/components/card/data-card/options.jsx
@@ -413,10 +413,10 @@
      field: 'autoExec',
      label: '自动执行',
      initval: wrap.autoExec || '',
      tooltip: '数据更新时自动执行按钮。注:此按钮执行成功后谨慎选择刷新项,避免造成循环执行。',
      tooltip: subtype === 'propcard' ? '数据更新时自动执行按钮。注:此按钮执行成功后谨慎选择刷新项,避免造成循环执行。' : '初始化自动执行按钮。',
      required: false,
      options: buttons,
      forbid: subtype !== 'propcard',
      forbid: subtype !== 'propcard' && subtype !== 'datacard',
      controlFields: [
        {field: 'emptyExec', notNull: true},
      ]
@@ -646,6 +646,7 @@
      required: true,
      forbid: subtype !== 'datacard' || appType === 'mob' || isprint,
      span: 24,
      actions: ['edit', 'del', 'add', 'move'],
      columns: [
        {
          title: '序号',
src/menu/components/card/double-data-card/index.jsx
@@ -331,8 +331,30 @@
  getWrapForms = () => {
    const { card } = this.state
    let buttons = []
    card.action && card.action.forEach(n => {
      buttons.push({
        value: n.uuid,
        label: n.label
      })
    })
    card.subcards.forEach(m => {
      if (m.$cardType !== 'extendCard') return
      m.elements.forEach(n => {
        if (n.eleType === 'button') {
          buttons.push({
            value: n.uuid,
            label: n.label
          })
        }
      })
    })
    
    return getWrapForm(card.wrap, card.columns, card.setting)
    return getWrapForm(card.wrap, card.columns, card.setting, buttons)
  }
  updateWrap = (res) => {
@@ -501,7 +523,7 @@
            <NormalForm title="双重数据卡设置" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="datacard" card={card}/>
            <CopyComponent type="doublecard" card={card}/>
            <PasteComponent options={['action', 'search', 'form', 'cardcell']} updateConfig={this.pasteComponent} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
src/menu/components/card/double-data-card/options.jsx
@@ -1,7 +1,7 @@
/**
 * @description Wrap表单配置信息
 */
export default function (wrap, columns = [], setting) {
export default function (wrap, columns = [], setting, buttons = []) {
  let appType = sessionStorage.getItem('appType')
  let laypage = setting && setting.laypage !== 'false'
  let roleList = sessionStorage.getItem('sysRoles')
@@ -183,6 +183,15 @@
      required: false
    },
    {
      type: 'select',
      field: 'autoExec',
      label: '自动执行',
      initval: wrap.autoExec || '',
      tooltip: '初始化自动执行按钮。',
      required: false,
      options: buttons
    },
    {
      type: 'number',
      field: 'minWidth',
      label: '最小宽度',
src/menu/components/carousel/data-card/index.jsx
@@ -207,7 +207,7 @@
            <NormalForm title="轮播-动态数据" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="datacard" card={card}/>
            <CopyComponent type="cardatacard" card={card}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
            <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)}/>
src/menu/components/carousel/prop-card/index.jsx
@@ -252,7 +252,7 @@
            <NormalForm title="轮播-静态数据" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="propcard" card={card}/>
            <CopyComponent type="carpropcard" card={card}/>
            <PasteComponent config={card} options={['cardcell']} updateConfig={this.updateComponent} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx
@@ -179,7 +179,7 @@
      initval: card.menus || [],
      required: true,
      span: 24,
      actions: appType === 'pc' ? ['view'] : [],
      actions: ['edit', 'del', 'add', 'move', 'view'],
      columns: [
        {
          title: '标识',
src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx
@@ -157,7 +157,7 @@
      initval: card.menus || [],
      required: true,
      span: 24,
      actions: appType === 'pc' ? ['view'] : [],
      actions: ['edit', 'del', 'add', 'move', 'view'],
      columns: [
        {
          title: '标识',
src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
@@ -187,7 +187,7 @@
      initval: card.menus || [],
      required: true,
      span: 24,
      actions: ['view'],
      actions: ['edit', 'del', 'add', 'move', 'view'],
      forbid: appType === 'mob' || card.chartType !== 'bar',
      hidden: card.click !== 'menus',
      columns: [
src/menu/components/chart/antv-scatter/index.jsx
@@ -350,7 +350,7 @@
            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
            {appType !== 'mob' ? <PlusSquareOutlined className="plus" title="添加按钮" onClick={this.addButton}/> : null}
            <ChartCompileForm config={card} plotchange={this.updateComponent}/>
            <CopyComponent type="line" card={card}/>
            <CopyComponent type="scatter" card={card}/>
            <PasteComponent config={card} options={['action', 'search']} updateConfig={this.updateComponent}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
src/menu/components/chart/chart-custom/index.jsx
@@ -251,7 +251,7 @@
          <div className="mk-popover-control">
            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
            <ChartCompileForm config={card} plotchange={this.updateComponent}/>
            <CopyComponent type="line" card={card}/>
            <CopyComponent type="chart" card={card}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <ClockComponent config={card} updateConfig={this.updateComponent}/>
            <DeleteOutlined className="close" title="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
src/menu/components/form/dragtitle/card.jsx
@@ -90,7 +90,7 @@
          <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
        </NormalForm>
        <CopyComponent type="formgroup" card={card}/>
        <PasteForms config={card} updateConfig={(res) => pasteForm(res, id)} />
        <PasteForms config={card} update={(res) => pasteForm(res, id)} />
        <CloseOutlined className="close" type="close" onClick={close} />
      </div>
    } trigger="hover">
src/menu/components/form/formaction/index.jsx
@@ -100,8 +100,10 @@
      supId = config.wrap.supModule[config.wrap.supModule.length - 1]
    }
    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid, supId)
    let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, config.uuid) || []
    let menu = window.GLOB.customMenu
    let modules = MenuUtils.getSubModules(menu.components, config.uuid, supId, menu.interfaces || null)
    let anchors = MenuUtils.getAnchors(menu.components, config.uuid) || []
    if (card.type === 'submit' && !card.Ot) {
      card.Ot = config.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
src/menu/components/group/groupcomponents/index.jsx
@@ -51,7 +51,7 @@
    drop(item) {
      if (item.hasOwnProperty('originalIndex') || item.added) {
        return
      } else if (['login', 'navbar', 'topbar', 'tabs', 'search', 'group', 'menubar'].includes(item.component)) {
      } else if (['login', 'navbar', 'topbar', 'tabs', 'search', 'group', 'menubar', 'iframe', 'sharecode', 'officialAccount'].includes(item.component)) {
        return
      }
src/menu/components/group/normal-group/index.jsx
@@ -15,7 +15,7 @@
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
const PasteComponent = asyncIconComponent(() => import('../paste'))
const PasteController = asyncIconComponent(() => import('@/menu/pastecontroller'))
const GroupComponents = asyncComponent(() => import('../groupcomponents'))
class NormalGroup extends Component {
@@ -178,9 +178,9 @@
            <NormalForm title="分组设置" width={700} update={this.updateWrap} getForms={this.getWrapForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="tabs" card={group}/>
            <CopyComponent type="group" card={group}/>
            <UngroupOutlined title="释放" style={group.components.length > 0 ? {color: '#32c5d2'} : {color: '#eeeeee', cursor: 'not-allowed'}} onClick={this.unGroup}/>
            <PasteComponent insert={this.insert} />
            <PasteController type="group" tab={group} insert={this.insert} />
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <DeleteOutlined className="close" title="delete" onClick={() => this.props.deletecomponent(group.uuid)} />
          </div>
src/menu/components/group/paste/index.jsx
File was deleted
src/menu/components/group/paste/index.scss
src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -780,6 +780,7 @@
      let className = ''
      let content = null
      let initVal = item.initVal || ''
      let help = item.help || ''
      if (item.type === 'splitLine') {
        fields.push(
@@ -857,6 +858,7 @@
            filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
              option.props.extend.toLowerCase().indexOf(input.toLowerCase()) >= 0}
            onChange={(value) => {this.optionChange(item.key, value)}}
            on
            getPopupContainer={() => document.getElementById('winter')}
          >
            {item.options.map((option, index) =>
@@ -909,7 +911,7 @@
        rules = [
          { required: item.required, message: '请添加' + item.label + '!' }
        ]
        content = (<MKTable tip={''} columns={item.columns || []} actions={[]}/>)
        content = (<MKTable columns={item.columns || []} actions={item.actions}/>)
      } else if (item.type === 'icon') {
        rules = [
          { required: item.required, message: '请选择' + item.label + '!' }
@@ -936,7 +938,7 @@
          { required: item.required, message: '请选择' + item.label + '!' }
        ]
        content = <MkPrintTemps />
        content = <MkPrintTemps onChange={(value) => {this.optionChange(item.key, value)}}/>
      } else if (item.type === 'keyinterface') {
        span = 24
        className = 'textarea'
@@ -947,9 +949,13 @@
        content = <KeyInterface type={item.key === 'exInterface' ? 'develop' : 'product'}/>
      }
      if (help && typeof(help) === 'function') {
        help = help(this.record)
      }
      fields.push(
        <Col span={span} key={index}>
          <Form.Item className={className} help={item.help} label={item.tooltip ?
          <Form.Item className={className} help={help} label={item.tooltip ?
            <Tooltip placement="topLeft" overlayStyle={{maxWidth: item.tooltip.length > 25 ? 350 : 250 }} title={<span onClick={(e) => e.stopPropagation()}>{item.tooltip}</span>}>
              <QuestionCircleOutlined className="mk-form-tip" />
              {item.label}
src/menu/components/share/actioncomponent/formconfig.jsx
@@ -1,5 +1,5 @@
import React from 'react'
import { btnClasses } from '@/utils/option.js'
/**
 * @description 获取按钮表单配置信息
@@ -161,6 +161,7 @@
    { value: 'print', text: '标签打印' },
    { value: 'refund', text: '退款' },
    { value: 'closetab', text: '标签关闭' },
    // { value: 'expPdf', text: '导出PDF' },
    { value: 'megvii', text: '旷视面板机' },
    { value: 'filezip', text: '文件压缩包' },
  ]
@@ -468,6 +469,19 @@
      key: 'printTemp',
      label: '打印模板',
      initVal: card.printTemp || '',
      help: (record) => {
        if (record.printTemp) {
          return <span onClick={() => {
            sessionStorage.setItem('mk-print-temp', record.printTemp)
            window.open('#/hs')
            setTimeout(() => {
              sessionStorage.removeItem('mk-print-temp')
            }, 50)
          }} style={{color: '#1890ff', cursor: 'pointer', fontSize: '13px'}}>#查看模板</span>
        }
        return ''
      },
      required: true
    },
    {
@@ -1349,7 +1363,7 @@
      label: '组件列表',
      initVal: card.syncComponents || [],
      required: true,
      actions: [],
      actions: ['edit', 'del', 'add', 'move'],
      columns: [
        {
          title: '组件',
@@ -1430,6 +1444,7 @@
    { value: 'print', text: '标签打印' },
    { value: 'refund', text: '退款' },
    { value: 'closetab', text: '标签关闭' },
    // { value: 'expPdf', text: '导出PDF' },
    { value: 'megvii', text: '旷视面板机' },
    { value: 'filezip', text: '文件压缩包' },
  ]
@@ -1603,6 +1618,19 @@
      key: 'printTemp',
      label: '打印模板',
      initVal: card.printTemp || '',
      help: (record) => {
        if (record.printTemp) {
          return <span onClick={() => {
            sessionStorage.setItem('mk-print-temp', record.printTemp)
            window.open('#/hs')
            setTimeout(() => {
              sessionStorage.removeItem('mk-print-temp')
            }, 50)
          }} style={{color: '#1890ff', cursor: 'pointer', fontSize: '13px'}}>#查看模板</span>
        }
        return ''
      },
      required: true
    },
    {
@@ -2221,7 +2249,7 @@
      label: '组件列表',
      initVal: card.syncComponents || [],
      required: true,
      actions: [],
      actions: ['edit', 'del', 'add', 'move'],
      columns: [
        {
          title: '组件',
src/menu/components/share/actioncomponent/index.jsx
@@ -206,8 +206,10 @@
        supId = ''
      }
    }
    let menu = window.GLOB.customMenu
    
    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid, supId, config.subtype !== 'basetable')
    let modules = MenuUtils.getSubModules(menu.components, config.uuid, supId, menu.interfaces || null)
    if (config.subtype === 'basetable') {
      delete card.eleType // 区分按钮位置
@@ -218,7 +220,7 @@
        formlist: getBaseTableActionForm(card, functip, config, usefulFields, modules)
      })
    } else {
      let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, config.uuid) || []
      let anchors = MenuUtils.getAnchors(menu.components, config.uuid) || []
  
      this.setState({
        visible: true,
src/menu/components/share/pastecomponent/index.jsx
@@ -168,24 +168,28 @@
      } else if (type === 'cols') {
        config.cols = config.cols.filter(col => !col.origin)
        let keys = config.cols.map(col => (col.field || '$empty'))
        let cols = []
        res.cols.forEach(col => {
          if (!col.field || !keys.includes(col.field)) {
            cols.push(col)
          }
        })
        if (cols.length === 0) {
          notification.warning({
            top: 92,
            message: '显示列已存在!',
            duration: 5
          })
          return
        if (config.subtype === 'normaltable' && res.cols.length === 1) {
          config.cols.push(...res.cols)
        } else {
          config.cols.push(...cols)
          let keys = config.cols.map(col => (col.field || '$empty'))
          let cols = []
          res.cols.forEach(col => {
            if (!col.field || !keys.includes(col.field)) {
              cols.push(col)
            }
          })
          if (cols.length === 0) {
            notification.warning({
              top: 92,
              message: '显示列已存在!',
              duration: 5
            })
            return
          } else {
            config.cols.push(...cols)
          }
        }
      }
src/menu/components/table/base-table/columns/editColumn/index.scss
@@ -34,7 +34,7 @@
  .ant-popover-inner-content {
    div {
      max-width: 750px;
      word-break: break-all;
      word-break: normal;
    }
  }
}
src/menu/components/table/base-table/index.jsx
@@ -219,7 +219,7 @@
  getWrapForms = () => {
    const { wrap, action, columns, cols } = this.state.card
    let _actions = [...action]
    let _actions = []
    cols.forEach(col => {
      if (col.type === 'custom') {
@@ -231,7 +231,7 @@
      }
    })
    return getWrapForm(wrap, _actions, columns)
    return getWrapForm(wrap, _actions, columns, action)
  }
  updateWrap = (res) => {
src/menu/components/table/base-table/options.jsx
@@ -1,7 +1,7 @@
/**
 * @description Wrap表单配置信息
 */
export default function (wrap, action = [], columns = []) {
export default function (wrap, action = [], columns = [], toolBtns = []) {
  const wrapForm = [
    {
      type: 'radio',
@@ -167,7 +167,16 @@
      tooltip: '双击表格中行,触发的按钮。',
      required: false,
      allowClear: true,
      options: action.map(item => ({value: item.uuid, label: item.label})),
      options: [...toolBtns, ...action].map(item => ({value: item.uuid, label: item.label})),
    },
    {
      type: 'select',
      field: 'autoExec',
      label: '自动执行',
      initval: wrap.autoExec || '',
      tooltip: '初始化自动执行按钮。',
      required: false,
      options: toolBtns.map(item => ({value: item.uuid, label: item.label}))
    },
    {
      type: 'select',
src/menu/components/table/edit-table/columns/editColumn/index.scss
@@ -57,7 +57,7 @@
  .ant-popover-inner-content {
    div {
      max-width: 750px;
      word-break: break-all;
      word-break: normal;
    }
  }
}
src/menu/components/table/edit-table/columns/tableIn/index.jsx
@@ -196,8 +196,10 @@
        supId = ''
      }
    }
    let menu = window.GLOB.customMenu
    
    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, uuid, supId)
    let modules = MenuUtils.getSubModules(menu.components, uuid, supId, menu.interfaces || null)
    this.setState({
      fields: fromJS(columns).toJS().filter(item => item.field !== setting.primaryKey),
src/menu/components/table/normal-table/columns/editColumn/index.scss
@@ -34,7 +34,7 @@
  .ant-popover-inner-content {
    div {
      max-width: 750px;
      word-break: break-all;
      word-break: normal;
    }
  }
}
src/menu/components/table/normal-table/index.jsx
@@ -280,7 +280,7 @@
  getWrapForms = () => {
    const { wrap, action, columns, cols } = this.state.card
    let _actions = [...action]
    let _actions = []
    cols.forEach(col => {
      if (col.type === 'custom') {
@@ -292,7 +292,7 @@
      }
    })
    return getWrapForm(wrap, _actions, columns)
    return getWrapForm(wrap, _actions, columns, action)
  }
  updateWrap = (res) => {
@@ -374,7 +374,7 @@
            <PlusOutlined className="plus" title="添加列" onClick={() => this.addColumns()}/>
            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="添加搜索" onClick={this.addSearch}/> : null}
            <PlusSquareOutlined className="plus" title="添加按钮" onClick={this.addButton}/>
            <NormalForm title="表格设置" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
            <NormalForm title="表格设置" width={850} update={this.updateWrap} getForms={this.getWrapForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="normaltable" card={card}/>
src/menu/components/table/normal-table/options.jsx
@@ -1,7 +1,7 @@
/**
 * @description Wrap表单配置信息
 */
export default function (wrap, action = [], columns = []) {
export default function (wrap, action = [], columns = [], toolBtns) {
  let roleList = sessionStorage.getItem('sysRoles')
  let appType = sessionStorage.getItem('appType')
  let isprint = sessionStorage.getItem('MenuType') === 'billPrint'
@@ -209,11 +209,20 @@
      tooltip: '双击表格中行,触发的按钮。',
      required: false,
      allowClear: true,
      options: action.map(item => ({value: item.uuid, label: item.label})),
      options: [...toolBtns, ...action].map(item => ({value: item.uuid, label: item.label})),
      forbid: appType === 'mob'
    },
    {
      type: 'select',
      field: 'autoExec',
      label: '自动执行',
      initval: wrap.autoExec || '',
      tooltip: '初始化自动执行按钮。',
      required: false,
      options: toolBtns.map(item => ({value: item.uuid, label: item.label}))
    },
    {
      type: 'select',
      field: 'tipField',
      label: '信息提示',
      initval: wrap.tipField || '',
src/menu/components/tabs/antv-tabs/index.jsx
@@ -16,7 +16,7 @@
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('../paste'))
const PasteController = asyncIconComponent(() => import('@/menu/pastecontroller'))
const TabComponents = asyncComponent(() => import('../tabcomponents'))
const { TabPane } = Tabs
@@ -181,11 +181,11 @@
    this.props.updateConfig(tabs)
  }
  insert = (item, tab) => {
  insert = (item, tabId) => {
    let tabs = fromJS(this.state.tabs).toJS()
    tabs.subtabs.forEach(stab => {
      if (stab.uuid === tab.uuid) {
      if (stab.uuid === tabId) {
        stab.components.push(item)
      }
    })
@@ -220,7 +220,7 @@
    editab.hide = res.hide || 'false'
    editab.backgroundColor = res.backgroundColor
    // editab.controlVal = res.controlVal || ''
    editab.selectVal = res.selectVal || ''
    // editab.selectVal = res.selectVal || ''
    editab.blacklist = res.blacklist
    if (editab.uuid) {
@@ -264,6 +264,17 @@
      delete res.controlVals
    }
    if (res.selectVals) {
      let values = {}
      res.selectVals.forEach(item => {
        values[item.uuid] = item.value
      })
      tabs.subtabs.forEach(tab => {
        tab.selectVal = values[tab.uuid]
      })
      delete res.selectVals
    }
    res.tabStyle = res.tabStyle || 'line'
    res.cusClass = ''
@@ -297,7 +308,7 @@
                  <NormalForm title="标签编辑" width={800} update={this.updateTab} getForms={() => this.getTabForms(tab)}>
                    <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
                  </NormalForm>
                  <PasteComponent Tab={tab} insert={this.insert} />
                  <PasteController type="tabs" tab={tab} insert={(item) => this.insert(item, tab.uuid)} />
                  <CloseOutlined className="close" onClick={() => this.delTab(tab)} />
                </div>
              } trigger="hover">
src/menu/components/tabs/antv-tabs/options.jsx
@@ -42,14 +42,14 @@
    //   tooltip: '当禁用字段值与隐藏标记相等时,标签页会隐藏。注:1、多个值请用逗号分隔,2、@pass@值表示忽略此设置(始终显示),2、@pass_empty@值表示忽略空值,即未获取上级组件信息时显示(可与其他值拼接)。',
    //   required: false,
    // },
    {
      type: 'text',
      field: 'selectVal',
      label: '选中标记',
      initval: tab.selectVal || '',
      tooltip: '当选中字段值与选中标记相等时,标签页默认选中。',
      required: false
    },
    // {
    //   type: 'text',
    //   field: 'selectVal',
    //   label: '选中标记',
    //   initval: tab.selectVal || '',
    //   tooltip: '当选中字段值与选中标记相等时,标签页默认选中。',
    //   required: false
    // },
    {
      type: 'color',
      field: 'backgroundColor',
@@ -105,7 +105,8 @@
    roleList = []
  }
  let controlVals = subtabs.map(item => ({uuid: item.uuid, label: item.label, value: item.controlVal}))
  let controlVals = subtabs.map(item => ({uuid: item.uuid, label: item.label, value: item.controlVal || ''}))
  let selectVals = subtabs.map(item => ({uuid: item.uuid, label: item.label, value: item.selectVal || ''}))
  let tabStyle = setting.cusClass || setting.tabStyle
@@ -238,7 +239,10 @@
      label: '选中字段',
      initval: setting.selectField || '',
      tooltip: '用于控制标签页初始化选中,在标签中填入选中标记,注:数据来源于url参数。',
      required: false
      required: false,
      controlFields: [
        {field: 'selectVals', notNull: true},
      ]
    },
    {
      type: 'color',
@@ -271,11 +275,11 @@
    {
      type: 'table',
      field: 'controlVals',
      label: '标签组',
      label: '标签组(禁用)',
      initval: controlVals,
      tooltip: '当禁用字段值与隐藏标记相等时,标签页会隐藏。注:1、多个值请用逗号分隔,2、@pass@值表示忽略此设置(始终显示),2、@pass_empty@值表示忽略空值,即未获取上级组件信息时显示(可与其他值拼接)。',
      required: false,
      fixed: true,
      actions: ['edit'],
      span: 24,
      columns: [
        {
@@ -294,6 +298,33 @@
          width: '50%'
        }
      ]
    },
    {
      type: 'table',
      field: 'selectVals',
      label: '标签组(选中)',
      initval: selectVals,
      tooltip: '当选中字段值与选中标记相等时,标签页默认选中。',
      required: false,
      actions: ['edit'],
      span: 24,
      columns: [
        {
          title: '标签名称',
          dataIndex: 'label',
          editable: false,
          required: false,
          width: '30%'
        },
        {
          title: '选中标记',
          dataIndex: 'value',
          inputType: 'input',
          editable: true,
          required: false,
          width: '50%'
        }
      ]
    }
  ]
src/menu/components/tabs/paste/index.jsx
File was deleted
src/menu/components/tabs/paste/index.scss
src/menu/components/tabs/tabcomponents/index.jsx
@@ -80,7 +80,7 @@
    drop(item) {
      if (item.hasOwnProperty('originalIndex') || item.added) {
        return
      } else if (['login', 'navbar', 'topbar'].includes(item.component)) {
      } else if (['login', 'navbar', 'topbar', 'iframe'].includes(item.component)) {
        return
      }
      
src/menu/debug/index.jsx
@@ -254,13 +254,16 @@
        item.action && item.action.forEach(cell => {
          if (cell.hidden === 'true') return false
          let sql = this.resetButton(item, cell, process)
          let res = this.resetButton(item, cell, process)
          if (sql) {
            if (typeof(sql) === 'string') {
              children.push({label: cell.label, sql: sql})
          if (res) {
            if (typeof(res) === 'string') {
              children.push({label: cell.label, sql: res})
            } else if (res.backSql) {
              children.push({label: cell.label, sql: res.sql})
              children.push({label: cell.label + '(回调)', sql: res.backSql})
            } else {
              children.push({label: cell.label, tabName: cell.label, sql: '', children: sql})
              children.push({label: cell.label, tabName: cell.label, sql: '', children: res})
            }
          }
        })
@@ -276,13 +279,16 @@
              } else if (col.type === 'custom') {
                col.elements.forEach(cell => {
                  if (cell.eleType !== 'button' || cell.hidden === 'true') return
                  let sql = this.resetButton(item, cell, process)
                  let res = this.resetButton(item, cell, process)
                  if (sql) {
                    if (typeof(sql) === 'string') {
                      children.push({label: cell.label, sql: sql})
                  if (res) {
                    if (typeof(res) === 'string') {
                      children.push({label: cell.label, sql: res})
                    } else if (res.backSql) {
                      children.push({label: cell.label, sql: res.sql})
                      children.push({label: cell.label + '(回调)', sql: res.backSql})
                    } else {
                      children.push({label: cell.label, tabName: cell.label, sql: '', children: sql})
                      children.push({label: cell.label, tabName: cell.label, sql: '', children: res})
                    }
                  }
                })
@@ -300,13 +306,16 @@
          item.subcards && item.subcards.forEach(card => {
            card.elements && card.elements.forEach(cell => {
              if (cell.eleType !== 'button' || cell.hidden === 'true') return
              let sql = this.resetButton(item, cell, process)
              let res = this.resetButton(item, cell, process)
              if (sql) {
                if (typeof(sql) === 'string') {
                  children.push({label: cell.label, sql: sql})
              if (res) {
                if (typeof(res) === 'string') {
                  children.push({label: cell.label, sql: res})
                } else if (res.backSql) {
                  children.push({label: cell.label, sql: res.sql})
                  children.push({label: cell.label + '(回调)', sql: res.backSql})
                } else {
                  children.push({label: cell.label, tabName: cell.label, sql: '', children: sql})
                  children.push({label: cell.label, tabName: cell.label, sql: '', children: res})
                }
              }
            })
@@ -315,13 +324,16 @@
  
            card.backElements.forEach(cell => {
              if (cell.eleType !== 'button' || cell.hidden === 'true') return
              let sql = this.resetButton(item, cell, process, null, true)
              let res = this.resetButton(item, cell, process, null, true)
              if (sql) {
                if (typeof(sql) === 'string') {
                  children.push({label: cell.label, sql: sql})
              if (res) {
                if (typeof(res) === 'string') {
                  children.push({label: cell.label, sql: res})
                } else if (res.backSql) {
                  children.push({label: cell.label, sql: res.sql})
                  children.push({label: cell.label + '(回调)', sql: res.backSql})
                } else {
                  children.push({label: cell.label, tabName: cell.label, sql: '', children: sql})
                  children.push({label: cell.label, tabName: cell.label, sql: '', children: res})
                }
              }
            })
@@ -329,13 +341,16 @@
        } else if (item.type === 'balcony') {
          item.elements.forEach(cell => {
            if (cell.eleType !== 'button' || cell.hidden === 'true') return
            let sql = this.resetButton(item, cell, process)
            let res = this.resetButton(item, cell, process)
            if (sql) {
              if (typeof(sql) === 'string') {
                children.push({label: cell.label, sql: sql})
            if (res) {
              if (typeof(res) === 'string') {
                children.push({label: cell.label, sql: res})
              } else if (res.backSql) {
                children.push({label: cell.label, sql: res.sql})
                children.push({label: cell.label + '(回调)', sql: res.backSql})
              } else {
                children.push({label: cell.label, tabName: cell.label, sql: '', children: sql})
                children.push({label: cell.label, tabName: cell.label, sql: '', children: res})
              }
            }
          })
@@ -345,10 +360,15 @@
            if (!group.subButton.Ot) {
              group.subButton.Ot = item.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
            }
            let sql = this.resetButton(item, group.subButton, process, group)
            let res = this.resetButton(item, group.subButton, process, group)
            if (sql) {
              children.push({label: group.subButton.label, sql: sql})
            if (res) {
              if (typeof(res) === 'string') {
                children.push({label: group.subButton.label, sql: res})
              } else if (res.backSql) {
                children.push({label: group.subButton.label, sql: res.sql})
                children.push({label: group.subButton.label + '(回调)', sql: res.backSql})
              }
            }
          })
        }
@@ -372,9 +392,52 @@
          let _item = fromJS(item).toJS()
          _item.columns = _item.subColumns || []
          _item.setting.primaryKey = _item.setting.subKey
          sql = this.getSysDefaultSql(cell, _item, process, group)
          sql = this.getSysDefaultSql(cell, _item, process, group, false)
        } else {
          sql = this.getSysDefaultSql(cell, item, process, group)
          sql = this.getSysDefaultSql(cell, item, process, group, false)
        }
      }
      if (cell.callbackType === 'script' && cell.verify && cell.verify.cbScripts) {
        let defSql = ''
        if (item.subtype === 'dualdatacard' && isback) {
          let _item = fromJS(item).toJS()
          _item.columns = _item.subColumns || []
          _item.setting.primaryKey = _item.setting.subKey
          defSql = this.getSysDefaultSql(cell, _item, process, group, true)
        } else {
          defSql = this.getSysDefaultSql(cell, item, process, group, true)
        }
        let backSql = this.getSysBackSql(cell.verify.cbScripts, cell.cbTable)
        if (backSql) {
          backSql = `${defSql}
            ${backSql}
          `
          if (cell.output) {
            backSql += `
              aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg,${cell.output} as mk_b_id`
          } else {
            backSql += `
              aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
          }
          backSql = backSql.replace(/@ID@/ig, `'id'`)
          backSql = backSql.replace(/@BID@/ig, `'bid'`)
          backSql = backSql.replace(/@LoginUID@/ig, `'LoginUID'`)
          backSql = backSql.replace(/@SessionUid@/ig, `'SessionUid'`)
          backSql = backSql.replace(/@UserID@/ig, `'UserID'`)
          backSql = backSql.replace(/@Appkey@/ig, `'appkey'`)
          backSql = backSql.replace(/@typename@/ig, `'typename'`)
          backSql = backSql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`)
        }
        if (backSql) {
          return {
            backSql,
            sql
          }
        }
      }
    } else if (cell.OpenType === 'excelIn') {
@@ -421,7 +484,88 @@
    return sql
  }
  getSysDefaultSql = (btn, component, process, group) => {
  getSysBackSql = (scripts, cbTable) => {
    let _prev = ''
    let _back = ''
    scripts.forEach(script => {
      if (script.status === 'false') return
      if (script.position === 'front') {
        _prev += `
      /* 自定义脚本 */
      ${script.sql}
      `
      } else {
        _back += `
      /* 自定义脚本 */
      ${script.sql}
      `
      }
    })
    if (!_prev) return ''
    let tbs = []
    _prev.replace(/\n|\r/g, ' ').split(/\sdeclare\s/ig).forEach(line => {
      if (!/^\s*(@|#)[a-zA-Z0-9_]+\s+table\s+\(/ig.test(line)) return
      let tb = line.match(/(@|#)[a-zA-Z0-9_]+\s+table\s+\(.+(\)|date|datetime)\s*\)/ig)
      if (tb && tb.length === 1) {
        tbs.push(tb[0])
      }
    })
    tbs.forEach(tb => {
      let tbName = tb.match(/(@|#)[a-zA-Z0-9_]+/ig)[0]
      if (!tbName) return
      let content = tb.replace(/(@|#)[a-zA-Z0-9_]+\s+table\s+\(\s*/, '').replace(/\s*\)$/, '')
      content = content.replace(/decimal\(\s*\d+\s*,\s*\d+\s*\)/ig, 'decimal')
      let keys = []
      let vals = []
      let error = false
      let istop = new RegExp(cbTable + '$', 'ig').test(tbName)
      let id = tbName.replace(/@|#/, '')
      content.split(/\s*,\s*/).forEach(m => {
        let ms = m.split(/\s+/)
        if (ms.length > 1) {
          keys.push(ms[0])
          if (/^mk_level$/i.test(ms[0])) {
            vals.push(istop ? `'1'` : `'2'`)
          } else if (/^mk_id$/i.test(ms[0])) {
            vals.push(istop ? `'${cbTable}'` : `'${id}'`)
          } else if (/^mk_bid$/i.test(ms[0])) {
            vals.push(istop ? `''` : `'${cbTable}'`)
          } else if (/nvarchar/i.test(ms[1])) {
            vals.push(`'mk'`)
          } else if (/date/i.test(ms[1])) {
            vals.push(`'1949-10-01'`)
          } else if (/int|decimal/i.test(ms[1])) {
            vals.push('0')
          } else {
            error = true
          }
        } else {
          error = true
        }
      })
      if (error || vals.length === 0) return
      _prev += `
      Insert into ${tbName} (${keys.join(',')})
      Select ${vals.join(',')}
      `
    })
    return _prev + _back
  }
  getSysDefaultSql = (btn, component, process, group, retmsg) => {
    let primaryId = 'id'
    let BID = 'bid'
    let verify = btn.verify || {}
@@ -492,6 +636,9 @@
            _item.fieldlen = item.decimal || 0
          } else  if (_item.type === 'date') {
            _item.type = item.declareType === 'nvarchar(50)' ? 'text' : 'date'
          } else if (item.declare === 'decimal') {
            _item.type = 'number'
            _item.fieldlen = item.decimal || 0
          }
    
          formdata.push(_item)
@@ -536,6 +683,9 @@
            _item.fieldlen = item.decimal || 0
          } else  if (_item.type === 'date') {
            _item.type = item.declareType === 'nvarchar(50)' ? 'text' : 'date'
          } else if (item.declare === 'decimal') {
            _item.type = 'number'
            _item.fieldlen = item.decimal || 0
          }
    
          formdata.push(_item)
@@ -671,6 +821,10 @@
        /* 显示列变量赋值 */
        select ${_initColfields.join(',')}
        `
    }
    if (retmsg) {
      return _sql
    }
  
    // 去除禁用的验证
@@ -879,15 +1033,13 @@
        item.field.split(',').forEach((_field, index) => {
          let _key = _field.toLowerCase()
          let _val = ''
          let _fval = `'${_val}'`
  
          arr.push(_key)
          if (_key === 'bid') { // 表单中没有bid则使用系统bid变量
            _fval = '@BID@'
            _val = BID
          }
          arr.push(_key)
          _fieldValue.push(`${_key}=${_fval}`)
          _fieldValue.push(`${_key}='${_val}'`)
          _value.push(`${_labels[index] || ''}:${_val || ''}`)
        })
  
src/menu/pastecontroller/index.jsx
@@ -1,7 +1,9 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Modal, Button, notification } from 'antd'
import { SnippetsOutlined } from '@ant-design/icons'
import md5 from 'md5'
import MenuUtils from '@/utils/utils-custom.js'
import asyncComponent from '@/utils/asyncComponent'
@@ -18,60 +20,264 @@
    visible: false
  }
  resetconfig = (item, appType) => {
  resetconfig = (item, appType, commonId) => {
    if (item.type === 'tabs') {
      item.uuid = MenuUtils.getuuid()
      item.uuid = md5(commonId + item.uuid)
      item.setting.name = (item.setting.name || '') + MenuUtils.getSignName()
      item.name = item.setting.name
      item.subtabs.forEach(tab => {
        tab.uuid = MenuUtils.getuuid()
        tab.uuid = md5(commonId + tab.uuid)
        if (appType !== 'mob') {
          tab.components = tab.components.filter(cell => cell.type !== 'menubar')
        }
        tab.components = tab.components.map(cell => {
          cell = this.resetconfig(cell, appType)
          cell = this.resetconfig(cell, appType, commonId)
          return cell
        })
      })
    } else if (item.type === 'group') {
      item.uuid = MenuUtils.getuuid()
      item.uuid = md5(commonId + item.uuid)
      item.setting.name = (item.setting.name || '') + MenuUtils.getSignName()
      item.name = item.setting.name
      item.components = item.components.map(cell => {
        cell = MenuUtils.resetComponentConfig(cell, appType)
        cell.uuid = md5(commonId + cell.uuid)
        cell = MenuUtils.resetComponentConfig(cell, appType, commonId)
        return cell
      })
    } else {
      item = MenuUtils.resetComponentConfig(item, appType)
      item.uuid = md5(commonId + item.uuid)
      item = MenuUtils.resetComponentConfig(item, appType, commonId)
    }
    return item
  }
  pasteSubmit = () => {
    let appType = sessionStorage.getItem('appType')
    let options = ['tabs', 'timeline', 'datacard', 'propcard', 'simpleform', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'bar', 'editor', 'pie', 'scatter', 'iframe', 'sandbox']
  resetlink = (item, commonId) => {
    if (item.type === 'tabs') {
      item.subtabs.forEach(tab => {
        tab.components.forEach(cell => {
          this.resetlink(cell, commonId)
        })
      })
    } else if (item.type === 'group') {
      item.components.forEach(cell => {
        this.resetlink(cell, commonId)
      })
    } else {
      if (['card', 'carousel', 'timeline'].includes(item.type)) {
        item.subcards.forEach(card => {
          card.elements && card.elements.forEach(cell => {
            if (cell.eleType === 'button') {
              this.resetBtn(cell, commonId)
            }
          })
          card.backElements && card.backElements.forEach(cell => {
            if (cell.eleType === 'button') {
              this.resetBtn(cell, commonId)
            }
          })
        })
      } else if (item.type === 'balcony') {
        item.elements && item.elements.forEach(cell => {
          if (cell.eleType === 'button') {
            this.resetBtn(cell, commonId)
          }
        })
      } else if (item.type === 'table' && item.cols) {
        let loopCol = (cols) => {
          cols.forEach(col => {
            if (col.type === 'colspan' && col.subcols) {
              loopCol(col.subcols)
            } else if (col.type === 'custom' && col.elements) {
              col.elements.forEach(cell => {
                if (cell.eleType === 'button') {
                  this.resetBtn(cell, commonId)
                }
              })
            }
          })
        }
        loopCol(item.cols)
      } else if (item.type === 'form') {
        item.subcards.forEach(cell => {
          if (cell.subButton) {
            this.resetBtn(cell.subButton, commonId)
          }
        })
      }
      item.action && item.action.forEach(cell => {
        this.resetBtn(cell, commonId)
      })
    if (appType === 'mob') {
      if (sessionStorage.getItem('editMenuType') !== 'popview') {
        options.push('menubar', 'topbar', 'singleSearch')
      } else {
      if (item.wrap && item.wrap.supType === 'multi') {
        if (item.setting && item.setting.supModule) {
          item.setting.supModule = ''
        }
        if (item.supNodes) {
          item.supNodes = item.supNodes.map(cell => {
            let id = cell.nodes[cell.nodes.length - 1]
            let _id = md5(commonId + id)
            if (this.modules[id] || this.modules[_id]) {
              cell.nodes = this.modules[id] || this.modules[_id]
              cell.componentId = cell.nodes[cell.nodes.length - 1]
              return cell
            }
            return null
          })
          item.supNodes = item.supNodes.filter(Boolean)
        }
        if (!item.supNodes || item.supNodes.length === 0) {
          item.wrap.supType = 'single'
          delete item.supNodes
        }
      }
      if (item.setting && item.setting.supModule && item.setting.supModule[0] !== 'empty') {
        let id = item.setting.supModule[item.setting.supModule.length - 1]
        let _id = md5(commonId + id)
        item.setting.supModule = this.modules[id] || this.modules[_id] || ''
      }
      if (item.wrap && item.wrap.supModule && item.wrap.supModule[0]) {
        let id = item.wrap.supModule[item.wrap.supModule.length - 1]
        let _id = md5(commonId + id)
        item.wrap.supModule = this.modules[id] || this.modules[_id] || ''
      }
    }
  }
  resetBtn (btn, commonId) {
    if (btn.switchTab && btn.switchTab.length > 0) {
      let id = btn.switchTab[btn.switchTab.length - 1]
      let _id = md5(commonId + id)
      btn.switchTab = this.modules[id] || this.modules[_id] || null
    }
    if (btn.anchors && btn.anchors.length > 0) {
      let id = btn.anchors[btn.anchors.length - 1]
      let _id = md5(commonId + id)
      btn.anchors = this.modules[id] || this.modules[_id] || null
    }
    if (btn.syncComponent && btn.syncComponent[0] === 'multiComponent' && btn.syncComponents) {
      btn.syncComponents = btn.syncComponents.map(m => {
        let id = m.syncComId[m.syncComId.length - 1]
        let _id = md5(commonId + id)
        return this.modules[id] || this.modules[_id] || null
      })
      btn.syncComponents = btn.syncComponents.filter(Boolean)
      if (btn.syncComponents.length === 0) {
        btn.syncComponent = null
        btn.syncComponents = null
      }
    } else if (btn.syncComponent && btn.syncComponent.length > 0) {
      let id = btn.syncComponent[btn.syncComponent.length - 1]
      let _id = md5(commonId + id)
      btn.syncComponent = this.modules[id] || this.modules[_id] || null
    }
  }
  resetmenu = (components, componentId, res) => {
    components.forEach(item => {
      if (item.type === 'tabs') {
        item.subtabs.forEach(tab => {
          if (tab.uuid === componentId) {
            tab.components.push(res)
          } else {
            this.resetmenu(tab.components, componentId, res)
          }
        })
      } else if (item.type === 'group' && item.uuid === componentId) {
        item.components.push(res)
      }
    })
  }
  getModules = (components, interfaces, sups = []) => {
    components.forEach(item => {
      this.modules[item.uuid] = [...sups, item.uuid]
      if (item.type === 'tabs') {
        item.subtabs.forEach(f_tab => {
          this.getModules(f_tab.components, null, [...sups, item.uuid, f_tab.uuid])
        })
      } else if (item.type === 'group') {
        item.components.forEach(cell => {
          this.modules[cell.uuid] = [...sups, item.uuid, cell.uuid]
        })
      }
    })
    if (interfaces && interfaces.length > 0) {
      interfaces.forEach(item => {
        this.modules[item.uuid] = [item.uuid]
      })
    }
  }
  pasteSubmit = () => {
    const { type, tab } = this.props
    let appType = sessionStorage.getItem('appType')
    // ['calendar', 'balcony', 'datacard', 'doublecard', 'propcard', 'tablecard', 'cardatacard', 'carpropcard', 'line', 'dashboard', 'antvG6', 'pie', 'scatter', 'antvX6', 'chart', 'sandbox', 'editor', 'simpleform', 'stepform', 'tabform', 'group', 'iframe', 'mainsearch', 'basetable', 'editable', 'normaltable', 'tabs', 'timeline', 'tree', 'menubar', 'singleSearch', 'topbar']
    let options = []
    let types = {
      topbar: '导航栏',
      singleSearch: '搜索',
      iframe: 'iframe',
      tabs: '标签页',
      group: '分组',
      menubar: '菜单栏',
      mainsearch: '搜索'
    }
    if (!type) {
      options = ['tabs', 'timeline', 'datacard', 'doublecard', 'propcard', 'cardatacard', 'carpropcard', 'simpleform', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'editor', 'pie', 'scatter', 'iframe', 'sandbox']
      if (appType === 'mob') {
        options.push('menubar', 'singleSearch')
        if (sessionStorage.getItem('editMenuType') !== 'popview') {
          options.push('topbar')
        }
      } else {
        options.push('editable', 'mainsearch', 'antvG6', 'antvX6', 'calendar', 'tree', 'dashboard', 'chart')
      }
    } else {
      options.push('editable', 'mainsearch', 'antvG6', 'antvX6', 'calendar', 'tree', 'dashboard', 'chart')
      if (appType === 'mob') {
        options = ['balcony', 'datacard', 'doublecard', 'propcard', 'tablecard', 'cardatacard', 'carpropcard', 'line', 'pie', 'scatter', 'sandbox', 'editor', 'simpleform', 'stepform', 'tabform', 'normaltable', 'timeline']
        if (type === 'tabs') {
          options.push('tabs', 'group', 'menubar')
        }
      } else {
        options = ['calendar', 'balcony', 'datacard', 'doublecard', 'propcard', 'tablecard', 'cardatacard', 'carpropcard', 'line', 'dashboard', 'antvG6', 'pie', 'scatter', 'antvX6', 'chart', 'sandbox', 'editor', 'simpleform', 'stepform', 'tabform', 'editable', 'normaltable', 'timeline', 'tree']
        if (type === 'tabs') {
          options.push('tabs', 'group', 'mainsearch')
        }
      }
    }
    this.pasteFormRef.handleConfirm().then(res => {
      if (res.copyType === 'basetable') {
        res.copyType = 'normaltable'
        res.subtype = 'normaltable'
      }
      if (!options.includes(res.copyType)) {
      if (!res.copyType) {
        notification.warning({
          top: 92,
          message: '配置信息格式错误!',
@@ -80,22 +286,116 @@
        return
      }
      res = this.resetconfig(res, appType)
      if (res.copyType === 'basetable') {
        res.copyType = 'normaltable'
        res.subtype = 'normaltable'
      }
      // delete res.copyType
      let menu = fromJS(window.GLOB.customMenu).toJS()
      if (!options.includes(res.copyType)) {
        if (type && types[res.copyType]) {
          notification.warning({
            top: 92,
            message: (type === 'group' ? '分组中' : '标签页中') + '不可添加《' + types[res.copyType] + '》组件!',
            duration: 5
          })
          return
        } else {
          notification.warning({
            top: 92,
            message: '配置信息格式错误!',
            duration: 5
          })
        }
        return
      } else if (appType === 'mob') {
        if (res.type === 'search') {
          if (menu.components.filter(card => card.type === 'topbar' && card.wrap.type !== 'navbar').length > 0) {
            notification.warning({
              top: 92,
              message: '导航栏使用了搜索,不可添加搜索组件!',
              duration: 5
            })
            return
          }
          if (menu.components.filter(card => card.type === 'search').length > 0) {
            notification.warning({
              top: 92,
              message: '搜索条件不可重复添加!',
              duration: 5
            })
            return
          }
        } else if (res.type === 'topbar') {
          if (menu.components.findIndex(m => m.type === 'topbar') > -1) {
            notification.warning({
              top: 92,
              message: '导航栏不可重复添加!',
              duration: 5
            })
            return
          }
        }
      } else if (res.type === 'search') {
        if (tab) {
          if (tab.components.findIndex(card => card.type === 'search') > -1) {
            notification.warning({
              top: 92,
              message: '搜索条件不可重复添加!',
              duration: 5
            })
            return
          }
        } else {
          if (menu.components.findIndex(m => m.type === 'search') > -1) {
            notification.warning({
              top: 92,
              message: '搜索条件不可重复添加!',
              duration: 5
            })
            return
          }
        }
      }
      delete res.copyType
      let commonId = MenuUtils.getuuid()
      res = this.resetconfig(res, appType, commonId)
      if (tab) {
        this.resetmenu(menu.components, tab.uuid, res)
      } else {
        menu.components.push(res)
      }
      this.modules = {}
      this.getModules(menu.components, menu.interfaces)
      this.resetlink(res, commonId)
      
      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 (
      <>
        <Button style={{borderColor: '#40a9ff', color: '#40a9ff'}} onClick={() => {this.setState({visible: true})}}><SnippetsOutlined />粘贴</Button>
        {type ? <SnippetsOutlined style={{color: 'purple'}} onClick={() => {this.setState({visible: true})}} /> :
        <Button style={{borderColor: '#40a9ff', color: '#40a9ff'}} onClick={() => {this.setState({visible: true})}}><SnippetsOutlined />粘贴</Button>}
        <Modal
          title="粘贴"
          visible={visible}
src/mob/components/tabs/antv-tabs/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Tabs, Popover, Modal, notification } from 'antd'
import { Tabs, Popover, Modal } from 'antd'
import { ToolOutlined, PlusOutlined, EditOutlined, FontColorsOutlined, DeleteOutlined, CloseOutlined } from '@ant-design/icons'
import MKEmitter from '@/utils/events.js'
@@ -16,7 +16,7 @@
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const PasteComponent = asyncIconComponent(() => import('@/menu/components/tabs/paste'))
const PasteController = asyncIconComponent(() => import('@/menu/pastecontroller'))
const TabComponents = asyncComponent(() => import('../tabcomponents'))
const { TabPane } = Tabs
@@ -203,20 +203,11 @@
    this.props.updateConfig(tabs)
  }
  insert = (item, tab) => {
  insert = (item, tabId) => {
    let tabs = fromJS(this.state.tabs).toJS()
    if (item.type === 'search') {
      notification.warning({
        top: 92,
        message: '移动端搜索组件不可粘贴!',
        duration: 5
      })
      return
    }
    tabs.subtabs.forEach(stab => {
      if (stab.uuid === tab.uuid) {
      if (stab.uuid === tabId) {
        stab.components.push(item)
      }
    })
@@ -251,7 +242,7 @@
    editab.hide = res.hide || 'false'
    editab.backgroundColor = res.backgroundColor
    // editab.controlVal = res.controlVal || ''
    editab.selectVal = res.selectVal || ''
    // editab.selectVal = res.selectVal || ''
    editab.blacklist = res.blacklist
    if (editab.uuid) {
@@ -295,6 +286,17 @@
      delete res.controlVals
    }
    if (res.selectVals) {
      let values = {}
      res.selectVals.forEach(item => {
        values[item.uuid] = item.value
      })
      tabs.subtabs.forEach(tab => {
        tab.selectVal = values[tab.uuid]
      })
      delete res.selectVals
    }
    tabs.setting = res
@@ -321,7 +323,7 @@
                  <NormalForm title="标签编辑" width={800} update={this.updateTab} getForms={() => this.getTabForms(tab)}>
                    <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
                  </NormalForm>
                  <PasteComponent Tab={tab} insert={this.insert} />
                  <PasteController type="tabs" tab={tab} insert={(item) => this.insert(item, tab.uuid)} />
                  <FontColorsOutlined className="style" title="调整样式" onClick={this.changeTabStyle}/>
                  <CloseOutlined className="close" onClick={() => this.delTab(tab)} />
                </div>
src/mob/components/tabs/antv-tabs/options.jsx
@@ -41,14 +41,14 @@
    //   tooltip: '当禁用字段值与隐藏标记相等时,标签页会隐藏。注:多个值请用逗号分隔。',
    //   required: false
    // },
    {
      type: 'text',
      field: 'selectVal',
      label: '选中标记',
      initval: tab.selectVal || '',
      tooltip: '当选中字段值与选中标记相等时,标签页默认选中。',
      required: false
    },
    // {
    //   type: 'text',
    //   field: 'selectVal',
    //   label: '选中标记',
    //   initval: tab.selectVal || '',
    //   tooltip: '当选中字段值与选中标记相等时,标签页默认选中。',
    //   required: false
    // },
    {
      type: 'color',
      field: 'backgroundColor',
@@ -82,7 +82,8 @@
    label: '上一页(url参数)'
  })
  let controlVals = subtabs.map(item => ({uuid: item.uuid, label: item.label, value: item.controlVal}))
  let controlVals = subtabs.map(item => ({uuid: item.uuid, label: item.label, value: item.controlVal || ''}))
  let selectVals = subtabs.map(item => ({uuid: item.uuid, label: item.label, value: item.selectVal || ''}))
  const tabForm = [
    {
@@ -156,7 +157,10 @@
      label: '选中字段',
      initval: setting.selectField || '',
      tooltip: '用于控制标签页初始化选中,在标签中填入选中标记,注:数据源于url参数。',
      required: false
      required: false,
      controlFields: [
        {field: 'selectVals', notNull: true},
      ]
    },
    {
      type: 'color',
@@ -180,11 +184,11 @@
    {
      type: 'table',
      field: 'controlVals',
      label: '标签组',
      label: '标签组(禁用)',
      initval: controlVals,
      tooltip: '当禁用字段值与隐藏标记相等时,标签页会隐藏。注:1、多个值请用逗号分隔,2、@pass@值表示忽略此设置(始终显示),2、@pass_empty@值表示忽略空值,即未获取上级组件信息时显示(可与其他值拼接)。',
      required: false,
      fixed: true,
      actions: ['edit'],
      span: 24,
      columns: [
        {
@@ -203,6 +207,33 @@
          width: '50%'
        }
      ]
    },
    {
      type: 'table',
      field: 'selectVals',
      label: '标签组(选中)',
      initval: selectVals,
      tooltip: '当选中字段值与选中标记相等时,标签页默认选中。',
      required: false,
      actions: ['edit'],
      span: 24,
      columns: [
        {
          title: '标签名称',
          dataIndex: 'label',
          editable: false,
          required: false,
          width: '30%'
        },
        {
          title: '选中标记',
          dataIndex: 'value',
          inputType: 'input',
          editable: true,
          required: false,
          width: '50%'
        }
      ]
    }
  ]
src/mob/components/tabs/tabcomponents/index.jsx
@@ -80,7 +80,7 @@
    drop(item) {
      if (item.hasOwnProperty('originalIndex') || item.added) {
        return
      } else if (['login', 'navbar', 'topbar'].includes(item.component)) {
      } else if (['login', 'navbar', 'topbar', 'iframe', 'sharecode', 'officialAccount'].includes(item.component)) {
        return
      }
      
src/mob/components/topbar/normal-navbar/options.jsx
@@ -219,7 +219,7 @@
      initval: wrap.menus || [],
      required: false,
      span: 24,
      actions: ['view'],
      actions: ['edit', 'del', 'add', 'move', 'view'],
      tip: <span style={{fontSize: '12px', color: '#959595', position: 'relative', top: '-8px'}}>当使用图标<MkIcon type="user"/>,且右侧只有一个菜单时,会显示用户头像。</span>,
      columns: [
        {
src/pc/components/login/normal-login/options.jsx
@@ -232,6 +232,7 @@
      label: '协议组',
      initval: wrap.groups || [],
      required: true,
      actions: ['edit', 'del', 'add', 'move'],
      span: 24,
      columns: [
        {
src/tabviews/basetable/index.jsx
@@ -208,7 +208,7 @@
          }
        })
      }
      // 获取主搜索条件
      config.components.forEach(component => {
        if (component.type === 'tabs') return
@@ -484,7 +484,7 @@
    }
    if (cell.OpenType === 'excelOut') { // 导出
      cell.$menuName = item.name
      cell.$menuName = item.$menuname
      if (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0) {
        cell.errorType = 'error1'
src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -1010,148 +1010,114 @@
        if (card.wrapStyle) {
          _style_ = {..._style_, ...card.wrapStyle}
        }
        let MkButton = null
  
        if (['exec', 'prompt', 'pop', 'form'].includes(card.OpenType)) {
          contents.push(
            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
              <NormalButton
                btn={card}
                BID={data.$$BID}
                BData={data.$$BData || ''}
                disabled={_disabled}
                setting={cards.setting}
                columns={cards.columns}
                selectedData={_data}
              />
            </div>
          )
          MkButton = <NormalButton
            btn={card}
            BID={data.$$BID}
            BData={data.$$BData || ''}
            disabled={_disabled}
            setting={cards.setting}
            columns={cards.columns}
            selectedData={_data}
          />
        } else if (card.OpenType === 'excelIn') {
          contents.push(
            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
              <ExcelInButton
                btn={card}
                BID={data.$$BID}
                BData={data.$$BData || ''}
                disabled={_disabled}
                setting={cards.setting}
                selectedData={_data}
              />
            </div>
          )
          MkButton = <ExcelInButton
            btn={card}
            BID={data.$$BID}
            BData={data.$$BData || ''}
            disabled={_disabled}
            setting={cards.setting}
            selectedData={_data}
          />
        } else if (card.OpenType === 'excelOut') {
          contents.push(
            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
              <ExcelOutButton
                btn={card}
                BID={data.$$BID}
                BData={data.$$BData || ''}
                disabled={_disabled}
                setting={cards.setting}
                selectedData={_data}
              />
            </div>
          )
          MkButton = <ExcelOutButton
            btn={card}
            BID={data.$$BID}
            BData={data.$$BData || ''}
            disabled={_disabled}
            setting={cards.setting}
            selectedData={_data}
          />
        } else if (card.OpenType === 'popview') {
          contents.push(
            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
              <PopupButton
                btn={card}
                BID={data.$$BID}
                BData={data.$$BData || ''}
                disabled={_disabled}
                setting={cards.setting}
                selectedData={_data}
              />
            </div>
          )
          MkButton = <PopupButton
            btn={card}
            BID={data.$$BID}
            BData={data.$$BData || ''}
            disabled={_disabled}
            setting={cards.setting}
            selectedData={_data}
          />
        } else if (card.OpenType === 'tab') {
          contents.push(
            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
              <TabButton
                btn={card}
                BID={data.$$BID}
                BData={data.$$BData || ''}
                disabled={_disabled}
                selectedData={_data}
              />
            </div>
          )
          MkButton = <TabButton
            btn={card}
            BID={data.$$BID}
            BData={data.$$BData || ''}
            disabled={_disabled}
            selectedData={_data}
          />
        } else if (card.OpenType === 'innerpage') {
          contents.push(
            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
              <NewPageButton
                btn={card}
                BID={data.$$BID}
                BData={data.$$BData || ''}
                disabled={_disabled}
                selectedData={_data}
              />
            </div>
          )
          MkButton = <NewPageButton
            btn={card}
            BID={data.$$BID}
            BData={data.$$BData || ''}
            disabled={_disabled}
            selectedData={_data}
          />
        } else if (card.OpenType === 'funcbutton') {
          if (card.funcType === 'changeuser' || card.funcType === 'closetab') {
            contents.push(
              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
                <ChangeUserButton
                  btn={card}
                  BID={data.$$BID}
                  BData={data.$$BData || ''}
                  disabled={_disabled}
                  setting={cards.setting}
                  selectedData={_data}
                />
              </div>
            )
            MkButton = <ChangeUserButton
              btn={card}
              BID={data.$$BID}
              BData={data.$$BData || ''}
              disabled={_disabled}
              setting={cards.setting}
              selectedData={_data}
            />
          } else if (card.funcType === 'print') {
            contents.push(
              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
                <PrintButton
                  btn={card}
                  BID={data.$$BID}
                  BData={data.$$BData || ''}
                  disabled={_disabled}
                  setting={cards.setting}
                  columns={cards.columns}
                  selectedData={_data}
                />
              </div>
            )
            MkButton = <PrintButton
              btn={card}
              BID={data.$$BID}
              BData={data.$$BData || ''}
              disabled={_disabled}
              setting={cards.setting}
              columns={cards.columns}
              selectedData={_data}
            />
          } else if (card.funcType === 'megvii') {
            contents.push(
              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
                <FuncMegvii
                  btn={card}
                  BID={data.$$BID}
                  disabled={_disabled}
                  setting={cards.setting}
                  selectedData={_data}
                />
              </div>
            )
            MkButton = <FuncMegvii
              btn={card}
              BID={data.$$BID}
              disabled={_disabled}
              setting={cards.setting}
              selectedData={_data}
            />
          } else if (card.funcType === 'filezip') {
            contents.push(
              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
                <FuncZip
                  btn={card}
                  BID={data.$$BID}
                  disabled={_disabled}
                  setting={cards.setting}
                  selectedData={_data}
                />
              </div>
            )
            MkButton = <FuncZip
              btn={card}
              BID={data.$$BID}
              disabled={_disabled}
              setting={cards.setting}
              selectedData={_data}
            />
          } else if (card.funcType === 'addline' || card.funcType === 'delline') {
            contents.push(
              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
                <EditLine
                  btn={card}
                  disabled={_disabled}
                  selectedData={_data}
                />
              </div>
            )
            MkButton = <EditLine
              btn={card}
              disabled={_disabled}
              selectedData={_data}
            />
          }
        }
        if (MkButton) {
          contents.push(
            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
              {MkButton}
            </div>
          )
        }
      }
    })
src/tabviews/custom/components/card/data-card/index.jsx
@@ -236,6 +236,8 @@
    }
    this.initExec()
    this.autoExec()
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -330,6 +332,25 @@
    }
  }
  autoExec = (times) => {
    const { config } = this.state
    if (!config.wrap.autoExec) return
    let btn = document.getElementById('button' + config.wrap.autoExec)
    this.autoTimer && clearTimeout(this.autoTimer)
    if (btn) {
      MKEmitter.emit('triggerBtnId', config.wrap.autoExec, [])
    } else if (!times || times < 20) {
      times = times ? times + 1 : 1
      this.autoTimer = setTimeout(() => {
        this.autoExec(times)
      }, 1000)
    }
  }
  transferSyncData = (syncId) => {
    const { config } = this.state
src/tabviews/custom/components/card/double-data-card/index.jsx
@@ -229,6 +229,8 @@
    if (config.setting.onload === 'true') {
      this.initExec()
    }
    this.autoExec()
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -319,6 +321,25 @@
      setTimeout(() => {
        this.loadData()
      }, config.setting.delay || 0)
    }
  }
  autoExec = (times) => {
    const { config } = this.state
    if (!config.wrap.autoExec) return
    let btn = document.getElementById('button' + config.wrap.autoExec)
    this.autoTimer && clearTimeout(this.autoTimer)
    if (btn) {
      MKEmitter.emit('triggerBtnId', config.wrap.autoExec, [])
    } else if (!times || times < 20) {
      times = times ? times + 1 : 1
      this.autoTimer = setTimeout(() => {
        this.autoExec(times)
      }, 1000)
    }
  }
@@ -1193,6 +1214,20 @@
                    subClass = opens.indexOf(item.key) > -1 ? 'mk-unfold' : 'mk-collapse'
                    unfold = opens.indexOf(item.key) > -1
                  }
                  if (!unfold && item.children.length > 5) {
                    return (
                      <Col key={index} span={card.setting.width} style={card.wStyle}>
                        <div className={className} style={wrapStyle}>
                          <CardItem card={card} cards={config} data={item} onDoubleClick={() => this.onDoubleClick(item.key, subClass)} onClick={() => {this.changeCard(item.key, item, subClass)}}>
                            <span className="circle-select"></span>
                            {card.setting.controlIcon === 'left' ? <PlusSquareOutlined className={subClass} onClick={(e) => this.changeUnfold(e, item.key, subClass)}/> : null}
                            {card.setting.controlIcon === 'right' ? <UpOutlined className={subClass} onClick={(e) => this.changeUnfold(e, item.key, subClass)}/> : null}
                          </CardItem>
                        </div>
                      </Col>
                    )
                  }
                }
                return (
src/tabviews/custom/components/card/prop-card/index.jsx
@@ -377,7 +377,7 @@
    let btn = document.getElementById('button' + config.wrap.autoExec)
    clearTimeout(this.autoTimer)
    this.autoTimer && clearTimeout(this.autoTimer)
    if (btn) {
      MKEmitter.emit('triggerBtnId', config.wrap.autoExec, data.$$empty ? [] : [data])
src/tabviews/custom/components/interfaces/interItem/index.jsx
@@ -124,6 +124,10 @@
    let searches = []
    if (config.setting.useMSearch) {
      searches = window.GLOB.SearchBox.get(config.$searchId) || []
      if (window.GLOB.SearchBox.has(config.$searchId + 'required') && searches.filter(item => item.required && item.value === '').length > 0) {
        return
      }
    }
    this.loading = true
src/tabviews/custom/components/table/base-table/index.jsx
@@ -606,6 +606,25 @@
    })
  }
  autoExec = (times) => {
    const { config } = this.state
    if (!config.wrap.autoExec) return
    let btn = document.getElementById('button' + config.wrap.autoExec)
    this.autoTimer && clearTimeout(this.autoTimer)
    if (btn) {
      MKEmitter.emit('triggerBtnId', config.wrap.autoExec, [])
    } else if (!times || times < 20) {
      times = times ? times + 1 : 1
      this.autoTimer = setTimeout(() => {
        this.autoExec(times)
      }, 1000)
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
@@ -621,6 +640,8 @@
    if (config.setting.useMSearch) {
      MKEmitter.addListener('searchRefresh', this.searchRefresh)
    }
    this.autoExec()
  }
  /**
src/tabviews/custom/components/table/normal-table/index.jsx
@@ -199,6 +199,8 @@
    }
    this.initExec()
    this.autoExec()
  }
  /**
@@ -301,6 +303,25 @@
    }
  }
  autoExec = (times) => {
    const { config } = this.state
    if (!config.wrap.autoExec) return
    let btn = document.getElementById('button' + config.wrap.autoExec)
    this.autoTimer && clearTimeout(this.autoTimer)
    if (btn) {
      MKEmitter.emit('triggerBtnId', config.wrap.autoExec, [])
    } else if (!times || times < 20) {
      times = times ? times + 1 : 1
      this.autoTimer = setTimeout(() => {
        this.autoExec(times)
      }, 1000)
    }
  }
  transferSyncData = (syncId) => {
    const { config } = this.state
src/tabviews/custom/index.jsx
@@ -249,7 +249,7 @@
      let initInters = []
      config.interfaces = this.formatInterSetting(config.interfaces, regs, MenuID, initInters)
      config.interfaces = this.formatInterSetting(config.interfaces, regs, MenuID, initInters, config.MenuName)
      config.components = this.filterComponent(config.components, roleId, window.GLOB.mkActions, balMap, skip, param, MenuID, config.interfaces, config.$cache, config.$time, config.MenuName, MenuID, MenuID, config.process === 'true')
      let params = []
@@ -887,7 +887,7 @@
    }
    if (cell.OpenType === 'excelOut') { // 导出
      cell.$menuName = item.name
      cell.$menuName = item.$menuname
      if (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0) {
        cell.errorType = 'error1'
@@ -1175,7 +1175,7 @@
  }
  // 格式化默认设置
  formatInterSetting = (inters, regs, MenuID, initInters) => {
  formatInterSetting = (inters, regs, MenuID, initInters, MenuName) => {
    if (!inters) return []
    let initlimit = false
@@ -1233,7 +1233,7 @@
      })
      delete inter.scripts
      inter.setting.$name = '公共数据源-' + inter.setting.name
      inter.setting.$name = (MenuName || '') + '-公共数据源-' + inter.setting.name
      inter.setting.execute = inter.setting.execute !== 'false'
      if (!inter.setting.execute) {
src/tabviews/custom/popview/index.jsx
@@ -608,7 +608,7 @@
    }
    if (cell.OpenType === 'excelOut') { // 导出
      cell.$menuName = item.name
      cell.$menuName = item.$menuname
      if (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0) {
        cell.errorType = 'error1'
src/tabviews/rolemanage/index.jsx
@@ -356,7 +356,7 @@
  /**
   * @description 获取权限分配树
   */
  getTree = (parents, options) => {
  getTree = (parents, options, addSelf) => {
    parents.forEach(parent => {
      parent.children = []
@@ -367,7 +367,7 @@
            title: option.MenuName,
            key: option.MenuID,
            addSelf: option.OnlySelf === 'true',
            tabs: option.Tabs
            // tabs: option.Tabs
          })
        }
      })
@@ -375,13 +375,13 @@
      if (parent.children.length === 0) {
        parent.children = null
        // 针对标签,生成新的id,并保存关联关系(标签不唯一)
        if (parent.tabs) {
          let _uuid = Utils.getuuid()
          linkMap.set(_uuid, parent.key)
        // if (parent.tabs) {
        //   let _uuid = Utils.getuuid()
        //   linkMap.set(_uuid, parent.key)
          parent.originKey = parent.key
          parent.key = _uuid
        }
        //   parent.originKey = parent.key
        //   parent.key = _uuid
        // }
      } else {
        // 三级菜单创建子项
        if (parent.addSelf) {
@@ -392,20 +392,29 @@
          parent.children.unshift({
            title: parent.title + '(仅页面)',
            key: _uuid,
            isSubView: true
            // isSubView: true
          })
        } else if (addSelf) {
          let _uuid = Utils.getuuid()
          linkMap.set(_uuid, parent.key)
          parent.subKey = _uuid
          parent.children.unshift({
            title: parent.title + '(表格)',
            key: _uuid,
          })
        }
        // 针对标签,生成新的id,并保存关联关系(标签不唯一)
        if (parent.tabs) {
          let _uuid = Utils.getuuid()
          linkMap.set(_uuid, parent.key)
        // if (parent.tabs) {
        //   let _uuid = Utils.getuuid()
        //   linkMap.set(_uuid, parent.key)
          
          parent.originKey = parent.key
          parent.key = _uuid
        }
        //   parent.originKey = parent.key
        //   parent.key = _uuid
        // }
        parent.children = this.getTree(parent.children, options)
        parent.children = this.getTree(parent.children, options, parent.addSelf)
      }
    })
    return parents
@@ -442,8 +451,8 @@
          }
        }
        return true
      } else if (parent.isSubView) {
        return true
      // } else if (parent.isSubView) {
      //   return true
      }
      return false
    })
src/tabviews/subtable/index.jsx
@@ -88,7 +88,6 @@
        config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
        config.setting.MenuName = Tab.label
        config.setting.$name = Tab.label
        config.setting.foreignKey = Tab.foreignKey || ''
        config.setting.supModule = Tab.supMenu || ''
        config.setting.ContainerId = Tab.ContainerId || ''
      } catch (e) {
src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -582,6 +582,7 @@
    return <>
      <Button
        type={type}
        id={'button' + btn.uuid}
        title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
        loading={loading}
        disabled={disabled}
src/tabviews/zshare/mutilform/index.jsx
@@ -1243,9 +1243,9 @@
          className = 'checkcard'
          content = (<MKCheckCard config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)}/>)
        } else if (item.type === 'switch') {
          content = (<MKSwitch config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)}/>)
          content = (<MKSwitch config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)} onSubmit={this.props.inputSubmit}/>)
        } else if (item.type === 'check') {
          content = (<MKCheck config={item} onChange={(val) => this.recordChange({[item.field]: val}, item)}/>)
          content = (<MKCheck config={item} onChange={(val) => this.recordChange({[item.field]: val}, item)} onSubmit={this.props.inputSubmit}/>)
        } else if (item.type === 'checkbox') {
          content = (<MKCheckbox config={item} onChange={(val) => this.recordChange({[item.field]: val})}/>)
        } else if (item.type === 'radio') {
src/tabviews/zshare/mutilform/mkCheck/index.jsx
@@ -2,6 +2,8 @@
import PropTypes from 'prop-types'
import { Checkbox } from 'antd'
import MKEmitter from '@/utils/events.js'
class MKCheck extends Component {
  static propTpyes = {
    config: PropTypes.object,
@@ -20,6 +22,21 @@
    } else {
      this.props.onChange(config.closeVal)
    }
    this.setState({}, () => {
      if (config.enter === 'tab') {
        MKEmitter.emit('mkFC', 'focus', config.tabUuid)
      } else if (config.enter === 'sub') {
        config.tabUuid && MKEmitter.emit('mkFC', 'focus', config.tabUuid)
        if (config.linkFields || config.subFields || config.controlFields) {
          setTimeout(() => {
            this.props.onSubmit(config.tabUuid)
          }, 1000)
        } else {
          this.props.onSubmit(config.tabUuid)
        }
      }
    })
  }
  componentWillUnmount () {
src/tabviews/zshare/mutilform/mkSwitch/index.jsx
@@ -33,6 +33,21 @@
    } else {
      this.props.onChange(config.closeVal, other)
    }
    this.setState({}, () => {
      if (config.enter === 'tab') {
        MKEmitter.emit('mkFC', 'focus', config.tabUuid)
      } else if (config.enter === 'sub') {
        config.tabUuid && MKEmitter.emit('mkFC', 'focus', config.tabUuid)
        if (config.linkFields || config.subFields || config.controlFields) {
          setTimeout(() => {
            this.props.onSubmit(config.tabUuid)
          }, 1000)
        } else {
          this.props.onSubmit(config.tabUuid)
        }
      }
    })
  }
  componentWillUnmount () {
src/templates/sharecomponent/actioncomponent/actionform/index.jsx
@@ -302,17 +302,10 @@
        }
      } else if (_funcType === 'closetab') {
        shows.push('refreshTab')
      } else if (_funcType === 'megvii') {
        shows.push('subFunc', 'progress')
      } else if (_funcType === 'refund') {
        shows.push('Ot', 'execSuccess', 'execError')
        reOptions.Ot = requireOptions.filter(op => op.value === 'requiredSgl')
      } else if (_funcType === 'filezip') {
        reOptions.Ot = requireOptions
        reRequired.innerFunc = false
        shows.push('innerFunc', 'Ot', 'execSuccess', 'execError', 'urlkey')
      }
    }
src/templates/sharecomponent/actioncomponent/formconfig.jsx
@@ -119,12 +119,6 @@
      }, {
        value: 'closetab',
        text: '标签关闭'
      }, {
        value: 'megvii',
        text: '旷视面板机'
      }, {
        value: 'filezip',
        text: '文件压缩包'
      }]
    },
    { // 旷视面板机接口 待扩展
src/templates/sharecomponent/actioncomponent/verifyexcelin/columnform/index.jsx
@@ -78,6 +78,10 @@
                  {
                    required: true,
                    message: '请输入字段!'
                  },
                  {
                    pattern: /^[\u4E00-\u9FA50-9a-zA-Z_]*$/ig,
                    message: '只允许包含数字、字母、汉字以及_'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleConfirm}/>)}
@@ -135,7 +139,7 @@
              )}
            </Form.Item>
          </Col>
          <Col span={6}>
          <Col span={6} style={{clear: 'left'}}>
            <Form.Item style={{marginBottom: 0}} label="导入">
              {getFieldDecorator('import', {
                initialValue: 'true'
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -59,6 +59,7 @@
        width: '15%',
        editable: true,
        inputType: 'select',
        keyCol: true,
        options: [
          { value: 'Nvarchar(10)', text: 'Nvarchar(10)' },
          { value: 'Nvarchar(20)', text: 'Nvarchar(20)' },
@@ -114,7 +115,10 @@
        required: false,
        inputType: 'number',
        unlimit: true,
        editable: true
        editable: true,
        keyVals: ['Int', 'Decimal(18,0)', 'Decimal(18,2)', 'Decimal(18,4)', 'Decimal(18,6)'],
        render: (text, record) => /^Decimal/ig.test(record.type) || /^int/ig.test(record.type) ? text : ''
      },
      {
        title: '最大值',
@@ -123,7 +127,9 @@
        required: false,
        inputType: 'number',
        unlimit: true,
        editable: true
        editable: true,
        keyVals: ['Int', 'Decimal(18,0)', 'Decimal(18,2)', 'Decimal(18,4)', 'Decimal(18,6)'],
        render: (text, record) => /^Decimal/ig.test(record.type) || /^int/ig.test(record.type) ? text : ''
      }
    ],
    uniqueColumns: [
@@ -447,6 +453,8 @@
      confirm({
        content: '部分字段名称与显示列不一致,是否更新?',
        okText: '更新',
        cancelText: '不更新',
        onOk() {
          _columns = _columns.map(item => {
            let key = item.Column.toLowerCase()
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.scss
@@ -76,6 +76,9 @@
        width: 89.5%;
      }
    }
    .ant-form-explain {
      white-space: nowrap;
    }
  }
  .custom-table .ant-empty {
    margin: 20px 8px!important;
src/templates/sharecomponent/actioncomponent/verifyexcelout/columnform/index.jsx
@@ -46,6 +46,10 @@
                  {
                    required: true,
                    message: '请输入字段!'
                  },
                  {
                    pattern: /^[\u4E00-\u9FA50-9a-zA-Z_]*$/ig,
                    message: '只允许包含数字、字母、汉字以及_'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleConfirm}/>)}
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -67,6 +67,7 @@
        inputType: 'select',
        editable: true,
        required: false,
        keyCol: true,
        width: '12%',
        render: (text) => {
          if (text === 'image') {
@@ -82,38 +83,6 @@
          {value: 'number', text: '数值'},
          {value: 'image', text: '图片'}
        ]
      },
      {
        title: '取绝对值',
        dataIndex: 'abs',
        inputType: 'radio',
        editable: true,
        required: false,
        width: '12%',
        render: (text, record) => {
          if (record.type !== 'number') return ''
          if (text === 'true') {
            return '是'
          } else {
            return '否'
          }
        },
        options: [
          {value: 'true', text: '是'},
          {value: 'false', text: '否'}
        ]
      },
      {
        title: '小数位',
        dataIndex: 'decimal',
        inputType: 'number',
        min: 0,
        max: 18,
        editable: true,
        required: false,
        width: '12%',
        render: (text, record) => record.type === 'number' ? text : ''
      },
      {
        title: '导出',
@@ -146,6 +115,40 @@
          {value: 'false', text: '否'}
        ]
      },
      {
        title: '取绝对值',
        dataIndex: 'abs',
        inputType: 'radio',
        editable: true,
        required: false,
        keyVals: ['number'],
        width: '12%',
        render: (text, record) => {
          if (record.type !== 'number') return ''
          if (text === 'true') {
            return '是'
          } else {
            return '否'
          }
        },
        options: [
          {value: 'true', text: '是'},
          {value: 'false', text: '否'}
        ]
      },
      {
        title: '小数位',
        dataIndex: 'decimal',
        inputType: 'number',
        min: 0,
        max: 18,
        editable: true,
        required: false,
        keyVals: ['number'],
        width: '12%',
        render: (text, record) => record.type === 'number' ? text : ''
      }
    ],
    scriptsColumns: [
      {
@@ -528,6 +531,13 @@
      if (card.intertype === 'system' && verify.dataType !== 'custom' && verify.columns.length > 0 && config.$c_ds && config.setting.interType === 'system' && config.columns && config.columns.length > 0) {
        let cols = []
        let columns = config.columns.map(c => c.field)
        if (config.subtype === 'dualdatacard' && config.subColumns) {
          config.subColumns.forEach(item => {
            columns.push(item.field)
          })
        }
        verify.columns.forEach(col => {
          if (col.output === 'false' || col.Column === '$Index') return
          if (!columns.includes(col.Column)) {
@@ -710,6 +720,8 @@
      confirm({
        content: '部分字段名称与显示列不一致,是否更新?',
        okText: '更新',
        cancelText: '不更新',
        onOk() {
          columns = columns.map(item => {
            let key = item.Column.toLowerCase()
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.scss
@@ -79,6 +79,9 @@
    .add {
      padding-top: 4px;
    }
    .ant-form-explain {
      white-space: nowrap;
    }
  }
  .custom-table .ant-empty {
    margin: 20px 8px!important;
src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
@@ -399,12 +399,16 @@
  }
  changeTemplate = (val) => {
    const { templates } = this.state
    const { templates, verify } = this.state
    let temp = templates.filter(temp => temp.value === val)[0]
    this.setState({
      selectimg: temp.img
      selectimg: temp.img,
      verify: {
        ...verify,
        Template: val
      }
    })
  }
@@ -854,7 +858,19 @@
                  </Form.Item>
                </Col> : null}
                {printMode !== 'custom' ? <Col span={8}>
                  <Form.Item label="打印模板">
                  <Form.Item label="打印模板" help={(() => {
                      if (verify.Template) {
                        return <span onClick={() => {
                          sessionStorage.setItem('mk-print-tab-temp', verify.Template)
                          window.open('#/hs')
                          setTimeout(() => {
                            sessionStorage.removeItem('mk-print-tab-temp')
                          }, 50)
                        }} style={{color: '#1890ff', cursor: 'pointer', fontSize: '13px'}}>#查看模板</span>
                      }
                      return null
                    })()}>
                    {getFieldDecorator('Template', {
                      initialValue: verify.Template || '',
                      rules: [
src/templates/sharecomponent/cardcomponent/formconfig.jsx
@@ -48,14 +48,14 @@
      required: false,
      options: equalTabs
    },
    {
      type: 'text',
      key: 'foreignKey',
      label: '外键',
      tooltip: '外键旨在标签页中执行默认函数(添加)时,替换BID字段',
      initVal: card.foreignKey || '',
      required: false
    },
    // {
    //   type: 'text',
    //   key: 'foreignKey',
    //   label: '外键',
    //   tooltip: '外键旨在标签页中执行默认函数(添加)时,替换BID字段',
    //   initVal: card.foreignKey || '',
    //   required: false
    // },
    {
      type: 'number',
      key: 'level',
src/templates/sharecomponent/tabscomponent/formconfig.jsx
@@ -48,14 +48,14 @@
      required: false,
      options: equalTabs
    },
    {
      type: 'text',
      key: 'foreignKey',
      label: '外键',
      tooltip: '外键旨在标签页中执行默认函数(添加)时,替换BID字段',
      initVal: card.foreignKey || '',
      required: false
    },
    // {
    //   type: 'text',
    //   key: 'foreignKey',
    //   label: '外键',
    //   tooltip: '外键旨在标签页中执行默认函数(添加)时,替换BID字段',
    //   initVal: card.foreignKey || '',
    //   required: false
    // },
    {
      type: 'number',
      key: 'level',
src/templates/sharecomponent/tabscomponent/tabform/index.jsx
@@ -117,12 +117,6 @@
      if (item.type === 'text') {
        let rules = []
        if (item.key === 'foreignKey') {
          rules.push({
            pattern: /^[a-zA-Z_]*$/ig,
            message: item.label + '字段只允许包含字母及下划线!'
          })
        }
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={
src/templates/zshare/editTable/index.jsx
@@ -3,7 +3,7 @@
import { is, fromJS } from 'immutable'
import { DndProvider, DragSource, DropTarget } from 'react-dnd'
import { Table, Input, InputNumber, Popconfirm, Switch, Form, Select, Radio, Cascader, notification, message, Modal, Typography } from 'antd'
import { CopyOutlined, EditOutlined, DeleteOutlined, SwapOutlined, PlusOutlined } from '@ant-design/icons'
import { CopyOutlined, EditOutlined, DeleteOutlined, SwapOutlined, PlusOutlined, ConsoleSqlOutlined } from '@ant-design/icons'
import Utils from '@/utils/utils.js'
import ColorSketch from '@/mob/colorsketch'
@@ -123,7 +123,7 @@
class EditableCell extends Component {
  getInput = (form) => {
    const { inputType, options, min, max, unlimit, allowClear } = this.props
    const { inputType, options, min, max, unlimit, allowClear, typeChange } = this.props
    if (inputType === 'number' && unlimit) {
      return <InputNumber onPressEnter={() => this.getValue(form)} />
@@ -137,7 +137,7 @@
      return <CusSwitch />
    } else if (inputType === 'select') {
      return (
        <Select>
        <Select onChange={typeChange}>
          {options.map((item, i) => (<Select.Option key={i} value={item.field || item.value}> {item.label || item.text} </Select.Option>))}
        </Select>
      )
@@ -176,11 +176,18 @@
  renderCell = (form) => {
    const { getFieldDecorator } = form
    const { editing, dataIndex, title, record, children, className, required, inputType, rules } = this.props
    const { editing, pass, dataIndex, title, record, children, className, required, inputType, rules } = this.props
    if (!editing) {
      return (
        <td className={className}>
          {children}
        </td>
      )
    }
    return (
      <td className={className}>
        {editing ? (
        {pass ? (
          <Form.Item style={{ margin: 0 }}>
            {getFieldDecorator(dataIndex, {
              rules: [
@@ -194,7 +201,7 @@
            })(this.getInput(form))}
          </Form.Item>
        ) : (
          children
          null
        )}
      </td>
    )
@@ -218,7 +225,9 @@
    data: [],
    editingKey: '',
    editLineId: '',
    columns: []
    columns: [],
    keyCol: null,
    keyVal: ''
  }
  UNSAFE_componentWillMount () {
@@ -226,6 +235,7 @@
    let columns = fromJS(this.props.columns).toJS()
    let operation = null
    let extra = null
    let keyCol = null
    
    if (actions) {
      actions.forEach(item => {
@@ -237,9 +247,17 @@
    if (actions && (actions.includes('edit') || actions.includes('copy') || actions.includes('del'))) {
      let _operation = null
      let render = null
      columns = columns.filter(item => {
        if (item.dataIndex === 'operation') {
          _operation = item
        }
        if (item.keyCol) {
          keyCol = item.dataIndex
        }
        if (item.dataIndex === 'sqlRender') {
          render = item.render
          return false
        }
        return item.dataIndex !== 'operation'
      })
@@ -271,7 +289,7 @@
            </div>
          ) : (
            <div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')} style={{minWidth: '110px', whiteSpace: 'nowrap'}}>
              {actions.includes('edit') ? <span className="primary" title="编辑" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><EditOutlined /></span> : null}
              {actions.includes('edit') ? <span className="primary" title="编辑" onClick={() => {editingKey === '' && this.edit(record)}}><EditOutlined /></span> : null}
              {extra ? <span className="status" title={extra[2]} onClick={() => {editingKey === '' && this.handleStatus(record, extra[1])}}><SwapOutlined /></span> : null}
              {actions.includes('status') ? <span className="status" title="是否启用" onClick={() => {editingKey === '' && this.handleStatus(record, 'status')}}><SwapOutlined /></span> : null}
              {actions.includes('copy') ? <span className="copy" title="复制" onClick={() => {editingKey === '' && this.copy(record)}}><CopyOutlined /></span> : null}
@@ -279,10 +297,11 @@
                overlayClassName="popover-confirm"
                title="确定删除吗?"
                onConfirm={() => this.handleDelete(record.uuid)
              }>
                }>
                <span className="danger"><DeleteOutlined /></span>
              </Popconfirm> : null}
              {actions.includes('del') && editingKey !== '' ? <span className="danger"><DeleteOutlined /></span> : null}
              {actions.includes('sql') ? <span className="primary" title="SQL" onClick={() => {editingKey === '' && this.showSql(record, render)}}><ConsoleSqlOutlined /></span> : null}
            </div>
          )
        }
@@ -298,7 +317,8 @@
    this.setState({
      data: data || [],
      operation,
      columns
      columns,
      keyCol
    })
  }
@@ -338,6 +358,20 @@
      return
    }
    MKEmitter.removeListener('editLineId', this.getEditLineId)
  }
  showSql = (record, render) => {
    let list = render(record)
    if (list) {
      Modal.info({
        title: '',
        width: 500,
        className: 'sql-example',
        icon: null,
        content: list.map((n, index) => <div key={index} dangerouslySetInnerHTML={{ __html: n }}></div>)
      })
    }
  }
  getEditLineId = (id) => {
@@ -719,8 +753,14 @@
    })
  }
  edit(uuid) {
    this.setState({ editingKey: uuid })
  edit(record) {
    const { keyCol } = this.state
    this.setState({ editingKey: record.uuid, keyVal: keyCol ? record[keyCol] : '' })
  }
  typeChange = (val) => {
    this.setState({ keyVal: val })
  }
  moveRow = (dragIndex, hoverIndex) => {
@@ -771,7 +811,7 @@
  render() {
    const { actions, indexShow, searchKey } = this.props
    const { editLineId } = this.state
    const { editLineId, keyVal } = this.state
    let components = {
      body: {
@@ -790,7 +830,9 @@
      if (col.copy) {
        col.render = (text) => (<Paragraph copyable>{text}</Paragraph>)
      }
      if (!col.editable) return col
      return {
        ...col,
        onCell: record => ({
@@ -804,9 +846,12 @@
          unlimit: col.unlimit,
          required: col.required !== false ? true : false,
          allowClear: col.allowClear === true,
          keyCol: col.keyCol === true,
          title: col.title,
          editing: this.isEditing(record),
          pass: col.keyVals ? col.keyVals.includes(keyVal) : true,
          onSave: this.onSave,
          typeChange: this.typeChange,
        }),
      }
    })
src/templates/zshare/editTable/index.scss
@@ -127,3 +127,10 @@
  }
}
.ant-modal.ant-modal-confirm.ant-modal-confirm-info.sql-example {
  top: 100px;
  .ant-modal-body {
    padding: 24px;
  }
}
src/templates/zshare/formconfig.jsx
@@ -2331,6 +2331,23 @@
    },
    {
      type: 'radio',
      key: 'mkfocus',
      label: '聚焦时',
      initVal: card.mkfocus || 'def',
      options: [{
        value: 'def',
        text: '默认'
      }, {
        value: 'check',
        text: '全选'
      }, {
        value: 'clear',
        text: '清空'
      }],
      forbid: appType !== 'mob'
    },
    {
      type: 'radio',
      key: 'sendType',
      label: '发送方式',
      initVal: card.sendType || 'local',
@@ -2535,7 +2552,7 @@
      key: 'enter',
      label: '回车事件',
      initVal: (card.type === 'text' || card.type === 'number') ? (card.enter || 'sub') : (card.enter || 'false'),
      tooltip: '点击Enter键,或文本类表单输入回车符。',
      tooltip: '1、点击Enter键或文本类表单输入回车符;2、下拉选择或开关的选项切换。',
      options: [{
        value: 'sub',
        text: '提交'
src/templates/zshare/modalform/index.jsx
@@ -20,8 +20,8 @@
const MkEditIcon = asyncComponent(() => import('@/components/mkIcon'))
const modalTypeOptions = {
  text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'span', 'labelwidth', 'encryption', 'tooltip', 'extra', 'enter', 'cursor', 'scan', 'splitline', 'placeholder', 'place', 'marginTop', 'marginBottom', 'lenControl', 'inputType', 'constant'],
  number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'splitline', 'place', 'marginTop', 'marginBottom'],
  text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'span', 'labelwidth', 'encryption', 'tooltip', 'extra', 'enter', 'cursor', 'scan', 'splitline', 'placeholder', 'place', 'marginTop', 'marginBottom', 'lenControl', 'inputType', 'constant', 'mkfocus'],
  number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'splitline', 'place', 'marginTop', 'marginBottom', 'mkfocus'],
  select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom', 'pickerMode'],
  checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'splitline', 'arrange', 'marginTop', 'marginBottom'],
  radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'splitline', 'arrange', 'marginTop', 'marginBottom'],
@@ -29,8 +29,8 @@
  multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'marginTop', 'marginBottom', 'dropdown'],
  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'linkField', 'linkSubField', 'span', 'place', 'labelwidth', 'tooltip', 'extra', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom', 'pickerMode'],
  fileupload: ['readonly', 'required', 'hidden', 'readin', 'fieldlength', 'maxfile', 'fileType', 'span', 'labelwidth', 'linkSubField', 'tooltip', 'extra', 'compress', 'miniSet', 'splitline', 'marginTop', 'marginBottom', 'maxSize'],
  switch: ['initval', 'openVal', 'closeVal', 'openText', 'closeText', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'linkSubField', 'tooltip', 'extra', 'splitline', 'marginTop', 'marginBottom'],
  check: ['initval', 'openVal', 'closeVal', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'marginTop', 'marginBottom', 'checkTip'],
  switch: ['initval', 'openVal', 'closeVal', 'openText', 'closeText', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'linkSubField', 'tooltip', 'extra', 'enter', 'splitline', 'marginTop', 'marginBottom'],
  check: ['initval', 'openVal', 'closeVal', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'splitline', 'marginTop', 'marginBottom', 'checkTip'],
  date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'mode', 'splitline', 'place', 'marginTop', 'marginBottom', 'minDate', 'maxDate', 'precision'],
  datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'place', 'marginTop', 'marginBottom'],
  // datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'mode', 'splitline', 'marginTop', 'marginBottom', 'minDate', 'maxDate'],
@@ -254,6 +254,9 @@
        }
      }
    } else if (type === 'switch' || type === 'check') {
      if (this.record.enter === 'tab' || this.record.enter === 'sub') {
        shows.push('tabField')
      }
      reOptions.initval = [
        {value: true, text: '开'},
        {value: false, text: '关'}
src/templates/zshare/verifycard/index.jsx
@@ -2,7 +2,7 @@
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Form, Tabs, Row, Col, Button, Popconfirm, notification, Modal, message, InputNumber, Typography } from 'antd'
import { CheckCircleOutlined, StopOutlined, EditOutlined, SwapOutlined, DeleteOutlined, ExclamationOutlined } from '@ant-design/icons'
import { CheckCircleOutlined, StopOutlined, EditOutlined, SwapOutlined, DeleteOutlined, ExclamationOutlined, ConsoleSqlOutlined } from '@ant-design/icons'
import Toast from 'antd-mobile/es/components/toast'
import Dialog from 'antd-mobile/es/components/dialog'
import moment from 'moment'
@@ -18,7 +18,7 @@
import BillcodeForm from './billcodeform'
import VoucherForm from './voucherform'
import asyncComponent from '@/utils/asyncComponent'
import { updateForm } from '@/utils/utils-update.js'
// import { updateForm } from '@/utils/utils-update.js'
import MKEmitter from '@/utils/events.js'
import './index.scss'
@@ -114,6 +114,34 @@
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
      },
      {
        dataIndex: 'sqlRender',
        render: (record) => {
          let _fieldValue = []
          let _value = []
          let _labels = record.fieldlabel.split(',')
          record.field.split(',').forEach((_field, index) => {
            let _key = _field.toLowerCase()
            _fieldValue.push(`${_key}=${_key === 'bid' ? '@BID@' : ''}`)
            _value.push(`${_labels[index] || ''}:xxx`)
          })
          let _verifyType = ''
          if (record.verifyType === 'logic') {
            _verifyType = ' and deleted=0'
          }
          let sql = `select @tbid='', @ErrorCode='',@retmsg=''
          select @tbid='X' from ${this.props.card.sql} where ${_fieldValue.join(' and ')}${_verifyType}
          If @tbid!=''
          Begin
            select @ErrorCode='${record.errorCode}',@retmsg='${_value.join(', ')} 已存在'
            goto aaa
          end`
          return sql.split(/\n\s{10}/ig).map(n => n.replace(/^\s{2}/ig, '&nbsp;&nbsp;'))
        }
      }
    ],
    onceUniqueColumns: [
@@ -151,6 +179,27 @@
            </div>
          )
      },
      {
        dataIndex: 'sqlRender',
        render: (record) => {
          let primaryKey = 'id'
          if (this.props.config && this.props.config.setting && this.props.config.setting.primaryKey) {
            primaryKey = this.props.config.setting.primaryKey
          }
          let sql = `Set @tbid=''
          Select top 1 @tbid='X' from (select distinct ${record.field},1 as n from (数据源) tb inner join (select ID from  dbo.SplitComma(@ID@)) sp on tb.${primaryKey}=sp.ID ) a having sum(n)>1
          If @tbid!=''
          Begin
            Set @ErrorCode='E' Set @retmsg='${record.fieldlabel} 值不唯一'
            goto aaa
          end`
          return sql.split(/\n\s{10}/ig).map(n => n.replace(/^\s{2}/ig, '&nbsp;&nbsp;'))
        }
      }
    ],
    contrastColumns: [
      {
@@ -163,7 +212,7 @@
      {
        title: '运算符',
        dataIndex: 'operator',
        width: '14%',
        width: '13%',
        editable: true,
        inputType: 'select',
        options: [
@@ -187,14 +236,14 @@
      {
        title: '提示信息',
        dataIndex: 'errmsg',
        width: '14%',
        width: '13%',
        inputType: 'input',
        editable: true
      },
      {
        title: '报错编码',
        dataIndex: 'errorCode',
        width: '14%',
        width: '13%',
        editable: true,
        inputType: 'select',
        options: [
@@ -224,6 +273,18 @@
              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
            </div>
          )
      },
      {
        dataIndex: 'sqlRender',
        render: (record) => {
          let sql = `If ${record.frontfield} ${record.operator} ${record.backfield}
          Begin
            select @ErrorCode='${record.errorCode}',@retmsg='${record.errmsg}'
            goto aaa
          end`
          return sql.split(/\n\s{10}/ig).map(n => n.replace(/^\s{2}/ig, '&nbsp;&nbsp;'))
        }
      }
    ],
    customColumns: [
@@ -530,6 +591,7 @@
            }>
              <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span>
            </Popconfirm>
            <span className="operation-btn" title="SQL" onClick={() => this.orderSql(record)} style={{color: '#1890ff'}}><ConsoleSqlOutlined /></span>
          </div>)
      }
    ]
@@ -657,37 +719,37 @@
      } else if (card.modal && (card.OpenType === 'pop' || !card.OpenType)) {
        _fields = card.modal.fields || []
        resolve(_fields)
      } else if (card.OpenType === 'pop') {
        Api.getCloudConfig({
          func: 'sPC_Get_LongParam',
          MenuID: card.uuid
        }).then(res => {
          if (res.status) {
            let _LongParam = ''
            if (res.LongParam) {
              try {
                _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
              } catch (e) {
                console.warn('Parse Failure')
                _LongParam = ''
              }
            }
      // } else if (card.OpenType === 'pop') {
      //   Api.getCloudConfig({
      //     func: 'sPC_Get_LongParam',
      //     MenuID: card.uuid
      //   }).then(res => {
      //     if (res.status) {
      //       let _LongParam = ''
      //       if (res.LongParam) {
      //         try {
      //           _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
      //         } catch (e) {
      //           console.warn('Parse Failure')
      //           _LongParam = ''
      //         }
      //       }
            
            if (!_LongParam) {
              message.warning('未获取到表单信息,部分验证将无法设置!')
            } else {
              _LongParam = updateForm(_LongParam)
              _fields = _LongParam.fields || []
            }
          } else {
            notification.warning({
              top: 92,
              message: res.message,
              duration: 5
            })
          }
          resolve(_fields)
        })
      //       if (!_LongParam) {
      //         message.warning('未获取到表单信息,部分验证将无法设置!')
      //       } else {
      //         _LongParam = updateForm(_LongParam)
      //         _fields = _LongParam.fields || []
      //       }
      //     } else {
      //       notification.warning({
      //         top: 92,
      //         message: res.message,
      //         duration: 5
      //       })
      //     }
      //     resolve(_fields)
      //   })
      } else {
        resolve(_fields)
      }
@@ -752,6 +814,9 @@
          _select.push(`@${_f.field}='1949-10-01'`)
        } else if (_f.type === 'number') {
          _type = `decimal(18,${_fieldlen})`
          _select.push(`@${_f.field}=0`)
        } else if (_f.declare === 'decimal') {
          _type = `decimal(18,${_f.decimal || 0})`
          _select.push(`@${_f.field}=0`)
        } else if (_f.type === 'rate') {
          _type = `decimal(18,2)`
@@ -1131,6 +1196,45 @@
          duration: 5
        })
      }
    })
  }
  orderSql = (record) => {
    let _ModularDetailCode = ''
    let _lpline = ''
    if (record.TypeCharOne === 'Lp') {
      if (record.linkField.toLowerCase() === 'bid') {
        _lpline = `set @ModularDetailCode= 'Lp'+ right('${record.mark || this.props.card.uuid}'+@BID@,48)`
      } else {
        _lpline = `set @ModularDetailCode= 'Lp'+ right('${record.mark || this.props.card.uuid}'+@${record.linkField.toLowerCase()},48)`
      }
      _ModularDetailCode = '@ModularDetailCode'
    } else if (record.TypeCharOne === 'BN') {
      _ModularDetailCode = `'${record.TypeCharOne}'`
    } else {
      _ModularDetailCode = `'${record.ModularDetailCode}'`
    }
    let sql = `select @BillCode='', @${record.field}='', @ModularDetailCode=''
    ${_lpline}
    exec s_get_BillCode
      @ModularDetailCode=${_ModularDetailCode},
      @Type=${record.Type},
      @TypeCharOne='${record.TypeCharOne}',
      @TypeCharTwo ='${record.TypeCharTwo}',
      @BillCode =@BillCode output,
      @ErrorCode =@ErrorCode output,
      @retmsg=@retmsg output
    if @ErrorCode!=''
      goto aaa
    set @${record.field}=@BillCode`
    Modal.info({
      title: '',
      width: 500,
      className: 'sql-example',
      icon: null,
      content: sql.split(/\n\s{4}/ig).map((n, index) => <div key={index} dangerouslySetInnerHTML={{ __html: n.replace(/\s/ig, '&nbsp;') }} style={{whiteSpace: 'nowrap'}}></div>)
    })
  }
@@ -1603,7 +1707,7 @@
            </span>
          } key="contrasts">
            <ContrastForm contrastChange={this.contrastChange}/>
            <EditTable actions={['edit', 'move', 'copy', 'del', 'status']} type="contrastverify" data={verify.contrasts} columns={contrastColumns} onChange={(contrasts) => this.setState({verify: {...verify, contrasts}})}/>
            <EditTable actions={['edit', 'move', 'copy', 'del', 'status', 'sql']} type="contrastverify" data={verify.contrasts} columns={contrastColumns} onChange={(contrasts) => this.setState({verify: {...verify, contrasts}})}/>
          </TabPane> : null}
          {verifyInter === 'system' ? <TabPane tab={
            <span>
@@ -1649,7 +1753,7 @@
              fields={card.Ot !== 'requiredOnce' ? uniqueFields : columnsFields}
              uniqueChange={this.uniqueChange}
            />
            <EditTable actions={['edit', 'move', 'del', 'status']} data={verify.uniques} columns={card.Ot !== 'requiredOnce' ? uniqueColumns : onceUniqueColumns} onChange={this.changeUniques}/>
            <EditTable actions={['edit', 'move', 'del', 'status', 'sql']} data={verify.uniques} columns={card.Ot !== 'requiredOnce' ? uniqueColumns : onceUniqueColumns} onChange={this.changeUniques}/>
          </TabPane> : null}
          {verifyInter === 'system' ? <TabPane tab={
            <span>
src/templates/zshare/verifycard/index.scss
@@ -106,6 +106,14 @@
  }
}
.ant-modal.ant-modal-confirm.ant-modal-confirm-info.sql-example {
  top: 100px;
  .ant-modal-body {
    padding: 24px;
  }
}
@media screen and (max-width: 1500px) {
  .mk-verify-tabs {
    .ant-tabs-nav .ant-tabs-tab {
src/utils/utils-custom.js
@@ -6,7 +6,7 @@
   * @description 获取下级模块
   * @return {String}  selfId  当前组件id
   */
  static getSubModules (components, selfId, supId, has) {
  static getSubModules (components, selfId, supId, interfaces) {
    let modules = []
    components.forEach(item => {
      if (item.uuid === selfId || item.type === 'navbar') {
@@ -49,7 +49,7 @@
                type: 'tab',
                value: f_tab.uuid,
                label: f_tab.label,
                children: this.getSubModules(f_tab.components, selfId, supId, has)
                children: this.getSubModules(f_tab.components, selfId, supId)
              }
  
              if (subItem.children.length === 0) {
@@ -94,6 +94,15 @@
        }
      }
    })
    if (interfaces && interfaces.length > 0) {
      interfaces.forEach(item => {
        modules.push({
          value: item.uuid,
          label: item.name
        })
      })
    }
    return modules
  }
@@ -719,7 +728,7 @@
  * @description 重置组件配置
  * @return {String}  item 组件信息
  */
  static resetComponentConfig = (item, appType) => {
  static resetComponentConfig = (item, appType, commonId) => {
    if (item.type === 'navbar') {
      return item
    }
@@ -727,9 +736,6 @@
    if (item.subtype === 'tablecard') { // 兼容
      item.type = 'card'
    }
    item.uuid = this.getuuid()
    let commonId = this.getuuid()
    // 重置组件名称
    let sign = this.getSignName()
@@ -952,20 +958,6 @@
        cell.uuid = this.getuuid()
        return cell
      })
    }
    if (item.setting && item.setting.supModule && item.setting.supModule[0] !== 'empty') {
      item.setting.supModule = ''
    }
    if (item.wrap && item.wrap.supType === 'multi') {
      item.wrap.supType = 'single'
      delete item.supNodes
    }
    if (item.wrap && item.wrap.supModule) {
      item.wrap.supModule = ''
    }
    if (item.wrap && item.wrap.doubleClick) {
src/utils/utils.js
@@ -1403,7 +1403,6 @@
  let datavars = {}                 // 声明的变量,表单及显示列
  let _actionType = null
  let _callbacksql = ''
  let foreignKey = setting.foreignKey ? setting.foreignKey.toLowerCase() : ''
  if (verify.default !== 'false') { // 判断是否使用默认sql
    _actionType = btn.sqlType
@@ -1786,19 +1785,13 @@
      item.field.split(',').forEach((_field, index) => {
        let _key = _field.toLowerCase()
        let _val = datavars[_key] !== undefined ? datavars[_key] : ''
        let _fval = `'${_val}'`
        if (_key === 'bid' && !datavars.bid) { // 表单中没有bid则使用系统bid变量
          _fval = '@BID@'
        }
        if (_key === 'bid' && foreignKey) {
          arr.push(foreignKey)
          _fieldValue.push(`${foreignKey}=${_fval}`)
        } else {
          arr.push(_key)
          _fieldValue.push(`${_key}=${_fval}`)
        arr.push(_key)
        if (_key === 'bid' && !_val) { // 表单中没有bid则使用系统bid变量
          _val = BID
        }
        
        _fieldValue.push(`${_key}='${_val}'`)
        _value.push(`${_labels[index] || ''}:${_val || ''}`)
      })
@@ -1914,14 +1907,7 @@
      values.push('@fullname')
    }
    if (!keys.includes('bid')) {
      if (foreignKey && !keys.includes(foreignKey)) {
        keys.push(foreignKey)
      } else {
        keys.push('bid')
      }
      values.push('@BID@')
    } else if (foreignKey && !keys.includes(foreignKey)) {
      keys.push(foreignKey)
      keys.push('bid')
      values.push('@BID@')
    }
src/views/basedesign/updateFormTab/index.jsx
@@ -915,7 +915,7 @@
    let _card = {
      uuid: newCon.uuid,
      type: 'table',
      name: newCon.name,
      name: newCon.name || '',
      format: 'array',
      pageable: true,
      switchable: true,
@@ -923,7 +923,7 @@
      action: [],
      subtype: 'normaltable',
      setting: { useMSearch: 'false', sync: 'false', onload: 'true' },
      wrap: {name: newCon.name},
      wrap: {name: newCon.name || ''},
      style: {},
      headerStyle: {},
      columns: [],
src/views/billprint/index.jsx
@@ -325,7 +325,7 @@
        let initInters = []
        this.formatInterSetting(config.interfaces, regs, initInters, params, BID)
        this.formatInterSetting(config.interfaces, regs, initInters, params, BID, config.MenuName)
        config.components = config.components.map(component => {
          if (component.action) {
@@ -341,6 +341,8 @@
            component.$searches = []
          }
          component.data = [] // 初始化数据为空
          component.$menuname = (config.MenuName || '') + '-' + (component.name || '')
          if (component.subtype === 'tablecard') { // 兼容
            component.type = 'card'
@@ -466,6 +468,7 @@
          component.setting.arr_field = component.columns ? component.columns.map(col => col.field).join(',') : ''
          component.setting.laypage = false   // 是否分页,转为boolean 统一格式
          component.setting.$name = component.$menuname
          if (component.format === 'object') {
            component.setting.$top = true
@@ -539,7 +542,7 @@
          return component
        })
        _pars = this.getFormatParam(_pars)
        _pars = this.getFormatParam(_pars, config.MenuName)
        if (_pars) {
          _pars.componentId = 'union'
@@ -640,7 +643,7 @@
    return cell
  }
  formatInterSetting = (inters, regs, initInters, params, BID) => {
  formatInterSetting = (inters, regs, initInters, params, BID, MenuName) => {
    if (!inters) return []
    let delay = 15
@@ -652,6 +655,7 @@
      inter.setting.supModule = ''
      inter.setting.arr_field = inter.columns.map(col => col.field).join(',')
      inter.setting.$name = (MenuName || '') + '-公共数据源-' + inter.setting.name
      if (inter.setting.interType !== 'system') {
        let param = UtilsDM.getQueryDataParams(inter.setting, [], inter.setting.order || '', 1, 1000, BID)
@@ -683,7 +687,6 @@
      })
      delete inter.scripts
      inter.setting.$name = '公共数据源-' + inter.setting.name
      inter.setting.execute = inter.setting.execute !== 'false'
      inter.setting.laypage = false
      inter.setting.$top = true
@@ -771,7 +774,7 @@
    }
  }
  getFormatParam = (params) => {
  getFormatParam = (params, MenuName) => {
    const { BID } = this.state
    if (!params || params.length === 0) return ''
@@ -841,6 +844,10 @@
      fullName: fullName
    }
    if (MenuName) {
      param.menuname = MenuName
    }
    param.LText = Utils.formatOptions(param.LText)
    param.LText_field = Utils.formatOptions(param.LText_field)
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
src/views/design/sidemenu/index.jsx
@@ -119,16 +119,16 @@
      }
      _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
      window.open(`#/menudesign/${_param}`)
    } else if (cell.type === 'BaseTable') {
      sessionStorage.setItem('menuTree', JSON.stringify(this.props.menuTree))
      let _param = window.btoa(window.encodeURIComponent(JSON.stringify(cell)))
      window.open(`#/tabledesign/${_param}`)
    } else if (['CommonTable', 'TreePage'].includes(cell.type)) {
      sessionStorage.setItem('menuTree', JSON.stringify(this.props.menuTree))
      let _param = window.btoa(window.encodeURIComponent(JSON.stringify(cell)))
      window.open(`#/basedesign/${_param}`)
    } else if (cell.type === 'BaseTable') {
      sessionStorage.setItem('menuTree', JSON.stringify(this.props.menuTree))
      let _param = window.btoa(window.encodeURIComponent(JSON.stringify(cell)))
      window.open(`#/tabledesign/${_param}`)
    } else if (['RolePermission', 'NewPage'].includes(cell.type)) {
      let _cell = fromJS(cell).toJS()
      _cell.Template = _cell.PageParam.Template
src/views/menudesign/index.jsx
@@ -125,6 +125,7 @@
    
    MKEmitter.addListener('changePopview', this.initPopview)
    MKEmitter.addListener('triggerMenuSave', this.triggerMenuSave)
    MKEmitter.addListener('changeEditMenu', this.changeEditMenu)
    setTimeout(() => {
      this.getRoleFields()
      setGLOBFuncs()
@@ -196,6 +197,49 @@
    }
    MKEmitter.removeListener('changePopview', this.initPopview)
    MKEmitter.removeListener('triggerMenuSave', this.triggerMenuSave)
    MKEmitter.removeListener('changeEditMenu', this.changeEditMenu)
  }
  changeEditMenu = (menu) => {
    if (menu.MenuID && menu.MenuID.length === 3 && menu.MenuNo && !this.menuLoading) {
      this.menuLoading = true
      let param = {
        func: 'sPC_Get_LongParam',
        MenuID: menu.MenuID[2]
      }
      Api.getCloudConfig(param).then(result => {
        this.menuLoading = false
        if (result.status) {
          let config = null
          try {
            config = result.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) : null
          } catch (e) {
            console.warn('Parse Failure')
            config = null
          }
          if (config) {
            let _param = {
              MenuId: menu.MenuID[2],
              MenuID: menu.MenuID[2],
              ParentId: menu.MenuID[1],
              MenuName: menu.MenuName,
              MenuNo: menu.MenuNo
            }
            if (config.Template === 'BaseTable') {
              _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
              window.open(`#/tabledesign/${_param}`)
            } else if (config.Template === 'CustomPage') {
              _param.MenuType = 'custom'
              _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
              window.open(`#/menudesign/${_param}`)
            }
          }
        }
      })
    }
  }
  triggerMenuSave = () => {
@@ -1091,12 +1135,6 @@
    this.setState({config})
    window.GLOB.customMenu = config
    notification.success({
      top: 92,
      message: '粘贴成功!',
      duration: 2
    })
  }
  changeSetting = () => {
src/views/menudesign/popview/index.jsx
@@ -246,12 +246,6 @@
    this.setState({config})
    window.GLOB.customMenu = config
    notification.success({
      top: 92,
      message: '粘贴成功!',
      duration: 2
    })
  }
  render () {
src/views/mobdesign/index.jsx
@@ -1858,49 +1858,14 @@
  insert = (item) => {
    let config = fromJS(this.state.config).toJS()
    if (item.type === 'search') {
      if (config.components.filter(card => card.type === 'topbar' && card.wrap.type !== 'navbar').length > 0) {
        notification.warning({
          top: 92,
          message: '导航栏使用了搜索,不可添加搜索组件!',
          duration: 5
        })
        return
      }
      if (config.components.filter(card => card.type === 'search').length > 0) {
        notification.warning({
          top: 92,
          message: '搜索条件不可重复添加!',
          duration: 5
        })
        return
      }
    }
    if (item.type === 'topbar') {
      if (config.components.findIndex(m => m.type === 'topbar') > -1) {
        notification.warning({
          top: 92,
          message: '导航栏不可重复添加!',
          duration: 5
        })
        return
      }
      if (!config.style.paddingTop) {
        config.style.paddingTop = '50px'
      }
    if (item.type === 'topbar' && !config.style.paddingTop) {
      config.style.paddingTop = '50px'
    }
    config.components.push(item)
    this.setState({config})
    window.GLOB.customMenu = config
    notification.success({
      top: 92,
      message: '粘贴成功!',
      duration: 2
    })
  }
  setHomeView = () => {
src/views/mobdesign/popview/index.jsx
@@ -248,12 +248,6 @@
    this.setState({config})
    window.GLOB.customMenu = config
    notification.success({
      top: 92,
      message: '粘贴成功!',
      duration: 2
    })
  }
  render () {
src/views/pcdesign/index.jsx
@@ -1550,12 +1550,6 @@
    this.setState({config})
    window.GLOB.customMenu = config
    notification.success({
      top: 92,
      message: '粘贴成功!',
      duration: 2
    })
  }
  setHomeView = () => {
src/views/systemfunc/sidemenu/index.jsx
@@ -40,18 +40,50 @@
    }
    let tb =  sessionStorage.getItem('mk-table-node')
    let temp = sessionStorage.getItem('mk-print-temp')
    let tabTemp = sessionStorage.getItem('mk-print-tab-temp')
    sessionStorage.removeItem('mk-table-node')
    sessionStorage.removeItem('mk-print-temp')
    sessionStorage.removeItem('mk-print-tab-temp')
    this.setState({
      subMenulist: menulist,
      rootSubmenuKeys: menulist.map(item => item.MenuID),
      openKeys: [menulist[0].MenuID]
    }, () => {
      if (tb && menulist[0] && menulist[0].children[0] && menulist[0].children[0].MenuNo === 'sDatasM') {
        setTimeout(() => {
          MKEmitter.emit('modifyTabs', fromJS(menulist[0].children[0]).toJS())
        }, 500)
      if (!menulist[0] || menulist[0].children.length === 0) return
      if (tb) {
        let menu = menulist[0].children.filter(item => item.MenuNo === 'sDatasM')[0]
        if (menu) {
          setTimeout(() => {
            MKEmitter.emit('modifyTabs', fromJS(menu).toJS())
          }, 500)
        }
      } else if (temp) {
        let menu = menulist[0].children.filter(item => item.MenuNo === 'sPrintTemplate_webM')[0]
        if (menu) {
          menu = fromJS(menu).toJS()
          menu.param = {}
          menu.param.$searchkey = 'PrintTempNO'
          menu.param.$searchval = temp
          setTimeout(() => {
            MKEmitter.emit('modifyTabs', menu)
          }, 500)
        }
      } else if (tabTemp) {
        let menu = menulist[0].children.filter(item => item.MenuNo === 'sPrintTemplateM')[0]
        if (menu) {
          menu = fromJS(menu).toJS()
          menu.param = {}
          menu.param.$searchkey = 'PrintTempNO'
          menu.param.$searchval = tabTemp
          setTimeout(() => {
            MKEmitter.emit('modifyTabs', menu)
          }, 500)
        }
      }
      sessionStorage.removeItem('mk-table-node')
    })
  }