From 43008f1240d6568a3364721bb01fc7e31b33d147 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期日, 24 十二月 2023 23:39:51 +0800
Subject: [PATCH] Merge branch 'develop'

---
 src/templates/zshare/modalform/index.jsx                                         |   11 
 src/templates/sharecomponent/tabscomponent/formconfig.jsx                        |   16 
 src/templates/zshare/editTable/index.jsx                                         |   71 +
 src/menu/components/table/edit-table/columns/tableIn/index.jsx                   |    4 
 src/mob/components/tabs/antv-tabs/index.jsx                                      |   32 
 src/mob/components/tabs/antv-tabs/options.jsx                                    |   55 +
 src/views/basedesign/updateFormTab/index.jsx                                     |    4 
 src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx                    |    2 
 src/utils/utils-custom.js                                                        |   32 
 src/tabviews/zshare/actionList/excelInbutton/index.jsx                           |    1 
 src/pc/components/login/normal-login/options.jsx                                 |    1 
 src/tabviews/custom/popview/index.jsx                                            |    2 
 src/menu/components/chart/antv-scatter/index.jsx                                 |    2 
 src/menu/components/tabs/tabcomponents/index.jsx                                 |    2 
 src/tabviews/basetable/index.jsx                                                 |    4 
 src/menu/components/form/formaction/index.jsx                                    |    6 
 src/menu/components/table/edit-table/columns/editColumn/index.scss               |    2 
 src/views/billprint/index.jsx                                                    |   17 
 src/views/design/sidemenu/index.jsx                                              |   10 
 src/views/mobdesign/index.jsx                                                    |   39 -
 src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx             |   12 
 src/templates/zshare/editTable/index.scss                                        |    7 
 src/views/menudesign/index.jsx                                                   |   50 +
 src/tabviews/custom/components/card/data-card/index.jsx                          |   21 
 src/templates/sharecomponent/actioncomponent/verifyexcelin/index.scss            |    3 
 src/tabviews/custom/components/card/cardcellList/index.jsx                       |  220 ++---
 src/tabviews/custom/components/card/prop-card/index.jsx                          |    2 
 src/menu/components/card/double-data-card/options.jsx                            |   11 
 src/menu/components/card/cardcellcomponent/index.jsx                             |    5 
 src/menu/components/card/data-card/options.jsx                                   |    5 
 src/menu/components/share/actioncomponent/formconfig.jsx                         |   34 
 src/templates/sharecomponent/actioncomponent/actionform/index.jsx                |    7 
 src/tabviews/custom/components/table/normal-table/index.jsx                      |   21 
 src/menu/components/carousel/prop-card/index.jsx                                 |    2 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/columnform/index.jsx |    4 
 src/menu/components/card/double-data-card/index.jsx                              |   26 
 src/menu/components/tabs/antv-tabs/options.jsx                                   |   55 +
 src/menu/pastecontroller/index.jsx                                               |  346 ++++++++
 src/menu/components/card/data-card/index.jsx                                     |   24 
 src/tabviews/zshare/mutilform/index.jsx                                          |    4 
 src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx                    |    2 
 src/menu/components/share/actioncomponent/actionform/index.jsx                   |   12 
 src/tabviews/custom/index.jsx                                                    |    8 
 src/menu/debug/index.jsx                                                         |  224 +++++-
 src/menu/components/card/cardcellcomponent/elementform/index.scss                |    2 
 src/menu/components/table/normal-table/index.jsx                                 |    6 
 src/menu/components/tabs/antv-tabs/index.jsx                                     |   21 
 src/menu/components/calendar/options.jsx                                         |    3 
 src/menu/components/card/cardcomponent/options.jsx                               |    4 
 src/menu/components/group/normal-group/index.jsx                                 |    6 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/index.scss           |    3 
 src/templates/sharecomponent/cardcomponent/formconfig.jsx                        |   16 
 src/tabviews/custom/components/table/base-table/index.jsx                        |   21 
 src/templates/sharecomponent/actioncomponent/formconfig.jsx                      |    6 
 src/views/menudesign/popview/index.jsx                                           |    6 
 src/tabviews/zshare/mutilform/mkSwitch/index.jsx                                 |   15 
 src/menu/components/table/normal-table/options.jsx                               |   13 
 src/menu/components/group/groupcomponents/index.jsx                              |    2 
 src/templates/sharecomponent/actioncomponent/verifyexcelin/columnform/index.jsx  |    6 
 src/tabviews/custom/components/card/double-data-card/index.jsx                   |   35 
 src/menu/components/chart/chart-custom/index.jsx                                 |    2 
 src/mob/components/topbar/normal-navbar/options.jsx                              |    2 
 src/tabviews/zshare/mutilform/mkCheck/index.jsx                                  |   17 
 src/mob/components/tabs/tabcomponents/index.jsx                                  |    2 
 src/components/normalform/modalform/mkTable/index.jsx                            |   31 
 src/tabviews/subtable/index.jsx                                                  |    1 
 src/menu/components/table/normal-table/columns/editColumn/index.scss             |    2 
 src/menu/components/carousel/data-card/index.jsx                                 |    2 
 src/templates/zshare/verifycard/index.scss                                       |    8 
 src/utils/utils.js                                                               |   24 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx            |   76 +
 src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx               |   22 
 src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx                   |    2 
 src/menu/components/share/pastecomponent/index.jsx                               |   38 
 src/components/normalform/modalform/index.jsx                                    |    4 
 src/tabviews/rolemanage/index.jsx                                                |   45 
 src/views/pcdesign/index.jsx                                                     |    6 
 src/templates/zshare/formconfig.jsx                                              |   19 
 src/menu/components/table/base-table/options.jsx                                 |   13 
 src/templates/sharecomponent/tabscomponent/tabform/index.jsx                     |    6 
 src/templates/zshare/verifycard/index.jsx                                        |  178 +++-
 src/tabviews/custom/components/interfaces/interItem/index.jsx                    |    4 
 src/views/mobdesign/popview/index.jsx                                            |    6 
 src/views/systemfunc/sidemenu/index.jsx                                          |   42 +
 src/menu/components/share/actioncomponent/index.jsx                              |    6 
 /dev/null                                                                        |    0 
 src/menu/components/table/base-table/columns/editColumn/index.scss               |    2 
 src/menu/components/table/base-table/index.jsx                                   |    4 
 src/menu/components/form/dragtitle/card.jsx                                      |    2 
 89 files changed, 1,563 insertions(+), 586 deletions(-)

diff --git a/src/components/normalform/modalform/index.jsx b/src/components/normalform/modalform/index.jsx
index aafd7bf..785a379 100644
--- a/src/components/normalform/modalform/index.jsx
+++ b/src/components/normalform/modalform/index.jsx
@@ -282,7 +282,7 @@
       let label = item.tooltip ? <Tooltip placement="topLeft" title={item.tooltip}><QuestionCircleOutlined className="mk-form-tip" />{item.label}</Tooltip> : item.label
     
       if (item.type === 'text') {
-        content = (<MKEInput config={item} onChange={(val, defer) => !defer && this.recordChange({[item.field]: val})} onSubmit={this.props.inputSubmit} />)
+        content = (<MKEInput config={item} onChange={(val, defer) => !defer && this.recordChange({[item.field]: val}, item)} onSubmit={this.props.inputSubmit} />)
       } else if (item.type === 'number') {
         content = (<MKNumberInput config={item} onChange={(val, defer) => !defer && this.recordChange({[item.field]: val})} onSubmit={this.props.inputSubmit} />)
       } else if (item.type === 'select' || item.type === 'multiselect') {
@@ -306,7 +306,7 @@
       } else if (item.type === 'source') {
         content = (<SourceComponent type="" placement="right"/>)
       } else if (item.type === 'table') {
-        content = (<MKTable tip={item.tip || ''} fixed={item.fixed === true} columns={item.columns || []} actions={item.actions || []}/>)
+        content = (<MKTable tip={item.tip || ''} columns={item.columns || []} actions={item.actions || []}/>)
       } else if (item.type === 'hint') {
         fields.push(
           <Col span={24} key={index}>
diff --git a/src/components/normalform/modalform/mkTable/index.jsx b/src/components/normalform/modalform/mkTable/index.jsx
index 3fdd300..1baf22f 100644
--- a/src/components/normalform/modalform/mkTable/index.jsx
+++ b/src/components/normalform/modalform/mkTable/index.jsx
@@ -153,8 +153,9 @@
 
 class EditTable extends Component {
   static propTpyes = {
-    columns: PropTypes.array,       // 鏄剧ず鍒�
-    onChange: PropTypes.func        // 鏁版嵁鍙樺寲
+    actions: PropTypes.array,
+    columns: PropTypes.array,
+    onChange: PropTypes.func
   }
 
   state = {
@@ -166,7 +167,7 @@
   }
 
   UNSAFE_componentWillMount () {
-    let actions = this.props.actions || []
+    const { actions } = this.props
     let columns = fromJS(this.props.columns).toJS()
 
     let operation = {
@@ -189,16 +190,16 @@
           </div>
         ) : (
           <div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')} style={{minWidth: '110px', whiteSpace: 'nowrap'}}>
-            <span className="primary" onClick={() => {editingKey === '' && this.edit(record)}}><EditOutlined /></span>
-            {editingKey === '' ? <Popconfirm
+            {actions.includes('edit') ? <span className="primary" onClick={() => {editingKey === '' && this.edit(record)}}><EditOutlined /></span> : null}
+            {actions.includes('del') && editingKey === '' ? <Popconfirm
               overlayClassName="popover-confirm"
               title="纭畾鍒犻櫎鍚�?"
               onConfirm={() => this.handleDelete(record.uuid)
             }>
               <span className="danger"><DeleteOutlined /></span>
             </Popconfirm> : null}
-            {editingKey !== '' ? <span className="danger"><DeleteOutlined /></span> : null}
-            {actions.includes('view') ? <span className="copy" onClick={() => {editingKey === '' && this.changeMenu(record.menu)}}><ArrowRightOutlined /></span> : null}
+            {actions.includes('del') && editingKey !== '' ? <span className="danger"><DeleteOutlined /></span> : null}
+            {actions.includes('view') ? <span className="copy" onClick={() => {editingKey === '' && this.changeMenu(record)}}><ArrowRightOutlined /></span> : null}
           </div>
         )
       }
@@ -217,7 +218,8 @@
   //   return !is(fromJS(this.state), fromJS(nextState))
   // }
 
-  changeMenu = (MenuId) => {
+  changeMenu = (record) => {
+    let MenuId = record.menu
     if (MenuId === 'IM') {
       if (!sessionStorage.getItem('instantMessage')) return
 
@@ -231,7 +233,7 @@
   
       MKEmitter.emit('changeEditMenu', {routerUrl: '/imdesign/' + param})
     } else {
-      MKEmitter.emit('changeEditMenu', {MenuID: MenuId})
+      MKEmitter.emit('changeEditMenu', { ...record, MenuID: MenuId})
     }
   }
 
@@ -392,7 +394,7 @@
   }
 
   render() {
-    const { fixed } = this.props
+    const { actions } = this.props
     let components = {
       body: {
         cell: EditableCell
@@ -401,8 +403,11 @@
 
     let moveprops = {}
     components.body.row = DragableBodyRow
-    moveprops.moveAble = !this.state.editingKey
-    moveprops.moveRow = this.moveRow
+
+    if (actions.includes('move')) {
+      moveprops.moveAble = !this.state.editingKey
+      moveprops.moveRow = this.moveRow
+    }
     
     let  columns = this.state.columns.map(col => {
       if (col.copy) {
@@ -437,7 +442,7 @@
     return (
       <EditableContext.Provider value={this.props.form}>
         <div className="modal-editable-table">
-          {!fixed ? <Button disabled={!!this.state.editingKey} type="link" onClick={this.addline}><PlusOutlined style={{}}/></Button> : null}
+          {actions.includes('add') ? <Button disabled={!!this.state.editingKey} type="link" onClick={this.addline}><PlusOutlined style={{}}/></Button> : null}
           <DndProvider>
             <Table
               bordered
diff --git a/src/menu/components/calendar/options.jsx b/src/menu/components/calendar/options.jsx
index f7ae8e9..c581ef8 100644
--- a/src/menu/components/calendar/options.jsx
+++ b/src/menu/components/calendar/options.jsx
@@ -195,6 +195,7 @@
       label: '棰滆壊鏍囪瘑',
       initval: wrap.signs || [],
       required: false,
+      actions: ['edit', 'del', 'add', 'move'],
       span: 24,
       columns: [
         {
@@ -224,7 +225,7 @@
       initval: wrap.menus || [],
       required: true,
       span: 24,
-      actions: ['view'],
+      actions: ['edit', 'del', 'add', 'move', 'view'],
       forbid: isprint,
       columns: [
         {
diff --git a/src/menu/components/card/cardcellcomponent/elementform/index.scss b/src/menu/components/card/cardcellcomponent/elementform/index.scss
index 45788e3..aaa2c39 100644
--- a/src/menu/components/card/cardcellcomponent/elementform/index.scss
+++ b/src/menu/components/card/cardcellcomponent/elementform/index.scss
@@ -43,7 +43,7 @@
   .ant-popover-inner-content {
     div {
       max-width: 750px;
-      word-break: break-all;
+      word-break: normal;
     }
   }
 }
\ No newline at end of file
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index 5460326..f0249c1 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -310,8 +310,9 @@
         supId = ''
       }
     }
+    let menu = window.GLOB.customMenu
 
-    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, cards.uuid, supId, true)
+    let modules = MenuUtils.getSubModules(menu.components, cards.uuid, supId, menu.interfaces || null)
 
     if (cards.subtype === 'basetable') {
       this.setState({
@@ -320,7 +321,7 @@
         formlist: getBaseTableActionForm(card, functip, cards, usefulFields, modules)
       })
     } else {
-      let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, cards.uuid) || []
+      let anchors = MenuUtils.getAnchors(menu.components, cards.uuid) || []
 
       this.setState({
         actvisible: true,
diff --git a/src/menu/components/card/cardcomponent/options.jsx b/src/menu/components/card/cardcomponent/options.jsx
index b8550d5..e4f29d3 100644
--- a/src/menu/components/card/cardcomponent/options.jsx
+++ b/src/menu/components/card/cardcomponent/options.jsx
@@ -67,7 +67,7 @@
       required: false,
       options: [
         {value: 'card', label: '灞炴�у崱'},
-        {value: 'header', label: '琛ㄦ牸澶�'},
+        {value: 'header', label: '琛ㄦ牸澶达紙鍙帓搴忥級'},
       ],
       controlFields: [
         {field: 'type', values: ['card']},
@@ -286,7 +286,7 @@
       initval: menus,
       required: true,
       span: 24,
-      actions: ['view'],
+      actions: ['edit', 'del', 'add', 'move', 'view'],
       columns: [
         {
           title: '鏍囪瘑',
diff --git a/src/menu/components/card/data-card/index.jsx b/src/menu/components/card/data-card/index.jsx
index 5822912..b16fec5 100644
--- a/src/menu/components/card/data-card/index.jsx
+++ b/src/menu/components/card/data-card/index.jsx
@@ -341,8 +341,30 @@
 
   getWrapForms = () => {
     const { card } = this.state
+
+    let buttons = []
+
+    card.action && card.action.forEach(n => {
+      buttons.push({
+        value: n.uuid,
+        label: n.label
+      })
+    })
+
+    card.subcards.forEach(m => {
+      if (m.$cardType !== 'extendCard') return
+
+      m.elements.forEach(n => {
+        if (n.eleType === 'button') {
+          buttons.push({
+            value: n.uuid,
+            label: n.label
+          })
+        }
+      })
+    })
     
-    return getWrapForm(card.wrap, card.subtype, card.columns, card.uuid, card.supNodes, card.setting)
+    return getWrapForm(card.wrap, card.subtype, card.columns, card.uuid, card.supNodes, card.setting, buttons)
   }
 
   updateWrap = (res) => {
diff --git a/src/menu/components/card/data-card/options.jsx b/src/menu/components/card/data-card/options.jsx
index 0140681..3d2fa34 100644
--- a/src/menu/components/card/data-card/options.jsx
+++ b/src/menu/components/card/data-card/options.jsx
@@ -413,10 +413,10 @@
       field: 'autoExec',
       label: '鑷姩鎵ц',
       initval: wrap.autoExec || '',
-      tooltip: '鏁版嵁鏇存柊鏃惰嚜鍔ㄦ墽琛屾寜閽�傛敞锛氭鎸夐挳鎵ц鎴愬姛鍚庤皑鎱庨�夋嫨鍒锋柊椤癸紝閬垮厤閫犳垚寰幆鎵ц銆�',
+      tooltip: subtype === 'propcard' ? '鏁版嵁鏇存柊鏃惰嚜鍔ㄦ墽琛屾寜閽�傛敞锛氭鎸夐挳鎵ц鎴愬姛鍚庤皑鎱庨�夋嫨鍒锋柊椤癸紝閬垮厤閫犳垚寰幆鎵ц銆�' : '鍒濆鍖栬嚜鍔ㄦ墽琛屾寜閽��',
       required: false,
       options: buttons,
-      forbid: subtype !== 'propcard',
+      forbid: subtype !== 'propcard' && subtype !== 'datacard',
       controlFields: [
         {field: 'emptyExec', notNull: true},
       ]
@@ -646,6 +646,7 @@
       required: true,
       forbid: subtype !== 'datacard' || appType === 'mob' || isprint,
       span: 24,
+      actions: ['edit', 'del', 'add', 'move'],
       columns: [
         {
           title: '搴忓彿',
diff --git a/src/menu/components/card/double-data-card/index.jsx b/src/menu/components/card/double-data-card/index.jsx
index 81cf755..cedcc93 100644
--- a/src/menu/components/card/double-data-card/index.jsx
+++ b/src/menu/components/card/double-data-card/index.jsx
@@ -331,8 +331,30 @@
 
   getWrapForms = () => {
     const { card } = this.state
+
+    let buttons = []
+
+    card.action && card.action.forEach(n => {
+      buttons.push({
+        value: n.uuid,
+        label: n.label
+      })
+    })
+
+    card.subcards.forEach(m => {
+      if (m.$cardType !== 'extendCard') return
+
+      m.elements.forEach(n => {
+        if (n.eleType === 'button') {
+          buttons.push({
+            value: n.uuid,
+            label: n.label
+          })
+        }
+      })
+    })
     
-    return getWrapForm(card.wrap, card.columns, card.setting)
+    return getWrapForm(card.wrap, card.columns, card.setting, buttons)
   }
 
   updateWrap = (res) => {
@@ -501,7 +523,7 @@
             <NormalForm title="鍙岄噸鏁版嵁鍗¤缃�" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
-            <CopyComponent type="datacard" card={card}/>
+            <CopyComponent type="doublecard" card={card}/>
             <PasteComponent options={['action', 'search', 'form', 'cardcell']} updateConfig={this.pasteComponent} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
             <ClockComponent config={card} updateConfig={this.updateComponent}/>
diff --git a/src/menu/components/card/double-data-card/options.jsx b/src/menu/components/card/double-data-card/options.jsx
index 942b421..591c305 100644
--- a/src/menu/components/card/double-data-card/options.jsx
+++ b/src/menu/components/card/double-data-card/options.jsx
@@ -1,7 +1,7 @@
 /**
  * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
  */
-export default function (wrap, columns = [], setting) {
+export default function (wrap, columns = [], setting, buttons = []) {
   let appType = sessionStorage.getItem('appType')
   let laypage = setting && setting.laypage !== 'false'
   let roleList = sessionStorage.getItem('sysRoles')
@@ -183,6 +183,15 @@
       required: false
     },
     {
+      type: 'select',
+      field: 'autoExec',
+      label: '鑷姩鎵ц',
+      initval: wrap.autoExec || '',
+      tooltip: '鍒濆鍖栬嚜鍔ㄦ墽琛屾寜閽��',
+      required: false,
+      options: buttons
+    },
+    {
       type: 'number',
       field: 'minWidth',
       label: '鏈�灏忓搴�',
diff --git a/src/menu/components/carousel/data-card/index.jsx b/src/menu/components/carousel/data-card/index.jsx
index 7fd4050..2d4401d 100644
--- a/src/menu/components/carousel/data-card/index.jsx
+++ b/src/menu/components/carousel/data-card/index.jsx
@@ -207,7 +207,7 @@
             <NormalForm title="杞挱-鍔ㄦ�佹暟鎹�" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
-            <CopyComponent type="datacard" card={card}/>
+            <CopyComponent type="cardatacard" card={card}/>
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
             <ClockComponent config={card} updateConfig={this.updateComponent}/>
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)}/>
diff --git a/src/menu/components/carousel/prop-card/index.jsx b/src/menu/components/carousel/prop-card/index.jsx
index c9afca3..ab40408 100644
--- a/src/menu/components/carousel/prop-card/index.jsx
+++ b/src/menu/components/carousel/prop-card/index.jsx
@@ -252,7 +252,7 @@
             <NormalForm title="杞挱-闈欐�佹暟鎹�" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
-            <CopyComponent type="propcard" card={card}/>
+            <CopyComponent type="carpropcard" card={card}/>
             <PasteComponent config={card} options={['cardcell']} updateConfig={this.updateComponent} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
             <ClockComponent config={card} updateConfig={this.updateComponent}/>
diff --git a/src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx
index f473165..2292bc0 100644
--- a/src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx
@@ -179,7 +179,7 @@
       initval: card.menus || [],
       required: true,
       span: 24,
-      actions: appType === 'pc' ? ['view'] : [],
+      actions: ['edit', 'del', 'add', 'move', 'view'],
       columns: [
         {
           title: '鏍囪瘑',
diff --git a/src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx
index f3ef986..eb79052 100644
--- a/src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx
@@ -157,7 +157,7 @@
       initval: card.menus || [],
       required: true,
       span: 24,
-      actions: appType === 'pc' ? ['view'] : [],
+      actions: ['edit', 'del', 'add', 'move', 'view'],
       columns: [
         {
           title: '鏍囪瘑',
diff --git a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
index e89781e..6195549 100644
--- a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
@@ -187,7 +187,7 @@
       initval: card.menus || [],
       required: true,
       span: 24,
-      actions: ['view'],
+      actions: ['edit', 'del', 'add', 'move', 'view'],
       forbid: appType === 'mob' || card.chartType !== 'bar',
       hidden: card.click !== 'menus',
       columns: [
diff --git a/src/menu/components/chart/antv-scatter/index.jsx b/src/menu/components/chart/antv-scatter/index.jsx
index 8c1a624..9a20837 100644
--- a/src/menu/components/chart/antv-scatter/index.jsx
+++ b/src/menu/components/chart/antv-scatter/index.jsx
@@ -350,7 +350,7 @@
             {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="娣诲姞鎼滅储" onClick={this.addSearch}/> : null}
             {appType !== 'mob' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton}/> : null}
             <ChartCompileForm config={card} plotchange={this.updateComponent}/>
-            <CopyComponent type="line" card={card}/>
+            <CopyComponent type="scatter" card={card}/>
             <PasteComponent config={card} options={['action', 'search']} updateConfig={this.updateComponent}/>
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
             <ClockComponent config={card} updateConfig={this.updateComponent}/>
diff --git a/src/menu/components/chart/chart-custom/index.jsx b/src/menu/components/chart/chart-custom/index.jsx
index 16d9daf..5dc3f45 100644
--- a/src/menu/components/chart/chart-custom/index.jsx
+++ b/src/menu/components/chart/chart-custom/index.jsx
@@ -251,7 +251,7 @@
           <div className="mk-popover-control">
             {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="娣诲姞鎼滅储" onClick={this.addSearch}/> : null}
             <ChartCompileForm config={card} plotchange={this.updateComponent}/>
-            <CopyComponent type="line" card={card}/>
+            <CopyComponent type="chart" card={card}/>
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
             <ClockComponent config={card} updateConfig={this.updateComponent}/>
             <DeleteOutlined className="close" title="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
diff --git a/src/menu/components/form/dragtitle/card.jsx b/src/menu/components/form/dragtitle/card.jsx
index a2eb77d..7413512 100644
--- a/src/menu/components/form/dragtitle/card.jsx
+++ b/src/menu/components/form/dragtitle/card.jsx
@@ -90,7 +90,7 @@
           <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
         </NormalForm>
         <CopyComponent type="formgroup" card={card}/>
-        <PasteForms config={card} updateConfig={(res) => pasteForm(res, id)} />
+        <PasteForms config={card} update={(res) => pasteForm(res, id)} />
         <CloseOutlined className="close" type="close" onClick={close} />
       </div>
     } trigger="hover">
diff --git a/src/menu/components/form/formaction/index.jsx b/src/menu/components/form/formaction/index.jsx
index dc697e0..3ca3fb7 100644
--- a/src/menu/components/form/formaction/index.jsx
+++ b/src/menu/components/form/formaction/index.jsx
@@ -100,8 +100,10 @@
       supId = config.wrap.supModule[config.wrap.supModule.length - 1]
     }
 
-    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid, supId)
-    let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, config.uuid) || []
+    let menu = window.GLOB.customMenu
+
+    let modules = MenuUtils.getSubModules(menu.components, config.uuid, supId, menu.interfaces || null)
+    let anchors = MenuUtils.getAnchors(menu.components, config.uuid) || []
 
     if (card.type === 'submit' && !card.Ot) {
       card.Ot = config.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
diff --git a/src/menu/components/group/groupcomponents/index.jsx b/src/menu/components/group/groupcomponents/index.jsx
index 5754e85..666d180 100644
--- a/src/menu/components/group/groupcomponents/index.jsx
+++ b/src/menu/components/group/groupcomponents/index.jsx
@@ -51,7 +51,7 @@
     drop(item) {
       if (item.hasOwnProperty('originalIndex') || item.added) {
         return
-      } else if (['login', 'navbar', 'topbar', 'tabs', 'search', 'group', 'menubar'].includes(item.component)) {
+      } else if (['login', 'navbar', 'topbar', 'tabs', 'search', 'group', 'menubar', 'iframe', 'sharecode', 'officialAccount'].includes(item.component)) {
         return
       }
 
diff --git a/src/menu/components/group/normal-group/index.jsx b/src/menu/components/group/normal-group/index.jsx
index ae1d50b..e26fb57 100644
--- a/src/menu/components/group/normal-group/index.jsx
+++ b/src/menu/components/group/normal-group/index.jsx
@@ -15,7 +15,7 @@
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
-const PasteComponent = asyncIconComponent(() => import('../paste'))
+const PasteController = asyncIconComponent(() => import('@/menu/pastecontroller'))
 const GroupComponents = asyncComponent(() => import('../groupcomponents'))
 
 class NormalGroup extends Component {
@@ -178,9 +178,9 @@
             <NormalForm title="鍒嗙粍璁剧疆" width={700} update={this.updateWrap} getForms={this.getWrapForms}>
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
-            <CopyComponent type="tabs" card={group}/>
+            <CopyComponent type="group" card={group}/>
             <UngroupOutlined title="閲婃斁" style={group.components.length > 0 ? {color: '#32c5d2'} : {color: '#eeeeee', cursor: 'not-allowed'}} onClick={this.unGroup}/>
-            <PasteComponent insert={this.insert} />
+            <PasteController type="group" tab={group} insert={this.insert} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
             <DeleteOutlined className="close" title="delete" onClick={() => this.props.deletecomponent(group.uuid)} />
           </div>
diff --git a/src/menu/components/group/paste/index.jsx b/src/menu/components/group/paste/index.jsx
deleted file mode 100644
index 8a9b436..0000000
--- a/src/menu/components/group/paste/index.jsx
+++ /dev/null
@@ -1,99 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { Modal, notification } from 'antd'
-import { SnippetsOutlined } from '@ant-design/icons'
-
-import MenuUtils from '@/utils/utils-custom.js'
-import asyncComponent from '@/utils/asyncComponent'
-// import './index.scss'
-
-const PasteForm = asyncComponent(() => import('@/templates/zshare/pasteform'))
-
-class PasteGroup extends Component {
-  static propTpyes = {
-    insert: PropTypes.func
-  }
-
-  state = {
-    visible: false
-  }
-
-  pasteSubmit = () => {
-    let appType = sessionStorage.getItem('appType')
-    let options = ['datacard', 'propcard', 'balcony', 'timeline', 'simpleform', 'stepform', 'tabform', 'basetable', 'normaltable', 'tablecard', 'editor', 'line', 'bar', 'pie', 'scatter', 'sandbox']
-    let types = {
-      login: '鐧诲綍',
-      navbar: '瀵艰埅鏍�',
-      topbar: '瀵艰埅鏍�',
-      tabs: '鏍囩椤�',
-      search: '鎼滅储',
-      mainsearch: '鎼滅储',
-      group: '鍒嗙粍',
-      menubar: '鑿滃崟'
-    }
-
-    if (appType !== 'mob') {
-      options.push('editable', 'antvG6', 'antvX6', 'calendar', 'tree', 'dashboard', 'chart')
-    }
-
-    this.pasteFormRef.handleConfirm().then(res => {
-      if (res.copyType && types[res.copyType]) {
-        notification.warning({
-          top: 92,
-          message: '鍒嗙粍涓笉鍙坊鍔犮��' + types[res.copyType] + '銆嬬粍浠讹紒',
-          duration: 5
-        })
-        return
-      } else if (!options.includes(res.copyType)) {
-        notification.warning({
-          top: 92,
-          message: '閰嶇疆淇℃伅鏍煎紡閿欒锛�',
-          duration: 5
-        })
-        return
-      }
-
-      if (res.copyType === 'basetable') {
-        res.copyType = 'normaltable'
-        res.subtype = 'normaltable'
-      }
-
-      res = MenuUtils.resetComponentConfig(res, appType)
-
-      delete res.copyType
-      
-      this.props.insert(res)
-
-      this.setState({visible: false})
-
-      notification.success({
-        top: 92,
-        message: '绮樿创鎴愬姛锛�',
-        duration: 2
-      })
-    })
-  }
-
-  render() {
-    const { visible } = this.state
-
-    return (
-      <div style={{display: 'inline-block'}}>
-        <SnippetsOutlined style={{color: 'purple'}} onClick={() => {this.setState({visible: true})}} />
-        <Modal
-          title="绮樿创"
-          visible={visible}
-          width={600}
-          maskClosable={false}
-          onOk={this.pasteSubmit}
-          onCancel={() => {this.setState({visible: false})}}
-          destroyOnClose
-        >
-          <PasteForm wrappedComponentRef={(inst) => this.pasteFormRef = inst} inputSubmit={this.pasteSubmit}/>
-        </Modal>
-      </div>
-    )
-  }
-}
-
-export default PasteGroup
\ No newline at end of file
diff --git a/src/menu/components/group/paste/index.scss b/src/menu/components/group/paste/index.scss
deleted file mode 100644
index e69de29..0000000
--- a/src/menu/components/group/paste/index.scss
+++ /dev/null
diff --git a/src/menu/components/share/actioncomponent/actionform/index.jsx b/src/menu/components/share/actioncomponent/actionform/index.jsx
index 3c8a93c..63d4fe6 100644
--- a/src/menu/components/share/actioncomponent/actionform/index.jsx
+++ b/src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -780,6 +780,7 @@
       let className = ''
       let content = null
       let initVal = item.initVal || ''
+      let help = item.help || ''
 
       if (item.type === 'splitLine') {
         fields.push(
@@ -857,6 +858,7 @@
             filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
               option.props.extend.toLowerCase().indexOf(input.toLowerCase()) >= 0}
             onChange={(value) => {this.optionChange(item.key, value)}}
+            on
             getPopupContainer={() => document.getElementById('winter')}
           >
             {item.options.map((option, index) =>
@@ -909,7 +911,7 @@
         rules = [
           { required: item.required, message: '璇锋坊鍔�' + item.label + '!' }
         ]
-        content = (<MKTable tip={''} columns={item.columns || []} actions={[]}/>)
+        content = (<MKTable columns={item.columns || []} actions={item.actions}/>)
       } else if (item.type === 'icon') {
         rules = [
           { required: item.required, message: '璇烽�夋嫨' + item.label + '!' }
@@ -936,7 +938,7 @@
           { required: item.required, message: '璇烽�夋嫨' + item.label + '!' }
         ]
 
-        content = <MkPrintTemps />
+        content = <MkPrintTemps onChange={(value) => {this.optionChange(item.key, value)}}/>
       } else if (item.type === 'keyinterface') {
         span = 24
         className = 'textarea'
@@ -947,9 +949,13 @@
         content = <KeyInterface type={item.key === 'exInterface' ? 'develop' : 'product'}/>
       }
 
+      if (help && typeof(help) === 'function') {
+        help = help(this.record)
+      }
+
       fields.push(
         <Col span={span} key={index}>
-          <Form.Item className={className} help={item.help} label={item.tooltip ?
+          <Form.Item className={className} help={help} label={item.tooltip ?
             <Tooltip placement="topLeft" overlayStyle={{maxWidth: item.tooltip.length > 25 ? 350 : 250 }} title={<span onClick={(e) => e.stopPropagation()}>{item.tooltip}</span>}>
               <QuestionCircleOutlined className="mk-form-tip" />
               {item.label}
diff --git a/src/menu/components/share/actioncomponent/formconfig.jsx b/src/menu/components/share/actioncomponent/formconfig.jsx
index 974b6fd..00b31aa 100644
--- a/src/menu/components/share/actioncomponent/formconfig.jsx
+++ b/src/menu/components/share/actioncomponent/formconfig.jsx
@@ -1,5 +1,5 @@
+import React from 'react'
 import { btnClasses } from '@/utils/option.js'
-
 
 /**
  * @description 鑾峰彇鎸夐挳琛ㄥ崟閰嶇疆淇℃伅
@@ -161,6 +161,7 @@
     { value: 'print', text: '鏍囩鎵撳嵃' },
     { value: 'refund', text: '閫�娆�' },
     { value: 'closetab', text: '鏍囩鍏抽棴' },
+    // { value: 'expPdf', text: '瀵煎嚭PDF' },
     { value: 'megvii', text: '鏃疯闈㈡澘鏈�' },
     { value: 'filezip', text: '鏂囦欢鍘嬬缉鍖�' },
   ]
@@ -468,6 +469,19 @@
       key: 'printTemp',
       label: '鎵撳嵃妯℃澘',
       initVal: card.printTemp || '',
+      help: (record) => {
+        if (record.printTemp) {
+          return <span onClick={() => {
+            sessionStorage.setItem('mk-print-temp', record.printTemp)
+            window.open('#/hs')
+
+            setTimeout(() => {
+              sessionStorage.removeItem('mk-print-temp')
+            }, 50)
+          }} style={{color: '#1890ff', cursor: 'pointer', fontSize: '13px'}}>#鏌ョ湅妯℃澘</span>
+        }
+        return ''
+      },
       required: true
     },
     {
@@ -1349,7 +1363,7 @@
       label: '缁勪欢鍒楄〃',
       initVal: card.syncComponents || [],
       required: true,
-      actions: [],
+      actions: ['edit', 'del', 'add', 'move'],
       columns: [
         {
           title: '缁勪欢',
@@ -1430,6 +1444,7 @@
     { value: 'print', text: '鏍囩鎵撳嵃' },
     { value: 'refund', text: '閫�娆�' },
     { value: 'closetab', text: '鏍囩鍏抽棴' },
+    // { value: 'expPdf', text: '瀵煎嚭PDF' },
     { value: 'megvii', text: '鏃疯闈㈡澘鏈�' },
     { value: 'filezip', text: '鏂囦欢鍘嬬缉鍖�' },
   ]
@@ -1603,6 +1618,19 @@
       key: 'printTemp',
       label: '鎵撳嵃妯℃澘',
       initVal: card.printTemp || '',
+      help: (record) => {
+        if (record.printTemp) {
+          return <span onClick={() => {
+            sessionStorage.setItem('mk-print-temp', record.printTemp)
+            window.open('#/hs')
+
+            setTimeout(() => {
+              sessionStorage.removeItem('mk-print-temp')
+            }, 50)
+          }} style={{color: '#1890ff', cursor: 'pointer', fontSize: '13px'}}>#鏌ョ湅妯℃澘</span>
+        }
+        return ''
+      },
       required: true
     },
     {
@@ -2221,7 +2249,7 @@
       label: '缁勪欢鍒楄〃',
       initVal: card.syncComponents || [],
       required: true,
-      actions: [],
+      actions: ['edit', 'del', 'add', 'move'],
       columns: [
         {
           title: '缁勪欢',
diff --git a/src/menu/components/share/actioncomponent/index.jsx b/src/menu/components/share/actioncomponent/index.jsx
index 0109542..f0c909a 100644
--- a/src/menu/components/share/actioncomponent/index.jsx
+++ b/src/menu/components/share/actioncomponent/index.jsx
@@ -206,8 +206,10 @@
         supId = ''
       }
     }
+
+    let menu = window.GLOB.customMenu
     
-    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid, supId, config.subtype !== 'basetable')
+    let modules = MenuUtils.getSubModules(menu.components, config.uuid, supId, menu.interfaces || null)
 
     if (config.subtype === 'basetable') {
       delete card.eleType // 鍖哄垎鎸夐挳浣嶇疆
@@ -218,7 +220,7 @@
         formlist: getBaseTableActionForm(card, functip, config, usefulFields, modules)
       })
     } else {
-      let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, config.uuid) || []
+      let anchors = MenuUtils.getAnchors(menu.components, config.uuid) || []
   
       this.setState({
         visible: true,
diff --git a/src/menu/components/share/pastecomponent/index.jsx b/src/menu/components/share/pastecomponent/index.jsx
index d809808..7f0b88c 100644
--- a/src/menu/components/share/pastecomponent/index.jsx
+++ b/src/menu/components/share/pastecomponent/index.jsx
@@ -168,24 +168,28 @@
       } else if (type === 'cols') {
         config.cols = config.cols.filter(col => !col.origin)
 
-        let keys = config.cols.map(col => (col.field || '$empty'))
-
-        let cols = []
-        res.cols.forEach(col => {
-          if (!col.field || !keys.includes(col.field)) {
-            cols.push(col)
-          }
-        })
-
-        if (cols.length === 0) {
-          notification.warning({
-            top: 92,
-            message: '鏄剧ず鍒楀凡瀛樺湪锛�',
-            duration: 5
-          })
-          return
+        if (config.subtype === 'normaltable' && res.cols.length === 1) {
+          config.cols.push(...res.cols)
         } else {
-          config.cols.push(...cols)
+          let keys = config.cols.map(col => (col.field || '$empty'))
+  
+          let cols = []
+          res.cols.forEach(col => {
+            if (!col.field || !keys.includes(col.field)) {
+              cols.push(col)
+            }
+          })
+  
+          if (cols.length === 0) {
+            notification.warning({
+              top: 92,
+              message: '鏄剧ず鍒楀凡瀛樺湪锛�',
+              duration: 5
+            })
+            return
+          } else {
+            config.cols.push(...cols)
+          }
         }
       }
 
diff --git a/src/menu/components/table/base-table/columns/editColumn/index.scss b/src/menu/components/table/base-table/columns/editColumn/index.scss
index e653f84..d0a30f3 100644
--- a/src/menu/components/table/base-table/columns/editColumn/index.scss
+++ b/src/menu/components/table/base-table/columns/editColumn/index.scss
@@ -34,7 +34,7 @@
   .ant-popover-inner-content {
     div {
       max-width: 750px;
-      word-break: break-all;
+      word-break: normal;
     }
   }
 }
diff --git a/src/menu/components/table/base-table/index.jsx b/src/menu/components/table/base-table/index.jsx
index 95759e2..4b4394e 100644
--- a/src/menu/components/table/base-table/index.jsx
+++ b/src/menu/components/table/base-table/index.jsx
@@ -219,7 +219,7 @@
   getWrapForms = () => {
     const { wrap, action, columns, cols } = this.state.card
 
-    let _actions = [...action]
+    let _actions = []
 
     cols.forEach(col => {
       if (col.type === 'custom') {
@@ -231,7 +231,7 @@
       }
     })
 
-    return getWrapForm(wrap, _actions, columns)
+    return getWrapForm(wrap, _actions, columns, action)
   }
 
   updateWrap = (res) => {
diff --git a/src/menu/components/table/base-table/options.jsx b/src/menu/components/table/base-table/options.jsx
index 775a39c..38d54a9 100644
--- a/src/menu/components/table/base-table/options.jsx
+++ b/src/menu/components/table/base-table/options.jsx
@@ -1,7 +1,7 @@
 /**
  * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
  */
-export default function (wrap, action = [], columns = []) {
+export default function (wrap, action = [], columns = [], toolBtns = []) {
   const wrapForm = [
     {
       type: 'radio',
@@ -167,7 +167,16 @@
       tooltip: '鍙屽嚮琛ㄦ牸涓锛岃Е鍙戠殑鎸夐挳銆�',
       required: false,
       allowClear: true,
-      options: action.map(item => ({value: item.uuid, label: item.label})),
+      options: [...toolBtns, ...action].map(item => ({value: item.uuid, label: item.label})),
+    },
+    {
+      type: 'select',
+      field: 'autoExec',
+      label: '鑷姩鎵ц',
+      initval: wrap.autoExec || '',
+      tooltip: '鍒濆鍖栬嚜鍔ㄦ墽琛屾寜閽��',
+      required: false,
+      options: toolBtns.map(item => ({value: item.uuid, label: item.label}))
     },
     {
       type: 'select',
diff --git a/src/menu/components/table/edit-table/columns/editColumn/index.scss b/src/menu/components/table/edit-table/columns/editColumn/index.scss
index 82b274d..f2127e8 100644
--- a/src/menu/components/table/edit-table/columns/editColumn/index.scss
+++ b/src/menu/components/table/edit-table/columns/editColumn/index.scss
@@ -57,7 +57,7 @@
   .ant-popover-inner-content {
     div {
       max-width: 750px;
-      word-break: break-all;
+      word-break: normal;
     }
   }
 }
\ No newline at end of file
diff --git a/src/menu/components/table/edit-table/columns/tableIn/index.jsx b/src/menu/components/table/edit-table/columns/tableIn/index.jsx
index 5908fa2..3518c0c 100644
--- a/src/menu/components/table/edit-table/columns/tableIn/index.jsx
+++ b/src/menu/components/table/edit-table/columns/tableIn/index.jsx
@@ -196,8 +196,10 @@
         supId = ''
       }
     }
+
+    let menu = window.GLOB.customMenu
     
-    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, uuid, supId)
+    let modules = MenuUtils.getSubModules(menu.components, uuid, supId, menu.interfaces || null)
 
     this.setState({
       fields: fromJS(columns).toJS().filter(item => item.field !== setting.primaryKey),
diff --git a/src/menu/components/table/normal-table/columns/editColumn/index.scss b/src/menu/components/table/normal-table/columns/editColumn/index.scss
index e653f84..d0a30f3 100644
--- a/src/menu/components/table/normal-table/columns/editColumn/index.scss
+++ b/src/menu/components/table/normal-table/columns/editColumn/index.scss
@@ -34,7 +34,7 @@
   .ant-popover-inner-content {
     div {
       max-width: 750px;
-      word-break: break-all;
+      word-break: normal;
     }
   }
 }
diff --git a/src/menu/components/table/normal-table/index.jsx b/src/menu/components/table/normal-table/index.jsx
index 5a6fd01..6bdefb2 100644
--- a/src/menu/components/table/normal-table/index.jsx
+++ b/src/menu/components/table/normal-table/index.jsx
@@ -280,7 +280,7 @@
   getWrapForms = () => {
     const { wrap, action, columns, cols } = this.state.card
 
-    let _actions = [...action]
+    let _actions = []
 
     cols.forEach(col => {
       if (col.type === 'custom') {
@@ -292,7 +292,7 @@
       }
     })
 
-    return getWrapForm(wrap, _actions, columns)
+    return getWrapForm(wrap, _actions, columns, action)
   }
 
   updateWrap = (res) => {
@@ -374,7 +374,7 @@
             <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.addColumns()}/>
             {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="娣诲姞鎼滅储" onClick={this.addSearch}/> : null}
             <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton}/>
-            <NormalForm title="琛ㄦ牸璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
+            <NormalForm title="琛ㄦ牸璁剧疆" width={850} update={this.updateWrap} getForms={this.getWrapForms}>
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
             <CopyComponent type="normaltable" card={card}/>
diff --git a/src/menu/components/table/normal-table/options.jsx b/src/menu/components/table/normal-table/options.jsx
index 8b1eae1..4c8ba91 100644
--- a/src/menu/components/table/normal-table/options.jsx
+++ b/src/menu/components/table/normal-table/options.jsx
@@ -1,7 +1,7 @@
 /**
  * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
  */
-export default function (wrap, action = [], columns = []) {
+export default function (wrap, action = [], columns = [], toolBtns) {
   let roleList = sessionStorage.getItem('sysRoles')
   let appType = sessionStorage.getItem('appType')
   let isprint = sessionStorage.getItem('MenuType') === 'billPrint'
@@ -209,11 +209,20 @@
       tooltip: '鍙屽嚮琛ㄦ牸涓锛岃Е鍙戠殑鎸夐挳銆�',
       required: false,
       allowClear: true,
-      options: action.map(item => ({value: item.uuid, label: item.label})),
+      options: [...toolBtns, ...action].map(item => ({value: item.uuid, label: item.label})),
       forbid: appType === 'mob'
     },
     {
       type: 'select',
+      field: 'autoExec',
+      label: '鑷姩鎵ц',
+      initval: wrap.autoExec || '',
+      tooltip: '鍒濆鍖栬嚜鍔ㄦ墽琛屾寜閽��',
+      required: false,
+      options: toolBtns.map(item => ({value: item.uuid, label: item.label}))
+    },
+    {
+      type: 'select',
       field: 'tipField',
       label: '淇℃伅鎻愮ず',
       initval: wrap.tipField || '',
diff --git a/src/menu/components/tabs/antv-tabs/index.jsx b/src/menu/components/tabs/antv-tabs/index.jsx
index 002bc4b..eaa3206 100644
--- a/src/menu/components/tabs/antv-tabs/index.jsx
+++ b/src/menu/components/tabs/antv-tabs/index.jsx
@@ -16,7 +16,7 @@
 
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
-const PasteComponent = asyncIconComponent(() => import('../paste'))
+const PasteController = asyncIconComponent(() => import('@/menu/pastecontroller'))
 const TabComponents = asyncComponent(() => import('../tabcomponents'))
 
 const { TabPane } = Tabs
@@ -181,11 +181,11 @@
     this.props.updateConfig(tabs)
   }
 
-  insert = (item, tab) => {
+  insert = (item, tabId) => {
     let tabs = fromJS(this.state.tabs).toJS()
 
     tabs.subtabs.forEach(stab => {
-      if (stab.uuid === tab.uuid) {
+      if (stab.uuid === tabId) {
         stab.components.push(item)
       }
     })
@@ -220,7 +220,7 @@
     editab.hide = res.hide || 'false'
     editab.backgroundColor = res.backgroundColor
     // editab.controlVal = res.controlVal || ''
-    editab.selectVal = res.selectVal || ''
+    // editab.selectVal = res.selectVal || ''
     editab.blacklist = res.blacklist
 
     if (editab.uuid) {
@@ -264,6 +264,17 @@
 
       delete res.controlVals
     }
+    if (res.selectVals) {
+      let values = {}
+      res.selectVals.forEach(item => {
+        values[item.uuid] = item.value
+      })
+      tabs.subtabs.forEach(tab => {
+        tab.selectVal = values[tab.uuid]
+      })
+
+      delete res.selectVals
+    }
 
     res.tabStyle = res.tabStyle || 'line'
     res.cusClass = ''
@@ -297,7 +308,7 @@
                   <NormalForm title="鏍囩缂栬緫" width={800} update={this.updateTab} getForms={() => this.getTabForms(tab)}>
                     <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
                   </NormalForm>
-                  <PasteComponent Tab={tab} insert={this.insert} />
+                  <PasteController type="tabs" tab={tab} insert={(item) => this.insert(item, tab.uuid)} />
                   <CloseOutlined className="close" onClick={() => this.delTab(tab)} />
                 </div>
               } trigger="hover">
diff --git a/src/menu/components/tabs/antv-tabs/options.jsx b/src/menu/components/tabs/antv-tabs/options.jsx
index b04d73f..329358c 100644
--- a/src/menu/components/tabs/antv-tabs/options.jsx
+++ b/src/menu/components/tabs/antv-tabs/options.jsx
@@ -42,14 +42,14 @@
     //   tooltip: '褰撶鐢ㄥ瓧娈靛�间笌闅愯棌鏍囪鐩哥瓑鏃讹紝鏍囩椤典細闅愯棌銆傛敞锛�1銆佸涓�艰鐢ㄩ�楀彿鍒嗛殧锛�2銆丂pass@鍊艰〃绀哄拷鐣ユ璁剧疆锛堝缁堟樉绀猴級锛�2銆丂pass_empty@鍊艰〃绀哄拷鐣ョ┖鍊硷紝鍗虫湭鑾峰彇涓婄骇缁勪欢淇℃伅鏃舵樉绀猴紙鍙笌鍏朵粬鍊兼嫾鎺ワ級銆�',
     //   required: false,
     // },
-    {
-      type: 'text',
-      field: 'selectVal',
-      label: '閫変腑鏍囪',
-      initval: tab.selectVal || '',
-      tooltip: '褰撻�変腑瀛楁鍊间笌閫変腑鏍囪鐩哥瓑鏃讹紝鏍囩椤甸粯璁ら�変腑銆�',
-      required: false
-    },
+    // {
+    //   type: 'text',
+    //   field: 'selectVal',
+    //   label: '閫変腑鏍囪',
+    //   initval: tab.selectVal || '',
+    //   tooltip: '褰撻�変腑瀛楁鍊间笌閫変腑鏍囪鐩哥瓑鏃讹紝鏍囩椤甸粯璁ら�変腑銆�',
+    //   required: false
+    // },
     {
       type: 'color',
       field: 'backgroundColor',
@@ -105,7 +105,8 @@
     roleList = []
   }
 
-  let controlVals = subtabs.map(item => ({uuid: item.uuid, label: item.label, value: item.controlVal}))
+  let controlVals = subtabs.map(item => ({uuid: item.uuid, label: item.label, value: item.controlVal || ''}))
+  let selectVals = subtabs.map(item => ({uuid: item.uuid, label: item.label, value: item.selectVal || ''}))
 
   let tabStyle = setting.cusClass || setting.tabStyle
 
@@ -238,7 +239,10 @@
       label: '閫変腑瀛楁',
       initval: setting.selectField || '',
       tooltip: '鐢ㄤ簬鎺у埗鏍囩椤靛垵濮嬪寲閫変腑锛屽湪鏍囩涓~鍏ラ�変腑鏍囪锛屾敞锛氭暟鎹潵婧愪簬url鍙傛暟銆�',
-      required: false
+      required: false,
+      controlFields: [
+        {field: 'selectVals', notNull: true},
+      ]
     },
     {
       type: 'color',
@@ -271,11 +275,11 @@
     {
       type: 'table',
       field: 'controlVals',
-      label: '鏍囩缁�',
+      label: '鏍囩缁�(绂佺敤)',
       initval: controlVals,
       tooltip: '褰撶鐢ㄥ瓧娈靛�间笌闅愯棌鏍囪鐩哥瓑鏃讹紝鏍囩椤典細闅愯棌銆傛敞锛�1銆佸涓�艰鐢ㄩ�楀彿鍒嗛殧锛�2銆丂pass@鍊艰〃绀哄拷鐣ユ璁剧疆锛堝缁堟樉绀猴級锛�2銆丂pass_empty@鍊艰〃绀哄拷鐣ョ┖鍊硷紝鍗虫湭鑾峰彇涓婄骇缁勪欢淇℃伅鏃舵樉绀猴紙鍙笌鍏朵粬鍊兼嫾鎺ワ級銆�',
       required: false,
-      fixed: true,
+      actions: ['edit'],
       span: 24,
       columns: [
         {
@@ -294,6 +298,33 @@
           width: '50%'
         }
       ]
+    },
+    {
+      type: 'table',
+      field: 'selectVals',
+      label: '鏍囩缁�(閫変腑)',
+      initval: selectVals,
+      tooltip: '褰撻�変腑瀛楁鍊间笌閫変腑鏍囪鐩哥瓑鏃讹紝鏍囩椤甸粯璁ら�変腑銆�',
+      required: false,
+      actions: ['edit'],
+      span: 24,
+      columns: [
+        {
+          title: '鏍囩鍚嶇О',
+          dataIndex: 'label',
+          editable: false,
+          required: false,
+          width: '30%'
+        },
+        {
+          title: '閫変腑鏍囪',
+          dataIndex: 'value',
+          inputType: 'input',
+          editable: true,
+          required: false,
+          width: '50%'
+        }
+      ]
     }
   ]
 
diff --git a/src/menu/components/tabs/paste/index.jsx b/src/menu/components/tabs/paste/index.jsx
deleted file mode 100644
index db15490..0000000
--- a/src/menu/components/tabs/paste/index.jsx
+++ /dev/null
@@ -1,129 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { Modal, notification } from 'antd'
-import { SnippetsOutlined } from '@ant-design/icons'
-
-import MenuUtils from '@/utils/utils-custom.js'
-import asyncComponent from '@/utils/asyncComponent'
-// import './index.scss'
-
-const PasteForm = asyncComponent(() => import('@/templates/zshare/pasteform'))
-
-class PasteGroup extends Component {
-  static propTpyes = {
-    Tab: PropTypes.any,         // 鏍囩
-    insert: PropTypes.func
-  }
-
-  state = {
-    visible: false
-  }
-
-  resetconfig = (item, appType) => {
-    if (item.type === 'tabs') {
-      item.uuid = MenuUtils.getuuid()
-      item.setting.name = item.setting.name + MenuUtils.getSignName()
-      item.name = item.setting.name
-      
-      item.subtabs.forEach(tab => {
-        tab.uuid = MenuUtils.getuuid()
-
-        tab.components = tab.components.map(cell => {
-          cell = this.resetconfig(cell, appType)
-          return cell
-        })
-      })
-    } else if (item.type === 'group') {
-      item.uuid = MenuUtils.getuuid()
-      item.setting.name = item.setting.name + MenuUtils.getSignName()
-      item.name = item.setting.name
-
-      item.components = item.components.map(cell => {
-        cell = MenuUtils.resetComponentConfig(cell, appType)
-
-        return cell
-      })
-    } else {
-      item = MenuUtils.resetComponentConfig(item, appType)
-    }
-
-    return item
-  }
-
-  pasteSubmit = () => {
-    const { Tab } = this.props
-    let appType = sessionStorage.getItem('appType')
-    let options = ['tabs', 'group', 'datacard', 'propcard', 'timeline', 'balcony', 'basetable', 'normaltable', 'mainsearch', 'simpleform', 'stepform', 'tabform', 'editor', 'tablecard', 'line', 'bar', 'pie', 'scatter', 'sandbox']
-    let types = {
-      login: '鐧诲綍',
-      navbar: '瀵艰埅鏍�',
-      topbar: '瀵艰埅鏍�'
-    }
-
-    if (appType === 'mob') {
-      options.push('menubar')
-    } else {
-      options.push('editable', 'antvG6', 'antvX6', 'calendar', 'tree', 'dashboard', 'chart')
-    }
-
-    this.pasteFormRef.handleConfirm().then(res => {
-      if (res.copyType && types[res.copyType]) {
-        notification.warning({
-          top: 92,
-          message: '鍒嗙粍涓笉鍙坊鍔犮��' + types[res.copyType] + '銆嬬粍浠讹紒',
-          duration: 5
-        })
-        return
-      } else if (!options.includes(res.copyType)) {
-        notification.warning({
-          top: 92,
-          message: '閰嶇疆淇℃伅鏍煎紡閿欒锛�',
-          duration: 5
-        })
-        return
-      }
-
-      if (res.copyType === 'basetable') {
-        res.copyType = 'normaltable'
-        res.subtype = 'normaltable'
-      }
-
-      res = this.resetconfig(res, appType)
-
-      delete res.copyType
-      
-      this.props.insert(res, Tab)
-
-      this.setState({visible: false})
-
-      notification.success({
-        top: 92,
-        message: '绮樿创鎴愬姛锛�',
-        duration: 2
-      })
-    })
-  }
-
-  render() {
-    const { visible } = this.state
-
-    return (
-      <div style={{display: 'inline-block'}}>
-        <SnippetsOutlined style={{color: 'purple'}} onClick={() => {this.setState({visible: true})}} />
-        <Modal
-          title="绮樿创"
-          visible={visible}
-          width={600}
-          maskClosable={false}
-          onOk={this.pasteSubmit}
-          onCancel={() => {this.setState({visible: false})}}
-          destroyOnClose
-        >
-          <PasteForm wrappedComponentRef={(inst) => this.pasteFormRef = inst} inputSubmit={this.pasteSubmit}/>
-        </Modal>
-      </div>
-    )
-  }
-}
-
-export default PasteGroup
\ No newline at end of file
diff --git a/src/menu/components/tabs/paste/index.scss b/src/menu/components/tabs/paste/index.scss
deleted file mode 100644
index e69de29..0000000
--- a/src/menu/components/tabs/paste/index.scss
+++ /dev/null
diff --git a/src/menu/components/tabs/tabcomponents/index.jsx b/src/menu/components/tabs/tabcomponents/index.jsx
index 8f345f6..673c529 100644
--- a/src/menu/components/tabs/tabcomponents/index.jsx
+++ b/src/menu/components/tabs/tabcomponents/index.jsx
@@ -80,7 +80,7 @@
     drop(item) {
       if (item.hasOwnProperty('originalIndex') || item.added) {
         return
-      } else if (['login', 'navbar', 'topbar'].includes(item.component)) {
+      } else if (['login', 'navbar', 'topbar', 'iframe'].includes(item.component)) {
         return
       }
       
diff --git a/src/menu/debug/index.jsx b/src/menu/debug/index.jsx
index d761bee..afaf6ae 100644
--- a/src/menu/debug/index.jsx
+++ b/src/menu/debug/index.jsx
@@ -254,13 +254,16 @@
 
         item.action && item.action.forEach(cell => {
           if (cell.hidden === 'true') return false
-          let sql = this.resetButton(item, cell, process)
+          let res = this.resetButton(item, cell, process)
 
-          if (sql) {
-            if (typeof(sql) === 'string') {
-              children.push({label: cell.label, sql: sql})
+          if (res) {
+            if (typeof(res) === 'string') {
+              children.push({label: cell.label, sql: res})
+            } else if (res.backSql) {
+              children.push({label: cell.label, sql: res.sql})
+              children.push({label: cell.label + '锛堝洖璋冿級', sql: res.backSql})
             } else {
-              children.push({label: cell.label, tabName: cell.label, sql: '', children: sql})
+              children.push({label: cell.label, tabName: cell.label, sql: '', children: res})
             }
           }
         })
@@ -276,13 +279,16 @@
               } else if (col.type === 'custom') {
                 col.elements.forEach(cell => {
                   if (cell.eleType !== 'button' || cell.hidden === 'true') return
-                  let sql = this.resetButton(item, cell, process)
+                  let res = this.resetButton(item, cell, process)
 
-                  if (sql) {
-                    if (typeof(sql) === 'string') {
-                      children.push({label: cell.label, sql: sql})
+                  if (res) {
+                    if (typeof(res) === 'string') {
+                      children.push({label: cell.label, sql: res})
+                    } else if (res.backSql) {
+                      children.push({label: cell.label, sql: res.sql})
+                      children.push({label: cell.label + '锛堝洖璋冿級', sql: res.backSql})
                     } else {
-                      children.push({label: cell.label, tabName: cell.label, sql: '', children: sql})
+                      children.push({label: cell.label, tabName: cell.label, sql: '', children: res})
                     }
                   }
                 })
@@ -300,13 +306,16 @@
           item.subcards && item.subcards.forEach(card => {
             card.elements && card.elements.forEach(cell => {
               if (cell.eleType !== 'button' || cell.hidden === 'true') return
-              let sql = this.resetButton(item, cell, process)
+              let res = this.resetButton(item, cell, process)
 
-              if (sql) {
-                if (typeof(sql) === 'string') {
-                  children.push({label: cell.label, sql: sql})
+              if (res) {
+                if (typeof(res) === 'string') {
+                  children.push({label: cell.label, sql: res})
+                } else if (res.backSql) {
+                  children.push({label: cell.label, sql: res.sql})
+                  children.push({label: cell.label + '锛堝洖璋冿級', sql: res.backSql})
                 } else {
-                  children.push({label: cell.label, tabName: cell.label, sql: '', children: sql})
+                  children.push({label: cell.label, tabName: cell.label, sql: '', children: res})
                 }
               }
             })
@@ -315,13 +324,16 @@
   
             card.backElements.forEach(cell => {
               if (cell.eleType !== 'button' || cell.hidden === 'true') return
-              let sql = this.resetButton(item, cell, process, null, true)
+              let res = this.resetButton(item, cell, process, null, true)
 
-              if (sql) {
-                if (typeof(sql) === 'string') {
-                  children.push({label: cell.label, sql: sql})
+              if (res) {
+                if (typeof(res) === 'string') {
+                  children.push({label: cell.label, sql: res})
+                } else if (res.backSql) {
+                  children.push({label: cell.label, sql: res.sql})
+                  children.push({label: cell.label + '锛堝洖璋冿級', sql: res.backSql})
                 } else {
-                  children.push({label: cell.label, tabName: cell.label, sql: '', children: sql})
+                  children.push({label: cell.label, tabName: cell.label, sql: '', children: res})
                 }
               }
             })
@@ -329,13 +341,16 @@
         } else if (item.type === 'balcony') {
           item.elements.forEach(cell => {
             if (cell.eleType !== 'button' || cell.hidden === 'true') return
-            let sql = this.resetButton(item, cell, process)
+            let res = this.resetButton(item, cell, process)
 
-            if (sql) {
-              if (typeof(sql) === 'string') {
-                children.push({label: cell.label, sql: sql})
+            if (res) {
+              if (typeof(res) === 'string') {
+                children.push({label: cell.label, sql: res})
+              } else if (res.backSql) {
+                children.push({label: cell.label, sql: res.sql})
+                children.push({label: cell.label + '锛堝洖璋冿級', sql: res.backSql})
               } else {
-                children.push({label: cell.label, tabName: cell.label, sql: '', children: sql})
+                children.push({label: cell.label, tabName: cell.label, sql: '', children: res})
               }
             }
           })
@@ -345,10 +360,15 @@
             if (!group.subButton.Ot) {
               group.subButton.Ot = item.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
             }
-            let sql = this.resetButton(item, group.subButton, process, group)
+            let res = this.resetButton(item, group.subButton, process, group)
 
-            if (sql) {
-              children.push({label: group.subButton.label, sql: sql})
+            if (res) {
+              if (typeof(res) === 'string') {
+                children.push({label: group.subButton.label, sql: res})
+              } else if (res.backSql) {
+                children.push({label: group.subButton.label, sql: res.sql})
+                children.push({label: group.subButton.label + '锛堝洖璋冿級', sql: res.backSql})
+              }
             }
           })
         }
@@ -372,9 +392,52 @@
           let _item = fromJS(item).toJS()
           _item.columns = _item.subColumns || []
           _item.setting.primaryKey = _item.setting.subKey
-          sql = this.getSysDefaultSql(cell, _item, process, group)
+          sql = this.getSysDefaultSql(cell, _item, process, group, false)
         } else {
-          sql = this.getSysDefaultSql(cell, item, process, group)
+          sql = this.getSysDefaultSql(cell, item, process, group, false)
+        }
+      }
+      if (cell.callbackType === 'script' && cell.verify && cell.verify.cbScripts) {
+        let defSql = ''
+        if (item.subtype === 'dualdatacard' && isback) {
+          let _item = fromJS(item).toJS()
+          _item.columns = _item.subColumns || []
+          _item.setting.primaryKey = _item.setting.subKey
+          defSql = this.getSysDefaultSql(cell, _item, process, group, true)
+        } else {
+          defSql = this.getSysDefaultSql(cell, item, process, group, true)
+        }
+
+        let backSql = this.getSysBackSql(cell.verify.cbScripts, cell.cbTable)
+
+        if (backSql) {
+          backSql = `${defSql}
+            ${backSql}
+          `
+
+          if (cell.output) {
+            backSql += `
+              aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg,${cell.output} as mk_b_id`
+          } else {
+            backSql += `
+              aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
+          }
+
+          backSql = backSql.replace(/@ID@/ig, `'id'`)
+          backSql = backSql.replace(/@BID@/ig, `'bid'`)
+          backSql = backSql.replace(/@LoginUID@/ig, `'LoginUID'`)
+          backSql = backSql.replace(/@SessionUid@/ig, `'SessionUid'`)
+          backSql = backSql.replace(/@UserID@/ig, `'UserID'`)
+          backSql = backSql.replace(/@Appkey@/ig, `'appkey'`)
+          backSql = backSql.replace(/@typename@/ig, `'typename'`)
+          backSql = backSql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`)
+        }
+
+        if (backSql) {
+          return {
+            backSql,
+            sql
+          }
         }
       }
     } else if (cell.OpenType === 'excelIn') {
@@ -421,7 +484,88 @@
     return sql
   }
 
-  getSysDefaultSql = (btn, component, process, group) => {
+  getSysBackSql = (scripts, cbTable) => {
+    let _prev = ''
+    let _back = ''
+
+    scripts.forEach(script => {
+      if (script.status === 'false') return
+
+      if (script.position === 'front') {
+        _prev += `
+      /* 鑷畾涔夎剼鏈� */
+      ${script.sql}
+      `
+      } else {
+        _back += `
+      /* 鑷畾涔夎剼鏈� */
+      ${script.sql}
+      `
+      }
+    })
+
+    if (!_prev) return ''
+
+    let tbs = []
+    _prev.replace(/\n|\r/g, ' ').split(/\sdeclare\s/ig).forEach(line => {
+      if (!/^\s*(@|#)[a-zA-Z0-9_]+\s+table\s+\(/ig.test(line)) return
+      let tb = line.match(/(@|#)[a-zA-Z0-9_]+\s+table\s+\(.+(\)|date|datetime)\s*\)/ig)
+
+      if (tb && tb.length === 1) {
+        tbs.push(tb[0])
+      }
+    })
+
+    tbs.forEach(tb => {
+      let tbName = tb.match(/(@|#)[a-zA-Z0-9_]+/ig)[0]
+
+      if (!tbName) return
+
+      let content = tb.replace(/(@|#)[a-zA-Z0-9_]+\s+table\s+\(\s*/, '').replace(/\s*\)$/, '')
+      content = content.replace(/decimal\(\s*\d+\s*,\s*\d+\s*\)/ig, 'decimal')
+
+      let keys = []
+      let vals = []
+      let error = false
+      let istop = new RegExp(cbTable + '$', 'ig').test(tbName)
+      let id = tbName.replace(/@|#/, '')
+
+      content.split(/\s*,\s*/).forEach(m => {
+        let ms = m.split(/\s+/)
+        if (ms.length > 1) {
+          keys.push(ms[0])
+          if (/^mk_level$/i.test(ms[0])) {
+            vals.push(istop ? `'1'` : `'2'`)
+          } else if (/^mk_id$/i.test(ms[0])) {
+            vals.push(istop ? `'${cbTable}'` : `'${id}'`)
+          } else if (/^mk_bid$/i.test(ms[0])) {
+            vals.push(istop ? `''` : `'${cbTable}'`)
+          } else if (/nvarchar/i.test(ms[1])) {
+            vals.push(`'mk'`)
+          } else if (/date/i.test(ms[1])) {
+            vals.push(`'1949-10-01'`)
+          } else if (/int|decimal/i.test(ms[1])) {
+            vals.push('0')
+          } else {
+            error = true
+          }
+        } else {
+          error = true
+        }
+      })
+
+      if (error || vals.length === 0) return
+
+      _prev += `
+      Insert into ${tbName} (${keys.join(',')})
+      Select ${vals.join(',')}
+      `
+    })
+
+    return _prev + _back
+  }
+
+  getSysDefaultSql = (btn, component, process, group, retmsg) => {
     let primaryId = 'id'
     let BID = 'bid'
     let verify = btn.verify || {}
@@ -492,6 +636,9 @@
             _item.fieldlen = item.decimal || 0
           } else  if (_item.type === 'date') {
             _item.type = item.declareType === 'nvarchar(50)' ? 'text' : 'date'
+          } else if (item.declare === 'decimal') {
+            _item.type = 'number'
+            _item.fieldlen = item.decimal || 0
           }
     
           formdata.push(_item)
@@ -536,6 +683,9 @@
             _item.fieldlen = item.decimal || 0
           } else  if (_item.type === 'date') {
             _item.type = item.declareType === 'nvarchar(50)' ? 'text' : 'date'
+          } else if (item.declare === 'decimal') {
+            _item.type = 'number'
+            _item.fieldlen = item.decimal || 0
           }
     
           formdata.push(_item)
@@ -671,6 +821,10 @@
         /* 鏄剧ず鍒楀彉閲忚祴鍊� */
         select ${_initColfields.join(',')}
         `
+    }
+
+    if (retmsg) {
+      return _sql
     }
   
     // 鍘婚櫎绂佺敤鐨勯獙璇�
@@ -879,15 +1033,13 @@
         item.field.split(',').forEach((_field, index) => {
           let _key = _field.toLowerCase()
           let _val = ''
-          let _fval = `'${_val}'`
   
+          arr.push(_key)
           if (_key === 'bid') { // 琛ㄥ崟涓病鏈塨id鍒欎娇鐢ㄧ郴缁焍id鍙橀噺
-            _fval = '@BID@'
+            _val = BID
           }
 
-          arr.push(_key)
-          _fieldValue.push(`${_key}=${_fval}`)
-          
+          _fieldValue.push(`${_key}='${_val}'`)
           _value.push(`${_labels[index] || ''}锛�${_val || ''}`)
         })
   
diff --git a/src/menu/pastecontroller/index.jsx b/src/menu/pastecontroller/index.jsx
index 513c64e..1ef0452 100644
--- a/src/menu/pastecontroller/index.jsx
+++ b/src/menu/pastecontroller/index.jsx
@@ -1,7 +1,9 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
+import { fromJS } from 'immutable'
 import { Modal, Button, notification } from 'antd'
 import { SnippetsOutlined } from '@ant-design/icons'
+import md5 from 'md5'
 
 import MenuUtils from '@/utils/utils-custom.js'
 import asyncComponent from '@/utils/asyncComponent'
@@ -18,60 +20,264 @@
     visible: false
   }
 
-  resetconfig = (item, appType) => {
+  resetconfig = (item, appType, commonId) => {
     if (item.type === 'tabs') {
-      item.uuid = MenuUtils.getuuid()
+      item.uuid = md5(commonId + item.uuid)
       item.setting.name = (item.setting.name || '') + MenuUtils.getSignName()
       item.name = item.setting.name
 
       item.subtabs.forEach(tab => {
-        tab.uuid = MenuUtils.getuuid()
+        tab.uuid = md5(commonId + tab.uuid)
 
         if (appType !== 'mob') {
           tab.components = tab.components.filter(cell => cell.type !== 'menubar')
         }
 
         tab.components = tab.components.map(cell => {
-          cell = this.resetconfig(cell, appType)
+          cell = this.resetconfig(cell, appType, commonId)
           return cell
         })
       })
     } else if (item.type === 'group') {
-      item.uuid = MenuUtils.getuuid()
+      item.uuid = md5(commonId + item.uuid)
       item.setting.name = (item.setting.name || '') + MenuUtils.getSignName()
       item.name = item.setting.name
 
       item.components = item.components.map(cell => {
-        cell = MenuUtils.resetComponentConfig(cell, appType)
+        cell.uuid = md5(commonId + cell.uuid)
+
+        cell = MenuUtils.resetComponentConfig(cell, appType, commonId)
         return cell
       })
     } else {
-      item = MenuUtils.resetComponentConfig(item, appType)
+      item.uuid = md5(commonId + item.uuid)
+
+      item = MenuUtils.resetComponentConfig(item, appType, commonId)
     }
 
     return item
   }
 
-  pasteSubmit = () => {
-    let appType = sessionStorage.getItem('appType')
-    let options = ['tabs', 'timeline', 'datacard', 'propcard', 'simpleform', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'bar', 'editor', 'pie', 'scatter', 'iframe', 'sandbox']
+  resetlink = (item, commonId) => {
+    if (item.type === 'tabs') {
+      item.subtabs.forEach(tab => {
+        tab.components.forEach(cell => {
+          this.resetlink(cell, commonId)
+        })
+      })
+    } else if (item.type === 'group') {
+      item.components.forEach(cell => {
+        this.resetlink(cell, commonId)
+      })
+    } else {
+      if (['card', 'carousel', 'timeline'].includes(item.type)) {
+        item.subcards.forEach(card => {
+          card.elements && card.elements.forEach(cell => {
+            if (cell.eleType === 'button') {
+              this.resetBtn(cell, commonId)
+            }
+          })
+          card.backElements && card.backElements.forEach(cell => {
+            if (cell.eleType === 'button') {
+              this.resetBtn(cell, commonId)
+            }
+          })
+        })
+      } else if (item.type === 'balcony') {
+        item.elements && item.elements.forEach(cell => {
+          if (cell.eleType === 'button') {
+            this.resetBtn(cell, commonId)
+          }
+        })
+      } else if (item.type === 'table' && item.cols) {
+        let loopCol = (cols) => {
+          cols.forEach(col => {
+            if (col.type === 'colspan' && col.subcols) {
+              loopCol(col.subcols)
+            } else if (col.type === 'custom' && col.elements) {
+              col.elements.forEach(cell => {
+                if (cell.eleType === 'button') {
+                  this.resetBtn(cell, commonId)
+                }
+              })
+            }
+          })
+        }
+  
+        loopCol(item.cols)
+      } else if (item.type === 'form') {
+        item.subcards.forEach(cell => {
+          if (cell.subButton) {
+            this.resetBtn(cell.subButton, commonId)
+          }
+        })
+      }
+  
+      item.action && item.action.forEach(cell => {
+        this.resetBtn(cell, commonId)
+      })
 
-    if (appType === 'mob') {
-      if (sessionStorage.getItem('editMenuType') !== 'popview') {
-        options.push('menubar', 'topbar', 'singleSearch')
-      } else {
+      if (item.wrap && item.wrap.supType === 'multi') {
+        if (item.setting && item.setting.supModule) {
+          item.setting.supModule = ''
+        }
+
+        if (item.supNodes) {
+          item.supNodes = item.supNodes.map(cell => {
+            let id = cell.nodes[cell.nodes.length - 1]
+            let _id = md5(commonId + id)
+  
+            if (this.modules[id] || this.modules[_id]) {
+              cell.nodes = this.modules[id] || this.modules[_id]
+              cell.componentId = cell.nodes[cell.nodes.length - 1]
+  
+              return cell
+            }
+  
+            return null
+          })
+  
+          item.supNodes = item.supNodes.filter(Boolean)
+        }
+
+        if (!item.supNodes || item.supNodes.length === 0) {
+          item.wrap.supType = 'single'
+          delete item.supNodes
+        }
+      }
+      if (item.setting && item.setting.supModule && item.setting.supModule[0] !== 'empty') {
+        let id = item.setting.supModule[item.setting.supModule.length - 1]
+        let _id = md5(commonId + id)
+
+        item.setting.supModule = this.modules[id] || this.modules[_id] || ''
+      }
+
+      if (item.wrap && item.wrap.supModule && item.wrap.supModule[0]) {
+        let id = item.wrap.supModule[item.wrap.supModule.length - 1]
+        let _id = md5(commonId + id)
+
+        item.wrap.supModule = this.modules[id] || this.modules[_id] || ''
+      }
+    }
+  }
+
+  resetBtn (btn, commonId) {
+    if (btn.switchTab && btn.switchTab.length > 0) {
+      let id = btn.switchTab[btn.switchTab.length - 1]
+      let _id = md5(commonId + id)
+
+      btn.switchTab = this.modules[id] || this.modules[_id] || null
+    }
+    if (btn.anchors && btn.anchors.length > 0) {
+      let id = btn.anchors[btn.anchors.length - 1]
+      let _id = md5(commonId + id)
+
+      btn.anchors = this.modules[id] || this.modules[_id] || null
+    }
+    if (btn.syncComponent && btn.syncComponent[0] === 'multiComponent' && btn.syncComponents) {
+      btn.syncComponents = btn.syncComponents.map(m => {
+        let id = m.syncComId[m.syncComId.length - 1]
+        let _id = md5(commonId + id)
+
+        return this.modules[id] || this.modules[_id] || null
+      })
+      btn.syncComponents = btn.syncComponents.filter(Boolean)
+
+      if (btn.syncComponents.length === 0) {
+        btn.syncComponent = null
+        btn.syncComponents = null
+      }
+    } else if (btn.syncComponent && btn.syncComponent.length > 0) {
+      let id = btn.syncComponent[btn.syncComponent.length - 1]
+      let _id = md5(commonId + id)
+
+      btn.syncComponent = this.modules[id] || this.modules[_id] || null
+    }
+  }
+
+  resetmenu = (components, componentId, res) => {
+    components.forEach(item => {
+      if (item.type === 'tabs') {
+        item.subtabs.forEach(tab => {
+          if (tab.uuid === componentId) {
+            tab.components.push(res)
+          } else {
+            this.resetmenu(tab.components, componentId, res)
+          }
+        })
+      } else if (item.type === 'group' && item.uuid === componentId) {
+        item.components.push(res)
+      }
+    })
+  }
+
+  getModules = (components, interfaces, sups = []) => {
+    components.forEach(item => {
+      this.modules[item.uuid] = [...sups, item.uuid]
+      if (item.type === 'tabs') {
+        item.subtabs.forEach(f_tab => {
+          this.getModules(f_tab.components, null, [...sups, item.uuid, f_tab.uuid])
+        })
+      } else if (item.type === 'group') {
+        item.components.forEach(cell => {
+          this.modules[cell.uuid] = [...sups, item.uuid, cell.uuid]
+        })
+      }
+    })
+
+    if (interfaces && interfaces.length > 0) {
+      interfaces.forEach(item => {
+        this.modules[item.uuid] = [item.uuid]
+      })
+    }
+  }
+
+  pasteSubmit = () => {
+    const { type, tab } = this.props
+
+    let appType = sessionStorage.getItem('appType')
+    // ['calendar', 'balcony', 'datacard', 'doublecard', 'propcard', 'tablecard', 'cardatacard', 'carpropcard', 'line', 'dashboard', 'antvG6', 'pie', 'scatter', 'antvX6', 'chart', 'sandbox', 'editor', 'simpleform', 'stepform', 'tabform', 'group', 'iframe', 'mainsearch', 'basetable', 'editable', 'normaltable', 'tabs', 'timeline', 'tree', 'menubar', 'singleSearch', 'topbar']
+    let options = []
+
+    let types = {
+      topbar: '瀵艰埅鏍�',
+      singleSearch: '鎼滅储',
+      iframe: 'iframe',
+      tabs: '鏍囩椤�',
+      group: '鍒嗙粍',
+      menubar: '鑿滃崟鏍�',
+      mainsearch: '鎼滅储'
+    }
+
+    if (!type) {
+      options = ['tabs', 'timeline', 'datacard', 'doublecard', 'propcard', 'cardatacard', 'carpropcard', 'simpleform', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'editor', 'pie', 'scatter', 'iframe', 'sandbox']
+  
+      if (appType === 'mob') {
         options.push('menubar', 'singleSearch')
+        if (sessionStorage.getItem('editMenuType') !== 'popview') {
+          options.push('topbar')
+        }
+      } else {
+        options.push('editable', 'mainsearch', 'antvG6', 'antvX6', 'calendar', 'tree', 'dashboard', 'chart')
       }
     } else {
-      options.push('editable', 'mainsearch', 'antvG6', 'antvX6', 'calendar', 'tree', 'dashboard', 'chart')
+      if (appType === 'mob') {
+        options = ['balcony', 'datacard', 'doublecard', 'propcard', 'tablecard', 'cardatacard', 'carpropcard', 'line', 'pie', 'scatter', 'sandbox', 'editor', 'simpleform', 'stepform', 'tabform', 'normaltable', 'timeline']
+  
+        if (type === 'tabs') {
+          options.push('tabs', 'group', 'menubar')
+        }
+      } else {
+        options = ['calendar', 'balcony', 'datacard', 'doublecard', 'propcard', 'tablecard', 'cardatacard', 'carpropcard', 'line', 'dashboard', 'antvG6', 'pie', 'scatter', 'antvX6', 'chart', 'sandbox', 'editor', 'simpleform', 'stepform', 'tabform', 'editable', 'normaltable', 'timeline', 'tree']
+        
+        if (type === 'tabs') {
+          options.push('tabs', 'group', 'mainsearch')
+        }
+      }
     }
 
     this.pasteFormRef.handleConfirm().then(res => {
-      if (res.copyType === 'basetable') {
-        res.copyType = 'normaltable'
-        res.subtype = 'normaltable'
-      }
-      if (!options.includes(res.copyType)) {
+      if (!res.copyType) {
         notification.warning({
           top: 92,
           message: '閰嶇疆淇℃伅鏍煎紡閿欒锛�',
@@ -80,22 +286,116 @@
         return
       }
 
-      res = this.resetconfig(res, appType)
+      if (res.copyType === 'basetable') {
+        res.copyType = 'normaltable'
+        res.subtype = 'normaltable'
+      }
 
-      // delete res.copyType
+      let menu = fromJS(window.GLOB.customMenu).toJS()
+      
+      if (!options.includes(res.copyType)) {
+        if (type && types[res.copyType]) {
+          notification.warning({
+            top: 92,
+            message: (type === 'group' ? '鍒嗙粍涓�' : '鏍囩椤典腑') + '涓嶅彲娣诲姞銆�' + types[res.copyType] + '銆嬬粍浠讹紒',
+            duration: 5
+          })
+          return
+        } else {
+          notification.warning({
+            top: 92,
+            message: '閰嶇疆淇℃伅鏍煎紡閿欒锛�',
+            duration: 5
+          })
+        }
+        return
+      } else if (appType === 'mob') {
+        if (res.type === 'search') {
+          if (menu.components.filter(card => card.type === 'topbar' && card.wrap.type !== 'navbar').length > 0) {
+            notification.warning({
+              top: 92,
+              message: '瀵艰埅鏍忎娇鐢ㄤ簡鎼滅储锛屼笉鍙坊鍔犳悳绱㈢粍浠讹紒',
+              duration: 5
+            })
+            return
+          }
+          if (menu.components.filter(card => card.type === 'search').length > 0) {
+            notification.warning({
+              top: 92,
+              message: '鎼滅储鏉′欢涓嶅彲閲嶅娣诲姞锛�',
+              duration: 5
+            })
+            return
+          }
+        } else if (res.type === 'topbar') {
+          if (menu.components.findIndex(m => m.type === 'topbar') > -1) {
+            notification.warning({
+              top: 92,
+              message: '瀵艰埅鏍忎笉鍙噸澶嶆坊鍔狅紒',
+              duration: 5
+            })
+            return
+          }
+        }
+      } else if (res.type === 'search') {
+        if (tab) {
+          if (tab.components.findIndex(card => card.type === 'search') > -1) {
+            notification.warning({
+              top: 92,
+              message: '鎼滅储鏉′欢涓嶅彲閲嶅娣诲姞锛�',
+              duration: 5
+            })
+            return
+          }
+        } else {
+          if (menu.components.findIndex(m => m.type === 'search') > -1) {
+            notification.warning({
+              top: 92,
+              message: '鎼滅储鏉′欢涓嶅彲閲嶅娣诲姞锛�',
+              duration: 5
+            })
+            return
+          }
+        }
+      }
+      delete res.copyType
+
+      let commonId = MenuUtils.getuuid()
+
+      res = this.resetconfig(res, appType, commonId)
+
+      if (tab) {
+        this.resetmenu(menu.components, tab.uuid, res)
+      } else {
+        menu.components.push(res)
+      }
+
+      this.modules = {}
+
+      this.getModules(menu.components, menu.interfaces)
+
+      this.resetlink(res, commonId)
       
       this.props.insert(res)
 
       this.setState({visible: false})
+
+      notification.success({
+        top: 92,
+        message: '绮樿创鎴愬姛锛�',
+        duration: 2
+      })
     })
   }
 
   render() {
+    const { type } = this.props
     const { visible } = this.state
 
     return (
       <>
-        <Button style={{borderColor: '#40a9ff', color: '#40a9ff'}} onClick={() => {this.setState({visible: true})}}><SnippetsOutlined />绮樿创</Button>
+        {type ? <SnippetsOutlined style={{color: 'purple'}} onClick={() => {this.setState({visible: true})}} /> :
+        <Button style={{borderColor: '#40a9ff', color: '#40a9ff'}} onClick={() => {this.setState({visible: true})}}><SnippetsOutlined />绮樿创</Button>}
         <Modal
           title="绮樿创"
           visible={visible}
diff --git a/src/mob/components/tabs/antv-tabs/index.jsx b/src/mob/components/tabs/antv-tabs/index.jsx
index fdd6b21..9653b81 100644
--- a/src/mob/components/tabs/antv-tabs/index.jsx
+++ b/src/mob/components/tabs/antv-tabs/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Tabs, Popover, Modal, notification } from 'antd'
+import { Tabs, Popover, Modal } from 'antd'
 import { ToolOutlined, PlusOutlined, EditOutlined, FontColorsOutlined, DeleteOutlined, CloseOutlined } from '@ant-design/icons'
 
 import MKEmitter from '@/utils/events.js'
@@ -16,7 +16,7 @@
 
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
-const PasteComponent = asyncIconComponent(() => import('@/menu/components/tabs/paste'))
+const PasteController = asyncIconComponent(() => import('@/menu/pastecontroller'))
 const TabComponents = asyncComponent(() => import('../tabcomponents'))
 
 const { TabPane } = Tabs
@@ -203,20 +203,11 @@
     this.props.updateConfig(tabs)
   }
 
-  insert = (item, tab) => {
+  insert = (item, tabId) => {
     let tabs = fromJS(this.state.tabs).toJS()
 
-    if (item.type === 'search') {
-      notification.warning({
-        top: 92,
-        message: '绉诲姩绔悳绱㈢粍浠朵笉鍙矘璐达紒',
-        duration: 5
-      })
-      return
-    }
-
     tabs.subtabs.forEach(stab => {
-      if (stab.uuid === tab.uuid) {
+      if (stab.uuid === tabId) {
         stab.components.push(item)
       }
     })
@@ -251,7 +242,7 @@
     editab.hide = res.hide || 'false'
     editab.backgroundColor = res.backgroundColor
     // editab.controlVal = res.controlVal || ''
-    editab.selectVal = res.selectVal || ''
+    // editab.selectVal = res.selectVal || ''
     editab.blacklist = res.blacklist
 
     if (editab.uuid) {
@@ -295,6 +286,17 @@
 
       delete res.controlVals
     }
+    if (res.selectVals) {
+      let values = {}
+      res.selectVals.forEach(item => {
+        values[item.uuid] = item.value
+      })
+      tabs.subtabs.forEach(tab => {
+        tab.selectVal = values[tab.uuid]
+      })
+
+      delete res.selectVals
+    }
 
     tabs.setting = res
 
@@ -321,7 +323,7 @@
                   <NormalForm title="鏍囩缂栬緫" width={800} update={this.updateTab} getForms={() => this.getTabForms(tab)}>
                     <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
                   </NormalForm>
-                  <PasteComponent Tab={tab} insert={this.insert} />
+                  <PasteController type="tabs" tab={tab} insert={(item) => this.insert(item, tab.uuid)} />
                   <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeTabStyle}/>
                   <CloseOutlined className="close" onClick={() => this.delTab(tab)} />
                 </div>
diff --git a/src/mob/components/tabs/antv-tabs/options.jsx b/src/mob/components/tabs/antv-tabs/options.jsx
index 3fe37fb..0fd6eca 100644
--- a/src/mob/components/tabs/antv-tabs/options.jsx
+++ b/src/mob/components/tabs/antv-tabs/options.jsx
@@ -41,14 +41,14 @@
     //   tooltip: '褰撶鐢ㄥ瓧娈靛�间笌闅愯棌鏍囪鐩哥瓑鏃讹紝鏍囩椤典細闅愯棌銆傛敞锛氬涓�艰鐢ㄩ�楀彿鍒嗛殧銆�',
     //   required: false
     // },
-    {
-      type: 'text',
-      field: 'selectVal',
-      label: '閫変腑鏍囪',
-      initval: tab.selectVal || '',
-      tooltip: '褰撻�変腑瀛楁鍊间笌閫変腑鏍囪鐩哥瓑鏃讹紝鏍囩椤甸粯璁ら�変腑銆�',
-      required: false
-    },
+    // {
+    //   type: 'text',
+    //   field: 'selectVal',
+    //   label: '閫変腑鏍囪',
+    //   initval: tab.selectVal || '',
+    //   tooltip: '褰撻�変腑瀛楁鍊间笌閫変腑鏍囪鐩哥瓑鏃讹紝鏍囩椤甸粯璁ら�変腑銆�',
+    //   required: false
+    // },
     {
       type: 'color',
       field: 'backgroundColor',
@@ -82,7 +82,8 @@
     label: '涓婁竴椤碉紙url鍙傛暟锛�'
   })
 
-  let controlVals = subtabs.map(item => ({uuid: item.uuid, label: item.label, value: item.controlVal}))
+  let controlVals = subtabs.map(item => ({uuid: item.uuid, label: item.label, value: item.controlVal || ''}))
+  let selectVals = subtabs.map(item => ({uuid: item.uuid, label: item.label, value: item.selectVal || ''}))
 
   const tabForm = [
     {
@@ -156,7 +157,10 @@
       label: '閫変腑瀛楁',
       initval: setting.selectField || '',
       tooltip: '鐢ㄤ簬鎺у埗鏍囩椤靛垵濮嬪寲閫変腑锛屽湪鏍囩涓~鍏ラ�変腑鏍囪锛屾敞锛氭暟鎹簮浜巙rl鍙傛暟銆�',
-      required: false
+      required: false,
+      controlFields: [
+        {field: 'selectVals', notNull: true},
+      ]
     },
     {
       type: 'color',
@@ -180,11 +184,11 @@
     {
       type: 'table',
       field: 'controlVals',
-      label: '鏍囩缁�',
+      label: '鏍囩缁�(绂佺敤)',
       initval: controlVals,
       tooltip: '褰撶鐢ㄥ瓧娈靛�间笌闅愯棌鏍囪鐩哥瓑鏃讹紝鏍囩椤典細闅愯棌銆傛敞锛�1銆佸涓�艰鐢ㄩ�楀彿鍒嗛殧锛�2銆丂pass@鍊艰〃绀哄拷鐣ユ璁剧疆锛堝缁堟樉绀猴級锛�2銆丂pass_empty@鍊艰〃绀哄拷鐣ョ┖鍊硷紝鍗虫湭鑾峰彇涓婄骇缁勪欢淇℃伅鏃舵樉绀猴紙鍙笌鍏朵粬鍊兼嫾鎺ワ級銆�',
       required: false,
-      fixed: true,
+      actions: ['edit'],
       span: 24,
       columns: [
         {
@@ -203,6 +207,33 @@
           width: '50%'
         }
       ]
+    },
+    {
+      type: 'table',
+      field: 'selectVals',
+      label: '鏍囩缁�(閫変腑)',
+      initval: selectVals,
+      tooltip: '褰撻�変腑瀛楁鍊间笌閫変腑鏍囪鐩哥瓑鏃讹紝鏍囩椤甸粯璁ら�変腑銆�',
+      required: false,
+      actions: ['edit'],
+      span: 24,
+      columns: [
+        {
+          title: '鏍囩鍚嶇О',
+          dataIndex: 'label',
+          editable: false,
+          required: false,
+          width: '30%'
+        },
+        {
+          title: '閫変腑鏍囪',
+          dataIndex: 'value',
+          inputType: 'input',
+          editable: true,
+          required: false,
+          width: '50%'
+        }
+      ]
     }
   ]
 
diff --git a/src/mob/components/tabs/tabcomponents/index.jsx b/src/mob/components/tabs/tabcomponents/index.jsx
index 1d146b5..8097bd05 100644
--- a/src/mob/components/tabs/tabcomponents/index.jsx
+++ b/src/mob/components/tabs/tabcomponents/index.jsx
@@ -80,7 +80,7 @@
     drop(item) {
       if (item.hasOwnProperty('originalIndex') || item.added) {
         return
-      } else if (['login', 'navbar', 'topbar'].includes(item.component)) {
+      } else if (['login', 'navbar', 'topbar', 'iframe', 'sharecode', 'officialAccount'].includes(item.component)) {
         return
       }
       
diff --git a/src/mob/components/topbar/normal-navbar/options.jsx b/src/mob/components/topbar/normal-navbar/options.jsx
index 5fbab72..33f0c7d 100644
--- a/src/mob/components/topbar/normal-navbar/options.jsx
+++ b/src/mob/components/topbar/normal-navbar/options.jsx
@@ -219,7 +219,7 @@
       initval: wrap.menus || [],
       required: false,
       span: 24,
-      actions: ['view'],
+      actions: ['edit', 'del', 'add', 'move', 'view'],
       tip: <span style={{fontSize: '12px', color: '#959595', position: 'relative', top: '-8px'}}>褰撲娇鐢ㄥ浘鏍�<MkIcon type="user"/>锛屼笖鍙充晶鍙湁涓�涓彍鍗曟椂锛屼細鏄剧ず鐢ㄦ埛澶村儚銆�</span>,
       columns: [
         {
diff --git a/src/pc/components/login/normal-login/options.jsx b/src/pc/components/login/normal-login/options.jsx
index 634d7bf..72dae60 100644
--- a/src/pc/components/login/normal-login/options.jsx
+++ b/src/pc/components/login/normal-login/options.jsx
@@ -232,6 +232,7 @@
       label: '鍗忚缁�',
       initval: wrap.groups || [],
       required: true,
+      actions: ['edit', 'del', 'add', 'move'],
       span: 24,
       columns: [
         {
diff --git a/src/tabviews/basetable/index.jsx b/src/tabviews/basetable/index.jsx
index f2dd7d0..444c709 100644
--- a/src/tabviews/basetable/index.jsx
+++ b/src/tabviews/basetable/index.jsx
@@ -208,7 +208,7 @@
           }
         })
       }
-      
+
       // 鑾峰彇涓绘悳绱㈡潯浠�
       config.components.forEach(component => {
         if (component.type === 'tabs') return
@@ -484,7 +484,7 @@
     }
 
     if (cell.OpenType === 'excelOut') { // 瀵煎嚭
-      cell.$menuName = item.name
+      cell.$menuName = item.$menuname
 
       if (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0) {
         cell.errorType = 'error1'
diff --git a/src/tabviews/custom/components/card/cardcellList/index.jsx b/src/tabviews/custom/components/card/cardcellList/index.jsx
index 5535c30..142622f 100644
--- a/src/tabviews/custom/components/card/cardcellList/index.jsx
+++ b/src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -1011,148 +1011,114 @@
         if (card.wrapStyle) {
           _style_ = {..._style_, ...card.wrapStyle}
         }
+
+        let MkButton = null
   
         if (['exec', 'prompt', 'pop', 'form'].includes(card.OpenType)) {
-          contents.push(
-            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
-              <NormalButton
-                btn={card}
-                BID={data.$$BID}
-                BData={data.$$BData || ''}
-                disabled={_disabled}
-                setting={cards.setting}
-                columns={cards.columns}
-                selectedData={_data}
-              />
-            </div>
-          )
+          MkButton = <NormalButton
+            btn={card}
+            BID={data.$$BID}
+            BData={data.$$BData || ''}
+            disabled={_disabled}
+            setting={cards.setting}
+            columns={cards.columns}
+            selectedData={_data}
+          />
         } else if (card.OpenType === 'excelIn') {
-          contents.push(
-            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
-              <ExcelInButton
-                btn={card}
-                BID={data.$$BID}
-                BData={data.$$BData || ''}
-                disabled={_disabled}
-                setting={cards.setting}
-                selectedData={_data}
-              />
-            </div>
-          )
+          MkButton = <ExcelInButton
+            btn={card}
+            BID={data.$$BID}
+            BData={data.$$BData || ''}
+            disabled={_disabled}
+            setting={cards.setting}
+            selectedData={_data}
+          />
         } else if (card.OpenType === 'excelOut') {
-          contents.push(
-            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
-              <ExcelOutButton
-                btn={card}
-                BID={data.$$BID}
-                BData={data.$$BData || ''}
-                disabled={_disabled}
-                setting={cards.setting}
-                selectedData={_data}
-              />
-            </div>
-          )
+          MkButton = <ExcelOutButton
+            btn={card}
+            BID={data.$$BID}
+            BData={data.$$BData || ''}
+            disabled={_disabled}
+            setting={cards.setting}
+            selectedData={_data}
+          />
         } else if (card.OpenType === 'popview') {
-          contents.push(
-            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
-              <PopupButton
-                btn={card}
-                BID={data.$$BID}
-                BData={data.$$BData || ''}
-                disabled={_disabled}
-                setting={cards.setting}
-                selectedData={_data}
-              />
-            </div>
-          )
+          MkButton = <PopupButton
+            btn={card}
+            BID={data.$$BID}
+            BData={data.$$BData || ''}
+            disabled={_disabled}
+            setting={cards.setting}
+            selectedData={_data}
+          />
         } else if (card.OpenType === 'tab') {
-          contents.push(
-            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
-              <TabButton
-                btn={card}
-                BID={data.$$BID}
-                BData={data.$$BData || ''}
-                disabled={_disabled}
-                selectedData={_data}
-              />
-            </div>
-          )
+          MkButton = <TabButton
+            btn={card}
+            BID={data.$$BID}
+            BData={data.$$BData || ''}
+            disabled={_disabled}
+            selectedData={_data}
+          />
         } else if (card.OpenType === 'innerpage') {
-          contents.push(
-            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
-              <NewPageButton
-                btn={card}
-                BID={data.$$BID}
-                BData={data.$$BData || ''}
-                disabled={_disabled}
-                selectedData={_data}
-              />
-            </div>
-          )
+          MkButton = <NewPageButton
+            btn={card}
+            BID={data.$$BID}
+            BData={data.$$BData || ''}
+            disabled={_disabled}
+            selectedData={_data}
+          />
         } else if (card.OpenType === 'funcbutton') {
           if (card.funcType === 'changeuser' || card.funcType === 'closetab') {
-            contents.push(
-              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
-                <ChangeUserButton
-                  btn={card}
-                  BID={data.$$BID}
-                  BData={data.$$BData || ''}
-                  disabled={_disabled}
-                  setting={cards.setting}
-                  selectedData={_data}
-                />
-              </div>
-            )
+            MkButton = <ChangeUserButton
+              btn={card}
+              BID={data.$$BID}
+              BData={data.$$BData || ''}
+              disabled={_disabled}
+              setting={cards.setting}
+              selectedData={_data}
+            />
           } else if (card.funcType === 'print') {
-            contents.push(
-              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
-                <PrintButton
-                  btn={card}
-                  BID={data.$$BID}
-                  BData={data.$$BData || ''}
-                  disabled={_disabled}
-                  setting={cards.setting}
-                  columns={cards.columns}
-                  selectedData={_data}
-                />
-              </div>
-            )
+            MkButton = <PrintButton
+              btn={card}
+              BID={data.$$BID}
+              BData={data.$$BData || ''}
+              disabled={_disabled}
+              setting={cards.setting}
+              columns={cards.columns}
+              selectedData={_data}
+            />
           } else if (card.funcType === 'megvii') {
-            contents.push(
-              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
-                <FuncMegvii
-                  btn={card}
-                  BID={data.$$BID}
-                  disabled={_disabled}
-                  setting={cards.setting}
-                  selectedData={_data}
-                />
-              </div>
-            )
+            MkButton = <FuncMegvii
+              btn={card}
+              BID={data.$$BID}
+              disabled={_disabled}
+              setting={cards.setting}
+              selectedData={_data}
+            />
           } else if (card.funcType === 'filezip') {
-            contents.push(
-              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
-                <FuncZip
-                  btn={card}
-                  BID={data.$$BID}
-                  disabled={_disabled}
-                  setting={cards.setting}
-                  selectedData={_data}
-                />
-              </div>
-            )
+            MkButton = <FuncZip
+              btn={card}
+              BID={data.$$BID}
+              disabled={_disabled}
+              setting={cards.setting}
+              selectedData={_data}
+            />
           } else if (card.funcType === 'addline' || card.funcType === 'delline') {
-            contents.push(
-              <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
-                <EditLine
-                  btn={card}
-                  disabled={_disabled}
-                  selectedData={_data}
-                />
-              </div>
-            )
+            MkButton = <EditLine
+              btn={card}
+              disabled={_disabled}
+              selectedData={_data}
+            />
           }
         }
+
+        if (MkButton) {
+          contents.push(
+            <div className={'ant-col mk-cell-btn ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
+              {MkButton}
+            </div>
+          )
+        }
       }
     })
 
diff --git a/src/tabviews/custom/components/card/data-card/index.jsx b/src/tabviews/custom/components/card/data-card/index.jsx
index 1e3d074..4315f80 100644
--- a/src/tabviews/custom/components/card/data-card/index.jsx
+++ b/src/tabviews/custom/components/card/data-card/index.jsx
@@ -236,6 +236,8 @@
     }
 
     this.initExec()
+
+    this.autoExec()
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -330,6 +332,25 @@
     }
   }
 
+  autoExec = (times) => {
+    const { config } = this.state
+
+    if (!config.wrap.autoExec) return
+
+    let btn = document.getElementById('button' + config.wrap.autoExec)
+
+    this.autoTimer && clearTimeout(this.autoTimer)
+
+    if (btn) {
+      MKEmitter.emit('triggerBtnId', config.wrap.autoExec, [])
+    } else if (!times || times < 20) {
+      times = times ? times + 1 : 1
+      this.autoTimer = setTimeout(() => {
+        this.autoExec(times)
+      }, 1000)
+    }
+  }
+
   transferSyncData = (syncId) => {
     const { config } = this.state
 
diff --git a/src/tabviews/custom/components/card/double-data-card/index.jsx b/src/tabviews/custom/components/card/double-data-card/index.jsx
index e65fe19..df7f722 100644
--- a/src/tabviews/custom/components/card/double-data-card/index.jsx
+++ b/src/tabviews/custom/components/card/double-data-card/index.jsx
@@ -229,6 +229,8 @@
     if (config.setting.onload === 'true') {
       this.initExec()
     }
+
+    this.autoExec()
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -319,6 +321,25 @@
       setTimeout(() => {
         this.loadData()
       }, config.setting.delay || 0)
+    }
+  }
+
+  autoExec = (times) => {
+    const { config } = this.state
+
+    if (!config.wrap.autoExec) return
+
+    let btn = document.getElementById('button' + config.wrap.autoExec)
+
+    this.autoTimer && clearTimeout(this.autoTimer)
+
+    if (btn) {
+      MKEmitter.emit('triggerBtnId', config.wrap.autoExec, [])
+    } else if (!times || times < 20) {
+      times = times ? times + 1 : 1
+      this.autoTimer = setTimeout(() => {
+        this.autoExec(times)
+      }, 1000)
     }
   }
 
@@ -1193,6 +1214,20 @@
                     subClass = opens.indexOf(item.key) > -1 ? 'mk-unfold' : 'mk-collapse'
                     unfold = opens.indexOf(item.key) > -1
                   }
+
+                  if (!unfold && item.children.length > 5) {
+                    return (
+                      <Col key={index} span={card.setting.width} style={card.wStyle}>
+                        <div className={className} style={wrapStyle}>
+                          <CardItem card={card} cards={config} data={item} onDoubleClick={() => this.onDoubleClick(item.key, subClass)} onClick={() => {this.changeCard(item.key, item, subClass)}}>
+                            <span className="circle-select"></span>
+                            {card.setting.controlIcon === 'left' ? <PlusSquareOutlined className={subClass} onClick={(e) => this.changeUnfold(e, item.key, subClass)}/> : null}
+                            {card.setting.controlIcon === 'right' ? <UpOutlined className={subClass} onClick={(e) => this.changeUnfold(e, item.key, subClass)}/> : null}
+                          </CardItem>
+                        </div>
+                      </Col>
+                    )
+                  }
                 }
 
                 return (
diff --git a/src/tabviews/custom/components/card/prop-card/index.jsx b/src/tabviews/custom/components/card/prop-card/index.jsx
index 93ab97e..82064c3 100644
--- a/src/tabviews/custom/components/card/prop-card/index.jsx
+++ b/src/tabviews/custom/components/card/prop-card/index.jsx
@@ -377,7 +377,7 @@
 
     let btn = document.getElementById('button' + config.wrap.autoExec)
 
-    clearTimeout(this.autoTimer)
+    this.autoTimer && clearTimeout(this.autoTimer)
 
     if (btn) {
       MKEmitter.emit('triggerBtnId', config.wrap.autoExec, data.$$empty ? [] : [data])
diff --git a/src/tabviews/custom/components/interfaces/interItem/index.jsx b/src/tabviews/custom/components/interfaces/interItem/index.jsx
index 0d86e30..185a5a6 100644
--- a/src/tabviews/custom/components/interfaces/interItem/index.jsx
+++ b/src/tabviews/custom/components/interfaces/interItem/index.jsx
@@ -124,6 +124,10 @@
     let searches = []
     if (config.setting.useMSearch) {
       searches = window.GLOB.SearchBox.get(config.$searchId) || []
+
+      if (window.GLOB.SearchBox.has(config.$searchId + 'required') && searches.filter(item => item.required && item.value === '').length > 0) {
+        return
+      }
     }
 
     this.loading = true
diff --git a/src/tabviews/custom/components/table/base-table/index.jsx b/src/tabviews/custom/components/table/base-table/index.jsx
index 0693483..7f975c1 100644
--- a/src/tabviews/custom/components/table/base-table/index.jsx
+++ b/src/tabviews/custom/components/table/base-table/index.jsx
@@ -606,6 +606,25 @@
     })
   }
 
+  autoExec = (times) => {
+    const { config } = this.state
+
+    if (!config.wrap.autoExec) return
+
+    let btn = document.getElementById('button' + config.wrap.autoExec)
+
+    this.autoTimer && clearTimeout(this.autoTimer)
+
+    if (btn) {
+      MKEmitter.emit('triggerBtnId', config.wrap.autoExec, [])
+    } else if (!times || times < 20) {
+      times = times ? times + 1 : 1
+      this.autoTimer = setTimeout(() => {
+        this.autoExec(times)
+      }, 1000)
+    }
+  }
+
   shouldComponentUpdate (nextProps, nextState) {
     return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
   }
@@ -621,6 +640,8 @@
     if (config.setting.useMSearch) {
       MKEmitter.addListener('searchRefresh', this.searchRefresh)
     }
+
+    this.autoExec()
   }
 
   /**
diff --git a/src/tabviews/custom/components/table/normal-table/index.jsx b/src/tabviews/custom/components/table/normal-table/index.jsx
index a1492a3..595c5e5 100644
--- a/src/tabviews/custom/components/table/normal-table/index.jsx
+++ b/src/tabviews/custom/components/table/normal-table/index.jsx
@@ -199,6 +199,8 @@
     }
 
     this.initExec()
+
+    this.autoExec()
   }
 
   /**
@@ -301,6 +303,25 @@
     }
   }
 
+  autoExec = (times) => {
+    const { config } = this.state
+
+    if (!config.wrap.autoExec) return
+
+    let btn = document.getElementById('button' + config.wrap.autoExec)
+
+    this.autoTimer && clearTimeout(this.autoTimer)
+
+    if (btn) {
+      MKEmitter.emit('triggerBtnId', config.wrap.autoExec, [])
+    } else if (!times || times < 20) {
+      times = times ? times + 1 : 1
+      this.autoTimer = setTimeout(() => {
+        this.autoExec(times)
+      }, 1000)
+    }
+  }
+
   transferSyncData = (syncId) => {
     const { config } = this.state
 
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index 5af3787..7bc164c 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -249,7 +249,7 @@
 
       let initInters = []
 
-      config.interfaces = this.formatInterSetting(config.interfaces, regs, MenuID, initInters)
+      config.interfaces = this.formatInterSetting(config.interfaces, regs, MenuID, initInters, config.MenuName)
       config.components = this.filterComponent(config.components, roleId, window.GLOB.mkActions, balMap, skip, param, MenuID, config.interfaces, config.$cache, config.$time, config.MenuName, MenuID, MenuID, config.process === 'true')
 
       let params = []
@@ -887,7 +887,7 @@
     }
 
     if (cell.OpenType === 'excelOut') { // 瀵煎嚭
-      cell.$menuName = item.name
+      cell.$menuName = item.$menuname
 
       if (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0) {
         cell.errorType = 'error1'
@@ -1175,7 +1175,7 @@
   }
 
   // 鏍煎紡鍖栭粯璁よ缃�
-  formatInterSetting = (inters, regs, MenuID, initInters) => {
+  formatInterSetting = (inters, regs, MenuID, initInters, MenuName) => {
     if (!inters) return []
 
     let initlimit = false
@@ -1233,7 +1233,7 @@
       })
       delete inter.scripts
 
-      inter.setting.$name = '鍏叡鏁版嵁婧�-' + inter.setting.name
+      inter.setting.$name = (MenuName || '') + '-鍏叡鏁版嵁婧�-' + inter.setting.name
       inter.setting.execute = inter.setting.execute !== 'false'
 
       if (!inter.setting.execute) {
diff --git a/src/tabviews/custom/popview/index.jsx b/src/tabviews/custom/popview/index.jsx
index eb22032..2012480 100644
--- a/src/tabviews/custom/popview/index.jsx
+++ b/src/tabviews/custom/popview/index.jsx
@@ -608,7 +608,7 @@
     }
 
     if (cell.OpenType === 'excelOut') { // 瀵煎嚭
-      cell.$menuName = item.name
+      cell.$menuName = item.$menuname
 
       if (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0) {
         cell.errorType = 'error1'
diff --git a/src/tabviews/rolemanage/index.jsx b/src/tabviews/rolemanage/index.jsx
index 63aa365..f397ce4 100644
--- a/src/tabviews/rolemanage/index.jsx
+++ b/src/tabviews/rolemanage/index.jsx
@@ -356,7 +356,7 @@
   /**
    * @description 鑾峰彇鏉冮檺鍒嗛厤鏍�
    */
-  getTree = (parents, options) => {
+  getTree = (parents, options, addSelf) => {
     parents.forEach(parent => {
       parent.children = []
 
@@ -367,7 +367,7 @@
             title: option.MenuName,
             key: option.MenuID,
             addSelf: option.OnlySelf === 'true',
-            tabs: option.Tabs
+            // tabs: option.Tabs
           })
         }
       })
@@ -375,13 +375,13 @@
       if (parent.children.length === 0) {
         parent.children = null
         // 閽堝鏍囩锛岀敓鎴愭柊鐨刬d锛屽苟淇濆瓨鍏宠仈鍏崇郴锛堟爣绛句笉鍞竴锛�
-        if (parent.tabs) {
-          let _uuid = Utils.getuuid()
-          linkMap.set(_uuid, parent.key)
+        // if (parent.tabs) {
+        //   let _uuid = Utils.getuuid()
+        //   linkMap.set(_uuid, parent.key)
 
-          parent.originKey = parent.key
-          parent.key = _uuid
-        }
+        //   parent.originKey = parent.key
+        //   parent.key = _uuid
+        // }
       } else {
         // 涓夌骇鑿滃崟鍒涘缓瀛愰」
         if (parent.addSelf) {
@@ -392,20 +392,29 @@
           parent.children.unshift({
             title: parent.title + '(浠呴〉闈�)',
             key: _uuid,
-            isSubView: true
+            // isSubView: true
+          })
+        } else if (addSelf) {
+          let _uuid = Utils.getuuid()
+          linkMap.set(_uuid, parent.key)
+          parent.subKey = _uuid
+
+          parent.children.unshift({
+            title: parent.title + '(琛ㄦ牸)',
+            key: _uuid,
           })
         }
 
         // 閽堝鏍囩锛岀敓鎴愭柊鐨刬d锛屽苟淇濆瓨鍏宠仈鍏崇郴锛堟爣绛句笉鍞竴锛�
-        if (parent.tabs) {
-          let _uuid = Utils.getuuid()
-          linkMap.set(_uuid, parent.key)
+        // if (parent.tabs) {
+        //   let _uuid = Utils.getuuid()
+        //   linkMap.set(_uuid, parent.key)
           
-          parent.originKey = parent.key
-          parent.key = _uuid
-        }
+        //   parent.originKey = parent.key
+        //   parent.key = _uuid
+        // }
 
-        parent.children = this.getTree(parent.children, options)
+        parent.children = this.getTree(parent.children, options, parent.addSelf)
       }
     })
     return parents
@@ -442,8 +451,8 @@
           }
         }
         return true
-      } else if (parent.isSubView) {
-        return true
+      // } else if (parent.isSubView) {
+      //   return true
       }
       return false
     })
diff --git a/src/tabviews/subtable/index.jsx b/src/tabviews/subtable/index.jsx
index ffe6c3d..c10bc79 100644
--- a/src/tabviews/subtable/index.jsx
+++ b/src/tabviews/subtable/index.jsx
@@ -88,7 +88,6 @@
         config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
         config.setting.MenuName = Tab.label
         config.setting.$name = Tab.label
-        config.setting.foreignKey = Tab.foreignKey || ''
         config.setting.supModule = Tab.supMenu || ''
         config.setting.ContainerId = Tab.ContainerId || ''
       } catch (e) {
diff --git a/src/tabviews/zshare/actionList/excelInbutton/index.jsx b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
index df4b7d4..ea19291 100644
--- a/src/tabviews/zshare/actionList/excelInbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -582,6 +582,7 @@
     return <>
       <Button
         type={type}
+        id={'button' + btn.uuid}
         title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
         loading={loading}
         disabled={disabled}
diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx
index 970a9c0..61dbda9 100644
--- a/src/tabviews/zshare/mutilform/index.jsx
+++ b/src/tabviews/zshare/mutilform/index.jsx
@@ -1232,9 +1232,9 @@
           className = 'checkcard'
           content = (<MKCheckCard config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)}/>)
         } else if (item.type === 'switch') {
-          content = (<MKSwitch config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)}/>)
+          content = (<MKSwitch config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)} onSubmit={this.props.inputSubmit}/>)
         } else if (item.type === 'check') {
-          content = (<MKCheck config={item} onChange={(val) => this.recordChange({[item.field]: val}, item)}/>)
+          content = (<MKCheck config={item} onChange={(val) => this.recordChange({[item.field]: val}, item)} onSubmit={this.props.inputSubmit}/>)
         } else if (item.type === 'checkbox') {
           content = (<MKCheckbox config={item} onChange={(val) => this.recordChange({[item.field]: val})}/>)
         } else if (item.type === 'radio') {
diff --git a/src/tabviews/zshare/mutilform/mkCheck/index.jsx b/src/tabviews/zshare/mutilform/mkCheck/index.jsx
index aea3f25..b6c3195 100644
--- a/src/tabviews/zshare/mutilform/mkCheck/index.jsx
+++ b/src/tabviews/zshare/mutilform/mkCheck/index.jsx
@@ -2,6 +2,8 @@
 import PropTypes from 'prop-types'
 import { Checkbox } from 'antd'
 
+import MKEmitter from '@/utils/events.js'
+
 class MKCheck extends Component {
   static propTpyes = {
     config: PropTypes.object,
@@ -20,6 +22,21 @@
     } else {
       this.props.onChange(config.closeVal)
     }
+
+    this.setState({}, () => {
+      if (config.enter === 'tab') {
+        MKEmitter.emit('mkFC', 'focus', config.tabUuid)
+      } else if (config.enter === 'sub') {
+        config.tabUuid && MKEmitter.emit('mkFC', 'focus', config.tabUuid)
+        if (config.linkFields || config.subFields || config.controlFields) {
+          setTimeout(() => {
+            this.props.onSubmit(config.tabUuid)
+          }, 1000)
+        } else {
+          this.props.onSubmit(config.tabUuid)
+        }
+      }
+    })
   }
 
   componentWillUnmount () {
diff --git a/src/tabviews/zshare/mutilform/mkSwitch/index.jsx b/src/tabviews/zshare/mutilform/mkSwitch/index.jsx
index 62f8822..7cea5b9 100644
--- a/src/tabviews/zshare/mutilform/mkSwitch/index.jsx
+++ b/src/tabviews/zshare/mutilform/mkSwitch/index.jsx
@@ -33,6 +33,21 @@
     } else {
       this.props.onChange(config.closeVal, other)
     }
+
+    this.setState({}, () => {
+      if (config.enter === 'tab') {
+        MKEmitter.emit('mkFC', 'focus', config.tabUuid)
+      } else if (config.enter === 'sub') {
+        config.tabUuid && MKEmitter.emit('mkFC', 'focus', config.tabUuid)
+        if (config.linkFields || config.subFields || config.controlFields) {
+          setTimeout(() => {
+            this.props.onSubmit(config.tabUuid)
+          }, 1000)
+        } else {
+          this.props.onSubmit(config.tabUuid)
+        }
+      }
+    })
   }
 
   componentWillUnmount () {
diff --git a/src/templates/sharecomponent/actioncomponent/actionform/index.jsx b/src/templates/sharecomponent/actioncomponent/actionform/index.jsx
index 227e56b..3e9c1ae 100644
--- a/src/templates/sharecomponent/actioncomponent/actionform/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/actionform/index.jsx
@@ -302,17 +302,10 @@
         }
       } else if (_funcType === 'closetab') {
         shows.push('refreshTab')
-      } else if (_funcType === 'megvii') {
-        shows.push('subFunc', 'progress')
       } else if (_funcType === 'refund') {
         shows.push('Ot', 'execSuccess', 'execError')
 
         reOptions.Ot = requireOptions.filter(op => op.value === 'requiredSgl')
-      } else if (_funcType === 'filezip') {
-        reOptions.Ot = requireOptions
-        reRequired.innerFunc = false
-
-        shows.push('innerFunc', 'Ot', 'execSuccess', 'execError', 'urlkey')
       }
     }
 
diff --git a/src/templates/sharecomponent/actioncomponent/formconfig.jsx b/src/templates/sharecomponent/actioncomponent/formconfig.jsx
index 42ef767..0476049 100644
--- a/src/templates/sharecomponent/actioncomponent/formconfig.jsx
+++ b/src/templates/sharecomponent/actioncomponent/formconfig.jsx
@@ -119,12 +119,6 @@
       }, {
         value: 'closetab',
         text: '鏍囩鍏抽棴'
-      }, {
-        value: 'megvii',
-        text: '鏃疯闈㈡澘鏈�'
-      }, {
-        value: 'filezip',
-        text: '鏂囦欢鍘嬬缉鍖�'
       }]
     },
     { // 鏃疯闈㈡澘鏈烘帴鍙� 寰呮墿灞�
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/columnform/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelin/columnform/index.jsx
index afb9c56..7450d0d 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/columnform/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/columnform/index.jsx
@@ -78,6 +78,10 @@
                   {
                     required: true,
                     message: '璇疯緭鍏ュ瓧娈�!'
+                  },
+                  {
+                    pattern: /^[\u4E00-\u9FA50-9a-zA-Z_]*$/ig,
+                    message: '鍙厑璁稿寘鍚暟瀛椼�佸瓧姣嶃�佹眽瀛椾互鍙奯'
                   }
                 ]
               })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleConfirm}/>)}
@@ -135,7 +139,7 @@
               )}
             </Form.Item>
           </Col>
-          <Col span={6}>
+          <Col span={6} style={{clear: 'left'}}>
             <Form.Item style={{marginBottom: 0}} label="瀵煎叆">
               {getFieldDecorator('import', {
                 initialValue: 'true'
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
index 18de67e..aa4e7b5 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -59,6 +59,7 @@
         width: '15%',
         editable: true,
         inputType: 'select',
+        keyCol: true,
         options: [
           { value: 'Nvarchar(10)', text: 'Nvarchar(10)' },
           { value: 'Nvarchar(20)', text: 'Nvarchar(20)' },
@@ -114,7 +115,10 @@
         required: false,
         inputType: 'number',
         unlimit: true,
-        editable: true
+        editable: true,
+        keyVals: ['Int', 'Decimal(18,0)', 'Decimal(18,2)', 'Decimal(18,4)', 'Decimal(18,6)'],
+        render: (text, record) => /^Decimal/ig.test(record.type) || /^int/ig.test(record.type) ? text : ''
+        
       },
       {
         title: '鏈�澶у��',
@@ -123,7 +127,9 @@
         required: false,
         inputType: 'number',
         unlimit: true,
-        editable: true
+        editable: true,
+        keyVals: ['Int', 'Decimal(18,0)', 'Decimal(18,2)', 'Decimal(18,4)', 'Decimal(18,6)'],
+        render: (text, record) => /^Decimal/ig.test(record.type) || /^int/ig.test(record.type) ? text : ''
       }
     ],
     uniqueColumns: [
@@ -447,6 +453,8 @@
 
       confirm({
         content: '閮ㄥ垎瀛楁鍚嶇О涓庢樉绀哄垪涓嶄竴鑷达紝鏄惁鏇存柊锛�',
+        okText: '鏇存柊',
+        cancelText: '涓嶆洿鏂�',
         onOk() {
           _columns = _columns.map(item => {
             let key = item.Column.toLowerCase()
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.scss b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.scss
index 54d7f31..120f02d 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.scss
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.scss
@@ -76,6 +76,9 @@
         width: 89.5%;
       }
     }
+    .ant-form-explain {
+      white-space: nowrap;
+    }
   }
   .custom-table .ant-empty {
     margin: 20px 8px!important;
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/columnform/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/columnform/index.jsx
index 9d9f0e3..3e535cb 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/columnform/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/columnform/index.jsx
@@ -46,6 +46,10 @@
                   {
                     required: true,
                     message: '璇疯緭鍏ュ瓧娈�!'
+                  },
+                  {
+                    pattern: /^[\u4E00-\u9FA50-9a-zA-Z_]*$/ig,
+                    message: '鍙厑璁稿寘鍚暟瀛椼�佸瓧姣嶃�佹眽瀛椾互鍙奯'
                   }
                 ]
               })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleConfirm}/>)}
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
index fb05456..7527155 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -67,6 +67,7 @@
         inputType: 'select',
         editable: true,
         required: false,
+        keyCol: true,
         width: '12%',
         render: (text) => {
           if (text === 'image') {
@@ -82,38 +83,6 @@
           {value: 'number', text: '鏁板��'},
           {value: 'image', text: '鍥剧墖'}
         ]
-      },
-      {
-        title: '鍙栫粷瀵瑰��',
-        dataIndex: 'abs',
-        inputType: 'radio',
-        editable: true,
-        required: false,
-        width: '12%',
-        render: (text, record) => {
-          if (record.type !== 'number') return ''
-
-          if (text === 'true') {
-            return '鏄�'
-          } else {
-            return '鍚�'
-          }
-        },
-        options: [
-          {value: 'true', text: '鏄�'},
-          {value: 'false', text: '鍚�'}
-        ]
-      },
-      {
-        title: '灏忔暟浣�',
-        dataIndex: 'decimal',
-        inputType: 'number',
-        min: 0,
-        max: 18,
-        editable: true,
-        required: false,
-        width: '12%',
-        render: (text, record) => record.type === 'number' ? text : ''
       },
       {
         title: '瀵煎嚭',
@@ -146,6 +115,40 @@
           {value: 'false', text: '鍚�'}
         ]
       },
+      {
+        title: '鍙栫粷瀵瑰��',
+        dataIndex: 'abs',
+        inputType: 'radio',
+        editable: true,
+        required: false,
+        keyVals: ['number'],
+        width: '12%',
+        render: (text, record) => {
+          if (record.type !== 'number') return ''
+
+          if (text === 'true') {
+            return '鏄�'
+          } else {
+            return '鍚�'
+          }
+        },
+        options: [
+          {value: 'true', text: '鏄�'},
+          {value: 'false', text: '鍚�'}
+        ]
+      },
+      {
+        title: '灏忔暟浣�',
+        dataIndex: 'decimal',
+        inputType: 'number',
+        min: 0,
+        max: 18,
+        editable: true,
+        required: false,
+        keyVals: ['number'],
+        width: '12%',
+        render: (text, record) => record.type === 'number' ? text : ''
+      }
     ],
     scriptsColumns: [
       {
@@ -528,6 +531,13 @@
       if (card.intertype === 'system' && verify.dataType !== 'custom' && verify.columns.length > 0 && config.$c_ds && config.setting.interType === 'system' && config.columns && config.columns.length > 0) {
         let cols = []
         let columns = config.columns.map(c => c.field)
+
+        if (config.subtype === 'dualdatacard' && config.subColumns) {
+          config.subColumns.forEach(item => {
+            columns.push(item.field)
+          })
+        }
+
         verify.columns.forEach(col => {
           if (col.output === 'false' || col.Column === '$Index') return
           if (!columns.includes(col.Column)) {
@@ -710,6 +720,8 @@
 
       confirm({
         content: '閮ㄥ垎瀛楁鍚嶇О涓庢樉绀哄垪涓嶄竴鑷达紝鏄惁鏇存柊锛�',
+        okText: '鏇存柊',
+        cancelText: '涓嶆洿鏂�',
         onOk() {
           columns = columns.map(item => {
             let key = item.Column.toLowerCase()
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.scss b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.scss
index 3a59dce..f96c1d1 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.scss
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.scss
@@ -79,6 +79,9 @@
     .add {
       padding-top: 4px;
     }
+    .ant-form-explain {
+      white-space: nowrap;
+    }
   }
   .custom-table .ant-empty {
     margin: 20px 8px!important;
diff --git a/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
index 827c5af..1509c78 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
@@ -399,12 +399,16 @@
   }
 
   changeTemplate = (val) => {
-    const { templates } = this.state
+    const { templates, verify } = this.state
 
     let temp = templates.filter(temp => temp.value === val)[0]
 
     this.setState({
-      selectimg: temp.img
+      selectimg: temp.img,
+      verify: {
+        ...verify,
+        Template: val
+      }
     })
   }
 
@@ -854,7 +858,19 @@
                   </Form.Item>
                 </Col> : null}
                 {printMode !== 'custom' ? <Col span={8}>
-                  <Form.Item label="鎵撳嵃妯℃澘">
+                  <Form.Item label="鎵撳嵃妯℃澘" help={(() => {
+                      if (verify.Template) {
+                        return <span onClick={() => {
+                          sessionStorage.setItem('mk-print-tab-temp', verify.Template)
+                          window.open('#/hs')
+
+                          setTimeout(() => {
+                            sessionStorage.removeItem('mk-print-tab-temp')
+                          }, 50)
+                        }} style={{color: '#1890ff', cursor: 'pointer', fontSize: '13px'}}>#鏌ョ湅妯℃澘</span>
+                      }
+                      return null
+                    })()}>
                     {getFieldDecorator('Template', {
                       initialValue: verify.Template || '',
                       rules: [
diff --git a/src/templates/sharecomponent/cardcomponent/formconfig.jsx b/src/templates/sharecomponent/cardcomponent/formconfig.jsx
index 2ae0ec4..4889e32 100644
--- a/src/templates/sharecomponent/cardcomponent/formconfig.jsx
+++ b/src/templates/sharecomponent/cardcomponent/formconfig.jsx
@@ -48,14 +48,14 @@
       required: false,
       options: equalTabs
     },
-    {
-      type: 'text',
-      key: 'foreignKey',
-      label: '澶栭敭',
-      tooltip: '澶栭敭鏃ㄥ湪鏍囩椤典腑鎵ц榛樿鍑芥暟锛堟坊鍔狅級鏃讹紝鏇挎崲BID瀛楁',
-      initVal: card.foreignKey || '',
-      required: false
-    },
+    // {
+    //   type: 'text',
+    //   key: 'foreignKey',
+    //   label: '澶栭敭',
+    //   tooltip: '澶栭敭鏃ㄥ湪鏍囩椤典腑鎵ц榛樿鍑芥暟锛堟坊鍔狅級鏃讹紝鏇挎崲BID瀛楁',
+    //   initVal: card.foreignKey || '',
+    //   required: false
+    // },
     {
       type: 'number',
       key: 'level',
diff --git a/src/templates/sharecomponent/tabscomponent/formconfig.jsx b/src/templates/sharecomponent/tabscomponent/formconfig.jsx
index 2dc9860..080a960 100644
--- a/src/templates/sharecomponent/tabscomponent/formconfig.jsx
+++ b/src/templates/sharecomponent/tabscomponent/formconfig.jsx
@@ -48,14 +48,14 @@
       required: false,
       options: equalTabs
     },
-    {
-      type: 'text',
-      key: 'foreignKey',
-      label: '澶栭敭',
-      tooltip: '澶栭敭鏃ㄥ湪鏍囩椤典腑鎵ц榛樿鍑芥暟锛堟坊鍔狅級鏃讹紝鏇挎崲BID瀛楁',
-      initVal: card.foreignKey || '',
-      required: false
-    },
+    // {
+    //   type: 'text',
+    //   key: 'foreignKey',
+    //   label: '澶栭敭',
+    //   tooltip: '澶栭敭鏃ㄥ湪鏍囩椤典腑鎵ц榛樿鍑芥暟锛堟坊鍔狅級鏃讹紝鏇挎崲BID瀛楁',
+    //   initVal: card.foreignKey || '',
+    //   required: false
+    // },
     {
       type: 'number',
       key: 'level',
diff --git a/src/templates/sharecomponent/tabscomponent/tabform/index.jsx b/src/templates/sharecomponent/tabscomponent/tabform/index.jsx
index a7e0ec3..b32a839 100644
--- a/src/templates/sharecomponent/tabscomponent/tabform/index.jsx
+++ b/src/templates/sharecomponent/tabscomponent/tabform/index.jsx
@@ -117,12 +117,6 @@
       if (item.type === 'text') {
         let rules = []
 
-        if (item.key === 'foreignKey') {
-          rules.push({
-            pattern: /^[a-zA-Z_]*$/ig,
-            message: item.label + '瀛楁鍙厑璁稿寘鍚瓧姣嶅強涓嬪垝绾匡紒'
-          })
-        }
         fields.push(
           <Col span={12} key={index}>
             <Form.Item label={
diff --git a/src/templates/zshare/editTable/index.jsx b/src/templates/zshare/editTable/index.jsx
index 6b4c9f4..fcc5e6d 100644
--- a/src/templates/zshare/editTable/index.jsx
+++ b/src/templates/zshare/editTable/index.jsx
@@ -3,7 +3,7 @@
 import { is, fromJS } from 'immutable'
 import { DndProvider, DragSource, DropTarget } from 'react-dnd'
 import { Table, Input, InputNumber, Popconfirm, Switch, Form, Select, Radio, Cascader, notification, message, Modal, Typography } from 'antd'
-import { CopyOutlined, EditOutlined, DeleteOutlined, SwapOutlined, PlusOutlined } from '@ant-design/icons'
+import { CopyOutlined, EditOutlined, DeleteOutlined, SwapOutlined, PlusOutlined, ConsoleSqlOutlined } from '@ant-design/icons'
 
 import Utils from '@/utils/utils.js'
 import ColorSketch from '@/mob/colorsketch'
@@ -123,7 +123,7 @@
 
 class EditableCell extends Component {
   getInput = (form) => {
-    const { inputType, options, min, max, unlimit, allowClear } = this.props
+    const { inputType, options, min, max, unlimit, allowClear, typeChange } = this.props
 
     if (inputType === 'number' && unlimit) {
       return <InputNumber onPressEnter={() => this.getValue(form)} />
@@ -137,7 +137,7 @@
       return <CusSwitch />
     } else if (inputType === 'select') {
       return (
-        <Select>
+        <Select onChange={typeChange}>
           {options.map((item, i) => (<Select.Option key={i} value={item.field || item.value}> {item.label || item.text} </Select.Option>))}
         </Select>
       )
@@ -176,11 +176,18 @@
 
   renderCell = (form) => {
     const { getFieldDecorator } = form
-    const { editing, dataIndex, title, record, children, className, required, inputType, rules } = this.props
+    const { editing, pass, dataIndex, title, record, children, className, required, inputType, rules } = this.props
 
+    if (!editing) {
+      return (
+        <td className={className}>
+          {children}
+        </td>
+      )
+    }
     return (
       <td className={className}>
-        {editing ? (
+        {pass ? (
           <Form.Item style={{ margin: 0 }}>
             {getFieldDecorator(dataIndex, {
               rules: [
@@ -194,7 +201,7 @@
             })(this.getInput(form))}
           </Form.Item>
         ) : (
-          children
+          null
         )}
       </td>
     )
@@ -218,7 +225,9 @@
     data: [],
     editingKey: '',
     editLineId: '',
-    columns: []
+    columns: [],
+    keyCol: null,
+    keyVal: ''
   }
 
   UNSAFE_componentWillMount () {
@@ -226,6 +235,7 @@
     let columns = fromJS(this.props.columns).toJS()
     let operation = null
     let extra = null
+    let keyCol = null
     
     if (actions) {
       actions.forEach(item => {
@@ -237,9 +247,17 @@
 
     if (actions && (actions.includes('edit') || actions.includes('copy') || actions.includes('del'))) {
       let _operation = null
+      let render = null
       columns = columns.filter(item => {
         if (item.dataIndex === 'operation') {
           _operation = item
+        }
+        if (item.keyCol) {
+          keyCol = item.dataIndex
+        }
+        if (item.dataIndex === 'sqlRender') {
+          render = item.render
+          return false
         }
         return item.dataIndex !== 'operation'
       })
@@ -271,7 +289,7 @@
             </div>
           ) : (
             <div className={'edit-operation-btn' + (editingKey !== '' ? ' disabled' : '')} style={{minWidth: '110px', whiteSpace: 'nowrap'}}>
-              {actions.includes('edit') ? <span className="primary" title="缂栬緫" onClick={() => {editingKey === '' && this.edit(record.uuid)}}><EditOutlined /></span> : null}
+              {actions.includes('edit') ? <span className="primary" title="缂栬緫" onClick={() => {editingKey === '' && this.edit(record)}}><EditOutlined /></span> : null}
               {extra ? <span className="status" title={extra[2]} onClick={() => {editingKey === '' && this.handleStatus(record, extra[1])}}><SwapOutlined /></span> : null}
               {actions.includes('status') ? <span className="status" title="鏄惁鍚敤" onClick={() => {editingKey === '' && this.handleStatus(record, 'status')}}><SwapOutlined /></span> : null}
               {actions.includes('copy') ? <span className="copy" title="澶嶅埗" onClick={() => {editingKey === '' && this.copy(record)}}><CopyOutlined /></span> : null}
@@ -279,10 +297,11 @@
                 overlayClassName="popover-confirm"
                 title="纭畾鍒犻櫎鍚�?"
                 onConfirm={() => this.handleDelete(record.uuid)
-              }>
+                }>
                 <span className="danger"><DeleteOutlined /></span>
               </Popconfirm> : null}
               {actions.includes('del') && editingKey !== '' ? <span className="danger"><DeleteOutlined /></span> : null}
+              {actions.includes('sql') ? <span className="primary" title="SQL" onClick={() => {editingKey === '' && this.showSql(record, render)}}><ConsoleSqlOutlined /></span> : null}
             </div>
           )
         }
@@ -298,7 +317,8 @@
     this.setState({
       data: data || [],
       operation,
-      columns
+      columns,
+      keyCol
     })
   }
 
@@ -338,6 +358,20 @@
       return
     }
     MKEmitter.removeListener('editLineId', this.getEditLineId)
+  }
+
+  showSql = (record, render) => {
+    let list = render(record)
+
+    if (list) {
+      Modal.info({
+        title: '',
+        width: 500,
+        className: 'sql-example',
+        icon: null,
+        content: list.map((n, index) => <div key={index} dangerouslySetInnerHTML={{ __html: n }}></div>)
+      })
+    }
   }
 
   getEditLineId = (id) => {
@@ -719,8 +753,14 @@
     })
   }
 
-  edit(uuid) {
-    this.setState({ editingKey: uuid })
+  edit(record) {
+    const { keyCol } = this.state
+
+    this.setState({ editingKey: record.uuid, keyVal: keyCol ? record[keyCol] : '' })
+  }
+
+  typeChange = (val) => {
+    this.setState({ keyVal: val })
   }
 
   moveRow = (dragIndex, hoverIndex) => {
@@ -771,7 +811,7 @@
 
   render() {
     const { actions, indexShow, searchKey } = this.props
-    const { editLineId } = this.state
+    const { editLineId, keyVal } = this.state
 
     let components = {
       body: {
@@ -790,7 +830,9 @@
       if (col.copy) {
         col.render = (text) => (<Paragraph copyable>{text}</Paragraph>)
       }
+
       if (!col.editable) return col
+
       return {
         ...col,
         onCell: record => ({
@@ -804,9 +846,12 @@
           unlimit: col.unlimit,
           required: col.required !== false ? true : false,
           allowClear: col.allowClear === true,
+          keyCol: col.keyCol === true,
           title: col.title,
           editing: this.isEditing(record),
+          pass: col.keyVals ? col.keyVals.includes(keyVal) : true,
           onSave: this.onSave,
+          typeChange: this.typeChange,
         }),
       }
     })
diff --git a/src/templates/zshare/editTable/index.scss b/src/templates/zshare/editTable/index.scss
index 564dc79..76e6bfd 100644
--- a/src/templates/zshare/editTable/index.scss
+++ b/src/templates/zshare/editTable/index.scss
@@ -127,3 +127,10 @@
   }
 }
 
+.ant-modal.ant-modal-confirm.ant-modal-confirm-info.sql-example {
+  top: 100px;
+  .ant-modal-body {
+    padding: 24px;
+  }
+}
+
diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx
index 16eda0b..c306270 100644
--- a/src/templates/zshare/formconfig.jsx
+++ b/src/templates/zshare/formconfig.jsx
@@ -2331,6 +2331,23 @@
     },
     {
       type: 'radio',
+      key: 'mkfocus',
+      label: '鑱氱劍鏃�',
+      initVal: card.mkfocus || 'def',
+      options: [{
+        value: 'def',
+        text: '榛樿'
+      }, {
+        value: 'check',
+        text: '鍏ㄩ��'
+      }, {
+        value: 'clear',
+        text: '娓呯┖'
+      }],
+      forbid: appType !== 'mob'
+    },
+    {
+      type: 'radio',
       key: 'sendType',
       label: '鍙戦�佹柟寮�',
       initVal: card.sendType || 'local',
@@ -2535,7 +2552,7 @@
       key: 'enter',
       label: '鍥炶溅浜嬩欢',
       initVal: (card.type === 'text' || card.type === 'number') ? (card.enter || 'sub') : (card.enter || 'false'),
-      tooltip: '鐐瑰嚮Enter閿紝鎴栨枃鏈被琛ㄥ崟杈撳叆鍥炶溅绗︺��',
+      tooltip: '1銆佺偣鍑籈nter閿垨鏂囨湰绫昏〃鍗曡緭鍏ュ洖杞︾锛�2銆佷笅鎷夐�夋嫨鎴栧紑鍏崇殑閫夐」鍒囨崲銆�',
       options: [{
         value: 'sub',
         text: '鎻愪氦'
diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx
index ffe236a..2b37e7c 100644
--- a/src/templates/zshare/modalform/index.jsx
+++ b/src/templates/zshare/modalform/index.jsx
@@ -20,8 +20,8 @@
 const MkEditIcon = asyncComponent(() => import('@/components/mkIcon'))
 
 const modalTypeOptions = {
-  text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'span', 'labelwidth', 'encryption', 'tooltip', 'extra', 'enter', 'cursor', 'scan', 'splitline', 'placeholder', 'place', 'marginTop', 'marginBottom', 'lenControl', 'inputType', 'constant'],
-  number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'splitline', 'place', 'marginTop', 'marginBottom'],
+  text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'span', 'labelwidth', 'encryption', 'tooltip', 'extra', 'enter', 'cursor', 'scan', 'splitline', 'placeholder', 'place', 'marginTop', 'marginBottom', 'lenControl', 'inputType', 'constant', 'mkfocus'],
+  number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'splitline', 'place', 'marginTop', 'marginBottom', 'mkfocus'],
   select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom', 'pickerMode'],
   checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'splitline', 'arrange', 'marginTop', 'marginBottom'],
   radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'splitline', 'arrange', 'marginTop', 'marginBottom'],
@@ -29,8 +29,8 @@
   multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'marginTop', 'marginBottom', 'dropdown'],
   link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'linkField', 'linkSubField', 'span', 'place', 'labelwidth', 'tooltip', 'extra', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom', 'pickerMode'],
   fileupload: ['readonly', 'required', 'hidden', 'readin', 'fieldlength', 'maxfile', 'fileType', 'span', 'labelwidth', 'linkSubField', 'tooltip', 'extra', 'compress', 'miniSet', 'splitline', 'marginTop', 'marginBottom', 'maxSize'],
-  switch: ['initval', 'openVal', 'closeVal', 'openText', 'closeText', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'linkSubField', 'tooltip', 'extra', 'splitline', 'marginTop', 'marginBottom'],
-  check: ['initval', 'openVal', 'closeVal', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'marginTop', 'marginBottom', 'checkTip'],
+  switch: ['initval', 'openVal', 'closeVal', 'openText', 'closeText', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'linkSubField', 'tooltip', 'extra', 'enter', 'splitline', 'marginTop', 'marginBottom'],
+  check: ['initval', 'openVal', 'closeVal', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'splitline', 'marginTop', 'marginBottom', 'checkTip'],
   date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'mode', 'splitline', 'place', 'marginTop', 'marginBottom', 'minDate', 'maxDate', 'precision'],
   datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'place', 'marginTop', 'marginBottom'],
   // datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'mode', 'splitline', 'marginTop', 'marginBottom', 'minDate', 'maxDate'],
@@ -254,6 +254,9 @@
         }
       }
     } else if (type === 'switch' || type === 'check') {
+      if (this.record.enter === 'tab' || this.record.enter === 'sub') {
+        shows.push('tabField')
+      }
       reOptions.initval = [
         {value: true, text: '寮�'},
         {value: false, text: '鍏�'}
diff --git a/src/templates/zshare/verifycard/index.jsx b/src/templates/zshare/verifycard/index.jsx
index 00076a1..a74034f 100644
--- a/src/templates/zshare/verifycard/index.jsx
+++ b/src/templates/zshare/verifycard/index.jsx
@@ -2,7 +2,7 @@
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
 import { Form, Tabs, Row, Col, Button, Popconfirm, notification, Modal, message, InputNumber, Typography } from 'antd'
-import { CheckCircleOutlined, StopOutlined, EditOutlined, SwapOutlined, DeleteOutlined, ExclamationOutlined } from '@ant-design/icons'
+import { CheckCircleOutlined, StopOutlined, EditOutlined, SwapOutlined, DeleteOutlined, ExclamationOutlined, ConsoleSqlOutlined } from '@ant-design/icons'
 import Toast from 'antd-mobile/es/components/toast'
 import Dialog from 'antd-mobile/es/components/dialog'
 import moment from 'moment'
@@ -18,7 +18,7 @@
 import BillcodeForm from './billcodeform'
 import VoucherForm from './voucherform'
 import asyncComponent from '@/utils/asyncComponent'
-import { updateForm } from '@/utils/utils-update.js'
+// import { updateForm } from '@/utils/utils-update.js'
 import MKEmitter from '@/utils/events.js'
 import './index.scss'
 
@@ -114,6 +114,34 @@
               <CheckCircleOutlined style={{marginLeft: '5px'}}/>
             </div>
           )
+      },
+      {
+        dataIndex: 'sqlRender',
+        render: (record) => {
+          let _fieldValue = []
+          let _value = []
+          let _labels = record.fieldlabel.split(',')
+
+          record.field.split(',').forEach((_field, index) => {
+            let _key = _field.toLowerCase()
+            _fieldValue.push(`${_key}=${_key === 'bid' ? '@BID@' : ''}`)
+            _value.push(`${_labels[index] || ''}锛歺xx`)
+          })
+
+          let _verifyType = ''
+          if (record.verifyType === 'logic') {
+            _verifyType = ' and deleted=0'
+          }
+
+          let sql = `select @tbid='', @ErrorCode='',@retmsg=''
+          select @tbid='X' from ${this.props.card.sql} where ${_fieldValue.join(' and ')}${_verifyType}
+          If @tbid!=''
+          Begin
+            select @ErrorCode='${record.errorCode}',@retmsg='${_value.join(', ')} 宸插瓨鍦�'
+            goto aaa
+          end`
+          return sql.split(/\n\s{10}/ig).map(n => n.replace(/^\s{2}/ig, '&nbsp;&nbsp;'))
+        }
       }
     ],
     onceUniqueColumns: [
@@ -151,6 +179,27 @@
             </div>
           )
       },
+      {
+        dataIndex: 'sqlRender',
+        render: (record) => {
+          let primaryKey = 'id'
+
+          if (this.props.config && this.props.config.setting && this.props.config.setting.primaryKey) {
+            primaryKey = this.props.config.setting.primaryKey
+          }
+
+          let sql = `Set @tbid=''
+          Select top 1 @tbid='X' from (select distinct ${record.field},1 as n from (鏁版嵁婧�) tb inner join (select ID from  dbo.SplitComma(@ID@)) sp on tb.${primaryKey}=sp.ID ) a having sum(n)>1
+          
+          If @tbid!=''
+          Begin
+            Set @ErrorCode='E' Set @retmsg='${record.fieldlabel} 鍊间笉鍞竴'
+            goto aaa
+          end`
+          
+          return sql.split(/\n\s{10}/ig).map(n => n.replace(/^\s{2}/ig, '&nbsp;&nbsp;'))
+        }
+      }
     ],
     contrastColumns: [
       {
@@ -163,7 +212,7 @@
       {
         title: '杩愮畻绗�',
         dataIndex: 'operator',
-        width: '14%',
+        width: '13%',
         editable: true,
         inputType: 'select',
         options: [
@@ -187,14 +236,14 @@
       {
         title: '鎻愮ず淇℃伅',
         dataIndex: 'errmsg',
-        width: '14%',
+        width: '13%',
         inputType: 'input',
         editable: true
       },
       {
         title: '鎶ラ敊缂栫爜',
         dataIndex: 'errorCode',
-        width: '14%',
+        width: '13%',
         editable: true,
         inputType: 'select',
         options: [
@@ -224,6 +273,18 @@
               <CheckCircleOutlined style={{marginLeft: '5px'}}/>
             </div>
           )
+      },
+      {
+        dataIndex: 'sqlRender',
+        render: (record) => {
+          let sql = `If ${record.frontfield} ${record.operator} ${record.backfield}
+          Begin
+            select @ErrorCode='${record.errorCode}',@retmsg='${record.errmsg}'
+            goto aaa
+          end`
+
+          return sql.split(/\n\s{10}/ig).map(n => n.replace(/^\s{2}/ig, '&nbsp;&nbsp;'))
+        }
       }
     ],
     customColumns: [
@@ -530,6 +591,7 @@
             }>
               <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span>
             </Popconfirm>
+            <span className="operation-btn" title="SQL" onClick={() => this.orderSql(record)} style={{color: '#1890ff'}}><ConsoleSqlOutlined /></span>
           </div>)
       }
     ]
@@ -657,37 +719,37 @@
       } else if (card.modal && (card.OpenType === 'pop' || !card.OpenType)) {
         _fields = card.modal.fields || []
         resolve(_fields)
-      } else if (card.OpenType === 'pop') {
-        Api.getCloudConfig({
-          func: 'sPC_Get_LongParam',
-          MenuID: card.uuid
-        }).then(res => {
-          if (res.status) {
-            let _LongParam = ''
-            if (res.LongParam) {
-              try {
-                _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
-              } catch (e) {
-                console.warn('Parse Failure')
-                _LongParam = ''
-              }
-            }
+      // } else if (card.OpenType === 'pop') {
+      //   Api.getCloudConfig({
+      //     func: 'sPC_Get_LongParam',
+      //     MenuID: card.uuid
+      //   }).then(res => {
+      //     if (res.status) {
+      //       let _LongParam = ''
+      //       if (res.LongParam) {
+      //         try {
+      //           _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
+      //         } catch (e) {
+      //           console.warn('Parse Failure')
+      //           _LongParam = ''
+      //         }
+      //       }
             
-            if (!_LongParam) {
-              message.warning('鏈幏鍙栧埌琛ㄥ崟淇℃伅锛岄儴鍒嗛獙璇佸皢鏃犳硶璁剧疆锛�')
-            } else {
-              _LongParam = updateForm(_LongParam)
-              _fields = _LongParam.fields || []
-            }
-          } else {
-            notification.warning({
-              top: 92,
-              message: res.message,
-              duration: 5
-            })
-          }
-          resolve(_fields)
-        })
+      //       if (!_LongParam) {
+      //         message.warning('鏈幏鍙栧埌琛ㄥ崟淇℃伅锛岄儴鍒嗛獙璇佸皢鏃犳硶璁剧疆锛�')
+      //       } else {
+      //         _LongParam = updateForm(_LongParam)
+      //         _fields = _LongParam.fields || []
+      //       }
+      //     } else {
+      //       notification.warning({
+      //         top: 92,
+      //         message: res.message,
+      //         duration: 5
+      //       })
+      //     }
+      //     resolve(_fields)
+      //   })
       } else {
         resolve(_fields)
       }
@@ -752,6 +814,9 @@
           _select.push(`@${_f.field}='1949-10-01'`)
         } else if (_f.type === 'number') {
           _type = `decimal(18,${_fieldlen})`
+          _select.push(`@${_f.field}=0`)
+        } else if (_f.declare === 'decimal') {
+          _type = `decimal(18,${_f.decimal || 0})`
           _select.push(`@${_f.field}=0`)
         } else if (_f.type === 'rate') {
           _type = `decimal(18,2)`
@@ -1131,6 +1196,45 @@
           duration: 5
         })
       }
+    })
+  }
+
+  orderSql = (record) => {
+    let _ModularDetailCode = ''
+    let _lpline = ''
+    if (record.TypeCharOne === 'Lp') {
+      if (record.linkField.toLowerCase() === 'bid') {
+        _lpline = `set @ModularDetailCode= 'Lp'+ right('${record.mark || this.props.card.uuid}'+@BID@,48)`
+      } else {
+        _lpline = `set @ModularDetailCode= 'Lp'+ right('${record.mark || this.props.card.uuid}'+@${record.linkField.toLowerCase()},48)`
+      }
+      _ModularDetailCode = '@ModularDetailCode'
+    } else if (record.TypeCharOne === 'BN') {
+      _ModularDetailCode = `'${record.TypeCharOne}'`
+    } else {
+      _ModularDetailCode = `'${record.ModularDetailCode}'`
+    }
+
+    let sql = `select @BillCode='', @${record.field}='', @ModularDetailCode=''
+    ${_lpline}
+    exec s_get_BillCode
+      @ModularDetailCode=${_ModularDetailCode},
+      @Type=${record.Type},
+      @TypeCharOne='${record.TypeCharOne}',
+      @TypeCharTwo ='${record.TypeCharTwo}',
+      @BillCode =@BillCode output,
+      @ErrorCode =@ErrorCode output,
+      @retmsg=@retmsg output
+    if @ErrorCode!=''
+      goto aaa
+    set @${record.field}=@BillCode`
+
+    Modal.info({
+      title: '',
+      width: 500,
+      className: 'sql-example',
+      icon: null,
+      content: sql.split(/\n\s{4}/ig).map((n, index) => <div key={index} dangerouslySetInnerHTML={{ __html: n.replace(/\s/ig, '&nbsp;') }} style={{whiteSpace: 'nowrap'}}></div>)
     })
   }
 
@@ -1603,7 +1707,7 @@
             </span>
           } key="contrasts">
             <ContrastForm contrastChange={this.contrastChange}/>
-            <EditTable actions={['edit', 'move', 'copy', 'del', 'status']} type="contrastverify" data={verify.contrasts} columns={contrastColumns} onChange={(contrasts) => this.setState({verify: {...verify, contrasts}})}/>
+            <EditTable actions={['edit', 'move', 'copy', 'del', 'status', 'sql']} type="contrastverify" data={verify.contrasts} columns={contrastColumns} onChange={(contrasts) => this.setState({verify: {...verify, contrasts}})}/>
           </TabPane> : null}
           {verifyInter === 'system' ? <TabPane tab={
             <span>
@@ -1649,7 +1753,7 @@
               fields={card.Ot !== 'requiredOnce' ? uniqueFields : columnsFields}
               uniqueChange={this.uniqueChange}
             />
-            <EditTable actions={['edit', 'move', 'del', 'status']} data={verify.uniques} columns={card.Ot !== 'requiredOnce' ? uniqueColumns : onceUniqueColumns} onChange={this.changeUniques}/>
+            <EditTable actions={['edit', 'move', 'del', 'status', 'sql']} data={verify.uniques} columns={card.Ot !== 'requiredOnce' ? uniqueColumns : onceUniqueColumns} onChange={this.changeUniques}/>
           </TabPane> : null}
           {verifyInter === 'system' ? <TabPane tab={
             <span>
diff --git a/src/templates/zshare/verifycard/index.scss b/src/templates/zshare/verifycard/index.scss
index 6ee9eb2..a8a721e 100644
--- a/src/templates/zshare/verifycard/index.scss
+++ b/src/templates/zshare/verifycard/index.scss
@@ -106,6 +106,14 @@
   }
 }
 
+.ant-modal.ant-modal-confirm.ant-modal-confirm-info.sql-example {
+  top: 100px;
+  .ant-modal-body {
+    padding: 24px;
+  }
+}
+
+
 @media screen and (max-width: 1500px) {
   .mk-verify-tabs {
     .ant-tabs-nav .ant-tabs-tab {
diff --git a/src/utils/utils-custom.js b/src/utils/utils-custom.js
index 44a9750..d08226b 100644
--- a/src/utils/utils-custom.js
+++ b/src/utils/utils-custom.js
@@ -6,7 +6,7 @@
    * @description 鑾峰彇涓嬬骇妯″潡
    * @return {String}  selfId  褰撳墠缁勪欢id
    */
-  static getSubModules (components, selfId, supId, has) {
+  static getSubModules (components, selfId, supId, interfaces) {
     let modules = []
     components.forEach(item => {
       if (item.uuid === selfId || item.type === 'navbar') {
@@ -49,7 +49,7 @@
                 type: 'tab',
                 value: f_tab.uuid,
                 label: f_tab.label,
-                children: this.getSubModules(f_tab.components, selfId, supId, has)
+                children: this.getSubModules(f_tab.components, selfId, supId)
               }
   
               if (subItem.children.length === 0) {
@@ -94,6 +94,15 @@
         }
       }
     })
+
+    if (interfaces && interfaces.length > 0) {
+      interfaces.forEach(item => {
+        modules.push({
+          value: item.uuid,
+          label: item.name
+        })
+      })
+    }
 
     return modules
   }
@@ -719,7 +728,7 @@
   * @description 閲嶇疆缁勪欢閰嶇疆
   * @return {String}  item 缁勪欢淇℃伅
   */
-  static resetComponentConfig = (item, appType) => {
+  static resetComponentConfig = (item, appType, commonId) => {
     if (item.type === 'navbar') {
       return item
     }
@@ -727,9 +736,6 @@
     if (item.subtype === 'tablecard') { // 鍏煎
       item.type = 'card'
     }
-
-    item.uuid = this.getuuid()
-    let commonId = this.getuuid()
 
     // 閲嶇疆缁勪欢鍚嶇О
     let sign = this.getSignName()
@@ -952,20 +958,6 @@
         cell.uuid = this.getuuid()
         return cell
       })
-    }
-
-    if (item.setting && item.setting.supModule && item.setting.supModule[0] !== 'empty') {
-      item.setting.supModule = ''
-    }
-    
-    if (item.wrap && item.wrap.supType === 'multi') {
-      item.wrap.supType = 'single'
-
-      delete item.supNodes
-    }
-    
-    if (item.wrap && item.wrap.supModule) {
-      item.wrap.supModule = ''
     }
 
     if (item.wrap && item.wrap.doubleClick) {
diff --git a/src/utils/utils.js b/src/utils/utils.js
index 6754540..3177c1d 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -1403,7 +1403,6 @@
   let datavars = {}                 // 澹版槑鐨勫彉閲忥紝琛ㄥ崟鍙婃樉绀哄垪
   let _actionType = null
   let _callbacksql = ''
-  let foreignKey = setting.foreignKey ? setting.foreignKey.toLowerCase() : ''
 
   if (verify.default !== 'false') { // 鍒ゆ柇鏄惁浣跨敤榛樿sql
     _actionType = btn.sqlType
@@ -1786,19 +1785,13 @@
       item.field.split(',').forEach((_field, index) => {
         let _key = _field.toLowerCase()
         let _val = datavars[_key] !== undefined ? datavars[_key] : ''
-        let _fval = `'${_val}'`
 
-        if (_key === 'bid' && !datavars.bid) { // 琛ㄥ崟涓病鏈塨id鍒欎娇鐢ㄧ郴缁焍id鍙橀噺
-          _fval = '@BID@'
-        }
-        if (_key === 'bid' && foreignKey) {
-          arr.push(foreignKey)
-          _fieldValue.push(`${foreignKey}=${_fval}`)
-        } else {
-          arr.push(_key)
-          _fieldValue.push(`${_key}=${_fval}`)
+        arr.push(_key)
+        if (_key === 'bid' && !_val) { // 琛ㄥ崟涓病鏈塨id鍒欎娇鐢ㄧ郴缁焍id鍙橀噺
+          _val = BID
         }
         
+        _fieldValue.push(`${_key}='${_val}'`)
         _value.push(`${_labels[index] || ''}锛�${_val || ''}`)
       })
 
@@ -1914,14 +1907,7 @@
       values.push('@fullname')
     }
     if (!keys.includes('bid')) {
-      if (foreignKey && !keys.includes(foreignKey)) {
-        keys.push(foreignKey)
-      } else {
-        keys.push('bid')
-      }
-      values.push('@BID@')
-    } else if (foreignKey && !keys.includes(foreignKey)) {
-      keys.push(foreignKey)
+      keys.push('bid')
       values.push('@BID@')
     }
 
diff --git a/src/views/basedesign/updateFormTab/index.jsx b/src/views/basedesign/updateFormTab/index.jsx
index bd06654..04821eb 100644
--- a/src/views/basedesign/updateFormTab/index.jsx
+++ b/src/views/basedesign/updateFormTab/index.jsx
@@ -915,7 +915,7 @@
     let _card = {
       uuid: newCon.uuid,
       type: 'table',
-      name: newCon.name,
+      name: newCon.name || '',
       format: 'array',
       pageable: true,
       switchable: true,
@@ -923,7 +923,7 @@
       action: [],
       subtype: 'normaltable',
       setting: { useMSearch: 'false', sync: 'false', onload: 'true' },
-      wrap: {name: newCon.name},
+      wrap: {name: newCon.name || ''},
       style: {},
       headerStyle: {},
       columns: [],
diff --git a/src/views/billprint/index.jsx b/src/views/billprint/index.jsx
index 0c287de..fd83600 100644
--- a/src/views/billprint/index.jsx
+++ b/src/views/billprint/index.jsx
@@ -325,7 +325,7 @@
 
         let initInters = []
 
-        this.formatInterSetting(config.interfaces, regs, initInters, params, BID)
+        this.formatInterSetting(config.interfaces, regs, initInters, params, BID, config.MenuName)
 
         config.components = config.components.map(component => {
           if (component.action) {
@@ -341,6 +341,8 @@
             component.$searches = []
           }
           component.data = [] // 鍒濆鍖栨暟鎹负绌�
+
+          component.$menuname = (config.MenuName || '') + '-' + (component.name || '')
 
           if (component.subtype === 'tablecard') { // 鍏煎
             component.type = 'card'
@@ -466,6 +468,7 @@
 
           component.setting.arr_field = component.columns ? component.columns.map(col => col.field).join(',') : ''
           component.setting.laypage = false   // 鏄惁鍒嗛〉锛岃浆涓篵oolean 缁熶竴鏍煎紡
+          component.setting.$name = component.$menuname
 
           if (component.format === 'object') {
             component.setting.$top = true
@@ -539,7 +542,7 @@
           return component
         })
 
-        _pars = this.getFormatParam(_pars)
+        _pars = this.getFormatParam(_pars, config.MenuName)
 
         if (_pars) {
           _pars.componentId = 'union'
@@ -640,7 +643,7 @@
     return cell
   }
 
-  formatInterSetting = (inters, regs, initInters, params, BID) => {
+  formatInterSetting = (inters, regs, initInters, params, BID, MenuName) => {
     if (!inters) return []
 
     let delay = 15
@@ -652,6 +655,7 @@
 
       inter.setting.supModule = ''
       inter.setting.arr_field = inter.columns.map(col => col.field).join(',')
+      inter.setting.$name = (MenuName || '') + '-鍏叡鏁版嵁婧�-' + inter.setting.name
 
       if (inter.setting.interType !== 'system') {
         let param = UtilsDM.getQueryDataParams(inter.setting, [], inter.setting.order || '', 1, 1000, BID)
@@ -683,7 +687,6 @@
       })
       delete inter.scripts
 
-      inter.setting.$name = '鍏叡鏁版嵁婧�-' + inter.setting.name
       inter.setting.execute = inter.setting.execute !== 'false'
       inter.setting.laypage = false
       inter.setting.$top = true
@@ -771,7 +774,7 @@
     }
   }
 
-  getFormatParam = (params) => {
+  getFormatParam = (params, MenuName) => {
     const { BID } = this.state
 
     if (!params || params.length === 0) return ''
@@ -841,6 +844,10 @@
       fullName: fullName
     }
 
+    if (MenuName) {
+      param.menuname = MenuName
+    }
+
     param.LText = Utils.formatOptions(param.LText)
     param.LText_field = Utils.formatOptions(param.LText_field)
     param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
diff --git a/src/views/design/sidemenu/index.jsx b/src/views/design/sidemenu/index.jsx
index 83ff546..e25d692 100644
--- a/src/views/design/sidemenu/index.jsx
+++ b/src/views/design/sidemenu/index.jsx
@@ -119,16 +119,16 @@
       }
       _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
       window.open(`#/menudesign/${_param}`)
+    } else if (cell.type === 'BaseTable') {
+      sessionStorage.setItem('menuTree', JSON.stringify(this.props.menuTree))
+      let _param = window.btoa(window.encodeURIComponent(JSON.stringify(cell)))
+      
+      window.open(`#/tabledesign/${_param}`)
     } else if (['CommonTable', 'TreePage'].includes(cell.type)) {
       sessionStorage.setItem('menuTree', JSON.stringify(this.props.menuTree))
       let _param = window.btoa(window.encodeURIComponent(JSON.stringify(cell)))
 
       window.open(`#/basedesign/${_param}`)
-    } else if (cell.type === 'BaseTable') {
-      sessionStorage.setItem('menuTree', JSON.stringify(this.props.menuTree))
-      let _param = window.btoa(window.encodeURIComponent(JSON.stringify(cell)))
-
-      window.open(`#/tabledesign/${_param}`)
     } else if (['RolePermission', 'NewPage'].includes(cell.type)) {
       let _cell = fromJS(cell).toJS()
       _cell.Template = _cell.PageParam.Template
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index 3a98723..b271577 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -125,6 +125,7 @@
     
     MKEmitter.addListener('changePopview', this.initPopview)
     MKEmitter.addListener('triggerMenuSave', this.triggerMenuSave)
+    MKEmitter.addListener('changeEditMenu', this.changeEditMenu)
     setTimeout(() => {
       this.getRoleFields()
       setGLOBFuncs()
@@ -196,6 +197,49 @@
     }
     MKEmitter.removeListener('changePopview', this.initPopview)
     MKEmitter.removeListener('triggerMenuSave', this.triggerMenuSave)
+    MKEmitter.removeListener('changeEditMenu', this.changeEditMenu)
+  }
+
+  changeEditMenu = (menu) => {
+    if (menu.MenuID && menu.MenuID.length === 3 && menu.MenuNo && !this.menuLoading) {
+      this.menuLoading = true
+      let param = {
+        func: 'sPC_Get_LongParam',
+        MenuID: menu.MenuID[2]
+      }
+  
+      Api.getCloudConfig(param).then(result => {
+        this.menuLoading = false
+        if (result.status) {
+          let config = null
+  
+          try {
+            config = result.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) : null
+          } catch (e) {
+            console.warn('Parse Failure')
+            config = null
+          }
+
+          if (config) {
+            let _param = {
+              MenuId: menu.MenuID[2],
+              MenuID: menu.MenuID[2],
+              ParentId: menu.MenuID[1],
+              MenuName: menu.MenuName,
+              MenuNo: menu.MenuNo
+            }
+            if (config.Template === 'BaseTable') {
+              _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
+              window.open(`#/tabledesign/${_param}`)
+            } else if (config.Template === 'CustomPage') {
+              _param.MenuType = 'custom'
+              _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
+              window.open(`#/menudesign/${_param}`)
+            }
+          }
+        }
+      })
+    }
   }
 
   triggerMenuSave = () => {
@@ -1091,12 +1135,6 @@
 
     this.setState({config})
     window.GLOB.customMenu = config
-
-    notification.success({
-      top: 92,
-      message: '绮樿创鎴愬姛锛�',
-      duration: 2
-    })
   }
 
   changeSetting = () => {
diff --git a/src/views/menudesign/popview/index.jsx b/src/views/menudesign/popview/index.jsx
index d5eccea..1cf34b5 100644
--- a/src/views/menudesign/popview/index.jsx
+++ b/src/views/menudesign/popview/index.jsx
@@ -246,12 +246,6 @@
     this.setState({config})
 
     window.GLOB.customMenu = config
-    
-    notification.success({
-      top: 92,
-      message: '绮樿创鎴愬姛锛�',
-      duration: 2
-    })
   }
 
   render () {
diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index b3dca30..4c6417c 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -1858,49 +1858,14 @@
   insert = (item) => {
     let config = fromJS(this.state.config).toJS()
 
-    if (item.type === 'search') {
-      if (config.components.filter(card => card.type === 'topbar' && card.wrap.type !== 'navbar').length > 0) {
-        notification.warning({
-          top: 92,
-          message: '瀵艰埅鏍忎娇鐢ㄤ簡鎼滅储锛屼笉鍙坊鍔犳悳绱㈢粍浠讹紒',
-          duration: 5
-        })
-        return
-      }
-      if (config.components.filter(card => card.type === 'search').length > 0) {
-        notification.warning({
-          top: 92,
-          message: '鎼滅储鏉′欢涓嶅彲閲嶅娣诲姞锛�',
-          duration: 5
-        })
-        return
-      }
-    }
-    
-    if (item.type === 'topbar') {
-      if (config.components.findIndex(m => m.type === 'topbar') > -1) {
-        notification.warning({
-          top: 92,
-          message: '瀵艰埅鏍忎笉鍙噸澶嶆坊鍔狅紒',
-          duration: 5
-        })
-        return
-      }
-      if (!config.style.paddingTop) {
-        config.style.paddingTop = '50px'
-      }
+    if (item.type === 'topbar' && !config.style.paddingTop) {
+      config.style.paddingTop = '50px'
     }
 
     config.components.push(item)
 
     this.setState({config})
     window.GLOB.customMenu = config
-
-    notification.success({
-      top: 92,
-      message: '绮樿创鎴愬姛锛�',
-      duration: 2
-    })
   }
 
   setHomeView = () => {
diff --git a/src/views/mobdesign/popview/index.jsx b/src/views/mobdesign/popview/index.jsx
index eeaa4c7..bfd1bf1 100644
--- a/src/views/mobdesign/popview/index.jsx
+++ b/src/views/mobdesign/popview/index.jsx
@@ -248,12 +248,6 @@
     this.setState({config})
 
     window.GLOB.customMenu = config
-    
-    notification.success({
-      top: 92,
-      message: '绮樿创鎴愬姛锛�',
-      duration: 2
-    })
   }
 
   render () {
diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx
index bc099f8..7ace0bb 100644
--- a/src/views/pcdesign/index.jsx
+++ b/src/views/pcdesign/index.jsx
@@ -1550,12 +1550,6 @@
 
     this.setState({config})
     window.GLOB.customMenu = config
-
-    notification.success({
-      top: 92,
-      message: '绮樿创鎴愬姛锛�',
-      duration: 2
-    })
   }
 
   setHomeView = () => {
diff --git a/src/views/systemfunc/sidemenu/index.jsx b/src/views/systemfunc/sidemenu/index.jsx
index b6c4b15..53dc77f 100644
--- a/src/views/systemfunc/sidemenu/index.jsx
+++ b/src/views/systemfunc/sidemenu/index.jsx
@@ -40,18 +40,50 @@
     }
 
     let tb =  sessionStorage.getItem('mk-table-node')
+    let temp = sessionStorage.getItem('mk-print-temp')
+    let tabTemp = sessionStorage.getItem('mk-print-tab-temp')
+
+    sessionStorage.removeItem('mk-table-node')
+    sessionStorage.removeItem('mk-print-temp')
+    sessionStorage.removeItem('mk-print-tab-temp')
 
     this.setState({
       subMenulist: menulist,
       rootSubmenuKeys: menulist.map(item => item.MenuID),
       openKeys: [menulist[0].MenuID]
     }, () => {
-      if (tb && menulist[0] && menulist[0].children[0] && menulist[0].children[0].MenuNo === 'sDatasM') {
-        setTimeout(() => {
-          MKEmitter.emit('modifyTabs', fromJS(menulist[0].children[0]).toJS())
-        }, 500)
+      if (!menulist[0] || menulist[0].children.length === 0) return
+
+      if (tb) {
+        let menu = menulist[0].children.filter(item => item.MenuNo === 'sDatasM')[0]
+        if (menu) {
+          setTimeout(() => {
+            MKEmitter.emit('modifyTabs', fromJS(menu).toJS())
+          }, 500)
+        }
+      } else if (temp) {
+        let menu = menulist[0].children.filter(item => item.MenuNo === 'sPrintTemplate_webM')[0]
+        if (menu) {
+          menu = fromJS(menu).toJS()
+          menu.param = {}
+          menu.param.$searchkey = 'PrintTempNO'
+          menu.param.$searchval = temp
+          setTimeout(() => {
+            MKEmitter.emit('modifyTabs', menu)
+          }, 500)
+        }
+      } else if (tabTemp) {
+        let menu = menulist[0].children.filter(item => item.MenuNo === 'sPrintTemplateM')[0]
+        if (menu) {
+          menu = fromJS(menu).toJS()
+          menu.param = {}
+          menu.param.$searchkey = 'PrintTempNO'
+          menu.param.$searchval = tabTemp
+          setTimeout(() => {
+            MKEmitter.emit('modifyTabs', menu)
+          }, 500)
+        }
       }
-      sessionStorage.removeItem('mk-table-node')
     })
   }
 

--
Gitblit v1.8.0