From d1cd5af5adb53e91efdd278328e1b6f8ad834fb5 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期四, 06 二月 2025 21:11:56 +0800
Subject: [PATCH] Merge branch 'positec' into dms

---
 src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx      |    1 
 src/templates/zshare/modalform/index.jsx                                    |    4 
 src/templates/zshare/editTable/index.jsx                                    |  288 +++-
 src/menu/components/table/edit-table/columns/tableIn/index.jsx              |  289 ++++
 src/menu/stylecombcontrolbutton/index.scss                                  |   22 
 src/menu/components/editor/braft-editor/options.jsx                         |   22 
 src/tabviews/custom/components/editor/braft-editor/index.jsx                |   42 
 src/menu/components/card/table-card/index.jsx                               |   25 
 src/menu/components/share/markcomponent/index.jsx                           |   11 
 src/menu/components/form/dragtitle/options.jsx                              |    4 
 src/menu/components/share/searchcomponent/index.jsx                         |   16 
 src/tabviews/custom/components/share/braftContent/index.scss                |    2 
 src/utils/utils-custom.js                                                   |   64 
 src/templates/comtableconfig/updatetable/index.jsx                          |   10 
 src/menu/components/card/balcony/options.jsx                                |    1 
 src/tabviews/zshare/actionList/excelInbutton/index.jsx                      |    8 
 src/menu/components/share/searchcomponent/dragsearch/card.jsx               |    4 
 src/pc/components/login/normal-login/options.jsx                            |    1 
 src/menu/components/chart/antv-scatter/index.jsx                            |    4 
 src/tabviews/basetable/index.jsx                                            |   29 
 src/views/pcdesign/index.scss                                               |    1 
 src/mob/modalconfig/index.jsx                                               |    2 
 src/assets/css/design.scss                                                  |   27 
 src/tabviews/zshare/actionList/normalbutton/index.jsx                       |   57 
 src/views/mobdesign/index.jsx                                               |   12 
 src/views/tabledesign/index.scss                                            |   21 
 src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx        |    4 
 src/templates/zshare/editTable/index.scss                                   |   25 
 src/tabviews/zshare/actionList/changeuserbutton/index.jsx                   |    2 
 src/views/menudesign/index.jsx                                              |   45 
 src/menu/datasource/verifycard/index.jsx                                    |   38 
 src/menu/normalCss/index.scss                                               |    1 
 src/menu/components/form/formaction/formconfig.jsx                          |   16 
 src/tabviews/custom/components/card/cardcellList/index.jsx                  |    4 
 src/menu/components/form/tab-form/index.jsx                                 |    1 
 src/menu/components/share/actioncomponent/formconfig.jsx                    |   48 
 src/menu/components/card/double-data-card/index.jsx                         |   25 
 src/menu/components/search/main-search/dragsearch/card.jsx                  |    4 
 src/menu/lowerField/index.scss                                              |    0 
 src/menu/pastecontroller/index.jsx                                          |    3 
 src/menu/components/card/data-card/index.jsx                                |   25 
 src/tabviews/custom/components/table/edit-table/normalTable/index.jsx       |    4 
 src/tabviews/zshare/mutilform/mkPopSelect/index.jsx                         |    8 
 src/menu/components/code/sandbox/codecontent/index.scss                     |    2 
 src/tabviews/custom/components/share/braftContent/index.jsx                 |   57 
 src/tabviews/zshare/mutilform/index.jsx                                     |    6 
 src/menu/components/share/actioncomponent/actionform/index.jsx              |   14 
 src/tabviews/custom/index.jsx                                               |   31 
 src/views/menudesign/index.scss                                             |   91 
 src/menu/components/table/edit-table/columns/tableIn/uniqueform/index.jsx   |    4 
 src/menu/debug/index.jsx                                                    |  202 +++
 src/menu/components/search/main-search/options.jsx                          |    3 
 src/views/menudesign/popview/index.jsx                                      |   30 
 src/menu/datasource/verifycard/index.scss                                   |   12 
 src/tabviews/zshare/topSearch/index.jsx                                     |   15 
 src/menu/normalCopy/index.scss                                              |   21 
 src/menu/components/form/formaction/actionform/index.jsx                    |    3 
 src/menu/components/card/cardcellcomponent/dragaction/index.jsx             |    2 
 src/menu/normalCopy/index.jsx                                               |   33 
 src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx            |    4 
 src/templates/sharecomponent/searchcomponent/index.jsx                      |   12 
 src/menu/components/form/simple-form/options.jsx                            |    4 
 src/tabviews/zshare/actionList/exceloutbutton/index.jsx                     |    8 
 src/menu/components/form/simple-form/index.jsx                              |    1 
 src/templates/sharecomponent/fieldscomponent/index.jsx                      |    3 
 src/menu/components/chart/antv-bar/index.jsx                                |    4 
 src/views/tabledesign/index.jsx                                             |   18 
 src/api/index.js                                                            |   14 
 src/templates/modalconfig/dragelement/index.jsx                             |   18 
 src/utils/utils.js                                                          |   61 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx       |    6 
 src/menu/components/share/pastecomponent/index.jsx                          |   24 
 src/components/normalform/modalform/index.jsx                               |    3 
 src/menu/components/form/step-form/index.jsx                                |    1 
 public/manifest.json                                                        |    2 
 src/views/pcdesign/index.jsx                                                |   10 
 src/templates/modalconfig/settingform/index.jsx                             |    4 
 src/templates/zshare/formconfig.jsx                                         |   14 
 src/templates/zshare/verifycard/index.jsx                                   |   58 
 src/views/mobdesign/popview/index.jsx                                       |    6 
 src/menu/replaceField/index.jsx                                             |  782 ++++++-------
 src/mob/components/formdragelement/index.jsx                                |   18 
 src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx           |   12 
 src/tabviews/zshare/actionList/printbutton/index.jsx                        |    8 
 src/menu/components/search/main-search/index.jsx                            |   11 
 src/menu/lowerField/index.jsx                                               |  321 +++++
 /dev/null                                                                   |   12 
 src/templates/sharecomponent/searchcomponent/settingform/index.jsx          |    8 
 src/menu/components/editor/braft-editor/index.jsx                           |    7 
 src/menu/components/module/account/index.jsx                                |    2 
 src/menu/modalconfig/index.jsx                                              |   23 
 src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx |  145 -
 src/utils/option.js                                                         |    2 
 src/views/menudesign/popview/index.scss                                     |   72 
 src/views/tabledesign/popview/index.jsx                                     |    4 
 95 files changed, 2,378 insertions(+), 1,070 deletions(-)

diff --git a/public/manifest.json b/public/manifest.json
index cb18af8..9376b3c 100644
--- a/public/manifest.json
+++ b/public/manifest.json
@@ -6,5 +6,5 @@
   "display": "standalone",
   "theme_color": "#000000",
   "background_color": "#ffffff",
-  "mk_version": "20250101"
+  "mk_version": "20250205"
 }
diff --git a/src/api/index.js b/src/api/index.js
index 6be24cd..ae9d25b 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -803,11 +803,10 @@
           if (res.mksqls) {
             res.mksqls.forEach(n => {
               n = n.replace(/(UNION ALL\s+)?SELECT obj_name='[\S\s]+sub_field=''\s+/ig, '')
-              if (!res.status) {
-                window.mkInfo('%c' + n, 'color: #f5222d')
-              } else {
-                window.mkInfo(n)
+              if (!res.status && param.data[0] && param.data[0].menuname) {
+                window.mkInfo('%c' + param.data[0].menuname, 'color: #f5222d')
               }
+              window.mkInfo(n)
             })
           }
           delete res.mksqls
@@ -1126,11 +1125,10 @@
           if (res.mksqls) {
             res.mksqls.forEach(n => {
               n = n.replace(/(UNION ALL\s+)?SELECT obj_name='[\S\s]+sub_field=''\s+/ig, '')
-              if (!res.status) {
-                window.mkInfo('%c' + n, 'color: #f5222d')
-              } else {
-                window.mkInfo(n)
+              if (!res.status && param.data[0] && param.data[0].menuname) {
+                window.mkInfo('%c' + param.data[0].menuname, 'color: #f5222d')
               }
+              window.mkInfo(n)
             })
           }
           delete res.mksqls
diff --git a/src/assets/css/design.scss b/src/assets/css/design.scss
index ceaad14..1c2be11 100644
--- a/src/assets/css/design.scss
+++ b/src/assets/css/design.scss
@@ -153,3 +153,30 @@
     color: #f5222d;
   }
 }
+
+.mk-opeartion-dropdown-wrap {
+  box-shadow: 0 0 2px #bcbcbc;
+  background: #ffffff;
+  min-width: 120px;
+  button {
+    display: block;
+    width: 100%;
+    height: 40px;
+    line-height: 40px;
+    border-radius: 0px;
+    border: none;
+    border-bottom: 1px solid #e8e8e8!important;
+    color: #26C281;
+
+    .anticon {
+      display: none;
+    }
+  }
+  button:hover {
+    color: #26C281;
+  }
+}
+
+.menu-setting .ant-typography-copy {
+  margin-left: 0px;
+}
diff --git a/src/components/normalform/modalform/index.jsx b/src/components/normalform/modalform/index.jsx
index 6c7d9f3..5b1cb47 100644
--- a/src/components/normalform/modalform/index.jsx
+++ b/src/components/normalform/modalform/index.jsx
@@ -22,6 +22,7 @@
 // const MKColor = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkColor'))
 const MkEditIcon = asyncComponent(() => import('@/components/mkIcon'))
 const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent'))
+const CodeMirror = asyncComponent(() => import('@/templates/zshare/codemirror'))
 
 class ModalForm extends Component {
   static propTpyes = {
@@ -362,6 +363,8 @@
         return
       } else if (item.type === 'printTemps') {
         content = <MkPrintTemps onChange={(val) => this.recordChange({[item.field]: val})}/>
+      } else if (item.type === 'codemirror') {
+        content = <CodeMirror mode="text/javascript" theme="cobalt" onChange={(val) => this.recordChange({[item.field]: val})}/>
       }
 
       if (!content) return
diff --git a/src/menu/components/card/balcony/options.jsx b/src/menu/components/card/balcony/options.jsx
index 519d5b1..36a2a1e 100644
--- a/src/menu/components/card/balcony/options.jsx
+++ b/src/menu/components/card/balcony/options.jsx
@@ -114,6 +114,7 @@
       label: '涓婄骇缁勪欢',
       initval: wrap.supModule || [],
       required: true,
+      allowClear: true,
       options: supmodules,
       forbid: isprint
     },
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/index.jsx b/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
index e3c1ff9..487ccc2 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
@@ -75,7 +75,7 @@
       message.warning('澶嶅埗澶辫触銆�')
     }
 
-    if (card.eleType !== 'button') {
+    if (card.eleType !== 'button' && !window.GLOB.CopyOnly) {
       _cards.push(copycard)
   
       handleList(_cards)
diff --git a/src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx b/src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx
index 5801b94..72bd04f 100644
--- a/src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx
+++ b/src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx
@@ -62,7 +62,6 @@
         dataIndex: 'remark',
         inputType: 'input',
         editable: true,
-        unique: false,
         required: false,
         width: '20%'
       }
diff --git a/src/menu/components/card/data-card/index.jsx b/src/menu/components/card/data-card/index.jsx
index 6e8d9fd..6723bb4 100644
--- a/src/menu/components/card/data-card/index.jsx
+++ b/src/menu/components/card/data-card/index.jsx
@@ -207,7 +207,7 @@
     this.updateComponent(_card)
   }
 
-  addSearch = (copy) => {
+  addSearch = (copy, type = '') => {
     const { card } = this.state
 
     let newcard = {}
@@ -228,7 +228,7 @@
     }
 
     // 娉ㄥ唽浜嬩欢-娣诲姞鎼滅储
-    MKEmitter.emit('addSearch', card.uuid, newcard)
+    MKEmitter.emit('addSearch', card.uuid, newcard, type)
   }
 
   addButton = (copy) => {
@@ -501,13 +501,22 @@
         }
   
         if (res.field && keys.includes(res.field.toLowerCase())) {
-          resolve({status: false, message: '鎼滅储瀛楁宸插瓨鍦紒'})
-          return
+          resolve({status: false})
+          const that = this
+          confirm({
+            title: '鎼滅储瀛楁宸插瓨鍦紒',
+            okText: '鐭ラ亾浜�',
+            cancelText: '鏇挎崲',
+            onOk() {},
+            onCancel() {
+              that.addSearch(res, 'replace')
+            }
+          })
+        } else {
+          resolve({status: true})
+  
+          this.addSearch(res)
         }
-
-        resolve({status: true})
-
-        this.addSearch(res)
       }
     } else if (type === 'action') {
       if (res.style) {
diff --git a/src/menu/components/card/double-data-card/index.jsx b/src/menu/components/card/double-data-card/index.jsx
index 62a639f..ca1be3d 100644
--- a/src/menu/components/card/double-data-card/index.jsx
+++ b/src/menu/components/card/double-data-card/index.jsx
@@ -201,7 +201,7 @@
     this.updateComponent(_card)
   }
 
-  addSearch = (copy) => {
+  addSearch = (copy, type = '') => {
     const { card } = this.state
 
     let newcard = {}
@@ -222,7 +222,7 @@
     }
 
     // 娉ㄥ唽浜嬩欢-娣诲姞鎼滅储
-    MKEmitter.emit('addSearch', card.uuid, newcard)
+    MKEmitter.emit('addSearch', card.uuid, newcard, type)
   }
 
   addButton = (copy) => {
@@ -466,13 +466,22 @@
         }
   
         if (res.field && keys.includes(res.field.toLowerCase())) {
-          resolve({status: false, message: '鎼滅储瀛楁宸插瓨鍦紒'})
-          return
+          resolve({status: false})
+          const that = this
+          confirm({
+            title: '鎼滅储瀛楁宸插瓨鍦紒',
+            okText: '鐭ラ亾浜�',
+            cancelText: '鏇挎崲',
+            onOk() {},
+            onCancel() {
+              that.addSearch(res, 'replace')
+            }
+          })
+        } else {
+          resolve({status: true})
+  
+          this.addSearch(res)
         }
-
-        resolve({status: true})
-
-        this.addSearch(res)
       }
     } else if (type === 'action') {
       if (appType === 'mob' && !['pop', 'prompt', 'exec', 'innerpage'].includes(res.OpenType)) {
diff --git a/src/menu/components/card/table-card/index.jsx b/src/menu/components/card/table-card/index.jsx
index 0f61b77..2cb6e75 100644
--- a/src/menu/components/card/table-card/index.jsx
+++ b/src/menu/components/card/table-card/index.jsx
@@ -220,7 +220,7 @@
     this.updateComponent(card)
   }
 
-  addSearch = (copy) => {
+  addSearch = (copy, type = '') => {
     const { card } = this.state
 
     let newcard = {}
@@ -242,7 +242,7 @@
     }
 
     // 娉ㄥ唽浜嬩欢-娣诲姞鎼滅储
-    MKEmitter.emit('addSearch', card.uuid, newcard)
+    MKEmitter.emit('addSearch', card.uuid, newcard, type)
   }
 
   move = (item, direction) => {
@@ -337,13 +337,22 @@
         }
   
         if (res.field && keys.includes(res.field.toLowerCase())) {
-          resolve({status: false, message: '鎼滅储瀛楁宸插瓨鍦紒'})
-          return
+          resolve({status: false})
+          const that = this
+          confirm({
+            title: '鎼滅储瀛楁宸插瓨鍦紒',
+            okText: '鐭ラ亾浜�',
+            cancelText: '鏇挎崲',
+            onOk() {},
+            onCancel() {
+              that.addSearch(res, 'replace')
+            }
+          })
+        } else {
+          resolve({status: true})
+  
+          this.addSearch(res)
         }
-
-        resolve({status: true})
-
-        this.addSearch(res)
       }
     }
   }
diff --git a/src/menu/components/chart/antv-bar/index.jsx b/src/menu/components/chart/antv-bar/index.jsx
index 0ad4db4..3436279 100644
--- a/src/menu/components/chart/antv-bar/index.jsx
+++ b/src/menu/components/chart/antv-bar/index.jsx
@@ -1337,12 +1337,12 @@
 
   plusSearch = (uuid, search, type) => {
     const { card } = this.state
-    if (card.uuid !== uuid || type !== 'simple') return
+    if (card.uuid !== uuid || (type !== 'simple' && type !== 'replace')) return
 
     search.uuid = Utils.getuuid()
     search.focus = true
 
-    MKEmitter.emit('addSearch', card.uuid, search)
+    MKEmitter.emit('addSearch', card.uuid, search, type === 'replace' ? 'replace' : '')
   }
 
   addButton = () => {
diff --git a/src/menu/components/chart/antv-scatter/index.jsx b/src/menu/components/chart/antv-scatter/index.jsx
index 9a20837..41bf3bd 100644
--- a/src/menu/components/chart/antv-scatter/index.jsx
+++ b/src/menu/components/chart/antv-scatter/index.jsx
@@ -278,12 +278,12 @@
 
   plusSearch = (uuid, search, type) => {
     const { card } = this.state
-    if (card.uuid !== uuid || type !== 'simple') return
+    if (card.uuid !== uuid || (type !== 'simple' && type !== 'replace')) return
 
     search.uuid = Utils.getuuid()
     search.focus = true
 
-    MKEmitter.emit('addSearch', card.uuid, search)
+    MKEmitter.emit('addSearch', card.uuid, search, type === 'replace' ? 'replace' : '')
   }
 
   addButton = () => {
diff --git a/src/menu/components/code/sandbox/codecontent/index.scss b/src/menu/components/code/sandbox/codecontent/index.scss
index f2f0d33..1bf75e2 100644
--- a/src/menu/components/code/sandbox/codecontent/index.scss
+++ b/src/menu/components/code/sandbox/codecontent/index.scss
@@ -18,7 +18,7 @@
       background-color: #f0f0f0;
     }
     td, th {
-      padding: 5px 14px;
+      padding: 5px 10px;
       font-size: 16px;
       border: 1px solid #ddd;
     }
diff --git a/src/menu/components/editor/braft-editor/index.jsx b/src/menu/components/editor/braft-editor/index.jsx
index 0878d3e..67fcb70 100644
--- a/src/menu/components/editor/braft-editor/index.jsx
+++ b/src/menu/components/editor/braft-editor/index.jsx
@@ -200,7 +200,7 @@
         <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
-            <NormalForm title="瀵屾枃鏈缃�" width={850} update={this.updateWrap} getForms={this.getWrapForms}>
+            <NormalForm title="瀵屾枃鏈缃�" width={900} update={this.updateWrap} getForms={this.getWrapForms}>
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
             <CopyComponent type="editor" card={card}/>
@@ -212,10 +212,7 @@
         } trigger="hover">
           <ToolOutlined />
         </Popover>
-        <BraftContent
-          value={card.wrap.datatype !== 'static' ? '<p class="empty-content">瀵屾枃鏈�</p>' : card.html}
-          encryption="false"
-        />
+        <BraftContent value={card.wrap.datatype !== 'static' ? '<p class="empty-content">瀵屾枃鏈�</p>' : card.html}/>
         <div className="component-name">
           <div className="center">
             <div className="title">{card.name}</div>
diff --git a/src/menu/components/editor/braft-editor/options.jsx b/src/menu/components/editor/braft-editor/options.jsx
index 72d9018..bd9e84c 100644
--- a/src/menu/components/editor/braft-editor/options.jsx
+++ b/src/menu/components/editor/braft-editor/options.jsx
@@ -167,6 +167,28 @@
     },
     {
       type: 'radio',
+      field: 'loaded',
+      label: '甯冨眬璋冩暣',
+      initval: wrap.loaded || 'false',
+      required: false,
+      options: [
+        {value: 'false', label: '鍏抽棴'},
+        {value: 'true', label: '寮�鍚�'},
+      ],
+      controlFields: [
+        {field: 'loadedfunc', values: ['true']},
+      ]
+    },
+    {
+      type: 'codemirror',
+      field: 'loadedfunc',
+      label: '澶勭悊鑴氭湰',
+      initval: wrap.loadedfunc || '',
+      required: true,
+      span: 24
+    },
+    {
+      type: 'radio',
       field: 'permission',
       label: '鏉冮檺楠岃瘉',
       initval: wrap.permission || 'false',
diff --git a/src/menu/components/form/dragtitle/options.jsx b/src/menu/components/form/dragtitle/options.jsx
index 485faea..80097ad 100644
--- a/src/menu/components/form/dragtitle/options.jsx
+++ b/src/menu/components/form/dragtitle/options.jsx
@@ -8,13 +8,13 @@
   if (appType === 'mob') {
     group.fields.forEach(f => {
       if (f.field && ['select', 'text', 'number', 'textarea'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
-        fields.push(f)
+        fields.push({...f, label: `${f.label}锛�${f.field}锛塦})
       }
     })
   } else {
     group.fields.forEach(f => {
       if (f.field && ['select', 'link', 'text', 'number', 'textarea'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
-        fields.push(f)
+        fields.push({...f, label: `${f.label}锛�${f.field}锛塦})
       }
     })
   }
diff --git a/src/menu/components/form/formaction/actionform/index.jsx b/src/menu/components/form/formaction/actionform/index.jsx
index a46a9ca..2f9e22f 100644
--- a/src/menu/components/form/formaction/actionform/index.jsx
+++ b/src/menu/components/form/formaction/actionform/index.jsx
@@ -62,6 +62,9 @@
       if (this.record.execSuccess === 'never') {
         shows.push('resetForms')
       }
+      if (this.record.refreshTab && this.record.refreshTab.length) {
+        shows.push('urlPar')
+      }
       if (this.record.syncComponent && this.record.syncComponent[0]) {
         shows.push('syncDelay')
       }
diff --git a/src/menu/components/form/formaction/formconfig.jsx b/src/menu/components/form/formaction/formconfig.jsx
index ef22b50..776f233 100644
--- a/src/menu/components/form/formaction/formconfig.jsx
+++ b/src/menu/components/form/formaction/formconfig.jsx
@@ -456,6 +456,22 @@
       options: menulist
     },
     {
+      type: 'radio',
+      key: 'urlPar',
+      label: 'URL鍙橀噺',
+      initVal: card.urlPar || 'false',
+      tooltip: '鍒锋柊鑿滃崟鏃舵槸鍚︽竻闄RL鍙橀噺銆�',
+      required: false,
+      options: [{
+        value: 'true',
+        text: '娓呯┖'
+      }, {
+        value: 'false',
+        text: '涓嶆竻绌�'
+      }],
+      forbid: appType === 'pc' || appType === 'mob' || viewType === 'popview',
+    },
+    {
       type: (appType === 'pc' || appType === 'mob') ? 'select' : 'cascader',
       key: 'linkmenu',
       label: '涓嬩竴姝ユ搷浣�',
diff --git a/src/menu/components/form/simple-form/index.jsx b/src/menu/components/form/simple-form/index.jsx
index 60e1f9f..94dee26 100644
--- a/src/menu/components/form/simple-form/index.jsx
+++ b/src/menu/components/form/simple-form/index.jsx
@@ -325,6 +325,7 @@
       orderType: 'asc',
       readonly: 'false',
       required: 'true',
+      readin: 'top',
       focus: true
     }
 
diff --git a/src/menu/components/form/simple-form/options.jsx b/src/menu/components/form/simple-form/options.jsx
index ab8acc7..df74b82 100644
--- a/src/menu/components/form/simple-form/options.jsx
+++ b/src/menu/components/form/simple-form/options.jsx
@@ -23,13 +23,13 @@
   if (appType === 'mob') {
     config.subcards[0].fields.forEach(f => {
       if (f.field && ['select', 'text', 'number', 'textarea'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
-        fields.push(f)
+        fields.push({...f, label: `${f.label}锛�${f.field}锛塦})
       }
     })
   } else {
     config.subcards[0].fields.forEach(f => {
       if (f.field && ['select', 'link', 'text', 'number', 'textarea'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
-        fields.push(f)
+        fields.push({...f, label: `${f.label}锛�${f.field}锛塦})
       }
     })
   }
diff --git a/src/menu/components/form/step-form/index.jsx b/src/menu/components/form/step-form/index.jsx
index dd5790b..e968838 100644
--- a/src/menu/components/form/step-form/index.jsx
+++ b/src/menu/components/form/step-form/index.jsx
@@ -425,6 +425,7 @@
       orderType: 'asc',
       readonly: 'false',
       required: 'true',
+      readin: 'top',
       focus: true
     }
 
diff --git a/src/menu/components/form/tab-form/index.jsx b/src/menu/components/form/tab-form/index.jsx
index 1758d75..7e830ce 100644
--- a/src/menu/components/form/tab-form/index.jsx
+++ b/src/menu/components/form/tab-form/index.jsx
@@ -431,6 +431,7 @@
       orderType: 'asc',
       readonly: 'false',
       required: 'true',
+      readin: 'top',
       focus: true
     }
 
diff --git a/src/menu/components/module/account/index.jsx b/src/menu/components/module/account/index.jsx
index 3ddeffa..098ad7f 100644
--- a/src/menu/components/module/account/index.jsx
+++ b/src/menu/components/module/account/index.jsx
@@ -11,6 +11,7 @@
 
 import './index.scss'
 
+const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 
 class Account extends Component {
@@ -129,6 +130,7 @@
             <NormalForm title="鍩烘湰璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
+            <CopyComponent type="account" card={card}/>
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} />
           </div>
diff --git a/src/menu/components/search/main-search/dragsearch/card.jsx b/src/menu/components/search/main-search/dragsearch/card.jsx
index e10a9d5..6e41e5d 100644
--- a/src/menu/components/search/main-search/dragsearch/card.jsx
+++ b/src/menu/components/search/main-search/dragsearch/card.jsx
@@ -57,6 +57,10 @@
       _defaultValue = [moment().startOf('month'), moment().endOf('month')]
     } else if (card.initval === 'lastMonth') {
       _defaultValue = [moment().subtract(1, 'months').startOf('month'), moment().subtract(1, 'months').endOf('month')]
+    } else if (card.initval === 'year') {
+      _defaultValue = [moment().startOf('year'), moment().endOf('year')]
+    } else if (card.initval === 'lastYear') {
+      _defaultValue = [moment().subtract(1, 'years').startOf('year'), moment().subtract(1, 'years').endOf('year')]
     } else if (card.initval) {
       try {
         let _initval = JSON.parse(card.initval)
diff --git a/src/menu/components/search/main-search/index.jsx b/src/menu/components/search/main-search/index.jsx
index 33814cc..5bf777b 100644
--- a/src/menu/components/search/main-search/index.jsx
+++ b/src/menu/components/search/main-search/index.jsx
@@ -342,6 +342,17 @@
 
       this.updateComponent(_card)
       this.handleSearch(item)
+    } else if (type === 'replace') {
+      delete item.focus
+      _card.search = _card.search.map(cell => {
+        if (cell.field && cell.field.toLowerCase() === item.field.toLowerCase()) {
+          return item
+        }
+        return cell
+      })
+
+      this.updateComponent(_card)
+      this.handleSearch(item)
     } else if (type === 'multil') {
       _card.search.push(...item)
 
diff --git a/src/menu/components/search/main-search/options.jsx b/src/menu/components/search/main-search/options.jsx
index 32f04b1..6d586f9 100644
--- a/src/menu/components/search/main-search/options.jsx
+++ b/src/menu/components/search/main-search/options.jsx
@@ -140,10 +140,12 @@
       field: 'resetContrl',
       label: '閲嶇疆鏃�',
       initval: wrap.resetContrl || 'init',
+      tooltip: '鍒锋柊鑿滃崟浼氭竻绌篣RL鍙橀噺銆�',
       required: false,
       options: [
         {value: 'init', label: '鎭㈠鍒濆鍊�'},
         {value: 'clear', label: '娓呯┖'},
+        {value: 'refresh', label: '鍒锋柊鑿滃崟'},
       ],
     },
     {
@@ -189,6 +191,7 @@
       label: '涓婄骇缁勪欢',
       initval: wrap.supModule || [],
       required: false,
+      allowClear: true,
       options: modules,
       forbid: sessionStorage.getItem('editMenuType') === 'popview'
     },
diff --git a/src/menu/components/share/actioncomponent/actionform/index.jsx b/src/menu/components/share/actioncomponent/actionform/index.jsx
index 6b1a7e1..1993cd4 100644
--- a/src/menu/components/share/actioncomponent/actionform/index.jsx
+++ b/src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -226,9 +226,15 @@
 
       if (Ot === 'required') {
         shows.push('progress')
+        if (intertype === 'inner' || intertype === 'system') {
+          shows.push('execType')
+          if (this.record.execType === 'single') {
+            shows.push('execInterval')
+          }
+        }
       }
-      if (Ot === 'required' && (intertype === 'inner' || intertype === 'system')) {
-        shows.push('execType')
+      if (intertype === 'outer' || intertype === 'custom') {
+        shows.push('execInterval')
       }
       if (this.record.openmenu && this.record.openmenu !== 'goback') {
         shows.push('open')
@@ -621,6 +627,10 @@
       }
     }
 
+    if (shows.includes('refreshTab') && this.record.refreshTab && this.record.refreshTab.length) {
+      shows.push('urlPar')
+    }
+
     return {
       shows,
       reOptions,
diff --git a/src/menu/components/share/actioncomponent/formconfig.jsx b/src/menu/components/share/actioncomponent/formconfig.jsx
index 53fe5e4..9213a97 100644
--- a/src/menu/components/share/actioncomponent/formconfig.jsx
+++ b/src/menu/components/share/actioncomponent/formconfig.jsx
@@ -1089,6 +1089,22 @@
       options: menulist
     },
     {
+      type: 'radio',
+      key: 'urlPar',
+      label: 'URL鍙橀噺',
+      initVal: card.urlPar || 'false',
+      tooltip: '鍒锋柊鑿滃崟鏃舵槸鍚︽竻闄RL鍙橀噺銆�',
+      required: false,
+      options: [{
+        value: 'true',
+        text: '娓呯┖'
+      }, {
+        value: 'false',
+        text: '涓嶆竻绌�'
+      }],
+      forbid: isApp || viewType === 'popview',
+    },
+    {
       type: !appType ? 'cascader' : 'select',
       key: 'openmenu',
       label: '鎵撳紑鑿滃崟',
@@ -1634,6 +1650,14 @@
         value: 'single',
         text: '閫愭潯璇锋眰'
       }]
+    },
+    {
+      type: 'number',
+      key: 'execInterval',
+      label: '鎵ц闂撮殧',
+      initVal: card.execInterval || 0,
+      tooltip: '涓ゆ璇锋眰鐨勬椂闂撮棿闅旓紙鍗曚綅姣锛夈��',
+      required: false
     },
     {
       type: 'radio',
@@ -2499,6 +2523,22 @@
       options: menulist
     },
     {
+      type: 'radio',
+      key: 'urlPar',
+      label: 'URL鍙橀噺',
+      initVal: card.urlPar || 'false',
+      tooltip: '鍒锋柊鑿滃崟鏃舵槸鍚︽竻闄RL鍙橀噺銆�',
+      required: false,
+      options: [{
+        value: 'true',
+        text: '娓呯┖'
+      }, {
+        value: 'false',
+        text: '涓嶆竻绌�'
+      }],
+      forbid: viewType === 'popview',
+    },
+    {
       type: 'cascader',
       key: 'openmenu',
       label: '鎵撳紑鑿滃崟',
@@ -2842,6 +2882,14 @@
       }]
     },
     {
+      type: 'number',
+      key: 'execInterval',
+      label: '鎵ц闂撮殧',
+      initVal: card.execInterval || 0,
+      tooltip: '涓ゆ璇锋眰鐨勬椂闂撮棿闅旓紙鍗曚綅姣锛夈��',
+      required: false
+    },
+    {
       type: 'radio',
       key: 'progress',
       label: '杩涘害鎻愮ず',
diff --git a/src/menu/components/share/markcomponent/index.jsx b/src/menu/components/share/markcomponent/index.jsx
index 4173b5b..927c936 100644
--- a/src/menu/components/share/markcomponent/index.jsx
+++ b/src/menu/components/share/markcomponent/index.jsx
@@ -36,15 +36,8 @@
         uniqueFunc: (data, item) => {
           let index = data.findIndex(mark => mark.uuid !== item.uuid && mark.contrastValue === item.contrastValue && mark.match === item.match && mark.field.join('') === item.field.join(''))
 
-          if (index > -1) {
-            notification.warning({
-              top: 92,
-              message: '姝ゆ爣璁板凡瀛樺湪锛�',
-              duration: 5
-            })
-            return false
-          }
-          return true
+          if (index > -1) return '姝ゆ爣璁板凡瀛樺湪锛�'
+          return ''
         },
         inputType: 'cascader',
         options: [],
diff --git a/src/menu/components/share/pastecomponent/index.jsx b/src/menu/components/share/pastecomponent/index.jsx
index f0e89a1..90944e9 100644
--- a/src/menu/components/share/pastecomponent/index.jsx
+++ b/src/menu/components/share/pastecomponent/index.jsx
@@ -10,6 +10,7 @@
 import asyncComponent from '@/utils/asyncComponent'
 // import './index.scss'
 
+const { confirm } = Modal
 const PasteForm = asyncComponent(() => import('@/templates/zshare/pasteform'))
 
 class PasteController extends Component {
@@ -173,17 +174,20 @@
           }
         }
 
-        if (res.field && keys.includes(res.field.toLowerCase())) {
-          notification.warning({
-            top: 92,
-            message: '鎼滅储瀛楁宸插瓨鍦紒',
-            duration: 5
-          })
-          return
-        }
-
-        MKEmitter.emit('plusSearch', config.uuid, res, 'simple')
         this.setState({visible: false})
+        if (res.field && keys.includes(res.field.toLowerCase())) {
+          confirm({
+            title: '鎼滅储瀛楁宸插瓨鍦紒',
+            okText: '鐭ラ亾浜�',
+            cancelText: '鏇挎崲',
+            onOk() {},
+            onCancel() {
+              MKEmitter.emit('plusSearch', config.uuid, res, 'replace')
+            }
+          })
+        } else {
+          MKEmitter.emit('plusSearch', config.uuid, res, 'simple')
+        }
         return
       } else if (type === 'cardcell') {
         config.subcards.push(res)
diff --git a/src/menu/components/share/searchcomponent/dragsearch/card.jsx b/src/menu/components/share/searchcomponent/dragsearch/card.jsx
index f13b469..e1fb8a8 100644
--- a/src/menu/components/share/searchcomponent/dragsearch/card.jsx
+++ b/src/menu/components/share/searchcomponent/dragsearch/card.jsx
@@ -56,6 +56,10 @@
       _defaultValue = [moment().startOf('month'), moment().endOf('month')]
     } else if (card.initval === 'lastMonth') {
       _defaultValue = [moment().subtract(1, 'months').startOf('month'), moment().subtract(1, 'months').endOf('month')]
+    } else if (card.initval === 'year') {
+      _defaultValue = [moment().startOf('year'), moment().endOf('year')]
+    } else if (card.initval === 'lastYear') {
+      _defaultValue = [moment().subtract(1, 'years').startOf('year'), moment().subtract(1, 'years').endOf('year')]
     } else if (card.initval) {
       try {
         let _initval = JSON.parse(card.initval)
diff --git a/src/menu/components/share/searchcomponent/index.jsx b/src/menu/components/share/searchcomponent/index.jsx
index 6eca698..27a0c1b 100644
--- a/src/menu/components/share/searchcomponent/index.jsx
+++ b/src/menu/components/share/searchcomponent/index.jsx
@@ -64,12 +64,24 @@
     MKEmitter.removeListener('addSearch', this.addSearch)
   }
 
-  addSearch = (cardId, element) => {
+  addSearch = (cardId, element, type) => {
     if (cardId !== this.props.config.uuid) return
 
     const { searchlist } = this.state
 
-    this.setState({searchlist: [...searchlist, element]})
+    if (type === 'replace') {
+      delete element.focus
+      this.setState({
+        searchlist: searchlist.map(cell => {
+          if (cell.field && cell.field.toLowerCase() === element.field.toLowerCase()) {
+            return element
+          }
+          return cell
+        }),
+      })
+    } else {
+      this.setState({searchlist: [...searchlist, element]})
+    }
     this.handleSearch(element)
   }
 
diff --git a/src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx b/src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx
index 0537dcf..eeb2476 100644
--- a/src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx
+++ b/src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx
@@ -1,9 +1,8 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Row, Col, Button, notification, Modal, Tooltip, Radio, Select, Switch } from 'antd'
+import { Form, Row, Col, Button, notification, Tooltip, Radio, Select, Switch } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 
-import Api from '@/api'
 import { checkSQL } from '@/utils/utils-custom.js'
 import CodeMirror from '@/templates/zshare/codemirror'
 // import './index.scss'
@@ -67,20 +66,12 @@
   }
 
   handleConfirm = () => {
-    const { type, btn } = this.props
+    const { type } = this.props
     const { editItem, skip } = this.state
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     this.props.form.validateFieldsAndScroll((err, values) => {
-      if (type === 'fullscreen' && err) {
-        notification.warning({
-          top: 92,
-          message: '璇疯緭鍏ql!',
-          duration: 5
-        })
-        return
-      }
       if (!err) {
-        if (/^[\s\n]+$/.test(values.sql)) {
+        if (!values.sql || /^[\s\n]+$/.test(values.sql)) {
           notification.warning({
             top: 92,
             message: '璇疯緭鍏ql!',
@@ -99,92 +90,39 @@
 
         if (!pass && !skip) return
 
-        let sheet = btn.sheet.replace(/(.*)\.(.*)\.|@db@/ig, '')
-        let tail = `
-          drop table #${sheet}
-          aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg
-        `
-
-        let _initCustomScript = '' // 鍒濆鍖栬剼鏈�
-        let _prevCustomScript = '' // 榛樿sql鍓嶆墽琛岃剼鏈�
-        let _backCustomScript = '' // 榛樿sql鍚庢墽琛岃剼鏈�
-
-        this.props.scripts.forEach(item => {
-          if (item.status === 'false') return
-
-          if (item.position === 'init') {
-            _initCustomScript += `
-            /* 鍒濆鍖栬剼鏈� */
-            ${values.uuid === item.uuid ? values.sql : item.sql}
-            `
-          } else if (item.position === 'front') {
-            _prevCustomScript += `
-            /* 榛樿sql鍓嶈剼鏈� */
-            ${values.uuid === item.uuid ? values.sql : item.sql}
-            `
-          } else {
-            _backCustomScript += `
-            /* 榛樿sql鍚庤剼鏈� */
-            ${values.uuid === item.uuid ? values.sql : item.sql}
-            `
-          }
-        })
-
-        if (!values.uuid) {
-          if (values.position === 'init') {
-            _initCustomScript += `
-            /* 鍒濆鍖栬剼鏈� */
-            ${values.sql}
-            `
-          } else if (values.position === 'front') {
-            _prevCustomScript += `
-            /* 榛樿sql鍓嶈剼鏈� */
-            ${values.sql}
-            `
-          } else {
-            _backCustomScript += `
-            /* 榛樿sql鍚庤剼鏈� */
-            ${values.sql}
-            `
-          }
+        if (/@ID@/ig.test(values.sql) && !skip) {
+          notification.warning({
+            top: 92,
+            message: '鑴氭湰涓笉鍙娇鐢ˊID@锛�',
+            duration: 5
+          })
+          return
         }
-
-        let sql = this.state.verifySql + _initCustomScript + _prevCustomScript + _backCustomScript + tail
-        
-        sql = sql.replace(/@\$|\$@/ig, '')
-        sql = sql.replace(/@datam@/ig, `''`)
-        sql = sql.replace(/@typename@/ig, `'debug'`)
 
         if (skip) {
           this.setState({
-            editItem: null,
-            skip: false
-          }, () => {
-            this.props.scriptsChange(values)
+            skip: false,
+            editItem: null
           })
           this.props.form.setFieldsValue({
-            sql: ' '
+            sql: ''
           })
+          this.props.scriptsChange(values)
         } else {
           this.setState({loading: true})
-          Api.sDebug(sql).then(res => {
-            if (res.status || res.ErrCode === '-2') {
-              this.setState({
-                loading: false,
-                editItem: null
-              }, () => {
-                this.props.scriptsChange(values)
-              })
-              this.props.form.setFieldsValue({
-                sql: ' '
-              })
-            } else {
-              this.setState({loading: false})
   
-              Modal.error({
-                title: res.message
-              })
-            }
+          this.props.scriptsChange(values, () => {
+            this.setState({
+              loading: false,
+              editItem: null
+            })
+            this.props.form.setFieldsValue({
+              sql: ''
+            })
+          }, () => {
+            this.setState({
+              loading: false
+            })
           })
         }
       }
@@ -202,14 +140,18 @@
   }
 
   selectScript = (value, option) => {
-    const { usefulfields, btn } = this.props
+    const { usefulfields, btn, setting } = this.props
 
     let _value = ''
     if (value === 'default') {
       let fields = usefulfields.map(col => col.field).join(',')
+      let upFields = usefulfields.map(col => `${col.field}=t.${col.field}`).join(',')
       
       if (fields) {
         fields = fields + ','
+      }
+      if (upFields) {
+        upFields = upFields + ','
       }
 
       let database = btn.sheet.match(/(.*)\.(.*)\.|@db@/ig) || ''
@@ -217,7 +159,20 @@
 
       database = database ? (database[0] || '') : ''
 
-      _value = `Insert into ${database}${sheet} (${fields}createuserid,createuser,createstaff,bid)\nSelect ${fields}@userid@,@username,@fullname,@BID@ From #${sheet}`
+      _value = `update a set ${upFields}modifydate=getdate(),modifyuserid=@UserID@,modifyuser=@username,modifystaff=@fullname,deleted=0
+      from (select * from #${sheet} where data_type='upt') t
+      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+      update a set deleted=1,modifydate=getdate(),modifyuserid=@UserID@,modifyuser=@username,modifystaff=@fullname 
+      from (select * from #${sheet} where data_type='del') t
+      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+      delete t from #${sheet} t inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+      Insert into ${database}${sheet} (${fields}createuserid,createuser,createstaff,bid)
+      Select ${fields}@UserID@,@username,@fullname,@BID@ From #${sheet}
+      `
+      _value = _value.replace(/\s{6}[fiuds]/ig, (word) => word.replace(/\s{6}/ig, ''))
     } else {
       _value = value
     }
@@ -331,15 +286,9 @@
             <Switch checked={skip} size="small" onChange={() => this.setState({skip: !skip})}/>
           </Col>
           <Col span={24} className="sql">
-            <Form.Item label="sql">
+            <Form.Item label="sql" required>
               {getFieldDecorator('sql', {
-                initialValue: '',
-                rules: [
-                  {
-                    required: true,
-                    message: '璇疯緭鍏ql!'
-                  }
-                ]
+                initialValue: ''
               })(<CodeMirror />)}
             </Form.Item>
           </Col>
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 4bf55dc..adb600f 100644
--- a/src/menu/components/table/edit-table/columns/tableIn/index.jsx
+++ b/src/menu/components/table/edit-table/columns/tableIn/index.jsx
@@ -136,6 +136,7 @@
           let _fields = record.field.split(',')
           let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
           _fields_ = _fields_.join(' and ')
+          _fields_ += ` and a.jskey != b.${this.props.config.setting.primaryKey || 'id'}`
 
           let _where = []
           _fields.forEach(f => {
@@ -400,7 +401,7 @@
     this.setState({verify: {...verify, uniques}})
   }
 
-  scriptsChange = (values) => {
+  scriptsChange = (values, resolve, reject) => {
     let verify = JSON.parse(JSON.stringify(this.state.verify))
 
     if (values.uuid) {
@@ -416,11 +417,287 @@
       verify.scripts.push(values)
     }
 
-    MKEmitter.emit('editLineId', values.uuid)
+    let sql = this.getEditTableSql(verify)
 
-    this.setState({
-      verify: verify
+    if (resolve) {
+      Api.sDebug(sql).then(res => {
+        if (res.status || res.ErrCode === '-2') {
+          resolve()
+          values && MKEmitter.emit('editLineId', values.uuid)
+
+          this.setState({ verify })
+        } else {
+          reject()
+  
+          Modal.error({
+            title: res.message
+          })
+        }
+      })
+    } else {
+      Api.sDebug(sql, true)
+
+      MKEmitter.emit('editLineId', values.uuid)
+  
+      this.setState({ verify })
+    }
+  }
+
+  getEditTableSql = (verify) => {
+    const { columns, setting, cols } = this.props.config
+
+    let btn = verify
+    let userName = sessionStorage.getItem('User_Name') || ''
+    let fullName = sessionStorage.getItem('Full_Name') || ''
+    let RoleID = sessionStorage.getItem('role_id') || ''
+    let departmentcode = sessionStorage.getItem('departmentcode') || ''
+    let organization = sessionStorage.getItem('organization') || ''
+    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+    let nation = sessionStorage.getItem('nation') || ''
+    let province = sessionStorage.getItem('province') || ''
+    let city = sessionStorage.getItem('city') || ''
+    let district = sessionStorage.getItem('district') || ''
+    let address = sessionStorage.getItem('address') || ''
+  
+    let _sheet = btn.sheet
+    let BID = 'bid'
+  
+    if (window.GLOB.externalDatabase !== null) {
+      _sheet = _sheet.replace(/@db@/ig, window.GLOB.externalDatabase)
+    }
+  
+    let database = _sheet.match(/(.*)\.(.*)\./ig)
+    let sheet = _sheet.replace(/(.*)\.(.*)\./ig, '')
+    
+    database = database ? (database[0] || '') : ''
+  
+    let vals = []
+    let forms = []
+    let _forms = {}
+    let index = 0
+
+    let getColumns = (cols) => {
+      cols.forEach(item => {
+        if (item.type === 'colspan') {
+          getColumns(item.subcols)
+        } else if (item.editable === 'true') {
+          item.$sort = index
+          _forms[item.field] = item
+          index++
+        }
+      })
+    }
+
+    getColumns(cols)
+
+    columns.forEach(item => {
+      if (item.field === setting.primaryKey) return
+
+      if (_forms[item.field]) {
+        let _item = {..._forms[item.field]}
+        if (_item.editType === 'date') {
+          _item.datatype = _item.declareType || 'datetime'
+        } else {
+          _item.datatype = item.datatype
+        }
+
+        forms.push(_item)
+      } else {
+        forms.push({...item, $sort: 999})
+      }
     })
+
+    forms.sort((a, b) => a.$sort - b.$sort)
+
+    forms.forEach(col => {
+      if (/date/.test(col.datatype)) {
+        vals.push(`'1949-10-01'`)
+      } else if (col.type === 'number') {
+        vals.push(`1`)
+      } else {
+        vals.push(`'mk'`)
+      }
+    })
+
+    vals.push(`'uuid'`)
+    vals.push(`'upt'`)
+    vals.push(`'${BID}'`)
+
+    vals = `Select ${vals.join(',')}`
+  
+    let sql = ''
+  
+    let _initCustomScript = '' // 鍒濆鍖栬剼鏈�
+    let _prevCustomScript = '' // 榛樿sql鍓嶆墽琛岃剼鏈�
+    let _backCustomScript = '' // 榛樿sql鍚庢墽琛岃剼鏈�
+    let isDM = sessionStorage.getItem('dataM') === 'true'
+    let regs = [
+      {reg: new RegExp('(^|\\s)@' + sheet + '(\\s|$)', 'ig'), value: ` #${sheet} `},
+      {reg: new RegExp('(^|\\s)@' + sheet + '\\(', 'ig'), value: ` #${sheet}(`},
+      {reg: new RegExp('(^|\\s)@' + sheet + '\\)', 'ig'), value: ` #${sheet})`},
+      {reg: /@typename@/ig, value: `'admin'`},
+      {reg: /\$@/ig, value: isDM ? '/*' : ''},
+      {reg: /@\$/ig, value: isDM ? '*/' : ''},
+      {reg: /@datam@/ig, value: isDM ? `'Y'` : `''`},
+    ]
+
+    btn.scripts && btn.scripts.forEach(script => {
+      if (script.status === 'false') return
+
+      let _sql = script.sql
+
+      regs.forEach(item => {
+        _sql = _sql.replace(item.reg, item.value)
+      })
+
+      if (script.position === 'init') {
+        _initCustomScript += `
+      /* 鑷畾涔夎剼鏈� */
+      ${_sql}
+      `
+      } else if (script.position === 'front') {
+        _prevCustomScript += `
+      /* 鑷畾涔夎剼鏈� */
+      ${_sql}
+      `
+      } else {
+        _backCustomScript += `
+      /* 鑷畾涔夎剼鏈� */
+      ${_sql}
+      `
+      }
+    })
+
+    let _uniquesql = ''
+    if (btn.uniques && btn.uniques.length > 0) {
+      let textFields = []
+      let numberFields = []
+      let dateFields = []
+      columns.forEach((col) => {
+        if (/Nvarchar/ig.test(col.datatype)) {
+          textFields.push(col.field)
+        } else if (/Decimal|int/ig.test(col.datatype)) {
+          numberFields.push(col.field)
+        } else if (/date/ig.test(col.datatype)) {
+          dateFields.push(col.field)
+        }
+      })
+      btn.uniques.forEach(unique => {
+        if (unique.status === 'false' || !unique.verifyType) return
+
+        let _fields = unique.field.split(',')
+        let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
+        _fields_ = _fields_.join(' and ')
+        _fields_ += ` and a.jskey != b.${setting.primaryKey || 'id'}`
+
+        let _where = []
+        _fields.forEach(f => {
+          if (textFields.includes(f)) {
+            _where.push(`${f}!=''`)
+          } else if (numberFields.includes(f)) {
+            _where.push(`${f}!=0`)
+          } else if (dateFields.includes(f)) {
+            _where.push(`${f}>'1949-10-01'`)
+          }
+        })
+        _where = _where.length ? `where ${_where.join(' and ')} ` : ''
+
+        if (unique.verifyType === 'logic' || unique.verifyType === 'logic_temp') {
+          _fields_ += ' and b.deleted=0'
+        }
+
+        let _afields = []
+        _fields = _fields.map(f => {
+          if (numberFields.includes(f)) {
+            _afields.push(`cast(a.${f} as nvarchar(50))`)
+            return `cast(${f} as nvarchar(50))`
+          } else if (dateFields.includes(f)) {
+            _afields.push(`CONVERT(nvarchar(50), a.${f}, 21)`)
+            return `CONVERT(nvarchar(50), ${f}, 21)`
+          }
+          _afields.push(`a.${f}`)
+
+          return f
+        })
+
+        _uniquesql += `
+      /* 閲嶅鎬ч獙璇� */
+      Set @tbid=''
+      Select top 1 @tbid=${_fields.join('+\' \'+')} from (select 1 as n,${unique.field} from #${sheet} ) a group by ${unique.field} having sum(n)>1
+      
+      If @tbid!=''
+      Begin
+        select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 閲嶅'
+        goto aaa
+      end
+      
+      ${unique.verifyType.indexOf('temp') === -1 ? `Set @tbid=''
+      Select top 1 @tbid=${_afields.join('+\' \'+')} from ${_where ? `(select * from #${sheet} ${_where})` : `#${sheet}`} a Inner join ${sheet} b on ${_fields_}
+      
+      If @tbid!=''
+      Begin
+        select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 涓庡凡鏈夋暟鎹噸澶�'
+        goto aaa
+      end` : ''}
+      `
+      })
+    }
+
+    let declarefields = []
+    let fields = []
+    let upFields = []
+
+    forms.forEach(col => {
+      let key = col.field.toLowerCase()
+      if (key === 'jskey' || key === 'bid' || key === 'data_type') return
+
+      declarefields.push(`${col.field} ${col.datatype}`)
+      fields.push(col.field)
+      upFields.push(`${col.field}=t.${col.field}`)
+    })
+
+    fields = fields.join(',')
+    upFields = upFields.join(',')
+
+    let _insert = ''
+    if (btn.default !== 'false') {
+      _insert = `
+      /* 榛樿sql */
+      update a set ${upFields},modifydate=getdate(),modifyuserid='${sessionStorage.getItem('UserID') || ''}',modifyuser=@username,modifystaff=@fullname,deleted=0
+      from (select * from #${sheet} where data_type='upt') t
+      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+      update a set deleted=1,modifydate=getdate(),modifyuserid='${sessionStorage.getItem('UserID') || ''}',modifyuser=@username,modifystaff=@fullname 
+      from (select * from #${sheet} where data_type='del') t
+      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+      delete t from #${sheet} t inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+      Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid)
+      Select ${fields},'${sessionStorage.getItem('UserID') || ''}',@username,@fullname,'${BID}' From #${sheet}
+      `
+    }
+
+    sql = `create table #${sheet} (${declarefields.join(',')},jskey nvarchar(50),data_type nvarchar(50),BID nvarchar(256))
+      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)
+      
+      Select  @ErrorCode='', @retmsg='', @UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
+      ${_initCustomScript}
+      Insert into #${sheet} (${fields},jskey,data_type,BID)
+
+      /* excel鏁版嵁*/
+      ${vals}
+
+      ${_uniquesql}
+      ${_prevCustomScript}
+      ${_insert}
+      ${_backCustomScript}
+
+      drop table #${sheet}
+      
+      aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
+  
+    return sql
   }
 
   handleDelete = (record, type) => {
@@ -612,7 +889,7 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item required label={'鎺ュ彛绫诲瀷'}>
+                  <Form.Item required label="鎺ュ彛绫诲瀷">
                     <Radio.Group value={verify.intertype} onChange={(e) => this.onOptionChange(e.target.value, 'intertype')}>
                       <Radio value="system">绯荤粺</Radio>
                       <Radio value="inner">鍐呴儴</Radio>
@@ -716,6 +993,7 @@
                 type="fullscreen"
                 btn={verify}
                 usefulfields={fields}
+                setting={config.setting}
                 scripts={verify.scripts}
                 systemScripts={this.state.systemScripts}
                 scriptsChange={this.scriptsChange}
@@ -725,6 +1003,7 @@
             <CustomScript
               btn={verify}
               usefulfields={fields}
+              setting={config.setting}
               scripts={verify.scripts}
               systemScripts={this.state.systemScripts}
               scriptsChange={this.scriptsChange}
diff --git a/src/menu/components/table/edit-table/columns/tableIn/uniqueform/index.jsx b/src/menu/components/table/edit-table/columns/tableIn/uniqueform/index.jsx
index fc5ff7d..1c4c169 100644
--- a/src/menu/components/table/edit-table/columns/tableIn/uniqueform/index.jsx
+++ b/src/menu/components/table/edit-table/columns/tableIn/uniqueform/index.jsx
@@ -99,7 +99,7 @@
           <Col span={7}>
             <Form.Item label="楠岃瘉绫诲瀷">
               {getFieldDecorator('verifyType', {
-                initialValue: 'physical',
+                initialValue: 'logic',
                 rules: [
                   {
                     required: true,
@@ -108,8 +108,8 @@
                 ]
               })(
                 <Select>
-                  <Select.Option value="physical"> 鐗╃悊楠岃瘉锛堝叏閲忛獙璇侊級 </Select.Option>
                   <Select.Option value="logic"> 閫昏緫楠岃瘉锛堝叏閲忛獙璇侊級 </Select.Option>
+                  <Select.Option value="physical"> 鐗╃悊楠岃瘉锛堝叏閲忛獙璇侊級 </Select.Option>
                   <Select.Option value="physical_temp"> 鐗╃悊楠岃瘉锛堜粎涓存椂琛級 </Select.Option>
                   <Select.Option value="logic_temp"> 閫昏緫楠岃瘉锛堜粎涓存椂琛級  </Select.Option>
                 </Select>
diff --git a/src/menu/datasource/verifycard/index.jsx b/src/menu/datasource/verifycard/index.jsx
index 5a09d3b..2de2854 100644
--- a/src/menu/datasource/verifycard/index.jsx
+++ b/src/menu/datasource/verifycard/index.jsx
@@ -62,6 +62,7 @@
         inputType: 'input',
         editable: true,
         searchable: true,
+        copy: true,
         width: '28%'
       },
       {
@@ -118,6 +119,7 @@
           { value: 'datetime', text: 'datetime' },
         ],
         editable: true,
+        copy: true,
         width: '25%',
       }
     ],
@@ -717,6 +719,13 @@
 
       let r = SettingUtils.getDebugSql(setting, _scripts, _columns, searches, config.subtype, config.hasExtend)
 
+      if (type === 'submit' && r.custompage && setting.queryType !== 'statistics') {
+        Modal.info({
+          title: '鏁版嵁婧愭垨鑷畾涔夎剼鏈腑浣跨敤浜嗚嚜瀹氫箟鍒嗛〉锛屾煡璇㈢被鍨嬭浣跨敤缁熻锛�',
+        })
+        reject()
+        return
+      }
       if (r.custompage && setting.laypage === 'true' && _columns.findIndex(col => col.field === 'mk_total') === -1) {
         if (config.subtype !== 'basetable') {
           const that = this
@@ -1208,33 +1217,6 @@
     })
   }
 
-  tolowercase = (type) => {
-    const that = this
-    confirm({
-      content: type === 'sub' ? '纭畾灏嗗瓙琛ㄥ瓧娈佃浆涓哄皬鍐欏悧锛�' : '纭畾灏嗗瓧娈佃浆涓哄皬鍐欏悧锛�',
-      onOk() {
-        that.execlowercase(type)
-      },
-      onCancel() {}
-    })
-  }
-
-  execlowercase = (type) => {
-    const { subColumns, columns } = this.state
-
-    if (type === 'sub') {
-      this.setState({subColumns: fromJS(subColumns).toJS().map(col => {
-        col.field = col.field.toLowerCase()
-        return col
-      })})
-    } else {
-      this.setState({columns: fromJS(columns).toJS().map(col => {
-        col.field = col.field.toLowerCase()
-        return col
-      })})
-    }
-  }
-
   /**
    * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
    */
@@ -1282,7 +1264,6 @@
               type="fields"
               updatefield={this.updatefields}
             />
-            <SwapOutlined className="columns-lowercase" title="杞皬鍐�" onClick={() => this.tolowercase()}/>
             <ExcelOut data={columns} setting={setting}/>
             <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} searchKey={searchKey} type="datasourcefield" wrappedComponentRef={(inst) => this.datasource = inst} data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/>
           </TabPane> : <TabPane tab={
@@ -1307,7 +1288,6 @@
               type="fields"
               updatefield={this.updateSubfields}
             />
-            <SwapOutlined className="columns-lowercase" title="杞皬鍐�" onClick={() => this.tolowercase('sub')}/>
             <ExcelOut data={subColumns} setting={setting}/>
             <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} searchKey={searchKey} type="datasourcefield" wrappedComponentRef={(inst) => this.subdatasource = inst} data={subColumns} columns={colColumns} onChange={(subColumns) => this.setState({subColumns})}/>
           </TabPane> : null}
diff --git a/src/menu/datasource/verifycard/index.scss b/src/menu/datasource/verifycard/index.scss
index b87af52..9982345 100644
--- a/src/menu/datasource/verifycard/index.scss
+++ b/src/menu/datasource/verifycard/index.scss
@@ -146,16 +146,6 @@
       margin-right: 5px;
       cursor: pointer;
     }
-    .columns-lowercase {
-      float: right;
-      position: relative;
-      z-index: 2;
-      right: 30px;
-      height: 0px;
-      top: -15px;
-      color: orange;
-      cursor: pointer;
-    }
     .columns-out {
       float: right;
       position: relative;
@@ -169,7 +159,7 @@
       .ant-table-thead {
         .copy-control {
           top: -18px;
-          right: 55px;
+          right: 35px;
           .anticon-copy {
             margin-right: 12px;
           }
diff --git a/src/menu/debug/index.jsx b/src/menu/debug/index.jsx
index 2df2119..faff4b8 100644
--- a/src/menu/debug/index.jsx
+++ b/src/menu/debug/index.jsx
@@ -27,6 +27,8 @@
   sqlList = []
   verSqls = []
   linkMain = null
+  modules = null
+  supError = null
 
   trigger = () => {
     let config = fromJS(this.props.config).toJS()
@@ -61,6 +63,30 @@
     if (error) {
       Modal.warning({
         title: error,
+        okText: '鐭ラ亾浜�'
+      })
+      return
+    }
+
+    this.modules = {}
+    this.supError = null
+
+    this.getModules(config.components, config.interfaces)
+
+    config.interfaces && config.interfaces.forEach(item => {
+      if (item.setting && item.setting.supModule && item.setting.supModule[0] !== 'empty') {
+        let id = item.setting.supModule[item.setting.supModule.length - 1]
+        if (!this.modules[id]) {
+          this.supError = item.name + '锛堝叕鍏辨暟鎹簮锛�'
+        }
+      }
+    })
+
+    this.checklink(config.components)
+
+    if (this.supError) {
+      Modal.warning({
+        title: this.supError + '锛氫笂绾х粍浠朵笉瀛樺湪锛�',
         okText: '鐭ラ亾浜�'
       })
       return
@@ -284,6 +310,122 @@
     })
 
     this.sqlList = []
+  }
+
+  getModules = (components, interfaces, sups = []) => {
+    components.forEach(item => {
+      this.modules[item.uuid] = [...sups, item.uuid]
+      if (item.type === 'tabs') {
+        item.subtabs.forEach(f_tab => {
+          this.getModules(f_tab.components, null, [...sups, item.uuid, f_tab.uuid])
+        })
+      } else if (item.type === 'group') {
+        item.components.forEach(cell => {
+          this.modules[cell.uuid] = [...sups, item.uuid, cell.uuid]
+        })
+      }
+    })
+
+    if (interfaces && interfaces.length > 0) {
+      interfaces.forEach(item => {
+        this.modules[item.uuid] = [item.uuid]
+      })
+    }
+  }
+
+  checklink = (components, suplabel = '') => {
+    if (this.supError) return
+    components.forEach(item => {
+      if (this.supError) return
+      if (item.type === 'tabs') {
+        item.subtabs.forEach(f_tab => {
+          this.checklink(f_tab.components, suplabel)
+        })
+      } else if (item.type === 'group' ) {
+        item.components && this.checklink(item.components, suplabel)
+      } else {
+        if (item.wrap && item.wrap.supType === 'multi') {
+          if (item.setting && item.setting.supModule) {
+            item.setting.supModule = ''
+          }
+          if (item.supNodes) {
+            item.supNodes.forEach(cell => {
+              let id = cell.nodes[cell.nodes.length - 1]
+              if (!this.modules[id]) {
+                this.supError = suplabel + item.name
+              }
+            })
+          }
+        } else if ((item.wrap && item.wrap.datatype === 'static') || (['mainsearch', 'voucher'].includes(item.subtype))) {
+          if (item.wrap && item.wrap.supModule && item.wrap.supModule[0]) {
+            let id = item.wrap.supModule[item.wrap.supModule.length - 1]
+            if (!this.modules[id]) {
+              this.supError = suplabel + item.name
+            }
+          }
+        } else if (item.setting && item.setting.supModule && item.setting.supModule[0] !== 'empty') {
+          let id = item.setting.supModule[item.setting.supModule.length - 1]
+          if (!this.modules[id]) {
+            this.supError = suplabel + item.name
+          }
+        }
+
+        if (this.supError) return
+
+        if (['card', 'carousel', 'timeline'].includes(item.type)) {
+          item.subcards.forEach(card => {
+            card.elements && card.elements.forEach(cell => {
+              if (cell.eleType === 'button' && cell.OpenType === 'popview') {
+                if (cell.config && cell.config.components && cell.config.enabled) {
+                  this.checklink(cell.config.components, item.name + '-' + cell.label + '锛堝脊绐楁爣绛撅級-')
+                }
+              }
+            })
+            card.backElements && card.backElements.forEach(cell => {
+              if (cell.eleType === 'button' && cell.OpenType === 'popview') {
+                if (cell.config && cell.config.components && cell.config.enabled) {
+                  this.checklink(cell.config.components, item.name + '-' + cell.label + '锛堝脊绐楁爣绛撅級-')
+                }
+              }
+            })
+          })
+        } else if (item.type === 'balcony') {
+          item.elements && item.elements.forEach(cell => {
+            if (cell.eleType === 'button' && cell.OpenType === 'popview') {
+              if (cell.config && cell.config.components && cell.config.enabled) {
+                this.checklink(cell.config.components, item.name + '-' + cell.label + '锛堝脊绐楁爣绛撅級-')
+              }
+            }
+          })
+        } else if (item.type === 'table' && item.cols) {
+          let loopCol = (cols) => {
+            cols.forEach(col => {
+              if (col.type === 'colspan' && col.subcols) {
+                loopCol(col.subcols)
+              } else if (col.type === 'custom' && col.elements) {
+                col.elements.forEach(cell => {
+                  if (cell.eleType === 'button' && cell.OpenType === 'popview') {
+                    if (cell.config && cell.config.components && cell.config.enabled) {
+                      this.checklink(cell.config.components, item.name + '-' + cell.label + '锛堝脊绐楁爣绛撅級-')
+                    }
+                  }
+                })
+              }
+            })
+          }
+    
+          loopCol(item.cols)
+        }
+    
+        item.action && item.action.forEach(cell => {
+          if (cell.OpenType === 'popview') {
+            if (cell.config && cell.config.components && cell.config.enabled) {
+              this.checklink(cell.config.components, item.name + '-' + cell.label + '锛堝脊绐楁爣绛撅級-')
+            }
+          }
+        })
+      }
+    })
   }
 
   filterComponent = (components, mainSearch, regs, process, ispop = false) => {
@@ -783,6 +925,11 @@
             writein: item.writein !== 'false',
             type: item.type
           }
+
+          if (item.type === 'linkMain' && item.verifyVal === 'true') {
+            _item.$verify = true
+            _item.label = item.label
+          }
     
           if (_item.type === 'datemonth') {
             _item.type = 'text'
@@ -832,6 +979,11 @@
             writein: item.writein !== 'false',
             type: item.type
           }
+
+          if (item.type === 'linkMain' && item.verifyVal === 'true') {
+            _item.$verify = true
+            _item.label = item.label
+          }
     
           if (_item.type === 'datemonth') {
             _item.type = 'text'
@@ -869,8 +1021,20 @@
         key: 'mk_n_id'
       })
     }
+
+    let verifyValSql = ''
     // 鑾峰彇瀛楁閿�煎
     formdata && formdata.forEach(form => {
+      if (form.$verify) {
+        verifyValSql += `
+        if @${form.key}=${form.type === 'number' ? 0 : `''`}
+        begin
+          select @errorcode='E',@retmsg='${form.label}锛屽叧鑱斾富琛ㄥけ鏁�'
+          goto aaa
+        end
+        `
+      }
+
       let _key = form.key.toLowerCase()
       if (!_initvars.includes(_key)) {
         _initvars.push(_key)
@@ -1111,22 +1275,21 @@
   
       verify.billcodes.forEach(item => {
         let _key = item.field.toLowerCase()
-        let _linkKey = item.linkField ? item.linkField.toLowerCase() : ''
   
         if (!keys.includes(_key)) return // 琛ㄥ崟涓笉鍚崟鍙风敓鎴愬瓧娈�
   
         let _lpline = ''
         if (item.TypeCharOne === 'Lp') {
-          if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
+          if (/^BID$/ig.test(item.linkField)) {
             _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@BID@,48)`
           } else {
-            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${_linkKey},48)`
+            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${item.linkField},48)`
           }
         } else if (item.TypeCharOne === 'BN') {
-          if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
+          if (/^BID$/ig.test(item.linkField)) {
             _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
           } else {
-            _lpline = `set @ModularDetailCode= 'BN'+ right(@${_linkKey},48)`
+            _lpline = `set @ModularDetailCode= 'BN'+ right(@${item.linkField},48)`
           }
         } else {
           _lpline = `set @ModularDetailCode= right('${item.ModularDetailCode}',50)`
@@ -1236,15 +1399,20 @@
     let hasvoucher = false
   
     // 鍑瘉-鏄剧ず鍒椾腑閫夊彇,蹇呴』閫夎
-    if (verify.voucher && verify.voucher.enabled && btn.Ot !== 'requiredOnce') {
+    if (verify.voucher && verify.voucher.enabled) {
       let _voucher = verify.voucher
+      let linkField = `@${_voucher.linkField}`
   
+      if (/^BID$/ig.test(_voucher.linkField)) {
+        linkField = `'${BID}'`
+      }
+
       hasvoucher = true
   
       _sql += `
         /* 鍒涘缓鍑瘉 */
         exec s_BVoucher_Create
-          @Bill = @${_voucher.linkField},
+          @Bill = ${linkField},
           @BVoucherType ='${_voucher.BVoucherType}',
           @VoucherTypeOne ='${_voucher.VoucherTypeOne}',
           @VoucherTypeTwo ='${_voucher.VoucherTypeTwo}',
@@ -1507,6 +1675,10 @@
       }
     } else if (_backCustomScript) {
       _sql += _backCustomScript
+    }
+
+    if (verifyValSql) {
+      _sql += verifyValSql
     }
   
     if (btn.procMode === 'system') {
@@ -1937,6 +2109,7 @@
         let _fields = unique.field.split(',')
         let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
         _fields_ = _fields_.join(' and ')
+        _fields_ += ` and a.jskey != b.${setting.primaryKey || 'id'}`
 
         let _where = []
         _fields.forEach(f => {
@@ -1993,6 +2166,7 @@
 
     let declarefields = []
     let fields = []
+    let upFields = []
 
     forms.forEach(col => {
       let key = col.field.toLowerCase()
@@ -2000,15 +2174,27 @@
 
       declarefields.push(`${col.field} ${col.datatype}`)
       fields.push(col.field)
+      upFields.push(`${col.field}=t.${col.field}`)
     })
 
     fields = fields.join(',')
+    upFields = upFields.join(',')
 
     let _insert = ''
     if (btn.default !== 'false') {
       _insert = `
       /* 榛樿sql */
-      Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid) 
+      update a set ${upFields},modifydate=getdate(),modifyuserid='${sessionStorage.getItem('UserID') || ''}',modifyuser=@username,modifystaff=@fullname,deleted=0
+      from (select * from #${sheet} where data_type='upt') t
+      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+      update a set deleted=1,modifydate=getdate(),modifyuserid='${sessionStorage.getItem('UserID') || ''}',modifyuser=@username,modifystaff=@fullname 
+      from (select * from #${sheet} where data_type='del') t
+      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+      delete t from #${sheet} t inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+      Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid)
       Select ${fields},'${sessionStorage.getItem('UserID') || ''}',@username,@fullname,'${BID}' From #${sheet}
       `
     }
diff --git a/src/menu/lowerField/index.jsx b/src/menu/lowerField/index.jsx
new file mode 100644
index 0000000..be8e891
--- /dev/null
+++ b/src/menu/lowerField/index.jsx
@@ -0,0 +1,321 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import { fromJS } from 'immutable'
+import { Modal, Button, notification } from 'antd'
+import { VerticalRightOutlined } from '@ant-design/icons'
+
+// import './index.scss'
+
+const { confirm } = Modal
+
+class LowerField extends Component {
+  static propTpyes = {
+    config: PropTypes.object,
+    updateConfig: PropTypes.func
+  }
+
+  trigger = () => {
+    const that = this
+    confirm({
+      content: `纭畾灏嗗瓧娈佃浆涓哄皬鍐欏悧锛焋,
+      onOk() {
+        that.exec()
+      },
+      onCancel() {}
+    })
+  }
+
+  exec = () => {
+    let config = fromJS(this.props.config).toJS()
+
+    let resetElement = (m) => {
+      if (m.datatype === 'dynamic' && m.field) {
+        m.field = m.field.toLowerCase()
+      }
+      if (m.posterField) {
+        m.posterField = m.posterField.toLowerCase()
+      }
+      if (m.bgImage) {
+        m.bgImage = m.bgImage.toLowerCase()
+      }
+      if (m.linkurl && /^[a-zA-Z0-9_]+$/.test(m.linkurl)) {
+        m.linkurl = m.linkurl.toLowerCase()
+      }
+      if (m.modal && m.modal.fields) {
+        m.modal.fields = m.modal.fields.map(col => {
+          if (col.field) {
+            col.field = col.field.toLowerCase()
+          }
+          if (col.type === 'split' && col.splitctrl) {
+            col.splitctrl = col.splitctrl.toLowerCase()
+          }
+          return col
+        })
+      }
+      if (m.verify) {
+        if (m.verify.columns) {
+          m.verify.columns = m.verify.columns.map(col => {
+            if (col.Column) {
+              col.Column = col.Column.toLowerCase()
+            }
+            return col
+          })
+        }
+        if (m.verify.uniques) {
+          m.verify.uniques = m.verify.uniques.map(col => {
+            if (col.field) {
+              col.field = col.field.split(',').map(_field => {
+                if (_field === 'BID') return _field
+                return _field.toLowerCase()
+              }).join(',')
+            }
+            return col
+          })
+        }
+        if (m.verify.accountfield && m.verify.accountfield !== 'BID') {
+          m.verify.accountfield = m.verify.accountfield.toLowerCase()
+        }
+        if (m.verify.voucher && m.verify.voucher.linkField && m.verify.voucher.linkField !== 'BID') {
+          m.verify.voucher.linkField = m.verify.voucher.linkField.toLowerCase()
+        }
+      }
+      if (m.controlField) {
+        m.controlField = m.controlField.toLowerCase()
+      }
+      if (m.config && m.config.components) {
+        m.config.components = _replace(m.config.components)
+      }
+    }
+    let _replace = (components) => {
+      return components.map(item => {
+        if (item.type === 'tabs') {
+          item.subtabs.forEach(tab => {
+            tab.components = _replace(tab.components)
+          })
+          return item
+        } else if (item.type === 'group') {
+          item.components = _replace(item.components)
+          return item
+        }
+        
+        if (item.columns) {
+          item.columns = item.columns.map(col => {
+            if (col.field) {
+              col.field = col.field.toLowerCase()
+            }
+            return col
+          })
+        }
+        if (item.setting && item.setting.primaryKey) {
+          item.setting.primaryKey = item.setting.primaryKey.toLowerCase()
+        }
+        if (item.subColumns) {
+          item.subColumns = item.subColumns.map(col => {
+            if (col.field) {
+              col.field = col.field.toLowerCase()
+            }
+            return col
+          })
+        }
+        if (item.search) {
+          if (item.type === 'topbar') {
+            if (item.search.fields) {
+              item.search.fields = item.search.fields.map(col => {
+                if (col.field) {
+                  col.field = col.field.toLowerCase()
+                }
+                return col
+              })
+            }
+            if (item.search.groups) {
+              item.search.groups = item.search.groups.map(group => {
+                group.fields = group.fields.map(col => {
+                  if (col.field) {
+                    col.field = col.field.toLowerCase()
+                  }
+                  return col
+                })
+                return group
+              })
+            }
+          } else if (Array.isArray(item.search)) {
+            item.search = item.search.map(col => {
+              if (col.field) {
+                col.field = col.field.toLowerCase()
+              }
+              return col
+            })
+          }
+        }
+
+        if (item.action) {
+          item.action.forEach(m => {
+            resetElement(m)
+          })
+        }
+
+        if (item.subcards) {
+          item.subcards.forEach(card => {
+            if (card.setting && card.setting.controlField) {
+              card.setting.controlField = card.setting.controlField.toLowerCase()
+            }
+            if (card.elements) {
+              card.elements = card.elements.map(m => {
+                resetElement(m)
+                return m
+              })
+            }
+
+            if (card.backElements) {
+              card.backElements = card.backElements.map(m => {
+                resetElement(m)
+                return m
+              })
+            }
+
+            if (card.fields) {
+              card.fields = card.fields.map(m => {
+                if (m.field) {
+                  m.field = m.field.toLowerCase()
+                }
+                if (m.type === 'split' && m.splitctrl) {
+                  m.splitctrl = m.splitctrl.toLowerCase()
+                }
+                return m
+              })
+            }
+          })
+        }
+
+        if (item.elements) {
+          item.elements = item.elements.map(m => {
+            resetElement(m)
+            return m
+          })
+        }
+
+        if (item.plot) {
+          if (item.plot.Xaxis) {
+            item.plot.Xaxis = item.plot.Xaxis.toLowerCase()
+          }
+          // 缁熻鍥�
+          if (item.plot.InfoValue) {
+            item.plot.InfoValue = item.plot.InfoValue.toLowerCase()
+          }
+          if (item.plot.InfoType) {
+            item.plot.InfoType = item.plot.InfoType.toLowerCase()
+          }
+          // 鍗犳瘮鍥�
+          if (item.plot.valueField) {
+            item.plot.valueField = item.plot.valueField.toLowerCase()
+          }
+          if (item.plot.labelField) {
+            item.plot.labelField = item.plot.labelField.toLowerCase()
+          }
+          // 楗煎浘
+          if (item.plot.type) {
+            item.plot.type = item.plot.type.toLowerCase()
+          }
+          // 鏁g偣鍥�
+          if (item.plot.gender) {
+            item.plot.gender = item.plot.gender.toLowerCase()
+          }
+          if (item.Yaxis) {
+            if (Array.isArray(item.Yaxis)) {
+              item.Yaxis = item.Yaxis.map(m => {
+                if (m) return m.toLowerCase()
+                return m
+              })
+            } else {
+              if (item.Yaxis) {
+                item.Yaxis = item.Yaxis.toLowerCase()
+              }
+            }
+          }
+        }
+
+        if (item.cols) {
+          let _update = (cols) => {
+            return cols.map(col => {
+              if (col.type === 'custom' && col.elements) {
+                col.elements = col.elements.map(m => {
+                  resetElement(m)
+                  return m
+                })
+              } else if (col.type === 'colspan') {
+                col.subcols = _update(col.subcols)
+              } else if (col.field) {
+                col.field = col.field.toLowerCase()
+              }
+              
+              return col
+            })
+          }
+
+          item.cols = _update(item.cols)
+        }
+
+        if (item.wrap) {
+          if (item.wrap.tipField) {
+            item.wrap.tipField = item.wrap.tipField.toLowerCase()
+          }
+          if (item.wrap.controlField) {
+            item.wrap.controlField = item.wrap.controlField.toLowerCase()
+          }
+          if (item.wrap.valueField) {
+            item.wrap.valueField = item.wrap.valueField.toLowerCase()
+          }
+          if (item.wrap.labelField) {
+            item.wrap.labelField = item.wrap.labelField.toLowerCase()
+          }
+          if (item.wrap.parentField) {
+            item.wrap.parentField = item.wrap.parentField.toLowerCase()
+          }
+          if (item.wrap.broadcast) {
+            item.wrap.broadcast = item.wrap.broadcast.toLowerCase()
+          }
+          if (item.wrap.jumpField) {
+            item.wrap.jumpField = item.wrap.jumpField.toLowerCase()
+          }
+          if (item.wrap.link) {
+            item.wrap.link = item.wrap.link.toLowerCase()
+          }
+        }
+
+        return item
+      })
+    }
+
+    config.components = _replace(config.components)
+
+    config.interfaces && config.interfaces.forEach(item => {
+      if (item.columns) {
+        item.columns = item.columns.map(col => {
+          if (col.field) {
+            col.field = col.field.toLowerCase()
+          }
+          return col
+        })
+      }
+      if (item.setting && item.setting.primaryKey) {
+        item.setting.primaryKey = item.setting.primaryKey.toLowerCase()
+      }
+    })
+
+    notification.success({
+      top: 92,
+      message: '杞崲宸插畬鎴愩��',
+      duration: 3
+    })
+
+    this.props.updateConfig(config)
+  }
+
+  render() {
+    return (
+      <Button className="mk-border-purple" onClick={this.trigger}><VerticalRightOutlined style={{transform: 'rotate(270deg)'}}/> 瀛楁杞皬鍐�</Button>
+    )
+  }
+}
+
+export default LowerField
\ No newline at end of file
diff --git a/src/menu/lowerField/index.scss b/src/menu/lowerField/index.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/menu/lowerField/index.scss
diff --git a/src/menu/modalconfig/index.jsx b/src/menu/modalconfig/index.jsx
index 884b633..26c3606 100644
--- a/src/menu/modalconfig/index.jsx
+++ b/src/menu/modalconfig/index.jsx
@@ -19,6 +19,7 @@
 
 const MkIcon = asyncComponent(() => import('@/components/mk-icon'))
 const TableComponent = asyncComponent(() => import('./tablecomponent'))
+const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
 const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
 const PasteForms = asyncComponent(() => import('@/menu/components/share/pasteforms'))
 const FormFork = asyncComponent(() => import('@/menu/modalconfig/formfork'))
@@ -181,15 +182,21 @@
     })
   }
 
-  submitConfig = () => {
+  submitConfig = (type) => {
     const { config } = this.state
 
-    this.setState({originConfig: fromJS(config).toJS(), saving: true})
-    this.props.handleSave(config)
+    if (type === 'cache') {
+      this.setState({originConfig: fromJS(config).toJS()})
+      this.props.handleSave(config)
 
-    setTimeout(() => {
-      MKEmitter.emit('triggerMenuSave')
-    }, 100)
+      message.success(<span>琛ㄥ崟閰嶇疆宸蹭繚瀛樿嚦鏈湴锛�<span style={{color: 'red'}}>灏氭湭鎻愪氦鑷充簯绔�</span>锛夈��</span>)
+    } else {
+      this.setState({originConfig: fromJS(config).toJS(), saving: true})
+      this.props.handleSave(config)
+      setTimeout(() => {
+        MKEmitter.emit('triggerMenuSave')
+      }, 100)
+    }
   }
 
   clearConfig = () => {
@@ -378,6 +385,7 @@
             <Collapse accordion defaultActiveKey="1" bordered={false}>
               <Panel header="鍩烘湰淇℃伅" key="0">
                 <TableComponent />
+                <NormalCopy />
               </Panel>
               <Panel header="琛ㄥ崟" key="1">
                 <div className="search-element">
@@ -392,8 +400,9 @@
           <div className="setting">
             <Card title="琛ㄥ崟閰嶇疆" bordered={false} extra={
               <div>
+                <Button className="mk-border-green" onClick={() => this.submitConfig('cache')}>瀛樿崏绋�</Button>
                 <PasteForms type="toolbar" config={config} update={this.pasteFields}/>
-                <Button type="primary" id="save-modal-config" loading={saving} onClick={this.submitConfig}>淇濆瓨</Button>
+                <Button type="primary" id="save-modal-config" loading={saving} onClick={() => this.submitConfig()}>淇濆瓨</Button>
                 <Button disabled={saving} onClick={this.cancelConfig}>杩斿洖</Button>
               </div>
             } style={{ width: '100%' }}>
diff --git a/src/menu/normalCopy/index.jsx b/src/menu/normalCopy/index.jsx
new file mode 100644
index 0000000..97ca028
--- /dev/null
+++ b/src/menu/normalCopy/index.jsx
@@ -0,0 +1,33 @@
+import React, { Component } from 'react'
+import { Radio } from 'antd'
+
+import './index.scss'
+
+class NormalCopy extends Component {
+  state = {
+    value: window.GLOB.CopyOnly === true ? 'true' : 'false'
+  }
+
+  selectChange = (val) => {
+    if (val === 'true') {
+      window.GLOB.CopyOnly = true
+    } else {
+      window.GLOB.CopyOnly = false
+    }
+  }
+
+  render() {
+    const { value } = this.state
+
+    return (
+      <div className="mk-normal-copy">
+        鍏冪礌澶嶅埗锛�<Radio.Group defaultValue={value} onChange={(e) => {this.selectChange(e.target.value)}}>
+          <Radio value="true">浠呭鍒�</Radio>
+          <Radio value="false">澶嶅埗+鑷</Radio>
+        </Radio.Group>
+      </div>
+    )
+  }
+}
+
+export default NormalCopy
\ No newline at end of file
diff --git a/src/menu/normalCopy/index.scss b/src/menu/normalCopy/index.scss
new file mode 100644
index 0000000..d0c8024
--- /dev/null
+++ b/src/menu/normalCopy/index.scss
@@ -0,0 +1,21 @@
+.mk-normal-copy {
+  padding-left: 18px;
+  white-space: nowrap;
+
+  .ant-radio-wrapper {
+    margin-right: 2px;
+  }
+}
+.model-tablename-manage-view + .mk-normal-copy {
+  margin-top: 15px;
+}
+.modal-form-board, .mob-form-board {
+  .mk-normal-copy {
+    padding-left: 0px;
+
+    span.ant-radio + * {
+      padding-right: 2px;
+      padding-left: 2px;
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/menu/normalCss/index.scss b/src/menu/normalCss/index.scss
index 872d481..35dc98a 100644
--- a/src/menu/normalCss/index.scss
+++ b/src/menu/normalCss/index.scss
@@ -1,5 +1,6 @@
 .mk-normal-css {
   padding-left: 18px;
+  margin-bottom: 15px;
 
   .anticon-edit {
     color: #1890ff;
diff --git a/src/menu/pastecontroller/index.jsx b/src/menu/pastecontroller/index.jsx
index 51b273d..a6d11d5 100644
--- a/src/menu/pastecontroller/index.jsx
+++ b/src/menu/pastecontroller/index.jsx
@@ -274,6 +274,9 @@
         }
       } else {
         options.push('editable', 'mainsearch', 'antvG6', 'antvX6', 'calendar', 'tree', 'dashboard', 'chart')
+        if (appType !== 'pc') {
+          options.push('account')
+        }
       }
     } else {
       if (appType === 'mob') {
diff --git a/src/menu/replaceField/index.jsx b/src/menu/replaceField/index.jsx
index d7d29ec..81403fe 100644
--- a/src/menu/replaceField/index.jsx
+++ b/src/menu/replaceField/index.jsx
@@ -12,7 +12,6 @@
 
 class ReplaceField extends Component {
   static propTpyes = {
-    type: PropTypes.string,
     config: PropTypes.object,
     updateConfig: PropTypes.func
   }
@@ -155,305 +154,281 @@
 
   // 渚濇嵁鍘熷瓧娈垫浛鎹负鏂板瓧娈�
   exec = (map) => {
-    const { type } = this.props
     let config = fromJS(this.props.config).toJS()
 
-    if (type === 'custom') {
-      let _replace = (components) => {
-        return components.map(item => {
-          if (item.type === 'tabs') {
-            item.subtabs.forEach(tab => {
-              tab.components = _replace(tab.components)
-            })
-            return item
-          } else if (item.type === 'group') {
-            item.components = _replace(item.components)
-            return item
-          }
-          
-          if (item.columns) {
-            item.columns = item.columns.map(col => {
-              let cell = map[col.field.toLowerCase()]
-              if (cell) {
-                col.field = cell.FieldName
-                if (cell.datatype) {
-                  col.datatype = cell.datatype
+    let _replace = (components) => {
+      return components.map(item => {
+        if (item.type === 'tabs') {
+          item.subtabs.forEach(tab => {
+            tab.components = _replace(tab.components)
+          })
+          return item
+        } else if (item.type === 'group') {
+          item.components = _replace(item.components)
+          return item
+        }
+        
+        if (item.columns) {
+          item.columns = item.columns.map(col => {
+            let cell = map[col.field.toLowerCase()]
+            if (cell) {
+              col.field = cell.FieldName
+              if (cell.datatype) {
+                col.datatype = cell.datatype
+              }
+            }
+            return col
+          })
+        }
+        if (item.search) {
+          item.search = item.search.map(col => {
+            if (col.field && map[col.field.toLowerCase()]) {
+              col.field = map[col.field.toLowerCase()].FieldName
+            }
+            return col
+          })
+        }
+
+        if (item.action) {
+          item.action.forEach(m => {
+            if (m.modal && m.modal.fields) {
+              m.modal.fields = m.modal.fields.map(col => {
+                if (col.field && map[col.field.toLowerCase()]) {
+                  col.field = map[col.field.toLowerCase()].FieldName
                 }
-              }
-              return col
-            })
-          }
-          if (item.search) {
-            item.search = item.search.map(col => {
-              if (col.field && map[col.field.toLowerCase()]) {
-                col.field = map[col.field.toLowerCase()].FieldName
-              }
-              return col
-            })
-          }
-
-          if (item.action) {
-            item.action.forEach(m => {
-              if (m.modal && m.modal.fields) {
-                m.modal.fields = m.modal.fields.map(col => {
-                  if (col.field && map[col.field.toLowerCase()]) {
-                    col.field = map[col.field.toLowerCase()].FieldName
-                  }
-                  return col
-                })
-              }
-              if (m.verify && m.verify.columns) {
-                m.verify.columns = m.verify.columns.map(col => {
-                  if (col.Column && map[col.Column.toLowerCase()]) {
-                    col.Column = map[col.Column.toLowerCase()].FieldName
-                  }
-                  return col
-                })
-              }
-              if (m.config && m.config.components) {
-                m.config.components = _replace(m.config.components)
-              }
-            })
-          }
-
-          if (item.subcards) {
-            item.subcards.forEach(card => {
-              if (card.elements) { // 鍗$墖
-                card.elements = card.elements.map(m => {
-                  if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
-                    m.field = map[m.field.toLowerCase()].FieldName
-                  }
-                  if (m.modal && m.modal.fields) {
-                    m.modal.fields = m.modal.fields.map(col => {
-                      if (col.field && map[col.field.toLowerCase()]) {
-                        col.field = map[col.field.toLowerCase()].FieldName
-                      }
-                      return col
-                    })
-                  }
-                  if (m.verify && m.verify.columns) {
-                    m.verify.columns = m.verify.columns.map(col => {
-                      if (col.Column && map[col.Column.toLowerCase()]) {
-                        col.Column = map[col.Column.toLowerCase()].FieldName
-                      }
-                      return col
-                    })
-                  }
-                  if (m.config && m.config.components) {
-                    m.config.components = _replace(m.config.components)
-                  }
-                  return m
-                })
-              }
-
-              if (card.backElements) { // 鍗$墖
-                card.backElements = card.backElements.map(m => {
-                  if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
-                    m.field = map[m.field.toLowerCase()].FieldName
-                  }
-                  if (m.modal && m.modal.fields) {
-                    m.modal.fields = m.modal.fields.map(col => {
-                      if (col.field && map[col.field.toLowerCase()]) {
-                        col.field = map[col.field.toLowerCase()].FieldName
-                      }
-                      return col
-                    })
-                  }
-                  if (m.verify && m.verify.columns) {
-                    m.verify.columns = m.verify.columns.map(col => {
-                      if (col.Column && map[col.Column.toLowerCase()]) {
-                        col.Column = map[col.Column.toLowerCase()].FieldName
-                      }
-                      return col
-                    })
-                  }
-                  if (m.config && m.config.components) {
-                    m.config.components = _replace(m.config.components)
-                  }
-                  return m
-                })
-              }
-
-              if (card.fields) { // 琛ㄥ崟
-                card.fields = card.fields.map(m => {
-                  if (m.field && map[m.field.toLowerCase()]) {
-                    m.field = map[m.field.toLowerCase()].FieldName
-                  }
-                  return m
-                })
-              }
-            })
-          }
-
-          if (item.elements) {
-            item.elements = item.elements.map(m => {
-              if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
-                m.field = map[m.field.toLowerCase()].FieldName
-              }
-              if (m.modal && m.modal.fields) {
-                m.modal.fields = m.modal.fields.map(col => {
-                  if (col.field && map[col.field.toLowerCase()]) {
-                    col.field = map[col.field.toLowerCase()].FieldName
-                  }
-                  return col
-                })
-              }
-              if (m.verify && m.verify.columns) {
-                m.verify.columns = m.verify.columns.map(col => {
-                  if (col.Column && map[col.Column.toLowerCase()]) {
-                    col.Column = map[col.Column.toLowerCase()].FieldName
-                  }
-                  return col
-                })
-              }
-              if (m.config && m.config.components) {
-                m.config.components = _replace(m.config.components)
-              }
-              return m
-            })
-          }
-
-          if (item.plot) {
-            if (item.plot.Xaxis && map[item.plot.Xaxis.toLowerCase()]) {
-              item.plot.Xaxis = map[item.plot.Xaxis.toLowerCase()].FieldName
-            }
-            // 缁熻鍥�
-            if (item.plot.InfoValue && map[item.plot.InfoValue.toLowerCase()]) {
-              item.plot.InfoValue = map[item.plot.InfoValue.toLowerCase()].FieldName
-            }
-            if (item.plot.InfoType && map[item.plot.InfoType.toLowerCase()]) {
-              item.plot.InfoType = map[item.plot.InfoType.toLowerCase()].FieldName
-            }
-            // 鍗犳瘮鍥�
-            if (item.plot.valueField && map[item.plot.valueField.toLowerCase()]) {
-              item.plot.valueField = map[item.plot.valueField.toLowerCase()].FieldName
-            }
-            if (item.plot.labelField && map[item.plot.labelField.toLowerCase()]) {
-              item.plot.labelField = map[item.plot.labelField.toLowerCase()].FieldName
-            }
-            // 楗煎浘
-            if (item.plot.type && map[item.plot.type.toLowerCase()]) {
-              item.plot.type = map[item.plot.type.toLowerCase()].FieldName
-            }
-            // 鏁g偣鍥�
-            if (item.plot.gender && map[item.plot.gender.toLowerCase()]) {
-              item.plot.gender = map[item.plot.gender.toLowerCase()].FieldName
-            }
-            if (item.Yaxis) {
-              if (Array.isArray(item.Yaxis)) {
-                item.Yaxis = item.Yaxis.map(m => {
-                  if (map[m.toLowerCase()]) {
-                    return map[m.toLowerCase()].FieldName
-                  }
-                  return m
-                })
-              } else {
-                if (item.Yaxis && map[item.Yaxis.toLowerCase()]) {
-                  item.Yaxis = map[item.Yaxis.toLowerCase()].FieldName
-                }
-              }
-            }
-          }
-
-          if (item.cols) {
-            let _update = (cols) => {
-              return cols.map(col => {
-                if (col.type === 'custom' && col.elements) {
-                  col.elements = col.elements.map(m => {
-                    if (m.eleType === 'button') {
-                      if (m.modal && m.modal.fields) {
-                        m.modal.fields = m.modal.fields.map(col => {
-                          if (col.field && map[col.field.toLowerCase()]) {
-                            col.field = map[col.field.toLowerCase()].FieldName
-                          }
-                          return col
-                        })
-                      }
-                      if (m.verify && m.verify.columns) {
-                        m.verify.columns = m.verify.columns.map(col => {
-                          if (col.Column && map[col.Column.toLowerCase()]) {
-                            col.Column = map[col.Column.toLowerCase()].FieldName
-                          }
-                          return col
-                        })
-                      }
-                      if (m.config && m.config.components) {
-                        m.config.components = _replace(m.config.components)
-                      }
-                    } else {
-                      if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
-                        m.field = map[m.field.toLowerCase()].FieldName
-                      }
-                    }
-
-                    return m
-                  })
-                } else if (col.type === 'colspan') {
-                  col.subcols = _update(col.subcols)
-                } else if (col.field) {
-                  if (map[col.field.toLowerCase()]) {
-                    col.field = map[col.field.toLowerCase()].FieldName
-                  }
-                }
-                
                 return col
               })
             }
+            if (m.verify && m.verify.columns) {
+              m.verify.columns = m.verify.columns.map(col => {
+                if (col.Column && map[col.Column.toLowerCase()]) {
+                  col.Column = map[col.Column.toLowerCase()].FieldName
+                }
+                return col
+              })
+            }
+            if (m.config && m.config.components) {
+              m.config.components = _replace(m.config.components)
+            }
+          })
+        }
 
-            item.cols = _update(item.cols)
+        if (item.subcards) {
+          item.subcards.forEach(card => {
+            if (card.elements) { // 鍗$墖
+              card.elements = card.elements.map(m => {
+                if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
+                  m.field = map[m.field.toLowerCase()].FieldName
+                }
+                if (m.modal && m.modal.fields) {
+                  m.modal.fields = m.modal.fields.map(col => {
+                    if (col.field && map[col.field.toLowerCase()]) {
+                      col.field = map[col.field.toLowerCase()].FieldName
+                    }
+                    return col
+                  })
+                }
+                if (m.verify && m.verify.columns) {
+                  m.verify.columns = m.verify.columns.map(col => {
+                    if (col.Column && map[col.Column.toLowerCase()]) {
+                      col.Column = map[col.Column.toLowerCase()].FieldName
+                    }
+                    return col
+                  })
+                }
+                if (m.config && m.config.components) {
+                  m.config.components = _replace(m.config.components)
+                }
+                return m
+              })
+            }
+
+            if (card.backElements) { // 鍗$墖
+              card.backElements = card.backElements.map(m => {
+                if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
+                  m.field = map[m.field.toLowerCase()].FieldName
+                }
+                if (m.modal && m.modal.fields) {
+                  m.modal.fields = m.modal.fields.map(col => {
+                    if (col.field && map[col.field.toLowerCase()]) {
+                      col.field = map[col.field.toLowerCase()].FieldName
+                    }
+                    return col
+                  })
+                }
+                if (m.verify && m.verify.columns) {
+                  m.verify.columns = m.verify.columns.map(col => {
+                    if (col.Column && map[col.Column.toLowerCase()]) {
+                      col.Column = map[col.Column.toLowerCase()].FieldName
+                    }
+                    return col
+                  })
+                }
+                if (m.config && m.config.components) {
+                  m.config.components = _replace(m.config.components)
+                }
+                return m
+              })
+            }
+
+            if (card.fields) { // 琛ㄥ崟
+              card.fields = card.fields.map(m => {
+                if (m.field && map[m.field.toLowerCase()]) {
+                  m.field = map[m.field.toLowerCase()].FieldName
+                }
+                return m
+              })
+            }
+          })
+        }
+
+        if (item.elements) {
+          item.elements = item.elements.map(m => {
+            if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
+              m.field = map[m.field.toLowerCase()].FieldName
+            }
+            if (m.modal && m.modal.fields) {
+              m.modal.fields = m.modal.fields.map(col => {
+                if (col.field && map[col.field.toLowerCase()]) {
+                  col.field = map[col.field.toLowerCase()].FieldName
+                }
+                return col
+              })
+            }
+            if (m.verify && m.verify.columns) {
+              m.verify.columns = m.verify.columns.map(col => {
+                if (col.Column && map[col.Column.toLowerCase()]) {
+                  col.Column = map[col.Column.toLowerCase()].FieldName
+                }
+                return col
+              })
+            }
+            if (m.config && m.config.components) {
+              m.config.components = _replace(m.config.components)
+            }
+            return m
+          })
+        }
+
+        if (item.plot) {
+          if (item.plot.Xaxis && map[item.plot.Xaxis.toLowerCase()]) {
+            item.plot.Xaxis = map[item.plot.Xaxis.toLowerCase()].FieldName
           }
-
-          if (item.subtype === 'basetable') {
-            item.cols = item.cols.map(col => {
-              if (col.field && map[col.field.toLowerCase()]) {
-                col.field = map[col.field.toLowerCase()].FieldName
+          // 缁熻鍥�
+          if (item.plot.InfoValue && map[item.plot.InfoValue.toLowerCase()]) {
+            item.plot.InfoValue = map[item.plot.InfoValue.toLowerCase()].FieldName
+          }
+          if (item.plot.InfoType && map[item.plot.InfoType.toLowerCase()]) {
+            item.plot.InfoType = map[item.plot.InfoType.toLowerCase()].FieldName
+          }
+          // 鍗犳瘮鍥�
+          if (item.plot.valueField && map[item.plot.valueField.toLowerCase()]) {
+            item.plot.valueField = map[item.plot.valueField.toLowerCase()].FieldName
+          }
+          if (item.plot.labelField && map[item.plot.labelField.toLowerCase()]) {
+            item.plot.labelField = map[item.plot.labelField.toLowerCase()].FieldName
+          }
+          // 楗煎浘
+          if (item.plot.type && map[item.plot.type.toLowerCase()]) {
+            item.plot.type = map[item.plot.type.toLowerCase()].FieldName
+          }
+          // 鏁g偣鍥�
+          if (item.plot.gender && map[item.plot.gender.toLowerCase()]) {
+            item.plot.gender = map[item.plot.gender.toLowerCase()].FieldName
+          }
+          if (item.Yaxis) {
+            if (Array.isArray(item.Yaxis)) {
+              item.Yaxis = item.Yaxis.map(m => {
+                if (map[m.toLowerCase()]) {
+                  return map[m.toLowerCase()].FieldName
+                }
+                return m
+              })
+            } else {
+              if (item.Yaxis && map[item.Yaxis.toLowerCase()]) {
+                item.Yaxis = map[item.Yaxis.toLowerCase()].FieldName
               }
+            }
+          }
+        }
+
+        if (item.cols) {
+          let _update = (cols) => {
+            return cols.map(col => {
+              if (col.type === 'custom' && col.elements) {
+                col.elements = col.elements.map(m => {
+                  if (m.eleType === 'button') {
+                    if (m.modal && m.modal.fields) {
+                      m.modal.fields = m.modal.fields.map(col => {
+                        if (col.field && map[col.field.toLowerCase()]) {
+                          col.field = map[col.field.toLowerCase()].FieldName
+                        }
+                        return col
+                      })
+                    }
+                    if (m.verify && m.verify.columns) {
+                      m.verify.columns = m.verify.columns.map(col => {
+                        if (col.Column && map[col.Column.toLowerCase()]) {
+                          col.Column = map[col.Column.toLowerCase()].FieldName
+                        }
+                        return col
+                      })
+                    }
+                    if (m.config && m.config.components) {
+                      m.config.components = _replace(m.config.components)
+                    }
+                  } else {
+                    if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
+                      m.field = map[m.field.toLowerCase()].FieldName
+                    }
+                  }
+
+                  return m
+                })
+              } else if (col.type === 'colspan') {
+                col.subcols = _update(col.subcols)
+              } else if (col.field) {
+                if (map[col.field.toLowerCase()]) {
+                  col.field = map[col.field.toLowerCase()].FieldName
+                }
+              }
+              
               return col
             })
           }
 
-          return item
-        })
-      }
-
-      config.components = _replace(config.components)
-    // } else if (type === 'table') {
-    //   config.columns = config.columns.map(col => {
-    //     if (col.field && map[col.field.toLowerCase()]) {
-    //       col.field = map[col.field.toLowerCase()].FieldName
-    //     }
-    //     return col
-    //   })
-
-    //   config.search = config.search.map(col => {
-    //     if (col.field && map[col.field.toLowerCase()]) {
-    //       col.field = map[col.field.toLowerCase()].FieldName
-    //     }
-    //     if (col.datefield && map[col.datefield.toLowerCase()]) {
-    //       col.datefield = map[col.datefield.toLowerCase()].FieldName
-    //     }
-    //     return col
-    //   })
-
-    //   config.action = config.action.map(m => {
-    //     if (m.verify && m.verify.columns) {
-    //       m.verify.columns = m.verify.columns.map(col => {
-    //         if (col.Column && map[col.Column.toLowerCase()]) {
-    //           col.Column = map[col.Column.toLowerCase()].FieldName
-    //         }
-    //         return col
-    //       })
-    //     }
-    //     return m
-    //   })
-    } else if (type === 'form') {
-      config.fields = config.fields.map(col => {
-        if (col.field && map[col.field.toLowerCase()]) {
-          col.field = map[col.field.toLowerCase()].FieldName
+          item.cols = _update(item.cols)
         }
-        return col
+
+        if (item.subtype === 'basetable') {
+          item.cols = item.cols.map(col => {
+            if (col.field && map[col.field.toLowerCase()]) {
+              col.field = map[col.field.toLowerCase()].FieldName
+            }
+            return col
+          })
+        }
+
+        return item
       })
     }
+
+    config.components = _replace(config.components)
+
+    config.interfaces && config.interfaces.forEach(item => {
+      if (item.columns) {
+        item.columns = item.columns.map(col => {
+          let cell = map[col.field.toLowerCase()]
+          if (cell) {
+            col.field = cell.FieldName
+            if (cell.datatype) {
+              col.datatype = cell.datatype
+            }
+          }
+          return col
+        })
+      }
+    })
 
     this.setState({
       confirming: false,
@@ -470,156 +445,131 @@
 
   // 渚濇嵁瀛楁鏇挎崲鍚嶇О
   execLabel = (map) => {
-    const { type } = this.props
     let config = fromJS(this.props.config).toJS()
 
-    if (type === 'custom') {
-      let _replace = (components) => {
-        return components.map(item => {
-          if (item.type === 'tabs') {
-            item.subtabs.forEach(tab => {
-              tab.components = _replace(tab.components)
-            })
-            return item
-          } else if (item.type === 'group') {
-            item.components = _replace(item.components)
-            return item
-          }
-          
-          if (item.columns) {
-            item.columns = item.columns.map(col => {
-              if (col.field && map[col.field.toLowerCase()]) {
-                col.label = map[col.field.toLowerCase()].FieldDec
-              }
-              return col
-            })
-          }
-          if (item.search) {
-            item.search = item.search.map(col => {
-              if (col.field && map[col.field.toLowerCase()]) {
-                col.label = map[col.field.toLowerCase()].FieldDec
-              }
-              return col
-            })
-          }
+    let _replace = (components) => {
+      return components.map(item => {
+        if (item.type === 'tabs') {
+          item.subtabs.forEach(tab => {
+            tab.components = _replace(tab.components)
+          })
+          return item
+        } else if (item.type === 'group') {
+          item.components = _replace(item.components)
+          return item
+        }
+        
+        if (item.columns) {
+          item.columns = item.columns.map(col => {
+            if (col.field && map[col.field.toLowerCase()]) {
+              col.label = map[col.field.toLowerCase()].FieldDec
+            }
+            return col
+          })
+        }
+        if (item.search) {
+          item.search = item.search.map(col => {
+            if (col.field && map[col.field.toLowerCase()]) {
+              col.label = map[col.field.toLowerCase()].FieldDec
+            }
+            return col
+          })
+        }
 
-          if (item.action) {
-            item.action.forEach(m => {
-              if (m.modal && m.modal.fields) {
-                m.modal.fields = m.modal.fields.map(col => {
-                  if (col.field && map[col.field.toLowerCase()]) {
-                    col.label = map[col.field.toLowerCase()].FieldDec
-                  }
-                  return col
-                })
-              }
-              if (m.verify && m.verify.columns) {
-                m.verify.columns = m.verify.columns.map(col => {
-                  if (col.Column && map[col.Column.toLowerCase()]) {
-                    col.Text = map[col.Column.toLowerCase()].FieldDec
-                  }
-                  return col
-                })
-              }
-              if (m.config && m.config.components) {
-                m.config.components = _replace(m.config.components)
-              }
-            })
-          }
-
-          if (item.cols) {
-            let _update = (cols) => {
-              return cols.map(col => {
-                if (col.type === 'custom' && col.elements) {
-                  col.elements = col.elements.map(m => {
-                    if (m.eleType === 'button') {
-                      if (m.modal && m.modal.fields) {
-                        m.modal.fields = m.modal.fields.map(col => {
-                          if (col.field && map[col.field.toLowerCase()]) {
-                            col.label = map[col.field.toLowerCase()].FieldDec
-                          }
-                          return col
-                        })
-                      }
-                      if (m.verify && m.verify.columns) {
-                        m.verify.columns = m.verify.columns.map(col => {
-                          if (col.Column && map[col.Column.toLowerCase()]) {
-                            col.Text = map[col.Column.toLowerCase()].FieldDec
-                          }
-                          return col
-                        })
-                      }
-                      if (m.config && m.config.components) {
-                        m.config.components = _replace(m.config.components)
-                      }
-                    }
-
-                    return m
-                  })
-                } else if (col.type === 'colspan') {
-                  col.subcols = _update(col.subcols)
-                } else if (col.field) {
-                  if (map[col.field.toLowerCase()]) {
-                    col.label = map[col.field.toLowerCase()].FieldDec
-                  }
+        if (item.action) {
+          item.action.forEach(m => {
+            if (m.modal && m.modal.fields) {
+              m.modal.fields = m.modal.fields.map(col => {
+                if (col.field && map[col.field.toLowerCase()]) {
+                  col.label = map[col.field.toLowerCase()].FieldDec
                 }
-                
                 return col
               })
             }
+            if (m.verify && m.verify.columns) {
+              m.verify.columns = m.verify.columns.map(col => {
+                if (col.Column && map[col.Column.toLowerCase()]) {
+                  col.Text = map[col.Column.toLowerCase()].FieldDec
+                }
+                return col
+              })
+            }
+            if (m.config && m.config.components) {
+              m.config.components = _replace(m.config.components)
+            }
+          })
+        }
 
-            item.cols = _update(item.cols)
-          }
+        if (item.cols) {
+          let _update = (cols) => {
+            return cols.map(col => {
+              if (col.type === 'custom' && col.elements) {
+                col.elements = col.elements.map(m => {
+                  if (m.eleType === 'button') {
+                    if (m.modal && m.modal.fields) {
+                      m.modal.fields = m.modal.fields.map(col => {
+                        if (col.field && map[col.field.toLowerCase()]) {
+                          col.label = map[col.field.toLowerCase()].FieldDec
+                        }
+                        return col
+                      })
+                    }
+                    if (m.verify && m.verify.columns) {
+                      m.verify.columns = m.verify.columns.map(col => {
+                        if (col.Column && map[col.Column.toLowerCase()]) {
+                          col.Text = map[col.Column.toLowerCase()].FieldDec
+                        }
+                        return col
+                      })
+                    }
+                    if (m.config && m.config.components) {
+                      m.config.components = _replace(m.config.components)
+                    }
+                  }
 
-          if (item.subtype === 'basetable') {
-            item.cols = item.cols.map(col => {
-              if (col.field && map[col.field.toLowerCase()]) {
-                col.label = map[col.field.toLowerCase()].FieldDec
+                  return m
+                })
+              } else if (col.type === 'colspan') {
+                col.subcols = _update(col.subcols)
+              } else if (col.field) {
+                if (map[col.field.toLowerCase()]) {
+                  col.label = map[col.field.toLowerCase()].FieldDec
+                }
               }
+              
               return col
             })
           }
 
-          return item
-        })
-      }
-
-      config.components = _replace(config.components)
-    // } else if (type === 'table') {
-    //   config.columns = config.columns.map(col => {
-    //     if (col.field && map[col.field.toLowerCase()]) {
-    //       col.label = map[col.field.toLowerCase()].FieldDec
-    //     }
-    //     return col
-    //   })
-      
-    //   config.search = config.search.map(col => {
-    //     if (col.field && map[col.field.toLowerCase()]) {
-    //       col.label = map[col.field.toLowerCase()].FieldDec
-    //     }
-    //     return col
-    //   })
-
-    //   config.action = config.action.map(m => {
-    //     if (m.verify && m.verify.columns) {
-    //       m.verify.columns = m.verify.columns.map(col => {
-    //         if (col.Column && map[col.Column.toLowerCase()]) {
-    //           col.Text = map[col.Column.toLowerCase()].FieldDec
-    //         }
-    //         return col
-    //       })
-    //     }
-    //     return m
-    //   })
-    } else if (type === 'form') {
-      config.fields = config.fields.map(col => {
-        if (col.field && map[col.field.toLowerCase()]) {
-          col.label = map[col.field.toLowerCase()].FieldDec
+          item.cols = _update(item.cols)
         }
-        return col
+
+        if (item.subtype === 'basetable') {
+          item.cols = item.cols.map(col => {
+            if (col.field && map[col.field.toLowerCase()]) {
+              col.label = map[col.field.toLowerCase()].FieldDec
+            }
+            return col
+          })
+        }
+
+        return item
       })
     }
 
+    config.components = _replace(config.components)
+
+    config.interfaces && config.interfaces.forEach(item => {
+      if (item.columns) {
+        item.columns = item.columns.map(col => {
+          if (col.field && map[col.field.toLowerCase()]) {
+            col.label = map[col.field.toLowerCase()].FieldDec
+          }
+          return col
+        })
+      }
+    })
+
     this.setState({
       confirming: false,
       visible: false
diff --git a/src/menu/stylecombcontrolbutton/index.scss b/src/menu/stylecombcontrolbutton/index.scss
index d6b8667..615c42e 100644
--- a/src/menu/stylecombcontrolbutton/index.scss
+++ b/src/menu/stylecombcontrolbutton/index.scss
@@ -7,7 +7,7 @@
   background: #ffffff;
 }
 body.style-control {
-  .pc-menu-view::before, .menu-control::before  {
+  .menu-setting::before, .mk-opeartion-list::before  {
     content: ' ';
     position: absolute;
     left: 0;
@@ -17,26 +17,20 @@
     z-index: 12;
     background:rgba(0, 0, 0, 0.2);
   }
-  .pc-poper-view::before {
-    content: ' ';
-    position: absolute;
-    left: 0;
-    top: 0;
-    bottom: 0;
-    right: 0;
-    z-index: 12;
-    background:rgba(0, 0, 0, 0.2);
+  .menu-setting .draw, .menu-control .draw {
+    display: none;
   }
-  .menu-body .menu-view >.ant-card >.ant-card-body {
-    position: relative;
-    z-index: 13;
-    background:#ffffff;
+  .style-control-button {
+    z-index: 12;
   }
   .menu-view {
     .anticon-tool {
       display: none;
     }
   }
+  .mk-pc-view .menu-setting {
+    display: none;
+  }
   .mk-mob-view .mob-shell {
     .anticon-tool {
       display: none;
diff --git a/src/mob/components/formdragelement/index.jsx b/src/mob/components/formdragelement/index.jsx
index e28f1f9..63cccb9 100644
--- a/src/mob/components/formdragelement/index.jsx
+++ b/src/mob/components/formdragelement/index.jsx
@@ -1,7 +1,7 @@
 import React, { useState } from 'react'
 import { useDrop } from 'react-dnd'
 import { is, fromJS } from 'immutable'
-import { Col } from 'antd'
+import { Col, message } from 'antd'
 import update from 'immutability-helper'
 import Utils from '@/utils/utils.js'
 import Card from './card'
@@ -72,11 +72,15 @@
     oInput.style.display = 'none'
     document.body.removeChild(oInput)
 
-    const _cards = update(cards, { $splice: [[overIndex + 1, 0, _card]] })
+    if (window.GLOB.CopyOnly) {
+      message.success('澶嶅埗鎴愬姛銆�')
+    } else {
+      const _cards = update(cards, { $splice: [[overIndex + 1, 0, _card]] })
 
-    setCards(_cards)
+      setCards(_cards)
 
-    handleList(_cards, _card)
+      handleList(_cards, _card)
+    }
   }
 
   const [, drop] = useDrop({
@@ -94,10 +98,14 @@
       newcard.options = []
       newcard.readonly = 'false'
       newcard.required = 'true'
+      newcard.readin = 'top'
       newcard.span = 24
       newcard.focus = true
 
-      if (item.subType === 'textarea') {
+      if (item.subType === 'linkMain') {
+        newcard.hidden = 'true'
+        newcard.verifyVal = 'true'
+      } else if (item.subType === 'textarea') {
         newcard.required = 'false'
       }
 
diff --git a/src/mob/modalconfig/index.jsx b/src/mob/modalconfig/index.jsx
index 0f75a32..7cbc35d 100644
--- a/src/mob/modalconfig/index.jsx
+++ b/src/mob/modalconfig/index.jsx
@@ -18,6 +18,7 @@
 const { confirm } = Modal
 const TableComponent = asyncComponent(() => import('@/menu/modalconfig/tablecomponent'))
 const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
+const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
 const PasteForms = asyncComponent(() => import('@/menu/components/share/pasteforms'))
 const DragElement = asyncComponent(() => import('@/mob/components/formdragelement'))
 const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
@@ -339,6 +340,7 @@
             <Collapse accordion defaultActiveKey="1" bordered={false}>
               <Panel header="鍩烘湰淇℃伅" key="0">
                 <TableComponent />
+                <NormalCopy/>
               </Panel>
               <Panel header="琛ㄥ崟" key="1">
                 <div className="search-element">
diff --git a/src/pc/components/login/normal-login/options.jsx b/src/pc/components/login/normal-login/options.jsx
index 76b6eda..80628c0 100644
--- a/src/pc/components/login/normal-login/options.jsx
+++ b/src/pc/components/login/normal-login/options.jsx
@@ -264,7 +264,6 @@
           dataIndex: 'link',
           inputType: 'input',
           editable: true,
-          unique: true,
           required: true,
           width: '40%'
         },
diff --git a/src/tabviews/basetable/index.jsx b/src/tabviews/basetable/index.jsx
index a53fbef..32a42d2 100644
--- a/src/tabviews/basetable/index.jsx
+++ b/src/tabviews/basetable/index.jsx
@@ -39,7 +39,8 @@
     userConfig: null,     // 鐢ㄦ埛鑷畾涔夎缃�
     visible: false,       // 鏍囩椤垫帶鍒�
     shortcuts: null,      // 蹇嵎閿�
-    autoMatic: null
+    autoMatic: null,
+    noParam: false
   }
 
   /**
@@ -47,6 +48,7 @@
    */
   async loadconfig () {
     const { MenuID, MenuName, param } = this.props
+    const { noParam } = this.state
 
     let _param = {
       func: 'sPC_Get_LongParam',
@@ -164,13 +166,17 @@
       let skip = window.GLOB.mkHS
       let urlparam = {} // url鍙傛暟
       if (param) {
-        Object.keys(param).forEach(key => {
-          if (/^\$/.test(key)) {
-            urlparam[key] = param[key]
-          } else {
-            urlparam[key.toLowerCase()] = param[key]
-          }
-        })
+        if (!noParam) {
+          Object.keys(param).forEach(key => {
+            if (/^\$/.test(key)) {
+              urlparam[key] = param[key]
+            } else {
+              urlparam[key.toLowerCase()] = param[key]
+            }
+          })
+        } else {
+          urlparam.$BID = param.$BID
+        }
       }
 
       window.GLOB.CacheData.set(MenuID, urlparam)
@@ -712,12 +718,12 @@
     })
   }
 
-  reloadMenuView = (menuId) => {
+  reloadMenuView = (menuId, clear) => {
     const { MenuID } = this.props
 
     if (MenuID !== menuId) return
 
-    this.reloadview()
+    this.reloadview(clear)
   }
 
   resetActiveMenu = (menuId) => {
@@ -779,7 +785,7 @@
     })
   }
 
-  reloadview = () => {
+  reloadview = (clear) => {
     window.GLOB.CacheData.delete(this.props.MenuID)
     if (this.state.config) {
       this.deleteCache(this.state.config.components)
@@ -791,6 +797,7 @@
       viewlost: false,      // 椤甸潰涓㈠け锛�1銆佹湭鑾峰彇鍒伴厤缃�-椤甸潰涓㈠け锛�2銆侀〉闈㈡湭鍚敤
       config: null,         // 椤甸潰閰嶇疆淇℃伅锛屽寘鎷粍浠剁瓑
       shortcuts: null,
+      noParam: clear === true
     }, () => {
       this.loadconfig()
     })
diff --git a/src/tabviews/custom/components/card/cardcellList/index.jsx b/src/tabviews/custom/components/card/cardcellList/index.jsx
index 9ebf5c9..a9140c0 100644
--- a/src/tabviews/custom/components/card/cardcellList/index.jsx
+++ b/src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -224,7 +224,7 @@
       return
     }
     
-    if (/^http.+(.txt|.doc|.docx|.pdf|.xlsx|.xls|.zip|.rar|.ppt)$/i.test(url) || card.linkType === 'download') {
+    if (/^(http|\/\/).+(.txt|.doc|.docx|.pdf|.xlsx|.xls|.zip|.rar|.ppt)$/i.test(url) || card.linkType === 'download') {
       let name = ''
       if (card.datatype === 'static') {
         name = card.value || ''
@@ -450,7 +450,7 @@
               url = data[card.linkurl]
             }
   
-            if (/^http.+(.txt|.doc|.docx|.pdf|.xlsx|.xls|.zip|.rar)$/i.test(url)) {
+            if (/^(http|\/\/).+(.txt|.doc|.docx|.pdf|.xlsx|.xls|.zip|.rar)$/i.test(url)) {
               if (/pdf$/i.test(url)) {
                 val = <><img src="./media/pdf.png" className="file-image" alt=""/> {val}</>
               } else if (/(.doc|.docx)$/i.test(url)) {
diff --git a/src/tabviews/custom/components/editor/braft-editor/index.jsx b/src/tabviews/custom/components/editor/braft-editor/index.jsx
index 2c5ddd6..067b69f 100644
--- a/src/tabviews/custom/components/editor/braft-editor/index.jsx
+++ b/src/tabviews/custom/components/editor/braft-editor/index.jsx
@@ -73,7 +73,7 @@
     }
 
     this.setState({
-      data: _data,
+      data: this.decodeHtml(_data, _config.wrap),
       BID: BID || '',
       config: _config,
     })
@@ -130,7 +130,7 @@
 
     let _data = window.GLOB.SyncData.get(config.dataName) || []
 
-    this.setState({data: _data})
+    this.setState({data: this.decodeHtml(_data, config.wrap)})
 
     window.GLOB.SyncData.delete(config.dataName)
 
@@ -158,7 +158,7 @@
         _data = [_data]
       }
 
-      this.setState({data: _data})
+      this.setState({data: this.decodeHtml(_data, config.wrap)})
     }
   }
 
@@ -224,7 +224,7 @@
     let result = await Api.genericInterface(param)
     if (result.status) {
       this.setState({
-        data: result.data || [],
+        data: this.decodeHtml(result.data, config.wrap),
         loading: false
       })
       
@@ -236,6 +236,35 @@
       
       UtilsDM.queryFail(result)
     }
+  }
+
+  decodeHtml = (data, wrap) => {
+    if (!data || data.length === 0) return []
+
+    data.forEach(item => {
+      item.$html = item[wrap.field] || ''
+      if (item.$html) {
+        if (wrap.encryption === 'true') {
+          try {
+            item.$html = window.decodeURIComponent(window.atob(item.$html))
+          } catch (e) {
+            item.$html = item[wrap.field] || ''
+          }
+        }
+
+        delete item[wrap.field]
+
+        if (/\$[\s\S]+\$/.test(item.$html)) {
+          Object.keys(item).forEach(key => {
+            if (/^\$/.test(key)) return
+            let reg = new RegExp('\\$' + key + '\\$', 'ig')
+            item.$html = item.$html.replace(reg, item[key])
+          })
+        }
+      }
+    })
+
+    return data
   }
 
   render() {
@@ -254,11 +283,10 @@
         <NormalHeader config={config}/>
         {config.wrap.datatype === 'static' ? <BraftContent
           value={config.html}
-          encryption={'false'}
         /> : data.map((item, index) => <BraftContent
           key={index}
-          value={item[config.wrap.field] || ''}
-          encryption={config.wrap.encryption}
+          value={item.$html}
+          script={config.wrap.loaded === 'true' ? config.wrap.loadedfunc : ''}
         />)}
       </div>
     )
diff --git a/src/tabviews/custom/components/share/braftContent/index.jsx b/src/tabviews/custom/components/share/braftContent/index.jsx
index 527e61f..553249f 100644
--- a/src/tabviews/custom/components/share/braftContent/index.jsx
+++ b/src/tabviews/custom/components/share/braftContent/index.jsx
@@ -1,13 +1,12 @@
-import React, {Component} from 'react'
+import React, { Component } from 'react'
 import PropTypes from 'prop-types'
-import { is, fromJS } from 'immutable'
 
 import './index.scss'
 
 class BraftContent extends Component {
   static propTpyes = {
     value: PropTypes.any,       // 鍐呭
-    encryption: PropTypes.any,  // 鏄惁瑙g爜
+    script: PropTypes.any       // 鑷畾涔夎剼鏈�
   }
 
   state = {
@@ -15,34 +14,42 @@
   }
 
   UNSAFE_componentWillMount () {
-    const { encryption, value } = this.props
-    let html = value
-
-    if (encryption === 'true' && html) {
-      try {
-        html = window.decodeURIComponent(window.atob(html))
-      } catch (e) {
-        html = value
-      }
-    }
+    const { value } = this.props
     
-    this.setState({html})
+    this.setState({html: value})
+  }
+
+  componentDidMount() {
+    this.loadScript()
   }
 
   UNSAFE_componentWillReceiveProps(nextProps) {
-    if (!is(fromJS(this.props), fromJS(nextProps))) {
-      const { encryption, value } = nextProps
-      let html = value
+    if (this.props.value !== nextProps.value) {
+      this.setState({html: nextProps.value}, () => {
+        this.loadScript()
+      })
+    }
+  }
 
-      if (encryption === 'true' && html) {
-        try {
-          html = window.decodeURIComponent(window.atob(html))
-        } catch (e) {
-          html = value
-        }
+  loadScript = () => {
+    const { script } = this.props
+    const { html } = this.state
+
+    if (script && html) {
+      const that = this
+      let _html = ''
+      try {
+        // eslint-disable-next-line
+        let func = new Function('that', 'html', script)
+        _html = func(that, html)
+      } catch (e) {
+        _html = ''
+        console.warn(e)
       }
-      
-      this.setState({html})
+
+      if (_html) {
+        this.setState({html: _html})
+      }
     }
   }
 
diff --git a/src/tabviews/custom/components/share/braftContent/index.scss b/src/tabviews/custom/components/share/braftContent/index.scss
index bf6b2f9..5064a93 100644
--- a/src/tabviews/custom/components/share/braftContent/index.scss
+++ b/src/tabviews/custom/components/share/braftContent/index.scss
@@ -36,7 +36,7 @@
       background-color: #f0f0f0;
     }
     td, th {
-      padding: 5px 14px;
+      padding: 5px 10px;
       font-size: 16px;
       border: 1px solid #ddd;
     }
diff --git a/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx b/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
index 42d57c8..9f8e3df 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
@@ -2544,7 +2544,7 @@
         this.execError({})
       })
     } else if (submit.intertype === 'system') { // 绯荤粺瀛樺偍杩囩▼
-      let result = getEditTableSql(submit, data, forms)
+      let result = getEditTableSql(submit, data, forms, setting)
       let param = {}
 
       param.func = 'sPC_TableData_InUpDe'
@@ -2573,7 +2573,7 @@
         this.execError({})
       })
     } else if (submit.intertype === 'inner' && submit.innerFunc) { // 鑷畾涔夊瓨鍌ㄨ繃绋�
-      let result = getEditTableSql(submit, data, forms)
+      let result = getEditTableSql(submit, data, forms, setting)
       let param = {}
 
       param.func = submit.innerFunc
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index 7e1cae0..61a6a47 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -69,7 +69,8 @@
     loading: false,       // 鍒楄〃鏁版嵁鍔犺浇涓�
     visible: false,       // 鏍囩椤垫帶鍒�
     shortcuts: null,      // 蹇嵎閿�
-    loadinginter: false
+    loadinginter: false,
+    noParam: false
   }
 
   stepInter = null
@@ -79,6 +80,7 @@
    */
   async loadconfig () {
     const { MenuID, MenuName, param } = this.props
+    const { noParam } = this.state
 
     let _param = {
       func: 'sPC_Get_LongParam',
@@ -209,13 +211,17 @@
       let skip = config.permission === 'false' || window.GLOB.mkHS
       let urlparam = {} // url鍙傛暟
       if (param) {
-        Object.keys(param).forEach(key => {
-          if (/^\$/.test(key)) {
-            urlparam[key] = param[key]
-          } else {
-            urlparam[key.toLowerCase()] = param[key]
-          }
-        })
+        if (!noParam) {
+          Object.keys(param).forEach(key => {
+            if (/^\$/.test(key)) {
+              urlparam[key] = param[key]
+            } else {
+              urlparam[key.toLowerCase()] = param[key]
+            }
+          })
+        } else {
+          urlparam.$BID = param.$BID
+        }
       }
 
       window.GLOB.CacheData.set(MenuID, urlparam)
@@ -1481,12 +1487,12 @@
     })
   }
 
-  reloadMenuView = (menuId) => {
+  reloadMenuView = (menuId, clear) => {
     const { MenuID } = this.props
 
     if (MenuID !== menuId) return
 
-    this.reloadview()
+    this.reloadview(clear)
   }
 
   resetActiveMenu = (menuId) => {
@@ -1581,7 +1587,7 @@
     })
   }
 
-  reloadview = () => {
+  reloadview = (clear) => {
     window.GLOB.CacheData.delete(this.props.MenuID)
     
     if (this.state.config) {
@@ -1599,7 +1605,8 @@
       viewlost: false,      // 椤甸潰涓㈠け锛�1銆佹湭鑾峰彇鍒伴厤缃�-椤甸潰涓㈠け锛�2銆侀〉闈㈡湭鍚敤
       config: null,         // 椤甸潰閰嶇疆淇℃伅锛屽寘鎷粍浠剁瓑
       loading: false,       // 鍒楄〃鏁版嵁鍔犺浇涓�
-      shortcuts: null
+      shortcuts: null,
+      noParam: clear === true
     }, () => {
       this.loadconfig()
     })
diff --git a/src/tabviews/sysmessage/index.jsx b/src/tabviews/sysmessage/index.jsx
deleted file mode 100644
index b3124cc..0000000
--- a/src/tabviews/sysmessage/index.jsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import React, { Component } from 'react'
-// import { is, fromJS } from 'immutable'
-import { notification, Spin } from 'antd'
-// import { BankOutlined } from '@ant-design/icons'
-
-import Api from '@/api'
-import MKEmitter from '@/utils/events.js'
-import './index.scss'
-
-export default class SysMessage extends Component {
-  state = {
-    loading: true
-  }
-
-  getAppList = () => {
-    let param = {
-      func: 's_get_kei'
-    }
-
-    Api.getSystemConfig(param).then(result => {
-      if (result.status) {
-        let applist = result.data.map(item => {
-          item.sublist = item.data_detail || []
-          item.sublist = item.sublist.map(cell => {
-            cell.ID = cell.d_id
-            return cell
-          })
-
-          return item
-        })
-        let selectApp = applist[0] || null
-
-        this.setState({ applist, selectApp })
-      } else {
-        notification.warning({
-          top: 92,
-          message: result.message,
-          duration: 5
-        })
-      }
-    })
-  }
-
-
-  reloadMenuView = (menuId) => {
-    if (menuId !== 'message_page_id') return
-
-    this.getAppList()
-  }
-
-  UNSAFE_componentWillMount () {
-
-  }
-
-  componentDidMount () {
-    MKEmitter.addListener('reloadMenuView', this.reloadMenuView)
-  }
-
-  /**
-   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
-   */
-  componentWillUnmount () {
-    this.setState = () => {
-      return
-    }
-    MKEmitter.removeListener('reloadMenuView', this.reloadMenuView)
-  }
-
-  render() {
-    const { loading, } = this.state
-
-    return (
-      <div className="mk-sys-message">
-        {loading && <Spin />}
-      </div>
-    )
-  }
-}
\ No newline at end of file
diff --git a/src/tabviews/sysmessage/index.scss b/src/tabviews/sysmessage/index.scss
deleted file mode 100644
index faa3779..0000000
--- a/src/tabviews/sysmessage/index.scss
+++ /dev/null
@@ -1,12 +0,0 @@
-.mk-sys-message {
-  min-height: calc(100vh - 94px);
-  height: 100%;
-  position: relative;
-  padding: 15px;
-  
-  .ant-spin {
-    position: absolute;
-    top: calc(50vh - 100px);
-    left: calc(50vw - 12px);
-  }
-}
\ No newline at end of file
diff --git a/src/tabviews/zshare/actionList/changeuserbutton/index.jsx b/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
index 4886b6f..37bd567 100644
--- a/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
@@ -114,7 +114,7 @@
       MKEmitter.emit('closeTabView', MenuID || btn.$MenuID)
 
       if (btn.refreshTab && btn.refreshTab.length > 0) {
-        MKEmitter.emit('reloadMenuView', btn.refreshTab[btn.refreshTab.length - 1])
+        MKEmitter.emit('reloadMenuView', btn.refreshTab[btn.refreshTab.length - 1], btn.urlPar === 'true')
       }
       return
     }
diff --git a/src/tabviews/zshare/actionList/excelInbutton/index.jsx b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
index b932b2c..ff95a03 100644
--- a/src/tabviews/zshare/actionList/excelInbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -187,7 +187,7 @@
     }
 
     if (tabId && btn.$MenuID === tabId) { // 鍒锋柊褰撳墠鑿滃崟鏃讹紝鍋滄鍏朵粬鎿嶄綔
-      MKEmitter.emit('reloadMenuView', tabId)
+      MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
       return
     }
 
@@ -216,7 +216,7 @@
     }
 
     if (tabId) {
-      MKEmitter.emit('reloadMenuView', tabId)
+      MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
     }
 
     if (btn.switchTab && btn.switchTab.length > 0) {
@@ -278,7 +278,7 @@
         tabId = btn.refreshTab[btn.refreshTab.length - 1]
       }
       if (tabId && btn.$MenuID === tabId) { // 鍒锋柊褰撳墠鑿滃崟鏃讹紝鍋滄鍏朵粬鎿嶄綔
-        MKEmitter.emit('reloadMenuView', tabId, 'table')
+        MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
         return
       }
 
@@ -303,7 +303,7 @@
       }
 
       if (tabId) {
-        MKEmitter.emit('reloadMenuView', tabId)
+        MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
       }
     }
 
diff --git a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
index 36f6a61..ac49651 100644
--- a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
@@ -990,7 +990,7 @@
     }
 
     if (tabId && btn.$MenuID === tabId) { // 鍒锋柊褰撳墠鑿滃崟鏃讹紝鍋滄鍏朵粬鎿嶄綔
-      MKEmitter.emit('reloadMenuView', tabId)
+      MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
       return
     }
 
@@ -1019,7 +1019,7 @@
     }
 
     if (tabId) {
-      MKEmitter.emit('reloadMenuView', tabId)
+      MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
     }
     
     if (btn.switchTab && btn.switchTab.length > 0) {
@@ -1081,7 +1081,7 @@
         tabId = btn.refreshTab[btn.refreshTab.length - 1]
       }
       if (tabId && btn.$MenuID === tabId) { // 鍒锋柊褰撳墠鑿滃崟鏃讹紝鍋滄鍏朵粬鎿嶄綔
-        MKEmitter.emit('reloadMenuView', tabId)
+        MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
         return
       }
 
@@ -1106,7 +1106,7 @@
       }
 
       if (tabId) {
-        MKEmitter.emit('reloadMenuView', tabId)
+        MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
       }
     }
 
diff --git a/src/tabviews/zshare/actionList/normalbutton/index.jsx b/src/tabviews/zshare/actionList/normalbutton/index.jsx
index 9ddcf4e..279985e 100644
--- a/src/tabviews/zshare/actionList/normalbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -846,7 +846,7 @@
 
       let val = form.value
       if (form.type === 'number' || form.type === 'rate') {
-        if (isNaN(val)) {
+        if (isNaN(val) || val === '') {
           val = 0
         }
       } else if (['date', 'datemonth'].includes(form.type)) {
@@ -1322,7 +1322,7 @@
         let val = form.value
   
         if (form.type === 'number' || form.type === 'rate') {
-          if (isNaN(val)) {
+          if (isNaN(val) || val === '') {
             val = 0
           }
           _initFormfields.push(`@${_key}=${val}`)
@@ -1943,6 +1943,10 @@
         if (params.length === 0) {
           this.execSuccess(result)
           _resolve()
+        } else if (btn.execInterval) {
+          setTimeout(() => {
+            this.customLoopRequest(params, _resolve)
+          }, btn.execInterval)
         } else {
           this.customLoopRequest(params, _resolve)
         }
@@ -1980,6 +1984,10 @@
         if (params.length === 0) {
           this.execSuccess(result)
           _resolve()
+        } else if (btn.execInterval) {
+          setTimeout(() => {
+            this.customLoopRequest(params, _resolve)
+          }, btn.execInterval)
         } else {
           this.customLoopRequest(params, _resolve)
         }
@@ -2002,6 +2010,10 @@
         if (params.length === 0) {
           this.execSuccess(res)
           _resolve()
+        } else if (btn.execInterval) {
+          setTimeout(() => {
+            this.customLoopRequest(params, _resolve)
+          }, btn.execInterval)
         } else {
           this.customLoopRequest(params, _resolve)
         }
@@ -2349,6 +2361,10 @@
         if (params.length === 0) {
           this.execSuccess(res)
           _resolve()
+        } else if (btn.execInterval) {
+          setTimeout(() => {
+            this.innerLoopRequest(params, btn, _resolve)
+          }, btn.execInterval)
         } else {
           this.innerLoopRequest(params, btn, _resolve)
         }
@@ -2598,6 +2614,10 @@
         if (params.length === 0) {
           this.execSuccess(result)
           _resolve()
+        } else if (btn.execInterval) {
+          setTimeout(() => {
+            this.outerLoopRequest(params, _resolve)
+          }, btn.execInterval)
         } else {
           this.outerLoopRequest(params, _resolve)
         }
@@ -2642,6 +2662,10 @@
         if (params.length === 0) {
           this.execSuccess(result)
           _resolve()
+        } else if (btn.execInterval) {
+          setTimeout(() => {
+            this.outerLoopRequest(params, _resolve)
+          }, btn.execInterval)
         } else {
           this.outerLoopRequest(params, _resolve)
         }
@@ -2665,6 +2689,10 @@
         if (params.length === 0) {
           this.execSuccess(res)
           _resolve()
+        } else if (btn.execInterval) {
+          setTimeout(() => {
+            this.outerLoopRequest(params, _resolve)
+          }, btn.execInterval)
         } else {
           this.outerLoopRequest(params, _resolve)
         }
@@ -2881,7 +2909,7 @@
       res.message = res.message.replace(/\s*<<.*>>\s*/g, '')
       val = val ? val[0].replace(/<<|>>/g, '') : ''
 
-      if (/^http/.test(val)) {
+      if (/^(http|\/\/)/.test(val)) {
         let audio = document.createElement('audio')
         audio.src = val
         audio.play()
@@ -2981,7 +3009,7 @@
     }
 
     if (tabId && btn.$MenuID === tabId) { // 鍒锋柊褰撳墠鑿滃崟鏃讹紝鍋滄鍏朵粬鎿嶄綔
-      MKEmitter.emit('reloadMenuView', tabId)
+      MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
 
       if (menu) {
         MKEmitter.emit('modifyTabs', menu, true)
@@ -3027,7 +3055,7 @@
     }
 
     if (tabId) {
-      MKEmitter.emit('reloadMenuView', tabId)
+      MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
     }
     
     if (btn.switchTab && btn.switchTab.length > 0) {
@@ -3647,7 +3675,7 @@
       res.message = res.message.replace(/\s*<<.*>>\s*/g, '')
       val = val ? val[0].replace(/<<|>>/g, '') : ''
 
-      if (/^http/.test(val)) {
+      if (/^(http|\/\/)/.test(val)) {
         let audio = document.createElement('audio')
         audio.src = val
         audio.play()
@@ -3731,7 +3759,7 @@
         tabId = btn.refreshTab[btn.refreshTab.length - 1]
       }
       if (tabId && btn.$MenuID === tabId) { // 鍒锋柊褰撳墠鑿滃崟鏃讹紝鍋滄鍏朵粬鎿嶄綔
-        MKEmitter.emit('reloadMenuView', tabId)
+        MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
         return
       }
 
@@ -3763,7 +3791,7 @@
       }
 
       if (tabId) {
-        MKEmitter.emit('reloadMenuView', tabId)
+        MKEmitter.emit('reloadMenuView', tabId, btn.urlPar === 'true')
       }
     }
 
@@ -3986,6 +4014,10 @@
       let key = item.field.toLowerCase()
       let _readin = item.readin !== 'false'
 
+      if (item.type === 'linkMain' && item.verifyVal === 'true') {
+        _item.$verify = true
+        _item.label = item.label
+      }
       if (_item.type === 'date') { // 鏃堕棿鍏煎
         _item.precision = item.precision || 'day'
       } else if (_item.type === 'datetime') {
@@ -4117,13 +4149,14 @@
    */
   getModels = () => {
     const { BID, btn, BData } = this.props
-    const { btnconfig, visible, dict, confirmLoading, submitType } = this.state
+    const { btnconfig, visible, dict, confirmLoading, submitType, loadingNumber, loadingTotal } = this.state
 
     if (!btnconfig || !btnconfig.setting) return null
 
     let title = btn.label
     let width = btnconfig.setting.width > 100 ? btnconfig.setting.width : btnconfig.setting.width + 'vw'
     let clickouter = btnconfig.setting.clickouter === 'close'
+    let num = loadingNumber && !loadingTotal ? `(${loadingNumber}) ` : ''
 
     if (btnconfig.setting.display === 'drawer') {
       let height = '100vh'
@@ -4192,9 +4225,9 @@
           onCancel={this.handleCancel}
           footer={[
             <Button key="cancel" onClick={this.handleCancel}>{dict['cancel'] || '鍙栨秷'}</Button>,
-            btn.extBtn === 'true' ? <Button key="extend" className={'extend-btn ' + (btn.extStyle || '')} disabled={confirmLoading && submitType !== btn.extValue} loading={confirmLoading && submitType === btn.extValue} onClick={() => this.handleOk(btn.extValue)}>{btn.extLabel}</Button> : null,
-            btn.extBtn === 'true' ? <Button key="confirm" className={'confirm-btn ' + (btn.confStyle || '')} disabled={confirmLoading && submitType !== ''} loading={confirmLoading && submitType === ''} onClick={() => this.handleOk()}>{btn.confLabel || dict['ok'] || '纭畾'}</Button> : null,
-            btn.extBtn !== 'true' ? <Button key="confirm" type="primary" loading={confirmLoading} onClick={() => this.handleOk()}>{dict['ok'] || '纭畾'}</Button> : null
+            btn.extBtn === 'true' ? <Button key="extend" className={'extend-btn ' + (btn.extStyle || '')} disabled={confirmLoading && submitType !== btn.extValue} loading={confirmLoading && submitType === btn.extValue} onClick={() => this.handleOk(btn.extValue)}>{submitType === btn.extValue ? num : ''}{btn.extLabel}</Button> : null,
+            btn.extBtn === 'true' ? <Button key="confirm" className={'confirm-btn ' + (btn.confStyle || '')} disabled={confirmLoading && submitType !== ''} loading={confirmLoading && submitType === ''} onClick={() => this.handleOk()}>{submitType === '' ? num : ''}{btn.confLabel || dict['ok'] || '纭畾'}</Button> : null,
+            btn.extBtn !== 'true' ? <Button key="confirm" type="primary" loading={confirmLoading} onClick={() => this.handleOk()}>{num}{dict['ok'] || '纭畾'}</Button> : null
           ]}
           destroyOnClose
         >
diff --git a/src/tabviews/zshare/actionList/printbutton/index.jsx b/src/tabviews/zshare/actionList/printbutton/index.jsx
index b0e6202..2414f0c 100644
--- a/src/tabviews/zshare/actionList/printbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -1008,7 +1008,7 @@
 
         let val = form.value
         if (form.type === 'number' || form.type === 'rate') {
-          if (isNaN(val)) {
+          if (isNaN(val) || val === '') {
             val = 0
           }
         } else if (['date', 'datemonth'].includes(form.type)) {
@@ -1142,7 +1142,7 @@
 
       if (form.type === 'number' || form.type === 'rate') {
         let val = form.value
-        if (isNaN(val)) {
+        if (isNaN(val) || val === '') {
           val = 0
         }
         _initvars.push(`@${_key}=${val}`)
@@ -2282,6 +2282,10 @@
       let key = item.field.toLowerCase()
       let _readin = item.readin !== 'false'
 
+      if (item.type === 'linkMain' && item.verifyVal === 'true') {
+        _item.$verify = true
+        _item.label = item.label
+      }
       if (_item.type === 'date') { // 鏃堕棿鍏煎
         _item.precision = item.precision || 'day'
       } else if (_item.type === 'datetime') {
diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx
index 9a1a0c5..7838109 100644
--- a/src/tabviews/zshare/mutilform/index.jsx
+++ b/src/tabviews/zshare/mutilform/index.jsx
@@ -184,6 +184,7 @@
       } else if (item.type === 'linkMain') {
         readin = false
         item.readin = false
+        item.$verify = item.verifyVal === 'true'
       } else if (item.type === 'number') {
         item.decimal = item.decimal || 0
         item.fieldlength = item.decimal
@@ -1545,6 +1546,11 @@
             key: item.field,
             isconst: item.constant === 'true'
           }
+
+          if (item.$verify) {
+            _item.$verify = true
+            _item.label = item.label
+          }
     
           _item.value = record[item.field] !== undefined ? record[item.field] : ''
     
diff --git a/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx b/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx
index 8b18bcf..bc9fe92 100644
--- a/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx
+++ b/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx
@@ -61,6 +61,7 @@
     })
 
     let placeholder = ''
+    let searchKey = ''
     if (!config.searchKey) {
       config.onload = 'true'
     } else {
@@ -74,6 +75,11 @@
       })
 
       placeholder = placeholder ? placeholder.join('銆�') : ''
+
+      if (value && !config.showValue) {
+        searchKey = value
+        config.onload = 'true'
+      }
     }
 
     this.state = {
@@ -84,7 +90,7 @@
       showValue: config.showValue,
       placeholder,
       arr_field: arrfield.join(','),
-      searchKey: '',
+      searchKey: searchKey,
       pageIndex: 1,
       pageSize: 10,
       orderBy: '',
diff --git a/src/tabviews/zshare/topSearch/index.jsx b/src/tabviews/zshare/topSearch/index.jsx
index 6e31879..088db55 100644
--- a/src/tabviews/zshare/topSearch/index.jsx
+++ b/src/tabviews/zshare/topSearch/index.jsx
@@ -55,7 +55,7 @@
     let linkFields = {}
     let record = {}
     let forbid = false // header涓笉璁剧疆楂樼骇鎼滅储
-    let _setting = {showAdv: false, show: false, style: null}
+    let _setting = {showAdv: false, show: false, style: null, $pageId: config.$pageId || ''}
     let BID = this.props.BID
     let sysvals = {}
 
@@ -170,6 +170,10 @@
               item.initval = [moment(d).startOf('month').format(item.format), moment(d).endOf('month').format(item.format)].join(',')
             } else if (item.$initval === 'lastMonth') {
               item.initval = [moment(d).subtract(1, 'months').startOf('month').format(item.format), moment(d).subtract(1, 'months').endOf('month').format(item.format)].join(',')
+            } else if (item.$initval === 'year') {
+              item.initval = [moment(d).startOf('year').format(item.format), moment(d).endOf('year').format(item.format)].join(',')
+            } else if (item.$initval === 'lastYear') {
+              item.initval = [moment(d).subtract(1, 'years').startOf('year').format(item.format), moment(d).subtract(1, 'years').endOf('year').format(item.format)].join(',')
             } else {
               try {
                 let _initval = JSON.parse(item.$initval)
@@ -445,6 +449,10 @@
               item.initval = [moment(d).startOf('month').format(item.format), moment(d).endOf('month').format(item.format)].join(',')
             } else if (item.$initval === 'lastMonth') {
               item.initval = [moment(d).subtract(1, 'months').startOf('month').format(item.format), moment(d).subtract(1, 'months').endOf('month').format(item.format)].join(',')
+            } else if (item.$initval === 'year') {
+              item.initval = [moment(d).startOf('year').format(item.format), moment(d).endOf('year').format(item.format)].join(',')
+            } else if (item.$initval === 'lastYear') {
+              item.initval = [moment(d).subtract(1, 'years').startOf('year').format(item.format), moment(d).subtract(1, 'years').endOf('year').format(item.format)].join(',')
             } else {
               try {
                 let _initval = JSON.parse(item.$initval)
@@ -1060,6 +1068,11 @@
   handleReset = () => {
     const { setting } = this.state
 
+    if (setting.resetContrl === 'refresh') {
+      MKEmitter.emit('reloadMenuView', setting.$pageId, true)
+      return
+    }
+
     let record = {}
     let advanceValues = []
     let searchlist = this.state.searchlist.map(item => {
diff --git a/src/templates/comtableconfig/updatetable/index.jsx b/src/templates/comtableconfig/updatetable/index.jsx
index f61593a..5f45777 100644
--- a/src/templates/comtableconfig/updatetable/index.jsx
+++ b/src/templates/comtableconfig/updatetable/index.jsx
@@ -635,16 +635,26 @@
       if (item.type === 'tabs') {
         item.subtabs.forEach(tab => {
           tab.components[0].action.forEach(btn => {
+            btn.uuid = Utils.getuuid()
             if (btn.OpenType === 'popview' && btn.config) {
               btn.config.$tables = getTables(btn.config.components[0])
+
+              btn.config.components[0].action && btn.config.components[0].action.forEach(cell => {
+                cell.uuid = Utils.getuuid()
+              })
             }
           })
           tab.components[0].cols.forEach(col => {
             if (col.type !== 'custom') return
             col.elements.forEach(btn => {
               if (btn.eleType !== 'button') return
+              btn.uuid = Utils.getuuid()
               if (btn.OpenType === 'popview' && btn.config) {
                 btn.config.$tables = getTables(btn.config.components[0])
+
+                btn.config.components[0].action && btn.config.components[0].action.forEach(cell => {
+                  cell.uuid = Utils.getuuid()
+                })
               }
             })
           })
diff --git a/src/templates/modalconfig/dragelement/index.jsx b/src/templates/modalconfig/dragelement/index.jsx
index 830681c..eb3a147 100644
--- a/src/templates/modalconfig/dragelement/index.jsx
+++ b/src/templates/modalconfig/dragelement/index.jsx
@@ -2,7 +2,7 @@
 import { useDrop } from 'react-dnd'
 import { is, fromJS } from 'immutable'
 import update from 'immutability-helper'
-import { Col } from 'antd'
+import { Col, message } from 'antd'
 import Utils from '@/utils/utils.js'
 import Card from './card'
 import './index.scss'
@@ -72,11 +72,15 @@
     oInput.style.display = 'none'
     document.body.removeChild(oInput)
 
-    const _cards = update(cards, { $splice: [[overIndex + 1, 0, _card]] })
-
-    setCards(_cards)
-
-    handleList(_cards, _card)
+    if (window.GLOB.CopyOnly) {
+      message.success('澶嶅埗鎴愬姛銆�')
+    } else {
+      const _cards = update(cards, { $splice: [[overIndex + 1, 0, _card]] })
+  
+      setCards(_cards)
+  
+      handleList(_cards, _card)
+    }
   }
 
   const [, drop] = useDrop({
@@ -94,10 +98,12 @@
       newcard.options = []
       newcard.readonly = 'false'
       newcard.required = 'true'
+      newcard.readin = 'top'
       newcard.focus = true
 
       if (item.subType === 'linkMain') {
         newcard.hidden = 'true'
+        newcard.verifyVal = 'true'
       } else if (item.subType === 'textarea') {
         newcard.required = 'false'
       }
diff --git a/src/templates/modalconfig/settingform/index.jsx b/src/templates/modalconfig/settingform/index.jsx
index 9d141c3..b0ff9d0 100644
--- a/src/templates/modalconfig/settingform/index.jsx
+++ b/src/templates/modalconfig/settingform/index.jsx
@@ -161,7 +161,7 @@
                 >
                   {fields.map(option =>
                     <Select.Option id={option.uuid} title={option.label} key={option.uuid} value={option.field}>
-                      {option.label}
+                      {`${option.label}锛�${option.field}锛塦}
                     </Select.Option>
                   )}
                 </Select>
@@ -185,7 +185,7 @@
                 >
                   {fields.map(option =>
                     <Select.Option key={option.uuid} value={option.uuid}>
-                      {option.label}
+                      {`${option.label}锛�${option.field}锛塦}
                     </Select.Option>
                   )}
                 </Select>
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
index f22a3ef..7931f0e 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -617,8 +617,8 @@
   columnChange = (values, callback) => {
     let verify = JSON.parse(JSON.stringify(this.state.verify))
 
-    let fields = verify.columns.map(item => item.Column)
-    if (fields.includes(values.Column)) {
+    let fields = verify.columns.map(item => item.Column.toLowerCase())
+    if (fields.includes(values.Column.toLowerCase())) {
       notification.warning({
         top: 92,
         message: values.Column + '瀛楁宸插瓨鍦紒',
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
index 502137b..7914366 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -41,6 +41,7 @@
         inputType: 'input',
         editable: true,
         unique: true,
+        strict: true,
         searchable: true,
         copy: true,
         width: '16%'
@@ -51,7 +52,6 @@
         inputType: 'input',
         editable: true,
         searchable: true,
-        unique: true,
         width: '16%'
       },
       {
@@ -494,8 +494,8 @@
   columnChange = (values, callback) => {
     let verify = JSON.parse(JSON.stringify(this.state.verify))
 
-    let fields = verify.columns.map(item => item.Column)
-    if (fields.includes(values.Column)) {
+    let fields = verify.columns.map(item => item.Column.toLowerCase())
+    if (fields.includes(values.Column.toLowerCase())) {
       notification.warning({
         top: 92,
         message: values.Column + '瀛楁宸插瓨鍦紒',
diff --git a/src/templates/sharecomponent/fieldscomponent/index.jsx b/src/templates/sharecomponent/fieldscomponent/index.jsx
index 9db6d1e..4bbf651 100644
--- a/src/templates/sharecomponent/fieldscomponent/index.jsx
+++ b/src/templates/sharecomponent/fieldscomponent/index.jsx
@@ -305,7 +305,8 @@
           decimal: item.decimal,
           orderType: 'asc',
           readonly: 'false',
-          required: 'true'
+          required: 'true',
+          readin: 'top'
         }
 
         if (/^icon|images?$/ig.test(item.field)) {
diff --git a/src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx b/src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx
index b8e407f..2b1fda7 100644
--- a/src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx
+++ b/src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx
@@ -57,6 +57,10 @@
       _defaultValue = [moment().startOf('month'), moment().endOf('month')]
     } else if (card.initval === 'lastMonth') {
       _defaultValue = [moment().subtract(1, 'months').startOf('month'), moment().subtract(1, 'months').endOf('month')]
+    } else if (card.initval === 'year') {
+      _defaultValue = [moment().startOf('year'), moment().endOf('year')]
+    } else if (card.initval === 'lastYear') {
+      _defaultValue = [moment().subtract(1, 'years').startOf('year'), moment().subtract(1, 'years').endOf('year')]
     } else if (card.initval) {
       try {
         let _initval = JSON.parse(card.initval)
diff --git a/src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx b/src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx
index b604984..48c6568 100644
--- a/src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx
@@ -2,7 +2,7 @@
 import { useDrop } from 'react-dnd'
 import { is, fromJS } from 'immutable'
 import update from 'immutability-helper'
-import { Col, Button, Popover } from 'antd'
+import { Col, Button, Popover, message } from 'antd'
 import { EditOutlined } from '@ant-design/icons'
 
 import Utils from '@/utils/utils.js'
@@ -68,11 +68,15 @@
       document.body.removeChild(oInput)
     }
 
-    const { index: overIndex } = findCard(id)
+    if (window.GLOB.CopyOnly) {
+      message.success('澶嶅埗鎴愬姛銆�')
+    } else {
+      const { index: overIndex } = findCard(id)
 
-    const _cards = update(cards, { $splice: [[overIndex + 1, 0, copycard]] })
+      const _cards = update(cards, { $splice: [[overIndex + 1, 0, copycard]] })
 
-    handleList(_cards, copycard)
+      handleList(_cards, copycard)
+    }
   }
 
   const [, drop] = useDrop({
diff --git a/src/templates/sharecomponent/searchcomponent/index.jsx b/src/templates/sharecomponent/searchcomponent/index.jsx
index c861729..16dcefa 100644
--- a/src/templates/sharecomponent/searchcomponent/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/index.jsx
@@ -61,6 +61,18 @@
       }, () => {
         this.handleSearch(item)
       })
+    } else if (type === 'replace') {
+      delete item.focus
+      this.setState({
+        searchlist: searchlist.map(cell => {
+          if (cell.field && cell.field.toLowerCase() === item.field.toLowerCase()) {
+            return item
+          }
+          return cell
+        }),
+      }, () => {
+        this.handleSearch(item)
+      })
     } else if (type === 'multil') {
       let list = [...searchlist, ...item]
       list = list.filter(item => !item.origin) // 鍘婚櫎绯荤粺椤�
diff --git a/src/templates/sharecomponent/searchcomponent/settingform/index.jsx b/src/templates/sharecomponent/searchcomponent/settingform/index.jsx
index 913d5a6..12fc9df 100644
--- a/src/templates/sharecomponent/searchcomponent/settingform/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/settingform/index.jsx
@@ -155,13 +155,19 @@
             </Form.Item>
           </Col>
           {show === 'true' ? <Col span={12}>
-            <Form.Item label="閲嶇疆鏃�">
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="鍒锋柊鑿滃崟浼氭竻绌篣RL鍙橀噺銆�">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                閲嶇疆鏃�
+              </Tooltip>
+            }>
               {getFieldDecorator('resetContrl', {
                 initialValue: setting.resetContrl || 'init',
               })(
                 <Radio.Group>
                   <Radio value="init">鎭㈠鍒濆鍊�</Radio>
                   <Radio value="clear">娓呯┖</Radio>
+                  <Radio value="refresh">鍒锋柊鑿滃崟</Radio>
                 </Radio.Group>
               )}
             </Form.Item>
diff --git a/src/templates/zshare/editTable/index.jsx b/src/templates/zshare/editTable/index.jsx
index 6a19cdb..932f55b 100644
--- a/src/templates/zshare/editTable/index.jsx
+++ b/src/templates/zshare/editTable/index.jsx
@@ -485,83 +485,151 @@
       return
     }
 
-    if (res.type === 'line') {
-      let unique = true
+    let ucol = columns.filter(col => col.unique === true)[0]
+    const that = this
+
+    if (data.length === 0) {
+      if (res.type === 'line') {
+        res.data.uuid = Utils.getuuid()
+        data.push(res.data)
+      } else if (res.type === 'array') {
+        res.data.forEach(cell => {
+          cell.uuid = Utils.getuuid()
+          data.push(cell)
+        })
+      }
+      this.setState({ data, editingKey: '', editLineId: res.type === 'line' ? res.data.uuid : '' }, () => {
+        this.props.onChange(data)
+      })
+    } else if (res.type === 'line') {
+      let index = -1
       res.data.uuid = Utils.getuuid()
-      columns.forEach(col => {
-        if (col.unique !== true || !unique) return
 
-        if (col.uniqueFunc) {
-          unique = col.uniqueFunc(data, res.data)
-        } else if (col.strict) {
-          let key = res.data[col.dataIndex].toLowerCase()
-          let _index = data.findIndex(item => key === item[col.dataIndex].toLowerCase())
+      if (ucol) {
+        if (ucol.uniqueFunc) {
+          let msg = ucol.uniqueFunc(data, res.data)
 
-          if (_index > -1) {
+          if (msg) {
             notification.warning({
               top: 92,
-              message: col.title + '涓嶅彲閲嶅锛�',
+              message: msg,
               duration: 5
             })
-            unique = false
+            callback()
+            return
+          }
+        } else if (ucol.strict) {
+          let key = res.data[ucol.dataIndex].toLowerCase()
+          index = data.findIndex(item => key === item[ucol.dataIndex].toLowerCase())
+        } else {
+          index = data.findIndex(item => res.data[ucol.dataIndex] === item[ucol.dataIndex])
+        }
+      }
+
+      if (index > -1) {
+        callback()
+        data.splice(index, 1, res.data)
+
+        confirm({
+          title: `${ucol.title}锛�${res.data[ucol.dataIndex]}锛夊凡瀛樺湪锛乣,
+          okText: '鐭ラ亾浜�',
+          cancelText: '鏇挎崲',
+          onOk() {},
+          onCancel() {
+            that.setState({ data, editingKey: '', editLineId: res.data.uuid || '' }, () => {
+              that.props.onChange(data)
+            })
+          }
+        })
+        return
+      } else {
+        if (type === 'excelcolumn') {
+          data.push(res.data)
+        } else {
+          data.unshift(res.data)
+        }
+  
+        this.setState({ data, editingKey: '', editLineId: res.data.uuid || '' }, () => {
+          this.props.onChange(data)
+        })
+      }
+    } else if (res.type === 'array') {
+      let repeats = []
+      let vals = []
+
+      if (ucol) {
+        if (ucol.uniqueFunc) {
+
+        } else if (ucol.strict) {
+          vals = data.map(item => item[ucol.dataIndex].toLowerCase())
+        } else {
+          vals = data.map(item => item[ucol.dataIndex])
+        }
+      }
+
+      res.data.forEach(cell => {
+        cell.uuid = Utils.getuuid()
+        
+        if (ucol) {
+          let unique = true
+          if (ucol.uniqueFunc) {
+            let msg = ucol.uniqueFunc(data, cell)
+  
+            if (msg) return
+          } else if (ucol.strict) {
+            unique = !vals.includes(cell[ucol.dataIndex].toLowerCase())
+          } else {
+            unique = !vals.includes(cell[ucol.dataIndex])
+          }
+
+          if (unique) {
+            data.push(cell)
+          } else {
+            repeats.push(cell)
           }
         } else {
-          let _index = data.findIndex(item => res.data[col.dataIndex] === item[col.dataIndex])
-
-          if (_index > -1) {
-            notification.warning({
-              top: 92,
-              message: col.title + '涓嶅彲閲嶅锛�',
-              duration: 5
-            })
-            unique = false
-          }
+          data.push(cell)
         }
       })
 
-      if (!unique) return
-
-      if (type === 'excelcolumn') {
-        data.push(res.data)
-      } else {
-        data.unshift(res.data)
-      }
-
-      this.setState({ data, editingKey: '', editLineId: res.data.uuid || '' }, () => {
-        this.props.onChange(data)
-      })
-    } else if (res.type === 'array') {
-      res.data.forEach(cell => {
-        let unique = true
-        cell.uuid = Utils.getuuid()
-        columns.forEach(col => {
-          if (col.unique !== true || !unique) return
-
-          if (col.uniqueFunc) {
-            unique = col.uniqueFunc(data, cell)
-          } else if (col.strict) {
-            let _index = data.findIndex(item => cell[col.dataIndex].toLowerCase() === item[col.dataIndex].toLowerCase())
-  
-            if (_index > -1) {
-              unique = false
+      if (repeats.length) {
+        callback()
+        let _data = fromJS(data).toJS().map(cell => {
+          let _cell = cell
+          repeats.forEach(item => {
+            if (ucol.strict) {
+              if (cell[ucol.dataIndex].toLowerCase() === item[ucol.dataIndex].toLowerCase()) {
+                _cell = item
+              }
+            } else if (cell[ucol.dataIndex] === item[ucol.dataIndex]) {
+              _cell = item
             }
-          } else {
-            let _index = data.findIndex(item => cell[col.dataIndex] === item[col.dataIndex])
-  
-            if (_index > -1) {
-              unique = false
-            }
-          }
+          })
+
+          return _cell
         })
 
-        if (!unique) return
-
-        data.push(cell)
-      })
-
-      this.setState({ data, editingKey: '' }, () => {
-        this.props.onChange(data)
-      })
+        confirm({
+          content: `瀛樺湪閲嶅鐨�${ucol.title}锛岃閫夋嫨澶勭悊鏂瑰紡銆俙,
+          okText: '璺宠繃',
+          cancelText: '鏇挎崲',
+          onOk() {
+            that.setState({ data, editingKey: '', editLineId: '' }, () => {
+              that.props.onChange(data)
+            })
+          },
+          onCancel() {
+            that.setState({ data: _data, editingKey: '', editLineId: '' }, () => {
+              that.props.onChange(data)
+            })
+          }
+        })
+        return
+      } else {
+        this.setState({ data, editingKey: '' }, () => {
+          this.props.onChange(data)
+        })
+      }
     }
 
     callback()
@@ -618,40 +686,36 @@
       return
     }
 
-    let unique = true
-    columns.forEach(col => {
-      if (col.unique !== true || !unique) return
+    let ucol = columns.filter(col => col.unique === true)[0]
+    if (ucol) {
+      let index = -1
+      if (ucol.uniqueFunc) {
+        let msg = ucol.uniqueFunc(newData, record)
 
-      if (col.uniqueFunc) {
-        unique = col.uniqueFunc(newData, record)
-        return
-      } else if (col.strict) {
-        let key = record[col.dataIndex].toLowerCase()
-        let _index = newData.findIndex(item => record.uuid !== item.uuid && key === item[col.dataIndex].toLowerCase())
-
-        if (_index > -1) {
+        if (msg) {
           notification.warning({
             top: 92,
-            message: col.title + '涓嶅彲閲嶅锛�',
+            message: msg,
             duration: 5
           })
-          unique = false
+          return
         }
+      } else if (ucol.strict) {
+        let key = record[ucol.dataIndex].toLowerCase()
+        index = newData.findIndex(item => record.uuid !== item.uuid && key === item[ucol.dataIndex].toLowerCase())
       } else {
-        let _index = newData.findIndex(item => record.uuid !== item.uuid && record[col.dataIndex] === item[col.dataIndex])
-  
-        if (_index > -1) {
-          notification.warning({
-            top: 92,
-            message: col.title + '涓嶅彲閲嶅锛�',
-            duration: 5
-          })
-          unique = false
-        }
+        index = newData.findIndex(item => record.uuid !== item.uuid && record[ucol.dataIndex] === item[ucol.dataIndex])
       }
-    })
 
-    if (!unique) return
+      if (index > -1) {
+        notification.warning({
+          top: 92,
+          message: ucol.title + '涓嶅彲閲嶅锛�',
+          duration: 5
+        })
+        return
+      }
+    }
 
     newData.splice(index, 1, record)
     this.setState({ data: newData, editingKey: '' }, () => {
@@ -704,40 +768,36 @@
         return
       }
 
-      let unique = true
-      columns.forEach(col => {
-        if (col.unique !== true || !unique) return
+      let ucol = columns.filter(col => col.unique === true)[0]
+      if (ucol) {
+        let _index = -1
+        if (ucol.uniqueFunc) {
+          let msg = ucol.uniqueFunc(newData, row)
 
-        if (col.uniqueFunc) {
-          unique = col.uniqueFunc(newData, row)
-          return
-        } else if (col.strict) {
-          let key = row[col.dataIndex].toLowerCase()
-          let _index = newData.findIndex(item => row.uuid !== item.uuid && key === item[col.dataIndex].toLowerCase())
-  
-          if (_index > -1) {
+          if (msg) {
             notification.warning({
               top: 92,
-              message: col.title + '涓嶅彲閲嶅锛�',
+              message: msg,
               duration: 5
             })
-            unique = false
+            return
           }
+        } else if (ucol.strict) {
+          let key = row[ucol.dataIndex].toLowerCase()
+          _index = newData.findIndex(item => row.uuid !== item.uuid && key === item[ucol.dataIndex].toLowerCase())
         } else {
-          let _index = newData.findIndex(item => row.uuid !== item.uuid && row[col.dataIndex] === item[col.dataIndex])
-  
-          if (_index > -1) {
-            notification.warning({
-              top: 92,
-              message: col.title + '涓嶅彲閲嶅锛�',
-              duration: 5
-            })
-            unique = false
-          }
+          _index = newData.findIndex(item => row.uuid !== item.uuid && row[ucol.dataIndex] === item[ucol.dataIndex])
         }
-      })
 
-      if (!unique) return
+        if (_index > -1) {
+          notification.warning({
+            top: 92,
+            message: ucol.title + '涓嶅彲閲嶅锛�',
+            duration: 5
+          })
+          return
+        }
+      }
 
       if (index > -1) {
         newData.splice(index, 1, row)
@@ -912,6 +972,10 @@
                 ...moveprops
               })}
             />
+            {actions.includes('copy') && data.length > 10 ? <span className="footer-copy-control">
+              <CopyOutlined title="澶嶅埗" onClick={() => this.copy()} />
+              <PasteBoard getPasteValue={this.pasteSubmit}/>
+            </span> : null}
           </DndProvider>
         </div>
       </EditableContext.Provider>
diff --git a/src/templates/zshare/editTable/index.scss b/src/templates/zshare/editTable/index.scss
index 76e6bfd..c8cb026 100644
--- a/src/templates/zshare/editTable/index.scss
+++ b/src/templates/zshare/editTable/index.scss
@@ -125,6 +125,31 @@
     font-size: 18px;
     color: #26C281;
   }
+  .footer-copy-control {
+    text-align: right;
+    margin: 10px;
+    display: block;
+    .anticon-copy {
+      margin-right: 15px;
+      color: #26C281;
+    }
+    .anticon-snippets {
+      color: purple;
+    }
+  }
+  .ant-typography-copy:not(.ant-typography-copy-success) {
+    opacity: 0;
+    transition: opacity 0.2s;
+  }
+
+  tr:hover {
+    .ant-typography-copy:not(.ant-typography-copy-success) {
+      opacity: 0.7;
+    }
+    .ant-typography-copy:hover {
+      opacity: 1;
+    }
+  }
 }
 
 .ant-modal.ant-modal-confirm.ant-modal-confirm-info.sql-example {
diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx
index b494bb7..2dacf15 100644
--- a/src/templates/zshare/formconfig.jsx
+++ b/src/templates/zshare/formconfig.jsx
@@ -1947,6 +1947,20 @@
     },
     {
       type: 'radio',
+      key: 'verifyVal',
+      label: '绌哄�奸獙璇�',
+      tooltip: '鎸夐挳鎻愪氦鏃堕獙璇佸瓧娈靛�兼槸鍚︿负绌猴紙鎴栨暟鍊间负0锛夈��',
+      initVal: card.verifyVal || 'false',
+      options: [{
+        value: 'true',
+        text: '寮�鍚�'
+      }, {
+        value: 'false',
+        text: '鍏抽棴'
+      }]
+    },
+    {
+      type: 'radio',
       key: 'format',
       label: '鏍煎紡鍖�',
       tooltip: '浣跨敤鍗冨垎浣嶆椂锛屾暟鍊煎皢浠ュ崈鍒嗕綅鏍煎紡鏄剧ず锛屾彁浜ゆ椂涓哄師鏁板�笺��',
diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx
index 8867247..a860265 100644
--- a/src/templates/zshare/modalform/index.jsx
+++ b/src/templates/zshare/modalform/index.jsx
@@ -43,7 +43,7 @@
   formula: ['label', 'type', 'marginTop', 'marginBottom', 'splitline', 'supField', 'span', 'labelwidth', 'formula', 'eval', 'postfix'],
   brafteditor: ['required', 'hidelabel', 'hidden', 'readin', 'fieldlength', 'readonly', 'span', 'labelwidth', 'tooltip', 'extra', 'encryption', 'marginTop', 'marginBottom', 'contHeidht'],
   funcvar: ['span', 'labelwidth', 'splitline', 'marginTop', 'marginBottom'],
-  linkMain: ['readonly', 'required', 'hidden','declare', 'span', 'labelwidth', 'tooltip', 'interception', 'extra', 'place', 'marginTop', 'marginBottom'],
+  linkMain: ['readonly', 'required', 'hidden','declare', 'span', 'labelwidth', 'tooltip', 'interception', 'extra', 'place', 'marginTop', 'marginBottom', 'verifyVal'],
   popSelect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'enter', 'dataSource', 'columns', 'primaryKey', 'order', 'controlField', 'laypage', 'onload', 'searchKey', 'showField', 'popWidth'],
   vercode: ['label', 'field', 'type', 'blacklist', 'supField', 'readonly', 'required', 'hidden', 'span', 'labelwidth', 'tooltip', 'marginTop', 'marginBottom', 'placeholder', 'enter', 'smsId', 'phoneField', 'sendType']
 }
@@ -426,7 +426,9 @@
 
       if (value === 'linkMain') {
         this.record.hidden = 'true'
+        this.record.verifyVal = 'true'
         _fieldval.hidden = 'true'
+        _fieldval.verifyVal = 'true'
       }
       
       if (this.record.type === 'cascader' && value !== 'cascader') {
diff --git a/src/templates/zshare/verifycard/index.jsx b/src/templates/zshare/verifycard/index.jsx
index 6846474..e6c8b75 100644
--- a/src/templates/zshare/verifycard/index.jsx
+++ b/src/templates/zshare/verifycard/index.jsx
@@ -746,6 +746,10 @@
         _f.writein = _f.writein !== 'false'
         _f.fieldlen = _f.fieldlength || 50
 
+        if (_f.type === 'linkMain' && _f.verifyVal === 'true') {
+          _f.$verify = true
+        }
+
         if (_f.type === 'datemonth') {
           _f.type = 'text'
         } else if (_f.type === 'number' || _f.type === 'rate') {
@@ -848,13 +852,19 @@
       colfields: colfields.join(', '),
       uniqueColumns: this.state.uniqueColumns.map(col => {
         if (col.dataIndex === 'field') {
-          col.options = unionFields
+          col.options = fromJS(unionFields).toJS().map(n => {
+            n.label = `${n.label}锛�${n.field}锛塦
+            return n
+          })
         }
         return col
       }),
       onceUniqueColumns: this.state.onceUniqueColumns.map(col => {
         if (col.dataIndex === 'field') {
-          col.options = _columns
+          col.options = fromJS(_columns).toJS().map(n => {
+            n.label = `${n.label}锛�${n.field}锛塦
+            return n
+          })
         }
         return col
       }),
@@ -1034,8 +1044,19 @@
 
     formdata = formdata.length ? formdata : null
 
+    let verifyValSql = ''
     // 鑾峰彇瀛楁閿�煎
     formdata && formdata.forEach(form => {
+      if (form.$verify) {
+        verifyValSql += `
+        if @${form.field}=${form.type === 'number' ? 0 : `''`}
+        begin
+          select @errorcode='E',@retmsg='${form.label}锛屽叧鑱斾富琛ㄥけ鏁�'
+          goto aaa
+        end
+        `
+      }
+
       let _key = form.field.toLowerCase()
       if (!_initvars.includes(_key)) {
         _initvars.push(_key)
@@ -1287,22 +1308,21 @@
   
       verify.billcodes.forEach(item => {
         let _key = item.field.toLowerCase()
-        let _linkKey = item.linkField ? item.linkField.toLowerCase() : ''
   
         if (!keys.includes(_key)) return // 琛ㄥ崟涓笉鍚崟鍙风敓鎴愬瓧娈�
   
         let _lpline = ''
         if (item.TypeCharOne === 'Lp') {
-          if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
+          if (/^BID$/ig.test(item.linkField)) {
             _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@BID@,48)`
           } else {
-            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${_linkKey},48)`
+            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${item.linkField},48)`
           }
         } else if (item.TypeCharOne === 'BN') {
-          if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
+          if (/^BID$/ig.test(item.linkField)) {
             _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
           } else {
-            _lpline = `set @ModularDetailCode= 'BN'+ right(@${_linkKey},48)`
+            _lpline = `set @ModularDetailCode= 'BN'+ right(@${item.linkField},48)`
           }
         } else {
           _lpline = `set @ModularDetailCode= right('${item.ModularDetailCode}',50)`
@@ -1423,15 +1443,20 @@
     let hasvoucher = false
   
     // 鍑瘉-鏄剧ず鍒椾腑閫夊彇,蹇呴』閫夎
-    if (verify.voucher && verify.voucher.enabled && btn.Ot !== 'requiredOnce') {
+    if (verify.voucher && verify.voucher.enabled) {
       let _voucher = verify.voucher
+      let linkField = `@${_voucher.linkField}`
+  
+      if (/^BID$/ig.test(_voucher.linkField)) {
+        linkField = `'${BID}'`
+      }
   
       hasvoucher = true
   
       _sql += `
         /* 鍒涘缓鍑瘉 */
         exec s_BVoucher_Create
-          @Bill = @${_voucher.linkField},
+          @Bill = ${linkField},
           @BVoucherType ='${_voucher.BVoucherType}',
           @VoucherTypeOne ='${_voucher.VoucherTypeOne}',
           @VoucherTypeTwo ='${_voucher.VoucherTypeTwo}',
@@ -1694,6 +1719,10 @@
     } else if (_backCustomScript) {
       _sql += _backCustomScript
     }
+
+    if (verifyValSql) {
+      _sql += verifyValSql
+    }
   
     if (btn.procMode === 'system') {
       _sql += `
@@ -1904,7 +1933,7 @@
       let hasvoucher = false
   
       // 鍑瘉-鏄剧ず鍒椾腑閫夊彇,蹇呴』閫夎
-      if (verify.voucher && verify.voucher.enabled && btn.Ot !== 'requiredOnce') {
+      if (verify.voucher && verify.voucher.enabled) {
         hasvoucher = true
       }
       if (hasvoucher) {
@@ -1998,7 +2027,8 @@
       _lpline = `set @ModularDetailCode= right('${record.ModularDetailCode}',50)`
     }
 
-    let sql = `select @BillCode='', @${record.field}='', @ModularDetailCode=''
+    let sql = `Declare @BillCode nvarchar(50),@ModularDetailCode nvarchar(50)
+    select @BillCode='', @${record.field}='', @ModularDetailCode=''
     ${_lpline}
     exec s_get_BillCode
       @ModularDetailCode=@ModularDetailCode,
@@ -2682,14 +2712,14 @@
             <EditTable actions={['edit', 'move', 'del', 'status', 'sql']} data={verify.uniques} columns={card.Ot !== 'requiredOnce' ? uniqueColumns : onceUniqueColumns} onChange={this.changeUniques}/>
           </TabPane> : null}
           {verifyInter === 'system' ? <TabPane tab={
-            <span title={card.Ot === 'requiredOnce' ? '澶氳鎷兼帴鏃朵笉鍙敤' : ''}>
+            <span>
               鍒涘缓鍑瘉
               {verify.voucher && verify.voucher.enabled ? <span className="count-tip">1</span> : null}
             </span>
-          } key="voucher" disabled={card.Ot === 'requiredOnce'}>
+          } key="voucher">
             <VoucherForm
               voucher={voucher}
-              columns={columns}
+              columns={unionFields}
               voucherobj={verify.voucher}
               voucherDetail={voucherDetail}
               voucherChange={this.voucherChange}
diff --git a/src/utils/option.js b/src/utils/option.js
index e025897..b311e85 100644
--- a/src/utils/option.js
+++ b/src/utils/option.js
@@ -133,6 +133,8 @@
     {value: 'week', text: '鏈懆'},
     {value: 'month', text: '鏈湀'},
     {value: 'lastMonth', text: '涓婃湀'},
+    {value: 'year', text: '鏈勾'},
+    {value: 'lastYear', text: '涓婂勾'},
   ],
   datetime: [
     {value: '', text: '绌�'},
diff --git a/src/utils/utils-custom.js b/src/utils/utils-custom.js
index 021894d..59eee91 100644
--- a/src/utils/utils-custom.js
+++ b/src/utils/utils-custom.js
@@ -1961,14 +1961,14 @@
       if (cell.OpenType === 'form' && cell.formType === 'count_line') return
      
       if (cell.intertype === 'system') {
-        if (cell.Ot === 'notRequired' && cell.verify && cell.verify.voucher && cell.verify.voucher.enabled) {
-          errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅娇鐢ㄤ簡鍒涘缓鍑瘉鍑芥暟锛岄渶瑕侀�夋嫨琛岋紒`})
-        }
+        // if (cell.Ot === 'notRequired' && cell.verify && cell.verify.voucher && cell.verify.voucher.enabled) {
+        //   errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅娇鐢ㄤ簡鍒涘缓鍑瘉鍑芥暟锛岄渶瑕侀�夋嫨琛岋紒`})
+        // }
       } else if (cell.intertype === 'custom' || cell.intertype === 'outer') {
         if (cell.callbackType === 'script' && (!cell.verify || !cell.verify.cbScripts || cell.verify.cbScripts.filter(item => item.status !== 'false').length === 0)) {
           errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅娇鐢ㄤ簡鑷畾涔夎剼鏈洖璋冿紝鍥炶皟鑴氭湰涓嶅彲涓虹┖锛乣})
-        } else if (cell.procMode === 'system' && cell.Ot === 'notRequired' && cell.verify && cell.verify.voucher && cell.verify.voucher.enabled) {
-          errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅娇鐢ㄤ簡鍒涘缓鍑瘉鍑芥暟锛岄渶瑕侀�夋嫨琛岋紒`})
+        // } else if (cell.procMode === 'system' && cell.Ot === 'notRequired' && cell.verify && cell.verify.voucher && cell.verify.voucher.enabled) {
+        //   errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅娇鐢ㄤ簡鍒涘缓鍑瘉鍑芥暟锛岄渶瑕侀�夋嫨琛岋紒`})
         }
       }
     } else if (cell.OpenType === 'funcbutton') {
@@ -3533,6 +3533,11 @@
             isconst: item.constant === 'true'
           }
 
+          if (item.type === 'linkMain' && item.verifyVal === 'true') {
+            _item.$verify = true
+            _item.label = item.label
+          }
+
           if (_item.type === 'datemonth') {
             _item.type = 'text'
           } else if (_item.type === 'number' || _item.type === 'rate') {
@@ -3571,8 +3576,19 @@
       formdata.push(item)
     }
 
+    let verifyValSql = ''
     // 鑾峰彇瀛楁閿�煎
     formdata && formdata.forEach(form => {
+      if (form.$verify) {
+        verifyValSql += `
+        if @${form.key}=${form.type === 'number' ? 0 : `''`}
+        begin
+          select @errorcode='E',@retmsg='${form.label}锛屽叧鑱斾富琛ㄥけ鏁�'
+          goto aaa
+        end
+        `
+      }
+
       let _key = form.key.toLowerCase()
 
       if (!formkeys.includes(_key)) {
@@ -3747,22 +3763,21 @@
     if (formdata && verify.billcodes && verify.billcodes.length > 0) {
       verify.billcodes.forEach(item => {
         let _key = item.field.toLowerCase()
-        let _linkKey = item.linkField ? item.linkField.toLowerCase() : ''
   
         if (!formkeys.includes(_key)) return // 琛ㄥ崟涓笉鍚崟鍙风敓鎴愬瓧娈�
   
         let _lpline = ''
         if (item.TypeCharOne === 'Lp') {
-          if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
+          if (/^BID$/ig.test(item.linkField)) {
             _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@BID@,48)`
           } else {
-            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${_linkKey},48)`
+            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${item.linkField},48)`
           }
         } else if (item.TypeCharOne === 'BN') {
-          if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
+          if (/^BID$/ig.test(item.linkField)) {
             _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
           } else {
-            _lpline = `set @ModularDetailCode= 'BN'+ right(@${_linkKey},48)`
+            _lpline = `set @ModularDetailCode= 'BN'+ right(@${item.linkField},48)`
           }
         } else {
           _lpline = `set @ModularDetailCode= right('${item.ModularDetailCode}',50)`
@@ -3875,15 +3890,20 @@
     let hasvoucher = false
   
     // 鍑瘉-鏄剧ず鍒椾腑閫夊彇,蹇呴』閫夎
-    if (verify.voucher && verify.voucher.enabled && btn.Ot !== 'requiredOnce') {
+    if (verify.voucher && verify.voucher.enabled) {
       let _voucher = verify.voucher
+      let linkField = `@${_voucher.linkField}`
+  
+      if (/^BID$/ig.test(_voucher.linkField)) {
+        linkField = BID
+      }
   
       hasvoucher = true
   
       _sql += `
         /* 鍒涘缓鍑瘉 */
         exec s_BVoucher_Create
-          @Bill = @${_voucher.linkField},
+          @Bill = ${linkField},
           @BVoucherType ='${_voucher.BVoucherType}',
           @VoucherTypeOne ='${_voucher.VoucherTypeOne}',
           @VoucherTypeTwo ='${_voucher.VoucherTypeTwo}',
@@ -4275,6 +4295,10 @@
       }
     } else if (_backCustomScript) {
       _sql += _backCustomScript
+    }
+
+    if (verifyValSql) {
+      _sql += verifyValSql
     }
 
     if (verify.workFlow === 'true' && process) {
@@ -5464,6 +5488,7 @@
         let _fields = unique.field.split(',')
         let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
         _fields_ = _fields_.join(' and ')
+        _fields_ += ` and a.jskey != b.${setting.primaryKey || 'id'}`
 
         let _where = []
         _fields.forEach(f => {
@@ -5520,6 +5545,7 @@
 
     let declarefields = []
     let fields = []
+    let upFields = []
 
     forms.forEach(col => {
       let key = col.field.toLowerCase()
@@ -5527,15 +5553,27 @@
 
       declarefields.push(`${col.field} ${col.datatype}`)
       fields.push(col.field)
+      upFields.push(`${col.field}=t.${col.field}`)
     })
 
     fields = fields.join(',')
+    upFields = upFields.join(',')
 
     let _insert = ''
     if (btn.default !== 'false') {
       _insert = `
         /* 榛樿sql */
-        Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid) 
+        update a set ${upFields},modifydate=getdate(),modifyuserid=@UserID@,modifyuser=@username,modifystaff=@fullname,deleted=0
+        from (select * from #${sheet} where data_type='upt') t
+        inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+        update a set deleted=1,modifydate=getdate(),modifyuserid=@UserID@,modifyuser=@username,modifystaff=@fullname 
+        from (select * from #${sheet} where data_type='del') t
+        inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+        delete t from #${sheet} t inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+        Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid)
         Select ${fields},@UserID@,@username,@fullname,@BID@ From #${sheet}
       `
     }
diff --git a/src/utils/utils.js b/src/utils/utils.js
index dde2cfb..09650c6 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -265,7 +265,7 @@
             }
 
             if (d) {
-              item.initval = moment(d).subtract(item.initval, 'month').format('YYYY-MM')
+              item.initval = moment(d).subtract(item.$initval, 'month').format('YYYY-MM')
             }
           }
         }
@@ -294,6 +294,10 @@
               item.initval = [moment().startOf('month').format(format), moment().endOf('month').format(format)].join(',')
             } else if (item.initval === 'lastMonth') {
               item.initval = [moment().subtract(1, 'months').startOf('month').format(format), moment().subtract(1, 'months').endOf('month').format(format)].join(',')
+            } else if (item.initval === 'year') {
+              item.initval = [moment().startOf('year').format(format), moment().endOf('year').format(format)].join(',')
+            } else if (item.initval === 'lastYear') {
+              item.initval = [moment().subtract(1, 'years').startOf('year').format(format), moment().subtract(1, 'years').endOf('year').format(format)].join(',')
             } else if (item.initval) {
               try {
                 let _initval = JSON.parse(item.initval)
@@ -335,6 +339,10 @@
                 item.initval = [moment(d).startOf('month').format(format), moment(d).endOf('month').format(format)].join(',')
               } else if (item.$initval === 'lastMonth') {
                 item.initval = [moment(d).subtract(1, 'months').startOf('month').format(format), moment(d).subtract(1, 'months').endOf('month').format(format)].join(',')
+              } else if (item.$initval === 'year') {
+                item.initval = [moment(d).startOf('year').format(format), moment(d).endOf('year').format(format)].join(',')
+              } else if (item.$initval === 'lastYear') {
+                item.initval = [moment(d).subtract(1, 'years').startOf('year').format(format), moment(d).subtract(1, 'years').endOf('year').format(format)].join(',')
               } else {
                 try {
                   let _initval = JSON.parse(item.$initval)
@@ -1522,7 +1530,7 @@
  * @return {Object} item   鎸夐挳淇℃伅
  * @return {Array}  data   excel鏁版嵁
  */
-export function getEditTableSql (verify, data, columns) {
+export function getEditTableSql (verify, data, columns, setting) {
   let btn = verify
   let userName = sessionStorage.getItem('User_Name') || ''
   let fullName = sessionStorage.getItem('Full_Name') || ''
@@ -1641,6 +1649,7 @@
         let _fields = unique.field.split(',')
         let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
         _fields_ = _fields_.join(' and ')
+        _fields_ += ` and a.jskey != b.${setting.primaryKey || 'id'}`
 
         let _where = []
         _fields.forEach(f => {
@@ -1697,6 +1706,7 @@
 
     let declarefields = []
     let fields = []
+    let upFields = []
 
     columns.forEach(col => {
       let key = col.field.toLowerCase()
@@ -1704,15 +1714,27 @@
 
       declarefields.push(`${col.field} ${col.datatype}`)
       fields.push(col.field)
+      upFields.push(`${col.field}=t.${col.field}`)
     })
 
     fields = fields.join(',')
+    upFields = upFields.join(',')
 
     let _insert = ''
     if (btn.default !== 'false') {
       _insert = `
       /* 榛樿sql */
-      Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid) 
+      update a set ${upFields},modifydate=getdate(),modifyuserid='${sessionStorage.getItem('UserID') || ''}',modifyuser=@username,modifystaff=@fullname,deleted=0
+      from (select * from #${sheet} where data_type='upt') t
+      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+      update a set deleted=1,modifydate=getdate(),modifyuserid='${sessionStorage.getItem('UserID') || ''}',modifyuser=@username,modifystaff=@fullname 
+      from (select * from #${sheet} where data_type='del') t
+      inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+      delete t from #${sheet} t inner join ${database}${sheet} a on t.jskey=a.${setting.primaryKey || 'id'}
+
+      Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid)
       Select ${fields},'${sessionStorage.getItem('UserID') || ''}',@username,@fullname,'${BID}' From #${sheet}
       `
     }
@@ -1820,9 +1842,20 @@
   let _initFormfields = []
   let _initColfields = []
   let _declarefields = []
+  let verifyValSql = ''
 
   // 鑾峰彇瀛楁閿�煎
   formdata && formdata.forEach(form => {
+    if (form.$verify) {
+      verifyValSql += `
+      if @${form.key}=${form.type === 'number' ? 0 : `''`}
+      begin
+        select @errorcode='E',@retmsg='${form.label}锛屽叧鑱斾富琛ㄥけ鏁�'
+        goto aaa
+      end
+      `
+    }
+
     let _key = form.key.toLowerCase()
 
     if (!_initvars.includes(_key)) {
@@ -1830,7 +1863,7 @@
       let val = form.value
 
       if (form.type === 'number' || form.type === 'rate') {
-        if (isNaN(val)) {
+        if (isNaN(val) || val === '') {
           val = 0
         }
         _initFormfields.push(`@${_key}=${val}`)
@@ -2111,22 +2144,21 @@
 
     verify.billcodes.forEach(item => {
       let _key = item.field.toLowerCase()
-      let _linkKey = item.linkField ? item.linkField.toLowerCase() : ''
 
       if (!keys.includes(_key)) return // 琛ㄥ崟涓笉鍚崟鍙风敓鎴愬瓧娈�
 
       let _lpline = ''
       if (item.TypeCharOne === 'Lp') {
-        if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
+        if (/^BID$/ig.test(item.linkField)) {
           _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@BID@,48)`
         } else {
-          _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${_linkKey},48)`
+          _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${item.linkField},48)`
         }
       } else if (item.TypeCharOne === 'BN') {
-        if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
+        if (/^BID$/ig.test(item.linkField)) {
           _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
         } else {
-          _lpline = `set @ModularDetailCode= 'BN'+ right(@${_linkKey},48)`
+          _lpline = `set @ModularDetailCode= 'BN'+ right(@${item.linkField},48)`
         }
       } else {
         _lpline = `set @ModularDetailCode= right('${item.ModularDetailCode}',50)`
@@ -2245,13 +2277,18 @@
   // 鍑瘉-鏄剧ず鍒椾腑閫夊彇,蹇呴』閫夎
   if (verify.voucher && verify.voucher.enabled) {
     let _voucher = verify.voucher
+    let linkField = `@${_voucher.linkField}`
+  
+    if (/^BID$/ig.test(_voucher.linkField)) {
+      linkField = `'${BID}'`
+    }
 
     hasvoucher = true
 
     _sql += `
       /* 鍒涘缓鍑瘉 */
       exec s_BVoucher_Create
-        @Bill = @${_voucher.linkField},
+        @Bill = ${linkField},
         @BVoucherType ='${_voucher.BVoucherType}',
         @VoucherTypeOne ='${_voucher.VoucherTypeOne}',
         @VoucherTypeTwo ='${_voucher.VoucherTypeTwo}',
@@ -2875,6 +2912,10 @@
     _sql += _backCustomScript
   }
 
+  if (verifyValSql) {
+    _sql += verifyValSql
+  }
+
   if (window.GLOB.breakpoint) {
     let start = new RegExp('\\/\\*\\$breakpoint_begin_' + window.GLOB.breakpoint + '@', 'ig')
     let end = new RegExp('@breakpoint_end_' + window.GLOB.breakpoint + '\\$\\*\\/', 'ig')
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index 29eb9eb..f29c056 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -4,8 +4,8 @@
 import { is, fromJS } from 'immutable'
 import moment from 'moment'
 import HTML5Backend from 'react-dnd-html5-backend'
-import { notification, Modal, Collapse, Card, Switch, Button, Typography, Spin, message } from 'antd'
-import { DoubleLeftOutlined, DoubleRightOutlined, EyeOutlined, EyeInvisibleOutlined, CopyOutlined } from '@ant-design/icons'
+import { notification, Modal, Collapse, Switch, Button, Typography, Spin, message, Dropdown } from 'antd'
+import { DoubleLeftOutlined, DoubleRightOutlined, EyeOutlined, EyeInvisibleOutlined, CopyOutlined, DownOutlined } from '@ant-design/icons'
 import html2canvas from 'html2canvas'
 import md5 from 'md5'
 
@@ -35,8 +35,10 @@
 const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
 const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
 const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
+const LowerField = asyncComponent(() => import('@/menu/lowerField'))
 const Debug = asyncComponent(() => import('@/menu/debug'))
 const NormalCss = asyncComponent(() => import('@/menu/normalCss'))
+const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
 const Versions = asyncComponent(() => import('@/menu/versions'))
 const TableNodes = asyncComponent(() => import('@/menu/tablenodes'))
 const SysInterface = asyncComponent(() => import('@/menu/sysinterface'))
@@ -1353,9 +1355,10 @@
                       />
                       {/* 琛ㄥ悕娣诲姞 */}
                       <TableComponent config={config} updatetable={this.updateConfig}/>
-                      <Paragraph style={{padding: '15px 0px 0px 37px'}} copyable={{ text: MenuId }}>鑿滃崟ID</Paragraph>
+                      <Paragraph style={{padding: '15px 0px 0px 32px'}} copyable={{ text: MenuId }}>鑿滃崟ID锛�</Paragraph>
                       <Paragraph style={{padding: '0px 0px 0px 18px'}}>鑿滃崟缁勪欢锛�<CopyOutlined onClick={this.copyMenu} style={{cursor: 'pointer', color: '#1890ff'}} /></Paragraph>
                       <NormalCss config={config} updateConfig={this.updateConfig}/>
+                      <NormalCopy />
                     </> : null}
                   </Panel>
                   {/* 缁勪欢娣诲姞 */}
@@ -1371,24 +1374,26 @@
                 </Collapse>
               </div>
               <div className={'menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}>
-                <Card bordered={false} extra={
-                  <div className="mk-opeartion-list">
-                    {config ? <Debug config={config}/> : null}
-                    <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 缁勪欢鍚�</Button>
-                    {config ? <Versions MenuId={MenuId} Template="CustomPage" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
-                    <TableNodes config={config} />
-                    <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
-                    <SysInterface config={config} updateConfig={this.updateConfig}/>
+                <div className="mk-opeartion-list">
+                  {config ? <Debug config={config}/> : null}
+                  <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 缁勪欢鍚�</Button>
+                  {config ? <Versions MenuId={MenuId} Template="CustomPage" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
+                  <TableNodes config={config} />
+                  <SysInterface config={config} updateConfig={this.updateConfig}/>
+                  <StyleCombControlButton menu={config} />
+                  <PasteController vType="admin" insert={this.insert} />
+                  {config ? <Dropdown placement="bottomCenter" overlay={<div className="mk-opeartion-dropdown-wrap">
+                    <ReplaceField config={config} updateConfig={this.resetConfig}/>
+                    <LowerField config={config} updateConfig={this.resetConfig}/>
                     <PictureController/>
-                    <StyleCombControlButton menu={config} />
-                    <PasteController vType="admin" insert={this.insert} />
-                    {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
-                    <Button type="primary" id="save-config" disabled={!config} className={needUpdate ? 'update-tip' : ''} onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
-                    <Button type="default" disabled={menuloading} onClick={this.closeView}>鍏抽棴</Button>
-                  </div>
-                } style={{ width: '100%' }}>
-                  {config && !comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : <Spin className="loading-config" size="large" />}
-                </Card>
+                  </div>} trigger={['hover']}>
+                    <div className="mk-button-more">鏇村<DownOutlined/></div>
+                  </Dropdown> : null}
+                  {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
+                  <Button type="primary" id="save-config" disabled={!config} className={needUpdate ? 'update-tip' : ''} onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
+                  <Button type="default" disabled={menuloading} onClick={this.closeView}>鍏抽棴</Button>
+                </div>
+                {config && !comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : <Spin className="loading-config" size="large" />}
               </div>
             </div>
           </div> : <PopView btn={this.state.popConfig} save={this.submitPopConfig} cancel={this.closePop}/>}
diff --git a/src/views/menudesign/index.scss b/src/views/menudesign/index.scss
index 5521e68..29669ce 100644
--- a/src/views/menudesign/index.scss
+++ b/src/views/menudesign/index.scss
@@ -183,42 +183,53 @@
       overflow-y: auto;
       transition: all 0.3s;
 
-      > .ant-card {
-        >.ant-card-head {
-          margin-bottom: 0px;
-          position: sticky;
-          top: 0px;
-          z-index: 10;
-          background: #ffffff;
-          .ant-card-head-title {
-            color: #1890ff;
-            padding: 5px 0;
-          }
-          .ant-card-extra {
-            padding: 5px 0;
-            button {
-              margin-left: 10px;
-            }
-            .mk-opeartion-list button:not(.ant-switch):not(:last-child):not(:nth-last-child(2)) {
-              padding: 0px 10px;
-            }
-            .ant-switch.big {
-              min-width: 60px;
-              height: 28px;
-              line-height: 28px;
-              margin-top: -2px;
-              .ant-switch-inner {
-                font-size: 14px;
-              }
-            }
-            .ant-switch.big:after {
-              width: 24px;
-              height: 24px;
-            }
+      .mk-opeartion-list {
+        position: sticky;
+        top: 0px;
+        left: 0px;
+        right: 0px;
+        text-align: right;
+        padding: 5px 10px 8px;
+        background: #ffffff;
+        border-bottom: 1px solid #e8e8e8;
+        height: 45px;
+        white-space: nowrap;
+        overflow: hidden;
+        z-index: 10;
+
+        button {
+          margin-left: 15px;
+        }
+        button:not(.ant-switch):not(:last-child):not(:nth-last-child(2)) {
+          padding: 0px 10px;
+        }
+        .mk-button-more {
+          display: inline-block;
+          height: 32px;
+          border: 1px solid #26C281;
+          color: #26C281;
+          line-height: 32px;
+          padding: 0 10px 0px 20px;
+          border-radius: 4px;
+          cursor: pointer;
+          vertical-align: top;
+          margin-left: 10px;
+          .anticon-down {
+            margin-left: 3px;
           }
         }
-        >.ant-card-body {
-          padding: 0px;
+        .ant-switch.big {
+          min-width: 60px;
+          height: 28px;
+          line-height: 28px;
+          margin-top: -2px;
+          .ant-switch-inner {
+            font-size: 14px;
+          }
+        }
+        .ant-switch.big:after {
+          width: 24px;
+          height: 24px;
         }
       }
     }
@@ -253,17 +264,5 @@
   .ant-table-thead > tr > th {
     background: transparent!important;
     border-radius: 0!important;
-  }
-}
-
-@media screen and (max-width: 1500px) {
-  .mk-opeartion-list .ant-btn {
-    min-width: 65px;
-    .anticon {
-      display: none;
-    }
-    .anticon + span {
-      margin-left: 0px;
-    }
   }
 }
\ No newline at end of file
diff --git a/src/views/menudesign/popview/index.jsx b/src/views/menudesign/popview/index.jsx
index 496f116..fa28c25 100644
--- a/src/views/menudesign/popview/index.jsx
+++ b/src/views/menudesign/popview/index.jsx
@@ -1,7 +1,7 @@
 import React, { Component } from 'react'
 import { is, fromJS } from 'immutable'
 import PropTypes from 'prop-types'
-import { notification, Modal, Collapse, Card, Switch, Button } from 'antd'
+import { notification, Modal, Collapse, Switch, Button } from 'antd'
 import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'
 
 import MKEmitter from '@/utils/events.js'
@@ -15,6 +15,7 @@
 const SourceWrap = asyncComponent(() => import('@/menu/modulesource'))
 const Modulecell = asyncComponent(() => import('@/menu/modulecell'))
 const MenuShell = asyncComponent(() => import('@/menu/menushell'))
+const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
 const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
 const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
 const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
@@ -260,6 +261,7 @@
               <Panel header="鍩烘湰淇℃伅" key="basedata">
                 {/* 琛ㄥ悕娣诲姞 */}
                 <TableComponent config={config} updatetable={this.updatetable}/>
+                <NormalCopy />
               </Panel>
               {/* 缁勪欢娣诲姞 */}
               <Panel header="缁勪欢" key="component">
@@ -274,21 +276,17 @@
             </Collapse>
           </div>
           <div className={'menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}>
-            <Card title={
-              <div> {config.MenuName} </div>
-            } bordered={false} extra={
-              <div>
-                <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 缁勪欢鍚�</Button>
-                <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
-                <StyleCombControlButton menu={config} />
-                <PasteController insert={this.insert} />
-                <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} />
-                <Button type="primary" id="save-pop-config" onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
-                <Button type="default" disabled={menuloading} onClick={this.closeView}>杩斿洖</Button>
-              </div>
-            } style={{ width: '100%' }}>
-              {!comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
-            </Card>
+            <div className="mk-opeartion-list">
+              <div className="btn-name">{config.MenuName}</div>
+              <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 缁勪欢鍚�</Button>
+              <ReplaceField config={config} updateConfig={this.resetConfig}/>
+              <StyleCombControlButton menu={config} />
+              <PasteController insert={this.insert} />
+              <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} />
+              <Button type="primary" id="save-pop-config" onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
+              <Button type="default" disabled={menuloading} onClick={this.closeView}>杩斿洖</Button>
+            </div>
+            {!comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
           </div>
         </div>
       </div>
diff --git a/src/views/menudesign/popview/index.scss b/src/views/menudesign/popview/index.scss
index 02b8796..204bdb8 100644
--- a/src/views/menudesign/popview/index.scss
+++ b/src/views/menudesign/popview/index.scss
@@ -62,11 +62,15 @@
       width: 300px;
       background: #ffffff;
       box-shadow: 0px 2px 5px #bcbcbc;
-      overflow-y: auto;
-      overflow-x: hidden;
 
       > .ant-collapse {
+        height: 100%;
+        overflow-y: auto;
+        overflow-x: hidden;
         background-color: #ffffff;
+        border-radius: 0px;
+        padding-bottom: 30px;
+
         .ant-collapse-item.ant-collapse-item-active {
           border-bottom: 1px solid #d9d9d9;
         }
@@ -98,15 +102,15 @@
         }
       }
     }
-    .menu-setting::-webkit-scrollbar {
+    .menu-setting >.ant-collapse::-webkit-scrollbar {
       width: 4px;
     }
-    .menu-setting::-webkit-scrollbar-thumb {
+    .menu-setting >.ant-collapse::-webkit-scrollbar-thumb {
       border-radius: 5px;
       box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.08);
       background: rgba(0, 0, 0, 0.08);
     }
-    .menu-setting::-webkit-scrollbar-track {
+    .menu-setting >.ant-collapse::-webkit-scrollbar-track {
       box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
       border-radius: 3px;
       border: 1px solid rgba(0, 0, 0, 0.07);
@@ -120,39 +124,33 @@
       height: calc(100vh - 50px);
       overflow-y: auto;
 
-      > .ant-card {
-        >.ant-card-head {
-          margin-bottom: 0px;
-          position: sticky;
-          top: 0px;
-          z-index: 10;
-          background: #ffffff;
-          .ant-card-head-title {
-            color: #1890ff;
-            padding: 5px 0;
-          }
-          .ant-card-extra {
-            padding: 5px 0;
-            button {
-              margin-left: 20px;
-            }
-            .ant-switch.big {
-              min-width: 60px;
-              height: 28px;
-              line-height: 28px;
-              margin-top: -2px;
-              .ant-switch-inner {
-                font-size: 14px;
-              }
-            }
-            .ant-switch.big:after {
-              width: 24px;
-              height: 24px;
-            }
-          }
+      .mk-opeartion-list {
+        position: sticky;
+        top: 0px;
+        left: 0px;
+        right: 0px;
+        text-align: right;
+        padding: 5px 10px 8px;
+        background: #ffffff;
+        border-bottom: 1px solid #e8e8e8;
+        height: 45px;
+        z-index: 10;
+
+        .btn-name {
+          float: left;
+          color: #1890ff;
+          padding: 5px 0;
+          font-size: 16px;
         }
-        >.ant-card-body {
-          padding: 0px;
+        button {
+          margin-left: 15px;
+        }
+        button:not(.ant-switch):not(:last-child):not(:nth-last-child(2)) {
+          padding: 0px 10px;
+        }
+        .ant-switch.big {
+          transform: scale(1.15);
+          top: -2px;
         }
       }
     }
diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index 1dbe670..4867d20 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -34,7 +34,9 @@
 const TableNodes = asyncComponent(() => import('@/menu/tablenodes'))
 const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
 const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
+const LowerField = asyncComponent(() => import('@/menu/lowerField'))
 const NormalCss = asyncComponent(() => import('@/menu/normalCss'))
+const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
 const SysInterface = asyncComponent(() => import('@/menu/sysinterface'))
 const Quotecomponent = asyncComponent(() => import('@/pc/quotecomponent'))
 const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
@@ -2275,10 +2277,11 @@
                     <UrlFieldComponent config={config} updateConfig={this.updateConfig}/>
                     {/* 琛ㄥ悕娣诲姞 */}
                     <TableComponent config={config} updatetable={this.updateConfig}/>
-                    <Paragraph style={{padding: '15px 0px 0px 37px'}} copyable={{ text: MenuId }}>鑿滃崟ID</Paragraph>
-                    <Paragraph style={{padding: '0px 0px 0px 23px'}} copyable={{ text:  `${window.GLOB.baseurl}mob/index.html#/index/${sessionStorage.getItem('kei_no')}/${sessionStorage.getItem('typename')}/${sessionStorage.getItem('lang')}/${MenuId}/@BID@` }}>鑿滃崟閾炬帴</Paragraph>
+                    <Paragraph style={{padding: '15px 0px 0px 32px'}} copyable={{ text: MenuId }}>鑿滃崟ID锛�</Paragraph>
+                    <Paragraph style={{padding: '0px 0px 0px 18px'}} copyable={{ text:  `${window.GLOB.baseurl}mob/index.html#/index/${sessionStorage.getItem('kei_no')}/${sessionStorage.getItem('typename')}/${sessionStorage.getItem('lang')}/${MenuId}/@BID@` }}>鑿滃崟閾炬帴锛�</Paragraph>
                     <Paragraph style={{padding: '0px 0px 0px 18px'}}>鑿滃崟缁勪欢锛�<CopyOutlined onClick={this.copyMenu} style={{cursor: 'pointer', color: '#1890ff'}} /></Paragraph>
                     <NormalCss config={config} updateConfig={this.updateConfig}/>
+                    <NormalCopy />
                   </> : null}
                 </Panel>
                 {/* 缁勪欢娣诲姞 */}
@@ -2299,7 +2302,7 @@
               {controlshow ? <DoubleRightOutlined onClick={() => {this.setState({controlshow: false})}}/> : null}
               {!controlshow ? <DoubleLeftOutlined onClick={() => {this.setState({controlshow: true})}}/> : null}
             </div>
-            <div className="wrap">
+            <div className="wrap mk-opeartion-list">
               <Button type="primary" className={needUpdate ? 'update-tip' : ''} disabled={!config} onClick={this.submitConfig} id="save-config" loading={menuloading}>淇濆瓨</Button>
               {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
               <ArrowLeftOutlined title="鍚庨��" className="back-view" onClick={this.backView}/>
@@ -2315,7 +2318,8 @@
               <StyleCombControlButton menu={config} />
               <Button className="mk-border-green set-home" disabled={MenuId === appHomeId} data-title="褰撳墠鑿滃崟涓哄簲鐢ㄩ椤�" onClick={this.setHomeView}><HomeOutlined /> 璁句负棣栭〉</Button>
               <Button className="mk-border-purple" disabled={MenuId === appLoginId} data-title="褰撳墠鑿滃崟涓哄簲鐢ㄧ櫥褰曢〉" onClick={this.setLoginView}><LoginOutlined /> 璁句负鐧诲綍椤�</Button>
-              <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
+              <ReplaceField config={config} updateConfig={this.resetConfig}/>
+              <LowerField config={config} updateConfig={this.resetConfig}/>
               <Transfer MenuID={MenuId} />
               {config ? <Versions MenuId={MenuId} Template="webPage" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
               <Button type="default" onClick={this.closeView}>鍏抽棴</Button>
diff --git a/src/views/mobdesign/popview/index.jsx b/src/views/mobdesign/popview/index.jsx
index 15edee3..c7ce41b 100644
--- a/src/views/mobdesign/popview/index.jsx
+++ b/src/views/mobdesign/popview/index.jsx
@@ -15,6 +15,7 @@
 const MobShell = asyncComponent(() => import('@/mob/mobshell'))
 const SourceWrap = asyncComponent(() => import('@/mob/modulesource'))
 const Modulecell = asyncComponent(() => import('@/menu/modulecell'))
+const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
 const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
 const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
 const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
@@ -266,6 +267,7 @@
               <Panel header="鍩烘湰淇℃伅" forceRender className="basedata" key="basedata">
                 {/* 琛ㄥ悕娣诲姞 */}
                 <TableComponent config={config} updatetable={this.updateConfig}/>
+                <NormalCopy />
               </Panel>
               {/* 缁勪欢娣诲姞 */}
               <Panel header="缁勪欢" className="component" key="component">
@@ -285,13 +287,13 @@
             {controlshow ? <DoubleRightOutlined onClick={() => {this.setState({controlshow: false})}}/> : null}
             {!controlshow ? <DoubleLeftOutlined onClick={() => {this.setState({controlshow: true})}}/> : null}
           </div>
-          <div className="wrap">
+          <div className="wrap mk-opeartion-list">
             <Button type="primary" onClick={this.submitConfig} id="save-config" loading={menuloading}>淇濆瓨</Button>
             <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config && config.enabled} onChange={this.onEnabledChange} />
             <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 缁勪欢鍚�</Button>
             <PasteController insert={this.insert} />
             <StyleCombControlButton menu={config} />
-            <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
+            <ReplaceField config={config} updateConfig={this.resetConfig}/>
             <Button type="default" onClick={this.closeView}>杩斿洖</Button>
           </div>
         </div>
diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx
index c5fc857..b4b6958 100644
--- a/src/views/pcdesign/index.jsx
+++ b/src/views/pcdesign/index.jsx
@@ -39,7 +39,9 @@
 const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
 const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
 const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
+const LowerField = asyncComponent(() => import('@/menu/lowerField'))
 const NormalCss = asyncComponent(() => import('@/menu/normalCss'))
+const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
 const SysInterface = asyncComponent(() => import('@/menu/sysinterface'))
 const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent'))
 const PictureController = asyncComponent(() => import('@/menu/picturecontroller'))
@@ -1901,9 +1903,10 @@
                       <UrlFieldComponent config={config} updateConfig={this.updateConfig}/>
                       {/* 琛ㄥ悕娣诲姞 */}
                       <TableComponent config={config} updatetable={this.updateConfig}/>
-                      <Paragraph style={{padding: '15px 0px 0px 37px'}} copyable={{ text: MenuId }}>鑿滃崟ID</Paragraph>
+                      <Paragraph style={{padding: '15px 0px 0px 32px'}} copyable={{ text: MenuId }}>鑿滃崟ID锛�</Paragraph>
                       <Paragraph style={{padding: '0px 0px 0px 18px'}}>鑿滃崟缁勪欢锛�<CopyOutlined onClick={this.copyMenu} style={{cursor: 'pointer', color: '#1890ff'}} /></Paragraph>
                       <NormalCss config={config} updateConfig={this.updateConfig}/>
+                      <NormalCopy />
                     </> : null}
                   </Panel>
                   {/* 缁勪欢娣诲姞 */}
@@ -1924,7 +1927,7 @@
                 {controlshow ? <DoubleRightOutlined onClick={() => {sessionStorage.setItem('controlshow', 'false'); this.setState({controlshow: false})}}/> : null}
                 {!controlshow ? <DoubleLeftOutlined onClick={() => {sessionStorage.setItem('controlshow', 'true'); this.setState({controlshow: true})}}/> : null}
               </div>
-              <div className="wrap">
+              <div className="wrap mk-opeartion-list">
                 <Button type="primary" className={needUpdate ? 'update-tip' : ''} disabled={!config} id="save-config" onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
                 {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                 <ArrowLeftOutlined title="鍚庨��" className="back-view" onClick={this.backView}/>
@@ -1940,7 +1943,8 @@
                 <StyleCombControlButton menu={config} />
                 <Button className="mk-border-green" disabled={MenuId === appHomeId} data-title="褰撳墠鑿滃崟涓哄簲鐢ㄩ椤�" onClick={this.setHomeView}><HomeOutlined /> 璁句负棣栭〉</Button>
                 <Button className="mk-border-purple" disabled={MenuId === appLoginId} data-title="褰撳墠鑿滃崟涓哄簲鐢ㄧ櫥褰曢〉" onClick={this.setLoginView}><LoginOutlined/> 璁句负鐧诲綍椤�</Button>
-                <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
+                <ReplaceField config={config} updateConfig={this.resetConfig}/>
+                <LowerField config={config} updateConfig={this.resetConfig}/>
                 <Transfer MenuID={MenuId} />
                 {config ? <Versions MenuId={MenuId} Template="webPage" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
                 <Button type="default" onClick={this.closeView}>鍏抽棴</Button>
diff --git a/src/views/pcdesign/index.scss b/src/views/pcdesign/index.scss
index b9138e1..3bbcf6e 100644
--- a/src/views/pcdesign/index.scss
+++ b/src/views/pcdesign/index.scss
@@ -214,6 +214,7 @@
       height: 100%;
       padding: 20px 10px;
       overflow-y: auto;
+      overflow-x: hidden;
     }
     .wrap::-webkit-scrollbar {
       width: 2px;
diff --git a/src/views/tabledesign/index.jsx b/src/views/tabledesign/index.jsx
index be78503..122600d 100644
--- a/src/views/tabledesign/index.jsx
+++ b/src/views/tabledesign/index.jsx
@@ -4,8 +4,8 @@
 import { is, fromJS } from 'immutable'
 import moment from 'moment'
 import HTML5Backend from 'react-dnd-html5-backend'
-import { notification, Modal, Collapse, Card, Switch, Button, Typography, message } from 'antd'
-import { DoubleLeftOutlined, DoubleRightOutlined, CopyOutlined } from '@ant-design/icons'
+import { notification, Modal, Collapse, Card, Switch, Button, Typography, message, Dropdown } from 'antd'
+import { DoubleLeftOutlined, DoubleRightOutlined, CopyOutlined, DownOutlined } from '@ant-design/icons'
 import md5 from 'md5'
 
 import Api from '@/api'
@@ -33,10 +33,12 @@
 const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
 const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
 const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
+const LowerField = asyncComponent(() => import('@/menu/lowerField'))
 const Debug = asyncComponent(() => import('@/menu/debug'))
 const Versions = asyncComponent(() => import('@/menu/versions'))
 const Transfer = asyncComponent(() => import('@/menu/transfer'))
 const Unattended = asyncComponent(() => import('@/templates/zshare/unattended'))
+const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
 const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent'))
 const ModalController = asyncComponent(() => import('@/menu/modalconfig/controller'))
 const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
@@ -1066,8 +1068,9 @@
                       />
                       {/* 琛ㄥ悕娣诲姞 */}
                       <TableComponent config={config} updatetable={this.updateConfig}/>
-                      <Paragraph style={{padding: '15px 0px 0px 18px'}} copyable={{ text: MenuId }}>鑿滃崟ID</Paragraph>
-                      <Paragraph style={{padding: '0px 0px 0px 5px'}}>鑿滃崟缁勪欢 <CopyOutlined onClick={this.copyMenu} style={{marginLeft: '3px', cursor: 'pointer', color: '#1890ff'}} /></Paragraph>
+                      <Paragraph style={{padding: '15px 0px 0px 32px'}} copyable={{ text: MenuId }}>鑿滃崟ID锛�</Paragraph>
+                      <Paragraph style={{padding: '0px 0px 0px 18px'}}>鑿滃崟缁勪欢锛�<CopyOutlined onClick={this.copyMenu} style={{cursor: 'pointer', color: '#1890ff'}} /></Paragraph>
+                      <NormalCopy />
                     </> : null}
                   </Panel>
                   <Panel header="鎼滅储" key="search">
@@ -1095,8 +1098,13 @@
                     {config ? <Unattended config={config} updateConfig={this.updateConfig}/> : null}
                     {config ? <Versions MenuId={MenuId} Template="BaseTable" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
                     <TableNodes config={config} />
-                    <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                     <PasteBaseTable type="page" insert={this.insert}/>
+                    {config ? <Dropdown placement="bottomCenter" overlay={<div className="mk-opeartion-dropdown-wrap">
+                      <ReplaceField config={config} updateConfig={this.resetConfig}/>
+                      <LowerField config={config} updateConfig={this.resetConfig}/>
+                    </div>} trigger={['hover']}>
+                      <div className="mk-button-more">鏇村<DownOutlined/></div>
+                    </Dropdown> : null}
                     {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                     <Button type="primary" id="save-config" disabled={!config} onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
                     <Button type="default" disabled={menuloading} onClick={this.closeView}>鍏抽棴</Button>
diff --git a/src/views/tabledesign/index.scss b/src/views/tabledesign/index.scss
index 84954ae..8ec16e2 100644
--- a/src/views/tabledesign/index.scss
+++ b/src/views/tabledesign/index.scss
@@ -151,8 +151,25 @@
             button {
               margin-left: 15px;
             }
-            .mk-opeartion-list button:not(.ant-switch):not(:last-child):not(:nth-last-child(2)) {
-              padding: 0px 10px;
+            .mk-opeartion-list {
+              button:not(.ant-switch):not(:last-child):not(:nth-last-child(2)) {
+                padding: 0px 10px;
+              }
+              .mk-button-more {
+                display: inline-block;
+                height: 32px;
+                border: 1px solid #26C281;
+                color: #26C281;
+                line-height: 32px;
+                padding: 0 10px 0px 20px;
+                border-radius: 4px;
+                cursor: pointer;
+                vertical-align: top;
+                margin-left: 15px;
+                .anticon-down {
+                  margin-left: 3px;
+                }
+              }
             }
             .ant-switch.big {
               min-width: 60px;
diff --git a/src/views/tabledesign/popview/index.jsx b/src/views/tabledesign/popview/index.jsx
index dbac3df..a824b3b 100644
--- a/src/views/tabledesign/popview/index.jsx
+++ b/src/views/tabledesign/popview/index.jsx
@@ -15,6 +15,7 @@
 
 const MenuShell = asyncComponent(() => import('@/menu/tableshell'))
 const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
+const NormalCopy = asyncComponent(() => import('@/menu/normalCopy'))
 const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
 const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
 
@@ -195,6 +196,7 @@
               <Panel header="鍩烘湰淇℃伅" key="basedata">
                 {/* 琛ㄥ悕娣诲姞 */}
                 <TableComponent config={config} updatetable={this.updatetable}/>
+                <NormalCopy />
               </Panel>
               {/* 缁勪欢娣诲姞 */}
               <Panel header="鎼滅储" key="search">
@@ -216,7 +218,7 @@
               <div> {config.MenuName} </div>
             } bordered={false} extra={
               <div>
-                <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
+                <ReplaceField config={config} updateConfig={this.resetConfig}/>
                 <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} />
                 <Button type="primary" id="save-pop-config" onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
                 <Button type="default" disabled={menuloading} onClick={this.closeView}>杩斿洖</Button>

--
Gitblit v1.8.0