From b91c28df2f734b680198e755b7828666e238cea0 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期五, 21 六月 2024 16:43:44 +0800
Subject: [PATCH] Merge branch 'develop'

---
 src/templates/zshare/modalform/index.jsx                                           |   12 
 src/mob/searchconfig/index.jsx                                                     |   11 
 src/tabviews/zshare/actionList/funcbutton/index.jsx                                |   35 
 src/views/appmanage/transmenu/index.jsx                                            |  519 ++++
 src/components/resetPassword/index.jsx                                             |   23 
 src/menu/components/card/cardcellcomponent/elementform/index.jsx                   |   22 
 src/templates/zshare/verifycard/customscript/index.jsx                             |    2 
 src/menu/components/share/actioncomponent/dragaction/index.jsx                     |    2 
 src/tabviews/custom/popview/index.jsx                                              |   15 
 src/views/design/header/transmenu/index.scss                                       |   36 
 src/menu/components/table/edit-table/options.jsx                                   |   19 
 src/templates/sharecomponent/searchcomponent/searchform/index.scss                 |   11 
 src/views/systemfunc/index.jsx                                                     |   10 
 src/menu/components/table/edit-table/columns/editColumn/index.scss                 |    9 
 src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx  |   22 
 src/tabviews/zshare/actionList/newpagebutton/index.jsx                             |   16 
 src/views/design/sidemenu/index.jsx                                                |    4 
 src/tabviews/commontable/index.jsx                                                 |    6 
 src/components/header/loginform.jsx                                                |   19 
 src/menu/components/table/edit-table/columns/editColumn/index.jsx                  |   32 
 src/views/interface/index.jsx                                                      |   13 
 src/tabviews/zshare/actionList/changeuserbutton/index.jsx                          |    6 
 src/menu/datasource/verifycard/index.jsx                                           |    7 
 src/assets/css/main.scss                                                           |   43 
 src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx             |   20 
 src/menu/components/form/formaction/formconfig.jsx                                 |   33 
 src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx                   |    1 
 src/tabviews/custom/components/card/cardcellList/index.jsx                         |    6 
 src/menu/components/share/searchcomponent/dragsearch/index.jsx                     |    2 
 src/tabviews/zshare/actionList/funczip/index.jsx                                   |   27 
 src/menu/components/card/data-card/options.jsx                                     |   14 
 src/mob/components/menubar/normal-menubar/menucomponent/options.jsx                |    1 
 src/tabviews/custom/components/table/edit-table/normalTable/index.jsx              |  104 
 src/components/breadview/index.jsx                                                 |    8 
 src/tabviews/zshare/mutilform/index.jsx                                            |   73 
 src/templates/zshare/modalform/index.scss                                          |    9 
 src/menu/components/share/actioncomponent/actionform/index.jsx                     |    8 
 src/tabviews/custom/index.jsx                                                      |   17 
 src/views/systemproc/index.jsx                                                     |    8 
 src/templates/zshare/customscript/index.jsx                                        |    2 
 src/menu/components/table/normal-table/columns/index.jsx                           |   12 
 src/views/appmanage/submutilform/index.jsx                                         |   22 
 src/menu/components/table/edit-table/columns/index.jsx                             |   12 
 src/menu/datasource/verifycard/utils.jsx                                           |   50 
 src/views/design/header/index.jsx                                                  |   12 
 src/views/login/loginform.jsx                                                      |   96 
 src/views/printTemplate/index.jsx                                                  |   56 
 src/tabviews/zshare/topSearch/index.jsx                                            |   19 
 src/menu/components/form/formaction/actionform/index.jsx                           |   17 
 src/menu/components/card/cardcellcomponent/dragaction/index.jsx                    |    2 
 src/menu/components/table/base-table/columns/editColumn/formconfig.jsx             |   15 
 src/menu/components/form/simple-form/options.jsx                                   |   15 
 src/tabviews/zshare/actionList/exceloutbutton/index.jsx                            |   83 
 src/menu/components/form/simple-form/index.jsx                                     |    8 
 src/views/basedesign/index.jsx                                                     |  107 
 src/tabviews/custom/components/table/edit-table/index.jsx                          |    1 
 src/views/tabledesign/index.jsx                                                    |   42 
 src/tabviews/zshare/actionList/index.jsx                                           |    4 
 src/api/index.js                                                                   |   62 
 src/tabviews/zshare/topSearch/index.scss                                           |    5 
 src/templates/sharecomponent/actioncomponent/verifyprint/utils.jsx                 |    2 
 src/tabviews/subtable/index.jsx                                                    |    6 
 src/templates/zshare/codemirror/index.jsx                                          |    3 
 src/menu/sysinterface/index.jsx                                                    |    2 
 src/tabviews/custom/components/card/table-card/index.jsx                           |    2 
 src/menu/components/table/base-table/columns/editColumn/index.jsx                  |    9 
 public/manifest.json                                                               |    2 
 src/views/pcdesign/index.jsx                                                       |   52 
 src/menu/datasource/verifycard/settingform/index.jsx                               |   14 
 src/mob/components/formdragelement/index.jsx                                       |    2 
 src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx              |    2 
 src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx                  |    2 
 src/menu/components/share/actioncomponent/index.jsx                                |    2 
 src/menu/components/search/main-search/index.jsx                                   |   13 
 src/setupProxy.js                                                                  |    6 
 src/templates/sharecomponent/actioncomponent/dragaction/index.jsx                  |    2 
 src/menu/components/share/copycomponent/index.jsx                                  |    2 
 src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx        |    2 
 src/components/pasteboard/index.jsx                                                |    2 
 src/views/systemfunc/sidemenu/config.jsx                                           |    8 
 src/pc/createview/settingform/index.jsx                                            |    1 
 src/views/login/index.jsx                                                          |  121 
 src/utils/utils-datamanage.js                                                      |    7 
 src/templates/zshare/editTable/index.jsx                                           |    2 
 src/tabviews/zshare/actionList/popupbutton/index.jsx                               |   13 
 src/tabviews/zshare/normalTable/index.jsx                                          |    2 
 src/menu/components/share/searchcomponent/index.jsx                                |   11 
 src/utils/utils-custom.js                                                          |  793 +++++++
 src/views/main/index.jsx                                                           |   17 
 src/views/mkiframe/index.jsx                                                       |   11 
 src/tabviews/custom/components/share/normalTable/index.scss                        |   25 
 src/tabviews/zshare/actionList/excelInbutton/index.jsx                             |   55 
 src/views/design/header/transmenu/index.jsx                                        |  885 ++++++++
 src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx              |    6 
 src/menu/components/table/normal-table/columns/editColumn/index.jsx                |    9 
 src/tabviews/basetable/index.jsx                                                   |    8 
 src/menu/components/form/formaction/index.jsx                                      |    2 
 src/menu/tablenodes/index.jsx                                                      |    4 
 src/tabviews/custom/components/module/invoice/index.jsx                            |    4 
 src/views/billprint/index.jsx                                                      |    1 
 src/tabviews/subtabtable/index.jsx                                                 |    6 
 src/tabviews/zshare/actionList/normalbutton/index.jsx                              |  181 +
 src/views/design/sidemenu/editthdmenu/index.jsx                                    |    4 
 src/views/mobdesign/index.jsx                                                      |  214 +
 src/views/menudesign/index.jsx                                                     |   42 
 src/tabviews/custom/components/card/data-card/index.jsx                            |   27 
 src/components/normalform/modalform/mkSelect/index.jsx                             |   41 
 src/menu/components/card/double-data-card/options.jsx                              |   41 
 src/mob/colorsketch/index.jsx                                                      |    7 
 src/views/appmanage/index.scss                                                     |    8 
 src/menu/components/share/actioncomponent/formconfig.jsx                           |   42 
 src/templates/zshare/pasteform/index.jsx                                           |    2 
 src/views/login/logincloudform.jsx                                                 |   14 
 src/tabviews/zshare/mutilform/mkPopSelect/index.jsx                                |    1 
 src/menu/components/table/base-table/columns/index.jsx                             |   10 
 src/views/appmanage/index.jsx                                                      |  481 ++--
 src/menu/debug/index.jsx                                                           |    2 
 src/views/imdesign/index.jsx                                                       |  173 
 src/menu/components/search/main-search/options.jsx                                 |   12 
 src/views/design/sidemenu/thdmenuplus/index.jsx                                    |    4 
 src/templates/sharecomponent/searchcomponent/index.scss                            |   10 
 src/tabviews/zshare/normalTable/index.scss                                         |   10 
 src/templates/sharecomponent/searchcomponent/searchform/index.jsx                  |   17 
 src/components/tabview/index.jsx                                                   |    6 
 src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx           |   15 
 src/mob/searchconfig/searchdragelement/index.jsx                                   |    2 
 src/tabviews/custom/components/card/double-data-card/index.scss                    |   40 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx |    2 
 src/components/resetPassword/resetpwd/index.jsx                                    |   57 
 src/menu/components/table/normal-table/options.jsx                                 |   21 
 src/views/appcheck/index.jsx                                                       |  220 +-
 src/components/header/index.jsx                                                    |   47 
 src/tabviews/custom/components/card/double-data-card/index.jsx                     |   43 
 src/templates/zshare/verifycard/callbackcustomscript/index.jsx                     |    2 
 src/menu/datasource/verifycard/customscript/index.jsx                              |    4 
 src/templates/sharecomponent/searchcomponent/index.jsx                             |   18 
 src/views/rolemanage/index.jsx                                                     |  107 
 src/tabviews/custom/components/calendar/board/index.jsx                            |    4 
 src/templates/sharecomponent/columncomponent/index.jsx                             |    2 
 src/templates/zshare/verifycard/customform/index.jsx                               |    2 
 src/tabviews/custom/components/share/normalTable/index.jsx                         |   25 
 src/templates/modalconfig/dragelement/index.jsx                                    |    2 
 src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx       |    1 
 src/tabviews/zshare/actionList/normalbutton/mkcounter/index.jsx                    |   14 
 src/tabviews/custom/components/card/data-card/index.scss                           |   26 
 src/menu/components/search/main-search/index.scss                                  |   11 
 src/utils/utils.js                                                                 |   24 
 src/index.js                                                                       |  112 
 src/views/sso/index.jsx                                                            |   12 
 src/menu/components/search/main-search/dragsearch/index.jsx                        |    2 
 src/tabviews/zshare/actionList/tabbutton/index.jsx                                 |   18 
 src/components/normalform/modalform/index.jsx                                      |    2 
 src/templates/zshare/formconfig.jsx                                                |   20 
 src/menu/components/table/base-table/options.jsx                                   |   20 
 src/pc/createview/index.jsx                                                        |    4 
 src/tabviews/zshare/actionList/printbutton/index.jsx                               |   88 
 src/store/options.js                                                               |   15 
 src/views/appmanage/transmenu/index.scss                                           |   16 
 /dev/null                                                                          |   17 
 src/tabviews/custom/components/table/edit-table/normalTable/index.scss             |   10 
 src/menu/components/card/cardcellcomponent/formconfig.jsx                          |   15 
 161 files changed, 4,635 insertions(+), 1,739 deletions(-)

diff --git a/public/manifest.json b/public/manifest.json
index 6f976ee..61ef54c 100644
--- a/public/manifest.json
+++ b/public/manifest.json
@@ -6,5 +6,5 @@
   "display": "standalone",
   "theme_color": "#000000",
   "background_color": "#ffffff",
-  "mk_version": "20240501"
+  "mk_version": "20240601"
 }
diff --git a/src/api/index.js b/src/api/index.js
index f1c531d..50f5937 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -15,7 +15,8 @@
 window.GLOB.$error = false
 
 let service = window.GLOB.service ? '-' + window.GLOB.service.replace('/', '') : ''
-let db = `mkdb${service}`
+let lang = sessionStorage.getItem('lang') !== 'zh-CN' ? sessionStorage.getItem('lang') : ''
+let db = `mkdb${service + lang}`
 
 if (window.indexedDB) {
   CacheUtils.openIndexDB(db)
@@ -97,13 +98,16 @@
   }
 
   /**
-   * @description 寰俊涓氬姟璇锋眰
+   * @description 寰俊涓氬姟璇锋眰 鍘熸帴鍙� 'wxpay/getaccesstoken'
    */
   wxAccessToken (domain = '') {
-    let _url = window.GLOB.baseurl + 'wxpay/getaccesstoken'
+    let _url = domain || window.GLOB.baseurl 
 
-    if (domain) {
-      _url = domain + 'wxpay/getaccesstoken'
+    if (/qingqiumarket.cn|cloud.mk9h.cn/.test(_url)) {
+      _url = _url.replace('http://qingqiumarket.cn', 'http://qingqiumarket.cn:8080')
+      _url = _url.replace('http://cloud.mk9h.cn', 'http://cloud.mk9h.cn:8080')
+      _url = _url.replace('https://qingqiumarket.cn', 'https://qingqiumarket.cn:8443')
+      _url = _url.replace('https://cloud.mk9h.cn', 'https://cloud.mk9h.cn:8443')
     }
 
     return new Promise(resolve => {
@@ -112,13 +116,15 @@
       } else {
         window.GLOB.accessToken = {domain}
         axios({
-          url: _url,
-          method: 'get'
+          url: _url + 'wechat/jsapi/getaccesstoken',
+          method: 'post',
+          headers: { 'Content-Type': 'application/json' },
+          data: JSON.stringify({appId: 'wx4d8a34c8d4494872'})
         }).then(res => {
-          if (res.oa_access_token || res.mini_access_token) {
+          if (res.oa_access_token) {
             window.GLOB.accessToken.accessTime = parseInt(new Date().getTime() / 1000)
             window.GLOB.accessToken.oa_access_token = res.oa_access_token
-            window.GLOB.accessToken.mini_access_token = res.mini_access_token
+            // window.GLOB.accessToken.mini_access_token = res.mini_access_token
           }
           resolve(res)
         })
@@ -128,6 +134,7 @@
 
   /**
    * @description 寰俊涓氬姟璇锋眰
+   * 39涓� qingqiumarket.cn|cloud.mk9h.cn|sso.mk9h.cn
    */
   wxNginxRequest (url, method, param) {
     let _url = url
@@ -137,16 +144,11 @@
       if (process.env.NODE_ENV === 'production') {
         _url = document.location.origin + '/' + url
       }
-      if (/^http:\/\/(qingqiumarket.cn|cloud.mk9h.cn|sso.mk9h.cn)/.test(_url)) {
-        _url = window.GLOB.location + ':8080/' + url
-        if (process.env.NODE_ENV === 'production') {
-          _url = document.location.origin + ':8080/' + url
-        }
-      } else if (/^https:\/\/(qingqiumarket.cn|cloud.mk9h.cn|sso.mk9h.cn)/.test(_url)) {
-        _url = window.GLOB.location + ':8443/' + url
-        if (process.env.NODE_ENV === 'production') {
-          _url = document.location.origin + ':8443/' + url
-        }
+      if (/qingqiumarket.cn|cloud.mk9h.cn/.test(_url)) {
+        _url = _url.replace('http://qingqiumarket.cn', 'http://qingqiumarket.cn:8080')
+        _url = _url.replace('http://cloud.mk9h.cn', 'http://cloud.mk9h.cn:8080')
+        _url = _url.replace('https://qingqiumarket.cn', 'https://qingqiumarket.cn:8443')
+        _url = _url.replace('https://cloud.mk9h.cn', 'https://cloud.mk9h.cn:8443')
       }
     }
     
@@ -1028,16 +1030,11 @@
     if (process.env.NODE_ENV === 'production') {
       _url = document.location.origin + '/file/oss/upload'
     }
-    if (/^http:\/\/(qingqiumarket.cn|cloud.mk9h.cn|sso.mk9h.cn)/.test(_url)) {
-      _url = window.GLOB.location + ':8080/file/oss/upload'
-      if (process.env.NODE_ENV === 'production') {
-        _url = document.location.origin + ':8080/file/oss/upload'
-      }
-    } else if (/^https:\/\/(qingqiumarket.cn|cloud.mk9h.cn|sso.mk9h.cn)/.test(_url)) {
-      _url = window.GLOB.location + ':8443/file/oss/upload'
-      if (process.env.NODE_ENV === 'production') {
-        _url = document.location.origin + ':8443/file/oss/upload'
-      }
+    if (/qingqiumarket.cn|cloud.mk9h.cn/.test(_url)) {
+      _url = _url.replace('http://qingqiumarket.cn', 'http://qingqiumarket.cn:8080')
+      _url = _url.replace('http://cloud.mk9h.cn', 'http://cloud.mk9h.cn:8080')
+      _url = _url.replace('https://qingqiumarket.cn', 'https://qingqiumarket.cn:8443')
+      _url = _url.replace('https://cloud.mk9h.cn', 'https://cloud.mk9h.cn:8443')
     }
     
     return axios({
@@ -1087,7 +1084,7 @@
   /**
    * @description sql妫�楠�
    */
-  sDebug (sql, rduri = null) {
+  sDebug (sql) {
     let param = {
       func: 's_debug_sql',
       exec_type: window.GLOB.execType || 'y',
@@ -1106,6 +1103,7 @@
     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(/@lang@/ig, `'${sessionStorage.getItem('lang')}'`)
     // sql = sql.replace(/@datam@/ig, `''`)
 
     if (window.GLOB.externalDatabase !== null) {
@@ -1122,10 +1120,6 @@
     param = this.encryptParam(param)
 
     let url = '/webapi/dostars'
-
-    if (rduri) {
-      url = rduri
-    }
 
     let timer = setTimeout(() => {
       let _param = {
diff --git a/src/assets/css/main.scss b/src/assets/css/main.scss
index 41db689..d9a3e78 100644
--- a/src/assets/css/main.scss
+++ b/src/assets/css/main.scss
@@ -728,6 +728,49 @@
     vertical-align: bottom;
   }
 }
+.fixed-table-height {
+  tr, td, th {
+    overflow: hidden;
+  }
+  ::-webkit-scrollbar {
+    width: 17px;
+    height: 17px;
+  }
+  ::-webkit-scrollbar-thumb {
+    background: rgba(193, 193, 193, 0.7);
+  }
+  ::-webkit-scrollbar-track {
+    background: #fafafa;
+  }
+  .ant-table-body {
+    min-height: 1px;
+    border-bottom: 1px solid rgba(0, 0, 0, .05);
+    .ant-table-fixed {
+      border-bottom: 0;
+    }
+  }
+}
+@media screen and (max-width: 1400px) {
+  .fixed-table-height {
+    ::-webkit-scrollbar {
+      width: 16px;
+    }
+  }
+}
+@media screen and (min-width: 1600px) {
+  .fixed-table-height {
+    ::-webkit-scrollbar {
+      width: 18px;
+    }
+  }
+}
+@media screen and (min-width: 1900px) {
+  .fixed-table-height {
+    ::-webkit-scrollbar {
+      width: 21px;
+    }
+  }
+}
 
 // 绯荤粺鑹茶缃�
 .mk-main-view {
diff --git a/src/components/breadview/index.jsx b/src/components/breadview/index.jsx
index 44494c8..ac52d25 100644
--- a/src/components/breadview/index.jsx
+++ b/src/components/breadview/index.jsx
@@ -18,7 +18,9 @@
 const Iframe = asyncComponent(() => import('@/tabviews/iframe'))
 const RoleManage = asyncComponent(() => import('@/tabviews/rolemanage'))
 
-moment.locale('zh-cn')
+if (sessionStorage.getItem('lang') === 'zh-CN') {
+  moment.locale('zh-cn')
+}
 
 class BreadView extends Component {
   state = {
@@ -32,7 +34,7 @@
   UNSAFE_componentWillMount () {
     let home = {
       MenuID: 'home_page_id',
-      MenuName: '棣栭〉',
+      MenuName: window.GLOB.dict['home'] || '棣栭〉',
       type: 'Home'
     }
     this.setState({tabview: home})
@@ -138,7 +140,7 @@
   gotoHome = () => {
     let home = {
       MenuID: 'home_page_id',
-      MenuName: '棣栭〉',
+      MenuName: window.GLOB.dict['home'] || '棣栭〉',
       type: 'Home'
     }
     this.setState({tabview: home})
diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index 1a8b396..2204476 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -34,7 +34,8 @@
     thdMenuList: [],
     debug: sessionStorage.getItem('debug') === 'true' && window.GLOB.memberLevel > 0,
     collapse: sessionStorage.getItem('collapse') === 'true',
-    lang: sessionStorage.getItem('lang') || ''
+    lang: sessionStorage.getItem('lang') || '',
+    dict: window.GLOB.dict
   }
 
   UNSAFE_componentWillMount () {
@@ -113,16 +114,18 @@
   }
 
   logout = () => {
+    const { dict } = this.state
     // 閫�鍑虹櫥褰�
     let _this = this
     confirm({
-      title: '鎮ㄧ‘瀹氳閫�鍑哄悧?',
+      title: dict['logout_query'] || '鎮ㄧ‘瀹氳閫�鍑哄悧锛�',
       content: '',
-      okText: '纭畾',
-      cancelText: '鍙栨秷',
+      okText: dict['ok'] || '纭畾',
+      cancelText: dict['cancel'] || '鍙栨秷',
       onOk() {
         sessionStorage.clear()
         _this.props.history.replace('/login')
+        window.location.reload()
       },
       onCancel() {}
     })
@@ -441,11 +444,10 @@
 
           sessionStorage.setItem('CloudLogo', res.open_logo || '')
 
-          let _url = window.location.href.split('#')[0] + 'cloud'
           if (param.remember) {
-            localStorage.setItem(_url, window.btoa(window.encodeURIComponent(JSON.stringify({time: new Date().getTime(), username: param.username, password: param.password}))))
+            localStorage.setItem(window.GLOB.sysSign + 'cloud', window.btoa(window.encodeURIComponent(JSON.stringify({time: new Date().getTime(), username: param.username, password: param.password}))))
           } else {
-            localStorage.setItem(_url, window.btoa(window.encodeURIComponent(JSON.stringify({time: new Date().getTime(), username: param.username, password: ''}))))
+            localStorage.setItem(window.GLOB.sysSign + 'cloud', window.btoa(window.encodeURIComponent(JSON.stringify({time: new Date().getTime(), username: param.username, password: ''}))))
           }
 
           window.GLOB.mainMenu = null
@@ -563,15 +565,19 @@
   }
 
   verup = () => {
+    const { dict } = this.state
+
     confirm({
-      title: '椤甸潰鏇存柊',
-      content: '閲嶆柊鍔犺浇搴旂敤淇℃伅',
+      title: dict['page_upd'] || '椤甸潰鏇存柊',
+      content: dict['reload_app'] || '閲嶆柊鍔犺浇搴旂敤淇℃伅',
+      okText: dict['ok'] || '纭畾',
+      cancelText: dict['cancel'] || '鍙栨秷',
       onOk() {
         return new Promise(resolve => {
           if (!window.GLOB.IndexDB) {
             notification.warning({
               top: 92,
-              message: '鏇存柊澶辫触锛岃鍒锋柊椤甸潰閲嶈瘯锛�',
+              message: dict['exc_fail'] || '鏇存柊澶辫触锛岃鍒锋柊椤甸潰閲嶈瘯锛�',
               duration: 2
             })
             resolve()
@@ -583,7 +589,7 @@
             setTimeout(() => {
               notification.success({
                 top: 92,
-                message: '鏇存柊鎴愬姛锛�',
+                message: dict['exc_success'] || '鏇存柊鎴愬姛锛�',
                 duration: 2
               })
               resolve()
@@ -597,7 +603,8 @@
 
   about = () => {
     Modal.success({
-      title: '绯荤粺鐗堟湰v' + window.GLOB.appVersion
+      title: (window.GLOB.dict['sys_ver'] || '绯荤粺鐗堟湰') + ' v' + window.GLOB.appVersion,
+      okText: window.GLOB.dict['got_it'] || '鐭ラ亾浜�',
     })
   }
 
@@ -608,32 +615,32 @@
   }
 
   render () {
-    const { thdMenuList, searchkey, debug, menulist, collapse } = this.state
+    const { thdMenuList, searchkey, debug, menulist, collapse, dict } = this.state
     const navBar = window.GLOB.navBar
 
     const menu = (
       <Menu className="header-dropdown">
         {debug && <Menu.Item key="switch">
-          缂栬緫
+          {dict['edit'] || '缂栬緫'}
           <Switch size="small" style={{marginLeft: '7px'}} checked={false} onChange={this.changeEditState} />
         </Menu.Item>}
-        <Menu.Item key="password" onClick={this.changePassword}>淇敼瀵嗙爜</Menu.Item>
-        {this.state.systems.length ? <Menu.SubMenu style={{minWidth: '110px'}} title="鍒囨崲绯荤粺">
+        <Menu.Item key="password" onClick={this.changePassword}>{dict['ch_pwd'] || '淇敼瀵嗙爜'}</Menu.Item>
+        {this.state.systems.length ? <Menu.SubMenu style={{minWidth: '110px'}} title={dict['swt_sys'] || '鍒囨崲绯荤粺'}>
           {this.state.systems.map((system, index) => (
             <Menu.Item style={{minWidth: '100px', lineHeight: '30px'}} key={'sub' + index} onClick={() => {this.changeSystem(system)}}> {system.AppName} </Menu.Item>
           ))}
         </Menu.SubMenu> : null}
-        <Menu.Item key="doc" onClick={this.gotoDoc}>鏂囨。涓績</Menu.Item>
+        <Menu.Item key="doc" onClick={this.gotoDoc}>{dict['doc_center'] || '鏂囨。涓績'}</Menu.Item>
         <Menu.Item key="verup" onClick={this.verup}>
-          椤甸潰鏇存柊
+          {dict['page_upd'] || '椤甸潰鏇存柊'}
         </Menu.Item>
         {window.GLOB.WXNotice ? <Menu.Item key="wxnotice" onClick={() => this.setState({wxVisible: true})}>
           寰俊娑堟伅
         </Menu.Item> : null}
         {window.GLOB.appVersion ? <Menu.Item key="version" onClick={this.about}>
-          鍏充簬
+          {dict['about'] || '鍏充簬'}
         </Menu.Item> : null}
-        <Menu.Item key="logout" onClick={this.logout}>閫�鍑�</Menu.Item>
+        <Menu.Item key="logout" onClick={this.logout}>{dict['logout'] || '閫�鍑�'}</Menu.Item>
       </Menu>
     )
 
diff --git a/src/components/header/loginform.jsx b/src/components/header/loginform.jsx
index 95e702f..5154a9c 100644
--- a/src/components/header/loginform.jsx
+++ b/src/components/header/loginform.jsx
@@ -3,8 +3,6 @@
 import { Form, Input, Checkbox } from 'antd'
 import { UserOutlined, LockOutlined } from '@ant-design/icons'
 
-import zhCN from '@/locales/zh-CN/login.js'
-import enUS from '@/locales/en-US/login.js'
 import './index.scss'
 
 class HeaderLoginForm extends Component {
@@ -13,7 +11,6 @@
   }
 
   state = {
-    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
     remember: false,
     username: '',
     password: '',
@@ -22,8 +19,7 @@
   }
 
   UNSAFE_componentWillMount () {
-    let _url = window.location.href.split('#')[0] + 'cloud'
-    let _user = localStorage.getItem(_url)
+    let _user = localStorage.getItem(window.GLOB.sysSign + 'cloud')
     
     if (_user) {
       try {
@@ -36,7 +32,7 @@
 
     if (_user && new Date().getTime() - _user.time > 1000 * 7 * 24 * 60 * 60) {
       _user = ''
-      localStorage.removeItem(_url)
+      localStorage.removeItem(window.GLOB.sysSign + 'cloud')
     }
 
     if (_user) {
@@ -86,10 +82,9 @@
 
   rememberChange = (e) => {
     let val = e.target.checked
-    let _url = window.location.href.split('#')[0] + 'cloud'
 
     if (!val) {
-      localStorage.removeItem(_url)
+      localStorage.removeItem(window.GLOB.sysSign + 'cloud')
     }
   }
 
@@ -116,12 +111,12 @@
         </Form.Item> : null}
         <Form.Item style={{marginBottom: '0px', height: '60px'}}>
           {getFieldDecorator('username', {
-            rules: [{ required: true, message: this.state.dict['login.username.empty'] }],
+            rules: [{ required: true, message: '璇疯緭鍏ョ敤鎴峰悕' }],
             initialValue: username,
           })(
             <Input
               prefix={<UserOutlined style={{ color: 'rgba(0,0,0,.25)' }}/>}
-              placeholder={this.state.dict['login.username']}
+              placeholder="鐢ㄦ埛鍚�"
               autoComplete="off"
               onPressEnter={(e) => {this.handleSubmit(e, 'password')}}
             />
@@ -133,10 +128,10 @@
             rules: [
               {
                 required: true,
-                message: this.state.dict['login.password.empty'],
+                message: '璇疯緭鍏ュ瘑鐮�',
               }
             ]
-          })(<Input.Password onPressEnter={(e) => {this.handleSubmit(e, 'username')}} placeholder={this.state.dict['login.password']} prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />} />)}
+          })(<Input.Password onPressEnter={(e) => {this.handleSubmit(e, 'username')}} placeholder="瀵嗙爜" prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />} />)}
         </Form.Item>
         {window.GLOB.keepKey ? <Form.Item style={{marginBottom: '10px'}}>
           {getFieldDecorator('remember', {
diff --git a/src/components/normalform/modalform/index.jsx b/src/components/normalform/modalform/index.jsx
index c685080..e30a12a 100644
--- a/src/components/normalform/modalform/index.jsx
+++ b/src/components/normalform/modalform/index.jsx
@@ -385,7 +385,7 @@
     }
 
     return (
-      <Form {...formItemLayout} className="normal-form-field">
+      <Form {...formItemLayout} className="normal-form-field" id="normal-form-field">
         <Row gutter={24}>{this.getFields()}</Row>
       </Form>
     )
diff --git a/src/components/normalform/modalform/mkSelect/index.jsx b/src/components/normalform/modalform/mkSelect/index.jsx
index abbd6ac..4b8ee1a 100644
--- a/src/components/normalform/modalform/mkSelect/index.jsx
+++ b/src/components/normalform/modalform/mkSelect/index.jsx
@@ -1,4 +1,4 @@
-import React, {Component} from 'react'
+import React, { Component } from 'react'
 import { is, fromJS } from 'immutable'
 import { Select } from 'antd'
 
@@ -115,24 +115,7 @@
     const { value, config, options } = this.state
 
     if (config.type !== 'multiselect') {
-      if (config.extendName) {
-        return (
-          <Select
-            showSearch
-            allowClear
-            value={value}
-            dropdownMatchSelectWidth={config.dropdown !== 'false'}
-            filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
-              option.props.extend.toLowerCase().indexOf(input.toLowerCase()) >= 0}
-            onSelect={this.selectChange}
-            onChange={(val) => val === undefined && this.selectChange('')}
-          >
-            {options.map((option, i) =>
-              <Select.Option key={i} disabled={option.disabled} title={option.label || option.text} extend={option[config.extendName] || ''} value={option.value || option.field || ''}>{option.label || option.text}</Select.Option>
-            )}
-          </Select>
-        )
-      } else {
+      if (config.joint) {
         return (
           <Select
             showSearch
@@ -142,13 +125,30 @@
             filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
             onSelect={this.selectChange}
             onChange={(val) => val === undefined && this.selectChange('')}
+            getPopupContainer={() => document.getElementById('normal-form-field')}
           >
             {options.map((option, i) =>
-              <Select.Option key={i} disabled={option.disabled} value={option.value || option.field || ''}>{option.label || option.text}</Select.Option>
+              <Select.Option key={i} disabled={option.disabled} value={option.field || ''}>{`${option.label}锛�${option.field}锛塦}</Select.Option>
             )}
           </Select>
         )
       }
+      return (
+        <Select
+          showSearch
+          allowClear
+          value={value}
+          dropdownMatchSelectWidth={config.dropdown !== 'false'}
+          filterOption={(input, option) => (option.props.children + option.props.extend).toLowerCase().indexOf(input.toLowerCase()) >= 0}
+          onSelect={this.selectChange}
+          onChange={(val) => val === undefined && this.selectChange('')}
+          getPopupContainer={() => document.getElementById('normal-form-field')}
+        >
+          {options.map((option, i) =>
+            <Select.Option key={i} disabled={option.disabled} title={option.label || option.text} extend={config.extendName ? (option[config.extendName] || '') : ''} value={option.value || option.field || ''}>{option.label || option.text}</Select.Option>
+          )}
+        </Select>
+      )
     } else {
       return (<Select
         showSearch
@@ -156,6 +156,7 @@
         defaultValue={value}
         filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
         onChange={this.mutilselectChange}
+        getPopupContainer={() => document.getElementById('normal-form-field')}
       >
         {options.map((option, i) =>
           <Select.Option key={i} disabled={option.disabled} value={option.value || option.field}>{option.label || option.text}</Select.Option>
diff --git a/src/components/pasteboard/index.jsx b/src/components/pasteboard/index.jsx
index aae3fa1..c7a79a1 100644
--- a/src/components/pasteboard/index.jsx
+++ b/src/components/pasteboard/index.jsx
@@ -46,7 +46,7 @@
       _config = JSON.parse(window.decodeURIComponent(window.atob(_config)))
 
       if (typeof(_config) === 'object' && _config.$srcId) {
-        let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+        let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
         if (srcid && _config.$srcId !== srcid) {
           notification.warning({
             top: 92,
diff --git a/src/components/resetPassword/index.jsx b/src/components/resetPassword/index.jsx
index 71ca86a..de2862b 100644
--- a/src/components/resetPassword/index.jsx
+++ b/src/components/resetPassword/index.jsx
@@ -14,7 +14,8 @@
     visible: false,
     loading: false,
     type: 'account',
-    okText: '纭畾',
+    okText: window.GLOB.dict['ok'] || '纭畾',
+    dict: window.GLOB.dict,
     smsId: '',
     mob: '',
     code: ''
@@ -40,7 +41,7 @@
       visible: true,
       loading: false,
       type: 'account',
-      okText: '纭畾',
+      okText: window.GLOB.dict['ok'] || '纭畾',
       mob: '',
       code: '',
       smsId: sessionStorage.getItem('mk_sms_id') || ''
@@ -48,7 +49,7 @@
   }
 
   resetPwdSubmit = () => {
-    const { type } = this.state
+    const { type, dict } = this.state
 
     if (type === 'account') {
       this.formRef.handleConfirm().then(res => {
@@ -77,7 +78,7 @@
             })
             notification.success({
               top: 92,
-              message: '淇敼鎴愬姛锛岃閲嶆柊鐧诲綍銆�',
+              message: dict['re_login'] || '淇敼鎴愬姛锛岃閲嶆柊鐧诲綍銆�',
               duration: 2
             })
             this.callback && this.callback()
@@ -98,7 +99,7 @@
         if (!/^1[3456789]\d{9}$/.test(res.phone)) {
           notification.warning({
             top: 92,
-            message: '鎵嬫満鍙锋牸寮忛敊璇紝璇烽噸濉紒',
+            message: dict['phone_error'] || '鎵嬫満鍙锋牸寮忛敊璇紝璇烽噸濉紒',
             duration: 5
           })
           return
@@ -114,7 +115,7 @@
         this.setState({
           code: res.vercode,
           type: 'phonepwd',
-          okText: '纭畾'
+          okText: dict['ok'] || '纭畾'
         })
       }, () => {})
     } else if (type === 'phonepwd') {
@@ -146,7 +147,7 @@
             })
             notification.success({
               top: 92,
-              message: '淇敼鎴愬姛锛岃閲嶆柊鐧诲綍銆�',
+              message: dict['re_login'] || '淇敼鎴愬姛锛岃閲嶆柊鐧诲綍銆�',
               duration: 2
             })
             this.callback && this.callback()
@@ -166,23 +167,23 @@
   }
 
   render() {
-    const { visible, loading, okText, type, mob, smsId } = this.state
+    const { visible, loading, okText, type, mob, smsId, dict } = this.state
 
     return (
       <Modal
-        title="淇敼瀵嗙爜"
+        title={dict['ch_pwd'] || '淇敼瀵嗙爜'}
         wrapClassName="reset-password-modal"
         visible={visible}
         maskClosable={false}
         onOk={this.resetPwdSubmit}
         onCancel={() => { this.setState({ visible: false })}}
         okText={okText}
-        cancelText="鍙栨秷"
+        cancelText={dict['cancel'] || '鍙栨秷'}
         confirmLoading={loading}
         destroyOnClose
       >
         <Resetpwd type={type} mob={mob} smsId={smsId} wrappedComponentRef={(inst) => this.formRef = inst} resetPwdSubmit={this.resetPwdSubmit}/>
-        {type === 'account' && smsId ? <div className="forget-pwd"><span onClick={() => this.setState({type: 'mob', okText: '涓嬩竴姝�'})}>蹇樿瀵嗙爜锛�</span></div> : null}
+        {type === 'account' && smsId ? <div className="forget-pwd"><span onClick={() => this.setState({type: 'mob', okText: dict['next'] || '涓嬩竴姝�'})}>{dict['forgot_pwd'] || '蹇樿瀵嗙爜锛�'}</span></div> : null}
       </Modal>
     )
   }
diff --git a/src/components/resetPassword/resetpwd/index.jsx b/src/components/resetPassword/resetpwd/index.jsx
index 514bab5..829571b 100644
--- a/src/components/resetPassword/resetpwd/index.jsx
+++ b/src/components/resetPassword/resetpwd/index.jsx
@@ -9,7 +9,8 @@
   state = {
     confirmDirty: false,
     autoCompleteResult: [],
-    level: localStorage.getItem(window.location.href.split('#')[0] + 'pwdlevel') || ''
+    level: localStorage.getItem(window.GLOB.sysSign + 'pwdlevel') || '',
+    dict: window.GLOB.dict,
   }
 
   LoginTimer = null
@@ -63,7 +64,7 @@
   compareToFirstPassword = (rule, value, callback) => {
     const { form } = this.props
     if (value && value !== form.getFieldValue('password')) {
-      callback('涓ゆ杈撳叆瀵嗙爜涓嶄竴鑷达紒')
+      callback(window.GLOB.dict['pwd_notM'] || '涓ゆ杈撳叆瀵嗙爜涓嶄竴鑷达紒')
     } else {
       callback()
     }
@@ -71,16 +72,16 @@
 
   validateToNextPassword = (rule, value, callback) => {
     const { form } = this.props
-    const { level } = this.state
+    const { level, dict } = this.state
 
     if (value && this.state.confirmDirty) {
       form.validateFields(['confirm'], { force: true })
     }
 
     if (level === 'letter_num' && value && /^[0-9a-zA-Z!@#$%^&*()_]*$/.test(value) && /^([^0-9]*|[^a-zA-Z]*)$/.test(value)) {
-      callback('瀵嗙爜涓繀椤诲惈鏈夋暟瀛楀拰瀛楁瘝銆�')
+      callback(dict['pwd_letter_num'] || '瀵嗙爜涓繀椤诲寘鍚暟瀛椾笌瀛楁瘝')
     } else if ((level === 'char_num' || level === 'char_num_90' || level === 'char_num_90_sms') && value && /^[0-9a-zA-Z!@#$%^&*()_]*$/.test(value) && /^([^0-9]*|[^a-zA-Z]*|[^!@#$%^&*()_]*)$/.test(value)) {
-      callback('瀵嗙爜涓繀椤诲惈鏈夋暟瀛椼�佸瓧姣嶅拰鐗规畩瀛楃銆�')
+      callback(dict['pwd_char_num'] || '瀵嗙爜涓繀椤诲惈鏈夋暟瀛椼�佸瓧姣嶄互鍙婄壒娈婂瓧绗�')
     } else {
       callback()
     }
@@ -191,12 +192,12 @@
   render() {
     const { type } = this.props
     const { getFieldDecorator } = this.props.form
-    const { level, delay, verdisabled } = this.state
+    const { level, delay, verdisabled, dict } = this.state
 
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
-        sm: { span: 6 }
+        sm: { span: 7 }
       },
       wrapperCol: {
         xs: { span: 24 },
@@ -208,38 +209,38 @@
     if (level) {
       rules.push({
         min: 8,
-        message: '瀵嗙爜闀垮害涓嶅彲灏忎簬8浣嶏紒'
+        message: dict['pwd_min'] || '瀵嗙爜闀垮害涓嶅彲灏忎簬8浣�'
       })
     }
 
     return (
       <>
         {type === 'account' ? <Form {...formItemLayout} onKeyDown={this.onEnterSubmit} id="reset-password-form">
-          <Form.Item label="鍘熷瘑鐮�">
+          <Form.Item label={dict['ori_pwd'] || '鍘熷瘑鐮�'}>
             {getFieldDecorator('originpwd', {
               rules: [
                 {
                   required: true,
-                  message: '璇疯緭鍏ュ師瀵嗙爜锛�'
+                  message: dict['oripwd_required'] || '璇疯緭鍏ュ師瀵嗙爜锛�'
                 }
               ]
             })(<Input.Password autoFocus/>)}
           </Form.Item>
-          <Form.Item label="鏂板瘑鐮�" hasFeedback>
+          <Form.Item label={dict['new_pwd'] || '鏂板瘑鐮�'} hasFeedback>
             {getFieldDecorator('password', {
               rules: [
                 {
                   required: true,
-                  message: '璇疯緭鍏ユ柊瀵嗙爜锛�'
+                  message: dict['newpwd_required'] || '璇疯緭鍏ユ柊瀵嗙爜锛�'
                 },
                 {
                   pattern: /^[0-9a-zA-Z!@#$%^&*()_]*$/ig,
-                  message: '瀵嗙爜鍙厑璁稿寘鍚暟瀛椼�佸瓧姣嶄互鍙�!@#$%&*()_銆�'
+                  message: dict['password_format'] || '瀵嗙爜鍙厑璁稿寘鍚暟瀛椼�佸瓧姣嶄互鍙�!@#$%&*()_銆�'
                 },
                 ...rules,
                 {
                   max: 50,
-                  message: '鏈�澶у瘑鐮侀暱搴︿负50浣嶏紒'
+                  message: dict['pwd_max'] || '瀵嗙爜闀垮害涓嶅彲瓒呰繃50涓瓧绗︼紒'
                 },
                 {
                   validator: this.validateToNextPassword
@@ -247,12 +248,12 @@
               ]
             })(<Input.Password />)}
           </Form.Item>
-          <Form.Item label="纭瀵嗙爜" hasFeedback>
+          <Form.Item label={dict['con_pwd'] || '纭瀵嗙爜'} hasFeedback>
             {getFieldDecorator('confirm', {
               rules: [
                 {
                   required: true,
-                  message: '璇风‘璁ゅ瘑鐮侊紒'
+                  message: dict['conpwd_required'] || '璇风‘璁ゅ瘑鐮侊紒'
                 },
                 {
                   validator: this.compareToFirstPassword
@@ -262,21 +263,21 @@
           </Form.Item>
         </Form> : null}
         {type === 'phonepwd' ? <Form {...formItemLayout} onKeyDown={(e) => e.key === 'Enter' && this.props.resetPwdSubmit()}>
-          <Form.Item label="鏂板瘑鐮�" hasFeedback>
+          <Form.Item label={dict['new_pwd'] || '鏂板瘑鐮�'} hasFeedback>
             {getFieldDecorator('password', {
               rules: [
                 {
                   required: true,
-                  message: '璇疯緭鍏ユ柊瀵嗙爜锛�'
+                  message: dict['newpwd_required'] || '璇疯緭鍏ユ柊瀵嗙爜锛�'
                 },
                 {
                   pattern: /^[0-9a-zA-Z!@#$%^&*()_]*$/ig,
-                  message: '瀵嗙爜鍙厑璁稿寘鍚暟瀛椼�佸瓧姣嶄互鍙�!@#$%&*()_銆�'
+                  message: dict['password_format'] || '瀵嗙爜鍙厑璁稿寘鍚暟瀛椼�佸瓧姣嶄互鍙�!@#$%&*()_銆�'
                 },
                 ...rules,
                 {
                   max: 50,
-                  message: '鏈�澶у瘑鐮侀暱搴︿负50浣嶏紒'
+                  message: dict['pwd_max'] || '瀵嗙爜闀垮害涓嶅彲瓒呰繃50涓瓧绗︼紒'
                 },
                 {
                   validator: this.validateToNextPassword
@@ -284,12 +285,12 @@
               ]
             })(<Input.Password />)}
           </Form.Item>
-          <Form.Item label="纭瀵嗙爜" hasFeedback>
+          <Form.Item label={dict['con_pwd'] || '纭瀵嗙爜'} hasFeedback>
             {getFieldDecorator('confirm', {
               rules: [
                 {
                   required: true,
-                  message: '璇风‘璁ゅ瘑鐮侊紒'
+                  message: dict['conpwd_required'] || '璇风‘璁ゅ瘑鐮侊紒'
                 },
                 {
                   validator: this.compareToFirstPassword
@@ -299,16 +300,16 @@
           </Form.Item>
         </Form> : null}
         {type === 'mob' ? <Form {...formItemLayout} onKeyDown={(e) => e.key === 'Enter' && this.props.resetPwdSubmit()}>
-          <Form.Item label="鎵嬫満鍙�">
+          <Form.Item label={dict['phone_no'] || '鎵嬫満鍙�'}>
             {getFieldDecorator('phone', {
               initialValue: '',
               rules: [
                 {
                   required: true,
-                  message: '璇疯緭鍏ユ墜鏈哄彿锛�'
+                  message: dict['phone_no_required'] || '璇疯緭鍏ユ墜鏈哄彿'
                 }
               ]
-            })(<Input placeholder="璇疯緭鍏ユ墜鏈哄彿" autoComplete="off" />)}
+            })(<Input placeholder={dict['phone_no'] || '鎵嬫満鍙�'} autoComplete="off" />)}
           </Form.Item>
         </Form> : null}
         {type === 'code' ? <Form wrapperCol={{ xs: { span: 24 }, sm: { span: 20 }}} onKeyDown={(e) => e.key === 'Enter' && this.props.resetPwdSubmit()}>
@@ -318,16 +319,16 @@
               rules: [
                 {
                   required: true,
-                  message: '璇疯緭鍏ラ獙璇佺爜锛�'
+                  message: dict['vercode_required'] || '璇疯緭鍏ラ獙璇佺爜'
                 }
               ]
             })(<Input
               addonAfter={
                 <Button type="link" size="small" disabled={verdisabled} onClick={this.getvercode}>
-                  {delay ? `${delay}s鍚庨噸鏂拌幏鍙朻 : '鑾峰彇楠岃瘉鐮�'}
+                  {delay ? `${delay}s` : dict['query_vercode'] || '鑾峰彇楠岃瘉鐮�'}
                 </Button>
               }
-              placeholder="璇疯緭鍏ラ獙璇佺爜"
+              placeholder={dict['vercode'] || '楠岃瘉鐮�'}
               autoComplete="off"
             />)}
           </Form.Item>
diff --git a/src/components/tabview/index.jsx b/src/components/tabview/index.jsx
index 51f9743..88e48b9 100644
--- a/src/components/tabview/index.jsx
+++ b/src/components/tabview/index.jsx
@@ -19,7 +19,9 @@
 const Iframe = asyncComponent(() => import('@/tabviews/iframe'))
 const RoleManage = asyncComponent(() => import('@/tabviews/rolemanage'))
 
-moment.locale('zh-cn')
+if (sessionStorage.getItem('lang') === 'zh-CN') {
+  moment.locale('zh-cn')
+}
 
 class TabViews extends Component {
   state = {
@@ -36,7 +38,7 @@
         activeId: 'home_page_id',
         tabviews: [{
           MenuID: 'home_page_id',
-          MenuName: '棣栭〉',
+          MenuName: window.GLOB.dict['home'] || '棣栭〉',
           type: 'Home'
         }]
       })
diff --git a/src/index.js b/src/index.js
index 2fbab2f..dbc9c37 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,9 +1,12 @@
 import React from 'react'
 import ReactDOM from 'react-dom'
+import { ConfigProvider } from 'antd'
+import zhCN from 'antd/es/locale/zh_CN'
+
 import Route from './router'
 import md5 from 'md5'
 import * as serviceWorker from './serviceWorker'
-import options, { styles } from '@/store/options.js'
+import options, { styles, langs } from '@/store/options.js'
 import '@/assets/css/main.scss'
 import '@/assets/css/action.scss'
 import '@/assets/css/viewstyle.scss'
@@ -17,13 +20,6 @@
     }
     return uuid.join('')
   })())
-}
-
-const render = Component => {
-  ReactDOM.render(
-    <Component/>,
-    document.getElementById('root')
-  )
 }
 
 fetch('../options.json')
@@ -61,6 +57,11 @@
     GLOB.upStatus = false
     GLOB.navBar = 'shutter' // 榛樿涓虹櫨鍙剁獥
     GLOB.style = 'bg_black_style_blue'
+    GLOB.defLang = ''
+
+    if (langs[config.defaultLang]) {
+      GLOB.defLang = config.defaultLang
+    }
 
     GLOB.sysType = options.sysType
     if (GLOB.sysType !== 'cloud') {
@@ -160,8 +161,39 @@
       }
     }
 
-    let _href = window.location.href.split('#')[0]
-    let _systemMsg = localStorage.getItem(_href + 'system')
+    if (process.env.NODE_ENV === 'production') { // 鐢ㄤ簬鏍¢獙鏄惁瀛樺湪寮�鍙戞潈闄�
+      let _service = window.location.href.replace(/\/admin(.*)/ig, '').replace(new RegExp(document.location.origin + '/?', 'ig'), '')
+      GLOB.service = _service ? _service + '/' : ''
+      GLOB.host = window.location.host + (_service ? '_' + _service : '')
+      GLOB.baseurl = document.location.origin + '/' + GLOB.service
+      GLOB.linkurl = GLOB.baseurl + 'index.html'
+    } else {
+      GLOB.location = config.host
+      GLOB.service = config.service
+      GLOB.host = config.host.replace(/http(s)?:\/\//ig, '') + (config.service ? '_' + config.service.replace(/\//ig, '') : '')
+      GLOB.baseurl = GLOB.location + '/' + GLOB.service
+      GLOB.linkurl = GLOB.baseurl + 'index.html'
+      GLOB.dataFormat = false
+
+      let mark = sessionStorage.getItem('system_mark')
+      let _mark = `sys_${GLOB.service.replace('/', '') || 'service'}`
+      if (mark && mark !== _mark) {
+        sessionStorage.clear()
+      }
+      sessionStorage.setItem('system_mark', _mark)
+    }
+
+    if (config.mainkey && GLOB.sysType !== 'cloud' && config.mainkey !== options.cakey) {
+      GLOB.localkey = GLOB.appkey
+      GLOB.appkey = config.mainkey
+    }
+
+    let lang = localStorage.getItem(window.location.href.split('#')[0] + 'lang') || GLOB.defLang || 'zh-CN'
+    sessionStorage.setItem('lang', lang)
+
+    GLOB.sysSign = GLOB.service + 'admin/' + lang + '/'
+
+    let _systemMsg = localStorage.getItem(GLOB.sysSign + 'system')
     let className = 'mk-blue-black'
 
     if (_systemMsg) {
@@ -224,38 +256,12 @@
       GLOB.filter = true
     }
 
-    if (process.env.NODE_ENV === 'production') { // 鐢ㄤ簬鏍¢獙鏄惁瀛樺湪寮�鍙戞潈闄�
-      let _service = window.location.href.replace(/\/admin(.*)/ig, '').replace(new RegExp(document.location.origin + '/?', 'ig'), '')
-      GLOB.service = _service ? _service + '/' : ''
-      GLOB.host = window.location.host + (_service ? '_' + _service : '')
-      GLOB.baseurl = document.location.origin + '/' + GLOB.service
-      GLOB.linkurl = GLOB.baseurl + 'index.html'
-    } else {
-      GLOB.location = config.host
-      GLOB.service = config.service
-      GLOB.host = config.host.replace(/http(s)?:\/\//ig, '') + (config.service ? '_' + config.service.replace(/\//ig, '') : '')
-      GLOB.baseurl = GLOB.location + '/' + GLOB.service
-      GLOB.linkurl = GLOB.baseurl + 'index.html'
-      GLOB.dataFormat = false
-
-      let mark = sessionStorage.getItem('system_mark')
-      let _mark = `sys_${GLOB.service.replace('/', '') || 'service'}`
-      if (mark && mark !== _mark) {
-        sessionStorage.clear()
-      }
-      sessionStorage.setItem('system_mark', _mark)
+    if (lang !== 'zh-CN') {
+      GLOB.WXNotice = false
     }
 
-    if (config.mainkey && GLOB.sysType !== 'cloud' && config.mainkey !== options.cakey) {
-      GLOB.localkey = GLOB.appkey
-      GLOB.appkey = config.mainkey
-    }
-
-    let lang = localStorage.getItem(_href + 'lang') || (config.defaultLang !== 'en-US' ? 'zh-CN' : 'en-US')
-    sessionStorage.setItem('lang', lang)
-
-    if (localStorage.getItem(_href + 'files') === md5(_href + 'files')) {
-      let d = localStorage.getItem(_href + 'filesDate')
+    if (localStorage.getItem(GLOB.sysSign + 'files') === md5(GLOB.sysSign + 'files')) {
+      let d = localStorage.getItem(GLOB.sysSign + 'filesDate')
 
       GLOB.storeFiles = true
       GLOB.storeDate = Math.ceil((new Date(d).getTime() - new Date().getTime()) / 86400000)
@@ -277,6 +283,17 @@
         d = d.slice(0, 4) + '-' + d.slice(4, 6) + '-' + d.slice(6)
         GLOB.storeDate = Math.ceil((new Date(d).getTime() - new Date().getTime()) / 86400000)
       }
+    }
+
+    GLOB.dict = {}
+
+    if (localStorage.getItem(GLOB.sysSign + 'js_trans')) {
+      let js_trans = JSON.parse(localStorage.getItem(GLOB.sysSign + 'js_trans'))
+
+      js_trans.forEach(item => {
+        if (lang !== item.lang) return
+        GLOB.dict[item.key] = item.val
+      })
     }
 
     GLOB.mkActions = {}  // 鎸夐挳鏉冮檺闆�
@@ -348,7 +365,20 @@
     window.GLOB.SyncData = new Map()     // 瀛樺偍鍚屾鏌ヨ鏁版嵁
     window.GLOB.mkThdMenus = new Map()   // 涓夌骇鑿滃崟
 
-    render(Route)
+    if (lang === 'zh-CN' || !/#\/(login|main|billprint|docprint|tab|iframe|view|ssologin)/.test(window.location.href)) { // 寮�鍙戜娇鐢ㄤ腑鏂�
+      ReactDOM.render(
+        <ConfigProvider locale={zhCN}>
+          <Route/>
+        </ConfigProvider>,
+        document.getElementById('root')
+      )
+    } else {
+      ReactDOM.render(
+        <Route/>,
+        document.getElementById('root')
+      )
+    }
+    
   })
 
 serviceWorker.unregister()
diff --git a/src/locales/en-US/login.js b/src/locales/en-US/login.js
deleted file mode 100644
index 9abd3b6..0000000
--- a/src/locales/en-US/login.js
+++ /dev/null
@@ -1,17 +0,0 @@
-export default {
-  'login.auth.tip': 'The system is not authorized, please contact the administrator.',
-  'login.ok': 'OK',
-  'login.cancel': 'Cancel',
-  'login.username': 'Username',
-  'login.username.empty': 'Please input your username!',
-  'login.phone': 'Mobile phone no',
-  'login.phone.empty': 'Please enter your cell phone number!',
-  'login.vercode': 'Verification code',
-  'login.vercode.empty': 'Please enter your verification code!',
-  'login.password': 'Password',
-  'login.password.empty': 'Please input your Password!',
-  'login.remember': 'Remember me',
-  'login.submit': 'Log in',
-  'login.copyright': 'Copyrights by',
-  'login.sync.cloud': 'Synchronous cloud application'
-}
\ No newline at end of file
diff --git a/src/locales/zh-CN/login.js b/src/locales/zh-CN/login.js
deleted file mode 100644
index ea06d7a..0000000
--- a/src/locales/zh-CN/login.js
+++ /dev/null
@@ -1,17 +0,0 @@
-export default {
-  'login.auth.tip': '绯荤粺鏈巿鏉冿紝璇疯仈绯荤鐞嗗憳銆�',
-  'login.ok': '纭畾',
-  'login.cancel': '鍙栨秷',
-  'login.username': '鐢ㄦ埛鍚�',
-  'login.username.empty': '璇疯緭鍏ョ敤鎴峰悕!',
-  'login.phone': '鎵嬫満鍙�',
-  'login.phone.empty': '璇疯緭鍏ユ墜鏈哄彿!',
-  'login.vercode': '楠岃瘉鐮�',
-  'login.vercode.empty': '璇疯緭鍏ラ獙璇佺爜!',
-  'login.password': '瀵嗙爜',
-  'login.password.empty': '璇疯緭鍏ュ瘑鐮�!',
-  'login.remember': '璁颁綇瀵嗙爜',
-  'login.submit': '鐧诲綍',
-  'login.copyright': '鎵�鏈夌浉鍏崇増鏉冨綊',
-  'login.sync.cloud': '鍚屾浜戠搴旂敤'
-}
\ No newline at end of file
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/index.jsx b/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
index 207e436..e55c040 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
@@ -58,7 +58,7 @@
     try {
       delete _val.$srcId
     
-      let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+      let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
       if (srcid) {
         _val.$srcId = srcid
       }
diff --git a/src/menu/components/card/cardcellcomponent/elementform/index.jsx b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
index 992eff8..0b03681 100644
--- a/src/menu/components/card/cardcellcomponent/elementform/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
-import { Form, Row, Col, Input, Select, Radio, Tooltip, InputNumber, Cascader, Popover, message, AutoComplete } from 'antd'
+import { Form, Row, Col, Input, Select, Radio, Checkbox, Tooltip, InputNumber, Cascader, Popover, message, AutoComplete } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 
 import { formRule } from '@/utils/option.js'
@@ -228,7 +228,7 @@
       }
     } else if (this.record.eleType === 'formula') {
       if (this.record.eval !== 'func') {
-        _options.push('prefix', 'postfix', 'fixStyle', 'alignItems')
+        _options.push('prefix', 'postfix', 'fixStyle', 'alignItems', 'evalchars')
       }
       if (this.record.eval === 'true') {
         _options.push('decimal')
@@ -578,6 +578,24 @@
             </Form.Item>
           </Col>
         )
+      } else if (item.type === 'checkbox') {
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={label}>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal,
+                rules: [{
+                  required: item.required,
+                  message: '璇烽�夋嫨' + item.label + '!'
+                }]
+              })(
+                <Checkbox.Group style={{whiteSpace: 'nowrap'}}>
+                  {item.options.map(option => <Checkbox key={option.value} value={option.value}>{option.text}</Checkbox>)}
+                </Checkbox.Group>
+              )}
+            </Form.Item>
+          </Col>
+        )
       } else if (item.type === 'color') {
         fields.push(
           <Col span={12} key={index} className="color-form">
diff --git a/src/menu/components/card/cardcellcomponent/formconfig.jsx b/src/menu/components/card/cardcellcomponent/formconfig.jsx
index 7b651e9..32da945 100644
--- a/src/menu/components/card/cardcellcomponent/formconfig.jsx
+++ b/src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -695,6 +695,21 @@
       required: true
     },
     {
+      type: 'checkbox',
+      key: 'evalchars',
+      label: '鏇挎崲瀛楃',
+      initVal: card.evalchars || ['enter', 'space'],
+      tooltip: '鍏紡瑙f瀽鍚庯紝鍙浛鎹㈠洖杞︺�佺┖鏍肩瓑瀛楃锛屽疄鐜版崲琛屻�佸瓧闂磋窛鎺у埗绛夐〉闈㈡晥鏋溿��',
+      required: false,
+      options: [{
+        value: 'enter',
+        text: '鍥炶溅绗�'
+      }, {
+        value: 'space',
+        text: '绌烘牸'
+      }]
+    },
+    {
       type: 'radio',
       key: 'noValue',
       label: '绌哄��',
diff --git a/src/menu/components/card/data-card/options.jsx b/src/menu/components/card/data-card/options.jsx
index 29de319..6a799d2 100644
--- a/src/menu/components/card/data-card/options.jsx
+++ b/src/menu/components/card/data-card/options.jsx
@@ -209,8 +209,21 @@
       controlFields: subtype !== 'propcard' ? [
         {field: 'printHeight', values: ['flex']},
         {field: 'cardFloat', values: ['grid']},
+        {field: 'zHeight', values: ['grid']},
       ] : [{field: 'cardFloat', values: ['grid']}],
       forbid: subtype === 'tablecard'
+    },
+    {
+      type: 'number',
+      field: 'zHeight',
+      label: '鏈�澶ч珮搴�',
+      initval: wrap.zHeight || '',
+      tooltip: '鍗$墖鍐呭鍖虹殑鏈�澶ч珮搴︼紙涓嶅寘鍚爣棰樸�佺炕椤电瓑鍏冪礌锛夛紝娣诲姞楂樺害鍚庣粍浠朵腑绗竴涓睘鎬у崱灏嗗浐瀹氫簬澶撮儴銆傛敞锛氬皬浜庣瓑浜�100澶т簬0鏃朵负楂樺害鐨勭櫨鍒嗘瘮锛屽皬浜�0鏃朵负绐楀彛楂樺害鍑忓幓姝ゅ�笺��',
+      min: -1000,
+      max: 3000,
+      precision: 0,
+      required: false,
+      forbid: subtype !== 'datacard' || appType === 'mob'
     },
     {
       type: 'radio',
@@ -565,6 +578,7 @@
       tooltip: '鐢ㄤ簬鎺у埗琛屾暟鎹槸鍚﹀彲閫夋嫨銆�',
       required: false,
       allowClear: true,
+      joint: true,
       options: columns,
       controlFields: [
         {field: 'controlVal', notNull: true},
diff --git a/src/menu/components/card/double-data-card/options.jsx b/src/menu/components/card/double-data-card/options.jsx
index 7d632f0..5cb3395 100644
--- a/src/menu/components/card/double-data-card/options.jsx
+++ b/src/menu/components/card/double-data-card/options.jsx
@@ -61,6 +61,18 @@
       required: true
     },
     {
+      type: 'number',
+      field: 'zHeight',
+      label: '鏈�澶ч珮搴�',
+      initval: wrap.zHeight || '',
+      tooltip: '鍗$墖鍐呭鍖虹殑鏈�澶ч珮搴︼紙涓嶅寘鍚爣棰樸�佺炕椤电瓑鍏冪礌锛夛紝娣诲姞楂樺害鍚庣粍浠朵腑绗竴涓睘鎬у崱灏嗗浐瀹氫簬澶撮儴銆傛敞锛氬皬浜庣瓑浜�100澶т簬0鏃朵负楂樺害鐨勭櫨鍒嗘瘮锛屽皬浜�0鏃朵负绐楀彛楂樺害鍑忓幓姝ゅ�笺��',
+      min: -1000,
+      max: 3000,
+      precision: 0,
+      required: false,
+      forbid: appType === 'mob'
+    },
+    {
       type: 'radio',
       field: 'pagestyle',
       label: '鍒嗛〉椋庢牸',
@@ -170,6 +182,7 @@
       tooltip: '鐢ㄤ簬鎺у埗琛屾暟鎹槸鍚﹀彲閫夋嫨銆�',
       required: false,
       allowClear: true,
+      joint: true,
       options: columns,
       controlFields: [
         {field: 'controlVal', notNull: true},
@@ -203,26 +216,14 @@
       tooltip: '璁剧疆鍗$墖鍖哄煙鐨勬渶灏忓搴︼紝鏄剧ず鍖哄煙灏忎簬姝ゅ�煎皢鍑虹幇妯悜婊氬姩銆�',
       required: false
     },
-    {
-      type: 'number',
-      field: 'zHeight',
-      label: '楂樺害',
-      min: 10,
-      max: 5000,
-      precision: 0,
-      initval: wrap.zHeight,
-      tooltip: '鍗$墖鍖哄煙楂樺害锛屽唴瀹硅秴鍑烘椂绾靛悜婊氬姩銆傛敞锛氬皬浜庣瓑浜�100鏃朵负楂樺害鐨勭櫨鍒嗘瘮锛岀涓�涓墿灞曞睘鎬у崱灏嗗畾浣嶅湪椤堕儴銆�',
-      required: false,
-      forbid: appType === 'mob'
-    },
-    {
-      type: 'color',
-      field: 'zBColor',
-      label: '杈规棰滆壊',
-      initval: wrap.zBColor || 'transparent',
-      tooltip: '鍗$墖鍖哄煙璁剧疆楂樺害鎴栨渶灏忓搴︽椂锛屾粴鍔ㄥ尯鍩熻竟妗嗙殑棰滆壊銆�',
-      required: false
-    },
+    // {
+    //   type: 'color',
+    //   field: 'zBColor',
+    //   label: '杈规棰滆壊',
+    //   initval: wrap.zBColor || 'transparent',
+    //   tooltip: '鍗$墖鍖哄煙璁剧疆楂樺害鎴栨渶灏忓搴︽椂锛屾粴鍔ㄥ尯鍩熻竟妗嗙殑棰滆壊銆�',
+    //   required: false
+    // },
     {
       type: 'radio',
       field: 'permission',
diff --git a/src/menu/components/form/formaction/actionform/index.jsx b/src/menu/components/form/formaction/actionform/index.jsx
index 33ebafb..a46a9ca 100644
--- a/src/menu/components/form/formaction/actionform/index.jsx
+++ b/src/menu/components/form/formaction/actionform/index.jsx
@@ -105,9 +105,9 @@
         shows.push('innerFunc')
       } else {
         shows.push('sql', 'sqlType')
-        if (this.record.execSuccess === 'never' && this.record.resetForms && this.record.resetForms[0]) {
-          shows.push('returnValue')
-        }
+        // if (this.record.execSuccess === 'never' && this.record.resetForms && this.record.resetForms[0]) {
+        //   shows.push('returnValue')
+        // }
       }
       
       if (this.record.linkmenu && this.record.linkmenu !== 'goback') {
@@ -170,7 +170,6 @@
 
   getFields() {
     const { getFieldDecorator } = this.props.form
-    const { interType, callbackType } = this.state
     const fields = []
 
     this.state.formlist.forEach((item, index) => {
@@ -206,7 +205,7 @@
             message: formRule.func.maxMessage
           }]
         } else if (item.key === 'output') {
-          if (interType === 'system' || ((interType === 'outer' || interType === 'custom') && callbackType === 'script')) {
+          if (this.record.intertype === 'system' || ((this.record.intertype === 'outer' || this.record.intertype === 'custom') && this.record.callbackType === 'script')) {
             _rules = [{
               pattern: /^@[0-9a-zA-Z_]+@?$/,
               message: '鍙橀噺浠绗﹀紑澶达紝鍙娇鐢ㄥ瓧姣嶃�佹暟瀛椾互鍙奯'
@@ -373,8 +372,12 @@
           if (values.outerBlacklist) {
             values.outerBlacklist = values.outerBlacklist.replace(/\s/ig, '')
           }
-          if (values.resetForms && values.resetForms.length === 0) {
-            values.resetForms = null
+          if (values.resetForms) {
+            if (values.resetForms.length === 0) {
+              values.resetForms = null
+            } else {
+              values.returnValue = 'true'
+            }
           }
           resolve(values)
         } else {
diff --git a/src/menu/components/form/formaction/formconfig.jsx b/src/menu/components/form/formaction/formconfig.jsx
index e3bc348..ef22b50 100644
--- a/src/menu/components/form/formaction/formconfig.jsx
+++ b/src/menu/components/form/formaction/formconfig.jsx
@@ -429,6 +429,7 @@
       key: 'execSuccess',
       label: '鎴愬姛鍚�',
       initVal: card.execSuccess || 'grid',
+      tooltip: '濡傞渶鑱氱劍琛ㄥ崟璇蜂互 @focus:鑱氱劍瀛楁@ 鏍煎紡杩斿洖銆�',
       required: true,
       options: [{
         value: 'never',
@@ -449,7 +450,7 @@
       key: 'refreshTab',
       label: '鍒锋柊鑿滃崟',
       initVal: card.refreshTab || [],
-      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栧姛鑳芥寜閽腑鏍囩鍏抽棴绫诲瀷锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑鑿滃崟',
+      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栨墽琛屽け璐ヤ笖瀛樺湪鍒锋柊椤规椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑鑿滃崟',
       required: false,
       forbid: appType === 'pc' || appType === 'mob' || viewType === 'popview',
       options: menulist
@@ -490,7 +491,7 @@
       key: 'syncComponent',
       label: '鍚屾鍒锋柊',
       initVal: card.syncComponent,
-      tooltip: '鎵ц鎴愬姛鍚庨渶瑕佸埛鏂扮殑缁勪欢銆傛敞锛氶�夋嫨褰撳墠缁勪欢鐨勪笂绾х粍浠舵棤鏁堬紝鍒锋柊涓婄骇缁勪欢璇烽�夋嫨鎴愬姛鍚庘�滃埛鏂颁笂绾х粍浠� - 琛屸�濄��',
+      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栨墽琛屽け璐ヤ笖瀛樺湪鍒锋柊椤规椂锛夐渶瑕佸埛鏂扮殑缁勪欢銆傛敞锛氶�夋嫨褰撳墠缁勪欢鐨勪笂绾х粍浠舵棤鏁堬紝鍒锋柊涓婄骇缁勪欢璇烽�夋嫨鎴愬姛鍚庘�滃埛鏂颁笂绾х粍浠� - 琛屸�濄��',
       required: false,
       options: modules
     },
@@ -532,20 +533,20 @@
       mode: 'multiple',
       options: resets
     },
-    {
-      type: 'radio',
-      key: 'returnValue',
-      label: '鏇存柊琛ㄥ崟',
-      initVal: card.returnValue || 'false',
-      tooltip: '涓庨噸缃〃鍗曢厤鍚堜娇鐢紝寮�鍚椂锛屽繀椤诲湪鑷畾涔夎剼鏈腑杩斿洖鏁版嵁锛岀敤浜庢浛鎹㈠瓧娈甸泦鍜屽~鍏呰〃鍗曘��',
-      options: [{
-        value: 'false',
-        text: '绂佺敤'
-      }, {
-        value: 'true',
-        text: '鍚敤'
-      }]
-    },
+    // {
+    //   type: 'radio',
+    //   key: 'returnValue',
+    //   label: '鏇存柊琛ㄥ崟',
+    //   initVal: card.returnValue || 'false',
+    //   tooltip: '涓庨噸缃〃鍗曢厤鍚堜娇鐢紝寮�鍚椂锛屽繀椤诲湪鑷畾涔夎剼鏈腑杩斿洖鏁版嵁锛岀敤浜庢浛鎹㈠瓧娈甸泦鍜屽~鍏呰〃鍗曘��',
+    //   options: [{
+    //     value: 'false',
+    //     text: '绂佺敤'
+    //   }, {
+    //     value: 'true',
+    //     text: '鍚敤'
+    //   }]
+    // },
     {
       type: 'radio',
       key: 'reload',
diff --git a/src/menu/components/form/formaction/index.jsx b/src/menu/components/form/formaction/index.jsx
index 3ca3fb7..0287ff7 100644
--- a/src/menu/components/form/formaction/index.jsx
+++ b/src/menu/components/form/formaction/index.jsx
@@ -226,7 +226,7 @@
             <ProfileOutlined className="profile" title="setting" onClick={() => this.profileAction()} />
           </div>
         } trigger="hover">
-          <Button type="link" className="submit mk-primary" onDoubleClick={this.changeMenu} style={resetStyle(group.subButton.style)}>{group.subButton.label}</Button>
+          <Button type="link" className="submit" onDoubleClick={this.changeMenu} style={resetStyle(group.subButton.style)}>{group.subButton.label}</Button>
         </Popover>
         {group.resetButton && group.resetButton.enable === 'true' ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
diff --git a/src/menu/components/form/simple-form/index.jsx b/src/menu/components/form/simple-form/index.jsx
index 07e1e2f..a159f9b 100644
--- a/src/menu/components/form/simple-form/index.jsx
+++ b/src/menu/components/form/simple-form/index.jsx
@@ -7,7 +7,7 @@
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
 import { getModalForm } from '@/templates/zshare/formconfig'
-import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
+import { resetStyle, getTables, checkComponent, getInterfaces } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
 import getWrapForm from './options'
@@ -340,6 +340,8 @@
     card.subcards[0].fields = card.subcards[0].fields.filter(item => !item.focus)
 
     this.setState({card, visible: false, editform: null})
+
+    this.updateComponent(card)
   }
 
   /**
@@ -466,9 +468,9 @@
         _card.setting.supModule = ''
       }
     } else if (res.datatype === 'public') {
-      let interfaces = window.GLOB.customMenu.interfaces || []
+      let interfaces = getInterfaces()
 
-      let d = interfaces.filter(m => m.uuid === res.publicId && m.status === 'true')[0]
+      let d = interfaces.filter(m => m.value === res.publicId)[0]
 
       if (d) {
         _card.columns = fromJS(d.columns).toJS()
diff --git a/src/menu/components/form/simple-form/options.jsx b/src/menu/components/form/simple-form/options.jsx
index b9108ff..a1a4dc4 100644
--- a/src/menu/components/form/simple-form/options.jsx
+++ b/src/menu/components/form/simple-form/options.jsx
@@ -1,4 +1,4 @@
-import MenuUtils from '@/utils/utils-custom.js'
+import MenuUtils, { getInterfaces } from '@/utils/utils-custom.js'
 
 /**
  * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
@@ -45,18 +45,7 @@
     }
   }
 
-  let interfaces = []
-  if (menu.interfaces) {
-    menu.interfaces.forEach(item => {
-      if (item.status === 'true') {
-        interfaces.push({
-          value: item.uuid,
-          label: item.name
-        })
-      }
-    })
-  }
-
+  let interfaces = getInterfaces()
   let buttons = []
 
   if (!wrap.enable || wrap.enable === 'true') {
diff --git a/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx b/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx
index c5cf723..a7834c9 100644
--- a/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx
+++ b/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx
@@ -253,7 +253,6 @@
                 filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                 onChange={this.selectScript}
               >
-                <Select.Option key="default" value="defaultSql">榛樿sql</Select.Option>
                 {systemScripts.map((option, i) =>
                   <Select.Option key={i} value={option.value}>{option.name}</Select.Option>
                 )}
diff --git a/src/menu/components/search/main-search/dragsearch/index.jsx b/src/menu/components/search/main-search/dragsearch/index.jsx
index 5af808c..04d5372 100644
--- a/src/menu/components/search/main-search/dragsearch/index.jsx
+++ b/src/menu/components/search/main-search/dragsearch/index.jsx
@@ -52,7 +52,7 @@
     try {
       delete _val.$srcId
     
-      let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+      let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
       if (srcid) {
         _val.$srcId = srcid
       }
diff --git a/src/menu/components/search/main-search/index.jsx b/src/menu/components/search/main-search/index.jsx
index 270358a..ef3e3c1 100644
--- a/src/menu/components/search/main-search/index.jsx
+++ b/src/menu/components/search/main-search/index.jsx
@@ -250,7 +250,7 @@
         return
       }
 
-      if (['select', 'multiselect', 'link', 'checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) {
+      if (['select', 'multiselect', 'link', 'checkcard'].includes(res.type) && res.resourceType === '1' && res.database !== 'sso' && /\s/.test(res.dataSource)) {
         this.setState({
           sqlVerifing: true
         })
@@ -258,13 +258,8 @@
         let sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)
         ${res.dataSource}`
         sql = sql.replace(/@\$|\$@/ig, '')
-
-        let rduri = ''
-        if (window.GLOB.mainSystemApi && res.database === 'sso') {
-          rduri = window.GLOB.mainSystemApi
-        }
         
-        Api.sDebug(sql, rduri).then(result => {
+        Api.sDebug(sql).then(result => {
           if (result.status || result.ErrCode === '-2') {
             this.setState({
               sqlVerifing: false,
@@ -381,7 +376,7 @@
     let _style = resetStyle(card.style)
 
     return (
-      <div className={`main-search-edit-list ${card.wrap.float} ${showField ? 'show-field' : ''}`} onClick={this.clickComponent} id={card.uuid} style={_style}>
+      <div className={`main-search-edit-list ${card.wrap.float} ${showField ? 'show-field' : ''} mk-size-${card.wrap.searchSize || ''}`} onClick={this.clickComponent} id={card.uuid} style={_style}>
         <FieldsComponent config={card} type="search" />
         <Switch checkedChildren="寮�" size="small" unCheckedChildren="鍏�" defaultChecked={showField} onChange={this.onFieldChange} />
         <DragElement
@@ -422,7 +417,7 @@
           title="鎼滅储鏉′欢-缂栬緫"
           wrapClassName="mk-scroll-modal"
           visible={visible}
-          width={850}
+          width={950}
           maskClosable={false}
           onOk={this.handleSubmit}
           confirmLoading={sqlVerifing}
diff --git a/src/menu/components/search/main-search/index.scss b/src/menu/components/search/main-search/index.scss
index 656580b..87b0e05 100644
--- a/src/menu/components/search/main-search/index.scss
+++ b/src/menu/components/search/main-search/index.scss
@@ -153,6 +153,17 @@
   }
 }
 
+.main-search-edit-list.mk-size-small {
+  .page-card {
+    height: 45px;
+  }
+  .mk-search-item-wrap.action {
+    .ant-form-item {
+      height: 45px!important;
+    }
+  }
+}
+
 .main-search-edit-list:not(.show-field) {
   .ant-form-explain {
     display: none;
diff --git a/src/menu/components/search/main-search/options.jsx b/src/menu/components/search/main-search/options.jsx
index 2ed6c06..32f04b1 100644
--- a/src/menu/components/search/main-search/options.jsx
+++ b/src/menu/components/search/main-search/options.jsx
@@ -160,6 +160,18 @@
     },
     {
       type: 'radio',
+      field: 'searchSize',
+      label: '鎼滅储闂磋窛',
+      initval: wrap.searchSize || 'middle',
+      tooltip: '鎼滅储鏉′欢鐨勪笂涓嬮棿璺濄��',
+      required: false,
+      options: [
+        {value: 'middle', label: '榛樿'},
+        {value: 'small', label: '灏�'},
+      ],
+    },
+    {
+      type: 'radio',
       field: 'cacheSearch',
       label: '鎼滅储缂撳瓨',
       initval: wrap.cacheSearch || 'false',
diff --git a/src/menu/components/share/actioncomponent/actionform/index.jsx b/src/menu/components/share/actioncomponent/actionform/index.jsx
index 3f88b64..104c448 100644
--- a/src/menu/components/share/actioncomponent/actionform/index.jsx
+++ b/src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -221,7 +221,7 @@
         }
         reRequired.innerFunc = true
       } else {
-        shows.push('sql', 'sqlType', 'output')
+        shows.push('sql', 'sqlType', 'output', 'database')
       }
 
       if (Ot === 'required') {
@@ -299,7 +299,7 @@
         shows.push('innerFunc', 'extraParam')
         reRequired.innerFunc = true
       } else {
-        shows.push('sql', 'sqlType')
+        shows.push('sql', 'sqlType', 'database')
       }
 
       if (this.record.execSuccess === 'goback') {
@@ -349,6 +349,8 @@
       } else if (this.record.intertype === 'inner') {
         shows.push('innerFunc', 'extraParam')
         reRequired.innerFunc = true
+      } else {
+        shows.push('database')
       }
       if (this.record.execSuccess === 'grid' || this.record.execError === 'grid') {
         shows.push('resetPageIndex')
@@ -384,6 +386,8 @@
       } else if (this.record.intertype === 'inner') {
         shows.push('innerFunc', 'extraParam')
         reRequired.innerFunc = true
+      } else {
+        shows.push('database')
       }
       if (this.record.execSuccess === 'grid' || this.record.execError === 'grid') {
         shows.push('resetPageIndex')
diff --git a/src/menu/components/share/actioncomponent/dragaction/index.jsx b/src/menu/components/share/actioncomponent/dragaction/index.jsx
index cab1425..a90eb21 100644
--- a/src/menu/components/share/actioncomponent/dragaction/index.jsx
+++ b/src/menu/components/share/actioncomponent/dragaction/index.jsx
@@ -74,7 +74,7 @@
     try {
       delete _val.$srcId
     
-      let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+      let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
       if (srcid) {
         _val.$srcId = srcid
       }
diff --git a/src/menu/components/share/actioncomponent/formconfig.jsx b/src/menu/components/share/actioncomponent/formconfig.jsx
index 8b93c3b..1106bec 100644
--- a/src/menu/components/share/actioncomponent/formconfig.jsx
+++ b/src/menu/components/share/actioncomponent/formconfig.jsx
@@ -26,6 +26,10 @@
     type = 'chart'
   }
 
+  if (card.color && (type !== 'datacard' || appType !== 'mob') && !card.class) {
+    card.class = 'primary'
+  }
+
   let opentypes = [
     {
       value: 'pop',
@@ -711,7 +715,7 @@
       key: 'execSuccess',
       label: '鎴愬姛鍚�',
       initVal: card.execSuccess || 'grid',
-      tooltip: refresh.length ? '鎵ц鍒锋柊婧愮粍浠舵椂锛岃鍦ㄦ簮鎸夐挳锛堝脊绐楁寜閽級涓缃叧闂悗鍒锋柊閭d竴椤癸紝娉細姝ゆ椂浼氬悓姝ュ埛鏂板綋鍓嶇粍浠跺拰涓婄骇缁勪欢-琛屻�傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級锛汙no_target_menu@ 涓嶆墽琛屾墦寮�鑿滃崟銆�' : '閫夋嫨鍒锋柊琛屾椂锛屽鏋滈�夋嫨澶氭潯鏁版嵁浼氬埛鏂扮粍浠讹紱閫夋嫨鍒锋柊琛� / 缁勪欢鏃讹紝濡傛灉褰撳墠琛屾暟鎹笉瀛樺湪浼氬埛鏂扮粍浠躲�傛敞锛氫笂绾х粍浠跺湪鏁版嵁婧愪腑娣诲姞銆傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級锛汙no_target_menu@ 涓嶆墽琛屾墦寮�鑿滃崟銆�',
+      tooltip: refresh.length ? '鎵ц鍒锋柊婧愮粍浠舵椂锛岃鍦ㄦ簮鎸夐挳锛堝脊绐楁寜閽級涓缃叧闂悗鍒锋柊閭d竴椤癸紝娉細姝ゆ椂浼氬悓姝ュ埛鏂板綋鍓嶇粍浠跺拰涓婄骇缁勪欢-琛屻�傚闇�鑱氱劍琛ㄥ崟璇蜂互 @focus:鑱氱劍瀛楁@ 鏍煎紡杩斿洖銆傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級锛汙no_target_menu@ 涓嶆墽琛屾墦寮�鑿滃崟銆�' : '閫夋嫨鍒锋柊琛屾椂锛屽鏋滈�夋嫨澶氭潯鏁版嵁浼氬埛鏂扮粍浠讹紱閫夋嫨鍒锋柊琛� / 缁勪欢鏃讹紝濡傛灉褰撳墠琛屾暟鎹笉瀛樺湪浼氬埛鏂扮粍浠躲�傛敞锛氫笂绾х粍浠跺湪鏁版嵁婧愪腑娣诲姞銆傚闇�鑱氱劍琛ㄥ崟璇蜂互 @focus:鑱氱劍瀛楁@ 鏍煎紡杩斿洖銆傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級锛汙no_target_menu@ 涓嶆墽琛屾墦寮�鑿滃崟銆�',
       required: true,
       options: [{
         value: 'never',
@@ -975,7 +979,7 @@
       key: 'syncComponent',
       label: '鍒锋柊缁勪欢',
       initVal: card.syncComponent || [],
-      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栧脊绐楁爣绛惧叧闂椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑缁勪欢銆傛敞锛氶�夋嫨褰撳墠缁勪欢鐨勪笂绾х粍浠舵棤鏁堬紝鍒锋柊涓婄骇缁勪欢璇烽�夋嫨鎴愬姛鍚庘�滃埛鏂颁笂绾х粍浠� - 琛屸�濄��',
+      tooltip: '鎵ц鎴愬姛鍚庯紙鎵ц澶辫触涓斿瓨鍦ㄥ埛鏂伴」銆佸脊绐楁爣绛惧叧闂級锛岄渶瑕佸悓姝ュ埛鏂扮殑缁勪欢銆傛敞锛氶�夋嫨褰撳墠缁勪欢鐨勪笂绾х粍浠舵棤鏁堬紝鍒锋柊涓婄骇缁勪欢璇烽�夋嫨鎴愬姛鍚庘�滃埛鏂颁笂绾х粍浠� - 琛屸�濄��',
       required: false,
       options: modules.length ? [...modules, {value: 'multiComponent', label: '澶氱粍浠�'}] : []
     },
@@ -1015,7 +1019,7 @@
       key: 'refreshTab',
       label: '鍒锋柊鑿滃崟',
       initVal: card.refreshTab || [],
-      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栧姛鑳芥寜閽腑鏍囩鍏抽棴绫诲瀷锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑鑿滃崟',
+      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栨墽琛屽け璐ヤ笖瀛樺湪鍒锋柊椤规椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑鑿滃崟',
       required: false,
       forbid: isApp || viewType === 'popview',
       options: menulist
@@ -1363,6 +1367,19 @@
       }, {
         value: 'true',
         text: '鏄�'
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'database',
+      label: '鏁版嵁搴�',
+      initVal: card.database || 'local',
+      options: [{
+        value: 'local',
+        text: '鏈湴'
+      }, {
+        value: 'sso',
+        text: '鍗曠偣'
       }]
     },
     {
@@ -2064,7 +2081,7 @@
       key: 'execSuccess',
       label: '鎴愬姛鍚�',
       initVal: card.execSuccess || 'grid',
-      tooltip: refresh.length ? '鎵ц鍒锋柊婧愮粍浠舵椂锛岃鍦ㄦ簮鎸夐挳锛堝脊绐楁寜閽級涓缃叧闂悗鍒锋柊閭d竴椤癸紝娉細姝ゆ椂浼氬悓姝ュ埛鏂板綋鍓嶇粍浠跺拰涓婄骇缁勪欢-琛屻�傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級锛汙no_target_menu@ 涓嶆墽琛屾墦寮�鑿滃崟銆�' : '閫夋嫨鍒锋柊琛屾椂锛屽鏋滈�夋嫨澶氭潯鏁版嵁浼氬埛鏂扮粍浠讹紱閫夋嫨鍒锋柊琛� / 缁勪欢鏃讹紝濡傛灉褰撳墠琛屾暟鎹笉瀛樺湪浼氬埛鏂扮粍浠躲�傛敞锛氫笂绾х粍浠跺湪鏁版嵁婧愪腑娣诲姞銆傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級锛汙no_target_menu@ 涓嶆墽琛屾墦寮�鑿滃崟銆�',
+      tooltip: refresh.length ? '鎵ц鍒锋柊婧愮粍浠舵椂锛岃鍦ㄦ簮鎸夐挳锛堝脊绐楁寜閽級涓缃叧闂悗鍒锋柊閭d竴椤癸紝娉細姝ゆ椂浼氬悓姝ュ埛鏂板綋鍓嶇粍浠跺拰涓婄骇缁勪欢-琛屻�傚闇�鑱氱劍琛ㄥ崟璇蜂互 @focus:鑱氱劍瀛楁@ 鏍煎紡杩斿洖銆傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級锛汙no_target_menu@ 涓嶆墽琛屾墦寮�鑿滃崟銆�' : '閫夋嫨鍒锋柊琛屾椂锛屽鏋滈�夋嫨澶氭潯鏁版嵁浼氬埛鏂扮粍浠讹紱閫夋嫨鍒锋柊琛� / 缁勪欢鏃讹紝濡傛灉褰撳墠琛屾暟鎹笉瀛樺湪浼氬埛鏂扮粍浠躲�傛敞锛氫笂绾х粍浠跺湪鏁版嵁婧愪腑娣诲姞銆傚闇�鑱氱劍琛ㄥ崟璇蜂互 @focus:鑱氱劍瀛楁@ 鏍煎紡杩斿洖銆傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級锛汙no_target_menu@ 涓嶆墽琛屾墦寮�鑿滃崟銆�',
       required: true,
       options: [{
         value: 'never',
@@ -2276,7 +2293,7 @@
       key: 'syncComponent',
       label: '鍒锋柊缁勪欢',
       initVal: card.syncComponent || [],
-      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栧脊绐楁爣绛惧叧闂椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑缁勪欢銆傛敞锛氶�夋嫨褰撳墠缁勪欢鐨勪笂绾х粍浠舵棤鏁堬紝鍒锋柊涓婄骇缁勪欢璇烽�夋嫨鎴愬姛鍚庘�滃埛鏂颁笂绾х粍浠� - 琛屸�濄��',
+      tooltip: '鎵ц鎴愬姛鍚庯紙鎵ц澶辫触涓斿瓨鍦ㄥ埛鏂伴」銆佸脊绐楁爣绛惧叧闂級锛岄渶瑕佸悓姝ュ埛鏂扮殑缁勪欢銆傛敞锛氶�夋嫨褰撳墠缁勪欢鐨勪笂绾х粍浠舵棤鏁堬紝鍒锋柊涓婄骇缁勪欢璇烽�夋嫨鎴愬姛鍚庘�滃埛鏂颁笂绾х粍浠� - 琛屸�濄��',
       required: false,
       options: modules.length ? [...modules, {value: 'multiComponent', label: '澶氱粍浠�'}] : []
     },
@@ -2314,7 +2331,7 @@
       key: 'refreshTab',
       label: '鍒锋柊鑿滃崟',
       initVal: card.refreshTab || [],
-      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栧姛鑳芥寜閽腑鏍囩鍏抽棴绫诲瀷锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑鑿滃崟',
+      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栨墽琛屽け璐ヤ笖瀛樺湪鍒锋柊椤规椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑鑿滃崟',
       required: false,
       forbid: viewType === 'popview',
       options: menulist
@@ -2558,6 +2575,19 @@
     },
     {
       type: 'radio',
+      key: 'database',
+      label: '鏁版嵁搴�',
+      initVal: card.database || 'local',
+      options: [{
+        value: 'local',
+        text: '鏈湴'
+      }, {
+        value: 'sso',
+        text: '鍗曠偣'
+      }]
+    },
+    {
+      type: 'radio',
       key: 'permission',
       label: '鏉冮檺楠岃瘉',
       initVal: card.permission || 'true',
diff --git a/src/menu/components/share/actioncomponent/index.jsx b/src/menu/components/share/actioncomponent/index.jsx
index 96a9190..27bde39 100644
--- a/src/menu/components/share/actioncomponent/index.jsx
+++ b/src/menu/components/share/actioncomponent/index.jsx
@@ -162,6 +162,8 @@
   addButton = (cardId, element) => {
     if (cardId !== this.props.config.uuid) return
 
+    delete element.eleType
+    
     const { actionlist } = this.state
 
     this.setState({actionlist: [...actionlist, element]})
diff --git a/src/menu/components/share/copycomponent/index.jsx b/src/menu/components/share/copycomponent/index.jsx
index af234aa..5450110 100644
--- a/src/menu/components/share/copycomponent/index.jsx
+++ b/src/menu/components/share/copycomponent/index.jsx
@@ -19,7 +19,7 @@
     try {
       delete _val.$srcId
     
-      let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+      let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
       if (srcid) {
         _val.$srcId = srcid
       }
diff --git a/src/menu/components/share/searchcomponent/dragsearch/index.jsx b/src/menu/components/share/searchcomponent/dragsearch/index.jsx
index 87b345e..3ead8c1 100644
--- a/src/menu/components/share/searchcomponent/dragsearch/index.jsx
+++ b/src/menu/components/share/searchcomponent/dragsearch/index.jsx
@@ -46,7 +46,7 @@
     try {
       delete _val.$srcId
     
-      let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+      let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
       if (srcid) {
         _val.$srcId = srcid
       }
diff --git a/src/menu/components/share/searchcomponent/index.jsx b/src/menu/components/share/searchcomponent/index.jsx
index b809cb9..62f1391 100644
--- a/src/menu/components/share/searchcomponent/index.jsx
+++ b/src/menu/components/share/searchcomponent/index.jsx
@@ -205,7 +205,7 @@
         return
       }
 
-      if (['select', 'multiselect', 'link', 'checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) {
+      if (['select', 'multiselect', 'link', 'checkcard'].includes(res.type) && res.resourceType === '1' && res.database !== 'sso' && /\s/.test(res.dataSource)) {
         this.setState({
           sqlVerifing: true
         })
@@ -213,13 +213,8 @@
         let sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)
         ${res.dataSource}`
         sql = sql.replace(/@\$|\$@/ig, '')
-
-        let rduri = ''
-        if (window.GLOB.mainSystemApi && res.database === 'sso') {
-          rduri = window.GLOB.mainSystemApi
-        }
         
-        Api.sDebug(sql, rduri).then(result => {
+        Api.sDebug(sql).then(result => {
           if (result.status || result.ErrCode === '-2') {
             this.setState({
               sqlVerifing: false,
@@ -286,7 +281,7 @@
         <Modal
           title="鎼滅储鏉′欢-缂栬緫"
           visible={visible}
-          width={850}
+          width={950}
           maskClosable={false}
           onOk={this.handleSubmit}
           confirmLoading={sqlVerifing}
diff --git a/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx
index cd62ff5..9c10aac 100644
--- a/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx
+++ b/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx
@@ -442,6 +442,21 @@
       required: true
     },
     {
+      type: 'checkbox',
+      key: 'evalchars',
+      label: '鏇挎崲瀛楃',
+      initVal: card.evalchars || ['enter', 'space'],
+      tooltip: '鍏紡瑙f瀽鍚庯紝鍙浛鎹㈠洖杞︺�佺┖鏍肩瓑瀛楃锛屽疄鐜版崲琛屻�佸瓧闂磋窛鎺у埗绛夐〉闈㈡晥鏋溿��',
+      required: false,
+      options: [{
+        value: 'enter',
+        text: '鍥炶溅绗�'
+      }, {
+        value: 'space',
+        text: '绌烘牸'
+      }]
+    },
+    {
       type: 'radio',
       key: 'noValue',
       label: '绌哄��',
diff --git a/src/menu/components/table/base-table/columns/editColumn/index.jsx b/src/menu/components/table/base-table/columns/editColumn/index.jsx
index dac43a3..fd0ad48 100644
--- a/src/menu/components/table/base-table/columns/editColumn/index.jsx
+++ b/src/menu/components/table/base-table/columns/editColumn/index.jsx
@@ -95,8 +95,13 @@
       } else if (this.record.perspective === 'linkurl') {
         _options.push('linkurl', 'open')
       }
-    } else if (this.record.type === 'formula' && this.record.eval === 'true') {
-      _options.push('decimal')
+    } else if (this.record.type === 'formula') {
+      if (this.record.eval === 'true') {
+        _options.push('decimal')
+      }
+      if (this.record.eval !== 'func') {
+        _options.push('evalchars')
+      }
     } else if (this.record.type === 'custom' && this.record.IsSort === 'true') {
       _options.push('sortField')
     }
diff --git a/src/menu/components/table/base-table/columns/index.jsx b/src/menu/components/table/base-table/columns/index.jsx
index aad0434..63cf2fa 100644
--- a/src/menu/components/table/base-table/columns/index.jsx
+++ b/src/menu/components/table/base-table/columns/index.jsx
@@ -193,10 +193,10 @@
         val = '$Index'
       } else if (column.type === 'formula') {
         val = column.formula
-        if (column.eval === 'false') {
-          val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
-          val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span>
-        }
+        // if (column.eval === 'false') {
+        //   val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
+        //   val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span>
+        // }
       }
       return (
         <td style={{...style}} className={className}>
@@ -549,7 +549,7 @@
       cols: columns.filter(col => !col.origin)
     }
 
-    let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+    let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
     if (srcid) {
       val.$srcId = srcid
     }
diff --git a/src/menu/components/table/base-table/options.jsx b/src/menu/components/table/base-table/options.jsx
index 288cd00..d482819 100644
--- a/src/menu/components/table/base-table/options.jsx
+++ b/src/menu/components/table/base-table/options.jsx
@@ -76,6 +76,18 @@
         {value: 'mini', label: '杩蜂綘'},
       ]
     },
+    {
+      type: 'radio',
+      field: 'searchSize',
+      label: '鎼滅储闂磋窛',
+      initval: wrap.searchSize || 'middle',
+      tooltip: '鎼滅储鏉′欢鐨勪笂涓嬮棿璺濄��',
+      required: false,
+      options: [
+        {value: 'middle', label: '榛樿'},
+        {value: 'small', label: '灏�'},
+      ],
+    },
     // {
     //   type: 'radio',
     //   field: 'selected',
@@ -151,10 +163,10 @@
     {
       type: 'number',
       field: 'height',
-      label: '琛ㄦ牸楂樺害',
+      label: '鏈�澶ч珮搴�',
       initval: wrap.height || '',
-      tooltip: '琛ㄦ牸楂樺害锛岀┖鍊兼椂楂樺害鑷�傚簲銆傛敞锛氬皬浜庣瓑浜�100鏃朵负楂樺害鐨勭櫨鍒嗘瘮銆�',
-      min: 10,
+      tooltip: '琛ㄦ牸鍐呭鍖虹殑鏈�澶ч珮搴︼紙涓嶅寘鍚〃澶达級锛岀┖鍊兼椂楂樺害鑷�傚簲銆傛敞锛氬皬浜庣瓑浜�100澶т簬0鏃朵负楂樺害鐨勭櫨鍒嗘瘮锛屽皬浜�0鏃朵负绐楀彛楂樺害鍑忓幓姝ゅ�笺��',
+      min: -1000,
       max: 3000,
       precision: 0,
       required: false,
@@ -186,6 +198,7 @@
       tooltip: '榧犳爣鎮诞浜庤涓婃柟鏃剁殑鎻愮ず淇℃伅銆�',
       required: false,
       allowClear: true,
+      joint: true,
       options: columns
     },
     {
@@ -196,6 +209,7 @@
       tooltip: '鐢ㄤ簬鎺у埗琛屾暟鎹槸鍚﹀彲閫夋嫨銆�',
       required: false,
       allowClear: true,
+      joint: true,
       options: columns,
       controlFields: [
         {field: 'controlVal', notNull: true},
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 4379c5c..b0b999e 100644
--- a/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
+++ b/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
@@ -446,7 +446,7 @@
       key: 'dataSource',
       label: '鏁版嵁婧�',
       initVal: card.dataSource || '',
-      placeholder: '绯荤粺鍙橀噺锛歮k_departmentcode銆乵k_organization銆乵k_user_type銆傚叕鍏卞�粿BID@銆�',
+      placeholder: '绯荤粺鍙橀噺锛歮k_departmentcode銆乵k_organization銆乵k_user_type銆傚叕鍏卞�硷細@BID@銆丂Appkey@銆丂UserID@銆丂SessionUid@銆丂LoginUID@銆丂lang@銆�',
       required: true,
     },
     {
@@ -562,6 +562,7 @@
       tooltip: '鐢ㄤ簬鎺у埗琛屾暟鎹槸鍚﹀彲閫夋嫨銆傚瓧娈靛�间负true鏃讹紝閫夐」涓嶅彲閫夈��',
       required: false,
       allowClear: true,
+      joint: true,
       options: 'columns'
     },
     {
@@ -694,7 +695,7 @@
         text: '鏈湴'
       }, {
         value: 'sso',
-        text: '绯荤粺'
+        text: '鍗曠偣'
       }]
     },
     {
@@ -831,6 +832,21 @@
       options: fields
     },
     {
+      type: 'checkbox',
+      key: 'evalchars',
+      label: '鏇挎崲瀛楃',
+      initVal: card.evalchars || ['enter', 'space'],
+      tooltip: '鍏紡瑙f瀽鍚庯紝鍙浛鎹㈠洖杞︺�佺┖鏍肩瓑瀛楃锛屽疄鐜版崲琛屻�佸瓧闂磋窛鎺у埗绛夐〉闈㈡晥鏋溿��',
+      required: false,
+      options: [{
+        value: 'enter',
+        text: '鍥炶溅绗�'
+      }, {
+        value: 'space',
+        text: '绌烘牸'
+      }]
+    },
+    {
       type: 'radio',
       key: 'noValue',
       label: '绌哄��',
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 dd97ea0..2515403 100644
--- a/src/menu/components/table/edit-table/columns/editColumn/index.jsx
+++ b/src/menu/components/table/edit-table/columns/editColumn/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Form, Row, Col, Input, Select, InputNumber, Radio, Tooltip, Modal, notification, Popover } from 'antd'
+import { Form, Row, Col, Input, Select, InputNumber, Radio, Checkbox, Tooltip, Modal, notification, Popover } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 
 import Api from '@/api'
@@ -107,8 +107,13 @@
         _options.push('hourFormat')
       }
     }
-    if (this.record.type === 'formula' && this.record.eval === 'true') {
-      _options.push('decimal')
+    if (this.record.type === 'formula') {
+      if (this.record.eval === 'true') {
+        _options.push('decimal')
+      }
+      if (this.record.eval !== 'func') {
+        _options.push('evalchars')
+      }
     } else if (this.record.type === 'custom' && this.record.IsSort === 'true') {
       _options.push('sortField')
     }
@@ -402,6 +407,15 @@
         content = <Radio.Group onChange={(e) => {this.typeChange(item.key, e.target.value)}}>
           {item.options.map(option => <Radio key={option.value} value={option.value}>{option.text}</Radio>)}
         </Radio.Group>
+      } else if (item.type === 'checkbox') {
+        rules = [
+          { required: item.required, message: '璇烽�夋嫨' + item.label + '!' }
+        ]
+        initVal = item.initVal
+
+        content = <Checkbox.Group onChange={(e) => {this.typeChange(item.key, e.target.value)}}>
+          {item.options.map(option => <Checkbox key={option.value} value={option.value}>{option.text}</Checkbox>)}
+        </Checkbox.Group>
       } else if (item.type === 'multiselect') { // 澶氶��
         content = <Select
           showSearch
@@ -447,6 +461,7 @@
           extra = <span className="add-resource-empty" onClick={this.handleEmpty}>绌�</span>
         }
         if (item.placeholder) {
+          className = 'show-public-var'
           extra = <><span className="resource-public-var">{item.placeholder}</span>{extra}</>
         }
 
@@ -580,7 +595,7 @@
           if (!pass) return
         }
 
-        if (values.editType === 'select' && values.resourceType === '1' && values.dataSource) {
+        if (values.editType === 'select' && values.resourceType === '1' && values.database !== 'sso' && values.dataSource) {
           let _option = Utils.getSelectQueryOptions(values)
 
           let sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)
@@ -588,13 +603,8 @@
   
           // LoginUID|SessionUid|UserID|Appkey 宸叉浛鎹�
           sql = sql.replace(/@\$|\$@/ig, '')
-  
-          let rduri = ''
-          if (window.GLOB.mainSystemApi && values.database === 'sso') {
-            rduri = window.GLOB.mainSystemApi
-          }
           
-          Api.sDebug(sql, rduri).then(result => {
+          Api.sDebug(sql).then(result => {
             if (result.status || result.ErrCode === '-2') {
               this.setState({visible: false, loading: false, formlist: null})
               this.props.submitCol(values)
@@ -692,7 +702,7 @@
           title="鏄剧ず鍒楃紪杈�"
           wrapClassName="mk-scroll-modal"
           visible={visible}
-          width={900}
+          width={950}
           maskClosable={false}
           onOk={this.handleSubmit}
           onCancel={this.editModalCancel}
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 f2127e8..35a64a8 100644
--- a/src/menu/components/table/edit-table/columns/editColumn/index.scss
+++ b/src/menu/components/table/edit-table/columns/editColumn/index.scss
@@ -44,11 +44,16 @@
     cursor: pointer;
     font-size: 14px;
   }
+  .show-public-var {
+    margin-top: 20px;
+  }
   .resource-public-var {
     position: absolute;
     left: 0px;
-    top: -25px;
-    font-size: 14px;
+    top: -45px;
+    right: 40px;
+    font-size: 13px;
+    color: rgba(0, 0, 0, 0.65);
   }
 }
 .formula-fields {
diff --git a/src/menu/components/table/edit-table/columns/index.jsx b/src/menu/components/table/edit-table/columns/index.jsx
index 120c12b..9deae06 100644
--- a/src/menu/components/table/edit-table/columns/index.jsx
+++ b/src/menu/components/table/edit-table/columns/index.jsx
@@ -47,7 +47,7 @@
       cols: [column]
     }
 
-    let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+    let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
     if (srcid) {
       val.$srcId = srcid
     }
@@ -195,10 +195,10 @@
         val = '$Index'
       } else if (column.type === 'formula') {
         val = column.formula
-        if (column.eval === 'false') {
-          val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
-          val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span>
-        }
+        // if (column.eval === 'false') {
+        //   val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
+        //   val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span>
+        // }
       }
       return (
         <td style={style} className={className}>
@@ -553,7 +553,7 @@
       cols: columns.filter(col => !col.origin)
     }
 
-    let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+    let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
     if (srcid) {
       val.$srcId = srcid
     }
diff --git a/src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx b/src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx
index e1a539a..77d5966 100644
--- a/src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx
+++ b/src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx
@@ -271,7 +271,7 @@
           </Col> : null}
           {!type ? <Col span={24} className="sqlfield">
             <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</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, lang, time_id</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>,&nbsp;
               {usefulfields},data_type锛堟敞锛歫skey涓轰富閿�硷紝鏂板鏃跺墠绔敓鎴愶紱data_type涓烘搷浣滅被鍨嬶紝鏂板 - add銆佷慨鏀� - upt銆佸垹闄� - del锛�
             </Form.Item>
diff --git a/src/menu/components/table/edit-table/options.jsx b/src/menu/components/table/edit-table/options.jsx
index 78c1a63..1e409a4 100644
--- a/src/menu/components/table/edit-table/options.jsx
+++ b/src/menu/components/table/edit-table/options.jsx
@@ -45,10 +45,10 @@
     {
       type: 'number',
       field: 'height',
-      label: '楂樺害',
+      label: '鏈�澶ч珮搴�',
       initval: wrap.height || '',
-      tooltip: '琛ㄦ牸楂樺害锛岀┖鍊兼椂楂樺害鑷�傚簲銆傛敞锛氬皬浜庣瓑浜�100鏃朵负楂樺害鐨勭櫨鍒嗘瘮銆�',
-      min: 10,
+      tooltip: '琛ㄦ牸鍐呭鍖虹殑鏈�澶ч珮搴︼紙涓嶅寘鍚〃澶达級锛岀┖鍊兼椂楂樺害鑷�傚簲銆傛敞锛氬皬浜庣瓑浜�100澶т簬0鏃朵负楂樺害鐨勭櫨鍒嗘瘮锛屽皬浜�0鏃朵负绐楀彛楂樺害鍑忓幓姝ゅ�笺��',
+      min: -1000,
       max: 3000,
       precision: 0,
       required: false
@@ -127,6 +127,18 @@
         {value: 'small', label: '灏�'},
         // {value: 'mini', label: '杩蜂綘'},
       ]
+    },
+    {
+      type: 'radio',
+      field: 'searchSize',
+      label: '鎼滅储闂磋窛',
+      initval: wrap.searchSize || 'middle',
+      tooltip: '鎼滅储鏉′欢鐨勪笂涓嬮棿璺濄��',
+      required: false,
+      options: [
+        {value: 'middle', label: '榛樿'},
+        {value: 'small', label: '灏�'},
+      ],
     },
     {
       type: 'radio',
@@ -225,6 +237,7 @@
       tooltip: '榧犳爣鎮诞浜庤涓婃柟鏃剁殑鎻愮ず淇℃伅銆�',
       required: false,
       allowClear: true,
+      joint: true,
       options: columns
     },
     {
diff --git a/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
index 6ad02d3..e5c2d75 100644
--- a/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
+++ b/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
@@ -513,6 +513,21 @@
       required: true
     },
     {
+      type: 'checkbox',
+      key: 'evalchars',
+      label: '鏇挎崲瀛楃',
+      initVal: card.evalchars || ['enter', 'space'],
+      tooltip: '鍏紡瑙f瀽鍚庯紝鍙浛鎹㈠洖杞︺�佺┖鏍肩瓑瀛楃锛屽疄鐜版崲琛屻�佸瓧闂磋窛鎺у埗绛夐〉闈㈡晥鏋溿��',
+      required: false,
+      options: [{
+        value: 'enter',
+        text: '鍥炶溅绗�'
+      }, {
+        value: 'space',
+        text: '绌烘牸'
+      }]
+    },
+    {
       type: 'radio',
       key: 'noValue',
       label: '绌哄��',
diff --git a/src/menu/components/table/normal-table/columns/editColumn/index.jsx b/src/menu/components/table/normal-table/columns/editColumn/index.jsx
index 5f3d09c..9ec8a74 100644
--- a/src/menu/components/table/normal-table/columns/editColumn/index.jsx
+++ b/src/menu/components/table/normal-table/columns/editColumn/index.jsx
@@ -94,8 +94,13 @@
       } else if (this.record.perspective === 'linkurl') {
         _options.push('linkurl', 'open')
       }
-    } else if (this.record.type === 'formula' && this.record.eval === 'true') {
-      _options.push('decimal')
+    } else if (this.record.type === 'formula') {
+      if (this.record.eval === 'true') {
+        _options.push('decimal')
+      }
+      if (this.record.eval !== 'func') {
+        _options.push('evalchars')
+      }
     } else if (this.record.type === 'custom' && this.record.IsSort === 'true') {
       _options.push('sortField')
     } else if (this.record.type === 'extend') {
diff --git a/src/menu/components/table/normal-table/columns/index.jsx b/src/menu/components/table/normal-table/columns/index.jsx
index 0279ed8..de7593e 100644
--- a/src/menu/components/table/normal-table/columns/index.jsx
+++ b/src/menu/components/table/normal-table/columns/index.jsx
@@ -47,7 +47,7 @@
       cols: [column]
     }
 
-    let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+    let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
     if (srcid) {
       val.$srcId = srcid
     }
@@ -195,10 +195,10 @@
         val = '$Index'
       } else if (column.type === 'formula') {
         val = column.formula
-        if (column.eval === 'false') {
-          val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
-          val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span>
-        }
+        // if (column.eval === 'false') {
+        //   val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
+        //   val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span>
+        // }
       }
       return (
         <td style={{...style}} className={className}>
@@ -518,7 +518,7 @@
       cols: columns.filter(col => !col.origin)
     }
 
-    let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+    let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
     if (srcid) {
       val.$srcId = srcid
     }
diff --git a/src/menu/components/table/normal-table/options.jsx b/src/menu/components/table/normal-table/options.jsx
index 22662e1..1806ca8 100644
--- a/src/menu/components/table/normal-table/options.jsx
+++ b/src/menu/components/table/normal-table/options.jsx
@@ -52,10 +52,10 @@
     {
       type: 'number',
       field: 'height',
-      label: '楂樺害',
+      label: '鏈�澶ч珮搴�',
       initval: wrap.height || '',
-      tooltip: '琛ㄦ牸楂樺害锛岀┖鍊兼椂楂樺害鑷�傚簲銆傛敞锛氬皬浜庣瓑浜�100鏃朵负楂樺害鐨勭櫨鍒嗘瘮銆�',
-      min: 10,
+      tooltip: '琛ㄦ牸鍐呭鍖虹殑鏈�澶ч珮搴︼紙涓嶅寘鍚〃澶达級锛岀┖鍊兼椂楂樺害鑷�傚簲銆傛敞锛氬皬浜庣瓑浜�100澶т簬0鏃朵负楂樺害鐨勭櫨鍒嗘瘮锛屽皬浜�0鏃朵负绐楀彛楂樺害鍑忓幓姝ゅ�笺��',
+      min: -1000,
       max: 3000,
       precision: 0,
       required: false,
@@ -161,6 +161,19 @@
     },
     {
       type: 'radio',
+      field: 'searchSize',
+      label: '鎼滅储闂磋窛',
+      initval: wrap.searchSize || 'middle',
+      tooltip: '鎼滅储鏉′欢鐨勪笂涓嬮棿璺濄��',
+      required: false,
+      options: [
+        {value: 'middle', label: '榛樿'},
+        {value: 'small', label: '灏�'},
+      ],
+      forbid: appType === 'mob'
+    },
+    {
+      type: 'radio',
       field: 'mode',
       label: '妯″紡',
       initval: wrap.mode || 'default',
@@ -233,6 +246,7 @@
       tooltip: '榧犳爣鎮诞浜庤涓婃柟鏃剁殑鎻愮ず淇℃伅銆�',
       required: false,
       allowClear: true,
+      joint: true,
       options: columns
     },
     {
@@ -243,6 +257,7 @@
       tooltip: '鐢ㄤ簬鎺у埗琛屾暟鎹槸鍚﹀彲閫夋嫨銆�',
       required: false,
       allowClear: true,
+      joint: true,
       options: columns,
       controlFields: [
         {field: 'controlVal', notNull: true},
diff --git a/src/menu/datasource/verifycard/customscript/index.jsx b/src/menu/datasource/verifycard/customscript/index.jsx
index 545d436..cf60479 100644
--- a/src/menu/datasource/verifycard/customscript/index.jsx
+++ b/src/menu/datasource/verifycard/customscript/index.jsx
@@ -243,9 +243,9 @@
           </Col>
           <Col span={24}>
             <Form.Item label="鍙敤瀛楁" className="field-able">
-              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, LoginUID, SessionUid, UserID, Appkey, time_id, typename, datam</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, LoginUID, SessionUid, UserID, Appkey, lang, time_id, typename, datam</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>,&nbsp;
-              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鎺掑簭銆佸垎椤典互鍙婃悳绱㈡潯浠跺彉閲忥紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆備娇鐢ˊpageSize@鎴朄orderBy@浠h〃鑷畾涔夊垎椤碉紝鎬绘暟璇蜂互mk_total杩斿洖銆�'}>orderBy, pageSize, pageIndex{usefulFields ? ', ' + usefulFields : ''}{type === 'calendar' ? ', mk_year' : ''}{hasExtend ? ', mk_time' : ''}</Tooltip>
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鎺掑簭銆佸垎椤典互鍙婃悳绱㈡潯浠跺彉閲忥紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆備娇鐢ˊpageSize@銆丂orderBy@ 鎴栬剼鏈腑瀛樺湪 @mk_total 浠h〃鑷畾涔夊垎椤碉紝鎬绘暟璇蜂互mk_total杩斿洖銆�'}>orderBy, pageSize, pageIndex{usefulFields ? ', ' + usefulFields : ''}{type === 'calendar' ? ', mk_year' : ''}{hasExtend ? ', mk_time' : ''}</Tooltip>
               <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'url鍙橀噺锛岃鎸夌収@xxx@鏍煎紡浣跨敤銆�'}>{urlFields ? ', ' : ''}<span style={{color: '#13c2c2'}}>{urlFields}</span></Tooltip>
               {window.GLOB.process ? <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'宸ヤ綔娴佸彉閲忥紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}>, <span style={{color: 'purple'}}>works_flow_code</span></Tooltip> : null}
             </Form.Item>
diff --git a/src/menu/datasource/verifycard/index.jsx b/src/menu/datasource/verifycard/index.jsx
index f38a70b..b59417f 100644
--- a/src/menu/datasource/verifycard/index.jsx
+++ b/src/menu/datasource/verifycard/index.jsx
@@ -4,7 +4,6 @@
 import { Form, Tabs, Popconfirm, notification, Modal, Typography, Spin, message, Button, Input } from 'antd'
 import { StopOutlined, CheckCircleOutlined, TableOutlined, EditOutlined, SwapOutlined, DeleteOutlined, CopyOutlined, BorderOutlined, SnippetsOutlined } from '@ant-design/icons'
 import moment from 'moment'
-import md5 from 'md5'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
@@ -683,8 +682,6 @@
 
       let r = SettingUtils.getDebugSql(setting, _scripts, _columns, searches, config.subtype, config.hasExtend)
 
-      let _debugId = md5(r.sql)
-      
       if (r.custompage && setting.laypage === 'true' && _columns.findIndex(col => col.field === 'mk_total') === -1) {
         if (config.subtype !== 'basetable') {
           Modal.warning({
@@ -704,7 +701,7 @@
         }
       }
 
-      if (debugId === _debugId) {
+      if (debugId === r.debugId) {
         resolve()
         return
       }
@@ -719,7 +716,7 @@
 
       Api.sDebug(r.sql).then(result => {
         if (result.status || result.ErrCode === '-2') {
-          this.setState({debugId: _debugId}, () => {
+          this.setState({debugId: r.debugId}, () => {
             resolve()
           })
         } else {
diff --git a/src/menu/datasource/verifycard/settingform/index.jsx b/src/menu/datasource/verifycard/settingform/index.jsx
index 97cedeb..1e7a410 100644
--- a/src/menu/datasource/verifycard/settingform/index.jsx
+++ b/src/menu/datasource/verifycard/settingform/index.jsx
@@ -105,6 +105,9 @@
           if (values.interType === 'system' && values.onload === 'false') {
             values.sync = 'false'
           }
+          if (values.interType === 'system' && values.database === 'sso') {
+            values.sync = 'false'
+          }
 
           // 鏁版嵁婧愬墠绔獙璇�
           if (values.interType === 'system' && values.execute !== 'false' && values.dataresource) {
@@ -515,6 +518,17 @@
                 </Radio.Group>)}
               </Form.Item>
             </Col> : null}
+            {setting.interType === 'system' ? <Col span={8}>
+              <Form.Item label="鏁版嵁搴�">
+                {getFieldDecorator('database', {
+                  initialValue: setting.database || 'local'
+                })(
+                <Radio.Group>
+                  <Radio value="local">鏈湴</Radio>
+                  <Radio value="sso">鍗曠偣</Radio>
+                </Radio.Group>)}
+              </Form.Item>
+            </Col> : null}
             {/* 1銆佷笉鍒嗛〉涓斾笉瀛樺湪涓婄骇妯″潡 */}
             {!['navbar', 'interface', 'calendar'].includes(config.type) && !['editable', 'basetable', 'dualdatacard', 'invoice', 'invTable'].includes(config.subtype) && (!config.pageable || (config.pageable && setting.laypage === 'false')) && (setting.supModule.length === 0 || setting.supModule[0] === 'empty') && setting.interType === 'system' && setting.onload !== 'false' ? <Col span={8}>
               <Form.Item label={
diff --git a/src/menu/datasource/verifycard/utils.jsx b/src/menu/datasource/verifycard/utils.jsx
index 67b552d..6714e81 100644
--- a/src/menu/datasource/verifycard/utils.jsx
+++ b/src/menu/datasource/verifycard/utils.jsx
@@ -1,4 +1,5 @@
 
+import md5 from 'md5'
 import { getSearchRegs, joinMainSearchkey } from '@/utils/utils-custom.js'
 
 export default class SettingUtils {
@@ -49,34 +50,24 @@
       })
     }
 
-    let getuuid = () => {
-      let uuid = []
-      let timestamp = new Date().getTime()
-      let _options = '0123456789abcdefghigklmnopqrstuv'
-      for (let i = 0; i < 19; i++) {
-        uuid.push(_options.substr(Math.floor(Math.random() * 0x20), 1))
-      }
-      uuid = timestamp + uuid.join('')
-      return uuid
-    }
-
     let regs = [
-      {reg: /@time_id@/ig, value: `'${getuuid()}'`},
-      {reg: /@BID@/ig, value: `'${getuuid()}'`},
-      {reg: /@upid@/ig, value: `'${getuuid()}'`},
+      // {reg: /@time_id@/ig, value: `'${getuuid()}'`}, // 璁$畻md5鍚庢浛鎹�
+      // {reg: /@BID@/ig, value: `'${getuuid()}'`},
+      // {reg: /@upid@/ig, value: `'${getuuid()}'`},
       {reg: /@typename@/ig, value: `'debug'`},
       {reg: /@datam@/ig, value: `''`},
       {reg: /@LoginUID@/ig, value: `'${sessionStorage.getItem('LoginUID')}'`},
       {reg: /@SessionUid@/ig, value: `'${localStorage.getItem('SessionUid')}'`},
       {reg: /@UserID@/ig, value: `'${sessionStorage.getItem('UserID')}'`},
       {reg: /@Appkey@/ig, value: `'${window.GLOB.appkey}'`},
+      {reg: /@lang@/ig, value: `'${sessionStorage.getItem('lang')}'`},
       {reg: /@\$|\$@/ig, value: ''},
       {reg: /@select\$|\$select@/ig, value: ''},
       {reg: /@sum\$|\$sum@/ig, value: ''},
     ]
 
     if (window.GLOB.process && type !== 'invoice') {
-      regs.push({reg: /@works_flow_code@/ig, value: `'${getuuid()}'`})
+      regs.push({reg: /@works_flow_code@/ig, value: `'mk_flow_code'`})
     }
 
     if (hasExtend) {
@@ -114,7 +105,7 @@
     }
 
     // 姝e垯鏇挎崲
-    let custompage = /@pageSize@|@orderBy@/i.test(_dataresource + _customScript)
+    let custompage = /@pageSize@|@orderBy@|@mk_total/i.test(_dataresource + _customScript)
     let _regoptions = getSearchRegs(searches)
 
     let _search = joinMainSearchkey(searches)
@@ -182,6 +173,29 @@
         ${_dataresource}`
     }
 
+    let debugId = md5(sql + window.GLOB.appkey)
+
+    let getuuid = () => {
+      let uuid = []
+      let timestamp = new Date().getTime()
+      let _options = '0123456789abcdefghigklmnopqrstuv'
+      for (let i = 0; i < 19; i++) {
+        uuid.push(_options.substr(Math.floor(Math.random() * 0x20), 1))
+      }
+      uuid = timestamp + uuid.join('')
+      return uuid
+    }
+
+    let _regs = [
+      {reg: /@time_id@/ig, value: `'${getuuid()}'`},
+      {reg: /@BID@/ig, value: `'${getuuid()}'`},
+      {reg: /@upid@/ig, value: `'${getuuid()}'`},
+    ]
+
+    _regs.forEach(item => {
+      sql = sql.replace(item.reg, item.value)
+    })
+
     let errors = []
 
     if (/@[0-9a-zA-Z_]+@/ig.test(sql)) {
@@ -214,8 +228,6 @@
       })
 
       arr.forEach(item => {
-        if (/@time_id@/ig.test(item)) return
-
         let reg = new RegExp(item, 'i')
         if (reg.test(_dataresource)) {
           errors.push(`鏁版嵁婧愪腑瀛樺湪鏈浛鎹㈠��${item}`)
@@ -232,6 +244,6 @@
       })
     }
 
-    return { error, sql, errors: errors.join('锛�'), custompage }
+    return { error, sql, errors: errors.join('锛�'), custompage, debugId }
   }
 }
\ No newline at end of file
diff --git a/src/menu/debug/index.jsx b/src/menu/debug/index.jsx
index c40298c..737fd3e 100644
--- a/src/menu/debug/index.jsx
+++ b/src/menu/debug/index.jsx
@@ -1956,7 +1956,7 @@
     item.setting.dataresource = _dataresource
     item.setting.customScript = _customScript
 
-    let custompage = /@pageSize@|@orderBy@/i.test(_dataresource + _customScript)
+    let custompage = /@pageSize@|@orderBy@|@mk_total/i.test(_dataresource + _customScript)
 
     if (_dataresource) {
       if (custompage) {
diff --git a/src/menu/sysinterface/index.jsx b/src/menu/sysinterface/index.jsx
index 1504093..3c61833 100644
--- a/src/menu/sysinterface/index.jsx
+++ b/src/menu/sysinterface/index.jsx
@@ -74,7 +74,7 @@
   copy = (item) => {
     let msg = { key: 'interface', type: 'line', data: item }
 
-    let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+    let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
     if (srcid) {
       msg.$srcId = srcid
     }
diff --git a/src/menu/tablenodes/index.jsx b/src/menu/tablenodes/index.jsx
index c04da88..12951c2 100644
--- a/src/menu/tablenodes/index.jsx
+++ b/src/menu/tablenodes/index.jsx
@@ -548,11 +548,11 @@
         }
       } else if (menu.param.type === 'app') {
         if (menu.param.typename !== 'pc') {
-          let _param = {...menu.param}
+          let _param = {...menu.param, lang: sessionStorage.getItem('lang')}
           _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
           window.open(`#/mobdesign/${_param}`)
         } else {
-          let _param = {...menu.param}
+          let _param = {...menu.param, lang: sessionStorage.getItem('lang')}
           _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
           window.open(`#/pcdesign/${_param}`)
         }
diff --git a/src/mob/colorsketch/index.jsx b/src/mob/colorsketch/index.jsx
index ac0a99e..2260cdd 100644
--- a/src/mob/colorsketch/index.jsx
+++ b/src/mob/colorsketch/index.jsx
@@ -12,7 +12,6 @@
   '#eb2f96', '#aeb303', '#c32539', '#1d3661', '#ffd591', '#ffe58f', '#fffb8f', '#eaff8f', '#b7eb8f', '#87e8de', '#91d5ff',
   '#adc6ff', '#EBE9E9', '#d9d9d9', 'rgba(0, 0, 0, 0.65)', 'rgba(0, 0, 0, 0.85)', '#000000', '#ffffff', 'transparent'
 ]
-const _href = window.location.href.split('#')[0]
 let loading = false
 
 class ColorSketch extends Component {
@@ -79,7 +78,7 @@
 
   getColors = (appColors) => {
     let colors = JSON.parse(JSON.stringify(presetColors))
-    let normal_colors = localStorage.getItem(_href + 'normal_colors')
+    let normal_colors = localStorage.getItem(window.GLOB.sysSign + 'normal_colors')
 
     if (normal_colors) {
       try {
@@ -135,7 +134,7 @@
     const { initVal, color } = this.state
     
     if (!status && color && color !== initVal && color !== 'rgba(0, 0, 0, 0)' && color !== 'transparent' && !/rgba\(\d+,\s*\d+,\s*\d+,\s*0\)/.test(color)) {
-      let normal_colors = localStorage.getItem(_href + 'normal_colors')
+      let normal_colors = localStorage.getItem(window.GLOB.sysSign + 'normal_colors')
 
       if (normal_colors) {
         try {
@@ -154,7 +153,7 @@
         normal_colors.length = 10
       }
 
-      localStorage.setItem(_href + 'normal_colors', JSON.stringify(normal_colors))
+      localStorage.setItem(window.GLOB.sysSign + 'normal_colors', JSON.stringify(normal_colors))
     }
   }
 
diff --git a/src/mob/components/formdragelement/index.jsx b/src/mob/components/formdragelement/index.jsx
index 838e79d..d357279 100644
--- a/src/mob/components/formdragelement/index.jsx
+++ b/src/mob/components/formdragelement/index.jsx
@@ -66,7 +66,7 @@
 
     delete val.$srcId
     
-    let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+    let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
     if (srcid) {
       val.$srcId = srcid
     }
diff --git a/src/mob/components/menubar/normal-menubar/menucomponent/options.jsx b/src/mob/components/menubar/normal-menubar/menucomponent/options.jsx
index d61728f..eace136 100644
--- a/src/mob/components/menubar/normal-menubar/menucomponent/options.jsx
+++ b/src/mob/components/menubar/normal-menubar/menucomponent/options.jsx
@@ -82,6 +82,7 @@
       required: false,
       options: menulist,
       extendName: 'MenuNo',
+      dropdown: 'false',
       controlFields: [
         {field: 'clearMenu', notNull: true},
       ],
diff --git a/src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx b/src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx
index cacce83..bb3818d 100644
--- a/src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx
+++ b/src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx
@@ -168,6 +168,7 @@
                 <Select
                   allowClear
                   showSearch
+                  dropdownMatchSelectWidth={false}
                   filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
                     option.props.extend.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                   onChange={(val) => this.setState({copyMenu: val})}
diff --git a/src/mob/searchconfig/index.jsx b/src/mob/searchconfig/index.jsx
index e943736..2f7454c 100644
--- a/src/mob/searchconfig/index.jsx
+++ b/src/mob/searchconfig/index.jsx
@@ -223,7 +223,7 @@
         return
       }
 
-      if (['checkcard'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) {
+      if (['checkcard'].includes(res.type) && res.resourceType === '1' && res.database !== 'sso' && /\s/.test(res.dataSource)) {
         this.setState({
           sqlVerifing: true
         })
@@ -232,12 +232,7 @@
         ${res.dataSource}`
         sql = sql.replace(/@\$|\$@/ig, '')
         
-        let rduri = ''
-        if (window.GLOB.mainSystemApi && res.database === 'sso') {
-          rduri = window.GLOB.mainSystemApi
-        }
-        
-        Api.sDebug(sql, rduri).then(result => {
+        Api.sDebug(sql).then(result => {
           if (result.status || result.ErrCode === '-2') {
             this.setState({
               sqlVerifing: false,
@@ -537,7 +532,7 @@
         <Modal
           title="缂栬緫"
           visible={this.state.visible}
-          width={850}
+          width={950}
           onCancel={this.editModalCancel}
           onOk={this.handleSubmit}
           confirmLoading={this.state.sqlVerifing}
diff --git a/src/mob/searchconfig/searchdragelement/index.jsx b/src/mob/searchconfig/searchdragelement/index.jsx
index 1583c99..cf7e96a 100644
--- a/src/mob/searchconfig/searchdragelement/index.jsx
+++ b/src/mob/searchconfig/searchdragelement/index.jsx
@@ -55,7 +55,7 @@
 
     delete val.$srcId
     
-    let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+    let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
     if (srcid) {
       val.$srcId = srcid
     }
diff --git a/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx b/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx
index f8ea138..3454eb1 100644
--- a/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx
+++ b/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx
@@ -159,7 +159,7 @@
               {getFieldDecorator('copyMenuId', {
                 initialValue: menu.copyMenuId || ''
               })(
-                <Select allowClear onChange={(val) => this.setState({copyMenu: val})}>
+                <Select allowClear dropdownMatchSelectWidth={false} onChange={(val) => this.setState({copyMenu: val})}>
                   {appMenus.map(item => (<Select.Option key={item.MenuID} value={item.MenuID}>{item.MenuName}</Select.Option>))}
                 </Select>
               )}
diff --git a/src/pc/createview/index.jsx b/src/pc/createview/index.jsx
index 856e54c..2465808 100644
--- a/src/pc/createview/index.jsx
+++ b/src/pc/createview/index.jsx
@@ -87,8 +87,8 @@
         MenuName: res.MenuName || '',
         PageParam: JSON.stringify({Template: 'webPage'}),
         open_edition: '',
-        LText: '',
-        LTexttb: ''
+        // LText: '',
+        // LTexttb: ''
       }
 
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
diff --git a/src/pc/createview/settingform/index.jsx b/src/pc/createview/settingform/index.jsx
index 0405709..730abc6 100644
--- a/src/pc/createview/settingform/index.jsx
+++ b/src/pc/createview/settingform/index.jsx
@@ -120,6 +120,7 @@
                 <Select
                   allowClear
                   showSearch
+                  dropdownMatchSelectWidth={false}
                   onChange={(val) => this.setState({copymenuId: val})}
                   filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                 >
diff --git a/src/setupProxy.js b/src/setupProxy.js
index 4d69c53..c82ef96 100644
--- a/src/setupProxy.js
+++ b/src/setupProxy.js
@@ -36,6 +36,12 @@
     changeOrigin: true
   }))
 
+  app.use(proxy('/wechat', {
+    target: `${options.host}/${options.service}`,
+    secure: false,
+    changeOrigin: true
+  }))
+
 //   app.use(proxy('/trans', {
 //     target: `${host}/${service}`,
 //     secure: false,
diff --git a/src/store/options.js b/src/store/options.js
index 3dc04f2..2f0df33 100644
--- a/src/store/options.js
+++ b/src/store/options.js
@@ -45,4 +45,19 @@
   bg_white_style_deep_red: 'mk-deep-red-white',
   bg_black_style_deep_blue: 'mk-deep-blue-black',
   bg_white_style_deep_blue: 'mk-deep-blue-white',
+}
+
+/**
+ * @description 璇█
+ */
+export const langs = {
+  'zh-CN': '绠�浣撲腑鏂�',
+  'en-US': 'English',
+  'fr-FR': 'Fran莽ais',
+  'de-DE': 'Deutsch',
+  'ko-KR': '頃滉淡鞏�',
+  'pt-BR': 'Portugu锚s',
+  'ja-jp': '鏃ユ湰瑾�',
+  'ar-AE': '毓乇亘賷 貙',
+  'ru-RU': '褉褍褋褋泻懈泄 褟蟹褘泻'
 }
\ No newline at end of file
diff --git a/src/tabviews/basetable/index.jsx b/src/tabviews/basetable/index.jsx
index b02c94b..3d13f4b 100644
--- a/src/tabviews/basetable/index.jsx
+++ b/src/tabviews/basetable/index.jsx
@@ -504,12 +504,6 @@
 
     if (cell.OpenType === 'excelOut') { // 瀵煎嚭
       cell.$menuName = item.$menuname
-
-      if (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0) {
-        cell.errorType = 'error1'
-      } else if (cell.intertype === 'system' && cell.verify.dataType !== 'custom' && item.setting.interType !== 'system') {
-        cell.errorType = 'error2'
-      }
     }
 
     if (cell.verify) {
@@ -677,7 +671,7 @@
       component.setting.customScript = _customScript // 鏁寸悊鍚庤嚜瀹氫箟鑴氭湰
       component.setting.tailScript = _tailScript     // 鍚庣疆鑷畾涔夎剼鏈�
 
-      component.setting.custompage = /@pageSize@|@orderBy@/i.test(component.setting.dataresource + component.setting.customScript)
+      component.setting.custompage = /@pageSize@|@orderBy@|@mk_total/i.test(component.setting.dataresource + component.setting.customScript)
 
       if (!component.setting.execute || component.setting.custompage) {
         component.forbidLine = true
diff --git a/src/tabviews/commontable/index.jsx b/src/tabviews/commontable/index.jsx
index e94c925..463dc0b 100644
--- a/src/tabviews/commontable/index.jsx
+++ b/src/tabviews/commontable/index.jsx
@@ -305,12 +305,6 @@
 
         if (item.OpenType === 'excelOut') { // 瀵煎嚭
           item.$menuName = MenuName
-    
-          if (!item.verify || !item.verify.columns || item.verify.columns.length === 0) {
-            item.errorType = 'error1'
-          } else if (item.intertype === 'system' && item.verify.dataType !== 'custom' && config.setting.interType !== 'system') {
-            item.errorType = 'error2'
-          }
         }
 
         if (item.verify && item.verify.invalid === 'true') {
diff --git a/src/tabviews/custom/components/calendar/board/index.jsx b/src/tabviews/custom/components/calendar/board/index.jsx
index fddbe03..f4e1e3b 100644
--- a/src/tabviews/custom/components/calendar/board/index.jsx
+++ b/src/tabviews/custom/components/calendar/board/index.jsx
@@ -10,7 +10,9 @@
 
 const { Option } = Select
 
-moment.locale('zh-cn')
+if (sessionStorage.getItem('lang') === 'zh-CN') {
+  moment.locale('zh-cn')
+}
 
 class CalendarBoard extends Component {
   static propTpyes = {
diff --git a/src/tabviews/custom/components/card/cardcellList/index.jsx b/src/tabviews/custom/components/card/cardcellList/index.jsx
index 16ec710..2412eb3 100644
--- a/src/tabviews/custom/components/card/cardcellList/index.jsx
+++ b/src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -991,8 +991,10 @@
   
         if (val !== '') {
           if (val && typeof(val) === 'string') {
-            val = val.replace(/\n/ig, '<br/>')
-            if (!/<(span|div|p|a|img)\s/g.test(val)) {
+            if (!card.evalchars || card.evalchars.includes('enter')) {
+              val = val.replace(/\n/ig, '<br/>')
+            }
+            if ((!card.evalchars || card.evalchars.includes('space')) && !/<(span|div|p|a|img)\s/g.test(val)) {
               val = val.replace(/\s/ig, '&nbsp;')
             }
 
diff --git a/src/tabviews/custom/components/card/data-card/index.jsx b/src/tabviews/custom/components/card/data-card/index.jsx
index f5d8dd2..b442a83 100644
--- a/src/tabviews/custom/components/card/data-card/index.jsx
+++ b/src/tabviews/custom/components/card/data-card/index.jsx
@@ -188,6 +188,23 @@
       }
     }
 
+    if (_config.wrap.zHeight) {
+      if (_config.wrap.zHeight <= 100) {
+        if (_config.wrap.zHeight < 0) {
+          _config.wrap.zHeight = `calc(100vh - ${-_config.wrap.zHeight}px)`
+        } else {
+          _config.wrap.zHeight = _config.wrap.zHeight + 'vh'
+        }
+      }
+
+      if (_config.style) {
+        delete _config.style.height
+      }
+      _config.wrap.layout += ' fix-height'
+    } else {
+      _config.wrap.zHeight = 'none'
+    }
+
     this.setState({
       pageSize: _config.setting.pageSize || 10,
       pageOptions,
@@ -599,7 +616,7 @@
       MKEmitter.emit('resetSelectLine', config.uuid, last ? last.$$uuid : '', last)
       MKEmitter.emit('syncBalconyData', config.uuid, items, data.length > 0 && data.length === keys.length)
       if (items.length === 0) {
-        message.warning('鏈幏鍙栧埌鏁版嵁锛�')
+        message.warning(window.GLOB.dict['no_data'] || '鏈幏鍙栧埌鏁版嵁锛�')
       }
     } else {
       this.setState({
@@ -1205,10 +1222,10 @@
             selectedData={selectedData}
           /> : null
         }
-        {config.wrap.pickup === 'true' && this.state.data.length > 0 ? <div className="pickup-wrap"><Switch title="鏀惰捣" checkedChildren="寮�" unCheckedChildren="鍏�" checked={pickup} onChange={this.pickupChange} /></div> : null}
+        {config.wrap.pickup === 'true' && this.state.data.length > 0 ? <div className="pickup-wrap"><Switch title="鏀惰捣" checkedChildren={window.GLOB.dict['open'] || '寮�'} unCheckedChildren={window.GLOB.dict['shut'] || '鍏�'} checked={pickup} onChange={this.pickupChange} /></div> : null}
         <div className={`data-zoom ${config.wrap.wrapClass}`}>
           {switchable ? <div className={'prev-page ' + (pageIndex === 1 ? 'disabled' : '')} onClick={this.prevPage}><div><div><img src={preImg} alt=""/></div></div></div> : null}
-          <Row className={'card-row-list ' + config.wrap.layout}>
+          <Row className={'card-row-list ' + config.wrap.layout} style={{maxHeight: config.wrap.zHeight}}>
             {precards.map((item, index) => (
               <Col key={'pre' + index} className="extend-card" style={item.wStyle} span={item.setting.width || 6}>
                 {item.setting.cardRole === 'header' ? <TableHeader card={item} data={extendData} refresh={this.refreshByHeader}>
@@ -1254,8 +1271,8 @@
           {switchable ? <div className={'prev-page ' + (total <= _total ? 'disabled' : '')} onClick={this.nextPage}><div><div><img src={nextImg} alt=""/></div></div></div> : null}
         </div>
         {config.$empty && data.length === 0 ? <Empty description={false}/> : null}
-        {config.wrap.pagestyle === 'page' ? <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.length > 0 ? <div className={'mk-more' + (pageSize * pageIndex >= total ? ' disabled' : '')} onClick={this.loadMore}>鏌ョ湅鏇村<DownOutlined/></div> : null}
+        {config.wrap.pagestyle === 'page' ? <Pagination size="small" total={total} showTotal={(t, range) => total > 0 ? `${range[0]}-${range[1]} ${window.GLOB.dict['of'] || '鍏�'} ${total} ${window.GLOB.dict['items'] || '鏉�'}` : `${total} ${window.GLOB.dict['items'] || '鏉�'}`} pageSize={pageSize} showSizeChanger={true} pageSizeOptions={this.state.pageOptions} onChange={this.changePageIndex} onShowSizeChange={this.pageSizeChange} current={pageIndex}/> : null}
+        {config.wrap.pagestyle === 'more' && data.length > 0 ? <div className={'mk-more' + (pageSize * pageIndex >= total ? ' disabled' : '')} onClick={this.loadMore}>{window.GLOB.dict['view_more'] || '鏌ョ湅鏇村'}<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 e26e385..7a3eefc 100644
--- a/src/tabviews/custom/components/card/data-card/index.scss
+++ b/src/tabviews/custom/components/card/data-card/index.scss
@@ -8,6 +8,7 @@
 
   .pickup-wrap {
     float: right;
+    margin-bottom: 3px;
     button {
       margin-top: 3px;
     }
@@ -64,6 +65,25 @@
   .card-row-list {
     flex: 10;
     max-width: 100%;
+  }
+  .card-row-list.fix-height {
+    border: 1px solid #e8e8e8;
+    border-radius: 4px;
+    overflow-y: auto;
+    .extend-card:first-child {
+      position: sticky;
+      top: 0;
+      z-index: 1;
+      .card-item-box {
+        margin-top: 0!important;
+        margin-bottom: 0!important;
+      }
+    }
+    div:last-child {
+      .card-item-box {
+        border-bottom: none!important;
+      }
+    }
   }
   .card-row-list.flex-layout {
     display: flex;
@@ -275,16 +295,16 @@
     }
   }
 }
-.custom-data-card-box::-webkit-scrollbar {
+.custom-data-card-box::-webkit-scrollbar, .custom-data-card-box .card-row-list::-webkit-scrollbar {
   width: 7px;
   height: 7px;
 }
-.custom-data-card-box::-webkit-scrollbar-thumb {
+.custom-data-card-box::-webkit-scrollbar-thumb, .custom-data-card-box .card-row-list::-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);
 }
-.custom-data-card-box::-webkit-scrollbar-track {
+.custom-data-card-box::-webkit-scrollbar-track, .custom-data-card-box .card-row-list::-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);
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 4f56e58..a5fd92e 100644
--- a/src/tabviews/custom/components/card/double-data-card/index.jsx
+++ b/src/tabviews/custom/components/card/double-data-card/index.jsx
@@ -129,6 +129,26 @@
 
     _config.wrap.wrapClass =  `${_config.wrap.selStyle} ${_config.wrap.cardType || ''}`
 
+    if (_config.wrap.zHeight || _config.wrap.minWidth) {
+      if (_config.wrap.zHeight) {
+        if (_config.wrap.zHeight <= 100) {
+          if (_config.wrap.zHeight < 0) {
+            _config.wrap.zHeight = `calc(100vh - ${-_config.wrap.zHeight}px)`
+          } else {
+            _config.wrap.zHeight = _config.wrap.zHeight + 'vh'
+          }
+        }
+        _config.wrap.wrapClass += ' fix-height'
+      }
+      _config.wrap.minWidth = _config.wrap.minWidth ? _config.wrap.minWidth + 'px' : '100%'
+      _config.wrap.zoomStyle = {
+        maxHeight: _config.wrap.zHeight || 'none',
+        '--mk-data-zoom-width': _config.wrap.minWidth
+      }
+    } else {
+      _config.wrap.zoomStyle = null
+    }
+
     if (_config.wrap.shifting === 'true') {
       _config.wrap.shifting = 'shifting'
     } else {
@@ -173,19 +193,6 @@
       if (_config.wrap.maxPageSize) {
         pageOptions = pageOptions.filter(item => item <= _config.wrap.maxPageSize)
       }
-    }
-
-    if (_config.wrap.zHeight) {
-      _config.wrap.zHeight = _config.wrap.zHeight <= 100 ? _config.wrap.zHeight + 'vh' : _config.wrap.zHeight
-    }
-
-    if (_config.wrap.zHeight || _config.wrap.minWidth) {
-      _config.wrap.zoomStyle = {
-        border: `1px solid ${_config.wrap.zBColor || 'transparent'}`,
-        height: _config.wrap.zHeight || 'auto'
-      }
-    } else {
-      _config.wrap.zoomStyle = null
     }
 
     this.setState({
@@ -1152,10 +1159,10 @@
             selectedData={selectedData}
           /> : null
         }
-        {config.wrap.pickup === 'true' && this.state.data.length > 0 ? <div className="pickup-wrap"><Switch title="鏀惰捣" checkedChildren="寮�" unCheckedChildren="鍏�" checked={pickup} onChange={this.pickupChange} /></div> : null}
+        {config.wrap.pickup === 'true' && this.state.data.length > 0 ? <div className="pickup-wrap"><Switch title="鏀惰捣" checkedChildren={window.GLOB.dict['open'] || '寮�'} unCheckedChildren={window.GLOB.dict['shut'] || '鍏�'} checked={pickup} onChange={this.pickupChange} /></div> : null}
         <div className={config.wrap.zoomStyle ? 'data-zoom-box' : ''} style={config.wrap.zoomStyle}>
-          <div className={`data-zoom ${config.wrap.wrapClass}`} style={config.wrap.minWidth ? {minWidth: config.wrap.minWidth} : null}>
-            <Row className={'card-row-list '}>
+          <div className={`data-zoom ${config.wrap.wrapClass}`}>
+            <Row className="card-row-list">
               {precards.map((item, index) => (
                 <Col key={'pre' + index} className="extend-card" style={item.wStyle} span={item.setting.width || 6}>
                   {item.setting.cardRole === 'header' ? <TableHeader card={item} data={extendData} refresh={this.refreshByHeader}>
@@ -1232,8 +1239,8 @@
           </div>
           {config.$empty && data.length === 0 ? <Empty description={false}/> : null}
         </div>
-        {config.wrap.pagestyle === 'page' ? <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.length > 0 ? <div className={'mk-more' + (pageSize * pageIndex >= total ? ' disabled' : '')} onClick={this.loadMore}>鏌ョ湅鏇村<DownOutlined/></div> : null}
+        {config.wrap.pagestyle === 'page' ? <Pagination size="small" total={total} showTotal={(t, range) => total > 0 ? `${range[0]}-${range[1]} ${window.GLOB.dict['of'] || '鍏�'} ${total} ${window.GLOB.dict['items'] || '鏉�'}` : `${total} ${window.GLOB.dict['items'] || '鏉�'}`} pageSize={pageSize} showSizeChanger={true} pageSizeOptions={this.state.pageOptions} onChange={this.changePageIndex} onShowSizeChange={this.pageSizeChange} current={pageIndex}/> : null}
+        {config.wrap.pagestyle === 'more' && data.length > 0 ? <div className={'mk-more' + (pageSize * pageIndex >= total ? ' disabled' : '')} onClick={this.loadMore}>{window.GLOB.dict['view_more'] || '鏌ョ湅鏇村'}<DownOutlined/></div> : null}
       </div>
     )
   }
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 3f19dd4..07c69b2 100644
--- a/src/tabviews/custom/components/card/double-data-card/index.scss
+++ b/src/tabviews/custom/components/card/double-data-card/index.scss
@@ -8,6 +8,7 @@
 
   .pickup-wrap {
     float: right;
+    margin-bottom: 3px;
     button {
       margin-top: 3px;
     }
@@ -26,6 +27,7 @@
   .data-zoom {
     display: flex;
     position: relative;
+    min-width: var(--mk-data-zoom-width, 100%);
     .mk-disabled {
       >.card-item-box {
         cursor: not-allowed;
@@ -42,14 +44,6 @@
   .card-row-list {
     flex: 10;
     max-width: 100%;
-  }
-  .card-row-list.flex-layout {
-    display: flex;
-    width: 100%;
-    >.ant-col {
-      width: 5%;
-      flex: 1;
-    }
   }
   .card-item-box {
     position: relative;
@@ -279,19 +273,31 @@
     width: 100%;
     overflow-x: auto;
     overflow-y: auto;
-    padding-bottom: 10px;
     border: 1px solid #e8e8e8;
     border-radius: 4px;
 
-    .extend-card:first-child {
-      position: sticky;
-      top: 0px;
-      z-index: 2;
+    .fix-height .card-row-list {
+      .extend-card:first-child {
+        position: sticky;
+        top: 0;
+        z-index: 1;
+        .card-item-box {
+          margin-top: 0!important;
+          margin-bottom: 0!important;
+        }
+      }
+      div:last-child {
+        .sub-card-wrap {
+          .card-item-box {
+            border-bottom: none!important;
+          }
+        }
+      }
     }
   }
   .data-zoom-box::-webkit-scrollbar {
     height: 9px;
-    width: 9px;
+    width: 7px;
   }
   .data-zoom-box::-webkit-scrollbar-thumb {
     border-radius: 5px;
@@ -322,16 +328,16 @@
     }
   }
 }
-.double-data-card-box::-webkit-scrollbar {
+.double-data-card-box::-webkit-scrollbar, .double-data-card-box .card-row-list::-webkit-scrollbar {
   width: 7px;
   height: 7px;
 }
-.double-data-card-box::-webkit-scrollbar-thumb {
+.double-data-card-box::-webkit-scrollbar-thumb, .double-data-card-box .card-row-list::-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);
 }
-.double-data-card-box::-webkit-scrollbar-track {
+.double-data-card-box::-webkit-scrollbar-track, .double-data-card-box .card-row-list::-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);
diff --git a/src/tabviews/custom/components/card/table-card/index.jsx b/src/tabviews/custom/components/card/table-card/index.jsx
index 5251e62..ef25ae7 100644
--- a/src/tabviews/custom/components/card/table-card/index.jsx
+++ b/src/tabviews/custom/components/card/table-card/index.jsx
@@ -612,7 +612,7 @@
           {data && data.length === 0 ? <Empty description={false}/> : null}
         </Row>
         {config.wrap.pagestyle === 'page' ? <Pagination size="small" current={pageIndex} total={total} onChange={this.changePageIndex} /> : null}
-        {config.wrap.pagestyle === 'more' && data && data.length > 0 ? <div className={'mk-more' + (config.setting.pageSize * pageIndex >= total ? ' disabled' : '')} onClick={this.loadMore}>鏌ョ湅鏇村<DownOutlined/></div> : null}
+        {config.wrap.pagestyle === 'more' && data && data.length > 0 ? <div className={'mk-more' + (config.setting.pageSize * pageIndex >= total ? ' disabled' : '')} onClick={this.loadMore}>{window.GLOB.dict['view_more'] || '鏌ョ湅鏇村'}<DownOutlined/></div> : null}
       </div>
     )
   }
diff --git a/src/tabviews/custom/components/module/invoice/index.jsx b/src/tabviews/custom/components/module/invoice/index.jsx
index ad7b49b..5733915 100644
--- a/src/tabviews/custom/components/module/invoice/index.jsx
+++ b/src/tabviews/custom/components/module/invoice/index.jsx
@@ -233,7 +233,7 @@
     item.setting.customScript = _customScript // 鏁寸悊鍚庤嚜瀹氫箟鑴氭湰
     item.setting.tailScript = _tailScript     // 鍚庣疆鑷畾涔夎剼鏈�
 
-    item.setting.custompage = /@pageSize@|@orderBy@/i.test(item.setting.dataresource + item.setting.customScript)
+    item.setting.custompage = /@pageSize@|@orderBy@|@mk_total/i.test(item.setting.dataresource + item.setting.customScript)
 
     return item
   }
@@ -714,6 +714,7 @@
     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(/@lang@/ig, `'${sessionStorage.getItem('lang')}'`)
     sql = sql.replace(/@typename@/ig, `'admin'`)
 
     if (window.GLOB.externalDatabase !== null) {
@@ -957,6 +958,7 @@
     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(/@lang@/ig, `'${sessionStorage.getItem('lang')}'`)
     sql = sql.replace(/@typename@/ig, `'admin'`)
 
     if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺
diff --git a/src/tabviews/custom/components/share/normalTable/index.jsx b/src/tabviews/custom/components/share/normalTable/index.jsx
index a468ec1..6ef27dd 100644
--- a/src/tabviews/custom/components/share/normalTable/index.jsx
+++ b/src/tabviews/custom/components/share/normalTable/index.jsx
@@ -446,7 +446,12 @@
         content = <span dangerouslySetInnerHTML={{__html: content}}></span>
       } else if (content !== '') {
         content = `${col.prefix || ''}${content}${col.postfix || ''}`
-        content = content.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
+        if (!col.evalchars || col.evalchars.includes('enter')) {
+          content = content.replace(/\n/ig, '<br/>')
+        }
+        if (!col.evalchars || col.evalchars.includes('space')) {
+          content = content.replace(/\s/ig, '&nbsp;')
+        }
         content = <span dangerouslySetInnerHTML={{__html: content}}></span>
       }
 
@@ -868,7 +873,7 @@
       MKEmitter.emit('resetSelectLine', MenuID, '', '')
       MKEmitter.emit('syncBalconyData', MenuID, data, data.length > 0)
       if (data.length === 0) {
-        message.warning('鏈幏鍙栧埌鏁版嵁锛�')
+        message.warning(window.GLOB.dict['no_data'] || '鏈幏鍙栧埌鏁版嵁锛�')
       }
     } else {
       this.setState({
@@ -1158,7 +1163,7 @@
         pageSizeOptions: pageOptions,
         showSizeChanger: true,
         total: this.props.total || 0,
-        showTotal: (total, range) => `${range[0]}-${range[1]} 鍏� ${total} 鏉
+        showTotal: (total, range) => `${range[0]}-${range[1]} ${window.GLOB.dict['of'] || '鍏�'} ${total} ${window.GLOB.dict['items'] || '鏉�'}`
       }
     }
 
@@ -1169,8 +1174,14 @@
     }
 
     let height = setting.height || false
-    if (height && height <= 100) {
-      height = height + 'vh'
+    if (height) {
+      if (height <= 100) {
+        if (height < 0) {
+          height = `calc(100vh - ${-height}px)`
+        } else {
+          height = height + 'vh'
+        }
+      }
     }
     let loading = this.props.loading
     if (setting.mask === 'hidden') {
@@ -1195,9 +1206,9 @@
     }
 
     return (
-      <div className={`normal-custom-table ${setting.tableHeader || ''} ${setting.parity === 'true' ? 'mk-parity' : ''} ${height ? 'fixed-height' : ''} ${setting.mode || ''} table-vertical-${setting.vertical || 'middle'} table-col-${columns.length} ${fixed}`} style={style}>
+      <div className={`normal-custom-table ${setting.tableHeader || ''} ${setting.parity === 'true' ? 'mk-parity' : ''} ${height ? 'fixed-table-height' : ''} ${setting.mode || ''} table-vertical-${setting.vertical || 'middle'} table-col-${columns.length} ${fixed}`} style={style}>
         {(setting.tableType === 'radio' || setting.tableType === 'checkbox') && data && data.length > 0 ?
-          <Switch title="鏀惰捣" className="main-pickup" checkedChildren="寮�" unCheckedChildren="鍏�" checked={pickup} onChange={this.pickupChange} /> : null
+          <Switch title="鏀惰捣" className="main-pickup" checkedChildren={window.GLOB.dict['open'] || '寮�'} unCheckedChildren={window.GLOB.dict['shut'] || '鍏�'} checked={pickup} onChange={this.pickupChange} /> : null
         }
         <Table
           components={components}
diff --git a/src/tabviews/custom/components/share/normalTable/index.scss b/src/tabviews/custom/components/share/normalTable/index.scss
index a7688af..b41bf8b 100644
--- a/src/tabviews/custom/components/share/normalTable/index.scss
+++ b/src/tabviews/custom/components/share/normalTable/index.scss
@@ -154,21 +154,6 @@
       // }
     }
   }
-  // .ant-table-body::-webkit-scrollbar {
-  //   width: 8px;
-  //   height: 10px;
-  // }
-  // ::-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);
-  // }
-  // ::-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);
-  // }
   .fix-header {
     .ant-table-body {
       min-height: unset
@@ -218,7 +203,7 @@
     background-color: #fafafa!important;
   }
 }
-.normal-custom-table:not(.fixed-height) {
+.normal-custom-table:not(.fixed-table-height) {
   .ant-table-body::-webkit-scrollbar {
     width: 8px;
     height: 10px;
@@ -233,14 +218,6 @@
     border-radius: 3px;
     border: 1px solid rgba(0, 0, 0, 0.07);
     background: rgba(0, 0, 0, 0);
-  }
-}
-.normal-custom-table.fixed-height {
-  .ant-table-body {
-    border-bottom: 1px solid rgba(0, 0, 0, .05);
-    .ant-table-fixed {
-      border-bottom: 0;
-    }
   }
 }
 .normal-custom-table.hidden {
diff --git a/src/tabviews/custom/components/table/edit-table/index.jsx b/src/tabviews/custom/components/table/edit-table/index.jsx
index ffd5efc..fcb0aa5 100644
--- a/src/tabviews/custom/components/table/edit-table/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/index.jsx
@@ -251,6 +251,7 @@
     config.dataSource = config.dataSource.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
     config.dataSource = config.dataSource.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
     config.dataSource = config.dataSource.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+    config.dataSource = config.dataSource.replace(/@lang@/ig, `'${sessionStorage.getItem('lang')}'`)
 
     if (/\s/.test(config.dataSource)) { // 鎷兼帴鍒悕
       config.dataSource = '(' + config.dataSource + ') tb'
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 762b303..9529a8e 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
@@ -978,7 +978,12 @@
         content = <span dangerouslySetInnerHTML={{__html: content}}></span>
       } else if (content !== '') {
         content = `${col.prefix || ''}${content}${col.postfix || ''}`
-        content = content.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
+        if (!col.evalchars || col.evalchars.includes('enter')) {
+          content = content.replace(/\n/ig, '<br/>')
+        }
+        if (!col.evalchars || col.evalchars.includes('space')) {
+          content = content.replace(/\s/ig, '&nbsp;')
+        }
         content = <span dangerouslySetInnerHTML={{__html: content}}></span>
       }
 
@@ -1292,7 +1297,12 @@
         content = <span dangerouslySetInnerHTML={{__html: content}}></span>
       } else if (content !== '') {
         content = `${col.prefix || ''}${content}${col.postfix || ''}`
-        content = content.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
+        if (!col.evalchars || col.evalchars.includes('enter')) {
+          content = content.replace(/\n/ig, '<br/>')
+        }
+        if (!col.evalchars || col.evalchars.includes('space')) {
+          content = content.replace(/\s/ig, '&nbsp;')
+        }
         content = <span dangerouslySetInnerHTML={{__html: content}}></span>
       }
 
@@ -1373,7 +1383,8 @@
     allColumns: null,
     checkForms: [],
     allForms: [],
-    reseting: false
+    reseting: false,
+    dict: window.GLOB.dict
   }
 
   timer = null
@@ -1615,7 +1626,7 @@
   }
 
   checkLine = () => {
-    const { edData, forms, checkForms } = this.state
+    const { edData, forms, checkForms, dict } = this.state
 
     let data = edData.filter(item => item.$$uuid === this.blurId)[0]
 
@@ -1658,7 +1669,7 @@
       if (col.type === 'text') {
         let val = record[col.field] !== undefined ? (record[col.field] + '') : ''
         if (col.required === 'true' && !val) {
-          err = `${col.label}涓嶅彲涓虹┖`
+          err = `${col.label}${dict['not_empty'] || '涓嶅彲涓虹┖'}`
         } else if (col.datatype === 'datetime' && !val) {
           val = '1949-10-01'
         }
@@ -1667,27 +1678,27 @@
         let val = record[col.field]
 
         if (col.required === 'true' && !val) {
-          err = `${col.label}涓嶅彲涓�${col.noValue === 'hide' ? '绌�' : '0'}`
+          err = `${col.label}${col.noValue === 'hide' ? (dict['not_empty'] || '涓嶅彲涓虹┖') : dict['not_zero'] || '涓嶅彲涓�0'}`
         } else if (col.noValue === 'hide' && !val) {
           if (col.clearField && checkForms.includes(col.clearField) && !record[col.clearField]) {
-            err = `璇峰~鍐� ${col.label} 鎴� ${col.clearName}`
+            err = `${dict['input_tip'] || '璇峰~鍐� '}${col.label} ${dict['or'] || '鎴�'} ${col.clearName}`
           }
           val = 0
         } else if (!val && val !== 0) {
-          err = `${col.label}涓嶅彲涓虹┖`
+          err = `${col.label}${dict['not_empty'] || '涓嶅彲涓虹┖'}`
         } else {
           val = +val
           if (isNaN(val)) {
-            err = `${col.label}鏁版嵁鏍煎紡閿欒`
+            err = `${col.label} ${dict['data_format'] || '鏁版嵁鏍煎紡閿欒'}`
             return
           }
   
           val = +val.toFixed(col.decimal || 0)
           
           if (typeof(col.max) === 'number' && val > col.max) {
-            err = `${col.label}涓嶅彲澶т簬${col.max}`
+            err = `${col.label}${dict['max_limit'] || ' 涓嶅彲澶т簬 '}${col.max}`
           } else if (typeof(col.min) === 'number' && val < col.min) {
-            err = `${col.label}涓嶅彲灏忎簬${col.min}`
+            err = `${col.label}${dict['less_limit'] || ' 涓嶅彲灏忎簬 '}${col.min}`
           }
         }
 
@@ -2220,7 +2231,7 @@
 
   checkData = () => {
     const { setting } = this.props
-    const { edData, forms, checkForms, selectedRowKeys } = this.state
+    const { edData, forms, checkForms, selectedRowKeys, dict } = this.state
 
     let data = fromJS(edData).toJS()
 
@@ -2234,7 +2245,7 @@
       if (data.length === 0) {
         notification.warning({
           top: 92,
-          message: '璇烽�夋嫨闇�瑕佹彁浜ょ殑鏁版嵁锛�',
+          message: dict['select_row'] || '璇烽�夋嫨闇�瑕佹彁浜ょ殑鏁版嵁锛�',
           duration: 5
         })
         return null
@@ -2244,7 +2255,7 @@
     if (data.length === 0) {
       notification.warning({
         top: 92,
-        message: '鏁版嵁鏈慨鏀癸紝涓嶅彲鎻愪氦锛�',
+        message: dict['un_modified'] || '鏁版嵁鏈慨鏀癸紝涓嶅彲鎻愪氦锛�',
         duration: 5
       })
       return null
@@ -2278,7 +2289,7 @@
         if (col.type === 'text') {
           let val = item[col.field] !== undefined ? (item[col.field] + '') : ''
           if (col.required === 'true' && !val) {
-            line.push(`${col.label}涓嶅彲涓虹┖`)
+            line.push(`${col.label}${dict['not_empty'] || '涓嶅彲涓虹┖'}`)
           } else if (col.datatype === 'datetime' && !val) {
             val = '1949-10-01'
           }
@@ -2286,31 +2297,31 @@
         } else if (col.type === 'number') {
           let val = item[col.field]
           if (col.required === 'true' && !val) {
-            err = `${col.label}涓嶅彲涓�${col.noValue === 'hide' ? '绌�' : '0'}`
+            err = `${col.label}${col.noValue === 'hide' ? (dict['not_empty'] || '涓嶅彲涓虹┖') : dict['not_zero'] || '涓嶅彲涓�0'}`
           } else if (col.noValue === 'hide' && !val) {
             if (col.clearField && checkForms.includes(col.clearField) && !item[col.clearField]) {
-              let msg = `璇峰~鍐� ${col.label} 鎴� ${col.clearName}`
+              let msg = `${dict['input_tip'] || '璇峰~鍐� '}${col.label} ${dict['or'] || '鎴�'} ${col.clearName}`
               if (!line.includes(msg)) {
                 line.push(msg)
               }
             }
             val = 0
           } else if (!val && val !== 0) {
-            line.push(`${col.label}涓嶅彲涓虹┖`)
+            line.push(`${col.label}${dict['not_empty'] || '涓嶅彲涓虹┖'}`)
             return
           } else {
             val = +val
             if (isNaN(val)) {
-              line.push(`${col.label}鏁版嵁鏍煎紡閿欒`)
+              line.push(`${col.label} ${dict['data_format'] || '鏁版嵁鏍煎紡閿欒'}`)
               return
             }
   
             val = +val.toFixed(col.decimal || 0)
             
             if (typeof(col.max) === 'number' && val > col.max) {
-              line.push(`${col.label}涓嶅彲澶т簬${col.max}`)
+              line.push(`${col.label}${dict['max_limit'] || ' 涓嶅彲澶т簬 '}${col.max}`)
             } else if (typeof(col.min) === 'number' && val < col.min) {
-              line.push(`${col.label}涓嶅彲灏忎簬${col.min}`)
+              line.push(`${col.label}${dict['less_limit'] || ' 涓嶅彲灏忎簬 '}${col.min}`)
             }
           }
 
@@ -2319,7 +2330,7 @@
       })
 
       if (line.length > 0) {
-        err += `绗�${Index}琛岋細` + line.join('锛�') + '锛�'
+        err += (dict['line'] ? `${dict['line']} ${Index}锛歚 : `绗�${Index}琛岋細`) + line.join('锛�') + '锛�'
       }
       if (!item.$deleted) {
         Index++
@@ -2343,14 +2354,14 @@
 
   submit = (record) => {
     const { submit, BID, setting } = this.props
-    const { forms } = this.state
+    const { forms, dict } = this.state
 
     this.setState({visible: false, midData: null})
 
     if (setting.supModule && !BID) {
       notification.warning({
         top: 92,
-        message: '闇�瑕佷笂绾т富閿�硷紒',
+        message: dict['sup_key_req'] || '闇�瑕佷笂绾т富閿�硷紒',
         duration: 5
       })
 
@@ -2428,17 +2439,18 @@
 
   execSuccess = (res, record) => {
     const { submit } = this.props
-    const { edData } = this.state
+    const { edData, dict } = this.state
 
     if (res && res.ErrCode === 'S') { // 鎵ц鎴愬姛
       notification.success({
         top: 92,
-        message: res.message || '鎵ц鎴愬姛',
+        message: res.message || dict['exc_success'] || '鎵ц鎴愬姛',
         duration: submit.stime ? submit.stime : 2
       })
     } else if (res && res.ErrCode === 'Y') { // 鎵ц鎴愬姛
       Modal.success({
-        title: res.message || '鎵ц鎴愬姛'
+        title: res.message || dict['exc_success'] || '鎵ц鎴愬姛',
+        okText: dict['got_it'] || '鐭ラ亾浜�'
       })
     } else if (res && res.ErrCode === '-1') { // 瀹屾垚鍚庝笉鎻愮ず
 
@@ -2484,26 +2496,28 @@
 
   execError = (res, record) => {
     const { submit } = this.props
+    const { dict } = this.state
 
     if (res.ErrCode === 'E') {
       Modal.error({
-        title: res.message || '鎵ц澶辫触锛�',
+        title: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
+        okText: dict['got_it'] || '鐭ラ亾浜�'
       })
     } else if (res.ErrCode === 'N') {
       notification.error({
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: submit.ntime ? submit.ntime : 10
       })
     } else if (res.ErrCode === 'F') {
       notification.error({
         className: 'notification-custom-error',
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: submit.ftime ? submit.ftime : 10
       })
     } else if (res.ErrCode === 'NM') {
-      message.error(res.message || '鎵ц澶辫触锛�')
+      message.error(res.message || dict['exc_fail'] || '鎵ц澶辫触锛�')
     }
     
     this.setState({
@@ -2617,7 +2631,7 @@
 
   render() {
     const { setting, lineMarks, submit } = this.props
-    const { edData, columns, loading, pageOptions, selectedRowKeys, visible, midData, reseting } = this.state
+    const { edData, columns, loading, pageOptions, selectedRowKeys, visible, midData, reseting, dict } = this.state
 
     if (reseting) return null
 
@@ -2648,13 +2662,19 @@
         pageSizeOptions: pageOptions,
         showSizeChanger: true,
         total: this.props.total || 0,
-        showTotal: (total, range) => `${range[0]}-${range[1]} 鍏� ${total} 鏉
+        showTotal: (total, range) => `${range[0]}-${range[1]} ${dict['of'] || '鍏�'} ${total} ${dict['items'] || '鏉�'}`
       }
     }
 
     let height = setting.height || false
-    if (height && height <= 100) {
-      height = height + 'vh'
+    if (height) {
+      if (height <= 100) {
+        if (height < 0) {
+          height = `calc(100vh - ${-height}px)`
+        } else {
+          height = height + 'vh'
+        }
+      }
     }
 
     let style = {
@@ -2667,9 +2687,9 @@
     return (
       <>
         {setting.hasSubmit && edData.length > 0 ? <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>
+          <Button style={submit.style} onClick={() => setTimeout(() => {this.submit()}, 10)} loading={loading} className="submit-table" type="link">{dict['submit'] || '鎻愪氦'}</Button>
         </div> : null}
-        <div className={`edit-custom-table ${setting.tableHeader || ''} ${setting.parity === 'true' ? 'mk-parity' : ''} ${height ? 'fixed-height' : ''} ${setting.mode || ''} table-vertical-${setting.vertical || ''} mk-edit-${setting.editType || 'simple'}`} style={style}>
+        <div className={`edit-custom-table ${setting.tableHeader || ''} ${setting.parity === 'true' ? 'mk-parity' : ''} ${height ? 'fixed-table-height' : ''} ${setting.mode || ''} table-vertical-${setting.vertical || ''} mk-edit-${setting.editType || 'simple'}`} style={style}>
           <Table
             rowKey="$$uuid"
             components={components}
@@ -2691,7 +2711,7 @@
             onChange={this.changeTable}
             pagination={_pagination}
           />
-          {setting.hasSubmit && _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">{dict['submit'] || '鎻愪氦'}</Button> : null}
         </div>
         <Modal
           className="mk-user-confirm"
@@ -2700,13 +2720,13 @@
           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>
+            <Button key="cancel" onClick={() => { this.setState({ visible: false, midData: null }) }}>{dict['cancel'] || '鍙栨秷'}</Button>,
+            <Button key="refresh" className="table-refresh" onClick={() => { midData && this.updateMutil(midData) }}>{dict['refresh'] || '鍒锋柊琛ㄦ牸'}</Button>,
+            <Button key="confirm" type="primary" onClick={() => setTimeout(() => {this.submit()}, 10)}>{dict['submit'] || '鎻愪氦鏁版嵁'}</Button>
           ]}
           destroyOnClose
         >
-          <div><QuestionCircleOutlined />琛ㄦ牸涓湁鏁版嵁灏氭湭鎻愪氦</div>
+          <div><QuestionCircleOutlined />{dict['data_not_sub'] || '琛ㄦ牸涓湁鏁版嵁灏氭湭鎻愪氦'}</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 52f01f0..62322be 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.scss
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.scss
@@ -294,7 +294,7 @@
     background-color: #fafafa!important;
   }
 }
-.edit-custom-table:not(.fixed-height) {
+.edit-custom-table:not(.fixed-table-height) {
   .ant-table-body::-webkit-scrollbar {
     width: 8px;
     height: 10px;
@@ -309,14 +309,6 @@
     border-radius: 3px;
     border: 1px solid rgba(0, 0, 0, 0.07);
     background: rgba(0, 0, 0, 0);
-  }
-}
-.edit-custom-table.fixed-height {
-  .ant-table-body {
-    border-bottom: 1px solid rgba(0, 0, 0, .05);
-    .ant-table-fixed {
-      border-bottom: 0;
-    }
   }
 }
 .edit-custom-table.hidden {
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index 9d8a16c..ce3f77e 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -791,6 +791,9 @@
           return cell.eleType !== 'button' || pass || permAction[cell.uuid] || cell.permission === 'false'
         })
       } else if (item.type === 'form') {
+        if (item.wrap.datatype === 'public') {
+          balMap.set(item.wrap.publicId + 'public', true)
+        }
         item.subcards = item.subcards.map(group => {
           group.subButton.uuid = group.uuid
           group.subButton.OpenType = 'formSubmit'
@@ -897,7 +900,7 @@
           item.setting.customScript = _customScript // 鏁寸悊鍚庤嚜瀹氫箟鑴氭湰
           item.setting.tailScript = _tailScript     // 鍚庣疆鑷畾涔夎剼鏈�
 
-          item.setting.custompage = /@pageSize@|@orderBy@/i.test(item.setting.dataresource + item.setting.customScript)
+          item.setting.custompage = /@pageSize@|@orderBy@|@mk_total/i.test(item.setting.dataresource + item.setting.customScript)
 
           if (!item.setting.execute || item.setting.custompage) {
             item.forbidLine = true
@@ -953,16 +956,6 @@
 
     if (cell.OpenType === 'excelOut') { // 瀵煎嚭
       cell.$menuName = item.$menuname
-
-      if (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0) {
-        cell.errorType = 'error1'
-      } else if (cell.intertype === 'system' && cell.verify.dataType !== 'custom') {
-        if (item.setting.interType !== 'system') {
-          cell.errorType = 'error2'
-        } else if (item.type === 'balcony' || item.subtype === 'propcard') {
-          cell.errorType = 'error2'
-        }
-      }
     } else if (cell.OpenType === 'pop' && item.$cache && item.$time && cell.modal) {
       cell.modal.$cache = item.$cache
       cell.modal.$time = item.$time
@@ -1334,7 +1327,7 @@
       inter.setting.customScript = _customScript // 鏁寸悊鍚庤嚜瀹氫箟鑴氭湰
       inter.setting.tailScript = _tailScript     // 鍚庣疆鑷畾涔夎剼鏈�
 
-      inter.setting.custompage = /@pageSize@|@orderBy@/i.test(inter.setting.dataresource + inter.setting.customScript)
+      inter.setting.custompage = /@pageSize@|@orderBy@|@mk_total/i.test(inter.setting.dataresource + inter.setting.customScript)
 
       return inter
     })
diff --git a/src/tabviews/custom/popview/index.jsx b/src/tabviews/custom/popview/index.jsx
index ff072e0..cf6e6a3 100644
--- a/src/tabviews/custom/popview/index.jsx
+++ b/src/tabviews/custom/popview/index.jsx
@@ -513,6 +513,9 @@
           return true
         })
       } else if (item.type === 'form') {
+        if (item.wrap.datatype === 'public') {
+          balMap.set(item.wrap.publicId + 'public', true)
+        }
         item.subcards = item.subcards.map(group => {
           group.subButton.uuid = group.uuid
           group.subButton.OpenType = 'formSubmit'
@@ -609,7 +612,7 @@
           item.setting.customScript = _customScript // 鏁寸悊鍚庤嚜瀹氫箟鑴氭湰
           item.setting.tailScript = _tailScript     // 鍚庣疆鑷畾涔夎剼鏈�
 
-          item.setting.custompage = /@pageSize@|@orderBy@/i.test(item.setting.dataresource + item.setting.customScript)
+          item.setting.custompage = /@pageSize@|@orderBy@|@mk_total/i.test(item.setting.dataresource + item.setting.customScript)
 
           if (!item.setting.execute || item.setting.custompage) {
             item.forbidLine = true
@@ -664,16 +667,6 @@
 
     if (cell.OpenType === 'excelOut') { // 瀵煎嚭
       cell.$menuName = item.$menuname
-
-      if (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0) {
-        cell.errorType = 'error1'
-      } else if (cell.intertype === 'system' && cell.verify.dataType !== 'custom') {
-        if (item.setting.interType !== 'system') {
-          cell.errorType = 'error2'
-        } else if (item.type === 'balcony' || item.subtype === 'propcard') {
-          cell.errorType = 'error2'
-        }
-      }
     }
 
     if (cell.verify) {
diff --git a/src/tabviews/subtable/index.jsx b/src/tabviews/subtable/index.jsx
index 39cbb1d..4dd6804 100644
--- a/src/tabviews/subtable/index.jsx
+++ b/src/tabviews/subtable/index.jsx
@@ -230,12 +230,6 @@
 
         if (item.OpenType === 'excelOut') { // 瀵煎嚭
           item.$menuName = Tab.label
-    
-          if (!item.verify || !item.verify.columns || item.verify.columns.length === 0) {
-            item.errorType = 'error1'
-          } else if (item.intertype === 'system' && item.verify.dataType !== 'custom' && config.setting.interType !== 'system') {
-            item.errorType = 'error2'
-          }
         }
 
         if (item.verify && item.verify.invalid === 'true') {
diff --git a/src/tabviews/subtabtable/index.jsx b/src/tabviews/subtabtable/index.jsx
index bc3c2db..888ef15 100644
--- a/src/tabviews/subtabtable/index.jsx
+++ b/src/tabviews/subtabtable/index.jsx
@@ -203,12 +203,6 @@
 
         if (item.OpenType === 'excelOut') { // 瀵煎嚭
           item.$menuName = Tab.label
-    
-          if (!item.verify || !item.verify.columns || item.verify.columns.length === 0) {
-            item.errorType = 'error1'
-          } else if (item.intertype === 'system' && item.verify.dataType !== 'custom' && config.setting.interType !== 'system') {
-            item.errorType = 'error2'
-          }
         }
 
         if (item.verify && item.verify.invalid === 'true') {
diff --git a/src/tabviews/zshare/actionList/changeuserbutton/index.jsx b/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
index 06cb05f..76bfb7c 100644
--- a/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
@@ -125,7 +125,7 @@
       // 闇�瑕侀�夋嫨鍗曡鏃讹紝鏍¢獙鏁版嵁
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨鍗曡鏁版嵁锛�',
+        message: window.GLOB.dict['select_single_row'] || '璇烽�夋嫨鍗曡鏁版嵁锛�',
         duration: 5
       })
       return
@@ -162,7 +162,9 @@
     param[setting.primaryKey] = primaryId
 
     confirm({
-      title: '纭畾瑕佹墽琛屽悧?',
+      title: window.GLOB.dict['exec_sure'] || '纭畾瑕佹墽琛屽悧?',
+      okText: window.GLOB.dict['ok'] || '纭畾',
+      cancelText: window.GLOB.dict['cancel'] || '鍙栨秷',
       onOk() {
         return new Promise(resolve => {
           Api.genericInterface(param).then(res => {
diff --git a/src/tabviews/zshare/actionList/excelInbutton/index.jsx b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
index ab1cc80..1be21b1 100644
--- a/src/tabviews/zshare/actionList/excelInbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -29,6 +29,7 @@
     disabled: false,
     hidden: false,
     primaryId: '',
+    dict: window.GLOB.dict
   }
 
   UNSAFE_componentWillMount () {
@@ -108,7 +109,7 @@
    */
   actionTrigger = (triggerId, record, type, lid) => {
     const { setting, BID, btn, selectedData, LID } = this.props
-    const { loading, disabled } = this.state
+    const { loading, disabled, dict } = this.state
 
     if (loading || disabled) return
     if (triggerId && btn.uuid !== triggerId) return
@@ -119,20 +120,14 @@
     if (setting.supModule && !BID) {
       notification.warning({
         top: 92,
-        message: '闇�瑕佷笂绾т富閿�硷紒',
+        message: dict['sup_key_req'] || '闇�瑕佷笂绾т富閿�硷紒',
         duration: 5
       })
     } else if (btn.Ot === 'requiredSgl' && data.length !== 1) {
       // 闇�瑕侀�夋嫨鍗曡鏃讹紝鏍¢獙鏁版嵁
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨鍗曡鏁版嵁锛�',
-        duration: 5
-      })
-    } else if (!btn.verify || !btn.verify.sheet || !btn.verify.columns || btn.verify.columns.length === 0) {
-      notification.warning({
-        top: 92,
-        message: 'excel瀵煎叆楠岃瘉淇℃伅鏈缃紒',
+        message: dict['select_single_row'] || '璇烽�夋嫨鍗曡鏁版嵁锛�',
         duration: 5
       })
     } else {
@@ -164,16 +159,18 @@
    */
   execSuccess = (res = {}) => {
     const { btn } = this.props
+    const { dict } = this.state
 
     if (res.ErrCode === 'S' || !res.ErrCode) { // 鎵ц鎴愬姛
       notification.success({
         top: 92,
-        message: res.message || '鎵ц鎴愬姛锛�',
+        message: res.message || dict['exc_success'] || '鎵ц鎴愬姛锛�',
         duration: btn.verify && btn.verify.stime ? btn.verify.stime : 2
       })
     } else if (res.ErrCode === 'Y') { // 鎵ц鎴愬姛
       Modal.success({
-        title: res.message || '鎵ц鎴愬姛锛�'
+        title: res.message || dict['exc_success'] || '鎵ц鎴愬姛锛�',
+        okText: dict['got_it'] || '鐭ラ亾浜�',
       })
     } else if (res.ErrCode === '-1') { // 瀹屾垚鍚庝笉鎻愮ず
 
@@ -226,6 +223,7 @@
    */
   execError = (res = {}) => {
     const { btn } = this.props
+    const { dict } = this.state
 
     if (!['LoginError', 'C', '-2', 'E', 'N', 'F', 'NM'].includes(res.ErrCode)) {
       res.ErrCode = 'E'
@@ -233,23 +231,24 @@
 
     if (res.ErrCode === 'E') {
       Modal.error({
-        title: res.message || '鎵ц澶辫触锛�',
+        title: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
+        okText: dict['got_it'] || '鐭ラ亾浜�'
       })
     } else if (res.ErrCode === 'N') {
       notification.error({
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: btn.verify && btn.verify.ntime ? btn.verify.ntime : 10
       })
     } else if (res.ErrCode === 'F') {
       notification.error({
         className: 'notification-custom-error',
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: btn.verify && btn.verify.ftime ? btn.verify.ftime : 10
       })
     } else if (res.ErrCode === 'NM') {
-      message.error(res.message || '鎵ц澶辫触锛�')
+      message.error(res.message || dict['exc_fail'] || '鎵ц澶辫触锛�')
     }
     
     this.setState({
@@ -260,6 +259,24 @@
       MKEmitter.emit('popclose')
     } else if (btn.execError !== 'never') {
       MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execError, btn, '', this.state.selines)
+
+      if (btn.syncComponentId) {
+        if (btn.syncComponentId === 'multiComponent') {
+          btn.syncComponentIds.forEach((id, i) => {
+            setTimeout(() => {
+              if (/\$focus/.test(id)) {
+                MKEmitter.emit('reloadData', id.split('$')[0], id.split('$')[1])
+              } else {
+                MKEmitter.emit('reloadData', id)
+              }
+            }, 20 * i)
+          })
+        } else if (/\$focus/.test(btn.syncComponentId)) {
+          MKEmitter.emit('reloadData', btn.syncComponentId.split('$')[0], btn.syncComponentId.split('$')[1])
+        } else {
+          MKEmitter.emit('reloadData', btn.syncComponentId)
+        }
+      }
     }
 
     if (btn.execError === 'popclose' && btn.$tabId) { // 鏍囩鍏抽棴鍒锋柊
@@ -336,6 +353,10 @@
         param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
       }
 
+      if (btn.database === 'sso' && window.GLOB.mainSystemApi) {
+        param.rduri = window.GLOB.mainSystemApi
+      }
+
       param.menuname = btn.logLabel
       
       if (window.GLOB.probation) {
@@ -358,8 +379,10 @@
           } else if (res.ErrCode === 'C') {
             const _this = this
             confirm({
-              title: '璇风‘璁�',
+              title: window.GLOB.dict['exec_sure'] || '璇风‘璁�',
               content: res.message,
+              okText: window.GLOB.dict['ok'] || '纭畾',
+              cancelText: window.GLOB.dict['cancel'] || '鍙栨秷',
               onOk() {
                 return new Promise(resolve => {
                   Api.genericInterface(unCheckParam).then(result => {
diff --git a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
index 0317ad6..cd40165 100644
--- a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
@@ -23,9 +23,10 @@
   }
 
   state = {
-    loading: false, // 瀵煎嚭涓�
+    loading: false,
     hidden: false,
-    disabled: false
+    disabled: false,
+    dict: window.GLOB.dict
   }
 
   UNSAFE_componentWillMount () {
@@ -92,7 +93,7 @@
    */
   actionTrigger = (triggerId, _, type, lid) => {
     const { setting, BID, btn, LID } = this.props
-    const { loading, disabled } = this.state
+    const { loading, disabled, dict } = this.state
 
     if (loading || disabled) return
     if (triggerId && btn.uuid !== triggerId) return
@@ -101,19 +102,7 @@
     if (setting.supModule && !BID) {
       notification.warning({
         top: 92,
-        message: '闇�瑕佷笂绾т富閿�硷紒',
-        duration: 5
-      })
-    } else if (btn.errorType === 'error1') {
-      notification.warning({
-        top: 92,
-        message: '璇疯缃鍑哄垪锛�',
-        duration: 5
-      })
-    } else if (btn.errorType === 'error2') {
-      notification.warning({
-        top: 92,
-        message: '鎸夐挳闇�鑷畾涔夊鍑烘暟鎹簮锛�',
+        message: dict['sup_key_req'] || '闇�瑕佷笂绾т富閿�硷紒',
         duration: 5
       })
     } else {
@@ -145,7 +134,7 @@
       if (!valid) {
         notification.warning({
           top: 92,
-          message: '鎼滅储鏉′欢涓嶅彲涓虹┖锛�',
+          message: window.GLOB.dict['miss_search'] || '鎼滅储鏉′欢涓嶅彲涓虹┖锛�',
           duration: 5
         })
         return
@@ -159,7 +148,9 @@
     if (btn.pagination !== 'true') {
       if (btn.intertype === 'system') { // 浣跨敤绯荤粺鍑芥暟
         let param = this.getExcelDefaultParam(viewParam.orderBy, viewParam.search)
-
+        if (btn.database === 'sso' && window.GLOB.mainSystemApi) {
+          param.rduri = window.GLOB.mainSystemApi
+        }
         Api.genericInterface(param).then(result => {
           if (result.status) {
             this.exportExcel(result.data, result.ErrCode, result.message, viewParam.search)
@@ -343,7 +334,7 @@
         Api.genericInterface(res).then(result => {
           if (result.status) {
             if (!result.data) {
-              this.execError({ErrCode: 'N', message: '鏈幏鍙栧埌鏁版嵁淇℃伅锛�'})
+              this.execError({ErrCode: 'N', message: window.GLOB.dict['no_data'] || '鏈幏鍙栧埌鏁版嵁淇℃伅锛�'})
             } else if (result.data.length >= pageSize) {
               data = data.concat(result.data)
               pageIndex++
@@ -376,6 +367,9 @@
     let param = null
     if (btn.intertype === 'system') { // 浣跨敤绯荤粺鍑芥暟
       param = this.getExcelDefaultParam(viewParam.orderBy, viewParam.search, true, pageIndex, pageSize)
+      if (btn.database === 'sso' && window.GLOB.mainSystemApi) {
+        param.rduri = window.GLOB.mainSystemApi
+      }
     } else if (btn.intertype === 'inner') { // 浣跨敤鍐呴儴鍑芥暟
       param = this.getExcelCustomParam(viewParam.orderBy, viewParam.search, true, pageIndex, pageSize)
       param.func = btn.innerFunc
@@ -422,7 +416,7 @@
     Api.genericInterface(param).then(result => {
       if (result.status) {
         if (!result.data) {
-          this.execError({ErrCode: 'N', message: '鏈幏鍙栧埌鏁版嵁淇℃伅锛�'})
+          this.execError({ErrCode: 'N', message: window.GLOB.dict['no_data'] || '鏈幏鍙栧埌鏁版嵁淇℃伅锛�'})
         } else if (result.data.length >= pageSize) {
           data = data.concat(result.data)
           pageIndex++
@@ -445,6 +439,7 @@
    */
   exportExcel = (data = [], ErrCode, msg, search) => {
     const { btn } = this.props
+    const { dict } = this.state
     
     let imgCol = false
     let merge = false
@@ -518,7 +513,7 @@
       if (errors.length) {
         notification.error({
           top: 92,
-          message: '鏁版嵁涓己灏戝瓧娈碉細' + errors.join('銆�'),
+          message: (dict['miss_field'] || '鏁版嵁涓己灏戝瓧娈�') + '锛�' + errors.join('銆�'),
           duration: 5
         })
 
@@ -535,7 +530,7 @@
         // eslint-disable-next-line
         let func = new Function('XLSX', 'data', 'columns', 'searches', 'callback', btn.verify.excel_func)
         func(XLSX, data, columns, search, (res) => {
-          res = res || {ErrCode: ErrCode || 'S', message: msg || '瀵煎嚭鎴愬姛锛�'}
+          res = res || {ErrCode: ErrCode || 'S', message: msg || dict['exc_success'] || '瀵煎嚭鎴愬姛锛�'}
           this.execSuccess(res)
         })
       } else if (imgCol) {
@@ -616,7 +611,7 @@
 
         this.table2excel(column, table)
 
-        this.execSuccess({ErrCode: ErrCode || 'S', message: msg || '瀵煎嚭鎴愬姛锛�'})
+        this.execSuccess({ErrCode: ErrCode || 'S', message: msg || dict['exc_success'] || '瀵煎嚭鎴愬姛锛�'})
       } else {
         let table = []
         let _header = []
@@ -776,7 +771,7 @@
   
         XLSX.writeFile(wb, `${btn.verify.excelName || btn.$menuName || ''}${moment().format('YYYYMMDDHHmmss')}.xlsx`)
   
-        this.execSuccess({ErrCode: ErrCode || 'S', message: msg || '瀵煎嚭鎴愬姛锛�'})
+        this.execSuccess({ErrCode: ErrCode || 'S', message: msg || dict['exc_success'] || '瀵煎嚭鎴愬姛锛�'})
       }
     } catch (e) {
       console.warn(e)
@@ -914,11 +909,18 @@
         _tailScript = _tailScript.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'')
       }
 
+      if (btn.$flowId && window.GLOB.UserCacheMap.has(btn.$flowId)) {
+        let flow = window.GLOB.UserCacheMap.get(btn.$flowId)
+        _setting.dataresource = _setting.dataresource.replace(/@works_flow_code@/ig, `'${flow.flow_code}'`)
+        _customScript = _customScript.replace(/@works_flow_code@/ig, `'${flow.flow_code}'`)
+        _tailScript = _tailScript.replace(/@works_flow_code@/ig, `'${flow.flow_code}'`)
+      }
+
       _setting.customScript = _customScript // 鏁寸悊鍚庤嚜瀹氫箟鑴氭湰
       _setting.tailScript = _tailScript     // 鍚庣疆鑷畾涔夎剼鏈�
 
       _setting.laypage = pagination
-      _setting.custompage = /@pageSize@|@orderBy@/i.test(_setting.dataresource + _setting.customScript)
+      _setting.custompage = /@pageSize@|@orderBy@|@mk_total/i.test(_setting.dataresource + _setting.customScript)
 
       _setting.queryType = btn.verify.queryType
       _setting.$name = btn.logLabel
@@ -973,7 +975,8 @@
       })
     } else if (res.ErrCode === 'Y') { // 鎵ц鎴愬姛
       Modal.success({
-        title: res.message
+        title: res.message,
+        okText: window.GLOB.dict['got_it'] || '鐭ラ亾浜�'
       })
     } else if (res.ErrCode === '-1') { // 瀹屾垚鍚庝笉鎻愮ず
 
@@ -1026,6 +1029,7 @@
    */
   execError = (res = {}) => {
     const { btn } = this.props
+    const { dict } = this.state
 
     if (!['LoginError', 'C', '-2', 'E', 'N', 'F', 'NM'].includes(res.ErrCode)) {
       res.ErrCode = 'E'
@@ -1033,23 +1037,24 @@
 
     if (res.ErrCode === 'E') {
       Modal.error({
-        title: res.message || '鎵ц澶辫触锛�',
+        title: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
+        okText: dict['got_it'] || '鐭ラ亾浜�'
       })
     } else if (res.ErrCode === 'N') {
       notification.error({
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: btn.verify && btn.verify.ntime ? btn.verify.ntime : 10
       })
     } else if (res.ErrCode === 'F') {
       notification.error({
         className: 'notification-custom-error',
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: btn.verify && btn.verify.ftime ? btn.verify.ftime : 10
       })
     } else if (res.ErrCode === 'NM') {
-      message.error(res.message || '鎵ц澶辫触锛�')
+      message.error(res.message || dict['exc_fail'] || '鎵ц澶辫触锛�')
     }
     
     this.setState({
@@ -1060,6 +1065,24 @@
       MKEmitter.emit('popclose')
     } else if (btn.execError !== 'never') {
       MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execError, btn, '', [])
+
+      if (btn.syncComponentId) {
+        if (btn.syncComponentId === 'multiComponent') {
+          btn.syncComponentIds.forEach((id, i) => {
+            setTimeout(() => {
+              if (/\$focus/.test(id)) {
+                MKEmitter.emit('reloadData', id.split('$')[0], id.split('$')[1])
+              } else {
+                MKEmitter.emit('reloadData', id)
+              }
+            }, 20 * i)
+          })
+        } else if (/\$focus/.test(btn.syncComponentId)) {
+          MKEmitter.emit('reloadData', btn.syncComponentId.split('$')[0], btn.syncComponentId.split('$')[1])
+        } else {
+          MKEmitter.emit('reloadData', btn.syncComponentId)
+        }
+      }
     }
 
     if (btn.execError === 'popclose' && btn.$tabId) { // 鏍囩鍏抽棴鍒锋柊
diff --git a/src/tabviews/zshare/actionList/funcbutton/index.jsx b/src/tabviews/zshare/actionList/funcbutton/index.jsx
index cf887d2..10786db 100644
--- a/src/tabviews/zshare/actionList/funcbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/funcbutton/index.jsx
@@ -23,6 +23,7 @@
     loading: false,
     disabled: false,
     hidden: false,
+    dict: window.GLOB.dict
   }
 
   UNSAFE_componentWillMount () {
@@ -102,7 +103,7 @@
    */
   actionTrigger = (triggerId, record, type, lid) => {
     const { btn, BID, selectedData, LID } = this.props
-    const { loading } = this.state
+    const { loading, dict } = this.state
 
     if (loading) return
     if (triggerId && btn.uuid !== triggerId) return
@@ -112,14 +113,14 @@
     let error = ''
 
     if (btn.funcType === 'shareLink' && window.GLOB.systemType === 'production' && !btn.shareProUrl) {
-      error = '灏氭湭璁剧疆姝e紡绯荤粺閾炬帴鍦板潃锛�'
+      error = dict['no_prod_link'] || '灏氭湭璁剧疆姝e紡绯荤粺閾炬帴鍦板潃锛�'
     } else if (btn.funcType === 'refund') {
       if (data.length === 0) {
-        error = '璇烽�夋嫨琛岋紒'
+        error = dict['select_row'] || '璇烽�夋嫨琛岋紒'
       } else if (data.length !== 1) {
-        error = '璇烽�夋嫨鍗曡鏁版嵁锛�'
+        error = dict['select_single_row'] || '璇烽�夋嫨鍗曡鏁版嵁锛�'
       } else if (!data[0].$$uuid) {
-        error = '鏈幏鍙栧埌璁㈠崟缂栧彿锛�'
+        error = dict['no_ordercode'] || '鏈幏鍙栧埌璁㈠崟缂栧彿锛�'
       }
     }
 
@@ -160,7 +161,9 @@
       const that = this
 
       confirm({
-        title: btn.tipTitle || '纭畾瑕佹墽琛屽悧?',
+        title: btn.tipTitle || dict['exec_sure'] || '纭畾瑕佹墽琛屽悧?',
+        okText: dict['ok'] || '纭畾',
+        cancelText: dict['cancel'] || '鍙栨秷',
         onOk() {
           that.execRefund(orderId)
         },
@@ -172,7 +175,7 @@
   execRefund = (orderId) => {
     Api.setRefund(orderId).then(res => {
       if (!res.status) {
-        this.execError({ErrCode: 'E', message: '鎵ц澶辫触锛�', ...res})
+        this.execError({ErrCode: 'E', message: window.GLOB.dict['exc_fail'] || '鎵ц澶辫触锛�', ...res})
       } else {
         this.execSuccess({ErrCode: 'S', ...res})
       }
@@ -243,22 +246,24 @@
         title: btn.shareTip
       })
     } else {
-      message.success('宸插鍒跺埌鍓垏鏉裤��')
+      message.success(window.GLOB.dict['copied'] || '宸插鍒跺埌鍓垏鏉裤��')
     }
   }
 
   execSuccess = (res = {}) => {
     const { btn } = this.props
+    const { dict } = this.state
 
     if (res.ErrCode === 'S' || !res.ErrCode) { // 鎵ц鎴愬姛
       notification.success({
         top: 92,
-        message: res.message || '鎵ц鎴愬姛锛�',
+        message: res.message || dict['exc_success'] || '鎵ц鎴愬姛锛�',
         duration: btn.verify && btn.verify.stime ? btn.verify.stime : 2
       })
     } else if (res.ErrCode === 'Y') { // 鎵ц鎴愬姛
       Modal.success({
-        title: res.message || '鎵ц鎴愬姛锛�'
+        title: res.message || dict['exc_success'] || '鎵ц鎴愬姛锛�',
+        okText: dict['got_it'] || '鐭ラ亾浜�'
       })
     } else if (res.ErrCode === '-1') { // 瀹屾垚鍚庝笉鎻愮ず
 
@@ -275,6 +280,7 @@
 
   execError = (res) => {
     const { btn } = this.props
+    const { dict } = this.state
 
     if (!['LoginError', 'C', '-2', 'E', 'N', 'F', 'NM'].includes(res.ErrCode)) {
       res.ErrCode = 'E'
@@ -282,23 +288,24 @@
 
     if (res.ErrCode === 'E') {
       Modal.error({
-        title: res.message || '鎵ц澶辫触锛�',
+        title: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
+        okText: dict['got_it'] || '鐭ラ亾浜�'
       })
     } else if (res.ErrCode === 'N') {
       notification.error({
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: btn.verify && btn.verify.ntime ? btn.verify.ntime : 10
       })
     } else if (res.ErrCode === 'F') {
       notification.error({
         className: 'notification-custom-error',
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: btn.verify && btn.verify.ftime ? btn.verify.ftime : 10
       })
     } else if (res.ErrCode === 'NM') {
-      message.error(res.message || '鎵ц澶辫触锛�')
+      message.error(res.message || dict['exc_fail'] || '鎵ц澶辫触锛�')
     }
     
     this.setState({
diff --git a/src/tabviews/zshare/actionList/funczip/index.jsx b/src/tabviews/zshare/actionList/funczip/index.jsx
index 5181920..9bee41a 100644
--- a/src/tabviews/zshare/actionList/funczip/index.jsx
+++ b/src/tabviews/zshare/actionList/funczip/index.jsx
@@ -22,6 +22,7 @@
     loading: false,
     disabled: false,
     hidden: false,
+    dict: window.GLOB.dict
   }
 
   UNSAFE_componentWillMount () {
@@ -101,7 +102,7 @@
    */
   actionTrigger = (triggerId, record, type, lid) => {
     const { BID, btn, selectedData, setting, LID } = this.props
-    const { loading, disabled } = this.state
+    const { loading, disabled, dict } = this.state
 
     if (loading || disabled) return
     if (triggerId && btn.uuid !== triggerId) return
@@ -112,21 +113,21 @@
     if (setting.supModule && !BID) {
       notification.warning({
         top: 92,
-        message: '闇�瑕佷笂绾т富閿�硷紒',
+        message: dict['sup_key_req'] || '闇�瑕佷笂绾т富閿�硷紒',
         duration: 5
       })
       return
     } else if (btn.Ot !== 'notRequired' && data.length === 0) {
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨琛岋紒',
+        message: dict['select_row'] || '璇烽�夋嫨琛岋紒',
         duration: 5
       })
       return
     } else if (btn.Ot === 'requiredSgl' && data.length !== 1) {
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨鍗曡鏁版嵁锛�',
+        message: dict['select_single_row'] || '璇烽�夋嫨鍗曡鏁版嵁锛�',
         duration: 5
       })
       return
@@ -351,43 +352,47 @@
    */
   execError = (res) => {
     const { btn } = this.props
+    const { dict } = this.state
 
     this.setState({
       loading: false
     })
 
     if (res.ErrCode === '01') {
-      message.error('鏈幏鍙栧埌涓嬭浇鏂囦欢銆�')
+      message.error(dict['exc_fail'] || '鏈幏鍙栧埌涓嬭浇鏂囦欢銆�')
       return
     } else if (res.ErrCode === '02') {
       Modal.error({
-        title: '閮ㄥ垎鏂囦欢涓嬭浇澶辫触锛�1銆佽妫�鏌ユ枃浠惰矾寰勬槸鍚︽纭紝2銆佽妫�鏌ユ枃浠舵槸鍚﹁法鍩熴��',
+        title: dict['exc_fail'] || '閮ㄥ垎鏂囦欢涓嬭浇澶辫触锛�1銆佽妫�鏌ユ枃浠惰矾寰勬槸鍚︽纭紝2銆佽妫�鏌ユ枃浠舵槸鍚﹁法鍩熴��',
+        okText: dict['got_it'] || '鐭ラ亾浜�'
       })
       return
     } else if (res.ErrCode === '03') {
       Modal.error({
-        title: '鏂囦欢涓嬭浇澶辫触锛�1銆佽妫�鏌ユ枃浠惰矾寰勬槸鍚︽纭紝2銆佽妫�鏌ユ枃浠舵槸鍚﹁法鍩熴��',
+        title: dict['exc_fail'] || '鏂囦欢涓嬭浇澶辫触锛�1銆佽妫�鏌ユ枃浠惰矾寰勬槸鍚︽纭紝2銆佽妫�鏌ユ枃浠舵槸鍚﹁法鍩熴��',
+        okText: dict['got_it'] || '鐭ラ亾浜�'
       })
       return
     } else if (res.ErrCode === 'E') {
       Modal.error({
-        title: res.message || '鎵ц澶辫触锛�',
+        title: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
+        okText: dict['got_it'] || '鐭ラ亾浜�'
       })
     } else if (res.ErrCode === 'N') {
       notification.error({
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: 10
       })
     } else if (res.ErrCode === 'F') {
       notification.error({
         className: 'notification-custom-error',
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: 10
       })
     } else if (res.ErrCode === 'NM') {
-      message.error(res.message || '鎵ц澶辫触锛�')
+      message.error(res.message || dict['exc_fail'] || '鎵ц澶辫触锛�')
     }
 
     if (btn.execError !== 'never') {
diff --git a/src/tabviews/zshare/actionList/index.jsx b/src/tabviews/zshare/actionList/index.jsx
index 8e213d8..d0a7bd4 100644
--- a/src/tabviews/zshare/actionList/index.jsx
+++ b/src/tabviews/zshare/actionList/index.jsx
@@ -231,7 +231,7 @@
           <div className="button-list toolbar-button">
             {this.getButtonList(actions)}
             {mores ? <Dropdown overlay={<div className="mk-button-dropdown-wrap">{this.getButtonList(mores)}</div>} trigger={['hover']}>
-              <div className="mk-button-more">鏇村<DownOutlined/></div>
+              <div className="mk-button-more">{window.GLOB.dict['more'] || '鏇村'}<DownOutlined/></div>
             </Dropdown> : null}
           </div>
         </Affix>
@@ -241,7 +241,7 @@
         <div className="button-list toolbar-button">
           {this.getButtonList(actions)}
           {mores ? <Dropdown overlay={<div className="mk-button-dropdown-wrap">{this.getButtonList(mores)}</div>} trigger={['hover']}>
-            <div className="mk-button-more">鏇村<DownOutlined/></div>
+            <div className="mk-button-more">{window.GLOB.dict['more'] || '鏇村'}<DownOutlined/></div>
           </Dropdown> : null}
         </div>
       )
diff --git a/src/tabviews/zshare/actionList/newpagebutton/index.jsx b/src/tabviews/zshare/actionList/newpagebutton/index.jsx
index 5a78f3e..55bdf19 100644
--- a/src/tabviews/zshare/actionList/newpagebutton/index.jsx
+++ b/src/tabviews/zshare/actionList/newpagebutton/index.jsx
@@ -114,7 +114,7 @@
       // 闇�瑕侀�夋嫨琛屾椂锛屾牎楠屾暟鎹�
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨琛岋紒',
+        message: window.GLOB.dict['select_row'] || '璇烽�夋嫨琛岋紒',
         duration: 5
       })
       return
@@ -122,14 +122,14 @@
       // 闇�瑕侀�夋嫨鍗曡鏃讹紝鏍¢獙鏁版嵁
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨鍗曡鏁版嵁锛�',
+        message: window.GLOB.dict['select_single_row'] || '璇烽�夋嫨鍗曡鏁版嵁锛�',
         duration: 5
       })
       return
     } else if (btn.pageTemplate === 'custom' && window.GLOB.systemType === 'production' && !btn.proUrl) {
       notification.warning({
         top: 92,
-        message: '灏氭湭璁剧疆姝e紡绯荤粺閾炬帴鍦板潃锛�',
+        message: window.GLOB.dict['no_prod_link'] || '灏氭湭璁剧疆姝e紡绯荤粺閾炬帴鍦板潃锛�',
         duration: 5
       })
       return
@@ -145,12 +145,12 @@
     let Id = ''
     let name = ''
     let MenuNo = ''
-    let Remark = ''
+    let lang = ''
     if (btn.Ot === 'requiredSgl' && data[0]) {
       Id = data[0].$$uuid || ''
       name = data[0].PrintTempName || ''
       MenuNo = data[0].PrintTempNO || ''
-      Remark = data[0].Remark || ''
+      lang = data[0].lang_s || ''
     }
 
     let _name = '鏂伴〉闈�'
@@ -228,12 +228,10 @@
         }
       }
     } else if (btn.pageTemplate === 'billprintTemp') {
-      let src = '#/menudesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({ MenuType: 'billPrint', MenuId: Id, MenuNo: MenuNo, MenuName: name || '鎵撳嵃', Remark: Remark })))
+      let src = '#/menudesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({ MenuType: 'billPrint', MenuId: Id, MenuNo: MenuNo, MenuName: name || '鎵撳嵃', lang })))
       window.open(src)
     } else if (btn.pageTemplate === 'print') {
-      let cloudmsg = '&cuid=' + (sessionStorage.getItem('CloudUserID') || '') + '&clid=' + (sessionStorage.getItem('CloudLoginUID') || '') + '&cun=' + (sessionStorage.getItem('CloudUserName') || '')
-      let msg = '&uid=' + sessionStorage.getItem('UserID') + '&lid=' + sessionStorage.getItem('LoginUID') + '&un=' + sessionStorage.getItem('User_Name')
-      let src = '#/print/' + window.btoa('ID=' + Id + msg + cloudmsg)
+      let src = '#/print/' + window.btoa(window.encodeURIComponent(JSON.stringify({ ID: Id, lang })))
       window.open(src)
     } else if (btn.pageTemplate === 'pay') {
       let _p = `ID=${Id}&userid=${sessionStorage.getItem('UserID')}&LoginUID=${sessionStorage.getItem('LoginUID')}&logo=${window.GLOB.doclogo}&name=${sessionStorage.getItem('Full_Name')}&icp=${window.GLOB.ICP}&copyRight=${window.GLOB.copyRight}`
diff --git a/src/tabviews/zshare/actionList/normalbutton/index.jsx b/src/tabviews/zshare/actionList/normalbutton/index.jsx
index bcf9a4f..8f0c450 100644
--- a/src/tabviews/zshare/actionList/normalbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -44,7 +44,8 @@
     hidden: false,
     autoMatic: false,
     check: false,
-    count: 0
+    count: 0,
+    dict: window.GLOB.dict
   }
 
   moduleParams = null
@@ -206,7 +207,7 @@
    */
   actionTrigger = (triggerId, record, type, lid, callback) => {
     const { btn, selectedData, LID } = this.props
-    const { loading, disabled } = this.state
+    const { loading, disabled, dict } = this.state
 
     if (type === 'preButton') {
       if (btn.uuid !== triggerId) return
@@ -242,7 +243,9 @@
     } else if (btn.OpenType === 'prompt') {
       this.setState({loading: true})
       confirm({
-        title: btn.tipTitle || '纭畾瑕佹墽琛屽悧?',
+        title: btn.tipTitle || dict['exec_sure'] || '纭畾瑕佹墽琛屽悧?',
+        okText: dict['ok'] || '纭畾',
+        cancelText: dict['cancel'] || '鍙栨秷',
         onOk() {
           return new Promise(resolve => {
             _this.execSubmit(data, resolve)
@@ -319,7 +322,7 @@
 
   preTrigger = (callback) => {
     const { btn, selectedData } = this.props
-    const { loading, disabled } = this.state
+    const { loading, disabled, dict } = this.state
 
     if (loading || disabled) {
       callback()
@@ -352,7 +355,9 @@
     } else if (btn.OpenType === 'prompt') {
       this.setState({loading: true})
       confirm({
-        title: btn.tipTitle || '纭畾瑕佹墽琛屽悧?',
+        title: btn.tipTitle || dict['exec_sure'] || '纭畾瑕佹墽琛屽悧?',
+        okText: dict['ok'] || '纭畾',
+        cancelText: dict['cancel'] || '鍙栨秷',
         onOk() {
           return new Promise(resolve => {
             _this.execSubmit(data, resolve)
@@ -402,11 +407,12 @@
 
   checkBtnData = (data) => {
     const { BID, btn, setting } = this.props
+    const { dict } = this.state
 
     if (setting.supModule && !BID) {
       notification.warning({
         top: 92,
-        message: '闇�瑕佷笂绾т富閿�硷紒',
+        message: dict['sup_key_req'] || '闇�瑕佷笂绾т富閿�硷紒',
         duration: 5
       })
       return false
@@ -414,7 +420,7 @@
       // 闇�瑕侀�夋嫨琛屾椂锛屾牎楠屾暟鎹�
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨琛岋紒',
+        message: dict['select_row'] || '璇烽�夋嫨琛岋紒',
         duration: 5
       })
       return false
@@ -422,42 +428,17 @@
       // 闇�瑕侀�夋嫨鍗曡鏃讹紝鏍¢獙鏁版嵁
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨鍗曡鏁版嵁锛�',
+        message: dict['select_single_row'] || '璇烽�夋嫨鍗曡鏁版嵁锛�',
         duration: 5
       })
       return false
-    } else if (btn.intertype === 'system') {
-      if (data.length === 0 && btn.verify && btn.verify.voucher && btn.verify.voucher.enabled) {
-        notification.warning({
-          top: 92,
-          message: '浣跨敤鍒涘缓鍑瘉鍑芥暟锛岄渶瑕侀�夋嫨琛岋紒',
-          duration: 5
-        })
-        return false
-      }
-    } else if (btn.intertype === 'custom' || btn.intertype === 'outer') {
-      if (btn.callbackType === 'script' && (!btn.verify || !btn.verify.cbScripts || !btn.verify.cbScripts.filter(item => item.status !== 'false').length === 0)) {
-        notification.warning({
-          top: 92,
-          message: '浣跨敤鑷畾涔夎剼鏈洖璋冩椂锛屽洖璋冭剼鏈笉鍙负绌猴紒',
-          duration: 5
-        })
-        return false
-      } else if (btn.procMode === 'system' && data.length === 0 && btn.verify && btn.verify.voucher && btn.verify.voucher.enabled) {
-        notification.warning({
-          top: 92,
-          message: '浣跨敤鍒涘缓鍑瘉鍑芥暟锛岄渶瑕侀�夋嫨琛岋紒',
-          duration: 5
-        })
-        return false
-      } else if (btn.intertype === 'custom' && window.GLOB.systemType === 'production' && !btn.proInterface) {
-        notification.warning({
-          top: 92,
-          message: '灏氭湭璁剧疆姝e紡绯荤粺鎺ュ彛鍦板潃锛�',
-          duration: 5
-        })
-        return false
-      }
+    } else if (btn.intertype === 'custom' && window.GLOB.systemType === 'production' && !btn.proInterface) {
+      notification.warning({
+        top: 92,
+        message: dict['no_prod_link'] || '灏氭湭璁剧疆姝e紡绯荤粺鎺ュ彛鍦板潃锛�',
+        duration: 5
+      })
+      return false
     }
 
     return true
@@ -1081,7 +1062,7 @@
     if (times > 50) {
       notification.warning({
         top: 92,
-        message: '鍓嶇疆鎸夐挳鍔犺浇澶辫触锛�',
+        message: window.GLOB.dict['pre_btn_failed'] || '鍓嶇疆鎸夐挳鍔犺浇澶辫触锛�',
         duration: 5
       })
       this.setState({loading: false})
@@ -1119,7 +1100,7 @@
     if (setting.supModule && !BID) {
       notification.warning({
         top: 92,
-        message: '闇�瑕佷笂绾т富閿�硷紒',
+        message: window.GLOB.dict['sup_key_req'] || '闇�瑕佷笂绾т富閿�硷紒',
         duration: 5
       })
       _resolve()
@@ -1134,6 +1115,12 @@
         if (btn.returnValue === 'true') {
           params = params.map(item => {
             item.script_type = 'Y'
+            return item
+          })
+        }
+        if (btn.database === 'sso' && window.GLOB.mainSystemApi) {
+          params = params.map(item => {
+            item.rduri = window.GLOB.mainSystemApi
             return item
           })
         }
@@ -1726,6 +1713,7 @@
       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(/@lang@/ig, `'${sessionStorage.getItem('lang')}'`)
       sql = sql.replace(/@typename@/ig, `'admin'`)
 
       if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺
@@ -1839,8 +1827,10 @@
         }
         const _this = this
         confirm({
-          title: '璇风‘璁�',
+          title: window.GLOB.dict['exec_sure'] || '璇风‘璁�',
           content: msg,
+          okText: window.GLOB.dict['ok'] || '纭畾',
+          cancelText: window.GLOB.dict['cancel'] || '鍙栨秷',
           onOk() {
             return new Promise(resolve => {
               Api.genericInterface(unCheckParam).then(result => {
@@ -2237,7 +2227,7 @@
    */
   execSuccess = (res = {}) => {
     const { btn } = this.props
-    const { autoMatic } = this.state
+    const { autoMatic, dict } = this.state
 
     if (btn.resetForms) {
       let data = {}
@@ -2272,6 +2262,17 @@
     }
 
     let sign = ''
+    let focusField = ''
+
+    if (/@focus:[a-z0-9_]+@/i.test(res.message)) {
+      let val = res.message.match(/@focus:[a-z0-9_]+@/i)
+      res.message = res.message.replace(/@focus:[a-z0-9_]+@/i, '')
+      focusField = val ? val[0].replace(/@focus:|@/ig, '') : ''
+
+      if (!res.message) {
+        res.ErrCode = '-1'
+      }
+    }
     if (/^@speak@/i.test(res.message)) {
       res.message = res.message.replace(/^@speak@/i, '')
       let val = res.message.match(/<<.*>>/)
@@ -2287,7 +2288,8 @@
       if (!res.message) {
         res.ErrCode = '-1'
       }
-    } else if (/@close_tab@|@close_popup@|@goback@|@no_target_menu@/i.test(res.message)) {
+    }
+    if (/@close_tab@|@close_popup@|@goback@|@no_target_menu@/i.test(res.message)) {
       sign = res.message.match(/@close_tab@|@close_popup@|@goback@|@no_target_menu@/i)[0].toLowerCase()
       res.message = res.message.replace(/@close_tab@|@close_popup@|@goback@|@no_target_menu@/i, '')
     }
@@ -2307,20 +2309,21 @@
       if (btn.formType !== 'counter' || res.message) {
         notification.success({
           top: 92,
-          message: res.message || '鎵ц鎴愬姛锛�',
+          message: res.message || dict['exc_success'] || '鎵ц鎴愬姛锛�',
           duration: btn.verify && btn.verify.stime ? btn.verify.stime : 2
         })
       }
     } else if (res.ErrCode === 'Y') { // 鎵ц鎴愬姛
-      let msg = res.message || '鎵ц鎴愬姛锛�'
+      let msg = res.message || dict['exc_success'] || '鎵ц鎴愬姛锛�'
       if (/\n|\r/.test(msg)) {
         msg = msg.replace(/\n|\r/ig, '<br/>')
         msg = <span dangerouslySetInnerHTML={{__html: msg}}></span>
       }
       Modal.success({
         title: msg,
+        okText: dict['got_it'] || '鐭ラ亾浜�',
         onOk: () => {
-          this.successContinue(sign, id, res)
+          this.successContinue(sign, id, res, focusField)
         }
       })
       return
@@ -2328,12 +2331,16 @@
 
     }
 
-    this.successContinue(sign, id, res)
+    this.successContinue(sign, id, res, focusField)
   }
 
-  successContinue = (sign, id, res) => {
+  successContinue = (sign, id, res, focusField) => {
     const { btn } = this.props
     const { btnconfig } = this.state
+
+    if (focusField) {
+      MKEmitter.emit('resetFocus', btn.uuid, focusField)
+    }
 
     this.setState({
       loadingNumber: '',
@@ -2444,7 +2451,7 @@
         if (!url) {
           notification.warning({
             top: 92,
-            message: '灏氭湭娣诲姞姝e紡绯荤粺閾炬帴鍦板潃锛�',
+            message: window.GLOB.dict['no_prod_link'] || '灏氭湭璁剧疆姝e紡绯荤粺閾炬帴鍦板潃锛�',
             duration: 5
           })
           return
@@ -2963,7 +2970,7 @@
    */
   execError = (res = {}) => {
     const { btn } = this.props
-    const { autoMatic } = this.state
+    const { autoMatic, dict } = this.state
 
     if (this.preCallback) {
       this.setState({
@@ -2975,7 +2982,7 @@
     } else if (autoMatic) {
       notification.error({
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: 10
       })
 
@@ -3015,13 +3022,14 @@
     }
 
     if (res.ErrCode === 'E') {
-      let msg = res.message || '鎵ц澶辫触锛�'
+      let msg = res.message || dict['exc_fail'] || '鎵ц澶辫触锛�'
       if (/\n|\r/.test(msg)) {
         msg = msg.replace(/\n|\r/ig, '<br/>')
         msg = <span dangerouslySetInnerHTML={{__html: msg}}></span>
       }
       Modal.error({
         title: msg,
+        okText: dict['got_it'] || '鐭ラ亾浜�',
         onOk: () => {
           this.errorContinue(sign)
         }
@@ -3030,18 +3038,18 @@
     } else if (res.ErrCode === 'N') {
       notification.error({
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: btn.verify && btn.verify.ntime ? btn.verify.ntime : 10
       })
     } else if (res.ErrCode === 'F') {
       notification.error({
         className: 'notification-custom-error',
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: btn.verify && btn.verify.ftime ? btn.verify.ftime : 10
       })
     } else if (res.ErrCode === 'NM') {
-      message.error(res.message || '鎵ц澶辫触锛�')
+      message.error(res.message || dict['exc_fail'] || '鎵ц澶辫触锛�')
     } else if (res.ErrCode === '-2') {
       this.setState({
         loadingNumber: '',
@@ -3078,8 +3086,47 @@
     } else if (btn.execError === 'closepoptab' || sign === '@close_popup@') {
       MKEmitter.emit('popclose')
     } else if (btn.execError !== 'never') {
+      let tabId = ''
+      if (btn.refreshTab && btn.refreshTab.length > 0) {
+        tabId = btn.refreshTab[btn.refreshTab.length - 1]
+      }
+      if (tabId && btn.$MenuID === tabId) { // 鍒锋柊褰撳墠鑿滃崟鏃讹紝鍋滄鍏朵粬鎿嶄綔
+        MKEmitter.emit('reloadMenuView', tabId, 'table')
+        return
+      }
+
       MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execError, btn, '', this.state.selines)
+
+      if (btn.syncComponentId) {
+        if (btn.syncComponentId === 'multiComponent') {
+          btn.syncComponentIds.forEach((id, i) => {
+            setTimeout(() => {
+              if (/\$focus/.test(id)) {
+                MKEmitter.emit('reloadData', id.split('$')[0], id.split('$')[1])
+              } else {
+                MKEmitter.emit('reloadData', id)
+              }
+            }, 20 * i)
+          })
+        } else if (/\$focus/.test(btn.syncComponentId)) {
+          MKEmitter.emit('reloadData', btn.syncComponentId.split('$')[0], btn.syncComponentId.split('$')[1])
+        } else {
+          if (btn.syncDelay) {
+            this.delayTimer && clearTimeout(this.delayTimer)
+            this.delayTimer = setTimeout(() => {
+              MKEmitter.emit('reloadData', btn.syncComponentId)
+            }, btn.syncDelay)
+          } else {
+            MKEmitter.emit('reloadData', btn.syncComponentId)
+          }
+        }
+      }
+
+      if (tabId) {
+        MKEmitter.emit('reloadMenuView', tabId, 'table')
+      }
     }
+
     if (btn.OpenType === 'form') {
       let data = this.props.selectedData && this.props.selectedData[0] ? this.props.selectedData[0] : null
 
@@ -3235,7 +3282,7 @@
 
   modelconfirm = () => {
     const { BID } = this.props
-    const { btnconfig, selines } = this.state
+    const { btnconfig, selines, dict } = this.state
     let _this = this
 
     let result = []
@@ -3379,7 +3426,9 @@
       this.execSubmit(selines, () => {}, result)
     } else {
       confirm({
-        title: btnconfig.setting.tipTitle || '纭畾瑕佹墽琛屽悧?',
+        title: btnconfig.setting.tipTitle || dict['exec_sure'] || '纭畾瑕佹墽琛屽悧?',
+        okText: dict['ok'] || '纭畾',
+        cancelText: dict['cancel'] || '鍙栨秷',
         onOk() {
           return new Promise(resolve => {
             _this.execSubmit(selines, resolve, result)
@@ -3398,7 +3447,7 @@
    */
   getModels = () => {
     const { BID, btn, BData } = this.props
-    const { btnconfig, visible } = this.state
+    const { btnconfig, visible, dict } = this.state
 
     if (!btnconfig || !btnconfig.setting) return null
 
@@ -3434,10 +3483,10 @@
           />
           <div className="ant-drawer-footer" style={{ position: 'absolute', zIndex: 1, right: 0, bottom: 0, width: '100%', borderTop: '1px solid #e9e9e9', padding: '10px 16px', background: '#fff', textAlign: 'right'}}>
             <Button onClick={this.handleCancel} style={{ marginRight: 8 }}>
-              {btnconfig.setting.formType !== 'check' ? '鍙栨秷' : '鍏抽棴'}
+              {btnconfig.setting.formType !== 'check' ? dict['cancel'] || '鍙栨秷' : dict['close'] || '鍏抽棴'}
             </Button>
             {btnconfig.setting.formType !== 'check' ? <Button onClick={this.handleOk} loading={this.state.confirmLoading} type="primary">
-              纭畾
+              {dict['ok'] || '纭畾'}
             </Button> : null}
           </div>
         </Drawer>
@@ -3465,6 +3514,8 @@
           wrapClassName={'action-modal' + (btnconfig.setting.moveable === 'true' ? ' moveable-modal modal-' + btn.uuid : '')}
           visible={visible}
           width={width}
+          okText={dict['ok'] || '纭畾'}
+          cancelText={dict['cancel'] || '鍙栨秷'}
           onOk={this.handleOk}
           maskStyle={btnconfig.setting.moveable === 'true' ?  {backgroundColor: 'rgba(0, 0, 0, 0.15)'} : null}
           confirmLoading={this.state.confirmLoading}
@@ -3529,7 +3580,7 @@
 
   changeLineCount = (count) => {
     const { btn, selectedData } = this.props
-    const { disabled } = this.state
+    const { disabled, dict } = this.state
 
     if (disabled) return
 
@@ -3539,7 +3590,7 @@
       // 闇�瑕侀�夋嫨琛屾椂锛屾牎楠屾暟鎹�
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨琛岋紒',
+        message: dict['select_row'] || '璇烽�夋嫨琛岋紒',
         duration: 5
       })
       return
@@ -3547,7 +3598,7 @@
       // 闇�瑕侀�夋嫨鍗曡鏃讹紝鏍¢獙鏁版嵁
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨鍗曡鏁版嵁锛�',
+        message: dict['select_single_row'] || '璇烽�夋嫨鍗曡鏁版嵁锛�',
         duration: 5
       })
       return
diff --git a/src/tabviews/zshare/actionList/normalbutton/mkcounter/index.jsx b/src/tabviews/zshare/actionList/normalbutton/mkcounter/index.jsx
index 05fb8a7..f3e36e6 100644
--- a/src/tabviews/zshare/actionList/normalbutton/mkcounter/index.jsx
+++ b/src/tabviews/zshare/actionList/normalbutton/mkcounter/index.jsx
@@ -35,10 +35,10 @@
     let val = count - 1
 
     if (btn.min !== '' && val < btn.min) {
-      message.warning(`涓嶅彲灏忎簬${btn.min}!`)
+      message.warning(`${window.GLOB.dict['less_limit'] || '涓嶅彲灏忎簬'}${btn.min}!`)
       return
     } else if (btn.max !== '' && val > btn.max) {
-      message.warning(`涓嶅彲澶т簬${btn.max}!`)
+      message.warning(`${window.GLOB.dict['max_limit'] || '涓嶅彲澶т簬'}${btn.max}!`)
       return
     }
 
@@ -58,10 +58,10 @@
     let val = count + 1
 
     if (btn.min !== '' && val < btn.min) {
-      message.warning(`涓嶅彲灏忎簬${btn.min}!`)
+      message.warning(`${window.GLOB.dict['less_limit'] || '涓嶅彲灏忎簬'}${btn.min}!`)
       return
     } else if (btn.max !== '' && val > btn.max) {
-      message.warning(`涓嶅彲澶т簬${btn.max}!`)
+      message.warning(`${window.GLOB.dict['max_limit'] || '涓嶅彲澶т簬'}${btn.max}!`)
       return
     }
 
@@ -79,14 +79,14 @@
     const { count, orival } = this.state
 
     if (count === '') {
-      message.warning(`涓嶅彲涓虹┖!`)
+      message.warning(window.GLOB.dict['not_empty'] || '涓嶅彲涓虹┖锛�')
       this.setState({count: 0})
       return
     } else if (btn.min !== '' && count < btn.min) {
-      message.warning(`涓嶅彲灏忎簬${btn.min}!`)
+      message.warning(`${window.GLOB.dict['less_limit'] || '涓嶅彲灏忎簬'}${btn.min}!`)
       return
     } else if (btn.max !== '' && count > btn.max) {
-      message.warning(`涓嶅彲澶т簬${btn.max}!`)
+      message.warning(`${window.GLOB.dict['max_limit'] || '涓嶅彲澶т簬'}${btn.max}!`)
       return
     }
 
diff --git a/src/tabviews/zshare/actionList/popupbutton/index.jsx b/src/tabviews/zshare/actionList/popupbutton/index.jsx
index dce034b..c6a9e99 100644
--- a/src/tabviews/zshare/actionList/popupbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/popupbutton/index.jsx
@@ -30,6 +30,7 @@
     disabled: false,
     hidden: false,
     loading: false,
+    dict: window.GLOB.dict
   }
 
   UNSAFE_componentWillMount () {
@@ -143,7 +144,7 @@
    */
   actionTrigger = (triggerId, record, type, lid) => {
     const { setting, BID, btn, selectedData, LID } = this.props
-    const { loading, disabled } = this.state
+    const { loading, disabled, dict } = this.state
 
     if (loading || disabled) return
     if (triggerId && btn.uuid !== triggerId) return
@@ -154,7 +155,7 @@
     if (setting.supModule && !BID) {
       notification.warning({
         top: 92,
-        message: '闇�瑕佷笂绾т富閿�硷紒',
+        message: dict['sup_key_req'] || '闇�瑕佷笂绾т富閿�硷紒',
         duration: 5
       })
       return
@@ -162,7 +163,7 @@
       // 闇�瑕侀�夋嫨鍗曡鏃讹紝鏍¢獙鏁版嵁
       notification.warning({
         top: 92,
-        message: data.length === 0 ? '璇烽�夋嫨琛岋紒' : '璇烽�夋嫨鍗曡鏁版嵁锛�',
+        message: data.length === 0 ? dict['select_row'] || '璇烽�夋嫨琛岋紒' : dict['select_single_row'] || '璇烽�夋嫨鍗曡鏁版嵁锛�',
         duration: 5
       })
       return
@@ -230,7 +231,7 @@
 
   getPop = () => {
     const { btn } = this.props
-    const { popData, primaryId, visible } = this.state
+    const { popData, primaryId, visible, dict } = this.state
 
     let ratio = btn.ratio || 85
 
@@ -248,7 +249,7 @@
         visible={visible}
         onCancel={this.popclose}
         footer={[
-          <Button key="close" onClick={this.popclose}>鍏抽棴</Button>
+          <Button key="close" onClick={this.popclose}>{dict['close'] || '鍏抽棴'}</Button>
         ]}
         destroyOnClose
       >
@@ -292,7 +293,7 @@
           {btn.$view === 'popview' ? <PopView Tab={btn} param={{$BID: (popData ? primaryId : this.props.BID), ...(popData || this.props.BData || {})}} /> : null}
           <div className="close-drawer">
             <Button onClick={this.popclose}>
-              鍏抽棴
+              {dict['close'] || '鍏抽棴'}
             </Button>
           </div>
         </Drawer>
diff --git a/src/tabviews/zshare/actionList/printbutton/index.jsx b/src/tabviews/zshare/actionList/printbutton/index.jsx
index 8373813..6d2e96c 100644
--- a/src/tabviews/zshare/actionList/printbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -37,7 +37,8 @@
     loading: false,
     disabled: false,
     hidden: false,
-    autoMatic: false
+    autoMatic: false,
+    dict: window.GLOB.dict
   }
 
   UNSAFE_componentWillMount () {
@@ -132,7 +133,7 @@
    */
   actionTrigger = (triggerId, record, type, lid) => {
     const { BID, btn, selectedData, setting, LID } = this.props
-    const { loading, disabled } = this.state
+    const { loading, disabled, dict } = this.state
 
     if (loading || disabled) return
     if (triggerId && btn.uuid !== triggerId) return
@@ -141,7 +142,7 @@
     if (setting.supModule && !BID) {
       notification.warning({
         top: 92,
-        message: '闇�瑕佷笂绾т富閿�硷紒',
+        message: dict['sup_key_req'] || '闇�瑕佷笂绾т富閿�硷紒',
         duration: 5
       })
       return
@@ -156,7 +157,7 @@
       // 闇�瑕侀�夋嫨琛屾椂锛屾牎楠屾暟鎹�
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨琛岋紒',
+        message: dict['select_row'] || '璇烽�夋嫨琛岋紒',
         duration: 5
       })
       return
@@ -164,21 +165,7 @@
       // 闇�瑕侀�夋嫨鍗曡鏃讹紝鏍¢獙鏁版嵁
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨鍗曡鏁版嵁锛�',
-        duration: 5
-      })
-      return
-    } else if (!btn.verify || !btn.verify.printMode) {
-      notification.warning({
-        top: 92,
-        message: '璇峰畬鍠勬墦鍗伴獙璇佷俊鎭紒',
-        duration: 5
-      })
-      return
-    } else if (btn.intertype === 'system' && btn.verify.dataType === 'custom' && (!btn.verify.setting || btn.verify.columns.length === 0)) {
-      notification.warning({
-        top: 92,
-        message: '鑷畾涔夋墦鍗版暟鎹璁剧疆鏁版嵁婧愶紒',
+        message: dict['select_single_row'] || '璇烽�夋嫨鍗曡鏁版嵁锛�',
         duration: 5
       })
       return
@@ -203,7 +190,9 @@
     } else if (btn.execMode === 'prompt') {
       this.setState({ loading: true })
       confirm({
-        title: '纭畾瑕佹墽琛屽悧?',
+        title: dict['exec_sure'] || '纭畾瑕佹墽琛屽悧?',
+        okText: dict['ok'] || '纭畾',
+        cancelText: dict['cancel'] || '鍙栨秷',
         onOk() {
           _this.triggerPrint(data)
         },
@@ -507,7 +496,7 @@
       if (list.length === 0) {
         notification.warning({
           top: 92,
-          message: '鏈幏鍙栧埌鎵撳嵃鏁版嵁锛�',
+          message: window.GLOB.dict['no_data'] || '鏈幏鍙栧埌鎵撳嵃鏁版嵁锛�',
           duration: 5
         })
         return false
@@ -534,7 +523,7 @@
       if (!result.ConfigParam) {
         notification.warning({
           top: 92,
-          message: '鏈幏鍙栧埌鎵撳嵃妯℃澘淇℃伅锛�',
+          message: window.GLOB.dict['no_print_temp'] || '鏈幏鍙栧埌鎵撳嵃妯℃澘淇℃伅锛�',
           duration: 5
         })
         this.setState({ loading: false })
@@ -785,7 +774,7 @@
 
       notification.warning({
         top: 92,
-        message: '鑷畾涔夊嚱鏁版墽琛岄敊璇紒',
+        message: window.GLOB.dict['func_error'] || '鑷畾涔夊嚱鏁版墽琛岄敊璇紒',
         duration: 5
       })
     }
@@ -1009,7 +998,7 @@
     }
 
     let isDataM = sessionStorage.getItem('dataM') === 'true'
-    let custompage = /@pageSize@|@orderBy@/i.test(_dataresource + _customScript + _tailScript)
+    let custompage = /@pageSize@|@orderBy@|@mk_total/i.test(_dataresource + _customScript + _tailScript)
     let regoptions = [
       { reg: /@orderBy@/ig, value: btn.verify.setting.order },
       { reg: /@pageSize@/ig, value: '9999' },
@@ -1020,6 +1009,7 @@
       { reg: /@SessionUid@/ig, value: `'${localStorage.getItem('SessionUid') || ''}'`},
       { reg: /@UserID@/ig, value: `'${sessionStorage.getItem('UserID') || ''}'`},
       { reg: /@Appkey@/ig, value: `'${window.GLOB.appkey || ''}'`},
+      { reg: /@lang@/ig, value: `'${sessionStorage.getItem('lang')}'`},
       { reg: /@typename@/ig, value: `'admin'`},
       { reg: /\$@/ig, value: isDataM ? '/*' : ''},
       { reg: /@\$/ig, value: isDataM ? '*/' : ''},
@@ -1344,7 +1334,7 @@
     let imgs = []
 
     if (!res.ConfigParam) {
-      error = '鏈幏鍙栧埌鎵撳嵃妯℃澘淇℃伅锛�'
+      error = window.GLOB.dict['no_print_temp'] || '鏈幏鍙栧埌鎵撳嵃妯℃澘淇℃伅锛�'
     } else {
       try {
         configParam = JSON.parse(window.decodeURIComponent(window.atob(res.ConfigParam)))
@@ -1501,7 +1491,7 @@
     if (list.length === 0) {
       notification.warning({
         top: 92,
-        message: '鏈幏鍙栧埌鎵撳嵃鏁版嵁锛�',
+        message: window.GLOB.dict['no_data'] || '鏈幏鍙栧埌鎵撳嵃鏁版嵁锛�',
         duration: 5
       })
       this.setState({ loading: false })
@@ -1620,7 +1610,7 @@
     Api.postekPrint(param).then(res => {
       if (res.retval === '0') {
         if (params.length === 0) {
-          this.execSuccess({ ErrCode: 'S', message: '鎵撳嵃璇锋眰宸插彂鍑恒��', status: true })
+          this.execSuccess({ ErrCode: 'S', message: window.GLOB.dict['print_out'] || '鎵撳嵃璇锋眰宸插彂鍑恒��', status: true })
         } else {
           setTimeout(() => {
             this.loopRFIDPrint(params)
@@ -1638,6 +1628,8 @@
 
   execPrint = (list, template) => {
     const { btn } = this.props
+    const { dict } = this.state
+
     let _errors = []
 
     let defaultPrinter = btn.verify.defaultPrinter || 'lackprinter'
@@ -1738,13 +1730,13 @@
       if (btn.verify.emptyTip === 'false') {
         this.execSuccess({
           ErrCode: '-1',
-          message: '鏈幏鍙栧埌鎵撳嵃淇℃伅锛�',
+          message: dict['no_data'] || '鏈幏鍙栧埌鎵撳嵃淇℃伅锛�',
           status: true
         })
       } else {
         this.execError({
           ErrCode: 'N',
-          message: '鏈幏鍙栧埌鎵撳嵃淇℃伅锛�',
+          message: dict['no_data'] || '鏈幏鍙栧埌鎵撳嵃淇℃伅锛�',
           status: false
         })
       }
@@ -1758,7 +1750,7 @@
           lackerror.push(`鏁版嵁涓湭鑾峰彇鍒版ā鏉匡紙${err.title}锛�${err.lacks.join('銆�')} 瀛楁`)
         }
         if (err.emptys.length > 0) {
-          emptyerror.push(`鏁版嵁涓ā鏉匡紙${err.title}锛� ${err.emptys.join('銆�')} 瀛楁涓嶅彲涓虹┖`)
+          emptyerror.push(dict['not_empty'] ? `${err.title}: ${err.emptys.join('銆�')} ${dict['not_empty']}` : `鏁版嵁涓ā鏉匡紙${err.title}锛� ${err.emptys.join('銆�')} 瀛楁涓嶅彲涓虹┖`)
         }
       })
 
@@ -1782,7 +1774,7 @@
     if (printerList.length === 0) {
       this.execSuccess({
         ErrCode: '-1',
-        message: '鏈幏鍙栧埌鎵撳嵃淇℃伅锛�',
+        message: dict['no_data'] || '鏈幏鍙栧埌鎵撳嵃淇℃伅锛�',
         status: true
       })
       return
@@ -1794,7 +1786,7 @@
       this.syncMessageSend(printerList, () => {
         this.execSuccess({
           ErrCode: 'S',
-          message: '鎵撳嵃璇锋眰宸插彂鍑恒��',
+          message: dict['print_out'] || '鎵撳嵃璇锋眰宸插彂鍑恒��',
           status: true
         })
       })
@@ -1805,7 +1797,7 @@
       this.syncMessageSend(printerList, () => {
         this.execSuccess({
           ErrCode: 'S',
-          message: '鎵撳嵃璇锋眰宸插彂鍑恒��',
+          message: dict['print_out'] || '鎵撳嵃璇锋眰宸插彂鍑恒��',
           status: true
         })
       })
@@ -1856,7 +1848,7 @@
     socket.onerror = () => {
       this.execError({
         ErrCode: 'N',
-        message: '鏃犳硶杩炴帴鍒�:' + btn.verify.linkUrl,
+        message: (dict['un_connect'] || '鏃犳硶杩炴帴鍒�') + ':' + btn.verify.linkUrl,
         status: false
       })
     }
@@ -1892,17 +1884,18 @@
    */
   execSuccess = (res = {}) => {
     const { btn } = this.props
-    const { autoMatic, btnconfig } = this.state
+    const { autoMatic, btnconfig, dict } = this.state
 
     if ((res.ErrCode === 'S' || !res.ErrCode) || autoMatic) { // 鎵ц鎴愬姛
       notification.success({
         top: 92,
-        message: res.message || '鎵ц鎴愬姛锛�',
+        message: res.message || dict['exc_success'] || '鎵ц鎴愬姛锛�',
         duration: btn.verify && btn.verify.stime ? btn.verify.stime : 2
       })
     } else if (res.ErrCode === 'Y') { // 鎵ц鎴愬姛
       Modal.success({
-        title: res.message || '鎵ц鎴愬姛锛�'
+        title: res.message || dict['exc_success'] || '鎵ц鎴愬姛锛�',
+        okText: dict['got_it'] || '鐭ラ亾浜�'
       })
     } else if (res.ErrCode === '-1') { // 瀹屾垚鍚庝笉鎻愮ず
 
@@ -1941,7 +1934,7 @@
    */
   execError = (res) => {
     const { btn } = this.props
-    const { btnconfig, autoMatic } = this.state
+    const { btnconfig, autoMatic, dict } = this.state
 
     if (!['LoginError', 'C', '-2', 'E', 'N', 'F', 'NM'].includes(res.ErrCode)) {
       res.ErrCode = 'E'
@@ -1949,23 +1942,24 @@
 
     if (res.ErrCode === 'E' && !autoMatic) {
       Modal.error({
-        title: res.message || '鎵ц澶辫触锛�',
+        title: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
+        okText: dict['got_it'] || '鐭ラ亾浜�'
       })
     } else if (res.ErrCode === 'N' || autoMatic) {
       notification.error({
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: btn.verify && btn.verify.ntime ? btn.verify.ntime : 10
       })
     } else if (res.ErrCode === 'F') {
       notification.error({
         className: 'notification-custom-error',
         top: 92,
-        message: res.message || '鎵ц澶辫触锛�',
+        message: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
         duration: btn.verify && btn.verify.ftime ? btn.verify.ftime : 10
       })
     } else if (res.ErrCode === 'NM') {
-      message.error(res.message || '鎵ц澶辫触锛�')
+      message.error(res.message || dict['exc_fail'] || '鎵ц澶辫触锛�')
     }
     
     this.setState({
@@ -2113,7 +2107,7 @@
   }
 
   modelconfirm = () => {
-    const { btnconfig, selines } = this.state
+    const { btnconfig, selines, dict } = this.state
     let _this = this
     let result = []
     let _data = {}
@@ -2256,7 +2250,9 @@
       this.execSubmit(selines, () => {}, result)
     } else {
       confirm({
-        title: '纭畾瑕佹墽琛屽悧?',
+        title: dict['exec_sure'] || '纭畾瑕佹墽琛屽悧?',
+        okText: dict['ok'] || '纭畾',
+        cancelText: dict['cancel'] || '鍙栨秷',
         onOk() {
           _this.triggerPrint(selines, result)
         },
@@ -2272,7 +2268,7 @@
    */
   getModels = () => {
     const { BID, btn } = this.props
-    const { btnconfig } = this.state
+    const { btnconfig, dict } = this.state
 
     if (!this.state.visible || !btnconfig || !btnconfig.setting) return null
 
@@ -2306,6 +2302,8 @@
         visible={this.state.visible}
         confirmLoading={this.state.confirmLoading}
         width={width}
+        okText={dict['ok'] || '纭畾'}
+        cancelText={dict['cancel'] || '鍙栨秷'}
         maskStyle={btnconfig.setting.moveable === 'true' ?  {backgroundColor: 'rgba(0, 0, 0, 0.15)'} : null}
         onOk={this.handleOk}
         onCancel={this.handleCancel}
diff --git a/src/tabviews/zshare/actionList/tabbutton/index.jsx b/src/tabviews/zshare/actionList/tabbutton/index.jsx
index d96f206..94322e0 100644
--- a/src/tabviews/zshare/actionList/tabbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/tabbutton/index.jsx
@@ -22,7 +22,8 @@
   state = {
     disabled: false,
     hidden: false,
-    primaryId: ''
+    primaryId: '',
+    dict: window.GLOB.dict
   }
 
   UNSAFE_componentWillMount () {
@@ -102,7 +103,7 @@
    */
   actionTrigger = (triggerId, record, type, lid) => {
     const { btn, selectedData, BID, LID } = this.props
-    const { disabled } = this.state
+    const { disabled, dict } = this.state
 
     if (disabled || btn.multiMenus) return
     if (triggerId && btn.uuid !== triggerId) return
@@ -114,7 +115,7 @@
       // 闇�瑕侀�夋嫨琛屾椂锛屾牎楠屾暟鎹�
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨琛岋紒',
+        message: dict['select_row'] || '璇烽�夋嫨琛岋紒',
         duration: 5
       })
       return false
@@ -122,7 +123,7 @@
       // 闇�瑕侀�夋嫨鍗曡鏃讹紝鏍¢獙鏁版嵁
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨鍗曡鏁版嵁锛�',
+        message: dict['select_single_row'] || '璇烽�夋嫨鍗曡鏁版嵁锛�',
         duration: 5
       })
       return
@@ -187,7 +188,7 @@
       if (!menu) {
         notification.warning({
           top: 92,
-          message: '鑿滃崟宸插垹闄ゆ垨娌℃湁璁块棶鏉冮檺锛�',
+          message: dict['no_perm'] || '鑿滃崟宸插垹闄ゆ垨娌℃湁璁块棶鏉冮檺锛�',
           duration: 5
         })
         return
@@ -219,6 +220,7 @@
 
   triggerMenu = (tab) => {
     const { btn, selectedData, BID } = this.props
+    const { dict } = this.state
 
     let data = selectedData || []
 
@@ -226,7 +228,7 @@
       // 闇�瑕侀�夋嫨琛屾椂锛屾牎楠屾暟鎹�
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨琛岋紒',
+        message: dict['select_row'] || '璇烽�夋嫨琛岋紒',
         duration: 5
       })
       return false
@@ -234,7 +236,7 @@
       // 闇�瑕侀�夋嫨鍗曡鏃讹紝鏍¢獙鏁版嵁
       notification.warning({
         top: 92,
-        message: '璇烽�夋嫨鍗曡鏁版嵁锛�',
+        message: dict['select_single_row'] || '璇烽�夋嫨鍗曡鏁版嵁锛�',
         duration: 5
       })
       return
@@ -283,7 +285,7 @@
     if (!menu) {
       notification.warning({
         top: 92,
-        message: '鑿滃崟宸插垹闄ゆ垨娌℃湁璁块棶鏉冮檺锛�',
+        message: dict['no_perm'] || '鑿滃崟宸插垹闄ゆ垨娌℃湁璁块棶鏉冮檺锛�',
         duration: 5
       })
       return
diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx
index 78f4aa6..fb189b9 100644
--- a/src/tabviews/zshare/mutilform/index.jsx
+++ b/src/tabviews/zshare/mutilform/index.jsx
@@ -6,7 +6,6 @@
 import moment from 'moment'
 
 import Api from '@/api'
-import { formRule } from '@/utils/option.js'
 import Utils from '@/utils/utils.js'
 import asyncComponent from '@/utils/asyncComponent'
 import MKEmitter from '@/utils/events.js'
@@ -48,7 +47,8 @@
     timestamp: '',
     n_id: '',
     focusId: '',
-    reFocusId: ''
+    reFocusId: '',
+    dict: window.GLOB.dict
   }
 
   record = {}
@@ -56,6 +56,7 @@
 
   componentDidMount () {
     const { action, unload } = this.props
+    const { dict } = this.state
 
     let data = {}
     let BData = {}
@@ -315,14 +316,14 @@
         if (item.required === 'true') {
           item.rules.push({
             required: true,
-            message: item.label + '涓嶅彲涓虹┖!'
+            message: item.label + (dict['not_empty'] || '涓嶅彲涓虹┖锛�')
           })
         }
 
         item.rules.push({
           validator: (rule, value, callback) => {
             if (/'/.test(value)) {
-              callback('涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙凤紒')
+              callback(dict['single_quot'] || '涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙凤紒')
             // } else if (/--/.test(value)) {
             //   callback('涓嶅彲浣跨敤 -- 锛�')
             } else {
@@ -334,7 +335,7 @@
         if (!item.lenControl || item.lenControl === 'limit') {
           item.rules.push({
             max: item.fieldlength,
-            message: formRule.input.formMessage.replace('@max', item.fieldlength)
+            message: (dict['max_char'] || '鏈�澶欯max涓瓧绗�').replace('@max', item.fieldlength)
           })
         }
 
@@ -346,7 +347,7 @@
             }
             item.rules.push({
               pattern: reg,
-              message: item.regularText || formRule.input.numbermsg
+              message: item.regularText || dict['enter_num'] || '璇疯緭鍏ユ暟瀛楋紒'
             })
           } else if (item.regular === 'letter') {
             let reg = /^[a-zA-Z]*$/
@@ -355,7 +356,7 @@
             }
             item.rules.push({
               pattern: reg,
-              message: item.regularText || formRule.input.lettermsg
+              message: item.regularText || dict['enter_letter'] || '璇疯緭鍏ュ瓧姣嶏紒'
             })
           } else if (item.regular === 'letter_number') {
             let reg = /^[a-zA-Z0-9]*$/
@@ -364,7 +365,7 @@
             }
             item.rules.push({
               pattern: reg,
-              message: item.regularText || '璇疯緭鍏ユ暟瀛楁垨瀛楁瘝'
+              message: item.regularText || dict['enter_num_letter'] || '璇疯緭鍏ユ暟瀛楁垨瀛楁瘝'
             })
           } else if (item.regular === 'letter&number') {
             let reg = /^[a-zA-Z0-9@_.]*$/
@@ -373,24 +374,24 @@
             }
             item.rules.push({
               pattern: reg,
-              message: item.regularText || '璇疯緭鍏ユ暟瀛椼�佸瓧姣嶄互鍙夽_.'
+              message: item.regularText || dict['enter_num_letter_char'] || '璇疯緭鍏ユ暟瀛椼�佸瓧姣嶄互鍙夽_.'
             })
           } else if (item.regular === 'phone') {
             item.rules.push({
               pattern: /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/,
-              message: item.regularText || '璇锋纭緭鍏ユ墜鏈哄彿'
+              message: item.regularText || dict['phone_error'] || '璇锋纭緭鍏ユ墜鏈哄彿'
             })
           } else if (item.regular === 'email') {
             item.rules.push({
               pattern: /^([a-zA-Z0-9._-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/,
-              message: item.regularText || '璇锋纭緭鍏ラ偖绠卞湴鍧�'
+              message: item.regularText || dict['email_error'] || '璇锋纭緭鍏ラ偖绠卞湴鍧�'
             })
           }
         }
       } else if (item.type === 'number') {
         item.rules = [{
           required: true,
-          message: item.label + '涓嶅彲涓虹┖!'
+          message: item.label + (dict['not_empty'] || '涓嶅彲涓虹┖锛�')
         }]
 
         if (typeof(item.min) === 'number' || typeof(item.max) === 'number' || item.notZero === 'true') {
@@ -399,9 +400,9 @@
               if (isNaN(value)) {
                 callback()
               } else if (item.notZero === 'true' && value === 0) {
-                callback(item.label + '涓嶅彲涓�0')
+                callback(item.label + (dict['not_zero'] || '涓嶅彲涓�0'))
               } else if (typeof(item.min) === 'number' && value < item.min) {
-                if (item.min < 1e-6) {
+                if (item.min > 0 && item.min < 1e-6) {
                   if (item.min === 1e-6) {
                     callback(item.label + '鏈�灏忓�间负 0.000001')
                   } else if (item.min === 1e-7) {
@@ -415,13 +416,13 @@
                   } else if (item.min === 1e-11) {
                     callback(item.label + '鏈�灏忓�间负 0.00000000001')
                   } else {
-                    callback(item.label + '鏈�灏忓�间负 ' + item.min)
+                    callback(item.label + (dict['less_limit'] || '鏈�灏忓�间负 ') + item.min)
                   }
                 } else {
-                  callback(item.label + '鏈�灏忓�间负 ' + item.min)
+                  callback(item.label + (dict['less_limit'] || '鏈�灏忓�间负 ') + item.min)
                 }
               } else if (typeof(item.max) === 'number' && value > item.max) {
-                callback(item.label + '鏈�澶у�间负 ' + item.max)
+                callback(item.label + (dict['max_limit'] || '鏈�澶у�间负 ') + item.max)
               } else {
                 callback()
               }
@@ -432,14 +433,14 @@
         if (item.required === 'true') {
           item.rules.push({
             required: true,
-            message: item.label + '涓嶅彲涓虹┖!'
+            message: item.label + (dict['not_empty'] || '涓嶅彲涓虹┖锛�')
           })
         }
 
         item.rules.push({
           validator: (rule, value, callback) => {
             if (/'/.test(value)) {
-              callback('涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙凤紒')
+              callback(dict['single_quot'] || '涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙凤紒')
             // } else if (/--/.test(value)) {
             //   callback('涓嶅彲浣跨敤 -- 锛�')
             } else {
@@ -448,38 +449,38 @@
           }
         }, {
           max: item.fieldlength,
-          message: formRule.input.formMessage.replace('@max', item.fieldlength)
+          message: (dict['max_char'] || '鏈�澶欯max涓瓧绗�').replace('@max', item.fieldlength)
         })
       } else if (item.type === 'brafteditor') {
         if (item.required === 'true') {
           item.rules.push({
             required: true,
-            message: item.label + '涓嶅彲涓虹┖!'
+            message: item.label + (dict['not_empty'] || '涓嶅彲涓虹┖锛�')
           })
         }
 
         item.rules.push({
           max: item.fieldlength,
-          message: formRule.input.formMessage.replace('@max', item.fieldlength)
+          message: (dict['max_char'] || '鏈�澶欯max涓瓧绗�').replace('@max', item.fieldlength)
         })
       } else if (item.type === 'linkMain' || item.type === 'vercode') {
         if (item.required === 'true') {
           item.rules.push({
             required: true,
-            message: item.label + '涓嶅彲涓虹┖!'
+            message: item.label + (dict['not_empty'] || '涓嶅彲涓虹┖锛�')
           })
         }
       } else {
         if (item.required === 'true') {
           item.rules.push({
             required: true,
-            message: '璇烽�夋嫨' + item.label + '!'
+            message: (dict['select_tip'] || '璇烽�夋嫨') + item.label + '!'
           })
         }
         if (['cascader', 'checkbox', 'checkcard', 'fileupload', 'multiselect'].includes(item.type) && item.fieldlength) {
           item.rules.push({
             max: item.fieldlength,
-            message: formRule.input.formMessage.replace('@max', item.fieldlength)
+            message: (dict['max_char'] || '鏈�澶欯max涓瓧绗�').replace('@max', item.fieldlength)
           })
         }
       }
@@ -748,6 +749,7 @@
     if (action.subButton && action.subButton.resetForms) {
       MKEmitter.addListener('resetForms', this.resetForms)
     }
+    MKEmitter.addListener('resetFocus', this.resetFocus)
   }
 
   componentWillUnmount () {
@@ -755,6 +757,27 @@
       return
     }
     MKEmitter.removeListener('resetForms', this.resetForms)
+    MKEmitter.removeListener('resetFocus', this.resetFocus)
+  }
+
+  resetFocus = (id, field) => {
+    const { action } = this.props
+
+    if (id !== action.uuid) return
+
+    let focusId = ''
+
+    this.state.formlist.forEach(item => {
+      if (item.field === field) {
+        focusId = item.uuid
+      }
+    })
+
+    if (!focusId) return
+
+    setTimeout(() => {
+      MKEmitter.emit('mkFC', 'focus', focusId)
+    }, 20)
   }
 
   resetForms = (id, data) => {
diff --git a/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx b/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx
index 7b76860..4d3b9a4 100644
--- a/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx
+++ b/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx
@@ -39,6 +39,7 @@
     config.dataSource = config.dataSource.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
     config.dataSource = config.dataSource.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
     config.dataSource = config.dataSource.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+    config.dataSource = config.dataSource.replace(/@lang@/ig, `'${sessionStorage.getItem('lang')}'`)
 
     if (/\s/.test(config.dataSource)) { // 鎷兼帴鍒悕
       config.dataSource = '(' + config.dataSource + ') tb'
diff --git a/src/tabviews/zshare/normalTable/index.jsx b/src/tabviews/zshare/normalTable/index.jsx
index 8439a3a..691422b 100644
--- a/src/tabviews/zshare/normalTable/index.jsx
+++ b/src/tabviews/zshare/normalTable/index.jsx
@@ -1283,7 +1283,7 @@
     }
 
     return (
-      <div className={'normal-data-table mingke-table ' + (height ? 'fixed-height' : '') + ` table-col-${columns.length}`}>
+      <div className={'normal-data-table mingke-table ' + (height ? 'fixed-table-height' : '') + ` table-col-${columns.length}`}>
         <Table
           components={components}
           size={setting.size || 'middle'}
diff --git a/src/tabviews/zshare/normalTable/index.scss b/src/tabviews/zshare/normalTable/index.scss
index c65a3ae..563a668 100644
--- a/src/tabviews/zshare/normalTable/index.scss
+++ b/src/tabviews/zshare/normalTable/index.scss
@@ -249,7 +249,7 @@
     }
   }
 }
-.normal-data-table:not(.fixed-height) {
+.normal-data-table:not(.fixed-table-height) {
   .ant-table-body::-webkit-scrollbar {
     width: 8px;
     height: 10px;
@@ -264,13 +264,5 @@
     border-radius: 3px;
     border: 1px solid rgba(0, 0, 0, 0.07);
     background: rgba(0, 0, 0, 0);
-  }
-}
-.normal-data-table.fixed-height {
-  .ant-table-body {
-    border-bottom: 1px solid rgba(0, 0, 0, .05);
-    .ant-table-fixed {
-      border-bottom: 0;
-    }
   }
 }
\ No newline at end of file
diff --git a/src/tabviews/zshare/topSearch/index.jsx b/src/tabviews/zshare/topSearch/index.jsx
index 0e1c29d..f169891 100644
--- a/src/tabviews/zshare/topSearch/index.jsx
+++ b/src/tabviews/zshare/topSearch/index.jsx
@@ -67,6 +67,7 @@
       _setting.wrapperCol = {style: {width: (100 - _setting.labelwidth) + '%'}}
       _setting.borderRadius = config.wrap.borderRadius
       _setting.resetContrl = config.wrap.resetContrl || 'init'
+      _setting.size = config.wrap.searchSize || ''
 
       if (config.wrap.searchBtn === 'show') {
         _setting.showBtn = true
@@ -729,7 +730,7 @@
       const _rules = [
         {
           required: item.required,
-          message: item.label + '涓嶅彲涓虹┖!'
+          message: item.label + (window.GLOB.dict['not_empty'] || '涓嶅彲涓虹┖锛�')
         }
       ]
 
@@ -790,13 +791,13 @@
             wrapperCol={setting.wrapperCol}
           >
             {setting.show ? <Button style={style} type="primary" onClick={this.handleSubmit}>
-              鎼滅储
+              {window.GLOB.dict['search'] || '鎼滅储'}
             </Button> : null}
             {setting.show ? <Button style={{ marginLeft: 8, ...style }} onClick={this.handleReset}>
-              閲嶇疆
+              {window.GLOB.dict['reset'] || '閲嶇疆'}
             </Button> : null}
             {setting.showAdv ? <Button className={visible ? 'visible' : ''} type="link" onClick={this.handleAdvance}>
-              楂樼骇{setting.advanceType === 'pulldown' ? <DownOutlined /> : null}
+              {window.GLOB.dict['senior'] || '楂樼骇'}{setting.advanceType === 'pulldown' ? <DownOutlined /> : null}
             </Button> : null}
           </Form.Item>
         </Col>
@@ -806,7 +807,7 @@
         <Col className="mk-search-col search-button" key="actions">
           <Form.Item>
             <Button type="primary" onClick={this.handleSubmit}>
-              鎼滅储
+              {window.GLOB.dict['search'] || '鎼滅储'}
             </Button>
           </Form.Item>
         </Col>
@@ -892,7 +893,7 @@
       
             notification.warning({
               top: 92,
-              message: '璇疯緭鍏�' + labels.join('銆�') + ' !',
+              message: (window.GLOB.dict['input_tip'] || '璇疯緭鍏�') + labels.join('銆�') + ' !',
               duration: 3
             })
             return
@@ -1124,7 +1125,7 @@
 
     return (
       <>
-        <Form {...formItemLayout} className={`mk-search-wrap mk-float-${setting.float}`} style={setting.style}>
+        <Form {...formItemLayout} className={`mk-search-wrap mk-float-${setting.float} mk-size-${setting.size}`} style={setting.style}>
           <Row gutter={24}>{this.getFields()}</Row>
           {advanceValues.length && (setting.advanceType !== 'pulldown' || (setting.advanceType === 'pulldown' && !visible)) ? <Row gutter={24}>
             <div className="advanced-list">
@@ -1140,7 +1141,7 @@
           </Row> : null}
         </Form>
         {setting.advanceType === 'modal' ? <Modal
-          title="楂樼骇鎼滅储"
+          title={window.GLOB.dict['adv_search'] || '楂樼骇鎼滅储'}
           maskClosable={false}
           visible={visible}
           width={setting.advWidth}
@@ -1156,7 +1157,7 @@
           />
         </Modal> : null}
         {setting.advanceType === 'drawer' ? <Drawer
-          title="楂樼骇鎼滅储"
+          title={window.GLOB.dict['adv_search'] || '楂樼骇鎼滅储'}
           className="mk-search-drawer"
           width={setting.advWidth}
           height={setting.advHeight}
diff --git a/src/tabviews/zshare/topSearch/index.scss b/src/tabviews/zshare/topSearch/index.scss
index bf4590a..021510b 100644
--- a/src/tabviews/zshare/topSearch/index.scss
+++ b/src/tabviews/zshare/topSearch/index.scss
@@ -132,6 +132,11 @@
     text-align: right;
   }
 }
+.mk-search-wrap.mk-size-small {
+  .ant-form-item, .search-button {
+    min-height: 45px;
+  }
+}
 .mk-search-drawer {
   .ant-drawer-wrapper-body {
     position: relative;
diff --git a/src/templates/modalconfig/dragelement/index.jsx b/src/templates/modalconfig/dragelement/index.jsx
index 4798f28..6d6c0c5 100644
--- a/src/templates/modalconfig/dragelement/index.jsx
+++ b/src/templates/modalconfig/dragelement/index.jsx
@@ -66,7 +66,7 @@
 
     delete val.$srcId
     
-    let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+    let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
     if (srcid) {
       val.$srcId = srcid
     }
diff --git a/src/templates/sharecomponent/actioncomponent/dragaction/index.jsx b/src/templates/sharecomponent/actioncomponent/dragaction/index.jsx
index 5de06eb..c0076ff 100644
--- a/src/templates/sharecomponent/actioncomponent/dragaction/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/dragaction/index.jsx
@@ -70,7 +70,7 @@
       }
       delete _val.$srcId
     
-      let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+      let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
       if (srcid) {
         _val.$srcId = srcid
       }
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
index ab01815..f0d8651 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
@@ -232,11 +232,25 @@
 
     let _value = ''
     if (value === 'default') {
-      let fields = usefulfields.filter(item => item.import !== 'false')
-      fields = fields.map(col => col.Column).join(',')
+      let fields = []
+      let decls = []
+      usefulfields.forEach(col => {
+        if (col.import === 'false') return
+        
+        if (col.type === 'date') {
+          decls.push(`${col.Column} Nvarchar(50)`)
+        } else {
+          decls.push(`${col.Column} ${col.type}`)
+        }
+        fields.push(col.Column)
+      })
+
+      decls = decls.join(',')
+      fields = fields.join(',')
       
       if (fields) {
         fields = fields + ','
+        decls = decls + ','
       }
 
       let database = btn.sheet.match(/(.*)\.(.*)\.|@db@/ig) || ''
@@ -244,7 +258,7 @@
 
       database = database ? (database[0] || '') : ''
 
-      _value = `Insert into ${database}${sheet} (${fields}createuserid,createuser,createstaff,bid)\nSelect ${fields}@userid@,@username,@fullname,@BID@ From #${sheet}`
+      _value = `/* create table #${sheet} (${decls}jskey nvarchar(50),BID nvarchar(50) ) */\nInsert into ${database}${sheet} (${fields}createuserid,createuser,createstaff,bid)\nSelect ${fields}@userid@,@username,@fullname,@BID@ From #${sheet}`
     } else if (value === 'flowSql') {
       let sheet = btn.sheet.replace(/(.*)\.(.*)\.|@db@/ig, '')
 
@@ -318,7 +332,7 @@
           </Col> : null}
           {!type ? <Col span={24} className="sqlfield">
             <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={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, lang, time_id, typename</span></Tooltip>,&nbsp;
               {workFlow === 'true' ? <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title="宸ヤ綔娴佸彉閲忥紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�"><span style={{color: '#26C281'}}>works_flow_code, works_flow_name, works_flow_param, works_flow_detail_id, status, statusname, work_group, work_grade, start_type, </span></Tooltip> : null}
               <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>,&nbsp;
               {usefulfields}
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
index b7645c9..3f2c50d 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
@@ -215,7 +215,7 @@
           </Col>
           <Col span={24} className="sqlfield">
             <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={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, lang, 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>
               <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鎺掑簭銆佸垎椤典互鍙婃悳绱㈡潯浠跺彉閲忥紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}>, orderBy, pageSize, pageIndex{usefulfields ? ', ' + usefulfields : ''}</Tooltip>
               {linefields ? <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'琛ㄥ崟鍙婅鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}>,&nbsp;{linefields}</Tooltip> : null}
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx
index f4e335c..4949841 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx
@@ -50,7 +50,7 @@
       _dataresource = '(' + _dataresource + ') tb'
     }
 
-    let custompage = /@pageSize@|@orderBy@/i.test(_dataresource + _customScript)
+    let custompage = /@pageSize@|@orderBy@|@mk_total/i.test(_dataresource + _customScript)
     
     // 姝e垯鏇挎崲
     regoptions.push({
@@ -73,6 +73,10 @@
       value: ''
     })
 
+    if (window.GLOB.process) {
+      regoptions.push({reg: /@works_flow_code@/ig, value: `'mk_flow_code'`})
+    }
+
     regoptions.forEach(item => {
       _dataresource = _dataresource.replace(item.reg, item.value)
       _customScript = _customScript.replace(item.reg, item.value)
diff --git a/src/templates/sharecomponent/actioncomponent/verifyprint/utils.jsx b/src/templates/sharecomponent/actioncomponent/verifyprint/utils.jsx
index c33d899..719ba0e 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyprint/utils.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyprint/utils.jsx
@@ -34,7 +34,7 @@
       _dataresource = '(' + _dataresource + ') tb'
     }
 
-    let custompage = /@pageSize@|@orderBy@/i.test(_dataresource + _customScript)
+    let custompage = /@pageSize@|@orderBy@|@mk_total/i.test(_dataresource + _customScript)
 
     // 姝e垯鏇挎崲
     let regoptions = [{
diff --git a/src/templates/sharecomponent/columncomponent/index.jsx b/src/templates/sharecomponent/columncomponent/index.jsx
index c44b763..f390b59 100644
--- a/src/templates/sharecomponent/columncomponent/index.jsx
+++ b/src/templates/sharecomponent/columncomponent/index.jsx
@@ -373,7 +373,7 @@
       columns: columnlist
     }
 
-    let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+    let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
     if (srcid) {
       val.$srcId = srcid
     }
diff --git a/src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx b/src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx
index 277f247..3edd6e1 100644
--- a/src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx
@@ -54,7 +54,7 @@
     try {
       delete _val.$srcId
 
-      let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+      let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
       if (srcid) {
         _val.$srcId = srcid
       }
diff --git a/src/templates/sharecomponent/searchcomponent/index.jsx b/src/templates/sharecomponent/searchcomponent/index.jsx
index 6380283..37498c6 100644
--- a/src/templates/sharecomponent/searchcomponent/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/index.jsx
@@ -205,7 +205,7 @@
         return
       }
 
-      if (['checkcard', 'select', 'multiselect', 'link'].includes(res.type) && res.resourceType === '1' && /\s/.test(res.dataSource)) {
+      if (['checkcard', 'select', 'multiselect', 'link'].includes(res.type) && res.resourceType === '1' && res.database !== 'sso' && /\s/.test(res.dataSource)) {
         this.setState({
           sqlVerifing: true
         })
@@ -213,13 +213,8 @@
         let sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)
         ${res.dataSource}`
         sql = sql.replace(/@\$|\$@/ig, '')
-
-        let rduri = ''
-        if (window.GLOB.mainSystemApi && res.database === 'sso') {
-          rduri = window.GLOB.mainSystemApi
-        }
         
-        Api.sDebug(sql, rduri).then(result => {
+        Api.sDebug(sql).then(result => {
           if (result.status || result.ErrCode === '-2') {
             this.setState({
               sqlVerifing: false,
@@ -330,8 +325,13 @@
     const { config } = this.props
     const { searchlist, visible, sqlVerifing, card, showField, setVisible } = this.state
 
+    let size = ''
+    if (config.wrap && config.wrap.searchSize) {
+      size = ' mk-size-' + config.wrap.searchSize
+    }
+
     return (
-      <div className={'model-table-search-list length' + searchlist.length + (showField ? ' show-field' : '')}>
+      <div className={'model-table-search-list length' + searchlist.length + (showField ? ' show-field' : '') + size}>
         <FieldsComponent config={{uuid: config.uuid, search: searchlist}} type="search" />
         <Switch className="switch-field-show" checkedChildren="寮�" unCheckedChildren="鍏�" defaultChecked={showField} onChange={this.onFieldChange} />
         <DragElement
@@ -347,7 +347,7 @@
           title={card && card.copyType === 'search' ?  '鎼滅储鏉′欢-澶嶅埗' : '鎼滅储鏉′欢-缂栬緫'}
           wrapClassName="mk-scroll-modal"
           visible={visible}
-          width={850}
+          width={950}
           maskClosable={false}
           onOk={this.handleSubmit}
           confirmLoading={sqlVerifing}
diff --git a/src/templates/sharecomponent/searchcomponent/index.scss b/src/templates/sharecomponent/searchcomponent/index.scss
index b82e0a3..b156cdb 100644
--- a/src/templates/sharecomponent/searchcomponent/index.scss
+++ b/src/templates/sharecomponent/searchcomponent/index.scss
@@ -141,4 +141,14 @@
       display: block;
     }
   }
+}
+.model-table-search-list.mk-size-small {
+  .page-card {
+    height: 45px;
+  }
+  .mk-search-item-wrap.action {
+    .ant-form-item {
+      height: 45px!important;
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
index e91fee9..0979803 100644
--- a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
@@ -234,8 +234,11 @@
         if (this.record.selectStyle === 'custom') {
           shows.push('backgroundColor')
         }
-        if (this.record.multiple === 'dropdown' && this.record.resourceType === '1') {
-          shows.push('mark', 'parentField')
+        if (this.record.multiple === 'dropdown') {
+          shows.push('mark')
+          if (this.record.resourceType === '1') {
+            shows.push('parentField')
+          }
         }
       }
       shows.push('linkField')
@@ -595,19 +598,18 @@
           { required: item.required, message: '璇疯緭鍏�' + item.label + '!' }
         ]
         span = 24
-        className = 'text-area'
 
         if (this.record.type === 'select' || this.record.type === 'link') {
           extra = <span className="add-resource-empty" onClick={this.handleEmpty}>鍏ㄩ儴</span>
         }
         if (item.placeholder) {
+          className = 'show-public-var'
           extra = <><span className="resource-public-var">{item.placeholder}</span>{extra}</>
         }
 
         content = <CodeMirror />
       } else if (item.type === 'options') {
         span = 24
-        className = 'text-area'
 
         let type = this.record.type
         
@@ -654,7 +656,6 @@
         }
       } else if (item.type === 'fields') {
         span = 24
-        className = 'text-area'
 
         rules = [
           { required: item.required, message: '璇锋坊鍔�' + item.label + '!' }
@@ -667,7 +668,7 @@
         ]
 
         content = <Checkbox.Group style={{width: '105%'}} options={item.options} onChange={(values) => this.optionChange(item.key, values)}/>
-      } else if (item.type === 'multiselect') { // 澶氶��
+      } else if (item.type === 'multiselect') {
         content = <Select
           showSearch
           mode="multiple"
@@ -677,8 +678,8 @@
             <Select.Option id={i} key={i} value={option.value}>{option.text}</Select.Option>
           )}
         </Select>
-      } else if (item.type === 'cascader') { // 澶氶��
-        content = <Cascader options={item.options} placeholder="" />
+      } else if (item.type === 'cascader') {
+        content = <Cascader options={item.options} />
       } else if (item.type === 'color') {
         className = 'color-form-item'
         rules = [
diff --git a/src/templates/sharecomponent/searchcomponent/searchform/index.scss b/src/templates/sharecomponent/searchcomponent/searchform/index.scss
index 6a66718..aded9be 100644
--- a/src/templates/sharecomponent/searchcomponent/searchform/index.scss
+++ b/src/templates/sharecomponent/searchcomponent/searchform/index.scss
@@ -4,7 +4,7 @@
     padding-left: 6px!important;
     padding-bottom: 20px;
   }
-  .ant-form-item.text-area {
+  .ant-col-24 {
     // margin-bottom: 0px;
     .ant-form-item-control-wrapper {
       width: 84%;
@@ -45,10 +45,15 @@
     cursor: pointer;
     font-size: 14px;
   }
+  .show-public-var {
+    margin-top: 20px;
+  }
   .resource-public-var {
     position: absolute;
     left: 0px;
-    top: -22px;
-    font-size: 14px;
+    top: -45px;
+    right: 40px;
+    font-size: 13px;
+    color: rgba(0, 0, 0, 0.65);
   }
 }
\ No newline at end of file
diff --git a/src/templates/zshare/codemirror/index.jsx b/src/templates/zshare/codemirror/index.jsx
index 0980534..dfe9c2b 100644
--- a/src/templates/zshare/codemirror/index.jsx
+++ b/src/templates/zshare/codemirror/index.jsx
@@ -169,8 +169,7 @@
         return
       }
 
-      let _href = window.location.href.split('#')[0]
-      localStorage.setItem(_href + 'sql_char', JSON.stringify([res.origin, res.value]))
+      localStorage.setItem(window.GLOB.sysSign + 'sql_char', JSON.stringify([res.origin, res.value]))
 
       _sql = _sql.replace(reg, res.value)
 
diff --git a/src/templates/zshare/customscript/index.jsx b/src/templates/zshare/customscript/index.jsx
index 0286596..e2da7de 100644
--- a/src/templates/zshare/customscript/index.jsx
+++ b/src/templates/zshare/customscript/index.jsx
@@ -333,7 +333,7 @@
             </Col>
             <Col span={24} className="sqlfield">
               <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</span></Tooltip>,&nbsp;
+                <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, lang, time_id</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>,&nbsp;
                 <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鎺掑簭銆佸垎椤典互鍙婃悳绱㈡潯浠跺彉閲忥紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}>orderBy{setting.laypage === 'true' ? ', pageSize, pageIndex': ''}{usefulFields ? ', ' + usefulFields : ''}</Tooltip>
                 {urlFields ?<Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'url鍙橀噺锛岃鎸夌収@xxx@鏍煎紡浣跨敤銆�'}>, <span style={{color: '#13c2c2'}}>{urlFields}</span></Tooltip> : ''}
diff --git a/src/templates/zshare/editTable/index.jsx b/src/templates/zshare/editTable/index.jsx
index 9ce9e95..b14d57a 100644
--- a/src/templates/zshare/editTable/index.jsx
+++ b/src/templates/zshare/editTable/index.jsx
@@ -419,7 +419,7 @@
     }
 
     try {
-      let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+      let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
       if (srcid) {
         msg.$srcId = srcid
       }
diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx
index 621dd29..286fddb 100644
--- a/src/templates/zshare/formconfig.jsx
+++ b/src/templates/zshare/formconfig.jsx
@@ -261,7 +261,7 @@
       label: '鏁版嵁婧�',
       initVal: card.dataSource || '',
       tooltip: '鏁版嵁鏉冮檺鏇挎崲绗� $@ -> /* 鎴� \'\'銆� @$ -> */ 鎴� \'\'',
-      placeholder: '绯荤粺鍙橀噺锛歮k_departmentcode銆乵k_organization銆乵k_user_type銆�',
+      placeholder: '绯荤粺鍙橀噺锛歮k_departmentcode銆乵k_organization銆乵k_user_type銆傚叕鍏卞�硷細@BID@銆丂Appkey@銆丂UserID@銆丂SessionUid@銆丂LoginUID@銆丂lang@銆�',
       required: true
     },
     {
@@ -444,7 +444,7 @@
         text: '鏈湴'
       }, {
         value: 'sso',
-        text: '绯荤粺'
+        text: '鍗曠偣'
       }]
     },
     {
@@ -1012,12 +1012,20 @@
 
   let options = card.options || []
   if (['select', 'radio', 'link'].includes(card.type) && card.setAll === 'true') { // 鍏煎
-    options.unshift({
+    let cell = {
       key: 'empty',
       Value: '',
       Text: card.emptyText || '绌�',
       ParentID: ''
-    })
+    }
+
+    if (card.linkSubField) {
+      card.linkSubField.forEach(m => {
+        cell[m] = ''
+      })
+    }
+
+    options.unshift(cell)
   }
 
   let initval = card.initval || ''
@@ -1199,7 +1207,7 @@
       label: '鏁版嵁婧�',
       initVal: card.dataSource || '',
       tooltip: '鏁版嵁鏉冮檺鏇挎崲绗� $@ -> /* 鎴� \'\'銆� @$ -> */ 鎴� \'\'',
-      placeholder: '绯荤粺鍙橀噺锛歮k_departmentcode銆乵k_organization銆乵k_user_type銆傚叕鍏卞�硷細@ID@銆丂BID@銆�',
+      placeholder: '绯荤粺鍙橀噺锛歮k_departmentcode銆乵k_organization銆乵k_user_type銆傚叕鍏卞�硷細@ID@銆丂BID@銆丂Appkey@銆丂UserID@銆丂SessionUid@銆丂LoginUID@銆丂lang@銆�',
       required: true,
       readonly: false
     },
@@ -1869,7 +1877,7 @@
         text: '鏈湴'
       }, {
         value: 'sso',
-        text: '绯荤粺'
+        text: '鍗曠偣'
       }]
     },
     {
diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx
index 7b515e6..8fe2851 100644
--- a/src/templates/zshare/modalform/index.jsx
+++ b/src/templates/zshare/modalform/index.jsx
@@ -764,6 +764,7 @@
           extra = <span className="add-resource-empty" onClick={this.handleEmpty}>绌�</span>
         }
         if (item.placeholder) {
+          className = 'show-public-var'
           extra = <><span className="resource-public-var">{item.placeholder}</span>{extra}</>
         }
 
@@ -1095,22 +1096,17 @@
 
           window.GLOB.formId = card.uuid
 
-          if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(values.type) && values.resourceType === '1' && values.dataSource) {
+          if (['select', 'multiselect', 'link', 'checkbox', 'radio', 'checkcard'].includes(values.type) && values.resourceType === '1' && values.database !== 'sso' && values.dataSource) {
             let _option = Utils.getSelectQueryOptions(values)
 
             let sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)
             ${_option.sql}`
     
-            // LoginUID|SessionUid|UserID|Appkey 宸叉浛鎹�
+            // LoginUID|SessionUid|UserID|Appkey|lang 宸叉浛鎹�
             sql = sql.replace(/@\$|\$@/ig, '')
-    
-            let rduri = ''
-            if (window.GLOB.mainSystemApi && values.database === 'sso') {
-              rduri = window.GLOB.mainSystemApi
-            }
             
             resolve({values, loading: true, promise: () => new Promise((resolve, reject) => {
-              Api.sDebug(sql, rduri).then(result => {
+              Api.sDebug(sql).then(result => {
                 if (result.status || result.ErrCode === '-2') {
                   resolve()
                 } else {
diff --git a/src/templates/zshare/modalform/index.scss b/src/templates/zshare/modalform/index.scss
index e718410..a59ba16 100644
--- a/src/templates/zshare/modalform/index.scss
+++ b/src/templates/zshare/modalform/index.scss
@@ -46,10 +46,15 @@
     cursor: pointer;
     font-size: 14px;
   }
+  .show-public-var {
+    margin-top: 20px;
+  }
   .resource-public-var {
     position: absolute;
     left: 0px;
-    top: -25px;
-    font-size: 14px;
+    top: -45px;
+    right: 40px;
+    font-size: 13px;
+    color: rgba(0, 0, 0, 0.65);
   }
 }
\ No newline at end of file
diff --git a/src/templates/zshare/pasteform/index.jsx b/src/templates/zshare/pasteform/index.jsx
index 73d666e..f3c3d6b 100644
--- a/src/templates/zshare/pasteform/index.jsx
+++ b/src/templates/zshare/pasteform/index.jsx
@@ -41,7 +41,7 @@
             _config = JSON.parse(window.decodeURIComponent(window.atob(_config)))
 
             if (typeof(_config) === 'object' && _config.$srcId) {
-              let srcid = localStorage.getItem(window.location.href.split('#')[0] + 'srcId')
+              let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
               if (srcid && _config.$srcId !== srcid) {
                 notification.warning({
                   top: 92,
diff --git a/src/templates/zshare/verifycard/callbackcustomscript/index.jsx b/src/templates/zshare/verifycard/callbackcustomscript/index.jsx
index 22d6853..9105198 100644
--- a/src/templates/zshare/verifycard/callbackcustomscript/index.jsx
+++ b/src/templates/zshare/verifycard/callbackcustomscript/index.jsx
@@ -227,7 +227,7 @@
           </Col> : null}
           {!type ? <Col span={24} className="sqlfield">
             <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, datam</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, lang, time_id, typename, datam</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, mk_deleted</span></Tooltip>,&nbsp;
               <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞跺湪鍗曞彿鐢熸垚鎴栧垱寤哄嚟璇佹椂浣跨敤銆�'}><span style={{color: '#13c2c2'}}>BillCode, BVoucher, FIBVoucherDate, FiYear, ModularDetailCode</span></Tooltip>
               {formfields ? <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title="琛ㄥ崟鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��">, <span style={{color: '#8E44AD'}}>{formfields}</span></Tooltip> : ''}
diff --git a/src/templates/zshare/verifycard/customform/index.jsx b/src/templates/zshare/verifycard/customform/index.jsx
index a111016..345b9f6 100644
--- a/src/templates/zshare/verifycard/customform/index.jsx
+++ b/src/templates/zshare/verifycard/customform/index.jsx
@@ -130,7 +130,7 @@
         <Row gutter={24}>
           <Col span={21} className="sqlfield">
             <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</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, lang, time_id</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, mk_deleted</span></Tooltip>,&nbsp;
               <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞跺湪鍗曞彿鐢熸垚鎴栧垱寤哄嚟璇佹椂浣跨敤銆�'}><span style={{color: '#13c2c2'}}>BillCode, BVoucher, FIBVoucherDate, FiYear, ModularDetailCode</span></Tooltip>
               {formfields ? <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title="琛ㄥ崟鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��">, <span style={{color: '#8E44AD'}}>{formfields}</span></Tooltip> : ''}
diff --git a/src/templates/zshare/verifycard/customscript/index.jsx b/src/templates/zshare/verifycard/customscript/index.jsx
index 05231cc..eb193a5 100644
--- a/src/templates/zshare/verifycard/customscript/index.jsx
+++ b/src/templates/zshare/verifycard/customscript/index.jsx
@@ -359,7 +359,7 @@
           </Col> : null}
           {!_type ? <Col span={24} className="sqlfield">
             <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, datam</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title="鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�"><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, lang, time_id, typename, datam</span></Tooltip>,&nbsp;
               {window.GLOB.process && workFlow === 'true' ? <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title="宸ヤ綔娴佸彉閲忥紝璇锋寜鐓xxx@鏍煎紡浣跨敤锛寃orks_flow_sign 涓哄垎鏀惎鐢ㄩ珮绾ц缃椂鐨勬爣璁板�笺��"><span style={{color: '#26C281'}}>works_flow_code, works_flow_name, works_flow_param, works_flow_detail_id, status, statusname, work_group, work_grade, start_type, check_type, notice_type, check_userids, notice_userids, works_flow_sign, </span></Tooltip> : null}
               <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, mk_deleted</span></Tooltip>,&nbsp;
               <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title="绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞跺湪鍗曞彿鐢熸垚鎴栧垱寤哄嚟璇佹椂浣跨敤銆�"><span style={{color: '#13c2c2'}}>BillCode, BVoucher, FIBVoucherDate, FiYear, ModularDetailCode</span></Tooltip>
diff --git a/src/utils/utils-custom.js b/src/utils/utils-custom.js
index d49eb33..1141a14 100644
--- a/src/utils/utils-custom.js
+++ b/src/utils/utils-custom.js
@@ -558,6 +558,9 @@
           })
         }
       } else if (item.type === 'form') {
+        if (item.wrap.datatype === 'public' && item.wrap.publicId) {
+          item.wrap.publicId = md5(commonId + item.wrap.publicId)
+        }
         item.subcards = item.subcards.map(cell => {
           cell.uuid = this.getuuid()
   
@@ -626,7 +629,7 @@
         })
       }
 
-      if (item.setting && item.setting.supModule && item.setting.supModule[0] !== 'empty') {
+      if (item.setting && item.setting.supModule && item.setting.supModule[0] !== 'empty' && item.setting.supModule[0] !== 'preview') {
         item.setting.supModule = item.setting.supModule.map(c => {
           return md5(commonId + c)
         })
@@ -1105,6 +1108,8 @@
         value = item.initval || `${item.minValue || '-999999999'},${item.maxValue || '999999999'}`
       } else if (item.type === 'multiselect' || (item.type === 'checkcard' && item.multiple === 'true')) {
         type = 'multi'
+      } else {
+        value = item.initval || '0'
       }
 
       newsearches.push({
@@ -1794,23 +1799,31 @@
       if (!cell.modal || cell.modal.fields.length === 0) {
         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)) {
-      errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
+    } else if (cell.OpenType === 'excelIn') {
+      if (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0) {
+        errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
+      }
     } else if (cell.OpenType === 'excelOut') {
       if (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0) {
         errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-      } else if (cell.intertype === 'system' && cell.verify.dataType !== 'custom' && card.$c_ds && columns.length > 0) {
-        let cols = []
-        cell.verify.columns.forEach(col => {
-          if (col.output === 'false' || col.Column === '$Index') return
-          if (!columns.includes(col.Column)) {
-            cols.push(col.Column)
+      } else if (cell.intertype === 'system' && cell.verify.dataType !== 'custom') {
+        if (!card.setting || card.setting.interType !== 'system') {
+          errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濋渶鑷畾涔夊鍑烘暟鎹簮锛乣})
+        } else if (card.type === 'balcony' || card.subtype === 'propcard') {
+          errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濋渶鑷畾涔夊鍑烘暟鎹簮锛乣})
+        } else if (card.$c_ds && columns.length > 0) {
+          let cols = []
+          cell.verify.columns.forEach(col => {
+            if (col.output === 'false' || col.Column === '$Index') return
+            if (!columns.includes(col.Column)) {
+              cols.push(col.Column)
+            }
+          })
+          if (cols.length) {
+            errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楋紙${cols.join('銆�')}锛夊湪瀛楁闆嗕腑涓嶅瓨鍦紒`})
           }
-        })
-        if (cols.length) {
-          errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楋紙${cols.join('銆�')}锛夊湪瀛楁闆嗕腑涓嶅瓨鍦紒`})
         }
-      }
+      } 
     }
 
     if (['pop', 'prompt', 'exec'].includes(cell.OpenType) && cell.verify && !cell.output) {
@@ -1818,6 +1831,32 @@
         errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濇湭璁剧疆杩斿洖鍊肩煭淇″彂閫佹棤鏁堬紒`})
       } else if (cell.verify.emailEnable === 'true') {
         errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濇湭璁剧疆杩斿洖鍊奸偖浠跺彂閫佹棤鏁堬紒`})
+      }
+    }
+
+    if (['exec', 'prompt', 'pop', 'form', 'formSubmit'].includes(cell.OpenType)) {
+      if (cell.OpenType === 'form' && cell.formType === 'count_line') return
+     
+      if (cell.intertype === 'system') {
+        if (cell.Ot === 'notRequired' && cell.verify && cell.verify.voucher && cell.verify.voucher.enabled) {
+          errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅娇鐢ㄤ簡鍒涘缓鍑瘉鍑芥暟锛岄渶瑕侀�夋嫨琛岋紒`})
+        }
+      } else if (cell.intertype === 'custom' || cell.intertype === 'outer') {
+        if (cell.callbackType === 'script' && (!cell.verify || !cell.verify.cbScripts || !cell.verify.cbScripts.filter(item => item.status !== 'false').length === 0)) {
+          errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅娇鐢ㄤ簡鑷畾涔夎剼鏈洖璋冿紝鍥炶皟鑴氭湰涓嶅彲涓虹┖锛乣})
+        } else if (cell.procMode === 'system' && cell.Ot === 'notRequired' && cell.verify && cell.verify.voucher && cell.verify.voucher.enabled) {
+          errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅娇鐢ㄤ簡鍒涘缓鍑瘉鍑芥暟锛岄渶瑕侀�夋嫨琛岋紒`})
+        }
+      }
+    } else if (cell.OpenType === 'funcbutton' && cell.funcType === 'print') {
+      if (!cell.verify || !cell.verify.printMode) {
+        errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濊瀹屽杽楠岃瘉淇℃伅锛乣})
+      } else if (cell.intertype === 'system' && cell.verify.dataType === 'custom' && (!cell.verify.setting || cell.verify.columns.length === 0)) {
+        errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅娇鐢ㄤ簡鑷畾涔夋墦鍗版暟鎹紝璇疯缃暟鎹簮锛乣})
+      }
+    } else if (cell.OpenType === 'innerpage' || cell.OpenType === 'outerpage') {
+      if (!cell.pageTemplate) {
+        errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濋〉闈㈢被鍨嬭缃敊璇紒`})
       }
     }
   }
@@ -2004,6 +2043,13 @@
       duration: 5
     })
     return false
+  } else if (/\send\s+begin\s/ig.test(sql)) {
+    notification.warning({
+      top: 92,
+      message: `end 鍚庝笉鍙揣璺� begin銆俙,
+      duration: 5
+    })
+    return false
   } else if (type === 'customscript' && /\son\s+[a-z0-9_]+\.[a-z0-9_]+\s*=\s*[a-z0-9_]+\.[a-z0-9_]+/ig.test(sql)) {
     let list = sql.match(/\son\s+[a-z0-9_]+\.[a-z0-9_]+\s*=\s*[a-z0-9_]+\.[a-z0-9_]+/ig)
     let errors = []
@@ -2064,4 +2110,725 @@
   }
 
   return true
+}
+
+/**
+ * @description 鑾峰彇璇█杞崲淇℃伅
+ */
+export function getLangTrans (config) {
+  let langList = sessionStorage.getItem('langList')
+  let appType = sessionStorage.getItem('appType')
+
+  if (appType === 'mob' || appType === 'pc') {
+    langList = sessionStorage.getItem('applangList')
+  }
+  
+  if (!langList) return
+
+  let defLang = ''
+
+  try {
+    langList = JSON.parse(langList)
+    defLang = langList[0]
+  } catch (e) {
+    defLang = ''
+  }
+
+  if (!defLang) return ''
+
+  let sql = []
+  let btn = []
+  let ops = []
+  let text = []
+  let menu = []
+
+  let filterElement = (card) => {
+    if (card.datatype === 'static' && card.eleType === 'text' && !/@.+@/g.test(card.value)) {
+      sql.push(card.value)
+    }
+    if (card.prefix) {
+      sql.push(card.prefix)
+    }
+    if (card.postfix) {
+      sql.push(card.postfix)
+    }
+  }
+
+  let filterSql = (sl) => {
+    if (!sl) return
+
+    let cutreg = /[\u4E00-\u9FA5銆傦紒锛屻�乚+/ig
+    let tbs = sl.match(cutreg)
+
+    if (!tbs) return
+    
+    text.push(...tbs)
+  }
+
+  let filterBtn = (btn) => {
+    if (!btn.verify) return
+
+    btn.verify.customverifys && btn.verify.customverifys.forEach(script => {
+      filterSql(script.sql)
+    })
+    btn.verify.scripts && btn.verify.scripts.forEach(script => {
+      filterSql(script.sql)
+    })
+    btn.verify.cbScripts && btn.verify.cbScripts.forEach(script => {
+      filterSql(script.sql)
+    })
+
+    if (btn.OpenType === 'funcbutton') {
+      if (btn.intertype === 'system' && btn.verify.dataType === 'custom' && btn.verify.setting) {
+        filterSql(btn.verify.setting.dataresource)
+      }
+    } else if (btn.OpenType === 'excelOut') {
+      filterSql(btn.verify.dataresource)
+    }
+  }
+
+  let filterForm = (n) => {
+    sql.push(n.label)
+    if (n.resourceType === '1') {
+      filterSql(n.dataSource)
+    } else if (n.options) {
+      n.options.forEach(o => {
+        ops.push(o.Text)
+      })
+    }
+  }
+
+  let traversal = (components) => {
+    if (!components) return
+
+    components.forEach(item => {
+      if (item.type === 'tabs') {
+        item.subtabs.forEach(tab => {
+          sql.push(tab.label)
+          traversal(tab.components)
+        })
+      } else if (item.type === 'group') {
+        traversal(item.components)
+      } else {
+        if (item.setting && (!item.wrap || !item.wrap.datatype || item.wrap.datatype === 'dynamic')) {
+          if (item.setting.interType === 'system') {
+            filterSql(item.setting.dataresource)
+            item.scripts && item.scripts.forEach(script => {
+              filterSql(script.sql)
+            })
+          }
+        }
+
+        if (item.columns) {
+          item.columns.forEach(cell => {
+            sql.push(cell.label)
+          })
+        }
+        if (item.search) {
+          if (item.type === 'topbar') {
+            if (item.search.fields) {
+              item.search.fields.forEach(cell => {
+                filterForm(cell)
+              })
+            }
+            if (item.search.groups) {
+              item.search.groups.forEach(group => {
+                if (group.fields) {
+                  group.fields.forEach(cell => {
+                    filterForm(cell)
+                  })
+                }
+              })
+            }
+          } else {
+            item.search.forEach(cell => {
+              filterForm(cell)
+            })
+          }
+        }
+        if (item.action) {
+          item.action.forEach(cell => {
+            btn.push(cell.label)
+            filterBtn(cell)
+            if (cell.OpenType === 'popview' && cell.config) {
+              traversal(cell.config.components)
+            } else if (cell.OpenType === 'pop') {
+              if (cell.modal && cell.modal.fields.length) {
+                cell.modal.fields.forEach(n => {
+                  filterForm(n)
+                })
+              }
+            }
+          })
+        }
+
+        if (item.type === 'navbar') {
+          if (item.menus) {
+            item.menus.forEach(first => {
+              menu.push(first.name)
+              if (first.sublist) {
+                first.sublist.forEach(sec => {
+                  menu.push(sec.name)
+                  if (sec.sublist) {
+                    sec.sublist.forEach(thd => {
+                      menu.push(thd.name)
+                    })
+                  }
+                })
+              }
+            })
+          }
+        } else if (item.type === 'menubar') {
+          item.subMenus.forEach(cell => {
+            if (cell.setting.name) {
+              menu.push(cell.setting.name)
+            }
+          })
+        } else if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
+          item.subcards.forEach(card => {
+            card.elements && card.elements.forEach(cell => {
+              if (cell.eleType === 'button') {
+                btn.push(cell.label)
+                filterBtn(cell)
+                if (cell.OpenType === 'popview' && cell.config) {
+                  traversal(cell.config.components)
+                } else if (cell.OpenType === 'pop') {
+                  if (cell.modal && cell.modal.fields.length) {
+                    cell.modal.fields.forEach(n => {
+                      filterForm(n)
+                    })
+                  }
+                }
+              } else {
+                filterElement(cell)
+              }
+            })
+            card.backElements && card.backElements.forEach(cell => {
+              if (cell.eleType === 'button') {
+                btn.push(cell.label)
+                filterBtn(cell)
+                if (cell.OpenType === 'popview' && cell.config) {
+                  traversal(cell.config.components)
+                } else if (cell.OpenType === 'pop') {
+                  if (cell.modal && cell.modal.fields.length) {
+                    cell.modal.fields.forEach(n => {
+                      filterForm(n)
+                    })
+                  }
+                }
+              } else {
+                filterElement(cell)
+              }
+            })
+          })
+        } else if (item.type === 'balcony') {
+          item.elements && item.elements.forEach(cell => {
+            if (cell.eleType === 'button') {
+              btn.push(cell.label)
+              filterBtn(cell)
+              if (cell.OpenType === 'popview' && cell.config) {
+                traversal(cell.config.components)
+              } else if (cell.OpenType === 'pop') {
+                if (cell.modal && cell.modal.fields.length) {
+                  cell.modal.fields.forEach(n => {
+                    filterForm(n)
+                  })
+                }
+              }
+            } else {
+              filterElement(cell)
+            }
+          })
+        } else if (item.type === 'table') {
+          let loopCol = (cols) => {
+            cols.forEach(col => {
+              sql.push(col.label)
+              if (col.prefix) {
+                sql.push(col.prefix)
+              }
+              if (col.postfix) {
+                sql.push(col.postfix)
+              }
+              if (col.type === 'colspan') {
+                loopCol(col.subcols)
+              } else if (col.type === 'custom') {
+                col.elements.forEach(cell => {
+                  if (cell.eleType === 'button') {
+                    btn.push(cell.label)
+                    filterBtn(cell)
+                    if (cell.OpenType === 'popview' && cell.config) {
+                      traversal(cell.config.components)
+                    } else if (cell.OpenType === 'pop') {
+                      if (cell.modal && cell.modal.fields.length) {
+                        cell.modal.fields.forEach(n => {
+                          filterForm(n)
+                        })
+                      }
+                    }
+                  } else {
+                    filterElement(cell)
+                  }
+                })
+              }
+            })
+          }
+          loopCol(item.cols)
+        } else if (item.type === 'form') {
+          item.subcards.forEach(cell => {
+            filterBtn(cell.subButton)
+            cell.fields.forEach(n => {
+              filterForm(n)
+            })
+          })
+        }
+      }
+    })
+  }
+
+  if (config.interfaces) {
+    config.interfaces.forEach(item => {
+      if (item.setting.interType === 'system') {
+        filterSql(item.setting.dataresource)
+        item.scripts && item.scripts.forEach(script => {
+          filterSql(script.sql)
+        })
+      }
+    })
+  }
+
+  traversal(config.components)
+
+  if (config.MenuName) {
+    menu.push(config.MenuName)
+  }
+
+  if (config.fstMenuId && config.parentId && config.fstMenuId !== 'BillPrintTemp') {
+    let menulist = sessionStorage.getItem('fstMenuList')
+    try {
+      menulist = JSON.parse(menulist)
+    } catch(e) {
+      menulist = []
+    }
+
+    menulist.forEach(item => {
+      if (item.MenuID !== config.fstMenuId) return
+      menu.push(item.MenuName)
+      item.children.forEach(cell => {
+        if (cell.MenuID !== config.parentId) return
+        menu.push(cell.MenuName)
+      })
+    })
+  }
+
+  sql = sql.filter(Boolean)
+  btn = btn.filter(Boolean)
+  ops = ops.filter(Boolean)
+  text = text.filter(Boolean)
+  menu = menu.filter(Boolean)
+
+  sql = Array.from(new Set(sql))
+  btn = Array.from(new Set(btn))
+  ops = Array.from(new Set(ops))
+  text = Array.from(new Set(text))
+  menu = Array.from(new Set(menu))
+
+  sql = sql.map(l => `'${l}','title'`)
+  btn = btn.map(l => `'${l}','button'`)
+  ops = ops.map(l => `'${l}','list'`)
+  text = text.map(l => `'${l}','text'`)
+  menu = menu.map(l => `'${l}','menu'`)
+
+  let list = [...menu, ...btn, ...sql, ...ops, ...text]
+
+  let result = []
+
+  langList.forEach(lan => {
+    if (lan === defLang) return
+
+    list.forEach(n => {
+      result.push(`'${lan}',${n}`)
+    })
+  })
+
+  config.trans = true
+  
+  return result.join(';')
+}
+
+/**
+ * @description 璇█杞崲
+ */
+export function setLangTrans (config, btnDict, titDict, lisDict, menuDict, regs, tail) {
+  let filterElement = (card) => {
+    if (card.datatype === 'static' && card.eleType === 'text' && !/@.+@/g.test(card.value)) {
+      if (card.value && titDict[card.value]) {
+        card.value = titDict[card.value]
+      }
+    }
+    if (card.prefix && titDict[card.prefix]) {
+      card.prefix = titDict[card.prefix]
+    }
+    if (card.postfix && titDict[card.postfix]) {
+      card.postfix = titDict[card.postfix]
+    }
+  }
+
+  let filterSql = (sl) => {
+    if (!sl) return
+
+    regs.forEach(item => {
+      sl = sl.replace(item.reg, item.value)
+    })
+
+    return sl
+  }
+
+  let filterBtn = (btn) => {
+    if (btn.label && btnDict[btn.label]) {
+      btn.label = btnDict[btn.label]
+    }
+
+    if (btn.OpenType === 'tab' && btn.linkmenu) {
+      if (btn.linkmenu[0] === 'multiMenu') {
+        btn.multiMenus.forEach(menu => {
+          menu.menuId = menu.menuId.map(c => {
+            if (c.length <= 24) {
+              return md5(window.GLOB.appkey + c + sessionStorage.getItem('lang')).toLowerCase()
+            } else {
+              return c.slice(0, 24) + tail
+            }
+          })
+
+          menu.MenuID = menu.menuId[menu.menuId.length - 1]
+        })
+      } else {
+        btn.linkmenu = btn.linkmenu.map(c => {
+          if (c.length <= 24) {
+            return md5(window.GLOB.appkey + c + sessionStorage.getItem('lang')).toLowerCase()
+          } else {
+            return c.slice(0, 24) + tail
+          }
+        })
+        btn.MenuID = btn.linkmenu[btn.linkmenu.length - 1]
+      }
+    } else {
+      if (btn.refreshTab && btn.refreshTab.length > 0) {
+        btn.refreshTab = btn.refreshTab.map(c => {
+          if (c.length <= 24) {
+            return md5(window.GLOB.appkey + c + sessionStorage.getItem('lang')).toLowerCase()
+          } else {
+            return c.slice(0, 24) + tail
+          }
+        })
+      }
+      if (btn.openmenu && Array.isArray(btn.openmenu) && btn.openmenu.length > 0) {
+        btn.openmenu = btn.openmenu.map(c => {
+          if (c.length <= 24) {
+            return md5(window.GLOB.appkey + c + sessionStorage.getItem('lang')).toLowerCase()
+          } else {
+            return c.slice(0, 24) + tail
+          }
+        })
+        btn.MenuID = btn.openmenu[btn.openmenu.length - 1]
+      } else if (btn.openmenu && typeof(btn.openmenu) === 'string' && btn.openmenu !== 'goback') {
+        btn.openmenu = btn.openmenu.slice(0, 24) + tail
+      }
+
+      if (btn.pageTemplate === 'linkpage' && btn.linkmenu && typeof(btn.linkmenu) === 'string') {
+        btn.linkmenu = btn.linkmenu.slice(0, 24) + tail
+      }
+    }
+
+    if (!btn.verify) return
+
+    btn.verify.customverifys && btn.verify.customverifys.forEach(script => {
+      script.sql = filterSql(script.sql)
+    })
+    btn.verify.scripts && btn.verify.scripts.forEach(script => {
+      script.sql = filterSql(script.sql)
+    })
+    btn.verify.cbScripts && btn.verify.cbScripts.forEach(script => {
+      script.sql = filterSql(script.sql)
+    })
+
+    if (btn.OpenType === 'funcbutton') {
+      if (btn.intertype === 'system' && btn.verify.dataType === 'custom' && btn.verify.setting) {
+        btn.verify.setting.dataresource = filterSql(btn.verify.setting.dataresource)
+      }
+    } else if (btn.OpenType === 'excelOut' && btn.verify.dataresource) {
+      btn.verify.dataresource = filterSql(btn.verify.dataresource)
+    }
+  }
+
+  let filterForm = (n) => {
+    if (n.label && titDict[n.label]) {
+      n.label = titDict[n.label]
+    }
+    if (n.resourceType === '1') {
+      n.dataSource = filterSql(n.dataSource)
+    } else if (n.options) {
+      n.options.forEach(o => {
+        if (o.Text && lisDict[o.Text]) {
+          o.Text = lisDict[o.Text]
+        }
+      })
+    }
+  }
+
+  let resetMenu = (wrap) => {
+    if (!wrap.menu) return
+    
+    if (typeof(wrap.menu) === 'string') {
+      wrap.menu = wrap.menu.slice(0, 24) + tail
+      if (wrap.MenuID) {
+        wrap.MenuID = wrap.menu
+      }
+    } else {
+      wrap.menu = wrap.menu.map(c => {
+        if (c.length <= 24) {
+          return md5(window.GLOB.appkey + c + sessionStorage.getItem('lang')).toLowerCase()
+        } else {
+          return c.slice(0, 24) + tail
+        }
+      })
+      if (wrap.MenuID) {
+        wrap.MenuID = wrap.menu[wrap.menu.length - 1]
+      }
+    }
+  }
+  let resetMenus = (wrap) => {
+    if (!wrap.menus) return
+    
+    wrap.menus.forEach(m => {
+      if (typeof(m.menu) === 'string') {
+        m.menu = m.menu.slice(0, 24) + tail
+      } else {
+        m.menu = m.menu.map(c => {
+          if (c.length <= 24) {
+            return md5(window.GLOB.appkey + c + sessionStorage.getItem('lang')).toLowerCase()
+          } else {
+            return c.slice(0, 24) + tail
+          }
+        })
+        if (m.MenuID) {
+          m.MenuID = m.menu[m.menu.length - 1]
+        }
+      }
+    })
+  }
+
+  let traversal = (components) => {
+    if (!components) return
+
+    components.forEach(item => {
+      if (item.type === 'tabs') {
+        item.subtabs.forEach(tab => {
+          if (tab.label && titDict[tab.label]) {
+            tab.label = titDict[tab.label]
+          }
+          traversal(tab.components)
+        })
+      } else if (item.type === 'group') {
+        traversal(item.components)
+      } else {
+        if (item.wrap && (item.wrap.click === 'menu' || item.wrap.click === 'menus')) {
+          if (item.wrap.click === 'menu') {
+            resetMenu(item.wrap)
+          } else if (item.wrap.click === 'menus') {
+            resetMenus(item.wrap)
+          }
+        } else if (item.plot && (item.plot.click === 'menu' || item.plot.click === 'menus')) {
+          if (item.plot.click === 'menu') {
+            resetMenu(item.plot)
+          } else if (item.plot.click === 'menus') {
+            resetMenus(item.plot)
+          }
+        }
+        if (item.setting && (!item.wrap || !item.wrap.datatype || item.wrap.datatype === 'dynamic')) {
+          if (item.setting.interType === 'system') {
+            item.setting.dataresource = filterSql(item.setting.dataresource)
+            item.scripts && item.scripts.forEach(script => {
+              script.sql = filterSql(script.sql)
+            })
+          }
+        }
+
+        if (item.columns) {
+          item.columns.forEach(cell => {
+            if (cell.label && titDict[cell.label]) {
+              cell.label = titDict[cell.label]
+            }
+          })
+        }
+        if (item.search) {
+          if (item.type === 'topbar') {
+            if (item.search.fields) {
+              item.search.fields.forEach(cell => {
+                filterForm(cell)
+              })
+            }
+            if (item.search.groups) {
+              item.search.groups.forEach(group => {
+                if (group.fields) {
+                  group.fields.forEach(cell => {
+                    filterForm(cell)
+                  })
+                }
+              })
+            }
+          } else {
+            item.search.forEach(cell => {
+              filterForm(cell)
+            })
+          }
+        }
+        if (item.action) {
+          item.action.forEach(cell => {
+            filterBtn(cell)
+            if (cell.OpenType === 'popview' && cell.config) {
+              traversal(cell.config.components)
+            } else if (cell.OpenType === 'pop') {
+              if (cell.modal && cell.modal.fields.length) {
+                cell.modal.fields.forEach(n => {
+                  filterForm(n)
+                })
+              }
+            }
+          })
+        }
+
+        if (item.type === 'navbar') {
+          item.uuid = item.uuid.slice(0, 24) + tail
+        } else if (item.type === 'login') {
+          item.wrap.linkmenu = item.wrap.linkmenu.slice(0, 24) + tail
+        } else if (item.type === 'menubar') {
+          item.subMenus = item.subMenus.map(cell => {
+            if (cell.setting.name && menuDict[cell.setting.name]) {
+              cell.setting.name = menuDict[cell.setting.name]
+            }
+            if (cell.setting.type === 'linkmenu') {
+              cell.setting.linkMenuId = cell.setting.linkMenuId.slice(0, 24) + tail
+            }
+            return cell
+          })
+        } else if (item.type === 'topbar') {
+          if (item.wrap.menus) {
+            resetMenus(item.wrap)
+          }
+        } else if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
+          item.subcards.forEach(card => {
+            if (card.setting.click === 'menus') {
+              resetMenus(card)
+            } else if (card.setting.click === 'menu') {
+              resetMenu(card.setting)
+            }
+            card.elements && card.elements.forEach(cell => {
+              if (cell.eleType === 'button') {
+                filterBtn(cell)
+                if (cell.OpenType === 'popview' && cell.config) {
+                  traversal(cell.config.components)
+                } else if (cell.OpenType === 'pop') {
+                  if (cell.modal && cell.modal.fields.length) {
+                    cell.modal.fields.forEach(n => {
+                      filterForm(n)
+                    })
+                  }
+                }
+              } else {
+                filterElement(cell)
+              }
+            })
+            card.backElements && card.backElements.forEach(cell => {
+              if (cell.eleType === 'button') {
+                filterBtn(cell)
+                if (cell.OpenType === 'popview' && cell.config) {
+                  traversal(cell.config.components)
+                } else if (cell.OpenType === 'pop') {
+                  if (cell.modal && cell.modal.fields.length) {
+                    cell.modal.fields.forEach(n => {
+                      filterForm(n)
+                    })
+                  }
+                }
+              } else {
+                filterElement(cell)
+              }
+            })
+          })
+        } else if (item.type === 'balcony') {
+          item.elements && item.elements.forEach(cell => {
+            if (cell.eleType === 'button') {
+              filterBtn(cell)
+              if (cell.OpenType === 'popview' && cell.config) {
+                traversal(cell.config.components)
+              } else if (cell.OpenType === 'pop') {
+                if (cell.modal && cell.modal.fields.length) {
+                  cell.modal.fields.forEach(n => {
+                    filterForm(n)
+                  })
+                }
+              }
+            } else {
+              filterElement(cell)
+            }
+          })
+        } else if (item.type === 'table') {
+          let loopCol = (cols) => {
+            cols.forEach(col => {
+              if (col.label && titDict[col.label]) {
+                col.label = titDict[col.label]
+              }
+              if (col.prefix && titDict[col.prefix]) {
+                col.prefix = titDict[col.prefix]
+              }
+              if (col.postfix && titDict[col.postfix]) {
+                col.postfix = titDict[col.postfix]
+              }
+              if (col.type === 'colspan') {
+                loopCol(col.subcols)
+              } else if (col.type === 'custom') {
+                col.elements.forEach(cell => {
+                  if (cell.eleType === 'button') {
+                    filterBtn(cell)
+                    if (cell.OpenType === 'popview' && cell.config) {
+                      traversal(cell.config.components)
+                    } else if (cell.OpenType === 'pop') {
+                      if (cell.modal && cell.modal.fields.length) {
+                        cell.modal.fields.forEach(n => {
+                          filterForm(n)
+                        })
+                      }
+                    }
+                  } else {
+                    filterElement(cell)
+                  }
+                })
+              }
+            })
+          }
+          loopCol(item.cols)
+        } else if (item.type === 'form') {
+          item.subcards.forEach(cell => {
+            filterBtn(cell.subButton)
+            cell.fields.forEach(n => {
+              filterForm(n)
+            })
+          })
+        }
+      }
+    })
+  }
+
+  if (config.interfaces) {
+    config.interfaces.forEach(item => {
+      if (item.setting.interType === 'system') {
+        item.setting.dataresource = filterSql(item.setting.dataresource)
+        item.scripts && item.scripts.forEach(script => {
+          script.sql = filterSql(script.sql)
+        })
+      }
+    })
+  }
+
+  traversal(config.components)
 }
\ No newline at end of file
diff --git a/src/utils/utils-datamanage.js b/src/utils/utils-datamanage.js
index 6210d62..0415658 100644
--- a/src/utils/utils-datamanage.js
+++ b/src/utils/utils-datamanage.js
@@ -151,6 +151,7 @@
       { reg: /@SessionUid@/ig, value: `'${localStorage.getItem('SessionUid') || ''}'`},
       { reg: /@UserID@/ig, value: `'${sessionStorage.getItem('UserID') || ''}'`},
       { reg: /@Appkey@/ig, value: `'${window.GLOB.appkey || ''}'`},
+      { reg: /@lang@/ig, value: `'${sessionStorage.getItem('lang')}'`},
       { reg: /@typename@/ig, value: `'admin'`},
     )
 
@@ -322,6 +323,10 @@
       param.s_version_up = 'true'
     }
 
+    if (setting.database === 'sso' && window.GLOB.mainSystemApi) {
+      param.rduri = window.GLOB.mainSystemApi
+    }
+
     return param
   }
 
@@ -379,6 +384,7 @@
       { reg: /@SessionUid@/ig, value: `'${localStorage.getItem('SessionUid') || ''}'`},
       { reg: /@UserID@/ig, value: `'${sessionStorage.getItem('UserID') || ''}'`},
       { reg: /@Appkey@/ig, value: `'${window.GLOB.appkey || ''}'`},
+      { reg: /@lang@/ig, value: `'${sessionStorage.getItem('lang')}'`},
       { reg: /@typename@/ig, value: `'admin'`},
     )
 
@@ -578,6 +584,7 @@
     { reg: /@SessionUid@/ig, value: `'${localStorage.getItem('SessionUid') || ''}'`},
     { reg: /@UserID@/ig, value: `'${sessionStorage.getItem('UserID') || ''}'`},
     { reg: /@Appkey@/ig, value: `'${window.GLOB.appkey || ''}'`},
+    { reg: /@lang@/ig, value: `'${sessionStorage.getItem('lang')}'`},
     { reg: /@typename@/ig, value: `'admin'`},
   ]
 
diff --git a/src/utils/utils.js b/src/utils/utils.js
index 1fa8b28..2b7f1d6 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -916,6 +916,7 @@
     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(/@lang@/ig, `'${sessionStorage.getItem('lang')}'`)
 
     return {
       sql: sql,
@@ -1094,6 +1095,7 @@
       {reg: /@SessionUid@/ig, value: `'${localStorage.getItem('SessionUid') || ''}'`},
       {reg: /@UserID@/ig, value: `'${sessionStorage.getItem('UserID') || ''}'`},
       {reg: /@Appkey@/ig, value: `'${window.GLOB.appkey || ''}'`},
+      {reg: /@lang@/ig, value: `'${sessionStorage.getItem('lang')}'`},
       {reg: /@typename@/ig, value: `'admin'`},
       {reg: /\$@/ig, value: isDM ? '/*' : ''},
       {reg: /@\$/ig, value: isDM ? '*/' : ''},
@@ -1425,6 +1427,7 @@
       {reg: /@SessionUid@/ig, value: `'${localStorage.getItem('SessionUid') || ''}'`},
       {reg: /@UserID@/ig, value: `'${sessionStorage.getItem('UserID') || ''}'`},
       {reg: /@Appkey@/ig, value: `'${window.GLOB.appkey || ''}'`},
+      {reg: /@lang@/ig, value: `'${sessionStorage.getItem('lang')}'`},
       {reg: /@typename@/ig, value: `'admin'`},
       {reg: /\$@/ig, value: isDM ? '/*' : ''},
       {reg: /@\$/ig, value: isDM ? '*/' : ''},
@@ -2563,15 +2566,29 @@
       begin
           select @retmsg='X' from s_my_works_flow_role where works_flow_id=@ID@ and works_flow_code=@works_flow_code@ and userid=@userid@
 
-          if @retmsg !='' 
+          if @retmsg !=''
           begin
               select @ErrorCode='E', @retmsg='褰撳墠鍗曟嵁宸插鏍革紝璇峰埛鏂板悗閲嶈瘯'
-            goto aaa 
+            goto aaa
+          end
+
+          if @dataM@ !='' 
+          begin
+            set @retmsg =''
+            select @retmsg='X' from s_my_works_flow_role where works_flow_id=@ID@ and works_flow_code=@works_flow_code@ and deleted=0  
+
+            if @retmsg != ''
+            begin
+                goto goto_mk
+            end
           end
 
           select @retmsg='椤甸潰鏁版嵁宸叉洿鏂帮紝鎴栨病鏈夊綋鍓嶅崟鎹殑瀹℃壒鏉冮檺'
             goto aaa 
-      end
+      end 
+
+      goto_mk:
+
       set @retmsg=''
 
       update s_my_works_flow set status=@status@,statusname=@statusname@,works_flow_param=@works_flow_param@,works_flow_detail_id=@works_flow_detail_id@,modifydate=getdate(),upid=@time_id@,modifyuserid=@userid@,modifyuser=@username,modifystaff=@fullname${verify.flowRemark ? ',remark=@' + verify.flowRemark : ''}
@@ -2670,6 +2687,7 @@
   _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(/@lang@/ig, `'${sessionStorage.getItem('lang')}'`)
   _sql = _sql.replace(/@typename@/ig, `'admin'`)
 
   if (window.GLOB.externalDatabase !== null) {
diff --git a/src/views/appcheck/index.jsx b/src/views/appcheck/index.jsx
index 49c4d5b..3154996 100644
--- a/src/views/appcheck/index.jsx
+++ b/src/views/appcheck/index.jsx
@@ -1,16 +1,14 @@
 import React, {Component} from 'react'
-import { Spin, notification, Table, ConfigProvider, Typography, Row, Col, Tooltip } from 'antd'
+import { Spin, notification, Table, Typography, Row, Col, Tooltip } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
-import enUS from 'antd/es/locale/en_US'
-import zhCN from 'antd/es/locale/zh_CN'
 
 import Api from '@/api'
+import { langs } from '@/store/options.js'
 import asyncComponent from '@/utils/asyncComponent'
 import './index.scss'
 
 const { Paragraph } = Typography
 
-const _locale = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
 const Header = asyncComponent(() => import('./header'))
 
 const skinStyle = {
@@ -139,116 +137,114 @@
 
     return (
       <div className="mk-app-check">
-        <ConfigProvider locale={_locale}>
-          <Header view="manage" />
-          {loading ?
-            <div className="loading-mask">
-              <Spin size="large" />
-            </div> : null
-          }
-          <div className="view-wrap">
-            <div className="left-view">
-              <div className="app-table">
-                <Table
-                  rowKey="ID"
-                  columns={columns}
-                  dataSource={applist}
-                  pagination={false}
-                  rowSelection={{ type: 'radio', selectedRowKeys: selectApp ? [selectApp.ID] : [], onChange: this.onSelectChange }}
-                  onRow={(record) => ({ onClick: () => this.setState({ selectApp: record })})}
-                />
-              </div>
-            </div>
-            <div className="right-view">
-              {selectApp ? <div className="app-title">{selectApp.remark}</div> : null}
-              {selectApp && selectApp.sublist.map((item, index) => {
-                let css = skinStyle[item.css] ? skinStyle[item.css].name : ''
-                let color = skinStyle[item.css] ? skinStyle[item.css].color : '#e8e8e8'
-                let binding = ''
-                if (item.user_binding) {
-                  if (item.user_binding.indexOf('uname_pwd') > -1) {
-                    binding = '鐢ㄦ埛鍚�'
-                  }
-                  if (item.user_binding.indexOf('sms_vcode') > -1) {
-                    binding = binding ? binding + '锛屾墜鏈哄彿' : '鎵嬫満鍙�'
-                  }
-                }
-                return (
-                  <div className="sub-app" key={index} style={{borderColor: color}}>
-                    <Row>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">搴旂敤绫诲瀷:</div>
-                          <div className="content" style={{fontSize: '18px', fontWeight: 600}}>{item.typename}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">璇█:</div>
-                          <div className="content" style={{textDecoration: 'underline'}}>{item.lang === 'en-US' ? '鑻辨枃' : '涓枃'}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">鏉冮檺绠$悊:</div>
-                          <div className="content">{item.role_type === 'false' ? '涓嶅惎鐢�' : '鍚敤'}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">鐨偆:</div>
-                          <div className="content" style={{color: color}}>{css}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          {binding ? <div className="label">
-                            <Tooltip placement="topLeft" title="寰俊鍏紬鍙风櫥褰曟椂锛岀郴缁熺敤鎴蜂笌寰俊鐢ㄦ埛鐨勭粦瀹氭柟寮忋��">
-                              <QuestionCircleOutlined className="mk-form-tip" />
-                              鐢ㄦ埛缁戝畾:
-                            </Tooltip>
-                          </div> : null}
-                          <div className="content">{binding}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">鏍囬:</div>
-                          <div className="content">{item.title || '鏃�'}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">缃戠珯澶村儚:</div>
-                          <div className="content">{item.favicon ? <img style={{width: '18px', height: '18px'}} src={item.favicon} alt="" /> : '鏃�'}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">鐗堟潈:</div>
-                          <div className="content">{item.copyright || '鏃�'}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">LOGO:</div>
-                          <div className="content">{item.logo ? <img style={{height: '18px'}} src={item.logo} alt="" /> : '鏃�'}</div>
-                        </div>
-                      </Col>
-                    </Row>
-                    <div className="action">
-                      <Paragraph style={{display: 'inline-block', margin: 0}} copyable={{ text: `${window.GLOB.baseurl}${item.typename === 'pad' ? 'mob' : item.typename}/index.html#/index/${this.state.selectApp.kei_no}/${item.typename !== 'pc' ? item.typename + '/' : ''}${item.lang}` }}></Paragraph>
-                    </div>
-                  </div>
-                )
-              })}
+        <Header view="manage" />
+        {loading ?
+          <div className="loading-mask">
+            <Spin size="large" />
+          </div> : null
+        }
+        <div className="view-wrap">
+          <div className="left-view">
+            <div className="app-table">
+              <Table
+                rowKey="ID"
+                columns={columns}
+                dataSource={applist}
+                pagination={false}
+                rowSelection={{ type: 'radio', selectedRowKeys: selectApp ? [selectApp.ID] : [], onChange: this.onSelectChange }}
+                onRow={(record) => ({ onClick: () => this.setState({ selectApp: record })})}
+              />
             </div>
           </div>
-        </ConfigProvider>
+          <div className="right-view">
+            {selectApp ? <div className="app-title">{selectApp.remark}</div> : null}
+            {selectApp && selectApp.sublist.map((item, index) => {
+              let css = skinStyle[item.css] ? skinStyle[item.css].name : ''
+              let color = skinStyle[item.css] ? skinStyle[item.css].color : '#e8e8e8'
+              let binding = ''
+              if (item.user_binding) {
+                if (item.user_binding.indexOf('uname_pwd') > -1) {
+                  binding = '鐢ㄦ埛鍚�'
+                }
+                if (item.user_binding.indexOf('sms_vcode') > -1) {
+                  binding = binding ? binding + '锛屾墜鏈哄彿' : '鎵嬫満鍙�'
+                }
+              }
+              return (
+                <div className="sub-app" key={index} style={{borderColor: color}}>
+                  <Row>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">搴旂敤绫诲瀷:</div>
+                        <div className="content" style={{fontSize: '18px', fontWeight: 600}}>{item.typename}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">璇█:</div>
+                        <div className="content" style={{textDecoration: 'underline'}}>{langs[item.lang]}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">鏉冮檺绠$悊:</div>
+                        <div className="content">{item.role_type === 'false' ? '涓嶅惎鐢�' : '鍚敤'}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">鐨偆:</div>
+                        <div className="content" style={{color: color}}>{css}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        {binding ? <div className="label">
+                          <Tooltip placement="topLeft" title="寰俊鍏紬鍙风櫥褰曟椂锛岀郴缁熺敤鎴蜂笌寰俊鐢ㄦ埛鐨勭粦瀹氭柟寮忋��">
+                            <QuestionCircleOutlined className="mk-form-tip" />
+                            鐢ㄦ埛缁戝畾:
+                          </Tooltip>
+                        </div> : null}
+                        <div className="content">{binding}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">鏍囬:</div>
+                        <div className="content">{item.title || '鏃�'}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">缃戠珯澶村儚:</div>
+                        <div className="content">{item.favicon ? <img style={{width: '18px', height: '18px'}} src={item.favicon} alt="" /> : '鏃�'}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">鐗堟潈:</div>
+                        <div className="content">{item.copyright || '鏃�'}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">LOGO:</div>
+                        <div className="content">{item.logo ? <img style={{height: '18px'}} src={item.logo} alt="" /> : '鏃�'}</div>
+                      </div>
+                    </Col>
+                  </Row>
+                  <div className="action">
+                    <Paragraph style={{display: 'inline-block', margin: 0}} copyable={{ text: `${window.GLOB.baseurl}${item.typename === 'pad' ? 'mob' : item.typename}/index.html#/index/${this.state.selectApp.kei_no}/${item.typename !== 'pc' ? item.typename + '/' : ''}${item.lang}` }}></Paragraph>
+                  </div>
+                </div>
+              )
+            })}
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/views/appmanage/index.jsx b/src/views/appmanage/index.jsx
index c2d907c..21ccb4b 100644
--- a/src/views/appmanage/index.jsx
+++ b/src/views/appmanage/index.jsx
@@ -1,14 +1,13 @@
 import React, {Component} from 'react'
 import { fromJS } from 'immutable'
-import { Spin, notification, Input, Button, Table, Modal, ConfigProvider, Typography, Row, Col, Tooltip } from 'antd'
+import { Spin, notification, Input, Button, Table, Modal, Typography, Row, Col, Tooltip } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 import moment from 'moment'
 import md5 from 'md5'
-import enUS from 'antd/es/locale/en_US'
-import zhCN from 'antd/es/locale/zh_CN'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
+import { langs } from '@/store/options.js'
 import asyncComponent from '@/utils/asyncComponent'
 import './index.scss'
 
@@ -16,12 +15,12 @@
 const { Paragraph } = Typography
 const { Search } = Input
 
-const _locale = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
 const Header = asyncComponent(() => import('./header'))
 const MutilForm = asyncComponent(() => import('./mutilform'))
 const TransForm = asyncComponent(() => import('./transform'))
 const ScriptForm = asyncComponent(() => import('./scriptform'))
 const SubMutilForm = asyncComponent(() => import('./submutilform'))
+const TransMenu = asyncComponent(() => import('./transmenu'))
 
 const skinStyle = {
   bg_black_style_blue: {name: '钃濊壊', color: '#1890ff'},
@@ -517,8 +516,7 @@
         })
 
         if (!selectApp && applist[0]) {
-          let _href = window.location.href.split('#')[0] + 'app_record'
-          let record = localStorage.getItem(_href)
+          let record = localStorage.getItem(window.GLOB.sysSign + 'app_record')
           record = record ? JSON.parse(record) : null
 
           if (record && record.dates) {
@@ -537,7 +535,7 @@
             })
 
             if (reset) {
-              localStorage.setItem(_href, JSON.stringify(record))
+              localStorage.setItem(window.GLOB.sysSign + 'app_record', JSON.stringify(record))
             }
           }
         }
@@ -715,17 +713,16 @@
   jumpApp = (item) => {
     const { selectApp } = this.state
 
-    let _href = window.location.href.split('#')[0] + 'app_record'
-    let record = localStorage.getItem(_href)
+    let record = localStorage.getItem(window.GLOB.sysSign + 'app_record')
     record = record ? JSON.parse(record) : null
 
     if (!record || !record.dates) {
-      localStorage.setItem(_href, JSON.stringify({preId: selectApp.ID, activeId: selectApp.ID, dates: {[selectApp.ID]: new Date().getTime()}}))
+      localStorage.setItem(window.GLOB.sysSign + 'app_record', JSON.stringify({preId: selectApp.ID, activeId: selectApp.ID, dates: {[selectApp.ID]: new Date().getTime()}}))
     } else {
       if (record.preId === selectApp.ID || record.activeId === selectApp.ID) {
-        localStorage.setItem(_href, JSON.stringify({preId: selectApp.ID, activeId: selectApp.ID, dates: {...record.dates, [selectApp.ID]: new Date().getTime()}}))
+        localStorage.setItem(window.GLOB.sysSign + 'app_record', JSON.stringify({preId: selectApp.ID, activeId: selectApp.ID, dates: {...record.dates, [selectApp.ID]: new Date().getTime()}}))
       } else {
-        localStorage.setItem(_href, JSON.stringify({...record, preId: selectApp.ID}))
+        localStorage.setItem(window.GLOB.sysSign + 'app_record', JSON.stringify({...record, preId: selectApp.ID}))
       }
     }
 
@@ -733,7 +730,23 @@
     if (item.typename === 'pc') {
       route = 'pcdesign'
     }
-    let param = {...item, kei_no: selectApp.kei_no, remark: selectApp.remark, type: 'app'}
+
+    let applangList = []
+    if (item.lang === 'zh-CN') {
+      selectApp.sublist.forEach(cell => {
+        if (cell.typename === item.typename && cell.lang !== 'zh-CN') {
+          applangList.push(cell.lang)
+        }
+      })
+    }
+    if (applangList.length) {
+      applangList.unshift('zh-CN')
+      applangList = JSON.stringify(applangList)
+    } else {
+      applangList = ''
+    }
+
+    let param = {...item, kei_no: selectApp.kei_no, remark: selectApp.remark, applangList, type: 'app'}
 
     window.open(window.location.href.replace(/#.+/ig, `#/${route}/${window.btoa(window.encodeURIComponent(JSON.stringify(param)))}`))
   }
@@ -741,7 +754,22 @@
   jumpMenu = (item) => {
     const { selectApp } = this.state
 
-    window.open(window.location.href.replace(/#.+/ig, `#/role/${window.btoa(window.encodeURIComponent(JSON.stringify({...item, kei_no: selectApp.kei_no, remark: selectApp.remark, type: 'app'})))}`))
+    let applangList = []
+    if (item.lang === 'zh-CN') {
+      selectApp.sublist.forEach(cell => {
+        if (cell.typename === item.typename && cell.lang !== 'zh-CN') {
+          applangList.push(cell.lang)
+        }
+      })
+    }
+    if (applangList.length) {
+      applangList.unshift('zh-CN')
+      applangList = JSON.stringify(applangList)
+    } else {
+      applangList = ''
+    }
+
+    window.open(window.location.href.replace(/#.+/ig, `#/role/${window.btoa(window.encodeURIComponent(JSON.stringify({...item, kei_no: selectApp.kei_no, remark: selectApp.remark, applangList, type: 'app'})))}`))
   }
 
   onSelectChange = selectedRowKeys => {
@@ -876,10 +904,10 @@
         ID = selectApp.ID
       } else {
         let lowerKei = res.kei_no.toLowerCase()
-        if (lowerKei === 'mob') {
+        if (['mob', 'pad', 'pc', 'admin'].includes(lowerKei)) {
           notification.warning({
             top: 92,
-            message: '搴旂敤缂栫爜涓嶅厑璁镐娇鐢╩ob锛�',
+            message: '搴旂敤缂栫爜涓嶅厑璁镐娇鐢╩ob銆乸ad銆乸c銆乤dmin锛�',
             duration: 3
           })
           return
@@ -1055,221 +1083,220 @@
 
     return (
       <div className="mk-app-manage">
-        <ConfigProvider locale={_locale}>
-          <Header view="manage" />
-          {loading ?
-            <div className="loading-mask">
-              <Spin size="large" />
-            </div> : null
-          }
-          <div className="view-wrap">
-            <div className="left-view">
-              <div className="app-table">
-                <div className="app-action">
-                  <Button className="mk-green" onClick={() => this.setState({ visible: 'plus' })}>娣诲姞搴旂敤</Button>
-                </div>
-                <Table
-                  rowKey="ID"
-                  columns={columns}
-                  dataSource={applist}
-                  pagination={false}
-                  rowSelection={{ type: 'radio', selectedRowKeys: selectApp ? [selectApp.ID] : [], onChange: this.onSelectChange }}
-                  onRow={(record) => ({ onClick: () => this.setState({ selectApp: record })})}
-                />
+        <Header view="manage" />
+        {loading ?
+          <div className="loading-mask">
+            <Spin size="large" />
+          </div> : null
+        }
+        <div className="view-wrap">
+          <div className="left-view">
+            <div className="app-table">
+              <div className="app-action">
+                <Button className="mk-green" onClick={() => this.setState({ visible: 'plus' })}>娣诲姞搴旂敤</Button>
               </div>
-              <div className={'trans-table' + (this.state.transTotal <= 10 ? ' no-footer' : '')}>
-                <div className="app-action">
-                  <Button className="mk-green" onClick={() => this.setState({ transVisible: 'plus' })}>娣诲姞浼犺緭鍙�</Button>
-                  <Search placeholder="缁煎悎鎼滅储" onSearch={value => this.tranSearch(value)} enterButton />
-                </div>
-                <Table
-                  rowKey="ID"
-                  columns={transcolumns}
-                  dataSource={translist}
-                  pagination={{
-                    current: this.state.transIndex,
-                    pageSize: 10,
-                    total: this.state.transTotal || 0,
-                    showTotal: (total, range) => `${range[0]}-${range[1]} 鍏� ${total} 鏉
-                  }}
-                  rowSelection={{ type: 'radio', selectedRowKeys: selectTran ? [selectTran.ID] : [], onChange: this.onTransChange }}
-                  onRow={(record) => ({ onClick: () => {
-                    if (this.forbid) {
-                      this.forbid = false
-                      return
-                    }
-                    this.onTransSelect(record)
-                  }})}
-                  onChange={this.changeTable}
-                />
+              <Table
+                rowKey="ID"
+                columns={columns}
+                dataSource={applist}
+                pagination={false}
+                rowSelection={{ type: 'radio', selectedRowKeys: selectApp ? [selectApp.ID] : [], onChange: this.onSelectChange }}
+                onRow={(record) => ({ onClick: () => this.setState({ selectApp: record })})}
+              />
+            </div>
+            <div className={'trans-table' + (this.state.transTotal <= 10 ? ' no-footer' : '')}>
+              <div className="app-action">
+                <Button className="mk-green" onClick={() => this.setState({ transVisible: 'plus' })}>娣诲姞浼犺緭鍙�</Button>
+                <Search placeholder="缁煎悎鎼滅储" onSearch={value => this.tranSearch(value)} enterButton />
               </div>
-              {selectTran ? <div className="script-table">
-                <div className="app-action">
-                  <Button className="mk-green" onClick={() => this.setState({ scriptVisible: true })}>娣诲姞鑴氭湰</Button>
-                  <Button className="mk-danger" onClick={this.deleteScripts} style={{marginLeft: '15px'}}>鍒犻櫎</Button>
-                  <Search placeholder="缁煎悎鎼滅储" defaultValue={this.state.scriptSearchKey} onSearch={value => this.scriptSearch(value)} enterButton />
-                </div>
-                <Table
-                  rowKey="ID"
-                  columns={scriptcolumns}
-                  dataSource={scriptlist}
-                  pagination={{
-                    current: this.state.scriptIndex,
-                    pageSize: 10,
-                    total: this.state.scriptTotal || 0,
-                    showTotal: (total, range) => `${range[0]}-${range[1]} 鍏� ${total} 鏉
-                  }}
-                  rowSelection={{ type: 'checkbox', selectedRowKeys: selectScriptKeys, onChange: this.onScriptChange }}
-                  onRow={(record) => ({ onClick: () => this.onScriptSelect(record)})}
-                  onChange={this.changeScriptTable}
-                />
-              </div> : null}
+              <Table
+                rowKey="ID"
+                columns={transcolumns}
+                dataSource={translist}
+                pagination={{
+                  current: this.state.transIndex,
+                  pageSize: 10,
+                  total: this.state.transTotal || 0,
+                  showTotal: (total, range) => `${range[0]}-${range[1]} 鍏� ${total} 鏉
+                }}
+                rowSelection={{ type: 'radio', selectedRowKeys: selectTran ? [selectTran.ID] : [], onChange: this.onTransChange }}
+                onRow={(record) => ({ onClick: () => {
+                  if (this.forbid) {
+                    this.forbid = false
+                    return
+                  }
+                  this.onTransSelect(record)
+                }})}
+                onChange={this.changeTable}
+              />
             </div>
-            <div className="right-view">
-              {selectApp ? <div className="app-title">{selectApp.remark}</div> : null}
-              {selectApp && selectApp.sublist.map((item, index) => {
-                let css = skinStyle[item.css] ? skinStyle[item.css].name : ''
-                let color = skinStyle[item.css] ? skinStyle[item.css].color : '#e8e8e8'
-                let binding = ''
-                if (item.user_binding === 'true') {
-                  binding = '鐢ㄦ埛缁戝畾'
-                }
-                if (item.share === 'true') {
-                  binding = binding ? binding + '銆佸垎浜�' : '鍒嗕韩'
-                }
-
-                return (
-                  <div className="sub-app" key={index} style={{borderColor: color}}>
-                    <Row>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">搴旂敤绫诲瀷:</div>
-                          <div className="content" style={{fontSize: '18px', fontWeight: 600}}>{item.typename}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">璇█:</div>
-                          <div className="content" style={{textDecoration: 'underline'}}>{item.lang === 'en-US' ? '鑻辨枃' : '涓枃'}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">鏉冮檺绠$悊:</div>
-                          <div className="content">{item.role_type === 'false' ? '涓嶅惎鐢�' : '鍚敤'}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          {/* <div className="label">鐨偆:</div>
-                          <div className="content" style={{color: color}}>{css}</div> */}
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">鐨偆:</div>
-                          <div className="content" style={{color: color}}>{css}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          {/* {binding ? <div className="label">
-                            <Tooltip placement="topLeft" title="寰俊鍏紬鍙风櫥褰曟椂锛岀郴缁熺敤鎴蜂笌寰俊鐢ㄦ埛鐨勭粦瀹氭柟寮忋��">
-                              <QuestionCircleOutlined className="mk-form-tip" />
-                              鐢ㄦ埛缁戝畾:
-                            </Tooltip>
-                          </div> : null} */}
-                          {binding ? <div className="label">
-                            <Tooltip placement="topLeft" title="寰俊鍏紬鍙锋垨灏忕▼搴忎腑锛岀粦瀹氱郴缁熺敤鎴枫�佽嚜瀹氫箟鍒嗕韩绛夊姛鑳姐��">
-                              <QuestionCircleOutlined className="mk-form-tip" />
-                              鎵╁睍鍔熻兘:
-                            </Tooltip>
-                          </div> : null}
-                          <div className="content">{binding}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">鏍囬:</div>
-                          <div className="content">{item.title || '鏃�'}</div>
-                        </div>
-                      </Col>
-                      <Col span={12}>
-                        <div className="app-item">
-                          <div className="label">缃戠珯澶村儚:</div>
-                          <div className="content">{item.favicon ? <img style={{width: '18px', height: '18px', borderRadius: '4px'}} src={item.favicon} alt="" /> : '鏃�'}</div>
-                        </div>
-                      </Col>
-                    </Row>
-                    <div className="action">
-                      <Button type="link" onClick={() => this.jumpMenu(item)} style={{color: 'rgba(30, 228, 224, 1)'}}>鑿滃崟&鏉冮檺</Button>
-                      <Button type="link" onClick={() => this.setState({ selectSubApp: item, subVisible: 'edit' })} style={{color: '#8E44AD'}}>淇敼</Button>
-                      <Button type="link" onClick={() => this.deleteSubApp(item)} style={{color: '#ff4d4f'}}>鍒犻櫎</Button>
-                      <Button type="link" onClick={() => this.jumpApp(item)}>缂栬緫搴旂敤</Button>
-                      <Paragraph style={{display: 'inline-block', margin: 0}} copyable={{ text: `${window.GLOB.baseurl}${item.typename === 'pad' ? 'mob' : item.typename}/index.html#/index/${this.state.selectApp.kei_no}/${item.typename !== 'pc' ? item.typename + '/' : ''}${item.lang}` }}></Paragraph>
-                    </div>
-                  </div>
-                )
-              })}
-            </div>
+            {selectTran ? <div className="script-table">
+              <div className="app-action">
+                <Button className="mk-green" onClick={() => this.setState({ scriptVisible: true })}>娣诲姞鑴氭湰</Button>
+                <Button className="mk-danger" onClick={this.deleteScripts} style={{marginLeft: '15px'}}>鍒犻櫎</Button>
+                <Search placeholder="缁煎悎鎼滅储" defaultValue={this.state.scriptSearchKey} onSearch={value => this.scriptSearch(value)} enterButton />
+              </div>
+              <Table
+                rowKey="ID"
+                columns={scriptcolumns}
+                dataSource={scriptlist}
+                pagination={{
+                  current: this.state.scriptIndex,
+                  pageSize: 10,
+                  total: this.state.scriptTotal || 0,
+                  showTotal: (total, range) => `${range[0]}-${range[1]} 鍏� ${total} 鏉
+                }}
+                rowSelection={{ type: 'checkbox', selectedRowKeys: selectScriptKeys, onChange: this.onScriptChange }}
+                onRow={(record) => ({ onClick: () => this.onScriptSelect(record)})}
+                onChange={this.changeScriptTable}
+              />
+            </div> : null}
           </div>
-          <Modal
-            title={'缂栬緫搴旂敤'}
-            width={'600px'}
-            maskClosable={false}
-            visible={visible !== false}
-            onCancel={() => this.setState({visible: false, confirmloading: false})}
-            confirmLoading={this.state.confirmloading}
-            onOk={this.submitCard}
-            cancelText="鍙栨秷"
-            okText="纭畾"
-            destroyOnClose
-          >
-            <MutilForm type={visible} card={visible === 'edit' ? selectApp : ''} wrappedComponentRef={(inst) => this.mobcardRef = inst} inputSubmit={this.submitCard} />
-          </Modal>
-          <Modal
-            title={transVisible === 'plus' ? '娣诲姞浼犺緭鍙�' : '缂栬緫浼犺緭鍙�'}
-            width={'600px'}
-            maskClosable={false}
-            visible={transVisible !== false}
-            onCancel={() => this.setState({transVisible: false, confirmloading: false})}
-            confirmLoading={this.state.confirmloading}
-            onOk={this.submitTrans}
-            cancelText="鍙栨秷"
-            okText="纭畾"
-            destroyOnClose
-          >
-            <TransForm type={transVisible} card={transVisible === 'edit' ? this.state.editTran : ''} wrappedComponentRef={(inst) => this.transRef = inst} inputSubmit={this.submitTrans} />
-          </Modal>
-          <Modal
-            title={'娣诲姞鑴氭湰'}
-            width={900}
-            maskClosable={false}
-            visible={scriptVisible}
-            onCancel={() => this.setState({scriptVisible: false, confirmloading: false})}
-            confirmLoading={this.state.confirmloading}
-            onOk={this.submitScript}
-            cancelText="鍙栨秷"
-            okText="纭畾"
-            destroyOnClose
-          >
-            <ScriptForm applist={applist} wrappedComponentRef={(inst) => this.scriptRef = inst} inputSubmit={this.submitScript} />
-          </Modal>
-          <Modal
-            title={subVisible === 'plus' ? '娣诲姞瀛愬簲鐢�' : '缂栬緫瀛愬簲鐢�'}
-            width={'850px'}
-            maskClosable={false}
-            visible={subVisible !== false}
-            onCancel={() => this.setState({subVisible: false, confirmloading: false})}
-            confirmLoading={this.state.confirmloading}
-            onOk={this.submitSubCard}
-            cancelText="鍙栨秷"
-            okText="纭畾"
-            destroyOnClose
-          >
-            <SubMutilForm type={subVisible} card={subVisible === 'edit' ? selectSubApp : ''} wrappedComponentRef={(inst) => this.submobcardRef = inst} inputSubmit={this.submitSubCard} />
-          </Modal>
-        </ConfigProvider>
+          <div className="right-view">
+            {selectApp ? <div className="app-title">{selectApp.remark}</div> : null}
+            {selectApp && selectApp.sublist.map((item, index) => {
+              let css = skinStyle[item.css] ? skinStyle[item.css].name : ''
+              let color = skinStyle[item.css] ? skinStyle[item.css].color : '#e8e8e8'
+              let binding = ''
+              if (item.user_binding === 'true') {
+                binding = '鐢ㄦ埛缁戝畾'
+              }
+              if (item.share === 'true') {
+                binding = binding ? binding + '銆佸垎浜�' : '鍒嗕韩'
+              }
+
+              return (
+                <div className="sub-app" key={index} style={{borderColor: color}}>
+                  <Row>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">搴旂敤绫诲瀷:</div>
+                        <div className="content" style={{fontSize: '18px', fontWeight: 600}}>{item.typename}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">璇█:</div>
+                        <div className="content" style={{textDecoration: 'underline'}}>{langs[item.lang]}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">鏉冮檺绠$悊:</div>
+                        <div className="content">{item.role_type === 'false' ? '涓嶅惎鐢�' : '鍚敤'}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        {/* <div className="label">鐨偆:</div>
+                        <div className="content" style={{color: color}}>{css}</div> */}
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">鐨偆:</div>
+                        <div className="content" style={{color: color}}>{css}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        {/* {binding ? <div className="label">
+                          <Tooltip placement="topLeft" title="寰俊鍏紬鍙风櫥褰曟椂锛岀郴缁熺敤鎴蜂笌寰俊鐢ㄦ埛鐨勭粦瀹氭柟寮忋��">
+                            <QuestionCircleOutlined className="mk-form-tip" />
+                            鐢ㄦ埛缁戝畾:
+                          </Tooltip>
+                        </div> : null} */}
+                        {binding ? <div className="label">
+                          <Tooltip placement="topLeft" title="寰俊鍏紬鍙锋垨灏忕▼搴忎腑锛岀粦瀹氱郴缁熺敤鎴枫�佽嚜瀹氫箟鍒嗕韩绛夊姛鑳姐��">
+                            <QuestionCircleOutlined className="mk-form-tip" />
+                            鎵╁睍鍔熻兘:
+                          </Tooltip>
+                        </div> : null}
+                        <div className="content">{binding}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">鏍囬:</div>
+                        <div className="content">{item.title || '鏃�'}</div>
+                      </div>
+                    </Col>
+                    <Col span={12}>
+                      <div className="app-item">
+                        <div className="label">缃戠珯澶村儚:</div>
+                        <div className="content">{item.favicon ? <img style={{width: '18px', height: '18px', borderRadius: '4px'}} src={item.favicon} alt="" /> : '鏃�'}</div>
+                      </div>
+                    </Col>
+                  </Row>
+                  <div className="action">
+                    {item.lang !== 'zh-CN' ? <TransMenu app={item} supApp={selectApp} /> : null}
+                    <Button type="link" onClick={() => this.jumpMenu(item)} style={{color: 'rgba(30, 228, 224, 1)'}}>鑿滃崟&鏉冮檺</Button>
+                    <Button type="link" onClick={() => this.setState({ selectSubApp: item, subVisible: 'edit' })} style={{color: '#8E44AD'}}>淇敼</Button>
+                    <Button type="link" onClick={() => this.deleteSubApp(item)} style={{color: '#ff4d4f'}}>鍒犻櫎</Button>
+                    <Button type="link" onClick={() => this.jumpApp(item)}>缂栬緫搴旂敤</Button>
+                    <Paragraph style={{display: 'inline-block', margin: 0}} copyable={{ text: `${window.GLOB.baseurl}${item.typename === 'pad' ? 'mob' : item.typename}/index.html#/index/${this.state.selectApp.kei_no}/${item.typename !== 'pc' ? item.typename + '/' : ''}${item.lang}` }}></Paragraph>
+                  </div>
+                </div>
+              )
+            })}
+          </div>
+        </div>
+        <Modal
+          title={'缂栬緫搴旂敤'}
+          width={'600px'}
+          maskClosable={false}
+          visible={visible !== false}
+          onCancel={() => this.setState({visible: false, confirmloading: false})}
+          confirmLoading={this.state.confirmloading}
+          onOk={this.submitCard}
+          cancelText="鍙栨秷"
+          okText="纭畾"
+          destroyOnClose
+        >
+          <MutilForm type={visible} card={visible === 'edit' ? selectApp : ''} wrappedComponentRef={(inst) => this.mobcardRef = inst} inputSubmit={this.submitCard} />
+        </Modal>
+        <Modal
+          title={transVisible === 'plus' ? '娣诲姞浼犺緭鍙�' : '缂栬緫浼犺緭鍙�'}
+          width={'600px'}
+          maskClosable={false}
+          visible={transVisible !== false}
+          onCancel={() => this.setState({transVisible: false, confirmloading: false})}
+          confirmLoading={this.state.confirmloading}
+          onOk={this.submitTrans}
+          cancelText="鍙栨秷"
+          okText="纭畾"
+          destroyOnClose
+        >
+          <TransForm type={transVisible} card={transVisible === 'edit' ? this.state.editTran : ''} wrappedComponentRef={(inst) => this.transRef = inst} inputSubmit={this.submitTrans} />
+        </Modal>
+        <Modal
+          title={'娣诲姞鑴氭湰'}
+          width={900}
+          maskClosable={false}
+          visible={scriptVisible}
+          onCancel={() => this.setState({scriptVisible: false, confirmloading: false})}
+          confirmLoading={this.state.confirmloading}
+          onOk={this.submitScript}
+          cancelText="鍙栨秷"
+          okText="纭畾"
+          destroyOnClose
+        >
+          <ScriptForm applist={applist} wrappedComponentRef={(inst) => this.scriptRef = inst} inputSubmit={this.submitScript} />
+        </Modal>
+        <Modal
+          title={subVisible === 'plus' ? '娣诲姞瀛愬簲鐢�' : '缂栬緫瀛愬簲鐢�'}
+          width={'850px'}
+          maskClosable={false}
+          visible={subVisible !== false}
+          onCancel={() => this.setState({subVisible: false, confirmloading: false})}
+          confirmLoading={this.state.confirmloading}
+          onOk={this.submitSubCard}
+          cancelText="鍙栨秷"
+          okText="纭畾"
+          destroyOnClose
+        >
+          <SubMutilForm type={subVisible} card={subVisible === 'edit' ? selectSubApp : ''} wrappedComponentRef={(inst) => this.submobcardRef = inst} inputSubmit={this.submitSubCard} />
+        </Modal>
       </div>
     )
   }
diff --git a/src/views/appmanage/index.scss b/src/views/appmanage/index.scss
index 65395e4..474ecaa 100644
--- a/src/views/appmanage/index.scss
+++ b/src/views/appmanage/index.scss
@@ -101,6 +101,14 @@
           .ant-typography-copy {
             color: #26C281;
           }
+          .ant-btn {
+            padding: 0 5px;
+            margin: 0 10px;
+          }
+          .anticon-swap {
+            color: #1890ff;
+            padding: 5px 10px;
+          }
         }
       }
     }
diff --git a/src/views/appmanage/submutilform/index.jsx b/src/views/appmanage/submutilform/index.jsx
index 20d6daf..de2a0a2 100644
--- a/src/views/appmanage/submutilform/index.jsx
+++ b/src/views/appmanage/submutilform/index.jsx
@@ -3,6 +3,7 @@
 import { Form, Row, Col, Select, Radio, Input, Tooltip, InputNumber, Checkbox } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 
+import { langs } from '@/store/options.js'
 import asyncComponent from '@/utils/asyncComponent'
 import './index.scss'
 
@@ -16,13 +17,21 @@
     inputSubmit: PropTypes.func  // input鍥炶溅鎻愪氦
   }
 
-  state = {typename: 'mob', adapters: [], exts: []}
+  state = {
+    typename: 'mob',
+    adapters: [],
+    exts: []
+  }
 
   UNSAFE_componentWillMount() {
     const { card } = this.props
     let adapters = []
     let exts = []
     let typename = 'mob'
+    let _langs = []
+    Object.keys(langs).forEach(key => {
+      _langs.push({value: key, label: langs[key]})
+    })
 
     if (card) {
       typename = card.typename || 'mob'
@@ -38,7 +47,7 @@
       }
     }
 
-    this.setState({typename, adapters, exts})
+    this.setState({typename, adapters, exts, langs: _langs})
   }
 
   /**
@@ -80,7 +89,7 @@
   render() {
     const { card, type } = this.props
     const { getFieldDecorator } = this.props.form
-    const { typename, adapters, exts } = this.state
+    const { typename, adapters, exts, langs } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -113,10 +122,9 @@
               {getFieldDecorator('lang', {
                 initialValue: card ? card.lang || 'zh-CN' : 'zh-CN'
               })(
-                <Radio.Group disabled={type === 'edit'}>
-                  <Radio value="zh-CN">涓枃</Radio>
-                  <Radio value="en-US">鑻辨枃</Radio>
-                </Radio.Group>
+                <Select disabled={type === 'edit'}>
+                  {langs.map(item => <Select.Option key={item.value} value={item.value}>{item.label}</Select.Option>)}
+                </Select>
               )}
             </Form.Item>
           </Col>
diff --git a/src/views/appmanage/transmenu/index.jsx b/src/views/appmanage/transmenu/index.jsx
new file mode 100644
index 0000000..101ddeb
--- /dev/null
+++ b/src/views/appmanage/transmenu/index.jsx
@@ -0,0 +1,519 @@
+import React, { Component } from 'react'
+import { is, fromJS } from 'immutable'
+import { Modal, notification, Spin, Select } from 'antd'
+import { SwapOutlined } from '@ant-design/icons'
+import moment from 'moment'
+import md5 from 'md5'
+
+import Api from '@/api'
+import Utils from '@/utils/utils.js'
+import MenuUtils, { setLangTrans } from '@/utils/utils-custom.js'
+import './index.scss'
+
+const { confirm } = Modal
+
+class TransMenu extends Component {
+  state = {
+    visible: false,
+    loading: false,
+    saveing: false,
+    dicts: [],
+    menus: [],
+    values: '',
+    kei_no: '',
+    zhApp: null
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  trigger = () => {
+    const { supApp, app } = this.props
+
+    let zhApp = supApp.sublist.filter(item => item.typename === app.typename && item.lang === 'zh-CN')[0]
+
+    this.setState({
+      loading: true,
+      visible: true,
+      saveing: false,
+      values: '',
+      kei_no: supApp.kei_no,
+      zhApp
+    })
+    
+    this.getDicts()
+    this.getMenus(zhApp, supApp.kei_no)
+  }
+  
+  getDicts = () => {
+    // let sql = `select id,lang,lang_name,mother_tongue,translation,use_type,case when use_type='menu' then '鑿滃崟' when  use_type='button' then '鎸夐挳'  when  use_type='title' then '鏍囬'   when  use_type='list' then '閫夐」' else '鏂囨湰' end as use_type_text from s_app_lang_translation where appkey=@appkey@ and deleted=0 and translation != ''`
+    let sql = `select mother_tongue as reg,translation as value,use_type as type,case when use_type='menu' then '鑿滃崟' when  use_type='button' then '鎸夐挳'  when  use_type='title' then '鏍囬'   when  use_type='list' then '閫夐」' else '鏂囨湰' end as use_type_text from s_app_lang_translation where appkey=@appkey@ and deleted=0 and translation != '' and lang='${sessionStorage.getItem('lang') || ''}'`
+
+    let param = {
+      func: 'sPC_Get_SelectedList',
+      LText: Utils.formatOptions(sql, 'x'),
+      obj_name: 'data',
+      arr_field: 'reg,value,type',
+      exec_type: 'x'
+    }
+
+    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    param.secretkey = Utils.encrypt('', param.timestamp)
+    param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
+
+    Api.getCloudConfig(param).then(result => {
+      if (!result.status) {
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+        return
+      }
+
+      this.setState({dicts: result.data || []})
+    })
+  }
+
+  getMenus = (zhApp, kei_no) => {
+    if (this.state.menus.length > 0) {
+      this.setState({loading: false})
+      return
+    }
+
+    let param = {
+      func: 's_get_app_menus',
+      TypeCharOne: kei_no,
+      typename: zhApp.typename,
+      LText: `select '${window.GLOB.appkey}'`,
+      timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
+      lang: 'zh-CN'
+    }
+
+    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+
+    Api.getCloudConfig(param).then(result => {
+      if (result.status) {
+        let menus = []
+        result.menus.forEach(item => {
+          if (zhApp.userbind === item.MenuID || zhApp.instantMessage === item.MenuID) return
+          
+          menus.push(item)
+        })
+
+        this.setState({menus: menus, loading: false})
+      } else {
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  submit = () => {
+    const { values } = this.state
+
+    if (!values) {
+      notification.warning({
+        top: 92,
+        message: '璇烽�夋嫨鑿滃崟锛�',
+        duration: 5
+      })
+      return
+    }
+
+    this.setState({saveing: true})
+
+    this.transThdMenu()
+  }
+
+  transThdMenu = () => {
+    const { app } = this.props
+    const { zhApp, dicts, values, kei_no } = this.state
+
+    let _param = {
+      func: 'sPC_Get_LongParam',
+      TypeCharOne: kei_no,
+      typename: zhApp.typename,
+      MenuID: values,
+      lang: 'zh-CN'
+    }
+
+    Api.getCloudConfig(_param).then(res => {
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+        this.setState({saveing: false})
+        return
+      }
+
+      let config = null
+      if (res.LongParam) {
+        try {
+          config = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
+        } catch (e) {
+          console.warn('Parse Failure')
+          config = ''
+        }
+      }
+
+      if (!config) {
+        notification.warning({
+          top: 92,
+          message: '鏈幏鍙栧埌鑿滃崟閰嶇疆淇℃伅',
+          duration: 5
+        })
+        this.setState({saveing: false})
+      }
+
+      let btnDict = {}
+      let titDict = {}
+      let lisDict = {}
+      let menuDict = {}
+      let regs = []
+
+      dicts.forEach(item => {
+        if (item.type === 'button') {
+          btnDict[item.reg] = item.value
+        } else if (item.type === 'title') {
+          titDict[item.reg] = item.value
+        } else if (item.type === 'list') {
+          lisDict[item.reg] = item.value
+        } else if (item.type === 'text') {
+          regs.push({reg: new RegExp(item.reg, 'g'), value: item.value, sort: item.reg.length})
+        } else if (item.type === 'menu') {
+          menuDict[item.reg] = item.value
+        }
+      })
+
+      regs.sort((a, b) => b.sort - a.sort)
+
+      let tail = md5(window.GLOB.appkey + kei_no + zhApp.typename + app.lang).toLowerCase()
+
+      tail = tail.slice(-8)
+
+      let menus_rolelist = ''
+      if (config.type === 'navbar') {
+        config.menus.forEach(item => {
+          if (item.linkMenuId) {
+            item.linkMenuId = item.linkMenuId.slice(0, 24) + tail
+          } else {
+            item.MenuID = item.MenuID.slice(0, 24) + tail
+          }
+          if (item.name && menuDict[item.name]) {
+            item.name = menuDict[item.name]
+          }
+          if (item.sublist) {
+            item.sublist.forEach(sec => {
+              if (sec.linkMenuId) {
+                sec.linkMenuId = sec.linkMenuId.slice(0, 24) + tail
+              } else {
+                sec.MenuID = sec.MenuID.slice(0, 24) + tail
+              }
+              if (sec.name && menuDict[sec.name]) {
+                sec.name = menuDict[sec.name]
+              }
+              if (sec.sublist) {
+                sec.sublist.forEach(thd => {
+                  if (thd.linkMenuId) {
+                    thd.linkMenuId = thd.linkMenuId.slice(0, 24) + tail
+                  } else {
+                    thd.MenuID = thd.MenuID.slice(0, 24) + tail
+                  }
+                  if (thd.name && menuDict[thd.name]) {
+                    thd.name = menuDict[thd.name]
+                  }
+                })
+              }
+            })
+          }
+        })
+        if (config.columns) {
+          config.columns.forEach(cell => {
+            if (cell.label && titDict[cell.label]) {
+              cell.label = titDict[cell.label]
+            }
+          })
+        }
+
+        config.MenuNo = 'navbar_' + app.lang
+        if (config.name === menuDict[config.name]) {
+          config.name = menuDict[config.name]
+        } else {
+          config.name = config.name + '_' + app.lang
+        }
+
+        menus_rolelist = {
+          type: 'navbar',
+          version: '1.0',
+          key: config.uuid,
+          title: config.name,
+          children: []
+        }
+
+        if (config.wrap.permission === 'true') {
+          menus_rolelist.children = config.menus.map(fst => {
+            if (fst.property === 'classify' && fst.sublist.length > 0) {
+              return {
+                key: fst.MenuID,
+                title: fst.name,
+                children: fst.sublist.map(scd => {
+                  if (scd.property === 'classify' && scd.sublist.length > 0) {
+                    return {
+                      key: scd.MenuID,
+                      title: scd.name,
+                      children: scd.sublist.map(thd => {
+                        return { key: thd.MenuID, title: thd.name }
+                      })
+                    }
+                  } else {
+                    return { key: scd.MenuID, title: scd.name }
+                  }
+                })
+              }
+            } else {
+              return { key: fst.MenuID, title: fst.name }
+            }
+          })
+        } else {
+          menus_rolelist.pass = true
+        }
+        menus_rolelist = window.btoa(window.encodeURIComponent(JSON.stringify(menus_rolelist)))
+      } else {
+        setLangTrans(config, btnDict, titDict, lisDict, menuDict, regs, tail)
+  
+        if (config.components) {
+          let commonId = Utils.getuuid()
+          if (config.interfaces && config.interfaces.length > 0) {
+            config.interfaces = config.interfaces.map(inter => {
+              inter.uuid = md5(commonId + inter.uuid)
+              return inter
+            })
+          }
+          config.components = MenuUtils.resetConfig(config.components, commonId, false)
+          config.tables = config.tables || []
+          config.style = config.style || {}
+        }
+  
+        config.enabled = false
+        config.Template = 'webPage'
+        if (config.MenuNo) {
+          config.MenuNo = config.MenuNo + '_' + app.lang
+        }
+        if (config.MenuName === menuDict[config.MenuName]) {
+          config.MenuName = menuDict[config.MenuName]
+        } else {
+          config.MenuName = config.MenuName + '_' + app.lang
+        }
+      }
+
+      config.uuid = values.slice(0, 24) + tail
+      config.MenuID = config.uuid
+      config.open_edition = ''
+      
+      let param = {
+        func: 'sPC_TrdMenu_AddUpt',
+        FstID: 'mk_app',
+        SndID: 'mk_app',
+        ParentID: 'mk_app',
+        MenuID: config.uuid,
+        MenuNo: config.MenuNo,
+        EasyCode: '',
+        TypeCharOne: kei_no,
+        Typename: app.typename,
+        Template: config.Template || config.type,
+        MenuName: config.MenuName || config.name || '',
+        PageParam: JSON.stringify({Template: config.Template || config.type}),
+        lang: app.lang
+      }
+
+      if (menus_rolelist) {
+        param.menus_rolelist = menus_rolelist
+      }
+
+      Api.getCloudConfig({
+        func: 'sPC_Get_LongParam',
+        TypeCharOne: kei_no,
+        typename: app.typename,
+        MenuID: config.MenuID,
+        lang: app.lang
+      }).then(res => {
+        if (!res.status) {
+          notification.warning({
+            top: 92,
+            message: res.message,
+            duration: 5
+          })
+          this.setState({saveing: false})
+          return
+        }
+
+        config.open_edition = res.open_edition || ''
+        param.open_edition = config.open_edition
+        param.LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(config)))
+
+        if (res.LongParam) {
+          const that = this
+          confirm({
+            title: '鑿滃崟宸插瓨鍦紝纭畾閲嶆柊鐢熸垚鍚�?',
+            content: '',
+            onOk() {
+              that.setMenu(param, config)
+            },
+            onCancel() {}
+          })
+        } else {
+          this.setMenu(param, config)
+        }
+      })
+    })
+  }
+
+  setMenu = (param, config) => {
+    const { app } = this.props
+    const { kei_no } = this.state
+
+    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    param.secretkey = Utils.encrypt('', param.timestamp)
+
+    Api.getCloudConfig(param).then(res => {
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+        this.setState({saveing: false})
+        return
+      }
+
+      if (config.type === 'navbar') {
+        Api.getCloudConfig({
+          func: 's_get_keyids',
+          bid: app.ID
+        }).then(res => {
+          if (!res.status) {
+            notification.warning({
+              top: 92,
+              message: res.message,
+              duration: 5
+            })
+            this.setState({saveing: false})
+            return
+          }
+  
+          let appViewList = res.data || []
+          appViewList = appViewList.filter(item => item.keys_id !== config.uuid)
+          appViewList.unshift({
+            appkey: window.GLOB.appkey || '',
+            bid: app.ID,
+            kei_no: kei_no || '',
+            keys_id: config.uuid,
+            keys_type: 'navbar',
+            remark: config.name
+          })
+  
+          let param = {
+            func: 's_kei_link_keyids_addupt',
+            BID: app.ID,
+            exec_type: 'x',
+            LText: ''
+          }
+  
+          param.LText = appViewList.map(item => `select '${item.keys_id}','${item.keys_type}','${item.kei_no}','${item.appkey}','${item.bid}','${sessionStorage.getItem('CloudUserID')}','${item.remark}'`)
+          param.LText = param.LText.join(' union all ')
+          param.LText = Utils.formatOptions(param.LText, 'x')
+    
+          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+          param.secretkey = Utils.encrypt('', param.timestamp)
+  
+          Api.getCloudConfig(param).then(result => {
+            if (!result.status) {
+              notification.warning({
+                top: 92,
+                message: result.message,
+                duration: 5
+              })
+              this.setState({saveing: false})
+              return
+            }
+  
+            notification.success({
+              top: 92,
+              message: '娣诲姞鎴愬姛銆�',
+              duration: 5
+            })
+            
+            this.setState({
+              loading: false,
+              visible: false
+            })
+          })
+        })
+      } else {
+        notification.success({
+          top: 92,
+          message: '娣诲姞鎴愬姛銆�',
+          duration: 5
+        })
+        
+        this.setState({
+          loading: false,
+          visible: false
+        })
+      }
+    })
+  }
+
+  cancel = () => {
+    this.setState({
+      loading: false,
+      visible: false
+    })
+  }
+
+  render () {
+    const { supApp, app } = this.props
+    const { visible, loading, saveing, menus } = this.state
+
+    if (supApp.sublist.findIndex(item => item.typename === app.typename && item.lang === 'zh-CN') === -1) return null
+
+    return (
+      <>
+        <SwapOutlined onClick={this.trigger}/>
+        <Modal
+          wrapClassName="sync-menu-modal"
+          title="鑿滃崟杞崲"
+          visible={visible}
+          width={600}
+          closable={false}
+          maskClosable={false}
+          onOk={this.submit}
+          onCancel={this.cancel}
+          confirmLoading={saveing}
+          destroyOnClose
+        >
+          {loading ? <Spin /> : <div>
+            <Select
+              showSearch
+              placeholder="璇烽�夋嫨鑿滃崟"
+              dropdownMatchSelectWidth={false}
+              onChange={(val) => this.setState({values: val})}
+              filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
+            >
+              {menus.map((item, i) => (<Select.Option key={i} value={item.MenuID}>{`${item.MenuName}锛�${item.MenuNo}锛塦}</Select.Option>))}
+            </Select>
+          </div>}
+        </Modal>
+      </>
+    )
+  }
+}
+
+export default TransMenu
\ No newline at end of file
diff --git a/src/views/appmanage/transmenu/index.scss b/src/views/appmanage/transmenu/index.scss
new file mode 100644
index 0000000..73c8958
--- /dev/null
+++ b/src/views/appmanage/transmenu/index.scss
@@ -0,0 +1,16 @@
+.sync-menu-modal {
+  .ant-modal-body {
+    position: relative;
+    padding: 24px 50px;
+    min-height: 250px;
+    max-height: calc(100vh - 210px);
+    .ant-select {
+      width: 300px;
+    }
+    .ant-spin {
+      position: absolute;
+      left: calc(50% - 10px);
+      top: 75px;
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/views/basedesign/index.jsx b/src/views/basedesign/index.jsx
index da66e53..5e9d0f5 100644
--- a/src/views/basedesign/index.jsx
+++ b/src/views/basedesign/index.jsx
@@ -1,7 +1,5 @@
 import React, {Component} from 'react'
-import { notification, Spin, ConfigProvider } from 'antd'
-import enUS from 'antd/es/locale/en_US'
-import zhCN from 'antd/es/locale/zh_CN'
+import { notification, Spin } from 'antd'
 
 import Api from '@/api'
 import asyncComponent from '@/utils/asyncComponent'
@@ -10,7 +8,6 @@
 import '@/assets/css/design.scss'
 import './index.scss'
 
-const _locale = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
 const Header = asyncComponent(() => import('@/menu/header'))
 const ComTableConfig = asyncLoadComponent(() => import('@/templates/comtableconfig'))
 const TreePageConfig = asyncLoadComponent(() => import('@/templates/treepageconfig'))
@@ -189,58 +186,56 @@
 
     return (
       <div className="mk-base-design-wrap">
-        <ConfigProvider locale={_locale}>
-          <Header/>
-          {this.state.tabview === 'CommonTable' ?
-            <ComTableConfig
-              menu={editMenu}
-              reloadmenu={() => {localStorage.setItem('menuUpdate', new Date().getTime())}}
-              handleView={this.handleView}
-            /> : null
-          }
-          {this.state.tabview === 'SubTable' ?
-            <SubTable
-              menu={editMenu}
-              editTab={this.state.editTab}
-              editSubTab={this.state.editSubTab}
-              tabConfig={this.state.tabConfig}
-              btnTab={btnTab}
-              btnTabConfig={this.state.btnTabConfig}
-              config={subConfig}
-              handleView={this.handleView}
-            /> : null
-          }
-          {this.state.tabview === 'Modal' ?
-            <ModalConfig
-              menu={editMenu}
-              editTab={this.state.editTab}
-              tabConfig={this.state.tabConfig}
-              editSubTab={this.state.editSubTab}
-              subTabConfig={this.state.subTabConfig}
-              btnTab={btnTab}
-              btnTabConfig={this.state.btnTabConfig}
-              editAction={this.state.editAction}
-              subConfig={subConfig}
-              handleView={this.handleView}
-            /> : null
-          }
-          {this.state.tabview === 'TreePage' ?
-            <TreePageConfig
-              menu={editMenu}
-              reloadmenu={() => {localStorage.setItem('menuUpdate', new Date().getTime())}}
-              handleView={this.handleView}
-            /> : null
-          }
-          {this.state.tabview === 'FormTab' ?
-            <UpdateFormTab
-              menu={editMenu}
-              btnTab={btnTab}
-              config={subConfig}
-              handleView={this.handleView}
-            /> : null
-          }
-          {loading ? <Spin className="loading-view" size="large"/> : null}
-        </ConfigProvider>
+        <Header/>
+        {this.state.tabview === 'CommonTable' ?
+          <ComTableConfig
+            menu={editMenu}
+            reloadmenu={() => {localStorage.setItem('menuUpdate', new Date().getTime())}}
+            handleView={this.handleView}
+          /> : null
+        }
+        {this.state.tabview === 'SubTable' ?
+          <SubTable
+            menu={editMenu}
+            editTab={this.state.editTab}
+            editSubTab={this.state.editSubTab}
+            tabConfig={this.state.tabConfig}
+            btnTab={btnTab}
+            btnTabConfig={this.state.btnTabConfig}
+            config={subConfig}
+            handleView={this.handleView}
+          /> : null
+        }
+        {this.state.tabview === 'Modal' ?
+          <ModalConfig
+            menu={editMenu}
+            editTab={this.state.editTab}
+            tabConfig={this.state.tabConfig}
+            editSubTab={this.state.editSubTab}
+            subTabConfig={this.state.subTabConfig}
+            btnTab={btnTab}
+            btnTabConfig={this.state.btnTabConfig}
+            editAction={this.state.editAction}
+            subConfig={subConfig}
+            handleView={this.handleView}
+          /> : null
+        }
+        {this.state.tabview === 'TreePage' ?
+          <TreePageConfig
+            menu={editMenu}
+            reloadmenu={() => {localStorage.setItem('menuUpdate', new Date().getTime())}}
+            handleView={this.handleView}
+          /> : null
+        }
+        {this.state.tabview === 'FormTab' ?
+          <UpdateFormTab
+            menu={editMenu}
+            btnTab={btnTab}
+            config={subConfig}
+            handleView={this.handleView}
+          /> : null
+        }
+        {loading ? <Spin className="loading-view" size="large"/> : null}
       </div>
     )
   }
diff --git a/src/views/billprint/index.jsx b/src/views/billprint/index.jsx
index 416c51d..9346380 100644
--- a/src/views/billprint/index.jsx
+++ b/src/views/billprint/index.jsx
@@ -813,6 +813,7 @@
       { reg: /@SessionUid@/ig, value: `'${localStorage.getItem('SessionUid') || ''}'`},
       { reg: /@UserID@/ig, value: `'${sessionStorage.getItem('UserID') || ''}'`},
       { reg: /@Appkey@/ig, value: `'${window.GLOB.appkey || ''}'`},
+      { reg: /@lang@/ig, value: `'${sessionStorage.getItem('lang')}'`},
       { reg: /@typename@/ig, value: `'admin'`},
     ]
 
diff --git a/src/views/design/header/index.jsx b/src/views/design/header/index.jsx
index 70fd769..f41e3ec 100644
--- a/src/views/design/header/index.jsx
+++ b/src/views/design/header/index.jsx
@@ -16,6 +16,8 @@
 const VersionsUp = asyncComponent(() => import('./versions'))
 const ThawMenu = asyncComponent(() => import('@/components/thawmenu'))
 const MenuForm = asyncComponent(() => import('./editfirstmenu/menuform'))
+const TransMenu = asyncComponent(() => import('./transmenu'))
+
 const { confirm } = Modal
 
 class Header extends Component {
@@ -24,6 +26,7 @@
     userName: sessionStorage.getItem('CloudUserName'),
     avatar: Utils.getrealurl(sessionStorage.getItem('CloudAvatar')),
     logo: sessionStorage.getItem('CloudLogo') || MainLogo,
+    subLang: sessionStorage.getItem('subLangList') !== null,
     visible: false,
     loading: false
   }
@@ -37,6 +40,7 @@
       onOk() {
         sessionStorage.clear()
         _this.props.history.replace('/login')
+        window.location.reload()
       },
       onCancel() {}
     })
@@ -409,7 +413,7 @@
 
   render () {
     const { mainMenu, editLevel } = this.props
-    const { menulist, visible, loading, logo } = this.state
+    const { menulist, visible, loading, logo, subLang } = this.state
 
     return (
       <header className={'sys-header-container ant-menu-dark ' + (['level2', 'level3'].includes(editLevel) ? 'mask' : '')} id="main-header-container">
@@ -493,6 +497,12 @@
               缂栬緫
             </Button>
           </div> : null}
+          {window.GLOB.systemType !== 'production' && subLang ? <div className="entrance">
+            <div className="icon"><PlusOutlined /></div>
+            <div className="title">鑿滃崟杞崲</div>
+            <div className="detail">鍙�夋嫨姣嶈绯荤粺鐨勮彍鍗曪紝蹇�熻浆鎹㈠埌褰撳墠璇█銆傛墦鍗版ā鏉胯鍦℉S涓嬪鍒跺悗锛屽湪姝ゅ閫夋嫨鎸囧畾妯℃澘杩涜璇█杞崲銆�</div>
+            <TransMenu reload={this.reload} menulist={menulist}/>
+          </div> : null}
         </div>
         {/* 缂栬緫鑿滃崟 */}
         {editLevel === 'level1' ? <EditMenu menulist={this.state.menulist} reload={this.reload} exitEdit={this.exitEdit}/> : null}
diff --git a/src/views/design/header/transmenu/index.jsx b/src/views/design/header/transmenu/index.jsx
new file mode 100644
index 0000000..4a278f6
--- /dev/null
+++ b/src/views/design/header/transmenu/index.jsx
@@ -0,0 +1,885 @@
+import React, { Component } from 'react'
+import { is, fromJS } from 'immutable'
+import { Modal, Radio, notification, Button, Spin, Select, Cascader } from 'antd'
+import moment from 'moment'
+import md5 from 'md5'
+
+import Api from '@/api'
+import Utils from '@/utils/utils.js'
+import MenuUtils, { setLangTrans } from '@/utils/utils-custom.js'
+import './index.scss'
+
+const { confirm } = Modal
+
+class TransMenu extends Component {
+  state = {
+    visible: false,
+    loading: false,
+    saveing: false,
+    lang: '',
+    type: '',
+    dicts: [],
+    menus: [],
+    billMenus: [],
+    tabMenus: [],
+    values: '',
+    images: '',
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  trigger = () => {
+    let langs = sessionStorage.getItem('subLangList')
+    langs = JSON.parse(langs)
+
+    this.setState({
+      lang: langs[0],
+      loading: true,
+      visible: true,
+      saveing: false,
+      type: 'menu',
+      images: '',
+      values: ''
+    })
+    
+    this.getDicts()
+    this.getMenus(langs[0])
+  }
+  
+  getDicts = () => {
+    // let sql = `select id,lang,lang_name,mother_tongue,translation,use_type,case when use_type='menu' then '鑿滃崟' when  use_type='button' then '鎸夐挳'  when  use_type='title' then '鏍囬'   when  use_type='list' then '閫夐」' else '鏂囨湰' end as use_type_text from s_app_lang_translation where appkey=@appkey@ and deleted=0 and translation != ''`
+    let sql = `select mother_tongue as reg,translation as value,use_type as type,case when use_type='menu' then '鑿滃崟' when  use_type='button' then '鎸夐挳'  when  use_type='title' then '鏍囬'   when  use_type='list' then '閫夐」' else '鏂囨湰' end as use_type_text from s_app_lang_translation where appkey=@appkey@ and deleted=0 and translation != '' and lang='${sessionStorage.getItem('lang') || ''}'`
+
+    let param = {
+      func: 'sPC_Get_SelectedList',
+      LText: Utils.formatOptions(sql, 'x'),
+      obj_name: 'data',
+      arr_field: 'reg,value,type',
+      exec_type: 'x'
+    }
+
+    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    param.secretkey = Utils.encrypt('', param.timestamp)
+    param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
+
+    Api.getCloudConfig(param).then(result => {
+      if (!result.status) {
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+        return
+      }
+
+      this.setState({dicts: result.data || []})
+    })
+  }
+
+  getMenus = (lang) => {
+    if (this.state.menus.length > 0) {
+      this.setState({loading: false})
+      return
+    }
+
+    let _param = {
+      func: 's_get_pc_menus',
+      systemType: window.GLOB.sysType,
+      pro_sys: '',
+      lang: lang,
+      debug: 'Y'
+    }
+
+    Api.getCloudConfig(_param).then(res => {
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+        return
+      }
+
+      let menus = []
+
+      res.fst_menu && res.fst_menu.forEach(fst => {
+        let fstItem = {
+          value: fst.MenuID,
+          label: fst.MenuName,
+          children: []
+        }
+  
+        fst.snd_menu && fst.snd_menu.forEach(snd => {
+          let sndItem = {
+            value: snd.MenuID,
+            label: snd.MenuName,
+            children: []
+          }
+
+          snd.trd_menu && snd.trd_menu.forEach(trd => {
+            let trdItem = {
+              value: trd.MenuID,
+              label: trd.MenuName,
+              MenuNo: trd.MenuNo,
+            }
+
+            if (!trd.PageParam) return
+            
+            let PageParam = null
+            try {
+              PageParam = JSON.parse(trd.PageParam)
+            } catch (e) {
+              PageParam = null
+            }
+
+            if (!PageParam || !['BaseTable', 'CustomPage'].includes(PageParam.Template)) return
+
+            trdItem.PageParam = PageParam
+
+            sndItem.children.push(trdItem)
+          })
+
+          if (sndItem.children.length === 0) return
+
+          fstItem.children.push(sndItem)
+        })
+
+        if (fstItem.children.length === 0) return
+  
+        menus.push(fstItem)
+      })
+
+      menus.push({
+        value: 'home_page_id',
+        label: '棣栭〉',
+      })
+
+      this.setState({menus: menus, loading: false})
+    })
+  }
+
+  submit = () => {
+    const { values, type } = this.state
+
+    if (!values) {
+      notification.warning({
+        top: 92,
+        message: type === 'menu' ? '璇烽�夋嫨鑿滃崟锛�' : '璇烽�夋嫨妯℃澘锛�',
+        duration: 5
+      })
+      return
+    }
+
+    if (type === 'bill') {
+      this.billSubmit()
+      return
+    } else if (type === 'tab') {
+      this.tabSubmit()
+      return
+    }
+
+    if (values.length !== 3 && values[0] !== 'home_page_id') {
+      notification.warning({
+        top: 92,
+        message: '璇烽�夋嫨鑿滃崟锛�',
+        duration: 5
+      })
+      return
+    }
+
+    this.setState({saveing: true})
+
+    if (values[0] === 'home_page_id') {
+      this.transThdMenu({
+        value: 'home_page_id',
+        MenuID: 'home_page_id',
+        label: '棣栭〉'
+      })
+    } else {
+      this.transFirstMenu(values[0], values[1], values[2])
+    }
+  }
+
+  transFirstMenu = (firstId, secId, thdId) => {
+    const { menulist } = this.props
+    const { menus, dicts } = this.state
+    let tail = md5(window.GLOB.appkey + sessionStorage.getItem('lang')).toLowerCase()
+
+    tail = tail.slice(-8)
+
+    let oriFirstMenu = menus.filter(item => item.value === firstId)[0]
+    let oriSecMenu = oriFirstMenu.children.filter(item => item.value === secId)[0]
+    let oriThdMenu = oriSecMenu.children.filter(item => item.value === thdId)[0]
+
+    oriThdMenu = fromJS(oriThdMenu).toJS()
+
+    let curFirstId = firstId
+    if (curFirstId.length <= 24) {
+      curFirstId = md5(window.GLOB.appkey + curFirstId + sessionStorage.getItem('lang')).toLowerCase()
+    } else {
+      curFirstId = curFirstId.slice(0, 24) + tail
+    }
+
+    let curSectId = secId
+    if (curSectId.length <= 24) {
+      curSectId = md5(window.GLOB.appkey + curSectId + sessionStorage.getItem('lang')).toLowerCase()
+    } else {
+      curSectId = curSectId.slice(0, 24) + tail
+    }
+
+    let curThdId = thdId
+    if (curThdId.length <= 24) {
+      curThdId = md5(window.GLOB.appkey + curThdId + sessionStorage.getItem('lang')).toLowerCase()
+    } else {
+      curThdId = curThdId.slice(0, 24) + tail
+    }
+
+    let firstName = oriFirstMenu.label
+    let secName = oriSecMenu.label
+
+    dicts.forEach(item => {
+      if (item.type !== 'menu') return
+      if (item.reg === firstName) {
+        firstName = item.value
+      }
+      if (item.reg === secName) {
+        secName = item.value
+      }
+      if (item.reg === oriThdMenu.label) {
+        oriThdMenu.label = item.value
+      }
+    })
+
+    let firstParam = {
+      func: 'sPC_MainMenu_Add',
+      MenuID: curFirstId,
+      MenuName: firstName,
+      PageParam: JSON.stringify({
+        OpenType: 'menu',
+        linkUrl: ''
+      })
+    }
+
+    let secParam = {
+      func: 'sPC_SndMenu_Add',
+      ParentID: curFirstId,
+      MenuID: curSectId,
+      MenuName: secName,
+      PageParam: JSON.stringify({
+        Icon: ''
+      })
+    }
+
+    oriThdMenu.fstMenuId = curFirstId
+    oriThdMenu.parentId = curSectId
+    oriThdMenu.MenuID = curThdId
+
+    if (menulist.findIndex(item => item.MenuID === firstParam.MenuID) === -1) {
+      Api.getCloudConfig(firstParam).then(res => {
+        if (!res.status) {
+          notification.warning({
+            top: 92,
+            message: res.message,
+            duration: 5
+          })
+          this.setState({saveing: false})
+          return
+        }
+
+        this.transSecondMenu(secParam, oriThdMenu, true)
+      })
+    } else {
+      this.transSecondMenu(secParam, oriThdMenu)
+    }
+  }
+
+  transSecondMenu = (secParam, oriThdMenu, reload) => {
+    const { menulist } = this.props
+
+    let creat = true
+
+    menulist.forEach(item => {
+      if (item.children.findIndex(cell => cell.MenuID === secParam.MenuID) > -1) {
+        creat = false
+      }
+    })
+
+    if (creat) {
+      Api.getCloudConfig(secParam).then(res => {
+        if (!res.status) {
+          notification.warning({
+            top: 92,
+            message: res.message,
+            duration: 5
+          })
+          this.setState({saveing: false})
+          return
+        }
+
+        this.transThdMenu(oriThdMenu, true)
+      })
+    } else {
+      this.transThdMenu(oriThdMenu, reload)
+    }
+  }
+
+  transThdMenu = (menu, reload) => {
+    const { menulist } = this.props
+    const { lang, dicts } = this.state
+
+    let _param = {
+      func: 'sPC_Get_LongParam',
+      MenuID: menu.value,
+      lang: lang
+    }
+
+    let creat = true
+
+    if (menu.MenuID === 'home_page_id') {
+      creat = false
+    } else {
+      menulist.forEach(item => {
+        item.children.forEach(cell => {
+          if (cell.children.findIndex(n => n.MenuID === menu.MenuID) > -1) {
+            creat = false
+          }
+        })
+      })
+    }
+
+    Api.getCloudConfig(_param).then(res => {
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+        this.setState({saveing: false})
+        return
+      }
+
+      let config = null
+      if (res.LongParam) {
+        try {
+          config = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
+        } catch (e) {
+          console.warn('Parse Failure')
+          config = ''
+        }
+      }
+
+      if (!config) {
+        notification.warning({
+          top: 92,
+          message: '鏈幏鍙栧埌鑿滃崟閰嶇疆淇℃伅',
+          duration: 5
+        })
+        this.setState({saveing: false})
+
+        if (reload) {
+          this.props.reload()
+        }
+        return
+      }
+
+      let btnDict = {}
+      let titDict = {}
+      let lisDict = {}
+      let regs = []
+
+      dicts.forEach(item => {
+        if (item.type === 'button') {
+          btnDict[item.reg] = item.value
+        } else if (item.type === 'title') {
+          titDict[item.reg] = item.value
+        } else if (item.type === 'list') {
+          lisDict[item.reg] = item.value
+        } else if (item.type === 'text') {
+          regs.push({reg: new RegExp(item.reg, 'g'), value: item.value, sort: item.reg.length})
+        }
+      })
+
+      regs.sort((a, b) => b.sort - a.sort)
+
+      let tail = md5(window.GLOB.appkey + sessionStorage.getItem('lang')).toLowerCase()
+
+      tail = tail.slice(-8)
+
+      setLangTrans(config, btnDict, titDict, lisDict, {}, regs, tail)
+
+      if (config.components) {
+        let commonId = Utils.getuuid()
+        if (config.interfaces && config.interfaces.length > 0) {
+          config.interfaces = config.interfaces.map(inter => {
+            inter.uuid = md5(commonId + inter.uuid)
+            return inter
+          })
+        }
+        config.components = MenuUtils.resetConfig(config.components, commonId, false)
+        config.tables = config.tables || []
+        config.style = config.style || {}
+      }
+
+      config.enabled = false
+      config.MenuName = menu.label
+      config.fstMenuId = menu.fstMenuId || ''
+      config.parentId = menu.parentId || ''
+      config.uuid = menu.MenuID || ''
+      config.open_edition = ''
+      if (config.MenuNo) {
+        config.MenuNo = config.MenuNo + '_' + sessionStorage.getItem('lang')
+      }
+
+      let param = {
+        func: 'sPC_TrdMenu_AddUpt',
+        FstID: config.fstMenuId,
+        SndID: config.parentId,
+        ParentID: config.parentId,
+        MenuID: config.uuid,
+        MenuNo: config.MenuNo || '',
+        EasyCode: config.easyCode || '',
+        Template: config.Template,
+        MenuName: config.MenuName || '',
+        PageParam: JSON.stringify({Template: config.Template, OpenType: config.OpenType || 'newtab'})
+      }
+
+      if (creat) {
+        param.open_edition = config.open_edition
+        param.LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(config)))
+
+        this.setMenu(param, true)
+      } else {
+        Api.getCloudConfig({
+          func: 'sPC_Get_LongParam',
+          MenuID: menu.MenuID
+        }).then(res => {
+          if (!res.status) {
+            notification.warning({
+              top: 92,
+              message: res.message,
+              duration: 5
+            })
+            this.setState({saveing: false})
+            return
+          }
+
+          config.open_edition = res.open_edition || ''
+          param.open_edition = config.open_edition
+          param.LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(config)))
+  
+          if (res.LongParam) {
+            const that = this
+            confirm({
+              title: '鑿滃崟宸插瓨鍦紝纭畾閲嶆柊鐢熸垚鍚�?',
+              content: '',
+              onOk() {
+                that.setMenu(param, true)
+              },
+              onCancel() {}
+            })
+          } else {
+            this.setMenu(param, true)
+          }
+        })
+      }
+    })
+  }
+
+  setMenu = (param, reload) => {
+    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    param.secretkey = Utils.encrypt('', param.timestamp)
+
+    Api.getCloudConfig(param).then(res => {
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+        this.setState({saveing: false})
+        return
+      }
+
+      notification.success({
+        top: 92,
+        message: '娣诲姞鎴愬姛銆�',
+        duration: 5
+      })
+      
+      this.setState({
+        loading: false,
+        visible: false
+      })
+
+      if (reload) {
+        this.props.reload()
+      }
+    })
+  }
+
+  cancel = () => {
+    this.setState({
+      loading: false,
+      visible: false
+    })
+  }
+
+  onChange = (e) => {
+    this.setState({
+      type: e.target.value,
+      images: '',
+      values: ''
+    })
+
+    if (e.target.value === 'bill') {
+      this.getBillMenus()
+    } else if (e.target.value === 'tab') {
+      this.getTabMenus()
+    }
+  }
+
+  getBillMenus = () => {
+    const { billMenus } = this.state
+
+    if (billMenus.length) return
+
+    let _param = {
+      func: 's_get_sPrintTemplate_web',
+      OrderCol: 'ID desc',
+      lang_s: sessionStorage.getItem('lang'),
+      dataM: 'Y',
+      PageIndex: 1,
+      PageSize: 1000
+    }
+
+    Api.getCloudConfig(_param).then(res => {
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+        return
+      }
+
+      this.setState({billMenus: res.data || []})
+    })
+  }
+
+  getTabMenus = () => {
+    const { tabMenus } = this.state
+
+    if (tabMenus.length) return
+
+    let _param = {
+      func: 's_get_sPrintTemplate',
+      OrderCol: 'ID desc',
+      lang_s: sessionStorage.getItem('lang'),
+      dataM: 'Y',
+      PageIndex: 1,
+      PageSize: 1000
+    }
+
+    Api.getCloudConfig(_param).then(res => {
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+        return
+      }
+
+      this.setState({tabMenus: res.data || []})
+    })
+  }
+
+  billSubmit = () => {
+    const { dicts, values, billMenus } = this.state
+
+    let _param = {
+      func: 'sPC_Get_LongParam',
+      MenuID: values
+    }
+
+    this.setState({saveing: true})
+
+    let temp = billMenus.filter(item => item.ID === values)[0]
+
+    Api.getCloudConfig(_param).then(res => {
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+        this.setState({saveing: false})
+        return
+      }
+
+      let config = null
+      if (res.LongParam) {
+        try {
+          config = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
+        } catch (e) {
+          console.warn('Parse Failure')
+          config = ''
+        }
+      }
+
+      if (!config) {
+        notification.warning({
+          top: 92,
+          message: '鏈幏鍙栧埌妯℃澘閰嶇疆淇℃伅',
+          duration: 5
+        })
+        this.setState({saveing: false})
+        return
+      }
+
+      let btnDict = {}
+      let titDict = {}
+      let lisDict = {}
+      let regs = []
+
+      dicts.forEach(item => {
+        if (item.type === 'button') {
+          btnDict[item.reg] = item.value
+        } else if (item.type === 'title') {
+          titDict[item.reg] = item.value
+        } else if (item.type === 'list') {
+          lisDict[item.reg] = item.value
+        } else if (item.type === 'text') {
+          regs.push({reg: new RegExp(item.reg, 'g'), value: item.value, sort: item.reg.length})
+        }
+      })
+
+      regs.sort((a, b) => b.sort - a.sort)
+
+      let tail = md5(window.GLOB.appkey + sessionStorage.getItem('lang')).toLowerCase()
+
+      tail = tail.slice(-8)
+
+      setLangTrans(config, btnDict, titDict, lisDict, {}, regs, tail)
+
+      if (config.components) {
+        let commonId = Utils.getuuid()
+        if (config.interfaces && config.interfaces.length > 0) {
+          config.interfaces = config.interfaces.map(inter => {
+            inter.uuid = md5(commonId + inter.uuid)
+            return inter
+          })
+        }
+        config.components = MenuUtils.resetConfig(config.components, commonId, false)
+        config.tables = config.tables || []
+        config.style = config.style || {}
+      }
+
+      config.enabled = false
+      config.MenuNo = temp.PrintTempNO || ''
+      config.MenuName = temp.PrintTempName || ''
+      config.fstMenuId = 'BillPrintTemp'
+      config.parentId = 'BillPrintTemp'
+      config.uuid = values
+      config.MenuID = config.uuid
+
+      config.open_edition = res.open_edition || ''
+
+      let param = {
+        func: 'sPC_TrdMenu_AddUpt',
+        FstID: config.fstMenuId,
+        SndID: config.parentId,
+        ParentID: config.parentId,
+        MenuID: config.uuid,
+        MenuNo: config.MenuNo || '',
+        EasyCode: config.easyCode || '',
+        Template: config.Template,
+        MenuName: config.MenuName || '',
+        open_edition: config.open_edition,
+        PageParam: JSON.stringify({Template: config.Template, OpenType: config.OpenType || 'newtab'})
+      }
+
+      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+      param.secretkey = Utils.encrypt('', param.timestamp)
+
+      Api.getCloudConfig(param).then(res => {
+        if (!res.status) {
+          notification.warning({
+            top: 92,
+            message: res.message,
+            duration: 5
+          })
+          this.setState({saveing: false})
+          return
+        }
+
+        notification.success({
+          top: 92,
+          message: '杞崲鎴愬姛銆�',
+          duration: 5
+        })
+        
+        this.setState({
+          saveing: false,
+          visible: false
+        })
+      })
+    })
+  }
+
+  tabSubmit = () => {
+    const { values, dicts, tabMenus } = this.state
+
+    let param = {
+      func: 's_PrintTemplateMGetData',
+      Type: 'Y',
+      ID: values
+    }
+
+    this.setState({saveing: true})
+
+    let temp = tabMenus.filter(item => item.ID === values)[0]
+
+    Api.getCloudConfig(param).then(result => {
+      if (!result.status) {
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+        this.setState({saveing: false})
+      } else if (!result.ConfigParam) {
+        notification.warning({
+          top: 92,
+          message: '鏈幏鍙栧埌鎵撳嵃妯℃澘淇℃伅锛�',
+          duration: 5
+        })
+        this.setState({saveing: false})
+      } else {
+        let config = ''
+        try {
+          config = JSON.parse(window.decodeURIComponent(window.atob(result.ConfigParam)))
+        } catch (e) {
+          config = ''
+        }
+  
+        if (!config) {
+          notification.warning({
+            top: 92,
+            message: '鏈幏鍙栧埌鎵撳嵃妯℃澘淇℃伅锛�',
+            duration: 5
+          })
+          this.setState({saveing: false})
+          return
+        }
+
+        let titDict = {}
+
+        dicts.forEach(item => {
+          if (item.type === 'title') {
+            titDict[item.reg] = item.value
+          }
+        })
+
+        config.elements.forEach(item => {
+          if (item.type === 'text' && item.value && titDict[item.value]) {
+            item.value = titDict[item.value]
+          }
+        })
+
+        config.name = temp.PrintTempName || ''
+        config.remark = temp.Remark || ''
+        config.PrintTempNO = temp.PrintTempNO || ''
+
+        let _param = {
+          func: 's_PrintTemplateMSub',
+          ID: values,
+          ConfigParam: window.btoa(window.encodeURIComponent(JSON.stringify(config))),
+          Images: temp.Images || '',
+          PrintTempName: config.name,
+          Remark: config.remark,
+          PrintTempNO: config.PrintTempNO
+        }
+
+        Api.getCloudConfig(_param).then(result => {
+          if (!result.status) {
+            notification.warning({
+              top: 92,
+              message: result.message,
+              duration: 5
+            })
+            this.setState({saveing: false})
+            return
+          }
+
+          notification.success({
+            top: 92,
+            message: '杞崲鎴愬姛銆�',
+            duration: 5
+          })
+          
+          this.setState({
+            saveing: false,
+            visible: false
+          })
+        })
+      }
+    })
+  }
+
+  render () {
+    const { visible, loading, saveing, menus, type, billMenus, tabMenus, images } = this.state
+
+    return (
+      <>
+        <Button type="primary" onClick={this.trigger}>
+          杞崲
+        </Button>
+        <Modal
+          wrapClassName="sync-menu-modal"
+          title="鑿滃崟杞崲"
+          visible={visible}
+          width={600}
+          closable={false}
+          maskClosable={false}
+          onOk={this.submit}
+          onCancel={this.cancel}
+          confirmLoading={saveing}
+          destroyOnClose
+        >
+          {loading ? <Spin /> : <div>
+            <Radio.Group defaultValue="menu" onChange={this.onChange}>
+              <Radio.Button value="menu">鑿滃崟</Radio.Button>
+              <Radio.Button value="bill">鍗曟嵁鎵撳嵃妯℃澘</Radio.Button>
+              <Radio.Button value="tab">鏍囩鎵撳嵃妯℃澘</Radio.Button>
+            </Radio.Group>
+            {type === 'menu' ? <Cascader popupClassName="sync-cascader" onChange={(val) => this.setState({values: val})} options={menus} expandTrigger="hover" placeholder="璇烽�夋嫨鑿滃崟"/> : null}
+            {type === 'bill' ? <Select
+              showSearch
+              placeholder="璇烽�夋嫨鍗曟嵁妯℃澘"
+              dropdownMatchSelectWidth={false}
+              onChange={(val, option) => this.setState({values: val, images: option.props.images || ''})}
+              filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
+            >
+              {billMenus.map((item, i) => (<Select.Option key={i} images={item.Images || ''} value={item.ID}>{`${item.PrintTempName}锛�${item.PrintTempNO}锛塦}</Select.Option>))}
+            </Select> : null}
+            {type === 'tab' ? <Select
+              showSearch
+              placeholder="璇烽�夋嫨鏍囩妯℃澘"
+              dropdownMatchSelectWidth={false}
+              onChange={(val, option) => this.setState({values: val, images: option.props.images || ''})}
+              filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
+            >
+              {tabMenus.map((item, i) => (<Select.Option key={i} images={item.Images || ''} value={item.ID}>{`${item.PrintTempName}锛�${item.PrintTempNO}锛塦}</Select.Option>))}
+            </Select> : null}
+            {images ? <img src={images} alt=""/> : null}
+          </div>}
+        </Modal>
+      </>
+    )
+  }
+}
+
+export default TransMenu
\ No newline at end of file
diff --git a/src/views/design/header/transmenu/index.scss b/src/views/design/header/transmenu/index.scss
new file mode 100644
index 0000000..9d4d17c
--- /dev/null
+++ b/src/views/design/header/transmenu/index.scss
@@ -0,0 +1,36 @@
+.sync-menu-modal {
+  .ant-modal-body {
+    position: relative;
+    padding: 24px 50px;
+    min-height: 250px;
+    max-height: calc(100vh - 210px);
+    .ant-cascader-picker, .ant-select {
+      width: 300px;
+    }
+    .ant-radio-group {
+      display: block;
+      margin-bottom: 20px;
+      .ant-radio-button-wrapper {
+        width: 150px;
+        text-align: center;
+      }
+    }
+    img {
+      max-width: 300px;
+      max-height: 150px;
+      display: block;
+      margin: 10px;
+    }
+    .ant-spin {
+      position: absolute;
+      left: calc(50% - 10px);
+      top: 75px;
+    }
+  }
+}
+.sync-cascader {
+  .ant-cascader-menu {
+    height: 200px;
+    min-width: 120px;
+  }
+}
\ No newline at end of file
diff --git a/src/views/design/sidemenu/editthdmenu/index.jsx b/src/views/design/sidemenu/editthdmenu/index.jsx
index d482996..e90f4a7 100644
--- a/src/views/design/sidemenu/editthdmenu/index.jsx
+++ b/src/views/design/sidemenu/editthdmenu/index.jsx
@@ -214,8 +214,8 @@
         MenuName: res.MenuName,
         PageParam: JSON.stringify(PageParam),
         LongParam: '',
-        LText: '',
-        LTexttb: ''
+        // LText: '',
+        // LTexttb: ''
       }
 
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
diff --git a/src/views/design/sidemenu/index.jsx b/src/views/design/sidemenu/index.jsx
index d43da38..7f9b43f 100644
--- a/src/views/design/sidemenu/index.jsx
+++ b/src/views/design/sidemenu/index.jsx
@@ -249,8 +249,8 @@
         MenuName: res.MenuName,
         PageParam: JSON.stringify(PageParam),
         LongParam: '',
-        LText: '',
-        LTexttb: ''
+        // LText: '',
+        // LTexttb: ''
       }
 
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
diff --git a/src/views/design/sidemenu/thdmenuplus/index.jsx b/src/views/design/sidemenu/thdmenuplus/index.jsx
index be78279..a159c98 100644
--- a/src/views/design/sidemenu/thdmenuplus/index.jsx
+++ b/src/views/design/sidemenu/thdmenuplus/index.jsx
@@ -174,8 +174,8 @@
         MenuName: values.MenuName,
         PageParam: JSON.stringify(PageParam),
         LongParam: '',
-        LText: '',
-        LTexttb: '',
+        // LText: '',
+        // LTexttb: '',
         Sort: sysMenu.menuSort
       }
 
diff --git a/src/views/imdesign/index.jsx b/src/views/imdesign/index.jsx
index 6bd3c0c..1960d4b 100644
--- a/src/views/imdesign/index.jsx
+++ b/src/views/imdesign/index.jsx
@@ -2,13 +2,11 @@
 import { withRouter } from 'react-router'
 import { is, fromJS } from 'immutable'
 import moment from 'moment'
-import { ConfigProvider, notification, Modal, Collapse, Button, Spin } from 'antd'
+import { notification, Modal, Collapse, Button, Spin } from 'antd'
 import { DoubleLeftOutlined, DoubleRightOutlined, LeftOutlined, UserOutlined, EllipsisOutlined } from '@ant-design/icons'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
-import antdEnUS from 'antd/es/locale/en_US'
-import antdZhCN from 'antd/es/locale/zh_CN'
 // import MKEmitter from '@/utils/events.js'
 import asyncComponent from '@/utils/asyncComponent'
 import getWrapForm from './options'
@@ -32,7 +30,6 @@
 
 class ImDesign extends Component {
   state = {
-    localedict: sessionStorage.getItem('lang') !== 'en-US' ? antdZhCN : antdEnUS,
     loading: true,
     MenuId: '',
     MenuName: '',
@@ -49,10 +46,12 @@
     try {
       let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
 
+      if (param.lang) {
+        sessionStorage.setItem('lang', param.lang)
+      }
       if (param.type === 'app') {
         sessionStorage.setItem('appId', param.ID || '')
         sessionStorage.setItem('appName', param.remark || '')
-        sessionStorage.setItem('lang', param.lang || 'zh-CN')
         sessionStorage.setItem('kei_no', param.kei_no || '')
         sessionStorage.setItem('typename', param.typename || 'mob')
         sessionStorage.setItem('adapter', param.adapter || '')
@@ -60,9 +59,6 @@
         sessionStorage.setItem('userbind', param.userbind || '')
         sessionStorage.setItem('instantMessage', param.instantMessage || '')
 
-        this.setState({
-          localedict: sessionStorage.getItem('lang') !== 'en-US' ? antdZhCN : antdEnUS,
-        })
         this.getAppMessage(param.MenuID)
       } else if (param.type === 'view') {
         window.GLOB.winWidth = 420
@@ -149,7 +145,8 @@
     let param = {
       MenuID: config.wrap.linkmenu,
       copyMenuId: '',
-      type: 'view'
+      type: 'view',
+      lang: sessionStorage.getItem('lang')
     }
 
     param = window.btoa(window.encodeURIComponent(JSON.stringify(param)))
@@ -177,7 +174,7 @@
       }
 
       sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
-      this.props.history.replace('/imdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: MenuID, type: 'view'}))))
+      this.props.history.replace('/imdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: MenuID, type: 'view', lang: sessionStorage.getItem('lang')}))))
       window.location.reload()
     })
   }
@@ -361,8 +358,8 @@
         PageParam: JSON.stringify({Template: 'imPage'}),
         open_edition: config.open_edition,
         menus_rolelist: window.btoa(window.encodeURIComponent(JSON.stringify({type: 'im', key: config.uuid, title: config.MenuName, children: []}))),
-        LText: '',
-        LTexttb: ''
+        // LText: '',
+        // LTexttb: ''
       }
 
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
@@ -421,96 +418,94 @@
   }
 
   render () {
-    const { localedict, loading, settingshow, controlshow, MenuId, config, menuloading } = this.state
+    const { loading, settingshow, controlshow, MenuId, config, menuloading } = this.state
 
     return (
-      <ConfigProvider locale={localedict}>
-        <div className="mk-mob-view" id="mk-mob-design-view">
-          <Header/>
-          {loading ? <Spin className="view-spin" size="large" /> : null}
-          <div className={'menu-setting ' + (!settingshow ? 'hidden' : '')}>
-            <div className="draw">
-              {settingshow ? <DoubleLeftOutlined onClick={() => {this.setState({settingshow: false})}} /> : null}
-              {!settingshow ? <DoubleRightOutlined onClick={() => {this.setState({settingshow: true})}} /> : null}
-            </div>
-            <div className="pc-setting-tools">
-              <Collapse accordion defaultActiveKey="basedata" bordered={false}>
-                {/* 鍩烘湰淇℃伅 */}
-                <Panel header="鍩烘湰淇℃伅" forceRender key="basedata">
-                  {/* 鑿滃崟淇℃伅 */}
-                  {config ? <MenuForm
-                    config={config}
-                    MenuId={MenuId}
-                    updateConfig={this.updateConfig}
-                  /> : null}
-                </Panel>
-                <Panel header="椤甸潰鏍峰紡" key="background">
-                  {config ? <BgController config={config} updateConfig={this.updateConfig} /> : null}
-                </Panel>
-              </Collapse>
-            </div>
+      <div className="mk-mob-view" id="mk-mob-design-view">
+        <Header/>
+        {loading ? <Spin className="view-spin" size="large" /> : null}
+        <div className={'menu-setting ' + (!settingshow ? 'hidden' : '')}>
+          <div className="draw">
+            {settingshow ? <DoubleLeftOutlined onClick={() => {this.setState({settingshow: false})}} /> : null}
+            {!settingshow ? <DoubleRightOutlined onClick={() => {this.setState({settingshow: true})}} /> : null}
           </div>
-          <div className={'menu-control ' + (!controlshow ? 'hidden' : '')}>
-            <div className="draw">
-              {controlshow ? <DoubleRightOutlined onClick={() => {this.setState({controlshow: false})}}/> : null}
-              {!controlshow ? <DoubleLeftOutlined onClick={() => {this.setState({controlshow: true})}}/> : null}
-            </div>
-            <div className="wrap">
-              <Button type="primary" onClick={this.submitConfig} id="save-config" loading={menuloading}>淇濆瓨</Button>
-              <NormalForm title="鍗虫椂閫氫俊璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
-                <Button type="default" style={{borderColor: 'rgb(64, 169, 255)', color: 'rgb(64, 169, 255)'}}>璁剧疆</Button>
-              </NormalForm>
-              <Button type="default" className="mk-border-purple" onClick={this.backView}>鍚庨��</Button>
-              <CreateView resetmenu={this.getAppMenus} />
-              <Transfer MenuID={MenuId} />
-              <Button type="default" onClick={this.closeView}>鍏抽棴</Button>
-            </div>
+          <div className="pc-setting-tools">
+            <Collapse accordion defaultActiveKey="basedata" bordered={false}>
+              {/* 鍩烘湰淇℃伅 */}
+              <Panel header="鍩烘湰淇℃伅" forceRender key="basedata">
+                {/* 鑿滃崟淇℃伅 */}
+                {config ? <MenuForm
+                  config={config}
+                  MenuId={MenuId}
+                  updateConfig={this.updateConfig}
+                /> : null}
+              </Panel>
+              <Panel header="椤甸潰鏍峰紡" key="background">
+                {config ? <BgController config={config} updateConfig={this.updateConfig} /> : null}
+              </Panel>
+            </Collapse>
           </div>
-          <div className={'menu-body menu-view'}>
-            <div className="mob-shell" style={{width: window.GLOB.shellWidth, height: window.GLOB.shellHeight}}>
-              <div className="instant-message" style={config ? config.style : null}>
-                <div className="header">
-                  <LeftOutlined/>
-                  <span className="title">鏈嬪弸</span>
-                  {config && config.wrap.linkmenu ? <EllipsisOutlined onDoubleClick={this.changeEditMenu}/> : null}
-                </div>
-                <div className="mk-content-wrap">
-                  <div className="line-wrap">
-                    <div className="time-line">12:34</div>
-                    <div className="line-msg">
-                      <div className="portrait">
-                        <div className="img"><UserOutlined /></div>
-                      </div>
-                      <div className="msg">
-                        <div className="title">鏈嬪弸</div>
-                        <div className="words">鎮ㄥソ</div>
-                      </div>
+        </div>
+        <div className={'menu-control ' + (!controlshow ? 'hidden' : '')}>
+          <div className="draw">
+            {controlshow ? <DoubleRightOutlined onClick={() => {this.setState({controlshow: false})}}/> : null}
+            {!controlshow ? <DoubleLeftOutlined onClick={() => {this.setState({controlshow: true})}}/> : null}
+          </div>
+          <div className="wrap">
+            <Button type="primary" onClick={this.submitConfig} id="save-config" loading={menuloading}>淇濆瓨</Button>
+            <NormalForm title="鍗虫椂閫氫俊璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
+              <Button type="default" style={{borderColor: 'rgb(64, 169, 255)', color: 'rgb(64, 169, 255)'}}>璁剧疆</Button>
+            </NormalForm>
+            <Button type="default" className="mk-border-purple" onClick={this.backView}>鍚庨��</Button>
+            <CreateView resetmenu={this.getAppMenus} />
+            <Transfer MenuID={MenuId} />
+            <Button type="default" onClick={this.closeView}>鍏抽棴</Button>
+          </div>
+        </div>
+        <div className={'menu-body menu-view'}>
+          <div className="mob-shell" style={{width: window.GLOB.shellWidth, height: window.GLOB.shellHeight}}>
+            <div className="instant-message" style={config ? config.style : null}>
+              <div className="header">
+                <LeftOutlined/>
+                <span className="title">鏈嬪弸</span>
+                {config && config.wrap.linkmenu ? <EllipsisOutlined onDoubleClick={this.changeEditMenu}/> : null}
+              </div>
+              <div className="mk-content-wrap">
+                <div className="line-wrap">
+                  <div className="time-line">12:34</div>
+                  <div className="line-msg">
+                    <div className="portrait">
+                      <div className="img"><UserOutlined /></div>
                     </div>
-                  </div>
-                  <div className="line-wrap">
-                    <div className="time-line">12:45</div>
-                    <div className="line-msg right">
-                      <div className="msg">
-                        <div className="words">
-                          鎮ㄥソ
-                        </div>
-                      </div>
-                      <div className="portrait">
-                        <div className="img"><UserOutlined /></div>
-                      </div>
+                    <div className="msg">
+                      <div className="title">鏈嬪弸</div>
+                      <div className="words">鎮ㄥソ</div>
                     </div>
                   </div>
                 </div>
-                <div className="send-wrap">
-                  <div className="adm-input"></div>
-                  <div className="send"><Button>鍙戦��</Button></div>
+                <div className="line-wrap">
+                  <div className="time-line">12:45</div>
+                  <div className="line-msg right">
+                    <div className="msg">
+                      <div className="words">
+                        鎮ㄥソ
+                      </div>
+                    </div>
+                    <div className="portrait">
+                      <div className="img"><UserOutlined /></div>
+                    </div>
+                  </div>
                 </div>
+              </div>
+              <div className="send-wrap">
+                <div className="adm-input"></div>
+                <div className="send"><Button>鍙戦��</Button></div>
               </div>
             </div>
           </div>
-          <StyleController />
         </div>
-      </ConfigProvider>
+        <StyleController />
+      </div>
     )
   }
 }
diff --git a/src/views/interface/index.jsx b/src/views/interface/index.jsx
index 573e87c..3d88456 100644
--- a/src/views/interface/index.jsx
+++ b/src/views/interface/index.jsx
@@ -1,7 +1,4 @@
 import React, {Component} from 'react'
-import { ConfigProvider } from 'antd'
-import enUS from 'antd/es/locale/en_US'
-import zhCN from 'antd/es/locale/zh_CN'
 
 import Header from './header'
 import History from './history'
@@ -9,17 +6,13 @@
 
 import './index.scss'
 
-const _locale = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
-
 class Interface extends Component {
   render () {
     return (
       <div className="interface-view">
-        <ConfigProvider locale={_locale}>
-          <Header key="header"/>
-          <History key="history"/>
-          <WorkSpace key="workspace"/>
-        </ConfigProvider>
+        <Header key="header"/>
+        <History key="history"/>
+        <WorkSpace key="workspace"/>
       </div>
     )
   }
diff --git a/src/views/login/index.jsx b/src/views/login/index.jsx
index d8a5ada..362d15f 100644
--- a/src/views/login/index.jsx
+++ b/src/views/login/index.jsx
@@ -7,8 +7,6 @@
 import Utils from '@/utils/utils.js' 
 import MKEmitter from '@/utils/events.js'
 import { styles } from '@/store/options.js'
-import zhCN from '@/locales/zh-CN/login.js'
-import enUS from '@/locales/en-US/login.js'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncLoadComponent from '@/utils/asyncLoadComponent'
 import './index.scss'
@@ -16,14 +14,9 @@
 const LoginForm = asyncLoadComponent(() => import('./loginform'))
 const Resetpwd = asyncLoadComponent(() => import('@/components/resetPassword'))
 const LoginCloudForm = asyncComponent(() => import('./logincloudform'))
-const iszhCN = sessionStorage.getItem('lang') !== 'en-US'
-
-const _href = window.location.href.split('#')[0]
 
 class Login extends Component {
   state = {
-    selectedlang: iszhCN ? 'zh-CN' : 'en-US',
-    dict: iszhCN ? zhCN : enUS,
     isDisabled: false,
     auth: false,
     authError: '',
@@ -37,7 +30,6 @@
     langList: [],
     syncApp: false,
     loginWays: null,
-    touristLogin: false,
     syncing: false,
   }
 
@@ -95,13 +87,10 @@
         window.GLOB.externalDatabase = `[${res.paas_externalDatabase}]..`
       }
 
-      localStorage.setItem(_href + 'lang', param.lang || 'zh-CN')
-      sessionStorage.setItem('lang', param.lang || 'zh-CN')
-
       sessionStorage.removeItem('visitorUserID')
       sessionStorage.removeItem('visitorLoginUID')
       
-      let users = localStorage.getItem(_href + 'users')
+      let users = localStorage.getItem(window.GLOB.sysSign + 'users')
       
       if (users) {
         try {
@@ -122,9 +111,9 @@
 
       users.unshift({username: param.username, password: param.remember ? param.password : ''})
 
-      localStorage.setItem(_href + 'users', window.btoa(window.encodeURIComponent(JSON.stringify(users))))
+      localStorage.setItem(window.GLOB.sysSign + 'users', window.btoa(window.encodeURIComponent(JSON.stringify(users))))
 
-      let level = localStorage.getItem(_href + 'pwdlevel')
+      let level = localStorage.getItem(window.GLOB.sysSign + 'pwdlevel')
 
       if (level && process.env.NODE_ENV === 'production') {
         let visible = false
@@ -213,9 +202,6 @@
         sessionStorage.setItem('externalDatabase', res.paas_externalDatabase)
         window.GLOB.externalDatabase = `[${res.paas_externalDatabase}]..`
       }
-
-      localStorage.setItem(_href + 'lang', param.lang || 'zh-CN')
-      sessionStorage.setItem('lang', param.lang || 'zh-CN')
 
       sessionStorage.removeItem('visitorUserID')
       sessionStorage.removeItem('visitorLoginUID')
@@ -310,6 +296,9 @@
     // 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")
 
+    sessionStorage.removeItem('subLangList')
+    sessionStorage.removeItem('langList')
+
     setTimeout(() => {
       Api.delCacheConfig()
     }, 50)
@@ -322,14 +311,14 @@
       }
     }
 
-    const _addressUrl = _href + 'queryAddress'
+    const _addressUrl = window.location.href.split('#')[0] + 'queryAddress'
 
     if (localStorage.getItem(_addressUrl) === 'true') {
       this.queryAddress()
     }
 
     const timeStamp = new Date().getTime()
-    const _authUrl = _href + 'AuthCode'
+    const _authUrl = window.location.href.split('#')[0] + 'AuthCode'
 
     let authCode = localStorage.getItem(_authUrl)
     let _s = md5('mksoft' + moment().format('YYYYMMDD'))
@@ -376,7 +365,7 @@
           lictime = Math.floor(new Date(lictime).getTime() / 86400000)
           let curtime = Math.floor(new Date().getTime() / 86400000)
           let licday = lictime - curtime
-          let _mindUrl = _href + 'notMind'
+          let _mindUrl = window.location.href.split('#')[0] + 'notMind'
 
           if (licday < 0 || isNaN(licday)) {
             Modal.warning({
@@ -466,12 +455,12 @@
             localStorage.setItem(_authUrl, box)
 
             if (res.e_files === 'true') {
-              localStorage.setItem(_href + 'files', md5(_href + 'files'))
-              localStorage.setItem(_href + 'filesDate', res.e_files_end_date)
+              localStorage.setItem(window.GLOB.sysSign + 'files', md5(window.GLOB.sysSign + 'files'))
+              localStorage.setItem(window.GLOB.sysSign + 'filesDate', res.e_files_end_date)
               window.GLOB.storeFiles = true
               window.GLOB.storeDate = Math.ceil((new Date(res.e_files_end_date).getTime() - new Date().getTime()) / 86400000)
             } else {
-              localStorage.removeItem(_href + 'files')
+              localStorage.removeItem(window.GLOB.sysSign + 'files')
               window.GLOB.storeFiles = false
             }
     
@@ -487,7 +476,7 @@
             }
           } else {
             localStorage.removeItem(_authUrl)
-            localStorage.removeItem(_href + 'files')
+            localStorage.removeItem(window.GLOB.sysSign + 'files')
             window.GLOB.storeFiles = false
 
             this.setState({
@@ -561,10 +550,6 @@
         sessionStorage.setItem('visitorUserID', result.UserID || '')
         sessionStorage.setItem('visitorLoginUID', result.LoginUID || '')
 
-        if (result.UserID && result.LoginUID) {
-          this.setState({touristLogin: true})
-        }
-
         // 鑾峰彇绯荤粺淇℃伅
         let _param = {
           func: 's_Get_style',
@@ -582,7 +567,7 @@
           if (!res) return
           
           if (res.status) {
-            if (window.GLOB.sysType === 'local' && window.GLOB.systemType !== 'production') {
+            if (res.member_type && window.GLOB.sysType === 'local' && window.GLOB.systemType !== 'production') {
               if (md5(('mk' + appkey + res.sys_datetime + res.member_type + res.registry_date).toLowerCase()) !== res.secret_key) {
                 Modal.warning({
                   title: '瀵嗛挜閿欒锛岃鑱旂郴绠$悊鍛橈紒',
@@ -606,14 +591,13 @@
               res.menu_type = 'shutter'
             }
 
-            let _url = _href + 'system'
             let systemMsg = {
               favicon: res.titlelogo || '',
               platTitle: res.titleName || '',
               platName: res.SysName || '',
               bgImage: res.Banner || '',
               loginlogo: res.loginlogo || '',
-              copyRight: res.CopyRightYear && res.CopyRightOrg ? `Copyright漏${res.CopyRightYear}    鎵�鏈夌浉鍏崇増鏉冨綊    ${res.CopyRightOrg}` : '',
+              copyRight: res.CopyRightYear && res.CopyRightOrg ? `Copyright漏${res.CopyRightYear}    ${window.GLOB.dict['copyrights_by'] || '鎵�鏈夌浉鍏崇増鏉冨綊'}    ${res.CopyRightOrg}` : '',
               ICP: res.ICP || '',
               mainlogo: res.indexlogo || '',
               doclogo: res.doclogo || '',
@@ -642,12 +626,12 @@
               level = ''
             }
 
-            localStorage.setItem(_href + 'pwdlevel', level)
+            localStorage.setItem(window.GLOB.sysSign + 'pwdlevel', level)
 
             if (res.srcid) {
-              localStorage.setItem(_href + 'srcId', res.srcid)
+              localStorage.setItem(window.GLOB.sysSign + 'srcId', res.srcid)
             } else {
-              localStorage.removeItem(_href + 'srcId')
+              localStorage.removeItem(window.GLOB.sysSign + 'srcId')
             }
 
             sessionStorage.setItem('home_background', res.index_background_color || '')
@@ -662,21 +646,41 @@
             document.title = systemMsg.platTitle
 
             try {
-              localStorage.setItem(_url, window.btoa(window.encodeURIComponent(JSON.stringify(systemMsg))))
+              localStorage.setItem(window.GLOB.sysSign + 'system', window.btoa(window.encodeURIComponent(JSON.stringify(systemMsg))))
             } catch (e) {
-              localStorage.removeItem(_url)
+              localStorage.removeItem(window.GLOB.sysSign + 'system')
             }
 
-            let _loginurl = _href + 'loginways'
+            if (res.lang_translation_js && res.lang_data && res.lang_data[0] && (res.lang_data.length > 1 || res.lang_data[0].Lang !== 'zh-CN')) {
+              let lang = sessionStorage.getItem('lang')
+              let js_trans = res.lang_translation_js.map(item => {
+                if (['not_empty', 'not_zero', 'max_limit', 'less_limit'].includes(item.msn_code)) {
+                  item.translation = ' ' + item.translation
+                }
+                if (['input_tip', 'select_tip', 'max_limit', 'less_limit'].includes(item.msn_code)) {
+                  item.translation = item.translation + ' '
+                }
+                if (lang === item.lang) {
+                  window.GLOB.dict[item.msn_code] = item.translation
+                }
+
+                return {
+                  lang: item.lang,
+                  key: item.msn_code,
+                  val: item.translation
+                }
+              })
+
+              localStorage.setItem(window.GLOB.sysSign + 'js_trans', JSON.stringify(js_trans))
+            }
+
+            let _loginurl = window.GLOB.sysSign + 'loginways'
             let login_ways = []
-            let login_types = []
             if (res.login_ways && res.login_ways.length > 0) {
               res.login_ways.forEach(item => {
                 // 鐭俊楠岃瘉鐮佺櫥褰曪紝蹇呴』璁剧疆鐭俊Id
                 if (item.way_no === 'sms_vcode' && !item.sms_id) return
-                if (login_types.includes(item.way_no)) return
-
-                login_types.push(item.way_no)
+                if (!['sms_vcode', 'uname_pwd', 'app_scan', 'weixin_scan'].includes(item.way_no)) return
 
                 login_ways.push({
                   type: item.way_no,
@@ -698,6 +702,30 @@
               localStorage.setItem(_loginurl, window.btoa(window.encodeURIComponent(JSON.stringify(login_ways))))
             } catch (e) {
               localStorage.removeItem(_loginurl)
+            }
+
+            if (res.lang_data && res.lang_data.length > 1 && window.GLOB.systemType !== 'production') {
+              let list = res.lang_data.map(item => item.Lang)
+              let lang = 'zh-CN'
+              if (window.GLOB.defLang && list.includes(window.GLOB.defLang)) {
+                lang = window.GLOB.defLang
+              }
+
+              if (list.includes(lang)) {
+                list = [lang, ...list.filter(item => item !== lang)]
+                if (lang === sessionStorage.getItem('lang')) {
+                  sessionStorage.setItem('langList', JSON.stringify(list))
+                } else {
+                  sessionStorage.setItem('subLangList', JSON.stringify(list))
+                }
+              }
+            }
+
+            if (res.lang_data.length === 1 && res.lang_data[0].Lang !== sessionStorage.getItem('lang')) {
+              localStorage.setItem(window.location.href.split('#')[0] + 'lang', res.lang_data[0].Lang)
+              sessionStorage.setItem('lang', res.lang_data[0].Lang)
+              window.location.reload()
+              return
             }
             
             this.setState({
@@ -760,7 +788,7 @@
       }
     })
     
-    let loginWays = localStorage.getItem(_href + 'loginways')
+    let loginWays = localStorage.getItem(window.GLOB.sysSign + 'loginways')
     if (loginWays) {
       try {
         loginWays = JSON.parse(window.decodeURIComponent(window.atob(loginWays)))
@@ -870,7 +898,7 @@
   }
 
   render () {
-    const { lineColor, bgImage, loginlogo, copyRight, webSite, ICP, loginWays, touristLogin } = this.state
+    const { lineColor, bgImage, loginlogo, copyRight, webSite, ICP, loginWays } = this.state
 
     return (
       <div className="login-container" id="mk-login-view" style={bgImage ? {backgroundImage: 'url(' + bgImage + ')'} : {}}>
@@ -880,12 +908,9 @@
         </div>
         <div className="login-middle" style={lineColor ? {borderColor: lineColor} : {}}>
           {loginWays ? <LoginForm
-            dict={this.state.dict}
             auth={this.state.auth}
             authError={this.state.authError}
-            touristLogin={touristLogin}
             loginWays={loginWays}
-            lang={this.state.selectedlang}
             langList={this.state.langList}
             isDisabled={this.state.isDisabled}
             handleSubmit={() => this.handleSubmit()}
@@ -903,9 +928,7 @@
         </div>
         {/* 缂栬緫鐘舵�佺櫥褰� */}
         <Modal
-          title={this.state.dict['login.sync.cloud']}
-          okText={this.state.dict['login.ok']}
-          cancelText={this.state.dict['login.cancel']}
+          title="鍚屾浜戠搴旂敤"
           visible={this.state.syncApp}
           onOk={this.syncSubmit}
           maskClosable={false}
diff --git a/src/views/login/logincloudform.jsx b/src/views/login/logincloudform.jsx
index 374ef07..7ecb9f5 100644
--- a/src/views/login/logincloudform.jsx
+++ b/src/views/login/logincloudform.jsx
@@ -2,17 +2,11 @@
 import PropTypes from 'prop-types'
 import { Form, Input } from 'antd'
 import { UserOutlined, LockOutlined } from '@ant-design/icons'
-import zhCN from '@/locales/zh-CN/login.js'
-import enUS from '@/locales/en-US/login.js'
 import './index.scss'
 
 class HeaderLoginForm extends Component {
   static propTpyes = {
     handleSubmit: PropTypes.func
-  }
-
-  state = {
-    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
   }
 
   handleConfirm = () => {
@@ -60,12 +54,12 @@
       <Form style={{margin: '0px 10px'}}>
         <Form.Item>
           {getFieldDecorator('cloudusername', {
-            rules: [{ required: true, message: this.state.dict['login.username.empty'] }],
+            rules: [{ required: true, message: '璇疯緭鍏ョ敤鎴峰悕' }],
             initialValue: '',
           })(
             <Input
               prefix={<UserOutlined style={{ color: 'rgba(0,0,0,.25)' }} />}
-              placeholder={this.state.dict['login.username']}
+              placeholder="鐢ㄦ埛鍚�"
               autoComplete="off"
               onPressEnter={(e) => {this.handleSubmit(e, 'cloudpassword')}}
             />
@@ -77,10 +71,10 @@
             rules: [
               {
                 required: true,
-                message: this.state.dict['login.password.empty'],
+                message: '璇疯緭鍏ュ瘑鐮�',
               }
             ]
-          })(<Input.Password onPressEnter={(e) => {this.handleSubmit(e, 'cloudusername')}} placeholder={this.state.dict['login.password']} prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />} />)}
+          })(<Input.Password onPressEnter={(e) => {this.handleSubmit(e, 'cloudusername')}} placeholder="瀵嗙爜" prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />} />)}
         </Form.Item>
       </Form>
     )
diff --git a/src/views/login/loginform.jsx b/src/views/login/loginform.jsx
index 33fca8a..4f4d150 100644
--- a/src/views/login/loginform.jsx
+++ b/src/views/login/loginform.jsx
@@ -21,11 +21,8 @@
     isDisabled: PropTypes.bool,
     handleSubmit: PropTypes.func,
     authLogin: PropTypes.func,
-    dict: PropTypes.object,
     auth: PropTypes.bool,
     authError: PropTypes.string,
-    touristLogin: PropTypes.bool,
-    lang: PropTypes.string,
     langList: PropTypes.array,
     loginWays: PropTypes.array
   }
@@ -42,7 +39,10 @@
     verdisabled: false,
     hasScan: false,
     timeout: false,
-    users: []
+    wayLabels: {},
+    dict: window.GLOB.dict,
+    users: [],
+    lang: sessionStorage.getItem('lang')
   }
 
   timer = null
@@ -51,9 +51,14 @@
   UNSAFE_componentWillMount () {
     const { loginWays } = this.props
     let remember = true
-    let _url = window.location.href.split('#')[0]
+
+    if (localStorage.getItem(window.location.href.split('#')[0] + 'users')) { // 杩囨浮
+      localStorage.setItem(window.GLOB.sysSign + 'users', localStorage.getItem(window.location.href.split('#')[0] + 'users'))
+      localStorage.setItem(window.GLOB.sysSign + 'remember', localStorage.getItem(window.location.href.split('#')[0] + 'remember'))
+      localStorage.removeItem(window.location.href.split('#')[0] + 'users')
+    }
     
-    if (localStorage.getItem(_url + 'remember') === 'false') {
+    if (localStorage.getItem(window.GLOB.sysSign + 'remember') === 'false') {
       remember = false
     }
     if (!window.GLOB.keepKey) {
@@ -63,28 +68,28 @@
     let smsId = ''
     let hasScan = false
     let _loginWays = []
+    let wayLabels = {app_scan: 'APP鎵爜', weixin_scan: '寰俊鎵爜', uname_pwd: '璐﹀彿鐧诲綍', sms_vcode: '鐭俊鐧诲綍'}
+
     loginWays.forEach(item => {
+      item.label = window.GLOB.dict[item.type] || wayLabels[item.type]
+      wayLabels[item.type] = item.label
       if (item.type === 'sms_vcode') {
-        item.label = '鐭俊鐧诲綍'
         smsId = item.smsId
         _loginWays.push(item)
       } else if (item.type === 'uname_pwd') {
-        item.label = '璐﹀彿鐧诲綍'
         _loginWays.push(item)
       } else if (item.type === 'app_scan') {
-        item.label = 'APP鎵爜'
         _loginWays.push(item)
         hasScan = true
       } else if (item.type === 'weixin_scan') {
-        item.label = '寰俊鎵爜'
         _loginWays.push(item)
         hasScan = true
       }
     })
 
     let activeKey = _loginWays[0].type
-
-    let users = localStorage.getItem(_url + 'users')
+    
+    let users = localStorage.getItem(window.GLOB.sysSign + 'users')
     let _user = null
     
     if (users) {
@@ -111,6 +116,7 @@
       scanId: activeKey === 'app_scan' || activeKey === 'weixin_scan' ? Utils.getuuid() : '',
       timeout: false,
       remember,
+      wayLabels,
       hasScan
     })
 
@@ -180,22 +186,20 @@
   }
 
   changelang = (val) => {
-    const _href = window.location.href.split('#')[0]
-    localStorage.setItem(_href + 'lang', val)
+    localStorage.setItem(window.location.href.split('#')[0] + 'lang', val)
     sessionStorage.setItem('lang', val)
 
     window.location.reload()
   }
 
   handleSubmit = e => {
-    const { activeKey } = this.state
+    const { activeKey, dict } = this.state
     // 鐧诲綍鍙傛暟妫�楠�
     e && e.preventDefault()
     if (!this.props.auth) {
       warning({
-        title: this.props.authError || this.props.dict['login.auth.tip'],
-        okText: this.props.dict['login.ok'],
-        cancelText: this.props.dict['login.cancel'],
+        title: this.props.authError || dict['auth_tip'] || '绯荤粺鏈巿鏉冿紝璇疯仈绯荤鐞嗗憳銆�',
+        okText: dict['got_it'] || '鐭ラ亾浜�',
         onOk() {},
         onCancel() {}
       })
@@ -275,16 +279,16 @@
   }
 
   getvercode = () => {
-    const { smsId } = this.state
+    const { smsId, dict } = this.state
     let _phone = this.props.form.getFieldValue('phone')
     if (!_phone) {
-      message.warning('璇疯緭鍏ユ墜鏈哄彿锛�')
+      message.warning(dict['phone_no_required'] || '璇疯緭鍏ユ墜鏈哄彿锛�')
       return
     } else if (!/^1[3456789]\d{9}$/.test(_phone)) {
-      message.warning('鎵嬫満鍙锋牸寮忛敊璇紝璇烽噸濉紒')
+      message.warning(dict['phone_error'] || '鎵嬫満鍙锋牸寮忛敊璇紝璇烽噸濉紒')
       return
-    } else if (!this.props.touristLogin) {
-      message.warning('鏈幏鍙栭獙璇佺爜璁剧疆锛岃绋嶅悗鎴栧埛鏂伴噸璇曪紒')
+    } else if (!sessionStorage.getItem('visitorUserID') || !sessionStorage.getItem('visitorLoginUID')) {
+      message.warning(dict['vercode_error'] || '鏈幏鍙栭獙璇佺爜璁剧疆锛岃绋嶅悗鎴栧埛鏂伴噸璇曪紒')
       return
     }
 
@@ -392,9 +396,8 @@
 
   rememberChange = (e) => {
     let val = e.target.checked
-    let _url = window.location.href.split('#')[0]
 
-    localStorage.setItem(_url + 'remember', val)
+    localStorage.setItem(window.GLOB.sysSign + 'remember', val)
   }
 
   complete = (val) => {
@@ -422,9 +425,7 @@
     
     this.setState({users: _users})
 
-    let _url = window.location.href.split('#')[0]
-
-    localStorage.setItem(_url + 'users', window.btoa(window.encodeURIComponent(JSON.stringify(_users))))
+    localStorage.setItem(window.GLOB.sysSign + 'users', window.btoa(window.encodeURIComponent(JSON.stringify(_users))))
   }
 
   /**
@@ -440,8 +441,7 @@
   render() {
     const { langList } = this.props
     const { getFieldDecorator } = this.props.form
-    const { activeKey, verdisabled, delay, loginWays, remember, scanId, timeout, hasScan, users } = this.state
-    const wayLabels = {app_scan: 'APP鎵爜', weixin_scan: '寰俊鎵爜', uname_pwd: '璐﹀彿鐧诲綍', sms_vcode: '鐭俊鐧诲綍'}
+    const { activeKey, verdisabled, delay, loginWays, remember, scanId, timeout, hasScan, users, wayLabels, dict, lang } = this.state
 
     return (
       <Form className="login-form" id="login-form" onSubmit={this.handleSubmit}>
@@ -450,7 +450,7 @@
         {activeKey === 'uname_pwd' ? <div className="form-item-wrap">
           <Form.Item>
             {getFieldDecorator('username', {
-              rules: [{ required: true, message: this.props.dict['login.username.empty'] }],
+              rules: [{ required: true, message: dict['username_required'] || '璇疯緭鍏ョ敤鎴峰悕' }],
               initialValue: this.state.username || '',
             })(
               <AutoComplete
@@ -467,7 +467,7 @@
               >
                 <Input
                   prefix={<UserOutlined style={{ color: 'rgba(0,0,0,.25)' }} />}
-                  placeholder={this.props.dict['login.username']}
+                  placeholder={dict['username'] || '鐢ㄦ埛鍚�'}
                   autoComplete="off"
                 />
               </AutoComplete>
@@ -479,20 +479,20 @@
               rules: [
                 {
                   required: true,
-                  message: this.props.dict['login.password.empty'],
+                  message: dict['password_required'] || '璇疯緭鍏ュ瘑鐮�',
                 }
               ]
-            })(<Input.Password placeholder={this.props.dict['login.password']} prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />} />)}
+            })(<Input.Password placeholder={dict['password'] || '瀵嗙爜'} prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />} />)}
           </Form.Item>
           {window.GLOB.keepKey ? <Form.Item className="minline">
             {getFieldDecorator('remember', {
               valuePropName: 'checked',
               initialValue: remember,
-            })(<Checkbox onChange={this.rememberChange}>{this.props.dict['login.remember']}</Checkbox>)}
+            })(<Checkbox onChange={this.rememberChange}>{dict['remember_me'] || '璁颁綇瀵嗙爜'}</Checkbox>)}
           </Form.Item> : <div style={{height: '30px', float: 'left'}}></div>}
           {langList && langList.length > 0 ? <Form.Item className="minline right">
             {getFieldDecorator('lang', {
-              initialValue: this.props.lang,
+              initialValue: lang,
             })(
               <Select
                 onChange={(value) => {this.changelang(value)}}
@@ -506,7 +506,7 @@
           </Form.Item> : null}
           <Form.Item className="btn-login">
             <Button type="primary" htmlType="submit" className="login-form-button" disabled={this.props.isDisabled} loading={this.props.isDisabled}>
-              {this.props.dict['login.submit']}
+              {dict['log_in'] || '鐧诲綍'}
             </Button>
           </Form.Item>
           {window.GLOB.sysType === 'cloud' && options.cdomain.indexOf('mk9h') > -1 ? <Form.Item className="register-line">
@@ -517,11 +517,11 @@
         {activeKey === 'sms_vcode' ? <div className="form-item-wrap">
           <Form.Item>
             {getFieldDecorator('phone', {
-              rules: [{ required: true, message: this.props.dict['login.phone.empty'] }],
+              rules: [{ required: true, message: dict['phone_no_required'] || '璇疯緭鍏ユ墜鏈哄彿' }],
               initialValue: '',
             })(
               <Input
-                placeholder={this.props.dict['login.phone']}
+                placeholder={dict['phone_no'] || '鎵嬫満鍙�'}
                 autoComplete="off"
               />
             )}
@@ -532,24 +532,24 @@
               rules: [
                 {
                   required: true,
-                  message: this.props.dict['login.vercode.empty'],
+                  message: dict['vercode_required'] || '璇疯緭鍏ラ獙璇佺爜',
                 }
               ]
             })(
               <Input
                 addonAfter={
                   <Button type="link" className="vercode" size="small" disabled={verdisabled} onClick={this.getvercode}>
-                    {delay ? `${delay}s鍚庨噸鏂拌幏鍙朻 : '鑾峰彇楠岃瘉鐮�'}
+                    {delay ? `${delay}s` : dict['query_vercode'] || '鑾峰彇楠岃瘉鐮�'}
                   </Button>
                 }
-                placeholder={this.props.dict['login.vercode']}
+                placeholder={dict['vercode'] || '楠岃瘉鐮�'}
                 autoComplete="off"
               />
             )}
           </Form.Item>
           {langList && langList.length > 0 ? <Form.Item className="minline right">
             {getFieldDecorator('lang', {
-              initialValue: this.props.lang,
+              initialValue: lang,
             })(
               <Select
                 onChange={(value) => {this.changelang(value)}}
@@ -563,7 +563,7 @@
           </Form.Item> : null}
           <Form.Item className="btn-login">
             <Button type="primary" htmlType="submit" className="login-form-button" disabled={this.props.isDisabled} loading={this.props.isDisabled}>
-              {this.props.dict['login.submit']}
+              {dict['log_in'] || '鐧诲綍'}
             </Button>
           </Form.Item>
           {window.GLOB.sysType === 'cloud' && options.cdomain.indexOf('mk9h') > -1 ? <Form.Item className="register-line">
@@ -577,10 +577,10 @@
               {scanId ? <QrCode card={{qrWidth: 500, color: '#000000'}} value={`https://cloud.mk9h.cn/mob/mknotice.html?originurl=${window.btoa(window.GLOB.baseurl + 'mob/index.html#/wx/' + scanId)}`}/> : null}
               {timeout ? <div className="qrcode-out">
                 <RedoOutlined onClick={this.reCode} />
-                浜岀淮鐮佸凡澶辨晥銆�
+                {dict['code_expired'] || '浜岀淮鐮佸凡澶辨晥銆�'}
               </div> : null}
             </div>
-            <img src={wxicon} alt=""/>璇蜂娇鐢ㄥ井淇℃壂涓�鎵櫥褰�
+            <img src={wxicon} alt=""/>{dict['wechat_scan'] || '璇蜂娇鐢ㄥ井淇℃壂涓�鎵櫥褰�'}
           </div>
         </div> : null}
         {activeKey === 'app_scan' ? <div className="form-item-wrap">
@@ -589,10 +589,10 @@
               {scanId ? <QrCode card={{qrWidth: 500, color: '#000000'}} value={`mkpcscan,${window.GLOB.appkey},${scanId}`}/> : null}
               {timeout ? <div className="qrcode-out">
                 <RedoOutlined onClick={this.reCode} />
-                浜岀淮鐮佸凡澶辨晥銆�
+                {dict['code_expired'] || '浜岀淮鐮佸凡澶辨晥銆�'}
               </div> : null}
             </div>
-            璇蜂娇鐢ㄥ鎴风鎵竴鎵櫥褰�
+            {dict['client_scan'] || '璇蜂娇鐢ㄥ鎴风鎵竴鎵櫥褰�'}
           </div>
         </div> : null}
         <div className={'login-ways ' + (activeKey === 'app_scan' || activeKey === 'weixin_scan' ? 'center' : '')}>
diff --git a/src/views/main/index.jsx b/src/views/main/index.jsx
index 8f64b52..8723ebc 100644
--- a/src/views/main/index.jsx
+++ b/src/views/main/index.jsx
@@ -1,7 +1,4 @@
 import React, {Component} from 'react'
-import { ConfigProvider } from 'antd'
-// import enUS from 'antd/es/locale/en_US'
-import zhCN from 'antd/es/locale/zh_CN'
 
 import asyncComponent from '@/utils/asyncComponent'
 import Header from '@/components/header'
@@ -76,14 +73,12 @@
 
     return (
       <div className="mk-main-view">
-        <ConfigProvider locale={zhCN}>
-          <Header key="header"/>
-          {navBar === 'shutter' ? <Sidemenu key="sidemenu"/> : null}
-          {navBar === 'shutter' || navBar === 'menu_board_navigation' ?
-            <Tabview key="tabview"/> :
-            <Breadview key="breadview"/>}
-          {window.GLOB.systemType === 'production' ? <QueryLog /> : null}
-        </ConfigProvider>
+        <Header key="header"/>
+        {navBar === 'shutter' ? <Sidemenu key="sidemenu"/> : null}
+        {navBar === 'shutter' || navBar === 'menu_board_navigation' ?
+          <Tabview key="tabview"/> :
+          <Breadview key="breadview"/>}
+        {window.GLOB.systemType === 'production' ? <QueryLog /> : null}
         <ImgScale />
       </div>
     )
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index ad11d1f..f453d28 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -4,16 +4,16 @@
 import { is, fromJS } from 'immutable'
 import moment from 'moment'
 import HTML5Backend from 'react-dnd-html5-backend'
-import { ConfigProvider, notification, Modal, Collapse, Card, Switch, Button, Typography, Spin } from 'antd'
+import { notification, Modal, Collapse, Card, Switch, Button, Typography, Spin } from 'antd'
 import { DoubleLeftOutlined, DoubleRightOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'
 import html2canvas from 'html2canvas'
 import md5 from 'md5'
 
 import Api from '@/api'
 import Utils, { setGLOBFuncs } from '@/utils/utils.js'
-import antdZhCN from 'antd/es/locale/zh_CN'
+import { langs } from '@/store/options'
 import MKEmitter from '@/utils/events.js'
-import { getTables, getFuncsAndInters } from '@/utils/utils-custom.js'
+import { getTables, getFuncsAndInters, getLangTrans } from '@/utils/utils-custom.js'
 import asyncComponent from '@/utils/asyncComponent'
 
 import '@/assets/css/design.scss'
@@ -22,7 +22,6 @@
 const { Panel } = Collapse
 const { confirm } = Modal
 const { Paragraph } = Typography
-const _locale = antdZhCN
 
 const MenuForm = asyncComponent(() => import('./menuform'))
 const HomeForm = asyncComponent(() => import('./homeform'))
@@ -67,6 +66,7 @@
     eyeopen: false,
     view: '',
     popConfig: null,
+    langName: '',
     needUpdate: false
   }
 
@@ -98,12 +98,17 @@
 
       sessionStorage.setItem('MenuType', param.MenuType || 'custom')
 
+      if (param.MenuType === 'billPrint' && param.lang) {
+        sessionStorage.setItem('lang', param.lang)
+      }
+
       this.setState({
         MenuType: param.MenuType,
         MenuId: param.MenuId || param.MenuID,
         ParentId: param.ParentId || '',
         MenuName: param.MenuName || '',
         MenuNo: param.MenuNo || '',
+        langName: sessionStorage.getItem('lang') !== 'zh-CN' && langs[sessionStorage.getItem('lang')] ? `锛�${langs[sessionStorage.getItem('lang')]}锛塦 : ''
       }, () => {
         this.getMenuParam()
       })
@@ -772,6 +777,18 @@
         duration: 5
       })
       return
+    } else if (this.checklog()) {
+      if (sessionStorage.getItem('langList') && !config.trans) {
+
+      } else {
+        notification.success({
+          top: 92,
+          message: '褰撳墠閰嶇疆鏈慨鏀癸紝鏃犻渶淇濆瓨銆�',
+          duration: 5
+        })
+        MKEmitter.emit('completeSave')
+        return
+      }
     }
 
     this.setState({
@@ -834,6 +851,7 @@
 
       let interfaces = getFuncsAndInters(config)
       let urlFields = config.urlFields ? config.urlFields.join(',') : ''
+      let langSql = getLangTrans(config)
 
       let param = {
         func: 'sPC_TrdMenu_AddUpt',
@@ -847,12 +865,16 @@
         MenuName: config.MenuName || '',
         PageParam: JSON.stringify({Template: 'CustomPage', OpenType: config.OpenType || 'newtab', hidden: config.hidden || 'false', menuColor: config.menuColor || '', interfaces, urlFields}),
         open_edition: config.open_edition,
-        LText: '',
-        LTexttb: '',
+        // LText: '',
+        // LTexttb: '',
         debug_md5: key,
         debug_url: url,
         debug_list: window.btoa(tbs),
         LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(config)))
+      }
+
+      if (langSql) {
+        param.lang_translation = window.btoa(window.encodeURIComponent(langSql))
       }
 
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
@@ -1185,11 +1207,11 @@
   }
 
   render () {
-    const { view, comloading, MenuType, MenuId, config, settingshow, ParentId, menuloading, eyeopen, needUpdate } = this.state
+    const { view, comloading, MenuType, MenuId, config, settingshow, ParentId, menuloading, eyeopen, needUpdate, langName } = this.state
 
     return (
-      <ConfigProvider locale={_locale}>
-        <Header menuName={config ? config.MenuName : ''}/>
+      <>
+        <Header menuName={config ? config.MenuName + langName : ''}/>
         <DndProvider backend={HTML5Backend}>
           {view !== 'popview' ? <div className={'pc-menu-view ' + (MenuType || '')}>
             <div className="menu-body">
@@ -1265,7 +1287,7 @@
         <ModalController />
         <StyleController />
         <StyleCombController />
-      </ConfigProvider>
+      </>
     )
   }
 }
diff --git a/src/views/mkiframe/index.jsx b/src/views/mkiframe/index.jsx
index b6e9761..329ef36 100644
--- a/src/views/mkiframe/index.jsx
+++ b/src/views/mkiframe/index.jsx
@@ -1,6 +1,5 @@
 import React, {Component} from 'react'
-import { Spin, notification, ConfigProvider } from 'antd'
-import zhCN from 'antd/es/locale/zh_CN'
+import { Spin, notification } from 'antd'
 
 import Api from '@/api'
 import asyncComponent from '@/utils/asyncLoadComponent'
@@ -267,11 +266,9 @@
 
     return (
       <div className="main-iframe">
-        <ConfigProvider locale={zhCN}>
-          {loading ? <Spin size="large" /> : null}
-          {!loading && type === 'CustomPage' ? <CustomPage MenuID={MenuId} param={{$BID: BID}} changeTemp={this.changeTemp}/> : null}
-          {!loading && type === 'BaseTable' ? <BaseTable MenuID={MenuId} param={{$BID: BID}} changeTemp={this.changeTemp}/> : null}
-        </ConfigProvider>
+        {loading ? <Spin size="large" /> : null}
+        {!loading && type === 'CustomPage' ? <CustomPage MenuID={MenuId} param={{$BID: BID}} changeTemp={this.changeTemp}/> : null}
+        {!loading && type === 'BaseTable' ? <BaseTable MenuID={MenuId} param={{$BID: BID}} changeTemp={this.changeTemp}/> : null}
         <ImgScale />
       </div>
     )
diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index b713e00..dbf4105 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -3,16 +3,15 @@
 import { withRouter } from 'react-router'
 import { is, fromJS } from 'immutable'
 import HTML5Backend from 'react-dnd-html5-backend'
-import { ConfigProvider, notification, Modal, Collapse, Switch, Button, message, Spin, Typography } from 'antd'
+import { notification, Modal, Collapse, Switch, Button, message, Spin, Typography } from 'antd'
 import { DoubleLeftOutlined, DoubleRightOutlined, HomeOutlined, LoginOutlined, ArrowLeftOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'
 import moment from 'moment'
 import md5 from 'md5'
 
 import Api from '@/api'
 import Utils, { setGLOBFuncs } from '@/utils/utils.js'
-import antdZhCN from 'antd/es/locale/zh_CN'
 import MKEmitter from '@/utils/events.js'
-import MenuUtils, { getTables, getFuncsAndInters } from '@/utils/utils-custom.js'
+import MenuUtils, { getTables, getFuncsAndInters, getLangTrans } from '@/utils/utils-custom.js'
 import asyncComponent from '@/utils/asyncComponent'
 
 import '@/assets/css/design.scss'
@@ -99,11 +98,14 @@
 
     try {
       let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
+      
+      if (param.lang) {
+        sessionStorage.setItem('lang', param.lang)
+      }
 
       if (param.type === 'app') {
         sessionStorage.setItem('appId', param.ID || '')
         sessionStorage.setItem('appName', param.remark || '')
-        sessionStorage.setItem('lang', param.lang || 'zh-CN')
         sessionStorage.setItem('kei_no', param.kei_no || '')
         sessionStorage.setItem('typename', param.typename || 'mob')
         sessionStorage.setItem('adapter', param.adapter || '')
@@ -111,6 +113,12 @@
         sessionStorage.setItem('direction', param.direction || 'vertical')
         sessionStorage.setItem('userbind', param.userbind || '')
         sessionStorage.setItem('instantMessage', param.instantMessage || '')
+
+        if (param.applangList) {
+          sessionStorage.setItem('applangList', param.applangList)
+        } else {
+          sessionStorage.removeItem('applangList')
+        }
 
         this.getAppMessage(param.MenuID)
       } else if (param.type === 'view') {
@@ -390,7 +398,8 @@
       MenuID: menu.MenuID,
       copyMenuId: menu.copyMenuId || '',
       clearMenu: menu.clearMenu !== 'false',
-      type: 'view'
+      type: 'view',
+      lang: sessionStorage.getItem('lang')
     }
 
     param.MenuNo = menu.MenuNo || ''
@@ -463,12 +472,12 @@
             })
           } else {
             sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
-            this.props.history.replace('/mobdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: homeId, type: 'view'}))))
+            this.props.history.replace('/mobdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: homeId, type: 'view', lang: sessionStorage.getItem('lang')}))))
           }
         })
       } else {
         sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
-        this.props.history.replace('/mobdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: MenuID || homeId, type: 'view'}))))
+        this.props.history.replace('/mobdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: MenuID || homeId, type: 'view', lang: sessionStorage.getItem('lang')}))))
       }
     })
   }
@@ -1406,6 +1415,18 @@
         activeKey: 'basedata'
       })
       return
+    } else if (this.checklog()) {
+      if (sessionStorage.getItem('applangList') && !config.trans) {
+
+      } else {
+        notification.success({
+          top: 92,
+          message: '褰撳墠閰嶇疆鏈慨鏀癸紝鏃犻渶淇濆瓨銆�',
+          duration: 5
+        })
+        MKEmitter.emit('completeSave')
+        return
+      }
     }
 
     this.setState({
@@ -1509,6 +1530,7 @@
 
       let interfaces = getFuncsAndInters(config)
       roleParam.interfaces = interfaces
+      let langSql = getLangTrans(config)
 
       let param = {
         func: 'sPC_TrdMenu_AddUpt',
@@ -1525,12 +1547,16 @@
         PageParam: JSON.stringify({Template: 'webPage', interfaces}),
         open_edition: config.open_edition,
         menus_rolelist: window.btoa(window.encodeURIComponent(JSON.stringify(roleParam))),
-        LText: '',
-        LTexttb: '',
+        // LText: '',
+        // LTexttb: '',
         menus_used_list,
         debug_md5: key,
         debug_url: url,
         debug_list: window.btoa(tbs)
+      }
+
+      if (langSql) {
+        param.lang_translation = window.btoa(window.encodeURIComponent(langSql))
       }
 
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
@@ -1594,8 +1620,8 @@
               PageParam: JSON.stringify({Template: NavBar.type}),
               open_edition: _item ? (_item.open_edition || '') : '',
               menus_rolelist: window.btoa(window.encodeURIComponent(JSON.stringify(roles))),
-              LText: '',
-              LTexttb: ''
+              // LText: '',
+              // LTexttb: ''
             }
 
             _param.LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(NavBar)))
@@ -2048,92 +2074,90 @@
     const { view, viewType, comloading, loading, settingshow, controlshow, activeKey, MenuId, config, menuloading, adapters, eyeopen, needUpdate } = this.state
 
     return (
-      <ConfigProvider locale={antdZhCN}>
-        <div className={'mk-mob-view ' + viewType} id="mk-mob-design-view">
-          <Header/>
-          {loading ? <Spin className="view-spin" size="large" /> : null}
-          <DndProvider backend={HTML5Backend}>
-            {view !== 'popview' ? <><div className={'menu-setting ' + (!settingshow ? 'hidden' : '')}>
-              <div className="draw">
-                {settingshow ? <DoubleLeftOutlined onClick={() => {this.setState({settingshow: false})}} /> : null}
-                {!settingshow ? <DoubleRightOutlined onClick={() => {this.setState({settingshow: true})}} /> : null}
-              </div>
-              <div className="pc-setting-tools">
-                <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
-                  {/* 鍩烘湰淇℃伅 */}
-                  <Panel header="鍩烘湰淇℃伅" forceRender className="basedata" key="basedata">
-                    {config ? <>
-                      <MenuForm
-                        config={config}
-                        MenuId={MenuId}
-                        adapters={adapters}
-                        updateConfig={(con) => {
-                          this.updateConfig(con)
-                          if (con.direction !== config.direction) {
-                            this.changeView(con.direction)
-                          }
-                        }}
-                      />
-                      <UrlFieldComponent config={config} updateConfig={this.updateConfig}/>
-                      {/* 琛ㄥ悕娣诲姞 */}
-                      <TableComponent config={config} updatetable={this.updateConfig}/>
-                      <Paragraph style={{padding: '15px 0px 0px 18px'}} copyable={{ text: MenuId }}>鑿滃崟ID</Paragraph>
-                      <Paragraph style={{padding: '10px 0px 0px 18px'}} copyable={{ text:  `${window.GLOB.baseurl}mob/index.html#/index/${sessionStorage.getItem('kei_no')}/${sessionStorage.getItem('typename')}/${sessionStorage.getItem('lang')}/${MenuId}/@BID@` }}>鑿滃崟閾炬帴</Paragraph>
-                      <NormalCss config={config} updateConfig={this.updateConfig}/>
-                    </> : null}
-                  </Panel>
-                  {/* 缁勪欢娣诲姞 */}
-                  <Panel header="缁勪欢" className="component" key="component">
-                    <SourceWrap />
-                  </Panel>
-                  <Panel header="鍏冪礌" key="element">
-                    <Modulecell />
-                  </Panel>
-                  <Panel header="椤甸潰鏍峰紡" key="background">
-                    {config ? <BgController config={config} updateConfig={this.updateConfig} /> : null}
-                  </Panel>
-                </Collapse>
-              </div>
+      <div className={'mk-mob-view ' + viewType} id="mk-mob-design-view">
+        <Header/>
+        {loading ? <Spin className="view-spin" size="large" /> : null}
+        <DndProvider backend={HTML5Backend}>
+          {view !== 'popview' ? <><div className={'menu-setting ' + (!settingshow ? 'hidden' : '')}>
+            <div className="draw">
+              {settingshow ? <DoubleLeftOutlined onClick={() => {this.setState({settingshow: false})}} /> : null}
+              {!settingshow ? <DoubleRightOutlined onClick={() => {this.setState({settingshow: true})}} /> : null}
             </div>
-            <div className={'menu-control' + (!controlshow ? ' hidden' : '')}>
-              <div className="draw">
-                {controlshow ? <DoubleRightOutlined onClick={() => {this.setState({controlshow: false})}}/> : null}
-                {!controlshow ? <DoubleLeftOutlined onClick={() => {this.setState({controlshow: true})}}/> : null}
-              </div>
-              <div className="wrap">
-                <Button type="primary" className={needUpdate ? 'update-tip' : ''} onClick={this.submitConfig} id="save-config" loading={menuloading}>淇濆瓨</Button>
-                {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
-                <ArrowLeftOutlined title="鍚庨��" className="back-view" onClick={this.backView}/>
-                {config ? <Debug config={config}/> : null}
-                <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 缁勪欢鍚�</Button>
-                <CreateView resetmenu={this.getAppMenus} />
-                <PasteController insert={this.insert} />
-                <TableNodes config={config} />
-                <ViewNodes config={config} MenuId={MenuId}/>
-                <SysInterface config={config} updateConfig={this.updateConfig}/>
-                <PictureController/>
-                <Quotecomponent config={config} updateConfig={this.updateConfig}/>
-                <StyleCombControlButton menu={config} />
-                <Button className="mk-border-green set-home" onClick={this.setHomeView}><HomeOutlined /> 璁句负棣栭〉</Button>
-                <Button className="mk-border-purple set-login" onClick={this.setLoginView}><LoginOutlined /> 璁句负鐧诲綍椤�</Button>
-                <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
-                <Transfer MenuID={MenuId} />
-                {config ? <Versions MenuId={MenuId} Template="webPage" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
-                <Button type="default" onClick={this.closeView}>鍏抽棴</Button>
-              </div>
+            <div className="pc-setting-tools">
+              <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
+                {/* 鍩烘湰淇℃伅 */}
+                <Panel header="鍩烘湰淇℃伅" forceRender className="basedata" key="basedata">
+                  {config ? <>
+                    <MenuForm
+                      config={config}
+                      MenuId={MenuId}
+                      adapters={adapters}
+                      updateConfig={(con) => {
+                        this.updateConfig(con)
+                        if (con.direction !== config.direction) {
+                          this.changeView(con.direction)
+                        }
+                      }}
+                    />
+                    <UrlFieldComponent config={config} updateConfig={this.updateConfig}/>
+                    {/* 琛ㄥ悕娣诲姞 */}
+                    <TableComponent config={config} updatetable={this.updateConfig}/>
+                    <Paragraph style={{padding: '15px 0px 0px 18px'}} copyable={{ text: MenuId }}>鑿滃崟ID</Paragraph>
+                    <Paragraph style={{padding: '10px 0px 0px 18px'}} copyable={{ text:  `${window.GLOB.baseurl}mob/index.html#/index/${sessionStorage.getItem('kei_no')}/${sessionStorage.getItem('typename')}/${sessionStorage.getItem('lang')}/${MenuId}/@BID@` }}>鑿滃崟閾炬帴</Paragraph>
+                    <NormalCss config={config} updateConfig={this.updateConfig}/>
+                  </> : null}
+                </Panel>
+                {/* 缁勪欢娣诲姞 */}
+                <Panel header="缁勪欢" className="component" key="component">
+                  <SourceWrap />
+                </Panel>
+                <Panel header="鍏冪礌" key="element">
+                  <Modulecell />
+                </Panel>
+                <Panel header="椤甸潰鏍峰紡" key="background">
+                  {config ? <BgController config={config} updateConfig={this.updateConfig} /> : null}
+                </Panel>
+              </Collapse>
             </div>
-            <div className={'menu-body menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}>
-              {config && !comloading ? <div className="mob-shell" style={{width: window.GLOB.shellWidth, height: window.GLOB.shellHeight}}>
-                <MobShell menu={config} handleList={this.updateConfig} />
-              </div> : null}
-            </div></> : <PopView btn={this.state.popConfig} save={this.submitPopConfig} cancel={this.closePop}/>}
-          </DndProvider>
-          <StyleController />
-          <StyleCombController />
-          <ModalController />
-          <SearchController />
-        </div>
-      </ConfigProvider>
+          </div>
+          <div className={'menu-control' + (!controlshow ? ' hidden' : '')}>
+            <div className="draw">
+              {controlshow ? <DoubleRightOutlined onClick={() => {this.setState({controlshow: false})}}/> : null}
+              {!controlshow ? <DoubleLeftOutlined onClick={() => {this.setState({controlshow: true})}}/> : null}
+            </div>
+            <div className="wrap">
+              <Button type="primary" className={needUpdate ? 'update-tip' : ''} onClick={this.submitConfig} id="save-config" loading={menuloading}>淇濆瓨</Button>
+              {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
+              <ArrowLeftOutlined title="鍚庨��" className="back-view" onClick={this.backView}/>
+              {config ? <Debug config={config}/> : null}
+              <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 缁勪欢鍚�</Button>
+              <CreateView resetmenu={this.getAppMenus} />
+              <PasteController insert={this.insert} />
+              <TableNodes config={config} />
+              <ViewNodes config={config} MenuId={MenuId}/>
+              <SysInterface config={config} updateConfig={this.updateConfig}/>
+              <PictureController/>
+              <Quotecomponent config={config} updateConfig={this.updateConfig}/>
+              <StyleCombControlButton menu={config} />
+              <Button className="mk-border-green set-home" onClick={this.setHomeView}><HomeOutlined /> 璁句负棣栭〉</Button>
+              <Button className="mk-border-purple set-login" onClick={this.setLoginView}><LoginOutlined /> 璁句负鐧诲綍椤�</Button>
+              <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
+              <Transfer MenuID={MenuId} />
+              {config ? <Versions MenuId={MenuId} Template="webPage" checklog={this.checklog} updateConfig={this.updateLogConfig}/> : null}
+              <Button type="default" onClick={this.closeView}>鍏抽棴</Button>
+            </div>
+          </div>
+          <div className={'menu-body menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}>
+            {config && !comloading ? <div className="mob-shell" style={{width: window.GLOB.shellWidth, height: window.GLOB.shellHeight}}>
+              <MobShell menu={config} handleList={this.updateConfig} />
+            </div> : null}
+          </div></> : <PopView btn={this.state.popConfig} save={this.submitPopConfig} cancel={this.closePop}/>}
+        </DndProvider>
+        <StyleController />
+        <StyleCombController />
+        <ModalController />
+        <SearchController />
+      </div>
     )
   }
 }
diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx
index 63ef5fb..b1abf07 100644
--- a/src/views/pcdesign/index.jsx
+++ b/src/views/pcdesign/index.jsx
@@ -3,15 +3,14 @@
 import { withRouter } from 'react-router'
 import { is, fromJS } from 'immutable'
 import HTML5Backend from 'react-dnd-html5-backend'
-import { ConfigProvider, notification, Modal, Collapse, Switch, Button, message, Spin, Typography } from 'antd'
+import { notification, Modal, Collapse, Switch, Button, message, Spin, Typography } from 'antd'
 import { DoubleLeftOutlined, DoubleRightOutlined, HomeOutlined, LoginOutlined, ArrowLeftOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'
 import moment from 'moment'
 import md5 from 'md5'
 
 import Api from '@/api'
 import Utils, { setGLOBFuncs } from '@/utils/utils.js'
-import { getTables, getFuncsAndInters } from '@/utils/utils-custom.js'
-import antdZhCN from 'antd/es/locale/zh_CN'
+import { getTables, getFuncsAndInters, getLangTrans } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import MenuUtils from '@/utils/utils-custom.js'
 import asyncComponent from '@/utils/asyncComponent'
@@ -100,12 +99,21 @@
     try {
       let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
 
+      if (param.lang) {
+        sessionStorage.setItem('lang', param.lang)
+      }
+
       if (param.type === 'app') {
         sessionStorage.setItem('appId', param.ID || '')
         sessionStorage.setItem('appName', param.remark || '')
-        sessionStorage.setItem('lang', param.lang || 'zh-CN')
         sessionStorage.setItem('kei_no', param.kei_no || '')
         sessionStorage.setItem('sysBgColor', param.sysBgColor || '#ffffff')
+
+        if (param.applangList) {
+          sessionStorage.setItem('applangList', param.applangList)
+        } else {
+          sessionStorage.removeItem('applangList')
+        }
 
         this.getAppMessage(param.MenuID)
       } else if (param.type === 'view') {
@@ -240,7 +248,8 @@
       MenuID: menu.MenuID,
       copyMenuId: menu.copyMenuId || '',
       clearMenu: menu.clearMenu !== 'false',
-      type: 'view'
+      type: 'view',
+      lang: sessionStorage.getItem('lang')
     }
 
     // param.MenuNo = menu.MenuNo || ''
@@ -316,12 +325,12 @@
             })
           } else {
             sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
-            this.props.history.replace('/pcdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: homeId, type: 'view'}))))
+            this.props.history.replace('/pcdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: homeId, type: 'view', lang: sessionStorage.getItem('lang')}))))
           }
         })
       } else {
         sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
-        this.props.history.replace('/pcdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: MenuID || homeId, type: 'view'}))))
+        this.props.history.replace('/pcdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: MenuID || homeId, type: 'view', lang: sessionStorage.getItem('lang')}))))
       }
     })
   }
@@ -1140,6 +1149,18 @@
 
     if (!this.checkBase()) {
       return
+    } else if (this.checklog()) {
+      if (sessionStorage.getItem('applangList') && !config.trans) {
+
+      } else {
+        notification.success({
+          top: 92,
+          message: '褰撳墠閰嶇疆鏈慨鏀癸紝鏃犻渶淇濆瓨銆�',
+          duration: 5
+        })
+        MKEmitter.emit('completeSave')
+        return
+      }
     }
 
     this.setState({
@@ -1208,6 +1229,7 @@
 
       let interfaces = getFuncsAndInters(config)
       roleParam.interfaces = interfaces
+      let langSql = getLangTrans(config)
 
       let param = {
         func: 'sPC_TrdMenu_AddUpt',
@@ -1224,12 +1246,16 @@
         PageParam: JSON.stringify({Template: 'webPage', interfaces}),
         menus_rolelist: window.btoa(window.encodeURIComponent(JSON.stringify(roleParam))),
         open_edition: config.open_edition,
-        LText: '',
-        LTexttb: '',
+        // LText: '',
+        // LTexttb: '',
         menus_used_list,
         debug_md5: key,
         debug_url: url,
         debug_list: window.btoa(tbs)
+      }
+
+      if (langSql) {
+        param.lang_translation = window.btoa(window.encodeURIComponent(langSql))
       }
 
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
@@ -1310,8 +1336,8 @@
               PageParam: JSON.stringify({Template: NavBar.type}),
               menus_rolelist: window.btoa(window.encodeURIComponent(JSON.stringify(roles))),
               open_edition: NavBar.open_edition,
-              LText: '',
-              LTexttb: ''
+              // LText: '',
+              // LTexttb: ''
             }
 
             _param.LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(NavBar)))
@@ -1696,7 +1722,7 @@
     const { view, loading, comloading, activeKey, settingshow, controlshow, MenuId, config, menuloading, eyeopen, needUpdate } = this.state
 
     return (
-      <ConfigProvider locale={antdZhCN}>
+      <>
         <DndProvider backend={HTML5Backend}>
           {view !== 'popview' ? <div className={'mk-pc-view '} id="mk-pc-design-view">
             {loading ? <Spin className="view-spin" size="large" /> : null}
@@ -1773,7 +1799,7 @@
         <StyleController />
         <StyleCombController />
         <ModalController />
-      </ConfigProvider>
+      </>
     )
   }
 }
diff --git a/src/views/printTemplate/index.jsx b/src/views/printTemplate/index.jsx
index 8f72e0c..75783b8 100644
--- a/src/views/printTemplate/index.jsx
+++ b/src/views/printTemplate/index.jsx
@@ -20,6 +20,7 @@
   qrurl,
   imgurl
 } from './option.js'
+import { langs } from '@/store/options'
 import Utils from '@/utils/utils.js'
 import printCtrl from './print.js'
 import Api from '@/api'
@@ -35,7 +36,9 @@
 class PrintTemplate extends Component {
   state = {
     config: null,
+    oriConfig: null,
     ID: null,
+    langName: '',
     editItemId: '',
     editItemType: '',
     fields: [],
@@ -67,16 +70,24 @@
   }
 
   UNSAFE_componentWillMount () {
-    let _param = window.atob(this.props.match.params.param)
-    let _params = {}
-    _param.split('&').forEach(cell => {
-      let _cell = cell.split('=')
-      _params[_cell[0]] = _cell[1]
-    })
+    try {
+      let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
 
-    this.setState({
-      ID: _params.ID
-    })
+      if (param.lang) {
+        sessionStorage.setItem('lang', param.lang)
+      }
+
+      this.setState({
+        langName: sessionStorage.getItem('lang') !== 'zh-CN' && langs[sessionStorage.getItem('lang')] ? `锛�${langs[sessionStorage.getItem('lang')]}锛塦 : '',
+        ID: param.ID
+      })
+    } catch (e) {
+      notification.warning({
+        top: 92,
+        message: '妯℃澘淇℃伅瑙f瀽閿欒锛�',
+        duration: 5
+      })
+    }
   }
 
   componentDidMount () {
@@ -88,7 +99,7 @@
       let cy = position.cy
       let _selectItem = null
 
-      let _config = JSON.parse(JSON.stringify(this.state.config))
+      let _config = fromJS(this.state.config).toJS()
 
       _config.elements.forEach(element => {
         let x = +element.left
@@ -156,8 +167,8 @@
         return
       }
 
-      let _selectItem = JSON.parse(JSON.stringify(this.state.config.elements.filter(ele => ele.uuid === this.state.editItemId)[0]))
-      let _preItem = JSON.parse(JSON.stringify(_selectItem))
+      let _selectItem = fromJS(this.state.config.elements.filter(ele => ele.uuid === this.state.editItemId)[0]).toJS()
+      let _preItem = fromJS(_selectItem).toJS()
 
       let position = this.getclickpoint(e)
       let cx = position.cx
@@ -214,7 +225,7 @@
               let result = this.resetItem(_selectItem)
 
               if (!is(fromJS(result), fromJS(_preItem))) {
-                _preItem = JSON.parse(JSON.stringify(result))
+                _preItem = fromJS(result).toJS()
                 this.FormRef.resetForm(result)
 
                 config.elements = config.elements.map(item => {
@@ -261,7 +272,7 @@
               let result = this.resetItem(fromJS(_selectItem).toJS())
 
               if (!is(fromJS(result), fromJS(_preItem))) {
-                _preItem = JSON.parse(JSON.stringify(result))
+                _preItem = fromJS(result).toJS()
                 this.FormRef.resetForm(result)
 
                 config.elements = config.elements.map(item => {
@@ -407,6 +418,7 @@
       this.handleResize()
       this.setState({
         config: _config,
+        oriConfig: fromJS(_config).toJS(),
         editItemId: _config.uuid,
         editItemType: _config.type,
         formlist: getpageform(_config)
@@ -779,9 +791,16 @@
   }
 
   submitConfig = () => {
-    const { config } = this.state
+    const { config, oriConfig } = this.state
 
-    if (config.height / config.width > 10 || config.width / config.height > 10) {
+    if (is(fromJS(config), fromJS(oriConfig))) {
+      notification.success({
+        top: 92,
+        message: '褰撳墠妯℃澘鏈慨鏀癸紝鏃犻渶淇濆瓨銆�',
+        duration: 5
+      })
+      return
+    } else if (config.height / config.width > 10 || config.width / config.height > 10) {
       notification.warning({
         top: 92,
         message: '绾稿紶绾垫í姣斾笉鍙秴杩�10!',
@@ -878,6 +897,7 @@
         })
       }
       this.setState({
+        oriConfig: fromJS(config).toJS(),
         saveloading: false
       })
     })
@@ -950,13 +970,13 @@
   }
 
   render () {
-    const { debug } = this.state
+    const { debug, langName } = this.state
     
     return (
       <div className="print-template">
         <DndProvider backend={HTML5Backend}>
           <header className="print-header-container ant-menu-dark">
-            妯℃澘鍒朵綔
+            妯℃澘鍒朵綔{langName}
             <div>蹇嵎閿細Delete锛堝垹闄ゅ厓绱狅級銆乧trl + q锛堝鍒跺厓绱狅級</div>
           </header>
           <aside className="tools">
diff --git a/src/views/rolemanage/index.jsx b/src/views/rolemanage/index.jsx
index cd23aaa..e030560 100644
--- a/src/views/rolemanage/index.jsx
+++ b/src/views/rolemanage/index.jsx
@@ -1,9 +1,8 @@
 import React, {Component} from 'react'
 import { fromJS } from 'immutable'
-import { Spin, notification, Button, Table, Modal, ConfigProvider, Tree, Input, Empty } from 'antd'
+import { Spin, notification, Button, Table, Modal, Tree, Input, Empty } from 'antd'
 import moment from 'moment'
 import md5 from 'md5'
-import zhCN from 'antd/es/locale/zh_CN'
 import { ApiOutlined } from '@ant-design/icons'
 
 import Api from '@/api'
@@ -83,6 +82,10 @@
   UNSAFE_componentWillMount() {
     document.body.className = ''
     let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
+
+    if (param.lang) {
+      sessionStorage.setItem('lang', param.lang)
+    }
 
     this.setState({app: param}, () => {
       this.getTreeList()
@@ -916,61 +919,59 @@
 
     return (
       <div className="mk-role-manage">
-        <ConfigProvider locale={zhCN}>
-          <Header app={app} />
-          {loading ?
-            <div className="loading-mask">
-              <Spin size="large" />
-            </div> : null
-          }
-          <div className="view-wrap">
-            <div className="left-view">
-              <div className="app-table">
-                <div className="app-action">
-                  <Button className="mk-green" onClick={this.triggerThaw}>瑙e喕鑿滃崟</Button>
-                  <Search placeholder="缁煎悎鎼滅储" onSearch={value => this.setState({ searchkey: value })} enterButton />
-                </div>
-                <Table
-                  rowKey="MenuID"
-                  columns={columns}
-                  dataSource={_menulist}
-                  pagination={false}
-                  onChange={this.changeTable}
-                />
-              </div>
-            </div>
-            <div className="right-view">
+        <Header app={app} />
+        {loading ?
+          <div className="loading-mask">
+            <Spin size="large" />
+          </div> : null
+        }
+        <div className="view-wrap">
+          <div className="left-view">
+            <div className="app-table">
               <div className="app-action">
-                <Button className="mk-primary" onClick={this.initTree}>閲嶇疆</Button>
-                {/* <Button className="mk-purple" onClick={this.syncTree}>鍚屾</Button> */}
-                <Button className="mk-green save" onClick={this.saveTree}>淇濆瓨</Button>
+                <Button className="mk-green" onClick={this.triggerThaw}>瑙e喕鑿滃崟</Button>
+                <Search placeholder="缁煎悎鎼滅储" onSearch={value => this.setState({ searchkey: value })} enterButton />
               </div>
-              {trees && trees.length ? <Tree
-                className="draggable-tree"
-                defaultExpandedKeys={this.state.expandedKeys}
-                // showLine
-                draggable
-                blockNode
-                onDrop={this.onDrop}
-              >
-                {this.renderNode(trees)}
-              </Tree> : <div className="empty">
-                <Empty />
-              </div>}
+              <Table
+                rowKey="MenuID"
+                columns={columns}
+                dataSource={_menulist}
+                pagination={false}
+                onChange={this.changeTable}
+              />
             </div>
           </div>
-          <Modal
-            title="瑙i櫎鍐荤粨"
-            visible={this.state.visible}
-            width={600}
-            onOk={this.thawSubmit}
-            confirmLoading={this.state.confirmLoading}
-            onCancel={() => this.setState({visible: false, targetKeys: []})}
-            destroyOnClose
-          >
-            <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={this.state.thawmenulist}/>
-          </Modal>
-        </ConfigProvider>
+          <div className="right-view">
+            <div className="app-action">
+              <Button className="mk-primary" onClick={this.initTree}>閲嶇疆</Button>
+              {/* <Button className="mk-purple" onClick={this.syncTree}>鍚屾</Button> */}
+              <Button className="mk-green save" onClick={this.saveTree}>淇濆瓨</Button>
+            </div>
+            {trees && trees.length ? <Tree
+              className="draggable-tree"
+              defaultExpandedKeys={this.state.expandedKeys}
+              // showLine
+              draggable
+              blockNode
+              onDrop={this.onDrop}
+            >
+              {this.renderNode(trees)}
+            </Tree> : <div className="empty">
+              <Empty />
+            </div>}
+          </div>
+        </div>
+        <Modal
+          title="瑙i櫎鍐荤粨"
+          visible={this.state.visible}
+          width={600}
+          onOk={this.thawSubmit}
+          confirmLoading={this.state.confirmLoading}
+          onCancel={() => this.setState({visible: false, targetKeys: []})}
+          destroyOnClose
+        >
+          <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={this.state.thawmenulist}/>
+        </Modal>
       </div>
     )
   }
diff --git a/src/views/sso/index.jsx b/src/views/sso/index.jsx
index 5b11539..007b51d 100644
--- a/src/views/sso/index.jsx
+++ b/src/views/sso/index.jsx
@@ -66,8 +66,6 @@
           res.menu_type = 'shutter'
         }
 
-        const _href = window.location.href.split('#')[0]
-        let _url = _href + 'system'
         let systemMsg = {
           favicon: res.titlelogo || '',
           platTitle: res.titleName || '',
@@ -103,12 +101,12 @@
           level = ''
         }
 
-        localStorage.setItem(_href + 'pwdlevel', level)
+        localStorage.setItem(window.GLOB.sysSign + 'pwdlevel', level)
 
         if (res.srcid) {
-          localStorage.setItem(_href + 'srcId', res.srcid)
+          localStorage.setItem(window.GLOB.sysSign + 'srcId', res.srcid)
         } else {
-          localStorage.removeItem(_href + 'srcId')
+          localStorage.removeItem(window.GLOB.sysSign + 'srcId')
         }
 
         sessionStorage.setItem('home_background', res.index_background_color || '')
@@ -123,9 +121,9 @@
         document.title = systemMsg.platTitle
 
         try {
-          localStorage.setItem(_url, window.btoa(window.encodeURIComponent(JSON.stringify(systemMsg))))
+          localStorage.setItem(window.GLOB.sysSign + 'system', window.btoa(window.encodeURIComponent(JSON.stringify(systemMsg))))
         } catch (e) {
-          localStorage.removeItem(_url)
+          localStorage.removeItem(window.GLOB.sysSign + 'system')
         }
 
         window.GLOB.mainlogo = systemMsg.mainlogo
diff --git a/src/views/systemfunc/index.jsx b/src/views/systemfunc/index.jsx
index 9c33163..179eb01 100644
--- a/src/views/systemfunc/index.jsx
+++ b/src/views/systemfunc/index.jsx
@@ -1,7 +1,5 @@
 import React, {Component} from 'react'
-import { ConfigProvider } from 'antd'
 import { withRouter } from 'react-router-dom'
-import zhCN from 'antd/es/locale/zh_CN'
 
 import asyncComponent from '@/utils/asyncComponent'
 import Header from './header'
@@ -59,11 +57,9 @@
   render () {
     return (
       <div className="mk-main-view">
-        <ConfigProvider locale={zhCN}>
-          <Sidemenu key="sidemenu"/>
-          <Tabview key="tabview"/>
-          <Header key="header"/>
-        </ConfigProvider>
+        <Sidemenu key="sidemenu"/>
+        <Tabview key="tabview"/>
+        <Header key="header"/>
         <ImgScale />
       </div>
     )
diff --git a/src/views/systemfunc/sidemenu/config.jsx b/src/views/systemfunc/sidemenu/config.jsx
index ce7475b..058481e 100644
--- a/src/views/systemfunc/sidemenu/config.jsx
+++ b/src/views/systemfunc/sidemenu/config.jsx
@@ -84,6 +84,14 @@
     MenuID: '15827879285193g85m3i2uprektpgmpf',
     MenuNo: 'bd_mes_techM',
     MenuName: '宸ヨ壓涓绘暟鎹�',
+  }, {
+    src: '',
+    systems: ['local'],
+    PageParam: {OpenType: 'newtab', Template: 'CustomPage'},
+    type: 'CustomPage',
+    MenuID: '17180925258436em38rhpqncckvohv0s',
+    MenuNo: 's_app_lang_translation_M',
+    MenuName: '璇█鍖�',
   }]
 }, {
   MenuID: 'systemManageViewInterface',
diff --git a/src/views/systemproc/index.jsx b/src/views/systemproc/index.jsx
index 9f1f68a..d6bf70e 100644
--- a/src/views/systemproc/index.jsx
+++ b/src/views/systemproc/index.jsx
@@ -1,7 +1,5 @@
 import React, {Component} from 'react'
-import { ConfigProvider } from 'antd'
 import { withRouter } from 'react-router-dom'
-import zhCN from 'antd/es/locale/zh_CN'
 
 import Header from '../systemfunc/header'
 import Proc from './proc'
@@ -20,10 +18,8 @@
 
     return (
       <div className="mk-proc-view">
-        <ConfigProvider locale={zhCN}>
-          <Header key="header"/>
-          <Proc func={func} />
-        </ConfigProvider>
+        <Header key="header"/>
+        <Proc func={func} />
       </div>
     )
   }
diff --git a/src/views/tabledesign/index.jsx b/src/views/tabledesign/index.jsx
index 3880a3d..6dd9642 100644
--- a/src/views/tabledesign/index.jsx
+++ b/src/views/tabledesign/index.jsx
@@ -4,15 +4,15 @@
 import { is, fromJS } from 'immutable'
 import moment from 'moment'
 import HTML5Backend from 'react-dnd-html5-backend'
-import { ConfigProvider, notification, Modal, Collapse, Card, Switch, Button, Typography } from 'antd'
+import { notification, Modal, Collapse, Card, Switch, Button, Typography } from 'antd'
 import { DoubleLeftOutlined, DoubleRightOutlined } from '@ant-design/icons'
 import md5 from 'md5'
 
 import Api from '@/api'
 import Utils, { setGLOBFuncs } from '@/utils/utils.js'
-import antdZhCN from 'antd/es/locale/zh_CN'
+import { langs } from '@/store/options'
 import MKEmitter from '@/utils/events.js'
-import { getTables, getFuncsAndInters } from '@/utils/utils-custom.js'
+import { getTables, getFuncsAndInters, getLangTrans } from '@/utils/utils-custom.js'
 import SourceElement from '@/templates/zshare/dragsource'
 import asyncComponent from '@/utils/asyncComponent'
 import Source from './source'
@@ -23,7 +23,6 @@
 const { Panel } = Collapse
 const { confirm } = Modal
 const { Paragraph } = Typography
-const _locale = antdZhCN
 
 const MenuForm = asyncComponent(() => import('./menuform'))
 const PopView = asyncComponent(() => import('./popview'))
@@ -59,6 +58,7 @@
     comloading: false,
     settingshow: sessionStorage.getItem('settingshow') !== 'false',
     view: null,
+    langName: '',
     popConfig: null
   }
 
@@ -93,6 +93,7 @@
         ParentId: param.ParentId || '',
         MenuName: param.MenuName || '',
         MenuNo: param.MenuNo || '',
+        langName: sessionStorage.getItem('lang') !== 'zh-CN' && langs[sessionStorage.getItem('lang')] ? `锛�${langs[sessionStorage.getItem('lang')]}锛塦 : ''
       }, () => {
         this.getMenuParam()
       })
@@ -425,8 +426,8 @@
         window.GLOB.urlFields = config.urlFields || []
 
         this.setState({
-          oriConfig: config,
-          config: fromJS(config).toJS()
+          oriConfig: config.components[0].isNew ? {} : fromJS(config).toJS(),
+          config: config
         })
         window.GLOB.customMenu = config
       } else {
@@ -532,6 +533,18 @@
 
     if (!this.checkBase()) {
       return
+    } else if (this.checklog()) {
+      if (sessionStorage.getItem('langList') && !config.trans) {
+
+      } else {
+        notification.success({
+          top: 92,
+          message: '褰撳墠閰嶇疆鏈慨鏀癸紝鏃犻渶淇濆瓨銆�',
+          duration: 5
+        })
+        MKEmitter.emit('completeSave')
+        return
+      }
     }
 
     this.setState({
@@ -582,6 +595,7 @@
 
       let interfaces = getFuncsAndInters(config)
       let urlFields = config.urlFields ? config.urlFields.join(',') : ''
+      let langSql = getLangTrans(config)
 
       let param = {
         func: 'sPC_TrdMenu_AddUpt',
@@ -595,12 +609,16 @@
         MenuName: config.MenuName || '',
         PageParam: JSON.stringify({Template: 'BaseTable', OpenType: config.OpenType || 'newtab', hidden: config.hidden || 'false', menuColor: config.menuColor || '', interfaces, urlFields}),
         open_edition: config.open_edition,
-        LText: '',
-        LTexttb: '',
+        // LText: '',
+        // LTexttb: '',
         debug_md5: key,
         debug_url: url,
         debug_list: window.btoa(tbs),
         LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(config)))
+      }
+
+      if (langSql) {
+        param.lang_translation = window.btoa(window.encodeURIComponent(langSql))
       }
 
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
@@ -841,11 +859,11 @@
   }
 
   render () {
-    const { view, activeKey, comloading, MenuId, config, settingshow, ParentId, menuloading } = this.state
+    const { view, activeKey, comloading, MenuId, config, settingshow, ParentId, menuloading, langName } = this.state
 
     return (
-      <ConfigProvider locale={_locale}>
-        <Header menuName={config ? config.MenuName : ''}/>
+      <>
+        <Header menuName={config ? config.MenuName + langName : ''}/>
         <DndProvider backend={HTML5Backend}>
         {view !== 'popview' ? <div className="pc-table-view">
             <div className="menu-body">
@@ -921,7 +939,7 @@
         </DndProvider>
         <StyleController />
         <ModalController />
-      </ConfigProvider>
+      </>
     )
   }
 }

--
Gitblit v1.8.0