king
2025-02-06 d1cd5af5adb53e91efdd278328e1b6f8ad834fb5
Merge branch 'positec' into dms
90个文件已修改
4个文件已添加
2个文件已删除
3526 ■■■■■ 已修改文件
public/manifest.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/design.scss 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/normalform/modalform/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/balcony/options.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/dragaction/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.jsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/double-data-card/index.jsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/table-card/index.jsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-scatter/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/code/sandbox/codecontent/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/editor/braft-editor/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/editor/braft-editor/options.jsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/dragtitle/options.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/actionform/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/formaction/formconfig.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/simple-form/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/simple-form/options.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/step-form/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/tab-form/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/module/account/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/dragsearch/card.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/index.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/options.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/actionform/index.jsx 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/formconfig.jsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/markcomponent/index.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/pastecomponent/index.jsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/searchcomponent/dragsearch/card.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/searchcomponent/index.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/tableIn/index.jsx 289 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/tableIn/uniqueform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/index.jsx 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/index.scss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/debug/index.jsx 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/lowerField/index.jsx 321 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/lowerField/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modalconfig/index.jsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/normalCopy/index.jsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/normalCopy/index.scss 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/normalCss/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/pastecontroller/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/replaceField/index.jsx 782 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/stylecombcontrolbutton/index.scss 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/formdragelement/index.jsx 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/modalconfig/index.jsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/login/normal-login/options.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/basetable/index.jsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardcellList/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/editor/braft-editor/index.jsx 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/braftContent/index.jsx 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/braftContent/index.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/edit-table/normalTable/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/sysmessage/index.jsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/sysmessage/index.scss 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/changeuserbutton/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/excelInbutton/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/exceloutbutton/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/normalbutton/index.jsx 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/printbutton/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/mkPopSelect/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/index.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/updatetable/index.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/dragelement/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/settingform/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/fieldscomponent/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/settingform/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editTable/index.jsx 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/editTable/index.scss 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/modalform/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/option.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-custom.js 64 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.scss 91 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/popview/index.jsx 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/popview/index.scss 72 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/popview/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/index.jsx 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/index.scss 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/popview/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/manifest.json
@@ -6,5 +6,5 @@
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff",
  "mk_version": "20250101"
  "mk_version": "20250205"
}
src/api/index.js
@@ -803,11 +803,10 @@
          if (res.mksqls) {
            res.mksqls.forEach(n => {
              n = n.replace(/(UNION ALL\s+)?SELECT obj_name='[\S\s]+sub_field=''\s+/ig, '')
              if (!res.status) {
                window.mkInfo('%c' + n, 'color: #f5222d')
              } else {
                window.mkInfo(n)
              if (!res.status && param.data[0] && param.data[0].menuname) {
                window.mkInfo('%c' + param.data[0].menuname, 'color: #f5222d')
              }
              window.mkInfo(n)
            })
          }
          delete res.mksqls
@@ -1126,11 +1125,10 @@
          if (res.mksqls) {
            res.mksqls.forEach(n => {
              n = n.replace(/(UNION ALL\s+)?SELECT obj_name='[\S\s]+sub_field=''\s+/ig, '')
              if (!res.status) {
                window.mkInfo('%c' + n, 'color: #f5222d')
              } else {
                window.mkInfo(n)
              if (!res.status && param.data[0] && param.data[0].menuname) {
                window.mkInfo('%c' + param.data[0].menuname, 'color: #f5222d')
              }
              window.mkInfo(n)
            })
          }
          delete res.mksqls
src/assets/css/design.scss
@@ -153,3 +153,30 @@
    color: #f5222d;
  }
}
.mk-opeartion-dropdown-wrap {
  box-shadow: 0 0 2px #bcbcbc;
  background: #ffffff;
  min-width: 120px;
  button {
    display: block;
    width: 100%;
    height: 40px;
    line-height: 40px;
    border-radius: 0px;
    border: none;
    border-bottom: 1px solid #e8e8e8!important;
    color: #26C281;
    .anticon {
      display: none;
    }
  }
  button:hover {
    color: #26C281;
  }
}
.menu-setting .ant-typography-copy {
  margin-left: 0px;
}
src/components/normalform/modalform/index.jsx
@@ -22,6 +22,7 @@
// const MKColor = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkColor'))
const MkEditIcon = asyncComponent(() => import('@/components/mkIcon'))
const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent'))
const CodeMirror = asyncComponent(() => import('@/templates/zshare/codemirror'))
class ModalForm extends Component {
  static propTpyes = {
@@ -362,6 +363,8 @@
        return
      } else if (item.type === 'printTemps') {
        content = <MkPrintTemps onChange={(val) => this.recordChange({[item.field]: val})}/>
      } else if (item.type === 'codemirror') {
        content = <CodeMirror mode="text/javascript" theme="cobalt" onChange={(val) => this.recordChange({[item.field]: val})}/>
      }
      if (!content) return
src/menu/components/card/balcony/options.jsx
@@ -114,6 +114,7 @@
      label: '上级组件',
      initval: wrap.supModule || [],
      required: true,
      allowClear: true,
      options: supmodules,
      forbid: isprint
    },
src/menu/components/card/cardcellcomponent/dragaction/index.jsx
@@ -75,7 +75,7 @@
      message.warning('复制失败。')
    }
    if (card.eleType !== 'button') {
    if (card.eleType !== 'button' && !window.GLOB.CopyOnly) {
      _cards.push(copycard)
  
      handleList(_cards)
src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx
@@ -62,7 +62,6 @@
        dataIndex: 'remark',
        inputType: 'input',
        editable: true,
        unique: false,
        required: false,
        width: '20%'
      }
src/menu/components/card/data-card/index.jsx
@@ -207,7 +207,7 @@
    this.updateComponent(_card)
  }
  addSearch = (copy) => {
  addSearch = (copy, type = '') => {
    const { card } = this.state
    let newcard = {}
@@ -228,7 +228,7 @@
    }
    // 注册事件-添加搜索
    MKEmitter.emit('addSearch', card.uuid, newcard)
    MKEmitter.emit('addSearch', card.uuid, newcard, type)
  }
  addButton = (copy) => {
@@ -501,13 +501,22 @@
        }
  
        if (res.field && keys.includes(res.field.toLowerCase())) {
          resolve({status: false, message: '搜索字段已存在!'})
          return
          resolve({status: false})
          const that = this
          confirm({
            title: '搜索字段已存在!',
            okText: '知道了',
            cancelText: '替换',
            onOk() {},
            onCancel() {
              that.addSearch(res, 'replace')
            }
          })
        } else {
          resolve({status: true})
          this.addSearch(res)
        }
        resolve({status: true})
        this.addSearch(res)
      }
    } else if (type === 'action') {
      if (res.style) {
src/menu/components/card/double-data-card/index.jsx
@@ -201,7 +201,7 @@
    this.updateComponent(_card)
  }
  addSearch = (copy) => {
  addSearch = (copy, type = '') => {
    const { card } = this.state
    let newcard = {}
@@ -222,7 +222,7 @@
    }
    // 注册事件-添加搜索
    MKEmitter.emit('addSearch', card.uuid, newcard)
    MKEmitter.emit('addSearch', card.uuid, newcard, type)
  }
  addButton = (copy) => {
@@ -466,13 +466,22 @@
        }
  
        if (res.field && keys.includes(res.field.toLowerCase())) {
          resolve({status: false, message: '搜索字段已存在!'})
          return
          resolve({status: false})
          const that = this
          confirm({
            title: '搜索字段已存在!',
            okText: '知道了',
            cancelText: '替换',
            onOk() {},
            onCancel() {
              that.addSearch(res, 'replace')
            }
          })
        } else {
          resolve({status: true})
          this.addSearch(res)
        }
        resolve({status: true})
        this.addSearch(res)
      }
    } else if (type === 'action') {
      if (appType === 'mob' && !['pop', 'prompt', 'exec', 'innerpage'].includes(res.OpenType)) {
src/menu/components/card/table-card/index.jsx
@@ -220,7 +220,7 @@
    this.updateComponent(card)
  }
  addSearch = (copy) => {
  addSearch = (copy, type = '') => {
    const { card } = this.state
    let newcard = {}
@@ -242,7 +242,7 @@
    }
    // 注册事件-添加搜索
    MKEmitter.emit('addSearch', card.uuid, newcard)
    MKEmitter.emit('addSearch', card.uuid, newcard, type)
  }
  move = (item, direction) => {
@@ -337,13 +337,22 @@
        }
  
        if (res.field && keys.includes(res.field.toLowerCase())) {
          resolve({status: false, message: '搜索字段已存在!'})
          return
          resolve({status: false})
          const that = this
          confirm({
            title: '搜索字段已存在!',
            okText: '知道了',
            cancelText: '替换',
            onOk() {},
            onCancel() {
              that.addSearch(res, 'replace')
            }
          })
        } else {
          resolve({status: true})
          this.addSearch(res)
        }
        resolve({status: true})
        this.addSearch(res)
      }
    }
  }
src/menu/components/chart/antv-bar/index.jsx
@@ -1337,12 +1337,12 @@
  plusSearch = (uuid, search, type) => {
    const { card } = this.state
    if (card.uuid !== uuid || type !== 'simple') return
    if (card.uuid !== uuid || (type !== 'simple' && type !== 'replace')) return
    search.uuid = Utils.getuuid()
    search.focus = true
    MKEmitter.emit('addSearch', card.uuid, search)
    MKEmitter.emit('addSearch', card.uuid, search, type === 'replace' ? 'replace' : '')
  }
  addButton = () => {
src/menu/components/chart/antv-scatter/index.jsx
@@ -278,12 +278,12 @@
  plusSearch = (uuid, search, type) => {
    const { card } = this.state
    if (card.uuid !== uuid || type !== 'simple') return
    if (card.uuid !== uuid || (type !== 'simple' && type !== 'replace')) return
    search.uuid = Utils.getuuid()
    search.focus = true
    MKEmitter.emit('addSearch', card.uuid, search)
    MKEmitter.emit('addSearch', card.uuid, search, type === 'replace' ? 'replace' : '')
  }
  addButton = () => {
src/menu/components/code/sandbox/codecontent/index.scss
@@ -18,7 +18,7 @@
      background-color: #f0f0f0;
    }
    td, th {
      padding: 5px 14px;
      padding: 5px 10px;
      font-size: 16px;
      border: 1px solid #ddd;
    }
src/menu/components/editor/braft-editor/index.jsx
@@ -200,7 +200,7 @@
        <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <NormalForm title="富文本设置" width={850} update={this.updateWrap} getForms={this.getWrapForms}>
            <NormalForm title="富文本设置" width={900} update={this.updateWrap} getForms={this.getWrapForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="editor" card={card}/>
@@ -212,10 +212,7 @@
        } trigger="hover">
          <ToolOutlined />
        </Popover>
        <BraftContent
          value={card.wrap.datatype !== 'static' ? '<p class="empty-content">富文本</p>' : card.html}
          encryption="false"
        />
        <BraftContent value={card.wrap.datatype !== 'static' ? '<p class="empty-content">富文本</p>' : card.html}/>
        <div className="component-name">
          <div className="center">
            <div className="title">{card.name}</div>
src/menu/components/editor/braft-editor/options.jsx
@@ -167,6 +167,28 @@
    },
    {
      type: 'radio',
      field: 'loaded',
      label: '布局调整',
      initval: wrap.loaded || 'false',
      required: false,
      options: [
        {value: 'false', label: '关闭'},
        {value: 'true', label: '开启'},
      ],
      controlFields: [
        {field: 'loadedfunc', values: ['true']},
      ]
    },
    {
      type: 'codemirror',
      field: 'loadedfunc',
      label: '处理脚本',
      initval: wrap.loadedfunc || '',
      required: true,
      span: 24
    },
    {
      type: 'radio',
      field: 'permission',
      label: '权限验证',
      initval: wrap.permission || 'false',
src/menu/components/form/dragtitle/options.jsx
@@ -8,13 +8,13 @@
  if (appType === 'mob') {
    group.fields.forEach(f => {
      if (f.field && ['select', 'text', 'number', 'textarea'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
        fields.push(f)
        fields.push({...f, label: `${f.label}(${f.field})`})
      }
    })
  } else {
    group.fields.forEach(f => {
      if (f.field && ['select', 'link', 'text', 'number', 'textarea'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
        fields.push(f)
        fields.push({...f, label: `${f.label}(${f.field})`})
      }
    })
  }
src/menu/components/form/formaction/actionform/index.jsx
@@ -62,6 +62,9 @@
      if (this.record.execSuccess === 'never') {
        shows.push('resetForms')
      }
      if (this.record.refreshTab && this.record.refreshTab.length) {
        shows.push('urlPar')
      }
      if (this.record.syncComponent && this.record.syncComponent[0]) {
        shows.push('syncDelay')
      }
src/menu/components/form/formaction/formconfig.jsx
@@ -456,6 +456,22 @@
      options: menulist
    },
    {
      type: 'radio',
      key: 'urlPar',
      label: 'URL变量',
      initVal: card.urlPar || 'false',
      tooltip: '刷新菜单时是否清除URL变量。',
      required: false,
      options: [{
        value: 'true',
        text: '清空'
      }, {
        value: 'false',
        text: '不清空'
      }],
      forbid: appType === 'pc' || appType === 'mob' || viewType === 'popview',
    },
    {
      type: (appType === 'pc' || appType === 'mob') ? 'select' : 'cascader',
      key: 'linkmenu',
      label: '下一步操作',
src/menu/components/form/simple-form/index.jsx
@@ -325,6 +325,7 @@
      orderType: 'asc',
      readonly: 'false',
      required: 'true',
      readin: 'top',
      focus: true
    }
src/menu/components/form/simple-form/options.jsx
@@ -23,13 +23,13 @@
  if (appType === 'mob') {
    config.subcards[0].fields.forEach(f => {
      if (f.field && ['select', 'text', 'number', 'textarea'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
        fields.push(f)
        fields.push({...f, label: `${f.label}(${f.field})`})
      }
    })
  } else {
    config.subcards[0].fields.forEach(f => {
      if (f.field && ['select', 'link', 'text', 'number', 'textarea'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
        fields.push(f)
        fields.push({...f, label: `${f.label}(${f.field})`})
      }
    })
  }
src/menu/components/form/step-form/index.jsx
@@ -425,6 +425,7 @@
      orderType: 'asc',
      readonly: 'false',
      required: 'true',
      readin: 'top',
      focus: true
    }
src/menu/components/form/tab-form/index.jsx
@@ -431,6 +431,7 @@
      orderType: 'asc',
      readonly: 'false',
      required: 'true',
      readin: 'top',
      focus: true
    }
src/menu/components/module/account/index.jsx
@@ -11,6 +11,7 @@
import './index.scss'
const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
class Account extends Component {
@@ -129,6 +130,7 @@
            <NormalForm title="基本设置" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
              <EditOutlined style={{color: '#1890ff'}} title="编辑"/>
            </NormalForm>
            <CopyComponent type="account" card={card}/>
            <FontColorsOutlined className="style" title="调整样式" onClick={this.changeStyle}/>
            <DeleteOutlined className="close" title="删除组件" onClick={() => this.props.deletecomponent(card.uuid)} />
          </div>
src/menu/components/search/main-search/dragsearch/card.jsx
@@ -57,6 +57,10 @@
      _defaultValue = [moment().startOf('month'), moment().endOf('month')]
    } else if (card.initval === 'lastMonth') {
      _defaultValue = [moment().subtract(1, 'months').startOf('month'), moment().subtract(1, 'months').endOf('month')]
    } else if (card.initval === 'year') {
      _defaultValue = [moment().startOf('year'), moment().endOf('year')]
    } else if (card.initval === 'lastYear') {
      _defaultValue = [moment().subtract(1, 'years').startOf('year'), moment().subtract(1, 'years').endOf('year')]
    } else if (card.initval) {
      try {
        let _initval = JSON.parse(card.initval)
src/menu/components/search/main-search/index.jsx
@@ -342,6 +342,17 @@
      this.updateComponent(_card)
      this.handleSearch(item)
    } else if (type === 'replace') {
      delete item.focus
      _card.search = _card.search.map(cell => {
        if (cell.field && cell.field.toLowerCase() === item.field.toLowerCase()) {
          return item
        }
        return cell
      })
      this.updateComponent(_card)
      this.handleSearch(item)
    } else if (type === 'multil') {
      _card.search.push(...item)
src/menu/components/search/main-search/options.jsx
@@ -140,10 +140,12 @@
      field: 'resetContrl',
      label: '重置时',
      initval: wrap.resetContrl || 'init',
      tooltip: '刷新菜单会清空URL变量。',
      required: false,
      options: [
        {value: 'init', label: '恢复初始值'},
        {value: 'clear', label: '清空'},
        {value: 'refresh', label: '刷新菜单'},
      ],
    },
    {
@@ -189,6 +191,7 @@
      label: '上级组件',
      initval: wrap.supModule || [],
      required: false,
      allowClear: true,
      options: modules,
      forbid: sessionStorage.getItem('editMenuType') === 'popview'
    },
src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -226,9 +226,15 @@
      if (Ot === 'required') {
        shows.push('progress')
        if (intertype === 'inner' || intertype === 'system') {
          shows.push('execType')
          if (this.record.execType === 'single') {
            shows.push('execInterval')
          }
        }
      }
      if (Ot === 'required' && (intertype === 'inner' || intertype === 'system')) {
        shows.push('execType')
      if (intertype === 'outer' || intertype === 'custom') {
        shows.push('execInterval')
      }
      if (this.record.openmenu && this.record.openmenu !== 'goback') {
        shows.push('open')
@@ -621,6 +627,10 @@
      }
    }
    if (shows.includes('refreshTab') && this.record.refreshTab && this.record.refreshTab.length) {
      shows.push('urlPar')
    }
    return {
      shows,
      reOptions,
src/menu/components/share/actioncomponent/formconfig.jsx
@@ -1089,6 +1089,22 @@
      options: menulist
    },
    {
      type: 'radio',
      key: 'urlPar',
      label: 'URL变量',
      initVal: card.urlPar || 'false',
      tooltip: '刷新菜单时是否清除URL变量。',
      required: false,
      options: [{
        value: 'true',
        text: '清空'
      }, {
        value: 'false',
        text: '不清空'
      }],
      forbid: isApp || viewType === 'popview',
    },
    {
      type: !appType ? 'cascader' : 'select',
      key: 'openmenu',
      label: '打开菜单',
@@ -1634,6 +1650,14 @@
        value: 'single',
        text: '逐条请求'
      }]
    },
    {
      type: 'number',
      key: 'execInterval',
      label: '执行间隔',
      initVal: card.execInterval || 0,
      tooltip: '两次请求的时间间隔(单位毫秒)。',
      required: false
    },
    {
      type: 'radio',
@@ -2499,6 +2523,22 @@
      options: menulist
    },
    {
      type: 'radio',
      key: 'urlPar',
      label: 'URL变量',
      initVal: card.urlPar || 'false',
      tooltip: '刷新菜单时是否清除URL变量。',
      required: false,
      options: [{
        value: 'true',
        text: '清空'
      }, {
        value: 'false',
        text: '不清空'
      }],
      forbid: viewType === 'popview',
    },
    {
      type: 'cascader',
      key: 'openmenu',
      label: '打开菜单',
@@ -2842,6 +2882,14 @@
      }]
    },
    {
      type: 'number',
      key: 'execInterval',
      label: '执行间隔',
      initVal: card.execInterval || 0,
      tooltip: '两次请求的时间间隔(单位毫秒)。',
      required: false
    },
    {
      type: 'radio',
      key: 'progress',
      label: '进度提示',
src/menu/components/share/markcomponent/index.jsx
@@ -36,15 +36,8 @@
        uniqueFunc: (data, item) => {
          let index = data.findIndex(mark => mark.uuid !== item.uuid && mark.contrastValue === item.contrastValue && mark.match === item.match && mark.field.join('') === item.field.join(''))
          if (index > -1) {
            notification.warning({
              top: 92,
              message: '此标记已存在!',
              duration: 5
            })
            return false
          }
          return true
          if (index > -1) return '此标记已存在!'
          return ''
        },
        inputType: 'cascader',
        options: [],
src/menu/components/share/pastecomponent/index.jsx
@@ -10,6 +10,7 @@
import asyncComponent from '@/utils/asyncComponent'
// import './index.scss'
const { confirm } = Modal
const PasteForm = asyncComponent(() => import('@/templates/zshare/pasteform'))
class PasteController extends Component {
@@ -173,17 +174,20 @@
          }
        }
        if (res.field && keys.includes(res.field.toLowerCase())) {
          notification.warning({
            top: 92,
            message: '搜索字段已存在!',
            duration: 5
          })
          return
        }
        MKEmitter.emit('plusSearch', config.uuid, res, 'simple')
        this.setState({visible: false})
        if (res.field && keys.includes(res.field.toLowerCase())) {
          confirm({
            title: '搜索字段已存在!',
            okText: '知道了',
            cancelText: '替换',
            onOk() {},
            onCancel() {
              MKEmitter.emit('plusSearch', config.uuid, res, 'replace')
            }
          })
        } else {
          MKEmitter.emit('plusSearch', config.uuid, res, 'simple')
        }
        return
      } else if (type === 'cardcell') {
        config.subcards.push(res)
src/menu/components/share/searchcomponent/dragsearch/card.jsx
@@ -56,6 +56,10 @@
      _defaultValue = [moment().startOf('month'), moment().endOf('month')]
    } else if (card.initval === 'lastMonth') {
      _defaultValue = [moment().subtract(1, 'months').startOf('month'), moment().subtract(1, 'months').endOf('month')]
    } else if (card.initval === 'year') {
      _defaultValue = [moment().startOf('year'), moment().endOf('year')]
    } else if (card.initval === 'lastYear') {
      _defaultValue = [moment().subtract(1, 'years').startOf('year'), moment().subtract(1, 'years').endOf('year')]
    } else if (card.initval) {
      try {
        let _initval = JSON.parse(card.initval)
src/menu/components/share/searchcomponent/index.jsx
@@ -64,12 +64,24 @@
    MKEmitter.removeListener('addSearch', this.addSearch)
  }
  addSearch = (cardId, element) => {
  addSearch = (cardId, element, type) => {
    if (cardId !== this.props.config.uuid) return
    const { searchlist } = this.state
    this.setState({searchlist: [...searchlist, element]})
    if (type === 'replace') {
      delete element.focus
      this.setState({
        searchlist: searchlist.map(cell => {
          if (cell.field && cell.field.toLowerCase() === element.field.toLowerCase()) {
            return element
          }
          return cell
        }),
      })
    } else {
      this.setState({searchlist: [...searchlist, element]})
    }
    this.handleSearch(element)
  }
src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx
@@ -1,9 +1,8 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Button, notification, Modal, Tooltip, Radio, Select, Switch } from 'antd'
import { Form, Row, Col, Button, notification, Tooltip, Radio, Select, Switch } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons'
import Api from '@/api'
import { checkSQL } from '@/utils/utils-custom.js'
import CodeMirror from '@/templates/zshare/codemirror'
// import './index.scss'
@@ -67,20 +66,12 @@
  }
  handleConfirm = () => {
    const { type, btn } = this.props
    const { type } = this.props
    const { editItem, skip } = this.state
    // 表单提交时检查输入值是否正确
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (type === 'fullscreen' && err) {
        notification.warning({
          top: 92,
          message: '请输入sql!',
          duration: 5
        })
        return
      }
      if (!err) {
        if (/^[\s\n]+$/.test(values.sql)) {
        if (!values.sql || /^[\s\n]+$/.test(values.sql)) {
          notification.warning({
            top: 92,
            message: '请输入sql!',
@@ -99,92 +90,39 @@
        if (!pass && !skip) return
        let sheet = btn.sheet.replace(/(.*)\.(.*)\.|@db@/ig, '')
        let tail = `
          drop table #${sheet}
          aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg
        `
        let _initCustomScript = '' // 初始化脚本
        let _prevCustomScript = '' // 默认sql前执行脚本
        let _backCustomScript = '' // 默认sql后执行脚本
        this.props.scripts.forEach(item => {
          if (item.status === 'false') return
          if (item.position === 'init') {
            _initCustomScript += `
            /* 初始化脚本 */
            ${values.uuid === item.uuid ? values.sql : item.sql}
            `
          } else if (item.position === 'front') {
            _prevCustomScript += `
            /* 默认sql前脚本 */
            ${values.uuid === item.uuid ? values.sql : item.sql}
            `
          } else {
            _backCustomScript += `
            /* 默认sql后脚本 */
            ${values.uuid === item.uuid ? values.sql : item.sql}
            `
          }
        })
        if (!values.uuid) {
          if (values.position === 'init') {
            _initCustomScript += `
            /* 初始化脚本 */
            ${values.sql}
            `
          } else if (values.position === 'front') {
            _prevCustomScript += `
            /* 默认sql前脚本 */
            ${values.sql}
            `
          } else {
            _backCustomScript += `
            /* 默认sql后脚本 */
            ${values.sql}
            `
          }
        if (/@ID@/ig.test(values.sql) && !skip) {
          notification.warning({
            top: 92,
            message: '脚本中不可使用@ID@!',
            duration: 5
          })
          return
        }
        let sql = this.state.verifySql + _initCustomScript + _prevCustomScript + _backCustomScript + tail
        sql = sql.replace(/@\$|\$@/ig, '')
        sql = sql.replace(/@datam@/ig, `''`)
        sql = sql.replace(/@typename@/ig, `'debug'`)
        if (skip) {
          this.setState({
            editItem: null,
            skip: false
          }, () => {
            this.props.scriptsChange(values)
            skip: false,
            editItem: null
          })
          this.props.form.setFieldsValue({
            sql: ' '
            sql: ''
          })
          this.props.scriptsChange(values)
        } else {
          this.setState({loading: true})
          Api.sDebug(sql).then(res => {
            if (res.status || res.ErrCode === '-2') {
              this.setState({
                loading: false,
                editItem: null
              }, () => {
                this.props.scriptsChange(values)
              })
              this.props.form.setFieldsValue({
                sql: ' '
              })
            } else {
              this.setState({loading: false})
  
              Modal.error({
                title: res.message
              })
            }
          this.props.scriptsChange(values, () => {
            this.setState({
              loading: false,
              editItem: null
            })
            this.props.form.setFieldsValue({
              sql: ''
            })
          }, () => {
            this.setState({
              loading: false
            })
          })
        }
      }
@@ -202,14 +140,18 @@
  }
  selectScript = (value, option) => {
    const { usefulfields, btn } = this.props
    const { usefulfields, btn, setting } = this.props
    let _value = ''
    if (value === 'default') {
      let fields = usefulfields.map(col => col.field).join(',')
      let upFields = usefulfields.map(col => `${col.field}=t.${col.field}`).join(',')
      
      if (fields) {
        fields = fields + ','
      }
      if (upFields) {
        upFields = upFields + ','
      }
      let database = btn.sheet.match(/(.*)\.(.*)\.|@db@/ig) || ''
@@ -217,7 +159,20 @@
      database = database ? (database[0] || '') : ''
      _value = `Insert into ${database}${sheet} (${fields}createuserid,createuser,createstaff,bid)\nSelect ${fields}@userid@,@username,@fullname,@BID@ From #${sheet}`
      _value = `update a set ${upFields}modifydate=getdate(),modifyuserid=@UserID@,modifyuser=@username,modifystaff=@fullname,deleted=0
      from (select * from #${sheet} where data_type='upt') t
      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
      update a set deleted=1,modifydate=getdate(),modifyuserid=@UserID@,modifyuser=@username,modifystaff=@fullname
      from (select * from #${sheet} where data_type='del') t
      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
      delete t from #${sheet} t inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
      Insert into ${database}${sheet} (${fields}createuserid,createuser,createstaff,bid)
      Select ${fields}@UserID@,@username,@fullname,@BID@ From #${sheet}
      `
      _value = _value.replace(/\s{6}[fiuds]/ig, (word) => word.replace(/\s{6}/ig, ''))
    } else {
      _value = value
    }
@@ -331,15 +286,9 @@
            <Switch checked={skip} size="small" onChange={() => this.setState({skip: !skip})}/>
          </Col>
          <Col span={24} className="sql">
            <Form.Item label="sql">
            <Form.Item label="sql" required>
              {getFieldDecorator('sql', {
                initialValue: '',
                rules: [
                  {
                    required: true,
                    message: '请输入sql!'
                  }
                ]
                initialValue: ''
              })(<CodeMirror />)}
            </Form.Item>
          </Col>
src/menu/components/table/edit-table/columns/tableIn/index.jsx
@@ -136,6 +136,7 @@
          let _fields = record.field.split(',')
          let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
          _fields_ = _fields_.join(' and ')
          _fields_ += ` and a.jskey != b.${this.props.config.setting.primaryKey || 'id'}`
          let _where = []
          _fields.forEach(f => {
@@ -400,7 +401,7 @@
    this.setState({verify: {...verify, uniques}})
  }
  scriptsChange = (values) => {
  scriptsChange = (values, resolve, reject) => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
    if (values.uuid) {
@@ -416,11 +417,287 @@
      verify.scripts.push(values)
    }
    MKEmitter.emit('editLineId', values.uuid)
    let sql = this.getEditTableSql(verify)
    this.setState({
      verify: verify
    if (resolve) {
      Api.sDebug(sql).then(res => {
        if (res.status || res.ErrCode === '-2') {
          resolve()
          values && MKEmitter.emit('editLineId', values.uuid)
          this.setState({ verify })
        } else {
          reject()
          Modal.error({
            title: res.message
          })
        }
      })
    } else {
      Api.sDebug(sql, true)
      MKEmitter.emit('editLineId', values.uuid)
      this.setState({ verify })
    }
  }
  getEditTableSql = (verify) => {
    const { columns, setting, cols } = this.props.config
    let btn = verify
    let userName = sessionStorage.getItem('User_Name') || ''
    let fullName = sessionStorage.getItem('Full_Name') || ''
    let RoleID = sessionStorage.getItem('role_id') || ''
    let departmentcode = sessionStorage.getItem('departmentcode') || ''
    let organization = sessionStorage.getItem('organization') || ''
    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
    let nation = sessionStorage.getItem('nation') || ''
    let province = sessionStorage.getItem('province') || ''
    let city = sessionStorage.getItem('city') || ''
    let district = sessionStorage.getItem('district') || ''
    let address = sessionStorage.getItem('address') || ''
    let _sheet = btn.sheet
    let BID = 'bid'
    if (window.GLOB.externalDatabase !== null) {
      _sheet = _sheet.replace(/@db@/ig, window.GLOB.externalDatabase)
    }
    let database = _sheet.match(/(.*)\.(.*)\./ig)
    let sheet = _sheet.replace(/(.*)\.(.*)\./ig, '')
    database = database ? (database[0] || '') : ''
    let vals = []
    let forms = []
    let _forms = {}
    let index = 0
    let getColumns = (cols) => {
      cols.forEach(item => {
        if (item.type === 'colspan') {
          getColumns(item.subcols)
        } else if (item.editable === 'true') {
          item.$sort = index
          _forms[item.field] = item
          index++
        }
      })
    }
    getColumns(cols)
    columns.forEach(item => {
      if (item.field === setting.primaryKey) return
      if (_forms[item.field]) {
        let _item = {..._forms[item.field]}
        if (_item.editType === 'date') {
          _item.datatype = _item.declareType || 'datetime'
        } else {
          _item.datatype = item.datatype
        }
        forms.push(_item)
      } else {
        forms.push({...item, $sort: 999})
      }
    })
    forms.sort((a, b) => a.$sort - b.$sort)
    forms.forEach(col => {
      if (/date/.test(col.datatype)) {
        vals.push(`'1949-10-01'`)
      } else if (col.type === 'number') {
        vals.push(`1`)
      } else {
        vals.push(`'mk'`)
      }
    })
    vals.push(`'uuid'`)
    vals.push(`'upt'`)
    vals.push(`'${BID}'`)
    vals = `Select ${vals.join(',')}`
    let sql = ''
    let _initCustomScript = '' // 初始化脚本
    let _prevCustomScript = '' // 默认sql前执行脚本
    let _backCustomScript = '' // 默认sql后执行脚本
    let isDM = sessionStorage.getItem('dataM') === 'true'
    let regs = [
      {reg: new RegExp('(^|\\s)@' + sheet + '(\\s|$)', 'ig'), value: ` #${sheet} `},
      {reg: new RegExp('(^|\\s)@' + sheet + '\\(', 'ig'), value: ` #${sheet}(`},
      {reg: new RegExp('(^|\\s)@' + sheet + '\\)', 'ig'), value: ` #${sheet})`},
      {reg: /@typename@/ig, value: `'admin'`},
      {reg: /\$@/ig, value: isDM ? '/*' : ''},
      {reg: /@\$/ig, value: isDM ? '*/' : ''},
      {reg: /@datam@/ig, value: isDM ? `'Y'` : `''`},
    ]
    btn.scripts && btn.scripts.forEach(script => {
      if (script.status === 'false') return
      let _sql = script.sql
      regs.forEach(item => {
        _sql = _sql.replace(item.reg, item.value)
      })
      if (script.position === 'init') {
        _initCustomScript += `
      /* 自定义脚本 */
      ${_sql}
      `
      } else if (script.position === 'front') {
        _prevCustomScript += `
      /* 自定义脚本 */
      ${_sql}
      `
      } else {
        _backCustomScript += `
      /* 自定义脚本 */
      ${_sql}
      `
      }
    })
    let _uniquesql = ''
    if (btn.uniques && btn.uniques.length > 0) {
      let textFields = []
      let numberFields = []
      let dateFields = []
      columns.forEach((col) => {
        if (/Nvarchar/ig.test(col.datatype)) {
          textFields.push(col.field)
        } else if (/Decimal|int/ig.test(col.datatype)) {
          numberFields.push(col.field)
        } else if (/date/ig.test(col.datatype)) {
          dateFields.push(col.field)
        }
      })
      btn.uniques.forEach(unique => {
        if (unique.status === 'false' || !unique.verifyType) return
        let _fields = unique.field.split(',')
        let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
        _fields_ = _fields_.join(' and ')
        _fields_ += ` and a.jskey != b.${setting.primaryKey || 'id'}`
        let _where = []
        _fields.forEach(f => {
          if (textFields.includes(f)) {
            _where.push(`${f}!=''`)
          } else if (numberFields.includes(f)) {
            _where.push(`${f}!=0`)
          } else if (dateFields.includes(f)) {
            _where.push(`${f}>'1949-10-01'`)
          }
        })
        _where = _where.length ? `where ${_where.join(' and ')} ` : ''
        if (unique.verifyType === 'logic' || unique.verifyType === 'logic_temp') {
          _fields_ += ' and b.deleted=0'
        }
        let _afields = []
        _fields = _fields.map(f => {
          if (numberFields.includes(f)) {
            _afields.push(`cast(a.${f} as nvarchar(50))`)
            return `cast(${f} as nvarchar(50))`
          } else if (dateFields.includes(f)) {
            _afields.push(`CONVERT(nvarchar(50), a.${f}, 21)`)
            return `CONVERT(nvarchar(50), ${f}, 21)`
          }
          _afields.push(`a.${f}`)
          return f
        })
        _uniquesql += `
      /* 重复性验证 */
      Set @tbid=''
      Select top 1 @tbid=${_fields.join('+\' \'+')} from (select 1 as n,${unique.field} from #${sheet} ) a group by ${unique.field} having sum(n)>1
      If @tbid!=''
      Begin
        select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 重复'
        goto aaa
      end
      ${unique.verifyType.indexOf('temp') === -1 ? `Set @tbid=''
      Select top 1 @tbid=${_afields.join('+\' \'+')} from ${_where ? `(select * from #${sheet} ${_where})` : `#${sheet}`} a Inner join ${sheet} b on ${_fields_}
      If @tbid!=''
      Begin
        select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 与已有数据重复'
        goto aaa
      end` : ''}
      `
      })
    }
    let declarefields = []
    let fields = []
    let upFields = []
    forms.forEach(col => {
      let key = col.field.toLowerCase()
      if (key === 'jskey' || key === 'bid' || key === 'data_type') return
      declarefields.push(`${col.field} ${col.datatype}`)
      fields.push(col.field)
      upFields.push(`${col.field}=t.${col.field}`)
    })
    fields = fields.join(',')
    upFields = upFields.join(',')
    let _insert = ''
    if (btn.default !== 'false') {
      _insert = `
      /* 默认sql */
      update a set ${upFields},modifydate=getdate(),modifyuserid='${sessionStorage.getItem('UserID') || ''}',modifyuser=@username,modifystaff=@fullname,deleted=0
      from (select * from #${sheet} where data_type='upt') t
      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
      update a set deleted=1,modifydate=getdate(),modifyuserid='${sessionStorage.getItem('UserID') || ''}',modifyuser=@username,modifystaff=@fullname
      from (select * from #${sheet} where data_type='del') t
      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
      delete t from #${sheet} t inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
      Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid)
      Select ${fields},'${sessionStorage.getItem('UserID') || ''}',@username,@fullname,'${BID}' From #${sheet}
      `
    }
    sql = `create table #${sheet} (${declarefields.join(',')},jskey nvarchar(50),data_type nvarchar(50),BID nvarchar(256))
      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)
      Select  @ErrorCode='', @retmsg='', @UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
      ${_initCustomScript}
      Insert into #${sheet} (${fields},jskey,data_type,BID)
      /* excel数据*/
      ${vals}
      ${_uniquesql}
      ${_prevCustomScript}
      ${_insert}
      ${_backCustomScript}
      drop table #${sheet}
      aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
    return sql
  }
  handleDelete = (record, type) => {
@@ -612,7 +889,7 @@
                  </Form.Item>
                </Col>
                <Col span={8}>
                  <Form.Item required label={'接口类型'}>
                  <Form.Item required label="接口类型">
                    <Radio.Group value={verify.intertype} onChange={(e) => this.onOptionChange(e.target.value, 'intertype')}>
                      <Radio value="system">系统</Radio>
                      <Radio value="inner">内部</Radio>
@@ -716,6 +993,7 @@
                type="fullscreen"
                btn={verify}
                usefulfields={fields}
                setting={config.setting}
                scripts={verify.scripts}
                systemScripts={this.state.systemScripts}
                scriptsChange={this.scriptsChange}
@@ -725,6 +1003,7 @@
            <CustomScript
              btn={verify}
              usefulfields={fields}
              setting={config.setting}
              scripts={verify.scripts}
              systemScripts={this.state.systemScripts}
              scriptsChange={this.scriptsChange}
src/menu/components/table/edit-table/columns/tableIn/uniqueform/index.jsx
@@ -99,7 +99,7 @@
          <Col span={7}>
            <Form.Item label="验证类型">
              {getFieldDecorator('verifyType', {
                initialValue: 'physical',
                initialValue: 'logic',
                rules: [
                  {
                    required: true,
@@ -108,8 +108,8 @@
                ]
              })(
                <Select>
                  <Select.Option value="physical"> 物理验证(全量验证) </Select.Option>
                  <Select.Option value="logic"> 逻辑验证(全量验证) </Select.Option>
                  <Select.Option value="physical"> 物理验证(全量验证) </Select.Option>
                  <Select.Option value="physical_temp"> 物理验证(仅临时表) </Select.Option>
                  <Select.Option value="logic_temp"> 逻辑验证(仅临时表)  </Select.Option>
                </Select>
src/menu/datasource/verifycard/index.jsx
@@ -62,6 +62,7 @@
        inputType: 'input',
        editable: true,
        searchable: true,
        copy: true,
        width: '28%'
      },
      {
@@ -118,6 +119,7 @@
          { value: 'datetime', text: 'datetime' },
        ],
        editable: true,
        copy: true,
        width: '25%',
      }
    ],
@@ -717,6 +719,13 @@
      let r = SettingUtils.getDebugSql(setting, _scripts, _columns, searches, config.subtype, config.hasExtend)
      if (type === 'submit' && r.custompage && setting.queryType !== 'statistics') {
        Modal.info({
          title: '数据源或自定义脚本中使用了自定义分页,查询类型请使用统计!',
        })
        reject()
        return
      }
      if (r.custompage && setting.laypage === 'true' && _columns.findIndex(col => col.field === 'mk_total') === -1) {
        if (config.subtype !== 'basetable') {
          const that = this
@@ -1208,33 +1217,6 @@
    })
  }
  tolowercase = (type) => {
    const that = this
    confirm({
      content: type === 'sub' ? '确定将子表字段转为小写吗?' : '确定将字段转为小写吗?',
      onOk() {
        that.execlowercase(type)
      },
      onCancel() {}
    })
  }
  execlowercase = (type) => {
    const { subColumns, columns } = this.state
    if (type === 'sub') {
      this.setState({subColumns: fromJS(subColumns).toJS().map(col => {
        col.field = col.field.toLowerCase()
        return col
      })})
    } else {
      this.setState({columns: fromJS(columns).toJS().map(col => {
        col.field = col.field.toLowerCase()
        return col
      })})
    }
  }
  /**
   * @description 组件销毁,清除state更新
   */
@@ -1282,7 +1264,6 @@
              type="fields"
              updatefield={this.updatefields}
            />
            <SwapOutlined className="columns-lowercase" title="转小写" onClick={() => this.tolowercase()}/>
            <ExcelOut data={columns} setting={setting}/>
            <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} searchKey={searchKey} type="datasourcefield" wrappedComponentRef={(inst) => this.datasource = inst} data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/>
          </TabPane> : <TabPane tab={
@@ -1307,7 +1288,6 @@
              type="fields"
              updatefield={this.updateSubfields}
            />
            <SwapOutlined className="columns-lowercase" title="转小写" onClick={() => this.tolowercase('sub')}/>
            <ExcelOut data={subColumns} setting={setting}/>
            <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} searchKey={searchKey} type="datasourcefield" wrappedComponentRef={(inst) => this.subdatasource = inst} data={subColumns} columns={colColumns} onChange={(subColumns) => this.setState({subColumns})}/>
          </TabPane> : null}
src/menu/datasource/verifycard/index.scss
@@ -146,16 +146,6 @@
      margin-right: 5px;
      cursor: pointer;
    }
    .columns-lowercase {
      float: right;
      position: relative;
      z-index: 2;
      right: 30px;
      height: 0px;
      top: -15px;
      color: orange;
      cursor: pointer;
    }
    .columns-out {
      float: right;
      position: relative;
@@ -169,7 +159,7 @@
      .ant-table-thead {
        .copy-control {
          top: -18px;
          right: 55px;
          right: 35px;
          .anticon-copy {
            margin-right: 12px;
          }
src/menu/debug/index.jsx
@@ -27,6 +27,8 @@
  sqlList = []
  verSqls = []
  linkMain = null
  modules = null
  supError = null
  trigger = () => {
    let config = fromJS(this.props.config).toJS()
@@ -61,6 +63,30 @@
    if (error) {
      Modal.warning({
        title: error,
        okText: '知道了'
      })
      return
    }
    this.modules = {}
    this.supError = null
    this.getModules(config.components, config.interfaces)
    config.interfaces && config.interfaces.forEach(item => {
      if (item.setting && item.setting.supModule && item.setting.supModule[0] !== 'empty') {
        let id = item.setting.supModule[item.setting.supModule.length - 1]
        if (!this.modules[id]) {
          this.supError = item.name + '(公共数据源)'
        }
      }
    })
    this.checklink(config.components)
    if (this.supError) {
      Modal.warning({
        title: this.supError + ':上级组件不存在!',
        okText: '知道了'
      })
      return
@@ -284,6 +310,122 @@
    })
    this.sqlList = []
  }
  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]
      })
    }
  }
  checklink = (components, suplabel = '') => {
    if (this.supError) return
    components.forEach(item => {
      if (this.supError) return
      if (item.type === 'tabs') {
        item.subtabs.forEach(f_tab => {
          this.checklink(f_tab.components, suplabel)
        })
      } else if (item.type === 'group' ) {
        item.components && this.checklink(item.components, suplabel)
      } else {
        if (item.wrap && item.wrap.supType === 'multi') {
          if (item.setting && item.setting.supModule) {
            item.setting.supModule = ''
          }
          if (item.supNodes) {
            item.supNodes.forEach(cell => {
              let id = cell.nodes[cell.nodes.length - 1]
              if (!this.modules[id]) {
                this.supError = suplabel + item.name
              }
            })
          }
        } else if ((item.wrap && item.wrap.datatype === 'static') || (['mainsearch', 'voucher'].includes(item.subtype))) {
          if (item.wrap && item.wrap.supModule && item.wrap.supModule[0]) {
            let id = item.wrap.supModule[item.wrap.supModule.length - 1]
            if (!this.modules[id]) {
              this.supError = suplabel + item.name
            }
          }
        } else if (item.setting && item.setting.supModule && item.setting.supModule[0] !== 'empty') {
          let id = item.setting.supModule[item.setting.supModule.length - 1]
          if (!this.modules[id]) {
            this.supError = suplabel + item.name
          }
        }
        if (this.supError) return
        if (['card', 'carousel', 'timeline'].includes(item.type)) {
          item.subcards.forEach(card => {
            card.elements && card.elements.forEach(cell => {
              if (cell.eleType === 'button' && cell.OpenType === 'popview') {
                if (cell.config && cell.config.components && cell.config.enabled) {
                  this.checklink(cell.config.components, item.name + '-' + cell.label + '(弹窗标签)-')
                }
              }
            })
            card.backElements && card.backElements.forEach(cell => {
              if (cell.eleType === 'button' && cell.OpenType === 'popview') {
                if (cell.config && cell.config.components && cell.config.enabled) {
                  this.checklink(cell.config.components, item.name + '-' + cell.label + '(弹窗标签)-')
                }
              }
            })
          })
        } else if (item.type === 'balcony') {
          item.elements && item.elements.forEach(cell => {
            if (cell.eleType === 'button' && cell.OpenType === 'popview') {
              if (cell.config && cell.config.components && cell.config.enabled) {
                this.checklink(cell.config.components, item.name + '-' + cell.label + '(弹窗标签)-')
              }
            }
          })
        } 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' && cell.OpenType === 'popview') {
                    if (cell.config && cell.config.components && cell.config.enabled) {
                      this.checklink(cell.config.components, item.name + '-' + cell.label + '(弹窗标签)-')
                    }
                  }
                })
              }
            })
          }
          loopCol(item.cols)
        }
        item.action && item.action.forEach(cell => {
          if (cell.OpenType === 'popview') {
            if (cell.config && cell.config.components && cell.config.enabled) {
              this.checklink(cell.config.components, item.name + '-' + cell.label + '(弹窗标签)-')
            }
          }
        })
      }
    })
  }
  filterComponent = (components, mainSearch, regs, process, ispop = false) => {
@@ -783,6 +925,11 @@
            writein: item.writein !== 'false',
            type: item.type
          }
          if (item.type === 'linkMain' && item.verifyVal === 'true') {
            _item.$verify = true
            _item.label = item.label
          }
    
          if (_item.type === 'datemonth') {
            _item.type = 'text'
@@ -832,6 +979,11 @@
            writein: item.writein !== 'false',
            type: item.type
          }
          if (item.type === 'linkMain' && item.verifyVal === 'true') {
            _item.$verify = true
            _item.label = item.label
          }
    
          if (_item.type === 'datemonth') {
            _item.type = 'text'
@@ -869,8 +1021,20 @@
        key: 'mk_n_id'
      })
    }
    let verifyValSql = ''
    // 获取字段键值对
    formdata && formdata.forEach(form => {
      if (form.$verify) {
        verifyValSql += `
        if @${form.key}=${form.type === 'number' ? 0 : `''`}
        begin
          select @errorcode='E',@retmsg='${form.label},关联主表失效'
          goto aaa
        end
        `
      }
      let _key = form.key.toLowerCase()
      if (!_initvars.includes(_key)) {
        _initvars.push(_key)
@@ -1111,22 +1275,21 @@
  
      verify.billcodes.forEach(item => {
        let _key = item.field.toLowerCase()
        let _linkKey = item.linkField ? item.linkField.toLowerCase() : ''
  
        if (!keys.includes(_key)) return // 表单中不含单号生成字段
  
        let _lpline = ''
        if (item.TypeCharOne === 'Lp') {
          if (_linkKey === 'bid' && BID) { // 替换bid
          if (/^BID$/ig.test(item.linkField)) {
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@BID@,48)`
          } else {
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${_linkKey},48)`
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${item.linkField},48)`
          }
        } else if (item.TypeCharOne === 'BN') {
          if (_linkKey === 'bid' && BID) { // 替换bid
          if (/^BID$/ig.test(item.linkField)) {
            _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
          } else {
            _lpline = `set @ModularDetailCode= 'BN'+ right(@${_linkKey},48)`
            _lpline = `set @ModularDetailCode= 'BN'+ right(@${item.linkField},48)`
          }
        } else {
          _lpline = `set @ModularDetailCode= right('${item.ModularDetailCode}',50)`
@@ -1236,15 +1399,20 @@
    let hasvoucher = false
  
    // 凭证-显示列中选取,必须选行
    if (verify.voucher && verify.voucher.enabled && btn.Ot !== 'requiredOnce') {
    if (verify.voucher && verify.voucher.enabled) {
      let _voucher = verify.voucher
      let linkField = `@${_voucher.linkField}`
  
      if (/^BID$/ig.test(_voucher.linkField)) {
        linkField = `'${BID}'`
      }
      hasvoucher = true
  
      _sql += `
        /* 创建凭证 */
        exec s_BVoucher_Create
          @Bill = @${_voucher.linkField},
          @Bill = ${linkField},
          @BVoucherType ='${_voucher.BVoucherType}',
          @VoucherTypeOne ='${_voucher.VoucherTypeOne}',
          @VoucherTypeTwo ='${_voucher.VoucherTypeTwo}',
@@ -1507,6 +1675,10 @@
      }
    } else if (_backCustomScript) {
      _sql += _backCustomScript
    }
    if (verifyValSql) {
      _sql += verifyValSql
    }
  
    if (btn.procMode === 'system') {
@@ -1937,6 +2109,7 @@
        let _fields = unique.field.split(',')
        let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
        _fields_ = _fields_.join(' and ')
        _fields_ += ` and a.jskey != b.${setting.primaryKey || 'id'}`
        let _where = []
        _fields.forEach(f => {
@@ -1993,6 +2166,7 @@
    let declarefields = []
    let fields = []
    let upFields = []
    forms.forEach(col => {
      let key = col.field.toLowerCase()
@@ -2000,15 +2174,27 @@
      declarefields.push(`${col.field} ${col.datatype}`)
      fields.push(col.field)
      upFields.push(`${col.field}=t.${col.field}`)
    })
    fields = fields.join(',')
    upFields = upFields.join(',')
    let _insert = ''
    if (btn.default !== 'false') {
      _insert = `
      /* 默认sql */
      Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid)
      update a set ${upFields},modifydate=getdate(),modifyuserid='${sessionStorage.getItem('UserID') || ''}',modifyuser=@username,modifystaff=@fullname,deleted=0
      from (select * from #${sheet} where data_type='upt') t
      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
      update a set deleted=1,modifydate=getdate(),modifyuserid='${sessionStorage.getItem('UserID') || ''}',modifyuser=@username,modifystaff=@fullname
      from (select * from #${sheet} where data_type='del') t
      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
      delete t from #${sheet} t inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
      Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid)
      Select ${fields},'${sessionStorage.getItem('UserID') || ''}',@username,@fullname,'${BID}' From #${sheet}
      `
    }
src/menu/lowerField/index.jsx
New file
@@ -0,0 +1,321 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Modal, Button, notification } from 'antd'
import { VerticalRightOutlined } from '@ant-design/icons'
// import './index.scss'
const { confirm } = Modal
class LowerField extends Component {
  static propTpyes = {
    config: PropTypes.object,
    updateConfig: PropTypes.func
  }
  trigger = () => {
    const that = this
    confirm({
      content: `确定将字段转为小写吗?`,
      onOk() {
        that.exec()
      },
      onCancel() {}
    })
  }
  exec = () => {
    let config = fromJS(this.props.config).toJS()
    let resetElement = (m) => {
      if (m.datatype === 'dynamic' && m.field) {
        m.field = m.field.toLowerCase()
      }
      if (m.posterField) {
        m.posterField = m.posterField.toLowerCase()
      }
      if (m.bgImage) {
        m.bgImage = m.bgImage.toLowerCase()
      }
      if (m.linkurl && /^[a-zA-Z0-9_]+$/.test(m.linkurl)) {
        m.linkurl = m.linkurl.toLowerCase()
      }
      if (m.modal && m.modal.fields) {
        m.modal.fields = m.modal.fields.map(col => {
          if (col.field) {
            col.field = col.field.toLowerCase()
          }
          if (col.type === 'split' && col.splitctrl) {
            col.splitctrl = col.splitctrl.toLowerCase()
          }
          return col
        })
      }
      if (m.verify) {
        if (m.verify.columns) {
          m.verify.columns = m.verify.columns.map(col => {
            if (col.Column) {
              col.Column = col.Column.toLowerCase()
            }
            return col
          })
        }
        if (m.verify.uniques) {
          m.verify.uniques = m.verify.uniques.map(col => {
            if (col.field) {
              col.field = col.field.split(',').map(_field => {
                if (_field === 'BID') return _field
                return _field.toLowerCase()
              }).join(',')
            }
            return col
          })
        }
        if (m.verify.accountfield && m.verify.accountfield !== 'BID') {
          m.verify.accountfield = m.verify.accountfield.toLowerCase()
        }
        if (m.verify.voucher && m.verify.voucher.linkField && m.verify.voucher.linkField !== 'BID') {
          m.verify.voucher.linkField = m.verify.voucher.linkField.toLowerCase()
        }
      }
      if (m.controlField) {
        m.controlField = m.controlField.toLowerCase()
      }
      if (m.config && m.config.components) {
        m.config.components = _replace(m.config.components)
      }
    }
    let _replace = (components) => {
      return components.map(item => {
        if (item.type === 'tabs') {
          item.subtabs.forEach(tab => {
            tab.components = _replace(tab.components)
          })
          return item
        } else if (item.type === 'group') {
          item.components = _replace(item.components)
          return item
        }
        if (item.columns) {
          item.columns = item.columns.map(col => {
            if (col.field) {
              col.field = col.field.toLowerCase()
            }
            return col
          })
        }
        if (item.setting && item.setting.primaryKey) {
          item.setting.primaryKey = item.setting.primaryKey.toLowerCase()
        }
        if (item.subColumns) {
          item.subColumns = item.subColumns.map(col => {
            if (col.field) {
              col.field = col.field.toLowerCase()
            }
            return col
          })
        }
        if (item.search) {
          if (item.type === 'topbar') {
            if (item.search.fields) {
              item.search.fields = item.search.fields.map(col => {
                if (col.field) {
                  col.field = col.field.toLowerCase()
                }
                return col
              })
            }
            if (item.search.groups) {
              item.search.groups = item.search.groups.map(group => {
                group.fields = group.fields.map(col => {
                  if (col.field) {
                    col.field = col.field.toLowerCase()
                  }
                  return col
                })
                return group
              })
            }
          } else if (Array.isArray(item.search)) {
            item.search = item.search.map(col => {
              if (col.field) {
                col.field = col.field.toLowerCase()
              }
              return col
            })
          }
        }
        if (item.action) {
          item.action.forEach(m => {
            resetElement(m)
          })
        }
        if (item.subcards) {
          item.subcards.forEach(card => {
            if (card.setting && card.setting.controlField) {
              card.setting.controlField = card.setting.controlField.toLowerCase()
            }
            if (card.elements) {
              card.elements = card.elements.map(m => {
                resetElement(m)
                return m
              })
            }
            if (card.backElements) {
              card.backElements = card.backElements.map(m => {
                resetElement(m)
                return m
              })
            }
            if (card.fields) {
              card.fields = card.fields.map(m => {
                if (m.field) {
                  m.field = m.field.toLowerCase()
                }
                if (m.type === 'split' && m.splitctrl) {
                  m.splitctrl = m.splitctrl.toLowerCase()
                }
                return m
              })
            }
          })
        }
        if (item.elements) {
          item.elements = item.elements.map(m => {
            resetElement(m)
            return m
          })
        }
        if (item.plot) {
          if (item.plot.Xaxis) {
            item.plot.Xaxis = item.plot.Xaxis.toLowerCase()
          }
          // 统计图
          if (item.plot.InfoValue) {
            item.plot.InfoValue = item.plot.InfoValue.toLowerCase()
          }
          if (item.plot.InfoType) {
            item.plot.InfoType = item.plot.InfoType.toLowerCase()
          }
          // 占比图
          if (item.plot.valueField) {
            item.plot.valueField = item.plot.valueField.toLowerCase()
          }
          if (item.plot.labelField) {
            item.plot.labelField = item.plot.labelField.toLowerCase()
          }
          // 饼图
          if (item.plot.type) {
            item.plot.type = item.plot.type.toLowerCase()
          }
          // 散点图
          if (item.plot.gender) {
            item.plot.gender = item.plot.gender.toLowerCase()
          }
          if (item.Yaxis) {
            if (Array.isArray(item.Yaxis)) {
              item.Yaxis = item.Yaxis.map(m => {
                if (m) return m.toLowerCase()
                return m
              })
            } else {
              if (item.Yaxis) {
                item.Yaxis = item.Yaxis.toLowerCase()
              }
            }
          }
        }
        if (item.cols) {
          let _update = (cols) => {
            return cols.map(col => {
              if (col.type === 'custom' && col.elements) {
                col.elements = col.elements.map(m => {
                  resetElement(m)
                  return m
                })
              } else if (col.type === 'colspan') {
                col.subcols = _update(col.subcols)
              } else if (col.field) {
                col.field = col.field.toLowerCase()
              }
              return col
            })
          }
          item.cols = _update(item.cols)
        }
        if (item.wrap) {
          if (item.wrap.tipField) {
            item.wrap.tipField = item.wrap.tipField.toLowerCase()
          }
          if (item.wrap.controlField) {
            item.wrap.controlField = item.wrap.controlField.toLowerCase()
          }
          if (item.wrap.valueField) {
            item.wrap.valueField = item.wrap.valueField.toLowerCase()
          }
          if (item.wrap.labelField) {
            item.wrap.labelField = item.wrap.labelField.toLowerCase()
          }
          if (item.wrap.parentField) {
            item.wrap.parentField = item.wrap.parentField.toLowerCase()
          }
          if (item.wrap.broadcast) {
            item.wrap.broadcast = item.wrap.broadcast.toLowerCase()
          }
          if (item.wrap.jumpField) {
            item.wrap.jumpField = item.wrap.jumpField.toLowerCase()
          }
          if (item.wrap.link) {
            item.wrap.link = item.wrap.link.toLowerCase()
          }
        }
        return item
      })
    }
    config.components = _replace(config.components)
    config.interfaces && config.interfaces.forEach(item => {
      if (item.columns) {
        item.columns = item.columns.map(col => {
          if (col.field) {
            col.field = col.field.toLowerCase()
          }
          return col
        })
      }
      if (item.setting && item.setting.primaryKey) {
        item.setting.primaryKey = item.setting.primaryKey.toLowerCase()
      }
    })
    notification.success({
      top: 92,
      message: '转换已完成。',
      duration: 3
    })
    this.props.updateConfig(config)
  }
  render() {
    return (
      <Button className="mk-border-purple" onClick={this.trigger}><VerticalRightOutlined style={{transform: 'rotate(270deg)'}}/> 字段转小写</Button>
    )
  }
}
export default LowerField
src/menu/lowerField/index.scss
src/menu/modalconfig/index.jsx
@@ -19,6 +19,7 @@
const MkIcon = asyncComponent(() => import('@/components/mk-icon'))
const TableComponent = asyncComponent(() => import('./tablecomponent'))
const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
const PasteForms = asyncComponent(() => import('@/menu/components/share/pasteforms'))
const FormFork = asyncComponent(() => import('@/menu/modalconfig/formfork'))
@@ -181,15 +182,21 @@
    })
  }
  submitConfig = () => {
  submitConfig = (type) => {
    const { config } = this.state
    this.setState({originConfig: fromJS(config).toJS(), saving: true})
    this.props.handleSave(config)
    if (type === 'cache') {
      this.setState({originConfig: fromJS(config).toJS()})
      this.props.handleSave(config)
    setTimeout(() => {
      MKEmitter.emit('triggerMenuSave')
    }, 100)
      message.success(<span>表单配置已保存至本地(<span style={{color: 'red'}}>尚未提交至云端</span>)。</span>)
    } else {
      this.setState({originConfig: fromJS(config).toJS(), saving: true})
      this.props.handleSave(config)
      setTimeout(() => {
        MKEmitter.emit('triggerMenuSave')
      }, 100)
    }
  }
  clearConfig = () => {
@@ -378,6 +385,7 @@
            <Collapse accordion defaultActiveKey="1" bordered={false}>
              <Panel header="基本信息" key="0">
                <TableComponent />
                <NormalCopy />
              </Panel>
              <Panel header="表单" key="1">
                <div className="search-element">
@@ -392,8 +400,9 @@
          <div className="setting">
            <Card title="表单配置" bordered={false} extra={
              <div>
                <Button className="mk-border-green" onClick={() => this.submitConfig('cache')}>存草稿</Button>
                <PasteForms type="toolbar" config={config} update={this.pasteFields}/>
                <Button type="primary" id="save-modal-config" loading={saving} onClick={this.submitConfig}>保存</Button>
                <Button type="primary" id="save-modal-config" loading={saving} onClick={() => this.submitConfig()}>保存</Button>
                <Button disabled={saving} onClick={this.cancelConfig}>返回</Button>
              </div>
            } style={{ width: '100%' }}>
src/menu/normalCopy/index.jsx
New file
@@ -0,0 +1,33 @@
import React, { Component } from 'react'
import { Radio } from 'antd'
import './index.scss'
class NormalCopy extends Component {
  state = {
    value: window.GLOB.CopyOnly === true ? 'true' : 'false'
  }
  selectChange = (val) => {
    if (val === 'true') {
      window.GLOB.CopyOnly = true
    } else {
      window.GLOB.CopyOnly = false
    }
  }
  render() {
    const { value } = this.state
    return (
      <div className="mk-normal-copy">
        元素复制:<Radio.Group defaultValue={value} onChange={(e) => {this.selectChange(e.target.value)}}>
          <Radio value="true">仅复制</Radio>
          <Radio value="false">复制+自增</Radio>
        </Radio.Group>
      </div>
    )
  }
}
export default NormalCopy
src/menu/normalCopy/index.scss
New file
@@ -0,0 +1,21 @@
.mk-normal-copy {
  padding-left: 18px;
  white-space: nowrap;
  .ant-radio-wrapper {
    margin-right: 2px;
  }
}
.model-tablename-manage-view + .mk-normal-copy {
  margin-top: 15px;
}
.modal-form-board, .mob-form-board {
  .mk-normal-copy {
    padding-left: 0px;
    span.ant-radio + * {
      padding-right: 2px;
      padding-left: 2px;
    }
  }
}
src/menu/normalCss/index.scss
@@ -1,5 +1,6 @@
.mk-normal-css {
  padding-left: 18px;
  margin-bottom: 15px;
  .anticon-edit {
    color: #1890ff;
src/menu/pastecontroller/index.jsx
@@ -274,6 +274,9 @@
        }
      } else {
        options.push('editable', 'mainsearch', 'antvG6', 'antvX6', 'calendar', 'tree', 'dashboard', 'chart')
        if (appType !== 'pc') {
          options.push('account')
        }
      }
    } else {
      if (appType === 'mob') {
src/menu/replaceField/index.jsx
@@ -12,7 +12,6 @@
class ReplaceField extends Component {
  static propTpyes = {
    type: PropTypes.string,
    config: PropTypes.object,
    updateConfig: PropTypes.func
  }
@@ -155,305 +154,281 @@
  // 依据原字段替换为新字段
  exec = (map) => {
    const { type } = this.props
    let config = fromJS(this.props.config).toJS()
    if (type === 'custom') {
      let _replace = (components) => {
        return components.map(item => {
          if (item.type === 'tabs') {
            item.subtabs.forEach(tab => {
              tab.components = _replace(tab.components)
            })
            return item
          } else if (item.type === 'group') {
            item.components = _replace(item.components)
            return item
          }
          if (item.columns) {
            item.columns = item.columns.map(col => {
              let cell = map[col.field.toLowerCase()]
              if (cell) {
                col.field = cell.FieldName
                if (cell.datatype) {
                  col.datatype = cell.datatype
    let _replace = (components) => {
      return components.map(item => {
        if (item.type === 'tabs') {
          item.subtabs.forEach(tab => {
            tab.components = _replace(tab.components)
          })
          return item
        } else if (item.type === 'group') {
          item.components = _replace(item.components)
          return item
        }
        if (item.columns) {
          item.columns = item.columns.map(col => {
            let cell = map[col.field.toLowerCase()]
            if (cell) {
              col.field = cell.FieldName
              if (cell.datatype) {
                col.datatype = cell.datatype
              }
            }
            return col
          })
        }
        if (item.search) {
          item.search = item.search.map(col => {
            if (col.field && map[col.field.toLowerCase()]) {
              col.field = map[col.field.toLowerCase()].FieldName
            }
            return col
          })
        }
        if (item.action) {
          item.action.forEach(m => {
            if (m.modal && m.modal.fields) {
              m.modal.fields = m.modal.fields.map(col => {
                if (col.field && map[col.field.toLowerCase()]) {
                  col.field = map[col.field.toLowerCase()].FieldName
                }
              }
              return col
            })
          }
          if (item.search) {
            item.search = item.search.map(col => {
              if (col.field && map[col.field.toLowerCase()]) {
                col.field = map[col.field.toLowerCase()].FieldName
              }
              return col
            })
          }
          if (item.action) {
            item.action.forEach(m => {
              if (m.modal && m.modal.fields) {
                m.modal.fields = m.modal.fields.map(col => {
                  if (col.field && map[col.field.toLowerCase()]) {
                    col.field = map[col.field.toLowerCase()].FieldName
                  }
                  return col
                })
              }
              if (m.verify && m.verify.columns) {
                m.verify.columns = m.verify.columns.map(col => {
                  if (col.Column && map[col.Column.toLowerCase()]) {
                    col.Column = map[col.Column.toLowerCase()].FieldName
                  }
                  return col
                })
              }
              if (m.config && m.config.components) {
                m.config.components = _replace(m.config.components)
              }
            })
          }
          if (item.subcards) {
            item.subcards.forEach(card => {
              if (card.elements) { // 卡片
                card.elements = card.elements.map(m => {
                  if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
                    m.field = map[m.field.toLowerCase()].FieldName
                  }
                  if (m.modal && m.modal.fields) {
                    m.modal.fields = m.modal.fields.map(col => {
                      if (col.field && map[col.field.toLowerCase()]) {
                        col.field = map[col.field.toLowerCase()].FieldName
                      }
                      return col
                    })
                  }
                  if (m.verify && m.verify.columns) {
                    m.verify.columns = m.verify.columns.map(col => {
                      if (col.Column && map[col.Column.toLowerCase()]) {
                        col.Column = map[col.Column.toLowerCase()].FieldName
                      }
                      return col
                    })
                  }
                  if (m.config && m.config.components) {
                    m.config.components = _replace(m.config.components)
                  }
                  return m
                })
              }
              if (card.backElements) { // 卡片
                card.backElements = card.backElements.map(m => {
                  if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
                    m.field = map[m.field.toLowerCase()].FieldName
                  }
                  if (m.modal && m.modal.fields) {
                    m.modal.fields = m.modal.fields.map(col => {
                      if (col.field && map[col.field.toLowerCase()]) {
                        col.field = map[col.field.toLowerCase()].FieldName
                      }
                      return col
                    })
                  }
                  if (m.verify && m.verify.columns) {
                    m.verify.columns = m.verify.columns.map(col => {
                      if (col.Column && map[col.Column.toLowerCase()]) {
                        col.Column = map[col.Column.toLowerCase()].FieldName
                      }
                      return col
                    })
                  }
                  if (m.config && m.config.components) {
                    m.config.components = _replace(m.config.components)
                  }
                  return m
                })
              }
              if (card.fields) { // 表单
                card.fields = card.fields.map(m => {
                  if (m.field && map[m.field.toLowerCase()]) {
                    m.field = map[m.field.toLowerCase()].FieldName
                  }
                  return m
                })
              }
            })
          }
          if (item.elements) {
            item.elements = item.elements.map(m => {
              if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
                m.field = map[m.field.toLowerCase()].FieldName
              }
              if (m.modal && m.modal.fields) {
                m.modal.fields = m.modal.fields.map(col => {
                  if (col.field && map[col.field.toLowerCase()]) {
                    col.field = map[col.field.toLowerCase()].FieldName
                  }
                  return col
                })
              }
              if (m.verify && m.verify.columns) {
                m.verify.columns = m.verify.columns.map(col => {
                  if (col.Column && map[col.Column.toLowerCase()]) {
                    col.Column = map[col.Column.toLowerCase()].FieldName
                  }
                  return col
                })
              }
              if (m.config && m.config.components) {
                m.config.components = _replace(m.config.components)
              }
              return m
            })
          }
          if (item.plot) {
            if (item.plot.Xaxis && map[item.plot.Xaxis.toLowerCase()]) {
              item.plot.Xaxis = map[item.plot.Xaxis.toLowerCase()].FieldName
            }
            // 统计图
            if (item.plot.InfoValue && map[item.plot.InfoValue.toLowerCase()]) {
              item.plot.InfoValue = map[item.plot.InfoValue.toLowerCase()].FieldName
            }
            if (item.plot.InfoType && map[item.plot.InfoType.toLowerCase()]) {
              item.plot.InfoType = map[item.plot.InfoType.toLowerCase()].FieldName
            }
            // 占比图
            if (item.plot.valueField && map[item.plot.valueField.toLowerCase()]) {
              item.plot.valueField = map[item.plot.valueField.toLowerCase()].FieldName
            }
            if (item.plot.labelField && map[item.plot.labelField.toLowerCase()]) {
              item.plot.labelField = map[item.plot.labelField.toLowerCase()].FieldName
            }
            // 饼图
            if (item.plot.type && map[item.plot.type.toLowerCase()]) {
              item.plot.type = map[item.plot.type.toLowerCase()].FieldName
            }
            // 散点图
            if (item.plot.gender && map[item.plot.gender.toLowerCase()]) {
              item.plot.gender = map[item.plot.gender.toLowerCase()].FieldName
            }
            if (item.Yaxis) {
              if (Array.isArray(item.Yaxis)) {
                item.Yaxis = item.Yaxis.map(m => {
                  if (map[m.toLowerCase()]) {
                    return map[m.toLowerCase()].FieldName
                  }
                  return m
                })
              } else {
                if (item.Yaxis && map[item.Yaxis.toLowerCase()]) {
                  item.Yaxis = map[item.Yaxis.toLowerCase()].FieldName
                }
              }
            }
          }
          if (item.cols) {
            let _update = (cols) => {
              return cols.map(col => {
                if (col.type === 'custom' && col.elements) {
                  col.elements = col.elements.map(m => {
                    if (m.eleType === 'button') {
                      if (m.modal && m.modal.fields) {
                        m.modal.fields = m.modal.fields.map(col => {
                          if (col.field && map[col.field.toLowerCase()]) {
                            col.field = map[col.field.toLowerCase()].FieldName
                          }
                          return col
                        })
                      }
                      if (m.verify && m.verify.columns) {
                        m.verify.columns = m.verify.columns.map(col => {
                          if (col.Column && map[col.Column.toLowerCase()]) {
                            col.Column = map[col.Column.toLowerCase()].FieldName
                          }
                          return col
                        })
                      }
                      if (m.config && m.config.components) {
                        m.config.components = _replace(m.config.components)
                      }
                    } else {
                      if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
                        m.field = map[m.field.toLowerCase()].FieldName
                      }
                    }
                    return m
                  })
                } else if (col.type === 'colspan') {
                  col.subcols = _update(col.subcols)
                } else if (col.field) {
                  if (map[col.field.toLowerCase()]) {
                    col.field = map[col.field.toLowerCase()].FieldName
                  }
                }
                return col
              })
            }
            if (m.verify && m.verify.columns) {
              m.verify.columns = m.verify.columns.map(col => {
                if (col.Column && map[col.Column.toLowerCase()]) {
                  col.Column = map[col.Column.toLowerCase()].FieldName
                }
                return col
              })
            }
            if (m.config && m.config.components) {
              m.config.components = _replace(m.config.components)
            }
          })
        }
            item.cols = _update(item.cols)
        if (item.subcards) {
          item.subcards.forEach(card => {
            if (card.elements) { // 卡片
              card.elements = card.elements.map(m => {
                if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
                  m.field = map[m.field.toLowerCase()].FieldName
                }
                if (m.modal && m.modal.fields) {
                  m.modal.fields = m.modal.fields.map(col => {
                    if (col.field && map[col.field.toLowerCase()]) {
                      col.field = map[col.field.toLowerCase()].FieldName
                    }
                    return col
                  })
                }
                if (m.verify && m.verify.columns) {
                  m.verify.columns = m.verify.columns.map(col => {
                    if (col.Column && map[col.Column.toLowerCase()]) {
                      col.Column = map[col.Column.toLowerCase()].FieldName
                    }
                    return col
                  })
                }
                if (m.config && m.config.components) {
                  m.config.components = _replace(m.config.components)
                }
                return m
              })
            }
            if (card.backElements) { // 卡片
              card.backElements = card.backElements.map(m => {
                if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
                  m.field = map[m.field.toLowerCase()].FieldName
                }
                if (m.modal && m.modal.fields) {
                  m.modal.fields = m.modal.fields.map(col => {
                    if (col.field && map[col.field.toLowerCase()]) {
                      col.field = map[col.field.toLowerCase()].FieldName
                    }
                    return col
                  })
                }
                if (m.verify && m.verify.columns) {
                  m.verify.columns = m.verify.columns.map(col => {
                    if (col.Column && map[col.Column.toLowerCase()]) {
                      col.Column = map[col.Column.toLowerCase()].FieldName
                    }
                    return col
                  })
                }
                if (m.config && m.config.components) {
                  m.config.components = _replace(m.config.components)
                }
                return m
              })
            }
            if (card.fields) { // 表单
              card.fields = card.fields.map(m => {
                if (m.field && map[m.field.toLowerCase()]) {
                  m.field = map[m.field.toLowerCase()].FieldName
                }
                return m
              })
            }
          })
        }
        if (item.elements) {
          item.elements = item.elements.map(m => {
            if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
              m.field = map[m.field.toLowerCase()].FieldName
            }
            if (m.modal && m.modal.fields) {
              m.modal.fields = m.modal.fields.map(col => {
                if (col.field && map[col.field.toLowerCase()]) {
                  col.field = map[col.field.toLowerCase()].FieldName
                }
                return col
              })
            }
            if (m.verify && m.verify.columns) {
              m.verify.columns = m.verify.columns.map(col => {
                if (col.Column && map[col.Column.toLowerCase()]) {
                  col.Column = map[col.Column.toLowerCase()].FieldName
                }
                return col
              })
            }
            if (m.config && m.config.components) {
              m.config.components = _replace(m.config.components)
            }
            return m
          })
        }
        if (item.plot) {
          if (item.plot.Xaxis && map[item.plot.Xaxis.toLowerCase()]) {
            item.plot.Xaxis = map[item.plot.Xaxis.toLowerCase()].FieldName
          }
          if (item.subtype === 'basetable') {
            item.cols = item.cols.map(col => {
              if (col.field && map[col.field.toLowerCase()]) {
                col.field = map[col.field.toLowerCase()].FieldName
          // 统计图
          if (item.plot.InfoValue && map[item.plot.InfoValue.toLowerCase()]) {
            item.plot.InfoValue = map[item.plot.InfoValue.toLowerCase()].FieldName
          }
          if (item.plot.InfoType && map[item.plot.InfoType.toLowerCase()]) {
            item.plot.InfoType = map[item.plot.InfoType.toLowerCase()].FieldName
          }
          // 占比图
          if (item.plot.valueField && map[item.plot.valueField.toLowerCase()]) {
            item.plot.valueField = map[item.plot.valueField.toLowerCase()].FieldName
          }
          if (item.plot.labelField && map[item.plot.labelField.toLowerCase()]) {
            item.plot.labelField = map[item.plot.labelField.toLowerCase()].FieldName
          }
          // 饼图
          if (item.plot.type && map[item.plot.type.toLowerCase()]) {
            item.plot.type = map[item.plot.type.toLowerCase()].FieldName
          }
          // 散点图
          if (item.plot.gender && map[item.plot.gender.toLowerCase()]) {
            item.plot.gender = map[item.plot.gender.toLowerCase()].FieldName
          }
          if (item.Yaxis) {
            if (Array.isArray(item.Yaxis)) {
              item.Yaxis = item.Yaxis.map(m => {
                if (map[m.toLowerCase()]) {
                  return map[m.toLowerCase()].FieldName
                }
                return m
              })
            } else {
              if (item.Yaxis && map[item.Yaxis.toLowerCase()]) {
                item.Yaxis = map[item.Yaxis.toLowerCase()].FieldName
              }
            }
          }
        }
        if (item.cols) {
          let _update = (cols) => {
            return cols.map(col => {
              if (col.type === 'custom' && col.elements) {
                col.elements = col.elements.map(m => {
                  if (m.eleType === 'button') {
                    if (m.modal && m.modal.fields) {
                      m.modal.fields = m.modal.fields.map(col => {
                        if (col.field && map[col.field.toLowerCase()]) {
                          col.field = map[col.field.toLowerCase()].FieldName
                        }
                        return col
                      })
                    }
                    if (m.verify && m.verify.columns) {
                      m.verify.columns = m.verify.columns.map(col => {
                        if (col.Column && map[col.Column.toLowerCase()]) {
                          col.Column = map[col.Column.toLowerCase()].FieldName
                        }
                        return col
                      })
                    }
                    if (m.config && m.config.components) {
                      m.config.components = _replace(m.config.components)
                    }
                  } else {
                    if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
                      m.field = map[m.field.toLowerCase()].FieldName
                    }
                  }
                  return m
                })
              } else if (col.type === 'colspan') {
                col.subcols = _update(col.subcols)
              } else if (col.field) {
                if (map[col.field.toLowerCase()]) {
                  col.field = map[col.field.toLowerCase()].FieldName
                }
              }
              return col
            })
          }
          return item
        })
      }
      config.components = _replace(config.components)
    // } else if (type === 'table') {
    //   config.columns = config.columns.map(col => {
    //     if (col.field && map[col.field.toLowerCase()]) {
    //       col.field = map[col.field.toLowerCase()].FieldName
    //     }
    //     return col
    //   })
    //   config.search = config.search.map(col => {
    //     if (col.field && map[col.field.toLowerCase()]) {
    //       col.field = map[col.field.toLowerCase()].FieldName
    //     }
    //     if (col.datefield && map[col.datefield.toLowerCase()]) {
    //       col.datefield = map[col.datefield.toLowerCase()].FieldName
    //     }
    //     return col
    //   })
    //   config.action = config.action.map(m => {
    //     if (m.verify && m.verify.columns) {
    //       m.verify.columns = m.verify.columns.map(col => {
    //         if (col.Column && map[col.Column.toLowerCase()]) {
    //           col.Column = map[col.Column.toLowerCase()].FieldName
    //         }
    //         return col
    //       })
    //     }
    //     return m
    //   })
    } else if (type === 'form') {
      config.fields = config.fields.map(col => {
        if (col.field && map[col.field.toLowerCase()]) {
          col.field = map[col.field.toLowerCase()].FieldName
          item.cols = _update(item.cols)
        }
        return col
        if (item.subtype === 'basetable') {
          item.cols = item.cols.map(col => {
            if (col.field && map[col.field.toLowerCase()]) {
              col.field = map[col.field.toLowerCase()].FieldName
            }
            return col
          })
        }
        return item
      })
    }
    config.components = _replace(config.components)
    config.interfaces && config.interfaces.forEach(item => {
      if (item.columns) {
        item.columns = item.columns.map(col => {
          let cell = map[col.field.toLowerCase()]
          if (cell) {
            col.field = cell.FieldName
            if (cell.datatype) {
              col.datatype = cell.datatype
            }
          }
          return col
        })
      }
    })
    this.setState({
      confirming: false,
@@ -470,156 +445,131 @@
  // 依据字段替换名称
  execLabel = (map) => {
    const { type } = this.props
    let config = fromJS(this.props.config).toJS()
    if (type === 'custom') {
      let _replace = (components) => {
        return components.map(item => {
          if (item.type === 'tabs') {
            item.subtabs.forEach(tab => {
              tab.components = _replace(tab.components)
            })
            return item
          } else if (item.type === 'group') {
            item.components = _replace(item.components)
            return item
          }
          if (item.columns) {
            item.columns = item.columns.map(col => {
              if (col.field && map[col.field.toLowerCase()]) {
                col.label = map[col.field.toLowerCase()].FieldDec
              }
              return col
            })
          }
          if (item.search) {
            item.search = item.search.map(col => {
              if (col.field && map[col.field.toLowerCase()]) {
                col.label = map[col.field.toLowerCase()].FieldDec
              }
              return col
            })
          }
    let _replace = (components) => {
      return components.map(item => {
        if (item.type === 'tabs') {
          item.subtabs.forEach(tab => {
            tab.components = _replace(tab.components)
          })
          return item
        } else if (item.type === 'group') {
          item.components = _replace(item.components)
          return item
        }
        if (item.columns) {
          item.columns = item.columns.map(col => {
            if (col.field && map[col.field.toLowerCase()]) {
              col.label = map[col.field.toLowerCase()].FieldDec
            }
            return col
          })
        }
        if (item.search) {
          item.search = item.search.map(col => {
            if (col.field && map[col.field.toLowerCase()]) {
              col.label = map[col.field.toLowerCase()].FieldDec
            }
            return col
          })
        }
          if (item.action) {
            item.action.forEach(m => {
              if (m.modal && m.modal.fields) {
                m.modal.fields = m.modal.fields.map(col => {
                  if (col.field && map[col.field.toLowerCase()]) {
                    col.label = map[col.field.toLowerCase()].FieldDec
                  }
                  return col
                })
              }
              if (m.verify && m.verify.columns) {
                m.verify.columns = m.verify.columns.map(col => {
                  if (col.Column && map[col.Column.toLowerCase()]) {
                    col.Text = map[col.Column.toLowerCase()].FieldDec
                  }
                  return col
                })
              }
              if (m.config && m.config.components) {
                m.config.components = _replace(m.config.components)
              }
            })
          }
          if (item.cols) {
            let _update = (cols) => {
              return cols.map(col => {
                if (col.type === 'custom' && col.elements) {
                  col.elements = col.elements.map(m => {
                    if (m.eleType === 'button') {
                      if (m.modal && m.modal.fields) {
                        m.modal.fields = m.modal.fields.map(col => {
                          if (col.field && map[col.field.toLowerCase()]) {
                            col.label = map[col.field.toLowerCase()].FieldDec
                          }
                          return col
                        })
                      }
                      if (m.verify && m.verify.columns) {
                        m.verify.columns = m.verify.columns.map(col => {
                          if (col.Column && map[col.Column.toLowerCase()]) {
                            col.Text = map[col.Column.toLowerCase()].FieldDec
                          }
                          return col
                        })
                      }
                      if (m.config && m.config.components) {
                        m.config.components = _replace(m.config.components)
                      }
                    }
                    return m
                  })
                } else if (col.type === 'colspan') {
                  col.subcols = _update(col.subcols)
                } else if (col.field) {
                  if (map[col.field.toLowerCase()]) {
                    col.label = map[col.field.toLowerCase()].FieldDec
                  }
        if (item.action) {
          item.action.forEach(m => {
            if (m.modal && m.modal.fields) {
              m.modal.fields = m.modal.fields.map(col => {
                if (col.field && map[col.field.toLowerCase()]) {
                  col.label = map[col.field.toLowerCase()].FieldDec
                }
                return col
              })
            }
            if (m.verify && m.verify.columns) {
              m.verify.columns = m.verify.columns.map(col => {
                if (col.Column && map[col.Column.toLowerCase()]) {
                  col.Text = map[col.Column.toLowerCase()].FieldDec
                }
                return col
              })
            }
            if (m.config && m.config.components) {
              m.config.components = _replace(m.config.components)
            }
          })
        }
            item.cols = _update(item.cols)
          }
        if (item.cols) {
          let _update = (cols) => {
            return cols.map(col => {
              if (col.type === 'custom' && col.elements) {
                col.elements = col.elements.map(m => {
                  if (m.eleType === 'button') {
                    if (m.modal && m.modal.fields) {
                      m.modal.fields = m.modal.fields.map(col => {
                        if (col.field && map[col.field.toLowerCase()]) {
                          col.label = map[col.field.toLowerCase()].FieldDec
                        }
                        return col
                      })
                    }
                    if (m.verify && m.verify.columns) {
                      m.verify.columns = m.verify.columns.map(col => {
                        if (col.Column && map[col.Column.toLowerCase()]) {
                          col.Text = map[col.Column.toLowerCase()].FieldDec
                        }
                        return col
                      })
                    }
                    if (m.config && m.config.components) {
                      m.config.components = _replace(m.config.components)
                    }
                  }
          if (item.subtype === 'basetable') {
            item.cols = item.cols.map(col => {
              if (col.field && map[col.field.toLowerCase()]) {
                col.label = map[col.field.toLowerCase()].FieldDec
                  return m
                })
              } else if (col.type === 'colspan') {
                col.subcols = _update(col.subcols)
              } else if (col.field) {
                if (map[col.field.toLowerCase()]) {
                  col.label = map[col.field.toLowerCase()].FieldDec
                }
              }
              return col
            })
          }
          return item
        })
      }
      config.components = _replace(config.components)
    // } else if (type === 'table') {
    //   config.columns = config.columns.map(col => {
    //     if (col.field && map[col.field.toLowerCase()]) {
    //       col.label = map[col.field.toLowerCase()].FieldDec
    //     }
    //     return col
    //   })
    //   config.search = config.search.map(col => {
    //     if (col.field && map[col.field.toLowerCase()]) {
    //       col.label = map[col.field.toLowerCase()].FieldDec
    //     }
    //     return col
    //   })
    //   config.action = config.action.map(m => {
    //     if (m.verify && m.verify.columns) {
    //       m.verify.columns = m.verify.columns.map(col => {
    //         if (col.Column && map[col.Column.toLowerCase()]) {
    //           col.Text = map[col.Column.toLowerCase()].FieldDec
    //         }
    //         return col
    //       })
    //     }
    //     return m
    //   })
    } else if (type === 'form') {
      config.fields = config.fields.map(col => {
        if (col.field && map[col.field.toLowerCase()]) {
          col.label = map[col.field.toLowerCase()].FieldDec
          item.cols = _update(item.cols)
        }
        return col
        if (item.subtype === 'basetable') {
          item.cols = item.cols.map(col => {
            if (col.field && map[col.field.toLowerCase()]) {
              col.label = map[col.field.toLowerCase()].FieldDec
            }
            return col
          })
        }
        return item
      })
    }
    config.components = _replace(config.components)
    config.interfaces && config.interfaces.forEach(item => {
      if (item.columns) {
        item.columns = item.columns.map(col => {
          if (col.field && map[col.field.toLowerCase()]) {
            col.label = map[col.field.toLowerCase()].FieldDec
          }
          return col
        })
      }
    })
    this.setState({
      confirming: false,
      visible: false
src/menu/stylecombcontrolbutton/index.scss
@@ -7,7 +7,7 @@
  background: #ffffff;
}
body.style-control {
  .pc-menu-view::before, .menu-control::before  {
  .menu-setting::before, .mk-opeartion-list::before  {
    content: ' ';
    position: absolute;
    left: 0;
@@ -17,26 +17,20 @@
    z-index: 12;
    background:rgba(0, 0, 0, 0.2);
  }
  .pc-poper-view::before {
    content: ' ';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    right: 0;
    z-index: 12;
    background:rgba(0, 0, 0, 0.2);
  .menu-setting .draw, .menu-control .draw {
    display: none;
  }
  .menu-body .menu-view >.ant-card >.ant-card-body {
    position: relative;
    z-index: 13;
    background:#ffffff;
  .style-control-button {
    z-index: 12;
  }
  .menu-view {
    .anticon-tool {
      display: none;
    }
  }
  .mk-pc-view .menu-setting {
    display: none;
  }
  .mk-mob-view .mob-shell {
    .anticon-tool {
      display: none;
src/mob/components/formdragelement/index.jsx
@@ -1,7 +1,7 @@
import React, { useState } from 'react'
import { useDrop } from 'react-dnd'
import { is, fromJS } from 'immutable'
import { Col } from 'antd'
import { Col, message } from 'antd'
import update from 'immutability-helper'
import Utils from '@/utils/utils.js'
import Card from './card'
@@ -72,11 +72,15 @@
    oInput.style.display = 'none'
    document.body.removeChild(oInput)
    const _cards = update(cards, { $splice: [[overIndex + 1, 0, _card]] })
    if (window.GLOB.CopyOnly) {
      message.success('复制成功。')
    } else {
      const _cards = update(cards, { $splice: [[overIndex + 1, 0, _card]] })
    setCards(_cards)
      setCards(_cards)
    handleList(_cards, _card)
      handleList(_cards, _card)
    }
  }
  const [, drop] = useDrop({
@@ -94,10 +98,14 @@
      newcard.options = []
      newcard.readonly = 'false'
      newcard.required = 'true'
      newcard.readin = 'top'
      newcard.span = 24
      newcard.focus = true
      if (item.subType === 'textarea') {
      if (item.subType === 'linkMain') {
        newcard.hidden = 'true'
        newcard.verifyVal = 'true'
      } else if (item.subType === 'textarea') {
        newcard.required = 'false'
      }
src/mob/modalconfig/index.jsx
@@ -18,6 +18,7 @@
const { confirm } = Modal
const TableComponent = asyncComponent(() => import('@/menu/modalconfig/tablecomponent'))
const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
const PasteForms = asyncComponent(() => import('@/menu/components/share/pasteforms'))
const DragElement = asyncComponent(() => import('@/mob/components/formdragelement'))
const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
@@ -339,6 +340,7 @@
            <Collapse accordion defaultActiveKey="1" bordered={false}>
              <Panel header="基本信息" key="0">
                <TableComponent />
                <NormalCopy/>
              </Panel>
              <Panel header="表单" key="1">
                <div className="search-element">
src/pc/components/login/normal-login/options.jsx
@@ -264,7 +264,6 @@
          dataIndex: 'link',
          inputType: 'input',
          editable: true,
          unique: true,
          required: true,
          width: '40%'
        },
src/tabviews/basetable/index.jsx
@@ -39,7 +39,8 @@
    userConfig: null,     // 用户自定义设置
    visible: false,       // 标签页控制
    shortcuts: null,      // 快捷键
    autoMatic: null
    autoMatic: null,
    noParam: false
  }
  /**
@@ -47,6 +48,7 @@
   */
  async loadconfig () {
    const { MenuID, MenuName, param } = this.props
    const { noParam } = this.state
    let _param = {
      func: 'sPC_Get_LongParam',
@@ -164,13 +166,17 @@
      let skip = window.GLOB.mkHS
      let urlparam = {} // url参数
      if (param) {
        Object.keys(param).forEach(key => {
          if (/^\$/.test(key)) {
            urlparam[key] = param[key]
          } else {
            urlparam[key.toLowerCase()] = param[key]
          }
        })
        if (!noParam) {
          Object.keys(param).forEach(key => {
            if (/^\$/.test(key)) {
              urlparam[key] = param[key]
            } else {
              urlparam[key.toLowerCase()] = param[key]
            }
          })
        } else {
          urlparam.$BID = param.$BID
        }
      }
      window.GLOB.CacheData.set(MenuID, urlparam)
@@ -712,12 +718,12 @@
    })
  }
  reloadMenuView = (menuId) => {
  reloadMenuView = (menuId, clear) => {
    const { MenuID } = this.props
    if (MenuID !== menuId) return
    this.reloadview()
    this.reloadview(clear)
  }
  resetActiveMenu = (menuId) => {
@@ -779,7 +785,7 @@
    })
  }
  reloadview = () => {
  reloadview = (clear) => {
    window.GLOB.CacheData.delete(this.props.MenuID)
    if (this.state.config) {
      this.deleteCache(this.state.config.components)
@@ -791,6 +797,7 @@
      viewlost: false,      // 页面丢失:1、未获取到配置-页面丢失;2、页面未启用
      config: null,         // 页面配置信息,包括组件等
      shortcuts: null,
      noParam: clear === true
    }, () => {
      this.loadconfig()
    })
src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -224,7 +224,7 @@
      return
    }
    
    if (/^http.+(.txt|.doc|.docx|.pdf|.xlsx|.xls|.zip|.rar|.ppt)$/i.test(url) || card.linkType === 'download') {
    if (/^(http|\/\/).+(.txt|.doc|.docx|.pdf|.xlsx|.xls|.zip|.rar|.ppt)$/i.test(url) || card.linkType === 'download') {
      let name = ''
      if (card.datatype === 'static') {
        name = card.value || ''
@@ -450,7 +450,7 @@
              url = data[card.linkurl]
            }
  
            if (/^http.+(.txt|.doc|.docx|.pdf|.xlsx|.xls|.zip|.rar)$/i.test(url)) {
            if (/^(http|\/\/).+(.txt|.doc|.docx|.pdf|.xlsx|.xls|.zip|.rar)$/i.test(url)) {
              if (/pdf$/i.test(url)) {
                val = <><img src="./media/pdf.png" className="file-image" alt=""/> {val}</>
              } else if (/(.doc|.docx)$/i.test(url)) {
src/tabviews/custom/components/editor/braft-editor/index.jsx
@@ -73,7 +73,7 @@
    }
    this.setState({
      data: _data,
      data: this.decodeHtml(_data, _config.wrap),
      BID: BID || '',
      config: _config,
    })
@@ -130,7 +130,7 @@
    let _data = window.GLOB.SyncData.get(config.dataName) || []
    this.setState({data: _data})
    this.setState({data: this.decodeHtml(_data, config.wrap)})
    window.GLOB.SyncData.delete(config.dataName)
@@ -158,7 +158,7 @@
        _data = [_data]
      }
      this.setState({data: _data})
      this.setState({data: this.decodeHtml(_data, config.wrap)})
    }
  }
@@ -224,7 +224,7 @@
    let result = await Api.genericInterface(param)
    if (result.status) {
      this.setState({
        data: result.data || [],
        data: this.decodeHtml(result.data, config.wrap),
        loading: false
      })
      
@@ -236,6 +236,35 @@
      
      UtilsDM.queryFail(result)
    }
  }
  decodeHtml = (data, wrap) => {
    if (!data || data.length === 0) return []
    data.forEach(item => {
      item.$html = item[wrap.field] || ''
      if (item.$html) {
        if (wrap.encryption === 'true') {
          try {
            item.$html = window.decodeURIComponent(window.atob(item.$html))
          } catch (e) {
            item.$html = item[wrap.field] || ''
          }
        }
        delete item[wrap.field]
        if (/\$[\s\S]+\$/.test(item.$html)) {
          Object.keys(item).forEach(key => {
            if (/^\$/.test(key)) return
            let reg = new RegExp('\\$' + key + '\\$', 'ig')
            item.$html = item.$html.replace(reg, item[key])
          })
        }
      }
    })
    return data
  }
  render() {
@@ -254,11 +283,10 @@
        <NormalHeader config={config}/>
        {config.wrap.datatype === 'static' ? <BraftContent
          value={config.html}
          encryption={'false'}
        /> : data.map((item, index) => <BraftContent
          key={index}
          value={item[config.wrap.field] || ''}
          encryption={config.wrap.encryption}
          value={item.$html}
          script={config.wrap.loaded === 'true' ? config.wrap.loadedfunc : ''}
        />)}
      </div>
    )
src/tabviews/custom/components/share/braftContent/index.jsx
@@ -1,13 +1,12 @@
import React, {Component} from 'react'
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import './index.scss'
class BraftContent extends Component {
  static propTpyes = {
    value: PropTypes.any,       // 内容
    encryption: PropTypes.any,  // 是否解码
    script: PropTypes.any       // 自定义脚本
  }
  state = {
@@ -15,34 +14,42 @@
  }
  UNSAFE_componentWillMount () {
    const { encryption, value } = this.props
    let html = value
    if (encryption === 'true' && html) {
      try {
        html = window.decodeURIComponent(window.atob(html))
      } catch (e) {
        html = value
      }
    }
    const { value } = this.props
    
    this.setState({html})
    this.setState({html: value})
  }
  componentDidMount() {
    this.loadScript()
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    if (!is(fromJS(this.props), fromJS(nextProps))) {
      const { encryption, value } = nextProps
      let html = value
    if (this.props.value !== nextProps.value) {
      this.setState({html: nextProps.value}, () => {
        this.loadScript()
      })
    }
  }
      if (encryption === 'true' && html) {
        try {
          html = window.decodeURIComponent(window.atob(html))
        } catch (e) {
          html = value
        }
  loadScript = () => {
    const { script } = this.props
    const { html } = this.state
    if (script && html) {
      const that = this
      let _html = ''
      try {
        // eslint-disable-next-line
        let func = new Function('that', 'html', script)
        _html = func(that, html)
      } catch (e) {
        _html = ''
        console.warn(e)
      }
      this.setState({html})
      if (_html) {
        this.setState({html: _html})
      }
    }
  }
src/tabviews/custom/components/share/braftContent/index.scss
@@ -36,7 +36,7 @@
      background-color: #f0f0f0;
    }
    td, th {
      padding: 5px 14px;
      padding: 5px 10px;
      font-size: 16px;
      border: 1px solid #ddd;
    }
src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
@@ -2544,7 +2544,7 @@
        this.execError({})
      })
    } else if (submit.intertype === 'system') { // 系统存储过程
      let result = getEditTableSql(submit, data, forms)
      let result = getEditTableSql(submit, data, forms, setting)
      let param = {}
      param.func = 'sPC_TableData_InUpDe'
@@ -2573,7 +2573,7 @@
        this.execError({})
      })
    } else if (submit.intertype === 'inner' && submit.innerFunc) { // 自定义存储过程
      let result = getEditTableSql(submit, data, forms)
      let result = getEditTableSql(submit, data, forms, setting)
      let param = {}
      param.func = submit.innerFunc
src/tabviews/custom/index.jsx
@@ -69,7 +69,8 @@
    loading: false,       // 列表数据加载中
    visible: false,       // 标签页控制
    shortcuts: null,      // 快捷键
    loadinginter: false
    loadinginter: false,
    noParam: false
  }
  stepInter = null
@@ -79,6 +80,7 @@
   */
  async loadconfig () {
    const { MenuID, MenuName, param } = this.props
    const { noParam } = this.state
    let _param = {
      func: 'sPC_Get_LongParam',
@@ -209,13 +211,17 @@
      let skip = config.permission === 'false' || window.GLOB.mkHS
      let urlparam = {} // url参数
      if (param) {
        Object.keys(param).forEach(key => {
          if (/^\$/.test(key)) {
            urlparam[key] = param[key]
          } else {
            urlparam[key.toLowerCase()] = param[key]
          }
        })
        if (!noParam) {
          Object.keys(param).forEach(key => {
            if (/^\$/.test(key)) {
              urlparam[key] = param[key]
            } else {
              urlparam[key.toLowerCase()] = param[key]
            }
          })
        } else {
          urlparam.$BID = param.$BID
        }
      }
      window.GLOB.CacheData.set(MenuID, urlparam)
@@ -1481,12 +1487,12 @@
    })
  }
  reloadMenuView = (menuId) => {
  reloadMenuView = (menuId, clear) => {
    const { MenuID } = this.props
    if (MenuID !== menuId) return
    this.reloadview()
    this.reloadview(clear)
  }
  resetActiveMenu = (menuId) => {
@@ -1581,7 +1587,7 @@
    })
  }
  reloadview = () => {
  reloadview = (clear) => {
    window.GLOB.CacheData.delete(this.props.MenuID)
    
    if (this.state.config) {
@@ -1599,7 +1605,8 @@
      viewlost: false,      // 页面丢失:1、未获取到配置-页面丢失;2、页面未启用
      config: null,         // 页面配置信息,包括组件等
      loading: false,       // 列表数据加载中
      shortcuts: null
      shortcuts: null,
      noParam: clear === true
    }, () => {
      this.loadconfig()
    })
src/tabviews/sysmessage/index.jsx
File was deleted
src/tabviews/sysmessage/index.scss
File was deleted
src/tabviews/zshare/actionList/changeuserbutton/index.jsx
@@ -114,7 +114,7 @@
      MKEmitter.emit('closeTabView', MenuID || btn.$MenuID)
      if (btn.refreshTab && btn.refreshTab.length > 0) {
        MKEmitter.emit('reloadMenuView', btn.refreshTab[btn.refreshTab.length - 1])
        MKEmitter.emit('reloadMenuView', btn.refreshTab[btn.refreshTab.length - 1], btn.urlPar === 'true')
      }
      return
    }
src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -187,7 +187,7 @@
    }
    if (tabId && btn.$MenuID === tabId) { // 刷新当前菜单时,停止其他操作
      MKEmitter.emit('reloadMenuView', tabId)
      MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
      return
    }
@@ -216,7 +216,7 @@
    }
    if (tabId) {
      MKEmitter.emit('reloadMenuView', tabId)
      MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
    }
    if (btn.switchTab && btn.switchTab.length > 0) {
@@ -278,7 +278,7 @@
        tabId = btn.refreshTab[btn.refreshTab.length - 1]
      }
      if (tabId && btn.$MenuID === tabId) { // 刷新当前菜单时,停止其他操作
        MKEmitter.emit('reloadMenuView', tabId, 'table')
        MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
        return
      }
@@ -303,7 +303,7 @@
      }
      if (tabId) {
        MKEmitter.emit('reloadMenuView', tabId)
        MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
      }
    }
src/tabviews/zshare/actionList/exceloutbutton/index.jsx
@@ -990,7 +990,7 @@
    }
    if (tabId && btn.$MenuID === tabId) { // 刷新当前菜单时,停止其他操作
      MKEmitter.emit('reloadMenuView', tabId)
      MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
      return
    }
@@ -1019,7 +1019,7 @@
    }
    if (tabId) {
      MKEmitter.emit('reloadMenuView', tabId)
      MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
    }
    
    if (btn.switchTab && btn.switchTab.length > 0) {
@@ -1081,7 +1081,7 @@
        tabId = btn.refreshTab[btn.refreshTab.length - 1]
      }
      if (tabId && btn.$MenuID === tabId) { // 刷新当前菜单时,停止其他操作
        MKEmitter.emit('reloadMenuView', tabId)
        MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
        return
      }
@@ -1106,7 +1106,7 @@
      }
      if (tabId) {
        MKEmitter.emit('reloadMenuView', tabId)
        MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
      }
    }
src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -846,7 +846,7 @@
      let val = form.value
      if (form.type === 'number' || form.type === 'rate') {
        if (isNaN(val)) {
        if (isNaN(val) || val === '') {
          val = 0
        }
      } else if (['date', 'datemonth'].includes(form.type)) {
@@ -1322,7 +1322,7 @@
        let val = form.value
  
        if (form.type === 'number' || form.type === 'rate') {
          if (isNaN(val)) {
          if (isNaN(val) || val === '') {
            val = 0
          }
          _initFormfields.push(`@${_key}=${val}`)
@@ -1943,6 +1943,10 @@
        if (params.length === 0) {
          this.execSuccess(result)
          _resolve()
        } else if (btn.execInterval) {
          setTimeout(() => {
            this.customLoopRequest(params, _resolve)
          }, btn.execInterval)
        } else {
          this.customLoopRequest(params, _resolve)
        }
@@ -1980,6 +1984,10 @@
        if (params.length === 0) {
          this.execSuccess(result)
          _resolve()
        } else if (btn.execInterval) {
          setTimeout(() => {
            this.customLoopRequest(params, _resolve)
          }, btn.execInterval)
        } else {
          this.customLoopRequest(params, _resolve)
        }
@@ -2002,6 +2010,10 @@
        if (params.length === 0) {
          this.execSuccess(res)
          _resolve()
        } else if (btn.execInterval) {
          setTimeout(() => {
            this.customLoopRequest(params, _resolve)
          }, btn.execInterval)
        } else {
          this.customLoopRequest(params, _resolve)
        }
@@ -2349,6 +2361,10 @@
        if (params.length === 0) {
          this.execSuccess(res)
          _resolve()
        } else if (btn.execInterval) {
          setTimeout(() => {
            this.innerLoopRequest(params, btn, _resolve)
          }, btn.execInterval)
        } else {
          this.innerLoopRequest(params, btn, _resolve)
        }
@@ -2598,6 +2614,10 @@
        if (params.length === 0) {
          this.execSuccess(result)
          _resolve()
        } else if (btn.execInterval) {
          setTimeout(() => {
            this.outerLoopRequest(params, _resolve)
          }, btn.execInterval)
        } else {
          this.outerLoopRequest(params, _resolve)
        }
@@ -2642,6 +2662,10 @@
        if (params.length === 0) {
          this.execSuccess(result)
          _resolve()
        } else if (btn.execInterval) {
          setTimeout(() => {
            this.outerLoopRequest(params, _resolve)
          }, btn.execInterval)
        } else {
          this.outerLoopRequest(params, _resolve)
        }
@@ -2665,6 +2689,10 @@
        if (params.length === 0) {
          this.execSuccess(res)
          _resolve()
        } else if (btn.execInterval) {
          setTimeout(() => {
            this.outerLoopRequest(params, _resolve)
          }, btn.execInterval)
        } else {
          this.outerLoopRequest(params, _resolve)
        }
@@ -2881,7 +2909,7 @@
      res.message = res.message.replace(/\s*<<.*>>\s*/g, '')
      val = val ? val[0].replace(/<<|>>/g, '') : ''
      if (/^http/.test(val)) {
      if (/^(http|\/\/)/.test(val)) {
        let audio = document.createElement('audio')
        audio.src = val
        audio.play()
@@ -2981,7 +3009,7 @@
    }
    if (tabId && btn.$MenuID === tabId) { // 刷新当前菜单时,停止其他操作
      MKEmitter.emit('reloadMenuView', tabId)
      MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
      if (menu) {
        MKEmitter.emit('modifyTabs', menu, true)
@@ -3027,7 +3055,7 @@
    }
    if (tabId) {
      MKEmitter.emit('reloadMenuView', tabId)
      MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
    }
    
    if (btn.switchTab && btn.switchTab.length > 0) {
@@ -3647,7 +3675,7 @@
      res.message = res.message.replace(/\s*<<.*>>\s*/g, '')
      val = val ? val[0].replace(/<<|>>/g, '') : ''
      if (/^http/.test(val)) {
      if (/^(http|\/\/)/.test(val)) {
        let audio = document.createElement('audio')
        audio.src = val
        audio.play()
@@ -3731,7 +3759,7 @@
        tabId = btn.refreshTab[btn.refreshTab.length - 1]
      }
      if (tabId && btn.$MenuID === tabId) { // 刷新当前菜单时,停止其他操作
        MKEmitter.emit('reloadMenuView', tabId)
        MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
        return
      }
@@ -3763,7 +3791,7 @@
      }
      if (tabId) {
        MKEmitter.emit('reloadMenuView', tabId)
        MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
      }
    }
@@ -3986,6 +4014,10 @@
      let key = item.field.toLowerCase()
      let _readin = item.readin !== 'false'
      if (item.type === 'linkMain' && item.verifyVal === 'true') {
        _item.$verify = true
        _item.label = item.label
      }
      if (_item.type === 'date') { // 时间兼容
        _item.precision = item.precision || 'day'
      } else if (_item.type === 'datetime') {
@@ -4117,13 +4149,14 @@
   */
  getModels = () => {
    const { BID, btn, BData } = this.props
    const { btnconfig, visible, dict, confirmLoading, submitType } = this.state
    const { btnconfig, visible, dict, confirmLoading, submitType, loadingNumber, loadingTotal } = this.state
    if (!btnconfig || !btnconfig.setting) return null
    let title = btn.label
    let width = btnconfig.setting.width > 100 ? btnconfig.setting.width : btnconfig.setting.width + 'vw'
    let clickouter = btnconfig.setting.clickouter === 'close'
    let num = loadingNumber && !loadingTotal ? `(${loadingNumber}) ` : ''
    if (btnconfig.setting.display === 'drawer') {
      let height = '100vh'
@@ -4192,9 +4225,9 @@
          onCancel={this.handleCancel}
          footer={[
            <Button key="cancel" onClick={this.handleCancel}>{dict['cancel'] || '取消'}</Button>,
            btn.extBtn === 'true' ? <Button key="extend" className={'extend-btn ' + (btn.extStyle || '')} disabled={confirmLoading && submitType !== btn.extValue} loading={confirmLoading && submitType === btn.extValue} onClick={() => this.handleOk(btn.extValue)}>{btn.extLabel}</Button> : null,
            btn.extBtn === 'true' ? <Button key="confirm" className={'confirm-btn ' + (btn.confStyle || '')} disabled={confirmLoading && submitType !== ''} loading={confirmLoading && submitType === ''} onClick={() => this.handleOk()}>{btn.confLabel || dict['ok'] || '确定'}</Button> : null,
            btn.extBtn !== 'true' ? <Button key="confirm" type="primary" loading={confirmLoading} onClick={() => this.handleOk()}>{dict['ok'] || '确定'}</Button> : null
            btn.extBtn === 'true' ? <Button key="extend" className={'extend-btn ' + (btn.extStyle || '')} disabled={confirmLoading && submitType !== btn.extValue} loading={confirmLoading && submitType === btn.extValue} onClick={() => this.handleOk(btn.extValue)}>{submitType === btn.extValue ? num : ''}{btn.extLabel}</Button> : null,
            btn.extBtn === 'true' ? <Button key="confirm" className={'confirm-btn ' + (btn.confStyle || '')} disabled={confirmLoading && submitType !== ''} loading={confirmLoading && submitType === ''} onClick={() => this.handleOk()}>{submitType === '' ? num : ''}{btn.confLabel || dict['ok'] || '确定'}</Button> : null,
            btn.extBtn !== 'true' ? <Button key="confirm" type="primary" loading={confirmLoading} onClick={() => this.handleOk()}>{num}{dict['ok'] || '确定'}</Button> : null
          ]}
          destroyOnClose
        >
src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -1008,7 +1008,7 @@
        let val = form.value
        if (form.type === 'number' || form.type === 'rate') {
          if (isNaN(val)) {
          if (isNaN(val) || val === '') {
            val = 0
          }
        } else if (['date', 'datemonth'].includes(form.type)) {
@@ -1142,7 +1142,7 @@
      if (form.type === 'number' || form.type === 'rate') {
        let val = form.value
        if (isNaN(val)) {
        if (isNaN(val) || val === '') {
          val = 0
        }
        _initvars.push(`@${_key}=${val}`)
@@ -2282,6 +2282,10 @@
      let key = item.field.toLowerCase()
      let _readin = item.readin !== 'false'
      if (item.type === 'linkMain' && item.verifyVal === 'true') {
        _item.$verify = true
        _item.label = item.label
      }
      if (_item.type === 'date') { // 时间兼容
        _item.precision = item.precision || 'day'
      } else if (_item.type === 'datetime') {
src/tabviews/zshare/mutilform/index.jsx
@@ -184,6 +184,7 @@
      } else if (item.type === 'linkMain') {
        readin = false
        item.readin = false
        item.$verify = item.verifyVal === 'true'
      } else if (item.type === 'number') {
        item.decimal = item.decimal || 0
        item.fieldlength = item.decimal
@@ -1545,6 +1546,11 @@
            key: item.field,
            isconst: item.constant === 'true'
          }
          if (item.$verify) {
            _item.$verify = true
            _item.label = item.label
          }
    
          _item.value = record[item.field] !== undefined ? record[item.field] : ''
    
src/tabviews/zshare/mutilform/mkPopSelect/index.jsx
@@ -61,6 +61,7 @@
    })
    let placeholder = ''
    let searchKey = ''
    if (!config.searchKey) {
      config.onload = 'true'
    } else {
@@ -74,6 +75,11 @@
      })
      placeholder = placeholder ? placeholder.join('、') : ''
      if (value && !config.showValue) {
        searchKey = value
        config.onload = 'true'
      }
    }
    this.state = {
@@ -84,7 +90,7 @@
      showValue: config.showValue,
      placeholder,
      arr_field: arrfield.join(','),
      searchKey: '',
      searchKey: searchKey,
      pageIndex: 1,
      pageSize: 10,
      orderBy: '',
src/tabviews/zshare/topSearch/index.jsx
@@ -55,7 +55,7 @@
    let linkFields = {}
    let record = {}
    let forbid = false // header中不设置高级搜索
    let _setting = {showAdv: false, show: false, style: null}
    let _setting = {showAdv: false, show: false, style: null, $pageId: config.$pageId || ''}
    let BID = this.props.BID
    let sysvals = {}
@@ -170,6 +170,10 @@
              item.initval = [moment(d).startOf('month').format(item.format), moment(d).endOf('month').format(item.format)].join(',')
            } else if (item.$initval === 'lastMonth') {
              item.initval = [moment(d).subtract(1, 'months').startOf('month').format(item.format), moment(d).subtract(1, 'months').endOf('month').format(item.format)].join(',')
            } else if (item.$initval === 'year') {
              item.initval = [moment(d).startOf('year').format(item.format), moment(d).endOf('year').format(item.format)].join(',')
            } else if (item.$initval === 'lastYear') {
              item.initval = [moment(d).subtract(1, 'years').startOf('year').format(item.format), moment(d).subtract(1, 'years').endOf('year').format(item.format)].join(',')
            } else {
              try {
                let _initval = JSON.parse(item.$initval)
@@ -445,6 +449,10 @@
              item.initval = [moment(d).startOf('month').format(item.format), moment(d).endOf('month').format(item.format)].join(',')
            } else if (item.$initval === 'lastMonth') {
              item.initval = [moment(d).subtract(1, 'months').startOf('month').format(item.format), moment(d).subtract(1, 'months').endOf('month').format(item.format)].join(',')
            } else if (item.$initval === 'year') {
              item.initval = [moment(d).startOf('year').format(item.format), moment(d).endOf('year').format(item.format)].join(',')
            } else if (item.$initval === 'lastYear') {
              item.initval = [moment(d).subtract(1, 'years').startOf('year').format(item.format), moment(d).subtract(1, 'years').endOf('year').format(item.format)].join(',')
            } else {
              try {
                let _initval = JSON.parse(item.$initval)
@@ -1060,6 +1068,11 @@
  handleReset = () => {
    const { setting } = this.state
    if (setting.resetContrl === 'refresh') {
      MKEmitter.emit('reloadMenuView', setting.$pageId, true)
      return
    }
    let record = {}
    let advanceValues = []
    let searchlist = this.state.searchlist.map(item => {
src/templates/comtableconfig/updatetable/index.jsx
@@ -635,16 +635,26 @@
      if (item.type === 'tabs') {
        item.subtabs.forEach(tab => {
          tab.components[0].action.forEach(btn => {
            btn.uuid = Utils.getuuid()
            if (btn.OpenType === 'popview' && btn.config) {
              btn.config.$tables = getTables(btn.config.components[0])
              btn.config.components[0].action && btn.config.components[0].action.forEach(cell => {
                cell.uuid = Utils.getuuid()
              })
            }
          })
          tab.components[0].cols.forEach(col => {
            if (col.type !== 'custom') return
            col.elements.forEach(btn => {
              if (btn.eleType !== 'button') return
              btn.uuid = Utils.getuuid()
              if (btn.OpenType === 'popview' && btn.config) {
                btn.config.$tables = getTables(btn.config.components[0])
                btn.config.components[0].action && btn.config.components[0].action.forEach(cell => {
                  cell.uuid = Utils.getuuid()
                })
              }
            })
          })
src/templates/modalconfig/dragelement/index.jsx
@@ -2,7 +2,7 @@
import { useDrop } from 'react-dnd'
import { is, fromJS } from 'immutable'
import update from 'immutability-helper'
import { Col } from 'antd'
import { Col, message } from 'antd'
import Utils from '@/utils/utils.js'
import Card from './card'
import './index.scss'
@@ -72,11 +72,15 @@
    oInput.style.display = 'none'
    document.body.removeChild(oInput)
    const _cards = update(cards, { $splice: [[overIndex + 1, 0, _card]] })
    setCards(_cards)
    handleList(_cards, _card)
    if (window.GLOB.CopyOnly) {
      message.success('复制成功。')
    } else {
      const _cards = update(cards, { $splice: [[overIndex + 1, 0, _card]] })
      setCards(_cards)
      handleList(_cards, _card)
    }
  }
  const [, drop] = useDrop({
@@ -94,10 +98,12 @@
      newcard.options = []
      newcard.readonly = 'false'
      newcard.required = 'true'
      newcard.readin = 'top'
      newcard.focus = true
      if (item.subType === 'linkMain') {
        newcard.hidden = 'true'
        newcard.verifyVal = 'true'
      } else if (item.subType === 'textarea') {
        newcard.required = 'false'
      }
src/templates/modalconfig/settingform/index.jsx
@@ -161,7 +161,7 @@
                >
                  {fields.map(option =>
                    <Select.Option id={option.uuid} title={option.label} key={option.uuid} value={option.field}>
                      {option.label}
                      {`${option.label}(${option.field})`}
                    </Select.Option>
                  )}
                </Select>
@@ -185,7 +185,7 @@
                >
                  {fields.map(option =>
                    <Select.Option key={option.uuid} value={option.uuid}>
                      {option.label}
                      {`${option.label}(${option.field})`}
                    </Select.Option>
                  )}
                </Select>
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -617,8 +617,8 @@
  columnChange = (values, callback) => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
    let fields = verify.columns.map(item => item.Column)
    if (fields.includes(values.Column)) {
    let fields = verify.columns.map(item => item.Column.toLowerCase())
    if (fields.includes(values.Column.toLowerCase())) {
      notification.warning({
        top: 92,
        message: values.Column + '字段已存在!',
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -41,6 +41,7 @@
        inputType: 'input',
        editable: true,
        unique: true,
        strict: true,
        searchable: true,
        copy: true,
        width: '16%'
@@ -51,7 +52,6 @@
        inputType: 'input',
        editable: true,
        searchable: true,
        unique: true,
        width: '16%'
      },
      {
@@ -494,8 +494,8 @@
  columnChange = (values, callback) => {
    let verify = JSON.parse(JSON.stringify(this.state.verify))
    let fields = verify.columns.map(item => item.Column)
    if (fields.includes(values.Column)) {
    let fields = verify.columns.map(item => item.Column.toLowerCase())
    if (fields.includes(values.Column.toLowerCase())) {
      notification.warning({
        top: 92,
        message: values.Column + '字段已存在!',
src/templates/sharecomponent/fieldscomponent/index.jsx
@@ -305,7 +305,8 @@
          decimal: item.decimal,
          orderType: 'asc',
          readonly: 'false',
          required: 'true'
          required: 'true',
          readin: 'top'
        }
        if (/^icon|images?$/ig.test(item.field)) {
src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx
@@ -57,6 +57,10 @@
      _defaultValue = [moment().startOf('month'), moment().endOf('month')]
    } else if (card.initval === 'lastMonth') {
      _defaultValue = [moment().subtract(1, 'months').startOf('month'), moment().subtract(1, 'months').endOf('month')]
    } else if (card.initval === 'year') {
      _defaultValue = [moment().startOf('year'), moment().endOf('year')]
    } else if (card.initval === 'lastYear') {
      _defaultValue = [moment().subtract(1, 'years').startOf('year'), moment().subtract(1, 'years').endOf('year')]
    } else if (card.initval) {
      try {
        let _initval = JSON.parse(card.initval)
src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx
@@ -2,7 +2,7 @@
import { useDrop } from 'react-dnd'
import { is, fromJS } from 'immutable'
import update from 'immutability-helper'
import { Col, Button, Popover } from 'antd'
import { Col, Button, Popover, message } from 'antd'
import { EditOutlined } from '@ant-design/icons'
import Utils from '@/utils/utils.js'
@@ -68,11 +68,15 @@
      document.body.removeChild(oInput)
    }
    const { index: overIndex } = findCard(id)
    if (window.GLOB.CopyOnly) {
      message.success('复制成功。')
    } else {
      const { index: overIndex } = findCard(id)
    const _cards = update(cards, { $splice: [[overIndex + 1, 0, copycard]] })
      const _cards = update(cards, { $splice: [[overIndex + 1, 0, copycard]] })
    handleList(_cards, copycard)
      handleList(_cards, copycard)
    }
  }
  const [, drop] = useDrop({
src/templates/sharecomponent/searchcomponent/index.jsx
@@ -61,6 +61,18 @@
      }, () => {
        this.handleSearch(item)
      })
    } else if (type === 'replace') {
      delete item.focus
      this.setState({
        searchlist: searchlist.map(cell => {
          if (cell.field && cell.field.toLowerCase() === item.field.toLowerCase()) {
            return item
          }
          return cell
        }),
      }, () => {
        this.handleSearch(item)
      })
    } else if (type === 'multil') {
      let list = [...searchlist, ...item]
      list = list.filter(item => !item.origin) // 去除系统项
src/templates/sharecomponent/searchcomponent/settingform/index.jsx
@@ -155,13 +155,19 @@
            </Form.Item>
          </Col>
          {show === 'true' ? <Col span={12}>
            <Form.Item label="重置时">
            <Form.Item label={
              <Tooltip placement="topLeft" title="刷新菜单会清空URL变量。">
                <QuestionCircleOutlined className="mk-form-tip" />
                重置时
              </Tooltip>
            }>
              {getFieldDecorator('resetContrl', {
                initialValue: setting.resetContrl || 'init',
              })(
                <Radio.Group>
                  <Radio value="init">恢复初始值</Radio>
                  <Radio value="clear">清空</Radio>
                  <Radio value="refresh">刷新菜单</Radio>
                </Radio.Group>
              )}
            </Form.Item>
src/templates/zshare/editTable/index.jsx
@@ -485,83 +485,151 @@
      return
    }
    if (res.type === 'line') {
      let unique = true
    let ucol = columns.filter(col => col.unique === true)[0]
    const that = this
    if (data.length === 0) {
      if (res.type === 'line') {
        res.data.uuid = Utils.getuuid()
        data.push(res.data)
      } else if (res.type === 'array') {
        res.data.forEach(cell => {
          cell.uuid = Utils.getuuid()
          data.push(cell)
        })
      }
      this.setState({ data, editingKey: '', editLineId: res.type === 'line' ? res.data.uuid : '' }, () => {
        this.props.onChange(data)
      })
    } else if (res.type === 'line') {
      let index = -1
      res.data.uuid = Utils.getuuid()
      columns.forEach(col => {
        if (col.unique !== true || !unique) return
        if (col.uniqueFunc) {
          unique = col.uniqueFunc(data, res.data)
        } else if (col.strict) {
          let key = res.data[col.dataIndex].toLowerCase()
          let _index = data.findIndex(item => key === item[col.dataIndex].toLowerCase())
      if (ucol) {
        if (ucol.uniqueFunc) {
          let msg = ucol.uniqueFunc(data, res.data)
          if (_index > -1) {
          if (msg) {
            notification.warning({
              top: 92,
              message: col.title + '不可重复!',
              message: msg,
              duration: 5
            })
            unique = false
            callback()
            return
          }
        } else if (ucol.strict) {
          let key = res.data[ucol.dataIndex].toLowerCase()
          index = data.findIndex(item => key === item[ucol.dataIndex].toLowerCase())
        } else {
          index = data.findIndex(item => res.data[ucol.dataIndex] === item[ucol.dataIndex])
        }
      }
      if (index > -1) {
        callback()
        data.splice(index, 1, res.data)
        confirm({
          title: `${ucol.title}(${res.data[ucol.dataIndex]})已存在!`,
          okText: '知道了',
          cancelText: '替换',
          onOk() {},
          onCancel() {
            that.setState({ data, editingKey: '', editLineId: res.data.uuid || '' }, () => {
              that.props.onChange(data)
            })
          }
        })
        return
      } else {
        if (type === 'excelcolumn') {
          data.push(res.data)
        } else {
          data.unshift(res.data)
        }
        this.setState({ data, editingKey: '', editLineId: res.data.uuid || '' }, () => {
          this.props.onChange(data)
        })
      }
    } else if (res.type === 'array') {
      let repeats = []
      let vals = []
      if (ucol) {
        if (ucol.uniqueFunc) {
        } else if (ucol.strict) {
          vals = data.map(item => item[ucol.dataIndex].toLowerCase())
        } else {
          vals = data.map(item => item[ucol.dataIndex])
        }
      }
      res.data.forEach(cell => {
        cell.uuid = Utils.getuuid()
        if (ucol) {
          let unique = true
          if (ucol.uniqueFunc) {
            let msg = ucol.uniqueFunc(data, cell)
            if (msg) return
          } else if (ucol.strict) {
            unique = !vals.includes(cell[ucol.dataIndex].toLowerCase())
          } else {
            unique = !vals.includes(cell[ucol.dataIndex])
          }
          if (unique) {
            data.push(cell)
          } else {
            repeats.push(cell)
          }
        } else {
          let _index = data.findIndex(item => res.data[col.dataIndex] === item[col.dataIndex])
          if (_index > -1) {
            notification.warning({
              top: 92,
              message: col.title + '不可重复!',
              duration: 5
            })
            unique = false
          }
          data.push(cell)
        }
      })
      if (!unique) return
      if (type === 'excelcolumn') {
        data.push(res.data)
      } else {
        data.unshift(res.data)
      }
      this.setState({ data, editingKey: '', editLineId: res.data.uuid || '' }, () => {
        this.props.onChange(data)
      })
    } else if (res.type === 'array') {
      res.data.forEach(cell => {
        let unique = true
        cell.uuid = Utils.getuuid()
        columns.forEach(col => {
          if (col.unique !== true || !unique) return
          if (col.uniqueFunc) {
            unique = col.uniqueFunc(data, cell)
          } else if (col.strict) {
            let _index = data.findIndex(item => cell[col.dataIndex].toLowerCase() === item[col.dataIndex].toLowerCase())
            if (_index > -1) {
              unique = false
      if (repeats.length) {
        callback()
        let _data = fromJS(data).toJS().map(cell => {
          let _cell = cell
          repeats.forEach(item => {
            if (ucol.strict) {
              if (cell[ucol.dataIndex].toLowerCase() === item[ucol.dataIndex].toLowerCase()) {
                _cell = item
              }
            } else if (cell[ucol.dataIndex] === item[ucol.dataIndex]) {
              _cell = item
            }
          } else {
            let _index = data.findIndex(item => cell[col.dataIndex] === item[col.dataIndex])
            if (_index > -1) {
              unique = false
            }
          }
          })
          return _cell
        })
        if (!unique) return
        data.push(cell)
      })
      this.setState({ data, editingKey: '' }, () => {
        this.props.onChange(data)
      })
        confirm({
          content: `存在重复的${ucol.title},请选择处理方式。`,
          okText: '跳过',
          cancelText: '替换',
          onOk() {
            that.setState({ data, editingKey: '', editLineId: '' }, () => {
              that.props.onChange(data)
            })
          },
          onCancel() {
            that.setState({ data: _data, editingKey: '', editLineId: '' }, () => {
              that.props.onChange(data)
            })
          }
        })
        return
      } else {
        this.setState({ data, editingKey: '' }, () => {
          this.props.onChange(data)
        })
      }
    }
    callback()
@@ -618,40 +686,36 @@
      return
    }
    let unique = true
    columns.forEach(col => {
      if (col.unique !== true || !unique) return
    let ucol = columns.filter(col => col.unique === true)[0]
    if (ucol) {
      let index = -1
      if (ucol.uniqueFunc) {
        let msg = ucol.uniqueFunc(newData, record)
      if (col.uniqueFunc) {
        unique = col.uniqueFunc(newData, record)
        return
      } else if (col.strict) {
        let key = record[col.dataIndex].toLowerCase()
        let _index = newData.findIndex(item => record.uuid !== item.uuid && key === item[col.dataIndex].toLowerCase())
        if (_index > -1) {
        if (msg) {
          notification.warning({
            top: 92,
            message: col.title + '不可重复!',
            message: msg,
            duration: 5
          })
          unique = false
          return
        }
      } else if (ucol.strict) {
        let key = record[ucol.dataIndex].toLowerCase()
        index = newData.findIndex(item => record.uuid !== item.uuid && key === item[ucol.dataIndex].toLowerCase())
      } else {
        let _index = newData.findIndex(item => record.uuid !== item.uuid && record[col.dataIndex] === item[col.dataIndex])
        if (_index > -1) {
          notification.warning({
            top: 92,
            message: col.title + '不可重复!',
            duration: 5
          })
          unique = false
        }
        index = newData.findIndex(item => record.uuid !== item.uuid && record[ucol.dataIndex] === item[ucol.dataIndex])
      }
    })
    if (!unique) return
      if (index > -1) {
        notification.warning({
          top: 92,
          message: ucol.title + '不可重复!',
          duration: 5
        })
        return
      }
    }
    newData.splice(index, 1, record)
    this.setState({ data: newData, editingKey: '' }, () => {
@@ -704,40 +768,36 @@
        return
      }
      let unique = true
      columns.forEach(col => {
        if (col.unique !== true || !unique) return
      let ucol = columns.filter(col => col.unique === true)[0]
      if (ucol) {
        let _index = -1
        if (ucol.uniqueFunc) {
          let msg = ucol.uniqueFunc(newData, row)
        if (col.uniqueFunc) {
          unique = col.uniqueFunc(newData, row)
          return
        } else if (col.strict) {
          let key = row[col.dataIndex].toLowerCase()
          let _index = newData.findIndex(item => row.uuid !== item.uuid && key === item[col.dataIndex].toLowerCase())
          if (_index > -1) {
          if (msg) {
            notification.warning({
              top: 92,
              message: col.title + '不可重复!',
              message: msg,
              duration: 5
            })
            unique = false
            return
          }
        } else if (ucol.strict) {
          let key = row[ucol.dataIndex].toLowerCase()
          _index = newData.findIndex(item => row.uuid !== item.uuid && key === item[ucol.dataIndex].toLowerCase())
        } else {
          let _index = newData.findIndex(item => row.uuid !== item.uuid && row[col.dataIndex] === item[col.dataIndex])
          if (_index > -1) {
            notification.warning({
              top: 92,
              message: col.title + '不可重复!',
              duration: 5
            })
            unique = false
          }
          _index = newData.findIndex(item => row.uuid !== item.uuid && row[ucol.dataIndex] === item[ucol.dataIndex])
        }
      })
      if (!unique) return
        if (_index > -1) {
          notification.warning({
            top: 92,
            message: ucol.title + '不可重复!',
            duration: 5
          })
          return
        }
      }
      if (index > -1) {
        newData.splice(index, 1, row)
@@ -912,6 +972,10 @@
                ...moveprops
              })}
            />
            {actions.includes('copy') && data.length > 10 ? <span className="footer-copy-control">
              <CopyOutlined title="复制" onClick={() => this.copy()} />
              <PasteBoard getPasteValue={this.pasteSubmit}/>
            </span> : null}
          </DndProvider>
        </div>
      </EditableContext.Provider>
src/templates/zshare/editTable/index.scss
@@ -125,6 +125,31 @@
    font-size: 18px;
    color: #26C281;
  }
  .footer-copy-control {
    text-align: right;
    margin: 10px;
    display: block;
    .anticon-copy {
      margin-right: 15px;
      color: #26C281;
    }
    .anticon-snippets {
      color: purple;
    }
  }
  .ant-typography-copy:not(.ant-typography-copy-success) {
    opacity: 0;
    transition: opacity 0.2s;
  }
  tr:hover {
    .ant-typography-copy:not(.ant-typography-copy-success) {
      opacity: 0.7;
    }
    .ant-typography-copy:hover {
      opacity: 1;
    }
  }
}
.ant-modal.ant-modal-confirm.ant-modal-confirm-info.sql-example {
src/templates/zshare/formconfig.jsx
@@ -1947,6 +1947,20 @@
    },
    {
      type: 'radio',
      key: 'verifyVal',
      label: '空值验证',
      tooltip: '按钮提交时验证字段值是否为空(或数值为0)。',
      initVal: card.verifyVal || 'false',
      options: [{
        value: 'true',
        text: '开启'
      }, {
        value: 'false',
        text: '关闭'
      }]
    },
    {
      type: 'radio',
      key: 'format',
      label: '格式化',
      tooltip: '使用千分位时,数值将以千分位格式显示,提交时为原数值。',
src/templates/zshare/modalform/index.jsx
@@ -43,7 +43,7 @@
  formula: ['label', 'type', 'marginTop', 'marginBottom', 'splitline', 'supField', 'span', 'labelwidth', 'formula', 'eval', 'postfix'],
  brafteditor: ['required', 'hidelabel', 'hidden', 'readin', 'fieldlength', 'readonly', 'span', 'labelwidth', 'tooltip', 'extra', 'encryption', 'marginTop', 'marginBottom', 'contHeidht'],
  funcvar: ['span', 'labelwidth', 'splitline', 'marginTop', 'marginBottom'],
  linkMain: ['readonly', 'required', 'hidden','declare', 'span', 'labelwidth', 'tooltip', 'interception', 'extra', 'place', 'marginTop', 'marginBottom'],
  linkMain: ['readonly', 'required', 'hidden','declare', 'span', 'labelwidth', 'tooltip', 'interception', 'extra', 'place', 'marginTop', 'marginBottom', 'verifyVal'],
  popSelect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'enter', 'dataSource', 'columns', 'primaryKey', 'order', 'controlField', 'laypage', 'onload', 'searchKey', 'showField', 'popWidth'],
  vercode: ['label', 'field', 'type', 'blacklist', 'supField', 'readonly', 'required', 'hidden', 'span', 'labelwidth', 'tooltip', 'marginTop', 'marginBottom', 'placeholder', 'enter', 'smsId', 'phoneField', 'sendType']
}
@@ -426,7 +426,9 @@
      if (value === 'linkMain') {
        this.record.hidden = 'true'
        this.record.verifyVal = 'true'
        _fieldval.hidden = 'true'
        _fieldval.verifyVal = 'true'
      }
      
      if (this.record.type === 'cascader' && value !== 'cascader') {
src/templates/zshare/verifycard/index.jsx
@@ -746,6 +746,10 @@
        _f.writein = _f.writein !== 'false'
        _f.fieldlen = _f.fieldlength || 50
        if (_f.type === 'linkMain' && _f.verifyVal === 'true') {
          _f.$verify = true
        }
        if (_f.type === 'datemonth') {
          _f.type = 'text'
        } else if (_f.type === 'number' || _f.type === 'rate') {
@@ -848,13 +852,19 @@
      colfields: colfields.join(', '),
      uniqueColumns: this.state.uniqueColumns.map(col => {
        if (col.dataIndex === 'field') {
          col.options = unionFields
          col.options = fromJS(unionFields).toJS().map(n => {
            n.label = `${n.label}(${n.field})`
            return n
          })
        }
        return col
      }),
      onceUniqueColumns: this.state.onceUniqueColumns.map(col => {
        if (col.dataIndex === 'field') {
          col.options = _columns
          col.options = fromJS(_columns).toJS().map(n => {
            n.label = `${n.label}(${n.field})`
            return n
          })
        }
        return col
      }),
@@ -1034,8 +1044,19 @@
    formdata = formdata.length ? formdata : null
    let verifyValSql = ''
    // 获取字段键值对
    formdata && formdata.forEach(form => {
      if (form.$verify) {
        verifyValSql += `
        if @${form.field}=${form.type === 'number' ? 0 : `''`}
        begin
          select @errorcode='E',@retmsg='${form.label},关联主表失效'
          goto aaa
        end
        `
      }
      let _key = form.field.toLowerCase()
      if (!_initvars.includes(_key)) {
        _initvars.push(_key)
@@ -1287,22 +1308,21 @@
  
      verify.billcodes.forEach(item => {
        let _key = item.field.toLowerCase()
        let _linkKey = item.linkField ? item.linkField.toLowerCase() : ''
  
        if (!keys.includes(_key)) return // 表单中不含单号生成字段
  
        let _lpline = ''
        if (item.TypeCharOne === 'Lp') {
          if (_linkKey === 'bid' && BID) { // 替换bid
          if (/^BID$/ig.test(item.linkField)) {
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@BID@,48)`
          } else {
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${_linkKey},48)`
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${item.linkField},48)`
          }
        } else if (item.TypeCharOne === 'BN') {
          if (_linkKey === 'bid' && BID) { // 替换bid
          if (/^BID$/ig.test(item.linkField)) {
            _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
          } else {
            _lpline = `set @ModularDetailCode= 'BN'+ right(@${_linkKey},48)`
            _lpline = `set @ModularDetailCode= 'BN'+ right(@${item.linkField},48)`
          }
        } else {
          _lpline = `set @ModularDetailCode= right('${item.ModularDetailCode}',50)`
@@ -1423,15 +1443,20 @@
    let hasvoucher = false
  
    // 凭证-显示列中选取,必须选行
    if (verify.voucher && verify.voucher.enabled && btn.Ot !== 'requiredOnce') {
    if (verify.voucher && verify.voucher.enabled) {
      let _voucher = verify.voucher
      let linkField = `@${_voucher.linkField}`
      if (/^BID$/ig.test(_voucher.linkField)) {
        linkField = `'${BID}'`
      }
  
      hasvoucher = true
  
      _sql += `
        /* 创建凭证 */
        exec s_BVoucher_Create
          @Bill = @${_voucher.linkField},
          @Bill = ${linkField},
          @BVoucherType ='${_voucher.BVoucherType}',
          @VoucherTypeOne ='${_voucher.VoucherTypeOne}',
          @VoucherTypeTwo ='${_voucher.VoucherTypeTwo}',
@@ -1694,6 +1719,10 @@
    } else if (_backCustomScript) {
      _sql += _backCustomScript
    }
    if (verifyValSql) {
      _sql += verifyValSql
    }
  
    if (btn.procMode === 'system') {
      _sql += `
@@ -1904,7 +1933,7 @@
      let hasvoucher = false
  
      // 凭证-显示列中选取,必须选行
      if (verify.voucher && verify.voucher.enabled && btn.Ot !== 'requiredOnce') {
      if (verify.voucher && verify.voucher.enabled) {
        hasvoucher = true
      }
      if (hasvoucher) {
@@ -1998,7 +2027,8 @@
      _lpline = `set @ModularDetailCode= right('${record.ModularDetailCode}',50)`
    }
    let sql = `select @BillCode='', @${record.field}='', @ModularDetailCode=''
    let sql = `Declare @BillCode nvarchar(50),@ModularDetailCode nvarchar(50)
    select @BillCode='', @${record.field}='', @ModularDetailCode=''
    ${_lpline}
    exec s_get_BillCode
      @ModularDetailCode=@ModularDetailCode,
@@ -2682,14 +2712,14 @@
            <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 title={card.Ot === 'requiredOnce' ? '多行拼接时不可用' : ''}>
            <span>
              创建凭证
              {verify.voucher && verify.voucher.enabled ? <span className="count-tip">1</span> : null}
            </span>
          } key="voucher" disabled={card.Ot === 'requiredOnce'}>
          } key="voucher">
            <VoucherForm
              voucher={voucher}
              columns={columns}
              columns={unionFields}
              voucherobj={verify.voucher}
              voucherDetail={voucherDetail}
              voucherChange={this.voucherChange}
src/utils/option.js
@@ -133,6 +133,8 @@
    {value: 'week', text: '本周'},
    {value: 'month', text: '本月'},
    {value: 'lastMonth', text: '上月'},
    {value: 'year', text: '本年'},
    {value: 'lastYear', text: '上年'},
  ],
  datetime: [
    {value: '', text: '空'},
src/utils/utils-custom.js
@@ -1961,14 +1961,14 @@
      if (cell.OpenType === 'form' && cell.formType === 'count_line') return
     
      if (cell.intertype === 'system') {
        if (cell.Ot === 'notRequired' && cell.verify && cell.verify.voucher && cell.verify.voucher.enabled) {
          errors.push({ level: 0, detail: `按钮“${cell.label}”使用了创建凭证函数,需要选择行!`})
        }
        // if (cell.Ot === 'notRequired' && cell.verify && cell.verify.voucher && cell.verify.voucher.enabled) {
        //   errors.push({ level: 0, detail: `按钮“${cell.label}”使用了创建凭证函数,需要选择行!`})
        // }
      } else if (cell.intertype === 'custom' || cell.intertype === 'outer') {
        if (cell.callbackType === 'script' && (!cell.verify || !cell.verify.cbScripts || cell.verify.cbScripts.filter(item => item.status !== 'false').length === 0)) {
          errors.push({ level: 0, detail: `按钮“${cell.label}”使用了自定义脚本回调,回调脚本不可为空!`})
        } else if (cell.procMode === 'system' && cell.Ot === 'notRequired' && cell.verify && cell.verify.voucher && cell.verify.voucher.enabled) {
          errors.push({ level: 0, detail: `按钮“${cell.label}”使用了创建凭证函数,需要选择行!`})
        // } else if (cell.procMode === 'system' && cell.Ot === 'notRequired' && cell.verify && cell.verify.voucher && cell.verify.voucher.enabled) {
        //   errors.push({ level: 0, detail: `按钮“${cell.label}”使用了创建凭证函数,需要选择行!`})
        }
      }
    } else if (cell.OpenType === 'funcbutton') {
@@ -3533,6 +3533,11 @@
            isconst: item.constant === 'true'
          }
          if (item.type === 'linkMain' && item.verifyVal === 'true') {
            _item.$verify = true
            _item.label = item.label
          }
          if (_item.type === 'datemonth') {
            _item.type = 'text'
          } else if (_item.type === 'number' || _item.type === 'rate') {
@@ -3571,8 +3576,19 @@
      formdata.push(item)
    }
    let verifyValSql = ''
    // 获取字段键值对
    formdata && formdata.forEach(form => {
      if (form.$verify) {
        verifyValSql += `
        if @${form.key}=${form.type === 'number' ? 0 : `''`}
        begin
          select @errorcode='E',@retmsg='${form.label},关联主表失效'
          goto aaa
        end
        `
      }
      let _key = form.key.toLowerCase()
      if (!formkeys.includes(_key)) {
@@ -3747,22 +3763,21 @@
    if (formdata && verify.billcodes && verify.billcodes.length > 0) {
      verify.billcodes.forEach(item => {
        let _key = item.field.toLowerCase()
        let _linkKey = item.linkField ? item.linkField.toLowerCase() : ''
  
        if (!formkeys.includes(_key)) return // 表单中不含单号生成字段
  
        let _lpline = ''
        if (item.TypeCharOne === 'Lp') {
          if (_linkKey === 'bid' && BID) { // 替换bid
          if (/^BID$/ig.test(item.linkField)) {
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@BID@,48)`
          } else {
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${_linkKey},48)`
            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${item.linkField},48)`
          }
        } else if (item.TypeCharOne === 'BN') {
          if (_linkKey === 'bid' && BID) { // 替换bid
          if (/^BID$/ig.test(item.linkField)) {
            _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
          } else {
            _lpline = `set @ModularDetailCode= 'BN'+ right(@${_linkKey},48)`
            _lpline = `set @ModularDetailCode= 'BN'+ right(@${item.linkField},48)`
          }
        } else {
          _lpline = `set @ModularDetailCode= right('${item.ModularDetailCode}',50)`
@@ -3875,15 +3890,20 @@
    let hasvoucher = false
  
    // 凭证-显示列中选取,必须选行
    if (verify.voucher && verify.voucher.enabled && btn.Ot !== 'requiredOnce') {
    if (verify.voucher && verify.voucher.enabled) {
      let _voucher = verify.voucher
      let linkField = `@${_voucher.linkField}`
      if (/^BID$/ig.test(_voucher.linkField)) {
        linkField = BID
      }
  
      hasvoucher = true
  
      _sql += `
        /* 创建凭证 */
        exec s_BVoucher_Create
          @Bill = @${_voucher.linkField},
          @Bill = ${linkField},
          @BVoucherType ='${_voucher.BVoucherType}',
          @VoucherTypeOne ='${_voucher.VoucherTypeOne}',
          @VoucherTypeTwo ='${_voucher.VoucherTypeTwo}',
@@ -4275,6 +4295,10 @@
      }
    } else if (_backCustomScript) {
      _sql += _backCustomScript
    }
    if (verifyValSql) {
      _sql += verifyValSql
    }
    if (verify.workFlow === 'true' && process) {
@@ -5464,6 +5488,7 @@
        let _fields = unique.field.split(',')
        let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
        _fields_ = _fields_.join(' and ')
        _fields_ += ` and a.jskey != b.${setting.primaryKey || 'id'}`
        let _where = []
        _fields.forEach(f => {
@@ -5520,6 +5545,7 @@
    let declarefields = []
    let fields = []
    let upFields = []
    forms.forEach(col => {
      let key = col.field.toLowerCase()
@@ -5527,15 +5553,27 @@
      declarefields.push(`${col.field} ${col.datatype}`)
      fields.push(col.field)
      upFields.push(`${col.field}=t.${col.field}`)
    })
    fields = fields.join(',')
    upFields = upFields.join(',')
    let _insert = ''
    if (btn.default !== 'false') {
      _insert = `
        /* 默认sql */
        Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid)
        update a set ${upFields},modifydate=getdate(),modifyuserid=@UserID@,modifyuser=@username,modifystaff=@fullname,deleted=0
        from (select * from #${sheet} where data_type='upt') t
        inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
        update a set deleted=1,modifydate=getdate(),modifyuserid=@UserID@,modifyuser=@username,modifystaff=@fullname
        from (select * from #${sheet} where data_type='del') t
        inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
        delete t from #${sheet} t inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
        Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid)
        Select ${fields},@UserID@,@username,@fullname,@BID@ From #${sheet}
      `
    }
src/utils/utils.js
@@ -265,7 +265,7 @@
            }
            if (d) {
              item.initval = moment(d).subtract(item.initval, 'month').format('YYYY-MM')
              item.initval = moment(d).subtract(item.$initval, 'month').format('YYYY-MM')
            }
          }
        }
@@ -294,6 +294,10 @@
              item.initval = [moment().startOf('month').format(format), moment().endOf('month').format(format)].join(',')
            } else if (item.initval === 'lastMonth') {
              item.initval = [moment().subtract(1, 'months').startOf('month').format(format), moment().subtract(1, 'months').endOf('month').format(format)].join(',')
            } else if (item.initval === 'year') {
              item.initval = [moment().startOf('year').format(format), moment().endOf('year').format(format)].join(',')
            } else if (item.initval === 'lastYear') {
              item.initval = [moment().subtract(1, 'years').startOf('year').format(format), moment().subtract(1, 'years').endOf('year').format(format)].join(',')
            } else if (item.initval) {
              try {
                let _initval = JSON.parse(item.initval)
@@ -335,6 +339,10 @@
                item.initval = [moment(d).startOf('month').format(format), moment(d).endOf('month').format(format)].join(',')
              } else if (item.$initval === 'lastMonth') {
                item.initval = [moment(d).subtract(1, 'months').startOf('month').format(format), moment(d).subtract(1, 'months').endOf('month').format(format)].join(',')
              } else if (item.$initval === 'year') {
                item.initval = [moment(d).startOf('year').format(format), moment(d).endOf('year').format(format)].join(',')
              } else if (item.$initval === 'lastYear') {
                item.initval = [moment(d).subtract(1, 'years').startOf('year').format(format), moment(d).subtract(1, 'years').endOf('year').format(format)].join(',')
              } else {
                try {
                  let _initval = JSON.parse(item.$initval)
@@ -1522,7 +1530,7 @@
 * @return {Object} item   按钮信息
 * @return {Array}  data   excel数据
 */
export function getEditTableSql (verify, data, columns) {
export function getEditTableSql (verify, data, columns, setting) {
  let btn = verify
  let userName = sessionStorage.getItem('User_Name') || ''
  let fullName = sessionStorage.getItem('Full_Name') || ''
@@ -1641,6 +1649,7 @@
        let _fields = unique.field.split(',')
        let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
        _fields_ = _fields_.join(' and ')
        _fields_ += ` and a.jskey != b.${setting.primaryKey || 'id'}`
        let _where = []
        _fields.forEach(f => {
@@ -1697,6 +1706,7 @@
    let declarefields = []
    let fields = []
    let upFields = []
    columns.forEach(col => {
      let key = col.field.toLowerCase()
@@ -1704,15 +1714,27 @@
      declarefields.push(`${col.field} ${col.datatype}`)
      fields.push(col.field)
      upFields.push(`${col.field}=t.${col.field}`)
    })
    fields = fields.join(',')
    upFields = upFields.join(',')
    let _insert = ''
    if (btn.default !== 'false') {
      _insert = `
      /* 默认sql */
      Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid)
      update a set ${upFields},modifydate=getdate(),modifyuserid='${sessionStorage.getItem('UserID') || ''}',modifyuser=@username,modifystaff=@fullname,deleted=0
      from (select * from #${sheet} where data_type='upt') t
      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
      update a set deleted=1,modifydate=getdate(),modifyuserid='${sessionStorage.getItem('UserID') || ''}',modifyuser=@username,modifystaff=@fullname
      from (select * from #${sheet} where data_type='del') t
      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
      delete t from #${sheet} t inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
      Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid)
      Select ${fields},'${sessionStorage.getItem('UserID') || ''}',@username,@fullname,'${BID}' From #${sheet}
      `
    }
@@ -1820,9 +1842,20 @@
  let _initFormfields = []
  let _initColfields = []
  let _declarefields = []
  let verifyValSql = ''
  // 获取字段键值对
  formdata && formdata.forEach(form => {
    if (form.$verify) {
      verifyValSql += `
      if @${form.key}=${form.type === 'number' ? 0 : `''`}
      begin
        select @errorcode='E',@retmsg='${form.label},关联主表失效'
        goto aaa
      end
      `
    }
    let _key = form.key.toLowerCase()
    if (!_initvars.includes(_key)) {
@@ -1830,7 +1863,7 @@
      let val = form.value
      if (form.type === 'number' || form.type === 'rate') {
        if (isNaN(val)) {
        if (isNaN(val) || val === '') {
          val = 0
        }
        _initFormfields.push(`@${_key}=${val}`)
@@ -2111,22 +2144,21 @@
    verify.billcodes.forEach(item => {
      let _key = item.field.toLowerCase()
      let _linkKey = item.linkField ? item.linkField.toLowerCase() : ''
      if (!keys.includes(_key)) return // 表单中不含单号生成字段
      let _lpline = ''
      if (item.TypeCharOne === 'Lp') {
        if (_linkKey === 'bid' && BID) { // 替换bid
        if (/^BID$/ig.test(item.linkField)) {
          _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@BID@,48)`
        } else {
          _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${_linkKey},48)`
          _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${item.linkField},48)`
        }
      } else if (item.TypeCharOne === 'BN') {
        if (_linkKey === 'bid' && BID) { // 替换bid
        if (/^BID$/ig.test(item.linkField)) {
          _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
        } else {
          _lpline = `set @ModularDetailCode= 'BN'+ right(@${_linkKey},48)`
          _lpline = `set @ModularDetailCode= 'BN'+ right(@${item.linkField},48)`
        }
      } else {
        _lpline = `set @ModularDetailCode= right('${item.ModularDetailCode}',50)`
@@ -2245,13 +2277,18 @@
  // 凭证-显示列中选取,必须选行
  if (verify.voucher && verify.voucher.enabled) {
    let _voucher = verify.voucher
    let linkField = `@${_voucher.linkField}`
    if (/^BID$/ig.test(_voucher.linkField)) {
      linkField = `'${BID}'`
    }
    hasvoucher = true
    _sql += `
      /* 创建凭证 */
      exec s_BVoucher_Create
        @Bill = @${_voucher.linkField},
        @Bill = ${linkField},
        @BVoucherType ='${_voucher.BVoucherType}',
        @VoucherTypeOne ='${_voucher.VoucherTypeOne}',
        @VoucherTypeTwo ='${_voucher.VoucherTypeTwo}',
@@ -2875,6 +2912,10 @@
    _sql += _backCustomScript
  }
  if (verifyValSql) {
    _sql += verifyValSql
  }
  if (window.GLOB.breakpoint) {
    let start = new RegExp('\\/\\*\\$breakpoint_begin_' + window.GLOB.breakpoint + '@', 'ig')
    let end = new RegExp('@breakpoint_end_' + window.GLOB.breakpoint + '\\$\\*\\/', 'ig')
src/views/menudesign/index.jsx
@@ -4,8 +4,8 @@
import { is, fromJS } from 'immutable'
import moment from 'moment'
import HTML5Backend from 'react-dnd-html5-backend'
import { notification, Modal, Collapse, Card, Switch, Button, Typography, Spin, message } from 'antd'
import { DoubleLeftOutlined, DoubleRightOutlined, EyeOutlined, EyeInvisibleOutlined, CopyOutlined } from '@ant-design/icons'
import { notification, Modal, Collapse, Switch, Button, Typography, Spin, message, Dropdown } from 'antd'
import { DoubleLeftOutlined, DoubleRightOutlined, EyeOutlined, EyeInvisibleOutlined, CopyOutlined, DownOutlined } from '@ant-design/icons'
import html2canvas from 'html2canvas'
import md5 from 'md5'
@@ -35,8 +35,10 @@
const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const LowerField = asyncComponent(() => import('@/menu/lowerField'))
const Debug = asyncComponent(() => import('@/menu/debug'))
const NormalCss = asyncComponent(() => import('@/menu/normalCss'))
const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
const Versions = asyncComponent(() => import('@/menu/versions'))
const TableNodes = asyncComponent(() => import('@/menu/tablenodes'))
const SysInterface = asyncComponent(() => import('@/menu/sysinterface'))
@@ -1353,9 +1355,10 @@
                      />
                      {/* 表名添加 */}
                      <TableComponent config={config} updatetable={this.updateConfig}/>
                      <Paragraph style={{padding: '15px 0px 0px 37px'}} copyable={{ text: MenuId }}>菜单ID</Paragraph>
                      <Paragraph style={{padding: '15px 0px 0px 32px'}} copyable={{ text: MenuId }}>菜单ID:</Paragraph>
                      <Paragraph style={{padding: '0px 0px 0px 18px'}}>菜单组件:<CopyOutlined onClick={this.copyMenu} style={{cursor: 'pointer', color: '#1890ff'}} /></Paragraph>
                      <NormalCss config={config} updateConfig={this.updateConfig}/>
                      <NormalCopy />
                    </> : null}
                  </Panel>
                  {/* 组件添加 */}
@@ -1371,24 +1374,26 @@
                </Collapse>
              </div>
              <div className={'menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}>
                <Card bordered={false} extra={
                  <div className="mk-opeartion-list">
                    {config ? <Debug config={config}/> : null}
                    <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button>
                    {config ? <Versions MenuId={MenuId} Template="CustomPage" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
                    <TableNodes config={config} />
                    <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                    <SysInterface config={config} updateConfig={this.updateConfig}/>
                <div className="mk-opeartion-list">
                  {config ? <Debug config={config}/> : null}
                  <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button>
                  {config ? <Versions MenuId={MenuId} Template="CustomPage" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
                  <TableNodes config={config} />
                  <SysInterface config={config} updateConfig={this.updateConfig}/>
                  <StyleCombControlButton menu={config} />
                  <PasteController vType="admin" insert={this.insert} />
                  {config ? <Dropdown placement="bottomCenter" overlay={<div className="mk-opeartion-dropdown-wrap">
                    <ReplaceField config={config} updateConfig={this.resetConfig}/>
                    <LowerField config={config} updateConfig={this.resetConfig}/>
                    <PictureController/>
                    <StyleCombControlButton menu={config} />
                    <PasteController vType="admin" insert={this.insert} />
                    {config ? <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                    <Button type="primary" id="save-config" disabled={!config} className={needUpdate ? 'update-tip' : ''} onClick={this.submitConfig} loading={menuloading}>保存</Button>
                    <Button type="default" disabled={menuloading} onClick={this.closeView}>关闭</Button>
                  </div>
                } style={{ width: '100%' }}>
                  {config && !comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : <Spin className="loading-config" size="large" />}
                </Card>
                  </div>} trigger={['hover']}>
                    <div className="mk-button-more">更多<DownOutlined/></div>
                  </Dropdown> : null}
                  {config ? <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                  <Button type="primary" id="save-config" disabled={!config} className={needUpdate ? 'update-tip' : ''} onClick={this.submitConfig} loading={menuloading}>保存</Button>
                  <Button type="default" disabled={menuloading} onClick={this.closeView}>关闭</Button>
                </div>
                {config && !comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : <Spin className="loading-config" size="large" />}
              </div>
            </div>
          </div> : <PopView btn={this.state.popConfig} save={this.submitPopConfig} cancel={this.closePop}/>}
src/views/menudesign/index.scss
@@ -183,42 +183,53 @@
      overflow-y: auto;
      transition: all 0.3s;
      > .ant-card {
        >.ant-card-head {
          margin-bottom: 0px;
          position: sticky;
          top: 0px;
          z-index: 10;
          background: #ffffff;
          .ant-card-head-title {
            color: #1890ff;
            padding: 5px 0;
          }
          .ant-card-extra {
            padding: 5px 0;
            button {
              margin-left: 10px;
            }
            .mk-opeartion-list button:not(.ant-switch):not(:last-child):not(:nth-last-child(2)) {
              padding: 0px 10px;
            }
            .ant-switch.big {
              min-width: 60px;
              height: 28px;
              line-height: 28px;
              margin-top: -2px;
              .ant-switch-inner {
                font-size: 14px;
              }
            }
            .ant-switch.big:after {
              width: 24px;
              height: 24px;
            }
      .mk-opeartion-list {
        position: sticky;
        top: 0px;
        left: 0px;
        right: 0px;
        text-align: right;
        padding: 5px 10px 8px;
        background: #ffffff;
        border-bottom: 1px solid #e8e8e8;
        height: 45px;
        white-space: nowrap;
        overflow: hidden;
        z-index: 10;
        button {
          margin-left: 15px;
        }
        button:not(.ant-switch):not(:last-child):not(:nth-last-child(2)) {
          padding: 0px 10px;
        }
        .mk-button-more {
          display: inline-block;
          height: 32px;
          border: 1px solid #26C281;
          color: #26C281;
          line-height: 32px;
          padding: 0 10px 0px 20px;
          border-radius: 4px;
          cursor: pointer;
          vertical-align: top;
          margin-left: 10px;
          .anticon-down {
            margin-left: 3px;
          }
        }
        >.ant-card-body {
          padding: 0px;
        .ant-switch.big {
          min-width: 60px;
          height: 28px;
          line-height: 28px;
          margin-top: -2px;
          .ant-switch-inner {
            font-size: 14px;
          }
        }
        .ant-switch.big:after {
          width: 24px;
          height: 24px;
        }
      }
    }
@@ -253,17 +264,5 @@
  .ant-table-thead > tr > th {
    background: transparent!important;
    border-radius: 0!important;
  }
}
@media screen and (max-width: 1500px) {
  .mk-opeartion-list .ant-btn {
    min-width: 65px;
    .anticon {
      display: none;
    }
    .anticon + span {
      margin-left: 0px;
    }
  }
}
src/views/menudesign/popview/index.jsx
@@ -1,7 +1,7 @@
import React, { Component } from 'react'
import { is, fromJS } from 'immutable'
import PropTypes from 'prop-types'
import { notification, Modal, Collapse, Card, Switch, Button } from 'antd'
import { notification, Modal, Collapse, Switch, Button } from 'antd'
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'
import MKEmitter from '@/utils/events.js'
@@ -15,6 +15,7 @@
const SourceWrap = asyncComponent(() => import('@/menu/modulesource'))
const Modulecell = asyncComponent(() => import('@/menu/modulecell'))
const MenuShell = asyncComponent(() => import('@/menu/menushell'))
const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
@@ -260,6 +261,7 @@
              <Panel header="基本信息" key="basedata">
                {/* 表名添加 */}
                <TableComponent config={config} updatetable={this.updatetable}/>
                <NormalCopy />
              </Panel>
              {/* 组件添加 */}
              <Panel header="组件" key="component">
@@ -274,21 +276,17 @@
            </Collapse>
          </div>
          <div className={'menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}>
            <Card title={
              <div> {config.MenuName} </div>
            } bordered={false} extra={
              <div>
                <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button>
                <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                <StyleCombControlButton menu={config} />
                <PasteController insert={this.insert} />
                <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config.enabled} onChange={this.onEnabledChange} />
                <Button type="primary" id="save-pop-config" onClick={this.submitConfig} loading={menuloading}>保存</Button>
                <Button type="default" disabled={menuloading} onClick={this.closeView}>返回</Button>
              </div>
            } style={{ width: '100%' }}>
              {!comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
            </Card>
            <div className="mk-opeartion-list">
              <div className="btn-name">{config.MenuName}</div>
              <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button>
              <ReplaceField config={config} updateConfig={this.resetConfig}/>
              <StyleCombControlButton menu={config} />
              <PasteController insert={this.insert} />
              <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config.enabled} onChange={this.onEnabledChange} />
              <Button type="primary" id="save-pop-config" onClick={this.submitConfig} loading={menuloading}>保存</Button>
              <Button type="default" disabled={menuloading} onClick={this.closeView}>返回</Button>
            </div>
            {!comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
          </div>
        </div>
      </div>
src/views/menudesign/popview/index.scss
@@ -62,11 +62,15 @@
      width: 300px;
      background: #ffffff;
      box-shadow: 0px 2px 5px #bcbcbc;
      overflow-y: auto;
      overflow-x: hidden;
      > .ant-collapse {
        height: 100%;
        overflow-y: auto;
        overflow-x: hidden;
        background-color: #ffffff;
        border-radius: 0px;
        padding-bottom: 30px;
        .ant-collapse-item.ant-collapse-item-active {
          border-bottom: 1px solid #d9d9d9;
        }
@@ -98,15 +102,15 @@
        }
      }
    }
    .menu-setting::-webkit-scrollbar {
    .menu-setting >.ant-collapse::-webkit-scrollbar {
      width: 4px;
    }
    .menu-setting::-webkit-scrollbar-thumb {
    .menu-setting >.ant-collapse::-webkit-scrollbar-thumb {
      border-radius: 5px;
      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.08);
      background: rgba(0, 0, 0, 0.08);
    }
    .menu-setting::-webkit-scrollbar-track {
    .menu-setting >.ant-collapse::-webkit-scrollbar-track {
      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
      border-radius: 3px;
      border: 1px solid rgba(0, 0, 0, 0.07);
@@ -120,39 +124,33 @@
      height: calc(100vh - 50px);
      overflow-y: auto;
      > .ant-card {
        >.ant-card-head {
          margin-bottom: 0px;
          position: sticky;
          top: 0px;
          z-index: 10;
          background: #ffffff;
          .ant-card-head-title {
            color: #1890ff;
            padding: 5px 0;
          }
          .ant-card-extra {
            padding: 5px 0;
            button {
              margin-left: 20px;
            }
            .ant-switch.big {
              min-width: 60px;
              height: 28px;
              line-height: 28px;
              margin-top: -2px;
              .ant-switch-inner {
                font-size: 14px;
              }
            }
            .ant-switch.big:after {
              width: 24px;
              height: 24px;
            }
          }
      .mk-opeartion-list {
        position: sticky;
        top: 0px;
        left: 0px;
        right: 0px;
        text-align: right;
        padding: 5px 10px 8px;
        background: #ffffff;
        border-bottom: 1px solid #e8e8e8;
        height: 45px;
        z-index: 10;
        .btn-name {
          float: left;
          color: #1890ff;
          padding: 5px 0;
          font-size: 16px;
        }
        >.ant-card-body {
          padding: 0px;
        button {
          margin-left: 15px;
        }
        button:not(.ant-switch):not(:last-child):not(:nth-last-child(2)) {
          padding: 0px 10px;
        }
        .ant-switch.big {
          transform: scale(1.15);
          top: -2px;
        }
      }
    }
src/views/mobdesign/index.jsx
@@ -34,7 +34,9 @@
const TableNodes = asyncComponent(() => import('@/menu/tablenodes'))
const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const LowerField = asyncComponent(() => import('@/menu/lowerField'))
const NormalCss = asyncComponent(() => import('@/menu/normalCss'))
const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
const SysInterface = asyncComponent(() => import('@/menu/sysinterface'))
const Quotecomponent = asyncComponent(() => import('@/pc/quotecomponent'))
const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
@@ -2275,10 +2277,11 @@
                    <UrlFieldComponent config={config} updateConfig={this.updateConfig}/>
                    {/* 表名添加 */}
                    <TableComponent config={config} updatetable={this.updateConfig}/>
                    <Paragraph style={{padding: '15px 0px 0px 37px'}} copyable={{ text: MenuId }}>菜单ID</Paragraph>
                    <Paragraph style={{padding: '0px 0px 0px 23px'}} copyable={{ text:  `${window.GLOB.baseurl}mob/index.html#/index/${sessionStorage.getItem('kei_no')}/${sessionStorage.getItem('typename')}/${sessionStorage.getItem('lang')}/${MenuId}/@BID@` }}>菜单链接</Paragraph>
                    <Paragraph style={{padding: '15px 0px 0px 32px'}} copyable={{ text: MenuId }}>菜单ID:</Paragraph>
                    <Paragraph style={{padding: '0px 0px 0px 18px'}} copyable={{ text:  `${window.GLOB.baseurl}mob/index.html#/index/${sessionStorage.getItem('kei_no')}/${sessionStorage.getItem('typename')}/${sessionStorage.getItem('lang')}/${MenuId}/@BID@` }}>菜单链接:</Paragraph>
                    <Paragraph style={{padding: '0px 0px 0px 18px'}}>菜单组件:<CopyOutlined onClick={this.copyMenu} style={{cursor: 'pointer', color: '#1890ff'}} /></Paragraph>
                    <NormalCss config={config} updateConfig={this.updateConfig}/>
                    <NormalCopy />
                  </> : null}
                </Panel>
                {/* 组件添加 */}
@@ -2299,7 +2302,7 @@
              {controlshow ? <DoubleRightOutlined onClick={() => {this.setState({controlshow: false})}}/> : null}
              {!controlshow ? <DoubleLeftOutlined onClick={() => {this.setState({controlshow: true})}}/> : null}
            </div>
            <div className="wrap">
            <div className="wrap mk-opeartion-list">
              <Button type="primary" className={needUpdate ? 'update-tip' : ''} disabled={!config} onClick={this.submitConfig} id="save-config" loading={menuloading}>保存</Button>
              {config ? <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
              <ArrowLeftOutlined title="后退" className="back-view" onClick={this.backView}/>
@@ -2315,7 +2318,8 @@
              <StyleCombControlButton menu={config} />
              <Button className="mk-border-green set-home" disabled={MenuId === appHomeId} data-title="当前菜单为应用首页" onClick={this.setHomeView}><HomeOutlined /> 设为首页</Button>
              <Button className="mk-border-purple" disabled={MenuId === appLoginId} data-title="当前菜单为应用登录页" onClick={this.setLoginView}><LoginOutlined /> 设为登录页</Button>
              <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
              <ReplaceField config={config} updateConfig={this.resetConfig}/>
              <LowerField config={config} updateConfig={this.resetConfig}/>
              <Transfer MenuID={MenuId} />
              {config ? <Versions MenuId={MenuId} Template="webPage" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
              <Button type="default" onClick={this.closeView}>关闭</Button>
src/views/mobdesign/popview/index.jsx
@@ -15,6 +15,7 @@
const MobShell = asyncComponent(() => import('@/mob/mobshell'))
const SourceWrap = asyncComponent(() => import('@/mob/modulesource'))
const Modulecell = asyncComponent(() => import('@/menu/modulecell'))
const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
@@ -266,6 +267,7 @@
              <Panel header="基本信息" forceRender className="basedata" key="basedata">
                {/* 表名添加 */}
                <TableComponent config={config} updatetable={this.updateConfig}/>
                <NormalCopy />
              </Panel>
              {/* 组件添加 */}
              <Panel header="组件" className="component" key="component">
@@ -285,13 +287,13 @@
            {controlshow ? <DoubleRightOutlined onClick={() => {this.setState({controlshow: false})}}/> : null}
            {!controlshow ? <DoubleLeftOutlined onClick={() => {this.setState({controlshow: true})}}/> : null}
          </div>
          <div className="wrap">
          <div className="wrap mk-opeartion-list">
            <Button type="primary" onClick={this.submitConfig} id="save-config" loading={menuloading}>保存</Button>
            <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config && config.enabled} onChange={this.onEnabledChange} />
            <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 组件名</Button>
            <PasteController insert={this.insert} />
            <StyleCombControlButton menu={config} />
            <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
            <ReplaceField config={config} updateConfig={this.resetConfig}/>
            <Button type="default" onClick={this.closeView}>返回</Button>
          </div>
        </div>
src/views/pcdesign/index.jsx
@@ -39,7 +39,9 @@
const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const LowerField = asyncComponent(() => import('@/menu/lowerField'))
const NormalCss = asyncComponent(() => import('@/menu/normalCss'))
const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
const SysInterface = asyncComponent(() => import('@/menu/sysinterface'))
const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent'))
const PictureController = asyncComponent(() => import('@/menu/picturecontroller'))
@@ -1901,9 +1903,10 @@
                      <UrlFieldComponent config={config} updateConfig={this.updateConfig}/>
                      {/* 表名添加 */}
                      <TableComponent config={config} updatetable={this.updateConfig}/>
                      <Paragraph style={{padding: '15px 0px 0px 37px'}} copyable={{ text: MenuId }}>菜单ID</Paragraph>
                      <Paragraph style={{padding: '15px 0px 0px 32px'}} copyable={{ text: MenuId }}>菜单ID:</Paragraph>
                      <Paragraph style={{padding: '0px 0px 0px 18px'}}>菜单组件:<CopyOutlined onClick={this.copyMenu} style={{cursor: 'pointer', color: '#1890ff'}} /></Paragraph>
                      <NormalCss config={config} updateConfig={this.updateConfig}/>
                      <NormalCopy />
                    </> : null}
                  </Panel>
                  {/* 组件添加 */}
@@ -1924,7 +1927,7 @@
                {controlshow ? <DoubleRightOutlined onClick={() => {sessionStorage.setItem('controlshow', 'false'); this.setState({controlshow: false})}}/> : null}
                {!controlshow ? <DoubleLeftOutlined onClick={() => {sessionStorage.setItem('controlshow', 'true'); this.setState({controlshow: true})}}/> : null}
              </div>
              <div className="wrap">
              <div className="wrap mk-opeartion-list">
                <Button type="primary" className={needUpdate ? 'update-tip' : ''} disabled={!config} id="save-config" onClick={this.submitConfig} loading={menuloading}>保存</Button>
                {config ? <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                <ArrowLeftOutlined title="后退" className="back-view" onClick={this.backView}/>
@@ -1940,7 +1943,8 @@
                <StyleCombControlButton menu={config} />
                <Button className="mk-border-green" disabled={MenuId === appHomeId} data-title="当前菜单为应用首页" onClick={this.setHomeView}><HomeOutlined /> 设为首页</Button>
                <Button className="mk-border-purple" disabled={MenuId === appLoginId} data-title="当前菜单为应用登录页" onClick={this.setLoginView}><LoginOutlined/> 设为登录页</Button>
                <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                <ReplaceField config={config} updateConfig={this.resetConfig}/>
                <LowerField config={config} updateConfig={this.resetConfig}/>
                <Transfer MenuID={MenuId} />
                {config ? <Versions MenuId={MenuId} Template="webPage" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
                <Button type="default" onClick={this.closeView}>关闭</Button>
src/views/pcdesign/index.scss
@@ -214,6 +214,7 @@
      height: 100%;
      padding: 20px 10px;
      overflow-y: auto;
      overflow-x: hidden;
    }
    .wrap::-webkit-scrollbar {
      width: 2px;
src/views/tabledesign/index.jsx
@@ -4,8 +4,8 @@
import { is, fromJS } from 'immutable'
import moment from 'moment'
import HTML5Backend from 'react-dnd-html5-backend'
import { notification, Modal, Collapse, Card, Switch, Button, Typography, message } from 'antd'
import { DoubleLeftOutlined, DoubleRightOutlined, CopyOutlined } from '@ant-design/icons'
import { notification, Modal, Collapse, Card, Switch, Button, Typography, message, Dropdown } from 'antd'
import { DoubleLeftOutlined, DoubleRightOutlined, CopyOutlined, DownOutlined } from '@ant-design/icons'
import md5 from 'md5'
import Api from '@/api'
@@ -33,10 +33,12 @@
const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const LowerField = asyncComponent(() => import('@/menu/lowerField'))
const Debug = asyncComponent(() => import('@/menu/debug'))
const Versions = asyncComponent(() => import('@/menu/versions'))
const Transfer = asyncComponent(() => import('@/menu/transfer'))
const Unattended = asyncComponent(() => import('@/templates/zshare/unattended'))
const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent'))
const ModalController = asyncComponent(() => import('@/menu/modalconfig/controller'))
const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
@@ -1066,8 +1068,9 @@
                      />
                      {/* 表名添加 */}
                      <TableComponent config={config} updatetable={this.updateConfig}/>
                      <Paragraph style={{padding: '15px 0px 0px 18px'}} copyable={{ text: MenuId }}>菜单ID</Paragraph>
                      <Paragraph style={{padding: '0px 0px 0px 5px'}}>菜单组件 <CopyOutlined onClick={this.copyMenu} style={{marginLeft: '3px', cursor: 'pointer', color: '#1890ff'}} /></Paragraph>
                      <Paragraph style={{padding: '15px 0px 0px 32px'}} copyable={{ text: MenuId }}>菜单ID:</Paragraph>
                      <Paragraph style={{padding: '0px 0px 0px 18px'}}>菜单组件:<CopyOutlined onClick={this.copyMenu} style={{cursor: 'pointer', color: '#1890ff'}} /></Paragraph>
                      <NormalCopy />
                    </> : null}
                  </Panel>
                  <Panel header="搜索" key="search">
@@ -1095,8 +1098,13 @@
                    {config ? <Unattended config={config} updateConfig={this.updateConfig}/> : null}
                    {config ? <Versions MenuId={MenuId} Template="BaseTable" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
                    <TableNodes config={config} />
                    <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                    <PasteBaseTable type="page" insert={this.insert}/>
                    {config ? <Dropdown placement="bottomCenter" overlay={<div className="mk-opeartion-dropdown-wrap">
                      <ReplaceField config={config} updateConfig={this.resetConfig}/>
                      <LowerField config={config} updateConfig={this.resetConfig}/>
                    </div>} trigger={['hover']}>
                      <div className="mk-button-more">更多<DownOutlined/></div>
                    </Dropdown> : null}
                    {config ? <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                    <Button type="primary" id="save-config" disabled={!config} onClick={this.submitConfig} loading={menuloading}>保存</Button>
                    <Button type="default" disabled={menuloading} onClick={this.closeView}>关闭</Button>
src/views/tabledesign/index.scss
@@ -151,8 +151,25 @@
            button {
              margin-left: 15px;
            }
            .mk-opeartion-list button:not(.ant-switch):not(:last-child):not(:nth-last-child(2)) {
              padding: 0px 10px;
            .mk-opeartion-list {
              button:not(.ant-switch):not(:last-child):not(:nth-last-child(2)) {
                padding: 0px 10px;
              }
              .mk-button-more {
                display: inline-block;
                height: 32px;
                border: 1px solid #26C281;
                color: #26C281;
                line-height: 32px;
                padding: 0 10px 0px 20px;
                border-radius: 4px;
                cursor: pointer;
                vertical-align: top;
                margin-left: 15px;
                .anticon-down {
                  margin-left: 3px;
                }
              }
            }
            .ant-switch.big {
              min-width: 60px;
src/views/tabledesign/popview/index.jsx
@@ -15,6 +15,7 @@
const MenuShell = asyncComponent(() => import('@/menu/tableshell'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
@@ -195,6 +196,7 @@
              <Panel header="基本信息" key="basedata">
                {/* 表名添加 */}
                <TableComponent config={config} updatetable={this.updatetable}/>
                <NormalCopy />
              </Panel>
              {/* 组件添加 */}
              <Panel header="搜索" key="search">
@@ -216,7 +218,7 @@
              <div> {config.MenuName} </div>
            } bordered={false} extra={
              <div>
                <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                <ReplaceField config={config} updateConfig={this.resetConfig}/>
                <Switch className="big" checkedChildren="启" unCheckedChildren="停" checked={config.enabled} onChange={this.onEnabledChange} />
                <Button type="primary" id="save-pop-config" onClick={this.submitConfig} loading={menuloading}>保存</Button>
                <Button type="default" disabled={menuloading} onClick={this.closeView}>返回</Button>