From 79e4981aa6cc9354276fc54cdf6d14eb08ab7fee Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期四, 22 六月 2023 15:59:04 +0800
Subject: [PATCH] Merge branch 'develop' of ssh://121.36.20.145:29418/~jinfei/pc-plat into develop

---
 src/templates/zshare/modalform/index.jsx                                           |    9 
 src/menu/components/card/cardcellcomponent/dragaction/action.jsx                   |   12 
 src/menu/components/card/cardcellcomponent/elementform/index.jsx                   |   11 
 src/menu/components/card/balcony/options.jsx                                       |   22 
 src/menu/components/chart/antv-X6/index.scss                                       |  209 +
 src/tabviews/custom/popview/index.jsx                                              |  101 
 src/menu/components/table/edit-table/columns/editColumn/index.scss                 |    6 
 src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx  |    1 
 src/templates/sharecomponent/tablecomponent/index.jsx                              |   29 
 src/tabviews/zshare/actionList/newpagebutton/index.jsx                             |   13 
 src/views/design/sidemenu/index.jsx                                                |    2 
 src/mob/modalconfig/index.jsx                                                      |    4 
 src/tabviews/commontable/index.jsx                                                 |  208 -
 src/tabviews/zshare/topSearch/mkCheckCard/index.scss                               |  188 +
 src/components/header/loginform.jsx                                                |    4 
 src/menu/components/table/edit-table/columns/editColumn/index.jsx                  |    3 
 src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx               |   34 
 src/menu/datasource/verifycard/index.jsx                                           |    5 
 src/views/menudesign/popview/menuform/index.jsx                                    |    5 
 src/assets/css/main.scss                                                           |   10 
 src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx             |   41 
 src/tabviews/custom/components/table/edit-table/index.scss                         |    5 
 src/menu/components/form/formaction/formconfig.jsx                                 |   83 
 src/tabviews/zshare/topSearch/mkCheckCard/index.jsx                                |  336 ++
 src/tabviews/custom/components/card/cardcellList/index.jsx                         |   36 
 src/tabviews/custom/components/card/prop-card/index.jsx                            |   54 
 src/tabviews/zshare/mutilform/mkCheckCard/index.scss                               |   19 
 src/menu/components/chart/antv-G6/index.scss                                       |   23 
 src/views/mkiframe/index.scss                                                      |    7 
 src/menu/components/card/cardcellcomponent/index.jsx                               |   34 
 src/menu/components/card/data-card/options.jsx                                     |   49 
 src/tabviews/custom/components/table/normal-table/index.jsx                        |   61 
 src/tabviews/custom/components/timeline/normal-timeline/index.jsx                  |   35 
 src/menu/components/card/cardcomponent/index.jsx                                   |    1 
 src/templates/subtableconfig/index.jsx                                             |    2 
 src/tabviews/custom/components/table/edit-table/normalTable/index.jsx              |  134 
 src/templates/sharecomponent/actioncomponent/verifymegvii/index.jsx                |   32 
 src/components/breadview/index.jsx                                                 |    5 
 src/tabviews/zshare/mutilform/index.jsx                                            |   14 
 src/templates/zshare/modalform/index.scss                                          |    6 
 src/menu/components/share/actioncomponent/actionform/index.jsx                     |   42 
 src/tabviews/custom/index.jsx                                                      |  101 
 src/menu/components/card/prop-card/index.jsx                                       |    4 
 src/menu/components/table/normal-table/columns/index.jsx                           |  138 
 src/menu/components/table/edit-table/columns/index.jsx                             |  144 
 package-lock.json                                                                  |   56 
 src/menu/components/card/cardcellcomponent/dragaction/index.scss                   |    1 
 src/views/login/loginform.jsx                                                      |    7 
 src/menu/components/share/actioncomponent/dragaction/card.jsx                      |    6 
 src/tabviews/zshare/topSearch/index.jsx                                            |  108 
 src/menu/components/form/formaction/actionform/index.jsx                           |  238 
 src/tabviews/custom/components/chart/antv-G6/index.jsx                             |  107 
 src/templates/comtableconfig/index.jsx                                             |    2 
 src/tabviews/zshare/actionList/exceloutbutton/index.jsx                            |   12 
 src/views/design/sidemenu/thdmenuform/index.jsx                                    |   15 
 src/menu/components/card/cardcellcomponent/dragaction/card.jsx                     |    3 
 src/views/basedesign/index.jsx                                                     |    8 
 src/menu/modalconfig/tablecomponent/index.scss                                     |   36 
 src/tabviews/custom/components/table/edit-table/index.jsx                          |   88 
 src/views/tabledesign/index.jsx                                                    |   19 
 src/api/index.js                                                                   |   97 
 src/tabviews/zshare/topSearch/index.scss                                           |   12 
 src/tabviews/subtable/index.jsx                                                    |  218 -
 src/tabviews/custom/components/iframe/index.jsx                                    |    6 
 src/menu/sysinterface/index.jsx                                                    |    1 
 src/tabviews/custom/components/card/table-card/index.jsx                           |   19 
 src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx                 |   32 
 src/tabviews/zshare/mutilform/mkCheckCard/index.jsx                                |   29 
 src/views/pcdesign/index.jsx                                                       |   18 
 src/menu/components/share/actioncomponent/index.jsx                                |    4 
 src/menu/components/card/cardsimplecomponent/index.jsx                             |    1 
 src/components/sidemenu/index.jsx                                                  |    2 
 src/components/pasteboard/index.jsx                                                |  134 
 src/views/login/index.jsx                                                          |   14 
 src/utils/utils-datamanage.js                                                      |  304 --
 src/tabviews/custom/components/code/sand-box/index.jsx                             |   19 
 src/templates/zshare/editTable/index.jsx                                           |  190 
 src/templates/zshare/modalform/fieldtable/index.jsx                                |   20 
 src/menu/components/table/edit-table/columns/tableIn/index.jsx                     |   75 
 src/menu/components/editor/braft-editor/options.jsx                                |   23 
 src/tabviews/custom/components/tree/antd-tree/index.jsx                            |    4 
 src/tabviews/zshare/actionList/popupbutton/index.jsx                               |   12 
 src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx                      |  140 
 src/tabviews/custom/components/tabs/antv-tabs/index.jsx                            |    4 
 src/utils/utils-custom.js                                                          |   25 
 src/templates/comtableconfig/updatetable/index.jsx                                 |   99 
 src/views/mkiframe/index.jsx                                                       |   58 
 src/templates/modalconfig/checkCard/index.scss                                     |   11 
 src/views/menudesign/homeform/index.jsx                                            |    5 
 src/tabviews/zshare/actionList/excelInbutton/index.jsx                             |   14 
 src/views/menudesign/menuform/index.jsx                                            |    5 
 src/templates/modalconfig/checkCard/index.jsx                                      |    6 
 src/templates/zshare/menuform/index.jsx                                            |    2 
 src/tabviews/basetable/index.jsx                                                   |   54 
 src/menu/menushell/card.jsx                                                        |   12 
 src/tabviews/subtabtable/index.jsx                                                 |  207 -
 src/menu/components/iframe/options.jsx                                             |    3 
 src/tabviews/zshare/actionList/normalbutton/index.jsx                              |  104 
 src/views/design/sidemenu/editthdmenu/index.jsx                                    |    2 
 src/views/mobdesign/index.jsx                                                      |   21 
 src/views/menudesign/index.jsx                                                     |   19 
 src/menu/modulesource/option.jsx                                                   |    2 
 src/tabviews/custom/components/card/data-card/index.jsx                            |   36 
 src/components/normalform/modalform/mkSelect/index.jsx                             |   11 
 src/mob/colorsketch/index.jsx                                                      |    2 
 src/templates/zshare/modalform/datatable/index.jsx                                 |   13 
 src/menu/components/share/actioncomponent/formconfig.jsx                           |  201 
 src/templates/sharecomponent/actioncomponent/actionform/index.jsx                  |    2 
 src/menu/modalconfig/tablecomponent/index.jsx                                      |  163 +
 src/menu/components/card/double-data-card/index.jsx                                |    2 
 src/views/login/logincloudform.jsx                                                 |    2 
 src/menu/stylecontroller/styleInput/index.jsx                                      |    3 
 src/router/index.js                                                                |    3 
 src/menu/components/card/data-card/index.jsx                                       |    2 
 src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx                      |    6 
 src/menu/components/table/base-table/columns/index.jsx                             |  140 
 src/tabviews/zshare/topSearch/advanceform/index.scss                               |   12 
 src/templates/sharecomponent/searchcomponent/index.scss                            |   12 
 src/templates/sharecomponent/searchcomponent/searchform/index.jsx                  |   22 
 src/components/tabview/index.jsx                                                   |    5 
 src/components/tabview/index.scss                                                  |    5 
 src/tabviews/custom/components/table/base-table/index.jsx                          |   29 
 src/tabviews/custom/components/card/double-data-card/index.scss                    |    1 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx |   31 
 src/menu/components/chart/antv-G6/index.jsx                                        |    8 
 src/components/header/index.jsx                                                    |   35 
 src/pc/components/navbar/normal-navbar/menusetting/menutable/index.scss            |    4 
 src/views/mobdesign/menuform/index.jsx                                             |    5 
 src/views/pcdesign/menuform/index.jsx                                              |    5 
 src/tabviews/custom/components/card/double-data-card/index.jsx                     |   82 
 src/tabviews/custom/components/card/cardItem/index.jsx                             |   19 
 src/menu/components/chart/antv-X6/index.jsx                                        | 1813 +++--------
 src/tabviews/calendar/index.jsx                                                    |   20 
 src/views/mobdesign/popview/menuform/index.jsx                                     |    5 
 src/views/tabledesign/menuform/index.jsx                                           |    2 
 src/tabviews/custom/components/share/normalTable/index.jsx                         |    2 
 src/tabviews/iframe/index.jsx                                                      |    1 
 src/menu/components/chart/antv-X6/nodeupdate/index.jsx                             |  288 +
 src/tabviews/zshare/actionList/normalbutton/mkcounter/index.jsx                    |    6 
 src/components/breadview/index.scss                                                |    5 
 src/tabviews/custom/components/card/data-card/index.scss                           |    1 
 src/menu/components/search/main-search/index.scss                                  |   12 
 src/utils/utils.js                                                                 |    2 
 src/tabviews/custom/components/card/table-card/index.scss                          |    7 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx              |   32 
 src/components/pasteboard/index.scss                                               |    0 
 src/menu/components/card/balcony/index.jsx                                         |    1 
 src/components/normalform/modalform/index.jsx                                      |   22 
 src/menu/stylecontroller/index.jsx                                                 |  199 +
 src/templates/zshare/formconfig.jsx                                                |  187 
 src/templates/zshare/verifycard/index.jsx                                          |   32 
 src/menu/components/chart/antv-X6/nodeupdate/index.scss                            |   67 
 src/tabviews/custom/components/table/edit-table/normalTable/index.scss             |   51 
 /dev/null                                                                          |   53 
 src/menu/components/card/cardcellcomponent/formconfig.jsx                          |   19 
 src/menu/modalconfig/index.jsx                                                     |    4 
 src/tabviews/custom/components/card/balcony/index.jsx                              |   15 
 package.json                                                                       |   12 
 src/menu/menushell/index.jsx                                                       |    1 
 src/utils/option.js                                                                |    8 
 160 files changed, 4,953 insertions(+), 3,790 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index f159b70..94e6602 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -624,9 +624,9 @@
       }
     },
     "@antv/x6": {
-      "version": "2.10.1",
-      "resolved": "https://registry.npmjs.org/@antv/x6/-/x6-2.10.1.tgz",
-      "integrity": "sha512-38Fi9Qgnp+ylTrnRnhrGsc2cxsDosULbN6toVs9GjVpOguzq3oxRUblzO6dcnJhbzXfZxIcB/IuQt3pYpXJBKA==",
+      "version": "2.11.1",
+      "resolved": "https://registry.npmjs.org/@antv/x6/-/x6-2.11.1.tgz",
+      "integrity": "sha512-DwyuT/zuTEhwsnKwCj67cadwLeEbB5jfdCxrkTnEm6pg0+vT3FinbF71IK7SHoY8d4HOHl+sJt7ikJfr61JqLw==",
       "requires": {
         "@antv/x6-common": "^2.0.12",
         "@antv/x6-geometry": "^2.0.5",
@@ -646,6 +646,54 @@
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/@antv/x6-geometry/-/x6-geometry-2.0.5.tgz",
       "integrity": "sha512-MId6riEQkxphBpVeTcL4ZNXL4lScyvDEPLyIafvWMcWNTGK0jgkK7N20XSzqt8ltJb0mGUso5s56mrk8ysHu2A=="
+    },
+    "@antv/x6-plugin-clipboard": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npmjs.org/@antv/x6-plugin-clipboard/-/x6-plugin-clipboard-2.1.6.tgz",
+      "integrity": "sha512-roZPLnZx6PK8MBvee0QMo90fz/TXeF0WNe4EGin2NBq5M1I5XTWrYvA6N2XVIiWAAI67gjQeEE8TpkL7f8QdqA=="
+    },
+    "@antv/x6-plugin-dnd": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@antv/x6-plugin-dnd/-/x6-plugin-dnd-2.0.5.tgz",
+      "integrity": "sha512-g8GGJS2XmM8C59juOBiFqaR/f8i8y8tqw9sJNwta7s1Phh3hwDd7o4kk36Kk5eTKkfZfnjEyWHMOqp/h+EDibQ=="
+    },
+    "@antv/x6-plugin-history": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/@antv/x6-plugin-history/-/x6-plugin-history-2.2.3.tgz",
+      "integrity": "sha512-yiv5e7CQKm1HrJe7je4iWjkzDzU+I0WsyL8En2j0UwXJrUNaKYyv4BkRg2tvyi52hydxidMgi3tNnNQHEZwoMg=="
+    },
+    "@antv/x6-plugin-keyboard": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/@antv/x6-plugin-keyboard/-/x6-plugin-keyboard-2.2.1.tgz",
+      "integrity": "sha512-sqfN0h4txVO211uIeKBd3zQ/IN2zPzDThWNTEhRx7Lecg1fO7uRXWBbOA48j3EgpRFXVexdSzIEVJEx+IWUdYw==",
+      "requires": {
+        "mousetrap": "^1.6.5"
+      }
+    },
+    "@antv/x6-plugin-scroller": {
+      "version": "2.0.9",
+      "resolved": "https://registry.npmjs.org/@antv/x6-plugin-scroller/-/x6-plugin-scroller-2.0.9.tgz",
+      "integrity": "sha512-f3fluvSIbZBp+c5iKyidAoz19i0beWOnPA0CPfu/K4C+Jf1eWNgaFXbN3hcHPQRvFRJiPtvPApK30aCaik9Omg=="
+    },
+    "@antv/x6-plugin-selection": {
+      "version": "2.1.7",
+      "resolved": "https://registry.npmjs.org/@antv/x6-plugin-selection/-/x6-plugin-selection-2.1.7.tgz",
+      "integrity": "sha512-ODfYLNwKSaLgIYMYfMW4dYQ9KKFOVBEdH0BzvyG8mfRol+JtZuyrm4BRbAvMryQKHrSxs4JCYXTFd2F7ZTuxLQ=="
+    },
+    "@antv/x6-plugin-snapline": {
+      "version": "2.1.7",
+      "resolved": "https://registry.npmjs.org/@antv/x6-plugin-snapline/-/x6-plugin-snapline-2.1.7.tgz",
+      "integrity": "sha512-AsysoCb9vES0U2USNhEpYuO/W8I0aYfkhlbee5Kt4NYiMfQfZKQyqW/YjDVaS2pm38C1NKu1LdPVk/BBr4CasA=="
+    },
+    "@antv/x6-plugin-stencil": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@antv/x6-plugin-stencil/-/x6-plugin-stencil-2.0.3.tgz",
+      "integrity": "sha512-pQkTIbMCezTqo38fofuFGnI30Rk0j5gHc/+Ndml1RHVEV0p8i1HGRAR5we7SVTcT56AHlP46H+oRFReQmVgvKA=="
+    },
+    "@antv/x6-plugin-transform": {
+      "version": "2.1.7",
+      "resolved": "https://registry.npmjs.org/@antv/x6-plugin-transform/-/x6-plugin-transform-2.1.7.tgz",
+      "integrity": "sha512-idzBr8/Bcw8zHQUSNS0Y8VSNMigCWiUuiwqO572Ac/P2tMfP6Ot2SahEYHGUOD2NEMPr95q4JMZc+Evvt4JFTw=="
     },
     "@antv/x6-react-components": {
       "version": "1.1.15",
@@ -11290,7 +11338,7 @@
     "insert-css": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-2.0.0.tgz",
-      "integrity": "sha1-610Ql7dUL0x56jBg067gfQU4gPQ="
+      "integrity": "sha512-xGq5ISgcUP5cvGkS2MMFLtPDBtrtQPSFfC6gA6U8wHKqfjTIMZLZNxOItQnoSjdOzlXOLU/yD32RKC4SvjNbtA=="
     },
     "internal-ip": {
       "version": "4.3.0",
diff --git a/package.json b/package.json
index c34f77a..ab2d13a 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,16 @@
     "@antv/g2": "^4.1.34",
     "@antv/g6": "^4.6.4",
     "@antv/util": "^2.0.17",
-    "@antv/x6": "^2.10.1",
+    "@antv/x6": "^2.11.1",
+    "@antv/x6-plugin-clipboard": "^2.1.6",
+    "@antv/x6-plugin-dnd": "^2.0.5",
+    "@antv/x6-plugin-history": "^2.2.3",
+    "@antv/x6-plugin-keyboard": "^2.2.1",
+    "@antv/x6-plugin-scroller": "^2.0.9",
+    "@antv/x6-plugin-selection": "^2.1.7",
+    "@antv/x6-plugin-snapline": "^2.1.7",
+    "@antv/x6-plugin-stencil": "^2.0.3",
+    "@antv/x6-plugin-transform": "^2.1.7",
     "@antv/xflow": "^1.0.50",
     "@babel/core": "7.5.5",
     "@svgr/webpack": "4.3.2",
@@ -55,6 +64,7 @@
     "identity-obj-proxy": "3.0.0",
     "immutability-helper": "^3.0.1",
     "immutable": "^4.0.0-rc.12",
+    "insert-css": "^2.0.0",
     "is-wsl": "^1.1.0",
     "jest": "24.8.0",
     "jest-environment-jsdom-fourteen": "0.1.0",
diff --git a/src/api/index.js b/src/api/index.js
index 2f79f5e..efaab37 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -23,19 +23,11 @@
 axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
 axios.defaults.withCredentials = false
 
-axios.interceptors.request.use((config) => {
-  if (/LoginAndRedirect|getjsonresult|wxNativePay|postek/ig.test(config.url)) {
-    config.data = qs.stringify(config.data)
-  } else if (/\/doupload|\/dopreload|\/upload/.test(config.url)) {
-    config.headers = { 'Content-Type': 'multipart/form-data' }
-  } else if (config.method === 'post' && config.data) {
-    config.data = JSON.stringify(config.data)
-  }
-
-  return config
-}, (error) => {
-  return Promise.reject(error)
-})
+// axios.interceptors.request.use((config) => {
+//   return config
+// }, (error) => {
+//   return Promise.reject(error)
+// })
 
 const setCurrentUrl = (res) => {
   if (!!(window.history && window.history.pushState)) {
@@ -49,6 +41,10 @@
 axios.interceptors.response.use((response) => {
   if (response.data.ErrCode === 'LoginError') {
     if (window.debugger === true) {
+      response.data.ErrCode = 'E'
+      return Promise.resolve(response.data)
+    } else if (window.GLOB.developing) {
+      sessionStorage.setItem('devError', 'true')
       response.data.ErrCode = 'E'
       return Promise.resolve(response.data)
     } else if (!sessionStorage.getItem('loginError')) {
@@ -91,7 +87,7 @@
     return axios({
       url: `/webapi/dostar${param.func ? '/' + param.func : ''}`,
       method: 'post',
-      data: param
+      data: JSON.stringify(param)
     })
   }
 
@@ -165,38 +161,8 @@
 
   /**
    * @description 鐩存帴璇锋眰
-   * @param {Object} param 鏌ヨ鍙婃彁浜ゅ弬鏁�
    */
-  directRequest (url, method = 'post', param, cross) {
-    if (cross === 'true' && param) {
-      return axios({
-        url,
-        method,
-        data: param
-      })
-    } else if (cross === 'true') {
-      return axios({
-        url,
-        method
-      })
-    }
-
-    let params = { method: 'post' }
-    let _url = url
-
-    if (method === 'get' && param) {
-      let keys = Object.keys(param).map(key => `${key}=${param[key]}`)
-      keys = keys.join('&')
-      if (keys) {
-        _url = _url + '?' + keys
-      }
-    } else if (method === 'post' && param) {
-      params.data = param
-    }
-
-    _url = _url.replace(/&/ig, '%26')
-    params.url = '/trans/redirect?rd=' + _url + '&method=' + method
-
+  directRequest (params) {
     return axios(params)
   }
 
@@ -231,7 +197,7 @@
       param.thd_party_openid = openid
       param.thd_party_appid = appid
       param.id = scanId
-    } else if (binding_type === 'login_check') { // appid 姝ゆ椂涓虹洰鏍�
+    } else if (binding_type === 'login_check') { // appid 姝ゆ椂涓虹洰鏍囧湴鍧�
       param.v_type = 'login_check'
       param.LoginUID = sessionStorage.getItem('LoginUID') || ''
       url = appid.replace(/\/webapi(.*)/, '/webapi/dologon/s_visitor_login')
@@ -254,7 +220,7 @@
     return axios({
       url: url,
       method: 'post',
-      data: param
+      data: JSON.stringify(param)
     })
   }
 
@@ -293,7 +259,7 @@
     return axios({
       url,
       method: 'post',
-      data: param
+      data: JSON.stringify(param)
     })
   }
 
@@ -348,7 +314,7 @@
     return axios({
       url,
       method: 'post',
-      data: param
+      data: JSON.stringify(param)
     })
   }
 
@@ -504,7 +470,7 @@
     return axios({
       url,
       method: 'post',
-      data: param
+      data: JSON.stringify(param)
     })
   }
 
@@ -528,7 +494,7 @@
     return axios({
       url: `${url}/${param.func}`,
       method: 'post',
-      data: param
+      data: JSON.stringify(param)
     })
   }
 
@@ -560,7 +526,7 @@
     return axios({
       url: `${url}${param.func ? '/' + param.func : ''}`,
       method: 'post',
-      data: param
+      data: JSON.stringify(param)
     })
   }
 
@@ -600,7 +566,7 @@
           axios({
             url: `${url}${param.func ? '/' + param.func : ''}`,
             method: 'post',
-            data: param
+            data: JSON.stringify(param)
           }).then(res => {
             if (res.status && window.GLOB.IndexDB) {
               let msg = {
@@ -626,7 +592,7 @@
         axios({
           url: `${url}${param.func ? '/' + param.func : ''}`,
           method: 'post',
-          data: param
+          data: JSON.stringify(param)
         }).then(res => {
           if (res.status) {
             window.GLOB.CacheMap.set(key, res)
@@ -725,7 +691,7 @@
         axios({
           url: `${url}${param.func ? '/' + param.func : ''}`,
           method: 'post',
-          data: param
+          data: JSON.stringify(param)
         }).then(res => {
           if (res.status) {
             window.GLOB.CacheMap.set(_param, res)
@@ -789,7 +755,7 @@
       axios({
         url: token.interface,
         method: 'post',
-        data: param
+        data: JSON.stringify(param)
       }).then(res => {
         _resolve(res)
       })
@@ -818,7 +784,7 @@
       axios({
         url,
         method: 'post',
-        data: _param
+        data: JSON.stringify(_param)
       }).then(result => {
         if (result.status) {
           window.GLOB.OuterToken[token.interface] = {
@@ -836,7 +802,7 @@
           axios({
             url: token.interface,
             method: 'post',
-            data: param
+            data: JSON.stringify(param)
           }).then(res => {
             _resolve(res)
           })
@@ -908,7 +874,7 @@
         return axios({
           url: `${url}${param.func ? '/' + param.func : ''}`,
           method: 'post',
-          data: param
+          data: JSON.stringify(param)
         })
       }
 
@@ -919,7 +885,7 @@
             axios({
               url: `${url}${param.func ? '/' + param.func : ''}`,
               method: 'post',
-              data: param
+              data: JSON.stringify(param)
             }).then(result => {
               resolve(result)
             })
@@ -932,7 +898,7 @@
       return axios({
         url: `${url}${param.func ? '/' + param.func : ''}`,
         method: 'post',
-        data: param
+        data: JSON.stringify(param)
       })
     }
   }
@@ -973,7 +939,7 @@
     return axios({
       url,
       method: 'post',
-      data: param
+      data: JSON.stringify(param)
     })
   }
 
@@ -984,6 +950,7 @@
     return axios({
       url: '/webapi/doupload',
       method: 'post',
+      headers: { 'Content-Type': 'multipart/form-data' },
       data: param
     })
   }
@@ -995,6 +962,7 @@
     return axios({
       url: '/webapi/dopreload',
       method: 'post',
+      headers: { 'Content-Type': 'multipart/form-data' },
       data: param
     })
   }
@@ -1022,6 +990,7 @@
     return axios({
       url: _url,
       method: 'post',
+      headers: { 'Content-Type': 'multipart/form-data' },
       data: param
     })
   }
@@ -1035,7 +1004,7 @@
     return axios({
       url: _url,
       method: 'post',
-      data: param
+      data: qs.stringify(param)
     })
   }
 
@@ -1043,7 +1012,7 @@
     return axios({
       url: 'http://127.0.0.1:888/postek/print',
       method: 'post',
-      data: data
+      data: qs.stringify(data)
     })
   }
 }
diff --git a/src/assets/css/main.scss b/src/assets/css/main.scss
index 6f5c18a..fca5df4 100644
--- a/src/assets/css/main.scss
+++ b/src/assets/css/main.scss
@@ -509,4 +509,14 @@
 
 .component-wrap >.ant-col {
   min-height: 0;
+}
+
+.ant-col.ant-col-0 {
+  display: inline-block;
+}
+
+.ant-dropdown {
+  .ant-dropdown-menu-item:hover, .ant-dropdown-menu-submenu-title:hover {
+    background-color: var(--mk-sys-color1);
+  }
 }
\ No newline at end of file
diff --git a/src/components/breadview/index.jsx b/src/components/breadview/index.jsx
index b1f59ca..a193961 100644
--- a/src/components/breadview/index.jsx
+++ b/src/components/breadview/index.jsx
@@ -15,7 +15,6 @@
 const CustomPage = asyncComponent(() => import('@/tabviews/custom'))
 const CommonTable = asyncComponent(() => import('@/tabviews/commontable'))
 const BaseTable = asyncComponent(() => import('@/tabviews/basetable'))
-const CalendarPage = asyncComponent(() => import('@/tabviews/calendar'))
 const TreePage = asyncComponent(() => import('@/tabviews/treepage'))
 const Iframe = asyncComponent(() => import('@/tabviews/iframe'))
 const RoleManage = asyncComponent(() => import('@/tabviews/rolemanage'))
@@ -99,12 +98,10 @@
       return (<CommonTable MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param} changeTemp={this.changeTemp}/>)
     } else if (view.type === 'TreePage') {
       return (<TreePage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
-    } else if (view.type === 'CalendarPage') {
-      return (<CalendarPage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
     } else if (view.type === 'FormTab') {
       return (<FormTab MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
     } else if (view.type === 'iframe') {
-      return (<Iframe key={view.MenuID} MenuID={view.MenuID} MenuNo={view.MenuNo} title={view.MenuName} MenuName={view.MenuName} url={window.GLOB.baseurl + 'zh-CN/' + view.LinkUrl}/>)
+      return (<Iframe key={view.MenuID} MenuID={view.MenuID} title={view.MenuName} url={view.src}/>)
     } else {
       return (<NotFount key={view.MenuID} />)
     }
diff --git a/src/components/breadview/index.scss b/src/components/breadview/index.scss
index 810603f..84c6567 100644
--- a/src/components/breadview/index.scss
+++ b/src/components/breadview/index.scss
@@ -30,10 +30,11 @@
   }
   iframe {
     width: 100%;
-    height: calc(100vh - 115px);
+    height: calc(100vh - 92px);
     overflow-y: scroll;
     border: 0;
-    margin-top: 16px;
+    margin: 0px;
+    vertical-align: top;
   }
   .ant-back-top {
     bottom: 10px;
diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index def0339..d53c6ed 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -80,8 +80,10 @@
 
   changeMenu (value) {
     // 涓昏彍鍗曞垏鎹�
-    if (value.OpenType === 'outpage') {
-      window.open(value.linkUrl)
+    if (value.OpenType === 'newpage') {
+      window.open(value.src)
+    } else if (value.OpenType === 'newtab') {
+      MKEmitter.emit('modifyTabs', value)
     } else if (value.OpenType === 'menu') {
       this.props.modifyMainMenu(value)
     }
@@ -188,8 +190,13 @@
           let PageParam = JSON.parse(fst.PageParam)
 
           if (PageParam.OpenType === 'outpage' && PageParam.linkUrl) {
-            fstItem.OpenType = 'outpage'
-            fstItem.linkUrl = PageParam.linkUrl
+            fstItem.OpenType = 'newpage'
+            fstItem.src = PageParam.linkUrl
+            if (/#\/iframe\//.test(fstItem.src)) {
+              fstItem.src = fstItem.src.replace(/@userid@/ig, sessionStorage.getItem('UserID')).replace(/@loginuid@/ig, sessionStorage.getItem('LoginUID'))
+              fstItem.type = 'iframe'
+              fstItem.OpenType = 'newtab'
+            }
           }
         } catch (e) {}
       }
@@ -237,16 +244,20 @@
                   trdItem.hidden = PageParam.hidden || 'false'
 
                   if (trdItem.type === 'NewPage') {
+                    trdItem.OpenType = 'newpage'
                     trdItem.src = PageParam.url || ''
+                    if (/#\/iframe\//.test(trdItem.src)) {
+                      trdItem.src = trdItem.src.replace(/@userid@/ig, sessionStorage.getItem('UserID')).replace(/@loginuid@/ig, sessionStorage.getItem('LoginUID'))
+                      trdItem.type = 'iframe'
+                      trdItem.OpenType = 'newtab'
+                    }
+                  } else {
+                    trdItem.src = '#/tab/' + trd.MenuID
                   }
                 } catch (e) {}
-              }
-
-              if (trdItem.type !== 'NewPage') {
+              } else {
                 trdItem.src = '#/tab/' + trd.MenuID
               }
-
-              trdItem.OpenType = trdItem.OpenType.toLowerCase() // NewPage涓烘墦寮�澶栭儴椤甸潰鍦板潃
 
               if (names.has(trdItem.menu_name)) {
                 doublenames.set(trdItem.menu_name, true)
@@ -482,8 +493,10 @@
 
   changeVerMenu(menu, type) {
     if (type === 'first') {
-      if (menu.OpenType === 'outpage') {
-        window.open(menu.linkUrl)
+      if (menu.OpenType === 'newpage') {
+        window.open(menu.src)
+      } else if (menu.OpenType === 'newtab') {
+        MKEmitter.emit('modifyTabs', menu)
       }
     } else {
       if (menu.OpenType === 'newpage') {
diff --git a/src/components/header/loginform.jsx b/src/components/header/loginform.jsx
index 45a57c0..b20fc13 100644
--- a/src/components/header/loginform.jsx
+++ b/src/components/header/loginform.jsx
@@ -58,6 +58,10 @@
           if (oripassword && values.password === '*********') {
             values.password = oripassword
           }
+          
+          values.username = values.username.replace(/\t*|\v*|\s*/g, '')
+          values.password = values.password.replace(/\t*|\v*|\s*/g, '')
+
           resolve(values)
         } else {
           reject(err)
diff --git a/src/components/normalform/modalform/index.jsx b/src/components/normalform/modalform/index.jsx
index c3e3144..7ce6bc5 100644
--- a/src/components/normalform/modalform/index.jsx
+++ b/src/components/normalform/modalform/index.jsx
@@ -178,7 +178,9 @@
   recordChange = (values, item) => {
     this.record = {...this.record, ...values}
 
-    if (item && item.controlFields) {
+    if (!item) return
+    
+    if (item.controlFields) {
       let map = new Map()
       this.state.formlist.forEach(cell => {
         if (!cell.field) return
@@ -239,6 +241,24 @@
           return item || cell
         })
       })
+    } else if (item.reset_source) {
+      let map = new Map()
+      this.state.formlist.forEach(cell => {
+        if (!cell.field) return
+        map.set(cell.field, cell)
+      })
+
+      item.callback(map, this.record)
+
+      this.setState({
+        formlist: this.state.formlist.map(cell => {
+          if (!cell.field) return cell
+
+          let item = map.get(cell.field)
+
+          return item || cell
+        })
+      })
     }
   }
 
diff --git a/src/components/normalform/modalform/mkSelect/index.jsx b/src/components/normalform/modalform/mkSelect/index.jsx
index 92784fe..840dd4a 100644
--- a/src/components/normalform/modalform/mkSelect/index.jsx
+++ b/src/components/normalform/modalform/mkSelect/index.jsx
@@ -31,6 +31,17 @@
     MKEmitter.addListener('mkFC', this.mkFormControl)
   }
 
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    const { config } = this.state
+
+    if (!is(fromJS(config.oriOptions), fromJS(nextProps.config.oriOptions))) {
+      this.setState({
+        config: fromJS(nextProps.config).toJS(),
+        options: fromJS(nextProps.config.options).toJS()
+      })
+    }
+  }
+
   shouldComponentUpdate (nextProps, nextState) {
     return !is(fromJS(this.state), fromJS(nextState))
   }
diff --git a/src/components/pasteboard/index.jsx b/src/components/pasteboard/index.jsx
new file mode 100644
index 0000000..aae3fa1
--- /dev/null
+++ b/src/components/pasteboard/index.jsx
@@ -0,0 +1,134 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Input, notification, Modal } from 'antd'
+import { SnippetsOutlined } from '@ant-design/icons'
+
+// import './index.scss'
+
+const { TextArea } = Input
+
+class PaseComponent extends Component {
+  static propTpyes = {
+    inputSubmit: PropTypes.func // 鍥炶溅浜嬩欢
+  }
+
+  state = {
+    visible: false,
+    value: ''
+  }
+
+  trigger = () => {
+    // navigator.clipboard
+    //   .readText()
+    //   .then((val) => {
+    //     this.evalContent(val)
+    //   })
+    //   .catch((v) => {
+    //     this.setState({visible: true, value: ''})
+    //   })
+
+    this.setState({visible: true, value: ''})
+  }
+
+  evalContent = (config) => {
+    let _config = config.replace(/(\n|\s)+/g, '')
+
+    if (!_config) {
+      notification.warning({
+        top: 92,
+        message: '鏈幏鍙栧埌閰嶇疆淇℃伅',
+        duration: 5
+      })
+      return
+    }
+
+    try {
+      _config = JSON.parse(window.decodeURIComponent(window.atob(_config)))
+
+      if (typeof(_config) === 'object' && _config.$srcId) {
+        let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+        if (srcid && _config.$srcId !== srcid) {
+          notification.warning({
+            top: 92,
+            message: '褰撳墠绯荤粺鏃犳潈闄愪娇鐢ㄦ椤归厤缃紒',
+            duration: 5
+          })
+
+          _config = ''
+        } else {
+          delete _config.$srcId
+        }
+      }
+    } catch (e) {
+      // 閫氳繃sql璇彞娣诲姞瀛楁闆�
+      if (/[a-zA-Z0-9_]+\s+(nvarchar\(\d+\)|Decimal\(18,\d+\)|Int)/ig.test(config)) {
+        _config = {
+          key: 'datasourcefield',
+          type: 'array',
+          data: []
+        }
+
+        let list = config.match(/[a-zA-Z0-9_]+\s+(nvarchar\(\d+\)|Decimal\(18,\d+\)|Int)/ig)
+
+        list.forEach(item => {
+          _config.data.unshift({
+            datatype: item.split(/\s+/)[1],
+            field: item.split(/\s+/)[0],
+            label: item.split(/\s+/)[0],
+          })
+        })
+      } else {
+        notification.warning({
+          top: 92,
+          message: '瑙f瀽閿欒',
+          duration: 5
+        })
+        _config = ''
+      }
+    }
+
+    if (!_config) return
+
+    this.props.getPasteValue(_config, () => {
+      this.setState({visible: false, value: ''})
+    })
+  }
+
+  changeVal = (e) => {
+    this.setState({value: e.target.value})
+  }
+
+  pasteSubmit = () => {
+    this.evalContent(this.state.value)
+  }
+
+  enterPress = (e) => {
+    e.stopPropagation()
+
+    this.evalContent(this.state.value)
+  }
+
+  render() {
+    const { children } = this.props
+    const { visible, value } = this.state
+
+    return (
+      <>
+        {children ? <span onClick={this.trigger}>{children}</span> : <SnippetsOutlined title="绮樿创" onClick={this.trigger} />}
+        <Modal
+          title="绮樿创"
+          visible={visible}
+          width={600}
+          maskClosable={false}
+          onOk={this.pasteSubmit}
+          onCancel={() => {this.setState({visible: false})}}
+          destroyOnClose
+        >
+          <TextArea placeholder="璇疯緭鍏ラ厤缃俊鎭�" autoFocus autoSize={{ minRows: 8, maxRows: 8 }} value={value} onChange={this.changeVal} onPressEnter={this.enterPress}/>
+        </Modal>
+      </>
+    )
+  }
+}
+
+export default PaseComponent
\ No newline at end of file
diff --git a/src/components/pasteboard/index.scss b/src/components/pasteboard/index.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/components/pasteboard/index.scss
diff --git a/src/components/sidemenu/index.jsx b/src/components/sidemenu/index.jsx
index 94686bd..2e51d24 100644
--- a/src/components/sidemenu/index.jsx
+++ b/src/components/sidemenu/index.jsx
@@ -108,7 +108,7 @@
                 {item.children.map(cell => {
                   return (
                     <Menu.Item key={cell.MenuID}>
-                      <a href={cell.src} id={cell.MenuID} onClick={(e) => this.changemenu(e, cell)}>{cell.MenuName}</a>
+                      <a href={cell.src} onClick={(e) => this.changemenu(e, cell)}>{cell.MenuName}</a>
                     </Menu.Item>
                   )
                 })}
diff --git a/src/components/tabview/index.jsx b/src/components/tabview/index.jsx
index 1b5e633..cf0660d 100644
--- a/src/components/tabview/index.jsx
+++ b/src/components/tabview/index.jsx
@@ -18,7 +18,6 @@
 const CustomPage = asyncComponent(() => import('@/tabviews/custom'))
 const CommonTable = asyncComponent(() => import('@/tabviews/commontable'))
 const BaseTable = asyncComponent(() => import('@/tabviews/basetable'))
-const CalendarPage = asyncComponent(() => import('@/tabviews/calendar'))
 const TreePage = asyncComponent(() => import('@/tabviews/treepage'))
 const Iframe = asyncComponent(() => import('@/tabviews/iframe'))
 const RoleManage = asyncComponent(() => import('@/tabviews/rolemanage'))
@@ -204,14 +203,12 @@
       return (<CustomPage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param} changeTemp={this.changeTemp}/>)
     } else if (view.type === 'TreePage') {
       return (<TreePage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
-    } else if (view.type === 'CalendarPage') {
-      return (<CalendarPage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
     } else if (view.type === 'RolePermission') {
       return (<RoleManage MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID}/>)
     } else if (view.type === 'FormTab') {
       return (<FormTab MenuNo={view.MenuNo} MenuID={view.MenuID} MenuName={view.MenuName} key={view.MenuID} param={view.param}/>)
     } else if (view.type === 'iframe') {
-      return (<Iframe key={view.MenuID} MenuID={view.MenuID} MenuNo={view.MenuNo} title={view.MenuName} MenuName={view.MenuName} url={window.GLOB.baseurl + 'zh-CN/' + view.LinkUrl}/>)
+      return (<Iframe key={view.MenuID} MenuID={view.MenuID} title={view.MenuName} url={view.src}/>)
     } else {
       return (<NotFount key={view.MenuID} />)
     }
diff --git a/src/components/tabview/index.scss b/src/components/tabview/index.scss
index 6f2fee2..13cb998 100644
--- a/src/components/tabview/index.scss
+++ b/src/components/tabview/index.scss
@@ -68,10 +68,11 @@
     }
     iframe {
       width: 100%;
-      height: calc(100vh - 115px);
+      height: calc(100vh - 92px);
       overflow-y: scroll;
       border: 0;
-      margin-top: 16px;
+      margin: 0px;
+      vertical-align: top;
     }
   }
   .ant-back-top {
diff --git a/src/menu/components/card/balcony/index.jsx b/src/menu/components/card/balcony/index.jsx
index b883cf9..691e7f3 100644
--- a/src/menu/components/card/balcony/index.jsx
+++ b/src/menu/components/card/balcony/index.jsx
@@ -207,6 +207,7 @@
       MKEmitter.emit('cardAddElement', card.uuid, res)
     } else {
       res.eleType = 'button'
+      res.width = res.width || 12
       MKEmitter.emit('cardAddElement', card.uuid, res)
     }
     resolve({status: true})
diff --git a/src/menu/components/card/balcony/options.jsx b/src/menu/components/card/balcony/options.jsx
index 97a6d83..b7dd426 100644
--- a/src/menu/components/card/balcony/options.jsx
+++ b/src/menu/components/card/balcony/options.jsx
@@ -78,7 +78,27 @@
       label: '鏁版嵁婧�',
       initval: wrap.publicId || '',
       required: true,
-      options: interfaces
+      options: interfaces,
+      reset_source: true,
+      callback: (map, record) => {
+        if (!record.publicId) return
+
+        let interfaces = window.GLOB.customMenu.interfaces || []
+
+        let d = interfaces.filter(m => m.uuid === record.publicId && m.status === 'true')[0]
+
+        if (!d || !d.columns) return
+
+        let columns = JSON.parse(JSON.stringify(d.columns))
+
+        let _bgField = map.get('bgField')
+
+        if (_bgField && !_bgField.forbid) {
+          _bgField.options = columns
+          _bgField.oriOptions = columns
+          map.set('bgField', _bgField)
+        }
+      }
     },
     {
       type: 'radio',
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/action.jsx b/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
index 5b2b78c..9f0deab 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
@@ -39,6 +39,9 @@
   let warning = null
   if (['pop', 'prompt', 'exec', 'form'].includes(card.OpenType)) {
     hasProfile = true
+    if (card.formType === 'count_line') {
+      hasProfile = false
+    }
   } else if (card.OpenType === 'excelIn' || card.OpenType === 'excelOut') {
     hasProfile = true
   } else if (card.funcType === 'print') {
@@ -53,7 +56,7 @@
   if (card.OpenType === 'form') {
     if (card.formType === 'switch') {
       btnElement = (<Switch style={_style} className={card.size === 'large' ? 'ant-switch-large' : ''} size={card.size} checkedChildren={card.openText || ''} unCheckedChildren={card.closeText || ''}/>)
-    } else if (card.formType === 'counter') {
+    } else if (card.formType === 'counter' || card.formType === 'count_line') {
       btnElement = (<div style={_style} className={'mk-counter ' + card.size}><span><MinusOutlined /></span><span>1</span><span><PlusOutlined /></span></div>)
     } else if (card.formType === 'radio') {
       btnElement = (<Checkbox style={_style}></Checkbox>)
@@ -82,6 +85,12 @@
     className += ' ' + card.checkType
   }
 
+  let updateTime = null
+
+  if (card.updateTime && card.updateTime.indexOf(window.GLOB.curDate) > -1) {
+    updateTime = card.updateTime.substr(11)
+  }
+
   return (
     <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
       <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
@@ -90,6 +99,7 @@
         <CloseOutlined className="close" title="鍒犻櫎" onClick={() => delCard(id)} />
         <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => changeStyle(id)} />
         {hasProfile ? <ProfileOutlined className="profile" title="setting" onClick={() => profileCard(id)} /> : null}
+        {updateTime}
       </div>
     } trigger="hover">
       <div ref={node => drag(drop(node))} style={_style_} className={'ant-col card-button-cell ant-col-' + className} onDoubleClick={(e) => {e.stopPropagation(); doubleClickCard(id)}}>
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
index 6494683..7435fd8 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
@@ -92,6 +92,9 @@
         <div className={'ant-mk-text line' + (card.height || '')} style={{height: card.innerHeight || 'auto'}}>{val}</div>
       )
     } else if (card.eleType === 'icon') {
+      if (card.tipType === 'text') {
+        return <div className={'ant-mk-text line' + (card.height || '')} style={{height: card.innerHeight || 'auto'}}>{card.value || card.field || ''}</div>
+      }
       return (<MkIcon style={{height: card.innerHeight || 'auto'}} className="ant-mk-icon" type={card.icon || 'bell'}/>)
     } else if (card.eleType === 'slider') {
       let val = card.value ? (card.value / card.maxValue) * 100 : 30
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/index.scss b/src/menu/components/card/cardcellcomponent/dragaction/index.scss
index 51310de..56d6af8 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/index.scss
+++ b/src/menu/components/card/cardcellcomponent/dragaction/index.scss
@@ -213,6 +213,7 @@
     background-position: center center;
     background-repeat: no-repeat;
     background-size: cover;
+    position: unset!important;
   }
   .sort-wrap {
     position: relative;
diff --git a/src/menu/components/card/cardcellcomponent/elementform/index.jsx b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
index b0620bb..2f3f53a 100644
--- a/src/menu/components/card/cardcellcomponent/elementform/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
@@ -19,7 +19,7 @@
   number: ['eleType', 'datatype', 'width', 'height', 'prefix', 'postfix', 'noValue', 'fixStyle', 'alignItems'],
   picture: ['eleType', 'datatype', 'width', 'lenWidRadio', 'maxWidth', 'link', 'noValue'],
   video: ['eleType', 'datatype', 'width', 'aspectRatio', 'autoPlay', 'loop', 'startTime', 'noValue', 'posterType'],
-  icon: ['eleType', 'datatype', 'width', 'tooltip'],
+  icon: ['eleType', 'datatype', 'tipType', 'width', 'tooltip'],
   slider: ['eleType', 'datatype', 'width', 'color', 'maxValue', 'showInfo', 'showType', 'strokeWidth', 'strokeLinecap', 'trailColor'],
   splitline: ['eleType', 'color', 'width', 'borderWidth'],
   barcode: ['eleType', 'datatype', 'width', 'barHeight', 'displayValue', 'interval', 'noValue'],
@@ -182,7 +182,7 @@
             _options.push('linkurl')
           }
         } else if (this.record.linkType === 'other') {
-          _options.push('linkurl', 'joint')
+          _options.push('linkurl', 'joint', 'open')
         } else {
           _options.push('linkurl')
         }
@@ -199,8 +199,13 @@
     } else if (this.record.eleType === 'icon') {
       if (this.record.datatype === 'dynamic') {
         _options.push('field', 'noValue')
+      } else if (this.record.tipType === 'text') {
+        _options.push('value')
       } else {
         _options.push('icon')
+      }
+      if (this.record.tipType === 'text') {
+        _options.push('height')
       }
     } else if (this.record.eleType === 'formula' && this.record.eval === 'true') {
       _options.push('decimal')
@@ -336,7 +341,7 @@
           return item
         })
       })
-    } else if (['datatype', 'showInfo', 'showType', 'fixStyle', 'posterType', 'eval', 'linkType'].includes(key)) {
+    } else if (['datatype', 'showInfo', 'showType', 'fixStyle', 'posterType', 'eval', 'linkType', 'tipType'].includes(key)) {
       let _options = this.getOptions()
 
       this.setState({
diff --git a/src/menu/components/card/cardcellcomponent/formconfig.jsx b/src/menu/components/card/cardcellcomponent/formconfig.jsx
index 603aeaf..2e494ac 100644
--- a/src/menu/components/card/cardcellcomponent/formconfig.jsx
+++ b/src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -6,12 +6,14 @@
  * @param {*} type
  */
 export function getCardCellForm (card, cards, cardCell) {
+  let appType = sessionStorage.getItem('appType')
+
   let _options = [
     { value: 'text', text: '鏂囨湰'},
     { value: 'number', text: '鏁板��'},
     { value: 'picture', text: '鍥剧墖'},
     { value: 'video', text: '瑙嗛'},
-    { value: 'icon', text: '鍥炬爣'},
+    { value: 'icon', text: '鎻愮ず锛堝浘鏍囷級'},
     { value: 'slider', text: '杩涘害鏉�'},
     { value: 'splitline', text: '鍒嗗壊绾�'},
     { value: 'barcode', text: '鏉″舰鐮�'},
@@ -36,7 +38,6 @@
   if (card.eleType === 'icon' && card.datatype === 'dynamic' && !card.field) { // 鎷栨嫿娣诲姞绫诲瀷杞崲
     card.datatype = 'static'
   }
-  let appType = sessionStorage.getItem('appType')
 
   let tooltip = ''
   if (cardCell.$cardType === 'extendCard') {
@@ -127,6 +128,17 @@
       options: [
         { value: 'dynamic', text: '鍔ㄦ��' },
         { value: 'static', text: '闈欐��' }
+      ]
+    },
+    {
+      type: 'radio',
+      key: 'tipType',
+      label: '鎻愮ず鍐呭',
+      initVal: card.tipType || 'icon',
+      required: false,
+      options: [
+        { value: 'icon', text: '鍥炬爣' },
+        { value: 'text', text: '鏂囨湰' }
       ]
     },
     {
@@ -603,6 +615,7 @@
       key: 'linkurl',
       label: '閾炬帴鍦板潃',
       initVal: card.linkurl || '',
+      tooltip: ['pc', 'mob'].includes(appType) ? '褰撻摼鎺ョ被鍨嬩负鈥滃叾浠栤�濓紝涓旈摼鎺ュ湴鍧�浠menuid@寮�澶存椂锛屽叾鍚庡唴瀹瑰皢琚涓鸿彍鍗旾D銆�' : '',
       required: true,
       options: []
     },
@@ -611,7 +624,7 @@
       key: 'open',
       label: '鎵撳紑鏂瑰紡',
       initVal: card.open || 'blank',
-      tooltip: '鑿滃崟鎵撳紑鏂瑰紡銆�',
+      tooltip: '鑿滃崟鎵撳紑鏂瑰紡锛岄摼鎺ユ棤鏁堛��',
       required: true,
       forbid: !['pc', 'mob'].includes(appType),
       options: [
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index 8e7bc2a..e5a5029 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -2,6 +2,7 @@
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
 import { Modal, Button } from 'antd'
+import moment from 'moment'
 
 import asyncComponent from '@/utils/asyncComponent'
 import { getCardCellForm } from './formconfig'
@@ -159,6 +160,8 @@
       options = ['background', 'border', 'margin']
     } else if (element.eleType === 'color') {
       options = ['border', 'margin', 'padding']
+    } else if (element.eleType === 'number' || element.eleType === 'icon') {
+      options.push('display')
     } else if (element.eleType === 'text') {
       options[0] = 'font2'
       options.push('display')
@@ -166,6 +169,10 @@
       options = ['padding', 'margin']
     } else if (element.eleType === 'splitline') {
       options = ['padding', 'margin']
+    }
+
+    if (element.eleType !== 'button') {
+      options.push('position')
     }
 
     options.push('clear')
@@ -179,12 +186,6 @@
 
   getStyle = (style) => {
     const { card, elements } = this.state
-
-    // if (card.eleType === 'button') {
-    //   if ((style.paddingLeft || style.paddingRight) && !style.width) {
-    //     style.width = 'auto'
-    //   }
-    // }
 
     let _card = this.resetCardStyle(card, style)
 
@@ -207,7 +208,7 @@
       _card.style = style
       let line = _card.height || null
 
-      if (['currentDate', 'sequence', 'icon'].includes(_card.eleType)) {
+      if (['currentDate', 'sequence'].includes(_card.eleType) || (_card.eleType === 'icon' && _card.tipType !== 'text')) {
         line = 1
       }
 
@@ -372,7 +373,7 @@
         if (cell.uuid === res.uuid) {
           res.style = cell.style || {}
 
-          if (res.eleType !== 'text') {
+          if (!['text', 'number', 'icon'].includes(res.eleType)) {
             delete res.style.display
           }
           
@@ -382,7 +383,7 @@
           } else if (['text', 'number', 'formula', 'currentDate', 'sequence', 'icon'].includes(res.eleType)) {
             let line = res.height || null
 
-            if (['currentDate', 'sequence', 'icon'].includes(res.eleType)) {
+            if (['currentDate', 'sequence'].includes(res.eleType) || (res.eleType === 'icon' && res.tipType !== 'text')) {
               line = 1
             }
 
@@ -443,17 +444,7 @@
         if (cell.uuid === res.uuid) {
           res.eleType = cell.eleType || null
           res.style = cell.style || null
-          // res.modal = cell.modal || null
-          // res.config = cell.config || null
           res.wrapStyle = cell.wrapStyle || null
-          // res = {...cell, ...res}
-
-          // if (!res.control) {
-          //   delete res.controlField
-          //   delete res.controlVal
-          // }
-          
-          // delete res.focus
 
           if (res.OpenType === 'form') {
             if (cell.OpenType !== 'form') {
@@ -479,6 +470,8 @@
             }
             res.style = {...res.style, ...style}
           }
+
+          res.updateTime = moment().format('YYYY-MM-DD HH:mm')
 
           return res
         }
@@ -536,6 +529,7 @@
       let _elements = elements.map(cell => {
         if (cell.uuid === card.uuid) {
           cell.verify = res
+          cell.updateTime = moment().format('YYYY-MM-DD HH:mm')
         }
 
         return cell
@@ -799,7 +793,7 @@
             destroyOnClose
           >
             <ActionForm
-              type={cards.type === 'balcony' ? '' : 'card'}
+              type={cards.type === 'balcony' || cardCell.$cardType === 'extendCard' ? '' : 'card'}
               card={card}
               formlist={this.state.formlist}
               inputSubmit={this.handleActionSubmit}
diff --git a/src/menu/components/card/cardcomponent/index.jsx b/src/menu/components/card/cardcomponent/index.jsx
index fe9bfc9..0d6a97d 100644
--- a/src/menu/components/card/cardcomponent/index.jsx
+++ b/src/menu/components/card/cardcomponent/index.jsx
@@ -286,6 +286,7 @@
 
     if (element.copyType === 'action') {
       element.eleType = 'button'
+      element.width = element.width || 12
     }
 
     element.uuid = _uuid
diff --git a/src/menu/components/card/cardsimplecomponent/index.jsx b/src/menu/components/card/cardsimplecomponent/index.jsx
index cf6e1d3..2eb816e 100644
--- a/src/menu/components/card/cardsimplecomponent/index.jsx
+++ b/src/menu/components/card/cardsimplecomponent/index.jsx
@@ -194,6 +194,7 @@
     
     if (element.copyType === 'action') {
       element.eleType = 'button'
+      element.width = element.width || 12
     }
 
     element.uuid = _uuid
diff --git a/src/menu/components/card/data-card/index.jsx b/src/menu/components/card/data-card/index.jsx
index ae1bcf9..3b75676 100644
--- a/src/menu/components/card/data-card/index.jsx
+++ b/src/menu/components/card/data-card/index.jsx
@@ -562,7 +562,7 @@
           <ToolOutlined />
         </Popover>
         <ActionComponent config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/>
-        <div className={'float-' + (card.wrap.cardFloat || 'left') + ' select-' + card.wrap.selStyle}>
+        <div className={`float-${card.wrap.cardFloat || 'left'} select-${card.wrap.selStyle || ''}`}>
           {card.subcards.map((subcard, index) => (<CardComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
         </div>
         <div style={{clear: 'both'}}></div>
diff --git a/src/menu/components/card/data-card/options.jsx b/src/menu/components/card/data-card/options.jsx
index 12783c8..9f2edb2 100644
--- a/src/menu/components/card/data-card/options.jsx
+++ b/src/menu/components/card/data-card/options.jsx
@@ -103,10 +103,11 @@
       ],
       linkFields: ['priKeyType'],
       controlFields: [
-        {field: 'goback', values: ['dynamic']},
+        {field: 'goback', values: ['dynamic', 'public']},
         {field: 'empty', values: ['dynamic', 'public']},
-        {field: 'jump', values: ['dynamic']},
-        {field: 'autoExec', values: ['dynamic']},
+        {field: 'jump', values: ['dynamic', 'public']},
+        {field: 'broadcast', values: ['dynamic', 'public']},
+        {field: 'autoExec', values: ['dynamic', 'public']},
         {field: 'supModule', values: ['static']},
         {field: 'publicId', values: ['public']},
       ],
@@ -119,7 +120,42 @@
       initval: wrap.publicId || '',
       required: true,
       options: interfaces,
-      forbid: subtype !== 'propcard'
+      reset_source: true,
+      forbid: subtype !== 'propcard',
+      callback: (map, record) => {
+        if (!record.publicId) return
+        
+        let interfaces = window.GLOB.customMenu.interfaces || []
+        
+        let d = interfaces.filter(m => m.uuid === record.publicId && m.status === 'true')[0]
+        
+        if (!d || !d.columns) return
+        let columns = JSON.parse(JSON.stringify(d.columns))
+
+        let _broadcast = map.get('broadcast')
+
+        if (_broadcast && !_broadcast.forbid) {
+          _broadcast.options = columns
+          _broadcast.oriOptions = columns
+          map.set('broadcast', _broadcast)
+        }
+        
+        let _jumpField = map.get('jumpField')
+
+        if (_jumpField && !_jumpField.forbid) {
+          _jumpField.options = columns
+          _jumpField.oriOptions = columns
+          map.set('jumpField', _jumpField)
+        }
+
+        let _link = map.get('link')
+
+        if (_link && !_link.forbid) {
+          _link.options = columns
+          _link.oriOptions = columns
+          map.set('link', _link)
+        }
+      }
     },
     {
       type: 'radio',
@@ -326,7 +362,7 @@
       field: 'broadcast',
       label: '璇煶鎾姤',
       initval: wrap.broadcast || '',
-      tooltip: '璇煶鎾姤鍦ㄧЩ鍔ㄧapp涓湁鏁堛�傛敞锛氫娇鐢ㄨ闊虫挱鎶ユ椂锛屾暟鎹簮涓嶈浣跨敤鍚屾鏌ヨ锛屾坊鍔犲畾鏃跺櫒鏃讹紝鍙惊鐜挱鎶�',
+      tooltip: '璇煶鎾姤鍦ㄧЩ鍔ㄧ鏈夋晥銆傛敞锛氬湪H5涓浣跨敤闊抽閾炬帴锛屾坊鍔犲畾鏃跺櫒鏃讹紝鍙惊鐜挱鎶�',
       required: false,
       options: columns,
       forbid: !columns || appType !== 'mob' || subtype !== 'propcard'
@@ -349,6 +385,7 @@
       field: 'display',
       label: '鏄剧ず鎺у埗',
       initval: wrap.display || 'normal',
+      tooltip: '褰撲娇鐢ㄥ睘鎬у崱杩涜鏌愪簺涓氬姟鎿嶄綔锛屼笖涓嶉渶瑕佸睍绀哄崱鐗囦俊鎭椂锛屽彲璁剧疆涓轰笉鍙銆�',
       required: false,
       options: [
         {value: 'normal', label: '姝e父鏄剧ず'},
@@ -408,7 +445,7 @@
       field: 'jumpField',
       label: '鎺у埗瀛楁',
       initval: wrap.jumpField || '',
-      tooltip: '褰撳瓧娈靛�间负true鏃�',
+      tooltip: '褰撳瓧娈靛�间负true鏃惰Е鍙戣烦杞��',
       required: true,
       options: columns,
       forbid: subtype !== 'propcard' || appType !== 'mob'
diff --git a/src/menu/components/card/double-data-card/index.jsx b/src/menu/components/card/double-data-card/index.jsx
index 1a47d2b..1374635 100644
--- a/src/menu/components/card/double-data-card/index.jsx
+++ b/src/menu/components/card/double-data-card/index.jsx
@@ -548,7 +548,7 @@
           <ToolOutlined />
         </Popover>
         <ActionComponent config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/>
-        <div className={'select-' + card.wrap.selStyle + extraName}>
+        <div className={`select-${card.wrap.selStyle || ''} ${extraName}`}>
           {card.subcards.map(subcard => {
             if (subcard.$cardType === 'extendCard') {
               return (<CardComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>)
diff --git a/src/menu/components/card/prop-card/index.jsx b/src/menu/components/card/prop-card/index.jsx
index b914926..12c8c19 100644
--- a/src/menu/components/card/prop-card/index.jsx
+++ b/src/menu/components/card/prop-card/index.jsx
@@ -123,7 +123,7 @@
 
   mkUpdateInter = (inter, split) => {
     const { card } = this.state
-    
+
     if (card.wrap.datatype === 'public' && card.wrap.publicId === inter.uuid) {
       let _card = {...card, columns: fromJS(inter.columns).toJS()}
 
@@ -423,7 +423,7 @@
         } trigger="hover">
           <ToolOutlined />
         </Popover>
-        <div className={(card.wrap.layout || 'grid') + '-layout float-' + (card.wrap.cardFloat || 'left') + ' select-' + card.wrap.selStyle}>
+        <div className={`${card.wrap.layout || 'grid'}-layout float-${card.wrap.cardFloat || 'left'} select-${card.wrap.selStyle || ''}`}>
           {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
         </div>
         {card.wrap.display === 'hidden' ? <HeatMapOutlined className="prop-hidden"/> : null}
diff --git a/src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx
index 9eed12a..4c4f683 100644
--- a/src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-G6/chartcompile/formconfig.jsx
@@ -236,7 +236,7 @@
         label: '涓婄骇缁勪欢'
       }, {
         value: 'line',
-        label: '琛�'
+        label: '鏁版嵁婧�'
       }],
       controlFields: [
         {field: 'rootLabel', values: ['fixed', 'supvalue']},
@@ -249,6 +249,7 @@
       field: 'rootValue',
       label: '鏍硅妭鐐瑰��',
       initval: card.rootValue || '',
+      tooltip: '鏍硅妭鐐逛娇鐢ㄤ笂绾х粍浠舵椂锛岃濉啓涓婄骇缁勪欢涓搴旂殑瀛楁銆�',
       required: true
     },
     {
@@ -256,6 +257,7 @@
       field: 'rootLabel',
       label: '鏍硅妭鐐规枃鏈�',
       initval: card.rootLabel || '',
+      tooltip: '鏍硅妭鐐逛娇鐢ㄤ笂绾х粍浠舵椂锛岃濉啓涓婄骇缁勪欢涓搴旂殑瀛楁銆�',
       required: true
     },
     {
@@ -345,7 +347,7 @@
       field: 'collapsed',
       label: '鑺傜偣鍚堝苟',
       initval: card.collapsed || 'false',
-      tooltip: '涓�绾ц妭鐐规槸鍚﹀悎骞躲��',
+      tooltip: '鍒濆鍖栨椂锛屼竴绾ц妭鐐规槸鍚﹀悎骞躲��',
       required: false,
       options: [
         {value: 'false', label: '鍚�'},
diff --git a/src/menu/components/chart/antv-G6/index.jsx b/src/menu/components/chart/antv-G6/index.jsx
index 985a6f5..652fbe6 100644
--- a/src/menu/components/chart/antv-G6/index.jsx
+++ b/src/menu/components/chart/antv-G6/index.jsx
@@ -1137,7 +1137,7 @@
     const { card } = this.state
 
     if (card.plot.subtype === 'mindmap') {
-      this.ponitrender()
+      this.mindrender()
     } else if (card.plot.subtype === 'indentTree') {
       this.indentrender()
     } else if (card.plot.subtype === 'kapmap') {
@@ -1270,9 +1270,9 @@
   }
 
   /**
-   * @description 鏁g偣鍥�
+   * @description 鎬濈淮瀵煎浘
    */
-  ponitrender = () => {
+  mindrender = () => {
     const { card } = this.state
     const plot = card.plot
     const data = this.getdata()
@@ -1404,7 +1404,7 @@
     let _style = resetStyle(card.style)
 
     return (
-      <div className="menu-scatter-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
+      <div className="menu-g6-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
             <ChartCompileForm config={card} plotchange={this.updateComponent}/>
diff --git a/src/menu/components/chart/antv-G6/index.scss b/src/menu/components/chart/antv-G6/index.scss
index 5d8ba6f..8a386a9 100644
--- a/src/menu/components/chart/antv-G6/index.scss
+++ b/src/menu/components/chart/antv-G6/index.scss
@@ -1,4 +1,4 @@
-.menu-scatter-chart-edit-box {
+.menu-g6-chart-edit-box {
   position: relative;
   box-sizing: border-box;
   background: #ffffff;
@@ -42,27 +42,8 @@
     color: rgba(0, 0, 0, 0.85);
     background: rgba(255, 255, 255, 0.55);
   }
-
-  .model-menu-action-list {
-    position: absolute;
-    right: 0px;
-    top: 30px;
-    z-index: 4;
-    font-size: 16px;
-  
-    .ant-row .anticon-plus {
-      float: right;
-    }
-  
-    .page-card {
-      float: right;
-    }
-  }
-  .normal-header + .canvas + .model-menu-action-list {
-    top: 45px;
-  }
 }
-.menu-scatter-chart-edit-box:hover {
+.menu-g6-chart-edit-box:hover {
   z-index: 1;
   box-shadow: 0px 0px 4px #1890ff;
 }
diff --git a/src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx
index 9eed12a..39827f8 100644
--- a/src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-X6/chartcompile/formconfig.jsx
@@ -106,7 +106,7 @@
       tooltip: '鐐瑰嚮鑺傜偣鏃惰Е鍙戠殑浜嬩欢銆�',
       required: false,
       options: [
-        {value: '', label: '鏁版嵁鍒囨崲'},
+        {value: '', label: '鏃�'},
         {value: 'menu', label: '鑿滃崟'},
         {value: 'menus', label: '鑿滃崟缁�'}
       ],
@@ -203,130 +203,18 @@
       type: 'select',
       field: 'subtype',
       label: '绫诲瀷',
-      initval: card.subtype || 'mindmap',
+      initval: card.subtype || 'xflow',
       required: true,
       options: [{
-        value: 'mindmap',
-        label: '鎬濈淮瀵煎浘'
+        value: 'xflow',
+        label: '娴佺▼鍥�'
       }, {
         value: 'indentTree',
-        label: '缂╄繘鏂囦欢鏍�'
+        label: '娉抽亾鍥�'
       }, {
         value: 'kapmap',
-        label: '鐭ヨ瘑鍥捐氨鏍�'
-      }],
-      controlFields: [
-        {field: 'dirField', values: ['mindmap']},
-        {field: 'nodeColor', values: ['mindmap']},
-        // {field: 'collapsed', values: ['indentTree', 'kapmap']},
-      ]
-    },
-    {
-      type: 'radio',
-      field: 'rootType',
-      label: '鏍硅妭鐐瑰彇鍊�',
-      initval: card.rootType || 'fixed',
-      tooltip: '閫夋嫨涓婄骇鏃讹紝璇峰~鍐欐牴鑺傜偣鐨勬枃鏈拰鍊肩殑瀛楁鍚�',
-      required: true,
-      options: [{
-        value: 'fixed',
-        label: '鍥哄畾鍊�'
-      }, {
-        value: 'supvalue',
-        label: '涓婄骇缁勪欢'
-      }, {
-        value: 'line',
-        label: '琛�'
-      }],
-      controlFields: [
-        {field: 'rootLabel', values: ['fixed', 'supvalue']},
-        {field: 'rootValue', values: ['fixed', 'supvalue']},
-        {field: 'mark', values: ['line']},
-      ]
-    },
-    {
-      type: 'text',
-      field: 'rootValue',
-      label: '鏍硅妭鐐瑰��',
-      initval: card.rootValue || '',
-      required: true
-    },
-    {
-      type: 'text',
-      field: 'rootLabel',
-      label: '鏍硅妭鐐规枃鏈�',
-      initval: card.rootLabel || '',
-      required: true
-    },
-    {
-      type: 'select',
-      field: 'valueField',
-      label: '鍊煎瓧娈�',
-      initval: card.valueField || '',
-      required: true,
-      options: columns
-    },
-    {
-      type: 'select',
-      field: 'labelField',
-      label: '鏂囨湰瀛楁',
-      initval: card.labelField || '',
-      required: true,
-      options: columns
-    },
-    {
-      type: 'select',
-      field: 'parentField',
-      label: '涓婄骇瀛楁',
-      initval: card.parentField || '',
-      required: true,
-      options: columns
-    },
-    {
-      type: 'text',
-      field: 'mark',
-      label: '椤剁骇鏍囪瘑',
-      initval: card.mark || '',
-      tooltip: '涓婄骇瀛楁鍊间笌椤剁骇鏍囪瘑鐩稿悓鏃讹紝瑙嗕负鏍硅妭鐐广��',
-      required: true
-    },
-    {
-      type: 'select',
-      field: 'dirField',
-      label: '鏂瑰悜鎺у埗',
-      initval: card.dirField || '',
-      required: false,
-      options: columns,
-      controlFields: [
-        {field: 'dirSign', notNull: true},
-        {field: 'leftColor', notNull: true},
-      ]
-    },
-    {
-      type: 'text',
-      field: 'dirSign',
-      label: '宸﹀悜鏍囪',
-      initval: card.dirSign || '',
-      tooltip: '褰撹妭鐐瑰�间笌鏍囪鐩稿悓鏃惰妭鐐逛俊鎭綅浜庤妭鐐瑰乏渚э紝澶氫釜鍊艰鐢ㄩ�楀彿鍒嗛殧銆�',
-      required: false
-    },
-    {
-      type: 'color',
-      field: 'nodeColor',
-      label: '鑺傜偣棰滆壊',
-      initval: card.nodeColor || '#1890ff',
-      tooltip: '鍙充晶鑺傜偣鐨勬爣璁伴鑹层��',
-      colorType: 'hex',
-      required: false
-    },
-    {
-      type: 'color',
-      field: 'leftColor',
-      label: '宸﹁妭鐐归鑹�',
-      initval: card.leftColor || '#26C281',
-      tooltip: '宸︿晶鑺傜偣鐨勬爣璁伴鑹层��',
-      colorType: 'hex',
-      required: false
+        label: '缁勭粐缁撴瀯鍥�'
+      }]
     },
     {
       type: 'radio',
@@ -339,18 +227,6 @@
         {value: 'show', label: '鍚�'},
         {value: 'hidden', label: '鏄�'},
       ],
-    },
-    {
-      type: 'radio',
-      field: 'collapsed',
-      label: '鑺傜偣鍚堝苟',
-      initval: card.collapsed || 'false',
-      tooltip: '涓�绾ц妭鐐规槸鍚﹀悎骞躲��',
-      required: false,
-      options: [
-        {value: 'false', label: '鍚�'},
-        {value: 'true', label: '鏄�'},
-      ],
-    },
+    }
   ]
 }
diff --git a/src/menu/components/chart/antv-X6/index.jsx b/src/menu/components/chart/antv-X6/index.jsx
index 985a6f5..6d20b17 100644
--- a/src/menu/components/chart/antv-X6/index.jsx
+++ b/src/menu/components/chart/antv-X6/index.jsx
@@ -1,947 +1,246 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Popover, message } from 'antd'
-import { ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
-import G6 from '@antv/g6'
+import { Popover, Tooltip, message } from 'antd'
+import { ToolOutlined, DeleteOutlined, FontColorsOutlined, VerticalAlignTopOutlined, VerticalAlignBottomOutlined, SaveOutlined, ZoomInOutlined, ZoomOutOutlined, OneToOneOutlined, DoubleLeftOutlined } from '@ant-design/icons'
+import { Graph, Shape } from '@antv/x6'
+import { Stencil } from '@antv/x6-plugin-stencil'
+import { Transform } from '@antv/x6-plugin-transform'
+import { Selection } from '@antv/x6-plugin-selection'
+import { Snapline } from '@antv/x6-plugin-snapline'
+import { Keyboard } from '@antv/x6-plugin-keyboard'
+import { Clipboard } from '@antv/x6-plugin-clipboard'
+import { History } from '@antv/x6-plugin-history'
 
 import MKEmitter from '@/utils/events.js'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
-import { resetStyle, getTables, getHeight, checkComponent } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
 import './index.scss'
-
-const { Util } = G6
 
 const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
 const ChartCompileForm = asyncIconComponent(() => import('./chartcompile'))
+const NodeUpdate = asyncIconComponent(() => import('./nodeupdate'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
-const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 
-const MindData = [
-  'Modeling Methods',
-  [
-    'Classification',
-    ['Logistic regression', 'Linear discriminant analysis', 'Rules', 'Decision trees', 'Naive Bayes', 'K nearest neighbor', 'Probabilistic neural network', 'Support vector machine']
-  ],
-  [
-    'Consensus',
-    [
-      'Models diversity',
-      ['Different initializations', 'Different parameter choices', 'Different architectures', 'Different modeling methods', 'Different training sets', 'Different feature sets']
-    ],
-    [
-      'Methods',
-      ['Classifier selection', 'Classifier fusion']
-    ],
-    [
-      'Common',
-      ['Bagging', 'Boosting', 'AdaBoost']
-    ]
-  ],
-  [
-    'Regression',
-    ['Multiple linear regression', 'Partial least squares', 'Multi-layer feedforward neural network', 'General regression neural network', 'Support vector regression']
-  ]
-]
-
-const styles = {
-  blue: '#1890ff',
-  red: '#f5222d',
-  orange_red: '#fa541c',
-  orange: '#fa8c16',
-  orange_yellow: '#faad14',
-  yellow: '#fadb14',
-  yellow_green: '#a0d911',
-  green: '#52c41a',
-  cyan: '#13c2c2',
-  blue_purple: '#2f54eb',
-  purple: '#722ed1',
-  magenta: '#eb2f96',
-  grass_green: '#aeb303',
-  deep_red: '#c32539',
-  deep_blue: '#1d3661'
-}
-
-let systemColor = '#1890ff'
-if (window.GLOB.style) {
-  let type = window.GLOB.style.replace(/bg_black_style_|bg_white_style_/, '')
-  systemColor = styles[type] || '#1890ff'
-}
-const COLORS = ['#5B8FF9', '#F6BD16', '#5AD8A6', '#945FB9', '#E86452', '#6DC8EC', '#FF99C3', '#1E9493', '#FF9845', '#5D7092']
-
-// 鎬濈淮瀵煎浘
-G6.registerNode(
-  'dice-mind-map-root', {
-    jsx: (cfg) => {
-      const width = Util.getTextSize(cfg.label, 16)[0] + 24
-
-      return `
-        <group>
-          <rect style={{width: ${width}, height: 42, stroke: ${systemColor}, radius: 4}} keyshape>
-            <text style={{ fontSize: 16, marginLeft: 6, marginTop: 12 }}>${cfg.label}</text>
-          </rect>
-        </group>
-      `
-    },
-    getAnchorPoints() {
-      return [
-        [0, 0.5],
-        [1, 0.5]
-      ]
-    }
-  },
-  'single-node',
-)
-
-G6.registerNode(
-  'dice-mind-map-leaf', {
-    jsx: (cfg) => {
-      const width = Util.getTextSize(cfg.label, 12)[0] + 24
-
-      return `
-        <group>
-          <rect style={{width: ${width}, height: 26, fill: 'transparent', cursor: pointer }}>
-            <text style={{ fontSize: 12, fill: ${cfg.selected ? systemColor : '#000000'}, marginLeft: 12, marginTop: 6, cursor: pointer }}>${cfg.label}</text>
-          </rect>
-          <rect style={{ fill: ${cfg.color}, width: ${width}, height: 2, x: 0, y: 32, cursor: pointer }} />
-        </group>
-      `
-    },
-    getAnchorPoints() {
-      return [
-        [0, 0.965],
-        [1, 0.965]
-      ]
-    }
-  },
-  'single-node',
-)
-G6.registerBehavior('dice-mindmap', {
-  getEvents() {
-    return {
-      'node:click': 'editNode',
-      'canvas:click': 'onCanvasClick'
-    }
-  },
-  editNode(evt) {
-    const item = evt.item
-    const model = item.get('model')
-
-    this.graph.getNodes().forEach(node => {
-      let _model = node.get('model')
-      if (_model.selected) {
-        _model.selected = false
-        this.graph.updateItem(node, _model, false)
-      }
-    })
-
-    model.selected = true
-    this.graph.updateItem(item, model, false)
-  },
-  onCanvasClick(e) {
-    this.graph.getNodes().forEach(node => {
-      let _model = node.get('model')
-      if (_model.selected) {
-        _model.selected = false
-        this.graph.updateItem(node, _model, false)
-      }
-    })
-  }
-})
-G6.registerBehavior('scroll-canvas', {
-  getEvents: function getEvents() {
-    return {
-      wheel: 'onWheel'
-    }
-  },
-  onWheel: function onWheel(ev) {
-    const { graph } = this
-    if (!graph) {
-      return
-    }
-    if (ev.ctrlKey) {
-      const canvas = graph.get('canvas')
-      const point = canvas.getPointByClient(ev.clientX, ev.clientY)
-      let ratio = graph.getZoom()
-      if (ev.wheelDelta > 0) {
-        ratio += ratio * 0.05
-      } else {
-        ratio *= ratio * 0.05
-      }
-      graph.zoomTo(ratio, {
-        x: point.x,
-        y: point.y
-      })
-    } else {
-      const x = ev.deltaX || ev.movementX
-      const y = ev.deltaY || ev.movementY || (-ev.wheelDelta * 125) / 3
-      graph.translate(-x, -y)
-    }
-    ev.preventDefault()
-  }
-})
-
-// 缂╄繘鏂囦欢鏍�
-G6.registerNode('indentedRoot', {
-  draw(model, group) {
-    const keyShape = group.addShape('rect', {
-      attrs: {
-        x: -46,
-        y: -16,
-        width: 92,
-        height: 32,
-        fill: systemColor,
-        radius: 2,
-        stroke: '#5B8FF9',
-        lineWidth: 0
-      },
-      name: 'key-shape'
-    })
-
-    const text = group.addShape('text', {
-      attrs: {
-        text: model.label || 'root',
-        fill: "#fff",
-        fontSize: 12,
-        x: 0,
-        y: 0,
-        textAlign: 'center',
-        textBaseline: 'middle'
-      },
-      name: 'root-text-shape'
-    })
-    const textBBox = text.getBBox()
-    const width = textBBox.width + 24
-    const height = textBBox.height + 12
-    keyShape.attr({
-      x: -width / 2,
-      y: -height / 2,
-      width,
-      height
-    })
-
-    return keyShape
-  },
-  getAnchorPoints() {
-    return [
-      [0.5, 1]
-    ]
-  },
-  update: undefined
-})
-
-G6.registerNode('indentedNode', {
-  addChildCount(group, tag, props) {
-    const { collapsed, branchColor, count } = props
-    let clickCircleY = 10
-    // 瀛愮被鏁伴噺 icon锛岀粯鍒跺渾鐐瑰湪鑺傜偣姝d笅鏂�
-    if (tag) {
-      const childCountGroup = group.addGroup({
-        name: 'child-count-group'
-      })
-      childCountGroup.setMatrix([1, 0, 0, 0, 1, 0, 0, clickCircleY, 1])
-      const countBackWidth = collapsed ? 26 : 12
-      childCountGroup.addShape('rect', {
-        attrs: {
-          width: countBackWidth,
-          height: 12,
-          radius: 6,
-          stroke: branchColor,
-          lineWidth: 2,
-          fill: collapsed ? branchColor : '#fff',
-          x: -countBackWidth / 2,
-          y: -6,
-          cursor: 'pointer',
-        },
-        name: 'child-count-rect-shape'
-      })
-      const childCountText = childCountGroup.addShape('text', {
-        attrs: {
-          text: count,
-          fill: '#fff',
-          x: 0,
-          y: 0,
-          fontSize: 10,
-          textAlign: 'center',
-          textBaseline: 'middle',
-          cursor: 'pointer',
-        },
-        name: 'child-count-text-shape'
-      })
-      const childHoverIcon = childCountGroup.addShape('path', {
-        attrs: {
-          stroke: '#fff',
-          lineWidth: 1,
-          cursor: 'pointer',
-          path: [['M', -3, 2], ['L', 0, -2], ['L', 3, 2]]
-        },
-        name: 'child-count-expand-icon',
-        capture: false
-      })
-      childHoverIcon.hide()
-
-      // 杩炴帴 count 鐨勭嚎娈�
-      const countLink = group.addShape('path', {
-        attrs: {
-          path: [['M', 0, 0], ['L', 0, 11]],
-          stroke: branchColor,
-          lineWidth: 2,
-        },
-        name: 'count-link'
-      })
-      countLink.toBack()
-
-      if (collapsed) {
-        childCountGroup.show()
-        childCountText.show()
-        countLink.show()
-      }
-      else {
-        childCountGroup.hide()
-        childCountText.hide()
-        countLink.hide()
-      }
-
-      clickCircleY += 16
-    }
-  },
-  addBottomLine(group, props) {
-    const { x, width, stroke, lineWidth } = props
-    return group.addShape('path', {
-      attrs: {
-        path: [
-          ['M', x - 1, 0],
-          ['L', width, 0],
-        ],
-        stroke,
-        lineWidth,
-      },
-      name: 'node-path-shape'
-    })
-  },
-  addName(group, props) {
-    const { label, x = 0, y, fill } = props
-    return group.addShape('text', {
-      attrs: {
-        text: label,
-        x,
-        y,
-        textAlign: 'start',
-        textBaseline: 'top',
-        fill,
-        fontSize: 14,
-        fontFamily: 'PingFangSC-Regular',
-        cursor: 'pointer',
-      },
-      name: 'not-root-text-shape'
-    })
-  },
-  draw(model, group) {
-    const { collapsed, depth, label, children, selected } = model
-    // 鏄惁涓烘牴鑺傜偣
-    const rootNode = depth === 0
-    // 瀛愯妭鐐规暟閲�
-    const childCount = children ? children.length : 0
-
-    let width = 0
-    const height = 24
-    const x = 0
-    const y = -height / 2
-    const borderRadius = 4
-    // 鍚嶇О鏂囨湰
-    const text = this.addName(group, { label, x, y })
-
-    let textWidth = text.getBBox().width
-    width = textWidth + 20
-
-    const keyShapeAttrs = {
-      x,
-      y,
-      width,
-      height,
-      radius: borderRadius,
-      fill: undefined,
-      stroke: undefined,
-    }
-
-    const keyShape = group.addShape('rect', {
-      attrs: keyShapeAttrs,
-      name: 'root-key-shape-rect-shape'
-    })
-
-    // 搴曢儴妯嚎
-    const bottomLine = this.addBottomLine(group, {
-      stroke: model.branchColor || '#AAB7C4',
-      lineWidth: 3,
-      x,
-      width
-    })
-
-    let nameColor = 'rgba(0, 0, 0, 0.85)'
-
-    if (selected) {
-      nameColor = systemColor
-    }
-
-    // 鍚嶇О
-    text.attr({
-      y: y - 12,
-      fill: nameColor
-    })
-    text.toFront()
-    textWidth = text.getBBox().width
-
-    if (bottomLine) bottomLine.toFront()
-
-    this.addChildCount(group, childCount && !rootNode, {
-      collapsed,
-      branchColor: model.branchColor,
-      count: childCount ? `${childCount}` : undefined
-    })
-
-    const bbox = group.getBBox()
-    const backContainer = group.addShape('path', {
-      attrs: {
-        path: childCount ? [
-          ['M', bbox.minX, bbox.minY],
-          ['L', bbox.maxX, bbox.minY],
-          ['L', bbox.maxX, bbox.maxY],
-          ['L', bbox.minX + 20, bbox.maxY],
-          ['L', bbox.minX + 20, bbox.maxY + 20],
-          ['L', bbox.minX, bbox.maxY + 20],
-          ['Z']
-        ] : [
-          ['M', bbox.minX, bbox.minY],
-          ['L', bbox.maxX, bbox.minY],
-          ['L', bbox.maxX, bbox.maxY],
-          ['L', bbox.minX, bbox.maxY],
-          ['Z']
-        ],
+// #region 鍒濆鍖栧浘褰�
+const groups = {
+  top: {
+    position: 'top',
+    attrs: {
+      circle: {
+        r: 4,
+        magnet: true,
+        stroke: 'var(--mk-sys-color)',
+        strokeWidth: 1,
         fill: '#fff',
-        opacity: 0
-      }
-    })
-    backContainer.toBack()
-    return keyShape
-  }
-})
-
-G6.registerEdge('indentedEdge', {
-  afterDraw: (cfg, group) => {
-    const sourceNode = cfg.sourceNode && cfg.sourceNode.getModel()
-    const targetNode = cfg.targetNode && cfg.targetNode.getModel()
-    const color = sourceNode.branchColor || targetNode.branchColor || cfg.color || '#000'
-
-    const keyShape = group.get('children')[0]
-    keyShape.attr({
-      stroke: color,
-      lineWidth: 3 // branchThick
-    })
-    group.toBack()
-  },
-  getControlPoints: (cfg) => {
-    const startPoint = cfg.startPoint
-    const endPoint = cfg.endPoint
-    return [
-      startPoint,
-      {
-        x: startPoint.x,
-        y: endPoint.y,
-      },
-      endPoint
-    ]
-  },
-  update: undefined
-}, 'polyline')
-
-G6.registerBehavior('wheel-scroll', {
-  getDefaultCfg() {
-    return {
-      direction: 'y',
-      zoomKey: 'ctrl',
-      sensitivity: 3,
-      scalableRange: -64
-    }
-  },
-  getEvents() {
-    return {
-      wheel: 'onWheel'
-    }
-  },
-  onWheel(ev) {
-    const graph = this.graph
-    let keyDown = ev[`${this.zoomKey}Key`]
-    if (this.zoomKey === 'control') keyDown = ev.ctrlKey
-    if (keyDown) {
-      const sensitivity = this.get('sensitivity')
-      const canvas = graph.get('canvas')
-      const point = canvas.getPointByClient(ev.clientX, ev.clientY)
-      let ratio = graph.getZoom()
-      if (ev.wheelDelta > 0) {
-        ratio *= (1 + 0.01 * sensitivity)
-      } else {
-        ratio *= (1 - 0.01 * sensitivity)
-      }
-      graph.zoomTo(ratio, {
-        x: point.x,
-        y: point.y
-      })
-      graph.emit('wheelzoom', ev)
-    } else {
-      let dx = ev.deltaX || ev.movementX
-      let dy = ev.deltaY || ev.movementY
-      if (!dy && navigator.userAgent.indexOf('Firefox') > -1) dy = (-ev.wheelDelta * 125) / 3
-
-      const width = this.graph.get('width')
-      const height = this.graph.get('height')
-      const graphCanvasBBox = this.graph.get('group').getCanvasBBox()
-
-      let expandWidth = this.scalableRange
-      let expandHeight = this.scalableRange
-      // 鑻� scalableRange 鏄� 0~1 鐨勫皬鏁帮紝鍒欎綔涓烘瘮渚嬭�冭檻
-      if (expandWidth < 1 && expandWidth > -1) {
-        expandWidth = width * expandWidth
-        expandHeight = height * expandHeight
-      }
-
-      const { minX, maxX, minY, maxY } = graphCanvasBBox
-
-      if (dx > 0) {
-        if (maxX < -expandWidth) {
-          dx = 0
-        } else if (maxX - dx < -expandWidth) {
-          dx = maxX + expandWidth
-        }
-      } else if (dx < 0) {
-        if (minX > width + expandWidth) {
-          dx = 0
-        } else if (minX - dx > width + expandWidth) {
-          dx = minX - (width + expandWidth)
-        }
-      }
-
-      if (dy > 0) {
-        if (maxY < -expandHeight) {
-          dy = 0
-        } else if (maxY - dy < -expandHeight) {
-          dy = maxY + expandHeight
-        }
-      } else if (dy < 0) {
-        if (minY > height + expandHeight) {
-          dy = 0
-        } else if (minY - dy > height + expandHeight) {
-          dy = minY - (height + expandHeight)
-        }
-      }
-
-      if (this.get('direction') === 'x') {
-        dy = 0
-      } else if (this.get('direction') === 'y') {
-        dx = 0
-      }
-
-      graph.translate(-dx, -dy)
-    }
-    ev.preventDefault()
-  }
-})
-G6.registerBehavior('hover-node', {
-  getEvents() {
-    return {
-      'node:mouseover': 'onNodeMouseOver',
-      'node:mouseleave': 'onNodeMouseLeave',
-      'node:mouseenter': 'onNodeMouseEnter'
-    }
-  },
-  onNodeMouseEnter(ev) {
-    const { item } = ev
-    if (!item || item.get('destroyed')) return
-    item.toFront()
-    const model = item.getModel()
-    const { collapsed, depth } = model
-    const rootNode = depth === 0 || model.isRoot
-    const group = item.getContainer()
-
-    if (rootNode) return
-
-    // 鎺у埗瀛愯妭鐐逛釜鏁版爣璁�
-    if (!collapsed) {
-      const childCountGroup = group.find(e => e.get('name') === 'child-count-group')
-      if (childCountGroup) {
-        childCountGroup.show()
-      }
-    }
-  },
-  onNodeMouseOver(ev) {
-    const shape = ev.target
-
-    // tooltip鏄剧ず銆侀殣钘�
-    this.graph.emit('tooltip: show', ev)
-
-    // expand 鐘舵�佷笅锛岃嫢 hover 鍒板瓙鑺傜偣涓暟鏍囪锛屽~鍏呰儗鏅�+鏄剧ず鏀惰捣 icon
-    const { item } = ev
-    const group = item.getContainer()
-    const model = item.getModel()
-    if (!model.collapsed) {
-      const childCountGroup = group.find(e => e.get('name') === 'child-count-group')
-      if (childCountGroup) {
-        childCountGroup.show()
-        const back = childCountGroup.find(e => e.get('name') === 'child-count-rect-shape')
-        const expandIcon = childCountGroup.find(e => e.get('name') === 'child-count-expand-icon')
-        const rootNode = model.depth === 0 || model.isRoot
-        const branchColor = rootNode ? '#576286' : model.branchColor
-        if (shape.get('parent').get('name') === 'child-count-group') {
-          if (back) {
-            back.attr('fill', branchColor || '#fff')
-          }
-          if (expandIcon) {
-            expandIcon.show()
-          }
-        } else {
-          if (back) {
-            back.attr('fill', '#fff')
-          }
-          if (expandIcon) {
-            expandIcon.hide()
-          }
+        style: {
+          visibility: 'hidden'
         }
       }
     }
   },
-  onNodeMouseLeave(ev) {
-    const { item } = ev
-    const model = item.getModel()
-    const group = item.getContainer()
-    const { collapsed } = model
-
-    if (!collapsed) {
-      const childCountGroup = group.find(e => e.get('name') === 'child-count-group')
-      if (childCountGroup) {
-        childCountGroup.hide()
+  right: {
+    position: 'right',
+    attrs: {
+      circle: {
+        r: 4,
+        magnet: true,
+        stroke: 'var(--mk-sys-color)',
+        strokeWidth: 1,
+        fill: '#fff',
+        style: {
+          visibility: 'hidden'
+        }
       }
-
-      const iconsLinkPath = group.find(e => e.get('name') === 'icons-link-path')
-      if (iconsLinkPath) {
-        iconsLinkPath.hide()
-      }
-    }
-
-    this.graph.emit('tooltip: hide', ev)
-  }
-})
-G6.registerBehavior('click-node', {
-  getEvents() {
-    return {
-      'node:click': 'onNodeClick',
-      'canvas:click': 'onCanvasClick'
     }
   },
-  onNodeClick(e) {
-    const { item, target } = e
-    const shape = target
-    const shapeName = shape.cfg.name
-    let model = item.getModel()
-
-    // 鐐瑰嚮鏀惰捣/灞曞紑 icon
-    if (shapeName === 'child-count-rect-shape' || shapeName === 'child-count-text-shape') {
-      const updatedCollapsed = !model.collapsed
-      this.graph.updateItem(item, { collapsed: updatedCollapsed })
-      this.graph.layout()
-      return
-    }
-
-    // 閫変腑鑺傜偣
-    this.graph.getNodes().forEach(node => {
-      let _model = node.get('model')
-      if (_model.selected) {
-        _model.selected = false
-        this.graph.updateItem(node, _model, false)
+  bottom: {
+    position: 'bottom',
+    attrs: {
+      circle: {
+        r: 4,
+        magnet: true,
+        stroke: 'var(--mk-sys-color)',
+        strokeWidth: 1,
+        fill: '#fff',
+        style: {
+          visibility: 'hidden'
+        }
       }
-    })
-
-    model.selected = true
-    this.graph.updateItem(item, model, false)
-
-    return
+    }
   },
-  onCanvasClick(e) {
-    this.graph.getNodes().forEach(node => {
-      let _model = node.get('model')
-      if (_model.selected) {
-        _model.selected = false
-        this.graph.updateItem(node, _model, false)
+  left: {
+    position: 'left',
+    attrs: {
+      circle: {
+        r: 4,
+        magnet: true,
+        stroke: 'var(--mk-sys-color)',
+        strokeWidth: 1,
+        fill: '#fff',
+        style: {
+          visibility: 'hidden'
+        }
       }
-    })
-  }
-})
-const dataIndTransform = (data) => {
-  const changeData = (d) => {
-    let data = { ...d }
-
-    data.type = data.isRoot ? 'indentedRoot' : 'indentedNode'
-
-    if (d.children) {
-      data.children = d.children.map((child) => changeData(child))
     }
-    // 缁欏畾 branchColor 鍜� 0-2 灞傝妭鐐� depth
-    if (data.children && data.children.length) {
-      data.depth = 0
-      data.children.forEach((subtree, i) => {
-        subtree.branchColor = COLORS[i % COLORS.length]
-        // dfs
-        let currentDepth = 1
-        subtree.depth = currentDepth
-        Util.traverseTree(subtree, child => {
-          child.branchColor = COLORS[i % COLORS.length]
-
-          if (!child.depth) {
-            child.depth = currentDepth + 1
-          }
-          else currentDepth = subtree.depth
-          if (child.children) {
-            child.children.forEach(subChild => {
-              subChild.depth = child.depth + 1
-            })
-          }
-
-          if (!data.isRoot) {
-            child.collapsed = data.collapsed || false
-          }
-          return true
-        })
-      })
-    }
-
-    return data
   }
-  return changeData(data)
 }
 
-// 鐭ヨ瘑鍥捐氨鏍�
-G6.registerNode('treeNode', {
-  draw: (cfg, group) => {
-    const { label, selected, children, isRoot } = cfg
-    const rootNode = !!isRoot
-    const hasChildren = children && children.length !== 0
-
-    let width = 0
-    const height = 28
-    const x = 0
-    const y = -height / 2
-
-    // 鍚嶇О鏂囨湰
-    const text = group.addShape('text', {
-      attrs: {
-        text: label,
-        x: x * 2,
-        y,
-        textAlign: 'left',
-        textBaseline: 'top',
-        fontFamily: 'PingFangSC-Regular',
+Graph.registerNode(
+  'mk-rect',
+  {
+    inherit: 'rect',
+    width: 66,
+    height: 36,
+    attrs: {
+      body: {
+        strokeWidth: 1,
+        stroke: '#5F95FF',
+        fill: '#EFF4FF'
       },
-      cursor: 'pointer',
-      name: 'name-text-shape',
-    })
-    const textWidth = text.getBBox().width
-    width = textWidth + 20
-
-    width = width < 60 ? 60 : width
-
-    if (!rootNode && hasChildren) {
-      width += 22
+      text: {
+        fontSize: 12,
+        fill: '#262626'
+      }
+    },
+    ports: {
+      groups,
+      items: [
+        { group: 'top' },
+        { group: 'right' },
+        { group: 'bottom' },
+        { group: 'left' }
+      ]
     }
+  },
+  true
+)
 
-    const keyShapeAttrs = {
-      x,
-      y,
-      width,
-      height,
-      radius: 4
-    }
-
-    const keyShape = group.addShape('rect', {
-      attrs: keyShapeAttrs,
-      name: 'root-key-shape-rect-shape'
-    })
-
-    if (!rootNode) {
-      // 搴曢儴妯嚎
-      group.addShape('path', {
-        attrs: {
-          path: [
-            ['M', x - 1, 0],
-            ['L', width, 0],
-          ],
-          stroke: '#AAB7C4',
-          lineWidth: 1,
-        },
-        name: 'node-path-shape'
-      })
-    }
-
-    const mainX = x - 10
-    const mainY = -height + 15
-
-    if (rootNode) {
-      group.addShape('rect', {
-        attrs: {
-          x: mainX,
-          y: mainY,
-          width: width + 12,
-          height,
-          radius: 14,
-          fill: systemColor,
-          cursor: 'pointer',
-        },
-        name: 'main-shape'
-      })
-    }
-
-    let nameColor = 'rgba(0, 0, 0, 0.85)'
-    if (selected) {
-      nameColor = systemColor
-    }
-
-    // 鍚嶇О
-    if (rootNode) {
-      group.addShape('text', {
-        attrs: {
-          text: label,
-          x: mainX + 18,
-          y: 1,
-          textAlign: 'left',
-          textBaseline: 'middle',
-          fill: '#ffffff',
-          fontSize: 12,
-          fontFamily: 'PingFangSC-Regular',
-          cursor: 'pointer',
-        },
-        name: 'root-text-shape'
-      })
-    } else {
-      group.addShape('text', {
-        attrs: {
-          text: label,
-          x: mainX + 6,
-          y: y - 5,
-          textAlign: 'start',
-          textBaseline: 'top',
-          fill: nameColor,
-          fontSize: 12,
-          fontFamily: 'PingFangSC-Regular',
-          cursor: 'pointer',
-        },
-        name: 'not-root-text-shape'
-      })
-    }
-
-    // 瀛愮被鏁伴噺
-    if (hasChildren && !rootNode) {
-      const childCountHeight = 12
-      const childCountX = width - 22
-      const childCountY = -childCountHeight / 2
-
-      group.addShape('rect', {
-        attrs: {
-          width: 22,
-          height: 12,
-          stroke: systemColor,
-          fill: '#fff',
-          x: childCountX,
-          y: childCountY,
-          radius: 6,
-          cursor: 'pointer',
-        },
-        name: 'child-count-rect-shape',
-      })
-      group.addShape('text', {
-        attrs: {
-          text: `${children.length}`,
-          fill: 'rgba(0, 0, 0, .65)',
-          x: childCountX + 11,
-          y: childCountY + 12,
-          fontSize: 10,
-          width: 22,
-          textAlign: 'center',
-          cursor: 'pointer',
-        },
-        name: 'child-count-text-shape'
-      })
-    }
-
-    return keyShape
-  }
-})
-
-G6.registerEdge('smooth', {
-  draw(cfg, group) {
-    const { startPoint, endPoint } = cfg
-    const hgap = Math.abs(endPoint.x - startPoint.x)
-
-    const path = [
-      ['M', startPoint.x, startPoint.y],
-      [
-        'C',
-        startPoint.x + hgap / 4,
-        startPoint.y,
-        endPoint.x - hgap / 2,
-        endPoint.y,
-        endPoint.x,
-        endPoint.y,
-      ],
-    ]
-
-    const shape = group.addShape('path', {
-      attrs: {
-        stroke: '#AAB7C4',
-        path,
+Graph.registerNode(
+  'mk-polygon',
+  {
+    inherit: 'polygon',
+    width: 66,
+    height: 36,
+    attrs: {
+      body: {
+        strokeWidth: 1,
+        stroke: '#5F95FF',
+        fill: '#EFF4FF'
       },
-      name: 'smooth-path-shape',
-    })
-    return shape
-  },
-})
-
-G6.registerBehavior('click-item', {
-  getEvents() {
-    return {
-      'node:click': 'onNodeClick',
-      'canvas:click': 'onCanvasClick'
+      text: {
+        fontSize: 12,
+        fill: '#262626'
+      }
+    },
+    ports: {
+      groups,
+      items: [
+        { group: 'top' },
+        { group: 'right' },
+        { group: 'bottom' },
+        { group: 'left' }
+      ]
     }
   },
-  onNodeClick(e) {
-    const { item } = e
-    let model = item.getModel()
+  true
+)
 
-    if (model.children) return
-    // 閫変腑鑺傜偣
-    this.graph.getNodes().forEach(node => {
-      let _model = node.get('model')
-      if (_model.selected) {
-        _model.selected = false
-        this.graph.updateItem(node, _model, false)
+Graph.registerNode(
+  'mk-circle',
+  {
+    inherit: 'circle',
+    width: 36,
+    height: 36,
+    attrs: {
+      body: {
+        strokeWidth: 1,
+        stroke: '#5F95FF',
+        fill: '#EFF4FF'
+      },
+      text: {
+        fontSize: 12,
+        fill: '#262626'
       }
-    })
-
-    model.selected = true
-    this.graph.updateItem(item, model, false)
-
-    return
+    },
+    ports: {
+      groups,
+      items: [
+        { group: 'top' },
+        { group: 'right' },
+        { group: 'bottom' },
+        { group: 'left' }
+      ]
+    }
   },
-  onCanvasClick(e) {
-    this.graph.getNodes().forEach(node => {
-      let _model = node.get('model')
-      if (_model.selected) {
-        _model.selected = false
-        this.graph.updateItem(node, _model, false)
-      }
-    })
-  }
-})
+  true
+)
 
-class antvG6Chart extends Component {
+Graph.registerNode(
+  'mk-ellipse',
+  {
+    inherit: 'ellipse',
+    width: 66,
+    height: 36,
+    attrs: {
+      body: {
+        strokeWidth: 1,
+        stroke: '#5F95FF',
+        fill: '#EFF4FF'
+      },
+      text: {
+        fontSize: 12,
+        fill: '#262626'
+      }
+    },
+    ports: {
+      groups,
+      items: [
+        { group: 'top' },
+        { group: 'right' },
+        { group: 'bottom' },
+        { group: 'left' }
+      ]
+    }
+  },
+  true
+)
+
+Graph.registerNode(
+  'mk-star',
+  {
+    inherit: 'polygon',
+    width: 36,
+    height: 36,
+    points: '100,10 40,198 190,78 10,78 160,198',
+    attrs: {
+      body: {
+        fill: '#EFF4FF',
+        stroke: '#5F95FF',
+        strokeWidth: 1,
+        fillRule: 'nonzero'
+      },
+      text: {
+        fontSize: 12,
+        fill: '#262626'
+      }
+    },
+    ports: {
+      groups,
+      items: [
+        { group: 'top' },
+        { group: 'right' },
+        { group: 'bottom' },
+        { group: 'left' }
+      ]
+    }
+  },
+  true
+)
+
+class antvX6Chart extends Component {
   static propTpyes = {
     card: PropTypes.object,
     updateConfig: PropTypes.func,
@@ -950,8 +249,14 @@
 
   state = {
     card: null,
-    eventListener: null
+    eventListener: null,
+    toolunfold: true,
+    nodeunfold: true,
+    node: null
   }
+
+  selectNode = null
+  mkGraph = null
 
   UNSAFE_componentWillMount () {
     const { card } = this.props
@@ -986,32 +291,12 @@
         plot: _plot,
       }
 
-      if (card.config) {
-        let config = fromJS(card.config).toJS()
-
-        _card.plot = config.plot
-        _card.plot.name = card.name
-        _card.style = config.style
-        _card.headerStyle = config.headerStyle
-
-        _card.setting = config.setting
-        _card.columns = config.columns
-        _card.scripts = config.scripts
-      }
-
       this.updateComponent(_card)
     } else {
       this.setState({
         card: fromJS(card).toJS()
       })
     }
-  }
-
-  componentDidMount () {
-    MKEmitter.addListener('tabsChange', this.handleTabsChange)
-    setTimeout(() => {
-      this.viewrender()
-    }, 1000)
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -1025,326 +310,364 @@
     this.setState = () => {
       return
     }
-    MKEmitter.removeListener('tabsChange', this.handleTabsChange)
   }
 
-  handleTabsChange = (parentId) => {
-    const { card } = this.state
-
-    if (parentId.indexOf(card.uuid) > -1 || parentId === 'all') {
-      let _element = document.getElementById(card.uuid + 'canvas')
-      if (_element) {
-        _element.innerHTML = ''
-      }
-
-      this.$timer && clearTimeout(this.$timer)
-      this.$timer = setTimeout(this.viewrender, 100)
-    }
-  }
-
-  getdata = () => {
-    const { card } = this.state
-
-    const setData = (list) => {
-      let item = {
-        label: list[0],
-        id: list[0],
-        children: []
-      }
-      if (!list[1]) {
-        delete item.children
-
-        return item
-      } else if (!Array.isArray(list[1])) {
-        return list.map(m => ({label: m, id: m}))
-      }
-
-      for (let i = 1; i < list.length; i++) {
-        let cell = setData(list[i])
-
-        if (Array.isArray(cell)) {
-          item.children.push(...cell)
-        } else {
-          item.children.push(cell)
-        }
-      }
-  
-      return item
-    }
-
-    let data = setData(MindData)
-
-    if (card.plot.subtype === 'mindmap') {
-      if (card.plot.dirField) {
-        data.children[0].direction = 'left'
-        data.children[2].direction = 'left'
-      }
-  
-      data.children.forEach(item => {
-        if (item.direction === 'left') {
-          item.color = card.plot.leftColor || '#26C281'
-        } else {
-          item.direction = 'right'
-          item.color = card.plot.nodeColor || '#1890ff'
-        }
-      })
-
-      data.collapsed = false
-      data.type = 'dice-mind-map-root'
-
-      const collapse = (item) => {
-        if (!item.children) return
-
-        item.children.forEach(cell => {
-          cell.collapsed = card.plot.collapsed === 'true'
-          cell.direction = cell.direction || 'right'
-          cell.type = 'dice-mind-map-leaf'
-          cell.color = cell.color || item.color
-          collapse(cell)
-        })
-      }
-
-      collapse(data)
-    } else if (card.plot.subtype === 'indentTree') {
-      data.isRoot = true
-      data.collapsed = false
-
-      data.children.forEach(item => {
-        item.collapsed = card.plot.collapsed === 'true'
-      })
-    } else if (card.plot.subtype === 'kapmap') {
-      data.isRoot = true
-      data.collapsed = false
-
-      if (card.plot.collapsed === 'true') {
-        const collapse = (item) => {
-          if (!item.children) return
-
-          item.children.forEach(cell => {
-            cell.collapsed = true
-            collapse(cell)
-          })
-        }
-
-        collapse(data)
-      }
-    }
-    
-    return data
+  componentDidMount () {
+    setTimeout(() => {
+      this.viewrender()
+    }, 1000)
   }
 
   viewrender = () => {
-    const { card } = this.state
+    // const { card } = this.state
 
-    if (card.plot.subtype === 'mindmap') {
-      this.ponitrender()
-    } else if (card.plot.subtype === 'indentTree') {
-      this.indentrender()
-    } else if (card.plot.subtype === 'kapmap') {
+    // if (card.plot.subtype === 'mindmap') {
+    //   this.ponitrender()
+    // } else if (card.plot.subtype === 'indentTree') {
+    //   this.indentrender()
+    // } else if (card.plot.subtype === 'kapmap') {
       this.kapmaprender()
-    }
+    // }
   }
 
   kapmaprender = () => {
     const { card } = this.state
-    const plot = card.plot
-    const data = this.getdata()
-    const height = getHeight(plot.height)
 
-    const graph = new G6.TreeGraph({
-      container: card.uuid + 'canvas',
-      width: this.wrap.scrollWidth - 30,
-      height: height,
-      modes: {
-        default: [
-          {
-            type: 'collapse-expand',
-          },
-          'drag-canvas',
-          'zoom-canvas',
-          'click-item'
-        ],
+    // #region 鍒濆鍖栫敾甯�
+    const graph = new Graph({
+      container: document.getElementById(card.uuid + 'container'),
+      // grid: {
+      //   visible: true,
+      //   type: 'doubleMesh',
+      //   args: [
+      //     {
+      //       color: '#eee', // 涓荤綉鏍肩嚎棰滆壊
+      //       thickness: 1   // 涓荤綉鏍肩嚎瀹藉害
+      //     },
+      //     {
+      //       color: '#ddd', // 娆$綉鏍肩嚎棰滆壊
+      //       thickness: 1,  // 娆$綉鏍肩嚎瀹藉害
+      //       factor: 4      // 涓绘缃戞牸绾块棿闅�
+      //     }
+      //   ]
+      // },
+      scaling: {
+        min: 0.5,
+        max: 2
       },
-      defaultNode: {
-        type: 'treeNode',
-        anchorPoints: [
-          [0, 0.5],
-          [1, 0.5],
-        ],
+      autoResize: true,
+      panning: true,
+      background: {
+        color: '#ffffff'
       },
-      defaultEdge: {
-        type: 'smooth',
+      mousewheel: {
+        enabled: true,
+        zoomAtMousePosition: true,
+        modifiers: 'ctrl'
       },
-      layout: {
-        type: 'compactBox',
-        direction: 'LR',
-        getId: function getId(d) {
-          return d.id
+      connecting: {
+        router: 'manhattan',
+        connector: {
+          name: 'rounded',
+          args: {
+            radius: 8
+          }
         },
-        getHeight: function getHeight() {
-          return 16
+        anchor: 'center',
+        connectionPoint: 'anchor',
+        allowBlank: false,
+        snap: {
+          radius: 20
         },
-        getWidth: function getWidth(d) {
-          const labelWidth = G6.Util.getTextSize(d.label, 12)[0]
-          const width = 60 + labelWidth
-          return width
+        createEdge() {
+          return new Shape.Edge({
+            attrs: {
+              line: {
+                stroke: '#A2B1C3',
+                strokeWidth: 2,
+                targetMarker: {
+                  name: 'block',
+                  width: 12,
+                  height: 8
+                }
+              }
+            },
+            zIndex: 0
+          })
         },
-        getVGap: function getVGap() {
-          return 15
-        },
-        getHGap: function getHGap() {
-          return 30
+        validateConnection({ targetMagnet }) {
+          return !!targetMagnet
+        }
+      },
+      highlighting: {
+        magnetAdsorbed: {
+          name: 'stroke',
+          args: {
+            attrs: {
+              fill: '#5F95FF',
+              stroke: '#5F95FF'
+            }
+          }
         }
       }
     })
 
-    graph.data(data)
-    graph.render()
-    graph.fitView()
+    // #region 浣跨敤鎻掍欢
+    graph
+      .use(new Transform({
+        resizing: true,
+        rotating: true
+      }))
+      .use(new Selection())
+      .use(new Snapline())
+      .use(new Keyboard())
+      .use(new Clipboard())
+      .use(new History())
 
-    if (plot.collapsed === 'true') {
-      graph.zoomTo(1, { x: 0, y: height / 2 })
+    // #region 鍒濆鍖� stencil
+    const stencil = new Stencil({
+      title: '娴佺▼鍥�',
+      target: graph,
+      stencilGraphWidth: 180,
+      stencilGraphHeight: 180,
+      groups: [
+        {
+          title: '閫氱敤鑺傜偣',
+          name: 'group1'
+        },
+        {
+          title: '鑷畾涔�',
+          name: 'group2',
+          graphHeight: 120,
+          layoutOptions: {
+            rowHeight: 70
+          }
+        }
+      ],
+      layoutOptions: {
+        columns: 2,
+        columnWidth: 80,
+        rowHeight: 55
+      }
+    })
+
+    document.getElementById(card.uuid + 'stencil').appendChild(stencil.container)
+
+    // #region 蹇嵎閿笌浜嬩欢
+    graph.bindKey(['meta+c', 'ctrl+c'], () => {
+      const cells = graph.getSelectedCells()
+      if (cells.length) {
+        graph.copy(cells)
+      }
+      return false
+    })
+    graph.bindKey(['meta+x', 'ctrl+x'], () => {
+      const cells = graph.getSelectedCells()
+      if (cells.length) {
+        graph.cut(cells)
+      }
+      return false
+    })
+    graph.bindKey(['meta+v', 'ctrl+v'], () => {
+      if (!graph.isClipboardEmpty()) {
+        graph.paste({ offset: 32 })
+      }
+      return false
+    })
+
+    // undo redo
+    graph.bindKey(['meta+z', 'ctrl+z'], () => {
+      if (graph.canUndo()) {
+        graph.undo()
+      }
+      return false
+    })
+    graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => {
+      if (graph.canRedo()) {
+        graph.redo()
+      }
+      return false
+    })
+
+    // 鍒犻櫎鍏冪礌
+    graph.bindKey(['backspace', 'delete'], () => {
+      const cells = graph.getSelectedCells()
+      if (cells.length) {
+        graph.removeCells(cells)
+        this.selectNode = null
+        this.setState({node: null})
+      }
+    })
+
+    // 鎺у埗杩炴帴妗╂樉绀�/闅愯棌
+    const showPorts = (ports, show) => {
+      for (let i = 0, len = ports.length; i < len; i += 1) {
+        ports[i].style.visibility = show ? 'visible' : 'hidden'
+      }
     }
+    graph.on('node:mouseenter', () => {
+      const container = document.getElementById(card.uuid + 'container')
+      const ports = container.querySelectorAll('.x6-port-body')
+      showPorts(ports, true)
+    })
+    graph.on('node:mouseleave', () => {
+      const container = document.getElementById(card.uuid + 'container')
+      const ports = container.querySelectorAll('.x6-port-body')
+      showPorts(ports, false)
+    })
+
+    graph.on('node:click', ({ e, x, y, node, view }) => {
+      this.selectNode = node
+      
+      this.setState({node: node.store.data})
+    })
+    graph.on('edge:click', ({ e, x, y, edge, view }) => {
+      this.selectNode = edge
+      
+      this.setState({node: edge.store.data})
+
+      graph.clearTransformWidgets()
+    })
+    graph.on('blank:click', ({ e, x, y }) => {
+      this.selectNode = null
+      
+      this.setState({node: null})
+    })
+    
+    const r1 = graph.createNode({
+      shape: 'mk-rect',
+      label: '寮�濮�',
+      attrs: {
+        body: {
+          rx: 20,
+          ry: 26
+        }
+      }
+    })
+    const r2 = graph.createNode({
+      shape: 'mk-rect',
+      label: '杩囩▼'
+    })
+    const r3 = graph.createNode({
+      shape: 'mk-rect',
+      attrs: {
+        body: {
+          rx: 6,
+          ry: 6
+        }
+      },
+      label: '鍙�夎繃绋�'
+    })
+    const r4 = graph.createNode({
+      shape: 'mk-polygon',
+      attrs: {
+        body: {
+          refPoints: '0,10 10,0 20,10 10,20'
+        }
+      },
+      label: '鍐崇瓥'
+    })
+    const r5 = graph.createNode({
+      shape: 'mk-polygon',
+      attrs: {
+        body: {
+          refPoints: '10,0 40,0 30,20 0,20'
+        }
+      },
+      label: '鏁版嵁'
+    })
+    const r6 = graph.createNode({
+      shape: 'mk-circle',
+      label: '杩炴帴'
+    })
+    
+    stencil.load([r1, r2, r3, r4, r5, r6], 'group1')
+    
+    const p1 = graph.createNode({
+      shape: 'mk-ellipse',
+      label: 'ellipse'
+    })
+    const p2 = graph.createNode({
+      shape: 'mk-star',
+      label: ''
+    })
+    
+    stencil.load([p1, p2], 'group2')
+    
+    this.mkGraph = graph
+  }
+  
+  setTop = () => {
+    if (!this.selectNode) {
+      message.warning('璇烽�夋嫨鑺傜偣锛�')
+      return
+    }
+    this.selectNode.toFront()
   }
 
-  indentrender = () => {
-    const { card } = this.state
-    const plot = card.plot
-    const data = this.getdata()
-
-    const tree = new G6.TreeGraph({
-      container: card.uuid + 'canvas',
-      width: this.wrap.scrollWidth - 30,
-      height: getHeight(plot.height),
-      layout: {
-        type: 'indented',
-        direction: 'LR',
-        isHorizontal: true,
-        indent: 40,
-        getHeight: (d) => {
-          if (d.isRoot) {
-            return 30
-          }
-          if (d.collapsed && d.children && d.children.length) {
-            return 36
-          }
-          return 22
-        },
-        getVGap: () => {
-          return 10
-        },
-      },
-      defaultEdge: {
-        type: 'indentedEdge',
-        style: {
-          lineWidth: 2,
-          radius: 16
-        }
-      },
-      minZoom: 0.5,
-      modes: {
-        default: [
-          'drag-canvas',
-          'wheel-scroll',
-          'hover-node',
-          'click-node'
-        ]
-      }
-    })
-    
-    tree.on('afterrender', e => {
-      tree.getEdges().forEach(edge => {
-        const targetNode = edge.getTarget().getModel()
-        const color = targetNode.branchColor
-        tree.updateItem(edge, { color })
-      })
-      setTimeout(() => {
-        tree.moveTo(32, 32)
-        tree.zoomTo(0.7)
-      }, 16)
-    })
-    
-    tree.data(dataIndTransform(data))
-    
-    tree.render()
+  setBottom = () => {
+    if (!this.selectNode) {
+      message.warning('璇烽�夋嫨鑺傜偣锛�')
+      return
+    }
+    // let cells = this.mkGraph.getCells()
+    this.selectNode.toBack()
   }
 
-  /**
-   * @description 鏁g偣鍥�
-   */
-  ponitrender = () => {
-    const { card } = this.state
-    const plot = card.plot
-    const data = this.getdata()
-    const width = this.wrap.scrollWidth - 30
-    const height = getHeight(plot.height)
-    let modes = ['drag-canvas', 'zoom-canvas', 'dice-mindmap']
+  // zoom() 鍙幏鍙栨垨鑰呰缃缉鏀炬瘮渚�
+  setZoomIn = () => {
+    this.mkGraph.zoom(0.1)
+  }
 
-    if (plot.collapsed === 'true') {
-      modes = [{ type: 'collapse-expand' },'drag-canvas', 'zoom-canvas', 'dice-mindmap']
-    }
+  setZoomOut = () => {
+    this.mkGraph.zoom(-0.1)
+  }
 
-    const tree = new G6.TreeGraph({
-      container: card.uuid + 'canvas',
-      width: width,
-      height: height,
-      fitView: true,
-      layout: {
-        type: 'mindmap',
-        direction: 'H',
-        getHeight: () => {
-          return 16
-        },
-        getWidth: (node) => {
-          return node.level === 0 ?
-            Util.getTextSize(node.label, 16)[0] + 12 :
-            Util.getTextSize(node.label, 12)[0]
-        },
-        getVGap: () => {
-          return 10
-        },
-        getHGap: () => {
-          return 60
-        },
-        getSide: (node) => {
-          return node.data.direction
+  setZoomInt = () => {
+    this.mkGraph.zoomTo(1)
+  }
+
+  save = () => {
+    // let nodes = this.mkGraph.toJSON()
+  }
+
+  changeProps = (value, key) => {
+    const { node } = this.state
+
+    if (node.shape === 'edge') {
+      if (key === 'title') {
+        this.selectNode.setLabels(value)
+      } else if (key === 'stroke') {
+        this.selectNode.attr('line/stroke', value)
+      } else if (key === 'strokeWidth') {
+        this.selectNode.attr('line/strokeWidth', value)
+      } else if (key === 'lineType') {
+        if (value === 'dash') {
+          this.selectNode.attr('line/strokeDasharray', 5)
+        } else {
+          this.selectNode.attr('line/strokeDasharray', 0)
         }
-      },
-      defaultEdge: {
-        type: 'cubic-horizontal',
-        style: {
-          lineWidth: 2
-        }
-      },
-      minZoom: 0.5,
-      modes: {
-        default: modes
+      } else if (key === 'fontSize') {
+        this.selectNode.attr('text/fontSize', value)
+      } else if (key === 'fontFill') {
+        this.selectNode.attr('text/fill', value)
       }
-    })
-
-    tree.data(data)
-    
-    tree.render()
-
-    if (plot.collapsed === 'true' && plot.dirField) {
-      tree.zoomTo(1, { x: width / 2, y: height / 2 })
-    } else if (plot.collapsed === 'true') {
-      tree.zoomTo(1, { x: 0, y: height / 2 })
+    } else {
+      if (key === 'title') {
+        this.selectNode.attr('text/text', value)
+      } else if (key === 'fill') {
+        this.selectNode.attr('body/fill', value)
+      } else if (key === 'stroke') {
+        this.selectNode.attr('body/stroke', value)
+      } else if (key === 'fontSize') {
+        this.selectNode.attr('text/fontSize', value)
+      } else if (key === 'fontFill') {
+        this.selectNode.attr('text/fill', value)
+      }
     }
   }
 
   updateComponent = (card) => {
-    if (this.state.card && (!is(fromJS(card.plot), fromJS(this.state.card.plot)) || !is(fromJS(card.style), fromJS(this.state.card.style)))) {
-      let _element = document.getElementById(card.uuid + 'canvas')
-      if (_element) {
-        _element.innerHTML = ''
-      }
-      this.$timer && clearTimeout(this.$timer)
-      this.$timer = setTimeout(() => {
-        this.viewrender()
-      }, 150)
-    }
-
     card.width = card.plot.width
     card.name = card.plot.name
     card.subtype = card.plot.subtype
@@ -1354,19 +677,6 @@
 
     if (card.errors.length === 0) {
       card.$tables = getTables(card)
-    }
-    
-    if (!card.plot.valueField) {
-      card.errors.push({ level: 0, detail: '鍥捐〃淇℃伅灏氭湭璁剧疆锛�'})
-    } else {
-      let columns = card.columns.map(c => c.field)
-      if (!columns.includes(card.plot.valueField)) {
-        card.errors.push({ level: 0, detail: '鍊煎瓧娈靛湪瀛楁闆嗕腑涓嶅瓨鍦�'})
-      } else if (!columns.includes(card.plot.labelField)) {
-        card.errors.push({ level: 0, detail: '鏂囨湰瀛楁鍦ㄥ瓧娈甸泦涓笉瀛樺湪'})
-      } else if (!columns.includes(card.plot.parentField)) {
-        card.errors.push({ level: 0, detail: '涓婄骇瀛楁鍦ㄥ瓧娈甸泦涓笉瀛樺湪'})
-      }
     }
 
     this.setState({
@@ -1400,17 +710,16 @@
   }
 
   render() {
-    const { card } = this.state
+    const { card, toolunfold, nodeunfold, node } = this.state
     let _style = resetStyle(card.style)
 
     return (
-      <div className="menu-scatter-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
+      <div className="menu-x6-chart-edit-box" style={_style} onClick={this.clickComponent} id={card.uuid}>
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
             <ChartCompileForm config={card} plotchange={this.updateComponent}/>
             <CopyComponent type="antvG6" card={card}/>
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
-            <UserComponent config={card}/>
             <DeleteOutlined className="close" title="delete" onClick={() => this.props.deletecomponent(card.uuid)}/>
             <SettingComponent config={card} updateConfig={this.updateComponent}/>
           </div>
@@ -1418,18 +727,48 @@
           <ToolOutlined/>
         </Popover>
         <NormalHeader config={card} updateComponent={this.updateComponent}/>
-        <div className="canvas" style={{minHeight: card.plot.height}} id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
+        <div className="mk-toolbar">
+          <div className="left-tool">
+            <Tooltip title="缃墠">
+              <VerticalAlignTopOutlined onClick={this.setTop}/>
+            </Tooltip>
+            <Tooltip title="缃悗">
+              <VerticalAlignBottomOutlined onClick={this.setBottom}/>
+            </Tooltip>
+            <Tooltip title="淇濆瓨">
+              <SaveOutlined onClick={this.save}/>
+            </Tooltip>
+          </div>
+          <div className="right-tool">
+            <Tooltip title="鏀惧ぇ">
+              <ZoomInOutlined onClick={this.setZoomIn}/>
+            </Tooltip>
+            <Tooltip title="缂╁皬">
+              <ZoomOutOutlined onClick={this.setZoomOut}/>
+            </Tooltip>
+            <Tooltip title="1:1">
+              <OneToOneOutlined onClick={this.setZoomInt}/>
+            </Tooltip>
+          </div>
+        </div>
+        <div className="canvas" style={{width: '100%', minHeight: card.plot.height, height: card.plot.height}} id={card.uuid + 'canvas'}>
+          <div id={card.uuid + 'stencil'} className={'mk-stencil ' + (toolunfold ? '' : 'merge')}>
+            <div className="tool-control" onClick={() => this.setState({toolunfold: !toolunfold})}>
+              <DoubleLeftOutlined />
+            </div>
+          </div>
+          <div id={card.uuid + 'container'} className="mk-container"></div>
+          <div className={'mk-node-edit ' + (nodeunfold ? '' : 'merge')}>
+            <div className="tool-control" onClick={() => this.setState({nodeunfold: !nodeunfold})}>
+              <DoubleLeftOutlined />
+            </div>
+            <div className="header">璁剧疆</div>
+            {!node ? <div className="empty">鏈�変腑</div> : <NodeUpdate node={node} onChange={this.changeProps}/>}
+          </div>
+        </div>
         <div className="component-name">
           <div className="center">
-            <div className="title" onDoubleClick={() => {
-              let oInput = document.createElement('input')
-              oInput.value = 'anchor' + card.uuid
-              document.body.appendChild(oInput)
-              oInput.select()
-              document.execCommand('Copy')
-              document.body.removeChild(oInput)
-              message.success('澶嶅埗鎴愬姛銆�')
-            }}>{card.name}</div>
+            <div className="title">{card.name}</div>
             <div className="content">
               {card.errors && card.errors.map((err, index) => {
                 if (err.level === 0) {
@@ -1446,4 +785,4 @@
   }
 }
 
-export default antvG6Chart
\ No newline at end of file
+export default antvX6Chart
\ No newline at end of file
diff --git a/src/menu/components/chart/antv-X6/index.scss b/src/menu/components/chart/antv-X6/index.scss
index 5d8ba6f..bb28fcb 100644
--- a/src/menu/components/chart/antv-X6/index.scss
+++ b/src/menu/components/chart/antv-X6/index.scss
@@ -1,4 +1,4 @@
-.menu-scatter-chart-edit-box {
+.menu-x6-chart-edit-box {
   position: relative;
   box-sizing: border-box;
   background: #ffffff;
@@ -6,10 +6,194 @@
   background-repeat: no-repeat;
   background-size: cover;
   
+  .mk-toolbar {
+    width: 100%;
+    height: 40px;
+    border: 1px solid #1890ff;
+
+    .left-tool {
+      float: left;
+      line-height: 40px;
+      .anticon {
+        margin: 0 10px;
+        font-size: 16px;
+        cursor: pointer;
+      }
+    }
+    .right-tool {
+      float: right;
+      line-height: 40px;
+      .anticon {
+        margin: 0 10px;
+        font-size: 16px;
+        cursor: pointer;
+      }
+    }
+  }
+  .x6-graph-scroller::-webkit-scrollbar {
+    display: none;
+  }
+  .x6-cell.x6-edge.x6-edge-selected path:nth-child(2) {
+    stroke: #1890ff;
+  }
+
   .canvas {
     margin: 0px;
-    padding: 15px;
     letter-spacing: 0px;
+    display: flex;
+
+    .mk-stencil {
+      width: 180px;
+      min-width: 180px;
+      height: 100%;
+      position: relative;
+      z-index: 2;
+      border-right: 1px solid #dfe3e8;
+      transition: all 0.2s;
+
+      .x6-widget-stencil-title {
+        display: none;
+      }
+      .x6-widget-stencil-content {
+        overflow-y: auto;
+      }
+      .x6-widget-stencil-content::-webkit-scrollbar {
+        width: 7px;
+      }
+      .x6-widget-stencil-content::-webkit-scrollbar-thumb {
+        border-radius: 5px;
+        box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+        background: rgba(0, 0, 0, 0.13);
+      }
+      .x6-widget-stencil-content::-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);
+        background: rgba(0, 0, 0, 0);
+      }
+      .tool-control {
+        position: absolute;
+        right: -13px;
+        top: 5px;
+        z-index: 3;
+        background: #ffffff;
+        width: 25px;
+        height: 25px;
+        border: 1px solid #d8d8d8;
+        border-radius: 30px;
+        text-align: center;
+        line-height: 25px;
+        cursor: pointer;
+      }
+    }
+    .mk-stencil.merge {
+      width: 0px;
+      min-width: 0px;
+
+      .tool-control {
+        right: -25px;
+        border-top-left-radius: 0px;
+        border-bottom-left-radius: 0px;
+        .anticon-double-left {
+          transform: rotate(180deg);
+        }
+      }
+    }
+
+    .mk-node-edit {
+      width: 180px;
+      min-width: 180px;
+      height: 100%;
+      position: relative;
+      z-index: 2;
+      border-left: 1px solid #dfe3e8;
+      transition: all 0.2s;
+
+      .header {
+        width: 100%;
+        height: 32px;
+        text-align: center;
+        line-height: 32px;
+        background-color: #f5f5f5!important;
+        overflow-x: hidden;
+        white-space: nowrap;
+      }
+      .empty {
+        width: 100%;
+        text-align: center;
+        padding-top: 20px;
+        overflow-x: hidden;
+        white-space: nowrap;
+      }
+
+      .tool-control {
+        position: absolute;
+        left: -13px;
+        top: 5px;
+        z-index: 3;
+        background: #ffffff;
+        width: 25px;
+        height: 25px;
+        border: 1px solid #d8d8d8;
+        border-radius: 30px;
+        text-align: center;
+        line-height: 25px;
+        cursor: pointer;
+        .anticon-double-left {
+          transform: rotate(180deg);
+        }
+      }
+    }
+    .mk-node-edit.merge {
+      width: 0px;
+      min-width: 0px;
+
+      .tool-control {
+        left: -25px;
+        border-top-right-radius: 0px;
+        border-bottom-right-radius: 0px;
+        .anticon-double-left {
+          transform: rotate(0deg);
+        }
+      }
+    }
+
+    .mk-container {
+      width: calc(100% - 180px);
+      height: 100%;
+    }
+    .x6-widget-stencil  {
+      background-color: #fff;
+    }
+    .x6-widget-stencil-title {
+      background-color: #fff;
+    }
+    .x6-widget-stencil-group-title {
+      background-color: #f5f5f5!important;
+    }
+    .x6-widget-transform {
+      margin: -1px 0 0 -1px;
+      padding: 0px;
+      border: 1px solid #239edd;
+    }
+    .x6-widget-transform > div {
+      border: 1px solid #239edd;
+    }
+    .x6-widget-transform > div:hover {
+      background-color: #3dafe4;
+    }
+    .x6-widget-transform-active-handle {
+      background-color: #3dafe4;
+    }
+    .x6-widget-transform-resize {
+      border-radius: 0;
+    }
+    .x6-widget-selection-inner {
+      border: 1px solid #239edd;
+    }
+    .x6-widget-selection-box {
+      opacity: 0;
+    }
   }
 
   .chart-header {
@@ -42,27 +226,8 @@
     color: rgba(0, 0, 0, 0.85);
     background: rgba(255, 255, 255, 0.55);
   }
-
-  .model-menu-action-list {
-    position: absolute;
-    right: 0px;
-    top: 30px;
-    z-index: 4;
-    font-size: 16px;
-  
-    .ant-row .anticon-plus {
-      float: right;
-    }
-  
-    .page-card {
-      float: right;
-    }
-  }
-  .normal-header + .canvas + .model-menu-action-list {
-    top: 45px;
-  }
 }
-.menu-scatter-chart-edit-box:hover {
+.menu-x6-chart-edit-box:hover {
   z-index: 1;
   box-shadow: 0px 0px 4px #1890ff;
 }
diff --git a/src/menu/components/chart/antv-X6/nodeupdate/index.jsx b/src/menu/components/chart/antv-X6/nodeupdate/index.jsx
new file mode 100644
index 0000000..5dcfb27
--- /dev/null
+++ b/src/menu/components/chart/antv-X6/nodeupdate/index.jsx
@@ -0,0 +1,288 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Form, Row, Col, Input, Select, Radio, InputNumber } from 'antd'
+
+import ColorSketch from '@/mob/colorsketch'
+
+import './index.scss'
+
+class NodeUpdate extends Component {
+  static propTpyes = {
+    node: PropTypes.object
+  }
+
+  state = {
+    formlist: null
+  }
+
+  UNSAFE_componentWillMount () {
+    this.setState({
+      formlist: this.getFormList(this.props.node)
+    })
+  }
+
+  UNSAFE_componentWillReceiveProps(nextProps) {
+    if (!is(fromJS(this.props.node), fromJS(nextProps.node))) {
+      this.setState({
+        formlist: null
+      }, () => {
+        this.setState({
+          formlist: this.getFormList(nextProps.node)
+        })
+      })
+    }
+  }
+
+  getFormList = (node) => {
+    let roleList = sessionStorage.getItem('sysRoles')
+    if (roleList) {
+      try {
+        roleList = JSON.parse(roleList)
+      } catch (e) {
+        roleList = []
+      }
+    } else {
+      roleList = []
+    }
+
+    let title = ''
+    if (node.attrs && node.attrs.text) {
+      title = node.attrs.text.text || ''
+    }
+
+    if (node.shape === 'edge') {
+      // let fontSize = 14
+      // if (node.attrs && node.attrs.text) {
+      //   fontSize = node.attrs.text.fontSize || 14
+      // }
+      let stroke = ''
+
+      if (node.attrs && node.attrs.line) {
+        stroke = node.attrs.line.stroke || '#A2B1C3'
+      }
+
+      let strokeWidth = ''
+
+      if (node.attrs && node.attrs.line) {
+        strokeWidth = node.attrs.line.strokeWidth || 2
+      }
+
+      let lineType = 'solid'
+
+      if (node.attrs && node.attrs.line && node.attrs.line.strokeDasharray) {
+        lineType = 'dash'
+      }
+
+      return [
+        {
+          type: 'title',
+          label: '鍐呭'
+        },
+        {
+          type: 'text',
+          field: 'title',
+          label: '鏍囩',
+          initval: title
+        },
+        {
+          type: 'title',
+          label: '鏍峰紡'
+        },
+        {
+          type: 'color',
+          field: 'stroke',
+          label: '棰滆壊',
+          initval: stroke
+        },
+        {
+          type: 'number',
+          field: 'strokeWidth',
+          label: '绾垮',
+          initval: strokeWidth
+        },
+        {
+          type: 'radio',
+          field: 'lineType',
+          label: '绾垮瀷',
+          initval: lineType,
+          options: [
+            {value: 'solid', text: '瀹炵嚎'},
+            {value: 'dash', text: '铏氱嚎'}
+          ]
+        },
+        // {
+        //   type: 'number',
+        //   field: 'fontSize',
+        //   label: '瀛楀彿',
+        //   initval: fontSize
+        // },
+        // {
+        //   type: 'color',
+        //   field: 'fontFill',
+        //   label: '棰滆壊',
+        //   initval: fontFill
+        // }
+      ]
+    } else {
+      let fontFill = '#262626'
+      if (node.attrs && node.attrs.text) {
+        fontFill = node.attrs.text.fill || '#262626'
+      }
+      
+      let fill = ''
+
+      if (node.attrs && node.attrs.body) {
+        fill = node.attrs.body.fill || ''
+      }
+      let fontSize = 12
+      if (node.attrs && node.attrs.text) {
+        fontSize = node.attrs.text.fontSize || 12
+      }
+      let stroke = ''
+
+      if (node.attrs && node.attrs.body) {
+        stroke = node.attrs.body.stroke || ''
+      }
+      return [
+        {
+          type: 'title',
+          label: '鍐呭'
+        },
+        {
+          type: 'text',
+          field: 'title',
+          label: '鏍囩',
+          initval: title
+        },
+        {
+          type: 'title',
+          label: '鏍峰紡'
+        },
+        {
+          type: 'color',
+          field: 'fill',
+          label: '鑳屾櫙',
+          initval: fill
+        },
+        {
+          type: 'color',
+          field: 'stroke',
+          label: '杈规',
+          initval: stroke
+        },
+        {
+          type: 'title',
+          label: '鏍囩鏍峰紡'
+        },
+        {
+          type: 'number',
+          field: 'fontSize',
+          label: '瀛楀彿',
+          initval: fontSize
+        },
+        {
+          type: 'color',
+          field: 'fontFill',
+          label: '棰滆壊',
+          initval: fontFill
+        }
+      ]
+    }
+  }
+
+  change = (value, key) => {
+    if (key === 'fontSize') {
+      if (typeof(value) !== 'number' || value < 0) {
+        return
+      }
+    }
+
+    this.props.onChange(value, key)
+  }
+
+  getFields() {
+    const { formlist } = this.state
+    const fields = []
+
+    if (!formlist) return
+
+    formlist.forEach((item, index) => {
+      if (item.type === 'title') {
+        fields.push(
+          <Col span={24} key={index}>
+            <span className="split-line">{item.label}</span>
+          </Col>
+        )
+      } else if (item.type === 'text') {
+        fields.push(
+          <Col span={24} key={index}>
+            <Form.Item label={item.label}>
+              <Input defaultValue={item.initval} placeholder="" autoComplete="off" onChange={(e) => this.change(e.target.value, item.field)} />
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'number') {
+        fields.push(
+          <Col span={24} key={index}>
+            <Form.Item label={item.label}>
+              <InputNumber defaultValue={item.initval} precision={0} min={0} onChange={(value) => this.change(value, item.field)} />
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'select') {
+        fields.push(
+          <Col span={24} key={index}>
+            <Form.Item label={item.label}>
+              <Select
+                showSearch
+                defaultValue={item.initval}
+                filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
+                onChange={(value) => {this.change(value, item.field)}}
+              >
+                {item.options.map(option =>
+                  <Select.Option key={option.value} value={option.value}>
+                    {option.text}
+                  </Select.Option>
+                )}
+              </Select>
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'radio') {
+        fields.push(
+          <Col span={24} key={index}>
+            <Form.Item label={item.label}>
+              <Radio.Group defaultValue={item.initval} style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.change(e.target.value, item.field)}}>
+                {item.options.map(option => {
+                  return (
+                    <Radio key={option.value} value={option.value}>{option.text}</Radio>
+                  )
+                })}
+              </Radio.Group>
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'color') {
+        fields.push(
+          <Col span={24} key={index}>
+            <Form.Item label={item.label}>
+              <ColorSketch defaultValue={item.initval} onChange={(value) => this.change(value, item.field)}/>
+            </Form.Item>
+          </Col>
+        )
+      }
+    })
+    return fields
+  }
+
+  render() {
+    return (
+      <Form className="node-edit-form">
+        <Row>{this.getFields()}</Row>
+      </Form>
+    )
+  }
+}
+
+export default NodeUpdate
\ No newline at end of file
diff --git a/src/menu/components/chart/antv-X6/nodeupdate/index.scss b/src/menu/components/chart/antv-X6/nodeupdate/index.scss
new file mode 100644
index 0000000..4434358
--- /dev/null
+++ b/src/menu/components/chart/antv-X6/nodeupdate/index.scss
@@ -0,0 +1,67 @@
+.node-edit-form {
+  padding-top: 10px;
+  .split-line {
+    display: block;
+    border-bottom: 1px solid #d9d9d9;
+    margin: 5px 12px 10px;
+    padding-bottom: 2px;
+    font-size: 13px;
+  }
+  .ant-form-item {
+    display: flex;
+    margin-bottom: 10px;
+
+    .ant-form-item-label {
+      width: 40px;
+      line-height: 24px;
+      label {
+        color: rgba(0,0,0,0.45);
+        font-size: 13px;
+      }
+      label::after {
+        display: none;
+      }
+    }
+    .ant-form-item-control-wrapper {
+      padding: 0 8px;
+      flex: 1;
+      .ant-form-item-control {
+        line-height: 24px;
+      }
+      .ant-input {
+        height: 24px;
+        padding: 0px 4px;
+        font-size: 13px;
+        line-height: 24px;
+        border-radius: 0px;
+      }
+      .ant-input-number {
+        height: 24px;
+        border-radius: 0px;
+        .ant-input-number-input {
+          height: 22px;
+          padding: 2px 4px;
+          font-size: 13px;
+        }
+      }
+      .ant-radio-wrapper {
+        margin-right: 0px;
+      }
+
+      .color-sketch-block {
+        height: 22px;
+        margin-top: 2px;
+        .color-sketch-block-box {
+          width: 22px;
+          height: 22px;
+        }
+        .color-sketch-value {
+          display: none;
+        }
+        .color-sketch-block-inner {
+          border-radius: 0px;
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/menu/components/editor/braft-editor/options.jsx b/src/menu/components/editor/braft-editor/options.jsx
index c746b12..908efea 100644
--- a/src/menu/components/editor/braft-editor/options.jsx
+++ b/src/menu/components/editor/braft-editor/options.jsx
@@ -80,14 +80,33 @@
       label: '鏁版嵁婧�',
       initval: wrap.publicId || '',
       required: true,
-      options: interfaces
+      options: interfaces,
+      reset_source: true,
+      callback: (map, record) => {
+        if (!record.publicId) return
+
+        let interfaces = window.GLOB.customMenu.interfaces || []
+
+        let d = interfaces.filter(m => m.uuid === record.publicId && m.status === 'true')[0]
+
+        if (!d || !d.columns) return
+
+        let columns = JSON.parse(JSON.stringify(d.columns))
+
+        let _field = map.get('field')
+
+        if (_field) {
+          _field.options = columns
+          _field.oriOptions = columns
+          map.set('field', _field)
+        }
+      }
     },
     {
       type: 'select',
       field: 'field',
       label: '鏂囨湰瀛楁',
       initval: wrap.field || '',
-      tooltip: '閫夋嫨鍔ㄦ�佸�兼椂锛岄渶璁剧疆鏂囨湰瀛楁鎵嶅彲鐢熸晥锛屼娇鐢ㄥ叕鍏辨暟鎹簮鏃讹紝闇�鍏堜繚瀛樻暟鎹簮鍚庡啀閫夊彇鏂囨湰瀛楁銆�',
       required: false,
       options: columns
     },
diff --git a/src/menu/components/form/formaction/actionform/index.jsx b/src/menu/components/form/formaction/actionform/index.jsx
index 7f5eae5..6e9ac94 100644
--- a/src/menu/components/form/formaction/actionform/index.jsx
+++ b/src/menu/components/form/formaction/actionform/index.jsx
@@ -1,6 +1,5 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-// import { fromJS } from 'immutable'
 import { Form, Row, Col, Input, Select, Radio, Tooltip, InputNumber, Cascader } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 import { formRule } from '@/utils/option.js'
@@ -17,89 +16,102 @@
   }
 
   state = {
-    formlist: null,  // 琛ㄥ崟淇℃伅
-    interType: null, // 鎺ュ彛绫诲瀷锛氬唴閮ㄣ�佸閮�
-    procMode: null,  // 鍙傛暟鏂瑰紡
-    linkmenu: null,
-    callbackType: null
+    formlist: null
   }
 
+  record = {}
   
   UNSAFE_componentWillMount () {
-    const { card } = this.props
+    this.props.formlist.forEach(item => {
+      this.record[item.key] = item.initVal
+    })
 
-    let _intertype = card.intertype || 'system'  // 鎺ュ彛绫诲瀷
-    let _procMode = card.procMode || 'system'    // 鍙傛暟璇锋眰鏂瑰紡
-    let _callbackType = card.callbackType || 'script'
-
-    let _options = this.getOptions(_intertype, _procMode, card.linkmenu, _callbackType)
+    let { shows, reRequired, reReadonly } = this.getMutilOptions()
 
     this.setState({
-      interType: _intertype,
-      procMode: _procMode,
-      callbackType: _callbackType,
-      linkmenu: card.linkmenu,
       formlist: this.props.formlist.map(item => {
-        if (item.key === 'innerFunc' && _procMode === 'inner') {
-          item.required = true
+        item.hidden = !shows.includes(item.key)
+        item.initVal = this.record[item.key]
+
+        if (reRequired[item.key] !== undefined) {
+          item.required = reRequired[item.key]
+        }
+        if (reReadonly[item.key] !== undefined) {
+          item.readonly = reReadonly[item.key]
         }
 
-        item.hidden = !_options.includes(item.key)
         return item
       })
     })
   }
 
-  getOptions = (_intertype, _procMode, linkmenu, _callbackType) => {
-    const { card } = this.props
+  getMutilOptions = () => {
+    let shows = []
+    let reRequired = {}
+    let reReadonly = {}
 
-    if (card.type === 'prev') {
-      return ['type', 'label', 'enable', 'actionType']
-    } else if (card.type === 'next') {
-      return ['type', 'label', 'enable', 'actionType']
-    } else if (card.type === 'close') {
-      return ['type', 'label', 'enable']
-    }
-    
-    let _options = ['type', 'label', 'intertype', 'Ot', 'execSuccess', 'syncComponent', 'anchors', 'linkmenu', 'enable', 'output', 'reload'] // 閫夐」鍒楄〃
-    
-    if (_intertype === 'custom') {
-      _options.pop()
-      _options.push('procMode', 'interface', 'callbackType', 'proInterface', 'method', 'cross')
-      if (_procMode === 'system') {
-        _options.push('sql', 'sqlType')
-      } else {
-        _options.push('innerFunc')
-      }
-      if (_callbackType === 'func') {
-        _options.push('callbackFunc')
-      } else if (_callbackType !== 'none') {
-        _options.push('cbTable')
-      }
-    } else if (_intertype === 'outer') {
-      _options.push('procMode', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackType')
-      if (_procMode === 'system') {
-        _options.push('sql', 'sqlType')
-      } else if (_procMode === 'inner') {
-        _options.push('innerFunc')
-      }
-      if (_callbackType === 'func') {
-        _options.push('callbackFunc')
-      } else if (_callbackType !== 'none') {
-        _options.push('cbTable')
-      }
-
-    } else if (_intertype === 'inner') {
-      _options.push('innerFunc')
+    if (this.record.type === 'prev') {
+      shows = ['type', 'label', 'enable', 'actionType']
+    } else if (this.record.type === 'next') {
+      shows = ['type', 'label', 'enable', 'actionType']
+    } else if (this.record.type === 'close') {
+      shows = ['type', 'label', 'enable']
     } else {
-      _options.push('sql', 'sqlType')
-    }
-    
-    if (linkmenu && linkmenu !== 'goback') {
-      _options.push('open')
+      shows = ['type', 'label', 'intertype', 'Ot', 'execSuccess', 'syncComponent', 'anchors', 'linkmenu', 'enable', 'output', 'reload'] // 閫夐」鍒楄〃
+      
+      if (this.record.intertype === 'custom') {
+        shows.pop()
+        shows.push('procMode', 'interface', 'callbackType', 'proInterface', 'method', 'cross', 'stringify')
+        if (this.record.procMode === 'system') {
+          shows.push('sql', 'sqlType')
+        } else if (this.record.procMode === 'inner') {
+          shows.push('innerFunc')
+        }
+        if (this.record.callbackType === 'func') {
+          shows.push('callbackFunc')
+        } else if (this.record.callbackType !== 'none') {
+          shows.push('cbTable')
+        }
+      } else if (this.record.intertype === 'outer') {
+        shows.push('procMode', 'sysInterface', 'interface', 'outerFunc', 'callbackType')
+        if (this.record.procMode === 'system') {
+          shows.push('sql', 'sqlType')
+        } else if (this.record.procMode === 'inner') {
+          shows.push('innerFunc')
+        }
+        if (this.record.callbackType === 'func') {
+          shows.push('callbackFunc')
+        } else if (this.record.callbackType !== 'none') {
+          shows.push('cbTable')
+        }
+
+        reRequired.outerFunc = false
+        if (this.record.sysInterface === 'false') {
+          reReadonly.interface = false
+          reRequired.interface = true
+
+          shows.push('proInterface')
+        } else if (this.record.sysInterface === 'true') {
+          reReadonly.interface = true
+          reRequired.interface = false
+          reRequired.outerFunc = true
+        }
+      } else if (this.record.intertype === 'inner') {
+        shows.push('innerFunc')
+      } else {
+        shows.push('sql', 'sqlType')
+      }
+      
+      if (this.record.linkmenu && this.record.linkmenu !== 'goback') {
+        shows.push('open')
+      }
     }
 
-    return _options
+    return {
+      shows,
+      reRequired,
+      reReadonly
+    }
   }
 
   /**
@@ -109,79 +121,35 @@
    * 3銆佸垏鎹㈡爣绛剧被鍨嬶紝閲嶇疆鍙�夋爣绛�
    */
   optionChange = (key, value) => {
-    const { procMode, linkmenu, callbackType } = this.state
+    this.record[key] = value
+    let _fieldval = {}
 
-    if (key === 'intertype') {
-      let _options = this.getOptions(value, procMode, linkmenu, callbackType)
-
-      this.setState({
-        interType: value,
-        formlist: this.state.formlist.map(item => {
-          item.hidden = !_options.includes(item.key)
-
-          if (item.key === 'interface') {
-            item.readonly = false
-          } else if (item.key === 'sysInterface') {
-            item.initVal = 'false'
-          }
-          return item
-        })
-      })
-    } else if (key === 'procMode') {
-      let _options = this.getOptions(this.state.interType, value, linkmenu, callbackType)
-
-      this.setState({
-        procMode: value,
-        formlist: this.state.formlist.map(item => {
-          item.hidden = !_options.includes(item.key)
-
-          if (item.key === 'procMode') {
-            item.initVal = value
-          }
-          return item
-        })
-      })
-    } else if (key === 'linkmenu') {
-      let _options = this.getOptions(this.state.interType, procMode, value, callbackType)
-
-      this.setState({
-        linkmenu: value,
-        formlist: this.state.formlist.map(item => {
-          item.hidden = !_options.includes(item.key)
-          return item
-        })
-      })
-    } else if (key === 'callbackType') {
-      let _options = this.getOptions(this.state.interType, procMode, linkmenu, value)
-
-      this.setState({
-        callbackType: value,
-        formlist: this.state.formlist.map(item => {
-          if (item.key === 'callbackType') {
-            item.initVal = value
-          }
-          item.hidden = !_options.includes(item.key)
-          return item
-        })
-      })
-    } else if (key === 'sysInterface') {
+    if (key === 'sysInterface') {
       if (value === 'true') {
-        this.props.form.setFieldsValue({
-          interface: window.GLOB.mainSystemApi || ''
-        })
+        _fieldval.interface = window.GLOB.mainSystemApi || ''
+        this.record.interface = window.GLOB.mainSystemApi || ''
       }
-      this.setState({
-        formlist: this.state.formlist.map(item => {
-          if (item.key === 'interface' && value === 'true') {
-            item.readonly = true
-          } else if (item.key === 'interface') {
-            item.readonly = false
-          }
-
-          return item
-        })
-      })
     }
+
+    let { shows, reRequired, reReadonly } = this.getMutilOptions()
+
+    this.setState({
+      formlist: this.state.formlist.map(item => {
+        item.hidden = !shows.includes(item.key)
+        item.initVal = this.record[item.key]
+
+        if (reRequired[item.key] !== undefined) {
+          item.required = reRequired[item.key]
+        }
+        if (reReadonly[item.key] !== undefined) {
+          item.readonly = reReadonly[item.key]
+        }
+
+        return item
+      })
+    }, () => {
+      this.props.form.setFieldsValue(_fieldval)
+    })
   }
 
   handleSubmit = (e) => {
@@ -394,7 +362,7 @@
                   }
                 ]
               })(
-                <Cascader options={item.options || []} expandTrigger="hover" placeholder=""/>
+                <Cascader onChange={(value) => {this.optionChange(item.key, value)}} options={item.options || []} expandTrigger="hover" placeholder=""/>
               )}
             </Form.Item>
           </Col>
diff --git a/src/menu/components/form/formaction/formconfig.jsx b/src/menu/components/form/formaction/formconfig.jsx
index 47ce8dd..6be2240 100644
--- a/src/menu/components/form/formaction/formconfig.jsx
+++ b/src/menu/components/form/formaction/formconfig.jsx
@@ -163,16 +163,16 @@
     {
       type: 'radio',
       key: 'sysInterface',
-      label: '绯荤粺鎺ュ彛',
+      label: '绯荤粺绫诲瀷',
       initVal: card.sysInterface || 'false',
-      tooltip: '鍗曠偣鐧诲綍绯荤粺',
+      tooltip: '涓氬姟绯荤粺鎸囧悓涓�sso涓嬬殑鍏朵粬涓氬姟绯荤粺',
       required: true,
       options: [{
         value: 'true',
-        text: '鏄�'
+        text: '鍗曠偣'
       }, {
         value: 'false',
-        text: '鍚�'
+        text: '涓氬姟'
       }]
     },
     {
@@ -198,35 +198,6 @@
       initVal: card.proInterface || '',
       tooltip: '姝e紡绯荤粺鎵�浣跨敤鐨勬帴鍙e湴鍧�銆�',
       required: false
-    },
-    {
-      type: 'radio',
-      key: 'method',
-      label: '璇锋眰鏂瑰紡',
-      initVal: card.method || 'post',
-      required: true,
-      options: [{
-        value: 'get',
-        text: 'GET'
-      }, {
-        value: 'post',
-        text: 'POST'
-      }]
-    },
-    {
-      type: 'radio',
-      key: 'cross',
-      label: '璺ㄥ煙璇锋眰',
-      initVal: card.cross || 'true',
-      tooltip: '濡傛灉鑷畾涔夋帴鍙d笉鏀寔璺ㄥ煙璇锋眰锛屼細閫氳繃褰撳墠绯荤粺杞彂銆�',
-      required: false,
-      options: [{
-        value: 'true',
-        text: '鏀寔'
-      }, {
-        value: 'false',
-        text: '涓嶆敮鎸�'
-      }]
     },
     {
       type: 'radio',
@@ -266,6 +237,52 @@
     },
     {
       type: 'radio',
+      key: 'method',
+      label: '璇锋眰鏂瑰紡',
+      initVal: card.method || 'post',
+      required: true,
+      options: [{
+        value: 'get',
+        text: 'GET'
+      }, {
+        value: 'post',
+        text: 'POST'
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'cross',
+      label: '鎺ュ彛璺ㄥ煙',
+      initVal: card.cross || 'true',
+      tooltip: '濡傛灉鑷畾涔夋帴鍙d笉鏀寔璺ㄥ煙璇锋眰锛屼細閫氳繃褰撳墠绯荤粺杞彂銆�',
+      required: false,
+      options: [{
+        value: 'true',
+        text: '鏀寔'
+      }, {
+        value: 'false',
+        text: '涓嶆敮鎸�'
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'stringify',
+      label: '搴忓垪鍖�',
+      initVal: card.stringify || 'text',
+      required: false,
+      options: [{
+        value: 'text',
+        text: 'Text'
+      }, {
+        value: 'JSON',
+        text: 'JSON'
+      }, {
+        value: 'qs',
+        text: 'qs'
+      }]
+    },
+    {
+      type: 'radio',
       key: 'Ot',
       label: '琛岃缃�',
       initVal: card.Ot,
diff --git a/src/menu/components/iframe/options.jsx b/src/menu/components/iframe/options.jsx
index b6e8ca6..38f9154 100644
--- a/src/menu/components/iframe/options.jsx
+++ b/src/menu/components/iframe/options.jsx
@@ -63,7 +63,7 @@
       field: 'height',
       label: '楂樺害',
       initval: wrap.height || '',
-      tooltip: 'ifram楂樺害銆�',
+      tooltip: 'ifram楂樺害銆傛敞锛氶珮搴�100vh鏃朵細鏍规嵁鏍囩椤电獥鍙h繘琛岃皟鏁�',
       required: true,
       options: ['px', 'vh', 'vw']
     },
@@ -99,6 +99,7 @@
       field: 'linkUrl',
       label: '鍦板潃閾炬帴',
       initval: wrap.linkUrl || '',
+      tooltip: '鍦板潃涓殑@userid@涓嶡loginuid@浼氳嚜鍔ㄦ浛鎹负褰撳墠绯荤粺鐨勭櫥褰曚俊鎭��',
       required: true,
       span: 24
     },
diff --git a/src/menu/components/search/main-search/index.scss b/src/menu/components/search/main-search/index.scss
index be92a36..6aff673 100644
--- a/src/menu/components/search/main-search/index.scss
+++ b/src/menu/components/search/main-search/index.scss
@@ -56,18 +56,6 @@
           padding: 4px 20px 4px 5px;
           font-size: 13px;
         }
-        .check-card-edit-box {
-          .no-margin-bottom {
-            margin-bottom: 0px;
-          }
-          .card-cell {
-            padding: 4px 6px;
-          }
-          .card-color-cell {
-            padding: 4px 6px;
-            min-height: 32px;
-          }
-        }
       }
     }
     .ant-form-item::after {
diff --git a/src/menu/components/share/actioncomponent/actionform/index.jsx b/src/menu/components/share/actioncomponent/actionform/index.jsx
index ca3792b..1f430f5 100644
--- a/src/menu/components/share/actioncomponent/actionform/index.jsx
+++ b/src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -12,6 +12,7 @@
 const { TextArea } = Input
 const { Paragraph } = Typography
 const MkEditIcon = asyncComponent(() => import('@/components/mkIcon'))
+const MKTable = asyncComponent(() => import('@/components/normalform/modalform/mkTable'))
 const acTyOptions = {
   pop: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'refreshTab', 'position', 'tipTitle', 'hidden'],
   prompt: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'refreshTab', 'position', 'tipTitle', 'hidden'],
@@ -92,6 +93,8 @@
 
     let hasclass = true
     this.props.formlist.forEach(item => {
+      if (!item.key) return
+
       this.record[item.key] = item.initVal
 
       if (item.key === 'class') {
@@ -163,7 +166,7 @@
       reOptions.intertype = this.state.interTypeOptions
 
       if (intertype === 'custom') {
-        shows.push('procMode', 'interface', 'callbackType', 'proInterface', 'method', 'cross')
+        shows.push('procMode', 'interface', 'callbackType', 'proInterface', 'method', 'cross', 'stringify')
         if (this.record.procMode === 'system') {
           shows.push('sql', 'sqlType')
         } else if (this.record.procMode === 'inner') {
@@ -191,6 +194,7 @@
           shows.push('cbTable')
         }
 
+        reRequired.outerFunc = false
         if (this.record.sysInterface === 'false') {
           reReadonly.interface = false
           reRequired.interface = true
@@ -199,6 +203,7 @@
         } else if (this.record.sysInterface === 'true') {
           reReadonly.interface = true
           reRequired.interface = false
+          reRequired.outerFunc = true
 
           shows.push('interface')
         } else if (this.record.sysInterface === 'external') {
@@ -246,7 +251,7 @@
 
       if (this.record.formType === 'switch') {
         shows.push('field', 'size', 'openVal', 'closeVal', 'openText', 'closeText')
-      } else if (this.record.formType === 'counter') {
+      } else if (this.record.formType === 'counter' || this.record.formType === 'count_line') {
         shows.push('field', 'size', 'min', 'max', 'decimal')
       } else if (this.record.formType === 'radio') {
         shows.push('field', 'checkType', 'openVal', 'closeVal')
@@ -270,6 +275,7 @@
           shows.push('cbTable')
         }
 
+        reRequired.outerFunc = false
         if (this.record.sysInterface === 'false') {
           reReadonly.interface = false
           reRequired.interface = true
@@ -278,6 +284,7 @@
         } else if (this.record.sysInterface === 'true') {
           reReadonly.interface = true
           reRequired.interface = false
+          reRequired.outerFunc = true
 
           shows.push('interface')
         } else if (this.record.sysInterface === 'external') {
@@ -305,6 +312,11 @@
         value: 'custom',
         text: '鑷畾涔�'
       }]
+
+      if (this.record.formType === 'count_line') {
+        reOptions.Ot = requireOptions.filter(op => ['requiredSgl'].includes(op.value))
+        shows = shows.filter(op => ['label', 'OpenType', 'formType', 'Ot', 'width', 'title', 'hidden', 'field', 'size', 'min', 'max', 'decimal'].includes(op))
+      }
     } else if (openType === 'excelIn') {
       reOptions.intertype = this.state.interTypeOptions.filter(op => op.value !== 'custom')
       reOptions.Ot = requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
@@ -313,6 +325,7 @@
         shows.push('innerFunc', 'sysInterface', 'outerFunc', 'callbackFunc')
         reRequired.innerFunc = false
         reRequired.callbackFunc = false
+        reRequired.outerFunc = false
 
         if (this.record.sysInterface === 'false') {
           reReadonly.interface = false
@@ -322,6 +335,7 @@
         } else if (this.record.sysInterface === 'true') {
           reReadonly.interface = true
           reRequired.interface = false
+          reRequired.outerFunc = true
 
           shows.push('interface')
         } else if (this.record.sysInterface === 'external') {
@@ -341,6 +355,7 @@
       if (this.record.intertype === 'outer') {
         shows.push('innerFunc', 'sysInterface', 'outerFunc')
         reRequired.innerFunc = false
+        reRequired.outerFunc = false
 
         if (this.record.sysInterface === 'false') {
           reReadonly.interface = false
@@ -350,6 +365,7 @@
         } else if (this.record.sysInterface === 'true') {
           reReadonly.interface = true
           reRequired.interface = false
+          reRequired.outerFunc = true
 
           shows.push('interface')
         } else if (this.record.sysInterface === 'external') {
@@ -413,6 +429,7 @@
           shows.push('innerFunc', 'sysInterface', 'outerFunc', 'callbackFunc')
           reRequired.innerFunc = false
           reRequired.callbackFunc = false
+          reRequired.outerFunc = false
 
           if (this.record.sysInterface === 'false') {
             reReadonly.interface = false
@@ -422,6 +439,7 @@
           } else if (this.record.sysInterface === 'true') {
             reReadonly.interface = true
             reRequired.interface = false
+            reRequired.outerFunc = true
   
             shows.push('interface')
           } else if (this.record.sysInterface === 'external') {
@@ -520,6 +538,10 @@
       }
     }
 
+    if (shows.includes('syncComponent') && this.record.syncComponent[0] === 'multiComponent') {
+      shows.push('syncComponents')
+    }
+
     if (this.record.show === 'icon') {
       reRequired.icon = true
     } else {
@@ -611,6 +633,11 @@
       }
 
       this.props.updRecord && this.props.updRecord(this.record)
+    } else if (key === 'formType') {
+      if (value === 'count_line') {
+        _fieldval.Ot = 'requiredSgl'
+        this.record.Ot = 'requiredSgl'
+      }
     } else if (key === 'funcType') {
       if (value === 'print') {
         _fieldval.label = '鎵撳嵃'
@@ -858,7 +885,14 @@
           { required: item.required, message: '璇烽�夋嫨' + item.label + '!' }
         ]
 
-        content = <Cascader options={item.options || []} expandTrigger="hover" placeholder=""/>
+        content = <Cascader onChange={(value) => {this.optionChange(item.key, value)}} options={item.options || []} expandTrigger="hover" placeholder=""/>
+      } else if (item.type === 'table') {
+        span = 24
+        className = 'textarea'
+        rules = [
+          { required: item.required, message: '璇锋坊鍔�' + item.label + '!' }
+        ]
+        content = (<MKTable tip={''} columns={item.columns || []} actions={[]}/>)
       } else if (item.type === 'icon') {
         rules = [
           { required: item.required, message: '璇烽�夋嫨' + item.label + '!' }
@@ -1041,7 +1075,7 @@
               }
             })
           }
-          
+
           resolve(values)
         } else {
           reject(err)
diff --git a/src/menu/components/share/actioncomponent/dragaction/card.jsx b/src/menu/components/share/actioncomponent/dragaction/card.jsx
index 3163444..4735517 100644
--- a/src/menu/components/share/actioncomponent/dragaction/card.jsx
+++ b/src/menu/components/share/actioncomponent/dragaction/card.jsx
@@ -97,6 +97,11 @@
     )
   }
 
+  let updateTime = null
+  if (card.updateTime && card.updateTime.indexOf(window.GLOB.curDate) > -1) {
+    updateTime = card.updateTime.substr(11)
+  }
+
   return (
     <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
       <div className="mk-popover-control">
@@ -105,6 +110,7 @@
         <CloseOutlined className="close" onClick={() => delCard(id)} />
         {type !== 'datacard' && type !== 'basetable' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => changeStyle(id)}/> : ''}
         {hasProfile ? <ProfileOutlined className="profile" title="楠岃瘉" onClick={() => profileCard(id)} /> : null}
+        {updateTime}
       </div>
     } trigger="hover">
       <div className="page-card" style={{ opacity: opacity}}>
diff --git a/src/menu/components/share/actioncomponent/formconfig.jsx b/src/menu/components/share/actioncomponent/formconfig.jsx
index 8ab35f0..31b4a64 100644
--- a/src/menu/components/share/actioncomponent/formconfig.jsx
+++ b/src/menu/components/share/actioncomponent/formconfig.jsx
@@ -276,7 +276,7 @@
       ]
     },
     {
-      type: 'radio',
+      type: formTypes.length ? 'select' : 'radio',
       key: 'formType',
       label: '琛ㄥ崟绫诲瀷',
       initVal: card.formType || 'switch',
@@ -290,6 +290,9 @@
       }, {
         value: 'counter',
         text: '璁℃暟鍣�'
+      }, {
+        value: 'count_line',
+        text: '璁℃暟鍣�(鏈湴)'
       }, 
       ...formTypes]
     },
@@ -481,35 +484,6 @@
     },
     {
       type: 'radio',
-      key: 'method',
-      label: '璇锋眰鏂瑰紡',
-      initVal: card.method || 'post',
-      required: true,
-      options: [{
-        value: 'get',
-        text: 'GET'
-      }, {
-        value: 'post',
-        text: 'POST'
-      }]
-    },
-    {
-      type: 'radio',
-      key: 'cross',
-      label: '璺ㄥ煙璇锋眰',
-      initVal: card.cross || 'true',
-      tooltip: '濡傛灉鑷畾涔夋帴鍙d笉鏀寔璺ㄥ煙璇锋眰锛屼細閫氳繃褰撳墠绯荤粺杞彂銆�',
-      required: false,
-      options: [{
-        value: 'true',
-        text: '鏀寔'
-      }, {
-        value: 'false',
-        text: '涓嶆敮鎸�'
-      }]
-    },
-    {
-      type: 'radio',
       key: 'callbackType',
       label: '鍥炶皟鏂瑰紡',
       initVal: card.callbackType || (card.callbackFunc ? 'func' : 'none'),
@@ -542,6 +516,52 @@
       label: '鍥炶皟鍑芥暟',
       initVal: card.callbackFunc || '',
       required: true
+    },
+    {
+      type: 'radio',
+      key: 'method',
+      label: '璇锋眰鏂瑰紡',
+      initVal: card.method || 'post',
+      required: true,
+      options: [{
+        value: 'get',
+        text: 'GET'
+      }, {
+        value: 'post',
+        text: 'POST'
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'cross',
+      label: '鎺ュ彛璺ㄥ煙',
+      initVal: card.cross || 'true',
+      tooltip: '濡傛灉鑷畾涔夋帴鍙d笉鏀寔璺ㄥ煙璇锋眰锛屼細閫氳繃褰撳墠绯荤粺杞彂銆�',
+      required: false,
+      options: [{
+        value: 'true',
+        text: '鏀寔'
+      }, {
+        value: 'false',
+        text: '涓嶆敮鎸�'
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'stringify',
+      label: '搴忓垪鍖�',
+      initVal: card.stringify || 'text',
+      required: false,
+      options: [{
+        value: 'text',
+        text: 'Text'
+      }, {
+        value: 'JSON',
+        text: 'JSON'
+      }, {
+        value: 'qs',
+        text: 'qs'
+      }]
     },
     {
       type: 'select',
@@ -749,7 +769,7 @@
       initVal: card.syncComponent || [],
       tooltip: '鎵ц鎴愬姛鍚庯紙鎴栧脊绐楁爣绛惧叧闂椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑缁勪欢銆傛敞锛氶�夋嫨褰撳墠缁勪欢鐨勪笂绾х粍浠舵棤鏁堬紝鍒锋柊涓婄骇缁勪欢璇烽�夋嫨鎴愬姛鍚庘�滃埛鏂颁笂绾х粍浠� - 琛屸�濄��',
       required: false,
-      options: modules
+      options: modules.length ? [...modules, {value: 'multiComponent', label: '澶氱粍浠�'}] : []
     },
     {
       type: 'radio',
@@ -1168,6 +1188,27 @@
         value: 'progressbar',
         text: '杩涘害鏉�'
       }]
+    },
+    {
+      type: 'table',
+      key: 'syncComponents',
+      label: '缁勪欢鍒楄〃',
+      initVal: card.syncComponents || [],
+      required: true,
+      actions: [],
+      columns: [
+        {
+          title: '缁勪欢',
+          dataIndex: 'syncComId',
+          inputType: 'cascader',
+          editable: true,
+          required: true,
+          extends: [{key: 'label', value: 'label'}],
+          width: '70%',
+          render: (text, record) => record.label,
+          options: modules
+        }
+      ]
     }
   ]
 
@@ -1486,35 +1527,6 @@
     },
     {
       type: 'radio',
-      key: 'method',
-      label: '璇锋眰鏂瑰紡',
-      initVal: card.method || 'post',
-      required: true,
-      options: [{
-        value: 'get',
-        text: 'GET'
-      }, {
-        value: 'post',
-        text: 'POST'
-      }]
-    },
-    {
-      type: 'radio',
-      key: 'cross',
-      label: '璺ㄥ煙璇锋眰',
-      initVal: card.cross || 'true',
-      tooltip: '濡傛灉鑷畾涔夋帴鍙d笉鏀寔璺ㄥ煙璇锋眰锛屼細閫氳繃褰撳墠绯荤粺杞彂銆�',
-      required: false,
-      options: [{
-        value: 'true',
-        text: '鏀寔'
-      }, {
-        value: 'false',
-        text: '涓嶆敮鎸�'
-      }]
-    },
-    {
-      type: 'radio',
       key: 'callbackType',
       label: '鍥炶皟鏂瑰紡',
       initVal: card.callbackType || (card.callbackFunc ? 'func' : 'none'),
@@ -1547,6 +1559,52 @@
       label: '鍥炶皟鍑芥暟',
       initVal: card.callbackFunc || '',
       required: true
+    },
+    {
+      type: 'radio',
+      key: 'method',
+      label: '璇锋眰鏂瑰紡',
+      initVal: card.method || 'post',
+      required: true,
+      options: [{
+        value: 'get',
+        text: 'GET'
+      }, {
+        value: 'post',
+        text: 'POST'
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'cross',
+      label: '鎺ュ彛璺ㄥ煙',
+      initVal: card.cross || 'true',
+      tooltip: '濡傛灉鑷畾涔夋帴鍙d笉鏀寔璺ㄥ煙璇锋眰锛屼細閫氳繃褰撳墠绯荤粺杞彂銆�',
+      required: false,
+      options: [{
+        value: 'true',
+        text: '鏀寔'
+      }, {
+        value: 'false',
+        text: '涓嶆敮鎸�'
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'stringify',
+      label: '搴忓垪鍖�',
+      initVal: card.stringify || 'text',
+      required: false,
+      options: [{
+        value: 'text',
+        text: 'Text'
+      }, {
+        value: 'JSON',
+        text: 'JSON'
+      }, {
+        value: 'qs',
+        text: 'qs'
+      }]
     },
     {
       type: 'select',
@@ -1704,7 +1762,7 @@
       initVal: card.syncComponent || [],
       tooltip: '鎵ц鎴愬姛鍚庯紙鎴栧脊绐楁爣绛惧叧闂椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑缁勪欢銆傛敞锛氶�夋嫨褰撳墠缁勪欢鐨勪笂绾х粍浠舵棤鏁堬紝鍒锋柊涓婄骇缁勪欢璇烽�夋嫨鎴愬姛鍚庘�滃埛鏂颁笂绾х粍浠� - 琛屸�濄��',
       required: false,
-      options: modules
+      options: modules.length ? [...modules, {value: 'multiComponent', label: '澶氱粍浠�'}] : []
     },
     {
       type: 'radio',
@@ -1931,6 +1989,27 @@
         value: 'progressbar',
         text: '杩涘害鏉�'
       }]
+    },
+    {
+      type: 'table',
+      key: 'syncComponents',
+      label: '缁勪欢鍒楄〃',
+      initVal: card.syncComponents || [],
+      required: true,
+      actions: [],
+      columns: [
+        {
+          title: '缁勪欢',
+          dataIndex: 'syncComId',
+          inputType: 'cascader',
+          editable: true,
+          required: true,
+          extends: [{key: 'label', value: 'label'}],
+          width: '70%',
+          render: (text, record) => record.label,
+          options: modules
+        }
+      ]
     }
   ]
 
diff --git a/src/menu/components/share/actioncomponent/index.jsx b/src/menu/components/share/actioncomponent/index.jsx
index 71fd65a..5746ac8 100644
--- a/src/menu/components/share/actioncomponent/index.jsx
+++ b/src/menu/components/share/actioncomponent/index.jsx
@@ -2,6 +2,7 @@
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
 import { Modal, notification, Button } from 'antd'
+import moment from 'moment'
 
 import Utils, { FuncUtils } from '@/utils/utils.js'
 import { getActionForm, getBaseTableActionForm } from './formconfig'
@@ -433,6 +434,8 @@
               btn.style = {}
             }
           }
+
+          btn.updateTime = moment().format('YYYY-MM-DD HH:mm')
           return btn
         } else {
           return item
@@ -505,6 +508,7 @@
       _actionlist = _actionlist.map(item => {
         if (item.uuid === card.uuid) {
           item.verify = res
+          item.updateTime = moment().format('YYYY-MM-DD HH:mm')
         }
   
         return item
diff --git a/src/menu/components/table/base-table/columns/index.jsx b/src/menu/components/table/base-table/columns/index.jsx
index c6b6e95..d1da3b4 100644
--- a/src/menu/components/table/base-table/columns/index.jsx
+++ b/src/menu/components/table/base-table/columns/index.jsx
@@ -51,68 +51,40 @@
   }
 
   render() {
-    const { connectDragSource, connectDropTarget, moveCol, addElement, dropCol, updateCol, editColumn, pasteCell, changeStyle, deleteCol, index, column, align, fields, children, ...restProps } = this.props
+    const { connectDragSource, connectDropTarget, moveCol, componentId, addElement, dropCol, updateCol, editColumn, pasteCell, changeStyle, deleteCol, index, column, align, fields, children, ...restProps } = this.props
 
-    if (index !== undefined && column) {
-      let style = {cursor: 'move', textAlign: align}
-      if (column.Width) {
-        style.width = column.Width
-        style.minWidth = column.Width
-      }
+    if (!column) return (
+      <th {...restProps}>{children}</th>
+    )
 
-      if (window.GLOB.columnId === column.uuid) {
-        style.color = '#1890ff'
-      }
-
-      return connectDragSource(
-        connectDropTarget(<th {...restProps} index={index} style={style} onDoubleClick={() => this.props.editColumn(column)}>
-          <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
-            <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
-              {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
-              {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
-              {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
-              <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
-              {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-              {column.type === 'custom' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
-              <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
-              {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
-            </div>
-          } trigger="hover">
-            {children}
-          </Popover>
-        </th>),
-      )
-    } else if (column) {
-      let style = {textAlign: align}
-      if (column.Width) {
-        style.width = column.Width
-        style.minWidth = column.Width
-      }
-
-      if (window.GLOB.columnId === column.uuid) {
-        style.color = '#1890ff'
-      }
-
-      return (
-        <th {...restProps} style={style} key={column.uuid} onDoubleClick={() => this.props.editColumn(column)}>
-          <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
-            <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
-              {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
-              {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
-              {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
-              <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
-              {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-              <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
-              {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
-            </div>
-          } trigger="hover">
-            {children}
-          </Popover>
-        </th>
-      )
-    } else {
-      return (<th {...restProps}>{children}</th>)
+    let style = {cursor: 'move', textAlign: align}
+    if (column.Width) {
+      style.width = column.Width
+      style.minWidth = column.Width
     }
+
+    if (window.GLOB.columnId === column.uuid) {
+      style.color = '#1890ff'
+    }
+
+    return connectDragSource(
+      connectDropTarget(<th {...restProps} index={index} style={style} onDoubleClick={() => this.props.editColumn(column)}>
+        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+          <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
+            {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
+            {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
+            {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
+            <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
+            {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
+            {column.type === 'custom' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
+            <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
+            {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
+          </div>
+        } trigger="hover">
+          {children}
+        </Popover>
+      </th>),
+    )
   }
 }
 
@@ -127,17 +99,28 @@
 const ColTarget = {
   drop(props, monitor) {
     const item = monitor.getItem()
-    const dragIndex = item.index
-    const hoverIndex = props.index
+    let dragIndex = item.index
+    let hoverIndex = props.index
 
     if (item.$init) {
-      props.dropCol(item, hoverIndex)
+      if (/sub_/.test(hoverIndex)) {
+        message.warning('鍚堝苟鍒楀瓙鍏冪礌鏆備笉鏀寔鎷栨嫿娣诲姞銆�')
+      } else {
+        props.dropCol(item, hoverIndex.replace(new RegExp(props.componentId + '@', 'ig'), ''))
+      }
       return
     } else if (dragIndex === undefined || hoverIndex === undefined || dragIndex === hoverIndex) {
       return
+    } else {
+      let reg = new RegExp(props.componentId + '@', 'ig')
+      if (reg.test(dragIndex)) {
+        props.moveCol(dragIndex.replace(reg, ''), hoverIndex.replace(reg, ''))
+      } else {
+        message.warning('鎷栧姩鍏冪礌涓嶅湪褰撳墠缁勪欢涓��')
+        return
+      }
     }
 
-    props.moveCol(dragIndex, hoverIndex)
     monitor.getItem().index = hoverIndex
   },
 }
@@ -304,12 +287,32 @@
   moveCol = (dragIndex, hoverIndex) => {
     let _columns = fromJS(this.state.columns).toJS()
 
-    _columns.splice(hoverIndex, 0, ..._columns.splice(dragIndex, 1))
+    if (/^sub_/.test(dragIndex) || /^sub_/.test(hoverIndex)) {
+      let sign1 = dragIndex.split('_')
+      let sign2 = hoverIndex.split('_')
+      if (sign1[1] !== sign2[1]) {
+        message.warning('鎷栧姩鍏冪礌涓嶅湪鍚屼竴涓悎骞跺垪涓��')
+        return
+      }
+      this.loopMoveCol(_columns, sign1[1], sign1[2], sign2[2])
+    } else {
+      _columns.splice(hoverIndex, 0, ..._columns.splice(dragIndex, 1))
+    }
 
     this.setState({
       columns: _columns
     }, () => {
       this.props.updatecolumn({...this.props.config, cols: _columns})
+    })
+  }
+
+  loopMoveCol = (columns, colId, dragIndex, hoverIndex) => {
+    columns.forEach(column => {
+      if (column.type === 'colspan' && column.uuid === colId) {
+        column.subcols.splice(hoverIndex, 0, ...column.subcols.splice(dragIndex, 1))
+      } else if (column.type === 'colspan') {
+        this.loopMoveCol(column.subcols, colId, dragIndex, hoverIndex)
+      }
     })
   }
 
@@ -554,7 +557,7 @@
     document.body.removeChild(oInput)
   }
 
-  handlecolumns = (columns, fields, config, isSub) => {
+  handlecolumns = (columns, fields, config, pId) => {
     return columns.map((col, index) => {
       return {
         title: col.label,
@@ -568,8 +571,9 @@
           upComponent: this.updateCol
         }),
         onHeaderCell: () => ({
-          index: isSub ? undefined : index,
+          index: pId ? config.uuid + '@sub_' + pId + '_' + index : config.uuid + '@' + index,
           column: col,
+          componentId: config.uuid,
           fields: fields,
           align: col.Align,
           moveCol: this.moveCol,
@@ -581,7 +585,7 @@
           changeStyle: this.changeStyle,
           deleteCol: this.deleteCol,
         }),
-        children: col.subcols && col.subcols.length ? this.handlecolumns(col.subcols, fields, config, true) : null,
+        children: col.subcols && col.subcols.length ? this.handlecolumns(col.subcols, fields, config, col.uuid) : null,
       }
     })
   }
@@ -609,7 +613,7 @@
     let n = []
 
     config.columns.forEach(col => {
-      m.push(`${col.field}(${col.label})`)
+      m.push(`${col.field} ${col.datatype}`)
       n.push(col.field)
     })
 
diff --git a/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
index 14981f8..263da80 100644
--- a/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
+++ b/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
@@ -55,22 +55,30 @@
       label: '鏃犲姩浣�'
     }
   ]
-  columns.forEach(col => {
-    if (col.editable === 'true' && col.uuid !== card.uuid) {
-      editCols.push({
-        field: col.uuid,
-        label: col.label
-      })
-    } else if (col.type === 'colspan') {
-      col.subcols.forEach(subcol => {
-        if (subcol.editable === 'true' && subcol.uuid !== card.uuid) {
-          editCols.push({
-            field: subcol.uuid,
-            label: col.label + '-' + subcol.label
-          })
-        }
-      })
-    }
+
+  let cols = []
+  let getcols = (columns, suplabel = '') => {
+    columns.forEach(col => {
+      if (col.editable === 'true' && col.uuid !== card.uuid) {
+        cols.push({
+          field: col.uuid,
+          label: suplabel + col.label
+        })
+      } else if (col.type === 'colspan') {
+        getcols(col.subcols, col.label + '-')
+      }
+    })
+  }
+
+  getcols(columns)
+ 
+  editCols.push(...cols)
+
+  cols.forEach(col => {
+    editCols.push({
+      field: '$next_' + col.field,
+      label: col.label + '锛堜笅涓�琛岋級'
+    })
   })
 
   return [
@@ -257,6 +265,7 @@
       key: 'dataSource',
       label: '鏁版嵁婧�',
       initVal: card.dataSource || '',
+      placeholder: '绯荤粺鍙橀噺锛歮k_departmentcode銆乵k_organization銆乵k_user_type銆�',
       required: true,
     },
     {
diff --git a/src/menu/components/table/edit-table/columns/editColumn/index.jsx b/src/menu/components/table/edit-table/columns/editColumn/index.jsx
index 9a0143c..06b4348 100644
--- a/src/menu/components/table/edit-table/columns/editColumn/index.jsx
+++ b/src/menu/components/table/edit-table/columns/editColumn/index.jsx
@@ -373,6 +373,9 @@
         className = 'text-area'
 
         extra = <span className="add-resource-empty" onClick={this.handleEmpty}>绌�</span>
+        if (item.placeholder) {
+          extra = <><span className="resource-public-var">{item.placeholder}</span>{extra}</>
+        }
 
         content = <CodeMirror />
       } else if (item.type === 'options') {
diff --git a/src/menu/components/table/edit-table/columns/editColumn/index.scss b/src/menu/components/table/edit-table/columns/editColumn/index.scss
index 4b369ac..05b0e19 100644
--- a/src/menu/components/table/edit-table/columns/editColumn/index.scss
+++ b/src/menu/components/table/edit-table/columns/editColumn/index.scss
@@ -37,6 +37,12 @@
     cursor: pointer;
     font-size: 14px;
   }
+  .resource-public-var {
+    position: absolute;
+    left: 0px;
+    top: -25px;
+    font-size: 14px;
+  }
   >.ant-row >.ant-col {
     display: inline-block;
     vertical-align: top;
diff --git a/src/menu/components/table/edit-table/columns/index.jsx b/src/menu/components/table/edit-table/columns/index.jsx
index 51b977c..ba13cb7 100644
--- a/src/menu/components/table/edit-table/columns/index.jsx
+++ b/src/menu/components/table/edit-table/columns/index.jsx
@@ -52,71 +52,40 @@
   }
 
   render() {
-    const { connectDragSource, connectDropTarget, moveCol, dropCol, addElement, updateCol, editColumn, pasteCell, changeStyle, deleteCol, index, column, align, fields, children, ...restProps } = this.props
+    const { connectDragSource, connectDropTarget, moveCol, componentId, dropCol, addElement, updateCol, editColumn, pasteCell, changeStyle, deleteCol, index, column, align, fields, children, ...restProps } = this.props
 
     if (!column) return (
-      <th {...restProps} index={index}>
-        {children}
-      </th>
+      <th {...restProps}>{children}</th>
     )
 
-    if (index !== undefined) {
-      let style = {cursor: 'move', textAlign: align}
-      if (column.Width) {
-        style.width = column.Width
-        style.minWidth = column.Width
-      }
-
-      if (window.GLOB.columnId === column.uuid) {
-        style.color = '#1890ff'
-      }
-
-      return connectDragSource(
-        connectDropTarget(<th {...restProps} index={index} style={style} onDoubleClick={() => this.props.editColumn(column)}>
-          <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
-            <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
-              {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
-              {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
-              {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
-              <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
-              {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-              {column.type === 'custom' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
-              <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
-              {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
-            </div>
-          } trigger="hover">
-            {children}
-          </Popover>
-        </th>),
-      )
-    } else if (column) {
-      let style = {textAlign: align}
-      if (column.Width) {
-        style.width = column.Width
-        style.minWidth = column.Width
-      }
-      if (window.GLOB.columnId === column.uuid) {
-        style.color = '#1890ff'
-      }
-
-      return (
-        <th {...restProps} style={style} key={column.uuid} onDoubleClick={() => this.props.editColumn(column)}>
-          <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
-            <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
-              {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
-              {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
-              {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
-              <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
-              {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-              <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
-              {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
-            </div>
-          } trigger="hover">
-            {children}
-          </Popover>
-        </th>
-      )
+    let style = {cursor: 'move', textAlign: align}
+    if (column.Width) {
+      style.width = column.Width
+      style.minWidth = column.Width
     }
+
+    if (window.GLOB.columnId === column.uuid) {
+      style.color = '#1890ff'
+    }
+
+    return connectDragSource(
+      connectDropTarget(<th {...restProps} index={index} style={style} onDoubleClick={() => this.props.editColumn(column)}>
+        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+          <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
+            {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
+            {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
+            {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
+            <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
+            {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
+            {column.type === 'custom' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
+            <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
+            {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
+          </div>
+        } trigger="hover">
+          {children}
+        </Popover>
+      </th>),
+    )
   }
 }
 
@@ -131,17 +100,28 @@
 const ColTarget = {
   drop(props, monitor) {
     const item = monitor.getItem()
-    const dragIndex = item.index
-    const hoverIndex = props.index
+    let dragIndex = item.index
+    let hoverIndex = props.index
 
     if (item.$init) {
-      props.dropCol(item, hoverIndex)
+      if (/sub_/.test(hoverIndex)) {
+        message.warning('鍚堝苟鍒楀瓙鍏冪礌鏆備笉鏀寔鎷栨嫿娣诲姞銆�')
+      } else {
+        props.dropCol(item, hoverIndex.replace(new RegExp(props.componentId + '@', 'ig'), ''))
+      }
       return
     } else if (dragIndex === undefined || hoverIndex === undefined || dragIndex === hoverIndex) {
       return
+    } else {
+      let reg = new RegExp(props.componentId + '@', 'ig')
+      if (reg.test(dragIndex)) {
+        props.moveCol(dragIndex.replace(reg, ''), hoverIndex.replace(reg, ''))
+      } else {
+        message.warning('鎷栧姩鍏冪礌涓嶅湪褰撳墠缁勪欢涓��')
+        return
+      }
     }
-
-    props.moveCol(dragIndex, hoverIndex)
+    
     monitor.getItem().index = hoverIndex
   },
 }
@@ -281,12 +261,32 @@
   moveCol = (dragIndex, hoverIndex) => {
     let _columns = fromJS(this.state.columns).toJS()
 
-    _columns.splice(hoverIndex, 0, ..._columns.splice(dragIndex, 1))
+    if (/^sub_/.test(dragIndex) || /^sub_/.test(hoverIndex)) {
+      let sign1 = dragIndex.split('_')
+      let sign2 = hoverIndex.split('_')
+      if (sign1[1] !== sign2[1]) {
+        message.warning('鎷栧姩鍏冪礌涓嶅湪鍚屼竴涓悎骞跺垪涓��')
+        return
+      }
+      this.loopMoveCol(_columns, sign1[1], sign1[2], sign2[2])
+    } else {
+      _columns.splice(hoverIndex, 0, ..._columns.splice(dragIndex, 1))
+    }
 
     this.setState({
       columns: _columns
     }, () => {
       this.props.updatecolumn({...this.props.config, cols: _columns})
+    })
+  }
+
+  loopMoveCol = (columns, colId, dragIndex, hoverIndex) => {
+    columns.forEach(column => {
+      if (column.type === 'colspan' && column.uuid === colId) {
+        column.subcols.splice(hoverIndex, 0, ...column.subcols.splice(dragIndex, 1))
+      } else if (column.type === 'colspan') {
+        this.loopMoveCol(column.subcols, colId, dragIndex, hoverIndex)
+      }
     })
   }
 
@@ -624,7 +624,7 @@
     MKEmitter.removeListener('submitStyle', this.getStyle)
   }
 
-  handlecolumns = (columns, fields, config, isSub) => {
+  handlecolumns = (columns, fields, config, pId) => {
     return columns.map((col, index) => {
       let title = col.label
       if (col.editable === 'true') {
@@ -643,8 +643,9 @@
           upComponent: this.updateCol
         }),
         onHeaderCell: () => ({
-          index: isSub ? undefined : index,
+          index: pId ? config.uuid + '@sub_' + pId + '_' + index : config.uuid + '@' + index,
           column: col,
+          componentId: config.uuid,
           fields: fields,
           align: col.Align,
           moveCol: this.moveCol,
@@ -656,7 +657,7 @@
           changeStyle: this.changeStyle,
           deleteCol: this.deleteCol,
         }),
-        children: col.subcols && col.subcols.length ? this.handlecolumns(col.subcols, fields, config, true) : null,
+        children: col.subcols && col.subcols.length ? this.handlecolumns(col.subcols, fields, config, col.uuid) : null,
       }
     })
   }
@@ -728,10 +729,7 @@
           destroyOnClose
         >
           <TableVerify
-            card={config.submit}
-            setting={config.setting}
-            cols={config.cols}
-            columns={config.columns}
+            config={config}
             wrappedComponentRef={(inst) => this.verifyRef = inst}
           />
         </Modal>
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 4bdb8d8..8d5c18e 100644
--- a/src/menu/components/table/edit-table/columns/tableIn/index.jsx
+++ b/src/menu/components/table/edit-table/columns/tableIn/index.jsx
@@ -1,13 +1,14 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
-import { Form, Tabs, Row, Col, Input, Button, Popconfirm, notification, Modal, message, InputNumber, Radio, Typography } from 'antd'
-import { StopTwoTone, CheckCircleTwoTone, EditOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
+import { Form, Tabs, Row, Col, Input, Button, Popconfirm, notification, Modal, message, Cascader, Tooltip, InputNumber, Radio, Typography } from 'antd'
+import { StopTwoTone, CheckCircleTwoTone, EditOutlined, SwapOutlined, DeleteOutlined, QuestionCircleOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
 import MKEmitter from '@/utils/events.js'
+import MenuUtils from '@/utils/utils-custom.js'
 import UniqueForm from './uniqueform'
 import CustomScript from './customscript'
 import asyncComponent from '@/utils/asyncComponent'
@@ -28,6 +29,7 @@
   state = {
     verify: {},
     fields: [],
+    modules: [],
     fieldLabel: {},
     systemScripts: [],
     activeKey: 'basemsg',
@@ -175,27 +177,32 @@
   }
 
   UNSAFE_componentWillMount() {
-    const { columns, card, setting } = this.props
-    let _verify = fromJS(card).toJS()
+    const { columns, submit, setting, uuid } = this.props.config
+    let _verify = fromJS(submit).toJS()
     _verify.sheet = _verify.sheet || setting.tableName
 
     let fieldLabel = {}
-    // let _columns = []
-    // let _fields = {}
 
     columns.forEach(col => {
       fieldLabel[col.field] = col.label
-      // _fields[col.field] = col
     })
-    // cols.forEach(col => {
-    //   if (!col.field || col.type === 'index' || !_fields[col.field]) return
-      
-    //   _columns.push(_fields[col.field])
-    // })
+
+    let supId = ''
+    if (setting && setting.supModule) {
+      let pid = setting.supModule[setting.supModule.length - 1]
+      if (pid && pid !== 'empty') {
+        supId = pid
+      } else {
+        supId = ''
+      }
+    }
+    
+    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, uuid, supId)
 
     this.setState({
       fields: fromJS(columns).toJS().filter(item => item.field !== setting.primaryKey),
       fieldLabel,
+      modules: modules,
       verify: _verify
     }, () => {
       this.resetUniqueColumns()
@@ -491,7 +498,7 @@
   }
 
   render() {
-    const { verify, scriptsColumns, uniqueColumns, activeKey, fields } = this.state
+    const { verify, scriptsColumns, uniqueColumns, activeKey, fields, modules } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -562,6 +569,16 @@
                     </Radio.Group>
                   </Form.Item>
                 </Col> : null}
+                <Col span={8}>
+                  <Form.Item label={
+                    <Tooltip placement="topLeft" title="鎵ц鎴愬姛鍚庯紙鎴栧脊绐楁爣绛惧叧闂椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑缁勪欢銆傛敞锛氶�夋嫨褰撳墠缁勪欢鐨勪笂绾х粍浠舵棤鏁堬紝鍒锋柊涓婄骇缁勪欢璇烽�夋嫨鎴愬姛鍚庘�滀笂绾э紙琛岋級鈥濄��">
+                      <QuestionCircleOutlined className="mk-form-tip" />
+                      鍒锋柊缁勪欢
+                    </Tooltip>
+                  }>
+                    <Cascader options={modules} value={verify.syncComponent || []} expandTrigger="hover" allowClear placeholder="" onChange={(val) => this.onOptionChange(val, 'syncComponent')}/>
+                  </Form.Item>
+                </Col>
               </Row>
             </Form>
           </TabPane>
@@ -611,7 +628,7 @@
             <Form {...formItemLayout}>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> S </span>
                     <Button onClick={() => {this.showError('S')}} type="primary" size="small">
                       鏌ョ湅
@@ -619,14 +636,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.stime || 2} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'stime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> Y </span>
                     <Button onClick={() => {this.showError('Y')}} type="primary" size="small">
                       鏌ョ湅
@@ -636,7 +653,15 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -1 </span>
+                    鎵ц鎴愬姛鏃犳彁绀恒��
+                  </Form.Item>
+                </Col>
+              </Row>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> N </span>
                     <Button onClick={() => {this.showError('N')}} type="primary" size="small">
                       鏌ョ湅
@@ -644,14 +669,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.ntime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> F </span>
                     <Button onClick={() => {this.showError('F')}} type="primary" size="small">
                       鏌ョ湅
@@ -659,14 +684,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.ftime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> E </span>
                     <Button onClick={() => {this.showError('E')}} type="primary" size="small">
                       鏌ョ湅
@@ -676,7 +701,7 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> NM </span>
                     <Button onClick={() => {this.showError('NM')}} type="primary" size="small">
                       鏌ョ湅
@@ -686,9 +711,9 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
-                    <span className="errorval"> -1 </span>
-                    涓嶆彁绀�
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -2 </span>
+                    鎵ц澶辫触鏃犳彁绀�
                   </Form.Item>
                 </Col>
               </Row>
diff --git a/src/menu/components/table/normal-table/columns/index.jsx b/src/menu/components/table/normal-table/columns/index.jsx
index 47ea9a5..1713c3c 100644
--- a/src/menu/components/table/normal-table/columns/index.jsx
+++ b/src/menu/components/table/normal-table/columns/index.jsx
@@ -52,68 +52,40 @@
   }
 
   render() {
-    const { connectDragSource, connectDropTarget, moveCol, dropCol, addElement, updateCol, editColumn, pasteCell, changeStyle, deleteCol, index, column, align, fields, children, ...restProps } = this.props
+    const { connectDragSource, connectDropTarget, moveCol, componentId, dropCol, addElement, updateCol, editColumn, pasteCell, changeStyle, deleteCol, index, column, align, fields, children, ...restProps } = this.props
 
-    if (index !== undefined && column) {
-      let style = {cursor: 'move', textAlign: align}
-      if (column.Width) {
-        style.width = column.Width
-        style.minWidth = column.Width
-      }
+    if (!column) return (
+      <th {...restProps}>{children}</th>
+    )
 
-      if (window.GLOB.columnId === column.uuid) {
-        style.color = '#1890ff'
-      }
-
-      return connectDragSource(
-        connectDropTarget(<th {...restProps} index={index} style={style} onDoubleClick={() => this.props.editColumn(column)}>
-          <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
-            <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
-              {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
-              {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
-              {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
-              <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
-              {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-              {column.type === 'custom' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
-              <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
-              {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
-            </div>
-          } trigger="hover">
-            {children}
-          </Popover>
-        </th>),
-      )
-    } else if (column) {
-      let style = {textAlign: align}
-      if (column.Width) {
-        style.width = column.Width
-        style.minWidth = column.Width
-      }
-
-      if (window.GLOB.columnId === column.uuid) {
-        style.color = '#1890ff'
-      }
-
-      return (
-        <th {...restProps} style={style} key={column.uuid} onDoubleClick={() => this.props.editColumn(column)}>
-          <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
-            <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
-              {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
-              {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
-              {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
-              <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
-              {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-              <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
-              {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
-            </div>
-          } trigger="hover">
-            {children}
-          </Popover>
-        </th>
-      )
-    } else {
-      return (<th {...restProps}>{children}</th>)
+    let style = {cursor: 'move', textAlign: align}
+    if (column.Width) {
+      style.width = column.Width
+      style.minWidth = column.Width
     }
+
+    if (window.GLOB.columnId === column.uuid) {
+      style.color = '#1890ff'
+    }
+
+    return connectDragSource(
+      connectDropTarget(<th {...restProps} index={index} style={style} onDoubleClick={() => this.props.editColumn(column)}>
+        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+          <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
+            {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
+            {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
+            {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
+            <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
+            {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
+            {column.type === 'custom' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
+            <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
+            {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
+          </div>
+        } trigger="hover">
+          {children}
+        </Popover>
+      </th>),
+    )
   }
 }
 
@@ -128,17 +100,28 @@
 const ColTarget = {
   drop(props, monitor) {
     const item = monitor.getItem()
-    const dragIndex = item.index
-    const hoverIndex = props.index
+    let dragIndex = item.index
+    let hoverIndex = props.index
 
     if (item.$init) {
-      props.dropCol(item, hoverIndex)
+      if (/sub_/.test(hoverIndex)) {
+        message.warning('鍚堝苟鍒楀瓙鍏冪礌鏆備笉鏀寔鎷栨嫿娣诲姞銆�')
+      } else {
+        props.dropCol(item, hoverIndex.replace(new RegExp(props.componentId + '@', 'ig'), ''))
+      }
       return
     } else if (dragIndex === undefined || hoverIndex === undefined || dragIndex === hoverIndex) {
       return
+    } else {
+      let reg = new RegExp(props.componentId + '@', 'ig')
+      if (reg.test(dragIndex)) {
+        props.moveCol(dragIndex.replace(reg, ''), hoverIndex.replace(reg, ''))
+      } else {
+        message.warning('鎷栧姩鍏冪礌涓嶅湪褰撳墠缁勪欢涓��')
+        return
+      }
     }
 
-    props.moveCol(dragIndex, hoverIndex)
     monitor.getItem().index = hoverIndex
   },
 }
@@ -278,12 +261,32 @@
   moveCol = (dragIndex, hoverIndex) => {
     let _columns = fromJS(this.state.columns).toJS()
 
-    _columns.splice(hoverIndex, 0, ..._columns.splice(dragIndex, 1))
+    if (/^sub_/.test(dragIndex) || /^sub_/.test(hoverIndex)) {
+      let sign1 = dragIndex.split('_')
+      let sign2 = hoverIndex.split('_')
+      if (sign1[1] !== sign2[1]) {
+        message.warning('鎷栧姩鍏冪礌涓嶅湪鍚屼竴涓悎骞跺垪涓��')
+        return
+      }
+      this.loopMoveCol(_columns, sign1[1], sign1[2], sign2[2])
+    } else {
+      _columns.splice(hoverIndex, 0, ..._columns.splice(dragIndex, 1))
+    }
 
     this.setState({
       columns: _columns
     }, () => {
       this.props.updatecolumn({...this.props.config, cols: _columns})
+    })
+  }
+
+  loopMoveCol = (columns, colId, dragIndex, hoverIndex) => {
+    columns.forEach(column => {
+      if (column.type === 'colspan' && column.uuid === colId) {
+        column.subcols.splice(hoverIndex, 0, ...column.subcols.splice(dragIndex, 1))
+      } else if (column.type === 'colspan') {
+        this.loopMoveCol(column.subcols, colId, dragIndex, hoverIndex)
+      }
     })
   }
 
@@ -507,7 +510,7 @@
     document.body.removeChild(oInput)
   }
 
-  handlecolumns = (columns, fields, config, isSub) => {
+  handlecolumns = (columns, fields, config, pId) => {
     return columns.map((col, index) => {
       return {
         title: col.label,
@@ -521,8 +524,9 @@
           upComponent: this.updateCol
         }),
         onHeaderCell: () => ({
-          index: isSub ? undefined : index,
+          index: pId ? config.uuid + '@sub_' + pId + '_' + index : config.uuid + '@' + index,
           column: col,
+          componentId: config.uuid,
           fields: fields,
           align: col.Align,
           moveCol: this.moveCol,
@@ -534,7 +538,7 @@
           changeStyle: this.changeStyle,
           deleteCol: this.deleteCol,
         }),
-        children: col.subcols && col.subcols.length ? this.handlecolumns(col.subcols, fields, config, true) : null,
+        children: col.subcols && col.subcols.length ? this.handlecolumns(col.subcols, fields, config, col.uuid) : null,
       }
     })
   }
diff --git a/src/menu/datasource/verifycard/index.jsx b/src/menu/datasource/verifycard/index.jsx
index e557a15..ddd14c0 100644
--- a/src/menu/datasource/verifycard/index.jsx
+++ b/src/menu/datasource/verifycard/index.jsx
@@ -64,6 +64,7 @@
         inputType: 'input',
         editable: true,
         unique: true,
+        strict: true,
         copy: true,
         rules: [{
           pattern: /^[\u4E00-\u9FA50-9a-zA-Z_]*$/ig,
@@ -906,7 +907,7 @@
     let n = []
 
     columns.forEach(col => {
-      m.push(`${col.field}(${col.label})`)
+      m.push(`${col.field} ${col.datatype}`)
       n.push(col.field)
     })
 
@@ -927,7 +928,7 @@
     let n = []
 
     subColumns.forEach(col => {
-      m.push(`${col.field}(${col.label})`)
+      m.push(`${col.field} ${col.datatype}`)
       n.push(col.field)
     })
 
diff --git a/src/menu/menushell/card.jsx b/src/menu/menushell/card.jsx
index 467795d..1719f71 100644
--- a/src/menu/menushell/card.jsx
+++ b/src/menu/menushell/card.jsx
@@ -32,6 +32,7 @@
 const Account = asyncComponent(() => import('@/menu/components/module/account'))
 const Iframe = asyncComponent(() => import('@/menu/components/iframe'))
 const AntvG6 = asyncComponent(() => import('@/menu/components/chart/antv-G6'))
+const AntvX6 = asyncComponent(() => import('@/menu/components/chart/antv-X6'))
 
 const Card = ({ id, card, moveCard, findCard, delCard, unGroup, updateConfig }) => {
   const originalIndex = findCard(id).index
@@ -123,12 +124,23 @@
       return (<Iframe card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'antvG6') {
       return (<AntvG6 card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'antvX6') {
+      return (<AntvX6 card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'module' && card.subtype === 'voucher') {
       return (<Voucher card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'module' && card.subtype === 'account') {
       return (<Account card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     }
   }
+
+  // if (card.type === 'antvX6') { // 娴嬭瘯
+  //   return (
+  //     <div className={'ant-col mk-component-card ant-col-' + (card.width || 24)} style={style}>
+  //       <AntvX6 card={card} updateConfig={updateConfig} deletecomponent={delCard}/>
+  //     </div>
+  //   )
+  // }
+
   return (
     <div className={'ant-col mk-component-card ant-col-' + (card.width || 24)} ref={node => drag(drop(node))} style={style}>
       {getCardComponent()}
diff --git a/src/menu/menushell/index.jsx b/src/menu/menushell/index.jsx
index 9533aa5..06b1c59 100644
--- a/src/menu/menushell/index.jsx
+++ b/src/menu/menushell/index.jsx
@@ -118,6 +118,7 @@
         balcony: '娴姩鍗�',
         timeline: '鏃堕棿杞�',
         antvG6: '鏍戝浘',
+        antvX6: '娴佺▼鍥�',
         iframe: 'iframe',
         module: '妯″潡',
         card: '鍗$墖'
diff --git a/src/menu/modalconfig/index.jsx b/src/menu/modalconfig/index.jsx
index a0409b1..a6741f2 100644
--- a/src/menu/modalconfig/index.jsx
+++ b/src/menu/modalconfig/index.jsx
@@ -20,6 +20,7 @@
 
 const { Panel } = Collapse
 const { confirm } = Modal
+const TableComponent = asyncComponent(() => import('./tablecomponent'))
 const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
 const PasteForms = asyncComponent(() => import('@/menu/components/share/pasteforms'))
 const DragElement = asyncComponent(() => import('@/templates/modalconfig/dragelement'))
@@ -525,6 +526,9 @@
         <DndProvider backend={HTML5Backend}>
           <div className="tools">
             <Collapse accordion defaultActiveKey="1" bordered={false}>
+              <Panel header="鍩烘湰淇℃伅" key="0">
+                <TableComponent />
+              </Panel>
               <Panel header="琛ㄥ崟" key="1">
                 <div className="search-element">
                   {SearchItems.map((item, index) => {
diff --git a/src/menu/modalconfig/tablecomponent/index.jsx b/src/menu/modalconfig/tablecomponent/index.jsx
new file mode 100644
index 0000000..01fd0f2
--- /dev/null
+++ b/src/menu/modalconfig/tablecomponent/index.jsx
@@ -0,0 +1,163 @@
+import React, {Component} from 'react'
+import { fromJS } from 'immutable'
+import { Tooltip, Select, List, notification } from 'antd'
+import { QuestionCircleOutlined, CloseOutlined } from '@ant-design/icons'
+import moment from 'moment'
+
+import Api from '@/api'
+import options from '@/store/options.js'
+import Utils from '@/utils/utils.js'
+import MKEmitter from '@/utils/events.js'
+import { queryTableSql } from '@/utils/option.js'
+
+import './index.scss'
+
+const { Option } = Select
+
+class TablesComponent extends Component {
+  state = {
+    tables: [],          // 绯荤粺琛�
+    selectedTables: [],  // 宸查�夎〃
+  }
+
+  /**
+   * @description 鎼滅储鏉′欢鍒濆鍖�
+   */
+  UNSAFE_componentWillMount () {
+    this.setState({
+      selectedTables: window.GLOB.publicTables ? fromJS(window.GLOB.publicTables).toJS() : []
+    })
+  }
+
+  componentDidMount () {
+    this.gettables()
+  }
+
+  /**
+   * @description 鑾峰彇绯荤粺琛�
+   */
+  gettables = () => {
+    let param = {
+      func: 'sPC_Get_SelectedList',
+      LText: queryTableSql,
+      obj_name: 'data',
+      arr_field: 'TbName,Remark'
+    }
+
+    param.LText = Utils.formatOptions(param.LText)
+    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+    param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp) // 浜戠鏁版嵁楠岃瘉
+
+    if (options.cloudServiceApi) { // 涓斿瓨鍦ㄤ簯绔湴鍧�
+      param.rduri = options.cloudServiceApi
+      param.userid = sessionStorage.getItem('CloudUserID') || ''
+      param.LoginUID = sessionStorage.getItem('CloudLoginUID') || ''
+    }
+
+    Api.getSystemCacheConfig(param).then(res => {
+      if (res.status) {
+        this.setState({
+          tables: res.data
+        })
+      } else {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  /**
+   * @description 娣诲姞琛ㄥ悕
+   */
+  onTableChange = (value) => {
+    const { tables, selectedTables } = this.state
+
+    let _table = tables.filter(item => item.TbName === value)[0]
+    let isSelected = !!selectedTables.filter(cell => cell.TbName === value)[0]
+    if (!isSelected) {
+      let _tables = [...selectedTables, _table]
+
+      MKEmitter.emit('publicTableChange', value, 'plus')
+
+      this.setState({
+        selectedTables: _tables
+      })
+    }
+  }
+
+  /**
+   * @description 鍒犻櫎琛ㄥ悕
+   */
+  deleteTable = (table) => {
+    const { selectedTables } = this.state
+
+    let _tables = selectedTables.filter(item => item.TbName !== table.TbName)
+
+    MKEmitter.emit('publicTableChange', table, 'del')
+
+    this.setState({
+      selectedTables: _tables
+    })
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  render() {
+    const { tables, selectedTables } = this.state
+
+    return (
+      <div className="model-tablename-manage-view">
+        {/* 琛ㄥ悕娣诲姞 */}
+        <div className="ant-col ant-form-item-label">
+          <label>
+            <Tooltip placement="topLeft" title="姝ゅ鍙互娣诲姞椤甸潰閰嶇疆鐩稿叧鐨勫父鐢ㄨ〃銆�">
+              <QuestionCircleOutlined className="mk-form-tip" />
+              琛ㄥ悕
+            </Tooltip>
+          </label>
+        </div>
+        <Select
+          showSearch
+          className="tables"
+          style={{ width: '100%' }}
+          optionFilterProp="children"
+          value="璇烽�夋嫨琛ㄥ悕"
+          onSelect={this.onTableChange}
+          dropdownClassName="mk-tables"
+          dropdownMatchSelectWidth={false}
+          showArrow={false}
+          filterOption={(input, option) => {
+            return option.props.children[0].toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
+              option.props.children[2].toLowerCase().indexOf(input.toLowerCase()) >= 0
+          }}
+        > 
+          {tables.map((table, index) => (
+            <Option key={index} title={table.TbName} value={table.TbName}>{table.Remark}<br/>{table.TbName}</Option>
+          ))}
+        </Select>
+        {selectedTables.length > 0 && <List
+          size="small"
+          bordered
+          dataSource={selectedTables}
+          renderItem={(item, index) => <List.Item key={index} title={item.Remark + ' (' + item.TbName + ')'}>
+            {item.Remark + ' (' + item.TbName + ')'}
+            <CloseOutlined onClick={() => this.deleteTable(item)}/>
+          </List.Item>}
+        />}
+      </div>
+    )
+  }
+}
+
+export default TablesComponent
\ No newline at end of file
diff --git a/src/menu/modalconfig/tablecomponent/index.scss b/src/menu/modalconfig/tablecomponent/index.scss
new file mode 100644
index 0000000..92d6c69
--- /dev/null
+++ b/src/menu/modalconfig/tablecomponent/index.scss
@@ -0,0 +1,36 @@
+.model-tablename-manage-view {
+  >.ant-list {
+    margin-top: 20px;
+    .ant-list-item {
+      display: -webkit-box;
+      padding-right: 20px;
+      position: relative;
+      padding-left: 5px;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      -webkit-line-clamp: 2;
+      -webkit-box-orient: vertical;
+      min-height: 55px;
+      width: 100%;
+      .anticon {
+        position: absolute;
+        top: 0px;
+        right: 0px;
+        padding: 3px 3px 10px 10px;
+        cursor: pointer;
+      }
+    }
+  }
+  .tables {
+    width: 66.66666667%!important;
+    .ant-select-selection-selected-value {
+      opacity: 0.4!important;
+    }
+  }
+  >.ant-form-item-label {
+    width: 33.33333333%;
+  }
+}
+.mk-tables {
+  max-width: 300px;
+}
\ No newline at end of file
diff --git a/src/menu/modulesource/option.jsx b/src/menu/modulesource/option.jsx
index e79babd..50d70b5 100644
--- a/src/menu/modulesource/option.jsx
+++ b/src/menu/modulesource/option.jsx
@@ -1,7 +1,6 @@
 import bar from '@/assets/mobimg/bar.png'
 import bar1 from '@/assets/mobimg/bar1.png'
 import line from '@/assets/mobimg/line.png'
-// import line1 from '@/assets/mobimg/line1.png'
 import tabs from '@/assets/mobimg/tabs.png'
 import group from '@/assets/mobimg/group.png'
 import card1 from '@/assets/mobimg/card1.png'
@@ -53,7 +52,6 @@
   { type: 'menu', url: timeline, component: 'timeline', subtype: 'timeline', title: '鏃堕棿杞�', width: 12 },
   { type: 'menu', url: tree, component: 'tree', subtype: 'normaltree', title: '鏍戝舰鍒楄〃', width: 12, forbid: ['billPrint'] },
   { type: 'menu', url: line, component: 'line', subtype: 'line', title: '鎶樼嚎鍥�', width: 24 },
-  // { type: 'menu', url: line1, component: 'line', subtype: 'line1', title: '闃舵鎶樼嚎鍥�', width: 24 },
   { type: 'menu', url: bar, component: 'bar', subtype: 'bar', title: '鏌辩姸鍥�', width: 24 },
   { type: 'menu', url: bar1, component: 'bar', subtype: 'bar1', title: '鏉″舰鍥�', width: 24 },
   { type: 'menu', url: Pie, component: 'pie', subtype: 'pie', title: '楗煎浘', width: 12 },
diff --git a/src/menu/stylecontroller/index.jsx b/src/menu/stylecontroller/index.jsx
index e06a198..a781f01 100644
--- a/src/menu/stylecontroller/index.jsx
+++ b/src/menu/stylecontroller/index.jsx
@@ -1,7 +1,6 @@
 import React, {Component} from 'react'
-import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Collapse, Form, Col, InputNumber, Input, Select, Radio, Drawer, Button } from 'antd'
+import { Collapse, Form, Col, InputNumber, Input, Select, Radio, Drawer, Button, message } from 'antd'
 import {
   ColumnHeightOutlined,
   FontSizeOutlined,
@@ -29,7 +28,7 @@
   ArrowLeftOutlined,
   ArrowRightOutlined,
   SwapOutlined,
-  EnterOutlined,
+  EnterOutlined
 } from '@ant-design/icons'
 
 import MKEmitter from '@/utils/events.js'
@@ -42,14 +41,10 @@
 const { Panel } = Collapse
 const { Option } = Select
 const ColorSketch = asyncComponent(() => import('@/mob/colorsketch'))
+const PasteBoard = asyncComponent(() => import('@/components/pasteboard'))
 const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent'))
 
 class MobController extends Component {
-  static propTpyes = {
-    editElem: PropTypes.any,
-    updateStyle: PropTypes.func,
-  }
-
   state = {
     card: null,
     fonts: null,
@@ -167,7 +162,7 @@
     this.callback = null
   }
 
-  updateStyle = (style, prop) => {
+  updateStyle = (style) => {
     const { card } = this.state
 
     let _style = {
@@ -175,8 +170,16 @@
       ...style
     }
 
-    if (prop && !_style[prop]) {
-      delete _style[prop]
+    Object.keys(style).forEach(key => {
+      if (!_style[key] && _style[key] !== 0) {
+        delete _style[key]
+      }
+    })
+
+    if (_style.position === 'relative' || _style.position === 'absolute') {
+      _style.zIndex = 1
+    } else {
+      delete _style.zIndex
     }
 
     this.setState({
@@ -282,7 +285,7 @@
    * @description 淇敼鑳屾櫙棰滆壊 锛岄鑹叉帶浠�
    */
   changeBackgroundColor = (val) => {
-    this.updateStyle({backgroundColor: val}, 'backgroundColor')
+    this.updateStyle({backgroundColor: val})
   }
 
   changeBackground = (val) => {
@@ -442,15 +445,86 @@
   }
 
   changeWidth = (val) => {
-    this.updateStyle({width: val === '0px' ? '' : val}, 'width')
+    this.updateStyle({width: val})
   }
 
   changeHeight = (val) => {
-    this.updateStyle({height: val === '0px' ? '' : val}, 'height')
+    this.updateStyle({height: val})
   }
 
   changeNormalStyle = (val, type) => {
     this.updateStyle({[type]: val})
+  }
+
+  copy = () => {
+    const { card, options } = this.state
+
+    let msg = { copyType: 'style' }
+
+    msg.data = card
+    msg.options = options
+
+    try {
+      msg = window.btoa(window.encodeURIComponent(JSON.stringify(msg)))
+    } catch (e) {
+      console.warn('Stringify Failure')
+      msg = ''
+    }
+
+    if (msg) {
+      let oInput = document.createElement('input')
+      oInput.value = msg
+      document.body.appendChild(oInput)
+      oInput.select()
+      document.execCommand('Copy')
+      document.body.removeChild(oInput)
+      message.success('澶嶅埗鎴愬姛銆�')
+    }
+  }
+
+  paste = (res, callback) => {
+    const { options } = this.state
+
+    if (res.copyType !== 'style') {
+      message.warning('閰嶇疆淇℃伅鏍煎紡閿欒锛�', 5)
+      return
+    } else if (JSON.stringify(res.options) !== JSON.stringify(options)) {
+      message.warning('鏍峰紡閫夐」涓嶄竴鑷达紝涓嶅彲绮樿创锛�', 5)
+      return
+    }
+
+    let style = res.data || {}
+
+    let backgroundImage = ''
+    if (style.backgroundImage && /^url/ig.test(style.backgroundImage)) {
+      backgroundImage = style.backgroundImage.replace(/^url\(/ig, '').replace(/\)$/ig, '')
+    }
+
+    let borposition = 'outer'
+
+    if (!style.borderWidth) {
+      if (style.borderLeftWidth) {
+        borposition = 'left'
+      } else if (style.borderRightWidth) {
+        borposition = 'right'
+      } else if (style.borderTopWidth) {
+        borposition = 'top'
+      } else if (style.borderBottomWidth) {
+        borposition = 'bottom'
+      }
+    }
+
+    this.setState({
+      card: style,
+      borposition,
+      backgroundImage
+    })
+
+    this.callback && this.callback(style)
+
+    callback()
+
+    message.success('绮樿创鎴愬姛銆�')
   }
 
   render () {
@@ -492,7 +566,7 @@
                     label={<ColumnWidthOutlined title="瀹藉害"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <StyleInput defaultValue={card.width || ''} options={['px', 'vh', 'vw', '%', 'auto']} onChange={this.changeWidth}/>
+                    <StyleInput clear={true} defaultValue={card.width || ''} options={['px', 'vh', 'vw', '%', 'auto']} onChange={this.changeWidth}/>
                   </Form.Item>
                 </Col>
               </Panel> : null}
@@ -503,7 +577,7 @@
                     label={<ColumnHeightOutlined title="楂樺害"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <StyleInput defaultValue={card.height || ''} options={['px', 'vh', 'vw']} onChange={this.changeHeight}/>
+                    <StyleInput clear={true} defaultValue={card.height || ''} options={['px', 'vh', 'vw']} onChange={this.changeHeight}/>
                   </Form.Item>
                 </Col>
               </Panel> : null}
@@ -561,7 +635,7 @@
                     label={<FontColorsOutlined title="瀛椾綋棰滆壊"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <ColorSketch value={card.color || 'rgba(0, 0, 0, 0.85)'} onChange={this.changeFontColor} />
+                    <ColorSketch value={card.color || ''} onChange={this.changeFontColor} />
                   </Form.Item>
                   <Form.Item
                     colon={false}
@@ -771,11 +845,11 @@
                     label={<BgColorsOutlined title="杈规棰滆壊"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    {borposition === 'outer' ? <ColorSketch value={card.borderColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
-                    {borposition === 'left' ? <ColorSketch value={card.borderLeftColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
-                    {borposition === 'right' ? <ColorSketch value={card.borderRightColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
-                    {borposition === 'top' ? <ColorSketch value={card.borderTopColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
-                    {borposition === 'bottom' ? <ColorSketch value={card.borderBottomColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
+                    {borposition === 'outer' ? <ColorSketch value={card.borderColor || ''} onChange={this.changeBorderColor} /> : null}
+                    {borposition === 'left' ? <ColorSketch value={card.borderLeftColor || ''} onChange={this.changeBorderColor} /> : null}
+                    {borposition === 'right' ? <ColorSketch value={card.borderRightColor || ''} onChange={this.changeBorderColor} /> : null}
+                    {borposition === 'top' ? <ColorSketch value={card.borderTopColor || ''} onChange={this.changeBorderColor} /> : null}
+                    {borposition === 'bottom' ? <ColorSketch value={card.borderBottomColor || ''} onChange={this.changeBorderColor} /> : null}
                   </Form.Item>
                   <Form.Item
                     colon={false}
@@ -791,7 +865,7 @@
                     label={<RadiusSettingOutlined title="鍦嗚"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <StyleInput defaultValue={card.borderRadius || '0px'} options={['px', '%']} onChange={(val) => this.changeNormalStyle(val, 'borderRadius')}/>
+                    <StyleInput clear={true} defaultValue={card.borderRadius || ''} options={['px', '%']} onChange={(val) => this.changeNormalStyle(val, 'borderRadius')}/>
                   </Form.Item>
                 </Col>
               </Panel> : null}
@@ -802,7 +876,7 @@
                     label={<BgColorsOutlined title="闃村奖棰滆壊"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <ColorSketch value={card.shadowColor || 'transparent'} onChange={this.changeShadowColor} />
+                    <ColorSketch value={card.shadowColor || ''} onChange={this.changeShadowColor} />
                   </Form.Item>
                   <Form.Item
                     colon={false}
@@ -847,7 +921,7 @@
                     label={<ArrowUpOutlined title="涓婅竟璺�"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <StyleInput defaultValue={card.marginTop || '0px'} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'marginTop')}/>
+                    <StyleInput clear={true} defaultValue={card.marginTop || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'marginTop')}/>
                   </Form.Item>
                 </Col>
                 <Col span={24}>
@@ -856,7 +930,7 @@
                     label={<ArrowDownOutlined title="涓嬭竟璺�"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <StyleInput defaultValue={card.marginBottom || '0px'} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'marginBottom')}/>
+                    <StyleInput clear={true} defaultValue={card.marginBottom || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'marginBottom')}/>
                   </Form.Item>
                 </Col>
                 <Col span={24}>
@@ -865,7 +939,7 @@
                     label={<ArrowLeftOutlined title="宸﹁竟璺�"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <StyleInput defaultValue={card.marginLeft || '0px'} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'marginLeft')}/>
+                    <StyleInput clear={true} defaultValue={card.marginLeft || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'marginLeft')}/>
                   </Form.Item>
                 </Col>
                 <Col span={24}>
@@ -874,7 +948,7 @@
                     label={<ArrowRightOutlined title="鍙宠竟璺�"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <StyleInput defaultValue={card.marginRight || '0px'} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'marginRight')}/>
+                    <StyleInput clear={true} defaultValue={card.marginRight || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'marginRight')}/>
                   </Form.Item>
                 </Col>
               </Panel> : null}
@@ -885,7 +959,7 @@
                     label={<ArrowUpOutlined title="涓婅竟璺�"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <StyleInput defaultValue={card.paddingTop || '0px'} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'paddingTop')}/>
+                    <StyleInput clear={true} defaultValue={card.paddingTop || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'paddingTop')}/>
                   </Form.Item>
                 </Col>
                 <Col span={24}>
@@ -894,7 +968,7 @@
                     label={<ArrowDownOutlined title="涓嬭竟璺�"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <StyleInput defaultValue={card.paddingBottom || '0px'} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'paddingBottom')}/>
+                    <StyleInput clear={true} defaultValue={card.paddingBottom || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'paddingBottom')}/>
                   </Form.Item>
                 </Col>
                 <Col span={24}>
@@ -903,7 +977,7 @@
                     label={<ArrowLeftOutlined title="宸﹁竟璺�"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <StyleInput defaultValue={card.paddingLeft || '0px'} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'paddingLeft')}/>
+                    <StyleInput clear={true} defaultValue={card.paddingLeft || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'paddingLeft')}/>
                   </Form.Item>
                 </Col>
                 <Col span={24}>
@@ -912,7 +986,7 @@
                     label={<ArrowRightOutlined title="鍙宠竟璺�"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <StyleInput defaultValue={card.paddingRight || '0px'} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'paddingRight')}/>
+                    <StyleInput clear={true} defaultValue={card.paddingRight || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'paddingRight')}/>
                   </Form.Item>
                 </Col>
               </Panel> : null}
@@ -938,7 +1012,7 @@
                     label={<ColumnHeightOutlined title="鏈�灏忛珮搴�"/>}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <StyleInput defaultValue={card.minHeight || ''} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'minHeight')}/>
+                    <StyleInput clear={true} defaultValue={card.minHeight || ''} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'minHeight')}/>
                   </Form.Item>
                 </Col>
               </Panel> : null}
@@ -970,10 +1044,65 @@
                   </Form.Item>
                 </Col>
               </Panel> : null}
+              {options.includes('position') ? <Panel header="瀹氫綅" key="position">
+                <Col span={24}>
+                  <Form.Item
+                    colon={false}
+                    label={<SwapOutlined title="瀹氫綅"/>}
+                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
+                  >
+                    <Radio.Group style={{whiteSpace: 'nowrap'}} defaultValue={card.position || 'unset'} onChange={(e) => this.changeNormalStyle(e.target.value, 'position')}>
+                      <Radio value="unset">鏃�</Radio>
+                      <Radio value="relative">鐩稿瀹氫綅</Radio>
+                      <Radio value="absolute">缁濆瀹氫綅</Radio>
+                    </Radio.Group>
+                  </Form.Item>
+                </Col>
+                <Col span={24}>
+                  <Form.Item
+                    colon={false}
+                    label={<ArrowUpOutlined title="涓�"/>}
+                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
+                  >
+                    <StyleInput clear={true} defaultValue={card.top || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'top')}/>
+                  </Form.Item>
+                </Col>
+                <Col span={24}>
+                  <Form.Item
+                    colon={false}
+                    label={<ArrowDownOutlined title="涓�"/>}
+                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
+                  >
+                    <StyleInput clear={true} defaultValue={card.bottom || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'bottom')}/>
+                  </Form.Item>
+                </Col>
+                <Col span={24}>
+                  <Form.Item
+                    colon={false}
+                    label={<ArrowLeftOutlined title="宸�"/>}
+                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
+                  >
+                    <StyleInput clear={true} defaultValue={card.left || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'left')}/>
+                  </Form.Item>
+                </Col>
+                <Col span={24}>
+                  <Form.Item
+                    colon={false}
+                    label={<ArrowRightOutlined title="鍙�"/>}
+                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
+                  >
+                    <StyleInput clear={true} defaultValue={card.right || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'right')}/>
+                  </Form.Item>
+                </Col>
+              </Panel> : null}
             </Collapse> : null}
           </Form>
-          <div style={{textAlign: 'right'}}>
-            <Button style={{margin: '30px 10px 30px 0px'}} onClick={this.onCloseDrawer}>鍏抽棴</Button>
+          <div style={{textAlign: 'right', lineHeight: '60px', marginBottom: '30px'}}>
+            <div style={{float: 'left'}}>
+              <Button onClick={() => this.copy()} className="mk-border-green" style={{marginRight: '10px'}}>澶嶅埗</Button>
+              <PasteBoard getPasteValue={this.paste}><Button style={{borderColor: 'rgb(64, 169, 255)', color: 'rgb(64, 169, 255)'}}>绮樿创</Button></PasteBoard>
+            </div>
+            <Button style={{marginRight: '10px'}} onClick={this.onCloseDrawer}>鍏抽棴</Button>
           </div>
         </div>
       </Drawer>
diff --git a/src/menu/stylecontroller/styleInput/index.jsx b/src/menu/stylecontroller/styleInput/index.jsx
index d7661d0..d3a93a0 100644
--- a/src/menu/stylecontroller/styleInput/index.jsx
+++ b/src/menu/stylecontroller/styleInput/index.jsx
@@ -105,6 +105,7 @@
   }
 
   changeValue = (e) => {
+    const { clear } = this.props
     const { unit } = this.state
     let val = e.target.value
 
@@ -126,7 +127,7 @@
 
     if (this.props.onChange) {
       if (!_val) {
-        this.props.onChange('0px')
+        this.props.onChange(clear ? '' : '0px')
       } else {
         this.props.onChange(`${_val}${unit}`)
       }
diff --git a/src/menu/sysinterface/index.jsx b/src/menu/sysinterface/index.jsx
index e957516..a486c0e 100644
--- a/src/menu/sysinterface/index.jsx
+++ b/src/menu/sysinterface/index.jsx
@@ -221,6 +221,7 @@
     this.setState({ interfaces })
     this.props.updateConfig({...config, interfaces})
 
+    MKEmitter.emit('editLineId', record.uuid)
     setTimeout(() => {
       MKEmitter.emit('mkUpdateInter', record, {delay: 0})
     }, 10)
diff --git a/src/mob/colorsketch/index.jsx b/src/mob/colorsketch/index.jsx
index 65c7df6..63abecf 100644
--- a/src/mob/colorsketch/index.jsx
+++ b/src/mob/colorsketch/index.jsx
@@ -140,7 +140,7 @@
             <div className="color-sketch-block-inner" style={ {background: color} }></div>
           </div>
         </Popover>
-        <div className="color-sketch-value">{color}{allowClear && color ? <CloseCircleFilled onClick={this.clear}/> : null}</div>
+        <div className="color-sketch-value">{color || <span style={{color: '#ff4d4f'}}>鏃�</span>}{allowClear && color ? <CloseCircleFilled onClick={this.clear}/> : null}</div>
       </div>
     )
   }
diff --git a/src/mob/modalconfig/index.jsx b/src/mob/modalconfig/index.jsx
index baa3cb9..285307a 100644
--- a/src/mob/modalconfig/index.jsx
+++ b/src/mob/modalconfig/index.jsx
@@ -20,6 +20,7 @@
 
 const { Panel } = Collapse
 const { confirm } = Modal
+const TableComponent = asyncComponent(() => import('@/menu/modalconfig/tablecomponent'))
 const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
 const PasteForms = asyncComponent(() => import('@/menu/components/share/pasteforms'))
 const DragElement = asyncComponent(() => import('@/mob/components/formdragelement'))
@@ -478,6 +479,9 @@
         <DndProvider backend={HTML5Backend}>
           <div className="tools">
             <Collapse accordion defaultActiveKey="1" bordered={false}>
+              <Panel header="鍩烘湰淇℃伅" key="0">
+                <TableComponent />
+              </Panel>
               <Panel header="琛ㄥ崟" key="1">
                 <div className="search-element">
                   {SearchItems.map((item, index) => {
diff --git a/src/pc/components/navbar/normal-navbar/menusetting/menutable/index.scss b/src/pc/components/navbar/normal-navbar/menusetting/menutable/index.scss
index 120837c..d0c38eb 100644
--- a/src/pc/components/navbar/normal-navbar/menusetting/menutable/index.scss
+++ b/src/pc/components/navbar/normal-navbar/menusetting/menutable/index.scss
@@ -31,8 +31,8 @@
   tr:not(.classify) + .ant-table-expanded-row {
     display: none;
   }
-  td[colspan="6"] {
-    padding: 5px 0px 5px 5px!important;
+  td[colspan="5"] {
+    padding: 5px 0px 5px 0px!important;
   }
   .ant-table-body {
     margin: 0!important;
diff --git a/src/router/index.js b/src/router/index.js
index 5a7b168..d51db23 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -24,6 +24,7 @@
 const RoleManage = asyncLoadComponent(() => import('@/views/rolemanage'))
 const SystemFunc = asyncLoadComponent(() => import('@/views/systemfunc'))
 const SystemProc = asyncLoadComponent(() => import('@/views/systemproc'))
+const MkIframe = asyncLoadComponent(() => import('@/views/mkiframe'))
 
 const routers = [
   {path: '/login', name: 'login', component: Login},
@@ -47,6 +48,8 @@
   {path: '/role/:param', name: 'role', component: RoleManage},
   {path: '/hs', name: 'hs', component: SystemFunc},
   {path: '/proc', name: 'proc', component: SystemProc},
+  {path: '/iframe/:menuId/:userId/:loginUid', name: 'iframe', component: MkIframe},
+  {path: '/iframe/:menuId/:userId/:loginUid/:bid', name: 'iframe', component: MkIframe},
   {path: '/interface', name: 'interface', component: Interface}
 ]
 
diff --git a/src/tabviews/basetable/index.jsx b/src/tabviews/basetable/index.jsx
index 816de31..59932b9 100644
--- a/src/tabviews/basetable/index.jsx
+++ b/src/tabviews/basetable/index.jsx
@@ -348,10 +348,29 @@
                 cell.$MenuID = this.props.MenuID
                 cell.$view = 'popview'
 
-                if (cell.syncComponentId === item.setting.supModule) {
-                  cell.syncComponentId = ''
-                  if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-                    cell.execSuccess = 'mainline'
+                if (cell.syncComponentId) {
+                  if (cell.syncComponentId === item.setting.supModule) {
+                    cell.syncComponentId = ''
+                    if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
+                      cell.execSuccess = 'mainline'
+                    }
+                  } else if (cell.syncComponentId === 'multiComponent') {
+                    let ids = cell.syncComponents.map(m => {
+                      return m.syncComId.pop() || ''
+                    })
+            
+                    if (item.setting.supModule && ids.includes(item.setting.supModule)) {
+                      if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
+                        cell.execSuccess = 'mainline'
+                      }
+                      ids = ids.filter(id => id !== item.setting.supModule)
+                    }
+                    
+                    if (ids.length === 0) {
+                      cell.syncComponentId = ''
+                    } else {
+                      cell.syncComponentIds = ids
+                    }
                   }
                 }
 
@@ -414,10 +433,29 @@
           cell.$view = 'popview'
           cell.$toolbtn = true
 
-          if (cell.syncComponentId === item.setting.supModule) {
-            cell.syncComponentId = ''
-            if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-              cell.execSuccess = 'mainline'
+          if (cell.syncComponentId) {
+            if (cell.syncComponentId === item.setting.supModule) {
+              cell.syncComponentId = ''
+              if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
+                cell.execSuccess = 'mainline'
+              }
+            } else if (cell.syncComponentId === 'multiComponent') {
+              let ids = cell.syncComponents.map(m => {
+                return m.syncComId.pop() || ''
+              })
+      
+              if (item.setting.supModule && ids.includes(item.setting.supModule)) {
+                if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
+                  cell.execSuccess = 'mainline'
+                }
+                ids = ids.filter(id => id !== item.setting.supModule)
+              }
+              
+              if (ids.length === 0) {
+                cell.syncComponentId = ''
+              } else {
+                cell.syncComponentIds = ids
+              }
             }
           }
 
diff --git a/src/tabviews/calendar/index.jsx b/src/tabviews/calendar/index.jsx
index 7dec056..7ed4d3f 100644
--- a/src/tabviews/calendar/index.jsx
+++ b/src/tabviews/calendar/index.jsx
@@ -37,7 +37,6 @@
     lostmsg: '',          // 椤甸潰涓㈠け鏃剁殑鎻愮ず淇℃伅
     config: {},           // 椤甸潰閰嶇疆淇℃伅锛屽寘鎷寜閽�佹悳绱€�佹樉绀哄垪銆佹爣绛剧瓑
     userConfig: null,     // 鐢ㄦ埛鑷畾涔夎缃�
-    searchlist: null,     // 鎼滅储鏉′欢
     arr_field: '',        // 鏌ヨ瀛楁闆�
     setting: null,        // 椤甸潰鍏ㄥ眬璁剧疆锛氭暟鎹簮銆佹寜閽強鏄剧ず鍒楀浐瀹氥�佷富閿瓑
     data: null,           // 鍒楄〃鏁版嵁闆�
@@ -190,6 +189,18 @@
         config.setting.customScript = _customScript
       }
 
+      config.type = 'table'
+      config.wrap = {
+        show: config.setting.show || '',
+        float: config.setting.float || '',
+        advanceType: config.setting.advanceType || '',
+        advanceWidth: config.setting.advanceWidth || '',
+        drawerPlacement: config.setting.drawerPlacement || '',
+        searchRatio: config.setting.searchRatio || '',
+        searchLwidth: config.setting.searchLwidth,
+        borderRadius: config.setting.borderRadius,
+      }
+
       this.setState({
         hasReqFields,
         BID: param && param.$BID ? param.$BID : '',
@@ -197,7 +208,6 @@
         config: config,
         userConfig: userConfig,
         setting: config.setting,
-        searchlist: config.search,
         arr_field: config.columns.map(item => item.field).join(','),
         search: Utils.initMainSearch(config.search)
       }, () => {
@@ -543,13 +553,13 @@
   }
 
   render() {
-    const { BID, setting, searchlist, loadingview, viewlost, config, loading, data, triggerTime } = this.state
+    const { BID, loadingview, viewlost, config, loading, data, triggerTime } = this.state
 
     return (
       <div className="calendar-page">
         {loadingview && <Spin size="large" />}
-        {searchlist && searchlist.length > 0 ?
-          <MainSearch BID={BID} searchlist={searchlist} setting={setting} refreshdata={this.refreshbysearch}/> : null
+        {config.search && config.search.length > 0 ?
+          <MainSearch BID={BID} config={config} refreshdata={this.refreshbysearch}/> : null
         }
         {config && config.calendar ? <CalendarComponent calendar={config.calendar} loading={loading} data={data} triggerDate={this.triggerDate} changeDate={this.changeDate}/> : null}
         {!window.GLOB.mkHS && window.GLOB.systemType !== 'production' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
diff --git a/src/tabviews/commontable/index.jsx b/src/tabviews/commontable/index.jsx
index f1a4fa3..d8e90c6 100644
--- a/src/tabviews/commontable/index.jsx
+++ b/src/tabviews/commontable/index.jsx
@@ -5,7 +5,6 @@
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
-import options from '@/store/options.js'
 import UtilsDM from '@/utils/utils-datamanage.js'
 import { updateCommonTable } from '@/utils/utils-update.js'
 import asyncComponent from '@/utils/asyncComponent'
@@ -46,7 +45,6 @@
     lostmsg: '',          // 椤甸潰涓㈠け鏃剁殑鎻愮ず淇℃伅
     config: {},           // 椤甸潰閰嶇疆淇℃伅锛屽寘鎷寜閽�佹悳绱€�佹樉绀哄垪銆佹爣绛剧瓑
     shortcuts: null,      // 蹇嵎閿�
-    searchlist: null,     // 鎼滅储鏉′欢
     actions: null,        // 鎸夐挳闆�
     columns: null,        // 鏄剧ず鍒�
     arr_field: '',        // 鏌ヨ瀛楁闆�
@@ -65,7 +63,6 @@
     statFields: [],       // 鍚堣瀛楁
     statFValue: [],       // 鍚堣鍊�
     absFields: [],        // 缁濆鍊煎瓧娈�
-    loadCustomApi: true,  // 鍔犺浇澶栭儴璧勬簮
     hasReqFields: false,
     autoMatic: null,
     visible: false
@@ -247,7 +244,7 @@
       config.setting.customScript = ''                                // 鑷畾涔夎剼鏈�
       config.setting.dataresource = config.setting.dataresource || ''
 
-      if (config.setting.interType === 'system' || (config.setting.interType === 'custom' && config.setting.requestMode === 'system')) {
+      if (config.setting.interType === 'system') {
         if (config.setting.scripts && config.setting.scripts.length > 0) {
           let _customScript = ''
           config.setting.scripts.forEach(item => {
@@ -447,6 +444,18 @@
         }
       }
 
+      config.type = 'table'
+      config.wrap = {
+        show: config.setting.show || '',
+        float: config.setting.float || '',
+        advanceType: config.setting.advanceType || '',
+        advanceWidth: config.setting.advanceWidth || '',
+        drawerPlacement: config.setting.drawerPlacement || '',
+        searchRatio: config.setting.searchRatio || '',
+        searchLwidth: config.setting.searchLwidth,
+        borderRadius: config.setting.borderRadius,
+      }
+
       this.setState({
         pageSize: config.setting.pageSize || 10,
         loadingview: false,
@@ -457,7 +466,6 @@
         statFields,
         shortcuts: shortcuts.length > 0 ? shortcuts : null,
         setting: config.setting,
-        searchlist: config.search,
         actions: _actions,
         columns: _columns,
         arr_field: _arrField.join(','),
@@ -531,7 +539,7 @@
 
   loadData = (id) => {
     const { MenuID } = this.props
-    const { setting, search, loadCustomApi, hasReqFields, ContainerId } = this.state
+    const { setting, search, hasReqFields, ContainerId } = this.state
 
     this.setState({
       selectedData: []
@@ -549,186 +557,16 @@
       }
     }
 
-    if (window.GLOB.systemType === 'production' && setting.interType === 'custom' && !setting.proInterface) {
+    if (setting.interType === 'custom') {
       notification.warning({
         top: 92,
-        message: '鏈缃寮忕郴缁熷湴鍧�!',
+        message: '绯荤粺涓嶅湪鏀寔鑷畾涔夋帴鍙�!',
         duration: 3
       })
       return
     }
 
-    if (setting.interType === 'custom' && loadCustomApi) {
-      if (setting.execTime === 'once') {
-        this.setState({loadCustomApi: false})
-      }
-
-      this.loadOutResource()
-      if (setting.execType === 'async') {
-        this.loadmaindata(id)
-      }
-    } else {
-      this.loadmaindata(id)
-    }
-  }
-
-  loadOutResource = () => {
-    const { setting, search, BID } = this.state
-
-    let param = UtilsDM.getPrevQueryParams(setting, search, BID)
-
-    if (setting.execType === 'sync') {
-      this.setState({
-        loading: true
-      })
-    }
-
-    Api.genericInterface(param).then(res => {
-      if (res.status) {
-        if (res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) {
-          this.loadmaindata()
-        } else {
-          this.customOuterRequest(res)
-        }
-      } else {
-        this.setState({
-          loading: false
-        })
-        notification.error({
-          top: 92,
-          message: res.message,
-          duration: 10
-        })
-      }
-    }, () => {
-      this.setState({
-        loading: false
-      })
-    })
-  }
-
-  customOuterRequest = (result) => {
-    const { setting } = this.state
-    let url = ''
-
-    if (window.GLOB.systemType === 'production') {
-      url = setting.proInterface
-    } else {
-      url = setting.interface
-    }
-
-    let mkey = result.mk_api_key || ''
-
-    delete result.mk_ex_invoke // 鏄惁缁х画鎵ц
-    delete result.status
-    delete result.message
-    delete result.ErrCode
-    delete result.ErrMesg
-    delete result.mk_api_key   // 褰撳墠璇锋眰鐨刱ey鍊硷紝鐢ㄤ簬鍥炶皟
-
-    let param = {}
-
-    Object.keys(result).forEach(key => {
-      key = key.replace(/^mk_/ig, '')
-      param[key] = result[key]
-    })
-
-    Api.directRequest(url, setting.method, param, setting.cross).then(res => {
-      if (typeof(res) !== 'object') {
-        let error = '鏈煡鐨勮繑鍥炵粨鏋滐紒'
-
-        if (typeof(res) === 'string') {
-          error = res.replace(/'/ig, '"')
-        }
-
-        let _result = {
-          mk_api_key: mkey,
-          $ErrCode: 'E',
-          $ErrMesg: error
-        }
-
-        this.customCallbackRequest(_result)
-      } else {
-        if (Array.isArray(res)) {
-          res = { data: res }
-        }
-        res.mk_api_key = mkey
-        this.customCallbackRequest(res)
-      }
-    }, (e) => {
-      let _result = {
-        mk_api_key: mkey,
-        $ErrCode: 'E',
-        $ErrMesg: e && e.statusText ? e.statusText : ''
-      }
-
-      this.customCallbackRequest(_result)
-    })
-  }
-
-  customCallbackRequest = (result) => {
-    const { setting, BID } = this.state
-    let errSql = ''
-    if (result.$ErrCode === 'E') {
-      errSql = `
-        set @ErrorCode='E'
-        set @retmsg='${result.$ErrMesg}'
-      `
-      delete result.$ErrCode
-      delete result.$ErrMesg
-    }
-
-    let lines = UtilsDM.getCallBackSql(setting, result)
-    let param = {}
-
-    if (setting.callbackType === 'script') { // 浣跨敤鑷畾涔夎剼鏈�
-      let sql = lines.map(item => (`
-        ${item.insert}
-        ${item.selects.join(` union all
-        `)}
-      `))
-      sql = sql.join('')
-      
-      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql, BID)
-    } else {
-      param.func = 's_ex_result_back'
-      param.s_ex_result = lines.map((item, index) => ({
-        MenuID: this.state.config.MenuID,
-        MenuName: this.state.config.MenuName,
-        TableName: item.table,
-        LongText: window.btoa(window.encodeURIComponent(`${item.insert}  ${item.selects.join(` union all `)}`)),
-        Sort: index + 1
-      }))
-
-      if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
-        let sql = lines.map(item => (`
-          ${item.insert}
-          ${item.selects.join(` union all
-          `)}
-        `))
-        sql = sql.join('')
-        console.info(sql.replace(/\n\s{10}/ig, '\n'))
-      }
-    }
-
-    Api.genericInterface(param).then(res => {
-      if (res.status) {
-        this.loadmaindata()
-      } else {
-        this.setState({
-          loading: false
-        })
-        notification.error({
-          top: 92,
-          message: res.message,
-          duration: 10
-        })
-      }
-    }, () => {
-      this.setState({
-        loading: false
-      })
-    })
+    this.loadmaindata(id)
   }
 
   /**
@@ -781,7 +619,7 @@
           item.$Index = start + index + ''
 
           if (setting.controlField) {
-            if (setting.controlVal.includes(item[setting.controlField])) {
+            if (setting.controlVal.includes(item[setting.controlField] + '')) {
               item.$disabled = true
             }
           }
@@ -898,7 +736,7 @@
   getStatFieldsValue = () => {
     const { setting, search, BID, orderBy, statFields } = this.state
 
-    if (statFields.length === 0 || !(setting.interType === 'system' || (setting.interType === 'custom' && setting.requestMode === 'system')) || !setting.dataresource) return
+    if (statFields.length === 0 || setting.interType !== 'system' || !setting.dataresource) return
 
     let _orderBy = orderBy || setting.order
     let param = UtilsDM.getStatQueryDataParams(setting, statFields, search, _orderBy, BID)
@@ -1015,7 +853,7 @@
   reloadview = () => {
     this.setState({ loadingview: true, viewlost: false, config: {}, setting: null,
       data: null, total: 0, loading: false, pageIndex: 1, shortcuts: null,
-      pageSize: 10, orderBy: '', search: '', BIDs: {}, pickup: false, searchlist: null
+      pageSize: 10, orderBy: '', search: '', BIDs: {}, pickup: false
     }, () => {
       this.loadconfig()
     })
@@ -1167,13 +1005,13 @@
 
   render() {
     const { MenuID } = this.props
-    const { BID, setting, searchlist, pageSize, actions, columns, loadingview, viewlost, pickup, config, chartId, search, selectedData, shortcuts, autoMatic } = this.state
+    const { BID, setting, pageSize, actions, columns, loadingview, viewlost, pickup, config, chartId, search, selectedData, shortcuts, autoMatic } = this.state
 
     return (
       <div className="commontable" id={this.state.ContainerId}>
         {loadingview ? <Spin size="large" /> : null}
-        {searchlist && searchlist.length ?
-          <MainSearch BID={BID} searchlist={searchlist} setting={setting} refreshdata={this.refreshbysearch}/> : null
+        {config && config.search && config.search.length ?
+          <MainSearch BID={BID} config={config} refreshdata={this.refreshbysearch}/> : null
         }
         {setting && config.charts ? <Row className="chart-view" gutter={16}>
           {/* 瑙嗗浘缁� */}
diff --git a/src/tabviews/custom/components/card/balcony/index.jsx b/src/tabviews/custom/components/card/balcony/index.jsx
index 1697e66..9d68b21 100644
--- a/src/tabviews/custom/components/card/balcony/index.jsx
+++ b/src/tabviews/custom/components/card/balcony/index.jsx
@@ -140,6 +140,7 @@
     MKEmitter.addListener('syncBalconyData', this.syncBalconyData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
     MKEmitter.addListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.addListener('refreshLineData', this.refreshLineData)
     MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult)
 
     if (config.wrap.datatype === 'public') {
@@ -176,6 +177,7 @@
     MKEmitter.removeListener('syncBalconyData', this.syncBalconyData)
     MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
     MKEmitter.removeListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.removeListener('refreshLineData', this.refreshLineData)
     MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult)
 
     this.timer && this.timer.stop()
@@ -250,6 +252,19 @@
     }
   }
 
+  refreshLineData = (menuId, btn, uuid, count) => {
+    const { config, data } = this.state
+
+    if (config.uuid !== menuId) return
+    
+    let _data = fromJS(data).toJS()
+    _data[btn.field] = count
+
+    this.setState({
+      data: _data
+    })
+  }
+
   syncBalconyData = (menuId, data, checked) => {
     const { syncConfig } = this.state
 
diff --git a/src/tabviews/custom/components/card/cardItem/index.jsx b/src/tabviews/custom/components/card/cardItem/index.jsx
index 92777c5..c378930 100644
--- a/src/tabviews/custom/components/card/cardItem/index.jsx
+++ b/src/tabviews/custom/components/card/cardItem/index.jsx
@@ -40,14 +40,16 @@
     }
   }
 
-  openView = () => {
+  openView = (e) => {
     const { card, data, cards, onClick } = this.props
 
     onClick && onClick()
     
     if (!card.setting.click || data.$disabled) return
 
-    if (card.setting.click === 'menus' && cards.subtype === 'datacard' && card.$cardType !== 'extendCard') {
+    e.stopPropagation()
+
+    if (card.setting.click === 'menus') {
       let menu = null
       
       if (card.menus && card.menus.length > 0) {
@@ -57,14 +59,7 @@
           menu = m
         })
       }
-      if (!menu || !menu.MenuID) {
-        notification.warning({
-          top: 92,
-          message: '鏈煡璇㈠埌鑿滃崟淇℃伅锛�',
-          duration: 5
-        })
-        return
-      }
+      if (!menu) return
 
       let newtab = {
         MenuID: menu.MenuID,
@@ -79,12 +74,13 @@
 
         Object.keys(data).forEach(key => {
           if (/^\$/.test(key)) return
+          if (key === 'children') return
           newtab.param[key] = data[key]
         })
       }
 
       MKEmitter.emit('modifyTabs', newtab, true)
-    } else if (card.setting.click === 'menu' && card.setting.menu) {
+    } else if (card.setting.click === 'menu') {
       let menuId = card.setting.MenuID || card.setting.menu.slice(-1)[0]
       let menu = window.GLOB.mkThdMenus.filter(m => m.MenuID === menuId)[0]
 
@@ -116,6 +112,7 @@
         
         Object.keys(data).forEach(key => {
           if (/^\$/.test(key)) return
+          if (key === 'children') return
           newtab.param[key] = data[key]
         })
       }
diff --git a/src/tabviews/custom/components/card/cardcellList/index.jsx b/src/tabviews/custom/components/card/cardcellList/index.jsx
index 8e9c1f8..f87948f 100644
--- a/src/tabviews/custom/components/card/cardcellList/index.jsx
+++ b/src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -100,7 +100,7 @@
       node && node.scrollIntoView({behavior: 'smooth', block: 'center', inline: 'nearest'})
     }
 
-    if (!card.link) return
+    if (!card.link || (card.linkType === 'qywx' || card.linkType === 'linkmenu')) return
     e.stopPropagation()
     
     let url = ''
@@ -131,7 +131,7 @@
       }
       window.open(_url)
       return
-    } else if (card.linkType === 'qywx' || card.linkType === 'linkmenu') {
+    } else if (card.linkType === 'other' && /^@menuid@/ig.test(url)) {
       return
     }
 
@@ -524,6 +524,8 @@
 
         if (card.datatype === 'dynamic') {
           icon = data[card.field] || ''
+        } else if (card.tipType === 'text') {
+          icon = card.value
         } else {
           icon = card.icon
         }
@@ -537,16 +539,28 @@
         } else {
           val = card.tooltip
         }
-  
-        contents.push(
-          <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
-            <div style={card.style}>
-              {val ? <Tooltip title={val}>
-                <MkIcon className="ant-mk-icon" style={{height: card.innerHeight}} type={icon}/>
-              </Tooltip> : <MkIcon className="ant-mk-icon" style={{height: card.innerHeight}} type={icon}/>}
+
+        if (card.tipType === 'text') {
+          contents.push(
+            <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
+              <div style={card.style}>
+                {val ? <Tooltip title={val}>
+                  <div className={'ant-mk-text line' + (card.height || '')} style={{height: card.innerHeight}}>{icon}</div>
+                </Tooltip> : <div className={'ant-mk-text line' + (card.height || '')} style={{height: card.innerHeight}}>{icon}</div>}
+              </div>
             </div>
-          </div>
-        )
+          )
+        } else {
+          contents.push(
+            <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
+              <div style={card.style}>
+                {val ? <Tooltip title={val}>
+                  <MkIcon className="ant-mk-icon" style={{height: card.innerHeight}} type={icon}/>
+                </Tooltip> : <MkIcon className="ant-mk-icon" style={{height: card.innerHeight}} type={icon}/>}
+              </div>
+            </div>
+          )
+        }
       } else if (card.eleType === 'slider') {
         let val = 0
         let color = card.color
diff --git a/src/tabviews/custom/components/card/data-card/index.jsx b/src/tabviews/custom/components/card/data-card/index.jsx
index fe8bcec..1d2e850 100644
--- a/src/tabviews/custom/components/card/data-card/index.jsx
+++ b/src/tabviews/custom/components/card/data-card/index.jsx
@@ -81,6 +81,7 @@
     }
 
     _config.$extend = false
+    _config.$empty = true
 
     _config.subcards.forEach(item => {
       if (item.setting.click === 'button' && !item.setting.linkbtn) {
@@ -98,9 +99,13 @@
         _card = item
       } else if (!_card) {
         _config.$extend = true
+        if (item.setting.width !== 24) {
+          _config.$empty = false
+        }
         precards.push(item)
       } else {
         _config.$extend = true
+        _config.$empty = false
         nextcards.push(item)
       }
     })
@@ -134,7 +139,7 @@
         item.$Index = index + 1 + ''
 
         if (_config.wrap.controlField) {
-          if (_config.wrap.controlVal.includes(item[_config.wrap.controlField])) {
+          if (_config.wrap.controlVal.includes(item[_config.wrap.controlField] + '')) {
             item.$disabled = true
           }
         }
@@ -210,6 +215,7 @@
     MKEmitter.addListener('mkCheckAll', this.mkCheckAll)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
     MKEmitter.addListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.addListener('refreshLineData', this.refreshLineData)
     MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult)
     
     if (config.timer) {
@@ -232,7 +238,7 @@
           item.$Index = index + 1 + ''
 
           if (config.wrap.controlField) {
-            if (config.wrap.controlVal.includes(item[config.wrap.controlField])) {
+            if (config.wrap.controlVal.includes(item[config.wrap.controlField] + '')) {
               item.$disabled = true
             }
           }
@@ -264,7 +270,7 @@
           item.$Index = index + 1 + ''
 
           if (config.wrap.controlField) {
-            if (config.wrap.controlVal.includes(item[config.wrap.controlField])) {
+            if (config.wrap.controlVal.includes(item[config.wrap.controlField] + '')) {
               item.$disabled = true
             }
           }
@@ -300,6 +306,7 @@
     MKEmitter.removeListener('mkCheckAll', this.mkCheckAll)
     MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
     MKEmitter.removeListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.removeListener('refreshLineData', this.refreshLineData)
     MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult)
 
     this.timer && this.timer.stop()
@@ -370,6 +377,23 @@
     if (position === 'popclose') { // 鎵ц鍚姩寮圭獥鐨勬寜閽墍閫夋嫨鐨勫埛鏂伴」
       btn.$tabId && MKEmitter.emit('refreshPopButton', btn.$tabId)
     }
+  }
+
+  refreshLineData = (menuId, btn, uuid, count) => {
+    const { config, data } = this.state
+
+    if (config.uuid !== menuId) return
+    
+    let _data = fromJS(data).toJS().map(item => {
+      if (item.$$uuid === uuid) {
+        item[btn.field] = count
+      }
+      return item
+    })
+
+    this.setState({
+      data: _data
+    })
   }
 
   checkTopLine = (id) => {
@@ -706,7 +730,7 @@
           item.$Index = index + 1 + ''
 
           if (config.wrap.controlField) {
-            if (config.wrap.controlVal.includes(item[config.wrap.controlField])) {
+            if (config.wrap.controlVal.includes(item[config.wrap.controlField] + '')) {
               item.$disabled = true
             }
           }
@@ -721,7 +745,7 @@
           item.$Index = index + start + ''
 
           if (config.wrap.controlField) {
-            if (config.wrap.controlVal.includes(item[config.wrap.controlField])) {
+            if (config.wrap.controlVal.includes(item[config.wrap.controlField] + '')) {
               item.$disabled = true
             }
           }
@@ -1045,8 +1069,8 @@
             ))}
           </Row>
           {switchable ? <div className={'prev-page ' + (total <= _total ? 'disabled' : '')} onClick={this.nextPage}><div><div><img src={nextImg} alt=""/></div></div></div> : null}
-          {!config.$extend && (!data || data.length === 0) ? <Empty description={false}/> : null}
         </div>
+        {config.$empty && (!data || data.length === 0) ? <Empty description={false}/> : null}
         {config.wrap.pagestyle === 'page' && data ? <Pagination size="small" total={total} showTotal={(t, range) => total > 0 ? `${range[0]}-${range[1]} 鍏� ${total} 鏉 : `鍏� ${total} 鏉} pageSize={pageSize} showSizeChanger={true} pageSizeOptions={this.state.pageOptions} onChange={this.changePageIndex} onShowSizeChange={this.pageSizeChange} current={pageIndex}/> : null}
         {config.wrap.pagestyle === 'more' && data && data.length > 0 ? <div className={'mk-more' + (pageSize * pageIndex >= total ? ' disabled' : '')} onClick={this.loadMore}>鏌ョ湅鏇村<DownOutlined/></div> : null}
       </div>
diff --git a/src/tabviews/custom/components/card/data-card/index.scss b/src/tabviews/custom/components/card/data-card/index.scss
index 34a81cf..bb71f96 100644
--- a/src/tabviews/custom/components/card/data-card/index.scss
+++ b/src/tabviews/custom/components/card/data-card/index.scss
@@ -104,7 +104,6 @@
   }
 
   .ant-empty {
-    width: 100%;
     min-height: 100px;
     padding-top: 15px;
 
diff --git a/src/tabviews/custom/components/card/double-data-card/index.jsx b/src/tabviews/custom/components/card/double-data-card/index.jsx
index 3d10bf5..3a19ad3 100644
--- a/src/tabviews/custom/components/card/double-data-card/index.jsx
+++ b/src/tabviews/custom/components/card/double-data-card/index.jsx
@@ -79,6 +79,7 @@
     }
 
     _config.$extend = false
+    _config.$empty = true
 
     _config.subcards.forEach(item => {
       if (item.setting.click === 'button' && !item.setting.linkbtn) {
@@ -96,9 +97,13 @@
         _card = item
       } else if (!_card) {
         _config.$extend = true
+        if (item.setting.width !== 24) {
+          _config.$empty = false
+        }
         precards.push(item)
       } else {
         _config.$extend = true
+        _config.$empty = false
         nextcards.push(item)
       }
     })
@@ -133,9 +138,9 @@
     subcard.setting = subcard.backSetting
 
     if (_card.setting.position === 'inner') {
-      wrapStyle = {}
+      wrapStyle = {backgroundColor: '#ffffff'}
       Object.keys(_card.style).forEach(key => {
-        if (!/^(margin|border|box)/.test(key)) return
+        if (!/^(margin|border|box|backgroundColor)/.test(key)) return
         wrapStyle[key] = _card.style[key]
         delete _card.style[key]
       })
@@ -200,6 +205,7 @@
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
     MKEmitter.addListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.addListener('refreshLineData', this.refreshLineData)
     MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult)
     
     if (config.timer) {
@@ -245,7 +251,7 @@
           item.$Index = index + 1 + ''
 
           if (config.wrap.controlField) {
-            if (config.wrap.controlVal.includes(item[config.wrap.controlField])) {
+            if (config.wrap.controlVal.includes(item[config.wrap.controlField] + '')) {
               item.$disabled = true
             }
           }
@@ -279,6 +285,7 @@
     MKEmitter.removeListener('reloadData', this.reloadData)
     MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
     MKEmitter.removeListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.removeListener('refreshLineData', this.refreshLineData)
     MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult)
 
     this.timer && this.timer.stop()
@@ -318,6 +325,28 @@
     if (position === 'popclose') { // 鎵ц鍚姩寮圭獥鐨勬寜閽墍閫夋嫨鐨勫埛鏂伴」
       btn.$tabId && MKEmitter.emit('refreshPopButton', btn.$tabId)
     }
+  }
+
+  refreshLineData = (menuId, btn, uuid, count) => {
+    const { config, data } = this.state
+
+    if (config.uuid !== menuId) return
+    
+    let _data = fromJS(data).toJS().map(item => {
+      if (item.$$uuid === uuid) {
+        item[btn.field] = count
+      }
+      item.children.forEach(cell => {
+        if (cell.$$uuid === uuid) {
+          cell[btn.field] = count
+        }
+      })
+      return item
+    })
+
+    this.setState({
+      data: _data
+    })
   }
 
   checkTopLine = (id) => {
@@ -605,7 +634,7 @@
           item.$Index = index + 1 + ''
 
           if (config.wrap.controlField) {
-            if (config.wrap.controlVal.includes(item[config.wrap.controlField])) {
+            if (config.wrap.controlVal.includes(item[config.wrap.controlField] + '')) {
               item.$disabled = true
             }
           }
@@ -644,7 +673,7 @@
           item.$Index = index + start + ''
 
           if (config.wrap.controlField) {
-            if (config.wrap.controlVal.includes(item[config.wrap.controlField])) {
+            if (config.wrap.controlVal.includes(item[config.wrap.controlField] + '')) {
               item.$disabled = true
             }
           }
@@ -886,6 +915,43 @@
     }
   }
 
+  changeSubCard = (item) => {
+    const { subcard, card } = this.state
+
+    if (subcard.setting.click || card.setting.position !== 'inner' || card.setting.click !== 'menu') return
+    
+    let menuId = card.setting.MenuID || card.setting.menu.slice(-1)[0]
+    let menu = window.GLOB.mkThdMenus.filter(m => m.MenuID === menuId)[0]
+
+    if (!menu && card.setting.MenuName && card.setting.tabType) {
+      menu = {
+        MenuID: menuId,
+        MenuName: card.setting.MenuName,
+        MenuNo: card.setting.MenuNo || '',
+        type: card.setting.tabType
+      }
+    }
+
+    if (!menu) return
+
+    let newtab = {
+      ...menu,
+      param: {}
+    }
+
+    if (card.setting.joint === 'true') {
+      newtab.param.$BID = item.$$uuid || ''
+      
+      Object.keys(item).forEach(key => {
+        if (/^\$/.test(key)) return
+        if (key === 'children') return
+        newtab.param[key] = item[key]
+      })
+    }
+
+    MKEmitter.emit('modifyTabs', newtab, true)
+  }
+
   onDoubleClick = (i, subClass) => {
     const { opens, card } = this.state
 
@@ -975,7 +1041,7 @@
                 let unfold = true
 
                 if (item.$disabled) {
-                  className = 'mk-disabled ' + mainBox
+                  className = 'card-item-wrap mk-disabled ' + mainBox
                 } else if (activeKey === index) {
                   className += 'active'
                 } else if (selectKeys.indexOf(index) > -1) {
@@ -1000,7 +1066,7 @@
                         {card.setting.controlIcon === 'left' ? (!unfold ? <PlusSquareOutlined className={subClass} onClick={(e) => this.changeUnfold(e, index, subClass)}/> : <MinusSquareOutlined className={subClass} onClick={(e) => this.changeUnfold(e, index, subClass)}/>) : null}
                         {card.setting.controlIcon === 'right' ? <UpOutlined className={subClass} onClick={(e) => this.changeUnfold(e, index, subClass)}/> : null}
                       </CardItem>
-                      <div className={'sub-card-wrap ' + subClass + (config.wrap.parity === 'true' ? ' mk-parity-bg' : '')}>
+                      <div className={'sub-card-wrap ' + subClass + (config.wrap.parity === 'true' ? ' mk-parity-bg' : '')} onClick={() => this.changeSubCard(item)}>
                         {item.children.map((cell, index) => <Col key={'sub' + index} span={subcard.setting.width || 24}>
                           <CardItem card={subcard} cards={subconfig} data={cell} />
                         </Col>)}
@@ -1019,8 +1085,8 @@
                 </Col>
               ))}
             </Row>
-            {!config.$extend && (!data || data.length === 0) ? <Empty description={false}/> : null}
           </div>
+          {config.$empty && (!data || data.length === 0) ? <Empty description={false}/> : null}
         </div>
         {config.wrap.pagestyle === 'page' && data ? <Pagination size="small" total={total} showTotal={(t, range) => total > 0 ? `${range[0]}-${range[1]} 鍏� ${total} 鏉 : `鍏� ${total} 鏉} pageSize={pageSize} showSizeChanger={true} pageSizeOptions={this.state.pageOptions} onChange={this.changePageIndex} onShowSizeChange={this.pageSizeChange} current={pageIndex}/> : null}
         {config.wrap.pagestyle === 'more' && data && data.length > 0 ? <div className={'mk-more' + (pageSize * pageIndex >= total ? ' disabled' : '')} onClick={this.loadMore}>鏌ョ湅鏇村<DownOutlined/></div> : null}
diff --git a/src/tabviews/custom/components/card/double-data-card/index.scss b/src/tabviews/custom/components/card/double-data-card/index.scss
index b3a5b8a..0ee2e47 100644
--- a/src/tabviews/custom/components/card/double-data-card/index.scss
+++ b/src/tabviews/custom/components/card/double-data-card/index.scss
@@ -76,7 +76,6 @@
   }
 
   .ant-empty {
-    width: 100%;
     min-height: 100px;
     padding-top: 15px;
 
diff --git a/src/tabviews/custom/components/card/prop-card/index.jsx b/src/tabviews/custom/components/card/prop-card/index.jsx
index 651bd23..681652b 100644
--- a/src/tabviews/custom/components/card/prop-card/index.jsx
+++ b/src/tabviews/custom/components/card/prop-card/index.jsx
@@ -135,9 +135,15 @@
       }
 
       if (_config.wrap.datatype === 'dynamic' && this.loaded) {
-        this.autoExec()
+        if (_config.wrap.goback === 'true' && _data.$$empty) {
+          this.timer && this.timer.stop()
+
+          MKEmitter.emit('closeTabView', _config.$pageId)
+        } else {
+          this.autoExec()
+        }
       }
-      if (!_config.wrap.cardType && _data.$$uuid) {
+      if (_data.$$uuid) {
         setTimeout(() => {
           this.transferLine()
         }, 200)
@@ -151,6 +157,7 @@
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
     MKEmitter.addListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.addListener('refreshLineData', this.refreshLineData)
     MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult)
 
     if (config.wrap.datatype === 'public') {
@@ -186,6 +193,7 @@
     MKEmitter.removeListener('mkPublicData', this.mkPublicData)
     MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
     MKEmitter.removeListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.removeListener('refreshLineData', this.refreshLineData)
     MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult)
 
     this.timer && this.timer.stop()
@@ -213,12 +221,18 @@
       this.loaded = true
 
       this.setState({sync: false, data: _data}, () => {
-        if (selected !== 'false') {
-          this.checkTopLine()
-        } else if (!config.wrap.cardType && _data.$$uuid) {
-          this.transferLine()
+        if (config.wrap.goback === 'true' && _data.$$empty) {
+          this.timer && this.timer.stop()
+
+          MKEmitter.emit('closeTabView', config.$pageId)
+        } else {
+          if (selected !== 'false') {
+            this.checkTopLine()
+          } else if (_data.$$uuid) {
+            this.transferLine()
+          }
+          this.autoExec()
         }
-        this.autoExec()
       })
     } else if (config.setting.useMSearch && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
       this.setState({}, () => {
@@ -240,10 +254,17 @@
       this.loaded = true
 
       this.setState({data: _data}, () => {
-        if (selected !== 'false') {
-          this.checkTopLine()
+        if (config.wrap.goback === 'true' && _data.$$empty) {
+          this.timer && this.timer.stop()
+
+          MKEmitter.emit('closeTabView', config.$pageId)
         } else {
-          this.transferLine()
+          if (selected !== 'false') {
+            this.checkTopLine()
+          } else {
+            this.transferLine()
+          }
+          this.autoExec()
         }
       })
     }
@@ -307,6 +328,19 @@
     }
   }
 
+  refreshLineData = (menuId, btn, uuid, count) => {
+    const { config, data } = this.state
+
+    if (config.uuid !== menuId) return
+    
+    let _data = fromJS(data).toJS()
+    _data[btn.field] = count
+
+    this.setState({
+      data: _data
+    })
+  }
+
   resetParentParam = (MenuID, id, data) => {
     const { config } = this.state
 
diff --git a/src/tabviews/custom/components/card/table-card/index.jsx b/src/tabviews/custom/components/card/table-card/index.jsx
index 16fc44e..f453ff7 100644
--- a/src/tabviews/custom/components/card/table-card/index.jsx
+++ b/src/tabviews/custom/components/card/table-card/index.jsx
@@ -117,6 +117,7 @@
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
     MKEmitter.addListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.addListener('refreshLineData', this.refreshLineData)
     MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult)
 
     if (config.timer) {
@@ -157,6 +158,7 @@
     MKEmitter.removeListener('reloadData', this.reloadData)
     MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
     MKEmitter.removeListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.removeListener('refreshLineData', this.refreshLineData)
     MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult)
 
     this.timer && this.timer.stop()
@@ -215,6 +217,23 @@
     }
   }
 
+  refreshLineData = (menuId, btn, uuid, count) => {
+    const { config, data } = this.state
+
+    if (config.uuid !== menuId) return
+    
+    let _data = fromJS(data).toJS().map(item => {
+      if (item.$$uuid === uuid) {
+        item[btn.field] = count
+      }
+      return item
+    })
+
+    this.setState({
+      data: _data
+    })
+  }
+
   resetParentParam = (MenuID, id, data) => {
     const { config } = this.state
 
diff --git a/src/tabviews/custom/components/card/table-card/index.scss b/src/tabviews/custom/components/card/table-card/index.scss
index c7b6fc8..088083a 100644
--- a/src/tabviews/custom/components/card/table-card/index.scss
+++ b/src/tabviews/custom/components/card/table-card/index.scss
@@ -105,6 +105,13 @@
     cursor: not-allowed;
     color: #bcbcbc;
   }
+  .ant-empty {
+    min-height: 100px;
+    padding-top: 15px;
+    .ant-empty-image {
+      height: 60px;
+    }
+  }
 }
 
 .custom-card-box::after {
diff --git a/src/tabviews/custom/components/chart/antv-G6/index.jsx b/src/tabviews/custom/components/chart/antv-G6/index.jsx
index ac96d6b..f481f2e 100644
--- a/src/tabviews/custom/components/chart/antv-G6/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-G6/index.jsx
@@ -814,6 +814,8 @@
   }
 
   data = []
+  mkgraph = null
+  selectedId = ''
 
   UNSAFE_componentWillMount () {
     const { config, data, initdata } = this.props
@@ -1183,9 +1185,20 @@
 
       _options.push(_item)
     })
-
-    root = this.getTree(root, _options)
+    
+    root.nodeNumber = 0
+    root = this.getTree(root, _options, root)
     root.children = root.children || []
+
+    if (root.selectedItem) {
+      let option = {...root.selectedItem}
+      setTimeout(() => {
+        MKEmitter.emit('resetSelectLine', config.uuid, option.id, option)
+      }, 20)
+      delete root.selectedItem
+    } else {
+      this.selectedId = ''
+    }
 
     if (plot.subtype === 'mindmap') {
       root.type = 'dice-mind-map-root'
@@ -1248,13 +1261,22 @@
     return root
   }
 
-  getTree = (parent, options) => {
+  getTree = (parent, options, root) => {
     parent.children = []
     // 娣诲姞鑿滃崟鐨勫瓙鍏冪礌
     options = options.filter(option => {
       if (option.$parentId === parent.id) {
         delete option.$parentId
+
+        if (this.selectedId && option.id === this.selectedId) {
+          root.selectedItem = {...option}
+          option.selected = true
+        }
+
         parent.children.push(option)
+
+        root.nodeNumber++
+
         return false
       }
       return true
@@ -1264,7 +1286,7 @@
       parent.children = null
     } else {
       parent.children = parent.children.map(item => {
-        item = this.getTree(item, options)
+        item = this.getTree(item, options, root)
 
         return item
       })
@@ -1274,30 +1296,71 @@
   }
 
   handleData = () => {
-    let _element = document.getElementById(this.state.chartId)
-    if (_element) {
-      _element.innerHTML = ''
-    }
+    const { config } = this.state
 
-    setTimeout(() => {
+    MKEmitter.emit('resetSelectLine', config.uuid, '', '')
+
+    if (this.mkgraph) {
+      this.mkgraph.clear()
+      this.resetrender()
+    } else {
       this.viewrender()
-    }, 100)
+    }
   }
 
   viewrender = () => {
     const { plot } = this.state
 
+    this.selectedId = ''
     if (this.data.length === 0) {
       this.setState({empty: true})
     } else {
       this.setState({empty: false})
 
       if (plot.subtype === 'mindmap') {
-        this.ponitrender()
+        this.mindrender()
       } else if (plot.subtype === 'indentTree') {
         this.indentrender()
       } else if (plot.subtype === 'kapmap') {
         this.kapmaprender()
+      }
+    }
+  }
+
+  resetrender = () => {
+    const { plot } = this.state
+
+    if (this.data.length === 0) {
+      this.setState({empty: true})
+      this.selectedId = ''
+    } else {
+      this.setState({empty: false})
+
+      const data = this.getdata()
+      if (plot.subtype === 'mindmap') {
+        this.mkgraph.data(data)
+
+        this.mkgraph.render()
+
+        const width = this.wrap.scrollWidth - 30
+
+        if (plot.collapsed === 'true' && plot.dirField) {
+          this.mkgraph.zoomTo(1, { x: width / 2, y: plot.height / 2 })
+        } else if (plot.collapsed === 'true' || data.nodeNumber < 5) {
+          this.mkgraph.zoomTo(1, { x: 0, y: plot.height / 2 })
+        }
+      } else if (plot.subtype === 'indentTree') {
+        this.mkgraph.data(dataIndTransform(data))
+
+        this.mkgraph.render()
+      } else if (plot.subtype === 'kapmap') {
+        this.mkgraph.data(data)
+        this.mkgraph.render()
+        this.mkgraph.fitView()
+
+        if (plot.collapsed === 'true' || data.nodeNumber < 5) {
+          this.mkgraph.zoomTo(1, { x: 0, y: plot.height / 2 })
+        }
       }
     }
   }
@@ -1357,9 +1420,11 @@
     graph.render()
     graph.fitView()
 
-    if (plot.collapsed === 'true') {
+    if (plot.collapsed === 'true' || data.nodeNumber < 5) {
       graph.zoomTo(1, { x: 0, y: plot.height / 2 })
     }
+
+    this.mkgraph = graph
   }
 
   indentrender = () => {
@@ -1421,12 +1486,14 @@
     tree.data(dataIndTransform(data))
     
     tree.render()
+
+    this.mkgraph = tree
   }
 
   /**
-   * @description 鏁g偣鍥�
+   * @description 鎬濈淮瀵煎浘
    */
-  ponitrender = () => {
+  mindrender = () => {
     const { config, plot, chartId } = this.state
     const data = this.getdata()
     const width = this.wrap.scrollWidth - 30
@@ -1480,9 +1547,11 @@
 
     if (plot.collapsed === 'true' && plot.dirField) {
       tree.zoomTo(1, { x: width / 2, y: plot.height / 2 })
-    } else if (plot.collapsed === 'true') {
+    } else if (plot.collapsed === 'true' || data.nodeNumber < 5) {
       tree.zoomTo(1, { x: 0, y: plot.height / 2 })
     }
+
+    this.mkgraph = tree
   }
 
   handleClick = (data = null) => {
@@ -1551,7 +1620,13 @@
 
       MKEmitter.emit('modifyTabs', newtab, true)
     } else {
-      MKEmitter.emit('resetSelectLine', config.uuid, (data ? data.$$uuid : ''), data)
+      if (data) {
+        this.selectedId = data.$$uuid || ''
+        MKEmitter.emit('resetSelectLine', config.uuid, data.$$uuid || '', data)
+      } else {
+        this.selectedId = ''
+        MKEmitter.emit('resetSelectLine', config.uuid, '', '')
+      }
     }
   }
 
diff --git a/src/tabviews/custom/components/code/sand-box/index.jsx b/src/tabviews/custom/components/code/sand-box/index.jsx
index fa09f57..dc1a995 100644
--- a/src/tabviews/custom/components/code/sand-box/index.jsx
+++ b/src/tabviews/custom/components/code/sand-box/index.jsx
@@ -22,6 +22,7 @@
     sync: false,               // 鏄惁缁熶竴璇锋眰鏁版嵁
     data: [],                  // 鏁版嵁
     html: '',
+    result: {}
   }
 
   loaded = false
@@ -199,8 +200,12 @@
         }, 10)
       }
 
+      let _result = {...result}
+      delete _result.data
+
       this.setState({
         data: _data,
+        result: _result,
         loading: false
       })
     } else {
@@ -216,7 +221,7 @@
   }
 
   renderView = () => {
-    const { data } = this.state
+    const { data, result } = this.state
     const { html, js, wrap, columns } = this.state.config
 
     let _html = html
@@ -239,16 +244,8 @@
       if (js) {
         try {
           // eslint-disable-next-line
-          let evalfunc = eval('(true && function (data) {' + js + '})')
-          evalfunc(data)
-          // if (wrap.compileMode !== 'custom') {
-          //   // eslint-disable-next-line no-eval
-          //   eval(js)
-          // } else {
-          //   // eslint-disable-next-line
-          //   let evalfunc = eval('(true && function (data) {' + js + '})')
-          //   evalfunc(data)
-          // }
+          let evalfunc = eval('(true && function (data, result) {' + js + '})')
+          evalfunc(data, result)
         } catch (e) {
           console.warn(e)
         }
diff --git a/src/tabviews/custom/components/iframe/index.jsx b/src/tabviews/custom/components/iframe/index.jsx
index 62981a9..b8397f3 100644
--- a/src/tabviews/custom/components/iframe/index.jsx
+++ b/src/tabviews/custom/components/iframe/index.jsx
@@ -65,6 +65,10 @@
       }
     }
 
+    if (_config.wrap.height === '100vh') {
+      _config.wrap.height = 'calc(100vh - 92px)'
+    }
+
     this.setState({
       linkUrl: linkUrl,
       sync: _sync,
@@ -257,7 +261,7 @@
         </div> : null}
         <div className="iframe-wrap" style={{height: config.wrap.height}}>
           {loading ? <div className="mask"><Spin size="large" /></div> : null}
-          {linkUrl ? <iframe title="mk" className="iframe" src={linkUrl} frameBorder="0"></iframe> : <Empty description={false}/>}
+          {linkUrl ? <iframe title="mk" className="iframe" src={linkUrl.replace(/@userid@/ig, sessionStorage.getItem('UserID')).replace(/@loginuid@/ig, sessionStorage.getItem('LoginUID'))} frameBorder="0"></iframe> : <Empty description={false}/>}
         </div>
       </div>
     )
diff --git a/src/tabviews/custom/components/share/normalTable/index.jsx b/src/tabviews/custom/components/share/normalTable/index.jsx
index 4922254..83b7612 100644
--- a/src/tabviews/custom/components/share/normalTable/index.jsx
+++ b/src/tabviews/custom/components/share/normalTable/index.jsx
@@ -6,13 +6,13 @@
 
 import asyncComponent from '@/utils/asyncComponent'
 import { getMark } from '@/utils/utils.js'
-import MkIcon from '@/components/mk-icon'
 import MKEmitter from '@/utils/events.js'
 import Encrypts from '@/components/encrypts'
 import './index.scss'
 
 const { Paragraph } = Typography
 const Video = asyncComponent(() => import('@/components/video'))
+const MkIcon = asyncComponent(() => import('@/components/mk-icon'))
 const MkPicture = asyncComponent(() => import('@/components/mkPicture'))
 const CardCellComponent = asyncComponent(() => import('@/tabviews/custom/components/card/cardcellList'))
 const PicRadio = {
diff --git a/src/tabviews/custom/components/table/base-table/index.jsx b/src/tabviews/custom/components/table/base-table/index.jsx
index 80579fb..9658a04 100644
--- a/src/tabviews/custom/components/table/base-table/index.jsx
+++ b/src/tabviews/custom/components/table/base-table/index.jsx
@@ -200,7 +200,7 @@
             })
           }
           if (setting.controlField) {
-            if (setting.controlVal.includes(item[setting.controlField])) {
+            if (setting.controlVal.includes(item[setting.controlField] + '')) {
               item.$disabled = true
             }
           }
@@ -396,26 +396,13 @@
    * 鍚湁鍒濆涓嶅姞杞界殑椤甸潰锛屼慨鏀硅缃�
    */
   refreshbysearch = (searches) => {
-    const { setting } = this.state
-
-    if (setting.onload === 'false') {
-      this.setState({
-        pageIndex: 1,
-        search: searches,
-        setting: {...setting, onload: 'true'}
-      }, () => {
-        this.loadmaindata()
-        this.getStatFieldsValue()
-      })
-    } else {
-      this.setState({
-        pageIndex: 1,
-        search: searches
-      }, () => {
-        this.loadmaindata(true, 'true')
-        this.getStatFieldsValue()
-      })
-    }
+    this.setState({
+      pageIndex: 1,
+      search: searches
+    }, () => {
+      this.loadmaindata(true, 'true')
+      this.getStatFieldsValue()
+    })
   }
 
   /**
diff --git a/src/tabviews/custom/components/table/edit-table/index.jsx b/src/tabviews/custom/components/table/edit-table/index.jsx
index 96dfbb6..f0cfdb3 100644
--- a/src/tabviews/custom/components/table/edit-table/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/index.jsx
@@ -37,7 +37,7 @@
     pageIndex: 1,         // 椤电爜
     pageSize: 10,         // 姣忛〉鏁版嵁鏉℃暟
     orderBy: '',          // 鎺掑簭
-    search: '',           // 鎼滅储鏉′欢鏁扮粍锛屼娇鐢ㄦ椂闇�鍒嗗満鏅鐞�
+    search: ''            // 鎼滅储鏉′欢鏁扮粍锛屼娇鐢ㄦ椂闇�鍒嗗満鏅鐞�
   }
 
   /**
@@ -79,6 +79,7 @@
     let _columns = []
     setting.initId = ''
     let triMap = new Map()
+    setting.hasSubmit = false
 
     let getColumns = (cols) => {
       return cols.filter(item => {
@@ -115,6 +116,7 @@
           }
 
           if (item.editable === 'true') {
+            setting.hasSubmit = true
             if (!setting.initId) {
               setting.initId = item.uuid
             }
@@ -331,25 +333,21 @@
         })
       }
 
-      try {
-        data = data.map(item => {
-          if (item.$$uuid === _data.$$uuid) {
-            _data.key = item.key
-            _data.$Index = item.$Index
-            return _data
-          } else {
-            return item
-          }
-        })
-        selectedData = selectedData.map(item => {
-          if (_data.$$uuid === item.$$uuid) {
-            return _data
-          }
+      data = data.map(item => {
+        if (item.$$uuid === _data.$$uuid) {
+          _data.key = item.key
+          _data.$Index = item.$Index
+          return _data
+        } else {
           return item
-        })
-      } catch (e) {
-        console.warn('鏁版嵁鏌ヨ閿欒')
-      }
+        }
+      })
+      selectedData = selectedData.map(item => {
+        if (_data.$$uuid === item.$$uuid) {
+          return _data
+        }
+        return item
+      })
 
       MKEmitter.emit('transferData', config.uuid, _data, 'line')
       MKEmitter.emit('resetSelectLine', config.uuid, _data.$$uuid, _data)
@@ -376,24 +374,12 @@
    * 鍚湁鍒濆涓嶅姞杞界殑椤甸潰锛屼慨鏀硅缃�
    */
   refreshbysearch = (searches) => {
-    const { setting } = this.state
-
-    if (setting.onload === 'false') {
-      this.setState({
-        pageIndex: 1,
-        search: searches,
-        setting: {...setting, onload: 'true'}
-      }, () => {
-        this.loadmaindata()
-      })
-    } else {
-      this.setState({
-        pageIndex: 1,
-        search: searches
-      }, () => {
-        this.loadmaindata(true, 'true')
-      })
-    }
+    this.setState({
+      pageIndex: 1,
+      search: searches
+    }, () => {
+      this.loadmaindata(true, 'true')
+    })
   }
 
   /**
@@ -516,6 +502,30 @@
     }
   }
 
+  refreshLineData = (menuId, btn, uuid, count) => {
+    const { config } = this.state
+
+    if (config.uuid !== menuId) return
+    
+    let _data = fromJS(this.state.data).toJS().map(item => {
+      if (item.$$uuid === uuid) {
+        item[btn.field] = count
+      }
+      return item
+    })
+    let _selectedData = fromJS(this.state.selectedData).toJS().map(item => {
+      if (item.$$uuid === uuid) {
+        item[btn.field] = count
+      }
+      return item
+    })
+
+    this.setState({
+      data: _data,
+      selectedData: _selectedData
+    })
+  }
+
   UNSAFE_componentWillReceiveProps(nextProps) {
     const { config } = this.state
 
@@ -534,6 +544,7 @@
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
     MKEmitter.addListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.addListener('refreshLineData', this.refreshLineData)
     MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult)
   }
 
@@ -547,6 +558,7 @@
     MKEmitter.removeListener('reloadData', this.reloadData)
     MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
     MKEmitter.removeListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.removeListener('refreshLineData', this.refreshLineData)
     MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult)
   }
 
@@ -559,7 +571,7 @@
     }
 
     return (
-      <div className="custom-edit-table" id={'anchor' + config.uuid} style={style}>
+      <div className={'custom-edit-table' + (setting.hasSubmit ? '' : ' withnot-submit')} id={'anchor' + config.uuid} style={style}>
         <NormalHeader config={config}/>
         {config.search && config.search.length ?
           <MainSearch BID={BID} config={config} refreshdata={this.refreshbysearch}/> : null
diff --git a/src/tabviews/custom/components/table/edit-table/index.scss b/src/tabviews/custom/components/table/edit-table/index.scss
index 18e3dda..04c258f 100644
--- a/src/tabviews/custom/components/table/edit-table/index.scss
+++ b/src/tabviews/custom/components/table/edit-table/index.scss
@@ -20,4 +20,9 @@
     right: 0px;
     margin-top: 15px;
   }
+}
+.custom-edit-table.withnot-submit {
+  .button-list.toolbar-button {
+    margin-right: 0px;
+  }
 }
\ No newline at end of file
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 2b09bfb..a38bb09 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
@@ -2,21 +2,19 @@
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
 import { Table, Typography, Modal, Input, InputNumber, Button, notification, message, Select } from 'antd'
-import { EditOutlined } from '@ant-design/icons'
+import { EditOutlined, QuestionCircleOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import Api from '@/api'
 import asyncComponent from '@/utils/asyncComponent'
 import Utils, { getEditTableSql, getMark } from '@/utils/utils.js'
-import MkIcon from '@/components/mk-icon'
 import MKEmitter from '@/utils/events.js'
-import zhCN from '@/locales/zh-CN/main.js'
-import enUS from '@/locales/en-US/main.js'
 import CusSwitch from './cusSwitch'
 import Encrypts from '@/components/encrypts'
 import './index.scss'
 
 const { Paragraph } = Typography
+const MkIcon = asyncComponent(() => import('@/components/mk-icon'))
 const CardCellComponent = asyncComponent(() => import('@/tabviews/custom/components/card/cardcellList'))
 
 class BodyRow extends React.Component {
@@ -121,7 +119,7 @@
 
     this.setState({editing: false})
     setTimeout(() => {
-      if (col.enter === '$next') {
+      if (/\$next/.test(col.enter)) {
         MKEmitter.emit('nextLine', col, record.$$uuid)
       } else if (col.enter === '$sub') {
         MKEmitter.emit('subLine', col, record)
@@ -210,7 +208,7 @@
     this.setState({editing: false})
 
     setTimeout(() => {
-      if (col.enter === '$next') {
+      if (/\$next/.test(col.enter)) {
         MKEmitter.emit('nextLine', col, record.$$uuid)
       } else if (col.enter === '$sub') {
         MKEmitter.emit('subLine', col, record)
@@ -242,7 +240,7 @@
     this.setState({editing: false})
 
     setTimeout(() => {
-      if (col.enter === '$next') {
+      if (/\$next/.test(col.enter)) {
         MKEmitter.emit('nextLine', col, record.$$uuid)
       } else if (col.enter === '$sub') {
         MKEmitter.emit('subLine', col, record)
@@ -544,7 +542,7 @@
     this.onBlur()
 
     setTimeout(() => {
-      if (col.enter === '$next') {
+      if (/\$next/.test(col.enter)) {
         MKEmitter.emit('nextLine', col, record.$$uuid)
       } else if (col.enter === '$sub') {
         MKEmitter.emit('subLine', col, record)
@@ -604,7 +602,7 @@
     const { col, record } = this.props
 
     setTimeout(() => {
-      if (col.enter === '$next') {
+      if (/\$next/.test(col.enter)) {
         MKEmitter.emit('nextLine', col, record.$$uuid)
       } else if (col.enter === '$sub') {
         MKEmitter.emit('subLine', col, record)
@@ -640,7 +638,7 @@
     }
 
     setTimeout(() => {
-      if (col.enter === '$next') {
+      if (/\$next/.test(col.enter)) {
         MKEmitter.emit('nextLine', col, record.$$uuid)
       } else if (col.enter === '$sub') {
         MKEmitter.emit('subLine', col, record)
@@ -910,7 +908,6 @@
   }
 
   state = {
-    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
     edData: [],
     selectedRowKeys: [],  // 琛ㄦ牸涓�変腑琛�
     tableId: '',          // 琛ㄦ牸ID
@@ -921,7 +918,9 @@
     orderfields: {},      // 鎺掑簭id涓巉ield杞崲
     loading: false,
     pageOptions: [],
-    deForms: null
+    deForms: null,
+    visible: false,
+    midData: null
   }
 
   UNSAFE_componentWillMount () {
@@ -1077,23 +1076,18 @@
   }
 
   transferData = (menuid, data, type) => {
-    const { MenuID, setting } = this.props
+    const { MenuID } = this.props
+    const { edData } = this.state
 
     if (menuid !== MenuID) return
 
     if (type !== 'line') {
-      if (setting.editType === 'multi' && data.length > 0) {
-        this.setState({edData: []}, () => {
-          this.setState({edData: data})
-        })
-      } else {
-        this.setState({edData: data})
-      }
+      let index = edData.findIndex(item => !item.$origin && !item.$forbid)
 
-      if (setting.addable && data.length === 0) {
-        setTimeout(() => {
-          this.plusLine(true)
-        }, 10)
+      if (index > -1) {
+        this.setState({visible: true, midData: data})
+      } else {
+        this.updateMutil(data)
       }
     } else if (type === 'line') {
       let _edData = this.state.edData.map(item => {
@@ -1105,6 +1099,24 @@
       })
 
       this.setState({edData: _edData})
+    }
+  }
+
+  updateMutil = (data) => {
+    const { setting } = this.props
+
+    if (setting.editType === 'multi' && data.length > 0) {
+      this.setState({edData: []}, () => {
+        this.setState({edData: data, visible: false, midData: null})
+      })
+    } else {
+      this.setState({edData: data, visible: false, midData: null})
+    }
+
+    if (setting.addable && data.length === 0) {
+      setTimeout(() => {
+        this.plusLine(true)
+      }, 10)
     }
   }
 
@@ -1300,7 +1312,12 @@
     let next = edData[index + 1] || null
     
     if (next) {
-      let node = document.getElementById(setting.initId + next.$$uuid)
+      let nextId = setting.initId + next.$$uuid
+      if (/^\$next_/.test(col.enter)) {
+        nextId = col.enter.split('_')[1] + next.$$uuid
+      }
+      
+      let node = document.getElementById(nextId)
       if (node) {
         if (setting.editType === 'multi') {
           if (setting.triType === 'click') {
@@ -1595,6 +1612,8 @@
     const { submit, BID, setting } = this.props
     const { forms } = this.state
 
+    this.setState({visible: false, midData: null})
+
     if (setting.supModule && !BID) {
       notification.warning({
         top: 92,
@@ -1670,44 +1689,36 @@
     }
   }
 
-  updataLine = (item) => {
-    if (item.$type === 'del') {
-      let _data = this.state.edData.filter(m => m.$$uuid !== item.$$uuid)
-
-      this.setState({edData: _data})
-    } else {
-      let _data = this.state.edData.map(m => {
-        if (m.$$uuid === item.$$uuid) {
-          item.$origin = true
-          return item
-        }
-        return m
-      })
-
-      this.setState({edData: _data})
-    }
-    MKEmitter.emit('reloadData', this.props.MenuID, item.$$uuid, item)
-  }
-
   execSuccess = (res) => {
     const { submit } = this.props
+    const { edData } = this.state
 
     if (res && res.ErrCode === 'S') { // 鎵ц鎴愬姛
       notification.success({
         top: 92,
-        message: res.ErrMesg || this.state.dict['main.action.confirm.success'],
+        message: res.ErrMesg || '鎵ц鎴愬姛',
         duration: submit.stime ? submit.stime : 2
       })
     } else if (res && res.ErrCode === 'Y') { // 鎵ц鎴愬姛
       Modal.success({
-        title: res.ErrMesg || this.state.dict['main.action.confirm.success']
+        title: res.ErrMesg || '鎵ц鎴愬姛'
       })
     } else if (res && res.ErrCode === '-1') { // 瀹屾垚鍚庝笉鎻愮ず
 
     }
 
+    let _edData = fromJS(edData).toJS()
+
+    _edData = _edData.map(item => {
+      if (!item.$forbid) {
+        item.$origin = true
+      }
+      return item
+    })
+
     this.setState({
-      loading: false
+      loading: false,
+      edData: _edData
     })
 
     if (submit.closetab === 'true') {
@@ -1717,6 +1728,8 @@
     if (submit.execSuccess !== 'never') {
       MKEmitter.emit('refreshByButtonResult', submit.$menuId, submit.execSuccess, submit)
     }
+
+    submit.syncComponentId && MKEmitter.emit('reloadData', submit.syncComponentId)
   }
 
   execError = (res) => {
@@ -1854,7 +1867,7 @@
 
   render() {
     const { setting, lineMarks, submit } = this.props
-    const { tableId, edData, columns, loading, pageOptions, selectedRowKeys } = this.state
+    const { tableId, edData, columns, loading, pageOptions, selectedRowKeys, visible, midData } = this.state
 
     const components = {
       body: {
@@ -1863,7 +1876,6 @@
       }
     }
 
-    // 鏁版嵁鏀惰捣鏃讹紝杩囨护宸查�夋暟鎹�
     let _data = edData.filter(item => !item.$deleted)
 
     // 璁剧疆琛ㄦ牸閫夋嫨灞炴�э細鍗曢�夈�佸閫夈�佷笉鍙��
@@ -1888,8 +1900,6 @@
       }
     }
 
-    let _footer = ''
-
     let height = setting.height || false
     if (height && height <= 100) {
       height = height + 'vh'
@@ -1897,9 +1907,9 @@
 
     return (
       <>
-        <div className="edit-custom-table-btn-wrap" style={submit.wrapStyle}>
+        {setting.hasSubmit ? <div className="edit-custom-table-btn-wrap" style={submit.wrapStyle}>
           <Button style={submit.style} onClick={() => setTimeout(() => {this.submit()}, 10)} loading={loading} className="submit-table" type="link">鎻愪氦</Button>
-        </div>
+        </div> : null}
         <div className={`edit-custom-table ${setting.tableHeader || ''} ${height ? 'fixed-height' : ''} ${setting.mode || ''} table-vertical-${setting.vertical || ''} mk-edit-${setting.editType || 'simple'}`} id={tableId}>
           <Table
             rowKey="$$uuid"
@@ -1922,9 +1932,23 @@
             onChange={this.changeTable}
             pagination={_pagination}
           />
-          {_footer ? <div className={'normal-table-footer ' + (_pagination ? 'pagination' : '')}>{_footer}</div> : null}
-          {_data.length > 10 ? <Button style={submit.style} onClick={() => setTimeout(() => {this.submit()}, 10)} loading={loading} className="submit-footer-table" type="link">鎻愪氦</Button> : null}
+          {setting.hasSubmit && _data.length > 10 ? <Button style={submit.style} onClick={() => setTimeout(() => {this.submit()}, 10)} loading={loading} className="submit-footer-table" type="link">鎻愪氦</Button> : null}
         </div>
+        <Modal
+          className="mk-user-confirm"
+          visible={visible}
+          width={450}
+          maskClosable={false}
+          closable={false}
+          footer={[
+            <Button key="cancel" onClick={() => { this.setState({ visible: false, midData: null }) }}>鍙栨秷</Button>,
+            <Button key="refresh" className="table-refresh" onClick={() => { midData && this.updateMutil(midData) }}>鍒锋柊琛ㄦ牸</Button>,
+            <Button key="confirm" type="primary" onClick={() => setTimeout(() => {this.submit()}, 10)}>鎻愪氦鏁版嵁</Button>
+          ]}
+          destroyOnClose
+        >
+          <div><QuestionCircleOutlined />琛ㄦ牸涓湁鏁版嵁灏氭湭鎻愪氦</div>
+        </Modal>
       </>
     )
   }
diff --git a/src/tabviews/custom/components/table/edit-table/normalTable/index.scss b/src/tabviews/custom/components/table/edit-table/normalTable/index.scss
index 84cb88f..9fcaf63 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.scss
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.scss
@@ -7,14 +7,6 @@
   --mk-table-font-size: 14px;
   --mk-table-font-weight: normal;
 
-  .normal-table-footer {
-    padding: 10px 0px;
-    color: rgba(0, 0, 0, 0.65);
-  }
-  .normal-table-footer.pagination {
-    position: absolute;
-    bottom: 10px;
-  }
   >.ant-table-wrapper {
     position: relative;
     z-index: 1;
@@ -278,17 +270,17 @@
   table tbody tr {
     color: var(--mk-table-color);
   }
-  .ant-table-bordered {
-    table {
-      tbody {
-        tr:last-child {
-          td {
-            border-bottom: none;
-          }
-        }
-      }
-    }
-  }
+  // .ant-table-bordered {
+  //   table {
+  //     tbody {
+  //       tr:last-child {
+  //         td {
+  //           border-bottom: none;
+  //         }
+  //       }
+  //     }
+  //   }
+  // }
 }
 .edit-custom-table.mk-edit-simple {
   table tbody tr td {
@@ -406,3 +398,24 @@
     margin-bottom: 10px!important;
   }
 }
+.mk-user-confirm {
+  top: 30vh;
+
+  .ant-modal-body {
+    font-size: 16px;
+  }
+  .anticon-question-circle {
+    color: orange;
+    font-size: 16px;
+    margin-right: 5px;
+  }
+  .ant-modal-footer {
+    border-top: 0px;
+    padding: 10px 20px 25px 0px;
+    .table-refresh, .table-refresh:hover, .table-refresh:active, .table-refresh:focus {
+      color: #fff!important;
+      background-color: #ff4d4f!important;
+      border-color: #ff4d4f!important;
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/tabviews/custom/components/table/normal-table/index.jsx b/src/tabviews/custom/components/table/normal-table/index.jsx
index 5788718..dc99a3a 100644
--- a/src/tabviews/custom/components/table/normal-table/index.jsx
+++ b/src/tabviews/custom/components/table/normal-table/index.jsx
@@ -112,7 +112,7 @@
         }
 
         if (setting.controlField) {
-          if (setting.controlVal.includes(item[setting.controlField])) {
+          if (setting.controlVal.includes(item[setting.controlField] + '')) {
             item.$disabled = true
           }
         }
@@ -273,7 +273,7 @@
         }
 
         if (setting.controlField) {
-          if (setting.controlVal.includes(item[setting.controlField])) {
+          if (setting.controlVal.includes(item[setting.controlField] + '')) {
             item.$disabled = true
           }
         }
@@ -475,26 +475,13 @@
    * 鍚湁鍒濆涓嶅姞杞界殑椤甸潰锛屼慨鏀硅缃�
    */
   refreshbysearch = (searches) => {
-    const { setting } = this.state
-
-    if (setting.onload === 'false') {
-      this.setState({
-        pageIndex: 1,
-        search: searches,
-        setting: {...setting, onload: 'true'}
-      }, () => {
-        this.loadmaindata()
-        this.getStatFieldsValue()
-      })
-    } else {
-      this.setState({
-        pageIndex: 1,
-        search: searches
-      }, () => {
-        this.loadmaindata(true, 'true')
-        this.getStatFieldsValue()
-      })
-    }
+    this.setState({
+      pageIndex: 1,
+      search: searches
+    }, () => {
+      this.loadmaindata(true, 'true')
+      this.getStatFieldsValue()
+    })
   }
 
   /**
@@ -619,6 +606,30 @@
     }
   }
 
+  refreshLineData = (menuId, btn, uuid, count) => {
+    const { config } = this.state
+
+    if (config.uuid !== menuId) return
+    
+    let _data = fromJS(this.state.data).toJS().map(item => {
+      if (item.$$uuid === uuid) {
+        item[btn.field] = count
+      }
+      return item
+    })
+    let _selectedData = fromJS(this.state.selectedData).toJS().map(item => {
+      if (item.$$uuid === uuid) {
+        item[btn.field] = count
+      }
+      return item
+    })
+
+    this.setState({
+      data: _data,
+      selectedData: _selectedData
+    })
+  }
+
   UNSAFE_componentWillReceiveProps(nextProps) {
     const { sync, config, setting, BID, BData } = this.state
 
@@ -643,7 +654,7 @@
           }
 
           if (setting.controlField) {
-            if (setting.controlVal.includes(item[setting.controlField])) {
+            if (setting.controlVal.includes(item[setting.controlField] + '')) {
               item.$disabled = true
             }
           }
@@ -681,6 +692,7 @@
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
     MKEmitter.addListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.addListener('refreshLineData', this.refreshLineData)
     MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult)
 
     if (config.timer) {
@@ -714,7 +726,7 @@
           }
 
           if (setting.controlField) {
-            if (setting.controlVal.includes(item[setting.controlField])) {
+            if (setting.controlVal.includes(item[setting.controlField] + '')) {
               item.$disabled = true
             }
           }
@@ -735,6 +747,7 @@
     MKEmitter.removeListener('reloadData', this.reloadData)
     MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
     MKEmitter.removeListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.removeListener('refreshLineData', this.refreshLineData)
     MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult)
 
     this.timer && this.timer.stop()
diff --git a/src/tabviews/custom/components/tabs/antv-tabs/index.jsx b/src/tabviews/custom/components/tabs/antv-tabs/index.jsx
index 69b47b4..6d8b799 100644
--- a/src/tabviews/custom/components/tabs/antv-tabs/index.jsx
+++ b/src/tabviews/custom/components/tabs/antv-tabs/index.jsx
@@ -36,7 +36,7 @@
         let val = ''
         Object.keys(data).forEach(key => {
           if (key.toLowerCase() === _tabs.setting.controlField) {
-            val = data[key]
+            val = data[key] + ''
           }
         })
         _tabs.subtabs = config.subtabs.filter(tab => {
@@ -96,7 +96,7 @@
         let val = ''
         Object.keys(data).forEach(key => {
           if (key.toLowerCase() === tabs.setting.controlField) {
-            val = data[key]
+            val = data[key] + ''
           }
         })
         this.setState({
diff --git a/src/tabviews/custom/components/timeline/normal-timeline/index.jsx b/src/tabviews/custom/components/timeline/normal-timeline/index.jsx
index 1905369..5126d9e 100644
--- a/src/tabviews/custom/components/timeline/normal-timeline/index.jsx
+++ b/src/tabviews/custom/components/timeline/normal-timeline/index.jsx
@@ -115,6 +115,7 @@
     MKEmitter.addListener('reloadData', this.reloadData)
     MKEmitter.addListener('resetSelectLine', this.resetParentParam)
     MKEmitter.addListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.addListener('refreshLineData', this.refreshLineData)
     MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult)
 
     if (config.timer) {
@@ -150,6 +151,7 @@
     MKEmitter.removeListener('reloadData', this.reloadData)
     MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
     MKEmitter.removeListener('queryModuleParam', this.queryModuleParam)
+    MKEmitter.removeListener('refreshLineData', this.refreshLineData)
     MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult)
 
     this.timer && this.timer.stop()
@@ -208,6 +210,23 @@
     }
   }
 
+  refreshLineData = (menuId, btn, uuid, count) => {
+    const { config, data } = this.state
+
+    if (config.uuid !== menuId) return
+    
+    let _data = fromJS(data).toJS().map(item => {
+      if (item.$$uuid === uuid) {
+        item[btn.field] = count
+      }
+      return item
+    })
+
+    this.setState({
+      data: _data
+    })
+  }
+
   resetParentParam = (MenuID, id, data) => {
     const { config } = this.state
 
@@ -219,6 +238,22 @@
     }
   }
 
+  refreshLineData = (menuId, btn, uuid, count) => {
+    const { config, data } = this.state
+
+    if (config.uuid !== menuId) return
+    
+    let _data = fromJS(data).toJS().forEach(item => {
+      if (item.$$uuid === uuid) {
+        item[btn.field] = count
+      }
+    })
+
+    this.setState({
+      data: _data
+    })
+  }
+
   reloadData = (menuId) => {
     const { config } = this.state
 
diff --git a/src/tabviews/custom/components/tree/antd-tree/index.jsx b/src/tabviews/custom/components/tree/antd-tree/index.jsx
index 922eba9..2d63a92 100644
--- a/src/tabviews/custom/components/tree/antd-tree/index.jsx
+++ b/src/tabviews/custom/components/tree/antd-tree/index.jsx
@@ -339,6 +339,7 @@
       if (pval === config.wrap.mark) {
         parentNodes.push({
           ...item,
+          mk_floor: 1,
           $$uuid: uuid,
           $title: item[config.wrap.labelField] || '',
           $key: val,
@@ -355,7 +356,7 @@
       }
     })
     let _treedata = this.getTree(parentNodes, _options)
-    
+
     let _treeNodes = []
 
     if (!searchkey) {
@@ -437,6 +438,7 @@
       // 娣诲姞鑿滃崟鐨勫瓙鍏冪礌
       options = options.filter(option => {
         if (option.$parentId === parent.$key) {
+          option.mk_floor = parent.mk_floor + 1
           parent.children.push(option)
           return false
         }
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index f10ec65..3c6b9b3 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -153,7 +153,7 @@
 
       // 鏁版嵁缂撳瓨璁剧疆
       if (config.cacheUseful === 'true') {
-        if (!['day', 'hour'].includes(config.timeUnit)) {
+        if (!['day', 'hour', 'minute'].includes(config.timeUnit)) {
           config.timeUnit = 'day'
         }
         config.cacheTime = config.cacheTime || 1
@@ -473,9 +473,7 @@
         item.search = Utils.initSearchVal(item.search)
       }
 
-      let mutil = false
       if (item.wrap && item.wrap.supType === 'multi') { // 鏁版嵁鍗″涓婄骇缁勪欢
-        mutil = true
         item.setting.supModule = item.supNodes[0].componentId
       } else if (item.setting && item.setting.supModule && typeof(item.setting.supModule) !== 'string') {
         let pid = item.setting.supModule.pop()
@@ -500,13 +498,6 @@
           cell = this.resetButton(item, cell, popview)
 
           cell.$toolbtn = true
-
-          if (!mutil && cell.syncComponentId === item.setting.supModule) {
-            cell.syncComponentId = ''
-            if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-              cell.execSuccess = 'mainline'
-            }
-          }
 
           if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 鎵撳嵃鏈鸿缃�
             cell = this.getPrinter(cell, item.uuid)
@@ -554,13 +545,6 @@
 
                   cell = this.resetButton(item, cell, popview)
 
-                  if (cell.syncComponentId === item.setting.supModule) {
-                    cell.syncComponentId = ''
-                    if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-                      cell.execSuccess = 'mainline'
-                    }
-                  }
-
                   if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 鎵撳嵃鏈鸿缃�
                     cell = this.getPrinter(cell, item.uuid)
                   }
@@ -594,6 +578,14 @@
         if (item.subtype === 'editable') {
           item.submit.logLabel = item.$menuname + '-鎻愪氦'
           item.submit.$menuId = item.uuid
+          item.submit.syncComponentId = item.submit.syncComponent ? (item.submit.syncComponent.pop() || '') : ''
+
+          if (item.submit.syncComponentId && item.submit.syncComponentId === item.setting.supModule) {
+            item.submit.syncComponentId = ''
+            if (item.submit.execSuccess === 'grid') {
+              item.submit.execSuccess = 'mainline'
+            }
+          }
         }
       } else if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
         item.subcards && item.subcards.forEach(card => {
@@ -610,13 +602,6 @@
 
               cell = this.resetButton(item, cell, popview)
 
-              if (!mutil && cell.syncComponentId === item.setting.supModule) {
-                cell.syncComponentId = ''
-                if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-                  cell.execSuccess = 'mainline'
-                }
-              }
-
               if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 鎵撳嵃鏈鸿缃�
                 cell = this.getPrinter(cell, item.uuid)
               }
@@ -627,6 +612,30 @@
             return cell.eleType !== 'button' || pass || permAction[cell.uuid]
           })
 
+          if (card.setting.click === 'menus') {
+            if (card.menus) {
+              card.menus = card.menus.filter(m => !!m.MenuID)
+              if (card.menus.length === 0) {
+                card.menus = null
+              }
+            }
+            if (!card.menus || item.subtype !== 'datacard' || card.$cardType === 'extendCard') {
+              card.setting.click = ''
+            }
+          } else if (card.setting.click === 'menu') {
+            if (!Array.isArray(card.setting.menu)) {
+              card.setting.click = ''
+            }
+          }
+
+          if (item.subtype === 'dualdatacard' && card.$cardType !== 'extendCard') {
+            if (card.backSetting && card.backSetting.click === 'menu') {
+              if (!Array.isArray(card.backSetting.menu)) {
+                card.backSetting.click = ''
+              }
+            }
+          }
+
           if (!card.backElements || card.backElements.length === 0) return
 
           card.backElements = card.backElements.filter(cell => {
@@ -634,13 +643,6 @@
               if (cell.hidden === 'true') return false
 
               cell = this.resetButton(item, cell, popview)
-
-              if (!mutil && cell.syncComponentId === item.setting.supModule) {
-                cell.syncComponentId = ''
-                if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-                  cell.execSuccess = 'mainline'
-                }
-              }
 
               if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 鎵撳嵃鏈鸿缃�
                 cell = this.getPrinter(cell, item.uuid)
@@ -666,13 +668,6 @@
 
             cell = this.resetButton(item, cell, popview)
 
-            if (cell.syncComponentId === item.wrap.supModule) {
-              cell.syncComponentId = ''
-              if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-                cell.execSuccess = 'mainline'
-              }
-            }
-
             if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 鎵撳嵃鏈鸿缃�
               cell = this.getPrinter(cell, item.uuid)
             }
@@ -696,9 +691,9 @@
             group.subButton.Ot = item.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
           }
 
-          group.subButton.syncComponentId = group.subButton.syncComponent ? group.subButton.syncComponent.pop() : ''
+          group.subButton.syncComponentId = group.subButton.syncComponent ? (group.subButton.syncComponent.pop() || '') : ''
 
-          if (group.subButton.syncComponentId === item.setting.supModule) {
+          if (group.subButton.syncComponentId && group.subButton.syncComponentId === item.setting.supModule) {
             group.subButton.syncComponentId = ''
             if (group.subButton.execSuccess === 'grid') {
               group.subButton.execSuccess = 'mainline'
@@ -797,6 +792,32 @@
       }
     }
 
+    if (cell.syncComponentId) {
+      if (cell.syncComponentId === item.setting.supModule) {
+        cell.syncComponentId = ''
+        if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
+          cell.execSuccess = 'mainline'
+        }
+      } else if (cell.syncComponentId === 'multiComponent') {
+        let ids = cell.syncComponents.map(m => {
+          return m.syncComId.pop() || ''
+        })
+
+        if (item.setting.supModule && ids.includes(item.setting.supModule)) {
+          if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
+            cell.execSuccess = 'mainline'
+          }
+          ids = ids.filter(id => id !== item.setting.supModule)
+        }
+        
+        if (ids.length === 0) {
+          cell.syncComponentId = ''
+        } else {
+          cell.syncComponentIds = ids
+        }
+      }
+    }
+
     return cell
   }
 
diff --git a/src/tabviews/custom/popview/index.jsx b/src/tabviews/custom/popview/index.jsx
index 6dccc71..0093459 100644
--- a/src/tabviews/custom/popview/index.jsx
+++ b/src/tabviews/custom/popview/index.jsx
@@ -97,7 +97,7 @@
 
     // 鏁版嵁缂撳瓨璁剧疆
     if (config.cacheUseful === 'true') {
-      if (!['day', 'hour'].includes(config.timeUnit)) {
+      if (!['day', 'hour', 'minute'].includes(config.timeUnit)) {
         config.timeUnit = 'day'
       }
       config.cacheTime = config.cacheTime || 1
@@ -302,9 +302,7 @@
         item.search = Utils.initSearchVal(item.search)
       }
 
-      let mutil = false
       if (item.wrap && item.wrap.supType === 'multi') { // 鏁版嵁鍗″涓婄骇缁勪欢
-        mutil = true
         item.setting.supModule = item.supNodes[0].componentId
       } else if (item.setting && item.setting.supModule && typeof(item.setting.supModule) !== 'string') {
         let pid = item.setting.supModule.pop()
@@ -322,13 +320,6 @@
 
           cell = this.resetButton(item, cell, Tab)
           cell.$toolbtn = true
-
-          if (!mutil && cell.syncComponentId === item.setting.supModule) {
-            cell.syncComponentId = ''
-            if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-              cell.execSuccess = 'mainline'
-            }
-          }
 
           return true
         })
@@ -371,13 +362,6 @@
                   if (cell.hidden === 'true' || cell.OpenType === 'popview') return false
             
                   cell = this.resetButton(item, cell, Tab)
-
-                  if (cell.syncComponentId === item.setting.supModule) {
-                    cell.syncComponentId = ''
-                    if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-                      cell.execSuccess = 'mainline'
-                    }
-                  }
                 } else {
                   cell = this.resetElement(cell)
                 }
@@ -407,6 +391,14 @@
         if (item.subtype === 'editable') {
           item.submit.logLabel = item.$menuname + '-鎻愪氦'
           item.submit.$menuId = item.uuid
+          item.submit.syncComponentId = item.submit.syncComponent ? (item.submit.syncComponent.pop() || '') : ''
+
+          if (item.submit.syncComponentId && item.submit.syncComponentId === item.setting.supModule) {
+            item.submit.syncComponentId = ''
+            if (item.submit.execSuccess === 'grid') {
+              item.submit.execSuccess = 'mainline'
+            }
+          }
         }
       } else if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
         item.subcards && item.subcards.forEach(card => {
@@ -422,19 +414,36 @@
               if (cell.hidden === 'true' || cell.OpenType === 'popview') return false
 
               cell = this.resetButton(item, cell, Tab)
-
-              if (!mutil && cell.syncComponentId === item.setting.supModule) {
-                cell.syncComponentId = ''
-                if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-                  cell.execSuccess = 'mainline'
-                }
-              }
             } else {
               cell = this.resetElement(cell)
             }
 
             return true
           })
+
+          if (card.setting.click === 'menus') {
+            if (card.menus) {
+              card.menus = card.menus.filter(m => !!m.MenuID)
+              if (card.menus.length === 0) {
+                card.menus = null
+              }
+            }
+            if (!card.menus || item.subtype !== 'datacard' || card.$cardType === 'extendCard') {
+              card.setting.click = ''
+            }
+          } else if (card.setting.click === 'menu') {
+            if (!Array.isArray(card.setting.menu)) {
+              card.setting.click = ''
+            }
+          }
+
+          if (item.subtype === 'dualdatacard' && card.$cardType !== 'extendCard') {
+            if (card.backSetting && card.backSetting.click === 'menu') {
+              if (!Array.isArray(card.backSetting.menu)) {
+                card.backSetting.click = ''
+              }
+            }
+          }
 
           if (!card.backElements || card.backElements.length === 0) return
 
@@ -443,13 +452,6 @@
               if (cell.hidden === 'true' || cell.OpenType === 'popview') return false
 
               cell = this.resetButton(item, cell, Tab)
-
-              if (!mutil && cell.syncComponentId === item.setting.supModule) {
-                cell.syncComponentId = ''
-                if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-                  cell.execSuccess = 'mainline'
-                }
-              }
             } else {
               cell = this.resetElement(cell)
             }
@@ -470,13 +472,6 @@
             if (cell.hidden === 'true' || cell.OpenType === 'popview') return false
 
             cell = this.resetButton(item, cell, Tab)
-
-            if (cell.syncComponentId === item.wrap.supModule) {
-              cell.syncComponentId = ''
-              if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-                cell.execSuccess = 'mainline'
-              }
-            }
           } else {
             cell = this.resetElement(cell)
           }
@@ -496,9 +491,9 @@
             group.subButton.Ot = item.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
           }
 
-          group.subButton.syncComponentId = group.subButton.syncComponent ? group.subButton.syncComponent.pop() : ''
+          group.subButton.syncComponentId = group.subButton.syncComponent ? (group.subButton.syncComponent.pop() || '') : ''
 
-          if (group.subButton.syncComponentId === item.setting.supModule) {
+          if (group.subButton.syncComponentId && group.subButton.syncComponentId === item.setting.supModule) {
             group.subButton.syncComponentId = ''
             if (group.subButton.execSuccess === 'grid') {
               group.subButton.execSuccess = 'mainline'
@@ -590,6 +585,32 @@
       }
     }
 
+    if (cell.syncComponentId) {
+      if (cell.syncComponentId === item.setting.supModule) {
+        cell.syncComponentId = ''
+        if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
+          cell.execSuccess = 'mainline'
+        }
+      } else if (cell.syncComponentId === 'multiComponent') {
+        let ids = cell.syncComponents.map(m => {
+          return m.syncComId.pop() || ''
+        })
+
+        if (item.setting.supModule && ids.includes(item.setting.supModule)) {
+          if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
+            cell.execSuccess = 'mainline'
+          }
+          ids = ids.filter(id => id !== item.setting.supModule)
+        }
+        
+        if (ids.length === 0) {
+          cell.syncComponentId = ''
+        } else {
+          cell.syncComponentIds = ids
+        }
+      }
+    }
+
     return cell
   }
 
diff --git a/src/tabviews/iframe/index.jsx b/src/tabviews/iframe/index.jsx
index c1186d4..eae4d43 100644
--- a/src/tabviews/iframe/index.jsx
+++ b/src/tabviews/iframe/index.jsx
@@ -6,7 +6,6 @@
   static propTypes = {
     title: PropTypes.string,
     MenuID: PropTypes.string,    // 鑿滃崟Id
-    MenuNo: PropTypes.string,    // 鑿滃崟鍙傛暟
     url: PropTypes.string
   }
 
diff --git a/src/tabviews/subtable/index.jsx b/src/tabviews/subtable/index.jsx
index ac80f8f..8cf8ac8 100644
--- a/src/tabviews/subtable/index.jsx
+++ b/src/tabviews/subtable/index.jsx
@@ -7,7 +7,6 @@
 import zhCN from '@/locales/zh-CN/main.js'
 import enUS from '@/locales/en-US/main.js'
 import Utils from '@/utils/utils.js'
-import options from '@/store/options.js'
 import UtilsDM from '@/utils/utils-datamanage.js'
 import { updateSubTable } from '@/utils/utils-update.js'
 import asyncComponent from '@/utils/asyncComponent'
@@ -41,7 +40,6 @@
     viewlost: false,      // 椤甸潰涓㈠け锛�1銆佹湭鑾峰彇鍒伴厤缃�-椤甸潰涓㈠け锛�2銆侀〉闈㈡湭鍚敤
     lostmsg: '',          // 椤甸潰涓㈠け鏃剁殑鎻愮ず淇℃伅
     config: null,         // 椤甸潰閰嶇疆淇℃伅锛屽寘鎷寜閽�佹悳绱€�佹樉绀哄垪銆佹爣绛剧瓑
-    searchlist: null,     // 鎼滅储鏉′欢
     actions: null,        // 鎸夐挳闆�
     columns: null,        // 鏄剧ず鍒�
     arr_field: '',        // 鏌ヨ瀛楁闆�
@@ -59,7 +57,6 @@
     statFields: [],       // 鍚堣瀛楁
     statFValue: [],       // 鍚堣鍊�
     absFields: [],        // 缁濆鍊煎瓧娈�
-    loadCustomApi: true,  // 鍔犺浇澶栭儴璧勬簮
     hasReqFields: false,
     BID: '',
     BData: ''
@@ -285,7 +282,7 @@
       config.setting.execute = config.setting.default !== 'false'     // 榛樿sql鏄惁鎵ц锛岃浆涓篵oolean 缁熶竴鏍煎紡
       config.setting.customScript = ''                                // 鑷畾涔夎剼鏈�
 
-      if (config.setting.interType === 'system' || (config.setting.interType === 'custom' && config.setting.requestMode === 'system')) {
+      if (config.setting.interType === 'system') {
         if (config.setting.scripts && config.setting.scripts.length > 0) {
           let _customScript = ''
           config.setting.scripts.forEach(item => {
@@ -351,6 +348,18 @@
         }
       }
 
+      config.type = 'table'
+      config.wrap = {
+        show: config.setting.show || '',
+        float: config.setting.float || '',
+        advanceType: config.setting.advanceType || '',
+        advanceWidth: config.setting.advanceWidth || '',
+        drawerPlacement: config.setting.drawerPlacement || '',
+        searchRatio: config.setting.searchRatio || '',
+        searchLwidth: config.setting.searchLwidth,
+        borderRadius: config.setting.borderRadius,
+      }
+
       this.setState({
         pageSize: config.setting.pageSize || 10,
         BID: this.props.BID || '',
@@ -361,7 +370,6 @@
         absFields,
         statFields,
         setting: config.setting,
-        searchlist: config.search,
         actions: _actions,
         columns: _columns,
         arr_field: _arrField.join(','),
@@ -389,7 +397,7 @@
   
   loadData = (id) => {
     const { mainSearch } = this.props
-    const { setting, BID, search, loadCustomApi, hasReqFields } = this.state
+    const { setting, BID, search, hasReqFields } = this.state
 
     let searches = fromJS(search).toJS()
     if (mainSearch && mainSearch.length > 0) { // 涓昏〃鎼滅储鏉′欢
@@ -406,6 +414,15 @@
       }
     }
 
+    if (setting.interType === 'custom') {
+      notification.warning({
+        top: 92,
+        message: '绯荤粺涓嶅湪鏀寔鑷畾涔夋帴鍙�!',
+        duration: 3
+      })
+      return
+    }
+
     if (this.props.Tab.supMenu && !BID) { // 涓昏〃ID涓嶅瓨鍦ㄦ椂锛屼笉鏌ヨ瀛愯〃
       this.setState({
         data: [],
@@ -415,13 +432,6 @@
       })
       MKEmitter.emit('changeTableLine', this.props.Tab.ContainerId, this.props.Tab.uuid, '', '')
       return
-    } else if (window.GLOB.systemType === 'production' && setting.interType === 'custom' && !setting.proInterface) {
-      notification.warning({
-        top: 92,
-        message: '鏈缃寮忕郴缁熷湴鍧�!',
-        duration: 3
-      })
-      return
     }
 
     this.setState({
@@ -429,177 +439,7 @@
     })
     MKEmitter.emit('changeTableLine', this.props.Tab.ContainerId, this.props.Tab.uuid, '', '')
 
-    if (setting.interType === 'custom' && loadCustomApi) {
-      if (setting.execTime === 'once') {
-        this.setState({loadCustomApi: false})
-      }
-
-      this.loadOutResource(searches)
-      if (setting.execType === 'async') {
-        this.loadmaindata(id)
-      }
-    } else {
-      this.loadmaindata(id)
-    }
-  }
-
-  loadOutResource = (searches) => {
-    const { setting, BID } = this.state
-
-    let param = UtilsDM.getPrevQueryParams(setting, searches, BID)
-
-    if (setting.execType === 'sync') {
-      this.setState({
-        loading: true
-      })
-    }
-
-    Api.genericInterface(param).then(res => {
-      if (res.status) {
-        if (res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) {
-          this.loadmaindata()
-        } else {
-          this.customOuterRequest(res)
-        }
-      } else {
-        this.setState({
-          loading: false
-        })
-        notification.error({
-          top: 92,
-          message: res.message,
-          duration: 10
-        })
-      }
-    }, () => {
-      this.setState({
-        loading: false
-      })
-    })
-  }
-
-  customOuterRequest = (result) => {
-    const { setting } = this.state
-    let url = ''
-
-    if (window.GLOB.systemType === 'production') {
-      url = setting.proInterface
-    } else {
-      url = setting.interface
-    }
-
-    let mkey = result.mk_api_key || ''
-
-    delete result.mk_ex_invoke
-    delete result.status
-    delete result.message
-    delete result.ErrCode
-    delete result.ErrMesg
-    delete result.mk_api_key
-
-    let param = {}
-
-    Object.keys(result).forEach(key => {
-      key = key.replace(/^mk_/ig, '')
-      param[key] = result[key]
-    })
-
-    Api.directRequest(url, setting.method, param, setting.cross).then(res => {
-      if (typeof(res) !== 'object') {
-        let error = '鏈煡鐨勮繑鍥炵粨鏋滐紒'
-
-        if (typeof(res) === 'string') {
-          error = res.replace(/'/ig, '"')
-        }
-
-        let _result = {
-          mk_api_key: mkey,
-          $ErrCode: 'E',
-          $ErrMesg: error
-        }
-
-        this.customCallbackRequest(_result)
-      } else {
-        if (Array.isArray(res)) {
-          res = { data: res }
-        }
-        res.mk_api_key = mkey
-        this.customCallbackRequest(res)
-      }
-    }, (e) => {
-      let _result = {
-        mk_api_key: mkey,
-        $ErrCode: 'E',
-        $ErrMesg: e && e.statusText ? e.statusText : ''
-      }
-
-      this.customCallbackRequest(_result)
-    })
-  }
-
-  customCallbackRequest = (result) => {
-    const { setting, BID } = this.state
-    let errSql = ''
-    if (result.$ErrCode === 'E') {
-      errSql = `
-        set @ErrorCode='E'
-        set @retmsg='${result.$ErrMesg}'
-      `
-      delete result.$ErrCode
-      delete result.$ErrMesg
-    }
-
-    let lines = UtilsDM.getCallBackSql(setting, result)
-    let param = {}
-
-    if (setting.callbackType === 'script') { // 浣跨敤鑷畾涔夎剼鏈�
-      let sql = lines.map(item => (`
-        ${item.insert}
-        ${item.selects.join(` union all
-        `)}
-      `))
-      sql = sql.join('')
-      
-      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql, BID)
-    } else {
-      param.func = 's_ex_result_back'
-      param.s_ex_result = lines.map((item, index) => ({
-        MenuID: this.props.MenuID,
-        MenuName: this.props.Tab.label,
-        TableName: item.table,
-        LongText: window.btoa(window.encodeURIComponent(`${item.insert}  ${item.selects.join(` union all `)}`)),
-        Sort: index + 1
-      }))
-
-      if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
-        let sql = lines.map(item => (`
-          ${item.insert}
-          ${item.selects.join(` union all
-          `)}
-        `))
-        sql = sql.join('')
-        console.info(sql.replace(/\n\s{10}/ig, '\n'))
-      }
-    }
-
-    Api.genericInterface(param).then(res => {
-      if (res.status) {
-        this.loadmaindata()
-      } else {
-        this.setState({
-          loading: false
-        })
-        notification.error({
-          top: 92,
-          message: res.message,
-          duration: 10
-        })
-      }
-    }, () => {
-      this.setState({
-        loading: false
-      })
-    })
+    this.loadmaindata(id)
   }
 
   /**
@@ -657,7 +497,7 @@
           item.$Index = start + index + ''
 
           if (setting.controlField) {
-            if (setting.controlVal.includes(item[setting.controlField])) {
+            if (setting.controlVal.includes(item[setting.controlField] + '')) {
               item.$disabled = true
             }
           }
@@ -771,7 +611,7 @@
   getStatFieldsValue = (searches) => {
     const { setting, BID, orderBy, statFields } = this.state
 
-    if (statFields.length === 0 || !(setting.interType === 'system' || (setting.interType === 'custom' && setting.requestMode === 'system')) || !setting.dataresource) return
+    if (statFields.length === 0 || setting.interType !== 'system' || !setting.dataresource) return
 
     let _orderBy = orderBy || setting.order
     let param = UtilsDM.getStatQueryDataParams(setting, statFields, searches, _orderBy, BID)
@@ -1007,13 +847,13 @@
   }
 
   render() {
-    const { config, BID, BData, setting, searchlist, pageSize, actions, columns, loadingview, viewlost, pickup, chartId, selectedData } = this.state
+    const { config, BID, BData, setting, pageSize, actions, columns, loadingview, viewlost, pickup, chartId, selectedData } = this.state
 
     return (
       <div className="subtable" id={'subtable' + this.props.MenuID}>
         {loadingview && <Spin />}
-        {searchlist && searchlist.length ?
-          <SubSearch BID={BID} setting={setting} searchlist={searchlist} refreshdata={this.refreshbysearch}/> : null
+        {config && config.search && config.search.length ?
+          <SubSearch BID={BID} config={config} refreshdata={this.refreshbysearch}/> : null
         }
         {config && config.charts ? <Row className="chart-view" gutter={16}>
           {/* 瑙嗗浘缁� */}
diff --git a/src/tabviews/subtabtable/index.jsx b/src/tabviews/subtabtable/index.jsx
index ef20200..24b4808 100644
--- a/src/tabviews/subtabtable/index.jsx
+++ b/src/tabviews/subtabtable/index.jsx
@@ -7,7 +7,6 @@
 import zhCN from '@/locales/zh-CN/main.js'
 import enUS from '@/locales/en-US/main.js'
 import Utils from '@/utils/utils.js'
-import options from '@/store/options.js'
 import UtilsDM from '@/utils/utils-datamanage.js'
 import { updateSubTabTable } from '@/utils/utils-update.js'
 import asyncComponent from '@/utils/asyncComponent'
@@ -36,7 +35,6 @@
     viewlost: false,      // 椤甸潰涓㈠け锛�1銆佹湭鑾峰彇鍒伴厤缃�-椤甸潰涓㈠け锛�2銆侀〉闈㈡湭鍚敤
     lostmsg: '',          // 椤甸潰涓㈠け鏃剁殑鎻愮ず淇℃伅
     config: null,         // 椤甸潰閰嶇疆淇℃伅锛屽寘鎷寜閽�佹悳绱€�佹樉绀哄垪銆佹爣绛剧瓑
-    searchlist: null,     // 鎼滅储鏉′欢
     actions: null,        // 鎸夐挳闆�
     columns: null,        // 鏄剧ず鍒�
     arr_field: '',        // 鏌ヨ瀛楁闆�
@@ -52,7 +50,6 @@
     statFields: [],       // 鍚堣瀛楁
     statFValue: [],       // 鍚堣鍊�
     absFields: [],        // 缁濆鍊煎瓧娈�
-    loadCustomApi: true,  // 鍔犺浇澶栭儴璧勬簮
     hasReqFields: false
   }
 
@@ -240,7 +237,7 @@
       config.setting.execute = config.setting.default !== 'false'     // 榛樿sql鏄惁鎵ц锛岃浆涓篵oolean 缁熶竴鏍煎紡
       config.setting.customScript = ''                                // 鑷畾涔夎剼鏈�
 
-      if (config.setting.interType === 'system' || (config.setting.interType === 'custom' && config.setting.requestMode === 'system')) {
+      if (config.setting.interType === 'system') {
         if (config.setting.scripts && config.setting.scripts.length > 0) {
           let _customScript = ''
           config.setting.scripts.forEach(item => {
@@ -306,6 +303,18 @@
         }
       }
 
+      config.type = 'table'
+      config.wrap = {
+        show: config.setting.show || '',
+        float: config.setting.float || '',
+        advanceType: config.setting.advanceType || '',
+        advanceWidth: config.setting.advanceWidth || '',
+        drawerPlacement: config.setting.drawerPlacement || '',
+        searchRatio: config.setting.searchRatio || '',
+        searchLwidth: config.setting.searchLwidth,
+        borderRadius: config.setting.borderRadius,
+      }
+
       this.setState({
         pageSize: config.setting.pageSize || 10,
         loadingview: false,
@@ -313,7 +322,6 @@
         absFields,
         statFields,
         setting: config.setting,
-        searchlist: config.search,
         actions: _actions,
         columns: _columns,
         arr_field: _arrField.join(','),
@@ -338,7 +346,7 @@
   }
 
   loadData = (id) => {
-    const { setting, search, hasReqFields, loadCustomApi } = this.state
+    const { setting, search, hasReqFields } = this.state
 
     let searches = fromJS(search).toJS()
 
@@ -352,10 +360,10 @@
       }
     }
 
-    if (window.GLOB.systemType === 'production' && setting.interType === 'custom' && !setting.proInterface) {
+    if (setting.interType === 'custom') {
       notification.warning({
         top: 92,
-        message: '鏈缃寮忕郴缁熷湴鍧�!',
+        message: '绯荤粺涓嶅湪鏀寔鑷畾涔夋帴鍙�!',
         duration: 3
       })
       return
@@ -365,178 +373,7 @@
       selectedData: []
     })
 
-    if (setting.interType === 'custom' && loadCustomApi) {
-      if (setting.execTime === 'once') {
-        this.setState({loadCustomApi: false})
-      }
-
-      this.loadOutResource(searches)
-      if (setting.execType === 'async') {
-        this.loadmaindata(id)
-      }
-    } else {
-      this.loadmaindata(id)
-    }
-  }
-
-  loadOutResource = (searches) => {
-    const { setting } = this.state
-
-    let param = UtilsDM.getPrevQueryParams(setting, searches, this.props.BID)
-
-    if (setting.execType === 'sync') {
-      this.setState({
-        loading: true
-      })
-    }
-
-    Api.genericInterface(param).then(res => {
-      if (res.status) {
-        if (res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) {
-          this.loadmaindata()
-        } else {
-          this.customOuterRequest(res)
-        }
-      } else {
-        this.setState({
-          loading: false
-        })
-        notification.error({
-          top: 92,
-          message: res.message,
-          duration: 10
-        })
-      }
-    }, () => {
-      this.setState({
-        loading: false
-      })
-    })
-  }
-
-  customOuterRequest = (result) => {
-    const { setting } = this.state
-    let url = ''
-
-    if (window.GLOB.systemType === 'production') {
-      url = setting.proInterface
-    } else {
-      url = setting.interface
-    }
-
-    let mkey = result.mk_api_key || ''
-
-    delete result.mk_ex_invoke
-    delete result.status
-    delete result.message
-    delete result.ErrCode
-    delete result.ErrMesg
-    delete result.mk_api_key
-
-    let param = {}
-
-    Object.keys(result).forEach(key => {
-      key = key.replace(/^mk_/ig, '')
-      param[key] = result[key]
-    })
-
-    Api.directRequest(url, setting.method, param, setting.cross).then(res => {
-      if (typeof(res) !== 'object') {
-        let error = '鏈煡鐨勮繑鍥炵粨鏋滐紒'
-
-        if (typeof(res) === 'string') {
-          error = res.replace(/'/ig, '"')
-        }
-
-        let _result = {
-          mk_api_key: mkey,
-          $ErrCode: 'E',
-          $ErrMesg: error
-        }
-
-        this.customCallbackRequest(_result)
-      } else {
-        if (Array.isArray(res)) {
-          res = { data: res }
-        }
-        res.mk_api_key = mkey
-        this.customCallbackRequest(res)
-      }
-    }, (e) => {
-      let _result = {
-        mk_api_key: mkey,
-        $ErrCode: 'E',
-        $ErrMesg: e && e.statusText ? e.statusText : ''
-      }
-
-      this.customCallbackRequest(_result)
-    })
-  }
-
-  customCallbackRequest = (result) => {
-    const { setting } = this.state
-    let errSql = ''
-    if (result.$ErrCode === 'E') {
-      errSql = `
-        set @ErrorCode='E'
-        set @retmsg='${result.$ErrMesg}'
-      `
-      delete result.$ErrCode
-      delete result.$ErrMesg
-    }
-
-    let lines = UtilsDM.getCallBackSql(setting, result)
-    let param = {}
-
-    if (setting.callbackType === 'script') { // 浣跨敤鑷畾涔夎剼鏈�
-      let sql = lines.map(item => (`
-        ${item.insert}
-        ${item.selects.join(` union all
-        `)}
-      `))
-      sql = sql.join('')
-      
-      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql, this.props.BID)
-    } else {
-      let name = this.props.Tab ? (this.props.Tab.label || '') : ''
-      param.func = 's_ex_result_back'
-      param.s_ex_result = lines.map((item, index) => ({
-        MenuID: this.props.MenuID,
-        MenuName: name,
-        TableName: item.table,
-        LongText: window.btoa(window.encodeURIComponent(`${item.insert}  ${item.selects.join(` union all `)}`)),
-        Sort: index + 1
-      }))
-
-      if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
-        let sql = lines.map(item => (`
-          ${item.insert}
-          ${item.selects.join(` union all
-          `)}
-        `))
-        sql = sql.join('')
-        console.info(sql.replace(/\n\s{10}/ig, '\n'))
-      }
-    }
-
-    Api.genericInterface(param).then(res => {
-      if (res.status) {
-        this.loadmaindata()
-      } else {
-        this.setState({
-          loading: false
-        })
-        notification.error({
-          top: 92,
-          message: res.message,
-          duration: 10
-        })
-      }
-    }, () => {
-      this.setState({
-        loading: false
-      })
-    })
+    this.loadmaindata(id)
   }
 
   /**
@@ -591,7 +428,7 @@
           item.$Index = start + index + ''
 
           if (setting.controlField) {
-            if (setting.controlVal.includes(item[setting.controlField])) {
+            if (setting.controlVal.includes(item[setting.controlField] + '')) {
               item.$disabled = true
             }
           }
@@ -626,7 +463,7 @@
     const { BID } = this.props
     const { setting, orderBy, statFields } = this.state
 
-    if (statFields.length === 0 || !(setting.interType === 'system' || (setting.interType === 'custom' && setting.requestMode === 'system')) || !setting.dataresource) return
+    if (statFields.length === 0 || setting.interType !== 'system' || !setting.dataresource) return
 
     let _orderBy = orderBy || setting.order
     let param = UtilsDM.getStatQueryDataParams(setting, statFields, searches, _orderBy, BID)
@@ -860,13 +697,13 @@
   }
 
   render() {
-    const { config, setting, searchlist, pageSize, actions, columns, loadingview, viewlost, selectedData } = this.state
+    const { config, setting, pageSize, actions, columns, loadingview, viewlost, selectedData } = this.state
 
     return (
       <div className="subtabtable" id={'subtabtable' + this.props.MenuID}>
         {loadingview && <Spin />}
-        {searchlist && searchlist.length ?
-          <SubSearch BID={this.props.BID} setting={setting} searchlist={searchlist} refreshdata={this.refreshbysearch}/> : null
+        {config && config.search && config.search.length ?
+          <SubSearch BID={this.props.BID} config={config} refreshdata={this.refreshbysearch}/> : null
         }
         {config ? <div style={{minHeight: '25px'}}>
           <SubAction
diff --git a/src/tabviews/zshare/actionList/excelInbutton/index.jsx b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
index 8856f16..2abe56f 100644
--- a/src/tabviews/zshare/actionList/excelInbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -199,8 +199,18 @@
       MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess, btn, '', this.state.selines)
     }
     
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-    
+    if (btn.syncComponentId) {
+      if (btn.syncComponentId === 'multiComponent') {
+        btn.syncComponentIds.forEach((id, i) => {
+          setTimeout(() => {
+            MKEmitter.emit('reloadData', id)
+          }, 20 * i)
+        })
+      } else {
+        MKEmitter.emit('reloadData', btn.syncComponentId)
+      }
+    }
+
     if (btn.switchTab && btn.switchTab.length > 0) {
       let id = btn.switchTab[btn.switchTab.length - 1]
       let node = document.getElementById('tab' + id)
diff --git a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
index 2d08e57..78fc739 100644
--- a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
@@ -1118,7 +1118,17 @@
       MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess, btn, '', [])
     }
     
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
+    if (btn.syncComponentId) {
+      if (btn.syncComponentId === 'multiComponent') {
+        btn.syncComponentIds.forEach((id, i) => {
+          setTimeout(() => {
+            MKEmitter.emit('reloadData', id)
+          }, 20 * i)
+        })
+      } else {
+        MKEmitter.emit('reloadData', btn.syncComponentId)
+      }
+    }
     
     if (btn.switchTab && btn.switchTab.length > 0) {
       let id = btn.switchTab[btn.switchTab.length - 1]
diff --git a/src/tabviews/zshare/actionList/newpagebutton/index.jsx b/src/tabviews/zshare/actionList/newpagebutton/index.jsx
index 94b50d8..7b094d7 100644
--- a/src/tabviews/zshare/actionList/newpagebutton/index.jsx
+++ b/src/tabviews/zshare/actionList/newpagebutton/index.jsx
@@ -192,6 +192,19 @@
       })
       window.open(url)
     } else if (btn.pageTemplate === 'custom') {
+      if (/#\/iframe\//.test(btn.url)) {
+        let menu = {
+          MenuID: btn.uuid,
+          MenuName: btn.label,
+          type: 'iframe',
+          OpenType: 'newtab',
+          src: btn.url.replace(/@userid@/ig, sessionStorage.getItem('UserID')).replace(/@loginuid@/ig, sessionStorage.getItem('LoginUID'))
+        }
+        MKEmitter.emit('modifyTabs', menu)
+
+        return
+      }
+      
       let url = btn.url
       let con = '?'
 
diff --git a/src/tabviews/zshare/actionList/normalbutton/index.jsx b/src/tabviews/zshare/actionList/normalbutton/index.jsx
index 4a56408..f49846b 100644
--- a/src/tabviews/zshare/actionList/normalbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -1,6 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import moment from 'moment'
+import qs from 'qs'
 import { is, fromJS } from 'immutable'
 import { Button, Modal, notification, message, Drawer, Switch, Checkbox, Progress } from 'antd'
 
@@ -61,7 +62,7 @@
     
     if (btn.OpenType === 'form') {
       let data = selectedData && selectedData[0] ? selectedData[0] : null
-      if (btn.formType === 'counter') {
+      if (btn.formType === 'counter' || btn.formType === 'count_line') {
         let count = 0
         if (data && data[btn.field]) {
           count = +data[btn.field]
@@ -108,7 +109,7 @@
 
     if (btn.OpenType === 'form') {
       let data = nextProps.selectedData && nextProps.selectedData[0] ? nextProps.selectedData[0] : null
-      if (btn.formType === 'counter') {
+      if (btn.formType === 'counter' || btn.formType === 'count_line') {
         let count = 0
         if (data && data[btn.field]) {
           count = +data[btn.field]
@@ -329,6 +330,9 @@
         return
       }
     } else if (!['inner', 'outer', 'system', 'custom'].includes(btn.intertype)) {
+      if (btn.OpenType === 'form' && btn.formType === 'count_line') {
+        return
+      }
       // 鎺ュ彛绫诲瀷閿欒
       notification.warning({
         top: 92,
@@ -744,8 +748,10 @@
     let _params = []
 
     if ( btn.Ot === 'notRequired' || btn.Ot === 'requiredSgl' || btn.Ot === 'requiredOnce' ) {
-      let param = {
-        func: btn.innerFunc || ''
+      let param = {}
+
+      if (btn.innerFunc) {
+        param.func = btn.innerFunc
       }
 
       if (this.props.BID) {
@@ -758,9 +764,7 @@
         let ids = data.map(d => { return d[setting.primaryKey] || ''})
         ids = ids.filter(Boolean)
         primaryId = ids.join(',')
-      }
 
-      if (setting.primaryKey) {
         param[setting.primaryKey] = primaryId // 璁剧疆涓婚敭鍙傛暟
       }
 
@@ -1269,7 +1273,46 @@
       param[key] = result[key]
     })
 
-    Api.directRequest(url, btn.method, param, btn.cross).then(res => {
+    let _params = {
+      url: url,
+      method: btn.method || 'post'
+    }
+
+    if (btn.cross === 'true') {
+      if (JSON.stringify(param) !== '{}') {
+        if (btn.stringify === 'qs') {
+          _params.data = qs.stringify(param)
+        } else if (btn.stringify === 'JSON') {
+          _params.data = param
+        } else {
+          _params.data = JSON.stringify(param)
+        }
+      }
+    } else {
+      let _url = url
+      if (JSON.stringify(param) !== '{}') {
+        if (_params.method === 'get') {
+          let keys = Object.keys(param).map(key => `${key}=${param[key]}`)
+          _url = _url + '?' + keys.join('&')
+        } else if (_params.method === 'post') {
+          if (btn.stringify === 'qs') {
+            _params.data = qs.stringify(param)
+          } else if (btn.stringify === 'JSON') {
+            _params.data = param
+          } else {
+            _params.data = JSON.stringify(param)
+          }
+        }
+      }
+  
+      _url = _url.replace(/&/ig, '%26')
+
+      _params.url = '/trans/redirect?rd=' + _url + '&method=' + _params.method
+
+      _params.method = 'post'
+    }
+
+    Api.directRequest(_params).then(res => {
       if (typeof(res) !== 'object') {
         let error = '鏈煡鐨勮繑鍥炵粨鏋滐紒'
 
@@ -2050,7 +2093,17 @@
       MKEmitter.emit('refreshDebugTable')
     }
     
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
+    if (btn.syncComponentId) {
+      if (btn.syncComponentId === 'multiComponent') {
+        btn.syncComponentIds.forEach((id, i) => {
+          setTimeout(() => {
+            MKEmitter.emit('reloadData', id)
+          }, 20 * i)
+        })
+      } else {
+        MKEmitter.emit('reloadData', btn.syncComponentId)
+      }
+    }
 
     if (tabId) {
       MKEmitter.emit('reloadMenuView', tabId, 'table')
@@ -2212,7 +2265,7 @@
         if (!res.oa_access_token) return
   
         params.forEach(n => {
-          Api.wxNginxRequest(`${domain2}cgi-bin/message/template/send?access_token=${res.oa_access_token}`, 'post', n).then(re => {
+          Api.wxNginxRequest(`${domain2}cgi-bin/message/template/send?access_token=${res.oa_access_token}`, 'post', JSON.stringify(n)).then(re => {
             if (verify.wxNoteCallback === 'true') {
               let msg = re.errmsg || ''
 
@@ -2869,6 +2922,37 @@
     })
   }
 
+  changeLineCount = (count) => {
+    const { btn, selectedData } = this.props
+    const { disabled } = this.state
+
+    if (disabled) return
+
+    let data = selectedData || []
+
+    if (data.length === 0) {
+      // 闇�瑕侀�夋嫨琛屾椂锛屾牎楠屾暟鎹�
+      notification.warning({
+        top: 92,
+        message: this.state.dict['main.action.confirm.selectline'],
+        duration: 5
+      })
+      return
+    } else if (data.length !== 1) {
+      // 闇�瑕侀�夋嫨鍗曡鏃讹紝鏍¢獙鏁版嵁
+      notification.warning({
+        top: 92,
+        message: this.state.dict['main.action.confirm.selectSingleLine'],
+        duration: 5
+      })
+      return
+    }
+
+    this.setState({count}, () => {
+      MKEmitter.emit('refreshLineData', btn.$menuId, btn, data[0].$$uuid, count)
+    })
+  }
+
   render() {
     const { btn } = this.props
     const { loadingNumber, loadingTotal, loading, disabled, hidden, check, count } = this.state
@@ -2879,6 +2963,8 @@
         return <Switch loading={loading} checked={check} disabled={disabled || loading} title={disabled ? (btn.reason || '') : ''} onChange={(val,e) => {e.stopPropagation();this.actionTrigger()}} style={btn.style} className={btn.size === 'large' ? 'ant-switch-large' : ''} size={btn.size} checkedChildren={btn.openText || ''} unCheckedChildren={btn.closeText || ''}/>
       } else if (btn.formType === 'counter') {
         return <MkCounter count={count} disabled={disabled} btn={btn} onChange={this.changeCount}/>
+      } else if (btn.formType === 'count_line') {
+        return <MkCounter count={count} disabled={disabled} btn={btn} onChange={this.changeLineCount}/>
       } else if (btn.formType === 'radio') {
         return <Checkbox className={btn.checkType || ''} disabled={disabled || loading} title={disabled ? (btn.reason || '') : ''} checked={check} onChange={(e) => {e.stopPropagation();this.actionTrigger()}} style={btn.style}></Checkbox>
       } else {
diff --git a/src/tabviews/zshare/actionList/normalbutton/mkcounter/index.jsx b/src/tabviews/zshare/actionList/normalbutton/mkcounter/index.jsx
index 5c0bfe3..8fed290 100644
--- a/src/tabviews/zshare/actionList/normalbutton/mkcounter/index.jsx
+++ b/src/tabviews/zshare/actionList/normalbutton/mkcounter/index.jsx
@@ -48,7 +48,7 @@
 
     this.timer = setTimeout(() => {
       this.props.onChange(val)
-    }, 1000)
+    }, btn.formType === 'count_line' ? 100 : 1000)
   }
 
   plus = () => {
@@ -71,7 +71,7 @@
 
     this.timer = setTimeout(() => {
       this.props.onChange(val)
-    }, 1000)
+    }, btn.formType === 'count_line' ? 100 : 1000)
   }
 
   submit = () => {
@@ -96,7 +96,7 @@
 
     this.timer = setTimeout(() => {
       this.props.onChange(count)
-    }, 1000)
+    }, btn.formType === 'count_line' ? 100 : 1000)
   }
 
   render() {
diff --git a/src/tabviews/zshare/actionList/popupbutton/index.jsx b/src/tabviews/zshare/actionList/popupbutton/index.jsx
index 247d5bb..f61eadf 100644
--- a/src/tabviews/zshare/actionList/popupbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/popupbutton/index.jsx
@@ -222,7 +222,17 @@
       MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.popClose, btn)
     }
 
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
+    if (btn.syncComponentId) {
+      if (btn.syncComponentId === 'multiComponent') {
+        btn.syncComponentIds.forEach((id, i) => {
+          setTimeout(() => {
+            MKEmitter.emit('reloadData', id)
+          }, 20 * i)
+        })
+      } else {
+        MKEmitter.emit('reloadData', btn.syncComponentId)
+      }
+    }
   }
 
   getPop = () => {
diff --git a/src/tabviews/zshare/fileupload-pice/index.jsx b/src/tabviews/zshare/fileupload-pice/index.jsx
deleted file mode 100644
index fc6b969..0000000
--- a/src/tabviews/zshare/fileupload-pice/index.jsx
+++ /dev/null
@@ -1,491 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { is, fromJS } from 'immutable'
-import moment from 'moment'
-import { Upload, Button, Progress, notification } from 'antd'
-import { UploadOutlined } from '@ant-design/icons'
-import SparkMD5 from 'spark-md5'
-import Api from '@/api'
-import './index.scss'
-
-class FileUpload extends Component {
-  static propTpyes = {
-    config: PropTypes.object,  // 琛ㄥ崟淇℃伅
-    onChange: PropTypes.func,  // 琛ㄥ崟鍙樺寲
-  }
-
-  state = {
-    percent: 0,
-    accept: '',
-    accepts: null,
-    maxFile: null,
-    rduri: '',
-    limit: 2,
-    compress: false,
-    fileType: 'text',
-    showprogress: false,
-    filelist: []
-  }
-
-  UNSAFE_componentWillMount () {
-    const { config } = this.props
-
-    let filelist = []
-    if (config.initval) {
-      if (/^data:image/.test(config.initval)) {
-        filelist = [{
-          uid: '0',
-          name: 'data:image/jpeg;base64',
-          status: 'done',
-          url: config.initval,
-          origin: true
-        }]
-      } else {
-        try {
-          filelist = config.initval.split(',').map((url, index) => {
-            return {
-              uid: `${index}`,
-              name: url.slice(url.lastIndexOf('/') + 1),
-              status: 'done',
-              url: url,
-              origin: true
-            }
-          })
-        } catch (e) {
-          filelist = []
-        }
-      }
-    }
-
-    let accept = ''
-    let accepts = null
-    let compress = false
-    let maxFile = config.maxfile && config.maxfile > 0 ? config.maxfile : null
-    if (config.compress === 'true' || config.compress === 'base64') {
-      compress = true
-      accepts = ['.jpg', '.png', '.gif', '.jpeg']
-      accept = accepts.join(',')
-      if (config.compress === 'base64') {
-        maxFile = 1
-      }
-    } else if (config.suffix) {
-      accepts = config.suffix.split(',').map(item => {
-        if (!/^\./ig.test(item)) {
-          item = '.' + item
-        }
-        return item
-      })
-      accept = accepts.join(',')
-    }
-    let rduri = config.rduri || ''
-    
-    if (window.GLOB.systemType === 'production') {
-      rduri = config.proRduri || ''
-    }
-
-    this.setState({
-      rduri,
-      accept,
-      accepts,
-      filelist,
-      compress,
-      limit: config.limit || 2,
-      maxFile: maxFile,
-      fileType: config.fileType || 'text'
-    })
-  }
-
-  shouldComponentUpdate (nextProps, nextState) {
-    return !is(fromJS(this.state), fromJS(nextState))
-  }
-
-  onChange = ({ fileList }) => {
-    fileList = fileList.map(item => {
-      if (item.status === 'error' && /^<!DOCTYPE html>/.test(item.response)) {
-        item.response = ''
-      }
-      return item
-    })
-
-    this.setState({filelist: fileList})
-  }
-
-  onRemove = file => {
-    const files = this.state.filelist.filter(v => v.uid !== file.uid)
-
-    this.setState({filelist: files})
-
-    let vals = []
-
-    files.forEach(item => {
-      if (item.origin && item.url) {
-        vals.push(item.url)
-      } else if (!item.origin && item.status === 'done' && item.response) {
-        vals.push(item.response)
-      }
-    })
-
-    this.props.onChange(vals.join(','))
-  }
-
-  onUpdate = (url) => {
-    let filelist = fromJS(this.state.filelist).toJS()
-
-    if (filelist[filelist.length -1]) {
-      filelist[filelist.length -1].status = 'done'
-      filelist[filelist.length -1].response = url
-      filelist[filelist.length -1].origin = false
-    }
-
-    filelist = filelist.filter(item => !!(item.url || item.response))
-
-    let vals = []
-
-    filelist.forEach(item => {
-      if (item.origin && item.url) {
-        vals.push(item.url)
-      } else if (!item.origin && item.status === 'done' && item.response) {
-        vals.push(item.response)
-      }
-    })
-
-    this.setState({filelist})
-    this.props.onChange(vals.join(','))
-  }
-
-  onFail = (msg) => {
-    let filelist = this.state.filelist.map(item => {
-      if (!item.url && !item.response && !item.status) {
-        item.status = 'error'
-      }
-      return item
-    })
-
-    this.setState({filelist, showprogress: false, percent: 0})
-
-    notification.warning({
-      top: 92,
-      message: msg || '鏂囦欢涓婁紶澶辫触锛�',
-      duration: 5
-    })
-  }
-
-  shardupload = (params) => {
-    let param = params.chunks.shift()
-    let form = new FormData()
-
-    form.append('file', param.binary)
-    form.append('fileMd5', params.file.fileMd5)
-    form.append('shardingMd5', param.chunkMd5)
-    form.append('baseDomain', window.GLOB.baseurl)
-    form.append('rootPath', 'Content/images/upload/')
-    form.append('fileName', params.file.fileName)
-    form.append('fileExt', params.file.fileType)
-    form.append('shardingCnt', param.chunks)
-    form.append('shardingNo', param.chunk)
-    form.append('LoginUID', sessionStorage.getItem('LoginUID') || '')
-    form.append('UserID', sessionStorage.getItem('UserID') || '')
-
-    Api.getLargeFileUpload(form).then(res => {
-      if (res.status) {
-        if (params.chunks.length > 0) {
-          this.setState({
-            percent: Math.floor(100 * (param.chunk / param.chunks))
-          })
-          this.shardupload(params)
-        } else {
-          if (res.urlPath) {
-            this.onUpdate(res.urlPath)
-          } else {
-            this.onFail()
-          }
-          this.setState({
-            percent: 100
-          }, () => {
-            setTimeout(() => {
-              this.setState({
-                showprogress: false,
-                percent: 0
-              })
-            }, 200)
-          })
-        }
-      } else {
-        this.onFail(res.message)
-      }
-    })
-  }
-
-  getuuid = () => {
-    let uuid = []
-    let _options = '0123456789abcdefghigklmnopqrstuv'
-    for (let i = 0; i < 19; i++) {
-      uuid.push(_options.substr(Math.floor(Math.random() * 0x20), 1))
-    }
-    uuid = uuid.join('')
-    return uuid
-  }
-
-  beforeUpload = (file) => {
-    const { accepts, compress, limit, rduri } = this.state
-
-    if (accepts && file.name) {
-      let pass = false
-      accepts.forEach(type => {
-        if (new RegExp(type + '$', 'ig').test(file.name)) {
-          pass = true
-        }
-      })
-      
-      if (!pass) {
-        setTimeout(() => {
-          this.onFail('鏂囦欢鏍煎紡閿欒锛�')
-        }, 10)
-        return false
-      }
-    }
-
-    this.setState({
-      showprogress: true,
-      percent: 0
-    })
-
-    if (compress) {
-      let reader = new FileReader()
-      let fileSize = file.size / 1024 / 1024
-      let compressRate = 0.9
-
-      if (fileSize / limit > 5) {
-        compressRate = 0.4
-      } else if (fileSize / limit > 4) {
-        compressRate = 0.5
-      } else if (fileSize / limit > 3) {
-        compressRate = 0.6
-      } else if (fileSize / limit > 2) {
-        compressRate = 0.7
-      } else if (fileSize > limit) {
-        compressRate = 0.8
-      }
-
-      reader.onload = (e) => {
-        let img = new Image()
-        let maxW = 640
- 
-        img.onload = () => {
-          let cvs = document.createElement( 'canvas')
-          let ctx = cvs.getContext( '2d')
-    
-          if (img.width > maxW) {
-            img.height *= maxW / img.width
-            img.width = maxW
-          }
-  
-          cvs.width = img.width
-          cvs.height = img.height
-  
-          ctx.clearRect(0, 0, cvs.width, cvs.height)
-          ctx.drawImage(img, 0, 0, img.width, img.height)
-
-          let param = {Base64Img: cvs.toDataURL('image/jpeg', compressRate)}
-
-          if (this.props.config.compress === 'base64') {
-            this.onUpdate(param.Base64Img)
-  
-            this.setState({
-              percent: 100
-            }, () => {
-              setTimeout(() => {
-                this.setState({
-                  showprogress: false,
-                  percent: 0
-                })
-              }, 200)
-            })
-          } else {
-            if (rduri) {
-              param.rduri = rduri
-            }
-  
-            Api.fileuploadbase64(param).then(result => {
-              if (result.status && result.Images) {
-                let url = window.GLOB.baseurl + result.Images
-  
-                if (rduri) {
-                  url = rduri.replace(/webapi(.*)$/, '') + result.Images
-                }
-  
-                this.onUpdate(url)
-  
-                this.setState({
-                  percent: 100
-                }, () => {
-                  setTimeout(() => {
-                    this.setState({
-                      showprogress: false,
-                      percent: 0
-                    })
-                  }, 200)
-                })
-              } else {
-                this.onFail(result.message)
-              }
-            })
-          }
-        }
-
-        img.onerror = () => {
-          this.onFail('鍥剧墖璇诲彇澶辫触锛�')
-        }
-    
-        img.src = e.target.result
-      }
-
-      reader.onerror = () => {
-        this.onFail('鏂囦欢璇诲彇澶辫触锛�')
-      }
-
-      reader.readAsDataURL(file)
-      return false
-    }
-
-    // 鍏煎鎬х殑澶勭悊
-    let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
-    let chunkSize = 1024 * 1024 * 2                // 鍒囩墖姣忔2M
-    let chunks = Math.ceil(file.size / chunkSize)  // 鍒囩墖鎬绘暟
-    let currentChunk = 0                           // 褰撳墠涓婁紶鐨刢hunk
-    let spark = new SparkMD5.ArrayBuffer()         // 瀵筧rrayBuffer鏁版嵁杩涜md5鍔犲瘑锛屼骇鐢熶竴涓猰d5瀛楃涓�
-    let chunkFileReader = new FileReader()         // 鐢ㄤ簬璁$畻鍑烘瘡涓猚hunkMd5
-    let totalFileReader = new FileReader()         // 鐢ㄤ簬璁$畻鍑烘�绘枃浠剁殑fileMd5
-    let params = {chunks: [], file: {}}            // 鐢ㄤ簬涓婁紶鎵�鏈夊垎鐗囩殑md5淇℃伅
-
-    params.file.fileName = file.name.replace(/\.{1}[^.]*$/ig, '')  // 鏂囦欢鍚嶏紙鍘婚櫎鍚庣紑鍚嶏級
-    params.file.fileType = file.name.replace(/^.*\.{1}/ig, '')     // 鏂囦欢绫诲瀷
-    params.file.fileSize = file.size                               // 鏂囦欢澶у皬
-    params.file.fileChunks = chunks                                // 璁板綍鎵�鏈塩hunks鐨勯暱搴�
-
-    if (!/^[A-Za-z0-9]+$/.test(params.file.fileName)) {            // 鏂囦欢鍚嶇О鍚湁鑻辨枃鍙婃暟瀛椾箣澶栧瓧绗︽椂锛屽悕绉扮郴缁熺敓鎴�
-      params.file.fileName = moment().format('YYYYMMDDHHmmss') + this.getuuid()
-    }
-
-    totalFileReader.readAsArrayBuffer(file)
-    totalFileReader.onload = (e) => {   // 瀵规暣涓猼otalFile鐢熸垚md5
-      spark.append(e.target.result)
-      params.file.fileMd5 = spark.end() // 璁$畻鏁翠釜鏂囦欢鐨刦ileMd5
-
-      let _param = new FormData()
-      _param.append('fileMd5', params.file.fileMd5)
-      
-      Api.getFilePreUpload(_param).then(res => {
-        if (res.status && res.urlPath) {
-          this.onUpdate(res.urlPath)
-          this.setState({
-            percent: 100
-          }, () => {
-            setTimeout(() => {
-              this.setState({
-                showprogress: false,
-                percent: 0
-              })
-            }, 200)
-          })
-        } else if (res.shardings && res.shardings.length > 0) {
-          res.shardings.forEach(shard => {
-            if (shard.shardingNo && parseInt(shard.shardingNo) > currentChunk) {
-              currentChunk = parseInt(shard.shardingNo)
-            }
-          })
-          loadNext()
-        } else {
-          loadNext()
-        }
-      })
-    }
-
-    chunkFileReader.onload = (e) => {
-      spark.append(e.target.result)      // 瀵规瘡涓�鐗囧垎鐗囪繘琛宮d5鍔犲瘑
-      
-      params.chunks[params.chunks.length - 1].chunkMd5 = spark.end() // 娣诲姞鍒囩墖md5
-      
-      currentChunk++  // 姣忎竴娆″垎鐗噊nload,currentChunk閮介渶瑕佸鍔狅紝浠ヤ究鏉ヨ绠楀垎鐗囩殑娆℃暟
-
-      if (currentChunk < chunks) { // 褰撳墠鍒囩墖鎬绘暟娌℃湁杈惧埌鎬绘暟鏃�
-        loadNext()
-      } else {
-        this.shardupload(params)
-      }
-    }
-
-    chunkFileReader.onerror = () => {
-      this.onFail('鏂囦欢璇诲彇澶辫触锛�')
-    }
-    totalFileReader.onerror = () => {
-      this.onFail('鏂囦欢璇诲彇澶辫触锛�')
-    }
-
-    let loadNext = () => {
-      let start = currentChunk * chunkSize              // 璁$畻鍒嗙墖鐨勮捣濮嬩綅缃�
-      let end = Math.min(file.size, start + chunkSize)  // 璁$畻鍒嗙墖鐨勭粨鏉熶綅缃�
-
-      let obj = {                                       // 姣忎竴涓垎鐗囬渶瑕佸寘鍚殑淇℃伅
-        chunk: currentChunk + 1,
-        binary: file.slice(start, end),
-        start: start,
-        end: end,
-        chunks
-      }
-
-      params.chunks.push(obj)
-      chunkFileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
-    }
-
-    return false
-  }
-
-  /**
-   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
-   */
-  componentWillUnmount () {
-    this.setState = () => {
-      return
-    }
-  }
-
-  render() {
-    const { showprogress, percent, filelist, maxFile, fileType, accept } = this.state
-
-    let uploadable = 'fileupload-form-container '
-
-    if (maxFile && filelist.length >= maxFile) {
-      uploadable += 'limit-fileupload'
-    }
-
-    const props = {
-      name: 'file',
-      disabled: showprogress,
-      listType: fileType,
-      fileList: filelist,
-      action: null,
-      accept: accept,
-      method: 'post',
-      multiple: false,
-      onChange: this.onChange,
-      onRemove: this.onRemove,
-      beforeUpload: this.beforeUpload,
-      className: uploadable
-    }
-
-    return (
-      <Upload {...props}>
-        {fileType !== 'picture-card' ? <Button>
-          <UploadOutlined /> 鐐瑰嚮涓婁紶
-        </Button> : null}
-        {fileType === 'picture-card' ? <span style={{whiteSpace: 'nowrap'}}>
-          <UploadOutlined /> 鐐瑰嚮涓婁紶
-        </span> : null}
-        {showprogress ? <Progress percent={percent} size="small" /> : null}
-      </Upload>
-    )
-  }
-}
-
-export default FileUpload
\ No newline at end of file
diff --git a/src/tabviews/zshare/fileupload-pice/index.scss b/src/tabviews/zshare/fileupload-pice/index.scss
deleted file mode 100644
index 86f8505..0000000
--- a/src/tabviews/zshare/fileupload-pice/index.scss
+++ /dev/null
@@ -1,53 +0,0 @@
-.fileupload-form-container {
-  .ant-progress-small.ant-progress-line {
-    position: absolute;
-    bottom: -20px;
-    left: 0px;
-  }
-
-  .ant-upload-select-picture-card {
-    .ant-progress-small.ant-progress-line {
-      bottom: 0px;
-    }
-  }
-  .ant-upload-list-picture-card-container {
-    width: 90px;
-    height: 90px;
-  }
-  // .ant-upload-list-picture-card .ant-upload-list-item-undefined {
-  //   border-color: #f5222d;
-  //   .ant-upload-list-item-name {
-  //     color: #f5222d;
-  //   }
-  // }
-  .ant-upload-list-picture-card .ant-upload-list-item {
-    width: 90px;
-    height: 90px;
-  }
-  .ant-upload.ant-upload-select-picture-card {
-    width: 90px;
-    height: 90px;
-  }
-  a[href^="data"] {
-    pointer-events: none;
-    .anticon-eye-o {
-      display: none;
-    }
-  }
-}
-.fileupload-form-container.limit-fileupload {
-  > .ant-upload {
-    display: inline;
-    >.ant-upload {
-      >input {
-        display: none;
-      }
-      >button {
-        display: none;
-      }
-    }
-  }
-  > .ant-upload-select-picture-card {
-    display: none;
-  }
-}
\ No newline at end of file
diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx
index 88e321e..067bfd2 100644
--- a/src/tabviews/zshare/mutilform/index.jsx
+++ b/src/tabviews/zshare/mutilform/index.jsx
@@ -546,9 +546,17 @@
       if (unload) return
       
       if (action.setting && action.setting.focus && fieldMap.has(action.setting.focus)) {
-        setTimeout(() => {
-          MKEmitter.emit('mkFC', 'focus', fieldMap.get(action.setting.focus).uuid)
-        }, 500)
+        let focusItem = fieldMap.get(action.setting.focus)
+
+        if (focusItem.type === 'text' || focusItem.type === 'number') {
+          setTimeout(() => {
+            MKEmitter.emit('mkFC', 'focus', focusItem.uuid)
+          }, 50)
+        } else {
+          setTimeout(() => {
+            MKEmitter.emit('mkFC', 'focus', focusItem.uuid)
+          }, 500)
+        }
       }
 
       if (deForms.length > 0) {
diff --git a/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx b/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx
index 154b7bd..a7dc070 100644
--- a/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx
+++ b/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Col, Row } from 'antd'
+import { Col, Row, Switch } from 'antd'
 import { CheckOutlined } from '@ant-design/icons'
 
 import MKEmitter from '@/utils/events.js'
@@ -281,6 +281,29 @@
     }
   }
 
+  onChange = (val) => {
+    if (val) {
+      let keys = []
+      this.state.options.forEach(item => {
+        if (item.$disabled) return
+
+        keys.push(item.$value)
+      })
+
+      this.setState({
+        selectKeys: keys
+      }, () => {
+        this.props.onChange(keys.join(','))
+      })
+    } else {
+      this.setState({
+        selectKeys: []
+      }, () => {
+        this.props.onChange('')
+      })
+    }
+  }
+
   render() {
     const { config, options } = this.state
 
@@ -289,9 +312,13 @@
     if (options.length * config.width > 24) {
       extend += ' mutile-line'
     }
+    if (config.border === 'hide') {
+      extend += ' border-hide'
+    }
 
     return (
       <div className={'check-card-form-box ' + extend}>
+        {config.checkAll === 'show' && options.length > 3 ? <Switch size="small" onChange={this.onChange}/> : null}
         <Row gutter={12}>{this.getCards()}</Row>
       </div>
     )
diff --git a/src/tabviews/zshare/mutilform/mkCheckCard/index.scss b/src/tabviews/zshare/mutilform/mkCheckCard/index.scss
index da3fdc4..7bb1021 100644
--- a/src/tabviews/zshare/mutilform/mkCheckCard/index.scss
+++ b/src/tabviews/zshare/mutilform/mkCheckCard/index.scss
@@ -1,11 +1,12 @@
 .check-card-form-box {
   margin-top: 5px;
+  position: relative;
   .card-cell {
     position: relative;
     border: 1px solid #bcbcbc;
     background: #ffffff;
     border-radius: 4px;
-    padding: 6px;
+    padding: 4px 6px;
     margin-bottom: 2px;
     line-height: 1.5;
     transition: all 0.3s;
@@ -109,9 +110,9 @@
     position: relative;
     border: 1px solid transparent;
     border-radius: 4px;
-    padding: 6px;
+    padding: 4px 6px;
     margin-bottom: 2px;
-    min-height: 35px;
+    min-height: 32px;
     cursor: pointer;
 
     .anticon-check {
@@ -133,6 +134,13 @@
     .anticon-check {
       display: inline-block;
     }
+  }
+
+  .ant-switch {
+    position: absolute;
+    top: -22px;
+    right: 0px;
+    opacity: 0.7;
   }
 
   .card-cell.disabled {
@@ -187,4 +195,9 @@
   .card-cell, .card-pic-cell {
     cursor: not-allowed;
   }
+}
+.check-card-form-box.border-hide {
+  .card-cell {
+    border: 0px;
+  }
 }
\ No newline at end of file
diff --git a/src/tabviews/zshare/topSearch/advanceform/index.scss b/src/tabviews/zshare/topSearch/advanceform/index.scss
index b16452d..b3cdf80 100644
--- a/src/tabviews/zshare/topSearch/advanceform/index.scss
+++ b/src/tabviews/zshare/topSearch/advanceform/index.scss
@@ -32,18 +32,6 @@
   .ant-calendar-picker-container {
     z-index: 10 !important;
   }
-  .check-card-form-box {
-    .no-margin-bottom {
-      margin-bottom: 0px;
-    }
-    .card-cell {
-      padding: 4px 6px;
-    }
-    .card-color-cell {
-      padding: 4px 6px;
-      min-height: 32px;
-    }
-  }
   .advance-button {
     position: absolute;
     left: 0;
diff --git a/src/tabviews/zshare/topSearch/index.jsx b/src/tabviews/zshare/topSearch/index.jsx
index 2ee1aaa..bdaf619 100644
--- a/src/tabviews/zshare/topSearch/index.jsx
+++ b/src/tabviews/zshare/topSearch/index.jsx
@@ -15,7 +15,7 @@
 import './index.scss'
 
 const MutilForm = asyncSpinComponent(() => import('./advanceform'))
-const MKCheckCard = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkCheckCard'))
+const MKCheckCard = asyncComponent(() => import('./mkCheckCard'))
 const MKCheck = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkCheck'))
 const MKSwitch = asyncComponent(() => import('@/tabviews/zshare/mutilform/mkSwitch'))
 const MKSelect = asyncComponent(() => import('./mkSelect'))
@@ -25,9 +25,7 @@
 class MainSearch extends Component {
   static propTpyes = {
     BID: PropTypes.any,          // 鐖剁骇Id锛岀敤浜庢煡璇笅鎷夐�夋嫨椤�
-    searchlist: PropTypes.array, // 鎼滅储鏉′欢鍒楄〃
     config: PropTypes.object,    // 缁勪欢閰嶇疆淇℃伅(鑷畾涔夐〉闈�)
-    setting: PropTypes.object,   // 缁勪欢閰嶇疆淇℃伅(鑷畾涔夐〉闈�)
     refreshdata: PropTypes.func  // 鍒锋柊鏁版嵁
   }
 
@@ -43,7 +41,7 @@
   sign = ''
 
   UNSAFE_componentWillMount () {
-    const { config, searchlist, setting } = this.props
+    const { config } = this.props
 
     let _searchlist = []
     let fieldMap = new Map()
@@ -56,43 +54,29 @@
     let hasReqFields = false
 
     let forbid = false // header涓笉璁剧疆楂樼骇鎼滅储
-    let _setting = {showAdv: false, show: false}
+    let _setting = {showAdv: false, show: false, style: null}
     
-    if (setting) {
-      _setting.show = setting.show !== 'false'
-      _setting.float = setting.float || 'left'
-      _setting.advanceType = setting.advanceType || 'modal'
-      _setting.advWidth = setting.advanceWidth || 1000
-      _setting.placement = setting.drawerPlacement || 'right'
-      _setting.ratio = setting.searchRatio || 6
-      _setting.labelwidth = setting.searchLwidth !== undefined ? setting.searchLwidth : 33.3
+    if (config.wrap) {
+      _setting.show = config.wrap.show !== 'false'
+      _setting.advanceType = config.wrap.advanceType || 'modal'
+      _setting.advWidth = config.wrap.advanceWidth || 1000
+      _setting.placement = config.wrap.drawerPlacement || 'right'
+      _setting.ratio = config.wrap.searchRatio || 6
+      _setting.labelwidth = config.wrap.searchLwidth !== undefined ? config.wrap.searchLwidth : 33.3
       _setting.labelCol = {style: {width: _setting.labelwidth + '%'}}
       _setting.wrapperCol = {style: {width: (100 - _setting.labelwidth) + '%'}}
-      _setting.style = null
-    } else if (config) {
-      if (config.wrap) {
-        _setting.show = config.wrap.show !== 'false'
-        _setting.advanceType = config.wrap.advanceType || 'modal'
-        _setting.advWidth = config.wrap.advanceWidth || 1000
-        _setting.placement = config.wrap.drawerPlacement || 'right'
-        _setting.ratio = config.wrap.searchRatio || 6
-        _setting.labelwidth = config.wrap.searchLwidth !== undefined ? config.wrap.searchLwidth : 33.3
-        _setting.labelCol = {style: {width: _setting.labelwidth + '%'}}
-        _setting.wrapperCol = {style: {width: (100 - _setting.labelwidth) + '%'}}
-        _setting.borderRadius = config.wrap.borderRadius
-      }
-      _setting.style = null
-      
-      if (config.type === 'search') {
-        _setting.float = config.wrap.float || 'left'
-        _setting.style = config.style
-      } else if (config.type === 'table') {
-        _setting.float = 'left'
-      } else {
-        _setting.float = 'right'
-        _setting.show = false
-        forbid = true
-      }
+      _setting.borderRadius = config.wrap.borderRadius
+    }
+    
+    if (config.type === 'search') {
+      _setting.float = config.wrap.float || 'left'
+      _setting.style = config.style
+    } else if (config.type === 'table') {
+      _setting.float = 'left'
+    } else {
+      _setting.float = 'right'
+      _setting.show = false
+      forbid = true
     }
 
     if (_setting.advanceType === 'drawer' && _setting.advWidth) {
@@ -110,11 +94,7 @@
       }
     }
 
-    if (searchlist) {
-      _searchlist = fromJS(searchlist).toJS()
-    } else if (config) {
-      _searchlist = fromJS(config.search).toJS()
-    }
+    _searchlist = fromJS(config.search).toJS()
 
     _searchlist.forEach(item => {
       if (item.linkField) {
@@ -176,6 +156,9 @@
 
         // 鏁版嵁婧愭煡璇㈣鍙�
         if (item.resourceType === '1' && item.dataSource) {
+          if (item.multiple === 'dropdown') {
+            item.parentField = 'pid'
+          }
           let _option = Utils.getSelectQueryOptions(item)
 
           if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
@@ -198,6 +181,10 @@
           }
         }
         item.oriOptions = fromJS(item.options).toJS()
+
+        if (item.type === 'checkcard' && item.multiple === 'dropdown' && item.resourceType === '0') {
+          this.resetCheckcard(item)
+        }
       }
 
       fieldMap.set(item.field, item)
@@ -243,6 +230,37 @@
         this.improveSearch(mainItems, localItems)
       }
     })
+  }
+
+  resetCheckcard = (item) => {
+    let _options = []
+    let _others = []
+    item.oriOptions.forEach(op => {
+      if (op.pid === item.mark) {
+        _options.push(op)
+      } else {
+        _others.push(op)
+      }
+    })
+
+    _options = _options.map(op => {
+      op.children = []
+
+      _others = _others.filter(cell => {
+        if (cell.pid === op.$value) {
+          op.children.push(cell)
+          return false
+        }
+        return true
+      })
+
+      op.subIds = op.children.map(cell => cell.$value)
+
+      return op
+    })
+
+    item.oriOptions = _options
+    item.options = _options
   }
 
   // 鏌ヨ涓嬫媺鑿滃崟
@@ -452,6 +470,10 @@
         })
 
         item.oriOptions = [...item.oriOptions, ...options]
+
+        if (item.type === 'checkcard' && item.multiple === 'dropdown') {
+          this.resetCheckcard(item)
+        }
       }
 
       if (item.linkField) {
diff --git a/src/tabviews/zshare/topSearch/index.scss b/src/tabviews/zshare/topSearch/index.scss
index 6ac744d..0f226d7 100644
--- a/src/tabviews/zshare/topSearch/index.scss
+++ b/src/tabviews/zshare/topSearch/index.scss
@@ -42,18 +42,6 @@
       content: '*';
     }
   }
-  .check-card-form-box {
-    .no-margin-bottom {
-      margin-bottom: 0px;
-    }
-    .card-cell {
-      padding: 4px 6px;
-    }
-    .card-color-cell {
-      padding: 4px 6px;
-      min-height: 32px;
-    }
-  }
   .search-button {
     min-height: 55px;
     .ant-btn-link, .ant-btn-link:hover, .ant-btn-link:active{
diff --git a/src/tabviews/zshare/topSearch/mkCheckCard/index.jsx b/src/tabviews/zshare/topSearch/mkCheckCard/index.jsx
new file mode 100644
index 0000000..2d0caf5
--- /dev/null
+++ b/src/tabviews/zshare/topSearch/mkCheckCard/index.jsx
@@ -0,0 +1,336 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Col, Row, Dropdown, Menu } from 'antd'
+import { CheckOutlined } from '@ant-design/icons'
+
+import MKEmitter from '@/utils/events.js'
+import './index.scss'
+
+class MKCheckCard extends Component {
+  static propTpyes = {
+    config: PropTypes.object,
+    onChange: PropTypes.func
+  }
+
+  state = {
+    selectKeys: null,
+    config: null,
+    options: []
+  }
+
+  UNSAFE_componentWillMount() {
+    let config = fromJS(this.props.config).toJS()
+
+    let selectKeys = config.initval
+    let initlength = 0
+    if (config.multiple === 'true') {
+      selectKeys = config.initval ? config.initval.split(',') : []
+      initlength = selectKeys.length
+      selectKeys = this.filterVals(config.options, selectKeys)
+    }
+
+    if (!config.selectStyle && config.backgroundColor) {
+      config.selectStyle = 'custom'
+    } else if (!config.selectStyle) {
+      config.selectStyle = 'background'
+    }
+
+    if (config.display === 'picture' && !config.picratio) { // 鍏煎鏃ф暟鎹�
+      config.picratio = config.ratio || '1:1'
+    }
+
+    config.selectClass = ` mk-${config.selectStyle} `
+    config.fields = config.fields || []
+
+    this.setState({
+      config: config,
+      options: fromJS(config.options).toJS(),
+      selectKeys: selectKeys
+    }, () => {
+      if (config.multiple === 'true' && selectKeys.length < initlength) {
+        this.props.onChange(selectKeys.join(','))
+      }
+    })
+  }
+
+  componentDidMount () {
+    const { config } = this.state
+
+    if (config.linkField) {
+      MKEmitter.addListener('mkFP', this.mkFormHandle)
+    }
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    const { config, selectKeys } = this.state
+
+    if (!is(fromJS(config.oriOptions), fromJS(nextProps.config.oriOptions))) {
+      if (config.multiple === 'true') {
+        let keys = this.filterVals(nextProps.config.options, fromJS(selectKeys).toJS())
+        if (keys.length < selectKeys.length) {
+          this.setState({
+            selectKeys: keys
+          }, () => {
+            this.props.onChange(keys.join(','))
+          })
+        }
+      }
+
+      this.setState({
+        config: {...config, oriOptions: nextProps.config.oriOptions},
+        options: fromJS(nextProps.config.options).toJS()
+      })
+    }
+  }
+
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+    MKEmitter.removeListener('mkFP', this.mkFormHandle)
+  }
+
+  filterVals = (options, vals) => {
+    if (options.length === 0 || vals.length === 0) return vals
+
+    let ops = options.map(item => item.$value)
+
+    vals = vals.filter(val => ops.includes(val))
+
+    return vals
+  }
+
+  mkFormHandle = (uuid, parentId, level) => {
+    if (uuid !== this.state.config.uuid) return
+
+    const { config } = this.state
+
+    let options = config.oriOptions.filter(option => option.ParentID === parentId)
+
+    if (config.multiple === 'true') {
+      this.setState({
+        options,
+        selectKeys: []
+      })
+      this.props.onChange('')
+    } else {
+      let _option = options[0] ? options[0] : null
+      let val = _option ? _option.$value : ''
+
+      this.setState({
+        options,
+        selectKeys: val
+      })
+  
+      let other = {}
+  
+      if (config.subFields && _option) {
+        config.subFields.forEach((n, i) => {
+          other[n.field] = _option[n.field]
+          setTimeout(() => {
+            MKEmitter.emit('mkFC', 'input', n.uuid, _option[n.field])
+          }, i * 5)
+        })
+      }
+  
+      this.props.onChange(val, other)
+  
+      if (level < 7 && config.linkFields) {
+        config.linkFields.forEach((m, i) => {
+          setTimeout(() => {
+            MKEmitter.emit('mkFP', m.uuid, val, level + 1)
+          }, (i + 1) * 70)
+        })
+      }
+    }
+  }
+
+  changeCard = (item) => {
+    const { selectKeys, config } = this.state
+
+    if (config.multiple === 'true') {
+      let keys = []
+      if (selectKeys.includes(item.$value)) {
+        keys = selectKeys.filter(key => key !== item.$value)
+      } else {
+        keys = [...selectKeys, item.$value]
+      }
+
+      this.setState({
+        selectKeys: keys
+      }, () => {
+        this.props.onChange(keys.join(','))
+      })
+    } else if (selectKeys !== item.$value) {
+      let other = {}
+      config.subFields && config.subFields.forEach((n, i) => {
+        other[n.field] = item[n.field]
+        setTimeout(() => {
+          MKEmitter.emit('mkFC', 'input', n.uuid, item[n.field])
+        }, i * 5)
+      })
+      config.linkFields && config.linkFields.forEach((m, i) => {
+        setTimeout(() => {
+          MKEmitter.emit('mkFP', m.uuid, item.$value, 0)
+        }, (i + 1) * 100)
+      })
+
+      this.setState({
+        selectKeys: item.$value
+      }, () => {
+        this.props.onChange(item.$value, other)
+      })
+    } else {
+      let other = {}
+      config.linkFields && config.linkFields.forEach((m, i) => {
+        setTimeout(() => {
+          MKEmitter.emit('mkFP', m.uuid, '', 0)
+        }, (i + 1) * 100)
+      })
+
+      this.setState({
+        selectKeys: ''
+      }, () => {
+        this.props.onChange('', other)
+      })
+    }
+  }
+
+  getCards = () => {
+    const { selectKeys, options, config } = this.state
+    const { display, width, fields, picratio, multiple, backgroundColor, selectStyle, selectClass } = config
+
+    if (options.length === 0) {
+      return null
+    } else if (display === 'color') {
+      return options.map(item => {
+        let _active = false
+        if (multiple === 'true') {
+          _active = selectKeys.includes(item.$value)
+        } else {
+          _active = selectKeys === item.$value
+        }
+
+        return <Col span={width} key={item.key}>
+          <div className={'card-color-cell' + (_active ? ' active' : '')} style={{background: item.$color}} onClick={() => this.changeCard(item)}>
+            {fields.map(col => {
+              return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
+            })}
+            <CheckOutlined />
+          </div>
+        </Col>
+      })
+    } else if (display === 'picture') {
+      let paddingTop = '100%'
+      if (picratio === '4:3') {
+        paddingTop = '75%'
+      } else if (picratio === '3:2') {
+        paddingTop = '66.7%'
+      } else if (picratio === '16:9') {
+        paddingTop = '56.25%'
+      }
+
+      return options.map(item => {
+        let _active = false
+        if (multiple === 'true') {
+          _active = selectKeys.includes(item.$value)
+        } else {
+          _active = selectKeys === item.$value
+        }
+
+        return <Col span={width} key={item.key}>
+          <div className={'card-pic-cell ' + (_active ? 'active' : '')} onClick={() => this.changeCard(item)} style={{paddingTop, backgroundImage: `url(${item.$url})`}}>
+            <div className="content-wrap">
+              <div className="content-center">
+                {fields.map(col => {
+                  return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
+                })}
+              </div>
+              <CheckOutlined />
+            </div>
+          </div>
+        </Col>
+      })
+    } else {
+      let _style = selectStyle === 'custom' ? {backgroundColor} : null
+
+      if (multiple === 'dropdown') {
+        return options.map(item => {
+          if (item.children.length) {
+            return <Col span={width} key={item.key}>
+              <Dropdown
+                overlayClassName="mk-search-card"
+                overlay={
+                <Menu>
+                  {item.children.map((cell, index) => (<Menu.Item className={selectKeys === cell.$value ? ' active' : ''} key={index} onClick={() => this.changeCard(cell)}>{cell[fields[0].field]}</Menu.Item>))}
+                </Menu>}
+                placement="bottomCenter"
+              >
+                <div className={'card-cell' + (selectKeys && (selectKeys === item.$value || item.subIds.includes(selectKeys)) ? ' active' : '') + selectClass} onClick={() => this.changeCard(item)}>
+                  <div className="bg-mask" style={_style}></div>
+                  {fields.map(col => {
+                    return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
+                  })}
+                </div>
+              </Dropdown>
+            </Col>
+
+          } else {
+            return <Col span={width} key={item.key}>
+              <div className={'card-cell' + (selectKeys === item.$value ? ' active' : '') + selectClass} onClick={() => this.changeCard(item)}>
+                <div className="bg-mask" style={_style}></div>
+                {fields.map(col => {
+                  return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
+                })}
+              </div>
+            </Col>
+          }
+        })
+      } else {
+        return options.map(item => {
+          let _active = false
+          if (multiple === 'true') {
+            _active = selectKeys.includes(item.$value)
+          } else {
+            _active = selectKeys === item.$value
+          }
+  
+          return <Col span={width} key={item.key}>
+            <div className={'card-cell' + (_active ? ' active' : '') + selectClass} onClick={() => this.changeCard(item)}>
+              <div className="bg-mask" style={_style}></div>
+              {fields.map(col => {
+                return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
+              })}
+            </div>
+          </Col>
+        })
+      }
+    }
+  }
+
+  render() {
+    const { config, options } = this.state
+
+    let extend = ''
+
+    if (options.length * config.width > 24) {
+      extend += ' mutile-line'
+    }
+    if (config.border === 'hide') {
+      extend += ' border-hide'
+    }
+
+    return (
+      <div className={'check-card-form-wrap ' + extend}>
+        <Row gutter={12}>{this.getCards()}</Row>
+      </div>
+    )
+  }
+}
+
+export default MKCheckCard
\ No newline at end of file
diff --git a/src/tabviews/zshare/topSearch/mkCheckCard/index.scss b/src/tabviews/zshare/topSearch/mkCheckCard/index.scss
new file mode 100644
index 0000000..e65f4c6
--- /dev/null
+++ b/src/tabviews/zshare/topSearch/mkCheckCard/index.scss
@@ -0,0 +1,188 @@
+.check-card-form-wrap {
+  margin-top: 5px;
+  .card-cell {
+    position: relative;
+    border: 1px solid #bcbcbc;
+    background: #ffffff;
+    border-radius: 4px;
+    padding: 4px 6px;
+    margin-bottom: 2px;
+    line-height: 1.5;
+    transition: all 0.3s;
+    cursor: pointer;
+    
+    .bg-mask {
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      opacity: 0.6;
+      border-radius: 4px;
+      background-color: transparent;
+      transition: opacity 0.3s;
+    }
+  }
+
+  .content-line {
+    display: block;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    position: relative;
+    z-index: 1;
+    line-height: 1.5;
+  }
+  .card-cell.mk-background.active {
+    border-color: var(--mk-sys-color);
+    background: var(--mk-sys-color);
+    span {
+      color: #ffffff!important;
+    }
+  }
+  .card-cell.mk-background.active::after {
+    content: ' ';
+    position: absolute;
+    display: table;
+    border: 2px solid #ffffff;
+    border-top: 0;
+    border-left: 0;
+    bottom: 0;
+    right: 10px;
+    width: 6px;
+    height: 12px;
+    transform: rotate(45deg) scale(1) translate(-50%, -50%);
+  }
+  .card-cell.mk-font.active {
+    border-color: var(--mk-sys-color);
+    span {
+      color: var(--mk-sys-color)!important;
+    }
+  }
+  .card-cell.mk-custom {
+    border-color: transparent;
+  }
+  .card-cell.mk-custom.active {
+    .bg-mask {
+      opacity: 1;
+    }
+  }
+  .card-pic-cell {
+    position: relative;
+    border: 1px solid #e8e8e8;
+    border-radius: 4px;
+    background-size: cover;
+    background-position: center;
+    margin-bottom: 2px;
+    line-height: 1.5;
+    cursor: pointer;
+    transition: all 0.3s;
+
+    .content-wrap {
+      position: absolute;
+      top: 6px;
+      left: 6px;
+      right: 6px;
+      bottom: 6px;
+      .content-center {
+        position: relative;
+        top: 50%;
+        transform: translate(0px, -50%);
+      }
+    }
+    .anticon-check {
+      display: none;
+      position: absolute;
+      color: #ffffff;
+      border-radius: 20px;
+      padding: 3px;
+      width: 18px;
+      height: 18px;
+      font-size: 12px;
+      right: -2px;
+      bottom: -2px;
+      background: var(--mk-sys-color);
+    }
+  }
+
+  .card-color-cell {
+    position: relative;
+    border: 1px solid transparent;
+    border-radius: 4px;
+    padding: 4px 6px;
+    margin-bottom: 2px;
+    min-height: 32px;
+    cursor: pointer;
+
+    .anticon-check {
+      display: none;
+      position: absolute;
+      color: #ffffff;
+      border-radius: 20px;
+      padding: 3px;
+      width: 18px;
+      height: 18px;
+      font-size: 12px;
+      right: 0px;
+      bottom: 0px;
+      background: var(--mk-sys-color);
+    }
+  }
+
+  .card-pic-cell.active, .card-color-cell.active {
+    .anticon-check {
+      display: inline-block;
+    }
+  }
+}
+
+.check-card-form-wrap.mutile-line {
+  .card-cell {
+    margin-bottom: 12px;
+  }
+  .card-pic-cell {
+    margin-bottom: 12px;
+  }
+  .card-color-cell {
+    margin-bottom: 12px;
+  }
+}
+
+.check-card-form-wrap {
+  .card-cell.mk-background:hover {
+    border-color: var(--mk-sys-color);
+    background: var(--mk-sys-color);
+    span {
+      color: #ffffff!important;
+    }
+  }
+  .card-cell.mk-font:hover {
+    border-color: var(--mk-sys-color);
+    span {
+      color: var(--mk-sys-color)!important;
+    }
+  }
+
+  .card-cell.mk-custom:not(.active):hover {
+    .bg-mask {
+      opacity: 0.8;
+    }
+  }
+  .card-pic-cell:hover {
+    border-color: var(--mk-sys-color);
+    box-shadow: 0px 0px 4px var(--mk-sys-color);
+  }
+}
+.check-card-form-wrap.border-hide {
+  .card-cell {
+    border: 0px;
+  }
+}
+.mk-search-card {
+  .ant-dropdown-menu-item {
+    min-width: 80px;
+  }
+  .ant-dropdown-menu-item.active {
+    color: var(--mk-sys-color);
+  }
+}
\ No newline at end of file
diff --git a/src/templates/comtableconfig/index.jsx b/src/templates/comtableconfig/index.jsx
index e55643e..44a0274 100644
--- a/src/templates/comtableconfig/index.jsx
+++ b/src/templates/comtableconfig/index.jsx
@@ -934,7 +934,7 @@
       }
     })
 
-    if ((config.setting.interType === 'system' || config.setting.requestMode === 'system') && config.setting.default === 'false' && config.setting.scripts && config.setting.scripts.filter(item => item.status !== 'false').length === 0) {
+    if (config.setting.interType === 'system' && config.setting.default === 'false' && config.setting.scripts && config.setting.scripts.filter(item => item.status !== 'false').length === 0) {
       return '鏁版嵁婧愪腑涓嶆墽琛岄粯璁ql锛屼笖鏈坊鍔犺嚜瀹氫箟鑴氭湰锛屼笉鍙惎鐢紒'
     } else if (config.setting.interType === 'custom' && config.setting.procMode !== 'inner' && config.setting.preScripts && config.setting.preScripts.filter(item => item.status !== 'false').length === 0) {
       return '鏁版嵁婧愭湭璁剧疆鍓嶇疆鑴氭湰锛屼笉鍙惎鐢紒'
diff --git a/src/templates/comtableconfig/updatetable/index.jsx b/src/templates/comtableconfig/updatetable/index.jsx
index e2a7d87..82d0052 100644
--- a/src/templates/comtableconfig/updatetable/index.jsx
+++ b/src/templates/comtableconfig/updatetable/index.jsx
@@ -694,6 +694,38 @@
     })
   }
 
+  checkBtns = (card) => {
+    card.action.forEach(cell => {
+      if (cell.hidden === 'true') return
+      if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+        if (!cell.modal || cell.modal.fields.length === 0) {
+          card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+        }
+      } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
+        card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
+      } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
+        card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
+      }
+    })
+
+    card.cols.forEach(col => {
+      if (col.type !== 'custom') return
+
+      col.elements.forEach(cell => {
+        if (cell.hidden === 'true' || cell.eleType !== 'button') return
+        if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+          if (!cell.modal || cell.modal.fields.length === 0) {
+            card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+          }
+        } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
+          card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
+        } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
+          card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
+        }
+      })
+    })
+  }
+
   submitConfig = (_resolve, config) => {
     let tbs = []
     config.components.forEach(item => {
@@ -702,11 +734,14 @@
           if (tab.components[0].$tables) {
             tbs.push(...tab.components[0].$tables)
           }
+
+          this.checkBtns(tab.components[0])
         })
       } else {
         if (item.$tables) {
           tbs.push(...item.$tables)
         }
+        this.checkBtns(item)
       }
     })
 
@@ -1118,27 +1153,29 @@
         popActions.push({origin: btn.uuid, linkTab: btn.linkTab || '', uuid: _btn.uuid, name: newCon.name, label: btn.label})
       } else if (_btn.OpenType === 'tab') {
         if (btn.tabTemplate === 'FormTab') {
-          if (newCon.isMain !== true) {
-            errors.push(newCon.name + '涓寜閽��' + btn.label + '銆嬩笉鍦ㄦ敮鎸�')
-            return
-          }
+          errors.push(newCon.name + '涓寜閽��' + btn.label + '銆嬩笉鍦ㄦ敮鎸�')
+          return
+          // if (newCon.isMain !== true) {
+          //   errors.push(newCon.name + '涓寜閽��' + btn.label + '銆嬩笉鍦ㄦ敮鎸�')
+          //   return
+          // }
 
-          delete _btn.tabTemplate
+          // delete _btn.tabTemplate
 
-          _btn.MenuID = 'tab' + md5(btn.uuid).substr(3)
-          _btn.MenuName = this.baseMsg.MenuName + '-' + btn.label
-          _btn.MenuNo = this.baseMsg.MenuNo + '_' + _btn.MenuID.substr(-4).toUpperCase()
-          _btn.hidden = _btn.hidden || 'false'
-          _btn.tabType = 'CustomPage'
-          _btn.linkmenu = [this.baseMsg.fstMenuId, this.baseMsg.parentId, _btn.MenuID]
+          // _btn.MenuID = 'tab' + md5(btn.uuid).substr(3)
+          // _btn.MenuName = this.baseMsg.MenuName + '-' + btn.label
+          // _btn.MenuNo = this.baseMsg.MenuNo + '_' + _btn.MenuID.substr(-4).toUpperCase()
+          // _btn.hidden = _btn.hidden || 'false'
+          // _btn.tabType = 'CustomPage'
+          // _btn.linkmenu = [this.baseMsg.fstMenuId, this.baseMsg.parentId, _btn.MenuID]
           
-          let _tab = {...btn}
+          // let _tab = {...btn}
 
-          _tab.MenuID = _btn.MenuID
-          _tab.MenuNo = _btn.MenuNo
-          _tab.MenuName = _btn.MenuName
+          // _tab.MenuID = _btn.MenuID
+          // _tab.MenuNo = _btn.MenuNo
+          // _tab.MenuName = _btn.MenuName
 
-          formTabs.push(_tab)
+          // formTabs.push(_tab)
         } else if (!btn.linkmenu || btn.linkmenu.length !== 3) {
 
           errors.push(newCon.name + '涓寜閽��' + btn.label + '銆嬩笉鍦ㄦ敮鎸�')
@@ -1229,36 +1266,6 @@
     } else if (!_card.setting.supModule) {
       _card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
     }
-
-    _card.action.forEach(cell => {
-      if (cell.hidden === 'true') return
-      if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-        if (!cell.modal || cell.modal.fields.length === 0) {
-          _card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-        }
-      } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-        _card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-      } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-        _card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-      }
-    })
-
-    _card.cols.forEach(col => {
-      if (col.type !== 'custom') return
-
-      col.elements.forEach(cell => {
-        if (cell.hidden === 'true' || cell.eleType !== 'button') return
-        if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-          if (!cell.modal || cell.modal.fields.length === 0) {
-            _card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
-          }
-        } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-          _card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-        } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-          _card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-        }
-      })
-    })
 
     return _card
   }
diff --git a/src/templates/modalconfig/checkCard/index.jsx b/src/templates/modalconfig/checkCard/index.jsx
index 558e172..0813fd3 100644
--- a/src/templates/modalconfig/checkCard/index.jsx
+++ b/src/templates/modalconfig/checkCard/index.jsx
@@ -25,7 +25,7 @@
     }
 
     let cls = ''
-    if (_options.length * width <= 24 && this.state.appType !== 'mob') {
+    if (_options.length * width <= 24) {
       cls = 'no-margin-bottom'
     }
     if (display === 'picture') {
@@ -104,8 +104,10 @@
   }
 
   render() {
+    const { config } = this.props
+    
     return (
-      <div className="check-card-edit-box" style={{marginTop: '5px'}}>
+      <div className={'check-card-edit-box border-' + (config.border || 'show')} style={{marginTop: '5px'}}>
         <Row gutter={12}>{this.getCards()}</Row>
       </div>
     )
diff --git a/src/templates/modalconfig/checkCard/index.scss b/src/templates/modalconfig/checkCard/index.scss
index 52cb625..4d08015 100644
--- a/src/templates/modalconfig/checkCard/index.scss
+++ b/src/templates/modalconfig/checkCard/index.scss
@@ -7,7 +7,7 @@
     position: relative;
     border: 1px solid #bcbcbc;
     border-radius: 4px;
-    padding: 6px;
+    padding: 4px 6px;
     margin-bottom: 12px;
     
     .bg-mask {
@@ -46,11 +46,11 @@
   .card-color-cell {
     border: 1px solid transparent;
     border-radius: 4px;
-    padding: 6px;
+    padding: 4px 6px;
     background-size: cover;
     background-position: center;
     margin-bottom: 12px;
-    min-height: 35px;
+    min-height: 32px;
   }
 
   .content-line {
@@ -64,4 +64,9 @@
   .no-margin-bottom {
     margin-bottom: 2px;
   }
+}
+.check-card-edit-box.border-hide {
+  .card-cell {
+    border: 0px;
+  }
 }
\ No newline at end of file
diff --git a/src/templates/sharecomponent/actioncomponent/actionform/index.jsx b/src/templates/sharecomponent/actioncomponent/actionform/index.jsx
index d3d1ea1..0661538 100644
--- a/src/templates/sharecomponent/actioncomponent/actionform/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/actionform/index.jsx
@@ -148,7 +148,7 @@
       reOptions.intertype = this.state.interTypeOptions
 
       if (intertype === 'custom') {
-        shows.push('procMode', 'interface', 'callbackType', 'proInterface', 'method', 'cross')
+        shows.push('procMode', 'interface', 'callbackType', 'proInterface', 'method', 'cross', 'stringify')
         if (this.record.procMode === 'system') {
           shows.push('sql', 'sqlType')
         } else if (this.record.procMode === 'inner') {
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
index 2895d40..837dd40 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
@@ -105,6 +105,7 @@
         }
         
         values.uuid = editItem ? editItem.uuid : ''
+        values.position = values.position || (editItem ? editItem.position : 'front')
 
         if (type === 'fullscreen' && editItem) {
           values.status = editItem.status || 'true'
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
index 85fbe84..a3460ed 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -498,7 +498,7 @@
     })
 
     if (reset) {
-      message.warn('鏁板�肩被鍨嬪潎涓哄繀濉��')
+      message.warning('鏁板�肩被鍨嬪潎涓哄繀濉��')
     }
 
     this.setState({verify: {...verify, columns}}, () => {
@@ -887,7 +887,7 @@
             <Form {...formItemLayout}>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> S </span>
                     <Button onClick={() => {this.showError('S')}} type="primary" size="small">
                       鏌ョ湅
@@ -895,14 +895,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.stime || 2} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'stime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> Y </span>
                     <Button onClick={() => {this.showError('Y')}} type="primary" size="small">
                       鏌ョ湅
@@ -912,7 +912,15 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -1 </span>
+                    鎵ц鎴愬姛鏃犳彁绀恒��
+                  </Form.Item>
+                </Col>
+              </Row>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> N </span>
                     <Button onClick={() => {this.showError('N')}} type="primary" size="small">
                       鏌ョ湅
@@ -920,14 +928,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.ntime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> F </span>
                     <Button onClick={() => {this.showError('F')}} type="primary" size="small">
                       鏌ョ湅
@@ -935,14 +943,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.ftime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> E </span>
                     <Button onClick={() => {this.showError('E')}} type="primary" size="small">
                       鏌ョ湅
@@ -952,7 +960,7 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> NM </span>
                     <Button onClick={() => {this.showError('NM')}} type="primary" size="small">
                       鏌ョ湅
@@ -962,9 +970,9 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
-                    <span className="errorval"> -1 </span>
-                    涓嶆彁绀�
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -2 </span>
+                    鎵ц澶辫触鏃犳彁绀�
                   </Form.Item>
                 </Col>
               </Row>
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
index cadda16..bf43e2c 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
@@ -114,8 +114,7 @@
     })
 
     this.props.form.setFieldsValue({
-      sql: record.sql,
-      // position: record.position || 'back'
+      sql: record.sql
     })
   }
 
@@ -271,43 +270,25 @@
       <Form {...formItemLayout} className="verify-form" id="verify-excelin-custom-scripts">
         <Row gutter={24}>
           <Col span={8}>
-            <Form.Item label={'琛ㄥ悕'} style={{whiteSpace: 'nowrap', margin: 0}}>
+            <Form.Item label="琛ㄥ悕" style={{whiteSpace: 'nowrap', margin: 0}}>
               {sheet}
             </Form.Item>
           </Col>
           <Col span={10}>
-            <Form.Item label={'鎶ラ敊瀛楁'} style={{margin: 0, whiteSpace: 'nowrap'}}>
+            <Form.Item label="鎶ラ敊瀛楁" style={{margin: 0, whiteSpace: 'nowrap'}}>
               ErrorCode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT锛�, retmsg
             </Form.Item>
           </Col>
           <Col span={24} className="sqlfield">
-            <Form.Item label={'鍙敤瀛楁'}>
+            <Form.Item label="鍙敤瀛楁">
               <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id, typename</span></Tooltip>,&nbsp;
               <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address</span></Tooltip>
               {usefulfields ? <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鎼滅储鏉′欢锛岃鎸夌収@xxx@鏍煎紡浣跨敤銆�'}>,&nbsp;{usefulfields}</Tooltip> : null}
               {linefields ? <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'琛ㄥ崟鍙婅鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}>,&nbsp;{linefields}</Tooltip> : null}
             </Form.Item>
           </Col>
-          {/* <Col span={8} style={{whiteSpace: 'nowrap'}}>
-            <Form.Item style={{marginBottom: 0}} label={
-              <Tooltip placement="bottomLeft" title={'鑷畾涔夎剼鏈笌榛樿sql浣嶇疆鍏崇郴銆�'}>
-                <QuestionCircleOutlined className="mk-form-tip" />
-                鎵ц浣嶇疆
-              </Tooltip>
-            }>
-              {getFieldDecorator('position', {
-                initialValue: 'front'
-              })(
-                <Radio.Group>
-                  <Radio value="init">鍒濆鍖�</Radio>
-                  <Radio value="front">sql鍓�</Radio>
-                  <Radio value="back">sql鍚�</Radio>
-                </Radio.Group>
-              )}
-            </Form.Item>
-          </Col> */}
           <Col span={8}>
-            <Form.Item style={{marginBottom: 0}} label={'蹇嵎娣诲姞'}>
+            <Form.Item style={{marginBottom: 0}} label="蹇嵎娣诲姞">
               <Select
                 showSearch
                 filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
@@ -337,7 +318,7 @@
             </Button>
           </Col>
           <Col span={24} className="sql">
-            <Form.Item label={'sql'}>
+            <Form.Item label="sql">
               {getFieldDecorator('sql', {
                 initialValue: '',
                 rules: [
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
index 5421c48..86d94de 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -1157,7 +1157,7 @@
             <Form {...formItemLayout}>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> S </span>
                     <Button onClick={() => {this.showError('S')}} type="primary" size="small">
                       鏌ョ湅
@@ -1165,14 +1165,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.stime || 2} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'stime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> Y </span>
                     <Button onClick={() => {this.showError('Y')}} type="primary" size="small">
                       鏌ョ湅
@@ -1182,7 +1182,15 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -1 </span>
+                    鎵ц鎴愬姛鏃犳彁绀恒��
+                  </Form.Item>
+                </Col>
+              </Row>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> N </span>
                     <Button onClick={() => {this.showError('N')}} type="primary" size="small">
                       鏌ョ湅
@@ -1190,14 +1198,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.ntime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> F </span>
                     <Button onClick={() => {this.showError('F')}} type="primary" size="small">
                       鏌ョ湅
@@ -1205,14 +1213,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.ftime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> E </span>
                     <Button onClick={() => {this.showError('E')}} type="primary" size="small">
                       鏌ョ湅
@@ -1222,7 +1230,7 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> NM </span>
                     <Button onClick={() => {this.showError('NM')}} type="primary" size="small">
                       鏌ョ湅
@@ -1232,9 +1240,9 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
-                    <span className="errorval"> -1 </span>
-                    涓嶆彁绀�
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -2 </span>
+                    鎵ц澶辫触鏃犳彁绀�
                   </Form.Item>
                 </Col>
               </Row>
diff --git a/src/templates/sharecomponent/actioncomponent/verifymegvii/index.jsx b/src/templates/sharecomponent/actioncomponent/verifymegvii/index.jsx
index bc04f46..e238cf8 100644
--- a/src/templates/sharecomponent/actioncomponent/verifymegvii/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifymegvii/index.jsx
@@ -156,7 +156,7 @@
             <Form {...formItemLayout}>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> S </span>
                     <Button onClick={() => {this.showError('S')}} type="primary" size="small">
                       鏌ョ湅
@@ -164,14 +164,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.stime || 2} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'stime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> Y </span>
                     <Button onClick={() => {this.showError('Y')}} type="primary" size="small">
                       鏌ョ湅
@@ -181,7 +181,15 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -1 </span>
+                    鎵ц鎴愬姛鏃犳彁绀恒��
+                  </Form.Item>
+                </Col>
+              </Row>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> N </span>
                     <Button onClick={() => {this.showError('N')}} type="primary" size="small">
                       鏌ョ湅
@@ -189,14 +197,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.ntime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> F </span>
                     <Button onClick={() => {this.showError('F')}} type="primary" size="small">
                       鏌ョ湅
@@ -204,14 +212,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.ftime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> E </span>
                     <Button onClick={() => {this.showError('E')}} type="primary" size="small">
                       鏌ョ湅
@@ -221,7 +229,7 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> NM </span>
                     <Button onClick={() => {this.showError('NM')}} type="primary" size="small">
                       鏌ョ湅
@@ -231,9 +239,9 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
-                    <span className="errorval"> -1 </span>
-                    涓嶆彁绀�
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -2 </span>
+                    鎵ц澶辫触鏃犳彁绀�
                   </Form.Item>
                 </Col>
               </Row>
diff --git a/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
index 6dbc194..90ff096 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
@@ -932,7 +932,7 @@
             <Form {...formItemLayout}>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> S </span>
                     <Button onClick={() => {this.showError('S')}} type="primary" size="small">
                       鏌ョ湅
@@ -940,14 +940,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.stime || 2} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'stime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> Y </span>
                     <Button onClick={() => {this.showError('Y')}} type="primary" size="small">
                       鏌ョ湅
@@ -957,7 +957,15 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -1 </span>
+                    鎵ц鎴愬姛鏃犳彁绀恒��
+                  </Form.Item>
+                </Col>
+              </Row>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> N </span>
                     <Button onClick={() => {this.showError('N')}} type="primary" size="small">
                       鏌ョ湅
@@ -965,14 +973,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.ntime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> F </span>
                     <Button onClick={() => {this.showError('F')}} type="primary" size="small">
                       鏌ョ湅
@@ -980,14 +988,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.ftime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> E </span>
                     <Button onClick={() => {this.showError('E')}} type="primary" size="small">
                       鏌ョ湅
@@ -997,7 +1005,7 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> NM </span>
                     <Button onClick={() => {this.showError('NM')}} type="primary" size="small">
                       鏌ョ湅
@@ -1007,9 +1015,9 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
-                    <span className="errorval"> -1 </span>
-                    涓嶆彁绀�
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -2 </span>
+                    鎵ц澶辫触鏃犳彁绀�
                   </Form.Item>
                 </Col>
               </Row>
diff --git a/src/templates/sharecomponent/searchcomponent/index.scss b/src/templates/sharecomponent/searchcomponent/index.scss
index 9ba3f42..3b00b21 100644
--- a/src/templates/sharecomponent/searchcomponent/index.scss
+++ b/src/templates/sharecomponent/searchcomponent/index.scss
@@ -66,18 +66,6 @@
           padding: 4px 20px 4px 5px;
           font-size: 13px;
         }
-        .check-card-edit-box {
-          .no-margin-bottom {
-            margin-bottom: 0px;
-          }
-          .card-cell {
-            padding: 4px 6px;
-          }
-          .card-color-cell {
-            padding: 4px 6px;
-            min-height: 32px;
-          }
-        }
       }
       .ant-form-explain {
         display: none;
diff --git a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
index 95350b6..62e41e1 100644
--- a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
@@ -119,11 +119,7 @@
   }
 
   state = {
-    openType: null,          // 鎼滅储鏉′欢鏄剧ず绫诲瀷
-    resourceType: null,      // 涓嬫媺鎼滅储鏃讹紝閫夐」鏉ユ簮绫诲瀷
-    formlist: null,          // 琛ㄥ崟
-    cFields: [],
-    textTooltip: '瀛楁鍚嶅彲浠ヤ娇鐢ㄩ�楀彿鍒嗛殧锛岃繘琛岀患鍚堟悳绱�',
+    formlist: null
   }
 
   record = {}
@@ -207,12 +203,15 @@
       } else {
         reRequired.fields = true
         if (this.record.resourceType === '0') {        // 鑷畾涔夎祫婧�
-          shows.push('options', 'fields', 'selectStyle')
+          shows.push('options', 'fields', 'selectStyle', 'border')
         } else if (this.record.resourceType === '1') { // 鏁版嵁婧�
-          shows.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'database', 'selectStyle')
+          shows.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'database', 'selectStyle', 'border')
         }
         if (this.record.selectStyle === 'custom') {
           shows.push('backgroundColor')
+        }
+        if (this.record.multiple === 'dropdown') {
+          shows.push('mark')
         }
       }
       shows.push('linkField')
@@ -487,7 +486,7 @@
             <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />
           </AutoComplete>
         } else {
-          content = <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />
+          content = <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} onChange={(e) => {this.optionChange(item.key, e.target.value)}}/>
         }
       } else if (item.type === 'number') {
         rules = [
@@ -554,7 +553,7 @@
           if (this.record.linkField) {
             type = 'link'
           }
-          content = <DataTable type={type} display={this.record.display} linkSubFields={[]} transfield={{}} fields={this.record.fields || []} onChange={this.changeOptions}/>
+          content = <DataTable type={type} multiple={this.record.multiple} display={this.record.display} linkSubFields={[]} transfield={{}} fields={this.record.fields || []} onChange={this.changeOptions}/>
         }
       } else if (item.type === 'fields') {
         span = 24
@@ -665,10 +664,15 @@
               values.options = []
             }
           } else if (values.type === 'checkcard') {
+            if (values.multiple === 'dropdown' && values.display !== 'text') {
+              values.multiple = 'false'
+            }
+
             if (values.resourceType === '0') {
               values.options = values.options || []
               values.options = values.options.map(m => {
                 m.ParentID = m.ParentID || ''
+                m.pid = m.pid || ''
                 return m
               })
 
diff --git a/src/templates/sharecomponent/tablecomponent/index.jsx b/src/templates/sharecomponent/tablecomponent/index.jsx
index 540dee1..15954e3 100644
--- a/src/templates/sharecomponent/tablecomponent/index.jsx
+++ b/src/templates/sharecomponent/tablecomponent/index.jsx
@@ -8,6 +8,7 @@
 import Api from '@/api'
 import options from '@/store/options.js'
 import Utils from '@/utils/utils.js'
+import MKEmitter from '@/utils/events.js'
 import { queryTableSql } from '@/utils/option.js'
 
 import './index.scss'
@@ -33,15 +34,28 @@
   UNSAFE_componentWillMount () {
     const { config } = this.props
 
+    let tables = config.tables ? fromJS(config.tables).toJS() : []
+
+    window.GLOB.publicTables = tables
+
     this.setState({
-      selectedTables: config.tables ? fromJS(config.tables).toJS() : []
+      selectedTables: tables
     }, () => {
       this.gettableFields()
     })
   }
 
   componentDidMount () {
+    MKEmitter.addListener('publicTableChange', this.publicTableChange)
     this.gettables()
+  }
+
+  publicTableChange = (table, type) => {
+    if (type === 'plus') {
+      this.onTableChange(table)
+    } else if (type === 'del') {
+      this.deleteTable(table)
+    }
   }
 
   /**
@@ -170,11 +184,15 @@
     let _table = tables.filter(item => item.TbName === value)[0]
     let isSelected = !!selectedTables.filter(cell => cell.TbName === value)[0]
     if (!isSelected) {
+      let _tables = [...selectedTables, _table]
+
+      window.GLOB.publicTables = _tables
+
       this.setState({
-        selectedTables: [...selectedTables, _table]
+        selectedTables: _tables
       })
 
-      let _config = {...config, tables: [...selectedTables, _table]}
+      let _config = {...config, tables: _tables}
       
       Api.getSystemConfig({func: 'sPC_Get_FieldName', TBName: value}).then(res => {
         if (res.status) {
@@ -248,6 +266,8 @@
     let _tables = selectedTables.filter(item => item.TbName !== table.TbName)
     let _fields = tableFields.filter(item => item.tableName !== table.TbName)
 
+    window.GLOB.publicTables = _tables
+
     this.setState({
       selectedTables: _tables,
       tableFields: _fields
@@ -265,6 +285,7 @@
     this.setState = () => {
       return
     }
+    MKEmitter.removeListener('publicTableChange', this.publicTableChange)
   }
 
   render() {
@@ -276,7 +297,7 @@
         {/* 琛ㄥ悕娣诲姞 */}
         <div className="ant-col ant-form-item-label">
           <label>
-            <Tooltip placement="topLeft" title="姝ゅ鍙互娣诲姞椤甸潰閰嶇疆鐩稿叧鐨勫父鐢ㄨ〃锛屽彲閫氳繃宸ュ叿鏍忎腑鐨勬坊鍔犳寜閽紝鍙壒閲忔坊鍔犺〃鏍肩浉鍏冲瓧娈点��">
+            <Tooltip placement="topLeft" title="姝ゅ鍙互娣诲姞椤甸潰閰嶇疆鐩稿叧鐨勫父鐢ㄨ〃銆�">
               <QuestionCircleOutlined className="mk-form-tip" />
               琛ㄥ悕
             </Tooltip>
diff --git a/src/templates/subtableconfig/index.jsx b/src/templates/subtableconfig/index.jsx
index 524b4f1..19bfb12 100644
--- a/src/templates/subtableconfig/index.jsx
+++ b/src/templates/subtableconfig/index.jsx
@@ -784,7 +784,7 @@
       }
     })
 
-    if ((config.setting.interType === 'system' || config.setting.requestMode === 'system') && config.setting.default === 'false' && config.setting.scripts && config.setting.scripts.filter(item => item.status !== 'false').length === 0) {
+    if (config.setting.interType === 'system' && config.setting.default === 'false' && config.setting.scripts && config.setting.scripts.filter(item => item.status !== 'false').length === 0) {
       return '鏁版嵁婧愪腑涓嶆墽琛岄粯璁ql锛屼笖鏈坊鍔犺嚜瀹氫箟鑴氭湰锛屼笉鍙惎鐢紒'
     } else if (config.setting.interType === 'custom' && config.setting.procMode !== 'inner' && config.setting.preScripts && config.setting.preScripts.filter(item => item.status !== 'false').length === 0) {
       return '鏁版嵁婧愭湭璁剧疆鍓嶇疆鑴氭湰锛屼笉鍙惎鐢紒'
diff --git a/src/templates/zshare/editTable/index.jsx b/src/templates/zshare/editTable/index.jsx
index e4e7d67..ad29e43 100644
--- a/src/templates/zshare/editTable/index.jsx
+++ b/src/templates/zshare/editTable/index.jsx
@@ -3,17 +3,17 @@
 import { is, fromJS } from 'immutable'
 import { DndProvider, DragSource, DropTarget } from 'react-dnd'
 import { Table, Input, InputNumber, Popconfirm, Form, Select, Radio, Cascader, notification, message, Modal, Typography } from 'antd'
-import { CopyOutlined, EditOutlined, DeleteOutlined, SnippetsOutlined, SwapOutlined } from '@ant-design/icons'
+import { CopyOutlined, EditOutlined, DeleteOutlined, SwapOutlined } from '@ant-design/icons'
 
 import Utils from '@/utils/utils.js'
 import ColorSketch from '@/mob/colorsketch'
-import PasteForm from '@/templates/zshare/pasteform'
 import asyncComponent from '@/utils/asyncComponent'
 import CusSwitch from './cusSwitch'
 import MKEmitter from '@/utils/events.js'
 import './index.scss'
 
 const MkEditIcon = asyncComponent(() => import('@/components/mkIcon'))
+const PasteBoard = asyncComponent(() => import('@/components/pasteboard'))
 const EditableContext = React.createContext()
 const { confirm } = Modal
 let dragingIndex = -1
@@ -172,7 +172,6 @@
   state = {
     data: [],
     editingKey: '',
-    visible: false,
     editLineId: '',
     columns: []
   }
@@ -196,7 +195,7 @@
           鎿嶄綔
           <span className="copy-control">
             {actions.includes('copy') ? <CopyOutlined title="澶嶅埗" onClick={() => this.copy()} /> : null}
-            {actions.includes('copy') ? <SnippetsOutlined title="绮樿创" onClick={this.paste} /> : null}
+            {actions.includes('copy') ? <PasteBoard getPasteValue={this.pasteSubmit}/> : null}
             {actions.includes('clear') ? <DeleteOutlined title="娓呯┖" onClick={this.clear} /> : null}
           </span>
         </div>),
@@ -352,66 +351,74 @@
     }
   }
   
-  paste = () => {
-    this.setState({visible: true})
-  }
-  
-  pasteSubmit = () => {
+  pasteSubmit = (res, callback) => {
     const { type } = this.props
     const { columns } = this.state
     let data = fromJS(this.state.data).toJS()
 
-    this.pasteFormRef.handleConfirm().then(res => {
-      if (res.copyType === 'columns' && type === 'datasourcefield') {
-        res.type = 'array'
-        res.data = []
-        res.columns.forEach(col => {
-          if (!col.field) return
-          if (col.type === 'number') {
-            let datatype = 'Int'
-            if (col.decimal) {
-              datatype = `Decimal(18,${col.decimal})`
-            }
-
-            res.data.push({
-              $index: res.data.length + 1,
-              datatype: datatype,
-              field: col.field,
-              decimal: col.decimal,
-              label: col.label,
-              type: 'number',
-              uuid: Utils.getuuid()
-            })
-          } else {
-            let datatype = 'Nvarchar(50)'
-            let fieldlength = 50
-            if (col.fieldlength && [10, 20, 50, 100, 256, 512, 1024, 2048].includes(col.fieldlength)) {
-              fieldlength = col.fieldlength
-              datatype = `Nvarchar(${fieldlength})`
-            }
-
-            res.data.push({
-              $index: res.data.length + 1,
-              datatype: datatype,
-              field: col.field,
-              fieldlength: fieldlength,
-              label: col.label,
-              type: 'text',
-              uuid: Utils.getuuid()
-            })
+    if (res.copyType === 'columns' && type === 'datasourcefield') {
+      res.type = 'array'
+      res.data = []
+      res.columns.forEach(col => {
+        if (!col.field) return
+        if (col.type === 'number') {
+          let datatype = 'Int'
+          if (col.decimal) {
+            datatype = `Decimal(18,${col.decimal})`
           }
-        })
-      } else if (res.key !== type) {
-        message.warning('閰嶇疆淇℃伅鏍煎紡閿欒锛�')
-        return
-      }
 
-      if (res.type === 'line') {
-        let unique = true
-        res.data.uuid = Utils.getuuid()
-        columns.forEach(col => {
-          if (col.unique !== true || !unique) return
+          res.data.push({
+            $index: res.data.length + 1,
+            datatype: datatype,
+            field: col.field,
+            decimal: col.decimal,
+            label: col.label,
+            type: 'number',
+            uuid: Utils.getuuid()
+          })
+        } else {
+          let datatype = 'Nvarchar(50)'
+          let fieldlength = 50
+          if (col.fieldlength && [10, 20, 50, 100, 256, 512, 1024, 2048].includes(col.fieldlength)) {
+            fieldlength = col.fieldlength
+            datatype = `Nvarchar(${fieldlength})`
+          }
 
+          res.data.push({
+            $index: res.data.length + 1,
+            datatype: datatype,
+            field: col.field,
+            fieldlength: fieldlength,
+            label: col.label,
+            type: 'text',
+            uuid: Utils.getuuid()
+          })
+        }
+      })
+    } else if (res.key !== type) {
+      message.warning('閰嶇疆淇℃伅鏍煎紡閿欒锛�')
+      return
+    }
+
+    if (res.type === 'line') {
+      let unique = true
+      res.data.uuid = Utils.getuuid()
+      columns.forEach(col => {
+        if (col.unique !== true || !unique) return
+
+        if (col.strict) {
+          let key = res.data[col.dataIndex].toLowerCase()
+          let _index = data.findIndex(item => key === item[col.dataIndex].toLowerCase())
+
+          if (_index > -1) {
+            notification.warning({
+              top: 92,
+              message: col.title + '涓嶅彲閲嶅锛�',
+              duration: 5
+            })
+            unique = false
+          }
+        } else {
           let _index = data.findIndex(item => res.data[col.dataIndex] === item[col.dataIndex])
 
           if (_index > -1) {
@@ -422,38 +429,49 @@
             })
             unique = false
           }
-        })
+        }
+      })
 
-        if (!unique) return
+      if (!unique) return
 
-        data.unshift(res.data)
-        this.setState({ data, editingKey: '', visible: false }, () => {
-          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
+      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.strict) {
+            let _index = data.findIndex(item => cell[col.dataIndex].toLowerCase() === item[col.dataIndex].toLowerCase())
+  
+            if (_index > -1) {
+              unique = false
+            }
+          } else {
             let _index = data.findIndex(item => cell[col.dataIndex] === item[col.dataIndex])
   
             if (_index > -1) {
               unique = false
             }
-          })
-  
-          if (!unique) return
-  
-          data.push(cell)
+          }
         })
 
-        this.setState({ data, editingKey: '', visible: false }, () => {
-          this.props.onChange(data)
-        })
-      }
-      message.success('绮樿创鎴愬姛銆�')
-    })
+        if (!unique) return
+
+        data.push(cell)
+      })
+
+      this.setState({ data, editingKey: '' }, () => {
+        this.props.onChange(data)
+      })
+    }
+
+    callback()
+    message.success('绮樿创鎴愬姛銆�')
   }
 
   handleStatus = (record) => {
@@ -673,18 +691,6 @@
               })}
             />
           </DndProvider>
-          {/* 淇℃伅绮樿创 */}
-          <Modal
-            title="绮樿创"
-            visible={this.state.visible}
-            width={600}
-            maskClosable={false}
-            onOk={this.pasteSubmit}
-            onCancel={() => {this.setState({visible: false})}}
-            destroyOnClose
-          >
-            <PasteForm wrappedComponentRef={(inst) => this.pasteFormRef = inst} inputSubmit={this.pasteSubmit}/>
-          </Modal>
         </div>
       </EditableContext.Provider>
     )
diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx
index bd96bbb..2dea436 100644
--- a/src/templates/zshare/formconfig.jsx
+++ b/src/templates/zshare/formconfig.jsx
@@ -386,6 +386,30 @@
     })
   }
 
+  let muloptions = [{
+    value: 'false',
+    text: '鍗曢��'
+  }, {
+    value: 'true',
+    text: '澶氶��'
+  }, {
+    value: 'dropdown',
+    text: '涓嬫媺鑿滃崟'
+  }]
+
+  if (appType !== '') {
+    muloptions = [{
+      value: 'false',
+      text: '鍗曢��'
+    }, {
+      value: 'true',
+      text: '澶氶��'
+    }]
+    if (card.multiple === 'dropdown') {
+      card.multiple = 'false'
+    }
+  }
+
   return [
     {
       type: 'text',
@@ -472,12 +496,12 @@
     {
       type: 'number',
       key: 'width',
-      min: 1,
+      min: 0,
       max: 24,
       precision: 0,
       label: '鍏冪礌瀹藉害',
-      initVal: card.width || 4,
-      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
+      initVal: card.width === 0 ? 0 : (card.width || 4),
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼�傛敞锛氬綋瀹藉害涓�0鏃讹紝鍏冪礌鏍规嵁鍐呭鑷�傚簲',
       required: true
     },
     {
@@ -573,14 +597,9 @@
       key: 'multiple',
       label: '閫夋嫨褰㈠紡',
       initVal: card.multiple || 'false',
+      tooltip: appType === '' ? '浣跨敤涓嬫媺鑿滃崟鏃讹紝閫夐」浼氫緷鎹� pid 缁勭粐鏁版嵁鐨勪笂涓嬬骇鍏崇郴锛屼簩绾ч�夐」浼氫笅鎷夊睍绀恒�傛敞锛�1銆佹樉绀轰负鏂囨湰鏃舵湁鏁堬紱2銆佷娇鐢ㄦ暟鎹簮璇疯繑鍥� pid 瀛楁銆�' : '',
       required: true,
-      options: [{
-        value: 'false',
-        text: '鍗曢��'
-      }, {
-        value: 'true',
-        text: '澶氶��'
-      }]
+      options: muloptions
     },
     {
       type: 'select',
@@ -826,6 +845,20 @@
     },
     {
       type: 'radio',
+      key: 'border',
+      label: '杈规',
+      initVal: card.border || 'show',
+      required: false,
+      options: [{
+        value: 'show',
+        text: '鏄剧ず'
+      }, {
+        value: 'hide',
+        text: '闅愯棌'
+      }]
+    },
+    {
+      type: 'radio',
       key: 'selectStyle',
       label: '閫変腑鏁堟灉',
       tooltip: '鑳屾櫙鍙婃枃瀛楀彉鍖栨椂浼氫娇鐢ㄧ郴缁熻壊銆�',
@@ -884,6 +917,14 @@
       initVal: card.backgroundColor || '',
       tooltip: '璁剧疆鑳屾櫙鑹插悗锛岄�変腑鏁堟灉鐢辫儗鏅鑹叉帶鍒躲��',
       required: true
+    },
+    {
+      type: 'text',
+      key: 'mark',
+      label: '椤剁骇鏍囪瘑',
+      initVal: card.mark || '',
+      tooltip: 'pid涓庨《绾ф爣璇嗙浉鍚屾椂锛岃涓洪《绾ц妭鐐广��',
+      required: false
     },
     {
       type: 'multiselect',
@@ -1204,35 +1245,6 @@
     },
     {
       type: 'radio',
-      key: 'method',
-      label: '璇锋眰鏂瑰紡',
-      initVal: card.method || 'post',
-      required: true,
-      options: [{
-        value: 'get',
-        text: 'GET'
-      }, {
-        value: 'post',
-        text: 'POST'
-      }]
-    },
-    {
-      type: 'radio',
-      key: 'cross',
-      label: '璺ㄥ煙璇锋眰',
-      initVal: card.cross || 'true',
-      tooltip: '濡傛灉鑷畾涔夋帴鍙d笉鏀寔璺ㄥ煙璇锋眰锛屼細閫氳繃褰撳墠绯荤粺杞彂銆�',
-      required: false,
-      options: [{
-        value: 'true',
-        text: '鏀寔'
-      }, {
-        value: 'false',
-        text: '涓嶆敮鎸�'
-      }]
-    },
-    {
-      type: 'radio',
       key: 'callbackType',
       label: '鍥炶皟鏂瑰紡',
       initVal: card.callbackType || (card.callbackFunc ? 'func' : 'none'),
@@ -1266,6 +1278,52 @@
       initVal: card.callbackFunc || '',
       required: true,
       readonly: false
+    },
+    {
+      type: 'radio',
+      key: 'method',
+      label: '璇锋眰鏂瑰紡',
+      initVal: card.method || 'post',
+      required: true,
+      options: [{
+        value: 'get',
+        text: 'GET'
+      }, {
+        value: 'post',
+        text: 'POST'
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'cross',
+      label: '鎺ュ彛璺ㄥ煙',
+      initVal: card.cross || 'true',
+      tooltip: '濡傛灉鑷畾涔夋帴鍙d笉鏀寔璺ㄥ煙璇锋眰锛屼細閫氳繃褰撳墠绯荤粺杞彂銆�',
+      required: false,
+      options: [{
+        value: 'true',
+        text: '鏀寔'
+      }, {
+        value: 'false',
+        text: '涓嶆敮鎸�'
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'stringify',
+      label: '搴忓垪鍖�',
+      initVal: card.stringify || 'text',
+      required: false,
+      options: [{
+        value: 'text',
+        text: 'Text'
+      }, {
+        value: 'JSON',
+        text: 'JSON'
+      }, {
+        value: 'qs',
+        text: 'qs'
+      }]
     },
     {
       type: 'radio',
@@ -2769,12 +2827,12 @@
     {
       type: 'number',
       key: 'width',
-      min: 1,
+      min: 0,
       max: 24,
       precision: 0,
       label: '鍏冪礌瀹藉害',
-      initVal: card.width || 4,
-      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
+      initVal: card.width === 0 ? 0 : (card.width || 4),
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼�傛敞锛氬綋瀹藉害涓�0鏃讹紝鍏冪礌鏍规嵁鍐呭鑷�傚簲',
       required: true
     },
     {
@@ -2854,6 +2912,7 @@
       key: 'dataSource',
       label: '鏁版嵁婧�',
       initVal: card.dataSource || '',
+      placeholder: '绯荤粺鍙橀噺锛歮k_departmentcode銆乵k_organization銆乵k_user_type銆�',
       required: true,
       readonly: false
     },
@@ -3399,6 +3458,36 @@
       }, {
         value: 'adaptive',
         text: '鑷�傚簲'
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'border',
+      label: '杈规',
+      initVal: card.border || 'show',
+      required: false,
+      options: [{
+        value: 'show',
+        text: '鏄剧ず'
+      }, {
+        value: 'hide',
+        text: '闅愯棌'
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'checkAll',
+      label: '鍏ㄩ��',
+      initVal: card.checkAll || 'hide',
+      tooltip: '鍙閫夌殑閫夐」鍗℃槸鍚︽樉绀哄叏閫夊紑鍏筹紝娉細褰撻�夐」澶т簬3涓椂鏈夋晥銆�',
+      required: false,
+      forbid: appType !== '',
+      options: [{
+        value: 'hide',
+        text: '闅愯棌'
+      }, {
+        value: 'show',
+        text: '鏄剧ず'
       }]
     },
     {
@@ -4062,8 +4151,7 @@
       key: 'icon',
       label: '鍥炬爣',
       initVal: card.icon || '',
-      required: false,
-      forbid: type === 'CalendarPage'
+      required: false
     },
     {
       type: 'select',
@@ -4071,8 +4159,7 @@
       label: '涓婄骇鏍囩',
       initVal: supMenu,
       required: false,
-      options: menus,
-      forbid: type === 'CalendarPage'
+      options: menus
     },
     {
       type: 'mutilselect',
@@ -4081,8 +4168,7 @@
       tooltip: '濡傛灉瀛愭爣绛句腑鍚湁鍒锋柊鍚岀骇鏍囩鐨勬寜閽紝鍦ㄦ澶勬坊鍔犻渶瑕佸埛鏂扮殑鏍囩銆�',
       initVal: equalTab,
       required: false,
-      options: equalTabs,
-      forbid: type === 'CalendarPage'
+      options: equalTabs
     },
     {
       type: 'text',
@@ -4090,8 +4176,7 @@
       label: '澶栭敭',
       tooltip: '澶栭敭鏃ㄥ湪鏍囩椤典腑鎵ц榛樿鍑芥暟锛堟坊鍔狅級鏃讹紝鏇挎崲BID瀛楁',
       initVal: card.foreignKey || '',
-      required: false,
-      forbid: type === 'CalendarPage'
+      required: false
     },
     {
       type: 'number',
@@ -4111,7 +4196,7 @@
       initVal: card.searchPass || 'false',
       tooltip: '浣跨敤涓昏〃鎼滅储鏉′欢鏃讹紝涓昏〃鐨勬悳绱㈡潯浠朵細浼犲叆瀛愯〃涓��',
       required: false,
-      forbid: type !== 'CommonTable' && type !== 'CalendarPage',
+      forbid: type !== 'CommonTable',
       options: [{
         value: 'true',
         text: '浣跨敤'
diff --git a/src/templates/zshare/menuform/index.jsx b/src/templates/zshare/menuform/index.jsx
index b3ce1f3..f70d08e 100644
--- a/src/templates/zshare/menuform/index.jsx
+++ b/src/templates/zshare/menuform/index.jsx
@@ -2,7 +2,7 @@
 import PropTypes from 'prop-types'
 import { Form, Row, Col, Input, Select } from 'antd'
 import { formRule } from '@/utils/option.js'
-import './index.scss'
+// import './index.scss'
 
 class MainSearch extends Component {
   static propTpyes = {
diff --git a/src/templates/zshare/modalform/datatable/index.jsx b/src/templates/zshare/modalform/datatable/index.jsx
index 75a9a67..8f3e62b 100644
--- a/src/templates/zshare/modalform/datatable/index.jsx
+++ b/src/templates/zshare/modalform/datatable/index.jsx
@@ -174,6 +174,7 @@
       !is(fromJS(this.props.fields), fromJS(nextProps.fields)) ||
       !is(fromJS(this.props.linkSubFields), fromJS(nextProps.linkSubFields)) ||
       this.props.display !== nextProps.display ||
+      (nextProps.multiple && this.props.multiple !== nextProps.multiple) ||
       this.props.type !== nextProps.type
     ) {
       this.setState({editingKey: ''}, () => {
@@ -185,9 +186,9 @@
   }
 
   getCloumns = () => {
-    const { display, fields, linkSubFields, transfield, type } = this.props
+    const { display, fields, linkSubFields, transfield, type, multiple } = this.props
     let columns = []
-    let keys = ['ParentID']
+    let keys = ['ParentID', 'pid']
 
     if (display === 'picture') {
       columns.push({
@@ -241,6 +242,14 @@
       editable: true,
     })
 
+    if (multiple === 'dropdown' && display === 'text') {
+      columns.unshift({
+        title: 'pid',
+        dataIndex: 'pid',
+        editable: true,
+      })
+    }
+
     if (type === 'link') {
       columns.unshift({
         title: 'ParentID',
diff --git a/src/templates/zshare/modalform/fieldtable/index.jsx b/src/templates/zshare/modalform/fieldtable/index.jsx
index d9100da..3b607cf 100644
--- a/src/templates/zshare/modalform/fieldtable/index.jsx
+++ b/src/templates/zshare/modalform/fieldtable/index.jsx
@@ -127,6 +127,26 @@
         this.setState({loading: false})
       })
       return
+    } else if (fields.filter(f => f.toLowerCase() === 'parentid').length > 0) {
+      notification.warning({
+        top: 92,
+        message: '瀛楁鍚嶄笉鍙娇鐢╬arentid锛�',
+        duration: 5
+      })
+      this.setState({loading: true}, () => {
+        this.setState({loading: false})
+      })
+      return
+    } else if (fields.filter(f => f.toLowerCase() === 'pid').length > 0) {
+      notification.warning({
+        top: 92,
+        message: '瀛楁鍚嶄笉鍙娇鐢╬id锛�',
+        duration: 5
+      })
+      this.setState({loading: true}, () => {
+        this.setState({loading: false})
+      })
+      return
     }
 
     this.setState({ data }, () => {
diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx
index 335f222..ac5c8a7 100644
--- a/src/templates/zshare/modalform/index.jsx
+++ b/src/templates/zshare/modalform/index.jsx
@@ -204,9 +204,9 @@
       } else {
         reRequired.fields = true
         if (this.record.resourceType === '0') {        // 鑷畾涔夎祫婧�
-          shows.push('options', 'fields', 'selectStyle')
+          shows.push('options', 'fields', 'selectStyle', 'border')
         } else if (this.record.resourceType === '1') { // 鏁版嵁婧�
-          shows.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'disableField', 'database', 'selectStyle')
+          shows.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'disableField', 'database', 'selectStyle', 'border')
         }
         if (this.record.selectStyle === 'custom') {
           shows.push('backgroundColor')
@@ -221,7 +221,7 @@
           shows.push('decimal')
         }
       } else {
-        shows.push('fieldlength')
+        shows.push('fieldlength', 'checkAll')
         reTooltip.initval = '娣诲姞澶氫釜鍒濆鍊艰浣跨敤閫楀彿鍒嗛殧銆�'
       }
 
@@ -727,6 +727,9 @@
         if (this.record.type === 'select' || this.record.type === 'link') {
           extra = <span className="add-resource-empty" onClick={this.handleEmpty}>绌�</span>
         }
+        if (item.placeholder) {
+          extra = <><span className="resource-public-var">{item.placeholder}</span>{extra}</>
+        }
 
         content = <CodeMirror />
       } else if (item.type === 'textarea') {
diff --git a/src/templates/zshare/modalform/index.scss b/src/templates/zshare/modalform/index.scss
index ee25254..23d5929 100644
--- a/src/templates/zshare/modalform/index.scss
+++ b/src/templates/zshare/modalform/index.scss
@@ -47,6 +47,12 @@
     cursor: pointer;
     font-size: 14px;
   }
+  .resource-public-var {
+    position: absolute;
+    left: 0px;
+    top: -25px;
+    font-size: 14px;
+  }
   >.ant-row >.ant-col {
     display: inline-block;
     vertical-align: top;
diff --git a/src/templates/zshare/verifycard/index.jsx b/src/templates/zshare/verifycard/index.jsx
index e7930e1..ade0e92 100644
--- a/src/templates/zshare/verifycard/index.jsx
+++ b/src/templates/zshare/verifycard/index.jsx
@@ -1690,7 +1690,7 @@
             <Form {...formItemLayout}>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> S </span>
                     <Button onClick={() => {this.showError('S')}} type="primary" size="small">
                       鏌ョ湅
@@ -1698,14 +1698,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.stime || 2} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'stime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> Y </span>
                     <Button onClick={() => {this.showError('Y')}} type="primary" size="small">
                       鏌ョ湅
@@ -1715,7 +1715,15 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -1 </span>
+                    鎵ц鎴愬姛鏃犳彁绀恒��
+                  </Form.Item>
+                </Col>
+              </Row>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> N </span>
                     <Button onClick={() => {this.showError('N')}} type="primary" size="small">
                       鏌ョ湅
@@ -1723,14 +1731,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.ntime || (appType === 'mob' ? 3 : 10)} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> F </span>
                     <Button onClick={() => {this.showError('F')}} type="primary" size="small">
                       鏌ョ湅
@@ -1738,14 +1746,14 @@
                   </Form.Item>
                 </Col>
                 <Col span={8}>
-                  <Form.Item label={'鍋滅暀鏃堕棿'}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
                     <InputNumber defaultValue={verify.ftime || (appType === 'mob' ? 3 : 10)} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} />
                   </Form.Item>
                 </Col>
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> E </span>
                     <Button onClick={() => {this.showError('E')}} type="primary" size="small">
                       鏌ョ湅
@@ -1755,7 +1763,7 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
+                  <Form.Item label="鎻愮ず缂栫爜">
                     <span className="errorval"> NM </span>
                     <Button onClick={() => {this.showError('NM')}} type="primary" size="small">
                       鏌ョ湅
@@ -1765,9 +1773,9 @@
               </Row>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
-                  <Form.Item label={'鎻愮ず缂栫爜'}>
-                    <span className="errorval"> -1 </span>
-                    涓嶆彁绀�
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -2 </span>
+                    鎵ц澶辫触鏃犳彁绀�
                   </Form.Item>
                 </Col>
               </Row>
diff --git a/src/utils/option.js b/src/utils/option.js
index e771dfe..4fe5606 100644
--- a/src/utils/option.js
+++ b/src/utils/option.js
@@ -1,7 +1,6 @@
 import nortable from '@/assets/img/normaltable.jpg'
 // import mainsubtable from '@/assets/img/mainsubtable.jpg'
 import treepage from '@/assets/img/treepage.jpg'
-import calendar from '@/assets/img/calendar.jpg'
 import customImg from '@/assets/img/custom.jpg'
 import newpage from '@/assets/img/newpage.jpg'
 import rolemanage from '@/assets/img/rolemanage.jpg'
@@ -78,13 +77,6 @@
     title: '鏍戝舰椤甸潰',
     type: 'TreePage',
     url: treepage,
-    baseconfig: '',
-    isSystem: true
-  },
-  {
-    title: '鏃ュ巻',
-    type: 'CalendarPage',
-    url: calendar,
     baseconfig: '',
     isSystem: true
   },
diff --git a/src/utils/utils-custom.js b/src/utils/utils-custom.js
index 2fde239..be4f888 100644
--- a/src/utils/utils-custom.js
+++ b/src/utils/utils-custom.js
@@ -19,6 +19,8 @@
       } else if (item.type === 'tabs') {
         if (item.subtype === 'tabletabs') {
           item.subtabs.forEach(tab => {
+            if (tab.components[0].uuid === selfId) return
+            
             modules.push({
               value: tab.components[0].uuid,
               label: tab.label,
@@ -542,8 +544,12 @@
 
                 return cell
               })
-            } else if (col.editable === 'true' && col.enter) {
-              col.enter = md5(commonId + col.enter)
+            } else if (col.editable === 'true' && col.enter && col.enter !== '$next' && col.enter !== '$sub') {
+              if (/\$next_/.test(col.enter)) {
+                col.enter = '$next_' + md5(commonId + col.enter.split('_')[1])
+              } else {
+                col.enter = md5(commonId + col.enter)
+              }
             }
 
             return col
@@ -655,7 +661,12 @@
     if (btn.anchors && btn.anchors.length > 0) {
       btn.anchors = btn.anchors.map(m => md5(commonId + m))
     }
-    if (btn.syncComponent && btn.syncComponent.length > 0) {
+    if (btn.syncComponent && btn.syncComponent[0] === 'multiComponent' && btn.syncComponents) {
+      btn.syncComponents = btn.syncComponents.map(m => {
+        m.syncComId = m.syncComId.map(n => md5(commonId + n))
+        return m
+      })
+    } else if (btn.syncComponent && btn.syncComponent.length > 0) {
       btn.syncComponent = btn.syncComponent.map(m => md5(commonId + m))
     }
   }
@@ -826,8 +837,12 @@
               }
               return cell
             })
-          } else if (col.editable === 'true' && col.enter) { // 鍙紪杈戣〃
-            col.enter = md5(commonId + col.enter)
+          } else if (col.editable === 'true' && col.enter && col.enter !== '$next' && col.enter !== '$sub') { // 鍙紪杈戣〃
+            if (/\$next_/.test(col.enter)) {
+              col.enter = '$next_' + md5(commonId + col.enter.split('_')[1])
+            } else {
+              col.enter = md5(commonId + col.enter)
+            }
           }
 
           return col
diff --git a/src/utils/utils-datamanage.js b/src/utils/utils-datamanage.js
index c081694..df476aa 100644
--- a/src/utils/utils-datamanage.js
+++ b/src/utils/utils-datamanage.js
@@ -18,7 +18,7 @@
   static getQueryDataParams (setting, arrFields, search = [], orderBy = '', pageIndex = 1, pageSize = 10, BID, id) {
     let param = null
 
-    if (setting.interType === 'system' || (setting.interType === 'custom' && setting.requestMode === 'system')) {
+    if (setting.interType === 'system') {
       param = this.getDefaultQueryParam(setting, arrFields, search, orderBy, pageIndex, pageSize, id, BID)
     } else {
       param = this.getCustomQueryParam(setting, search, orderBy, pageIndex, pageSize, id)
@@ -52,7 +52,7 @@
       param.PageSize = pageSize
     }
 
-    if (setting.interType === 'inner' || (setting.interType === 'custom' && setting.requestMode === 'inner')) {
+    if (setting.interType === 'inner') {
       param.func = setting.innerFunc
     } else {
       if (window.GLOB.mkHS) {
@@ -267,25 +267,6 @@
     param.LText = Utils.formatOptions(LText)
     param.DateCount = Utils.formatOptions(DateCount)
 
-    // 澶氬眰缁撴瀯鏁版嵁
-    // LText = `SELECT a.id as bid,a.ID,a.workerCode,a.workerName,a.jobName,a.Initials,case when isnull(m.friend_id ,'') ='' then '' 
-    // when isnull(m.status,0)=10 then '宸叉坊鍔�' else '寰呴�氳繃' end as friend_text
-    // ,case when images='' then  'http://epc.mk9h.cn/Content/images/upload/img/kane.jpg'  else images end as icon FROM  
-    // (select friend_id,status from oa_mail_list where userid='sso202004100959326131C0805998B6745F886F9' and  Initials=case when right('0',1)='0' then Initials else '0'  end 
-    // and status=10  and deleted=0) m 
-    //  inner join  (select * from BD_workers where 
-    //  Initials=case when right('0',1)='0' then Initials else '0' end and deleted=0 ) a
-    //  on a.id=m.friend_id `
-    // param.custom_script = ''
-    // param.LText = Utils.formatOptions(LText)
-    // param.DateCount = ''
-    // param.prm_field = 'workerCode'
-    // param.arr_field = 'workerName,jobName'
-    // param.tabid = 'ID'
-    // param.parid = 'BID'
-    // param.sub_name = 'sub_data'
-    // param.sub_field = 'BID,friend_text,icon,Initials'
-
     if (setting.sub_field) {
       param.sub_name = setting.subdata
       param.tabid = setting.primaryKey || ''
@@ -466,287 +447,6 @@
     }
 
     return param
-  }
-
-  /**
-   * @description 鏁版嵁婧愬悕绉帮紝鐢ㄤ簬缁熶竴鏌ヨ
-   * @param {Object}   setting      鏁版嵁婧愯缃�
-   * @param {String}   arrFields    鏌ヨ瀛楁
-   * @param {Array}    search       鎼滅储鏉′欢
-   * @param {String}   orderBy      鎺掑簭鏂瑰紡
-   * @param {Number}   pageIndex    椤电爜
-   * @param {Number}   pageSize     姣忛〉鏁伴噺
-   * @param {String}   BID          涓婄骇ID
-   * @return {Object}  param
-   */
-  static getPrevQueryParams (setting, search = [], BID) {
-    let param = null
-    if (setting.procMode !== 'inner') {
-      param = this.getDefaultPrevQueryParam(setting, search, BID)
-    } else {
-      param = Utils.formatCustomMainSearch(search)
-      param.func = setting.prevFunc || ''
-    }
-
-    if (BID) {
-      param.BID = BID
-    }
-
-    return param
-  }
-
-  /**
-   * @description 鑾峰彇绯荤粺鍓嶇疆鑴氭湰
-   */
-  static getDefaultPrevQueryParam (setting, search, BID) {
-    let param = {
-      func: 'sPC_TableData_InUpDe',
-      exec_type: 'y',
-      script_type: 'Y'
-    }
-
-    let sql = ''
-    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') || ''
-
-    if (sessionStorage.getItem('isEditState') === 'true') {
-      userName = sessionStorage.getItem('CloudUserName') || ''
-      fullName = sessionStorage.getItem('CloudFullName') || ''
-    }
-
-    setting.preScripts.forEach(item => {
-      if (item.status === 'false') return
-      sql += `${item.sql}
-      `
-    })
-
-    if (sql) {
-      sql = `/*鍓嶇疆鑴氭湰*/
-        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@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)
-        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}'
-        ${sql}
-        aaa:
-          if @ErrorCode!=''
-            insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@
-      `
-
-      let allSearch = Utils.getAllSearchOptions(search)
-      allSearch.forEach(item => {
-        sql = sql.replace(new RegExp('@' + item.key + '@', 'ig'), `'${item.value}'`)
-      })
-
-      if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺
-        sql = sql.replace(/\$@/ig, '/*')
-        sql = sql.replace(/@\$/ig, '*/')
-      } else {
-        sql = sql.replace(/@\$|\$@/ig, '')
-      }
-  
-      sql = sql.replace(/@userName@/ig, `'${userName}'`)
-      sql = sql.replace(/@fullName@/ig, `'${fullName}'`)
-
-      sql = sql.replace(/@ID@/ig, `''`)
-      sql = sql.replace(/@BID@/ig, `'${BID || ''}'`)
-      sql = sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
-      sql = sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
-      sql = sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
-      sql = sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
-      sql = sql.replace(/@typename@/ig, `'admin'`)
-
-      // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
-      if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
-        console.info(sql.replace(/\n\s{8}/ig, '\n'))
-      }
-    }
-
-    param.LText = Utils.formatOptions(sql)
-    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-    param.secretkey = Utils.encrypt('', param.timestamp)
-
-    if (window.GLOB.mkHS) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
-      param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
-    }
-
-    if (setting.$name) {
-      param.menuname = setting.$name
-    }
-
-    return param
-  }
-
-  /**
-   * @description 鑾峰彇绯荤粺鍥炶皟鑴氭湰
-   */
-  static getCallBackQueryParams (setting, sql, errSql, BID) {
-    let param = {
-      func: 'sPC_TableData_InUpDe',
-      exec_type: 'y',
-    }
-
-    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') || ''
-
-    if (sessionStorage.getItem('isEditState') === 'true') {
-      userName = sessionStorage.getItem('CloudUserName') || ''
-      fullName = sessionStorage.getItem('CloudFullName') || ''
-    }
-
-    let _prevCustomScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@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)
-        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}'
-        ${errSql}
-    `
-    let _backCustomScript = `
-    `
-
-    setting.cbScripts.forEach(script => {
-      if (script.status === 'false') return
-
-      if (script.position === 'front') {
-        _prevCustomScript += `
-        /* 鑷畾涔夎剼鏈� */
-        ${script.sql}
-        `
-      } else {
-        _backCustomScript += `
-        /* 鑷畾涔夎剼鏈� */
-        ${script.sql}
-        `
-      }
-    })
-
-    _backCustomScript += `
-      aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
-
-    sql = _prevCustomScript + sql
-    sql = sql + _backCustomScript
-    
-    if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺
-      sql = sql.replace(/\$@/ig, '/*')
-      sql = sql.replace(/@\$/ig, '*/')
-    } else {
-      sql = sql.replace(/@\$|\$@/ig, '')
-    }
-
-    sql = sql.replace(/@ID@/ig, `''`)
-    sql = sql.replace(/@BID@/ig, `'${BID || ''}'`)
-    sql = sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
-    sql = sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
-    sql = sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
-    sql = sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
-    sql = sql.replace(/@typename@/ig, `'admin'`)
-
-    if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
-      console.info(sql.replace(/\n\s{8}/ig, '\n'))
-    }
-
-    param.LText = sql
-
-    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-    param.secretkey = Utils.encrypt('', param.timestamp)
-    param.LText = Utils.formatOptions(param.LText)
-    
-    if (setting.$name) {
-      param.menuname = setting.$name
-    }
-
-    if (BID) {
-      param.BID = BID
-    }
-
-    if (window.GLOB.mkHS) { // 绯荤粺鍑芥暟浜戠楠岃瘉
-      param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
-    }
-
-    return param
-  }
-
-  /**
-   * @description 鑾峰彇鍥炶皟sql
-   */
-  static getCallBackSql (setting, result) {
-    let lines = []
-    let pre = setting.callbackType === 'script' ? '@' : ''
-
-    let getDefaultSql = (obj, tb, bid, level) => {
-      let keys = []
-      let vals = []
-      let subObjs = []
-      let id = Utils.getuuid()
-
-      delete obj.$$key
-
-      Object.keys(obj).forEach(key => {
-        let val = obj[key]
-        if (val === null || val === undefined) return
-        if (typeof(val) === 'object') {
-          if (Array.isArray(val)) {
-            val.forEach(item => {
-              if (typeof(item) !== 'object' || Array.isArray(item)) return
-              if (Object.keys(item).length > 0) {
-                item.$$key = tb + '_' + key
-                subObjs.push(item)
-              }
-            })
-          } else if (Object.keys(val).length > 0) {
-            val.$$key = tb + '_' + key
-            subObjs.push(val)
-          }
-        } else {
-          if (typeof(val) === 'string') {
-            val = val.replace(/'/ig, '"')
-          }
-          keys.push(key)
-          vals.push(`'${val}'`)
-        }
-      })
-
-      lines.push({
-        table: tb,
-        insert: `Insert into ${pre}${tb} (${keys.join(',')},mk_level,mk_id,mk_bid)`,
-        select: `Select ${vals.join(',')},'${level}','${id}','${bid}'`
-      })
-
-      subObjs.forEach(item => {
-        getDefaultSql(item, item.$$key, id, level + 1)
-      })
-    }
-    
-    getDefaultSql(result, setting.cbTable, '', 1)
-
-    let lineMap = new Map()
-    lines.forEach(line => {
-      if (lineMap.has(line.table)) {
-        let _line = lineMap.get(line.table)
-        _line.selects.push(line.select)
-        lineMap.set(line.table, _line)
-      } else {
-        lineMap.set(line.table, {
-          table: line.table,
-          insert: line.insert,
-          selects: [line.select]
-        })
-      }
-    })
-
-    return [...lineMap.values()]
   }
 }
 
diff --git a/src/utils/utils.js b/src/utils/utils.js
index 5f9d942..c62e490 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -800,6 +800,8 @@
         arrfield.push(item.urlField)
       } else if (item.colorField) {
         arrfield.push(item.colorField)
+      } else if (item.parentField) {
+        arrfield.push(item.parentField)
       }
     }
 
diff --git a/src/views/basedesign/index.jsx b/src/views/basedesign/index.jsx
index cfb79a4..b89d9cc 100644
--- a/src/views/basedesign/index.jsx
+++ b/src/views/basedesign/index.jsx
@@ -14,7 +14,6 @@
 const Header = asyncComponent(() => import('@/menu/header'))
 const ComTableConfig = asyncLoadComponent(() => import('@/templates/comtableconfig'))
 const TreePageConfig = asyncLoadComponent(() => import('@/templates/treepageconfig'))
-const CalendarPageConfig = asyncLoadComponent(() => import('@/templates/calendarconfig'))
 const FormTabConfig = asyncLoadComponent(() => import('@/templates/formtabconfig'))
 const ModalConfig = asyncLoadComponent(() => import('@/templates/modalconfig'))
 const SubTable = asyncLoadComponent(() => import('@/templates/subtableconfig'))
@@ -181,13 +180,6 @@
           <Header/>
           {this.state.tabview === 'TreePage' ?
             <TreePageConfig
-              menu={this.state.editMenu}
-              reloadmenu={() => {localStorage.setItem('menuUpdate', new Date().getTime())}}
-              handleView={this.handleView}
-            /> : null
-          }
-          {this.state.tabview === 'CalendarPage' ?
-            <CalendarPageConfig
               menu={this.state.editMenu}
               reloadmenu={() => {localStorage.setItem('menuUpdate', new Date().getTime())}}
               handleView={this.handleView}
diff --git a/src/views/design/sidemenu/editthdmenu/index.jsx b/src/views/design/sidemenu/editthdmenu/index.jsx
index 7b575a2..2a4c64b 100644
--- a/src/views/design/sidemenu/editthdmenu/index.jsx
+++ b/src/views/design/sidemenu/editthdmenu/index.jsx
@@ -109,7 +109,7 @@
           handleMVisible: true,
           sysMenu: _menu
         })
-      } else if (['CommonTable', 'TreePage', 'CalendarPage'].includes(_menu.PageParam.Template)) {
+      } else if (['CommonTable', 'TreePage'].includes(_menu.PageParam.Template)) {
         sessionStorage.setItem('menuTree', JSON.stringify(this.props.menuTree))
         let _param = window.btoa(window.encodeURIComponent(JSON.stringify(_menu)))
 
diff --git a/src/views/design/sidemenu/index.jsx b/src/views/design/sidemenu/index.jsx
index 8729535..597ee0f 100644
--- a/src/views/design/sidemenu/index.jsx
+++ b/src/views/design/sidemenu/index.jsx
@@ -121,7 +121,7 @@
       }
       _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
       window.open(`#/menudesign/${_param}`)
-    } else if (['CommonTable', 'TreePage', 'CalendarPage'].includes(cell.type)) {
+    } else if (['CommonTable', 'TreePage'].includes(cell.type)) {
       sessionStorage.setItem('menuTree', JSON.stringify(this.props.menuTree))
       let _param = window.btoa(window.encodeURIComponent(JSON.stringify(cell)))
 
diff --git a/src/views/design/sidemenu/thdmenuform/index.jsx b/src/views/design/sidemenu/thdmenuform/index.jsx
index e393aa9..338a3f0 100644
--- a/src/views/design/sidemenu/thdmenuform/index.jsx
+++ b/src/views/design/sidemenu/thdmenuform/index.jsx
@@ -1,7 +1,8 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
-import { Form, Row, Col, Input, Select } from 'antd'
+import { Form, Row, Col, Input, Select, Tooltip } from 'antd'
+import { QuestionCircleOutlined } from '@ant-design/icons'
 // import './index.scss'
 
 const { TextArea } = Input
@@ -74,7 +75,7 @@
       <Form {...formItemLayout} style={{paddingRight: '20px'}}>
         <Row gutter={24}>
           <Col span={22}>
-            <Form.Item label={'涓�绾ц彍鍗�'}>
+            <Form.Item label="涓�绾ц彍鍗�">
               {getFieldDecorator('fstMenuId', {
                 initialValue: menu.fstMenuId,
                 rules: [
@@ -97,7 +98,7 @@
             </Form.Item>
           </Col>
           <Col span={22}>
-            <Form.Item label={'浜岀骇鑿滃崟'}>
+            <Form.Item label="浜岀骇鑿滃崟">
               {getFieldDecorator('ParentID', {
                 initialValue: menu.ParentId,
                 rules: [
@@ -119,7 +120,7 @@
             </Form.Item>
           </Col>
           <Col span={22}>
-            <Form.Item label={'鑿滃崟鍚嶇О'}>
+            <Form.Item label="鑿滃崟鍚嶇О">
               {getFieldDecorator('MenuName', {
                 initialValue: menu.MenuName || '',
                 rules: [
@@ -132,7 +133,7 @@
             </Form.Item>
           </Col>
           <Col span={22}>
-            <Form.Item label={'鑿滃崟鍙傛暟'}>
+            <Form.Item label="鑿滃崟鍙傛暟">
               {getFieldDecorator('MenuNo', {
                 initialValue: menu.MenuNo || '',
                 rules: [
@@ -145,7 +146,9 @@
             </Form.Item>
           </Col>
           {menu.Template === 'NewPage' ? <Col span={22}>
-            <Form.Item label={'閾炬帴鍦板潃'}>
+            <Form.Item label={
+              <Tooltip overlayStyle={{minWidth: 500}} placement="topLeft" title={<div onClick={(e) => e.stopPropagation()}>浣跨敤鍚屼竴鍗曠偣绯荤粺涓嬬殑鍏朵粬涓氬姟绯荤粺锛岄摼鎺ユ牸寮忎负锛歨ttp://<span style={{color: 'orange'}}>******</span>/admin/index.html#/iframe/<span style={{color: 'orange'}}>menuId</span>/<span style={{color: 'orange'}}>userid</span>/<span style={{color: 'orange'}}>loginuid</span>/<span style={{color: 'orange'}}>BID</span>銆傛敞锛�******涓哄煙鍚�+铏氭嫙鐩綍锛沵enuId涓鸿彍鍗旾D锛泆serid涓虹敤鎴稩D锛堜娇鐢ˊuserid@鏃惰嚜鍔ㄦ浛鎹负褰撳墠绯荤粺鐨剈serid锛夛紱loginuid涓虹櫥褰曚俊鎭紙浣跨敤@loginuid@鏃惰嚜鍔ㄦ浛鎹负褰撳墠绯荤粺鐨刲oginuid锛夛紱BID鏄悜鑿滃崟涓殑浼犲弬锛屽彲涓虹┖銆�</div>}><QuestionCircleOutlined className="mk-form-tip" />閾炬帴鍦板潃</Tooltip>
+            }>
               {getFieldDecorator('url', {
                 initialValue: menu.url || '',
                 rules: [
diff --git a/src/views/login/index.jsx b/src/views/login/index.jsx
index da7b51b..55fba9b 100644
--- a/src/views/login/index.jsx
+++ b/src/views/login/index.jsx
@@ -281,16 +281,10 @@
     // md5("/ws/location/v1/ip?callback=callbackFunction&key=key&output=jsonp secret key")
     // md5("/ws/location/v1/ip?callback=callbackFunction&key=BA7BZ-4QB65-LFCIA-QPDA6-4G6O7-MJB4Q&output=jsonpuThL4ZM3XOj642ksEQh76tyHFjh4")
 
-    // 鑾峰彇ip鍙婂煄甯備俊鎭�
-    // let ipurl = window.atob('aHR0cHM6Ly9lcGMubWs5a$mkC5jbi93ZWJhcGkvaXBsb2M='.replace(/\$mk/ig, ''))
-    // Api.directRequest(ipurl, 'get', null, 'true').then(res => {
-    //   if (!res || !res.ip) return
-    //   sessionStorage.setItem('ipAddress', res.ip)
-    // })
-
     setTimeout(() => {
       Api.delCacheConfig()
     }, 50)
+
     if (window.GLOB.filter) {
       let view = document.getElementById('mk-login-view')
       
@@ -452,7 +446,11 @@
       param.sign = md5(values)
       param.t = new Date().getTime()
   
-      Api.directRequest(_rduri + '/' + _func, 'post', param, 'true').then(res => {
+      Api.directRequest({
+        url: _rduri + '/' + _func,
+        method: 'post',
+        data: JSON.stringify(param)
+      }).then(res => {
         if (res.status) {
           if (res.EPC === str) {
             let box = []
diff --git a/src/views/login/logincloudform.jsx b/src/views/login/logincloudform.jsx
index a8c70fc..c87cf3f 100644
--- a/src/views/login/logincloudform.jsx
+++ b/src/views/login/logincloudform.jsx
@@ -20,6 +20,8 @@
     return new Promise((resolve, reject) => {
       this.props.form.validateFieldsAndScroll((err, values) => {
         if (!err) {
+          values.cloudusername = values.cloudusername.replace(/\t*|\v*|\s*/g, '')
+          values.cloudpassword = values.cloudpassword.replace(/\t*|\v*|\s*/g, '')
           resolve(values)
         } else {
           reject(err)
diff --git a/src/views/login/loginform.jsx b/src/views/login/loginform.jsx
index da71b58..eda2530 100644
--- a/src/views/login/loginform.jsx
+++ b/src/views/login/loginform.jsx
@@ -139,6 +139,13 @@
     return new Promise((resolve, reject) => {
       this.props.form.validateFieldsAndScroll((err, values) => {
         if (!err) {
+          if (activeKey === 'uname_pwd') {
+            values.username = values.username.replace(/\t*|\v*|\s*/g, '')
+            values.password = values.password.replace(/\t*|\v*|\s*/g, '')
+          } else if (activeKey === 'sms_vcode') {
+            values.phone = values.phone.replace(/\t*|\v*|\s*/g, '')
+            values.vercode = values.vercode.replace(/\t*|\v*|\s*/g, '')
+          }
           resolve({type: activeKey, ...values})
         } else {
           reject(err)
diff --git a/src/views/menudesign/homeform/index.jsx b/src/views/menudesign/homeform/index.jsx
index 1fc96b3..4454c32 100644
--- a/src/views/menudesign/homeform/index.jsx
+++ b/src/views/menudesign/homeform/index.jsx
@@ -171,9 +171,10 @@
               {getFieldDecorator('timeUnit', {
                 initialValue: config.timeUnit || 'day'
               })(
-                <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}>
+                <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}>
                   <Radio value="day">澶�</Radio>
                   <Radio value="hour">灏忔椂</Radio>
+                  <Radio value="minute">鍒嗛挓</Radio>
                 </Radio.Group>
               )}
             </Form.Item>
@@ -189,7 +190,7 @@
                   }
                 ]
               })(
-                <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={this.changeCacheDay}/>
+                <InputNumber min={1} max={config.timeUnit === 'day' ? 7 : (config.timeUnit === 'hour' ? 23 : 59)} precision={0} onChange={this.changeCacheDay}/>
               )}
             </Form.Item>
           </Col> : null}
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index f5bc9e6..fdf22ba 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -73,12 +73,28 @@
   }
 
   UNSAFE_componentWillMount() {
+    if (sessionStorage.getItem('devError') === 'true') {
+      sessionStorage.clear()
+      window.history.replaceState(null, null, window.location.href.split('#')[0] + '#/login')
+      window.location.reload()
+      return
+    }
+    
+    if (!sessionStorage.getItem('UserID')) {
+      sessionStorage.removeItem('isEditState')
+      sessionStorage.removeItem('appType')
+      this.props.history.replace('/login')
+      return
+    }
+
     sessionStorage.setItem('editMenuType', 'menu') // 缂栬緫鑿滃崟绫诲瀷
 
+    window.GLOB.curDate = moment().format('YYYY-MM-DD')
     window.GLOB.UserComponentMap = new Map() // 缂撳瓨鐢ㄦ埛鑷畾涔夌粍浠�
     window.GLOB.TabsMap = new Map()          // 缂撳瓨鐢ㄦ埛鎿嶄綔鐨勬爣绛鹃〉
     window.GLOB.urlFields = []               // url鍙橀噺
     window.GLOB.customMenu = null            // 淇濆瓨鑿滃崟淇℃伅
+    window.GLOB.developing = true
 
     try {
       let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
@@ -106,6 +122,8 @@
   }
 
   componentDidMount () {
+    if (!sessionStorage.getItem('UserID')) return
+    
     MKEmitter.addListener('changePopview', this.initPopview)
     MKEmitter.addListener('triggerMenuSave', this.triggerMenuSave)
     MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent)
@@ -1041,6 +1059,7 @@
     this.setState({
       menuloading: false
     })
+
     if (!error) {
       notification.warning({
         top: 92,
diff --git a/src/views/menudesign/menuform/index.jsx b/src/views/menudesign/menuform/index.jsx
index 0f4433b..f746df1 100644
--- a/src/views/menudesign/menuform/index.jsx
+++ b/src/views/menudesign/menuform/index.jsx
@@ -363,9 +363,10 @@
               {getFieldDecorator('timeUnit', {
                 initialValue: config.timeUnit || 'day'
               })(
-                <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}>
+                <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}>
                   <Radio value="day">澶�</Radio>
                   <Radio value="hour">灏忔椂</Radio>
+                  <Radio value="minute">鍒嗛挓</Radio>
                 </Radio.Group>
               )}
             </Form.Item>
@@ -381,7 +382,7 @@
                   }
                 ]
               })(
-                <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={(val) => {this.selectChange('cacheTime', val)}}/>
+                <InputNumber min={1} max={config.timeUnit === 'day' ? 7 : (config.timeUnit === 'hour' ? 23 : 59)} precision={0} onChange={(val) => {this.selectChange('cacheTime', val)}}/>
               )}
             </Form.Item>
           </Col> : null}
diff --git a/src/views/menudesign/popview/menuform/index.jsx b/src/views/menudesign/popview/menuform/index.jsx
index d2899a2..e84a5af 100644
--- a/src/views/menudesign/popview/menuform/index.jsx
+++ b/src/views/menudesign/popview/menuform/index.jsx
@@ -86,9 +86,10 @@
               {getFieldDecorator('timeUnit', {
                 initialValue: config.timeUnit || 'day'
               })(
-                <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}>
+                <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}>
                   <Radio value="day">澶�</Radio>
                   <Radio value="hour">灏忔椂</Radio>
+                  <Radio value="minute">鍒嗛挓</Radio>
                 </Radio.Group>
               )}
             </Form.Item>
@@ -104,7 +105,7 @@
                   }
                 ]
               })(
-                <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={this.changeCacheDay}/>
+                <InputNumber min={1} max={config.timeUnit === 'day' ? 7 : (config.timeUnit === 'hour' ? 23 : 59)} precision={0} onChange={this.changeCacheDay}/>
               )}
             </Form.Item>
           </Col> : null}
diff --git a/src/views/mkiframe/index.jsx b/src/views/mkiframe/index.jsx
new file mode 100644
index 0000000..6967cea
--- /dev/null
+++ b/src/views/mkiframe/index.jsx
@@ -0,0 +1,58 @@
+import React, {Component} from 'react'
+import { Spin } from 'antd'
+
+import './index.scss'
+
+class MkIframe extends Component {
+  state = {
+    loading: true
+  }
+
+  UNSAFE_componentWillMount() {
+    // const { menuId, userId, loginUid, bid } = this.props.match.params
+
+    // sessionStorage.setItem('LoginUID', loginUid)
+  }
+
+  componentDidMount() {
+    // sessionStorage.setItem('ThirdMenu', this.props.match.params.menuId)
+
+    // if (sessionStorage.getItem('UserID')) {
+    //   this.props.history.replace('/main')
+    // } else {
+    //   localStorage.setItem('getSessionStorage', window.GLOB.appkey)
+    
+    //   window.addEventListener('storage', function(event) {
+    //     if (event.key === 'sessionStorage' && event.newValue && !sessionStorage.getItem('UserID')) {
+    //       let values = event.newValue
+    //       values = JSON.parse(values)
+
+    //       Object.keys(values).forEach(key => {
+    //         sessionStorage.setItem(key, values[key])
+    //       })
+    //     }
+    //   })
+
+    //   setTimeout(() => {
+    //     localStorage.removeItem('getSessionStorage')
+    //     localStorage.removeItem('sessionStorage')
+
+    //     if (sessionStorage.getItem('UserID')) {
+    //       this.props.history.replace('/main')
+    //     } else {
+    //       this.props.history.replace('/login')
+    //     }
+    //   }, 20)
+    // }
+  }
+
+  render () {
+    return (
+      <div className="main-iframe">
+        <Spin size="large" />
+      </div>
+    )
+  }
+}
+
+export default MkIframe
\ No newline at end of file
diff --git a/src/views/mkiframe/index.scss b/src/views/mkiframe/index.scss
new file mode 100644
index 0000000..2a3cc64
--- /dev/null
+++ b/src/views/mkiframe/index.scss
@@ -0,0 +1,7 @@
+.main-iframe {
+  .ant-spin {
+    position: absolute;
+    left: calc(50vw - 22px);
+    top: 45vh;
+  }
+}
\ No newline at end of file
diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index fd1711e..7c8d241 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -81,7 +81,25 @@
   }
 
   UNSAFE_componentWillMount() {
+    if (sessionStorage.getItem('devError') === 'true') {
+      sessionStorage.clear()
+      window.history.replaceState(null, null, window.location.href.split('#')[0] + '#/login')
+      window.location.reload()
+      return
+    }
+    
+    if (!sessionStorage.getItem('UserID')) {
+      sessionStorage.removeItem('isEditState')
+      sessionStorage.removeItem('editMenuType')
+      sessionStorage.removeItem('appType')
+      this.props.history.replace('/login')
+      return
+    }
+    
     if (memberLevel < 30) return
+
+    window.GLOB.developing = true
+
     try {
       let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
 
@@ -103,6 +121,7 @@
         window.GLOB.winHeight = 738
         window.GLOB.shellWidth = 376
         window.GLOB.shellHeight = 680
+        window.GLOB.curDate = moment().format('YYYY-MM-DD')
 
         let adapters = sessionStorage.getItem('adapter')
         if (adapters) {
@@ -139,6 +158,7 @@
   }
 
   componentDidMount () {
+    if (!sessionStorage.getItem('UserID')) return
     if (memberLevel < 30) {
       document.getElementById('mk-mob-design-view').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh; height: 100vh; background: #fff;">鏈簲鐢ㄦ病鏈塒C绔〉闈㈢殑缂栬緫鏉冮檺锛岃鑱旂郴绠$悊鍛橈紒</div>'
       return
@@ -1721,6 +1741,7 @@
     this.setState({
       menuloading: false
     })
+
     if (!error) {
       notification.warning({
         top: 92,
diff --git a/src/views/mobdesign/menuform/index.jsx b/src/views/mobdesign/menuform/index.jsx
index 8a6b1b7..b6371cf 100644
--- a/src/views/mobdesign/menuform/index.jsx
+++ b/src/views/mobdesign/menuform/index.jsx
@@ -168,9 +168,10 @@
               {getFieldDecorator('timeUnit', {
                 initialValue: config.timeUnit || 'day'
               })(
-                <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}>
+                <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}>
                   <Radio value="day">澶�</Radio>
                   <Radio value="hour">灏忔椂</Radio>
+                  <Radio value="minute">鍒嗛挓</Radio>
                 </Radio.Group>
               )}
             </Form.Item>
@@ -186,7 +187,7 @@
                   }
                 ]
               })(
-                <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={this.changeCacheDay}/>
+                <InputNumber min={1} max={config.timeUnit === 'day' ? 7 : (config.timeUnit === 'hour' ? 23 : 59)} precision={0} onChange={this.changeCacheDay}/>
               )}
             </Form.Item>
           </Col> : null}
diff --git a/src/views/mobdesign/popview/menuform/index.jsx b/src/views/mobdesign/popview/menuform/index.jsx
index d2899a2..e84a5af 100644
--- a/src/views/mobdesign/popview/menuform/index.jsx
+++ b/src/views/mobdesign/popview/menuform/index.jsx
@@ -86,9 +86,10 @@
               {getFieldDecorator('timeUnit', {
                 initialValue: config.timeUnit || 'day'
               })(
-                <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}>
+                <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}>
                   <Radio value="day">澶�</Radio>
                   <Radio value="hour">灏忔椂</Radio>
+                  <Radio value="minute">鍒嗛挓</Radio>
                 </Radio.Group>
               )}
             </Form.Item>
@@ -104,7 +105,7 @@
                   }
                 ]
               })(
-                <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={this.changeCacheDay}/>
+                <InputNumber min={1} max={config.timeUnit === 'day' ? 7 : (config.timeUnit === 'hour' ? 23 : 59)} precision={0} onChange={this.changeCacheDay}/>
               )}
             </Form.Item>
           </Col> : null}
diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx
index 38beaf3..a8dcca3 100644
--- a/src/views/pcdesign/index.jsx
+++ b/src/views/pcdesign/index.jsx
@@ -76,14 +76,30 @@
   }
 
   UNSAFE_componentWillMount() {
+    if (sessionStorage.getItem('devError') === 'true') {
+      sessionStorage.clear()
+      window.history.replaceState(null, null, window.location.href.split('#')[0] + '#/login')
+      window.location.reload()
+      return
+    }
+    
+    if (!sessionStorage.getItem('UserID')) {
+      sessionStorage.removeItem('isEditState')
+      sessionStorage.removeItem('appType')
+      this.props.history.replace('/login')
+      return
+    }
+    
     if (memberLevel < 30) return
 
     sessionStorage.setItem('editMenuType', 'menu') // 缂栬緫鑿滃崟绫诲瀷
 
+    window.GLOB.curDate = moment().format('YYYY-MM-DD')
     window.GLOB.TabsMap = new Map()          // 缂撳瓨鐢ㄦ埛鎿嶄綔鐨勬爣绛鹃〉
     window.GLOB.CacheIndependent = new Map()
     window.GLOB.urlFields = []               // url鍙橀噺
     window.GLOB.customMenu = null            // 淇濆瓨鑿滃崟淇℃伅
+    window.GLOB.developing = true
 
     try {
       let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
@@ -123,6 +139,7 @@
   }
 
   componentDidMount () {
+    if (!sessionStorage.getItem('UserID')) return
     if (memberLevel < 30) {
       document.getElementById('mk-pc-design-view').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh; height: 100vh; background: #fff;">鏈簲鐢ㄦ病鏈塒C绔〉闈㈢殑缂栬緫鏉冮檺锛岃鑱旂郴绠$悊鍛橈紒</div>'
       return
@@ -1442,6 +1459,7 @@
     this.setState({
       menuloading: false
     })
+
     if (!error) {
       notification.warning({
         top: 92,
diff --git a/src/views/pcdesign/menuform/index.jsx b/src/views/pcdesign/menuform/index.jsx
index 7bc9112..8c6262b 100644
--- a/src/views/pcdesign/menuform/index.jsx
+++ b/src/views/pcdesign/menuform/index.jsx
@@ -187,9 +187,10 @@
               {getFieldDecorator('timeUnit', {
                 initialValue: config.timeUnit || 'day'
               })(
-                <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}>
+                <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}>
                   <Radio value="day">澶�</Radio>
                   <Radio value="hour">灏忔椂</Radio>
+                  <Radio value="minute">鍒嗛挓</Radio>
                 </Radio.Group>
               )}
             </Form.Item>
@@ -205,7 +206,7 @@
                   }
                 ]
               })(
-                <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={this.changeCacheDay}/>
+                <InputNumber min={1} max={config.timeUnit === 'day' ? 7 : (config.timeUnit === 'hour' ? 23 : 59)} precision={0} onChange={this.changeCacheDay}/>
               )}
             </Form.Item>
           </Col> : null}
diff --git a/src/views/tabledesign/index.jsx b/src/views/tabledesign/index.jsx
index 507484b..759be21 100644
--- a/src/views/tabledesign/index.jsx
+++ b/src/views/tabledesign/index.jsx
@@ -63,12 +63,28 @@
   }
 
   UNSAFE_componentWillMount() {
+    if (sessionStorage.getItem('devError') === 'true') {
+      sessionStorage.clear()
+      window.history.replaceState(null, null, window.location.href.split('#')[0] + '#/login')
+      window.location.reload()
+      return
+    }
+    
+    if (!sessionStorage.getItem('UserID')) {
+      sessionStorage.removeItem('isEditState')
+      sessionStorage.removeItem('appType')
+      this.props.history.replace('/login')
+      return
+    }
+    
     sessionStorage.setItem('editMenuType', 'menu') // 缂栬緫鑿滃崟绫诲瀷
 
+    window.GLOB.curDate = moment().format('YYYY-MM-DD')
     window.GLOB.UserComponentMap = new Map() // 缂撳瓨鐢ㄦ埛鑷畾涔夌粍浠�
     window.GLOB.TabsMap = new Map()          // 缂撳瓨鐢ㄦ埛鎿嶄綔鐨勬爣绛鹃〉
     window.GLOB.urlFields = []               // url鍙橀噺
     window.GLOB.customMenu = null            // 淇濆瓨鑿滃崟淇℃伅
+    window.GLOB.developing = true
 
     try {
       let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
@@ -95,6 +111,8 @@
   }
 
   componentDidMount () {
+    if (!sessionStorage.getItem('UserID')) return
+    
     MKEmitter.addListener('changePopview', this.initPopview)
     MKEmitter.addListener('triggerMenuSave', this.triggerMenuSave)
     setTimeout(() => {
@@ -692,6 +710,7 @@
     this.setState({
       menuloading: false
     })
+
     if (!error) {
       notification.warning({
         top: 92,
diff --git a/src/views/tabledesign/menuform/index.jsx b/src/views/tabledesign/menuform/index.jsx
index 0d1dcea..fe0a8e6 100644
--- a/src/views/tabledesign/menuform/index.jsx
+++ b/src/views/tabledesign/menuform/index.jsx
@@ -194,8 +194,6 @@
       })
     } else if (key === 'parentId') {
       this.props.updateConfig({...config, parentId: value})
-    } else if (key === 'timeUnit') {
-      this.props.updateConfig({...config, timeUnit: value})
     } else if (key === 'OpenType') {
       this.props.updateConfig({...config, OpenType: value})
     } else if (key === 'hidden') {

--
Gitblit v1.8.0