From 8e003c1a94d26cc4d477e7aa03593ccb4d7e6c61 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期五, 11 十月 2024 17:47:40 +0800
Subject: [PATCH] 2024-10-11

---
 src/templates/zshare/modalform/index.jsx                                                 |    2 
 src/menu/datasource/verifycard/excelout/index.jsx                                        |   76 
 src/tabviews/custom/components/editor/braft-editor/index.jsx                             |   48 
 src/tabviews/zshare/mutilform/index.scss                                                 |    5 
 src/mob/mobshell/index.jsx                                                               |   45 
 src/tabviews/custom/components/share/braftContent/index.scss                             |   18 
 src/menu/components/card/balcony/options.jsx                                             |    1 
 src/tabviews/zshare/settingcomponent/index.jsx                                           |   49 
 src/templates/zshare/verifycard/customscript/index.jsx                                   |   35 
 src/views/menudesign/printmenuform/index.jsx                                             |  401 
 src/tabviews/custom/popview/index.jsx                                                    |   44 
 src/mob/components/navbar/normal-navbar/menus/index.jsx                                  |   12 
 src/tabviews/home/index.jsx                                                              |    2 
 src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx        |   92 
 src/tabviews/zshare/mutilform/mkInput/index.jsx                                          |    4 
 public/README.txt                                                                        |   12 
 src/tabviews/zshare/actionList/changeuserbutton/index.jsx                                |   10 
 src/menu/datasource/verifycard/index.jsx                                                 |  109 
 src/assets/css/main.scss                                                                 |    1 
 src/menu/components/card/cardcellcomponent/index.jsx                                     |   28 
 src/menu/components/form/tab-form/index.jsx                                              |   24 
 src/menu/components/carousel/prop-card/index.jsx                                         |    5 
 src/menu/components/search/main-search/dragsearch/card.jsx                               |    9 
 src/templates/modalconfig/dragelement/index.scss                                         |    4 
 src/views/pay/index.jsx                                                                  |  113 
 src/views/menudesign/index.scss                                                          |   12 
 src/pc/components/login/normal-login/signform.jsx                                        |    4 
 src/menu/components/card/prop-card/index.jsx                                             |    4 
 src/templates/sharecomponent/treesettingcomponent/index.jsx                              |   22 
 src/menu/components/table/edit-table/columns/index.jsx                                   |   16 
 src/menu/datasource/verifycard/utils.jsx                                                 |   28 
 package-lock.json                                                                        |    6 
 src/views/login/loginform.jsx                                                            |   11 
 src/views/menudesign/popview/index.jsx                                                   |    2 
 src/menu/datasource/verifycard/index.scss                                                |   33 
 src/menu/components/share/actioncomponent/dragaction/card.jsx                            |    4 
 src/tabviews/zshare/topSearch/index.jsx                                                  |  212 
 src/templates/comtableconfig/index.jsx                                                   |    4 
 src/menu/components/form/simple-form/options.jsx                                         |    1 
 src/menu/components/form/simple-form/index.jsx                                           |   12 
 src/tabviews/custom/components/table/edit-table/index.jsx                                |   70 
 src/api/index.js                                                                         |  311 
 src/templates/sharecomponent/cardcomponent/index.jsx                                     |   10 
 src/mob/mobshell/card.jsx                                                                |    3 
 public/index.html                                                                        |    4 
 src/views/interface/workspace/request/index.jsx                                          |    3 
 src/views/pcdesign/index.jsx                                                             |  112 
 src/menu/datasource/verifycard/settingform/index.jsx                                     |   34 
 src/menu/components/share/actioncomponent/index.jsx                                      |   17 
 src/setupProxy.js                                                                        |    6 
 src/menu/components/share/copycomponent/index.jsx                                        |   60 
 src/components/pasteboard/index.jsx                                                      |    4 
 src/menu/components/share/colsControl/index.jsx                                          |   12 
 src/templates/zshare/editTable/index.jsx                                                 |    6 
 src/menu/components/editor/braft-editor/options.jsx                                      |   27 
 src/mob/components/tabs/antv-tabs/index.jsx                                              |    6 
 src/tabviews/zshare/actionList/popupbutton/index.jsx                                     |    2 
 src/tabviews/custom/components/tabs/antv-tabs/index.jsx                                  |    4 
 src/menu/components/share/searchcomponent/index.jsx                                      |    8 
 src/templates/comtableconfig/updatetable/index.jsx                                       |   42 
 src/views/mkiframe/index.jsx                                                             |   10 
 src/templates/treepageconfig/index.jsx                                                   |    4 
 src/menu/datasource/index.jsx                                                            |  122 
 src/menu/components/form/formaction/index.jsx                                            |    2 
 src/views/billprint/index.jsx                                                            |  219 
 src/menu/datasource/verifycard/excelout/index.scss                                       |    0 
 src/menu/components/editor/braft-editor/index.scss                                       |   23 
 src/tabviews/zshare/actionList/normalbutton/index.jsx                                    |  998 +++
 src/views/tabledesign/index.scss                                                         |    5 
 src/views/menudesign/index.jsx                                                           |   68 
 src/tabviews/custom/components/card/data-card/index.jsx                                  |  179 
 src/menu/replaceField/settingform/index.jsx                                              |    4 
 src/tabviews/custom/components/module/voucher/index.jsx                                  |    8 
 src/templates/zshare/pasteform/index.jsx                                                 |    4 
 src/menu/components/card/double-data-card/index.jsx                                      |    4 
 src/views/tabledesign/popview/index.scss                                                 |    5 
 src/menu/pastecontroller/index.jsx                                                       |   57 
 src/menu/components/card/data-card/index.jsx                                             |    4 
 src/mob/header/index.scss                                                                |    7 
 src/views/appmanage/index.jsx                                                            |  108 
 src/menu/components/tabs/antv-tabs/index.jsx                                             |   12 
 src/tabviews/zshare/actionList/index.scss                                                |    3 
 src/templates/sharecomponent/settingcomponent/index.jsx                                  |   68 
 src/views/design/index.jsx                                                               |    4 
 src/views/pay/index.scss                                                                 |    8 
 src/components/header/index.jsx                                                          |    9 
 src/tabviews/custom/components/card/double-data-card/index.jsx                           |  160 
 src/templates/zshare/verifycard/callbackcustomscript/index.jsx                           |   12 
 src/menu/transfer/index.jsx                                                              |   18 
 src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx                   |   36 
 src/views/rolemanage/index.jsx                                                           |   48 
 src/templates/sharecomponent/fieldscomponent/index.jsx                                   |   24 
 src/views/billprint/index.scss                                                           |    3 
 src/templates/zshare/verifycard/customform/index.jsx                                     |   12 
 src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx             |    2 
 src/templates/sharecomponent/settingcomponent/settingform/utils.jsx                      |   24 
 src/tabviews/zshare/actionList/tabbutton/index.jsx                                       |    4 
 src/components/normalform/modalform/index.jsx                                            |   52 
 src/menu/stylecontroller/index.jsx                                                       |    7 
 src/views/rolemanage/index.scss                                                          |   14 
 src/menu/components/table/base-table/options.jsx                                         |   13 
 src/templates/zshare/verifycard/index.jsx                                                |   80 
 src/menu/components/share/sourcecomponent/index.jsx                                      |    4 
 src/tabviews/zshare/actionList/printbutton/index.jsx                                     |   89 
 src/menu/components/card/cardcellcomponent/formconfig.jsx                                |   20 
 src/templates/sharecomponent/actioncomponent/index.jsx                                   |    8 
 src/assets/img/map.jpg                                                                   |    0 
 src/menu/components/editor/braft-editor/index.jsx                                        |   23 
 src/tabviews/zshare/fileupload/index.jsx                                                 |   98 
 src/views/menudesign/popview/index.scss                                                  |    5 
 src/mob/header/index.jsx                                                                 |    4 
 src/mob/searchconfig/index.jsx                                                           |   22 
 src/tabviews/zshare/actionList/funcbutton/index.jsx                                      |  267 
 src/menu/components/share/markcomponent/index.jsx                                        |    6 
 src/views/basedesign/updateFormTab/index.jsx                                             |    4 
 src/components/editor/index.scss                                                         |   17 
 src/views/appmanage/transmenu/index.jsx                                                  |    2 
 src/menu/components/card/cardcellcomponent/index.scss                                    |    2 
 src/menu/components/card/cardcellcomponent/dragaction/action.jsx                         |    4 
 src/menu/components/card/cardcellcomponent/elementform/index.jsx                         |   18 
 src/templates/sharecomponent/actioncomponent/verifypay/customscript/index.jsx            |  224 
 src/menu/components/tabs/antv-tabs/index.scss                                            |    2 
 src/templates/modalconfig/index.jsx                                                      |   18 
 src/tabviews/zshare/actionList/newpagebutton/index.jsx                                   |  425 +
 src/views/design/sidemenu/index.jsx                                                      |    4 
 src/mob/modalconfig/index.jsx                                                            |   14 
 src/mob/modalconfig/index.scss                                                           |    5 
 src/components/header/loginform.jsx                                                      |   21 
 src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx                     |    6 
 src/views/interface/index.jsx                                                            |   14 
 src/utils/sqlFormatter.js                                                                |   46 
 src/tabviews/custom/components/card/cardcellList/index.jsx                               |   58 
 src/menu/components/carousel/data-card/options.jsx                                       |    5 
 src/menu/components/card/data-card/options.jsx                                           |   14 
 src/components/editor/index.jsx                                                          |  151 
 src/mob/components/menubar/normal-menubar/index.jsx                                      |    6 
 src/tabviews/custom/components/table/normal-table/index.jsx                              |  150 
 src/menu/components/tabs/antv-tabs/options.jsx                                           |   15 
 src/templates/subtableconfig/index.jsx                                                   |    4 
 src/tabviews/custom/components/table/edit-table/normalTable/index.jsx                    |  273 
 src/templates/sharecomponent/treesettingcomponent/settingform/index.jsx                  |   22 
 src/components/breadview/index.jsx                                                       |   12 
 src/tabviews/custom/components/editor/braft-editor/index.scss                            |   23 
 src/tabviews/custom/components/module/invoice/index.scss                                 |    2 
 src/tabviews/zshare/mutilform/index.jsx                                                  |  145 
 src/menu/components/share/actioncomponent/actionform/index.jsx                           |  101 
 src/tabviews/custom/index.jsx                                                            |   76 
 src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx                  |   14 
 src/menu/components/table/normal-table/columns/index.jsx                                 |   16 
 src/views/appmanage/submutilform/index.jsx                                               |   78 
 src/menu/components/timeline/normal-timeline/options.jsx                                 |    1 
 src/menu/components/card/cardcellcomponent/dragaction/index.scss                         |   21 
 src/views/design/header/index.jsx                                                        |  120 
 src/views/printTemplate/index.jsx                                                        |    6 
 src/pc/menushell/index.jsx                                                               |   45 
 src/templates/zshare/verifycard/fullScripts/index.jsx                                    |    2 
 src/menu/components/tabs/table-tabs/index.jsx                                            |    6 
 src/tabviews/zshare/actionList/exceloutbutton/index.jsx                                  |   49 
 src/menu/components/card/cardcellcomponent/dragaction/card.jsx                           |    8 
 src/views/design/sidemenu/index.scss                                                     |   20 
 src/views/tabledesign/index.jsx                                                          |   70 
 src/tabviews/zshare/actionList/index.jsx                                                 |    6 
 src/templates/sharecomponent/tabscomponent/index.jsx                                     |   18 
 src/menu/components/carousel/data-card/index.jsx                                         |    4 
 src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx                       |    2 
 src/menu/components/form/step-form/index.jsx                                             |   24 
 src/tabviews/zshare/mutilform/mkCheckCard/index.jsx                                      |    2 
 public/manifest.json                                                                     |    2 
 src/pc/components/login/normal-login/loginform.jsx                                       |    2 
 src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx                    |    2 
 src/menu/urlfieldcomponent/index.jsx                                                     |    4 
 src/menu/components/search/main-search/index.jsx                                         |    6 
 src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx              |    6 
 src/components/sidemenu/index.jsx                                                        |    2 
 src/mob/components/navbar/normal-navbar/index.jsx                                        |    2 
 src/utils/utils-datamanage.js                                                            |  230 
 src/menu/picturecontroller/index.jsx                                                     |    8 
 src/menu/components/card/table-card/index.jsx                                            |    4 
 src/utils/utils-custom.js                                                                | 3523 +++++++++++++
 src/mob/modulesource/option.jsx                                                          |    4 
 src/templates/sharecomponent/actioncomponent/verifypay/index.scss                        |   84 
 src/views/design/header/editfirstmenu/index.jsx                                          |    4 
 src/templates/sharecomponent/actioncomponent/verifypay/customscript/index.scss           |    0 
 src/tabviews/zshare/actionList/excelInbutton/index.jsx                                   |  647 +
 src/views/design/header/transmenu/index.jsx                                              |    4 
 public/options.json                                                                      |    8 
 src/pc/components/login/normal-login/options.jsx                                         |   15 
 src/tabviews/basetable/index.jsx                                                         |   26 
 src/menu/tablenodes/index.jsx                                                            |   11 
 src/tabviews/custom/components/module/invoice/index.jsx                                  |  686 +
 src/views/pcdesign/index.scss                                                            |    3 
 src/templates/sharecomponent/settingcomponent/settingform/index.jsx                      |   22 
 src/templates/modalconfig/dragelement/card.jsx                                           |    2 
 src/views/mobdesign/index.jsx                                                            |  134 
 src/views/interface/history/index.jsx                                                    |    4 
 src/components/normalform/modalform/mkSelect/index.jsx                                   |    6 
 src/menu/components/module/invoice/verifycard/customscript/index.jsx                     |    2 
 src/api/cacheutils.js                                                                    |    6 
 src/menu/components/share/actioncomponent/formconfig.jsx                                 |  390 
 src/menu/components/editor/braft-editor/editorcontent/index.scss                         |   10 
 src/tabviews/custom/components/tabs/antv-tabs/index.scss                                 |   10 
 src/tabviews/zshare/mutilform/mkPopSelect/index.jsx                                      |  167 
 src/menu/components/table/base-table/columns/index.jsx                                   |    4 
 src/menu/debug/index.jsx                                                                 |  594 +
 src/views/design/sidemenu/thdmenuplus/index.jsx                                          |    2 
 src/menu/components/group/normal-group/index.jsx                                         |    6 
 src/templates/sharecomponent/searchcomponent/searchform/index.jsx                        |    4 
 src/components/tabview/index.jsx                                                         |   14 
 src/menu/components/form/simple-form/index.scss                                          |   11 
 src/tabviews/custom/components/table/base-table/index.jsx                                |  146 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx       |    2 
 src/views/appcheck/index.jsx                                                             |   10 
 src/views/mobdesign/menuform/index.jsx                                                   |   27 
 src/menu/datasource/verifycard/customscript/index.jsx                                    |    2 
 src/mob/searchconfig/index.scss                                                          |    4 
 src/templates/sharecomponent/searchcomponent/index.jsx                                   |    8 
 src/templates/sharecomponent/columncomponent/index.jsx                                   |    8 
 src/views/mobdesign/index.scss                                                           |   42 
 src/tabviews/custom/components/share/normalTable/index.jsx                               |   76 
 src/menu/components/form/step-form/options.jsx                                           |    1 
 src/pc/components/navbar/normal-navbar/linksetting/linktable/index.jsx                   |    4 
 src/menu/components/search/main-search/index.scss                                        |    4 
 src/utils/utils.js                                                                       |  283 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx                    |    4 
 src/index.js                                                                             |   52 
 src/tabviews/custom/components/module/voucher/resetAttach/addAttach/fileupload/index.jsx |  109 
 src/tabviews/custom/components/share/tabtransfer/index.jsx                               |   48 
 src/templates/treepageconfig/updatetable/index.jsx                                       |    8 
 src/tabviews/custom/components/table/edit-table/normalTable/mkPopSelect/index.jsx        |  167 
 src/templates/zshare/formconfig.jsx                                                      |   17 
 src/pc/createview/index.jsx                                                              |    4 
 src/templates/sharecomponent/actioncomponent/verifypay/index.jsx                         |  516 +
 src/menu/modalconfig/index.scss                                                          |    4 
 src/menu/modalconfig/index.jsx                                                           |   20 
 src/tabviews/custom/components/card/cardcellList/index.scss                              |    4 
 src/templates/zshare/verifycard/baseform/index.jsx                                       |  192 
 src/menu/menushell/index.jsx                                                             |    1 
 src/views/tabledesign/popview/index.jsx                                                  |    2 
 src/templates/sharecomponent/chartgroupcomponent/index.jsx                               |   10 
 239 files changed, 12,693 insertions(+), 3,399 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index c560381..7e3b8fd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5508,9 +5508,9 @@
       }
     },
     "caniuse-lite": {
-      "version": "1.0.30001588",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz",
-      "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ=="
+      "version": "1.0.30001643",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz",
+      "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg=="
     },
     "canvg": {
       "version": "3.0.10",
diff --git a/public/README.txt b/public/README.txt
index 6cbdae7..d1ff2b5 100644
--- a/public/README.txt
+++ b/public/README.txt
@@ -11,14 +11,16 @@
 defaultLang       -- 鎵撳紑鐨勫瓙搴旂敤璇█绫诲瀷锛岄粯璁や负zh-CN
 WXAppID           -- 浣跨敤鍏紬鍙锋椂锛岀粦瀹氱殑鍏紬鍙稩D
 WXminiAppID       -- 浣跨敤寰俊灏忕▼搴忔椂锛岀粦瀹氱殑灏忕▼搴廔D
-nginx             -- 鏄惁寮�鍚簡nginx鏈嶅姟锛屽�间负 true 鏃跺紑鍚紝濡傞渶浣跨敤寰俊妯℃澘娑堟伅绛夋湇鍔★紝璇峰厛璁剧疆nginx鏈嶅姟骞跺紑鍚閰嶇疆
-debugger          -- 鍊间负 true 鏃跺紑鍚皟璇曟ā寮忥紝寮�鍚悗绉诲姩绔瓙搴旂敤涓細鏈夋帶鍒跺彴
+WXMerchID         -- 浣跨敤寰俊鏀粯鏃讹紝缁戝畾鐨勫晢鎴稩D
+WXNotice          -- 鏄惁寮�鍚槑绉戜簯鍏紬鍙锋秷鎭彁閱掞紝鍊间负 true 鏃跺紑鍚紝鍙�氳繃鏄庣浜戝彂閫佹ā鏉挎秷鎭�
+WXApps            -- 瀛樺湪澶氫釜鍏紬鍙枫�佸皬绋嬪簭鎴栧晢鎴锋椂鍙娇鐢ㄥ井淇PP鍒楄〃锛屾敞鎰忓~鍐欓粯璁ゅ叕浼楀彿銆佸皬绋嬪簭涓庡晢鎴峰彿锛屾牸寮� [{"appId": "", "appName": "", "appType": "public/miniProgram/merchant"}]
+debugger          -- 鍊间负 true 鏃跺紑鍚皟璇曟ā寮忥紝寮�鍚悗绉诲姩绔瓙搴旂敤涓細鏈夋帶鍒跺彴锛屽�间负 forbid 鏃讹紝绂佹绯荤粺鎵撳嵃鑴氭湰
+systemRun         -- 绯荤粺鎺ュ彛鐨勬墽琛屾柟寮忥紝鍊间负 backend 鏃讹紝鍦ㄥ悗绔繍琛�
 licenseKey        -- 璁稿彲瀵嗛挜锛屽湪鍐呴儴缃戠粶涓娇鐢ㄧ郴缁熸椂锛屼細璺宠繃epc楠岃瘉
 storeKey          -- 鐢靛瓙妗f鏈湴鎺堟潈鐮侊紝浣跨敤鏈湴璁稿彲瀵嗛挜鏃舵湁鏁�
 probation         -- 璇曠敤鏈燂紙YYYY-MM-DD锛夛紝鍦ㄦ寮忕郴缁熶腑锛岃瘯鐢ㄦ湡鍐呰皟鐢ㄧ郴缁熸帴鍙g殑鑴氭湰浼氳褰曚笅鏉�
 transfer          -- 鏄惁浣跨敤杞帴鍙o紝浣跨敤杞帴鍙f椂璇疯缃负 true, 浣跨敤杞帴鍙f椂锛屽閮ㄦ帴鍙h皟鐢ㄥ墠涓嶄細鍋氱櫥褰曢獙璇�
-keepPassword      -- 璁颁綇瀵嗙爜锛岄粯璁ゅ紑鍚紝褰撳�间负 false 鏃剁鐢�
+keepPwd           -- 璁颁綇瀵嗙爜锛岄粯璁ゅ紑鍚紝褰撳�间负 false 鏃剁鐢紝褰撳�间负 invisible 鏃惰浣忓瘑鐮佷絾瀵嗙爜涓嶅彲鏌ョ湅
 execType          -- 鑴氭湰浼犺緭鏂瑰紡锛屽�间负x鏃讹紝鍚敤AES鍔犲瘑
 updateStatus      -- 鏄惁鏇存柊寮�鍙戠姸鎬侊紝榛樿寮�鍚紝褰撳�间负 false 鏃剁鐢�
-forcedUpdate      -- 浼犺緭鍙峰崌绾ф椂锛屾槸鍚﹁嚜鍔ㄩ��鍑猴紝鏍煎紡涓猴紙YYYY-MM-DD锛夛紝鐢ㄤ簬鍗囩骇鍚庡埛鏂扮敤鎴锋湰鍦伴厤缃�
-platforms         -- 绉诲姩绔彲浣跨敤鐨勫钩鍙扮被鍨嬶紝榛樿涓� ["H5", "wechat", "android", "ios", "wxMiniProgram"] 鍒嗗埆浠h〃H5椤甸潰銆佸井淇″叕浼楀彿銆佸畨鍗揂PP銆佽嫻鏋淎PP銆佸井淇″皬绋嬪簭
\ No newline at end of file
+forcedUpdate      -- 浼犺緭鍙峰崌绾ф椂锛屾槸鍚﹁嚜鍔ㄩ��鍑猴紝鏍煎紡涓猴紙YYYY-MM-DD锛夛紝鐢ㄤ簬鍗囩骇鍚庡埛鏂扮敤鎴锋湰鍦伴厤缃�
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
index 3da241a..7719992 100644
--- a/public/index.html
+++ b/public/index.html
@@ -58,6 +58,10 @@
             }
           })
       }
+
+      window.mkInfo = function(value, color = '') {
+        console.info(value, color)
+      }
     </script>
   </head>
   <body>
diff --git a/public/manifest.json b/public/manifest.json
index 61ef54c..3027059 100644
--- a/public/manifest.json
+++ b/public/manifest.json
@@ -6,5 +6,5 @@
   "display": "standalone",
   "theme_color": "#000000",
   "background_color": "#ffffff",
-  "mk_version": "20240601"
+  "mk_version": "20241002"
 }
diff --git a/public/options.json b/public/options.json
index ba71614..a78b3b3 100644
--- a/public/options.json
+++ b/public/options.json
@@ -8,17 +8,17 @@
   "filter": "false",
   "defaultApp": "",
   "defaultLang": "zh-CN",
-  "WXAppID": "wx4d8a34c8d4494872",
+  "WXAppID": "",
   "WXminiAppID": "",
   "WXNotice": "false",
-  "nginx": "false",
   "debugger": true,
+  "systemRun": "backend",
+  "execType": "",
   "licenseKey": "",
   "storeKey": "",
   "probation": "",
   "transfer": true,
-  "keepPassword": "true",
-  "platforms": ["H5", "wechat", "android", "ios", "wxMiniProgram"],
+  "keepPwd": "true",
   "host": "http://bms-test.kresstools.cn",
   "service": "oc/"
 }
\ No newline at end of file
diff --git a/src/api/cacheutils.js b/src/api/cacheutils.js
index 3184290..b20d3f6 100644
--- a/src/api/cacheutils.js
+++ b/src/api/cacheutils.js
@@ -27,9 +27,9 @@
         if (!window.GLOB.IndexDB.objectStoreNames.contains('caches')) {
           window.GLOB.IndexDB.createObjectStore('caches', { keyPath: 'menuid' })
         }
-        if (!window.GLOB.IndexDB.objectStoreNames.contains('funcs')) {
-          window.GLOB.IndexDB.createObjectStore('funcs', { keyPath: 'id' })
-        }
+        // if (!window.GLOB.IndexDB.objectStoreNames.contains('funcs')) {
+        //   window.GLOB.IndexDB.createObjectStore('funcs', { keyPath: 'id' })
+        // }
       }
     } catch (e) {
       console.warn('IndexedDB 鍒濆鍖栧け璐ワ紒')
diff --git a/src/api/index.js b/src/api/index.js
index f9e44a1..f456e6e 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -120,35 +120,15 @@
   /**
    * @description 寰俊涓氬姟璇锋眰 wxpay/getaccesstoken
    */
-  wxAccessToken (domain = '') {
-    let _url = domain || window.GLOB.baseurl 
+  // wxAccessToken (appId, domain = '') {
+  //   let _url = domain || window.GLOB.baseurl
 
-    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 => {
-      if (window.GLOB.accessToken.domain === domain && window.GLOB.accessToken.accessTime && (parseInt(new Date().getTime() / 1000) - window.GLOB.accessToken.accessTime < 30)) {
-        resolve(window.GLOB.accessToken)
-      } else {
-        window.GLOB.accessToken = {domain}
-        axios({
-          url: _url + 'wxpay/getaccesstoken',
-          method: 'get'
-        }).then(res => {
-          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
-          }
-          resolve(res)
-        })
-      }
-    })
-  }
+  //   return axios({
+  //     url: _url + 'wechat/getaccesstoken',
+  //     method: 'post',
+  //     data: JSON.stringify({app_id: appId})
+  //   })
+  // }
 
   /**
    * @description 寰俊涓氬姟璇锋眰
@@ -162,12 +142,12 @@
       if (process.env.NODE_ENV === 'production') {
         _url = document.location.origin + '/' + 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')
-      }
+    }
+    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/')
     }
     
     if (param) {
@@ -187,7 +167,27 @@
   /**
    * @description 鐩存帴璇锋眰
    */
-  directRequest (params) {
+  directRequest (params, script, position) {
+    if (script) {
+      try {
+        // eslint-disable-next-line
+        let func = new Function('axios', 'Api', 'param', 'position', 'systemType', 'notification', script)
+        let promise = func(axios, this, params, position, window.GLOB.systemType, notification)
+
+        if (promise instanceof Promise) {
+          return promise
+        }
+      } catch (e) {
+        console.warn(e)
+      }
+
+      return Promise.resolve({
+        status: false,
+        message: '鑷畾涔夎剼鏈墽琛岄敊璇�',
+        ErrCode: 'E'
+      })
+    }
+    
     return axios(params)
   }
 
@@ -547,26 +547,26 @@
   /**
    * @description 鑾峰彇鎴栦慨鏀圭郴缁熼厤缃紝澧炲姞appkey
    */
-  getSystemFuncs (time) {
-    let param = {
-      func: 's_get_func_base_sso',
-      update_date: time,
-      userid: sessionStorage.getItem('UserID') || '',
-      lang: sessionStorage.getItem('lang') || '',
-      SessionUid: localStorage.getItem('SessionUid') || '',
-      LoginUID: sessionStorage.getItem('LoginUID') || '',
-      appkey: window.GLOB.appkey
-    }
+  // getSystemFuncs (time) {
+  //   let param = {
+  //     func: 's_get_func_base_sso',
+  //     update_date: time,
+  //     userid: sessionStorage.getItem('UserID') || '',
+  //     lang: sessionStorage.getItem('lang') || '',
+  //     SessionUid: localStorage.getItem('SessionUid') || '',
+  //     LoginUID: sessionStorage.getItem('LoginUID') || '',
+  //     appkey: window.GLOB.appkey
+  //   }
 
-    let url = window.GLOB.mainSystemApi || '/webapi/dostars'
-    param = this.encryptParam(param)
+  //   let url = window.GLOB.mainSystemApi || '/webapi/dostars'
+  //   param = this.encryptParam(param)
 
-    return axios({
-      url: `${url}/${param.func}`,
-      method: 'post',
-      data: JSON.stringify(param)
-    })
-  }
+  //   return axios({
+  //     url: `${url}/${param.func}`,
+  //     method: 'post',
+  //     data: JSON.stringify(param)
+  //   })
+  // }
 
   /**
    * @description 鑾峰彇鎴栦慨鏀圭郴缁熼厤缃紝澧炲姞appkey
@@ -725,6 +725,65 @@
     param.SessionUid = localStorage.getItem('SessionUid') || ''
     param.LoginUID = param.LoginUID || sessionStorage.getItem('LoginUID') || ''
     param.appkey = window.GLOB.appkey || ''
+
+    if (param.$backend) {
+      delete param.$backend
+
+      let id = ''
+      if (cache) {
+        id = param.data[0].id
+
+        if (window.GLOB.CacheMap.has(id)) {
+          return Promise.resolve(window.GLOB.CacheMap.get(id))
+        }
+      }
+
+      param.username = sessionStorage.getItem('User_Name') || ''
+      param.fullname = sessionStorage.getItem('Full_Name') || ''
+      param.s_debug = window.GLOB.debugger ? 'Y' : ''
+      param.data_md5 = param.data_md5 || ''
+      param.time_limit = param.time_limit || 0
+
+      let url = '/webapi/exstars'
+      if (param.rduri) {
+        param.rduri = param.rduri.replace(/dostars/ig, 'exstars')
+        if (!window.GLOB.transfer) {
+          url = param.rduri
+          delete param.rduri
+        }
+      }
+
+      if (param.$type) {
+        url += '/' + param.$type
+      }
+
+      delete param.$type
+
+      param = this.encryptParam(param)
+
+      return new Promise((resolve) => {
+        axios({
+          url: url,
+          method: 'post',
+          data: JSON.stringify(param)
+        }).then(res => {
+          if (res.mksqls) {
+            res.mksqls.forEach(n => {
+              n = n.replace(/(UNION ALL\s+)?SELECT obj_name='[\S\s]+sub_field=''\s+/ig, '')
+              window.mkInfo(n)
+            })
+          }
+          if (res.ErrCode === 'version_error') {
+            res.ErrCode = '-2'
+            MKEmitter.emit('reloadTabs')
+          }
+          if (res.status && id) {
+            window.GLOB.CacheMap.set(id, res)
+          }
+          resolve(res)
+        })
+      })
+    }
 
     let url = '/webapi/dostars'
     if (param.rduri && !window.GLOB.transfer) { // positecgroup
@@ -993,9 +1052,55 @@
           }
         })
       })
+    } else if (param.$backend) {
+      delete param.$backend
+
+      let url = '/webapi/exstars'
+      if (param.rduri) {
+        param.rduri = param.rduri.replace(/dostars/ig, 'exstars')
+        if (!window.GLOB.transfer) {
+          url = param.rduri
+          delete param.rduri
+        }
+      }
+
+      if (param.$type) {
+        url += '/' + param.$type
+      }
+
+      delete param.$type
+
+      param.username = sessionStorage.getItem('User_Name') || ''
+      param.fullname = sessionStorage.getItem('Full_Name') || ''
+      param.s_debug = window.GLOB.debugger ? 'Y' : ''
+      param.data_md5 = param.data_md5 || ''
+      param.time_limit = param.time_limit || 0
+
+      param = this.encryptParam(param)
+
+      return new Promise((resolve) => {
+        axios({
+          url: url,
+          method: 'post',
+          data: JSON.stringify(param),
+          requestId
+        }).then(res => {
+          if (res.mksqls) {
+            res.mksqls.forEach(n => {
+              n = n.replace(/(UNION ALL\s+)?SELECT obj_name='[\S\s]+sub_field=''\s+/ig, '')
+              window.mkInfo(n)
+            })
+          }
+          if (res.ErrCode === 'version_error') {
+            res.ErrCode = '-2'
+            MKEmitter.emit('reloadTabs')
+          }
+          resolve(res)
+        })
+      })
     } else {
       let url = '/webapi/dostars'
-      if (param.rduri && !window.GLOB.transfer && /\/dostars/.test(param.rduri) && param.func !== 'webapi_ChangeUser') {
+      if (param.rduri && (!window.GLOB.transfer || /https:\/\/sso.mk9h.cn/.test(param.rduri)) && /\/dostars/.test(param.rduri) && param.func !== 'webapi_ChangeUser') {
         url = param.rduri
         delete param.rduri
       }
@@ -1009,6 +1114,27 @@
         requestId
       })
     }
+  }
+
+  /**
+   * @description 娓呯┖鍚庣缂撳瓨
+   */
+  cacheInterface (param) {
+    param.appkey = window.GLOB.appkey || ''
+
+    let url = '/webapi/excache'
+    if (param.rduri && !window.GLOB.transfer) {
+      url = param.rduri
+      delete param.rduri
+    }
+
+    param = this.encryptParam(param)
+
+    return axios({
+      url: url,
+      method: 'post',
+      data: JSON.stringify(param),
+    })
   }
 
   /**
@@ -1054,26 +1180,45 @@
   /**
    * @description 澶ф枃浠朵笂浼�
    */
-  getLargeFileUpload (param) {
-    return axios({
-      url: '/webapi/doupload',
-      method: 'post',
-      headers: { 'Content-Type': 'multipart/form-data' },
-      data: param
+  getFileUpload (param) {
+    param.append('shardingCnt', 1)
+    param.append('LoginUID', sessionStorage.getItem('LoginUID') || '')
+    param.append('UserID', sessionStorage.getItem('UserID') || '')
+
+    return new Promise((resolve, reject) => {
+      axios({
+        url: '/webapi/doupload',
+        method: 'post',
+        headers: { 'Content-Type': 'multipart/form-data' },
+        data: param
+      }).then(res => {
+        if (res.status && res.urlPath) {
+          if (!/Content\/images/.test(res.urlPath)) {
+            let key = CryptoJS.enc.Utf8.parse('D1185ED7B32568C9')
+            let wordArray = CryptoJS.enc.Base64.parse(res.urlPath)
+            let decryptedWordArray = CryptoJS.AES.decrypt({ ciphertext: wordArray }, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
+            res.urlPath = CryptoJS.enc.Utf8.stringify(decryptedWordArray)
+          }
+          if (!/^http/.test(res.urlPath)) {
+            res.urlPath = window.GLOB.baseurl + res.urlPath
+          }
+        }
+        resolve(res)
+      })
     })
   }
 
   /**
    * @description 鏌ヨ鏂囦欢鏄惁宸蹭笂浼�
    */
-  getFilePreUpload (param) {
-    return axios({
-      url: '/webapi/dopreload',
-      method: 'post',
-      headers: { 'Content-Type': 'multipart/form-data' },
-      data: param
-    })
-  }
+  // getFilePreUpload (param) {
+  //   return axios({
+  //     url: '/webapi/dopreload',
+  //     method: 'post',
+  //     headers: { 'Content-Type': 'multipart/form-data' },
+  //     data: param
+  //   })
+  // }
 
   /**
    * @description oss鏂囦欢涓婁紶
@@ -1084,10 +1229,10 @@
       _url = document.location.origin + '/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')
+      _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({
@@ -1099,30 +1244,24 @@
   }
 
   /**
-   * @description 鑾峰彇寰俊鏀粯浜岀淮鐮�
+   * @description 鑾峰彇寰俊鏀粯浜岀淮鐮� 鍘熸帴鍙xpay/wxNativePay
    */
   getWxNativePay (param) {
-    let _url = window.GLOB.baseurl + 'wxpay/wxNativePay'
-
     return axios({
-      url: _url,
+      url: window.GLOB.baseurl + 'wechat/native',
       method: 'post',
-      data: qs.stringify(param)
+      data: JSON.stringify(param)
     })
   }
 
   /**
-   * @description 寰俊鏀粯閫�娆�
+   * @description 寰俊鏀粯閫�娆� 鍘熸帴鍙xpay/wxRefund
    */
-  setRefund (orderId) {
-    let _param = new FormData()
-    _param.append('out_biz_no', orderId)
-
+  setRefund (param) {
     return axios({
-      url: '/wxpay/wxRefund',
-      headers: { 'Content-Type': 'multipart/form-data' },
+      url: window.GLOB.baseurl + 'wechat/wxRefund',
       method: 'post',
-      data: _param
+      data: JSON.stringify(param)
     })
   }
 
@@ -1163,7 +1302,7 @@
       sql = sql.replace(/@db@/ig, window.GLOB.externalDatabase)
     }
 
-    console.info(`/* sql 楠岃瘉 */\n${sql.replace(/\n\s{6,20}/ig, '\n')}`)
+    window.mkInfo(`/* sql 楠岃瘉 */\n${sql.replace(/\n\s{6,20}/ig, '\n')}`)
 
     sql = sql.replace(/\n/ig, ' ')
 
diff --git a/src/assets/css/main.scss b/src/assets/css/main.scss
index d9a3e78..7f4eea2 100644
--- a/src/assets/css/main.scss
+++ b/src/assets/css/main.scss
@@ -322,6 +322,7 @@
   }
   .ant-modal-body::-webkit-scrollbar {
     width: 7px;
+    height: 0;
   }
   .ant-modal-body::-webkit-scrollbar-thumb {
     border-radius: 5px;
diff --git a/src/assets/img/map.jpg b/src/assets/img/map.jpg
index 5dd38ff..757308d 100644
--- a/src/assets/img/map.jpg
+++ b/src/assets/img/map.jpg
Binary files differ
diff --git a/src/components/breadview/index.jsx b/src/components/breadview/index.jsx
index ac52d25..340b188 100644
--- a/src/components/breadview/index.jsx
+++ b/src/components/breadview/index.jsx
@@ -42,9 +42,7 @@
 
   componentDidMount () {
     MKEmitter.addListener('modifyTabs', this.modifyTabs)
-    if (window.GLOB.forcedUpdate) {
-      MKEmitter.addListener('reloadTabs', this.reloadTabs)
-    }
+    MKEmitter.addListener('reloadTabs', this.reloadTabs)
   }
 
   /**
@@ -160,9 +158,15 @@
   reloadTabs = () => {
     if (this.reloading) return
 
-    this.reloading = true
     let time = new Date().getTime()
 
+    let oldTime = sessionStorage.getItem('mk_reloadTabs')
+    
+    if (oldTime && time - oldTime < 180000) return
+
+    sessionStorage.setItem('mk_reloadTabs', time)
+
+    this.reloading = true
     this.setState({visible: true})
 
     Api.getAppVersion(true).then((list) => {
diff --git a/src/components/editor/index.jsx b/src/components/editor/index.jsx
index ede20dc..a9e96de 100644
--- a/src/components/editor/index.jsx
+++ b/src/components/editor/index.jsx
@@ -1,12 +1,10 @@
-import React, {Component} from 'react'
+import React, { Component } from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
 import BraftEditor from 'braft-editor'
 import 'braft-editor/dist/index.css'
 import 'braft-extensions/dist/table.css'
 import Table from 'braft-extensions/dist/table'
-import SparkMD5 from 'spark-md5'
-import moment from 'moment'
 
 import Api from '@/api'
 import './index.scss'
@@ -21,7 +19,7 @@
 
   state = {
     editorState: '',
-    encryption: 'false',
+    encryption: 'false'
   }
 
   UNSAFE_componentWillMount () {
@@ -51,6 +49,7 @@
       encryption
     })
   }
+
   shouldComponentUpdate (nextProps, nextState) {
     return !is(fromJS(this.props), fromJS(nextProps))
   }
@@ -72,37 +71,21 @@
     }
   }
 
-  shardupload = (params, param) => {
-    let _param = params.chunks.shift()
+  handleUpload(param) {
     let form = new FormData()
 
-    form.append('file', _param.binary)
-    form.append('fileMd5', params.file.fileMd5)
-    form.append('shardingMd5', _param.chunkMd5)
-    form.append('baseDomain', window.GLOB.baseurl)
-    form.append('rootPath', 'Content/images/upload/')
-    form.append('fileName', params.file.fileName)
-    form.append('fileExt', params.file.fileType)
-    form.append('shardingCnt', _param.chunks)
-    form.append('shardingNo', _param.chunk)
-    form.append('LoginUID', sessionStorage.getItem('LoginUID') || '')
-    form.append('UserID', sessionStorage.getItem('UserID') || '')
+    form.append('file', param.file)
 
-    Api.getLargeFileUpload(form).then(res => {
+    Api.getFileUpload(form).then(res => {
       if (res.status) {
-        if (params.chunks.length > 0) {
-          param.progress(Math.floor(100 * (_param.chunk / _param.chunks)))
-          this.shardupload(params, param)
+        if (res.urlPath) {
+          param.success({
+            url: res.urlPath
+          })
         } else {
-          if (res.urlPath) {
-            param.success({
-              url: res.urlPath
-            })
-          } else {
-            param.error({
-              url: '涓婁紶澶辫触锛�'
-            })
-          }
+          param.error({
+            url: '涓婁紶澶辫触锛�'
+          })
         }
       } else {
         param.error({
@@ -112,111 +95,17 @@
     })
   }
 
-  getuuid = () => {
-    let uuid = []
-    let _options = '0123456789abcdefghigklmnopqrstuv'
-    for (let i = 0; i < 19; i++) {
-      uuid.push(_options.substr(Math.floor(Math.random() * 0x20), 1))
-    }
-    uuid = uuid.join('')
-    return uuid
-  }
-
-  handleUpload(param) {
-    const file = param.file
-
-    let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
-    let chunkSize = 1024 * 1024 * 2                // 鍒囩墖姣忔2M
-    let chunks = Math.ceil(file.size / chunkSize)  // 鍒囩墖鎬绘暟
-    let currentChunk = 0                           // 褰撳墠涓婁紶鐨刢hunk
-    let spark = new SparkMD5.ArrayBuffer()         // 瀵筧rrayBuffer鏁版嵁杩涜md5鍔犲瘑锛屼骇鐢熶竴涓猰d5瀛楃涓�
-    let chunkFileReader = new FileReader()         // 鐢ㄤ簬璁$畻鍑烘瘡涓猚hunkMd5
-    let totalFileReader = new FileReader()         // 鐢ㄤ簬璁$畻鍑烘�绘枃浠剁殑fileMd5
-    let params = {chunks: [], file: {}}            // 鐢ㄤ簬涓婁紶鎵�鏈夊垎鐗囩殑md5淇℃伅
-
-    params.file.fileName = file.name.replace(/\.{1}[^.]*$/ig, '')  // 鏂囦欢鍚嶏紙鍘婚櫎鍚庣紑鍚嶏級
-    params.file.fileType = file.name.replace(/^.*\.{1}/ig, '')     // 鏂囦欢绫诲瀷
-    params.file.fileSize = file.size                               // 鏂囦欢澶у皬
-    params.file.fileChunks = chunks                                // 璁板綍鎵�鏈塩hunks鐨勯暱搴�
-
-    if (!/^[A-Za-z0-9]+$/.test(params.file.fileName)) {            // 鏂囦欢鍚嶇О鍚湁鑻辨枃鍙婃暟瀛椾箣澶栧瓧绗︽椂锛屽悕绉扮郴缁熺敓鎴�
-      params.file.fileName = moment().format('YYYYMMDDHHmmss') + this.getuuid()
-    }
-
-    totalFileReader.readAsArrayBuffer(file)
-    totalFileReader.onload = (e) => {   // 瀵规暣涓猼otalFile鐢熸垚md5
-      spark.append(e.target.result)
-      params.file.fileMd5 = spark.end() // 璁$畻鏁翠釜鏂囦欢鐨刦ileMd5
-
-      let _param = new FormData()
-      _param.append('fileMd5', params.file.fileMd5)
-      
-      Api.getFilePreUpload(_param).then(res => {
-        if (res.status && res.urlPath) {
-          param.success({
-            url: res.urlPath
-          })
-        } else if (res.shardings && res.shardings.length > 0) {
-          res.shardings.forEach(shard => {
-            if (shard.shardingNo && parseInt(shard.shardingNo) > currentChunk) {
-              currentChunk = parseInt(shard.shardingNo)
-            }
-          })
-          loadNext()
-        } else {
-          loadNext()
-        }
-      })
-    }
-
-    chunkFileReader.onload = (e) => {
-      spark.append(e.target.result)      // 瀵规瘡涓�鐗囧垎鐗囪繘琛宮d5鍔犲瘑
-      
-      params.chunks[params.chunks.length - 1].chunkMd5 = spark.end() // 娣诲姞鍒囩墖md5
-      
-      currentChunk++  // 姣忎竴娆″垎鐗噊nload,currentChunk閮介渶瑕佸鍔狅紝浠ヤ究鏉ヨ绠楀垎鐗囩殑娆℃暟
-
-      if (currentChunk < chunks) { // 褰撳墠鍒囩墖鎬绘暟娌℃湁杈惧埌鎬绘暟鏃�
-        loadNext()
-      } else {
-        this.shardupload(params, param)
-      }
-    }
-
-    chunkFileReader.onerror = () => {
-      param.error({
-        url: '涓婁紶澶辫触锛�'
-      })
-      console.warn('File reading failed.')
-    }
-    totalFileReader.onerror = () => {
-      param.error({
-        url: '涓婁紶澶辫触锛�'
-      })
-    }
-
-    let loadNext = () => {
-      let start = currentChunk * chunkSize              // 璁$畻鍒嗙墖鐨勮捣濮嬩綅缃�
-      let end = Math.min(file.size, start + chunkSize)  // 璁$畻鍒嗙墖鐨勭粨鏉熶綅缃�
-
-      let obj = {                                       // 姣忎竴涓垎鐗囬渶瑕佸寘鍚殑淇℃伅
-        chunk: currentChunk + 1,
-        binary: file.slice(start, end),
-        start: start,
-        end: end,
-        chunks
-      }
-
-      params.chunks.push(obj)
-      chunkFileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
-    }
-  }
-
   render() {
+    const { config } = this.props
     const { editorState } = this.state
 
+    let style = null
+    if (config && config.contHeidht) {
+      style = {'--editor-height': config.contHeidht < 100 ? config.contHeidht + 'vh' : config.contHeidht + 'px'}
+    }
+
     return (
-      <div className="normal-braft-editor">
+      <div className="normal-braft-editor" style={style}>
         <BraftEditor
           value={editorState}
           onChange={this.handleEditorChange}
diff --git a/src/components/editor/index.scss b/src/components/editor/index.scss
index 44e33dc..9f9132f 100644
--- a/src/components/editor/index.scss
+++ b/src/components/editor/index.scss
@@ -1,12 +1,25 @@
 .normal-braft-editor {
+  overflow: hidden;
+  border: 1px solid #d9d9d9;
+  border-radius: 4px;
+  
   .bf-content {
     overflow-x: hidden;
     overflow-y: auto;
-    height: auto;
-    min-height: 500px;
+    height: var(--editor-height, auto);
+    min-height: var(--editor-height, 500px);
     padding-bottom: 0px;
     .public-DraftEditor-content {
       padding-bottom: 0;
+
+      * {
+        font-weight: inherit;
+        font-style: inherit;
+      }
+    }
+    .DraftEditor-root, .DraftEditor-editorContainer, .public-DraftEditor-content {
+      height: var(--editor-height, auto);
+      min-height: var(--editor-height, 500px);
     }
   }
   .bf-content::-webkit-scrollbar {
diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index 307b07e..4ea94db 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -56,7 +56,9 @@
   componentDidMount () {
     // 鑾峰彇绯荤粺鐨勭増鏈俊鎭紝寤舵椂鏌ヨ
     setTimeout(() => {
-      Api.getAppVersion()
+      if (!window.GLOB.$error) {
+        Api.getAppVersion()
+      }
     }, 1000)
 
     // sessionStorage 璺ㄩ〉闈㈠叡浜�
@@ -109,6 +111,7 @@
       setTimeout(() => {
         sessionStorage.clear()
         this.props.history.replace('/login')
+        window.location.reload()
       }, 2000)
     })
   }
@@ -116,7 +119,7 @@
   logout = () => {
     const { dict } = this.state
     // 閫�鍑虹櫥褰�
-    let _this = this
+    let that = this
     confirm({
       title: dict['logout_query'] || '鎮ㄧ‘瀹氳閫�鍑哄悧锛�',
       content: '',
@@ -124,7 +127,7 @@
       cancelText: dict['cancel'] || '鍙栨秷',
       onOk() {
         sessionStorage.clear()
-        _this.props.history.replace('/login')
+        that.props.history.replace('/login')
         window.location.reload()
       },
       onCancel() {}
diff --git a/src/components/header/loginform.jsx b/src/components/header/loginform.jsx
index 5154a9c..cca3f3d 100644
--- a/src/components/header/loginform.jsx
+++ b/src/components/header/loginform.jsx
@@ -12,9 +12,9 @@
 
   state = {
     remember: false,
+    lock: false,
     username: '',
     password: '',
-    oripassword: '',
     delay: +sessionStorage.getItem('mkDelay')
   }
 
@@ -39,22 +39,17 @@
       this.setState({
         remember: true,
         username: _user.username,
-        password: _user.password ? '*********' : '',
-        oripassword: _user.password
+        password: _user.password,
+        lock: true
       })
     }
   }
 
   handleConfirm = () => {
-    const { oripassword } = this.state
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     return new Promise((resolve, reject) => {
       this.props.form.validateFieldsAndScroll((err, values) => {
         if (!err) {
-          if (oripassword && values.password === '*********') {
-            values.password = oripassword
-          }
-          
           values.username = values.username.replace(/\t+|\v+|\s+/g, '')
           values.password = values.password.replace(/\t+|\v+|\s+/g, '')
 
@@ -88,6 +83,12 @@
     }
   }
 
+  unLock = (e) => {
+    if (e.target.value) return
+    
+    this.setState({ lock: false })
+  }
+
   componentDidMount () {
     const { username, password } = this.state
 
@@ -102,7 +103,7 @@
 
   render() {
     const { getFieldDecorator } = this.props.form
-    const { remember, username, password, delay } = this.state
+    const { remember, username, password, delay, lock } = this.state
 
     return (
       <Form style={{margin: '0px 10px'}}>
@@ -131,7 +132,7 @@
                 message: '璇疯緭鍏ュ瘑鐮�',
               }
             ]
-          })(<Input.Password onPressEnter={(e) => {this.handleSubmit(e, 'username')}} placeholder="瀵嗙爜" prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />} />)}
+          })(<Input.Password onPressEnter={(e) => {this.handleSubmit(e, 'username')}} placeholder="瀵嗙爜" visibilityToggle={!lock} onChange={this.unLock} 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 e30a12a..0ab789f 100644
--- a/src/components/normalform/modalform/index.jsx
+++ b/src/components/normalform/modalform/index.jsx
@@ -32,6 +32,7 @@
 
   state = {
     formlist: [],    // 琛ㄥ崟椤�
+    formId: ''
   }
 
   record = {}
@@ -40,6 +41,15 @@
     let record = {}
     let controlFields = {}
     let fieldMap = new Map()
+    let formId = (() => {
+      let uuid = []
+      let _options = '0123456789abcdefghigklmnopqrstuv'
+      for (let i = 0; i < 19; i++) {
+        uuid.push(_options.substr(Math.floor(Math.random() * 0x20), 1))
+      }
+      uuid = uuid.join('')
+      return uuid
+    })()
 
     let formlist = this.props.formlist.filter(item => {
       if (item.controlFields) { // 澶氬眰琛ㄥ崟鎺у埗
@@ -56,6 +66,7 @@
       if (item.options) {
         item.oriOptions = fromJS(item.options).toJS()
       }
+      item.$formId = formId
 
       if (item.type === 'text') {
         let _rules = [{
@@ -121,10 +132,11 @@
 
         let cell = fieldMap.get(item.field)
 
-        if (cell.hidden) return
+        cell.$ctrls = cell.$ctrls || []
+        cell.$ctrls.push(key)
 
-        if (cell.skip && supItem.forbid) { // 涓婄骇琛ㄥ崟绂佺敤鏃讹紝姝よ〃鍗曚笉鍙楁帶鍒�
-
+        if (cell.hidden) {
+          
         } else if (supItem.hidden) {
           cell.hidden = true
         } else if (item.notNull) {
@@ -151,6 +163,10 @@
     formlist = formlist.map(cell => {
       let item = fieldMap.get(cell.field)
 
+      if (item.$ctrls && item.$ctrls.length === 1) {
+        delete item.$ctrls
+      }
+
       if (item.linkField) {
         let supInitVal = fieldMap.get(item.linkField).initval || ''
         
@@ -162,7 +178,7 @@
 
     this.record = record
 
-    this.setState({ formlist })
+    this.setState({ formlist, formId })
   }
 
   checkNumber = (rule, value, callback, item) => {
@@ -217,6 +233,32 @@
             }
           } else {
             m.hidden = !cell.values.includes(val)
+          }
+
+          if (!m.hidden && m.$ctrls) {
+            m.$ctrls.forEach(n => {
+              if (n === current.field || m.hidden) return
+
+              let oth = map.get(n)
+              let _val = this.record[n]
+
+              if (_val && JSON.stringify(_val) === '[]') {
+                _val = ''
+              }
+
+              let p = oth.controlFields.filter(q => q.field === m.field)[0]
+
+              if (oth.hidden || (p.notNull && !_val)) {
+                m.hidden = true
+              } else if (oth.type === 'checkbox' || oth.type === 'multiselect') {
+                let _vals = [...(_val || []), ...p.values]
+                if (_vals.length === new Set(_vals).size) {
+                  m.hidden = true
+                }
+              } else if (!p.values.includes(_val)) {
+                m.hidden = true
+              }
+            })
           }
 
           if (m.hidden) {
@@ -385,7 +427,7 @@
     }
 
     return (
-      <Form {...formItemLayout} className="normal-form-field" id="normal-form-field">
+      <Form {...formItemLayout} className="normal-form-field" id={this.state.formId}>
         <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 4b8ee1a..7c7d8ed 100644
--- a/src/components/normalform/modalform/mkSelect/index.jsx
+++ b/src/components/normalform/modalform/mkSelect/index.jsx
@@ -125,7 +125,7 @@
             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')}
+            getPopupContainer={() => config.$formId ? document.getElementById(config.$formId) : document.body}
           >
             {options.map((option, i) =>
               <Select.Option key={i} disabled={option.disabled} value={option.field || ''}>{`${option.label}锛�${option.field}锛塦}</Select.Option>
@@ -142,7 +142,7 @@
           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')}
+          getPopupContainer={() => config.$formId ? document.getElementById(config.$formId) : document.body}
         >
           {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>
@@ -156,7 +156,7 @@
         defaultValue={value}
         filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
         onChange={this.mutilselectChange}
-        getPopupContainer={() => document.getElementById('normal-form-field')}
+        getPopupContainer={() => config.$formId ? document.getElementById(config.$formId) : document.body}
       >
         {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 c7a79a1..66c00c4 100644
--- a/src/components/pasteboard/index.jsx
+++ b/src/components/pasteboard/index.jsx
@@ -61,14 +61,14 @@
       }
     } catch (e) {
       // 閫氳繃sql璇彞娣诲姞瀛楁闆�
-      if (/[a-zA-Z0-9_]+\s+(nvarchar\(\d+\)|Decimal\(18,\d+\)|Int)/ig.test(config)) {
+      if (/[a-zA-Z0-9_]+\s+(nvarchar\(\d+\)|Decimal\(18,\d+\)|Int|datetime|date)/ig.test(config)) {
         _config = {
           key: 'datasourcefield',
           type: 'array',
           data: []
         }
 
-        let list = config.match(/[a-zA-Z0-9_]+\s+(nvarchar\(\d+\)|Decimal\(18,\d+\)|Int)/ig)
+        let list = config.match(/[a-zA-Z0-9_]+\s+(nvarchar\(\d+\)|Decimal\(18,\d+\)|Int|datetime|date)/ig)
 
         list.forEach(item => {
           _config.data.unshift({
diff --git a/src/components/sidemenu/index.jsx b/src/components/sidemenu/index.jsx
index 263d66f..802743b 100644
--- a/src/components/sidemenu/index.jsx
+++ b/src/components/sidemenu/index.jsx
@@ -79,7 +79,7 @@
       MKEmitter.emit('modifyTabs', menu)
     }
 
-    if (window.GLOB.systemType === 'production') {
+    if (window.GLOB.systemType === 'production') { // positecgroup
       MKEmitter.emit('queryTrigger', {menuId: menu.MenuID, name: '鑿滃崟'})
     }
   }
diff --git a/src/components/tabview/index.jsx b/src/components/tabview/index.jsx
index 88e48b9..dc50560 100644
--- a/src/components/tabview/index.jsx
+++ b/src/components/tabview/index.jsx
@@ -48,10 +48,7 @@
   componentDidMount () {
     MKEmitter.addListener('modifyTabs', this.modifyTabs)
     MKEmitter.addListener('closeTabView', this.closeTabView)
-
-    if (window.GLOB.forcedUpdate) {
-      MKEmitter.addListener('reloadTabs', this.reloadTabs)
-    }
+    MKEmitter.addListener('reloadTabs', this.reloadTabs)
   }
 
   /**
@@ -157,9 +154,16 @@
   reloadTabs = () => {
     if (this.reloading) return
 
-    this.reloading = true
     let time = new Date().getTime()
 
+    let oldTime = sessionStorage.getItem('mk_reloadTabs')
+    
+    if (oldTime && time - oldTime < 180000) return
+
+    sessionStorage.setItem('mk_reloadTabs', time)
+
+    this.reloading = true
+
     this.setState({visible: true})
 
     Api.getAppVersion(true).then((list) => {
diff --git a/src/index.js b/src/index.js
index aecaa7f..673b9a0 100644
--- a/src/index.js
+++ b/src/index.js
@@ -37,6 +37,8 @@
       }
     }
 
+    config.keepPwd = config.keepPwd || config.keepPassword
+
     let GLOB = {}
     GLOB.appId = config.appId || ''
     GLOB.lineColor = config.lineColor || ''
@@ -44,13 +46,13 @@
     GLOB.probation = false
     GLOB.watermark = config.watermark + '' !== 'false'
     GLOB.transfer = config.transfer + '' === 'true'
-    GLOB.keepKey = config.keepPassword + '' !== 'false'
-    GLOB.nginx = config.nginx + '' === 'true'
+    GLOB.keepKey = config.keepPwd + '' !== 'false'
+    GLOB.vispwd = config.keepPwd + '' !== 'invisible'
     GLOB.WXAppID = config.WXAppID || ''
     GLOB.WXminiAppID = config.WXminiAppID || ''
+    GLOB.WXMerchID = config.WXMerchID || ''
     GLOB.WXNotice = config.WXNotice + '' === 'true'
     GLOB.execType = config.execType === 'x' ? 'x' : ''
-    GLOB.accessToken = {}
     GLOB.mkHS = false
     GLOB.debugger = false
     GLOB.dataFormat = false
@@ -58,6 +60,13 @@
     GLOB.navBar = 'shutter' // 榛樿涓虹櫨鍙剁獥
     GLOB.style = 'bg_black_style_blue'
     GLOB.defLang = ''
+
+    if (config.WXApps) {
+      config.WXApps = config.WXApps.filter(app => app.appId && app.appName && ['public', 'miniProgram', 'merchant'].includes(app.appType))
+      if (config.WXApps.length) {
+        GLOB.WXApps = config.WXApps
+      }
+    }
 
     if (langs[config.defaultLang]) {
       GLOB.defLang = config.defaultLang
@@ -159,6 +168,11 @@
       if (GLOB.cloudServiceApi) {
         GLOB.mainSystemApi = GLOB.cloudServiceApi
       }
+
+      if (config.systemRun === 'backend') {
+        config.systemRun = '' // hs 涓嶄娇鐢ㄥ悗绔浛鎹�
+        GLOB.backend = true
+      }
     }
 
     if (process.env.NODE_ENV === 'production') { // 鐢ㄤ簬鏍¢獙鏄惁瀛樺湪寮�鍙戞潈闄�
@@ -174,14 +188,14 @@
       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)
     }
+    
+    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
@@ -336,7 +350,22 @@
       GLOB.memberLevel = 0
     }
 
-    if (GLOB.sysType === 'cloud') {
+    if (config.systemRun === 'backend') {
+      GLOB.debugger = false
+      Object.defineProperty(window, 'backend', {
+        writable: false,
+        value: true
+      })
+    }
+    if (config.debugger === 'forbid') {
+      sessionStorage.removeItem('breakpoint')
+      GLOB.debugger = false
+
+      Object.defineProperty(GLOB, 'debugger', {
+        writable: false,
+        value: GLOB.debugger
+      })
+    } else if (GLOB.sysType === 'cloud') {
       Object.defineProperty(GLOB, 'debugger', {
         writable: false,
         value: GLOB.debugger
@@ -378,7 +407,6 @@
         document.getElementById('root')
       )
     }
-    
   })
 
 serviceWorker.unregister()
diff --git a/src/menu/components/card/balcony/options.jsx b/src/menu/components/card/balcony/options.jsx
index 3361862..519d5b1 100644
--- a/src/menu/components/card/balcony/options.jsx
+++ b/src/menu/components/card/balcony/options.jsx
@@ -170,7 +170,6 @@
       initval: wrap.empty || 'show',
       tooltip: '褰撴煡璇㈡暟鎹负绌烘椂锛岄殣钘忚缁勪欢銆�',
       required: false,
-      skip: true,
       options: [
         {value: 'show', label: '鍚�'},
         {value: 'hidden', label: '鏄�'},
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/action.jsx b/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
index 4db573b..729095c 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
@@ -48,6 +48,8 @@
     hasProfile = true
   } else if (card.OpenType === 'innerpage' && !card.pageTemplate) {
     warning = <WarningOutlined style={{color: 'orange', marginLeft: '5px'}}/>
+  } else if (card.payMode === 'system') {
+    hasProfile = true
   }
 
   let btnElement = null
@@ -100,7 +102,7 @@
         <CopyOutlined className="copy" title="澶嶅埗" onClick={() => copyCard(id)} />
         <CloseOutlined className="close" title="鍒犻櫎" onClick={() => delCard(id)} />
         <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => changeStyle(id)} />
-        {hasProfile ? <ProfileOutlined className="profile" title="setting" onClick={() => profileCard(id)} /> : null}
+        {hasProfile ? <ProfileOutlined className="profile" title="楠岃瘉淇℃伅" onClick={() => profileCard(id)} /> : null}
         {updateTime}
       </div>
     } trigger="hover">
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
index abe02a7..2bee5ee 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
@@ -248,6 +248,12 @@
     mark = false
   }
 
+  let className = 'ant-col card-cell ant-col-' + card.width
+
+  if (card.noValue === 'hide') {
+    className += ' no-value-hide'
+  }
+
   return (
     <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
       <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
@@ -258,7 +264,7 @@
         {mark ? <MarkColumn field={card.field || ''} columns={fields} type={card.eleType} marks={card.marks} onSubmit={(vals) => updateMarks({...card, marks: vals})} /> : null }
       </div>
     } trigger="hover">
-      <div ref={node => drag(drop(node))} style={_style_} className={'ant-col card-cell ant-col-' + card.width}>
+      <div ref={node => drag(drop(node))} style={_style_} className={className}>
         <div style={_style} onClick={clickComponent} onDoubleClick={() => able && editCard(id)} id={card.uuid}>
           {getContent()}
         </div>
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/index.scss b/src/menu/components/card/cardcellcomponent/dragaction/index.scss
index 289da39..deb7cf3 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/index.scss
+++ b/src/menu/components/card/cardcellcomponent/dragaction/index.scss
@@ -240,4 +240,25 @@
       left: 0px;
     }
   }
+  .no-value-hide >div::before {
+    content: '*';
+    position: absolute;
+    top: 0px;
+    left: 0px;
+    font-size: 18px;
+    color: orange;
+    line-height: 1;
+    height: 8px;
+    opacity: 0;
+  }
+  .no-value-hide:hover >div::before {
+    opacity: 1;
+  }
+}
+td:hover {
+  .card-detail-row {
+    .no-value-hide >div::before {
+      opacity: 1;
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/menu/components/card/cardcellcomponent/elementform/index.jsx b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
index 0b03681..1435179 100644
--- a/src/menu/components/card/cardcellcomponent/elementform/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
@@ -233,6 +233,24 @@
       if (this.record.eval === 'true') {
         _options.push('decimal')
       }
+      if (this.record.eval !== 'func') {
+        _options.push('link')
+      }
+      if (this.record.link && this.record.eval !== 'func') {
+        _options.push('linkType')
+        if (this.record.linkType === 'linkmenu') {
+          _options.push('open')
+          if (this.record.link === 'static') {
+            _options.push('linkmenu')
+          } else {
+            _options.push('linkurl')
+          }
+        } else if (this.record.linkType === 'other') {
+          _options.push('linkurl', 'open')
+        } else {
+          _options.push('linkurl')
+        }
+      }
     }
     if (_options.includes('fixStyle') && this.record.fixStyle === 'alone') {
       _options.push('fixSize', 'fixColor', 'fixLeft', 'fixRight')
diff --git a/src/menu/components/card/cardcellcomponent/formconfig.jsx b/src/menu/components/card/cardcellcomponent/formconfig.jsx
index 32da945..99d6305 100644
--- a/src/menu/components/card/cardcellcomponent/formconfig.jsx
+++ b/src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -608,6 +608,16 @@
       ]
     },
     {
+      type: 'codemirror',
+      key: 'formula',
+      label: '鍏紡',
+      initVal: card.formula || '',
+      tooltip: '鎵ц鏃朵細浣跨敤鏌ヨ鍒扮殑鏁版嵁鏇挎崲鐩稿簲鐨勫瓧娈碉紝灞曠ず鑾峰緱鐨勭粨鏋滐紝鍦ㄤ笉浣跨敤瑙f瀽鏃舵崲琛岀鎴栫┖鏍间細鏇挎崲涓洪〉闈㈠厓绱犮�傚彲浣跨敤JS鐨勪竴浜涜娉曪紝濡傦細涓夊厓琛ㄨ揪寮� @field1@ > @field2@ ? 0 : 1锛汳ath瀵硅薄锛屽彇缁濆鍊� Math.abs(@field@)銆佸洓鑸嶄簲鍏� Math.round(@field@)绛夈�傛敞锛氫細鏇挎崲鍏紡涓殑@username@銆丂fullName@銆丂bid@銆�',
+      toolWidth: 450,
+      placeholder: '渚嬪锛欯price@ * @number@',
+      required: true
+    },
+    {
       type: 'radio',
       key: 'link',
       label: '閾炬帴',
@@ -683,16 +693,6 @@
         {value: 'blank', text: appType !== 'mob' ? '鏂扮獥鍙�' : '鏂伴〉闈�'},
         {value: 'self', text: appType !== 'mob' ? '褰撳墠绐楀彛' : '褰撳墠椤甸潰'},
       ]
-    },
-    {
-      type: 'codemirror',
-      key: 'formula',
-      label: '鍏紡',
-      initVal: card.formula || '',
-      tooltip: '鎵ц鏃朵細浣跨敤鏌ヨ鍒扮殑鏁版嵁鏇挎崲鐩稿簲鐨勫瓧娈碉紝灞曠ず鑾峰緱鐨勭粨鏋滐紝鍦ㄤ笉浣跨敤瑙f瀽鏃舵崲琛岀鎴栫┖鏍间細鏇挎崲涓洪〉闈㈠厓绱犮�傚彲浣跨敤JS鐨勪竴浜涜娉曪紝濡傦細涓夊厓琛ㄨ揪寮� @field1@ > @field2@ ? 0 : 1锛汳ath瀵硅薄锛屽彇缁濆鍊� Math.abs(@field@)銆佸洓鑸嶄簲鍏� Math.round(@field@)绛夈�傛敞锛氫細鏇挎崲鍏紡涓殑@username@銆丂fullName@銆丂bid@銆�',
-      toolWidth: 450,
-      placeholder: '渚嬪锛欯price@ * @number@',
-      required: true
     },
     {
       type: 'checkbox',
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index 50386cc..d6fa1a5 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -21,6 +21,7 @@
 const VerifyPrint = asyncComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyprint'))
 const VerifyExcelIn = asyncComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelin'))
 const VerifyExcelOut = asyncComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelout'))
+const VerifyPay = asyncComponent(() => import('@/templates/sharecomponent/actioncomponent/verifypay'))
 
 class CardCellComponent extends Component {
   static propTpyes = {
@@ -255,14 +256,9 @@
     } else if (_card.eleType === 'button') { // 鎷嗗垎style
       _card.style = fromJS(style).toJS()
 
-      if (style.float === 'center') {
-        delete _card.style.float
-      } else if (style.float) {
+      if (style.float) {
         _card.wrapStyle = {textAlign: style.float}
         delete _card.style.float
-      }
-      if (style.textAlign === 'center') {
-        delete _card.style.textAlign
       }
       if (style.minHeight === '28px') {
         delete _card.style.minHeight
@@ -395,6 +391,14 @@
       }
       if (res.width % 1) {
         res.width = (res.width + '').replace(/.5/, 'x')
+      }
+
+      if (res.eleType === 'formula' && res.eval === 'false' && res.noValue === 'hide') {
+        let keys = res.formula.match(/@[0-9a-z_]+@/ig)
+        if (keys) {
+          res.$keys = keys.map(key => key.slice(1, -1).toLowerCase())
+          res.$keys = Array.from(new Set(res.$keys))
+        }
       }
 
       let _elements = elements.map(cell => {
@@ -562,17 +566,17 @@
    */
   deleteElement = (card) => {
     const { elements } = this.state
-    let _this = this
+    let that = this
 
     confirm({
       content: '纭畾鍒犻櫎鍏冪礌鍚楋紵',
       onOk() {
         let _elements = elements.filter(item => item.uuid !== card.uuid)
 
-        _this.setState({
+        that.setState({
           elements: _elements
         }, () => {
-          _this.props.updateElement(_elements)
+          that.props.updateElement(_elements)
         })
       },
       onCancel() {}
@@ -806,6 +810,12 @@
         columns={side === 'sub' ? cards.subColumns : cards.columns}
         wrappedComponentRef={(inst) => this.verifyRef = inst}
       />
+    } else if (card.payMode === 'system') {
+      return <VerifyPay
+        card={card}
+        columns={side === 'sub' ? cards.subColumns : cards.columns}
+        wrappedComponentRef={(inst) => this.verifyRef = inst}
+      />
     }
   }
 
diff --git a/src/menu/components/card/cardcellcomponent/index.scss b/src/menu/components/card/cardcellcomponent/index.scss
index 7006456..52f4628 100644
--- a/src/menu/components/card/cardcellcomponent/index.scss
+++ b/src/menu/components/card/cardcellcomponent/index.scss
@@ -19,7 +19,7 @@
       background-position: center center;
       height: auto;
       min-height: 28px;
-      text-align: inherit;
+      // text-align: inherit;
       border-width: 0;
       padding: 0;
       overflow: hidden;
diff --git a/src/menu/components/card/data-card/index.jsx b/src/menu/components/card/data-card/index.jsx
index 7bb0284..6e8d9fd 100644
--- a/src/menu/components/card/data-card/index.jsx
+++ b/src/menu/components/card/data-card/index.jsx
@@ -182,14 +182,14 @@
    */
   deleteCard = (cell) => {
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     confirm({
       content: '纭畾鍒犻櫎鍗$墖鍚楋紵',
       onOk() {
         card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
 
-        _this.updateComponent(card)
+        that.updateComponent(card)
       },
       onCancel() {}
     })
diff --git a/src/menu/components/card/data-card/options.jsx b/src/menu/components/card/data-card/options.jsx
index 6a799d2..ad0ad59 100644
--- a/src/menu/components/card/data-card/options.jsx
+++ b/src/menu/components/card/data-card/options.jsx
@@ -161,7 +161,7 @@
         {value: 'public', label: '鍏叡鏁版嵁婧�', priKeyType: 'static'},
       ],
       linkFields: ['priKeyType'],
-      controlFields: [
+      controlFields: subtype === 'propcard' ? [
         {field: 'goback', values: ['dynamic', 'public']},
         {field: 'empty', values: ['dynamic', 'public']},
         {field: 'jump', values: ['dynamic', 'public']},
@@ -169,7 +169,7 @@
         {field: 'supModule', values: ['static']},
         {field: 'publicId', values: ['public']},
         {field: 'emptyExec', values: ['dynamic', 'public']},
-      ],
+      ] : null,
       forbid: subtype !== 'propcard'
     },
     {
@@ -440,9 +440,9 @@
         {value: 'normal', label: '姝e父鏄剧ず'},
         {value: 'hidden', label: '涓嶅彲瑙�'},
       ],
-      controlFields: [
+      controlFields: subtype === 'propcard' ? [
         {field: 'empty', values: ['normal']},
-      ],
+      ] : null,
       forbid: subtype !== 'propcard'
     },
     {
@@ -452,7 +452,6 @@
       initval: wrap.empty || 'show',
       tooltip: '褰撴煡璇㈡暟鎹负绌烘椂锛岄殣钘忚缁勪欢銆�',
       required: false,
-      skip: true,
       options: [
         {value: 'show', label: '鍚�'},
         {value: 'hidden', label: '鏄�'},
@@ -645,20 +644,19 @@
         {value: 'true', label: '鍚敤'},
         {value: 'false', label: '绂佺敤'},
       ],
-      forbid: !!appType || isprint
+      forbid: !!appType || subtype === 'propcard' || isprint
     },
     {
       type: 'radio',
       field: 'searchBtn',
       label: '鎼滅储鎸夐挳',
       initval: wrap.searchBtn || 'hidden',
-      // tooltip: '鍚敤鎼滅储鏉′欢缂撳瓨鍚庯紝鍦ㄨ彍鍗曞埛鏂版椂鎼滅储鏉′欢涓嶅彉銆�',
       required: false,
       options: [
         {value: 'hidden', label: '闅愯棌'},
         {value: 'show', label: '鏄剧ず'},
       ],
-      forbid: appType === 'mob' || isprint,
+      forbid: appType === 'mob' || subtype === 'propcard' || isprint,
     },
     {
       type: 'radio',
diff --git a/src/menu/components/card/double-data-card/index.jsx b/src/menu/components/card/double-data-card/index.jsx
index cedcc93..62a639f 100644
--- a/src/menu/components/card/double-data-card/index.jsx
+++ b/src/menu/components/card/double-data-card/index.jsx
@@ -176,14 +176,14 @@
    */
   deleteCard = (cell) => {
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     confirm({
       content: '纭畾鍒犻櫎鍗$墖鍚楋紵',
       onOk() {
         card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
 
-        _this.updateComponent(card)
+        that.updateComponent(card)
       },
       onCancel() {}
     })
diff --git a/src/menu/components/card/prop-card/index.jsx b/src/menu/components/card/prop-card/index.jsx
index 9f17c5f..85ce70f 100644
--- a/src/menu/components/card/prop-card/index.jsx
+++ b/src/menu/components/card/prop-card/index.jsx
@@ -161,14 +161,14 @@
    */
   deleteCard = (cell) => {
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     confirm({
       content: '纭畾鍒犻櫎鍗$墖鍚楋紵',
       onOk() {
         card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
 
-        _this.updateComponent(card)
+        that.updateComponent(card)
       },
       onCancel() {}
     })
diff --git a/src/menu/components/card/table-card/index.jsx b/src/menu/components/card/table-card/index.jsx
index 5672f99..0f61b77 100644
--- a/src/menu/components/card/table-card/index.jsx
+++ b/src/menu/components/card/table-card/index.jsx
@@ -164,14 +164,14 @@
    */
   deleteCard = (cell) => {
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     confirm({
       content: '纭畾鍒犻櫎鍗$墖鍚楋紵',
       onOk() {
         card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
 
-        _this.updateComponent(card)
+        that.updateComponent(card)
       },
       onCancel() {}
     })
diff --git a/src/menu/components/carousel/data-card/index.jsx b/src/menu/components/carousel/data-card/index.jsx
index 2d4401d..27bd2fd 100644
--- a/src/menu/components/carousel/data-card/index.jsx
+++ b/src/menu/components/carousel/data-card/index.jsx
@@ -141,14 +141,14 @@
    */
   deleteCard = (cell) => {
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     confirm({
       content: '纭畾鍒犻櫎鍗$墖鍚楋紵',
       onOk() {
         card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
 
-        _this.updateComponent(card)
+        that.updateComponent(card)
       },
       onCancel() {}
     })
diff --git a/src/menu/components/carousel/data-card/options.jsx b/src/menu/components/carousel/data-card/options.jsx
index f7ba65c..cf5156a 100644
--- a/src/menu/components/carousel/data-card/options.jsx
+++ b/src/menu/components/carousel/data-card/options.jsx
@@ -54,9 +54,9 @@
         {value: 'dynamic', label: '鍔ㄦ��'},
         {value: 'static', label: '闈欐��'},
       ],
-      controlFields: [
+      controlFields: subtype === 'propcard' ? [
         {field: 'empty', values: ['dynamic']},
-      ],
+      ] : null,
       forbid: subtype !== 'propcard'
     },
     {
@@ -197,7 +197,6 @@
       initval: wrap.empty || 'show',
       tooltip: '褰撴煡璇㈡暟鎹负绌烘椂锛岄殣钘忚缁勪欢銆�',
       required: false,
-      skip: true,
       options: [
         {value: 'show', label: '鍚�'},
         {value: 'hidden', label: '鏄�'},
diff --git a/src/menu/components/carousel/prop-card/index.jsx b/src/menu/components/carousel/prop-card/index.jsx
index ab40408..194fc41 100644
--- a/src/menu/components/carousel/prop-card/index.jsx
+++ b/src/menu/components/carousel/prop-card/index.jsx
@@ -140,14 +140,14 @@
    */
   deleteCard = (cell) => {
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     confirm({
       content: '纭畾鍒犻櫎鍗$墖鍚楋紵',
       onOk() {
         card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
 
-        _this.updateComponent(card)
+        that.updateComponent(card)
       },
       onCancel() {}
     })
@@ -255,7 +255,6 @@
             <CopyComponent type="carpropcard" card={card}/>
             <PasteComponent config={card} options={['cardcell']} updateConfig={this.updateComponent} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
-            <ClockComponent config={card} updateConfig={this.updateComponent}/>
             {card.wrap.datatype === 'dynamic' ? <ClockComponent config={card} updateConfig={this.updateComponent}/> : <ClockCircleOutlined style={{color: '#eeeeee', cursor: 'not-allowed'}}/>}
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} />
             {card.wrap.datatype === 'dynamic' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : <SettingOutlined style={{color: '#eeeeee', cursor: 'not-allowed'}}/>}
diff --git a/src/menu/components/editor/braft-editor/editorcontent/index.scss b/src/menu/components/editor/braft-editor/editorcontent/index.scss
index 25414a8..01d1ce3 100644
--- a/src/menu/components/editor/braft-editor/editorcontent/index.scss
+++ b/src/menu/components/editor/braft-editor/editorcontent/index.scss
@@ -4,14 +4,4 @@
   >.anticon-form {
     color: purple;
   }
-}
-.model-menu-edit-content-form {
-  .normal-braft-editor {
-    border: 1px solid #d9d9d9;
-    border-radius: 4px;
-    overflow-x: hidden;
-    .bf-container .DraftEditor-root, .bf-container .public-DraftEditor-content {
-      min-height: 500px;
-    }
-  }
 }
\ No newline at end of file
diff --git a/src/menu/components/editor/braft-editor/index.jsx b/src/menu/components/editor/braft-editor/index.jsx
index 6557e9c..ba699ef 100644
--- a/src/menu/components/editor/braft-editor/index.jsx
+++ b/src/menu/components/editor/braft-editor/index.jsx
@@ -38,7 +38,7 @@
       let _card = {
         uuid: card.uuid,
         type: card.type,
-        format: 'object',   // 缁勪欢灞炴�� - 鏁版嵁鏍煎紡
+        format: 'array',    // 缁勪欢灞炴�� - 鏁版嵁鏍煎紡
         pageable: false,    // 缁勪欢灞炴�� - 鏄惁鍙垎椤�
         switchable: false,  // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹�
         width: card.width || 24,
@@ -55,8 +55,16 @@
 
       this.updateComponent(_card)
     } else {
+      let _card = fromJS(card).toJS()
+
+      _card.format = 'array'
+      if (_card.wrap.firstTr === 'light') {
+        _card.wrap.tbStyle = 'th-light'
+        delete _card.wrap.firstTr
+      }
+
       this.setState({
-        card: fromJS(card).toJS()
+        card: _card
       })
     }
   }
@@ -101,8 +109,9 @@
     card.name = card.wrap.name
 
     card.errors = []
+    card.$tables = []
 
-    if (card.wrap.datatype !== 'static') {
+    if (card.wrap.datatype === 'dynamic') {
       card.$c_ds = true
       card.errors = checkComponent(card)
 
@@ -139,6 +148,10 @@
   updateWrap = (res) => {
     const { card } = this.state
 
+    if (res.tbStyle) {
+      res.tbStyle = res.tbStyle.join(' ')
+    }
+
     let _card = {...card, wrap: res}
 
     if (res.datatype === 'public') {
@@ -173,11 +186,11 @@
     let style = {...card.style}
 
     return (
-      <div className={'menu-normal-editor-box ' + (card.wrap.firstTr || '')} style={style} onClick={this.clickComponent} id={card.uuid}>
+      <div className={'menu-normal-editor-box ' + (card.wrap.tbStyle || '')} style={style} onClick={this.clickComponent} id={card.uuid}>
         <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
-            <NormalForm title="瀵屾枃鏈缃�" width={750} update={this.updateWrap} getForms={this.getWrapForms}>
+            <NormalForm title="瀵屾枃鏈缃�" width={850} update={this.updateWrap} getForms={this.getWrapForms}>
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
             <CopyComponent type="editor" card={card}/>
diff --git a/src/menu/components/editor/braft-editor/index.scss b/src/menu/components/editor/braft-editor/index.scss
index aa55923..6e533e8 100644
--- a/src/menu/components/editor/braft-editor/index.scss
+++ b/src/menu/components/editor/braft-editor/index.scss
@@ -25,15 +25,34 @@
     color: #bcbcbc;
   }
 }
-.menu-normal-editor-box.light {
+.menu-normal-editor-box.th-light {
   .braft-content {
     table {
       tr:first-child {
-        background-color:#ffffff;
+        background-color:transparent;
       }
     }
   }
 }
+.menu-normal-editor-box.no-border {
+  .braft-content {
+    table {
+      td, th {
+        border: none!important;
+      }
+      tr td:first-child {
+        padding-left: 0px;
+      }
+    }
+  }
+}
+.menu-normal-editor-box.tb-flex {
+  .braft-content {
+    table {
+      table-layout: fixed;
+    }
+  }
+}
 .menu-normal-editor-box::after {
   display: block;
   content: ' ';
diff --git a/src/menu/components/editor/braft-editor/options.jsx b/src/menu/components/editor/braft-editor/options.jsx
index e0bb4a2..d3f260f 100644
--- a/src/menu/components/editor/braft-editor/options.jsx
+++ b/src/menu/components/editor/braft-editor/options.jsx
@@ -125,24 +125,35 @@
       initval: wrap.empty || 'show',
       tooltip: '褰撴煡璇㈡暟鎹负绌烘椂锛岄殣钘忚缁勪欢銆�',
       required: false,
-      skip: true,
       options: [
         {value: 'show', label: '鍚�'},
         {value: 'hidden', label: '鏄�'},
       ],
     },
     {
-      type: 'radio',
-      field: 'firstTr',
-      label: '琛ㄦ牸棣栬',
-      initval: wrap.firstTr || 'deep',
-      tooltip: '瀵屾枃鏈腑table鐨勯琛岃儗鏅鑹层��',
+      type: 'checkbox',
+      field: 'tbStyle',
+      label: '琛ㄦ牸鏍峰紡',
+      initval: wrap.tbStyle ? wrap.tbStyle.split(' ') : [],
       required: false,
       options: [
-        {value: 'deep', label: '娣辫壊'},
-        {value: 'light', label: '娴呰壊'},
+        {value: 'th-light', label: '琛ㄥご閫忔槑'},
+        {value: 'no-border', label: '鏃犺竟妗�'},
+        {value: 'tb-flex', label: '鍒楃瓑瀹�'},
       ]
     },
+    // {
+    //   type: 'radio',
+    //   field: 'firstTr',
+    //   label: '琛ㄦ牸棣栬',
+    //   initval: wrap.firstTr || 'deep',
+    //   tooltip: '瀵屾枃鏈腑table鐨勯琛岃儗鏅鑹层��',
+    //   required: false,
+    //   options: [
+    //     {value: 'deep', label: '娣辫壊'},
+    //     {value: 'light', label: '娴呰壊'},
+    //   ]
+    // },
     {
       type: 'radio',
       field: 'permission',
diff --git a/src/menu/components/form/formaction/index.jsx b/src/menu/components/form/formaction/index.jsx
index 0287ff7..b577b18 100644
--- a/src/menu/components/form/formaction/index.jsx
+++ b/src/menu/components/form/formaction/index.jsx
@@ -223,7 +223,7 @@
           <div className="mk-popover-control">
             <EditOutlined className="edit" title="缂栬緫" onClick={() => this.handleAction(group.subButton)} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.handleStyle(group.subButton)}/>
-            <ProfileOutlined className="profile" title="setting" onClick={() => this.profileAction()} />
+            <ProfileOutlined className="profile" title="楠岃瘉淇℃伅" onClick={() => this.profileAction()} />
           </div>
         } trigger="hover">
           <Button type="link" className="submit" onDoubleClick={this.changeMenu} style={resetStyle(group.subButton.style)}>{group.subButton.label}</Button>
diff --git a/src/menu/components/form/simple-form/index.jsx b/src/menu/components/form/simple-form/index.jsx
index a159f9b..60e1f9f 100644
--- a/src/menu/components/form/simple-form/index.jsx
+++ b/src/menu/components/form/simple-form/index.jsx
@@ -241,7 +241,7 @@
   
   changecols = (type) => {
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     card.subcards[0].fields = card.subcards[0].fields.map(item => {
       item.labelwidth = 33.3
@@ -267,7 +267,7 @@
     confirm({
       content: `纭畾鍒囨崲涓�${type}鍒楀悧锛焋,
       onOk() {
-        _this.updateComponent(card)
+        that.updateComponent(card)
       },
       onCancel() {}
     })
@@ -288,14 +288,14 @@
 
   closeForm = (cell) => {
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     card.subcards[0].fields = card.subcards[0].fields.filter(item => item.uuid !== cell.uuid)
 
     confirm({
       content: `纭畾鍒犻櫎<<${cell.label}>>鍚楋紵`,
       onOk() {
-        _this.updateComponent(card)
+        that.updateComponent(card)
       },
       onCancel() {}
     })
@@ -503,14 +503,14 @@
 
   clearGroup = () => {
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     card.subcards[0].fields = []
 
     confirm({
       content: `纭畾娓呯┖琛ㄥ崟鍚楋紵`,
       onOk() {
-        _this.updateComponent(card)
+        that.updateComponent(card)
       },
       onCancel() {}
     })
diff --git a/src/menu/components/form/simple-form/index.scss b/src/menu/components/form/simple-form/index.scss
index 2615482..a88431e 100644
--- a/src/menu/components/form/simple-form/index.scss
+++ b/src/menu/components/form/simple-form/index.scss
@@ -58,17 +58,6 @@
       background-color: transparent;
     }
   }
-  // .form-area.mk-shadow {
-  //   .mob-form {
-  //     .am-list-line {
-  //       border: none!important;
-
-  //       .am-input-control {
-  //         background-color: var(--mk-sys-color1);
-  //       }
-  //     }
-  //   }
-  // }
 }
 .menu-simple-form-edit-box::after {
   display: block;
diff --git a/src/menu/components/form/simple-form/options.jsx b/src/menu/components/form/simple-form/options.jsx
index a1a4dc4..ab8acc7 100644
--- a/src/menu/components/form/simple-form/options.jsx
+++ b/src/menu/components/form/simple-form/options.jsx
@@ -233,7 +233,6 @@
       initval: wrap.empty || 'show',
       tooltip: '褰撴煡璇㈡暟鎹负绌烘椂锛岄殣钘忚缁勪欢銆�',
       required: false,
-      skip: true,
       options: [
         {value: 'show', label: '鍚�'},
         {value: 'hidden', label: '鏄�'},
diff --git a/src/menu/components/form/step-form/index.jsx b/src/menu/components/form/step-form/index.jsx
index 4395d59..dd5790b 100644
--- a/src/menu/components/form/step-form/index.jsx
+++ b/src/menu/components/form/step-form/index.jsx
@@ -273,7 +273,7 @@
   closeGroup = (cell) => {
     const { group } = this.state
     let card = fromJS(this.state.card).toJS()
-    const _this = this
+    const that = this
 
     confirm({
       content: '纭畾鍒犻櫎鍒嗙粍鍚楋紵',
@@ -285,8 +285,8 @@
           _group = card.subcards[0] || null
         }
 
-        _this.setState({group: _group})
-        _this.updateComponent(card)
+        that.setState({group: _group})
+        that.updateComponent(card)
       },
       onCancel() {}
     })
@@ -317,7 +317,7 @@
   changecols = (type) => {
     let card = fromJS(this.state.card).toJS()
     let config = fromJS(this.state.group).toJS()
-    let _this = this
+    let that = this
 
     config.fields = config.fields.map(item => {
       item.labelwidth = 33.3
@@ -349,8 +349,8 @@
           }
           return item
         })
-        _this.setState({group: config})
-        _this.updateComponent(card)
+        that.setState({group: config})
+        that.updateComponent(card)
       },
       onCancel() {}
     })
@@ -380,7 +380,7 @@
   closeForm = (cell) => {
     let group = fromJS(this.state.group).toJS()
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     group.fields = group.fields.filter(item => item.uuid !== cell.uuid)
 
@@ -394,8 +394,8 @@
     confirm({
       content: `纭畾鍒犻櫎<<${cell.label}>>鍚楋紵`,
       onOk() {
-        _this.setState({group})
-        _this.updateComponent(card)
+        that.setState({group})
+        that.updateComponent(card)
       },
       onCancel() {}
     })
@@ -571,7 +571,7 @@
   clearGroup = () => {
     let group = fromJS(this.state.group).toJS()
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     group.fields = []
 
@@ -585,8 +585,8 @@
     confirm({
       content: `纭畾娓呯┖琛ㄥ崟鍚楋紵`,
       onOk() {
-        _this.setState({group})
-        _this.updateComponent(card)
+        that.setState({group})
+        that.updateComponent(card)
       },
       onCancel() {}
     })
diff --git a/src/menu/components/form/step-form/options.jsx b/src/menu/components/form/step-form/options.jsx
index aca8cd7..a580960 100644
--- a/src/menu/components/form/step-form/options.jsx
+++ b/src/menu/components/form/step-form/options.jsx
@@ -204,7 +204,6 @@
       initval: wrap.empty || 'show',
       tooltip: '褰撴煡璇㈡暟鎹负绌烘椂锛岄殣钘忚缁勪欢銆�',
       required: false,
-      skip: true,
       options: [
         {value: 'show', label: '鍚�'},
         {value: 'hidden', label: '鏄�'},
diff --git a/src/menu/components/form/tab-form/index.jsx b/src/menu/components/form/tab-form/index.jsx
index c895e37..1758d75 100644
--- a/src/menu/components/form/tab-form/index.jsx
+++ b/src/menu/components/form/tab-form/index.jsx
@@ -279,7 +279,7 @@
   closeGroup = (cell) => {
     const { group } = this.state
     let card = fromJS(this.state.card).toJS()
-    const _this = this
+    const that = this
 
     confirm({
       content: '纭畾鍒犻櫎鍒嗙粍鍚楋紵',
@@ -291,8 +291,8 @@
           _group = card.subcards[0] || null
         }
 
-        _this.setState({group: _group})
-        _this.updateComponent(card)
+        that.setState({group: _group})
+        that.updateComponent(card)
       },
       onCancel() {}
     })
@@ -323,7 +323,7 @@
   changecols = (type) => {
     let card = fromJS(this.state.card).toJS()
     let config = fromJS(this.state.group).toJS()
-    let _this = this
+    let that = this
 
     config.fields = config.fields.map(item => {
       item.labelwidth = 33.3
@@ -355,8 +355,8 @@
           }
           return item
         })
-        _this.setState({group: config})
-        _this.updateComponent(card)
+        that.setState({group: config})
+        that.updateComponent(card)
       },
       onCancel() {}
     })
@@ -386,7 +386,7 @@
   closeForm = (cell) => {
     let group = fromJS(this.state.group).toJS()
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     group.fields = group.fields.filter(item => item.uuid !== cell.uuid)
 
@@ -400,8 +400,8 @@
     confirm({
       content: `纭畾鍒犻櫎<<${cell.label}>>鍚楋紵`,
       onOk() {
-        _this.setState({group})
-        _this.updateComponent(card)
+        that.setState({group})
+        that.updateComponent(card)
       },
       onCancel() {}
     })
@@ -573,7 +573,7 @@
   clearGroup = () => {
     let group = fromJS(this.state.group).toJS()
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     group.fields = []
 
@@ -587,8 +587,8 @@
     confirm({
       content: `纭畾娓呯┖琛ㄥ崟鍚楋紵`,
       onOk() {
-        _this.setState({group})
-        _this.updateComponent(card)
+        that.setState({group})
+        that.updateComponent(card)
       },
       onCancel() {}
     })
diff --git a/src/menu/components/group/normal-group/index.jsx b/src/menu/components/group/normal-group/index.jsx
index e26fb57..aa41f27 100644
--- a/src/menu/components/group/normal-group/index.jsx
+++ b/src/menu/components/group/normal-group/index.jsx
@@ -136,15 +136,15 @@
 
     if (group.components.length === 0) return
 
-    const _this = this
+    const that = this
     confirm({
       title: '纭畾閲婃斁鍒嗙粍鍏冪礌鍚楋紵',
       content: '',
       onOk() {
-        _this.props.unGroup(group.uuid)
+        that.props.unGroup(group.uuid)
 
         setTimeout(() => {
-          _this.updataGroup()
+          that.updataGroup()
         }, 10)
       },
       onCancel() {}
diff --git a/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx b/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx
index a7834c9..786f5c5 100644
--- a/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx
+++ b/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx
@@ -219,7 +219,7 @@
           </Col> : null}
           {!type ? <Col span={8}>
             <Form.Item label="鎶ラ敊瀛楁" style={{margin: 0, whiteSpace: 'nowrap'}}>
-              errorcode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT銆丆NT銆�-2NT锛�, retmsg
+              errorcode, retmsg
             </Form.Item>
           </Col> : null}
           {!type ? <Col span={24} className="sqlfield">
diff --git a/src/menu/components/module/invoice/verifycard/customscript/index.jsx b/src/menu/components/module/invoice/verifycard/customscript/index.jsx
index c9a1299..8d848ce 100644
--- a/src/menu/components/module/invoice/verifycard/customscript/index.jsx
+++ b/src/menu/components/module/invoice/verifycard/customscript/index.jsx
@@ -201,7 +201,7 @@
         <Row gutter={24}>
           {!type ? <Col span={8}>
             <Form.Item label={'鎶ラ敊瀛楁'} style={{margin: 0, whiteSpace: 'nowrap'}}>
-              errorcode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT銆丆NT銆�-2NT锛�, retmsg
+              errorcode, retmsg
             </Form.Item>
           </Col> : null}
           {!type ? <Col span={24} className="sqlfield">
diff --git a/src/menu/components/search/main-search/dragsearch/card.jsx b/src/menu/components/search/main-search/dragsearch/card.jsx
index 6e153b6..72462e7 100644
--- a/src/menu/components/search/main-search/dragsearch/card.jsx
+++ b/src/menu/components/search/main-search/dragsearch/card.jsx
@@ -132,6 +132,11 @@
     </>)
   }
 
+  let labelwidth = card.labelwidth || 33.3
+  if (card.labelShow === 'false') {
+    labelwidth = 0
+  }
+
   return (
     <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
       <div className="mk-popover-control">
@@ -143,8 +148,8 @@
       <div className={'page-card ' + (card.labelShow === 'false' ? 'label-hide ' : '') + card.type + (card.advanced === 'true' ? ' advanced' : '') + (card.query === 'false' ? ' no-query' : '')} style={{ opacity: opacity}}>
         <div ref={node => drag(drop(node))}>
           <Form.Item
-            labelCol={{xs: { span: 24 }, sm: { span: 8 }}}
-            wrapperCol = {{xs: { span: 24 }, sm: { span: 16 }}}
+            labelCol={{style: {width: labelwidth + '%'}}}
+            wrapperCol={{style: {width: (100 - labelwidth) + '%'}}}
             label={card.labelShow !== 'false' ? card.label : ''}
             required={card.required === 'true'}
             help={card.field + (card.datefield ? ', ' + card.datefield : '') + (card.advanced === 'true' ? '锛堥珮绾ф悳绱級' : '')}
diff --git a/src/menu/components/search/main-search/index.jsx b/src/menu/components/search/main-search/index.jsx
index ef3e3c1..33814cc 100644
--- a/src/menu/components/search/main-search/index.jsx
+++ b/src/menu/components/search/main-search/index.jsx
@@ -289,15 +289,15 @@
    * @description 鎼滅储鏉′欢鍒犻櫎
    */
   deleteElement = (cell) => {
-    let _this = this
+    let that = this
 
     confirm({
       content: `纭畾鍒犻櫎 - ${cell.label} 锛焋,
       onOk() {
-        let _card = fromJS(_this.state.card).toJS()
+        let _card = fromJS(that.state.card).toJS()
         _card.search = _card.search.filter(item => item.uuid !== cell.uuid)
 
-        _this.updateComponent(_card)
+        that.updateComponent(_card)
       },
       onCancel() {}
     })
diff --git a/src/menu/components/search/main-search/index.scss b/src/menu/components/search/main-search/index.scss
index 87b0e05..b5a03a5 100644
--- a/src/menu/components/search/main-search/index.scss
+++ b/src/menu/components/search/main-search/index.scss
@@ -44,7 +44,11 @@
     .ant-form-item {
       position: relative;
       margin-bottom: 0px;
+      .ant-form-item-label {
+        float: left;
+      }
       .ant-form-item-control-wrapper {
+        float: left;
         .ant-select {
           width: 100%;
           margin-top: 4px;
diff --git a/src/menu/components/share/actioncomponent/actionform/index.jsx b/src/menu/components/share/actioncomponent/actionform/index.jsx
index 104c448..dcf94bf 100644
--- a/src/menu/components/share/actioncomponent/actionform/index.jsx
+++ b/src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -18,8 +18,8 @@
   pop: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'hover', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'refreshTab', 'position', 'hoverTitle', 'hidden', 'preButton'],
   prompt: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'hover', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'refreshTab', 'position', 'tipTitle', 'hoverTitle', 'hidden', 'preButton'],
   exec: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'hover', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'refreshTab', 'hoverTitle', 'hidden', 'preButton'],
-  excelIn: ['label', 'Ot', 'OpenType', 'intertype', 'show', 'hover', 'icon', 'class', 'color', 'sheet', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'width', 'hidden'],
-  excelOut: ['label', 'Ot', 'OpenType', 'intertype', 'show', 'hover', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'pagination', 'search', 'width', 'hidden'],
+  excelIn: ['label', 'Ot', 'OpenType', 'intertype', 'show', 'hover', 'icon', 'class', 'color', 'sheet', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'width', 'hidden', 'refreshTab'],
+  excelOut: ['label', 'Ot', 'OpenType', 'intertype', 'show', 'hover', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'pagination', 'search', 'width', 'hidden', 'refreshTab'],
   popview: ['label', 'Ot', 'OpenType', 'show', 'hover', 'icon', 'class', 'color', 'popClose', 'width', 'display', 'ratio', 'syncComponent', 'clickouter', 'maskStyle', 'closeButton', 'hidden'],
   tab: ['label', 'Ot', 'OpenType', 'show', 'hover', 'icon', 'class', 'color', 'linkmenu', 'width', 'hidden', 'openTab'],
   innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'show', 'hover', 'swipe', 'icon', 'class', 'color', 'width', 'hidden'],
@@ -233,7 +233,7 @@
       if (this.record.openmenu && this.record.openmenu !== 'goback') {
         shows.push('open')
       }
-      if (this.record.execSuccess === 'grid' || this.record.execError === 'grid') {
+      if (['grid'].includes(this.record.execSuccess) || ['grid'].includes(this.record.execError)) {
         shows.push('resetPageIndex')
       }
 
@@ -305,7 +305,7 @@
       if (this.record.execSuccess === 'goback') {
         shows.push('reload')
       }
-      if (this.record.execSuccess === 'grid' || this.record.execError === 'grid') {
+      if (['grid'].includes(this.record.execSuccess) || ['grid'].includes(this.record.execError)) {
         shows.push('resetPageIndex')
       }
 
@@ -352,7 +352,7 @@
       } else {
         shows.push('database')
       }
-      if (this.record.execSuccess === 'grid' || this.record.execError === 'grid') {
+      if (['grid'].includes(this.record.execSuccess) || ['grid'].includes(this.record.execError)) {
         shows.push('resetPageIndex')
       }
     } else if (openType === 'excelOut') {
@@ -389,7 +389,7 @@
       } else {
         shows.push('database')
       }
-      if (this.record.execSuccess === 'grid' || this.record.execError === 'grid') {
+      if (['grid'].includes(this.record.execSuccess) || ['grid'].includes(this.record.execError)) {
         shows.push('resetPageIndex')
       }
       if (this.record.Ot !== 'notRequired' && appType === 'mob') {
@@ -443,6 +443,15 @@
         reOptions.Ot = requireOptions
       } else if (this.record.pageTemplate === 'pay') {
         reOptions.Ot = requireOptions.filter(op => op.value === 'requiredSgl')
+
+        shows.push('payMode', 'wxApp', 'wxMerch')
+        if (this.record.payMode === 'inner') {
+          reRequired.innerFunc = true
+          shows.push('innerFunc')
+        }
+        if (this.record.payMode !== 'none') {
+          shows.push('output')
+        }
       }
     } else if (openType === 'funcbutton') {
       reOptions.intertype = this.state.interTypeOptions.filter(op => op.value !== 'custom')
@@ -476,14 +485,16 @@
           shows.push('innerFunc', 'extraParam')
           reRequired.innerFunc = true
         }
-        if (this.record.execSuccess === 'grid' || this.record.execError === 'grid') {
+        if (['grid'].includes(this.record.execSuccess) || ['grid'].includes(this.record.execError)) {
           shows.push('resetPageIndex')
         }
         if (this.record.execMode === 'pop' || this.record.execMode === 'prompt') {
           shows.push('position')
         }
       } else if (_funcType === 'mkBinding' || _funcType === 'mkUnBinding') {
-        shows.push('execSuccess', 'execError')
+        shows.push('execSuccess', 'execError', 'tipTitle')
+      } else if (_funcType === 'mkUnsubscribe' || _funcType === 'reAuth') {
+        shows.push('tipTitle')
       } else if (_funcType === 'closetab') {
         shows.push('refreshTab')
       } else if (_funcType === 'scan') {
@@ -511,16 +522,38 @@
 
         shows.push('innerFunc', 'Ot', 'execSuccess', 'execError', 'urlkey')
       } else if (_funcType === 'pay') {
-        shows.push('payType', 'Ot', 'execSuccess', 'execError', 'syncComponent', 'openmenu')
+        shows.push('payType', 'wxApp', 'wxMerch', 'Ot', 'execSuccess', 'execError', 'syncComponent', 'openmenu')
         if (this.record.openmenu && this.record.openmenu !== 'goback') {
           shows.push('open')
         }
         reOptions.Ot = requireOptions.filter(op => ['requiredSgl'].includes(op.value))
+        shows.push('payMode')
+        if (this.record.payMode === 'inner') {
+          reRequired.innerFunc = true
+          shows.push('innerFunc')
+        }
+        if (this.record.payMode !== 'none') {
+          shows.push('output')
+        }
       } else if (_funcType === 'refund') {
         shows.push('Ot', 'execSuccess', 'execError', 'syncComponent', 'openmenu', 'tipTitle')
         reOptions.Ot = requireOptions.filter(op => ['requiredSgl'].includes(op.value))
+
+        shows.push('payMode')
+        if (this.record.payMode === 'inner') {
+          reRequired.innerFunc = true
+          shows.push('innerFunc')
+        }
+        if (this.record.payMode !== 'none') {
+          shows.push('output')
+        }
       } else if (_funcType === 'shareLink') {
         shows.push('shortUrl', 'shareUrl', 'shareProUrl', 'shareTip')
+      } else if (_funcType === 'openLocation') {
+        shows.push('Ot')
+        if (Ot === 'requiredSgl') {
+          shows.push('nameField', 'addressField')
+        }
       // } else if (_funcType === 'expPdf') {
       //   shows.push('exportType')
       }
@@ -856,22 +889,42 @@
             { max: 512, message: '鏈�澶�512涓瓧绗�' }
           )
         } else if (item.key === 'output') {
-          if (this.record.intertype === 'system' || ((this.record.intertype === 'outer' || this.record.intertype === 'custom') && this.record.callbackType === 'script')) {
-            rules = [{
-              pattern: /^@[0-9a-zA-Z_]+@?$/,
-              message: '鍙橀噺浠绗﹀紑澶达紝鍙娇鐢ㄥ瓧姣嶃�佹暟瀛椾互鍙奯'
-            }, {
-              max: 100,
-              message: '鏈�澶�100涓瓧绗︺��'
-            }]
+          if (['pop', 'prompt', 'exec'].includes(this.record.OpenType)) {
+            if (this.record.intertype === 'system' || ((this.record.intertype === 'outer' || this.record.intertype === 'custom') && this.record.callbackType === 'script')) {
+              rules = [{
+                pattern: /^@[0-9a-zA-Z_]+@?$/,
+                message: '鍙橀噺浠绗﹀紑澶达紝鍙娇鐢ㄥ瓧姣嶃�佹暟瀛椾互鍙奯'
+              }, {
+                max: 100,
+                message: '鏈�澶�100涓瓧绗︺��'
+              }]
+            } else {
+              rules = [{
+                pattern: /^[0-9a-zA-Z_]*$/,
+                message: '瀛楁鍙娇鐢ㄥ瓧姣嶃�佹暟瀛椾互鍙奯'
+              }, {
+                max: 100,
+                message: '鏈�澶�100涓瓧绗︺��'
+              }]
+            }
           } else {
-            rules = [{
-              pattern: /^[0-9a-zA-Z_]*$/,
-              message: '瀛楁鍙娇鐢ㄥ瓧姣嶃�佹暟瀛椾互鍙奯'
-            }, {
-              max: 100,
-              message: '鏈�澶�100涓瓧绗︺��'
-            }]
+            if (this.record.payMode === 'system') {
+              rules = [{
+                pattern: /^@[0-9a-zA-Z_]+@?$/,
+                message: '鍙橀噺浠绗﹀紑澶达紝鍙娇鐢ㄥ瓧姣嶃�佹暟瀛椾互鍙奯'
+              }, {
+                max: 100,
+                message: '鏈�澶�100涓瓧绗︺��'
+              }]
+            } else {
+              rules = [{
+                pattern: /^[0-9a-zA-Z_]*$/,
+                message: '瀛楁鍙娇鐢ㄥ瓧姣嶃�佹暟瀛椾互鍙奯'
+              }, {
+                max: 100,
+                message: '鏈�澶�100涓瓧绗︺��'
+              }]
+            }
           }
         } else {
           rules.push({ max: formRule.input.max, message: formRule.input.message })
diff --git a/src/menu/components/share/actioncomponent/dragaction/card.jsx b/src/menu/components/share/actioncomponent/dragaction/card.jsx
index a90472c..e65eb9b 100644
--- a/src/menu/components/share/actioncomponent/dragaction/card.jsx
+++ b/src/menu/components/share/actioncomponent/dragaction/card.jsx
@@ -46,6 +46,8 @@
     hasProfile = true
   } else if (card.funcType === 'megvii') {
     hasProfile = true
+  } else if (card.payMode === 'system') {
+    hasProfile = true
   }
 
   let btnElement = null
@@ -109,7 +111,7 @@
         {!card.$fixed ? <CopyOutlined className="copy" onClick={() => copyCard(id)} /> : null}
         {!card.$fixed ? <CloseOutlined className="close" onClick={() => delCard(id)} /> : null}
         {type !== 'datacard' && type !== 'basetable' && !card.$fixed ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => changeStyle(id)}/> : ''}
-        {hasProfile ? <ProfileOutlined className="profile" title="楠岃瘉" onClick={() => profileCard(id)} /> : null}
+        {hasProfile ? <ProfileOutlined className="profile" title="楠岃瘉淇℃伅" onClick={() => profileCard(id)} /> : null}
         {updateTime}
       </div>
     } trigger="hover">
diff --git a/src/menu/components/share/actioncomponent/formconfig.jsx b/src/menu/components/share/actioncomponent/formconfig.jsx
index 1106bec..e1544de 100644
--- a/src/menu/components/share/actioncomponent/formconfig.jsx
+++ b/src/menu/components/share/actioncomponent/formconfig.jsx
@@ -18,6 +18,11 @@
   let type = ''
   let alltype = config.type + '_' + config.subtype
 
+  columns = columns.map(item => ({
+    value: item.field,
+    text: `${item.label}锛�${item.field}锛塦
+  }))
+
   if (card.eleType === 'button') {
     type = 'card'
   } else if (config.subtype === 'datacard' || config.subtype === 'tablecard' || config.subtype === 'dualdatacard') {
@@ -211,6 +216,7 @@
       { value: 'copyurl', text: '澶嶅埗閾炬帴鍦板潃' },
       { value: 'expPdf', text: '瀵煎嚭PDF' },
       { value: 'shareLink', text: '鍒嗕韩閾炬帴' },
+      { value: 'openLocation', text: '鎵撳紑鍦板浘'},
       { value: 'logout', text: '閫�鍑�' },
       { value: 'goBack', text: '杩斿洖' },
     ]
@@ -222,6 +228,7 @@
     opentypes = opentypes.filter(item => item.value !== 'tab')
     funTypes = [
       { value: 'print', text: '鏍囩鎵撳嵃' },
+      { value: 'refund', text: '閫�娆�' },
     ]
     pageTemps = [
       { value: 'linkpage', text: '鍏宠仈鑿滃崟' },
@@ -318,7 +325,7 @@
   }
 
   let width = card.width || (card.width === 0 ? 0 : 12)
-  if (/x/.test(card.width)) {
+  if (card.width && /x/.test(card.width)) {
     width = +width.replace(/x/, '.5')
   }
 
@@ -330,9 +337,21 @@
     extraParam.push('dataM')
   }
 
+  let apps = []
+  let merchs = []
   if (!appType) {
     if (typeof(card.openmenu) === 'string') {
       card.openmenu = []
+    }
+
+    if (window.GLOB.WXApps) {
+      window.GLOB.WXApps.forEach(item => {
+        if (item.appType === 'merchant') {
+          merchs.push({value: item.appId, text: item.appName})
+        } else {
+          apps.push({value: item.appId, text: item.appName})
+        }
+      })
     }
   } else {
     if (typeof(card.openmenu) !== 'string') {
@@ -421,20 +440,20 @@
       required: true,
       options: []
     },
-    {
-      type: 'checkbox',
-      key: 'payType',
-      label: '鏀粯鏂瑰紡',
-      initVal: card.payType || [],
-      required: true,
-      options: [{
-        value: 'wxpay',
-        text: '寰俊'
-      // }, {
-      //   value: 'alipay',
-      //   text: '鏀粯瀹�'
-      }]
-    },
+    // {
+    //   type: 'checkbox',
+    //   key: 'payType',
+    //   label: '鏀粯鏂瑰紡',
+    //   initVal: card.payType || [],
+    //   required: true,
+    //   options: [{
+    //     value: 'wxpay',
+    //     text: '寰俊'
+    //   // }, {
+    //   //   value: 'alipay',
+    //   //   text: '鏀粯瀹�'
+    //   }]
+    // },
     {
       type: 'radio',
       key: 'procMode',
@@ -470,15 +489,6 @@
     },
     {
       type: 'text',
-      key: 'innerFunc',
-      label: '鍐呴儴鍑芥暟',
-      initVal: card.innerFunc || '',
-      tooltip: functip,
-      fields: usefulFields,
-      required: false,
-    },
-    {
-      type: 'text',
       key: 'urlkey',
       label: '鍦板潃瀛楁',
       initVal: card.urlkey || '',
@@ -493,6 +503,53 @@
       initVal: card.pageTemplate || '',
       required: true,
       options: pageTemps
+    },
+    {
+      type: 'radio',
+      key: 'payMode',
+      label: '鍙傛暟澶勭悊',
+      initVal: card.payMode || 'none',
+      tooltip: '鏀粯锛堟垨閫�娆撅級鍗曞彿鐨勯澶勭悊鏂瑰紡銆�',
+      required: true,
+      options: [{
+        value: 'system',
+        text: '绯荤粺鍑芥暟'
+      }, {
+        value: 'inner',
+        text: '鍐呴儴鍑芥暟'
+      }, {
+        value: 'none',
+        text: '鏃�'
+      }]
+    },
+    {
+      type: 'select',
+      key: 'wxApp',
+      label: '鍏宠仈搴旂敤',
+      initVal: card.wxApp || '',
+      tooltip: '璇峰叧鑱旀敮浠樼殑鍏紬鍙锋垨灏忕▼搴忋��',
+      required: true,
+      forbid: apps.length === 0,
+      options: apps
+    },
+    {
+      type: 'select',
+      key: 'wxMerch',
+      label: '鍏宠仈鍟嗘埛',
+      initVal: card.wxMerch || '',
+      tooltip: '璇峰叧鑱旀敮浠樼殑鍟嗘埛鍙枫��',
+      required: true,
+      forbid: merchs.length === 0,
+      options: merchs
+    },
+    {
+      type: 'text',
+      key: 'innerFunc',
+      label: '鍐呴儴鍑芥暟',
+      initVal: card.innerFunc || '',
+      tooltip: functip,
+      fields: usefulFields,
+      required: false,
     },
     {
       type: 'printTemps',
@@ -746,7 +803,7 @@
       key: 'execError',
       label: '澶辫触鍚�',
       initVal: card.execError || 'never',
-      tooltip: refresh.length ? '鎵ц鍒锋柊婧愮粍浠舵椂锛岃鍦ㄦ簮鎸夐挳锛堝脊绐楁寜閽級涓缃叧闂悗鍒锋柊閭d竴椤癸紝娉細姝ゆ椂浼氬悓姝ュ埛鏂板綋鍓嶇粍浠跺拰涓婄骇缁勪欢-琛屻�傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級銆�' : '閫夋嫨鍒锋柊琛屾椂锛屽鏋滈�夋嫨澶氭潯鏁版嵁浼氬埛鏂扮粍浠讹紱閫夋嫨鍒锋柊琛� / 缁勪欢鏃讹紝濡傛灉褰撳墠琛屾暟鎹笉瀛樺湪浼氬埛鏂扮粍浠躲�傛敞锛氫笂绾х粍浠跺湪鏁版嵁婧愪腑娣诲姞銆傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級銆�',
+      tooltip: refresh.length ? '鎵ц鍒锋柊婧愮粍浠舵椂锛岃鍦ㄦ簮鎸夐挳锛堝脊绐楁寜閽級涓缃叧闂悗鍒锋柊閭d竴椤癸紝娉細姝ゆ椂浼氬悓姝ュ埛鏂板綋鍓嶇粍浠跺拰涓婄骇缁勪欢-琛屻�傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級锛汙open_target_menu@ 鍙墽琛屾墦寮�鑿滃崟銆�' : '閫夋嫨鍒锋柊琛屾椂锛屽鏋滈�夋嫨澶氭潯鏁版嵁浼氬埛鏂扮粍浠讹紱閫夋嫨鍒锋柊琛� / 缁勪欢鏃讹紝濡傛灉褰撳墠琛屾暟鎹笉瀛樺湪浼氬埛鏂扮粍浠躲�傛敞锛氫笂绾х粍浠跺湪鏁版嵁婧愪腑娣诲姞銆傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級锛汙open_target_menu@ 鍙墽琛屾墦寮�鑿滃崟銆�',
       required: true,
       options: [{
         value: 'never',
@@ -804,6 +861,25 @@
         value: 'false',
         text: '涓嶉噸缃�'
       }]
+    },
+    {
+      type: 'select',
+      key: 'nameField',
+      label: '浣嶇疆鍚嶅瓧娈�',
+      initVal: card.nameField || '',
+      tooltip: '鎵撳紑鍦板浘鏃跺彲灞曠ず浣嶇疆鍚嶄笌璇︾粏鍦板潃锛岃缁戝畾鏁版嵁婧愬瓧娈甸泦锛岀粡绾害璇蜂娇鐢╨atitude銆乴ongitude涓旂粡绾害涓嶅彲涓虹┖銆�',
+      required: false,
+      allowClear: true,
+      options: columns
+    },
+    {
+      type: 'select',
+      key: 'addressField',
+      label: '鍦板潃瀛楁',
+      initVal: card.addressField || '',
+      required: false,
+      allowClear: true,
+      options: columns
     },
     {
       type: 'radio',
@@ -984,6 +1060,47 @@
       options: modules.length ? [...modules, {value: 'multiComponent', label: '澶氱粍浠�'}] : []
     },
     {
+      type: 'cascader',
+      key: 'refreshTab',
+      label: '鍒锋柊鑿滃崟',
+      initVal: card.refreshTab || [],
+      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栨墽琛屽け璐ヤ笖瀛樺湪鍒锋柊椤规椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑鑿滃崟',
+      required: false,
+      forbid: isApp || viewType === 'popview',
+      options: menulist
+    },
+    {
+      type: !appType ? 'cascader' : 'select',
+      key: 'openmenu',
+      label: '鎵撳紑鑿滃崟',
+      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栧け璐ユ椂杩斿洖@open_target_menu@锛夐渶瑕佹墦寮�鐨勮彍鍗曘��',
+      initVal: card.openmenu || (!appType ? [] : ''),
+      help: appType === 'mob' || appType === 'pc' ? '鍙繑鍥炰笂涓�椤点��' : null,
+      extendName: 'MenuNo',
+      required: false,
+      allowClear: true,
+      options: appType === 'mob' || appType === 'pc' ? appMenus : menulist,
+      forbid: viewType === 'popview'
+    },
+    {
+      type: 'cascader',
+      key: 'switchTab',
+      label: '鍒囨崲鏍囩',
+      initVal: card.switchTab || [],
+      tooltip: '鎵ц鎴愬姛鍚庯紝闇�瑕佸垏鎹㈢殑鏍囩椤点��' + (appType === 'mob' ? '娉細灏忕▼搴忎腑鏃犳晥' : ''),
+      required: false,
+      options: tabs
+    },
+    {
+      type: 'cascader',
+      key: 'anchors',
+      label: '璺宠浆閿氱偣',
+      initVal: card.anchors || [],
+      tooltip: '鎵ц鎴愬姛鍚庯紝闇�瑕佽烦杞殑閿氱偣銆�' + (appType === 'mob' ? '娉細灏忕▼搴忎腑鏃犳晥' : ''),
+      required: false,
+      options: anchors
+    },
+    {
       type: 'radio',
       key: 'pagination',
       label: '鍒嗛〉',
@@ -1013,47 +1130,6 @@
         text: '闈炲繀濉�'
       }],
       forbid: appType === 'mob'
-    },
-    {
-      type: 'cascader',
-      key: 'refreshTab',
-      label: '鍒锋柊鑿滃崟',
-      initVal: card.refreshTab || [],
-      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栨墽琛屽け璐ヤ笖瀛樺湪鍒锋柊椤规椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑鑿滃崟',
-      required: false,
-      forbid: isApp || viewType === 'popview',
-      options: menulist
-    },
-    {
-      type: !appType ? 'cascader' : 'select',
-      key: 'openmenu',
-      label: '鎵撳紑鑿滃崟',
-      tooltip: '鎵ц鎴愬姛鍚庨渶瑕佹墦寮�鐨勮彍鍗曘��',
-      initVal: card.openmenu || (!appType ? [] : ''),
-      help: appType === 'mob' || appType === 'pc' ? '鍙繑鍥炰笂涓�椤点��' : null,
-      extendName: 'MenuNo',
-      required: false,
-      allowClear: true,
-      options: appType === 'mob' || appType === 'pc' ? appMenus : menulist,
-      forbid: viewType === 'popview'
-    },
-    {
-      type: 'cascader',
-      key: 'switchTab',
-      label: '鍒囨崲鏍囩',
-      initVal: card.switchTab || [],
-      tooltip: '鎵ц鎴愬姛鍚庯紝闇�瑕佸垏鎹㈢殑鏍囩椤点��' + (appType === 'mob' ? '娉細灏忕▼搴忎腑鏃犳晥' : ''),
-      required: false,
-      options: tabs
-    },
-    {
-      type: 'cascader',
-      key: 'anchors',
-      label: '璺宠浆閿氱偣',
-      initVal: card.anchors || [],
-      tooltip: '鎵ц鎴愬姛鍚庯紝闇�瑕佽烦杞殑閿氱偣銆�' + (appType === 'mob' ? '娉細灏忕▼搴忎腑鏃犳晥' : ''),
-      required: false,
-      options: anchors
     },
     {
       type: 'select',
@@ -1100,10 +1176,7 @@
       required: false,
       allowClear: true,
       forbid: position !== 'line',
-      options: columns.map(item => ({
-        value: item.field,
-        text: `${item.label}锛�${item.field}锛塦
-      }))
+      options: columns
     },
     {
       type: 'radio',
@@ -1320,10 +1393,7 @@
       initVal: card.controlField || '',
       required: true,
       allowClear: true,
-      options: columns.map(item => ({
-        value: item.field,
-        text: `${item.label}锛�${item.field}锛塦
-      }))
+      options: columns
     },
     {
       type: 'text',
@@ -1735,6 +1805,24 @@
     extraParam.push('dataM')
   }
 
+  let apps = []
+  let merchs = []
+
+  if (window.GLOB.WXApps) {
+    window.GLOB.WXApps.forEach(item => {
+      if (item.appType === 'merchant') {
+        merchs.push({value: item.appId, text: item.appName})
+      } else {
+        apps.push({value: item.appId, text: item.appName})
+      }
+    })
+  }
+
+  let width = card.width || (card.width === 0 ? 0 : 12)
+  if (card.width && /x/.test(card.width)) {
+    width = +width.replace(/x/, '.5')
+  }
+
   let forms = [
     {
       type: 'select',
@@ -1795,20 +1883,20 @@
       required: true,
       options: []
     },
-    {
-      type: 'checkbox',
-      key: 'payType',
-      label: '鏀粯鏂瑰紡',
-      initVal: card.payType || [],
-      required: true,
-      options: [{
-        value: 'wxpay',
-        text: '寰俊'
-      // }, {
-      //   value: 'alipay',
-      //   text: '鏀粯瀹�'
-      }]
-    },
+    // {
+    //   type: 'checkbox',
+    //   key: 'payType',
+    //   label: '鏀粯鏂瑰紡',
+    //   initVal: card.payType || [],
+    //   required: true,
+    //   options: [{
+    //     value: 'wxpay',
+    //     text: '寰俊'
+    //   // }, {
+    //   //   value: 'alipay',
+    //   //   text: '鏀粯瀹�'
+    //   }]
+    // },
     {
       type: 'radio',
       key: 'procMode',
@@ -1844,15 +1932,6 @@
     },
     {
       type: 'text',
-      key: 'innerFunc',
-      label: '鍐呴儴鍑芥暟',
-      initVal: card.innerFunc || '',
-      tooltip: functip,
-      fields: usefulFields,
-      required: false,
-    },
-    {
-      type: 'text',
       key: 'urlkey',
       label: '鍦板潃瀛楁',
       initVal: card.urlkey || '',
@@ -1867,6 +1946,53 @@
       initVal: card.pageTemplate || '',
       required: true,
       options: pageTemps
+    },
+    {
+      type: 'radio',
+      key: 'payMode',
+      label: '鍙傛暟澶勭悊',
+      initVal: card.payMode || 'none',
+      tooltip: '鏀粯锛堟垨閫�娆撅級鍗曞彿鐨勯澶勭悊鏂瑰紡銆�',
+      required: true,
+      options: [{
+        value: 'system',
+        text: '绯荤粺鍑芥暟'
+      }, {
+        value: 'inner',
+        text: '鍐呴儴鍑芥暟'
+      }, {
+        value: 'none',
+        text: '鏃�'
+      }]
+    },
+    {
+      type: 'select',
+      key: 'wxApp',
+      label: '鍏宠仈搴旂敤',
+      initVal: card.wxApp || '',
+      tooltip: '璇峰叧鑱旀敮浠樼殑鍏紬鍙锋垨灏忕▼搴忋��',
+      required: true,
+      forbid: apps.length === 0,
+      options: apps
+    },
+    {
+      type: 'select',
+      key: 'wxMerch',
+      label: '鍏宠仈鍟嗘埛',
+      initVal: card.wxMerch || '',
+      tooltip: '璇峰叧鑱旀敮浠樼殑鍟嗘埛鍙枫��',
+      required: true,
+      forbid: merchs.length === 0,
+      options: merchs
+    },
+    {
+      type: 'text',
+      key: 'innerFunc',
+      label: '鍐呴儴鍑芥暟',
+      initVal: card.innerFunc || '',
+      tooltip: functip,
+      fields: usefulFields,
+      required: false,
     },
     {
       type: 'printTemps',
@@ -2109,7 +2235,7 @@
       key: 'execError',
       label: '澶辫触鍚�',
       initVal: card.execError || 'never',
-      tooltip: refresh.length ? '鎵ц鍒锋柊婧愮粍浠舵椂锛岃鍦ㄦ簮鎸夐挳锛堝脊绐楁寜閽級涓缃叧闂悗鍒锋柊鍝竴椤癸紝娉細姝ゆ椂浼氬悓姝ュ埛鏂板綋鍓嶇粍浠跺拰涓婄骇缁勪欢-琛屻�傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級銆�' : '閫夋嫨鍒锋柊琛屾椂锛屽鏋滈�夋嫨澶氭潯鏁版嵁浼氬埛鏂扮粍浠讹紱閫夋嫨鍒锋柊琛� / 缁勪欢鏃讹紝濡傛灉褰撳墠琛屾暟鎹笉瀛樺湪浼氬埛鏂扮粍浠躲�傛敞锛氫笂绾х粍浠跺湪鏁版嵁婧愪腑娣诲姞銆傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級銆�',
+      tooltip: refresh.length ? '鎵ц鍒锋柊婧愮粍浠舵椂锛岃鍦ㄦ簮鎸夐挳锛堝脊绐楁寜閽級涓缃叧闂悗鍒锋柊鍝竴椤癸紝娉細姝ゆ椂浼氬悓姝ュ埛鏂板綋鍓嶇粍浠跺拰涓婄骇缁勪欢-琛屻�傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級锛汙open_target_menu@ 鍙墽琛屾墦寮�鑿滃崟銆�' : '閫夋嫨鍒锋柊琛屾椂锛屽鏋滈�夋嫨澶氭潯鏁版嵁浼氬埛鏂扮粍浠讹紱閫夋嫨鍒锋柊琛� / 缁勪欢鏃讹紝濡傛灉褰撳墠琛屾暟鎹笉瀛樺湪浼氬埛鏂扮粍浠躲�傛敞锛氫笂绾х粍浠跺湪鏁版嵁婧愪腑娣诲姞銆傚闇�璇煶鎾姤璇蜂互@speak@寮�澶达紝鎾姤鍐呭鎴栨枃浠舵斁缃簬<<>>涓�傝繑鍥炰俊鎭紙@retmsg锛夌壒娈婃爣璇嗭細@close_tab@ 鎵ц锛堝叧闂爣绛�-绠$悊绯荤粺锛夛紱@close_popup@ 鎵ц锛堝叧闂脊绐楋級锛汙goback@ 鎵ц锛堣繑鍥炰笂涓�椤�-瀛愬簲鐢級锛汙open_target_menu@ 鍙墽琛屾墦寮�鑿滃崟銆�',
       required: true,
       options: [{
         value: 'never',
@@ -2218,18 +2344,18 @@
       tooltip: '鍒嗕韩鏃跺鐢ㄦ埛鐨勬彁绀轰俊鎭��',
       required: false
     },
-    // {
-    //   type: 'number',
-    //   key: 'width',
-    //   min: 1,
-    //   max: 24,
-    //   precision: 0,
-    //   label: '瀹藉害',
-    //   initVal: card.width || 12,
-    //   tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
-    //   forbid: card.eleType !== 'button',
-    //   required: true
-    // },
+    {
+      type: 'number',
+      key: 'width',
+      min: 0,
+      max: 24,
+      precision: 1,
+      label: '瀹藉害',
+      initVal: width,
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼�備负 0 鏃跺搴﹁嚜閫傚簲銆傚彲璁剧疆鍗婂垪鍗�.5銆�',
+      forbid: position !== 'line',
+      required: true
+    },
     {
       type: 'radio',
       key: 'show',
@@ -2298,6 +2424,28 @@
       options: modules.length ? [...modules, {value: 'multiComponent', label: '澶氱粍浠�'}] : []
     },
     {
+      type: 'cascader',
+      key: 'refreshTab',
+      label: '鍒锋柊鑿滃崟',
+      initVal: card.refreshTab || [],
+      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栨墽琛屽け璐ヤ笖瀛樺湪鍒锋柊椤规椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑鑿滃崟',
+      required: false,
+      forbid: viewType === 'popview',
+      options: menulist
+    },
+    {
+      type: 'cascader',
+      key: 'openmenu',
+      label: '鎵撳紑鑿滃崟',
+      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栧け璐ユ椂杩斿洖@open_target_menu@锛夐渶瑕佹墦寮�鐨勮彍鍗曘��',
+      initVal: card.openmenu || [],
+      extendName: 'MenuNo',
+      required: false,
+      allowClear: true,
+      options: menulist,
+      forbid: viewType === 'popview'
+    },
+    {
       type: 'radio',
       key: 'pagination',
       label: '鍒嗛〉',
@@ -2325,28 +2473,6 @@
         value: 'false',
         text: '闈炲繀濉�'
       }]
-    },
-    {
-      type: 'cascader',
-      key: 'refreshTab',
-      label: '鍒锋柊鑿滃崟',
-      initVal: card.refreshTab || [],
-      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栨墽琛屽け璐ヤ笖瀛樺湪鍒锋柊椤规椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑鑿滃崟',
-      required: false,
-      forbid: viewType === 'popview',
-      options: menulist
-    },
-    {
-      type: 'cascader',
-      key: 'openmenu',
-      label: '鎵撳紑鑿滃崟',
-      tooltip: '鎵ц鎴愬姛鍚庨渶瑕佹墦寮�鐨勮彍鍗曘��',
-      initVal: card.openmenu || [],
-      extendName: 'MenuNo',
-      required: false,
-      allowClear: true,
-      options: menulist,
-      forbid: viewType === 'popview'
     },
     {
       type: 'text',
diff --git a/src/menu/components/share/actioncomponent/index.jsx b/src/menu/components/share/actioncomponent/index.jsx
index 27bde39..c30f245 100644
--- a/src/menu/components/share/actioncomponent/index.jsx
+++ b/src/menu/components/share/actioncomponent/index.jsx
@@ -20,6 +20,7 @@
 const VerifyExcelIn = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelin'))
 const VerifyExcelOut = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelout'))
 const VerifyMegvii = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifymegvii'))
+const VerifyPay = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifypay'))
 
 class ActionComponent extends Component {
   static propTpyes = {
@@ -489,19 +490,19 @@
    */
   deleteElement = (card) => {
     const { config } = this.props
-    let _this = this
+    let that = this
 
     confirm({
       content: `纭畾鍒犻櫎 - ${card.label} 锛焋,
       onOk() {
-        let _actionlist = fromJS(_this.state.actionlist).toJS()
+        let _actionlist = fromJS(that.state.actionlist).toJS()
 
         _actionlist = _actionlist.filter(item => item.uuid !== card.uuid)
 
-        _this.setState({
+        that.setState({
           actionlist: _actionlist
         }, () => {
-          _this.props.updateaction({...config, action: _actionlist})
+          that.props.updateaction({...config, action: _actionlist})
         })
       },
       onCancel() {}
@@ -524,7 +525,7 @@
   verifySubmit = () => {
     const { config } = this.props
     const { card } = this.state
-    
+
     this.verifyRef.handleConfirm().then(res => {
       let _actionlist = fromJS(this.state.actionlist).toJS()
       _actionlist = _actionlist.filter(item => !item.origin || item.uuid === card.uuid)
@@ -698,6 +699,12 @@
         columns={config.columns}
         wrappedComponentRef={(inst) => this.verifyRef = inst}
       />
+    } else if (card.payMode === 'system') {
+      return <VerifyPay
+        card={card}
+        columns={config.columns}
+        wrappedComponentRef={(inst) => this.verifyRef = inst}
+      />
     }
   }
 
diff --git a/src/menu/components/share/colsControl/index.jsx b/src/menu/components/share/colsControl/index.jsx
index 882c037..29a113c 100644
--- a/src/menu/components/share/colsControl/index.jsx
+++ b/src/menu/components/share/colsControl/index.jsx
@@ -245,7 +245,7 @@
     _config.colsCtrls = colsCtrls
 
     if (this.customForm && this.customForm.state.editItem) {
-      const _this = this
+      const that = this
       let title = '瀛樺湪鏈繚瀛橀」锛岀‘瀹氬拷鐣ュ悧锛�'
       if (s.length > 0) {
         title = `瀛樺湪鏈繚瀛橀」锛屼笖绗� ${s.join('銆�')} 琛屼腑瀛楁鍦ㄦ悳绱㈡潯浠朵腑涓嶅瓨鍦紝纭畾蹇界暐鍚楋紵`
@@ -253,18 +253,18 @@
       confirm({
         title: title,
         onOk() {
-          _this.setState({ visible: false })
-          _this.props.onSubmit(_config)
+          that.setState({ visible: false })
+          that.props.onSubmit(_config)
         },
         onCancel() {}
       })
     } else if (s.length > 0) {
-      const _this = this
+      const that = this
       confirm({
         title: `绗� ${s.join('銆�')} 琛屼腑瀛楁鍦ㄦ悳绱㈡潯浠朵腑涓嶅瓨鍦紝纭畾蹇界暐鍚楋紵`,
         onOk() {
-          _this.setState({ visible: false })
-          _this.props.onSubmit(_config)
+          that.setState({ visible: false })
+          that.props.onSubmit(_config)
         },
         onCancel() {}
       })
diff --git a/src/menu/components/share/copycomponent/index.jsx b/src/menu/components/share/copycomponent/index.jsx
index 5450110..3cebc71 100644
--- a/src/menu/components/share/copycomponent/index.jsx
+++ b/src/menu/components/share/copycomponent/index.jsx
@@ -11,10 +11,48 @@
     card: PropTypes.object
   }
 
+  transConfig = (config, type) => {
+    if (type === 'menucell') {
+      config.setting.type = 'linkmenu'
+      config.setting.linkMenuId = ''
+      config.setting.copyMenuId = ''
+    } else if (type === 'mobnavbar') {
+      delete config.open_edition
+      delete config.dataName
+
+      config.menus.forEach(item => {
+        item.property = 'menu'
+        item.open = 'self'
+
+        delete item.copyMenuId
+        delete item.clearMenu
+        delete item.linkMenuId
+      })
+    } else if (config.type === 'menubar' && config.subtype === 'menubar') {
+      let cell = config.subMenus[0]
+      config.subMenus = []
+
+      if (cell) {
+        cell.setting.type = 'menu'
+        cell.setting.linkMenuId = ''
+        cell.setting.copyMenuId = ''
+
+        config.subMenus.push(cell)
+      }
+    } else if (['normaltable', 'editable', 'basetable'].includes(type)) {
+      config.action = config.action.filter(item => !item.origin)
+      config.cols = config.cols.filter(item => !item.origin)
+      config.search = config.search.filter(item => !item.origin)
+      delete config.isNew
+    }
+  }
+
   trigger = () => {
     const { card, type } = this.props
     let _val = fromJS(card).toJS()
     _val.copyType = type
+
+    this.transConfig(_val, type)
 
     try {
       delete _val.$srcId
@@ -22,28 +60,6 @@
       let srcid = localStorage.getItem(window.GLOB.sysSign + 'srcId')
       if (srcid) {
         _val.$srcId = srcid
-      }
-
-      if (type === 'menucell') {
-        _val.setting.type = 'linkmenu'
-        _val.setting.linkMenuId = ''
-        _val.setting.copyMenuId = ''
-      } else if (_val.type === 'menubar' && _val.subtype === 'menubar') {
-        let cell = _val.subMenus[0]
-        _val.subMenus = []
-
-        if (cell) {
-          cell.setting.type = 'menu'
-          cell.setting.linkMenuId = ''
-          cell.setting.copyMenuId = ''
-
-          _val.subMenus.push(cell)
-        }
-      } else if (['normaltable', 'editable', 'basetable'].includes(type)) {
-        _val.action = _val.action.filter(item => !item.origin)
-        _val.cols = _val.cols.filter(item => !item.origin)
-        _val.search = _val.search.filter(item => !item.origin)
-        delete _val.isNew
       }
 
       _val = window.btoa(window.encodeURIComponent(JSON.stringify(_val)))
diff --git a/src/menu/components/share/markcomponent/index.jsx b/src/menu/components/share/markcomponent/index.jsx
index 7185bea..160c1dd 100644
--- a/src/menu/components/share/markcomponent/index.jsx
+++ b/src/menu/components/share/markcomponent/index.jsx
@@ -399,12 +399,12 @@
       })
       this.props.onSubmit(marks)
     } else {
-      const _this = this
+      const that = this
       confirm({
         title: '瀛樺湪鏈繚瀛樻爣璁帮紝纭畾蹇界暐鍚楋紵',
         onOk() {
-          _this.setState({ visible: false })
-          _this.props.onSubmit(marks)
+          that.setState({ visible: false })
+          that.props.onSubmit(marks)
         },
         onCancel() {}
       })
diff --git a/src/menu/components/share/searchcomponent/index.jsx b/src/menu/components/share/searchcomponent/index.jsx
index 62f1391..6eca698 100644
--- a/src/menu/components/share/searchcomponent/index.jsx
+++ b/src/menu/components/share/searchcomponent/index.jsx
@@ -247,19 +247,19 @@
    */
   deleteElement = (card) => {
     const { config } = this.props
-    let _this = this
+    let that = this
 
     confirm({
       content: `纭畾鍒犻櫎 - ${card.label} 锛焋,
       onOk() {
-        let _searchlist = fromJS(_this.state.searchlist).toJS()
+        let _searchlist = fromJS(that.state.searchlist).toJS()
 
         _searchlist = _searchlist.filter(item => item.uuid !== card.uuid)
 
-        _this.setState({
+        that.setState({
           searchlist: _searchlist
         }, () => {
-          _this.props.updatesearch({...config, search: _searchlist})
+          that.props.updatesearch({...config, search: _searchlist})
         })
       },
       onCancel() {}
diff --git a/src/menu/components/share/sourcecomponent/index.jsx b/src/menu/components/share/sourcecomponent/index.jsx
index fe17598..c8f515b 100644
--- a/src/menu/components/share/sourcecomponent/index.jsx
+++ b/src/menu/components/share/sourcecomponent/index.jsx
@@ -74,12 +74,12 @@
         </Radio.Group> : null}
         {url && type === 'video' ? <div className="mk-source-item-info">
           <PaperClipOutlined />
-          <a target="_blank" rel="noopener noreferrer" href={url}>{name}</a>
+          <a target="_blank" rel="noopener noreferrer" href={url.replace(/@mywebsite@\//ig, window.GLOB.baseurl)}>{name}</a>
           <DeleteOutlined title="鍒犻櫎鏂囦欢" onClick={this.deleteUrl}/>
         </div> : null}
         {url && type !== 'video' && url !== '@icon@' ? <div className="mk-source-item-info picture">
           <img src={url.replace(/@mywebsite@\//ig, window.GLOB.baseurl)} alt="" />
-          <a target="_blank" rel="noopener noreferrer" href={url}>{name}</a>
+          <a target="_blank" rel="noopener noreferrer" href={url.replace(/@mywebsite@\//ig, window.GLOB.baseurl)}>{name}</a>
           <DeleteOutlined title="鍒犻櫎鏂囦欢" onClick={this.deleteUrl}/>
         </div> : null}
         {url && type !== 'video' && url === '@icon@' ? <div className="mk-source-item-info avatar">
diff --git a/src/menu/components/table/base-table/columns/index.jsx b/src/menu/components/table/base-table/columns/index.jsx
index 63cf2fa..96d01c3 100644
--- a/src/menu/components/table/base-table/columns/index.jsx
+++ b/src/menu/components/table/base-table/columns/index.jsx
@@ -21,12 +21,12 @@
 
 class HeaderCol extends Component {
   deleteCol = () => {
-    const _this = this
+    const that = this
 
     confirm({
       content: '纭畾鍒犻櫎鏄剧ず鍒楀悧锛�',
       onOk() {
-        _this.props.deleteCol(_this.props.column)
+        that.props.deleteCol(that.props.column)
       },
       onCancel() {}
     })
diff --git a/src/menu/components/table/base-table/options.jsx b/src/menu/components/table/base-table/options.jsx
index d482819..8c3f5fa 100644
--- a/src/menu/components/table/base-table/options.jsx
+++ b/src/menu/components/table/base-table/options.jsx
@@ -88,19 +88,6 @@
         {value: 'small', label: '灏�'},
       ],
     },
-    // {
-    //   type: 'radio',
-    //   field: 'selected',
-    //   label: '棣栬閫変腑',
-    //   initval: wrap.selected || 'false',
-    //   tooltip: '褰撴寜閽墽琛屽畬鎴愬苟杩斿洖涓婚敭鍊兼椂锛岄粯璁ら�変腑涓婚敭鍊煎搴旇銆�',
-    //   required: false,
-    //   options: [
-    //     {value: 'false', label: '鏃�'},
-    //     {value: 'init', label: '鍒濆鍖�'},
-    //     {value: 'always', label: '鏁版嵁鍔犺浇'},
-    //   ]
-    // },
     {
       type: 'radio',
       field: 'tableMode',
diff --git a/src/menu/components/table/edit-table/columns/index.jsx b/src/menu/components/table/edit-table/columns/index.jsx
index 9deae06..fcf33b1 100644
--- a/src/menu/components/table/edit-table/columns/index.jsx
+++ b/src/menu/components/table/edit-table/columns/index.jsx
@@ -22,12 +22,12 @@
 
 class HeaderCol extends Component {
   deleteCol = () => {
-    const _this = this
+    const that = this
 
     confirm({
       content: '纭畾鍒犻櫎鏄剧ず鍒楀悧锛�',
       onOk() {
-        _this.props.deleteCol(_this.props.column)
+        that.props.deleteCol(that.props.column)
       },
       onCancel() {}
     })
@@ -597,13 +597,13 @@
       columns.push(cell)
     })
 
-    const _this = this
+    const that = this
 
     confirm({
       content: '纭畾鍚屾瀛楁闆嗗悧锛�',
       onOk() {
-        _this.setState({columns}, () => {
-          _this.props.updatecolumn({..._this.props.config, cols: columns})
+        that.setState({columns}, () => {
+          that.props.updatecolumn({...that.props.config, cols: columns})
         })
       },
       onCancel() {}
@@ -611,13 +611,13 @@
   }
 
   clear = () => {
-    const _this = this
+    const that = this
 
     confirm({
       content: '纭畾娓呯┖鏄剧ず鍒楀悧锛�',
       onOk() {
-        _this.setState({columns: []}, () => {
-          _this.props.updatecolumn({..._this.props.config, cols: []})
+        that.setState({columns: []}, () => {
+          that.props.updatecolumn({...that.props.config, cols: []})
         })
       },
       onCancel() {}
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 77d5966..274f82e 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
@@ -152,6 +152,8 @@
         let sql = this.state.verifySql + _initCustomScript + _prevCustomScript + _backCustomScript + tail
         
         sql = sql.replace(/@\$|\$@/ig, '')
+        sql = sql.replace(/@datam@/ig, `''`)
+        sql = sql.replace(/@typename@/ig, `'debug'`)
 
         if (skip) {
           this.setState({
@@ -266,12 +268,12 @@
           </Col> : null}
           {!type ? <Col span={10}>
             <Form.Item label="鎶ラ敊瀛楁" style={{margin: 0, whiteSpace: 'nowrap'}}>
-              errorcode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT锛�, retmsg
+              errorcode, retmsg
             </Form.Item>
           </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, lang, time_id</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, LoginUID, SessionUid, UserID, Appkey, lang, typename, datam, 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/normal-table/columns/index.jsx b/src/menu/components/table/normal-table/columns/index.jsx
index de7593e..e6af839 100644
--- a/src/menu/components/table/normal-table/columns/index.jsx
+++ b/src/menu/components/table/normal-table/columns/index.jsx
@@ -22,12 +22,12 @@
 
 class HeaderCol extends Component {
   deleteCol = () => {
-    const _this = this
+    const that = this
 
     confirm({
       content: '纭畾鍒犻櫎鏄剧ず鍒楀悧锛�',
       onOk() {
-        _this.props.deleteCol(_this.props.column)
+        that.props.deleteCol(that.props.column)
       },
       onCancel() {}
     })
@@ -595,13 +595,13 @@
       columns.push(cell)
     })
 
-    const _this = this
+    const that = this
 
     confirm({
       content: '纭畾鍚屾瀛楁闆嗗悧锛�',
       onOk() {
-        _this.setState({columns}, () => {
-          _this.props.updatecolumn({..._this.props.config, cols: columns})
+        that.setState({columns}, () => {
+          that.props.updatecolumn({...that.props.config, cols: columns})
         })
       },
       onCancel() {}
@@ -609,13 +609,13 @@
   }
 
   clear = () => {
-    const _this = this
+    const that = this
 
     confirm({
       content: '纭畾娓呯┖鏄剧ず鍒楀悧锛�',
       onOk() {
-        _this.setState({columns: []}, () => {
-          _this.props.updatecolumn({..._this.props.config, cols: []})
+        that.setState({columns: []}, () => {
+          that.props.updatecolumn({...that.props.config, cols: []})
         })
       },
       onCancel() {}
diff --git a/src/menu/components/tabs/antv-tabs/index.jsx b/src/menu/components/tabs/antv-tabs/index.jsx
index eaa3206..145bcdc 100644
--- a/src/menu/components/tabs/antv-tabs/index.jsx
+++ b/src/menu/components/tabs/antv-tabs/index.jsx
@@ -147,7 +147,7 @@
 
   delTab = (tab) => {
     let tabs = fromJS(this.state.tabs).toJS()
-    const _this = this
+    const that = this
 
     tabs.subtabs = tabs.subtabs.filter(t => t.uuid !== tab.uuid)
 
@@ -155,8 +155,8 @@
       title: '纭畾鍒犻櫎鏍囩锛�',
       content: '',
       onOk() {
-        _this.setState({tabs})
-        _this.props.updateConfig(tabs)
+        that.setState({tabs})
+        that.props.updateConfig(tabs)
       },
       onCancel() {}
     })
@@ -223,6 +223,12 @@
     // editab.selectVal = res.selectVal || ''
     editab.blacklist = res.blacklist
 
+    if (/^\s+$/.test(editab.label) && editab.icon) {
+      editab.taType = 'only-icon'
+    } else {
+      delete editab.taType
+    }
+
     if (editab.uuid) {
       tabs.subtabs = tabs.subtabs.map(t => {
         if (t.uuid === editab.uuid) {
diff --git a/src/menu/components/tabs/antv-tabs/index.scss b/src/menu/components/tabs/antv-tabs/index.scss
index e45bad8..e8cac39 100644
--- a/src/menu/components/tabs/antv-tabs/index.scss
+++ b/src/menu/components/tabs/antv-tabs/index.scss
@@ -18,7 +18,7 @@
     padding-left: 0;
   }
   .ant-tabs-right-content {
-    padding-right: 0;
+    padding-right: 0!important;
   }
   .ant-tabs-bottom-bar {
     margin-top: 0;
diff --git a/src/menu/components/tabs/antv-tabs/options.jsx b/src/menu/components/tabs/antv-tabs/options.jsx
index 329358c..b547b6b 100644
--- a/src/menu/components/tabs/antv-tabs/options.jsx
+++ b/src/menu/components/tabs/antv-tabs/options.jsx
@@ -160,6 +160,21 @@
         {value: 'mk-tab-button', label: '鎸夐挳锛堝乏锛�'},
         {value: 'mk-tab-button tab-right', label: '鎸夐挳锛堝彸锛�'},
       ],
+      controlFields: [
+        {field: 'tabAlign', values: ['line']},
+      ]
+    },
+    {
+      type: 'select',
+      field: 'tabAlign',
+      label: '瀵归綈鏂瑰紡',
+      initval: setting.tabAlign || 'left',
+      required: true,
+      options: [
+        {value: 'left', label: '宸﹀榻�'},
+        {value: 'center', label: '灞呬腑瀵归綈'},
+        {value: 'right', label: '鍙冲榻�'},
+      ],
     },
     // {
     //   type: 'select',
diff --git a/src/menu/components/tabs/table-tabs/index.jsx b/src/menu/components/tabs/table-tabs/index.jsx
index 293312c..8dc040e 100644
--- a/src/menu/components/tabs/table-tabs/index.jsx
+++ b/src/menu/components/tabs/table-tabs/index.jsx
@@ -72,7 +72,7 @@
 
   delTab = (tab) => {
     let tabs = fromJS(this.state.tabs).toJS()
-    const _this = this
+    const that = this
 
     tabs.subtabs = tabs.subtabs.filter(t => t.uuid !== tab.uuid)
 
@@ -80,8 +80,8 @@
       title: '纭畾鍒犻櫎鏍囩锛�',
       content: '',
       onOk() {
-        _this.setState({tabs})
-        _this.props.updateConfig(tabs)
+        that.setState({tabs})
+        that.props.updateConfig(tabs)
       },
       onCancel() {}
     })
diff --git a/src/menu/components/timeline/normal-timeline/options.jsx b/src/menu/components/timeline/normal-timeline/options.jsx
index a1ea98b..ae0be4d 100644
--- a/src/menu/components/timeline/normal-timeline/options.jsx
+++ b/src/menu/components/timeline/normal-timeline/options.jsx
@@ -206,7 +206,6 @@
       initval: wrap.empty || 'show',
       tooltip: '褰撴煡璇㈡暟鎹负绌烘椂锛岄殣钘忚缁勪欢銆�',
       required: false,
-      skip: true,
       options: [
         {value: 'show', label: '鍚�'},
         {value: 'hidden', label: '鏄�'},
diff --git a/src/menu/datasource/index.jsx b/src/menu/datasource/index.jsx
index 92a16b3..f264a81 100644
--- a/src/menu/datasource/index.jsx
+++ b/src/menu/datasource/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Modal, Button } from 'antd'
+import { Modal, Button, notification } from 'antd'
 import { SettingOutlined } from '@ant-design/icons'
 
 import VerifyCard from './verifycard'
@@ -179,38 +179,100 @@
       }
 
       let maxScript = 0
+      let useExec = false
 
-      if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-        window.GLOB.funcs.forEach(m => {
-          let reg = new RegExp('\\$ex@' + m.func_code + '@ex\\$', 'ig')
-          if (res.setting.dataresource) {
-            res.setting.dataresource = res.setting.dataresource.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
+      let sFields = []
+      res.searches && res.searches.forEach(item => {
+        if (!item.key) return
+    
+        if (item.type === 'date') {
+          if (sFields.includes(item.key)) {
+            sFields.push(item.key + '1')
+          } else {
+            sFields.push(item.key)
           }
-          res.scripts.forEach(item => {
-            item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
-
-            if (item.status === 'false') return
-
-            if (/exec\s/ig.test(item.sql)) {
-              maxScript = 1000
-            } else if (item.sql.length > maxScript) {
-              maxScript = item.sql.length
-            }
+        } else if (item.type === 'dateweek' || item.type === 'range' || (item.type === 'datemonth' && item.match !== '=')) {
+          sFields.push(item.key)
+          sFields.push(item.key + '1')
+        } else if (item.type === 'daterange') {
+          if (/,/.test(item.key)) {
+            sFields.push(item.key.split(',')[0])
+            sFields.push(item.key.split(',')[1])
+          } else {
+            sFields.push(item.key)
+            sFields.push(item.key + '1')
+          }
+        } else if (item.type === 'text' || item.type === 'select') {
+          item.key.split(',').forEach(field => {
+            sFields.push(field)
           })
-        })
-      } else {
-        res.scripts.forEach(item => {
-          if (item.status === 'false') return
+        } else {
+          sFields.push(item.key)
+        }
+      })
+      delete res.searches
+      sFields = sFields.join('|')
 
-          if (/exec\s/ig.test(item.sql)) {
-            maxScript = 1000
-          } else if (item.sql.length > maxScript) {
-            maxScript = item.sql.length
-          }
-        })
+      // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+      //   window.GLOB.funcs.forEach(m => {
+      //     let reg = new RegExp('\\$ex@' + m.func_code + '@ex\\$', 'ig')
+      //     if (res.setting.dataresource) {
+      //       res.setting.dataresource = res.setting.dataresource.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
+      //     }
+      //     res.scripts.forEach(item => {
+      //       item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
+
+      //       if (item.status === 'false') return
+
+      //       if (/exec\s/ig.test(item.sql)) {
+      //         useExec = true
+      //         maxScript = 1000
+      //       } else if (item.sql.length > maxScript) {
+      //         maxScript = item.sql.length
+      //       }
+      //     })
+      //   })
+      // } else {
+      //   res.scripts.forEach(item => {
+      //     if (item.status === 'false') return
+
+      //     if (/exec\s/ig.test(item.sql)) {
+      //       useExec = true
+      //       maxScript = 1000
+      //     } else if (item.sql.length > maxScript) {
+      //       maxScript = item.sql.length
+      //     }
+      //   })
+      // }
+
+      if (res.setting.interType === 'system' && res.setting.dataresource && res.setting.execute !== 'false' && sFields) {
+        if (new RegExp(`@(${sFields})@`, 'ig').test(res.setting.dataresource)) {
+          maxScript = 1000
+        }
       }
 
+      res.scripts.forEach(item => {
+        if (item.status === 'false') return
+
+        if (/exec\s/ig.test(item.sql)) {
+          useExec = true
+          maxScript = 1000
+        } else if (sFields && new RegExp(`@(${sFields})@`, 'ig').test(item.sql)) {
+          maxScript = 1000
+        } else if (item.sql.length > maxScript) {
+          maxScript = item.sql.length
+        }
+      })
+
       res.setting.maxScript = maxScript
+
+      if (useExec && res.setting.sync === 'true') {
+        notification.warning({
+          top: 92,
+          message: '褰撳墠鏁版嵁婧愪娇鐢ㄤ簡鍚屾鏌ヨ涓旇嚜瀹氫箟鑴氭湰涓瓨鍦ㄥ嚱鏁癳xec锛屽閬囨帴鍙f姤閿欓渶鍏抽棴鍚屾鏌ヨ鍚庨噸鏂版祴璇曘��',
+          duration: 5
+        })
+      }
 
       if (config.subtype !== 'dualdatacard') {
         delete res.subColumns
@@ -277,6 +339,12 @@
     })
   }
 
+  cancel = () => {
+    this.verifyRef.closeDataSource(() => {
+      this.setState({ visible: false, loading: false })
+    })
+  }
+
   creatFunc = () => {
     const { config } = this.props
     const { mainSearch } = this.state
@@ -319,7 +387,7 @@
           onCancel={() => {this.setState({ visible: false, loading: false }) }}
           footer={[
             config.subtype !== 'dualdatacard' && record.interType === 'inner' ? <CreateFunc key="create" getMsg={this.creatFunc}/> : null,
-            <Button key="cancel" onClick={() => { this.setState({ visible: false, loading: false }) }}>鍙栨秷</Button>,
+            <Button key="cancel" onClick={this.cancel}>鍙栨秷</Button>,
             <Button key="confirm" type="primary" loading={loading} onClick={this.verifySubmit}>纭畾</Button>
           ]}
           destroyOnClose
diff --git a/src/menu/datasource/verifycard/customscript/index.jsx b/src/menu/datasource/verifycard/customscript/index.jsx
index cf60479..1a6b210 100644
--- a/src/menu/datasource/verifycard/customscript/index.jsx
+++ b/src/menu/datasource/verifycard/customscript/index.jsx
@@ -243,7 +243,7 @@
           </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, lang, 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{window.GLOB.getLocation ? ', mk_longitude, mk_latitude' : ''}</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@ 鎴栬剼鏈腑瀛樺湪 @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>
diff --git a/src/menu/datasource/verifycard/excelout/index.jsx b/src/menu/datasource/verifycard/excelout/index.jsx
new file mode 100644
index 0000000..a1fe536
--- /dev/null
+++ b/src/menu/datasource/verifycard/excelout/index.jsx
@@ -0,0 +1,76 @@
+import React, { Component } from 'react'
+import { notification } from 'antd'
+import * as XLSX from 'sheetjs-style'
+import { DownloadOutlined } from '@ant-design/icons'
+import moment from 'moment'
+
+// import './index.scss'
+
+class ExcelOutColumns extends Component {
+  /**
+   * @description 瀵煎嚭瀛楁闆�
+   */
+  actionTrigger = () => {
+    const { data, setting } = this.props
+
+    if (data.length === 0) {
+      notification.warning({
+        top: 92,
+        message: '瀛楁闆嗕笉鍙负绌猴紒',
+        duration: 5
+      })
+      return
+    }
+
+    let columns = [{
+      Column: 'label',
+      Text: '鍚嶇О'
+    }, {
+      Column: 'field',
+      Text: '瀛楁'
+    }, {
+      Column: 'datatype',
+      Text: '鏁版嵁绫诲瀷'
+    }]
+    
+    let table = []
+    let _header = []
+    let _topRow = {}
+    let colwidth = []
+
+    columns.forEach(col => {
+      _header.push(col.Column)
+      _topRow[col.Column] = col.Text
+      colwidth.push({wch: 25})
+    })
+
+    table.push(_topRow)
+
+    data.forEach((item) => {
+      let _row = {}
+
+      columns.forEach((col) => {
+        let val = item[col.Column]
+        _row[col.Column] = val
+      })
+
+      table.push(_row)
+    })
+
+    const ws = XLSX.utils.json_to_sheet(table, {header: _header, skipHeader: true})
+
+    ws['!cols'] = colwidth
+    ws['!rows'] = Array(table.length).fill({hpx: 18})
+
+    const wb = XLSX.utils.book_new()
+    XLSX.utils.book_append_sheet(wb, ws, 'Sheet1')
+
+    XLSX.writeFile(wb, `${setting.tableName || ''}${moment().format('YYYYMMDDHHmmss')}.xlsx`)
+  }
+
+  render() {
+    return (<DownloadOutlined className="columns-out" title="涓嬭浇" onClick={this.actionTrigger}/>)
+  }
+}
+
+export default ExcelOutColumns
\ No newline at end of file
diff --git a/src/menu/datasource/verifycard/excelout/index.scss b/src/menu/datasource/verifycard/excelout/index.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/menu/datasource/verifycard/excelout/index.scss
diff --git a/src/menu/datasource/verifycard/index.jsx b/src/menu/datasource/verifycard/index.jsx
index b59417f..500966b 100644
--- a/src/menu/datasource/verifycard/index.jsx
+++ b/src/menu/datasource/verifycard/index.jsx
@@ -23,6 +23,7 @@
 const { Search } = Input
 const { confirm } = Modal
 
+const ExcelOut = asyncComponent(() => import('./excelout'))
 const CodeMirror = asyncComponent(() => import('@/templates/zshare/codemirror'))
 const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
 const EditTable = asyncComponent(() => import('@/templates/zshare/editTable'))
@@ -41,9 +42,8 @@
     loading: false,
     colLoading: false,
     searchKey: '',
-    initsql: '',          // sql楠岃瘉鏃跺彉閲忓0鏄庡強璧嬪��
     usefulfields: '',
-    defaultsql: '',       // 榛樿Sql
+    defaultsql: '',
     systemScripts: [],
     median: {},
     visible: false,
@@ -51,6 +51,7 @@
     pvisible: false,
     reload: false,
     script: null,
+    oriConfig: null,
     scriptValue: '',
     cols: null,
     colColumns: [
@@ -200,17 +201,17 @@
     let _setting = fromJS(config.setting).toJS()
     let scripts = config.scripts ? fromJS(config.scripts).toJS() : []
 
-    if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-      window.GLOB.funcs.forEach(m => {
-        let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig')
-        if (_setting.dataresource) {
-          _setting.dataresource = _setting.dataresource.replace(reg, `$ex@${m.func_code}@ex$`)
-        }
-        scripts && scripts.forEach(item => {
-          item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
-        })
-      })
-    }
+    // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+    //   window.GLOB.funcs.forEach(m => {
+    //     let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig')
+    //     if (_setting.dataresource) {
+    //       _setting.dataresource = _setting.dataresource.replace(reg, `$ex@${m.func_code}@ex$`)
+    //     }
+    //     scripts && scripts.forEach(item => {
+    //       item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
+    //     })
+    //   })
+    // }
 
     let columns = config.columns ? fromJS(config.columns).toJS() : []
     let subColumns = config.subColumns ? fromJS(config.subColumns).toJS() : []
@@ -249,7 +250,13 @@
       median: _setting,
       searches: formatSearch(search),
       searchKey: '',
-      debugId: _setting.debugId || ''
+      debugId: _setting.debugId || '',
+      oriConfig: fromJS({
+        scripts,
+        columns: columns,
+        subColumns: subColumns,
+        setting: _setting
+      }).toJS()
     })
 
     this.getsysScript()
@@ -547,7 +554,7 @@
 
   submitDataSource = () => {
     const { config, mainSearch } = this.props
-    const { activeKey, setting, columns, subColumns, scripts, cols, median } = this.state
+    const { activeKey, setting, columns, subColumns, scripts, cols, median, searches } = this.state
 
     if (config.subtype === 'dualdatacard') {
       let arr = columns.map(col => col.field.toLowerCase())
@@ -612,12 +619,13 @@
           if (res.useMSearch === 'true') { // 浣跨敤涓绘悳绱㈡潯浠�
             search = [...search, ...mainSearch]
           }
+          let _searches = formatSearch(search)
 
           this.setState({
-            searches: formatSearch(search),
+            searches: _searches,
             setting: res
           }, () => {
-            this.sqlverify(() => { resolve({setting: res, columns, subColumns, scripts, cols }) }, reject, 'submit')
+            this.sqlverify(() => { resolve({setting: res, columns, subColumns, scripts, cols, searches: _searches }) }, reject, 'submit')
           })
         }, () => {
           reject()
@@ -632,7 +640,7 @@
           reject()
           return
         }
-        this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols }) }, reject, 'submit')
+        this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols, searches }) }, reject, 'submit')
       } else if (activeKey === 'subcolumns') {
         if (this.subdatasource && this.subdatasource.state.editingKey) {
           notification.warning({
@@ -643,11 +651,37 @@
           reject()
           return
         }
-        this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols }) }, reject, 'submit')
+        this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols, searches }) }, reject, 'submit')
       } else if (activeKey === 'scripts') {
-        this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols }) }, reject, 'submit')
+        this.sqlverify(() => { resolve({setting, columns, subColumns, scripts, cols, searches }) }, reject, 'submit')
       }
     })
+  }
+
+  closeDataSource = (callback) => {
+    const { setting, columns, subColumns, scripts, oriConfig } = this.state
+
+    let line = scripts.map(item => item.sql).join('')
+    line += columns.map(item => item.field + item.datatype).join('')
+    line += subColumns.map(item => item.field + item.datatype).join('')
+    line += setting.interType + (setting.dataresource || '') + (setting.order || '') + (setting.primaryKey || '')
+
+    let _line = oriConfig.scripts.map(item => item.sql).join('')
+    _line += oriConfig.columns.map(item => item.field + item.datatype).join('')
+    _line += oriConfig.subColumns.map(item => item.field + item.datatype).join('')
+    _line += oriConfig.setting.interType + (oriConfig.setting.dataresource || '') + (oriConfig.setting.order || '') + (oriConfig.setting.primaryKey || '')
+
+    if (line !== _line) {
+      confirm({
+        content: '鏁版嵁婧愬凡淇敼锛岀‘瀹氬彇娑堝悧锛�',
+        onOk() {
+          callback()
+        },
+        onCancel() {}
+      })
+    } else {
+      callback()
+    }
   }
 
   sqlverify = (resolve, reject, type, testScripts) => {
@@ -985,7 +1019,7 @@
     })
 
     if (window.debugger) {
-      console.info('select ' + s.join(', '))
+      window.mkInfo('select ' + s.join(', '))
     }
 
     let extend = ''
@@ -1152,6 +1186,33 @@
     })
   }
 
+  tolowercase = (type) => {
+    const that = this
+    confirm({
+      content: type === 'sub' ? '纭畾灏嗗瓙琛ㄥ瓧娈佃浆涓哄皬鍐欏悧锛�' : '纭畾灏嗗瓧娈佃浆涓哄皬鍐欏悧锛�',
+      onOk() {
+        that.execlowercase(type)
+      },
+      onCancel() {}
+    })
+  }
+
+  execlowercase = (type) => {
+    const { subColumns, columns } = this.state
+
+    if (type === 'sub') {
+      this.setState({subColumns: fromJS(subColumns).toJS().map(col => {
+        col.field = col.field.toLowerCase()
+        return col
+      })})
+    } else {
+      this.setState({columns: fromJS(columns).toJS().map(col => {
+        col.field = col.field.toLowerCase()
+        return col
+      })})
+    }
+  }
+
   /**
    * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
    */
@@ -1199,6 +1260,8 @@
               type="fields"
               updatefield={this.updatefields}
             />
+            <SwapOutlined className="columns-lowercase" title="杞皬鍐�" onClick={() => this.tolowercase()}/>
+            <ExcelOut data={columns} setting={setting}/>
             <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} searchKey={searchKey} type="datasourcefield" wrappedComponentRef={(inst) => this.datasource = inst} data={columns} columns={colColumns} onChange={(columns) => this.setState({columns})}/>
           </TabPane> : <TabPane tab={
             <span>
@@ -1207,6 +1270,7 @@
             </span>
           } key="columns">
             <div className="base-table-columns"></div>
+            <ExcelOut data={columns} setting={setting}/>
             <EditTable actions={[]} searchKey={searchKey} type="datasourcefield" data={columns} columns={colColumns}/>
           </TabPane>}
           {config.subtype === 'dualdatacard' ? <TabPane tab={
@@ -1221,6 +1285,8 @@
               type="fields"
               updatefield={this.updateSubfields}
             />
+            <SwapOutlined className="columns-lowercase" title="杞皬鍐�" onClick={() => this.tolowercase('sub')}/>
+            <ExcelOut data={subColumns} setting={setting}/>
             <EditTable actions={['edit', 'move', 'copy', 'del', 'clear']} searchKey={searchKey} type="datasourcefield" wrappedComponentRef={(inst) => this.subdatasource = inst} data={subColumns} columns={colColumns} onChange={(subColumns) => this.setState({subColumns})}/>
           </TabPane> : null}
           <TabPane tab={
@@ -1251,7 +1317,6 @@
               setting={setting}
               searches={searches}
               defaultsql={defaultsql}
-              initsql={this.state.initsql}
               customScripts={scripts}
               systemScripts={this.state.systemScripts}
               scriptsChange={this.scriptsChange}
diff --git a/src/menu/datasource/verifycard/index.scss b/src/menu/datasource/verifycard/index.scss
index 308bfb9..b87af52 100644
--- a/src/menu/datasource/verifycard/index.scss
+++ b/src/menu/datasource/verifycard/index.scss
@@ -146,6 +146,39 @@
       margin-right: 5px;
       cursor: pointer;
     }
+    .columns-lowercase {
+      float: right;
+      position: relative;
+      z-index: 2;
+      right: 30px;
+      height: 0px;
+      top: -15px;
+      color: orange;
+      cursor: pointer;
+    }
+    .columns-out {
+      float: right;
+      position: relative;
+      z-index: 2;
+      right: 5px;
+      height: 0px;
+      top: -15px;
+      color: rgb(24, 144, 255);
+    }
+    .columns-out + .modal-edit-table {
+      .ant-table-thead {
+        .copy-control {
+          top: -18px;
+          right: 55px;
+          .anticon-copy {
+            margin-right: 12px;
+          }
+          .anticon-delete {
+            margin-left: 12px;
+          }
+        }
+      }
+    }
   }
   .full-scripts {
     position: absolute;
diff --git a/src/menu/datasource/verifycard/settingform/index.jsx b/src/menu/datasource/verifycard/settingform/index.jsx
index 1e7a410..7e5f409 100644
--- a/src/menu/datasource/verifycard/settingform/index.jsx
+++ b/src/menu/datasource/verifycard/settingform/index.jsx
@@ -441,6 +441,10 @@
                     {
                       required: true,
                       message: '璇疯緭鍏ラ粯璁ゆ帓搴�!'
+                    },
+                    {
+                      pattern: /^[^'+]+$/,
+                      message: '鎺掑簭涓笉鍙娇鐢╘'涓�+'
                     }
                   ]
                 })(<Input placeholder={'ID asc, UID desc'} autoComplete="off" />)}
@@ -532,13 +536,13 @@
             {/* 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={
-                <Tooltip placement="topLeft" title={'鍒濆鍖栧姞杞芥椂锛屾槸鍚︿笌鍏朵粬缁勪欢涓�鍚屽姞杞芥暟鎹紝娉細濡傝彍鍗曟湭浣跨敤鍚庣缂撳瓨锛屽垯鏌ヨ璇彞澶т簬8000瀛楃鏃舵棤鏁堛��'}>
+                <Tooltip placement="topLeft" title={'鍒濆鍖栧姞杞芥椂锛屾槸鍚︿笌鍏朵粬缁勪欢涓�鍚屽姞杞芥暟鎹��'}>
                   <QuestionCircleOutlined className="mk-form-tip" />
                   鍚屾鏌ヨ
                 </Tooltip>
               }>
                 {getFieldDecorator('sync', {
-                  initialValue: setting.sync || 'true'
+                  initialValue: setting.sync || 'false'
                 })(
                   <Radio.Group>
                     <Radio value="true">鏄�</Radio>
@@ -589,6 +593,18 @@
                   <Radio.Group onChange={(e) => {this.onOptionChange(e.target.value, 'onload')}}>
                     <Radio value="true">鍔犺浇</Radio>
                     <Radio value="false">涓嶅姞杞�</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col> : null}
+            {window.backend && setting.interType === 'system' ? <Col span={8}>
+              <Form.Item label="浜嬪姟">
+                {getFieldDecorator('transact', {
+                  initialValue: setting.transact || 'false'
+                })(
+                  <Radio.Group onChange={(e) => {this.onOptionChange(e.target.value, 'transact')}}>
+                    <Radio value="true">鍚敤</Radio>
+                    <Radio value="false">绂佺敤</Radio>
                   </Radio.Group>
                 )}
               </Form.Item>
@@ -655,7 +671,7 @@
                   rules: [
                     {
                       required: true,
-                      message: '璇疯緭鍏ラ粯璁ゆ帓搴�!'
+                      message: '璇疯緭鍏ュ瓙琛ㄥ瓧娈�!'
                     }
                   ]
                 })(<Input placeholder={''} autoComplete="off" />)}
@@ -691,6 +707,18 @@
                 )}
               </Form.Item>
             </Col> : null}
+            {setting.onload !== 'false' ? <Col span={8}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="鍙欢杩熷垵濮嬪寲鏁版嵁鐨勫姞杞芥椂闂达紝鍗曚綅姣锛坢s锛夈��">
+                  <QuestionCircleOutlined className="mk-form-tip" />
+                  寤舵椂鍔犺浇
+                </Tooltip>
+              }>
+                {getFieldDecorator('delay', {
+                  initialValue: setting.delay,
+                })(<InputNumber min={0} max={60000} precision={0} />)}
+              </Form.Item>
+            </Col> : null}
           </Row>
         </Form>
         <Modal
diff --git a/src/menu/datasource/verifycard/utils.jsx b/src/menu/datasource/verifycard/utils.jsx
index 6714e81..cb79b71 100644
--- a/src/menu/datasource/verifycard/utils.jsx
+++ b/src/menu/datasource/verifycard/utils.jsx
@@ -42,13 +42,13 @@
       _dataresource = '(' + _dataresource + ') tb'
     }
     
-    if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-      window.GLOB.funcs.forEach(item => {
-        let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig')
-        _dataresource = _dataresource.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
-        _customScript = _customScript.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
-      })
-    }
+    // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+    //   window.GLOB.funcs.forEach(item => {
+    //     let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig')
+    //     _dataresource = _dataresource.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
+    //     _customScript = _customScript.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
+    //   })
+    // }
 
     let regs = [
       // {reg: /@time_id@/ig, value: `'${getuuid()}'`}, // 璁$畻md5鍚庢浛鎹�
@@ -62,8 +62,8 @@
       {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: ''},
+      // {reg: /@select\$|\$select@/ig, value: ''},
+      // {reg: /@sum\$|\$sum@/ig, value: ''},
     ]
 
     if (window.GLOB.process && type !== 'invoice') {
@@ -71,10 +71,16 @@
     }
 
     if (hasExtend) {
-      regs.push({reg: /@mk_time@/ig, value: '2024-04-29 17:20:00'})
+      regs.push({reg: /@mk_time@/ig, value: `'2024-04-29 17:20:00'`})
     }
     if (type === 'calendar') {
-      regs.push({reg: /@mk_year@/ig, value: '2024'})
+      regs.push({reg: /@mk_year@/ig, value: `'2024'`})
+    }
+    if (window.GLOB.getLocation) {
+      regs.push(
+        {reg: /@mk_longitude@/ig, value: 0},
+        {reg: /@mk_latitude@/ig, value: 0}
+      )
     }
 
     // 澶栬仈鏁版嵁搴撴浛鎹�
diff --git a/src/menu/debug/index.jsx b/src/menu/debug/index.jsx
index 737fd3e..cdbc753 100644
--- a/src/menu/debug/index.jsx
+++ b/src/menu/debug/index.jsx
@@ -1,4 +1,4 @@
-import React, {Component} from 'react'
+import React, { Component } from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
 import { Modal, Button, Drawer, Tooltip } from 'antd'
@@ -26,6 +26,7 @@
 
   sqlList = []
   verSqls = []
+  linkMain = null
 
   trigger = () => {
     let config = fromJS(this.props.config).toJS()
@@ -66,6 +67,7 @@
     }
 
     this.sqlList = []
+    this.linkMain = []
 
     let regs = [
       { reg: /@userName@/ig, value: `'User_Name'` },
@@ -88,76 +90,13 @@
     if (process) {
       regs.push({ reg: /@works_flow_code@/ig, value: `'1949-10-01 15:00:00'` })
     }
-    
-    if (config.interfaces && config.interfaces.length > 0) {
-      config.interfaces.forEach(m => {
-        if (m.status !== 'true' || m.setting.interType !== 'system') return false
-  
-        let sql = this.formatDataSource(m, regs)
-  
-        this.sqlList.push({label: m.setting.name, children: [{label: '鏁版嵁婧�', sql: sql}]})
-      })
-    }
 
-    this.filterComponent(config.components, [], regs, process)
+    let _mainSearch = []
 
-    let sqls = []
-    let foreachSql = (list, name, tabName = '', supName = '') => {
-      list.forEach(item => {
-        if (item.children) {
-          if (item.tabName) {
-            item.children.forEach(cell => {
-              if (cell.children) {
-                foreachSql(cell.children, cell.label, item.tabName, name)
-              }
-            })
-          } else {
-            foreachSql(item.children, name, tabName, supName)
-          }
-        } else if (item.sql) {
-          sqls.push({uuid: Utils.getuuid() ,label: item.label, name: name, tabName: tabName, supName: supName, sql: item.sql})
-        }
-      })
-    }
-
-    this.sqlList.forEach(item => {
-      if (item.children) {
-        foreachSql(item.children, item.label)
-      }
-    })
-
-    if (sqls.length === 0) {
-      Modal.warning({
-        title: '褰撳墠鑿滃崟鏃犲彲楠岃瘉鑴氭湰銆�',
-        okText: '鐭ラ亾浜�'
-      })
-      return
-    }
-
-    this.verSqls = sqls
-    let that = this
-
-    Modal.confirm({
-      content: `褰撳墠鑿滃崟鍏�${this.sqlList.length}涓粍浠讹紝${sqls.length}椤硅剼鏈渶瑕佹楠�${sqls.length > 20 ? '锛屾椂闂村ぇ姒傞渶瑕�' + parseInt(sqls.length / 2) + '绉�' : ''}銆俙,
-      onOk() {
-        that.setState({visible: true, status: 'loading', sqlList: fromJS(sqls).toJS(), successIds: [], errorIds: [], errorMsg: {}, execId: ''}, () => {
-          that.roopSql()
-        })
-      },
-      onCancel() {}
-    })
-
-    this.sqlList = []
-  }
-
-  filterComponent = (components, mainSearch, regs, process, ispop = false) => {
-    let appType = sessionStorage.getItem('appType')
-    let _mainSearch = mainSearch || []
-
-    if (appType === 'mob') {
+    if (sessionStorage.getItem('appType') === 'mob') {
       let search = []
       let ms = null
-      components.forEach(item => {
+      config.components.forEach(item => {
         if (item.type === 'topbar' && item.wrap.type !== 'navbar' && item.search) {
           ms = item.search
         } else if (item.type === 'search' && item.wrap.field) {
@@ -204,20 +143,168 @@
         _mainSearch = search
       }
     } else {
-      components.forEach(component => {
+      config.components.forEach(component => {
         if (component.type !== 'search') return
   
         _mainSearch = component.search || []
       })
     }
+    
+    if (config.interfaces && config.interfaces.length > 0) {
+      config.interfaces.forEach(m => {
+        if (m.status !== 'true' || m.setting.interType !== 'system') return false
+  
+        m.setting.laypage = 'false'
+        m.setting.$top = true
+
+        let sql = this.formatDataSource(m, regs, _mainSearch)
+  
+        this.sqlList.push({label: m.setting.name, children: [{label: '鏁版嵁婧�', sql: sql}]})
+      })
+    }
+
+    this.filterComponent(config.components, _mainSearch, regs, process)
+
+    let sqls = []
+    let foreachSql = (list, name, tabName = '', supName = '') => {
+      list.forEach(item => {
+        if (item.children) {
+          if (item.tabName) {
+            item.children.forEach(cell => {
+              if (cell.children) {
+                foreachSql(cell.children, cell.label, item.tabName, name)
+              }
+            })
+          } else {
+            foreachSql(item.children, name, tabName, supName)
+          }
+        } else if (item.sql) {
+          sqls.push({uuid: Utils.getuuid() ,label: item.label, name: name, tabName: tabName, supName: supName, sql: item.sql})
+        }
+      })
+    }
+
+    this.sqlList.forEach(item => {
+      if (item.children) {
+        foreachSql(item.children, item.label)
+      }
+    })
+
+    if (sqls.length === 0) {
+      Modal.warning({
+        title: '褰撳墠鑿滃崟鏃犲彲楠岃瘉鑴氭湰銆�',
+        okText: '鐭ラ亾浜�'
+      })
+      return
+    }
+
+    this.verSqls = sqls
+    let that = this
+
+    let formErrors = []
+    if (this.linkMain.length) {
+      let map = new Map()
+      if (config.interfaces) {
+        config.interfaces.forEach(m => {
+          if (m.status !== 'true' || !m.columns) return false
+    
+          map.set(m.uuid, m.columns)
+        })
+      }
+
+      let forEachComs = (components) => {
+        components.forEach(item => {
+          if (item.type === 'tabs') {
+            item.subtabs.forEach(tab => {
+              forEachComs(tab.components)
+            })
+          } else if (item.type === 'group') {
+            forEachComs(item.components)
+          } else if (item.columns && item.columns.length) {
+            map.set(item.uuid, item.columns)
+          }
+        })
+      }
+
+      forEachComs(config.components)
+
+      this.linkMain.forEach(item => {
+        if (item.config.wrap && item.config.wrap.datatype === 'public') return
+
+        let supModule = ''
+        if (item.config.wrap && item.config.wrap.datatype === 'static') {
+          supModule = item.config.wrap.supModule ? item.config.wrap.supModule[item.config.wrap.supModule.length - 1] : ''
+        } else if (item.config.setting && item.config.setting.supModule) {
+          supModule = item.config.setting.supModule[item.config.setting.supModule.length - 1] || ''
+          if (supModule === 'empty') {
+            supModule = ''
+          }
+        }
+
+        if (!supModule) return
+
+        let cols = map.get(supModule)
+
+        if (!cols) {
+          formErrors.push(<div key={item.forms[0].uuid}>
+            缁勪欢<span style={{color: '#1890ff', margin: '0 2px 0 2px'}}>{item.config.name}{item.label ? '-' + item.label : ''}</span>涓〃鍗�<span style={{color: 'orange', margin: '0 2px 0 2px'}}>{item.forms.map(c => c.label + ' (' + c.field + ')').join('銆�')}</span>鏃犳晥
+          </div>)
+        } else {
+          let _forms = []
+          let _cols = cols.map(col => col.field.toLowerCase())
+
+          item.forms.forEach(m => {
+            if (_cols.includes(m.field.toLowerCase())) return
+
+            _forms.push(m.label + ' (' + m.field + ')')
+          })
+
+          if (_forms.length) {
+            formErrors.push(<div key={item.forms[0].uuid}>
+              缁勪欢<span style={{color: '#1890ff', margin: '0 2px 0 2px'}}>{item.config.name}{item.label ? '-' + item.label : ''}</span>涓〃鍗�<span style={{color: 'orange', margin: '0 2px 0 2px'}}>{_forms.join('銆�')}</span>鏃犳晥
+            </div>)
+          }
+        }
+      })
+    }
+
+    formErrors = formErrors.length ? formErrors : ''
+
+    Modal.confirm({
+      content: <div style={{paddingLeft: '38px'}}>
+        {`褰撳墠鑿滃崟鍏�${this.sqlList.length}涓粍浠讹紝${sqls.length}椤硅剼鏈渶瑕佹楠�${sqls.length > 20 ? '锛屾椂闂村ぇ姒傞渶瑕�' + parseInt(sqls.length / 2) + '绉�' : ''}銆俙}
+        {formErrors}
+      </div>,
+      onOk() {
+        that.setState({visible: true, status: 'loading', sqlList: fromJS(sqls).toJS(), successIds: [], errorIds: [], errorMsg: {}, execId: ''}, () => {
+          that.roopSql()
+        })
+      },
+      onCancel() {}
+    })
+
+    this.sqlList = []
+  }
+
+  filterComponent = (components, mainSearch, regs, process, ispop = false) => {
+    let appType = sessionStorage.getItem('appType')
 
     components.forEach(item => {
       if (item.type === 'tabs') {
         item.subtabs.forEach(tab => {
+          let _mainSearch = mainSearch || []
+
+          if (appType !== 'mob') {
+            tab.components.forEach(com => {
+              if (com.type !== 'search') return
+        
+              _mainSearch = com.search || []
+            })
+          }
           this.filterComponent(tab.components, _mainSearch, regs, process)
         })
       } else if (item.type === 'group') {
-        this.filterComponent(item.components, _mainSearch, regs, process)
+        this.filterComponent(item.components, mainSearch, regs, process)
       } else {
         let children = []
         if (item.wrap && item.setting) {
@@ -235,13 +322,18 @@
         }
 
         if (item.setting && item.setting.interType === 'system') {
-          let sql = this.formatDataSource(item, regs, _mainSearch)
+          if (item.format === 'object') {
+            item.setting.laypage = 'false'
+            item.setting.$top = true
+          }
+
+          let sql = this.formatDataSource(item, regs, mainSearch)
   
           children.push({label: '鏁版嵁婧�', sql: sql})
         } else if (item.setting && item.setting.useMSearch === 'true') {
           let searches = item.search || []
-          if (_mainSearch.length > 0) {
-            searches = [...searches, ..._mainSearch]
+          if (mainSearch.length > 0) {
+            searches = [...searches, ...mainSearch]
           }
           item.$searches = fromJS(searches).toJS()
         }
@@ -293,7 +385,7 @@
           getCols(item.cols)
   
           if (item.subtype === 'editable' && item.submit.intertype === 'system') {
-            let sql = this.getEditTableSql(item.submit, item.cols, item.columns)
+            let sql = this.getEditTableSql(item.submit, item.cols, item.columns, item.setting)
             children.push({label: '鎻愪氦', sql: sql})
           }
         } else if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
@@ -354,6 +446,18 @@
             if (!group.subButton.Ot) {
               group.subButton.Ot = item.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
             }
+
+            if (group.fields) {
+              let cells = group.fields.filter(cell => cell.type === 'linkMain')
+
+              if (cells.length) {
+                this.linkMain.push({
+                  config: item,
+                  forms: cells
+                })
+              }
+            }
+
             let res = this.resetButton(item, group.subButton, process, group)
 
             if (res) {
@@ -380,6 +484,19 @@
 
   resetButton = (item, cell, process, group, isback) => {
     let sql = ''
+    if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+      if (cell.modal && cell.modal.fields.length) {
+        let cells = cell.modal.fields.filter(n => n.type === 'linkMain')
+  
+        if (cells.length) {
+          this.linkMain.push({
+            config: item,
+            forms: cells,
+            label: cell.label
+          })
+        }
+      }
+    }
     if (['exec', 'prompt', 'pop', 'form', 'formSubmit'].includes(cell.OpenType)) {
       if (cell.intertype === 'system' || cell.procMode === 'system') { // 绯荤粺鎺ュ彛
         if (item.subtype === 'dualdatacard' && isback) {
@@ -439,6 +556,12 @@
     } else if (cell.OpenType === 'funcbutton') {
       if (cell.funcType === 'print') {
 
+      } else if ((cell.funcType === 'refund' || cell.funcType === 'pay') && cell.payMode === 'system') {
+        sql = this.getPaySql(cell, item)
+      }
+    } else if (cell.OpenType === 'innerpage' || cell.OpenType === 'outerpage') {
+      if (cell.pageTemplate === 'pay' && cell.payMode === 'system') {
+        sql = this.getPaySql(cell, item)
       }
     } else if (cell.OpenType === 'popview') {
       if (cell.config && cell.config.components) {
@@ -454,7 +577,31 @@
         if (process) {
           regs.push({ reg: /@works_flow_code@/ig, value: `'1949-10-01 15:00:00'` })
         }
-        this.filterComponent(cell.config.components, [], regs, process, true)
+
+        let _mainSearch = []
+
+        if (sessionStorage.getItem('appType') === 'mob') {
+          cell.config.components.forEach(item => {
+            if (item.type === 'search' && item.wrap.field) {
+              _mainSearch.push({
+                type: 'text',
+                label: item.wrap.label,
+                field: item.wrap.field,
+                match: item.wrap.match,
+                required: item.wrap.required,
+                value: item.wrap.initval || ''
+              })
+            }
+          })
+        } else {
+          cell.config.components.forEach(component => {
+            if (component.type !== 'search') return
+      
+            _mainSearch = component.search || []
+          })
+        }
+
+        this.filterComponent(cell.config.components, _mainSearch, regs, process, true)
 
         if (this.sqlPopList.length) {
           sql = fromJS(this.sqlPopList).toJS()
@@ -485,7 +632,7 @@
       }
     })
 
-    if (!_prev) return ''
+    if (!_prev) return _back
 
     let tbs = []
     _prev.replace(/\n|\r/g, ' ').split(/\sdeclare\s/ig).forEach(line => {
@@ -551,8 +698,29 @@
     let BID = Utils.getuuid()
     let verify = btn.verify || {}
     let _actionType = null
-    let setting = component.setting
+    let setting = component.setting || {}
     let columns = component.columns || []
+
+    if (verify.invalid === 'true') {
+      if (component.wrap && (component.wrap.datatype === 'static' || component.wrap.datatype === 'public')) {
+        verify.invalid = 'false'
+      } else if (setting.maxScript && setting.maxScript >= 300) {
+        verify.invalid = 'false'
+      } else if (!setting.dataresource) {
+        verify.invalid = 'false'
+      } else if (btn.intertype !== 'system' && btn.procMode !== 'system') {
+        verify.invalid = 'false'
+      } else if (btn.sqlType === 'insert') {
+        verify.invalid = 'false'
+      } else if (btn.Ot === 'notRequired') {
+        verify.invalid = 'false'
+      }
+    }
+    if (verify.uniques && verify.uniques.length > 0 && btn.Ot === 'requiredOnce') {
+      if (component.wrap && (component.wrap.datatype === 'static' || component.wrap.datatype === 'public')) {
+        verify.uniques = []
+      }
+    }
   
     if (verify.default !== 'false') { // 鍒ゆ柇鏄惁浣跨敤榛樿sql
       _actionType = btn.sqlType
@@ -615,8 +783,10 @@
             _item.type = 'text'
           } else if (_item.type === 'number' || _item.type === 'rate') {
             _item.fieldlen = item.decimal || 0
-          } else  if (_item.type === 'date') {
+          } else if (_item.type === 'date') {
             _item.type = item.declareType === 'nvarchar(50)' ? 'text' : 'date'
+          } else if (_item.type === 'datetime') {
+            _item.type = 'date'
           } else if (item.declare === 'decimal') {
             _item.type = 'number'
             _item.fieldlen = item.decimal || 0
@@ -662,8 +832,10 @@
             _item.type = 'text'
           } else if (_item.type === 'number' || _item.type === 'rate') {
             _item.fieldlen = item.decimal || 0
-          } else  if (_item.type === 'date') {
+          } else if (_item.type === 'date') {
             _item.type = item.declareType === 'nvarchar(50)' ? 'text' : 'date'
+          } else if (_item.type === 'datetime') {
+            _item.type = 'date'
           } else if (item.declare === 'decimal') {
             _item.type = 'number'
             _item.fieldlen = item.decimal || 0
@@ -711,8 +883,8 @@
     })
   
     // 娣诲姞鏁版嵁涓瓧娈碉紝琛ㄥ崟鍊间紭鍏�(鎸夐挳涓嶉�夎鎴栧琛屾嫾鎺ユ椂璺宠繃)
-    if (btn.Ot !== 'notRequired' && columns && columns.length > 0) {
-      const setField = (col) => {
+    if (btn.Ot !== 'notRequired' && columns.length > 0) {
+      columns.forEach(col => {
         if (!col.field) return
         let _key = col.field.toLowerCase()
   
@@ -730,35 +902,7 @@
         
         if (!_vars.includes(_key)) {
           _vars.push(_key)
-  
-          if (col.datatype) {
-            _declarefields.push(`@${_key} ${col.datatype}`)
-          } else {
-            if (col.fieldlength && col.fieldlength > 4000) {
-              col.fieldlength = 'max'
-            }
-  
-            let _type = `nvarchar(${col.fieldlength || 50})`
-  
-            if (col.type === 'number') {
-              let _length = col.decimal ? col.decimal : 0
-              _type = `decimal(18,${_length})`
-            } else if (col.type === 'picture' || col.type === 'textarea') {
-              _type = `nvarchar(${col.fieldlength || 512})`
-            }
-  
-            _declarefields.push(`@${_key} ${_type}`)
-          }
-        }
-      }
-  
-      columns.forEach(col => {
-        if (col.type === 'colspan' || col.type === 'old_colspan') {
-          col.subcols.forEach(cell => {
-            setField(cell)
-          })
-        } else {
-          setField(col)
+          _declarefields.push(`@${_key} ${col.datatype || 'nvarchar(50)'}`)
         }
       })
     }
@@ -846,37 +990,31 @@
     }
   
     // 澶辨晥楠岃瘉锛屾坊鍔犳暟鎹椂涓嶇敤
-    if (btn.sqlType !== 'insert' && btn.Ot !== 'notRequired' && verify.invalid === 'true' && setting.dataresource) {
+    if (verify.invalid === 'true') {
       let datasource = setting.dataresource
       let customScript = setting.customScript || ''
-      let orderBy = setting.order
+  
+      let regoptions = [{
+        reg: new RegExp('@userName@', 'ig'),
+        value: `'${userName}'`
+      }, {
+        reg: new RegExp('@fullName@', 'ig'),
+        value: `'${fullName}'`
+      }, {
+        reg: new RegExp('@orderBy@', 'ig'),
+        value: setting.order || primaryKey
+      }, {
+        reg: new RegExp('@pageSize@', 'ig'),
+        value: 1
+      }, {
+        reg: new RegExp('@pageIndex@', 'ig'),
+        value: 1
+      }]
 
-      if (setting.queryType === 'statistics' || customScript) {
-        let searches = formatSearch(component.$searches || [])
-        let regoptions = getSearchRegs(searches)
-  
-        regoptions.push({
-          reg: new RegExp('@userName@', 'ig'),
-          value: `'${userName}'`
-        }, {
-          reg: new RegExp('@fullName@', 'ig'),
-          value: `'${fullName}'`
-        }, {
-          reg: new RegExp('@orderBy@', 'ig'),
-          value: orderBy
-        }, {
-          reg: new RegExp('@pageSize@', 'ig'),
-          value: 999999
-        }, {
-          reg: new RegExp('@pageIndex@', 'ig'),
-          value: 1
-        })
-  
-        regoptions.forEach(item => {
-          datasource = datasource.replace(item.reg, item.value)
-          customScript = customScript.replace(item.reg, item.value)
-        })
-      }
+      regoptions.forEach(item => {
+        datasource = datasource.replace(item.reg, item.value)
+        customScript = customScript.replace(item.reg, item.value)
+      })
   
       if (customScript) {
         _sql += `
@@ -951,7 +1089,6 @@
   
         if (!keys.includes(_key)) return // 琛ㄥ崟涓笉鍚崟鍙风敓鎴愬瓧娈�
   
-        let _ModularDetailCode = ''
         let _lpline = ''
         if (item.TypeCharOne === 'Lp') {
           if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
@@ -959,33 +1096,22 @@
           } else {
             _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${_linkKey},48)`
           }
-          _ModularDetailCode = '@ModularDetailCode'
         } else if (item.TypeCharOne === 'BN') {
-          let _val = ''
           if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
-            _val = BID
+            _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
           } else {
-            _val = 0
+            _lpline = `set @ModularDetailCode= 'BN'+ right(@${_linkKey},48)`
           }
-          _ModularDetailCode = `'${item.TypeCharOne + _val}'`
         } else {
-          _ModularDetailCode = `'${item.ModularDetailCode}'`
-        }
-  
-        let _declare = ''
-  
-        if (!_vars.includes(_key)) {
-          _declare = `Declare @${_key} nvarchar(50)`
-          _vars.push(_key)
+          _lpline = `set @ModularDetailCode= right('${item.ModularDetailCode}',50)`
         }
   
         _billcodesSql += `
         /* 鍗曞彿鐢熸垚 */
-        ${_declare}
         select @BillCode='', @${_key}='', @ModularDetailCode=''
         ${_lpline}
         exec s_get_BillCode
-          @ModularDetailCode=${_ModularDetailCode},
+          @ModularDetailCode=@ModularDetailCode,
           @Type=${item.Type},
           @TypeCharOne='${item.TypeCharOne}',
           @TypeCharTwo ='${item.TypeCharTwo}',
@@ -1005,6 +1131,17 @@
   
     // 鍞竴鎬ч獙璇侊紝蹇呴』瀛樺湪琛ㄥ崟锛堣〃鍗曞瓨鍦ㄦ椂锛屼富閿潎涓哄崟鍊硷級,蹇呴』濉啓鏁版嵁婧愶紝澶氳鎷兼帴鏃朵笉鍙敤
     if (formdata && verify.uniques && verify.uniques.length > 0 && btn.Ot !== 'requiredOnce') {
+      let dateForms = []
+      let numForms = []
+      formdata.forEach(form => {
+        let _key = form.key.toLowerCase()
+        if (form.type === 'date') {
+          dateForms.push(_key)
+        } else if (form.type === 'number' || form.type === 'rate') {
+          numForms.push(_key)
+        }
+      })
+
       verify.uniques.forEach(item => {
         let _fieldValue = []                     // 琛ㄥ崟閿�煎field=value
         let _value = []                          // 琛ㄥ崟鍊硷紝鐢ㄤ簬閿欒鎻愮ず
@@ -1018,16 +1155,15 @@
           arr.push(_key)
           if (_key === 'bid') { // 琛ㄥ崟涓病鏈塨id鍒欎娇鐢ㄧ郴缁焍id鍙橀噺
             _val = BID
+          } else if (numForms.includes(_key)) {
+            _val = '1'
+          } else if (dateForms.includes(_key)) {
+            _val = '1949-10-01'
           }
 
           _fieldValue.push(`${_key}='${_val}'`)
           _value.push(`${_labels[index] || ''}锛�${_val || ''}`)
         })
-  
-        let _verifyType = ''
-        if (item.verifyType === 'logic') {
-          _verifyType = ' and deleted=0'
-        }
   
         if (!arr.includes(primaryKey.toLowerCase())) {
           _fieldValue.push(`${primaryKey} !='${primaryId}'`)
@@ -1036,7 +1172,7 @@
         _sql += `
         /* 鍞竴鎬ч獙璇� */
         select @tbid='', @ErrorCode='',@retmsg=''
-        select @tbid='X' from ${btn.sql} where ${_fieldValue.join(' and ')}${_verifyType}
+        select @tbid='X' from ${btn.sql} where ${_fieldValue.join(' and ')}${item.verifyType === 'logic' ? ' and deleted=0' : ''}
         If @tbid!=''
         Begin
           select @ErrorCode='${item.errorCode}',@retmsg='${_value.join(', ')} 宸插瓨鍦�'
@@ -1243,7 +1379,7 @@
       if (columns && columns.length > 0 && btn.Ot !== 'notRequired') {
         let _index = 0
         columns.forEach(col => {
-          if (!col.field || col.Hide === 'true' || _index >= 4) return
+          if (!col.field || col.Hide === 'true' || _index >= 4 || col.field === primaryKey) return
           _msg += col.label + '=0,'
           _index++
         })
@@ -1328,13 +1464,7 @@
       if (_backCustomScript) {
         _sql += _backCustomScript
       }
-  
-      _sql = _sql.replace(/@start_type@/ig, `'寮�濮�'`)
-      _sql = _sql.replace(/@check_type@/ig, `'瀹℃牳'`)
-      _sql = _sql.replace(/@notice_type@/ig, `'鎶勯��'`)
-      _sql = _sql.replace(/@check_userids@/ig, `''`)
-      _sql = _sql.replace(/@notice_userids@/ig, `''`)
-      _sql = _sql.replace(/@works_flow_sign@/ig, `''`)
+
       _sql = _sql.replace(/@works_flow_code@/ig, `'mk'`)
       _sql = _sql.replace(/@works_flow_name@/ig, `'mk'`)
       _sql = _sql.replace(/@works_flow_param@/ig, `''`)
@@ -1343,6 +1473,18 @@
       _sql = _sql.replace(/@statusname@/ig, `'${statusName}'`)
       _sql = _sql.replace(/@work_group@/ig, `'mk'`)
       _sql = _sql.replace(/@work_grade@/ig, `'0'`)
+
+      if (verify.flowType === 'start') {
+        _sql = _sql.replace(/@start_type@/ig, `'寮�濮�'`)
+      } else {
+        _sql = _sql.replace(/@check_type@/ig, `'瀹℃牳'`)
+        _sql = _sql.replace(/@notice_type@/ig, `'鎶勯��'`)
+
+        _sql = _sql.replace(/@check_userids@/ig, `''`)
+        _sql = _sql.replace(/@notice_userids@/ig, `''`)
+
+        _sql = _sql.replace(/@works_flow_sign@/ig, `''`)
+      }
     } else if (_backCustomScript) {
       _sql += _backCustomScript
     }
@@ -1632,7 +1774,7 @@
     return sql
   }
 
-  getEditTableSql = (verify, cols, columns) => {
+  getEditTableSql = (verify, cols, columns, setting) => {
     let btn = verify
     let userName = sessionStorage.getItem('User_Name') || ''
     let fullName = sessionStorage.getItem('Full_Name') || ''
@@ -1660,30 +1802,46 @@
   
     let vals = []
     let forms = []
-    let _fields = {}
-
-    columns.forEach(col => {
-      _fields[col.field] = col.datatype
-    })
+    let _forms = {}
+    let index = 0
 
     let getColumns = (cols) => {
       cols.forEach(item => {
         if (item.type === 'colspan') {
           getColumns(item.subcols)
         } else if (item.editable === 'true') {
-          forms.push({
-            field: item.field,
-            type: item.type,
-            datatype: _fields[item.field] || 'nvarchar(50)'
-          })
+          item.$sort = index
+          _forms[item.field] = item
+          index++
         }
       })
     }
 
     getColumns(cols)
 
+    columns.forEach(item => {
+      if (item.field === setting.primaryKey) return
+
+      if (_forms[item.field]) {
+        let _item = {..._forms[item.field]}
+        if (_item.editType === 'date') {
+          _item.datatype = _item.declareType || 'datetime'
+        } else {
+          _item.datatype = item.datatype
+        }
+
+        forms.push(_item)
+      } else {
+        forms.push({...item, $sort: 999})
+      }
+    })
+
+    forms.sort((a, b) => a.$sort - b.$sort)
+
     forms.forEach(col => {
-      if (col.type === 'number') {
+      if (/date/.test(col.datatype)) {
+        vals.push(`'1949-10-01'`)
+      } else if (col.type === 'number') {
         vals.push(`1`)
       } else {
         vals.push(`'mk'`)
@@ -1896,9 +2054,57 @@
     return sql
   }
 
+  getPaySql = (btn, component) => {
+    let sysfields = ['username', 'fullname', 'roleid', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'tbid', 'bid']
+    let _declare = []
+    let _select = []
+    
+    component.columns.forEach(_f => {
+      if (sysfields.includes(_f.field.toLowerCase())) return
+
+      if (/decimal|int/ig.test(_f.datatype)) {
+        _select.push(`@${_f.field}=1`)
+      } else if (/date/ig.test(_f.datatype)) {
+        _select.push(`@${_f.field}='1949-10-01'`)
+      } else {
+        _select.push(`@${_f.field}=''`)
+      }
+
+      _declare.push(`@${_f.field} ${_f.datatype}`)
+    })
+
+    _declare = _declare.join(', ')
+    _select = _select.join(', ')
+
+    let _sql = `Declare @UserName nvarchar(50), @FullName nvarchar(50), @RoleID nvarchar(512), @mk_departmentcode nvarchar(512), @mk_organization nvarchar(512), @mk_user_type nvarchar(20), @mk_nation nvarchar(50), @mk_province nvarchar(50), @mk_city nvarchar(50), @mk_district nvarchar(50), @mk_address nvarchar(100), @ErrorCode nvarchar(50), @retmsg nvarchar(4000), @bid nvarchar(50), @tbid nvarchar(50), ${_declare}
+    Select @UserName='', @FullName='', @RoleID='', @mk_departmentcode='', @mk_organization='', @mk_user_type='', @mk_nation='', @mk_province='', @mk_city='', @mk_district='', @mk_address='', @ErrorCode='', @retmsg='', @bid='', ${_select}
+    `
+
+    btn.verify.scripts.forEach(item => {
+      if (item.status === 'false') return
+
+      _sql += `
+      ${item.sql}
+      `
+    })
+
+    if (btn.output) {
+      _sql += `
+        aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg,${btn.output} as mk_b_id`
+    } else {
+      _sql += `
+        aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
+    }
+
+    _sql = _sql.replace(/@typename@/ig, `'typename'`)
+    _sql = _sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`)
+
+    return _sql
+  }
+
   formatDataSource = (item, regs, mainSearch = []) => {
     if (!item.setting || item.setting.interType !== 'system') return false
-    
+
     let searches = item.search || []
     if (item.setting.useMSearch === 'true' && mainSearch.length > 0) {
       searches = [...searches, ...mainSearch]
@@ -1963,8 +2169,14 @@
         _dataresource = `/*system_query*/select ${arr_field} from ${_dataresource} ${_search} `
       } else if (item.setting.laypage === 'true' && item.setting.order) {
         _dataresource = `/*system_query*/select top 10 ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${item.setting.order}) as rows from ${_dataresource} ${_search}) tmptable where rows > 0 order by tmptable.rows `
+      } else if (item.setting.$top) {
+        if (item.setting.order) {
+          _dataresource = `/*system_query*/select top 1 ${arr_field} from ${_dataresource} ${_search} order by ${item.setting.order} `
+        } else {
+          _dataresource = `/*system_query*/select top 1 ${arr_field} from ${_dataresource} ${_search}  `
+        }
       } else if (item.setting.order) {
-        _dataresource = `/*system_query*/select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${item.setting.order}) as rows from ${_dataresource} ${_search}) tmptable order by tmptable.rows `
+        _dataresource = `/*system_query*/select ${arr_field} from ${_dataresource} ${_search} order by ${item.setting.order} `
       } else {
         _dataresource = `/*system_query*/select ${arr_field} from ${_dataresource} ${_search} `
       }
@@ -2009,10 +2221,16 @@
     )
 
     if (item.hasExtend) {
-      regs.push({reg: /@mk_time@/ig, value: '2024-04-29 17:20:00'})
+      regoptions.push({reg: /@mk_time@/ig, value: `'2024-04-29 17:20:00'`})
     }
     if (item.type === 'calendar') {
-      regoptions.push({ reg: /@mk_year@/ig, value: '2024' })
+      regoptions.push({ reg: /@mk_year@/ig, value: `'2024'` })
+    }
+    if (window.GLOB.getLocation) {
+      regoptions.push(
+        {reg: /@mk_longitude@/ig, value: 0},
+        {reg: /@mk_latitude@/ig, value: 0}
+      )
     }
 
     regoptions.forEach(cell => {
@@ -2040,7 +2258,7 @@
 
     this.setState({status: this.verSqls.length > 0 ? 'loading' : 'over', execId: item.uuid})
 
-    console.info(`/* 缁勪欢锛�${item.name}  妫�楠岄」锛�${item.label} */`)
+    window.mkInfo(`/* 缁勪欢锛�${item.name}  妫�楠岄」锛�${item.label} */`)
 
     Api.sDebug(item.sql).then(result => {
       if (result.status || result.ErrCode === '-2') {
@@ -2092,14 +2310,6 @@
           destroyOnClose
         >
           <div className="mk-sql-wrap">
-            {/* <div className="header">
-              <div className="sql-item">
-                <div className="sql-1">缁勪欢</div>
-                <div className="sql-2">妫�楠岄」</div>
-                <div className="sql-3">鍏朵粬</div>
-                <div className="sql-4">鐘舵��</div>
-              </div>
-            </div> */}
             <div className="body">
               {sqlList.map(item => {
                 let other = ''
diff --git a/src/menu/menushell/index.jsx b/src/menu/menushell/index.jsx
index 77c601f..6c73b42 100644
--- a/src/menu/menushell/index.jsx
+++ b/src/menu/menushell/index.jsx
@@ -141,7 +141,6 @@
         config: item.config,
         width: item.width || 24,
         name: name,
-        floor: 1,   // 缁勪欢鐨勫眰绾�
         isNew: true // 鏂版坊鍔犳爣蹇楋紝鐢ㄤ簬鍒濆鍖�
       }
       
diff --git a/src/menu/modalconfig/index.jsx b/src/menu/modalconfig/index.jsx
index 6f40e02..e76889a 100644
--- a/src/menu/modalconfig/index.jsx
+++ b/src/menu/modalconfig/index.jsx
@@ -165,15 +165,15 @@
    * @description 琛ㄥ崟鍒犻櫎骞跺埛鏂�
    */
   closeForm = (card) => {
-    let _this = this
+    let that = this
 
     confirm({
       content: `纭畾鍒犻櫎${card.label ? `<<${card.label}>>` : ''}鍚楋紵`,
       onOk() {
-        let _config = fromJS(_this.state.config).toJS()
+        let _config = fromJS(that.state.config).toJS()
         _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid))
 
-        _this.setState({
+        that.setState({
           config: _config,
         })
       },
@@ -193,13 +193,13 @@
   }
 
   clearConfig = () => {
-    const _this = this
+    const that = this
     let _config = {...this.state.config, fields: []}
 
     confirm({
       content: '纭畾娓呯┖琛ㄥ崟鍚楋紵',
       onOk() {
-        _this.setState({ config: _config })
+        that.setState({ config: _config })
       },
       onCancel() {}
     })
@@ -213,11 +213,11 @@
     const { config, originConfig } = this.state
 
     if (!is(fromJS(config), fromJS(originConfig))) {
-      let _this = this
+      let that = this
       confirm({
         content: '閰嶇疆淇℃伅鏈繚瀛橈紝纭畾杩斿洖鍚楋紵',
         onOk() {
-          _this.props.handleBack()
+          that.props.handleBack()
         },
         onCancel() {}
       })
@@ -279,7 +279,7 @@
 
   changecols = (type) => {
     let config = fromJS(this.state.config).toJS()
-    let _this = this
+    let that = this
 
     config.fields = config.fields.map(item => {
       item.labelwidth = 33.3
@@ -305,7 +305,7 @@
     confirm({
       content: `纭畾鍒囨崲涓�${type}鍒楀悧锛焋,
       onOk() {
-        _this.setState({config})
+        that.setState({config})
       },
       onCancel() {}
     })
@@ -394,7 +394,7 @@
               <div>
                 <PasteForms type="toolbar" config={config} update={this.pasteFields}/>
                 <Button type="primary" id="save-modal-config" loading={saving} onClick={this.submitConfig}>淇濆瓨</Button>
-                <Button onClick={this.cancelConfig}>杩斿洖</Button>
+                <Button disabled={saving} onClick={this.cancelConfig}>杩斿洖</Button>
               </div>
             } style={{ width: '100%' }}>
               <SettingOutlined onClick={this.changeSetting} />
diff --git a/src/menu/modalconfig/index.scss b/src/menu/modalconfig/index.scss
index ce93e36..1ddd864 100644
--- a/src/menu/modalconfig/index.scss
+++ b/src/menu/modalconfig/index.scss
@@ -223,10 +223,6 @@
               .ant-input-number {
                 margin-top: 4px;
               }
-              .normal-braft-editor {
-                border: 1px solid #d9d9d9;
-                border-radius: 4px;
-              }
             }
             .ant-form-item-control-wrapper::after {
               content: '';
diff --git a/src/menu/pastecontroller/index.jsx b/src/menu/pastecontroller/index.jsx
index 1ef0452..b9b8937 100644
--- a/src/menu/pastecontroller/index.jsx
+++ b/src/menu/pastecontroller/index.jsx
@@ -9,6 +9,8 @@
 import asyncComponent from '@/utils/asyncComponent'
 // import './index.scss'
 
+const { confirm } = Modal
+
 const PasteForm = asyncComponent(() => import('@/templates/zshare/pasteform'))
 
 class PasteController extends Component {
@@ -253,7 +255,7 @@
       options = ['tabs', 'timeline', 'datacard', 'doublecard', 'propcard', 'cardatacard', 'carpropcard', 'simpleform', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'editor', 'pie', 'scatter', 'iframe', 'sandbox']
   
       if (appType === 'mob') {
-        options.push('menubar', 'singleSearch')
+        options.push('menubar', 'singleSearch', 'mobnavbar')
         if (sessionStorage.getItem('editMenuType') !== 'popview') {
           options.push('topbar')
         }
@@ -336,6 +338,15 @@
             })
             return
           }
+        } else if (res.type === 'navbar') {
+          if (menu.components.findIndex(m => m.type === 'navbar') > -1) {
+            notification.warning({
+              top: 92,
+              message: '鑿滃崟鏍忎笉鍙噸澶嶆坊鍔狅紒',
+              duration: 5
+            })
+            return
+          }
         }
       } else if (res.type === 'search') {
         if (tab) {
@@ -376,15 +387,45 @@
 
       this.resetlink(res, commonId)
       
-      this.props.insert(res)
-
       this.setState({visible: false})
 
-      notification.success({
-        top: 92,
-        message: '绮樿创鎴愬姛锛�',
-        duration: 2
-      })
+      let skip = true
+      if (appType === 'mob' && res.type === 'navbar') {
+        let appMenus = sessionStorage.getItem('appViewList')
+        if (appMenus) {
+          try {
+            appMenus = JSON.parse(appMenus)
+            appMenus = appMenus.filter(item => item.keys_type === 'navbar')
+          } catch (e) {
+            appMenus = []
+          }
+        } else {
+          appMenus = []
+        }
+
+        if (appMenus.length) {
+          const that = this
+          skip = false
+
+          confirm({
+            title: '濡傞渶浣跨敤褰撳墠搴旂敤涓凡鏈夌殑鑿滃崟鏍忥紝璇风偣鍑诲彸渚у叧鑱旇彍鍗曟爮锛屽闇�娣诲姞璇风偣纭畾銆�',
+            onOk() {
+              that.props.insert(res)
+            },
+            onCancel() {}
+          })
+        }
+      }
+
+      if (skip) {
+        this.props.insert(res)
+  
+        notification.success({
+          top: 92,
+          message: '绮樿创鎴愬姛锛�',
+          duration: 2
+        })
+      }
     })
   }
 
diff --git a/src/menu/picturecontroller/index.jsx b/src/menu/picturecontroller/index.jsx
index 34ffe8a..a8633f1 100644
--- a/src/menu/picturecontroller/index.jsx
+++ b/src/menu/picturecontroller/index.jsx
@@ -161,7 +161,7 @@
   }
 
   deleteSource = (item) => {
-    const _this = this
+    const that = this
 
     confirm({
       title: '纭畾鍒犻櫎鍚楋紵',
@@ -181,14 +181,14 @@
             if (res.status) {
               if (item.typecharone === 'image') {
                 window.GLOB.app_pictures = res.data || []
-                _this.resetPicture(res.data || [])
+                that.resetPicture(res.data || [])
               } else if (item.typecharone === 'video') {
                 window.GLOB.app_videos = res.data || []
-                _this.resetVideo(res.data || [])
+                that.resetVideo(res.data || [])
               } else if (item.typecharone === 'color') {
                 window.GLOB.app_colors = res.data || []
                 sessionStorage.setItem('app_colors', JSON.stringify(res.data || []))
-                _this.resetColor(res.data || [])
+                that.resetColor(res.data || [])
               }
             } else {
               notification.warning({
diff --git a/src/menu/replaceField/settingform/index.jsx b/src/menu/replaceField/settingform/index.jsx
index 941c3f3..91d3236 100644
--- a/src/menu/replaceField/settingform/index.jsx
+++ b/src/menu/replaceField/settingform/index.jsx
@@ -76,13 +76,13 @@
   }
 
   clear = () => {
-    let _this = this
+    let that = this
     confirm({
       title: '纭畾娓呴櫎鍘嗗彶璁板綍鍚楋紵',
       content: '',
       onOk() {
         localStorage.removeItem('replaceRecord')
-        _this.setState({fields: [], labels: []})
+        that.setState({fields: [], labels: []})
       },
       onCancel() {}
     })
diff --git a/src/menu/stylecontroller/index.jsx b/src/menu/stylecontroller/index.jsx
index c5ed9e0..850eafb 100644
--- a/src/menu/stylecontroller/index.jsx
+++ b/src/menu/stylecontroller/index.jsx
@@ -1,6 +1,6 @@
 import React, {Component} from 'react'
 import { is, fromJS } from 'immutable'
-import { Collapse, Form, Col, InputNumber, Input, Select, Radio, Drawer, Button, message, Checkbox } from 'antd'
+import { Collapse, Form, Col, InputNumber, Input, Select, Radio, Drawer, Button, message, Checkbox, Tooltip } from 'antd'
 import {
   ColumnHeightOutlined,
   FontSizeOutlined,
@@ -30,7 +30,8 @@
   SwapOutlined,
   EnterOutlined,
   DragOutlined,
-  EyeOutlined
+  EyeOutlined,
+  QuestionCircleOutlined
 } from '@ant-design/icons'
 
 import MKEmitter from '@/utils/events.js'
@@ -1050,7 +1051,7 @@
                   </Form.Item>
                 </Col>
               </Panel> : null}
-              {options.includes('float') ? <Panel header="瀵归綈鏂瑰紡" key="float">
+              {options.includes('float') ? <Panel header={<Tooltip placement="topLeft" title="鎸夐挳鐩稿浜庢爡鏍肩殑浣嶇疆锛屾敞锛氳缃搴︽椂鏈夋晥銆�">瀵归綈鏂瑰紡<QuestionCircleOutlined style={{marginLeft: '3px'}} /></Tooltip>} key="float">
                 <Col span={24}>
                   <Form.Item
                     colon={false}
diff --git a/src/menu/tablenodes/index.jsx b/src/menu/tablenodes/index.jsx
index 12951c2..4174e4d 100644
--- a/src/menu/tablenodes/index.jsx
+++ b/src/menu/tablenodes/index.jsx
@@ -485,9 +485,12 @@
                 if (m.debug_url) {
                   let _param = JSON.parse(window.decodeURIComponent(window.atob(m.debug_url)))
                   let label = _param.MenuName
+                  _param.lang = _param.lang || 'zh-CN'
 
                   if (_param && _param.type === 'app') {
-                    label += ` (${_param.kei_no} | ${_param.typename}${param.lang !== 'zh-CN' ? ' | ' + param.lang : ''})`
+                    label += ` (${_param.kei_no} | ${_param.typename}${_param.lang !== 'zh-CN' ? ' | ' + _param.lang : ''})`
+                  } else if (_param && _param.lang && _param.lang !== 'zh-CN') {
+                    label += ` (${_param.lang})`
                   }
 
                   cell.children.push({
@@ -534,7 +537,7 @@
       }, 50)
     } else if (menu.param) {
       if (menu.param.type === 'admin') {
-        if (menu.param.MenuType === 'custom') {
+        if (['custom', 'home', 'billPrint'].includes(menu.param.MenuType)) {
           let _param = {...menu.param}
           delete _param.type
           _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
@@ -548,11 +551,11 @@
         }
       } else if (menu.param.type === 'app') {
         if (menu.param.typename !== 'pc') {
-          let _param = {...menu.param, lang: sessionStorage.getItem('lang')}
+          let _param = {...menu.param}
           _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
           window.open(`#/mobdesign/${_param}`)
         } else {
-          let _param = {...menu.param, lang: sessionStorage.getItem('lang')}
+          let _param = {...menu.param}
           _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
           window.open(`#/pcdesign/${_param}`)
         }
diff --git a/src/menu/transfer/index.jsx b/src/menu/transfer/index.jsx
index 1919b20..cdb834a 100644
--- a/src/menu/transfer/index.jsx
+++ b/src/menu/transfer/index.jsx
@@ -26,7 +26,7 @@
 
   trigger = () => {
     const { config } = this.props
-    const _this = this
+    const that = this
 
     if (!config.enabled) {
       let tb = config.components[0]
@@ -36,7 +36,7 @@
           content: '',
           onOk() {
             return new Promise(resolve => {
-              _this.execUpdate(resolve, true)
+              that.execUpdate(resolve, true)
             })
           },
           onCancel() {}
@@ -58,7 +58,7 @@
       content: '',
       onOk() {
         return new Promise(resolve => {
-          _this.execUpdate(resolve)
+          that.execUpdate(resolve)
         })
       },
       onCancel() {}
@@ -73,8 +73,6 @@
     _config.enabled = false
 
     delete _config.autoMatic
-
-    let useMSearch = false
 
     if (clear) {
       _config.components = []
@@ -91,9 +89,6 @@
             tab.components[0].width = 24
             tab.components[0].wrap.width = 24
             tab.components[0].wrap.name = tab.components[0].name
-            if (tab.components[0].setting.useMSearch === 'true') {
-              useMSearch = true
-            }
   
             tab.components[0].action.forEach(btn => {
               if (btn.OpenType === 'popview' && btn.config) {
@@ -145,14 +140,14 @@
       })
     }
 
-    if (useMSearch) {
+    if (_config.components[0].search && _config.components[0].search.length > 0) {
       let cell = {
         uuid: Utils.getuuid(),
         type: 'search',
         width: 24,
         subtype: 'mainsearch',
         name: '鎼滅储',
-        search: _config.components[0].search || [],
+        search: _config.components[0].search,
         style: {borderBottomColor: '#f0f0f0', borderBottomWidth: '1px'},
         wrap: {float: 'left', blacklist: [], name: '鎼滅储', width: 24}
       }
@@ -218,7 +213,8 @@
       type: 'admin',
       OpenType: _config.OpenType,
       PageParam: {Template: 'CustomPage', OpenType: 'newtab', hidden: _config.hidden},
-      MenuType: 'custom'
+      MenuType: 'custom',
+      lang: sessionStorage.getItem('lang')
     }
 
     let url = window.btoa(window.encodeURIComponent(JSON.stringify(urlparam)))
diff --git a/src/menu/urlfieldcomponent/index.jsx b/src/menu/urlfieldcomponent/index.jsx
index a25488e..a6ff171 100644
--- a/src/menu/urlfieldcomponent/index.jsx
+++ b/src/menu/urlfieldcomponent/index.jsx
@@ -61,14 +61,14 @@
 
   deleteField = (field) => {
     let config = JSON.stringify(this.props.config)
-    const _this = this
+    const that = this
 
     if (new RegExp('@' + field + '@', 'ig').test(config)) {
       confirm({
         title: `閰嶇疆涓瓨鍦ˊ${field}@锛岀‘瀹氬垹闄ゅ悧锛焋,
         content: '',
         onOk() {
-          _this.execDelete(field)
+          that.execDelete(field)
         },
         onCancel() {}
       })
diff --git a/src/mob/components/menubar/normal-menubar/index.jsx b/src/mob/components/menubar/normal-menubar/index.jsx
index 016fd2f..596f800 100644
--- a/src/mob/components/menubar/normal-menubar/index.jsx
+++ b/src/mob/components/menubar/normal-menubar/index.jsx
@@ -123,7 +123,7 @@
    */
   deleteCard = (cell, type) => {
     let card = fromJS(this.state.card).toJS()
-    let _this = this
+    let that = this
 
     if (type !== 'direct') {
       confirm({
@@ -131,8 +131,8 @@
         onOk() {
           card.subMenus = card.subMenus.filter(item => item.uuid !== cell.uuid)
   
-          _this.setState({card})
-          _this.props.updateConfig(card)
+          that.setState({card})
+          that.props.updateConfig(card)
         },
         onCancel() {}
       })
diff --git a/src/mob/components/navbar/normal-navbar/index.jsx b/src/mob/components/navbar/normal-navbar/index.jsx
index e33ea48..48a06f5 100644
--- a/src/mob/components/navbar/normal-navbar/index.jsx
+++ b/src/mob/components/navbar/normal-navbar/index.jsx
@@ -12,6 +12,7 @@
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const MenuComponent = asyncIconComponent(() => import('./menus'))
 const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
+const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 
 class NormalNavbar extends Component {
   static propTpyes = {
@@ -130,6 +131,7 @@
             <NormalForm title="鑿滃崟鏍忚缃�" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
+            <CopyComponent type="mobnavbar" card={card}/>
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} />
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} />
             {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
diff --git a/src/mob/components/navbar/normal-navbar/menus/index.jsx b/src/mob/components/navbar/normal-navbar/menus/index.jsx
index 43e0e28..7ade24d 100644
--- a/src/mob/components/navbar/normal-navbar/menus/index.jsx
+++ b/src/mob/components/navbar/normal-navbar/menus/index.jsx
@@ -114,7 +114,7 @@
       }
 
       if (editMenu.MenuID && editMenu.property === 'menu' && res.property !== 'menu') {
-        const _this = this
+        const that = this
         confirm({
           content: '鑿滃崟灏嗚閲嶇疆锛岀‘瀹氫慨鏀瑰悧锛�',
           onOk() {
@@ -124,8 +124,8 @@
               }
               return item
             })
-            _this.setState({menus: _menus, editMenu: null, visible: false}, () => {
-              _this.props.updateConfig(_menus)
+            that.setState({menus: _menus, editMenu: null, visible: false}, () => {
+              that.props.updateConfig(_menus)
             })
           },
           onCancel() {}
@@ -143,17 +143,17 @@
    */
   deleteElement = (card) => {
     const { menus } = this.state
-    let _this = this
+    let that = this
 
     confirm({
       content: `纭畾鍒犻櫎銆�${card.name}銆嬪悧锛焋,
       onOk() {
         let _menus = menus.filter(item => item.MenuID !== card.MenuID)
 
-        _this.setState({
+        that.setState({
           menus: _menus
         }, () => {
-          _this.props.updateConfig(_menus)
+          that.props.updateConfig(_menus)
         })
       },
       onCancel() {}
diff --git a/src/mob/components/tabs/antv-tabs/index.jsx b/src/mob/components/tabs/antv-tabs/index.jsx
index 9653b81..4bb2be3 100644
--- a/src/mob/components/tabs/antv-tabs/index.jsx
+++ b/src/mob/components/tabs/antv-tabs/index.jsx
@@ -169,7 +169,7 @@
 
   delTab = (tab) => {
     let tabs = fromJS(this.state.tabs).toJS()
-    const _this = this
+    const that = this
 
     tabs.subtabs = tabs.subtabs.filter(t => t.uuid !== tab.uuid)
 
@@ -177,8 +177,8 @@
       title: '纭畾鍒犻櫎鏍囩锛�',
       content: '',
       onOk() {
-        _this.setState({tabs})
-        _this.props.updateConfig(tabs)
+        that.setState({tabs})
+        that.props.updateConfig(tabs)
       },
       onCancel() {}
     })
diff --git a/src/mob/header/index.jsx b/src/mob/header/index.jsx
index 6d61f1f..7d372fb 100644
--- a/src/mob/header/index.jsx
+++ b/src/mob/header/index.jsx
@@ -1,5 +1,6 @@
 import React, {Component} from 'react'
 
+import { langs } from '@/store/options.js'
 import avatar from '@/assets/img/avatar.jpg'
 import MainLogo from '@/assets/img/main-logo.png'
 import './index.scss'
@@ -13,10 +14,13 @@
 
   render () {
     const { logo } = this.state
+    let lang = sessionStorage.getItem('lang')
+    lang = lang !== 'zh-CN' ? langs[lang] || '' : ''
 
     return (
       <header className="mob-header-container">
         <div className="header-logo"><img src={logo} alt=""/></div>
+        <span className="lang">{lang}</span>
         <div className="header-user">
           <img src={this.state.avatar} alt=""/>
           <span>
diff --git a/src/mob/header/index.scss b/src/mob/header/index.scss
index b4009e2..2f9cd6e 100644
--- a/src/mob/header/index.scss
+++ b/src/mob/header/index.scss
@@ -9,6 +9,13 @@
   background: #001529;
   border-bottom: 1px solid #000;
 
+  .lang {
+    position: absolute;
+    font-size: 18px;
+    left: calc(50% - 12px);
+    top: 10px;
+    color: #ffffff;
+  }
   .header-logo {
     float: left;
     width: 180px;
diff --git a/src/mob/mobshell/card.jsx b/src/mob/mobshell/card.jsx
index c5a1344..ca91322 100644
--- a/src/mob/mobshell/card.jsx
+++ b/src/mob/mobshell/card.jsx
@@ -31,7 +31,6 @@
 const Timeline = asyncComponent(() => import('@/menu/components/timeline/normal-timeline'))
 const OfficialAccount = asyncComponent(() => import('@/mob/components/official'))
 const ShareCode = asyncComponent(() => import('@/mob/components/sharecode'))
-const TxMap = asyncComponent(() => import('@/mob/components/txmap'))
 const Iframe = asyncComponent(() => import('@/menu/components/iframe'))
 const DoubleDataCard = asyncComponent(() => import('@/menu/components/card/double-data-card'))
 
@@ -151,8 +150,6 @@
       return (<Iframe card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'sharecode') {
       return (<ShareCode card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
-    } else if (card.type === 'map') {
-      return (<TxMap card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     }
   }
 
diff --git a/src/mob/mobshell/index.jsx b/src/mob/mobshell/index.jsx
index 257a3d7..de4fabb 100644
--- a/src/mob/mobshell/index.jsx
+++ b/src/mob/mobshell/index.jsx
@@ -183,7 +183,6 @@
         config: item.config,
         width: item.width || 24,
         name: name,
-        floor: 1,   // 缁勪欢鐨勫眰绾�
         isNew: true // 鏂版坊鍔犳爣蹇楋紝鐢ㄤ簬鍒濆鍖�
       }
       
@@ -217,12 +216,48 @@
         _cards.push(Navbar)
       }
 
-      if (style) {
-        handleList({...menu, style, components: _cards})
+      if (item.component === 'navbar') {
+        let appMenus = sessionStorage.getItem('appViewList')
+        if (appMenus) {
+          try {
+            appMenus = JSON.parse(appMenus)
+            appMenus = appMenus.filter(item => item.keys_type === 'navbar')
+          } catch (e) {
+            appMenus = []
+          }
+        } else {
+          appMenus = []
+        }
+
+        if (appMenus.length) {
+          confirm({
+            title: '濡傞渶浣跨敤褰撳墠搴旂敤涓凡鏈夌殑鑿滃崟鏍忥紝璇风偣鍑诲彸渚у叧鑱旇彍鍗曟爮锛屽闇�鏂板璇风偣纭畾銆�',
+            onOk() {
+              if (style) {
+                handleList({...menu, style, components: _cards})
+              } else {
+                handleList({...menu, components: _cards})
+              }
+              setCards(_cards)
+            },
+            onCancel() {}
+          })
+        } else {
+          if (style) {
+            handleList({...menu, style, components: _cards})
+          } else {
+            handleList({...menu, components: _cards})
+          }
+          setCards(_cards)
+        }
       } else {
-        handleList({...menu, components: _cards})
+        if (style) {
+          handleList({...menu, style, components: _cards})
+        } else {
+          handleList({...menu, components: _cards})
+        }
+        setCards(_cards)
       }
-      setCards(_cards)
     }
   })
 
diff --git a/src/mob/modalconfig/index.jsx b/src/mob/modalconfig/index.jsx
index 8ef83d0..0f75a32 100644
--- a/src/mob/modalconfig/index.jsx
+++ b/src/mob/modalconfig/index.jsx
@@ -170,15 +170,15 @@
    * @description 琛ㄥ崟鍒犻櫎骞跺埛鏂�
    */
   closeForm = (card) => {
-    let _this = this
+    let that = this
 
     confirm({
       content: `纭畾鍒犻櫎${card.label ? `<<${card.label}>>` : ''}鍚楋紵`,
       onOk() {
-        let _config = fromJS(_this.state.config).toJS()
+        let _config = fromJS(that.state.config).toJS()
         _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid))
 
-        _this.setState({
+        that.setState({
           config: _config,
         })
       },
@@ -201,11 +201,11 @@
     const { config, originConfig } = this.state
 
     if (!is(fromJS(config), fromJS(originConfig))) {
-      let _this = this
+      let that = this
       confirm({
         content: '閰嶇疆淇℃伅鏈繚瀛橈紝纭畾杩斿洖鍚楋紵',
         onOk() {
-          _this.props.handleBack()
+          that.props.handleBack()
         },
         onCancel() {}
       })
@@ -316,13 +316,13 @@
   }
 
   clearConfig = () => {
-    const _this = this
+    const that = this
     let _config = {...this.state.config, fields: []}
 
     confirm({
       content: '纭畾娓呯┖琛ㄥ崟鍚楋紵',
       onOk() {
-        _this.setState({ config: _config })
+        that.setState({ config: _config })
       },
       onCancel() {}
     })
diff --git a/src/mob/modalconfig/index.scss b/src/mob/modalconfig/index.scss
index 67a0528..a08b153 100644
--- a/src/mob/modalconfig/index.scss
+++ b/src/mob/modalconfig/index.scss
@@ -218,10 +218,6 @@
               .ant-input-number {
                 margin-top: 4px;
               }
-              .normal-braft-editor {
-                border: 1px solid #d9d9d9;
-                border-radius: 4px;
-              }
             }
             .ant-form-item-control-wrapper::after {
               content: '';
@@ -259,7 +255,6 @@
     background: rgba(0, 0, 0, 0);
   }
 }
-
 
 .modal-fields {
   .ant-modal {
diff --git a/src/mob/modulesource/option.jsx b/src/mob/modulesource/option.jsx
index 9e80200..aa5f650 100644
--- a/src/mob/modulesource/option.jsx
+++ b/src/mob/modulesource/option.jsx
@@ -28,7 +28,7 @@
 import officialAccount from '@/assets/mobimg/guanzhu.jpg'
 import Iframe from '@/assets/img/newpage.jpg'
 import Share from '@/assets/mobimg/share.jpg'
-import MkMap from '@/assets/img/map.jpg'
+// import MkMap from '@/assets/img/map.jpg'
 
 // 缁勪欢閰嶇疆淇℃伅
 export const menuOptions = [
@@ -62,7 +62,7 @@
   { type: 'menu', url: SandBox, component: 'code', subtype: 'sandbox', title: '鑷畾涔�', width: 24 },
   { type: 'menu', url: group, component: 'group', subtype: 'normalgroup', title: '鍒嗙粍', width: 24 },
   { type: 'menu', url: Login, component: 'login', subtype: 'normallogin', title: '娉ㄥ唽/鐧诲綍', width: 24 },
-  { type: 'menu', url: MkMap, component: 'map', subtype: 'txmap', title: '鍦板浘', width: 24, adapter: 'mini' },
+  // { type: 'menu', url: MkMap, component: 'map', subtype: 'txmap', title: '鍦板浘', width: 24, adapter: 'mini' },
   { type: 'menu', url: officialAccount, component: 'officialAccount', subtype: 'officialAccount', title: '鍏虫敞鍏紬鍙凤紙灏忕▼搴忎腑锛�', width: 24, adapter: 'mini' },
   { type: 'menu', url: Share, component: 'sharecode', subtype: 'sharecode', title: '鍒嗕韩鐮�', width: 24 },
   { type: 'menu', url: Iframe, component: 'iframe', subtype: 'iframe', title: 'iframe', width: 24 }
diff --git a/src/mob/searchconfig/index.jsx b/src/mob/searchconfig/index.jsx
index 2f7454c..fbfc001 100644
--- a/src/mob/searchconfig/index.jsx
+++ b/src/mob/searchconfig/index.jsx
@@ -19,7 +19,7 @@
 const { Panel } = Collapse
 const { confirm } = Modal
 const SearchForm = asyncComponent(() => import('@/templates/sharecomponent/searchcomponent/searchform'))
-const PasteComponent = asyncComponent(() => import('./pastecomponent'))
+// const PasteComponent = asyncComponent(() => import('./pastecomponent'))
 const DragElement = asyncComponent(() => import('./searchdragelement'))
 const GDragElement = asyncComponent(() => import('./groupdragelement'))
 const GroupForm = asyncComponent(() => import('./groupform'))
@@ -264,18 +264,18 @@
    * @description 琛ㄥ崟鍒犻櫎骞跺埛鏂�
    */
   closeForm = (card) => {
-    let _this = this
+    let that = this
 
     confirm({
       content: `纭畾鍒犻櫎${card.label ? `<<${card.label}>>` : ''}鍚楋紵`,
       onOk() {
-        let _group = fromJS(_this.state.group).toJS()
+        let _group = fromJS(that.state.group).toJS()
         _group.fields = _group.fields.filter(item => item.uuid !== card.uuid)
 
-        _this.setState({
+        that.setState({
           group: _group,
         })
-        _this.resetConfig(_group)
+        that.resetConfig(_group)
       },
       onCancel() {}
     })
@@ -296,11 +296,11 @@
     const { config, originConfig } = this.state
 
     if (!is(fromJS(config), fromJS(originConfig))) {
-      let _this = this
+      let that = this
       confirm({
         content: '閰嶇疆淇℃伅鏈繚瀛橈紝纭畾杩斿洖鍚楋紵',
         onOk() {
-          _this.props.handleBack()
+          that.props.handleBack()
         },
         onCancel() {}
       })
@@ -446,15 +446,15 @@
   }
 
   closeGroup = (g) => {
-    const _this = this
+    const that = this
     let _group = fromJS(this.state.group).toJS()
     _group.groups = _group.groups.filter(item => item.uuid !== g.uuid)
 
     confirm({
       content: `纭畾鍒犻櫎鍒嗙粍銆�${g.wrap.name}銆嬪悧锛焋,
       onOk() {
-        _this.setState({ group: _group })
-        _this.resetConfig(_group)
+        that.setState({ group: _group })
+        that.resetConfig(_group)
       },
       onCancel() {}
     })
@@ -489,7 +489,7 @@
             <Button type="primary" loading={saving} onClick={this.submitConfig}>淇濆瓨</Button>
             <Button onClick={this.cancelConfig}>鍏抽棴</Button>
             {!group.floor ? <Button onClick={this.returnUp}>杩斿洖涓婄骇</Button> : null}
-            <PasteComponent insert={this.insert} />
+            {/* <PasteComponent insert={this.insert} /> */}
             <Switch checkedChildren="寮�" unCheckedChildren="鍏�" defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
           </div>
           <div className="setting">
diff --git a/src/mob/searchconfig/index.scss b/src/mob/searchconfig/index.scss
index 659c627..8148739 100644
--- a/src/mob/searchconfig/index.scss
+++ b/src/mob/searchconfig/index.scss
@@ -243,10 +243,6 @@
               .ant-input-number {
                 margin-top: 4px;
               }
-              .normal-braft-editor {
-                border: 1px solid #d9d9d9;
-                border-radius: 4px;
-              }
             }
             .ant-form-item-control-wrapper::after {
               content: '';
diff --git a/src/pc/components/login/normal-login/loginform.jsx b/src/pc/components/login/normal-login/loginform.jsx
index 154fadd..8790dd8 100644
--- a/src/pc/components/login/normal-login/loginform.jsx
+++ b/src/pc/components/login/normal-login/loginform.jsx
@@ -157,7 +157,7 @@
             />
           </Form.Item>
           <Form.Item>
-            <Input.Password placeholder="瀵嗙爜" prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />} />
+            <Input.Password placeholder="瀵嗙爜" visibilityToggle={wrap.vispwd !== 'false'} prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />} />
           </Form.Item>
           {!activeWay.shortcut || activeWay.shortcut === 'remember' ? <Form.Item className="minline">
             <Checkbox>璁颁綇瀵嗙爜</Checkbox>
diff --git a/src/pc/components/login/normal-login/options.jsx b/src/pc/components/login/normal-login/options.jsx
index 72dae60..76b6eda 100644
--- a/src/pc/components/login/normal-login/options.jsx
+++ b/src/pc/components/login/normal-login/options.jsx
@@ -171,6 +171,21 @@
         {value: 'none', label: '鏃�'},
         {value: 'remember', label: '璁颁綇瀵嗙爜'},
         {value: 'autologon', label: '鑷姩鐧诲綍'},
+      ],
+      controlFields: [
+        {field: 'vispwd', values: ['remember', 'autologon']},
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'vispwd',
+      label: '鏌ョ湅瀵嗙爜',
+      initval: wrap.vispwd || 'true',
+      tooltip: '瀵嗙爜鏄惁鍙煡鐪嬶紙瀵嗙爜妗嗗彸渚у浘鏍囨槸鍚︽樉绀猴級銆�',
+      required: false,
+      options: [
+        {value: 'true', label: '鍚敤'},
+        {value: 'false', label: '绂佺敤'},
       ]
     },
     {
diff --git a/src/pc/components/login/normal-login/signform.jsx b/src/pc/components/login/normal-login/signform.jsx
index 4d3d42d..311c433 100644
--- a/src/pc/components/login/normal-login/signform.jsx
+++ b/src/pc/components/login/normal-login/signform.jsx
@@ -42,7 +42,7 @@
       } else if (way === 'weixin') {
         signWays.push({
           type: 'weixin',
-          label: '寰俊鐧诲綍',
+          label: '鎵嬫満鍙峰揩鎹风櫥褰�',
           icon: <WechatOutlined />,
           sort: 3
         })
@@ -79,7 +79,7 @@
         } else if (way === 'weixin') {
           signWays.push({
             type: 'weixin',
-            label: '寰俊鐧诲綍',
+            label: '鎵嬫満鍙峰揩鎹风櫥褰�',
             sort: 3
           })
         }
diff --git a/src/pc/components/navbar/normal-navbar/linksetting/linktable/index.jsx b/src/pc/components/navbar/normal-navbar/linksetting/linktable/index.jsx
index 6a2d85a..e6aa8f7 100644
--- a/src/pc/components/navbar/normal-navbar/linksetting/linktable/index.jsx
+++ b/src/pc/components/navbar/normal-navbar/linksetting/linktable/index.jsx
@@ -78,13 +78,13 @@
 
   delMenu = (record) => {
     const { data } = this.state
-    const _this = this
+    const that = this
 
     confirm({
       title: '纭畾鍒犻櫎鍚楋紵',
       content: '',
       onOk() {
-        _this.setState({data: data.filter(item => item.MenuID !== record.MenuID)})
+        that.setState({data: data.filter(item => item.MenuID !== record.MenuID)})
       },
       onCancel() {}
     })
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 3454eb1..76ad886 100644
--- a/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx
+++ b/src/pc/components/navbar/normal-navbar/menusetting/menuform/index.jsx
@@ -165,7 +165,7 @@
               )}
             </Form.Item>
           </Col> : null}
-          {property === 'menu' && copyMenu ? <Col span={12}>
+          {property === 'menu' && copyMenu ? <Col span={22}>
             <Form.Item label={
               <Tooltip placement="topLeft" title="澶嶅埗鑿滃崟鏃讹紝鏄惁娓呯┖鍘熼〉闈腑鐨勫叧鑱旇彍鍗曘��">
                 <QuestionCircleOutlined className="mk-form-tip" />
diff --git a/src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx b/src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx
index 3ee2c9c..e0a85cf 100644
--- a/src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx
+++ b/src/pc/components/navbar/normal-navbar/menusetting/menutable/index.jsx
@@ -88,15 +88,15 @@
 
   delMenu = (record) => {
     const { menu } = this.props
-    const _this = this
+    const that = this
     
     confirm({
       title: '纭畾鍒犻櫎鍚楋紵',
       content: '',
       onOk() {
-        let _data = _this.state.data.filter(item => item.MenuID !== record.MenuID)
-        _this.setState({data: _data})
-        _this.props.menuUpdate({...menu, sublist: _data})
+        let _data = that.state.data.filter(item => item.MenuID !== record.MenuID)
+        that.setState({data: _data})
+        that.props.menuUpdate({...menu, sublist: _data})
       },
       onCancel() {}
     })
@@ -137,7 +137,7 @@
         })
       }
       if (editMenu.MenuID && editMenu.property === 'menu' && _menu.property !== 'menu') {
-        const _this = this
+        const that = this
         confirm({
           content: '鑿滃崟灏嗚閲嶇疆锛岀‘瀹氫慨鏀瑰悧锛�',
           onOk() {
@@ -147,8 +147,8 @@
               }
               return item
             })
-            _this.setState({data: _data, editMenu: null, visible: false})
-            _this.props.menuUpdate({...menu, sublist: _data})
+            that.setState({data: _data, editMenu: null, visible: false})
+            that.props.menuUpdate({...menu, sublist: _data})
           },
           onCancel() {}
         })
@@ -271,15 +271,15 @@
 
   delMenu = (record) => {
     const { menu } = this.props
-    const _this = this
+    const that = this
     
     confirm({
       title: (record.property === 'classify' && record.sublist.length > 0 ? '鑿滃崟涓嬪惈鏈夊瓙鑿滃崟锛�' : '') + '纭畾鍒犻櫎鍚楋紵',
       content: '',
       onOk() {
-        let _data = _this.state.data.filter(item => item.MenuID !== record.MenuID)
-        _this.setState({data: _data})
-        _this.props.menuUpdate({...menu, sublist: _data})
+        let _data = that.state.data.filter(item => item.MenuID !== record.MenuID)
+        that.setState({data: _data})
+        that.props.menuUpdate({...menu, sublist: _data})
       },
       onCancel() {}
     })
@@ -320,7 +320,7 @@
         })
       }
       if (editMenu.MenuID && editMenu.property === 'menu' && _menu.property !== 'menu') {
-        const _this = this
+        const that = this
         confirm({
           content: '鑿滃崟灏嗚閲嶇疆锛岀‘瀹氫慨鏀瑰悧锛�',
           onOk() {
@@ -330,8 +330,8 @@
               }
               return item
             })
-            _this.setState({data: _data, editMenu: null, visible: false})
-            _this.props.menuUpdate({...menu, sublist: _data})
+            that.setState({data: _data, editMenu: null, visible: false})
+            that.props.menuUpdate({...menu, sublist: _data})
           },
           onCancel() {}
         })
@@ -466,13 +466,13 @@
 
   delMenu = (record) => {
     const { data } = this.state
-    const _this = this
+    const that = this
 
     confirm({
       title: (record.property === 'classify' && record.sublist.length > 0 ? '鑿滃崟涓嬪惈鏈夊瓙鑿滃崟锛�' : '') + '纭畾鍒犻櫎鍚楋紵',
       content: '',
       onOk() {
-        _this.setState({data: data.filter(item => item.MenuID !== record.MenuID)})
+        that.setState({data: data.filter(item => item.MenuID !== record.MenuID)})
       },
       onCancel() {}
     })
@@ -513,7 +513,7 @@
       }
 
       if (editMenu.MenuID && editMenu.property === 'menu' && _menu.property !== 'menu') {
-        const _this = this
+        const that = this
         confirm({
           content: '鑿滃崟灏嗚閲嶇疆锛岀‘瀹氫慨鏀瑰悧锛�',
           onOk() {
@@ -523,7 +523,7 @@
               }
               return item
             })
-            _this.setState({data: _data, editMenu: null, visible: false})
+            that.setState({data: _data, editMenu: null, visible: false})
           },
           onCancel() {}
         })
diff --git a/src/pc/createview/index.jsx b/src/pc/createview/index.jsx
index 2465808..bacaa39 100644
--- a/src/pc/createview/index.jsx
+++ b/src/pc/createview/index.jsx
@@ -175,6 +175,10 @@
               config.components = this.collectTB(config.components)
               config.version = 2.0
             }
+
+            if (_config.getLocation) {
+              config.getLocation = _config.getLocation
+            }
           }
   
           param.LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(config)))
diff --git a/src/pc/menushell/index.jsx b/src/pc/menushell/index.jsx
index 32b17b4..5d16e71 100644
--- a/src/pc/menushell/index.jsx
+++ b/src/pc/menushell/index.jsx
@@ -153,7 +153,6 @@
         config: item.config,
         width: item.width || 24,
         name: name,
-        floor: 1,   // 缁勪欢鐨勫眰绾�
         isNew: true // 鏂版坊鍔犳爣蹇楋紝鐢ㄤ簬鍒濆鍖�
       }
       
@@ -169,12 +168,48 @@
       const { index: overIndex } = findCard(`${targetId}`)
       const _cards = update(cards, { $splice: [[overIndex + 1, 0, newcard]] })
 
-      if (style) {
-        handleList({...menu, style, components: _cards})
+      if (item.component === 'navbar') {
+        let appMenus = sessionStorage.getItem('appViewList')
+        if (appMenus) {
+          try {
+            appMenus = JSON.parse(appMenus)
+            appMenus = appMenus.filter(item => item.keys_type === 'navbar')
+          } catch (e) {
+            appMenus = []
+          }
+        } else {
+          appMenus = []
+        }
+
+        if (appMenus.length) {
+          confirm({
+            title: '濡傞渶浣跨敤褰撳墠搴旂敤涓凡鏈夌殑鑿滃崟鏍忥紝璇风偣鍑诲彸渚у叧鑱旇彍鍗曟爮锛屽闇�鏂板璇风偣纭畾銆�',
+            onOk() {
+              if (style) {
+                handleList({...menu, style, components: _cards})
+              } else {
+                handleList({...menu, components: _cards})
+              }
+              setCards(_cards)
+            },
+            onCancel() {}
+          })
+        } else {
+          if (style) {
+            handleList({...menu, style, components: _cards})
+          } else {
+            handleList({...menu, components: _cards})
+          }
+          setCards(_cards)
+        }
       } else {
-        handleList({...menu, components: _cards})
+        if (style) {
+          handleList({...menu, style, components: _cards})
+        } else {
+          handleList({...menu, components: _cards})
+        }
+        setCards(_cards)
       }
-      setCards(_cards)
     }
   })
 
diff --git a/src/setupProxy.js b/src/setupProxy.js
index 31eb44a..015f092 100644
--- a/src/setupProxy.js
+++ b/src/setupProxy.js
@@ -36,12 +36,6 @@
     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/tabviews/basetable/index.jsx b/src/tabviews/basetable/index.jsx
index 3d13f4b..9af687c 100644
--- a/src/tabviews/basetable/index.jsx
+++ b/src/tabviews/basetable/index.jsx
@@ -2,6 +2,7 @@
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
 import { notification, Spin, Row, Col } from 'antd'
+import md5 from 'md5'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
@@ -173,6 +174,21 @@
       }
 
       window.GLOB.CacheData.set(MenuID, urlparam)
+
+      if (window.backend && config.allSqls) {
+        let keys = Object.keys(urlparam)
+        config.allSqls.forEach(item => {
+          item.id = md5(window.GLOB.appkey + item.v_id)
+          if (item.type === 'datasource' || item.type === 'excelOut') {
+            item.urlkeys = keys
+            item.urlparam = urlparam
+            if (config.flow_code) {
+              item.works_flow_code = config.flow_code
+            }
+          }
+          window.GLOB.CacheData.set('sql_' + item.uuid, item)
+        })
+      }
 
       let userName = sessionStorage.getItem('User_Name') || ''
       let fullName = sessionStorage.getItem('Full_Name') || ''
@@ -504,13 +520,13 @@
 
     if (cell.OpenType === 'excelOut') { // 瀵煎嚭
       cell.$menuName = item.$menuname
+    } else if (cell.OpenType === 'pop' && cell.modal) {
+      cell.modal.uuid = cell.uuid + '_pop'
     }
 
     if (cell.verify) {
       if (cell.verify.invalid === 'true') {
-        if (item.wrap && (item.wrap.datatype === 'static' || item.wrap.datatype === 'public')) {
-          cell.verify.invalid = 'false'
-        } else if (item.setting && item.setting.maxScript && item.setting.maxScript >= 300) {
+        if (item.setting && item.setting.maxScript && item.setting.maxScript >= 300) {
           cell.verify.invalid = 'false'
         } else if (cell.intertype !== 'system' && cell.procMode !== 'system') {
           cell.verify.invalid = 'false'
@@ -626,6 +642,8 @@
         return component
       }
 
+      component.setting.uuid = component.uuid
+
       let _customScript = ''
       let _tailScript = ''
       component.scripts && component.scripts.forEach(script => {
@@ -677,7 +695,7 @@
         component.forbidLine = true
       }
       
-      component.setting.delay = delay
+      component.setting.delay = delay + (component.setting.delay || 0)
       delay += 20
 
       return component
diff --git a/src/tabviews/custom/components/card/cardcellList/index.jsx b/src/tabviews/custom/components/card/cardcellList/index.jsx
index 15881fe..085f046 100644
--- a/src/tabviews/custom/components/card/cardcellList/index.jsx
+++ b/src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -553,6 +553,9 @@
           }
           if (card.format === 'percent') {
             val = val * 100
+            if (!card.round) {
+              val = +val.toFixed(2)
+            }
           } else if (card.format === 'abs') {
             val = Math.abs(val)
           }
@@ -943,7 +946,7 @@
                 // eslint-disable-next-line
                 _val = eval(_val)
               } catch (e) {
-                console.info(_val)
+                window.mkInfo(_val)
                 console.warn(e)
                 _val = 0
               }
@@ -957,6 +960,29 @@
           val = ''
         } else if (data) {
           let _val = card.formula
+
+          if (card.$keys && card.noValue === 'hide') { // 绌哄�奸殣钘�
+            let _data = {}
+            let empty = true
+
+            Object.keys(data).forEach(key => {
+              _data[key.toLowerCase()] = data[key]
+            })
+            _data.username = sessionStorage.getItem('User_Name') || ''
+            _data.fullname = sessionStorage.getItem('Full_Name') || ''
+            _data.bid = data.$$BID || ''
+
+            card.$keys.forEach(key => {
+              if (!_data.hasOwnProperty(key)) {
+                empty = false
+              } else if (_data[key] && !/^1949-10-01/.test(_data[key])) {
+                empty = false
+              }
+            })
+
+            if (empty) return null
+          }
+
           if (/@username@|@fullName@|@bid@/ig.test(_val)) {
             _val = _val.replace(/@username@/ig, sessionStorage.getItem('User_Name') || '').replace(/@fullName@/ig, sessionStorage.getItem('Full_Name') || '').replace(/@bid@/ig, data.$$BID || '')
           }
@@ -970,7 +996,7 @@
               // eslint-disable-next-line
               _val = eval(_val)
             } catch (e) {
-              console.info(_val)
+              window.mkInfo(_val)
               console.warn(e)
               _val = ''
             }
@@ -1033,14 +1059,26 @@
           className = mark.signType
         }
 
-        contents.push(
-          <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
-            <div style={_style}>
-              {card.alignItems ? <TextCell card={card} className={'ant-mk-text line' + (card.height || '') + className} value={val}/> : 
-              <div className={'ant-mk-text line' + (card.height || '') + className} style={{height: card.innerHeight}}>{val}</div>}
+        if (card.link && !data.$disabled) {
+          _style.cursor = 'pointer'
+          contents.push(
+            <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
+              <div style={_style} onClick={(e) => {this.openNewView(e, card)}}>
+                {card.alignItems ? <TextCell card={card} className={'ant-mk-text line' + (card.height || '') + className} value={val}/> : 
+                <div className={'ant-mk-text line' + (card.height || '') + className} style={{height: card.innerHeight}}>{val}</div>}
+              </div>
             </div>
-          </div>
-        )
+          )
+        } else {
+          contents.push(
+            <div className={'ant-col ant-col-' + card.width} key={card.uuid} style={_style_} span={card.width}>
+              <div style={_style}>
+                {card.alignItems ? <TextCell card={card} className={'ant-mk-text line' + (card.height || '') + className} value={val}/> : 
+                <div className={'ant-mk-text line' + (card.height || '') + className} style={{height: card.innerHeight}}>{val}</div>}
+              </div>
+            </div>
+          )
+        }
       } else if (card.eleType === 'tag') {
         let vals = ''
   
@@ -1222,6 +1260,7 @@
             name={name}
             BID={data.$$BID}
             LID={lid}
+            columns={cards.columns}
             BData={data.$$BData || ''}
             disabled={_disabled}
             selectedData={_data}
@@ -1284,6 +1323,7 @@
               disabled={_disabled}
               LID={lid}
               btn={card}
+              columns={cards.columns}
               selectedData={_data}
             />
           }
diff --git a/src/tabviews/custom/components/card/cardcellList/index.scss b/src/tabviews/custom/components/card/cardcellList/index.scss
index e5cfb31..b13d11b 100644
--- a/src/tabviews/custom/components/card/cardcellList/index.scss
+++ b/src/tabviews/custom/components/card/cardcellList/index.scss
@@ -54,7 +54,7 @@
       overflow: visible;
       text-align: center;
     }
-    span {
+    span, div {
       text-indent: 0px;
       font-style: inherit;
       font-weight: inherit;
@@ -117,7 +117,7 @@
       min-height: 28px;
       padding: 0;
       overflow: hidden;
-      text-align: inherit;
+      // text-align: inherit;
     }
     .ant-checkbox-wrapper:not(.square) {
       .ant-checkbox-inner, .ant-checkbox-checked::after {
diff --git a/src/tabviews/custom/components/card/data-card/index.jsx b/src/tabviews/custom/components/card/data-card/index.jsx
index b442a83..2682bca 100644
--- a/src/tabviews/custom/components/card/data-card/index.jsx
+++ b/src/tabviews/custom/components/card/data-card/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Spin, Empty, message, Row, Col, Pagination, Switch } from 'antd'
+import { Spin, Empty, message, Row, Col, Pagination, Switch, notification } from 'antd'
 import { DownOutlined } from '@ant-design/icons'
 
 import Api from '@/api'
@@ -410,9 +410,7 @@
 
     if (config.$searchId !== searchId) return
     
-    this.setState({pageIndex: 1}, () => {
-      this.loadData()
-    })
+    this.reloadIndex()
   }
 
   /**
@@ -426,6 +424,7 @@
 
     if (config.uuid !== menuId) return
 
+    let _id = config.wrap.selected === 'always' ? id : ''
     if (config.supNodes) {
       if (['mainline', 'maingrid', 'popclose'].includes(position)) {
         let supNode = this.supModules[this.supModules.length - 1]
@@ -441,18 +440,18 @@
       } else {
         if (position === 'line' || position === 'line_grid') {
           if (lines && lines.length === 1) {
-            this.loadLinedata(lines[0].$$uuid, position)
+            if (config.forbidLine) {
+              this.loadData(lines[0].$$uuid, 'repage')
+            } else {
+              this.loadLinedata(lines[0].$$uuid, position)
+            }
           } else {
-            this.loadData(id)
+            this.loadData(_id, 'repage')
           }
-        } else if (!btn || btn.resetPageIndex !== 'false') {
-          this.setState({
-            pageIndex: 1
-          }, () => {
-            this.loadData(id)
-          })
+        } else if (btn.resetPageIndex !== 'false') {
+          this.reloadIndex()
         } else {
-          this.loadData(id)
+          this.loadData(_id, 'repage')
         }
       }
     } else {
@@ -460,20 +459,20 @@
 
       if (position === 'line' || position === 'line_grid') {
         if (lines && lines.length === 1) {
-          this.loadLinedata(lines[0].$$uuid, position)
+          if (config.forbidLine) {
+            this.loadData(lines[0].$$uuid, 'repage')
+          } else {
+            this.loadLinedata(lines[0].$$uuid, position)
+          }
         } else {
-          this.loadData(id)
+          this.loadData(_id, 'repage')
         }
       } else if (['mainline', 'maingrid', 'popclose'].includes(position) && supModule) {
         MKEmitter.emit('reloadData', supModule, position === 'maingrid' ? '' : BID)
-      } else if (!btn || btn.resetPageIndex !== 'false') {
-        this.setState({
-          pageIndex: 1
-        }, () => {
-          this.loadData(id)
-        })
+      } else if (btn.resetPageIndex !== 'false') {
+        this.reloadIndex()
       } else {
-        this.loadData(id)
+        this.loadData(_id, 'repage')
       }
     }
   }
@@ -495,13 +494,21 @@
     })
   }
 
+  reloadIndex = () => {
+    this.setState({
+      pageIndex: 1
+    }, () => {
+      this.loadData()
+    })
+  }
+
   prevCheck = (id) => {
     const { selected } = this.state
 
     if (selected === 'false' && !id) return
 
     setTimeout(() => {
-      this.checkTopLine(id)
+      this.checkTopLine(id, selected)
     }, 10)
 
     if (selected === 'init') {
@@ -509,59 +516,39 @@
     }
   }
 
-  checkTopLine = (id) => {
-    const { config, data, selected } = this.state
+  checkTopLine = (id, selected) => {
+    const { config, data } = this.state
 
-    if (data.length === 0) {
-      this.setState({
-        activeKey: '',
-        selectKeys: [],
-        selectedData: []
-      })
-  
-      MKEmitter.emit('resetSelectLine', config.uuid, '', '')
-      if (config.setting.$hasSyncModule) {
-        MKEmitter.emit('syncBalconyData', config.uuid, [], false)
+    let index = -1
+    let keys = []
+    let items = []
+
+    if (data.length > 0) {
+      if (id) {
+        index = data.findIndex(item => item.$$uuid === id && !item.$disabled)
       }
-      return
-    }
-
-    if (selected === 'sign') {
-      let index = ''
-      let keys = []
-      let items = []
-      let last = ''
-      data.forEach((item, i) => {
-        if (!item.$disabled && item.selected === 'true') {
-          items.push(item)
-          keys.push(i)
-          index = i
-          last = item
+  
+      if (index !== -1) {
+        keys = [index]
+        items = [data[index]]
+      } else if (selected === 'sign') {
+        data.forEach((item, i) => {
+          if (!item.$disabled && item.selected === 'true') {
+            items.push(item)
+            keys.push(i)
+            index = i
+          }
+        })
+      } else if (selected !== 'false') {
+        if (!data[0].$disabled) {
+          index = 0
+          keys = [index]
+          items = [data[index]]
         }
-      })
-
-      this.setState({
-        activeKey: index,
-        selectKeys: keys,
-        selectedData: items
-      })
-  
-      MKEmitter.emit('resetSelectLine', config.uuid, last ? last.$$uuid : '', last)
-      if (config.setting.$hasSyncModule) {
-        MKEmitter.emit('syncBalconyData', config.uuid, items, data.length === keys.length)
-      }
-      return
-    }
-
-    let index = 0
-    if (id) {
-      index = data.findIndex(item => item.$$uuid === id)
-      if (index === -1) {
-        index = 0
       }
     }
 
-    if (data[index].$disabled) {
+    if (index === -1) {
       this.setState({
         activeKey: '',
         selectKeys: [],
@@ -574,16 +561,18 @@
       }
       return
     }
+
+    let item = items[items.length - 1]
 
     this.setState({
       activeKey: index,
-      selectKeys: [index],
-      selectedData: [data[index]]
+      selectKeys: keys,
+      selectedData: items
     })
 
-    MKEmitter.emit('resetSelectLine', config.uuid, data[index].$$uuid, data[index])
+    MKEmitter.emit('resetSelectLine', config.uuid, item.$$uuid, item)
     if (config.setting.$hasSyncModule) {
-      MKEmitter.emit('syncBalconyData', config.uuid, [data[index]], data.length === 1)
+      MKEmitter.emit('syncBalconyData', config.uuid, items, data.length === keys.length)
     }
   }
 
@@ -681,7 +670,9 @@
     if (config.uuid !== menuId) return
 
     if (!id) {
-      this.loadData()
+      this.reloadIndex()
+    } else if (config.forbidLine) {
+      this.loadData(id, 'repage')
     } else {
       this.loadLinedata(id)
     }
@@ -804,6 +795,11 @@
     if (result.status) {
       if (result.$requestId && this.requestId !== result.$requestId) return
 
+      if (type === 'repage' && result.data.length === 0 && pageIndex > 1) {
+        this.reloadIndex()
+        return
+      }
+
       let start = 1
       if (config.setting.laypage) {
         start = pageSize * (pageIndex - 1) + 1
@@ -814,7 +810,7 @@
         Api.writeCacheConfig(config.uuid, result.data || [], BID)
       }
 
-      if (selected !== 'false' || (id && config.wrap.selected !== 'false')) {
+      if (selected !== 'false' || id) {
         this.prevCheck(id)
       } else {
         MKEmitter.emit('resetSelectLine', config.uuid, '', '')
@@ -902,15 +898,6 @@
   async loadLinedata (id, position) {
     const { config, pageIndex, pageSize, search, BID, BData, orderBy } = this.state
 
-    if (config.forbidLine) {
-      this.setState({
-        pageIndex: 1
-      }, () => {
-        this.loadData()
-      })
-      return
-    }
-
     let searches = fromJS(search).toJS()
     if (config.setting.useMSearch) { // 涓昏〃鎼滅储鏉′欢
       let mainSearch = window.GLOB.SearchBox.get(config.$searchId) || []
@@ -932,7 +919,7 @@
     let result = await Api.genericInterface(param)
     if (result.status) {
       if (position === 'line_grid' && (!result.data || !result.data[0])) {
-        this.loadData()
+        this.reloadIndex()
         return
       }
 
@@ -946,6 +933,12 @@
         _data.$$uuid = _data[config.setting.primaryKey] || ''
         _data.$$BID = BID || ''
         _data.$$BData = BData || ''
+
+        if (config.wrap.controlField) {
+          if (config.wrap.controlVal.includes(_data[config.wrap.controlField] + '')) {
+            _data.$disabled = true
+          }
+        }
 
         data = data.map(item => {
           if (item.$$uuid === _data.$$uuid) {
@@ -1087,6 +1080,20 @@
   }
 
   refreshSearch = (list) => {
+    const { config, BID } = this.state
+
+    if (config.setting.supModule && !BID && config.wrap.supKey !== 'false') {
+      notification.warning({
+        top: 92,
+        message: window.GLOB.dict['sup_key_req'] || '闇�瑕佷笂绾т富閿�硷紒',
+        duration: 5
+      })
+      this.setState({
+        search: list
+      })
+      return
+    }
+
     this.setState({
       search: list,
       pageIndex: 1
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 a5fd92e..8ee5097 100644
--- a/src/tabviews/custom/components/card/double-data-card/index.jsx
+++ b/src/tabviews/custom/components/card/double-data-card/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Spin, Empty, Row, Col, Pagination, Switch } from 'antd'
+import { Spin, Empty, Row, Col, Pagination, Switch, notification } from 'antd'
 import { DownOutlined, UpOutlined, PlusSquareOutlined, MinusSquareOutlined } from '@ant-design/icons'
 
 import Api from '@/api'
@@ -358,9 +358,7 @@
 
     if (config.$searchId !== searchId) return
     
-    this.setState({pageIndex: 1}, () => {
-      this.loadData()
-    })
+    this.reloadIndex()
   }
 
   /**
@@ -373,22 +371,23 @@
 
     let supModule = config.setting.supModule
 
+    let _id = config.wrap.selected === 'always' ? id : ''
     if (position === 'line' || position === 'line_grid') {
       if (lines && lines.length === 1) {
-        this.loadLinedata(lines[0].$$parentId || lines[0].$$uuid, position)
+        if (config.forbidLine) {
+          this.loadData(lines[0].$$parentId || lines[0].$$uuid, 'repage')
+        } else {
+          this.loadLinedata(lines[0].$$parentId || lines[0].$$uuid, position)
+        }
       } else {
-        this.loadData(id)
+        this.loadData(_id, 'repage')
       }
     } else if (['mainline', 'maingrid', 'popclose'].includes(position) && supModule) {
       MKEmitter.emit('reloadData', supModule, position === 'maingrid' ? '' : BID)
-    } else if (!btn || btn.resetPageIndex !== 'false') {
-      this.setState({
-        pageIndex: 1
-      }, () => {
-        this.loadData(id)
-      })
+    } else if (btn.resetPageIndex !== 'false') {
+      this.reloadIndex()
     } else {
-      this.loadData(id)
+      this.loadData(_id, 'repage')
     }
   }
 
@@ -414,64 +413,40 @@
     })
   }
 
-  checkTopLine = (id) => {
-    const { config, data, selected, card } = this.state
+  checkTopLine = (id, selected) => {
+    const { config, data, card } = this.state
     let _opens = [...this.state.opens]
 
-    if (data.length === 0) {
-      this.setState({
-        activeKey: '',
-        selectKeys: [],
-        selectedData: []
-      })
-  
-      MKEmitter.emit('resetSelectLine', config.uuid, '', '')
-      return
-    }
+    let index = -1
+    let keys = []
+    let items = []
 
-    if (selected === 'sign') {
-      let index = ''
-      let keys = []
-      let items = []
-      let last = ''
-
-      if (card.setting.display === 'collapse') {
-        _opens = []
+    if (data.length > 0) {
+      if (id) {
+        index = data.findIndex(item => item.$$uuid === id && !item.$disabled)
       }
 
-      data.forEach((item, i) => {
-        if (!item.$disabled && item.selected === 'true') {
-          items.push(item)
-          keys.push(i)
-          index = i
-          last = item
-
-          if (card.setting.display === 'collapse') {
-            _opens.push(i)
+      if (index !== -1) {
+        keys = [index]
+        items = [data[index]]
+      } else if (selected === 'sign') {
+        data.forEach((item, i) => {
+          if (!item.$disabled && item.selected === 'true') {
+            items.push(item)
+            keys.push(i)
+            index = i
           }
+        })
+      } else if (selected !== 'false') {
+        if (!data[0].$disabled) {
+          index = 0
+          keys = [index]
+          items = [data[index]]
         }
-      })
-
-      this.setState({
-        opens: _opens,
-        activeKey: index,
-        selectKeys: keys,
-        selectedData: items
-      })
-  
-      MKEmitter.emit('resetSelectLine', config.uuid, last ? last.$$uuid : '', last)
-      return
-    }
-
-    let index = 0
-    if (id) {
-      index = data.findIndex(item => item.$$uuid === id)
-      if (index === -1) {
-        index = 0
       }
     }
 
-    if (data[index].$disabled) {
+    if (index === -1) {
       this.setState({
         activeKey: '',
         selectKeys: [],
@@ -483,17 +458,19 @@
     }
 
     if (card.setting.display === 'collapse') {
-      _opens = [index]
+      _opens = keys
     }
+
+    let item = items[items.length - 1]
 
     this.setState({
       opens: _opens,
       activeKey: index,
-      selectKeys: [index],
-      selectedData: [data[index]]
+      selectKeys: keys,
+      selectedData: items
     })
 
-    MKEmitter.emit('resetSelectLine', config.uuid, data[index].$$uuid, data[index])
+    MKEmitter.emit('resetSelectLine', config.uuid, item.$$uuid, item)
   }
 
   checkAll = () => {
@@ -541,7 +518,9 @@
     if (config.uuid !== menuId) return
 
     if (!id) {
-      this.loadData()
+      this.reloadIndex()
+    } else if (config.forbidLine) {
+      this.loadData(id, 'repage')
     } else {
       this.loadLinedata(id)
     }
@@ -637,6 +616,11 @@
     if (result.status) {
       if (result.$requestId && this.requestId !== result.$requestId) return
 
+      if (type === 'repage' && result.data.length === 0 && pageIndex > 1) {
+        this.reloadIndex()
+        return
+      }
+
       let start = 1
       if (config.setting.laypage) {
         start = pageSize * (pageIndex - 1) + 1
@@ -647,13 +631,10 @@
         Api.writeCacheConfig(config.uuid, result.data || [], BID)
       }
 
-      if (selected !== 'false' || (id && config.wrap.selected !== 'false')) {
+      if (selected !== 'false' || id) {
         setTimeout(() => {
-          this.checkTopLine(id)
+          this.checkTopLine(id, selected)
         }, 10)
-        if (selected === 'init') {
-          this.setState({selected: 'false'})
-        }
       } else {
         MKEmitter.emit('resetSelectLine', config.uuid, '', '')
       }
@@ -763,6 +744,10 @@
         loading: false
       })
 
+      if (selected === 'init') {
+        this.setState({selected: 'false'})
+      }
+
       if (config.timer && config.clearField && result.data && result.data[0]) {
         let vals = (config.clearValue || '').split(',')
         if (vals.includes(result.data[0][config.clearField])) {
@@ -787,15 +772,6 @@
   async loadLinedata (id, position) {
     const { config, pageIndex, pageSize, search, BID, BData, orderBy } = this.state
 
-    if (config.forbidLine) {
-      this.setState({
-        pageIndex: 1
-      }, () => {
-        this.loadData()
-      })
-      return
-    }
-
     let searches = fromJS(search).toJS()
     if (config.setting.useMSearch) { // 涓昏〃鎼滅储鏉′欢
       let mainSearch = window.GLOB.SearchBox.get(config.$searchId) || []
@@ -817,7 +793,7 @@
     let result = await Api.genericInterface(param)
     if (result.status) {
       if (position === 'line_grid' && (!result.data || !result.data[0])) {
-        this.loadData()
+        this.reloadIndex()
         return
       }
 
@@ -940,6 +916,14 @@
     }
   }
 
+  reloadIndex = () => {
+    this.setState({
+      pageIndex: 1
+    }, () => {
+      this.loadData()
+    })
+  }
+
   loadMore = () => {
     const { total, pageIndex, pageSize, loading } = this.state
 
@@ -963,6 +947,20 @@
   }
 
   refreshSearch = (list) => {
+    const { config, BID } = this.state
+
+    if (config.setting.supModule && !BID && config.wrap.supKey !== 'false') {
+      notification.warning({
+        top: 92,
+        message: window.GLOB.dict['sup_key_req'] || '闇�瑕佷笂绾т富閿�硷紒',
+        duration: 5
+      })
+      this.setState({
+        search: list
+      })
+      return
+    }
+
     this.setState({
       search: list,
       pageIndex: 1
diff --git a/src/tabviews/custom/components/editor/braft-editor/index.jsx b/src/tabviews/custom/components/editor/braft-editor/index.jsx
index 0b6db75..d5a8cea 100644
--- a/src/tabviews/custom/components/editor/braft-editor/index.jsx
+++ b/src/tabviews/custom/components/editor/braft-editor/index.jsx
@@ -21,14 +21,14 @@
     BID: '',                   // 涓婄骇ID
     config: null,              // 鍥捐〃閰嶇疆淇℃伅
     loading: false,            // 鏁版嵁鍔犺浇鐘舵��
-    data: {}                   // 鏁版嵁
+    data: []                   // 鏁版嵁
   }
 
   UNSAFE_componentWillMount () {
     const { config } = this.props
 
     let _config = fromJS(config).toJS()
-    let _data = { $$empty: true }
+    let _data = []
 
     let BID = ''
     let BData = ''
@@ -47,16 +47,25 @@
 
       if (_config.setting.sync === 'true' && window.GLOB.SyncData.has(_config.dataName)) {
         _data = window.GLOB.SyncData.get(_config.dataName) || []
-        _data = _data[0] || {$$empty: true}
-
         _config.setting.sync = 'false'
   
         window.GLOB.SyncData.delete(_config.dataName)
+      }
+    } else if (_config.wrap.datatype === 'public' && window.GLOB.CacheData.has(_config.wrap.publicId)) {
+      _data = window.GLOB.CacheData.get(_config.wrap.publicId)
+      _data = fromJS(_data).toJS()
+      if (_data.$$empty) {
+        _data = []
+      } else {
+        _data = [_data]
       }
     }
 
     if (_config.wrap.minHeight) {
       _config.style.minHeight = _config.wrap.minHeight
+    }
+    if (_config.wrap.firstTr === 'light') {
+      _config.wrap.tbStyle = 'th-light'
     }
 
     this.setState({
@@ -116,7 +125,6 @@
     if (config.$syncId !== syncId) return
 
     let _data = window.GLOB.SyncData.get(config.dataName) || []
-    _data = _data[0] || {$$empty: true}
 
     this.setState({data: _data})
 
@@ -140,6 +148,11 @@
 
     if (config.wrap.datatype === 'public' && config.wrap.publicId === publicId) {
       let _data = fromJS(data).toJS()
+      if (_data.$$empty) {
+        _data = []
+      } else {
+        _data = [_data]
+      }
 
       this.setState({data: _data})
     }
@@ -174,13 +187,13 @@
     
     if (config.wrap.datatype === 'static') {
       this.setState({
-        data: {$$empty: true},
+        data: [],
         loading: false
       })
       return
     } else if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
       this.setState({
-        data: {$$empty: true},
+        data: [],
         loading: false
       })
       return
@@ -204,11 +217,8 @@
 
     let result = await Api.genericInterface(param)
     if (result.status) {
-      let _data = result.data || []
-      _data = _data[0] || {$$empty: true}
-
       this.setState({
-        data: _data,
+        data: result.data || [],
         loading: false
       })
       
@@ -225,10 +235,10 @@
   render() {
     const { config, loading, data } = this.state
 
-    if (config.wrap.empty === 'hidden' && (!data || data.$$empty)) return null
+    if (config.wrap.empty === 'hidden' && (!data || data.length === 0)) return null
 
     return (
-      <div className={'custom-braft-editor-box ' + (config.wrap.firstTr || '')} id={'anchor' + config.uuid} style={config.style}>
+      <div className={'custom-braft-editor-box ' + (config.wrap.tbStyle || '')} id={'anchor' + config.uuid} style={config.style}>
         {loading ?
           <div className="loading-mask">
             <div className="ant-spin-blur"></div>
@@ -236,10 +246,14 @@
           </div> : null
         }
         <NormalHeader config={config}/>
-        <BraftContent
-          value={config.wrap.datatype !== 'static' ? (data[config.wrap.field] || '') : config.html}
-          encryption={config.wrap.datatype !== 'static' ? config.wrap.encryption : 'false'}
-        />
+        {config.wrap.datatype === 'static' ? <BraftContent
+          value={config.html}
+          encryption={'false'}
+        /> : data.map((item, index) => <BraftContent
+          key={index}
+          value={item[config.wrap.field] || ''}
+          encryption={config.wrap.encryption}
+        />)}
       </div>
     )
   }
diff --git a/src/tabviews/custom/components/editor/braft-editor/index.scss b/src/tabviews/custom/components/editor/braft-editor/index.scss
index 1829c88..e9e62b4 100644
--- a/src/tabviews/custom/components/editor/braft-editor/index.scss
+++ b/src/tabviews/custom/components/editor/braft-editor/index.scss
@@ -28,15 +28,34 @@
   }
 }
 
-.custom-braft-editor-box.light {
+.custom-braft-editor-box.th-light {
   .braft-content {
     table {
       tr:first-child {
-        background-color:#ffffff;
+        background-color: transparent;
       }
     }
   }
 }
+.custom-braft-editor-box.no-border {
+  .braft-content {
+    table {
+      td, th {
+        border: none!important;
+      }
+      tr td:first-child {
+        padding-left: 0px;
+      }
+    }
+  }
+}
+.custom-braft-editor-box.tb-flex {
+  .braft-content {
+    table {
+      table-layout: fixed;
+    }
+  }
+}
 
 .custom-braft-editor-box::after {
   content: ' ';
diff --git a/src/tabviews/custom/components/module/invoice/index.jsx b/src/tabviews/custom/components/module/invoice/index.jsx
index 5733915..5f130b2 100644
--- a/src/tabviews/custom/components/module/invoice/index.jsx
+++ b/src/tabviews/custom/components/module/invoice/index.jsx
@@ -85,6 +85,12 @@
     _config.buyer = this.formatSetting(_config.buyer, 'buyer')
     _config.detail = this.formatSetting(_config.detail, 'detail')
     _config.detail.uuid = _config.uuid
+    _config.buyer.setting.uuid = _config.uuid + 'buyer'
+    _config.detail.setting.uuid = _config.uuid + 'detail'
+    _config.billOutBtn.uuid = _config.uuid
+    _config.billSaveBtn.uuid = _config.uuid
+    _config.billOutBtn.logLabel = _config.$menuname + '-' + _config.billOutBtn.label
+    _config.billSaveBtn.logLabel = _config.$menuname + '-' + _config.billSaveBtn.label
 
     let book = null
     let pas = {}
@@ -487,18 +493,23 @@
 
     setTimeout(() => {
       this.getBillMsg().then(() => {
-        let sql = this.getPreSql(config.billSaveBtn)
-  
-        let param = {
-          func: 'sPC_TableData_InUpDe',
-          LText: sql,
-          exec_type: window.GLOB.execType || 'y',
-          timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
-          BID: BID
+        let param = null
+        if (window.backend && window.GLOB.CacheData.has('sql_' + config.uuid + config.billSaveBtn.type)) {
+          param = this.getBackPreParam(config.billSaveBtn)
+        } else {
+          let sql = this.getPreSql(config.billSaveBtn)
+    
+          param = {
+            func: 'sPC_TableData_InUpDe',
+            LText: sql,
+            exec_type: window.GLOB.execType || 'y',
+            timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
+            BID: BID
+          }
+    
+          param.secretkey = Utils.encrypt('', param.timestamp)
+          param.LText = Utils.formatOptions(param.LText, param.exec_type)
         }
-  
-        param.secretkey = Utils.encrypt('', param.timestamp)
-        param.LText = Utils.formatOptions(param.LText, param.exec_type)
 
         this.setState({
           saveType: 'bill'
@@ -510,7 +521,7 @@
           })
           if (res.status) {
             if (config.billSaveBtn.reTabId) {
-              MKEmitter.emit('reloadMenuView', config.billSaveBtn.reTabId, 'table')
+              MKEmitter.emit('reloadMenuView', config.billSaveBtn.reTabId)
             }
             if (config.billSaveBtn.syncComId) {
               MKEmitter.emit('reloadData', config.billSaveBtn.syncComId)
@@ -570,19 +581,24 @@
 
     setTimeout(() => {
       this.getBillMsg().then(() => {
-        let sql = this.getPreSql(config.billOutBtn)
-  
-        let param = {
-          func: 'sPC_TableData_InUpDe',
-          LText: sql,
-          script_type: 'Y',
-          exec_type: window.GLOB.execType || 'y',
-          timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
-          BID: BID
+        let param = null
+        if (window.backend && window.GLOB.CacheData.has('sql_' + config.uuid + config.billOutBtn.type)) {
+          param = this.getBackPreParam(config.billOutBtn)
+        } else {
+          let sql = this.getPreSql(config.billOutBtn)
+    
+          param = {
+            func: 'sPC_TableData_InUpDe',
+            LText: sql,
+            script_type: 'Y',
+            exec_type: window.GLOB.execType || 'y',
+            timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
+            BID: BID
+          }
+    
+          param.secretkey = Utils.encrypt('', param.timestamp)
+          param.LText = Utils.formatOptions(param.LText, param.exec_type)
         }
-  
-        param.secretkey = Utils.encrypt('', param.timestamp)
-        param.LText = Utils.formatOptions(param.LText, param.exec_type)
 
         this.setState({
           saveType: 'out'
@@ -728,10 +744,202 @@
     }
 
     if (window.GLOB.debugger === true) {
-      console.info(sql.replace(/\n\s{6}/ig, '\n'))
+      window.mkInfo(sql.replace(/\n\s{6}/ig, '\n'))
     }
 
     return sql
+  }
+
+  getBackPreParam = (btn) => {
+    const { config, book, ID, BID, io, details, oriDetails, business_type, invoice_type, from_to_name, from_to_tax_no, from_to_addr, from_to_tel, from_to_bank_name, from_to_account_no, from_to_mob, from_to_email, from_to_code, orgname, tax_no, addr, tel, bank_name, account_no, remark, reviewer, drawer, payee } = this.state
+    let ex = window.GLOB.CacheData.get('sql_' + btn.uuid + btn.type)
+    let exps = []
+
+    let values = {
+      time_id: Utils.getguid(),
+      roleid: sessionStorage.getItem('role_id') || '',
+      mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
+      mk_organization: sessionStorage.getItem('organization') || '',
+      mk_user_type: sessionStorage.getItem('mk_user_type') || '',
+      mk_nation: sessionStorage.getItem('nation') || '',
+      mk_province: sessionStorage.getItem('province') || '',
+      mk_city: sessionStorage.getItem('city') || '',
+      mk_district: sessionStorage.getItem('district') || '',
+      mk_address: sessionStorage.getItem('address') || '',
+      id: ID || '',
+      bid: BID || '',
+      datam: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_begin: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_end: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+    }
+
+    if (window.GLOB.externalDatabase !== null) {
+      values.db = window.GLOB.externalDatabase
+    }
+
+    let options = fromJS(oriDetails).toJS()
+    let price = 0
+    let tax = 0
+
+    let lines = []
+    details.forEach(line => {
+      if (!line.productcode) return
+
+      let vals = [line.productcode, line.productname, line.spec, line.unit, line.bill_count, line.unitprice, line.amount_line, line.tax_classify_code, line.tax_classify_name, line.tax_rate, line.tax_amount, line.free_tax_mark || '', line.vat_special_management || '', line.invoice_lp || '', line.tax_item, line.tax_method, line.uuid]
+      let data_type = 'add'
+
+      price += line.amount_line * 100
+      tax += line.tax_amount * 100
+
+      if (options.length) {
+        options = options.filter(option => {
+          if (option.uuid === line.uuid) {
+            data_type = 'upt'
+            return false
+          }
+          return true
+        })
+      }
+
+      vals.push(data_type)
+
+      lines.push(vals)
+    })
+
+    let _total = (price - tax) / 100
+    price = price / 100
+    tax = tax / 100
+
+    if (options.length) {
+      options.forEach(line => {
+        let vals = [line.productcode, line.productname, line.spec, line.unit, line.bill_count, line.unitprice, line.amount_line, line.tax_classify_code, line.tax_classify_name, line.tax_rate, line.tax_amount, line.free_tax_mark || '', line.vat_special_management || '', line.invoice_lp || '', line.tax_item, line.tax_method, line.uuid, 'del']
+        lines.push(vals)
+      })
+    }
+
+    ex.reps.forEach(n => {
+      let key = n.toLowerCase()
+      if (values.hasOwnProperty(key)) {
+        exps.push({
+          key: n,
+          value: values[key]
+        })
+      }
+    })
+
+    exps.push({
+      key: 'account_id',
+      value: book.account_id || ''
+    }, {
+      key: 'account_year_id',
+      value: book.account_year_id || ''
+    }, {
+      key: 'account_code',
+      value: book.account_code || ''
+    }, {
+      key: 'account_year_code',
+      value: book.account_year_code || ''
+    }, {
+      key: 'invoice_type',
+      value: invoice_type
+    }, {
+      key: 'from_to_name',
+      value: from_to_name
+    }, {
+      key: 'from_to_tax_no',
+      value: from_to_tax_no
+    }, {
+      key: 'from_to_addr',
+      value: from_to_addr
+    }, {
+      key: 'from_to_tel',
+      value: from_to_tel
+    }, {
+      key: 'from_to_bank_name',
+      value: from_to_bank_name
+    }, {
+      key: 'from_to_account_no',
+      value: from_to_account_no
+    }, {
+      key: 'from_to_mob',
+      value: from_to_mob
+    }, {
+      key: 'from_to_email',
+      value: from_to_email
+    }, {
+      key: 'from_to_code',
+      value: from_to_code
+    }, {
+      key: 'orgname',
+      value: orgname
+    }, {
+      key: 'tax_no',
+      value: tax_no
+    }, {
+      key: 'addr',
+      value: addr
+    }, {
+      key: 'tel',
+      value: tel
+    }, {
+      key: 'bank_name',
+      value: bank_name
+    }, {
+      key: 'account_no',
+      value: account_no
+    }, {
+      key: 'remark',
+      value: remark
+    }, {
+      key: 'payee',
+      value: payee
+    }, {
+      key: 'reviewer',
+      value: reviewer
+    }, {
+      key: 'drawer',
+      value: drawer
+    }, {
+      key: 'io',
+      value: io
+    }, {
+      key: 'orgcode',
+      value: book.orgcode || ''
+    }, {
+      key: 'total_net_amount',
+      value: _total
+    }, {
+      key: 'total_tax',
+      value: tax
+    }, {
+      key: 'total_amount',
+      value: price
+    }, {
+      key: 'business_type',
+      value: business_type || config.wrap.business_type || ''
+    })
+
+    exps.push({
+      key: 'mk_excel_data',
+      value: lines
+    })
+
+    let md5_id = ''
+    if (window.GLOB.probation) {
+      md5_id = md5(ex.id + JSON.stringify(exps) + Math.floor(new Date().getTime() / 600000))
+      md5_id = moment().format('YYYYMMDDHHmmss') + md5_id.slice(-18)
+    }
+
+    return {
+      $backend: true,
+      $type: 's_TableData_InUpDe',
+      data: [{
+        id: ex.id,
+        menuname: btn.logLabel || '',
+        exps: exps,
+        md5_id: md5_id
+      }]
+    }
   }
 
   getBillMsg = () => {
@@ -844,142 +1052,153 @@
   callBackBill = (result) => {
     const { config, BID, ID } = this.state
 
-    let btn = config.billOutBtn
-    let lines = []
-    let pre = '@'
+    let param = null
 
-    let getDefaultSql = (obj, tb, bid, level) => {
-      let keys = []
-      let vals = []
-      let subObjs = []
-      let id = Utils.getuuid()
-      let tbName = pre + tb
-
-      delete obj.$$key
-
-      Object.keys(obj).forEach(key => {
-        let val = obj[key]
-        if (val === null || val === undefined) return
-        if (typeof(val) === 'object') {
-          if (Array.isArray(val)) {
-            val.forEach(item => {
-              if (typeof(item) !== 'object' || Array.isArray(item)) return
-              if (Object.keys(item).length > 0) {
+    if (window.backend && window.GLOB.CacheData.has('sql_' + config.uuid + 'billback')) {
+      param = this.getCallBackendParam(config.billOutBtn, result)
+    } else {
+      let btn = config.billOutBtn
+      let lines = []
+      let pre = '@'
+  
+      let getDefaultSql = (obj, tb, bid, level) => {
+        let keys = []
+        let vals = []
+        let subObjs = []
+        let id = Utils.getuuid()
+        let tbName = pre + tb
+  
+        delete obj.$$key
+  
+        Object.keys(obj).forEach(key => {
+          let val = obj[key]
+          if (val === null || val === undefined) return
+          if (typeof(val) === 'object') {
+            if (Array.isArray(val)) {
+              val.forEach(item => {
+                if (typeof(item) !== 'object' || Array.isArray(item)) return
+                if (Object.keys(item).length === 0) return
+  
+                Object.keys(item).forEach(k => {
+                  if (item[k] === null) {
+                    item[k] = ''
+                  }
+                })
                 item.$$key = tb + '_' + key
                 subObjs.push(item)
-              }
-            })
-          } else if (Object.keys(val).length > 0) {
-            val.$$key = tb + '_' + key
-            subObjs.push(val)
+              })
+            } else if (Object.keys(val).length > 0) {
+              val.$$key = tb + '_' + key
+              subObjs.push(val)
+            }
+          } else {
+            if (typeof(val) === 'string') {
+              val = val.replace(/'/ig, '"')
+            }
+            keys.push('[' + key + ']')
+            vals.push(`'${val}'`)
           }
-        } else {
-          if (typeof(val) === 'string') {
-            val = val.replace(/'/ig, '"')
-          }
-          keys.push('[' + key + ']')
-          vals.push(`'${val}'`)
-        }
-      })
-
-      keys = keys.join(',')
-      vals = vals.join(',')
-
-      lines.push({
-        table: md5(tb + keys),
-        insert: `Insert into ${tbName} (${keys ? keys + ',' : ''}[mk_level],[mk_id],[mk_bid])`,
-        select: `Select ${keys ? vals + ',' : ''}'${level}','${id}','${bid}'`
-      })
-
-      subObjs.forEach(item => {
-        getDefaultSql(item, item.$$key, id, level + 1)
-      })
-    }
-    
-    getDefaultSql(result, btn.cbTable, '', 1)
-
-    let lineMap = new Map()
-    lines.forEach(line => {
-      if (lineMap.has(line.table)) {
-        let _line = lineMap.get(line.table)
-        _line.selects.push(line.select)
-        lineMap.set(line.table, _line)
-      } else {
-        lineMap.set(line.table, {
-          table: line.table,
-          insert: line.insert,
-          selects: [line.select]
+        })
+  
+        keys = keys.join(',')
+        vals = vals.join(',')
+  
+        lines.push({
+          table: md5(tb + keys),
+          insert: `Insert into ${tbName} (${keys ? keys + ',' : ''}[mk_level],[mk_id],[mk_bid])`,
+          select: `Select ${keys ? vals + ',' : ''}'${level}','${id}','${bid}'`
+        })
+  
+        subObjs.forEach(item => {
+          getDefaultSql(item, item.$$key, id, level + 1)
         })
       }
-    })
-
-    let param = {
-      func: 'sPC_TableData_InUpDe',
-      BID: BID,
-      menuname: config.name + '(鍥炶皟)'
-    }
-
-    let callbacksql = this.getBackSql()
-    let _prevCustomScript = `${callbacksql}
-    `
-    let _backCustomScript = ''
-
-    btn.cbScripts.forEach(script => {
-      if (script.status === 'false') return
-
-      if (script.position === 'front') {
-        _prevCustomScript += `
-      /* 鑷畾涔夎剼鏈� */
-      ${script.sql}
-      `
-      } else {
-        _backCustomScript += `
-      /* 鑷畾涔夎剼鏈� */
-      ${script.sql}
-      `
+      
+      getDefaultSql(result, btn.cbTable, '', 1)
+  
+      let lineMap = new Map()
+      lines.forEach(line => {
+        if (lineMap.has(line.table)) {
+          let _line = lineMap.get(line.table)
+          _line.selects.push(line.select)
+          lineMap.set(line.table, _line)
+        } else {
+          lineMap.set(line.table, {
+            table: line.table,
+            insert: line.insert,
+            selects: [line.select]
+          })
+        }
+      })
+  
+      param = {
+        func: 'sPC_TableData_InUpDe',
+        BID: BID,
+        menuname: config.name + '(鍥炶皟)'
       }
-    })
-
-    _backCustomScript += `
-      aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
-
-    let sql = [...lineMap.values()].map(item => (`
-      ${item.insert}
-      ${item.selects.join(` union all
-      `)}
-    `))
-    sql = sql.join('')
-    sql = _prevCustomScript + sql
-    sql = sql + _backCustomScript
-
-    sql = sql.replace(/@ID@/ig, `'${ID || ''}'`)
-    sql = sql.replace(/@BID@/ig, `'${BID || ''}'`)
-    sql = sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
-    sql = sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
-    sql = sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
-    sql = sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
-    sql = sql.replace(/@lang@/ig, `'${sessionStorage.getItem('lang')}'`)
-    sql = sql.replace(/@typename@/ig, `'admin'`)
-
-    if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺
-      sql = sql.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, `'Y'`)
-    } else {
-      sql = sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`)
-    }
-
-    if (window.GLOB.debugger === true) {
-      console.info('%c' + config.name + '(鍥炶皟)', 'color: blue')
-      console.info(sql.replace(/\n\s{8}/ig, '\n'))
-    }
-
-    param.LText = sql
-    param.exec_type = window.GLOB.execType || 'y' // 鍚庡彴瑙g爜
-    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-    param.secretkey = Utils.encrypt('', param.timestamp)
-    param.LText = Utils.formatOptions(param.LText, param.exec_type)
-
-    if (window.GLOB.probation) {
-      param.s_debug_type = 'Y'
+  
+      let callbacksql = this.getBackSql()
+      let _prevCustomScript = `${callbacksql}
+      `
+      let _backCustomScript = ''
+  
+      btn.cbScripts.forEach(script => {
+        if (script.status === 'false') return
+  
+        if (script.position === 'front') {
+          _prevCustomScript += `
+        /* 鑷畾涔夎剼鏈� */
+        ${script.sql}
+        `
+        } else {
+          _backCustomScript += `
+        /* 鑷畾涔夎剼鏈� */
+        ${script.sql}
+        `
+        }
+      })
+  
+      _backCustomScript += `
+        aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
+  
+      let sql = [...lineMap.values()].map(item => (`
+        ${item.insert}
+        ${item.selects.join(` union all
+        `)}
+      `))
+      sql = sql.join('')
+      sql = _prevCustomScript + sql
+      sql = sql + _backCustomScript
+  
+      sql = sql.replace(/@ID@/ig, `'${ID || ''}'`)
+      sql = sql.replace(/@BID@/ig, `'${BID || ''}'`)
+      sql = sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
+      sql = sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
+      sql = sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
+      sql = sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+      sql = sql.replace(/@lang@/ig, `'${sessionStorage.getItem('lang')}'`)
+      sql = sql.replace(/@typename@/ig, `'admin'`)
+  
+      if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺
+        sql = sql.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, `'Y'`)
+      } else {
+        sql = sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`)
+      }
+  
+      if (window.GLOB.debugger === true) {
+        window.mkInfo('%c' + config.name + '(鍥炶皟)', 'color: blue')
+        window.mkInfo(sql.replace(/\n\s{8}/ig, '\n'))
+      }
+  
+      param.LText = sql
+      param.exec_type = window.GLOB.execType || 'y' // 鍚庡彴瑙g爜
+      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+      param.secretkey = Utils.encrypt('', param.timestamp)
+      param.LText = Utils.formatOptions(param.LText, param.exec_type)
+  
+      if (window.GLOB.probation) {
+        param.s_debug_type = 'Y'
+      }
     }
 
     Api.genericInterface(param).then(res => {
@@ -988,7 +1207,7 @@
       })
       if (res.status) {
         if (config.billOutBtn.reTabId) {
-          MKEmitter.emit('reloadMenuView', config.billOutBtn.reTabId, 'table')
+          MKEmitter.emit('reloadMenuView', config.billOutBtn.reTabId)
         }
         if (config.billOutBtn.syncComId) {
           MKEmitter.emit('reloadData', config.billOutBtn.syncComId)
@@ -1010,6 +1229,163 @@
     })
   }
 
+  getCallBackendParam = (btn, result) => {
+    const { book, BID, ID } = this.state
+
+    let lines = []
+    let tables = []
+
+    btn.verify.cbScripts.forEach(script => {
+      if (script.status === 'false') return
+
+      if (/\s#[a-z0-9_]+(\s|\()/ig.test(script.sql)) {
+        tables.push(...script.sql.match(/\s#[a-z0-9_]+(\s|\()/ig))
+      }
+    })
+
+    tables = tables.map(tb => tb.replace(/\s|\(/g, ''))
+
+    if (result.$ErrCode) {
+      delete result.$ErrCode
+      delete result.$ErrMesg
+    }
+
+    let getDefaultSql = (obj, tb, bid, level) => {
+      let vals = {}
+      let subObjs = []
+      let id = Utils.getuuid()
+
+      delete obj.$$key
+
+      Object.keys(obj).forEach(key => {
+        let val = obj[key]
+        if (val === null || val === undefined) return
+        if (typeof(val) === 'object') {
+          if (Array.isArray(val)) {
+            val.forEach(item => {
+              if (typeof(item) !== 'object' || Array.isArray(item)) return
+              if (Object.keys(item).length === 0) return
+
+              Object.keys(item).forEach(k => {
+                if (item[k] === null) {
+                  item[k] = ''
+                }
+              })
+              item.$$key = tb + '_' + key
+              subObjs.push(item)
+            })
+          } else if (Object.keys(val).length > 0) {
+            val.$$key = tb + '_' + key
+            subObjs.push(val)
+          }
+        } else {
+          if (typeof(val) === 'string') {
+            val = val.replace(/'/ig, '"')
+          } else {
+            val = val + ''
+          }
+          vals[key] = val
+        }
+      })
+
+      vals.mk_level = level
+      vals.mk_id = id
+      vals.mk_bid = bid
+
+      let isnew = true
+      lines.forEach(line => {
+        if (line.tb === tb) {
+          line.values.push(vals)
+          isnew = false
+        }
+      })
+      if (isnew) {
+        lines.push({
+          tb: tb,
+          type: tables.includes('#' + tb) ? '01' : '02',
+          values: [vals]
+        })
+      }
+
+      subObjs.forEach(item => {
+        getDefaultSql(item, item.$$key, id, level + 1)
+      })
+    }
+    
+    getDefaultSql(result, btn.cbTable, '', 1)
+
+    let ex = window.GLOB.CacheData.get('sql_' + btn.uuid + 'billback')
+    let exps = []
+
+    let values = {
+      time_id: Utils.getguid(),
+      roleid: sessionStorage.getItem('role_id') || '',
+      mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
+      mk_organization: sessionStorage.getItem('organization') || '',
+      mk_user_type: sessionStorage.getItem('mk_user_type') || '',
+      mk_nation: sessionStorage.getItem('nation') || '',
+      mk_province: sessionStorage.getItem('province') || '',
+      mk_city: sessionStorage.getItem('city') || '',
+      mk_district: sessionStorage.getItem('district') || '',
+      mk_address: sessionStorage.getItem('address') || '',
+      id: ID || '',
+      bid: BID || '',
+      datam: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_begin: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_end: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+    }
+
+    if (window.GLOB.externalDatabase !== null) {
+      values.db = window.GLOB.externalDatabase
+    }
+
+    ex.reps.forEach(n => {
+      let key = n.toLowerCase()
+      if (values.hasOwnProperty(key)) {
+        exps.push({
+          key: n,
+          value: values[key]
+        })
+      }
+    })
+
+    exps.push({
+      key: 'account_id',
+      value: book.account_id || ''
+    }, {
+      key: 'account_year_id',
+      value: book.account_year_id || ''
+    }, {
+      key: 'account_code',
+      value: book.account_code || ''
+    }, {
+      key: 'account_year_code',
+      value: book.account_year_code || ''
+    })
+
+    exps.push({
+      key: 'mk_outer_params',  // 鍥炶皟鑴氭湰鐨勬暟鎹浛鎹�
+      value: lines
+    })
+
+    let md5_id = ''
+    if (window.GLOB.probation) {
+      md5_id = md5('back_' + btn.uuid + JSON.stringify(exps) + Math.floor(new Date().getTime() / 600000))
+      md5_id = moment().format('YYYYMMDDHHmmss') + md5_id.slice(-18)
+    }
+
+    return {
+      $backend: true,
+      $type: 's_TableData_InUpDe',
+      data: [{
+        id: ex.id,
+        menuname: btn.logLabel + '(鍥炶皟)',
+        exps: exps,
+        md5_id: md5_id
+      }]
+    }
+  }
+
   getBackSql = () => {
     const { book, BID } = this.state
 
diff --git a/src/tabviews/custom/components/module/invoice/index.scss b/src/tabviews/custom/components/module/invoice/index.scss
index 1ec31ae..dcae8ad 100644
--- a/src/tabviews/custom/components/module/invoice/index.scss
+++ b/src/tabviews/custom/components/module/invoice/index.scss
@@ -23,6 +23,8 @@
       margin-left: 0px;
       padding: 0px;
       box-shadow: none;
+      position: relative;
+      z-index: 1;
     }
     .mk-back::after {
       display: none;
diff --git a/src/tabviews/custom/components/module/voucher/index.jsx b/src/tabviews/custom/components/module/voucher/index.jsx
index 0fd7ac5..6e9f250 100644
--- a/src/tabviews/custom/components/module/voucher/index.jsx
+++ b/src/tabviews/custom/components/module/voucher/index.jsx
@@ -492,11 +492,11 @@
     }
 
     if (tip) {
-      const _this = this
+      const that = this
       confirm({
         content: tip + '纭瑕佷繚瀛樺悧锛�',
         onOk() {
-          _this.voucherSave(list, t)
+          that.voucherSave(list, t)
         },
         onCancel() {}
       })
@@ -700,7 +700,7 @@
       }
 
       if (tabId) {
-        MKEmitter.emit('reloadMenuView', tabId, 'table')
+        MKEmitter.emit('reloadMenuView', tabId)
       }
     })
   }
@@ -953,7 +953,7 @@
       }
 
       if (tabId) {
-        MKEmitter.emit('reloadMenuView', tabId, 'table')
+        MKEmitter.emit('reloadMenuView', tabId)
       }
     })
   }
diff --git a/src/tabviews/custom/components/module/voucher/resetAttach/addAttach/fileupload/index.jsx b/src/tabviews/custom/components/module/voucher/resetAttach/addAttach/fileupload/index.jsx
index 627a699..03c3d0f 100644
--- a/src/tabviews/custom/components/module/voucher/resetAttach/addAttach/fileupload/index.jsx
+++ b/src/tabviews/custom/components/module/voucher/resetAttach/addAttach/fileupload/index.jsx
@@ -1,10 +1,9 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import moment from 'moment'
 import { Upload, Button, Progress, notification } from 'antd'
 import { UploadOutlined } from '@ant-design/icons'
-import SparkMD5 from 'spark-md5'
+
 import Api from '@/api'
 import './index.scss'
 
@@ -90,54 +89,6 @@
     })
   }
 
-  shardupload = (param, name) => {
-    let form = new FormData()
-
-    form.append('file', param.binary)
-    form.append('fileMd5', param.fileMd5)
-    form.append('shardingMd5', param.fileMd5)
-    form.append('baseDomain', window.GLOB.baseurl)
-    form.append('rootPath', 'Content/images/upload/')
-    form.append('fileName', param.fileName)
-    form.append('fileExt', param.fileType)
-    form.append('shardingCnt', 1)
-    form.append('shardingNo', 1)
-    form.append('LoginUID', sessionStorage.getItem('LoginUID') || '')
-    form.append('UserID', sessionStorage.getItem('UserID') || '')
-
-    Api.getLargeFileUpload(form).then(res => {
-      if (res.status) {
-        if (res.urlPath) {
-          this.onUpdate(res.urlPath, name)
-        } else {
-          this.onFail()
-        }
-        this.setState({
-          percent: 100
-        }, () => {
-          setTimeout(() => {
-            this.setState({
-              showprogress: false,
-              percent: 0
-            })
-          }, 200)
-        })
-      } else {
-        this.onFail(res.message)
-      }
-    })
-  }
-
-  getuuid = () => {
-    let uuid = []
-    let _options = '0123456789abcdefghigklmnopqrstuv'
-    for (let i = 0; i < 19; i++) {
-      uuid.push(_options.substr(Math.floor(Math.random() * 0x20), 1))
-    }
-    uuid = uuid.join('')
-    return uuid
-  }
-
   beforeUpload = (file) => {
     const { accepts, maxSize } = this.state
 
@@ -172,49 +123,31 @@
       percent: 0
     })
 
-    // 鍏煎鎬х殑澶勭悊
-    let spark = new SparkMD5.ArrayBuffer()         // 瀵筧rrayBuffer鏁版嵁杩涜md5鍔犲瘑锛屼骇鐢熶竴涓猰d5瀛楃涓�
-    let totalFileReader = new FileReader()         // 鐢ㄤ簬璁$畻鍑烘�绘枃浠剁殑fileMd5
-    let param = {}
+    let form = new FormData()
 
-    param.fileName = file.name.replace(/\.{1}[^.]*$/ig, '')  // 鏂囦欢鍚嶏紙鍘婚櫎鍚庣紑鍚嶏級
-    param.fileType = file.name.replace(/^.*\.{1}/ig, '')     // 鏂囦欢绫诲瀷
+    form.append('file', file)
 
-    if (!/^[A-Za-z0-9]+$/.test(param.fileName)) {            // 鏂囦欢鍚嶇О鍚湁鑻辨枃鍙婃暟瀛椾箣澶栧瓧绗︽椂锛屽悕绉扮郴缁熺敓鎴�
-      param.fileName = moment().format('YYYYMMDDHHmmss') + this.getuuid()
-    }
-
-    totalFileReader.readAsArrayBuffer(file)
-    totalFileReader.onload = (e) => {   // 瀵规暣涓猼otalFile鐢熸垚md5
-      spark.append(e.target.result)
-      param.fileMd5 = spark.end()       // 璁$畻鏁翠釜鏂囦欢鐨刦ileMd5
-      param.binary = file
-
-      let _param = new FormData()
-      _param.append('fileMd5', param.fileMd5)
-      
-      Api.getFilePreUpload(_param).then(res => {
-        if (res.status && res.urlPath) {
+    Api.getFileUpload(form).then(res => {
+      if (res.status) {
+        if (res.urlPath) {
           this.onUpdate(res.urlPath, file.name)
-          this.setState({
-            percent: 100
-          }, () => {
-            setTimeout(() => {
-              this.setState({
-                showprogress: false,
-                percent: 0
-              })
-            }, 200)
-          })
         } else {
-          this.shardupload(param, file.name)
+          this.onFail()
         }
-      })
-    }
-
-    totalFileReader.onerror = () => {
-      this.onFail('鏂囦欢璇诲彇澶辫触锛�')
-    }
+        this.setState({
+          percent: 100
+        }, () => {
+          setTimeout(() => {
+            this.setState({
+              showprogress: false,
+              percent: 0
+            })
+          }, 200)
+        })
+      } else {
+        this.onFail(res.message)
+      }
+    })
 
     return false
   }
diff --git a/src/tabviews/custom/components/share/braftContent/index.scss b/src/tabviews/custom/components/share/braftContent/index.scss
index f2f0d33..bf6b2f9 100644
--- a/src/tabviews/custom/components/share/braftContent/index.scss
+++ b/src/tabviews/custom/components/share/braftContent/index.scss
@@ -1,14 +1,32 @@
 .braft-content {
+  padding: 15px;
   .media-wrap {
     max-width: 100%;
   }
   img {
     max-width: 100%;
   }
+  p {
+    margin-bottom: 0px!important;
+    min-height: 18px;
+  }
+  br {
+    content: "";
+    display: block;
+    height: 18px;
+  }
+  hr {
+    height: 15px;
+    border-top: 1px solid rgba(0, 0, 0, 0.1);
+    margin-top: 15px;
+  }
   video {
     max-width: 100%;
     width: 100%;
   }
+  table + p, hr + p {
+    min-height: 0px;
+  }
   table {
     width: 100%;
     border-collapse: collapse;
diff --git a/src/tabviews/custom/components/share/normalTable/index.jsx b/src/tabviews/custom/components/share/normalTable/index.jsx
index 6ef27dd..b01e03d 100644
--- a/src/tabviews/custom/components/share/normalTable/index.jsx
+++ b/src/tabviews/custom/components/share/normalTable/index.jsx
@@ -236,6 +236,9 @@
         }
         if (col.format === 'percent') {
           content = content * 100
+          if (!col.round) {
+            content = +content.toFixed(2)
+          }
         } else if (col.format === 'abs') {
           content = Math.abs(content)
         }
@@ -428,7 +431,7 @@
               content = ''
             }
           } catch (e) {
-            console.info(content)
+            window.mkInfo(content)
             console.warn(e)
             content = ''
           }
@@ -811,15 +814,27 @@
     this.props.refreshdata({pageIndex})
   }
 
-  mkCheckTopLine = (menuId, id, type) => {
+  mkCheckTopLine = (menuId, id, selected) => {
     const { MenuID, data, setting } = this.props
 
-    if (MenuID !== menuId || !data || data.length === 0) return
+    if (MenuID !== menuId) return
+    if (!data || data.length === 0) {
+      MKEmitter.emit('resetSelectLine', menuId, '', '')
+      return
+    }
 
-    if (type === 'sign') {
-      let index = ''
-      let keys = []
-      let items = []
+    let index = -1
+    let keys = []
+    let items = []
+
+    if (id) {
+      index = data.findIndex(item => item.$$uuid === id && !item.$disabled)
+    }
+    
+    if (index !== -1) {
+      keys = [index]
+      items = [data[index]]
+    } else if (selected === 'sign') {
       data.forEach((item, i) => {
         if (!item.$disabled && item.selected === 'true') {
           items.push(item)
@@ -827,33 +842,25 @@
           index = i
         }
       })
-  
-      this.changedata(index)
-      this.setState({ selectedRowKeys: keys, activeIndex: index })
-      this.props.chgSelectData(items)
-
-      if (setting.$hasSyncModule) {
-        MKEmitter.emit('syncBalconyData', MenuID, items, data.length === keys.length)
+    } else if (selected !== 'false') {
+      if (!data[0].$disabled) {
+        index = 0
+        keys = [index]
+        items = [data[index]]
       }
+    }
+
+    if (index === -1) {
+      MKEmitter.emit('resetSelectLine', menuId, '', '')
       return
     }
 
-    let index = 0
-    if (id) {
-      index = data.findIndex(item => item.$$uuid === id)
-      if (index === -1) {
-        index = 0
-      }
-    }
-
-    if (data[index].$disabled) return
-
     this.changedata(index)
-    this.setState({ selectedRowKeys: [index], activeIndex: index })
-    this.props.chgSelectData([data[index]])
+    this.setState({ selectedRowKeys: keys, activeIndex: index })
+    this.props.chgSelectData(items)
 
     if (setting.$hasSyncModule) {
-      MKEmitter.emit('syncBalconyData', MenuID, [data[index]], data.length === 1)
+      MKEmitter.emit('syncBalconyData', MenuID, items, data.length === keys.length)
     }
   }
 
@@ -1028,22 +1035,9 @@
       if (setting.$hasSyncModule) {
         MKEmitter.emit('syncBalconyData', MenuID, selects, data.length === selects.length)
       }
-    } else if (type === 'false') {
-      this.setState({
-        selectedRowKeys: [],
-        activeIndex: null,
-        pickup: false
-      })
-    } else if (type === 'repage') {
-      this.setState({
-        pageIndex: Index,
-        selectedRowKeys: [],
-        activeIndex: null,
-        pickup: false
-      })
     } else {
       this.setState({
-        pageIndex: 1,
+        pageIndex: type === 'false' ? this.state.pageIndex : 1,
         selectedRowKeys: [],
         activeIndex: null,
         pickup: false
diff --git a/src/tabviews/custom/components/share/tabtransfer/index.jsx b/src/tabviews/custom/components/share/tabtransfer/index.jsx
index 34289a8..0a67c42 100644
--- a/src/tabviews/custom/components/share/tabtransfer/index.jsx
+++ b/src/tabviews/custom/components/share/tabtransfer/index.jsx
@@ -50,9 +50,16 @@
   UNSAFE_componentWillMount () {
     let _config = fromJS(this.props.config).toJS()
 
+    let BID = ''
+    let BData = window.GLOB.CacheData.get(_config.$pageId)
+
+    if (BData) {
+      BID = BData.$BID || ''
+    }
+
     let params = []
     if (_config.type !== 'group') {
-      _config.components = this.formatSetting(_config.components, params)
+      _config.components = this.formatSetting(_config.components, params, BID)
     } else {
       let delay = 110
       _config.components.forEach(item => {
@@ -68,17 +75,17 @@
       config: _config
     }, () => {
       if (params.length > 0) {
-        this.loadmaindata(params)
+        this.loadmaindata(params, BID)
       }
     })
   }
 
-  formatSetting = (components, params) => {
+  formatSetting = (components, params, BID) => {
     let delay = 110
     return components.map(item => {
       if (item.type === 'tabs') return item
       if (item.type === 'group') {
-        item.components = this.formatSetting(item.components, params)
+        item.components = this.formatSetting(item.components, params, BID)
         return item
       }
 
@@ -102,7 +109,18 @@
           item.setting.sync = 'false'
           item.setting.onload = 'false'
         } else {
-          params.push(getStructDefaultParam(item, searchlist, params.length === 0))
+          let backend = false
+          if (window.backend && params.length === 0 && window.GLOB.CacheData.has('sql_' + item.uuid)) {
+            backend = true
+          } else if (window.backend && params[0] && params[0].exps) {
+            backend = true
+          }
+
+          if (backend && !window.GLOB.CacheData.has('sql_' + item.uuid)) {
+            item.setting.sync = 'false'
+          } else {
+            params.push(getStructDefaultParam(item, searchlist, params.length === 0, BID))
+          }
         }
       }
       
@@ -116,19 +134,17 @@
   /**
    * @description 涓昏〃鏁版嵁鍔犺浇
    */ 
-  loadmaindata = (params) => {
+  loadmaindata = (params, BID) => {
     const { config } = this.state
-    let BID = ''
-    let BData = window.GLOB.CacheData.get(config.$pageId)
-
-    if (BData) {
-      BID = BData.$BID || ''
-    }
 
     let param = getStructuredParams(params, config, BID)
 
     if (config.$cache && config.$time) {
-      Api.getLCacheConfig(params[0].uuid, config.$time, BID).then(res => {
+      let uuid = params[0].uuid || ''
+      if (params[0].id) {
+        uuid = window.GLOB.CacheData.get('first_' + params[0].id) || ''
+      }
+      Api.getLCacheConfig(uuid, config.$time, BID).then(res => {
         if (!res.valid) {
           this.getMainData(param, params, config.uuid)
         }
@@ -156,11 +172,11 @@
         }
 
         params.forEach((item) => {
-          let _data = result[item.name] || ''
+          let _data = result[item.dataName] || ''
           if (_data && !Array.isArray(_data)) {
             _data = [_data]
           }
-          window.GLOB.SyncData.set(item.name, _data)
+          window.GLOB.SyncData.set(item.dataName, _data)
         })
 
         MKEmitter.emit('transferSyncData', tabId)
@@ -386,7 +402,7 @@
     }
 
     return (
-      <Row className="component-wrap" id={'anchor' + config.uuid} gutter={8}>{this.getComponents(config.components)}</Row>
+      <Row className="component-wrap" id={'anchor' + config.uuid}>{this.getComponents(config.components)}</Row>
     )
   }
 }
diff --git a/src/tabviews/custom/components/table/base-table/index.jsx b/src/tabviews/custom/components/table/base-table/index.jsx
index 10d0453..5b5f0f3 100644
--- a/src/tabviews/custom/components/table/base-table/index.jsx
+++ b/src/tabviews/custom/components/table/base-table/index.jsx
@@ -67,8 +67,6 @@
 
     if (setting.selected !== 'always' && setting.selected !== 'init' && setting.selected !== 'sign') {
       setting.selected = 'false'
-    } else {
-      setting.orisel = true
     }
 
     _config.style = _config.style || {}
@@ -85,7 +83,7 @@
     }, () => {
       if (_config.setting.onload === 'true') {
         setTimeout(() => {
-          this.loadmaindata()
+          this.loadData()
           this.getStatFieldsValue()
         }, _config.setting.delay || 0)
       }
@@ -94,10 +92,8 @@
 
   /**
    * @description 涓昏〃鏁版嵁鍔犺浇
-   * @param { Boolean } reset  琛ㄦ牸鏄惁閲嶇疆
-   * @param { String }  repage 琛ㄦ牸鏄惁閲嶇疆椤电爜
    */
-  async loadmaindata (reset, repage, id) {
+  async loadData (reset, repage, id) {
     const { setting, config, search, orderBy, BID, pageIndex, pageSize, BData } = this.state
 
     if (setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
@@ -110,9 +106,6 @@
       
       MKEmitter.emit('resetSelectLine', config.uuid, '', '') // 骞挎挱鏁版嵁鍒囨崲
       reset && MKEmitter.emit('resetTable', config.uuid, 'true') // 鍒楄〃閲嶇疆
-      // if (setting.$hasSyncModule) {
-      //   MKEmitter.emit('syncBalconyData', config.uuid, [], false)
-      // }
 
       this.requestId = ''
       return
@@ -147,38 +140,12 @@
     if (result.status) {
       if (result.$requestId && this.requestId !== result.$requestId) return
 
-      if (repage === 'false' && result.data && result.data.length === 0 && result.total > 0 && pageIndex > 1) {
-        let _pageIndex = Math.ceil(result.total / pageSize)
-
-        if (_pageIndex < pageIndex) {
-          MKEmitter.emit('resetTable', config.uuid, 'repage', _pageIndex)
-          this.setState({
-            pageIndex: _pageIndex,
-            data: [],
-            selectedData: [],
-            total: result.total
-          }, () => {
-            this.loadmaindata()
-          })
-          return
-        }
+      if (repage === 'false' && result.data.length === 0 && pageIndex > 1) {
+        this.reloadIndex()
+        return
       }
 
-      if ((setting.selected !== 'false' || (setting.orisel && id)) && result.data && result.data.length > 0) {
-        setTimeout(() => {
-          MKEmitter.emit('mkCheckTopLine', config.uuid, id, setting.selected)
-        }, 200)
-        if (setting.selected === 'init') {
-          this.setState({setting: {...setting, selected: 'false'}})
-        }
-      } else {
-        MKEmitter.emit('resetSelectLine', config.uuid, '', '') // 骞挎挱鏁版嵁鍒囨崲
-        // if (setting.$hasSyncModule) {
-        //   MKEmitter.emit('syncBalconyData', config.uuid, [], false)
-        // }
-      }
-      
-      reset && MKEmitter.emit('resetTable', config.uuid, repage) // 鍒楄〃閲嶇疆
+      reset && MKEmitter.emit('resetTable', config.uuid, repage || '') // 鍒楄〃閲嶇疆
 
       let start = 1
       if (setting.laypage) {
@@ -214,12 +181,24 @@
         total = data[data.length - 1].mk_total || 0
       }
 
+      if (data.length && (id || setting.selected !== 'false')) {
+        setTimeout(() => {
+          MKEmitter.emit('mkCheckTopLine', config.uuid, id, setting.selected)
+        }, 200)
+      } else {
+        MKEmitter.emit('resetSelectLine', config.uuid, '', '') // 骞挎挱鏁版嵁鍒囨崲
+      }
+
       this.setState({
         data: data,
         selectedData: [],
         total: total,
         loading: false
       })
+
+      if (setting.selected === 'init') {
+        this.setState({setting: {...setting, selected: 'false'}})
+      }
 
       if (config.autoMatic) {
         if (result.data && result.data.length > 0) {
@@ -249,11 +228,6 @@
   async loadLinedata (id, position) {
     const { setting, config, search, orderBy, BID, pageIndex, pageSize, BData } = this.state
 
-    if (config.forbidLine) {
-      this.reloadtable()
-      return
-    }
-
     let searches = fromJS(search).toJS()
     if (config.setting.useMSearch) { // 涓昏〃鎼滅储鏉′欢
       let mainSearch = window.GLOB.SearchBox.get(config.$searchId) || []
@@ -275,7 +249,7 @@
     let result = await Api.genericInterface(param)
     if (result.status) {
       if (position === 'line_grid' && (!result.data || !result.data[0])) {
-        this.loadmaindata(true, 'false')
+        this.reloadIndex()
         return
       }
 
@@ -287,6 +261,12 @@
         _data.$$uuid = _data[setting.primaryKey] || ''
         _data.$$BID = BID || ''
         _data.$$BData = BData || ''
+
+        if (setting.controlField) {
+          if (setting.controlVal.includes(_data[setting.controlField] + '')) {
+            _data.$disabled = true
+          }
+        }
 
         if (config.absFields) {
           config.absFields.forEach(f => {
@@ -439,13 +419,25 @@
    * 鍚湁鍒濆涓嶅姞杞界殑椤甸潰锛屼慨鏀硅缃�
    */
   refreshbysearch = (searches) => {
-    const { config} = this.state
+    const { config, BID } = this.state
+
+    if (config.setting.supModule && !BID) {
+      notification.warning({
+        top: 92,
+        message: window.GLOB.dict['sup_key_req'] || '闇�瑕佷笂绾т富閿�硷紒',
+        duration: 5
+      })
+      this.setState({
+        search: searches
+      })
+      return
+    }
 
     this.setState({
       pageIndex: 1,
       search: searches
     }, () => {
-      this.loadmaindata(true, 'true')
+      this.loadData(true, 'true')
       this.getStatFieldsValue()
     })
 
@@ -463,7 +455,7 @@
       this.setState({
         pageIndex: pagination.pageIndex
       }, () => {
-        this.loadmaindata()
+        this.loadData()
       })
     } else {
       if (sorter.order) {
@@ -479,25 +471,8 @@
         pageSize: pagination.pageSize,
         orderBy: (sorter.field && sorter.order) ? `${sorter.field} ${sorter.order}` : ''
       }, () => {
-        this.loadmaindata()
+        this.loadData()
       })
-    }
-  }
-
-  /**
-   * @description 琛ㄦ牸鍒锋柊
-   */
-  reloadtable = (btn, id) => {
-    if (!btn || btn.resetPageIndex !== 'false') {
-      this.setState({
-        pageIndex: 1
-      }, () => {
-        this.loadmaindata(true, 'true', id)
-        this.getStatFieldsValue()
-      })
-    } else {
-      this.loadmaindata(true, 'false', id)
-      this.getStatFieldsValue()
     }
   }
 
@@ -532,7 +507,10 @@
     if (config.uuid !== menuId) return
 
     if (!id) {
-      this.reloadtable()
+      this.reloadIndex()
+    } else if (config.forbidLine) {
+      this.loadData(true, 'false', id)
+      this.getStatFieldsValue()
     } else {
       this.loadLinedata(id)
     }
@@ -549,7 +527,7 @@
         BData: data
       }, () => {
         if (!setting.checkBid) {
-          this.loadmaindata(true, 'true')
+          this.loadData(true, 'true')
           this.getStatFieldsValue()
         }
       })
@@ -558,25 +536,32 @@
 
   /**
    * @description 鎸夐挳鎵ц瀹屾垚鍚庨〉闈㈠埛鏂�
-   * @param {*} menuId     // 鑿滃崟Id
-   * @param {*} position   // 鍒锋柊浣嶇疆
-   * @param {*} btn        // 鎵ц鐨勬寜閽�
    */
   refreshByButtonResult = (menuId, position, btn, id, lines) => {
     const { config, BID } = this.state
 
     if (config.uuid !== menuId) return
 
+    let _id = config.wrap.selected === 'always' ? (id || '') : ''
     if (position === 'line' || position === 'line_grid') {
       if (lines && lines.length === 1) {
-        this.loadLinedata(lines[0].$$uuid, position)
+        if (config.forbidLine) {
+          this.loadData(true, 'false', lines[0].$$uuid)
+          this.getStatFieldsValue()
+        } else {
+          this.loadLinedata(lines[0].$$uuid, position)
+        }
       } else {
-        this.reloadtable(btn, id)
+        this.loadData(true, 'false', _id)
+        this.getStatFieldsValue()
       }
     } else if (['mainline', 'maingrid', 'popclose'].includes(position) && config.setting.supModule) {
       MKEmitter.emit('reloadData', config.setting.supModule, position === 'maingrid' ? '' : BID)
+    } else if (btn.resetPageIndex !== 'false') {
+      this.reloadIndex()
     } else {
-      this.reloadtable(btn, id)
+      this.loadData(true, 'false', _id)
+      this.getStatFieldsValue()
     }
   }
 
@@ -584,9 +569,16 @@
     const { config } = this.state
 
     if (config.$searchId !== searchId) return
-    
-    this.setState({pageIndex: 1}, () => {
-      this.reloadtable()
+
+    this.reloadIndex()
+  }
+
+  reloadIndex = () => {
+    this.setState({
+      pageIndex: 1
+    }, () => {
+      this.loadData(true, 'true')
+      this.getStatFieldsValue()
     })
   }
 
diff --git a/src/tabviews/custom/components/table/edit-table/index.jsx b/src/tabviews/custom/components/table/edit-table/index.jsx
index fcb0aa5..c3cdecd 100644
--- a/src/tabviews/custom/components/table/edit-table/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/index.jsx
@@ -1,6 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
+import { notification } from 'antd'
 import moment from 'moment'
 
 import Api from '@/api'
@@ -224,7 +225,7 @@
     }, () => {
       if (_config.setting.onload === 'true') {
         setTimeout(() => {
-          this.loadmaindata()
+          this.loadData()
         }, _config.setting.delay || 0)
       }
     })
@@ -420,10 +421,8 @@
 
   /**
    * @description 涓昏〃鏁版嵁鍔犺浇
-   * @param { Boolean } reset  琛ㄦ牸鏄惁閲嶇疆
-   * @param { String }  repage 琛ㄦ牸鏄惁閲嶇疆椤电爜
    */
-  async loadmaindata (reset, repage) {
+  async loadData (reset, repage) {
     const { setting, config, search, orderBy, BID, pageIndex, pageSize, BData } = this.state
 
     if (setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
@@ -529,11 +528,6 @@
    */ 
   async loadLinedata (id, position) {
     const { setting, config, search, orderBy, BID, pageIndex, pageSize, BData } = this.state
-
-    if (config.forbidLine) {
-      this.reloadtable()
-      return
-    }
     
     let searches = fromJS(search).toJS()
     if (config.setting.useMSearch) { // 涓昏〃鎼滅储鏉′欢
@@ -556,7 +550,7 @@
     let result = await Api.genericInterface(param)
     if (result.status) {
       if (position === 'line_grid' && (!result.data || !result.data[0])) {
-        this.loadmaindata(true, 'false')
+        this.reloadIndex()
         return
       }
 
@@ -633,11 +627,25 @@
    * 鍚湁鍒濆涓嶅姞杞界殑椤甸潰锛屼慨鏀硅缃�
    */
   refreshbysearch = (searches) => {
+    const { setting, BID } = this.state
+
+    if (setting.supModule && !BID) {
+      notification.warning({
+        top: 92,
+        message: window.GLOB.dict['sup_key_req'] || '闇�瑕佷笂绾т富閿�硷紒',
+        duration: 5
+      })
+      this.setState({
+        search: searches
+      })
+      return
+    }
+
     this.setState({
       pageIndex: 1,
       search: searches
     }, () => {
-      this.loadmaindata(true, 'true')
+      this.loadData(true, 'true')
     })
   }
 
@@ -658,23 +666,19 @@
       pageSize: pagination.pageSize,
       orderBy: (sorter.field && sorter.order) ? `${sorter.field} ${sorter.order}` : ''
     }, () => {
-      this.loadmaindata()
+      this.loadData()
     })
   }
 
   /**
    * @description 琛ㄦ牸鍒锋柊
    */
-  reloadtable = (btn) => {
-    if (!btn || btn.resetPageIndex !== 'false') {
-      this.setState({
-        pageIndex: 1
-      }, () => {
-        this.loadmaindata(true, 'true')
-      })
-    } else {
-      this.loadmaindata(true, 'false')
-    }
+  reloadIndex = () => {
+    this.setState({
+      pageIndex: 1
+    }, () => {
+      this.loadData(true, 'true')
+    })
   }
 
   /**
@@ -708,7 +712,9 @@
     if (config.uuid !== menuId) return
 
     if (!id) {
-      this.reloadtable()
+      this.reloadIndex()
+    } else if (config.forbidLine) {
+      this.loadData(true, 'false')
     } else {
       this.loadLinedata(id)
     }
@@ -730,7 +736,7 @@
       }, () => {
         if (!setting.checkBid) {
           setTimeout(() => {
-            this.loadmaindata(true, 'true')
+            this.loadData(true, 'true')
           }, setting.delay || 0)
         }
       })
@@ -750,14 +756,20 @@
 
     if (position === 'line' || position === 'line_grid') {
       if (lines && lines.length === 1) {
-        this.loadLinedata(lines[0].$$uuid, position)
+        if (config.forbidLine) {
+          this.loadData(true, 'false')
+        } else {
+          this.loadLinedata(lines[0].$$uuid, position)
+        }
       } else {
-        this.reloadtable(btn)
+        this.loadData(true, 'false')
       }
     } else if (['mainline', 'maingrid', 'popclose'].includes(position) && config.setting.supModule) {
       MKEmitter.emit('reloadData', config.setting.supModule, position === 'maingrid' ? '' : BID)
+    } else if (btn.resetPageIndex !== 'false') {
+      this.reloadIndex()
     } else {
-      this.reloadtable(btn)
+      this.loadData(true, 'false')
     }
   }
 
@@ -790,9 +802,7 @@
 
     if (config.$searchId !== searchId) return
     
-    this.setState({pageIndex: 1}, () => {
-      this.reloadtable()
-    })
+    this.reloadIndex()
   }
 
   shouldComponentUpdate (nextProps, nextState) {
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 9529a8e..03add13 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
@@ -586,19 +586,34 @@
     const { config } = this.props
     const { value, err } = this.state
 
-    return (
-      <InputNumber
-        title={err}
-        className={err ? 'has-error' : ''}
-        ref={ref => this.node = ref}
-        precision={config.decimal || 0}
-        value={value}
-        onChange={(value) => this.onChange(value)}
-        onPressEnter={this.enterPress}
-        onFocus={this.onFocus}
-        onBlur={this.onBlur}
-      />
-    )
+    if (!config.decimal && config.decimal !== 0) {
+      return (
+        <InputNumber
+          title={err}
+          className={err ? 'has-error' : ''}
+          ref={ref => this.node = ref}
+          value={value}
+          onChange={(value) => this.onChange(value)}
+          onPressEnter={this.enterPress}
+          onFocus={this.onFocus}
+          onBlur={this.onBlur}
+        />
+      )
+    } else {
+      return (
+        <InputNumber
+          title={err}
+          className={err ? 'has-error' : ''}
+          ref={ref => this.node = ref}
+          precision={config.decimal}
+          value={value}
+          onChange={(value) => this.onChange(value)}
+          onPressEnter={this.enterPress}
+          onFocus={this.onFocus}
+          onBlur={this.onBlur}
+        />
+      )
+    }
   }
 }
 
@@ -862,6 +877,9 @@
         }
         if (col.format === 'percent') {
           content = content * 100
+          if (!col.round) {
+            content = +content.toFixed(2)
+          }
         } else if (col.format === 'abs') {
           content = Math.abs(content)
         }
@@ -956,7 +974,7 @@
             // eslint-disable-next-line
             content = eval(content)
           } catch (e) {
-            console.info(content)
+            window.mkInfo(content)
             console.warn(e)
             content = ''
           }
@@ -1192,6 +1210,9 @@
           }
           if (col.format === 'percent') {
             content = content * 100
+            if (!col.round) {
+              content = +content.toFixed(2)
+            }
           } else if (col.format === 'abs') {
             content = Math.abs(content)
           }
@@ -1275,7 +1296,7 @@
             // eslint-disable-next-line
             content = eval(content)
           } catch (e) {
-            console.info(content)
+            window.mkInfo(content)
             console.warn(e)
             content = ''
           }
@@ -1470,6 +1491,9 @@
         } else {
           _item.datatype = item.datatype
         }
+        if (_item.type === 'number' && item.type === 'number') {
+          _item.decimal = item.decimal || 0
+        }
 
         forms.push(_item)
       } else {
@@ -1515,7 +1539,11 @@
       deForms: hasBid ? deForms : null
     }, () => {
       if (deForms.length > 0 && (!hasBid || BID)) {
-        this.improveActionForm(deForms, BID)
+        if (window.backend && window.GLOB.CacheData.has('sql_' + deForms[0].uuid)) {
+          this.improveBackActionForm(deForms, BID)
+        } else {
+          this.improveActionForm(deForms, BID)
+        }
       }
     })
   }
@@ -1529,7 +1557,11 @@
     const { deForms } = this.state
 
     if (deForms && nextProps.BID !== BID) {
-      this.improveActionForm(deForms, nextProps.BID)
+      if (window.backend && window.GLOB.CacheData.has('sql_' + deForms[0].uuid)) {
+        this.improveBackActionForm(deForms, nextProps.BID)
+      } else {
+        this.improveActionForm(deForms, nextProps.BID)
+      }
     }
     if (parCtrl && !is(fromJS(this.props.columns), fromJS(nextProps.columns))) {
       let getColumns = (cols, sk) => {
@@ -1892,7 +1924,7 @@
         sql = sql.replace(/@BID@/ig, `'${BID}'`)
 
         if (debug) {
-          console.info(sql)
+          window.mkInfo(sql)
         }
 
         sql = sql.replace(/%/ig, ' mpercent ')
@@ -1905,7 +1937,7 @@
         sql = sql.replace(/@BID@/ig, `'${BID}'`)
 
         if (debug) {
-          console.info(sql)
+          window.mkInfo(sql)
         }
 
         sql = sql.replace(/%/ig, ' mpercent ')
@@ -1987,6 +2019,100 @@
         })
       )
     }
+
+    Promise.all(deffers).then(response => {
+      let result = {...response[0], ...(response[1] || {})}
+
+      delete result.ErrCode
+      delete result.ErrMesg
+      delete result.message
+      delete result.status
+
+      this.resetFormList(result)
+    })
+  }
+
+  improveBackActionForm = (deForms, BID) => {
+    let sysvals = {
+      mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
+      mk_organization: sessionStorage.getItem('organization') || '',
+      mk_user_type: sessionStorage.getItem('mk_user_type') || '',
+      bid: BID || '',
+      datam: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_begin: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_end: sessionStorage.getItem('dataM') === 'true' ? 'Y' : ''
+    }
+    if (window.GLOB.externalDatabase !== null) {
+      sysvals.db = window.GLOB.externalDatabase
+    }
+
+    let deffers = []
+    let mainItems = []  // 浜戠鎴栧崟鐐规暟鎹�
+    let localItems = [] // 鏈湴鏁版嵁
+
+    deForms.forEach(item => {
+      let ex = window.GLOB.CacheData.get('sql_' + item.uuid)
+      
+      if (!ex) return
+      
+      let exps = []
+      ex.reps.forEach(n => {
+        let key = n.toLowerCase()
+        if (sysvals.hasOwnProperty(key)) {
+          exps.push({
+            key: n,
+            value: sysvals[key]
+          })
+        }
+      })
+
+      let cell = {
+        id: ex.id,
+        menuname: item.label + '锛堣〃鍗曪級',
+        exps: exps,
+        md5_id: ''
+      }
+
+      if (item.database === 'sso' && window.GLOB.mainSystemApi) {
+        mainItems.push(cell)
+      } else {
+        localItems.push(cell)
+      }
+    })
+
+    if (localItems.length) {
+      deffers.push({
+        $backend: true,
+        $type: 's_Get_SelectedList',
+        data: localItems
+      })
+    }
+
+    if (mainItems.length) {
+      deffers.push({
+        $backend: true,
+        $type: 's_Get_SelectedList',
+        data: mainItems,
+        rduri: window.GLOB.mainSystemApi
+      })
+    }
+
+    if (!deffers.length) return
+
+    deffers = deffers.map(item => {
+      return new Promise(resolve => {
+        Api.getSystemCacheConfig(item, false).then(res => {
+          if (!res.status) {
+            notification.warning({
+              top: 92,
+              message: res.message,
+              duration: 5
+            })
+          }
+          resolve(res)
+        })
+      })
+    })
 
     Promise.all(deffers).then(response => {
       let result = {...response[0], ...(response[1] || {})}
@@ -2377,22 +2503,32 @@
 
     if (!data) return
 
-    let result = getEditTableSql(submit, data, forms)
-
-    let param = {
-      excel_in: result.lines,
-      BID: BID || ''
-    }
-
     this.setState({
       loading: true
     })
 
-    if (submit.intertype === 'system') { // 绯荤粺瀛樺偍杩囩▼
-      param.func = 'sPC_TableData_InUpDe'
-      
-      delete param.excel_in
+    if (submit.intertype === 'system' && window.backend && window.GLOB.CacheData.has('sql_submit_' + submit.$menuId)) {
+      let ex = window.GLOB.CacheData.get('sql_submit_' + submit.$menuId)
+      let param = this.getExps(ex, submit, data, forms)
 
+      Api.genericInterface(param).then((res) => {
+        if (res.status) {
+          this.execSuccess(res, record)
+        } else {
+          this.execError(res, record)
+        }
+      }, (error) => {
+        if (error && error.ErrCode === 'LoginError') return
+
+        this.execError({})
+      })
+    } else if (submit.intertype === 'system') { // 绯荤粺瀛樺偍杩囩▼
+      let result = getEditTableSql(submit, data, forms)
+      let param = {}
+
+      param.func = 'sPC_TableData_InUpDe'
+      param.BID = BID || ''
+      
       param.exec_type = window.GLOB.execType || 'y'
       param.LText = Utils.formatOptions(result.sql, param.exec_type)
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
@@ -2416,7 +2552,12 @@
         this.execError({})
       })
     } else if (submit.intertype === 'inner' && submit.innerFunc) { // 鑷畾涔夊瓨鍌ㄨ繃绋�
+      let result = getEditTableSql(submit, data, forms)
+      let param = {}
+
       param.func = submit.innerFunc
+      param.BID = BID || ''
+      param.excel_in = result.lines
 
       if (submit.recordUser === 'true') {
         param.username = sessionStorage.getItem('User_Name') || ''
@@ -2437,6 +2578,78 @@
     }
   }
 
+  getExps = (ex, btn, data, forms) => {
+    const { BID } = this.props
+
+    let exps = []
+    let values = {
+      time_id: Utils.getguid(),
+      roleid: sessionStorage.getItem('role_id') || '',
+      mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
+      mk_organization: sessionStorage.getItem('organization') || '',
+      mk_user_type: sessionStorage.getItem('mk_user_type') || '',
+      mk_nation: sessionStorage.getItem('nation') || '',
+      mk_province: sessionStorage.getItem('province') || '',
+      mk_city: sessionStorage.getItem('city') || '',
+      mk_district: sessionStorage.getItem('district') || '',
+      mk_address: sessionStorage.getItem('address') || '',
+      bid: BID || '',
+      typename: 'admin',
+      datam: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_begin: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_end: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+    }
+
+    if (window.GLOB.externalDatabase !== null) {
+      values.db = window.GLOB.externalDatabase
+    }
+
+    let lines = data.map(item => {
+      let vals = []
+      forms.forEach(col => {
+        vals.push(item[col.field])
+      })
+  
+      vals.push(item.$$uuid)
+      vals.push(item.$type || 'upt')
+      vals.push(BID)
+  
+      return vals
+    })
+
+    ex.reps.forEach(n => {
+      let key = n.toLowerCase()
+      if (values.hasOwnProperty(key)) {
+        exps.push({
+          key: n,
+          value: values[key]
+        })
+      }
+    })
+
+    exps.push({
+      key: 'mk_excel_data',
+      value: lines
+    })
+
+    let md5_id = ''
+    if (window.GLOB.probation) {
+      md5_id = md5(ex.id + JSON.stringify(exps) + Math.floor(new Date().getTime() / 600000))
+      md5_id = moment().format('YYYYMMDDHHmmss') + md5_id.slice(-18)
+    }
+
+    return {
+      $backend: true,
+      $type: 's_TableData_InUpDe',
+      data: [{
+        id: ex.id,
+        menuname: btn.logLabel || '',
+        exps: exps,
+        md5_id: md5_id
+      }]
+    }
+  }
+
   execSuccess = (res, record) => {
     const { submit } = this.props
     const { edData, dict } = this.state
diff --git a/src/tabviews/custom/components/table/edit-table/normalTable/mkPopSelect/index.jsx b/src/tabviews/custom/components/table/edit-table/normalTable/mkPopSelect/index.jsx
index d74157b..df74eed 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/mkPopSelect/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/mkPopSelect/index.jsx
@@ -41,61 +41,128 @@
       loading: true
     })
 
-    let param = {
-      func: 'sPC_Get_TableData',
-      obj_name: 'data',
-      exec_type: window.GLOB.execType || 'y',
-      arr_field: config.arr_field,
-      default_sql: 'true',
-      custom_script: '',
-      menuname: config.label
-    }
+    let param = null
+    if (window.backend && window.GLOB.CacheData.has('sql_' + config.uuid)) {
+      let ex = window.GLOB.CacheData.get('sql_' + config.uuid)
+      let sysvals = {
+        time_id: Utils.getguid(),
+        mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
+        mk_organization: sessionStorage.getItem('organization') || '',
+        mk_user_type: sessionStorage.getItem('mk_user_type') || '',
+        id: ID || '',
+        bid: BID || '',
+        datam: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+        datam_begin: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+        datam_end: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+        orderby: orderBy || config.order || '',
+        pagesize: config.laypage === 'true' ? pageSize : '9999',
+        pageindex: pageIndex
+      }
+      if (window.GLOB.externalDatabase !== null) {
+        sysvals.db = window.GLOB.externalDatabase
+      }
 
-    let sql = ''
-    let DateCount = ''
-    let _search = ''
-    let _orderBy = orderBy || config.order || ''
-    let _datasource = config.dataSource
+      let exps = []
 
-    if (config.searchKey && searchKey) {
-      let fields = config.searchKey.split(',').map(field => field + ` like '%${searchKey}%'`)
-      _search = 'where ' + fields.join(' OR ')
-    }
+      if (config.searchKey) {
+        if (!searchKey) {
+          exps.push({
+            key: 'mk_search',
+            value: []
+          })
+        } else {
+          exps.push({
+            key: 'mk_search',
+            value: [{
+              key: config.searchKey,
+              match: '01',
+              type: /,/.test(config.searchKey) ? 'text_or' : 'text',
+              value: searchKey
+            }]
+          })
+        }
+        config.searchKey.split(',').forEach(key => {
+          sysvals[key.toLowerCase()] = searchKey || ''
+        })
+      }
 
-    _datasource = _datasource.replace(/@BID@/ig, `'${BID || ''}'`)
-    _datasource = _datasource.replace(/@ID@/ig, `'${ID || ''}'`)
-
-    if (config.laypage === 'true') {
-      sql = `/*system_query*/select top ${pageSize} ${config.arr_field} from (select ${config.arr_field} ,ROW_NUMBER() over(order by ${_orderBy}) as rows from ${_datasource} ${_search}) tmptable where rows > ${pageSize * (pageIndex - 1)} order by tmptable.rows `
-      DateCount = `/*system_query*/select count(1) as total from ${_datasource} ${_search}`
-    } else if (_orderBy) {
-      sql = `/*system_query*/select ${config.arr_field} from (select ${config.arr_field} ,ROW_NUMBER() over(order by ${_orderBy}) as rows from ${_datasource} ${_search}) tmptable order by tmptable.rows `
-    } else {
-      sql = `/*system_query*/select ${config.arr_field} from ${_datasource} ${_search}  `
-    }
-
-    let departmentcode = sessionStorage.getItem('departmentcode') || ''
-    let organization = sessionStorage.getItem('organization') || ''
-    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+      ex.reps.forEach(n => {
+        let key = n.toLowerCase()
+        if (sysvals.hasOwnProperty(key)) {
+          exps.push({
+            key: n,
+            value: sysvals[key]
+          })
+        }
+      })
     
-    sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)
-      Select @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}'
-      ${sql}`
-
-    // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
-    if (window.GLOB.debugger === true) {
-      console.info(`/*${config.label} 鏁版嵁婧�*/\n` + sql.replace(/\n\s{6}/ig, '\n'))
-      DateCount && console.info(`/*${config.label} 鎬绘暟鏌ヨ*/\n` + DateCount.replace(/\n\s{6}/ig, '\n'))
+      param = {
+        $backend: true,
+        $type: 's_Get_TableData',
+        data: [{
+          id: ex.id,
+          menuname: config.label || '',
+          exps: exps,
+          md5_id: ''
+        }]
+      }
+    } else {
+      param = {
+        func: 'sPC_Get_TableData',
+        obj_name: 'data',
+        exec_type: window.GLOB.execType || 'y',
+        arr_field: config.arr_field,
+        default_sql: 'true',
+        custom_script: '',
+        menuname: config.label
+      }
+  
+      let sql = ''
+      let DateCount = ''
+      let _search = ''
+      let _orderBy = orderBy || config.order || ''
+      let _datasource = config.dataSource
+  
+      if (config.searchKey && searchKey) {
+        let fields = config.searchKey.split(',').map(field => field + ` like '%${searchKey}%'`)
+        _search = 'where ' + fields.join(' OR ')
+      }
+  
+      _datasource = _datasource.replace(/@BID@/ig, `'${BID || ''}'`)
+      _datasource = _datasource.replace(/@ID@/ig, `'${ID || ''}'`)
+  
+      if (config.laypage === 'true') {
+        sql = `/*system_query*/select top ${pageSize} ${config.arr_field} from (select ${config.arr_field} ,ROW_NUMBER() over(order by ${_orderBy}) as rows from ${_datasource} ${_search}) tmptable where rows > ${pageSize * (pageIndex - 1)} order by tmptable.rows `
+        DateCount = `/*system_query*/select count(1) as total from ${_datasource} ${_search}`
+      } else if (_orderBy) {
+        sql = `/*system_query*/select ${config.arr_field} from (select ${config.arr_field} ,ROW_NUMBER() over(order by ${_orderBy}) as rows from ${_datasource} ${_search}) tmptable order by tmptable.rows `
+      } else {
+        sql = `/*system_query*/select ${config.arr_field} from ${_datasource} ${_search}  `
+      }
+  
+      let departmentcode = sessionStorage.getItem('departmentcode') || ''
+      let organization = sessionStorage.getItem('organization') || ''
+      let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+      
+      sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)
+        Select @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}'
+        ${sql}`
+  
+      // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
+      if (window.GLOB.debugger === true) {
+        window.mkInfo(`/*${config.label} 鏁版嵁婧�*/\n` + sql.replace(/\n\s{6}/ig, '\n'))
+        DateCount && window.mkInfo(`/*${config.label} 鎬绘暟鏌ヨ*/\n` + DateCount.replace(/\n\s{6}/ig, '\n'))
+      }
+  
+      param.LText = Utils.formatOptions(sql, param.exec_type)
+      param.DateCount = Utils.formatOptions(DateCount, param.exec_type)
+  
+      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+      param.secretkey = Utils.encrypt('', param.timestamp)
+  
+      param.username = sessionStorage.getItem('User_Name') || ''
+      param.fullname = sessionStorage.getItem('Full_Name') || ''
     }
-
-    param.LText = Utils.formatOptions(sql, param.exec_type)
-    param.DateCount = Utils.formatOptions(DateCount, param.exec_type)
-
-    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-    param.secretkey = Utils.encrypt('', param.timestamp)
-
-    param.username = sessionStorage.getItem('User_Name') || ''
-    param.fullname = sessionStorage.getItem('Full_Name') || ''
 
     Api.getSystemCacheConfig(param, config.cache === 'true').then(result => {
       if (result.status) {
diff --git a/src/tabviews/custom/components/table/normal-table/index.jsx b/src/tabviews/custom/components/table/normal-table/index.jsx
index a5e10c5..ae15927 100644
--- a/src/tabviews/custom/components/table/normal-table/index.jsx
+++ b/src/tabviews/custom/components/table/normal-table/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Collapse } from 'antd'
+import { Collapse, notification } from 'antd'
 import moment from 'moment'
 
 import Api from '@/api'
@@ -79,8 +79,6 @@
 
     if (setting.selected !== 'always' && setting.selected !== 'init' && setting.selected !== 'sign') {
       setting.selected = 'false'
-    } else {
-      setting.orisel = true
     }
 
     if (_config.setting.sync === 'true') {
@@ -200,7 +198,7 @@
         this.setState({
           pageIndex: 1
         }, () => {
-          this.loadmaindata(true, 'true', '', 'timer')
+          this.loadData(true, 'true', '', 'timer')
         })
       })
     }
@@ -237,7 +235,7 @@
           Api.getLCacheConfig(config.uuid, config.$time, BID).then(res => {
             if (!res.valid && config.setting.onload === 'true') {
               setTimeout(() => {
-                this.loadmaindata(false, 'true', '', 'init')
+                this.loadData(false, 'true', '', 'init')
               }, config.setting.delay || 0)
             }
   
@@ -299,13 +297,13 @@
 
         if (config.setting.onload === 'true') {
           setTimeout(() => {
-            this.loadmaindata(false, 'true', '', 'init')
+            this.loadData(false, 'true', '', 'init')
           }, config.setting.delay || 0)
         }
       }
     } else if (config.setting.onload === 'true') {
       setTimeout(() => {
-        this.loadmaindata()
+        this.loadData()
       }, config.setting.delay || 0)
     }
   }
@@ -511,10 +509,8 @@
 
   /**
    * @description 涓昏〃鏁版嵁鍔犺浇
-   * @param { Boolean } reset  琛ㄦ牸鏄惁閲嶇疆
-   * @param { String }  repage 琛ㄦ牸鏄惁閲嶇疆椤电爜
    */
-  async loadmaindata (reset, repage, id, type) {
+  async loadData (reset, repage, id, type) {
     const { setting, config, search, orderBy, BID, pageIndex, pageSize, BData } = this.state
 
     if (setting.supModule && !BID && setting.supKey !== 'false') { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
@@ -575,35 +571,9 @@
         Api.writeCacheConfig(config.uuid, result.data || [], BID)
       }
 
-      if (repage === 'false' && result.data && result.data.length === 0 && result.total > 0 && pageIndex > 1) {
-        let _pageIndex = Math.ceil(result.total / pageSize)
-
-        if (_pageIndex < pageIndex) {
-          MKEmitter.emit('resetTable', config.uuid, 'repage', _pageIndex)
-          this.setState({
-            pageIndex: _pageIndex,
-            data: [],
-            selectedData: [],
-            total: result.total
-          }, () => {
-            this.loadmaindata()
-          })
-          return
-        }
-      }
-      
-      if ((setting.selected !== 'false' || (setting.orisel && id)) && result.data && result.data.length > 0) {
-        setTimeout(() => {
-          MKEmitter.emit('mkCheckTopLine', config.uuid, id, setting.selected)
-        }, 200)
-        if (setting.selected === 'init') {
-          this.setState({setting: {...setting, selected: 'false'}})
-        }
-      } else {
-        MKEmitter.emit('resetSelectLine', config.uuid, '', '') // 骞挎挱鏁版嵁鍒囨崲
-        if (setting.$hasSyncModule) {
-          MKEmitter.emit('syncBalconyData', config.uuid, [], false)
-        }
+      if (repage === 'false' && result.data.length === 0 && pageIndex > 1) {
+        this.reloadIndex()
+        return
       }
       
       reset && MKEmitter.emit('resetTable', config.uuid, repage) // 鍒楄〃閲嶇疆
@@ -649,6 +619,17 @@
         allSearch.push(...searches)
       }
 
+      if (data.length && (id || setting.selected !== 'false')) {
+        setTimeout(() => {
+          MKEmitter.emit('mkCheckTopLine', config.uuid, id, setting.selected)
+        }, 200)
+      } else {
+        MKEmitter.emit('resetSelectLine', config.uuid, '', '') // 骞挎挱鏁版嵁鍒囨崲
+        if (setting.$hasSyncModule) {
+          MKEmitter.emit('syncBalconyData', config.uuid, [], false)
+        }
+      }
+
       this.setState({
         data: data,
         selectedData: [],
@@ -656,6 +637,10 @@
         total: total,
         loading: false
       })
+
+      if (setting.selected === 'init') {
+        this.setState({setting: {...setting, selected: 'false'}})
+      }
 
       if (config.$hasTopModule) {
         window.GLOB.CacheData.set(config.uuid + 'tb', data[0] || { $$empty: true, $$uuid: '' })
@@ -686,11 +671,6 @@
   async loadLinedata (id, position) {
     const { setting, config, search, orderBy, BID, pageIndex, pageSize, BData } = this.state
 
-    if (config.forbidLine) {
-      this.reloadtable()
-      return
-    }
-
     let searches = fromJS(search).toJS()
     if (config.setting.useMSearch) { // 涓昏〃鎼滅储鏉′欢
       let mainSearch = window.GLOB.SearchBox.get(config.$searchId) || []
@@ -712,7 +692,7 @@
     let result = await Api.genericInterface(param)
     if (result.status) {
       if (position === 'line_grid' && (!result.data || !result.data[0])) {
-        this.loadmaindata(true, 'false')
+        this.reloadIndex()
         return
       }
       
@@ -724,6 +704,12 @@
         _data.$$uuid = _data[setting.primaryKey] || ''
         _data.$$BID = BID || ''
         _data.$$BData = BData || ''
+
+        if (setting.controlField) {
+          if (setting.controlVal.includes(_data[setting.controlField] + '')) {
+            _data.$disabled = true
+          }
+        }
   
         if (config.absFields) {
           config.absFields.forEach(f => {
@@ -812,11 +798,25 @@
    * 鍚湁鍒濆涓嶅姞杞界殑椤甸潰锛屼慨鏀硅缃�
    */
   refreshbysearch = (searches) => {
+    const { setting, BID } = this.state
+
+    if (setting.supModule && !BID && setting.supKey !== 'false') {
+      notification.warning({
+        top: 92,
+        message: window.GLOB.dict['sup_key_req'] || '闇�瑕佷笂绾т富閿�硷紒',
+        duration: 5
+      })
+      this.setState({
+        search: searches
+      })
+      return
+    }
+
     this.setState({
       pageIndex: 1,
       search: searches
     }, () => {
-      this.loadmaindata(true, 'true')
+      this.loadData(true, 'true')
     })
   }
 
@@ -837,23 +837,19 @@
       pageSize: pagination.pageSize,
       orderBy: (sorter.field && sorter.order) ? `${sorter.field} ${sorter.order}` : ''
     }, () => {
-      this.loadmaindata()
+      this.loadData()
     })
   }
 
   /**
    * @description 琛ㄦ牸鍒锋柊
    */
-  reloadtable = (btn, id) => {
-    if (!btn || btn.resetPageIndex !== 'false') {
-      this.setState({
-        pageIndex: 1
-      }, () => {
-        this.loadmaindata(true, 'true', id)
-      })
-    } else {
-      this.loadmaindata(true, 'false', id)
-    }
+  reloadIndex = () => {
+    this.setState({
+      pageIndex: 1
+    }, () => {
+      this.loadData(true, 'true')
+    })
   }
 
   /**
@@ -887,7 +883,9 @@
     if (config.uuid !== menuId) return
 
     if (!id) {
-      this.reloadtable()
+      this.reloadIndex()
+    } else if (config.forbidLine) {
+      this.loadData(true, 'false', id)
     } else {
       this.loadLinedata(id)
     }
@@ -912,7 +910,7 @@
 
       if (bid !== this.state.BID || bid !== '') {
         this.setState({ BID: bid, BData: _data, pageIndex: 1 }, () => {
-          this.loadmaindata(true, 'true')
+          this.loadData(true, 'true')
         })
       }
     } else {
@@ -928,7 +926,7 @@
           BData: data
         }, () => {
           if (!setting.checkBid) {
-            this.loadmaindata(true, 'true')
+            this.loadData(true, 'true')
           }
         })
       }
@@ -937,15 +935,13 @@
 
   /**
    * @description 鎸夐挳鎵ц瀹屾垚鍚庨〉闈㈠埛鏂�
-   * @param {*} menuId     // 鑿滃崟Id
-   * @param {*} position   // 鍒锋柊浣嶇疆
-   * @param {*} btn        // 鎵ц鐨勬寜閽�
    */
   refreshByButtonResult = (menuId, position, btn, id, lines) => {
     const { config, BID } = this.state
 
     if (config.uuid !== menuId) return
 
+    let _id = config.wrap.selected === 'always' ? (id || '') : ''
     if (config.supNodes) {
       if (['mainline', 'maingrid', 'popclose'].includes(position)) {
         let supNode = this.supModules[this.supModules.length - 1]
@@ -961,25 +957,37 @@
       } else {
         if (position === 'line' || position === 'line_grid') {
           if (lines && lines.length === 1) {
-            this.loadLinedata(lines[0].$$uuid, position)
+            if (config.forbidLine) {
+              this.loadData(true, 'false', lines[0].$$uuid)
+            } else {
+              this.loadLinedata(lines[0].$$uuid, position)
+            }
           } else {
-            this.reloadtable(btn, id)
+            this.loadData(true, 'false', _id)
           }
+        } else if (btn.resetPageIndex !== 'false') {
+          this.reloadIndex()
         } else {
-          this.reloadtable(btn, id)
+          this.loadData(true, 'false', _id)
         }
       }
     } else {
       if (position === 'line' || position === 'line_grid') {
         if (lines && lines.length === 1) {
-          this.loadLinedata(lines[0].$$uuid, position)
+          if (config.forbidLine) {
+            this.loadData(true, 'false', lines[0].$$uuid)
+          } else {
+            this.loadLinedata(lines[0].$$uuid, position)
+          }
         } else {
-          this.reloadtable(btn, id)
+          this.loadData(true, 'false', _id)
         }
       } else if (['mainline', 'maingrid', 'popclose'].includes(position) && config.setting.supModule) {
         MKEmitter.emit('reloadData', config.setting.supModule, position === 'maingrid' ? '' : BID)
+      } else if (btn.resetPageIndex !== 'false') {
+        this.reloadIndex()
       } else {
-        this.reloadtable(btn, id)
+        this.loadData(true, 'false', _id)
       }
     }
   }
@@ -1013,9 +1021,7 @@
 
     if (config.$searchId !== searchId) return
     
-    this.setState({pageIndex: 1}, () => {
-      this.reloadtable()
-    })
+    this.reloadIndex()
   }
 
   render() {
diff --git a/src/tabviews/custom/components/tabs/antv-tabs/index.jsx b/src/tabviews/custom/components/tabs/antv-tabs/index.jsx
index 2701fbb..ea63ca4 100644
--- a/src/tabviews/custom/components/tabs/antv-tabs/index.jsx
+++ b/src/tabviews/custom/components/tabs/antv-tabs/index.jsx
@@ -146,10 +146,10 @@
     if (!tabs.subtabs.length) return null
 
     return (
-      <div className={`menu-antv-tabs-wrap ${tabs.setting.tabLabel || ''} ${tabs.setting.cusClass || ''}`} id={'anchor' + tabs.uuid} style={tabs.style}>
+      <div className={`menu-antv-tabs-wrap ${tabs.setting.tabLabel || ''} ${tabs.setting.cusClass || ''} align-${tabs.setting.tabAlign || ''}`} id={'anchor' + tabs.uuid} style={tabs.style}>
         <Tabs defaultActiveKey="1" tabBarStyle={{background: tabs.setting.backgroundColor || 'transparent'}} tabPosition={tabs.setting.position} type={tabs.setting.tabStyle}>
           {tabs.subtabs.map(tab => (
-            <TabPane tab={<span id={'tab' + tab.uuid}>{tab.icon ? <MkIcon type={tab.icon} /> : null}{tab.label}</span>} style={{backgroundColor: tab.backgroundColor || 'transparent'}} key={tab.uuid}>
+            <TabPane tab={<span className={tab.taType || ''} id={'tab' + tab.uuid}>{tab.icon ? <MkIcon type={tab.icon} /> : null}{tab.label}</span>} style={{backgroundColor: tab.backgroundColor || 'transparent'}} key={tab.uuid}>
               <TabTransfer config={tab}/>
             </TabPane>
           ))}
diff --git a/src/tabviews/custom/components/tabs/antv-tabs/index.scss b/src/tabviews/custom/components/tabs/antv-tabs/index.scss
index 42c4140..21a134e 100644
--- a/src/tabviews/custom/components/tabs/antv-tabs/index.scss
+++ b/src/tabviews/custom/components/tabs/antv-tabs/index.scss
@@ -23,6 +23,10 @@
   .ant-tabs-bottom-bar {
     margin-top: 0;
   }
+
+  .ant-tabs-tab .only-icon .anticon {
+    margin-right: 0px;
+  }
 }
 
 .menu-antv-tabs-wrap.hide >.ant-tabs >.ant-tabs-bar{
@@ -59,4 +63,10 @@
   .ant-tabs-nav-scroll {
     text-align: right;
   }
+}
+.menu-antv-tabs-wrap.align-right >.ant-tabs >.ant-tabs-bar .ant-tabs-nav-scroll {
+  text-align: right;
+}
+.menu-antv-tabs-wrap.align-center >.ant-tabs >.ant-tabs-bar .ant-tabs-nav-scroll {
+  text-align: center;
 }
\ No newline at end of file
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index ce3f77e..8e29805 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -3,6 +3,7 @@
 import { is, fromJS } from 'immutable'
 import { notification, Spin, Row, Col, Modal } from 'antd'
 import moment from 'moment'
+import md5 from 'md5'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
@@ -219,6 +220,21 @@
 
       window.GLOB.CacheData.set(MenuID, urlparam)
 
+      if (window.backend && config.allSqls) {
+        let keys = Object.keys(urlparam)
+        config.allSqls.forEach(item => {
+          item.id = md5(window.GLOB.appkey + item.v_id)
+          if (item.type === 'datasource' || item.type === 'excelOut') {
+            item.urlkeys = keys
+            item.urlparam = urlparam
+            if (config.flow_code) {
+              item.works_flow_code = config.flow_code
+            }
+          }
+          window.GLOB.CacheData.set('sql_' + item.uuid, item)
+        })
+      }
+
       let userName = sessionStorage.getItem('User_Name') || ''
       let fullName = sessionStorage.getItem('Full_Name') || ''
 
@@ -285,7 +301,7 @@
         }
       })
 
-      config.components = this.formatSetting(config.components, params, inherit, config.interfaces, balMap, tbMap)
+      config.components = this.formatSetting(config.components, params, inherit, config.interfaces, balMap, tbMap, BID)
 
       if (initInters.length > 0) {
         this.stepInter = {
@@ -680,6 +696,7 @@
 
         if (item.hasExtend) {
           item.setting.hasExtend = true
+          item.setting.sync = 'false'
           item.setting.tableMode = 'compatible'
           item.setting.extendTime = moment().format('YYYY-MM-DD HH:mm:ss')
           item.colsCtrls = null
@@ -698,6 +715,9 @@
           }
         }
       } else if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
+        if (item.wrap.datatype === 'public') {
+          balMap.set(item.wrap.publicId + 'public', true)
+        }
         item.subcards && item.subcards.forEach(card => {
           if (card.style.boxShadow) {
             delete card.style.hShadow
@@ -908,7 +928,7 @@
 
           if (item.setting.sync === 'true') {
             // pageable 鏄惁鍒嗛〉锛岀粍浠跺睘鎬э紝涓嶅垎椤电殑缁勪欢鎵嶅彲浠ョ粺涓�鏌ヨ
-            if ((!item.pageable || (item.pageable && !item.setting.laypage)) && item.setting.onload === 'true') {
+            if ((!item.pageable || (item.pageable && !item.setting.laypage)) && item.setting.onload === 'true' && !_tailScript) {
 
             } else {
               item.setting.sync = 'false'
@@ -956,15 +976,18 @@
 
     if (cell.OpenType === 'excelOut') { // 瀵煎嚭
       cell.$menuName = item.$menuname
-    } else if (cell.OpenType === 'pop' && item.$cache && item.$time && cell.modal) {
-      cell.modal.$cache = item.$cache
-      cell.modal.$time = item.$time
-      cell.modal.uuid = cell.uuid + 'pop'
+    } else if (cell.OpenType === 'pop' && cell.modal) {
+      if (item.$cache && item.$time) {
+        cell.modal.$cache = item.$cache
+        cell.modal.$time = item.$time
+      }
+      cell.modal.uuid = cell.uuid + '_pop'
     }
 
     if (cell.verify) {
+      let isStatic = item.wrap && (item.wrap.datatype === 'static' || item.wrap.datatype === 'public')
       if (cell.verify.invalid === 'true') {
-        if (item.wrap && (item.wrap.datatype === 'static' || item.wrap.datatype === 'public')) {
+        if (isStatic) {
           cell.verify.invalid = 'false'
         } else if (item.setting && item.setting.maxScript && item.setting.maxScript >= 300) {
           cell.verify.invalid = 'false'
@@ -975,6 +998,9 @@
         } else if (cell.Ot === 'notRequired') {
           cell.verify.invalid = 'false'
         }
+      }
+      if (cell.verify.uniques && cell.verify.uniques.length > 0 && cell.Ot === 'requiredOnce' && isStatic) {
+        cell.verify.uniques = []
       }
 
       if (cell.verify.linkEnable === 'true' && /@/.test(cell.verify.linkUrl)) {
@@ -1120,18 +1146,18 @@
   }
 
   // 鏍煎紡鍖栭粯璁よ缃�
-  formatSetting = (components, params, inherit, interfaces, balMap, tbMap) => {
+  formatSetting = (components, params, inherit, interfaces, balMap, tbMap, BID) => {
     let delay = 20
     return components.map(component => {
       if (component.type === 'tabs') {
         component.subtabs = component.subtabs.map(tab => {
-          tab.components = this.formatSetting(tab.components, null, inherit, interfaces, balMap, tbMap)
+          tab.components = this.formatSetting(tab.components, null, inherit, interfaces, balMap, tbMap, BID)
           tab = {...tab, ...inherit}
           return tab
         })
         return component
       } else if (component.type === 'group') {
-        component.components = this.formatSetting(component.components, params, null, interfaces, balMap, tbMap)
+        component.components = this.formatSetting(component.components, params, null, interfaces, balMap, tbMap, BID)
         return component
       }
 
@@ -1206,6 +1232,8 @@
 
       if (component.setting.interType !== 'system') return component
 
+      component.setting.uuid = component.uuid
+
       // dataName 绯荤粺鐢熸垚鐨勬暟鎹簮鍚嶇О
       if (component.setting.sync === 'true') {
         component.dataName = 'mk' + component.uuid.slice(-18)
@@ -1227,12 +1255,22 @@
             component.setting.sync = 'false'
             component.setting.onload = 'false'
           } else {
-            params.push(getStructDefaultParam(component, searchlist, params.length === 0))
+            let backend = false
+            if (window.backend && params.length === 0 && window.GLOB.CacheData.has('sql_' + component.uuid)) {
+              backend = true
+            } else if (window.backend && params[0] && params[0].exps) {
+              backend = true
+            }
+            if (backend && !window.GLOB.CacheData.has('sql_' + component.uuid)) {
+              component.setting.sync = 'false'
+            } else {
+              params.push(getStructDefaultParam(component, searchlist, params.length === 0, BID))
+            }
           }
         }
       }
       
-      component.setting.delay = delay
+      component.setting.delay = delay + (component.setting.delay || 0)
       delay += 20
 
       return component
@@ -1258,7 +1296,7 @@
     let delay = 15
     return interfaces.map(inter => {
       inter.MenuID = MenuID
-      inter.setting.delay = delay
+      inter.setting.delay = delay + (inter.setting.delay || 0)
       inter.$searchId = MenuID
       delay += 15
 
@@ -1281,6 +1319,8 @@
       inter.setting.arr_field = inter.columns.map(col => col.field).join(',')
 
       if (inter.setting.interType !== 'system') return inter
+
+      inter.setting.uuid = inter.uuid
 
       let _customScript = ''
       let _tailScript = ''
@@ -1343,7 +1383,11 @@
     this.setState({loading: true, loadingview: false})
 
     if (config.$cache && config.$time) {
-      Api.getLCacheConfig(params[0].uuid, config.$time, BID).then(res => {
+      let uuid = params[0].uuid || ''
+      if (params[0].id) {
+        uuid = window.GLOB.CacheData.get('first_' + params[0].id) || ''
+      }
+      Api.getLCacheConfig(uuid, config.$time, BID).then(res => {
         if (!res.valid) {
           this.getMainData(param, params, config.MenuID)
         } else {
@@ -1379,11 +1423,11 @@
         }
 
         params.forEach((item) => {
-          let _data = result[item.name] || ''
+          let _data = result[item.dataName] || ''
           if (_data && !Array.isArray(_data)) {
             _data = [_data]
           }
-          window.GLOB.SyncData.set(item.name, _data)
+          window.GLOB.SyncData.set(item.dataName, _data)
         })
 
         MKEmitter.emit('transferSyncData', MenuID)
diff --git a/src/tabviews/custom/popview/index.jsx b/src/tabviews/custom/popview/index.jsx
index cf6e6a3..71b9453 100644
--- a/src/tabviews/custom/popview/index.jsx
+++ b/src/tabviews/custom/popview/index.jsx
@@ -156,7 +156,7 @@
     let params = []
     let BID = urlparam.$BID || ''
 
-    config.components = this.formatSetting(config.components, params, balMap, tbMap)
+    config.components = this.formatSetting(config.components, params, balMap, tbMap, BID)
 
     this.setState({
       BID: BID,
@@ -414,6 +414,7 @@
 
         if (item.hasExtend) {
           item.setting.hasExtend = true
+          item.setting.sync = 'false'
           item.setting.tableMode = 'compatible'
           item.setting.extendTime = moment().format('YYYY-MM-DD HH:mm:ss')
           item.colsCtrls = null
@@ -432,6 +433,9 @@
           }
         }
       } else if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
+        if (item.wrap.datatype === 'public') {
+          balMap.set(item.wrap.publicId + 'public', true)
+        }
         item.subcards && item.subcards.forEach(card => {
           if (card.style.boxShadow) {
             delete card.style.hShadow
@@ -620,7 +624,7 @@
 
           if (item.setting.sync === 'true') {
             // pageable 鏄惁鍒嗛〉锛岀粍浠跺睘鎬э紝涓嶅垎椤电殑缁勪欢鎵嶅彲浠ョ粺涓�鏌ヨ
-            if ((!item.pageable || (item.pageable && !item.setting.laypage)) && item.setting.onload === 'true') {
+            if ((!item.pageable || (item.pageable && !item.setting.laypage)) && item.setting.onload === 'true' && !_tailScript) {
 
             } else {
               item.setting.sync = 'false'
@@ -667,11 +671,14 @@
 
     if (cell.OpenType === 'excelOut') { // 瀵煎嚭
       cell.$menuName = item.$menuname
+    } else if (cell.OpenType === 'pop' && cell.modal) {
+      cell.modal.uuid = cell.uuid + '_pop'
     }
 
     if (cell.verify) {
+      let isStatic = item.wrap && (item.wrap.datatype === 'static' || item.wrap.datatype === 'public')
       if (cell.verify.invalid === 'true') {
-        if (item.wrap && (item.wrap.datatype === 'static' || item.wrap.datatype === 'public')) {
+        if (isStatic) {
           cell.verify.invalid = 'false'
         } else if (item.setting && item.setting.maxScript && item.setting.maxScript >= 300) {
           cell.verify.invalid = 'false'
@@ -682,6 +689,10 @@
         } else if (cell.Ot === 'notRequired') {
           cell.verify.invalid = 'false'
         }
+      }
+
+      if (cell.verify.uniques && cell.verify.uniques.length > 0 && cell.Ot === 'requiredOnce' && isStatic) {
+        cell.verify.uniques = []
       }
 
       if (cell.verify.linkEnable === 'true' && /@/.test(cell.verify.linkUrl)) {
@@ -807,17 +818,17 @@
   }
 
   // 鏍煎紡鍖栭粯璁よ缃�
-  formatSetting = (components, params, balMap, tbMap) => {
+  formatSetting = (components, params, balMap, tbMap, BID) => {
     let delay = 20
     return components.map(component => {
       if (component.type === 'tabs') {
         component.subtabs = component.subtabs.map(tab => {
-          tab.components = this.formatSetting(tab.components, null, balMap, tbMap)
+          tab.components = this.formatSetting(tab.components, null, balMap, tbMap, BID)
           return tab
         })
         return component
       } else if (component.type === 'group') {
-        component.components = this.formatSetting(component.components, params, balMap, tbMap)
+        component.components = this.formatSetting(component.components, params, balMap, tbMap, BID)
         return component
       }
 
@@ -884,6 +895,8 @@
 
       if (component.setting.interType !== 'system') return component
 
+      component.setting.uuid = component.uuid
+      
       // dataName 绯荤粺鐢熸垚鐨勬暟鎹簮鍚嶇О
       if (component.setting.sync === 'true') {
         component.dataName = 'mk' + component.uuid.slice(-18)
@@ -905,12 +918,23 @@
             component.setting.sync = 'false'
             component.setting.onload = 'false'
           } else {
-            params.push(getStructDefaultParam(component, searchlist, params.length === 0))
+            let backend = false
+            if (window.backend && params.length === 0 && window.GLOB.CacheData.has('sql_' + component.uuid)) {
+              backend = true
+            } else if (window.backend && params[0] && params[0].exps) {
+              backend = true
+            }
+
+            if (backend && !window.GLOB.CacheData.has('sql_' + component.uuid)) {
+              component.setting.sync = 'false'
+            } else {
+              params.push(getStructDefaultParam(component, searchlist, params.length === 0, BID))
+            }
           }
         }
       }
 
-      component.setting.delay = delay
+      component.setting.delay = delay + (component.setting.delay || 0)
       delay += 20
 
       return component
@@ -948,11 +972,11 @@
         }
 
         params.forEach((item) => {
-          let _data = result[item.name] || ''
+          let _data = result[item.dataName] || ''
           if (_data && !Array.isArray(_data)) {
             _data = [_data]
           }
-          window.GLOB.SyncData.set(item.name, _data)
+          window.GLOB.SyncData.set(item.dataName, _data)
         })
 
         MKEmitter.emit('transferSyncData', Tab.uuid)
diff --git a/src/tabviews/home/index.jsx b/src/tabviews/home/index.jsx
index d8b8d6c..5dafb3f 100644
--- a/src/tabviews/home/index.jsx
+++ b/src/tabviews/home/index.jsx
@@ -43,7 +43,7 @@
       this.setState({
         waiting: false
       })
-    } else {
+    } else if (!window.GLOB.$error) {
       setTimeout(() => {
         this.check(times)
       }, 200)
diff --git a/src/tabviews/zshare/actionList/changeuserbutton/index.jsx b/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
index a29158d..fe198ff 100644
--- a/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
@@ -114,7 +114,7 @@
       MKEmitter.emit('closeTabView', MenuID || btn.$MenuID)
 
       if (btn.refreshTab && btn.refreshTab.length > 0) {
-        MKEmitter.emit('reloadMenuView', btn.refreshTab[btn.refreshTab.length - 1], 'table')
+        MKEmitter.emit('reloadMenuView', btn.refreshTab[btn.refreshTab.length - 1])
       }
       return
     }
@@ -142,7 +142,7 @@
    */
   changeUser = (primaryId) => {
     const { setting, btn } = this.props
-    let _this = this
+    let that = this
 
     let param = {
       func: 'webapi_ChangeUser',
@@ -197,16 +197,16 @@
                 message: res.message || '鎵ц澶辫触锛�',
                 duration: btn.verify && btn.verify.ntime ? btn.verify.ntime : 10
               })
-              _this.setState({loading: false})
+              that.setState({loading: false})
             }
           }, () => {
             resolve()
-            _this.setState({loading: false})
+            that.setState({loading: false})
           })
         })
       },
       onCancel() {
-        _this.setState({loading: false})
+        that.setState({loading: false})
       }
     })
   }
diff --git a/src/tabviews/zshare/actionList/excelInbutton/index.jsx b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
index 1be21b1..513cdc5 100644
--- a/src/tabviews/zshare/actionList/excelInbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -3,6 +3,7 @@
 import moment from 'moment'
 import { is, fromJS } from 'immutable'
 import { Button, Modal, notification, message } from 'antd'
+import md5 from 'md5'
 
 import ExcelIn from './excelin'
 import Utils, { getExcelInSql } from '@/utils/utils.js'
@@ -143,7 +144,7 @@
         this.refs.excelIn.exceltrigger()
       })
   
-      if (window.GLOB.systemType === 'production') {
+      if (window.GLOB.systemType === 'production') { // positecgroup
         MKEmitter.emit('queryTrigger', {menuId: btn.uuid, name: '瀵煎叆Excel'})
       }
     }
@@ -180,6 +181,16 @@
       loading: false
     })
 
+    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)
+      return
+    }
+
     if (btn.execSuccess === 'closepoptab') {
       MKEmitter.emit('popclose')
     } else if (btn.execSuccess !== 'never') {
@@ -202,6 +213,10 @@
       } else {
         MKEmitter.emit('reloadData', btn.syncComponentId)
       }
+    }
+
+    if (tabId) {
+      MKEmitter.emit('reloadMenuView', tabId)
     }
 
     if (btn.switchTab && btn.switchTab.length > 0) {
@@ -258,6 +273,15 @@
     if (btn.execError === 'closepoptab') {
       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) {
@@ -276,6 +300,10 @@
         } else {
           MKEmitter.emit('reloadData', btn.syncComponentId)
         }
+      }
+
+      if (tabId) {
+        MKEmitter.emit('reloadMenuView', tabId)
       }
     }
 
@@ -309,75 +337,47 @@
       })
     }
 
-    let result = getExcelInSql(btn, data, (BID || ''), this.state.primaryId)
+    if (btn.intertype === 'system' && window.backend && window.GLOB.CacheData.has('sql_' + btn.uuid)) {
+      let ex = window.GLOB.CacheData.get('sql_' + btn.uuid)
+      let param = this.getExps(ex, data)
 
-    if (result.errors) {
-      notification.warning({
-        top: 92,
-        message: result.errors,
-        duration: 5
-      })
-      this.setState({ loading: false })
-      return
-    }
-
-    let param = {
-      ID: this.state.primaryId,
-      excel_in: result.lines
-    }
-
-    if (BID) {
-      param.BID = BID
-    }
-
-    if (btn.intertype === 'system') { // 绯荤粺瀛樺偍杩囩▼
-      param.func = 'sPC_TableData_InUpDe'
-
-      delete param.excel_in
-
-      // param.excel_in_type = 'true'
-      param.exec_type = window.GLOB.execType || 'y'
-      param.LText = result.sql
-      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+      if (param.errors) {
+        notification.warning({
+          top: 92,
+          message: param.errors,
+          duration: 5
+        })
+        this.setState({ loading: false })
+        return
+      }
 
       let unCheckParam = null
 
-      if (/\$check@|@check\$/ig.test(param.LText)) {
+      if (ex.reps.includes('mk_check_begin')) {
         unCheckParam = fromJS(param).toJS()
-        param.LText = param.LText.replace(/\$check@|@check\$/ig, '')
-      }
 
-      param.LText = Utils.formatOptions(param.LText, param.exec_type)
-      param.secretkey = Utils.encrypt('', param.timestamp)
-      if (window.GLOB.mkHS) { // 浜戠楠岃瘉
-        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) {
-        param.s_debug_type = 'Y'
+        param.data[0].exps.push({
+          key: 'mk_check_begin',
+          value: ''
+        }, {
+          key: 'mk_check_end',
+          value: ''
+        })
+        unCheckParam.data[0].exps.push({
+          key: 'mk_check_begin',
+          value: 'Y'
+        }, {
+          key: 'mk_check_end',
+          value: 'Y'
+        })
       }
 
       if (unCheckParam) {
-        unCheckParam.LText = unCheckParam.LText.replace(/\$check@/ig, '/*').replace(/@check\$/ig, '*/')
-        unCheckParam.LText = Utils.formatOptions(unCheckParam.LText, unCheckParam.exec_type)
-        unCheckParam.secretkey = Utils.encrypt('', unCheckParam.timestamp)
-        unCheckParam.menuname = btn.logLabel
-
-        if (window.GLOB.probation) {
-          unCheckParam.s_debug_type = 'Y'
-        }
-
         Api.genericInterface(param).then(res => {
           if (res.status) {
             this.execSuccess(res)
           } else if (res.ErrCode === 'C') {
-            const _this = this
+            const that = this
             confirm({
               title: window.GLOB.dict['exec_sure'] || '璇风‘璁�',
               content: res.message,
@@ -387,16 +387,16 @@
                 return new Promise(resolve => {
                   Api.genericInterface(unCheckParam).then(result => {
                     if (result.status) {
-                      _this.execSuccess(result)
+                      that.execSuccess(result)
                     } else {
-                      _this.execError(result)
+                      that.execError(result)
                     }
                     resolve()
                   })
                 })
               },
               onCancel() {
-                _this.execError(res)
+                that.execError(res)
               }
             })
           } else {
@@ -418,132 +418,455 @@
           this.execError({})
         })
       }
-    } else if (btn.intertype === 'inner' && btn.innerFunc) { // 鑷畾涔夊瓨鍌ㄨ繃绋�
-      param.func = btn.innerFunc
-
-      if (btn.recordUser === 'true') {
-        param.username = sessionStorage.getItem('User_Name') || ''
-        param.fullname = sessionStorage.getItem('Full_Name') || ''
+    } else {
+      let result = getExcelInSql(btn, data, (BID || ''), this.state.primaryId)
+  
+      if (result.errors) {
+        notification.warning({
+          top: 92,
+          message: result.errors,
+          duration: 5
+        })
+        this.setState({ loading: false })
+        return
       }
-      if (btn.dataM === 'true') {
-        param.dataM = sessionStorage.getItem('dataM') === 'true' ? 'Y' : ''
+  
+      let param = {
+        ID: this.state.primaryId,
+        excel_in: result.lines
       }
-
-      Api.genericInterface(param).then((res) => {
-        if (res.status) {
-          this.execSuccess(res)
-        } else {
-          this.execError(res)
+  
+      if (BID) {
+        param.BID = BID
+      }
+  
+      if (btn.intertype === 'system') { // 绯荤粺瀛樺偍杩囩▼
+        param.func = 'sPC_TableData_InUpDe'
+  
+        delete param.excel_in
+  
+        // param.excel_in_type = 'true'
+        param.exec_type = window.GLOB.execType || 'y'
+        param.LText = result.sql
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+  
+        let unCheckParam = null
+  
+        if (/\$check@|@check\$/ig.test(param.LText)) {
+          unCheckParam = fromJS(param).toJS()
+          param.LText = param.LText.replace(/\$check@|@check\$/ig, '')
         }
-      }, (error) => {
-        if (error && error.ErrCode === 'LoginError') return
-        this.execError({})
-      })
-    } else if (btn.intertype === 'outer') { // 澶栭儴鎺ュ彛
-      let _outParam = null
-      let ver_token = false
-
-      new Promise(resolve => {
-        // 鍐呴儴璇锋眰
-        if (btn.innerFunc) {
-          param.func = btn.innerFunc
-          // 瀛樺湪鍐呴儴鍑芥暟鏃讹紝鏁版嵁棰勫鐞�
+  
+        param.LText = Utils.formatOptions(param.LText, param.exec_type)
+        param.secretkey = Utils.encrypt('', param.timestamp)
+        if (window.GLOB.mkHS) { // 浜戠楠岃瘉
+          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) {
+          param.s_debug_type = 'Y'
+        }
+  
+        if (unCheckParam) {
+          unCheckParam.LText = unCheckParam.LText.replace(/\$check@/ig, '/*').replace(/@check\$/ig, '*/')
+          unCheckParam.LText = Utils.formatOptions(unCheckParam.LText, unCheckParam.exec_type)
+          unCheckParam.secretkey = Utils.encrypt('', unCheckParam.timestamp)
+          unCheckParam.menuname = btn.logLabel
+  
+          if (window.GLOB.probation) {
+            unCheckParam.s_debug_type = 'Y'
+          }
+  
           Api.genericInterface(param).then(res => {
             if (res.status) {
-              delete res.ErrCode
-              delete res.ErrMesg
-              delete res.message
-              delete res.status
-
-              // 浣跨敤澶勭悊鍚庣殑鏁版嵁璋冪敤澶栭儴鎺ュ彛
-              let keys = Object.keys(res) // 鎻愪氦澶栭儴鎺ュ彛鍓嶏紝娣诲姞BID
-              if (this.props.BID && keys.filter(key => key.toLowerCase() === 'bid').length === 0) {
-                res.BID = this.props.BID
-              }
-              resolve(res)
+              this.execSuccess(res)
+            } else if (res.ErrCode === 'C') {
+              const that = this
+              confirm({
+                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 => {
+                      if (result.status) {
+                        that.execSuccess(result)
+                      } else {
+                        that.execError(result)
+                      }
+                      resolve()
+                    })
+                  })
+                },
+                onCancel() {
+                  that.execError(res)
+                }
+              })
             } else {
               this.execError(res)
-              resolve(false)
             }
           }, (error) => {
             if (error && error.ErrCode === 'LoginError') return
             this.execError({})
           })
         } else {
-          resolve(param)
+          Api.genericInterface(param).then((res) => {
+            if (res.status) {
+              this.execSuccess(res)
+            } else {
+              this.execError(res)
+            }
+          }, (error) => {
+            if (error && error.ErrCode === 'LoginError') return
+            this.execError({})
+          })
         }
-      }).then(res => {
-        if (!res) return
-        // 澶栭儴璇锋眰
-        _outParam = fromJS(res).toJS()
-
-        if (btn.sysInterface === 'true') {
-          if (window.GLOB.mainSystemApi) {
-            param.rduri = window.GLOB.mainSystemApi
-          }
-        } else if (btn.sysInterface === 'external') {
-          if (window.GLOB.systemType === 'production') {
-            param.$token = btn.exProInterface || ''
+      } else if (btn.intertype === 'inner' && btn.innerFunc) { // 鑷畾涔夊瓨鍌ㄨ繃绋�
+        param.func = btn.innerFunc
+  
+        if (btn.recordUser === 'true') {
+          param.username = sessionStorage.getItem('User_Name') || ''
+          param.fullname = sessionStorage.getItem('Full_Name') || ''
+        }
+        if (btn.dataM === 'true') {
+          param.dataM = sessionStorage.getItem('dataM') === 'true' ? 'Y' : ''
+        }
+  
+        Api.genericInterface(param).then((res) => {
+          if (res.status) {
+            this.execSuccess(res)
           } else {
-            param.$token = btn.exInterface || ''
+            this.execError(res)
           }
-          ver_token = true
-        } else {
-          if (window.GLOB.systemType === 'production' && btn.proInterface) {
-            param.rduri = btn.proInterface
+        }, (error) => {
+          if (error && error.ErrCode === 'LoginError') return
+          this.execError({})
+        })
+      } else if (btn.intertype === 'outer') { // 澶栭儴鎺ュ彛
+        let _outParam = null
+        let ver_token = false
+  
+        new Promise(resolve => {
+          // 鍐呴儴璇锋眰
+          if (btn.innerFunc) {
+            param.func = btn.innerFunc
+            // 瀛樺湪鍐呴儴鍑芥暟鏃讹紝鏁版嵁棰勫鐞�
+            Api.genericInterface(param).then(res => {
+              if (res.status) {
+                delete res.ErrCode
+                delete res.ErrMesg
+                delete res.message
+                delete res.status
+  
+                // 浣跨敤澶勭悊鍚庣殑鏁版嵁璋冪敤澶栭儴鎺ュ彛
+                let keys = Object.keys(res) // 鎻愪氦澶栭儴鎺ュ彛鍓嶏紝娣诲姞BID
+                if (this.props.BID && keys.filter(key => key.toLowerCase() === 'bid').length === 0) {
+                  res.BID = this.props.BID
+                }
+                resolve(res)
+              } else {
+                this.execError(res)
+                resolve(false)
+              }
+            }, (error) => {
+              if (error && error.ErrCode === 'LoginError') return
+              this.execError({})
+            })
           } else {
-            param.rduri = btn.interface
+            resolve(param)
           }
-          let host = window.GLOB.baseurl.replace(/http(s):\/\//, '')
-          if (param.rduri.indexOf(host) === -1 && /\/dostars/.test(param.rduri)) {
-            param.$login = true
-          }
-        }
-
-        if (btn.outerFunc) {
-          res.func = btn.outerFunc
-        }
-        
-        if (window.GLOB.mkHS && res.func === 's_sDataDictb_excelIn') { // s_sDataDictb_excelIn 浜戠楠岃瘉
-          let sql = `Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)`
-          param.LText = Utils.formatOptions(sql)
-          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-          param.secretkey = Utils.encrypt(param.LText, param.timestamp)
-          param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
-        }
-
-        return Api.genericInterface(res)
-      }).then(response => {
-        if (!response || response.ErrCode === 'LoginError') return
-        // 鍥炶皟璇锋眰
-        if (ver_token && response.ErrCode === 'token_error') {
-          response.ErrCode = 'E'
-          this.execError(response)
-        } else if (btn.callbackFunc ) {
-          // 瀛樺湪鍥炶皟鍑芥暟鏃讹紝璋冪敤
-          delete response.message
-          delete response.status
-
-          response.func = btn.callbackFunc
-
-          let _callbackparam = {..._outParam, ...response}
-          return Api.genericInterface(_callbackparam)
-        } else {
-          if (response.status) {
-            this.execSuccess(response)
+        }).then(res => {
+          if (!res) return
+          // 澶栭儴璇锋眰
+          _outParam = fromJS(res).toJS()
+  
+          if (btn.sysInterface === 'true') {
+            if (window.GLOB.mainSystemApi) {
+              param.rduri = window.GLOB.mainSystemApi
+            }
+          } else if (btn.sysInterface === 'external') {
+            if (window.GLOB.systemType === 'production') {
+              param.$token = btn.exProInterface || ''
+            } else {
+              param.$token = btn.exInterface || ''
+            }
+            ver_token = true
           } else {
+            if (window.GLOB.systemType === 'production' && btn.proInterface) {
+              param.rduri = btn.proInterface
+            } else {
+              param.rduri = btn.interface
+            }
+            let host = window.GLOB.baseurl.replace(/http(s):\/\//, '')
+            if (param.rduri.indexOf(host) === -1 && /\/dostars/.test(param.rduri)) {
+              param.$login = true
+            }
+          }
+  
+          if (btn.outerFunc) {
+            res.func = btn.outerFunc
+          }
+          
+          if (window.GLOB.mkHS && res.func === 's_sDataDictb_excelIn') { // s_sDataDictb_excelIn 浜戠楠岃瘉
+            let sql = `Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)`
+            param.LText = Utils.formatOptions(sql)
+            param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+            param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+            param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
+          }
+  
+          return Api.genericInterface(res)
+        }).then(response => {
+          if (!response || response.ErrCode === 'LoginError') return
+          // 鍥炶皟璇锋眰
+          if (ver_token && response.ErrCode === 'token_error') {
+            response.ErrCode = 'E'
             this.execError(response)
+          } else if (btn.callbackFunc ) {
+            // 瀛樺湪鍥炶皟鍑芥暟鏃讹紝璋冪敤
+            delete response.message
+            delete response.status
+  
+            response.func = btn.callbackFunc
+  
+            let _callbackparam = {..._outParam, ...response}
+            return Api.genericInterface(_callbackparam)
+          } else {
+            if (response.status) {
+              this.execSuccess(response)
+            } else {
+              this.execError(response)
+            }
+          }
+        }).then(res => {
+          if (!res || res.ErrCode === 'LoginError') return
+  
+          if (res.status) {
+            this.execSuccess(res)
+          } else {
+            this.execError(res)
+          }
+        })
+      }
+    }
+  }
+
+  getExps = (ex, data) => {
+    const { BID, btn } = this.props
+    const { primaryId } = this.state
+
+    let exps = []
+    let values = {
+      time_id: Utils.getguid(),
+      roleid: sessionStorage.getItem('role_id') || '',
+      mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
+      mk_organization: sessionStorage.getItem('organization') || '',
+      mk_user_type: sessionStorage.getItem('mk_user_type') || '',
+      mk_nation: sessionStorage.getItem('nation') || '',
+      mk_province: sessionStorage.getItem('province') || '',
+      mk_city: sessionStorage.getItem('city') || '',
+      mk_district: sessionStorage.getItem('district') || '',
+      mk_address: sessionStorage.getItem('address') || '',
+      id: primaryId || '',
+      bid: BID || '',
+      typename: 'admin',
+      datam: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_begin: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_end: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      // mk_check_begin: '',
+      // mk_check_end: ''
+    }
+
+    if (window.GLOB.externalDatabase !== null) {
+      values.db = window.GLOB.externalDatabase
+    }
+
+    let keys = ['delete', 'drop', 'insert', 'truncate', 'update']
+    let errors = []
+    let _topline = btn.verify.range || 0
+    let cols = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
+    for (let i = 0; i < 26; i++) {
+      cols.push('A' + cols[i])
+    }
+
+    let lines = data.map((item, lindex) => {
+      let vals = []
+      btn.verify.columns.forEach((col, cindex) => {
+        if (col.import === 'false') return
+
+        let val = item[col.Column] !== undefined ? item[col.Column] : ''
+        let _colindex = cols[cindex] || (cindex + 1)
+        let _position = (_topline + lindex + 1) + '琛� ' + _colindex + '鍒� '
+
+        if (col.import === 'init') {
+          if (/^Nvarchar/ig.test(col.type)) {
+            val = ''
+          } else if (/^Decimal/ig.test(col.type) || /^int/ig.test(col.type)) {
+            val = 0
+          } else if (col.type === 'date') {
+            val = '1949-10-01'
+          } else if (col.type === 'datetime') {
+            val = '1949-10-01 00:00:00'
+          }
+        } else if (/^Nvarchar/ig.test(col.type)) {
+          val = val + ''
+
+          if (/'/.test(val)) {
+            val = val.replace(/'/ig, '"')
+          }
+
+          val = val.replace(/(^\s+$)|\t+|\v+/ig, '')
+
+          if (!val && col.required === 'true') {            // 蹇呭~鏍¢獙
+            errors.push(_position + '鍐呭涓嶅彲涓虹┖')
+          } else if (col.limit && val.length > col.limit) { // 闀垮害鏍¢獙
+            errors.push(_position + '鍐呭瓒呴暱')
+          } else {                                          // 鍏抽敭瀛楁牎楠�
+            keys.forEach(key => {
+              let _patten = new RegExp('(^' + key + '\\s+)|(\\s+' + key + '\\s+)', 'ig')
+              if (_patten.test(val)) {
+                errors.push(_position + '鍚湁鍏抽敭瀛�' + key)
+              }
+            })
+          }
+        } else if (/^Decimal/ig.test(col.type) || /^int/ig.test(col.type)) {
+          if (col.required === 'false') {
+            if (!val || isNaN(val)) {
+              val = 0
+            }
+          } else if (!val && val !== 0) {
+            errors.push(_position + '鍐呭涓嶅彲涓虹┖')
+          } else if (isNaN(val)) {                                  // 妫�楠屾槸鍚︿负鏁板��
+            errors.push(_position + '鍐呭搴斾负鏁板��')
+          } else if ((col.min || col.min === 0) && val < col.min) { // 鏈�灏忓�兼楠�
+            errors.push(_position + '灏忎簬鏈�灏忓��')
+          } else if ((col.max || col.max === 0) && val > col.max) { // 鏈�澶у�兼楠�
+            errors.push(_position + '澶т簬鏈�澶у��')
+          }
+        } else if (col.type === 'date' || col.type === 'datetime') {
+          if (typeof(val) === 'number') {
+            if (val > 2958465 || val <= 0) {                 // 鏃堕棿杩囧ぇ鎴栧皬浜庣瓑浜�0
+              errors.push(_position + '鏃堕棿涓鸿礋鍊兼垨澶ぇ')
+            } else {                                         // 鏃堕棿鏍煎紡鍖�
+              if (val < 60) {                                // 1900-2-29锛宔xcel涓瓨鍦紝瀹為檯涓嶅瓨鍦�
+                val++
+              }
+              if (col.type === 'datetime') {
+                val = val - 2
+                let day = Math.floor(val)
+                let seconds = Math.round((val - day) * 24 * 60 * 60)
+                val = moment('19000101', 'YYYYMMDD').add(day, 'days').add(seconds, 'seconds').format('YYYY-MM-DD HH:mm:ss')
+              } else {
+                val = moment('19000101', 'YYYYMMDD').add(Math.floor(val - 2), 'days').format('YYYY-MM-DD')
+              }
+            }
+          } else if (typeof(val) === 'string') {
+            val = val.replace(/(^\s+$)|\t+|\v+/ig, '')
+            if (!val) {
+              if (col.required === 'true') {         // 鏃堕棿蹇呭~鏍¢獙
+                errors.push(_position + '鍐呭涓嶅彲涓虹┖')
+              } else if (col.type === 'date') {
+                val = '1949-10-01'
+              } else if (col.type === 'datetime') {
+                val = '1949-10-01 00:00:00'
+              }
+            } else if (!/^[1-9][0-9]{3}/.test(val)) { // 鏃堕棿姝e垯鏍¢獙
+              errors.push(_position + '鏃堕棿鏍煎紡閿欒')
+            }
+          } else {                                    // 鏃堕棿鏍煎紡閿欒
+            errors.push(_position + '鏃堕棿鏍煎紡閿欒')
           }
         }
-      }).then(res => {
-        if (!res || res.ErrCode === 'LoginError') return
 
-        if (res.status) {
-          this.execSuccess(res)
-        } else {
-          this.execError(res)
-        }
+        vals.push(val)
       })
+
+      let _lineIndex = '0000' + (lindex + 1) + '0'
+      _lineIndex = _lineIndex.substring(_lineIndex.length - 6)
+
+      vals.push(Utils.getguid() + _lineIndex)
+      vals.push(BID)
+
+      return vals
+    })
+
+    if (errors.length) return {errors: errors.join('; ')}
+
+    ex.reps.forEach(n => {
+      let key = n.toLowerCase()
+      if (values.hasOwnProperty(key)) {
+        exps.push({
+          key: n,
+          value: values[key]
+        })
+      }
+    })
+
+    exps.push({
+      key: 'mk_excel_data',
+      value: lines
+    })
+
+    if (btn.$process && btn.verify.workFlow === 'true') {
+      let flow = window.GLOB.UserCacheMap.get(btn.$flowId)
+      let target = flow ? flow.cells.filter(cell => cell.mknode === 'start')[0] : ''
+      
+      let error = ''
+      let msg = ''
+      let status = 0
+      let statusName = ''
+      let detailId = ''
+  
+      if (target) {
+        detailId = target.id
+        status = target.mkdata.status
+        statusName = target.mkdata.statusName
+
+        let label = target.attrs && target.attrs.text && target.attrs.text.text ? target.attrs.text.text : ''
+        msg = {...target.mkdata, label: label, id: target.id, checkIds: [], checkUsers: []}
+        msg = window.btoa(window.encodeURIComponent(JSON.stringify(msg)))
+      } else {
+        status = 0
+        statusName = '寮傚父'
+        error = '宸ヤ綔娴佹棤寮�濮嬭妭鐐�'
+      }
+
+      exps.push(
+        { key: 'works_flow_error', value: error },
+        { key: 'works_flow_code', value: flow ? flow.flow_code : '' },
+        { key: 'works_flow_name', value: flow ? flow.flow_name : '' },
+        { key: 'works_flow_param', value: msg },
+        { key: 'works_flow_detail_id', value: detailId },
+        { key: 'status', value: status },
+        { key: 'statusname', value: statusName },
+        { key: 'work_group', value: sessionStorage.getItem('work_group') || '' },
+        { key: 'work_grade', value: sessionStorage.getItem('work_grade') || 0 },
+        // { key: 'start_type', value: '寮�濮�' },
+      )
+    }
+
+    let md5_id = ''
+    if (window.GLOB.probation) {
+      md5_id = md5(ex.id + JSON.stringify(exps) + Math.floor(new Date().getTime() / 600000))
+      md5_id = moment().format('YYYYMMDDHHmmss') + md5_id.slice(-18)
+    }
+
+    return {
+      $backend: true,
+      $type: 's_TableData_InUpDe',
+      data: [{
+        id: ex.id,
+        menuname: btn.logLabel || '',
+        exps: exps,
+        md5_id: md5_id
+      }]
     }
   }
 
diff --git a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
index cd40165..3dddc9d 100644
--- a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
@@ -107,7 +107,7 @@
       })
     } else {
       MKEmitter.emit('queryModuleParam', btn.$menuId, this.triggerExcelout)
-      if (window.GLOB.systemType === 'production') {
+      if (window.GLOB.systemType === 'production') { // positecgroup
         MKEmitter.emit('queryTrigger', {menuId: btn.uuid, name: '瀵煎嚭Excel'})
       }
     }
@@ -381,7 +381,6 @@
       if (btn.dataM === 'true') {
         param.dataM = sessionStorage.getItem('dataM') === 'true' ? 'Y' : ''
       }
-
     } else if (btn.intertype === 'outer' && !btn.innerFunc) { // 浣跨敤澶栭儴鍑芥暟
       param = this.getExcelCustomParam(viewParam.orderBy, viewParam.search, true, pageIndex, pageSize)
 
@@ -863,7 +862,10 @@
 
     let _setting = {}
     let _orderBy = orderBy || ''
+
     if (btn.verify.dataType === 'custom') {
+      _setting.uuid = btn.uuid
+      _setting.interType = 'system'
       _setting.arr_field = []
 
       btn.verify.columns.forEach(col => {
@@ -932,6 +934,10 @@
       _setting.laypage = pagination
       _setting.arr_field = _setting.all_field || _setting.arr_field
 
+      if (setting.sub_field) {
+        _setting.uuid = btn.uuid
+      }
+
       delete _setting.sub_field
     }
 
@@ -941,17 +947,9 @@
       primaryId = primaryId ? 'excel:' + primaryId : ''
     }
 
-    let param = UtilsDM.getDefaultQueryParam(_setting, search, _orderBy, pageIndex, pageSize, primaryId, BID)
+    let param = UtilsDM.getQueryDataParams(_setting, search, _orderBy, pageIndex, pageSize, BID, primaryId)
     
-    param.DateCount = ''
-
-    // 鏁版嵁绠$悊鏉冮檺
-    if (sessionStorage.getItem('dataM') === 'true') {
-      param.dataM = 'Y'
-    }
-    if (BID) {
-      param.BID = BID
-    }
+    delete param.DateCount
 
     return param
   }
@@ -986,6 +984,16 @@
       loading: false
     })
 
+    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)
+      return
+    }
+
     if (btn.execSuccess === 'closepoptab') {
       MKEmitter.emit('popclose')
     } else if (btn.execSuccess !== 'never') {
@@ -1008,6 +1016,10 @@
       } else {
         MKEmitter.emit('reloadData', btn.syncComponentId)
       }
+    }
+
+    if (tabId) {
+      MKEmitter.emit('reloadMenuView', tabId)
     }
     
     if (btn.switchTab && btn.switchTab.length > 0) {
@@ -1064,6 +1076,15 @@
     if (btn.execError === 'closepoptab') {
       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)
+        return
+      }
+
       MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execError, btn, '', [])
 
       if (btn.syncComponentId) {
@@ -1083,6 +1104,10 @@
           MKEmitter.emit('reloadData', btn.syncComponentId)
         }
       }
+
+      if (tabId) {
+        MKEmitter.emit('reloadMenuView', tabId)
+      }
     }
 
     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 10786db..43430ed 100644
--- a/src/tabviews/zshare/actionList/funcbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/funcbutton/index.jsx
@@ -2,9 +2,11 @@
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
 import { Button, notification, message, Modal } from 'antd'
+import moment from 'moment'
 import md5 from 'md5'
 
 import Api from '@/api'
+import Utils from '@/utils/utils.js'
 import MKEmitter from '@/utils/events.js'
 import MkIcon from '@/components/mk-icon'
 
@@ -165,21 +167,272 @@
         okText: dict['ok'] || '纭畾',
         cancelText: dict['cancel'] || '鍙栨秷',
         onOk() {
-          that.execRefund(orderId)
+          that.execRefund(orderId, data[0])
         },
         onCancel() {}
       })
     }
   }
 
-  execRefund = (orderId) => {
-    Api.setRefund(orderId).then(res => {
-      if (!res.status) {
-        this.execError({ErrCode: 'E', message: window.GLOB.dict['exc_fail'] || '鎵ц澶辫触锛�', ...res})
-      } else {
-        this.execSuccess({ErrCode: 'S', ...res})
+  execRefund = (orderId, data) => {
+    const { btn, BID } = this.props
+
+    let param = null
+    if (btn.payMode === 'inner') {
+      param = {
+        func: btn.innerFunc || '',
+        BID: BID || '',
+        username: sessionStorage.getItem('User_Name') || '',
+        fullname: sessionStorage.getItem('Full_Name') || '',
+        dataM: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+        ID: orderId
+      }
+    } else if (window.backend && window.GLOB.CacheData.has('sql_' + btn.uuid)) {
+      param = this.getbackParam(orderId, data)
+    } else if (btn.payMode === 'system') {
+      let sql = this.getSysDeclareSql(orderId, data)
+
+      param = {
+        func: 'sPC_TableData_InUpDe',
+        BID: BID || '',
+        exec_type: window.GLOB.execType || 'y',
+        timestamp: moment().format('YYYY-MM-DD HH:mm:ss')
+      }
+
+      param.secretkey = Utils.encrypt('', param.timestamp)
+      param.LText = Utils.formatOptions(sql, param.exec_type)
+
+      if (btn.output) {
+        param.key_back_type = 'Y'
+      }
+
+      if (window.GLOB.mkHS) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
+        param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
+      }
+
+      param.menuname = btn.logLabel
+
+      if (window.GLOB.probation) {
+        param.s_debug_type = 'Y'
+      }
+    }
+
+    this.setState({loading: true})
+
+    if (param) {
+      Api.genericInterface(param).then(res => {
+        if (res.status) {
+          let id = orderId
+          if (btn.output) {
+            id = res.mk_b_id || res[btn.output] || orderId
+          }
+
+          Api.setRefund({out_biz_no: id}).then(res => {
+            if (!res.status) {
+              this.execError({ErrCode: 'E', message: res.message || window.GLOB.dict['exc_fail'] || '鎵ц澶辫触锛�', ...res})
+            } else {
+              this.execSuccess({ErrCode: 'S', ...res})
+            }
+          })
+        } else {
+          this.execError(res)
+        }
+      })
+    } else {
+      Api.setRefund({out_biz_no: orderId}).then(res => {
+        if (!res.status) {
+          this.execError({ErrCode: 'E', message: res.message || window.GLOB.dict['exc_fail'] || '鎵ц澶辫触锛�', ...res})
+        } else {
+          this.execSuccess({ErrCode: 'S', ...res})
+        }
+      })
+    }
+  }
+
+  getbackParam = (ID, data) => {
+    const { columns, btn, BID } = this.props
+
+    let ex = window.GLOB.CacheData.get('sql_' + btn.uuid)
+    let exps = []
+    let values = {
+      time_id: Utils.getguid(),
+      roleid: sessionStorage.getItem('role_id') || '',
+      mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
+      mk_organization: sessionStorage.getItem('organization') || '',
+      mk_user_type: sessionStorage.getItem('mk_user_type') || '',
+      mk_nation: sessionStorage.getItem('nation') || '',
+      mk_province: sessionStorage.getItem('province') || '',
+      mk_city: sessionStorage.getItem('city') || '',
+      mk_district: sessionStorage.getItem('district') || '',
+      mk_address: sessionStorage.getItem('address') || '',
+      id: ID || '',
+      bid: BID || '',
+      typename: 'admin',
+      datam: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_begin: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_end: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+    }
+  
+    if (window.GLOB.externalDatabase !== null) {
+      values.db = window.GLOB.externalDatabase
+    }
+
+    ex.reps.forEach(n => {
+      let key = n.toLowerCase()
+      if (values.hasOwnProperty(key)) {
+        exps.push({
+          key: n,
+          value: values[key]
+        })
       }
     })
+
+    let _data = {}
+    Object.keys(data).forEach(key => {
+      _data[key.toLowerCase()] = data[key]
+    })
+  
+    columns.forEach(col => {
+      if (!ex.reps.includes(col.field)) return
+      if (!col.datatype) return
+
+      let _key = col.field.toLowerCase()
+      let _val = _data.hasOwnProperty(_key) ? _data[_key] : ''
+
+      if (/^date/ig.test(col.datatype) && !_val) {
+        _val = '1949-10-01'
+      }
+
+      exps.push({
+        key: 'mk_' + col.field + '_mk',
+        value: _val
+      })
+    })
+
+    let md5_id = ''
+    if (window.GLOB.probation) {
+      md5_id = md5(ex.id + JSON.stringify(exps) + Math.floor(new Date().getTime() / 600000))
+      md5_id = moment().format('YYYYMMDDHHmmss') + md5_id.slice(-18)
+    }
+
+    return {
+      $backend: true,
+      $type: 's_TableData_InUpDe',
+      data: [{
+        id: ex.id,
+        menuname: btn.logLabel || '',
+        exps: exps,
+        md5_id: md5_id
+      }]
+    }
+  }
+
+  getSysDeclareSql = (ID, data) => {
+    const { columns, btn, BID } = this.props
+
+    // 绯荤粺鍙橀噺
+    let _vars = ['tbid', 'errorcode', 'retmsg', 'username', 'fullname', 'roleid', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'bid']
+    let _declare = []
+    let _initVal = []
+  
+    let _data = {}
+    Object.keys(data).forEach(key => {
+      _data[key.toLowerCase()] = data[key]
+    })
+  
+    columns.forEach(col => {
+      let _key = col.field.toLowerCase()
+
+      if (_vars.includes(_key)) return
+
+      _declare.push(`@${_key} ${col.datatype}`)
+
+      let _val = _data.hasOwnProperty(_key) ? _data[_key] : ''
+
+      if (/^date/ig.test(col.datatype) && !_val) {
+        _val = '1949-10-01'
+      }
+
+      if (/'/.test(_val)) {
+        _val = _val.replace(/'/ig, '"')
+      }
+
+      _initVal.push(`@${_key}='${_val}'`)
+    })
+  
+    // 鍙橀噺澹版槑
+    _declare = _declare.join(',')
+    if (_declare) {
+      _declare = ',' + _declare
+    }
+
+    let _sql = `/* 绯荤粺鐢熸垚 */
+      Declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000), @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@bid nvarchar(50),@tbid nvarchar(50)${_declare}
+    `
+  
+    let userName = sessionStorage.getItem('User_Name') || ''
+    let fullName = sessionStorage.getItem('Full_Name') || ''
+    let RoleID = sessionStorage.getItem('role_id') || ''
+    let departmentcode = sessionStorage.getItem('departmentcode') || ''
+    let organization = sessionStorage.getItem('organization') || ''
+    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+    let nation = sessionStorage.getItem('nation') || ''
+    let province = sessionStorage.getItem('province') || ''
+    let city = sessionStorage.getItem('city') || ''
+    let district = sessionStorage.getItem('district') || ''
+    let address = sessionStorage.getItem('address') || ''
+  
+    // 鍒濆鍖栧嚟璇佸強鐢ㄦ埛淇℃伅瀛楁
+    _sql += `
+      /* 鐢ㄦ埛淇℃伅鍒濆鍖栬祴鍊� */
+      select @ErrorCode='',@retmsg='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}', @bid='${BID}'
+    `
+    _sql += `
+      /* 鏄剧ず鍒楀彉閲忚祴鍊� */
+      select ${_initVal.join(',')}
+    `
+
+    btn.verify.scripts.forEach(item => {
+      if (item.status === 'false') return
+
+      _sql += `
+      ${item.sql}
+      `
+    })
+
+    if (btn.output) {
+      _sql += `
+        aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg,${btn.output} as mk_b_id`
+    } else {
+      _sql += `
+        aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
+    }
+
+    _sql = _sql.replace(/@ID@/ig, `'${ID || ''}'`)
+    _sql = _sql.replace(/@BID@/ig, `'${BID || ''}'`)
+    _sql = _sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
+    _sql = _sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
+    _sql = _sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
+    _sql = _sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+    _sql = _sql.replace(/@lang@/ig, `'${sessionStorage.getItem('lang')}'`)
+    _sql = _sql.replace(/@typename@/ig, `'admin'`)
+
+    if (window.GLOB.externalDatabase !== null) {
+      _sql = _sql.replace(/@db@/ig, window.GLOB.externalDatabase)
+    }
+
+    if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺
+      _sql = _sql.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, `'Y'`)
+    } else {
+      _sql = _sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`)
+    }
+
+    if (window.GLOB.debugger === true) {
+      window.mkInfo('%c' + btn.logLabel, 'color: blue')
+      window.mkInfo(_sql)
+    }
+
+    return _sql
   }
 
   getShortUrl = (url) => {
diff --git a/src/tabviews/zshare/actionList/index.jsx b/src/tabviews/zshare/actionList/index.jsx
index d0a7bd4..c0945f5 100644
--- a/src/tabviews/zshare/actionList/index.jsx
+++ b/src/tabviews/zshare/actionList/index.jsx
@@ -134,6 +134,7 @@
             BID={BID}
             btn={item}
             BData={BData}
+            columns={columns}
             selectedData={selectedData}
           />
         )
@@ -205,18 +206,19 @@
             btn={item}
             selectedData={selectedData}
             />
-            )
-          }
+          )
         } else {
           return (
             <FuncButton
               key={item.uuid}
               BID={BID}
               btn={item}
+              columns={columns}
               selectedData={selectedData}
             />
           )
         }
+      }
       return null
     })
   }
diff --git a/src/tabviews/zshare/actionList/index.scss b/src/tabviews/zshare/actionList/index.scss
index 700f589..3419db2 100644
--- a/src/tabviews/zshare/actionList/index.scss
+++ b/src/tabviews/zshare/actionList/index.scss
@@ -16,6 +16,9 @@
     width: auto;
     padding: 0 15px;
   }
+  .ant-btn.ant-btn-link {
+    border-color: #d9d9d9;
+  }
 
   .ant-btn.mk-btn-hover-bg:not([disabled]):hover {
     opacity: 1!important;
diff --git a/src/tabviews/zshare/actionList/newpagebutton/index.jsx b/src/tabviews/zshare/actionList/newpagebutton/index.jsx
index 55bdf19..6721fb5 100644
--- a/src/tabviews/zshare/actionList/newpagebutton/index.jsx
+++ b/src/tabviews/zshare/actionList/newpagebutton/index.jsx
@@ -1,8 +1,12 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Button, notification, Modal } from 'antd'
+import { Button, notification, Modal, message } from 'antd'
+import moment from 'moment'
+import md5 from 'md5'
 
+import Api from '@/api'
+import Utils from '@/utils/utils.js'
 import MKEmitter from '@/utils/events.js'
 import MkIcon from '@/components/mk-icon'
 import './index.scss'
@@ -21,8 +25,10 @@
 
   state = {
     disabled: false,
+    loading: false,
     hidden: false,
-    visible: false
+    visible: false,
+    dict: window.GLOB.dict
   }
 
   UNSAFE_componentWillMount () {
@@ -102,7 +108,7 @@
    */
   actionTrigger = (triggerId, record, type, lid) => {
     const { btn, selectedData, BID, LID } = this.props
-    const { disabled } = this.state
+    const { disabled, dict } = this.state
 
     if (disabled) return
     if (triggerId && btn.uuid !== triggerId) return
@@ -114,7 +120,7 @@
       // 闇�瑕侀�夋嫨琛屾椂锛屾牎楠屾暟鎹�
       notification.warning({
         top: 92,
-        message: window.GLOB.dict['select_row'] || '璇烽�夋嫨琛岋紒',
+        message: dict['select_row'] || '璇烽�夋嫨琛岋紒',
         duration: 5
       })
       return
@@ -122,14 +128,14 @@
       // 闇�瑕侀�夋嫨鍗曡鏃讹紝鏍¢獙鏁版嵁
       notification.warning({
         top: 92,
-        message: window.GLOB.dict['select_single_row'] || '璇烽�夋嫨鍗曡鏁版嵁锛�',
+        message: dict['select_single_row'] || '璇烽�夋嫨鍗曡鏁版嵁锛�',
         duration: 5
       })
       return
     } else if (btn.pageTemplate === 'custom' && window.GLOB.systemType === 'production' && !btn.proUrl) {
       notification.warning({
         top: 92,
-        message: window.GLOB.dict['no_prod_link'] || '灏氭湭璁剧疆姝e紡绯荤粺閾炬帴鍦板潃锛�',
+        message: dict['no_prod_link'] || '灏氭湭璁剧疆姝e紡绯荤粺閾炬帴鍦板潃锛�',
         duration: 5
       })
       return
@@ -153,10 +159,7 @@
       lang = data[0].lang_s || ''
     }
 
-    let _name = '鏂伴〉闈�'
-
     if (btn.pageTemplate === 'billprint') {
-      _name = '鍗曟嵁鎵撳嵃'
       if (btn.preHandle === 'true' && btn.pre_func) {
         MKEmitter.emit('queryModuleParam', btn.$menuId, (res) => {
           let searches = {}
@@ -215,16 +218,49 @@
       } else {
         if (btn.Ot === 'required') {
           data.forEach(item => {
-            let _id = item.$$uuid || ''
-            let url = '#/billprint/' + window.btoa(window.encodeURIComponent(JSON.stringify({ id: _id, tempId: btn.printTemp, pageId: btn.$MenuID || '', dataM: sessionStorage.getItem('dataM') })))
+            let _param = { id: item.$$uuid || '', tempId: btn.printTemp, pageId: btn.$MenuID || '', dataM: sessionStorage.getItem('dataM')}
+
+            Object.keys(item).forEach(key => {
+              if (/^\$/.test(key)) return
+              if (typeof(item[key]) !== 'string' && typeof(item[key]) !== 'number') return
+              if (typeof(item[key]) === 'string' && item[key].length > 50) return
+              if (['id', 'tempid', 'pageid', 'datam'].includes(key.toLowerCase())) return
+
+              _param[key.toLowerCase()] = item[key]
+            })
+
+            let url = '#/billprint/' + window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
             window.open(url)
           })
         } else if (btn.Ot === 'requiredOnce') {
           Id = data.map(item => item.$$uuid).filter(Boolean).join(',')
+          let _param = { id: Id, tempId: btn.printTemp, pageId: btn.$MenuID || '', dataM: sessionStorage.getItem('dataM')}
+          let item = data[0]
+
+          Object.keys(item).forEach(key => {
+            if (/^\$/.test(key)) return
+            if (typeof(item[key]) !== 'string' && typeof(item[key]) !== 'number') return
+            if (typeof(item[key]) === 'string' && item[key].length > 50) return
+            if (['id', 'tempid', 'pageid', 'datam'].includes(key.toLowerCase())) return
+
+            _param[key.toLowerCase()] = item[key]
+          })
   
-          window.open('#/billprint/' + window.btoa(window.encodeURIComponent(JSON.stringify({ id: Id, tempId: btn.printTemp, pageId: btn.$MenuID || '', dataM: sessionStorage.getItem('dataM') }))))
+          window.open('#/billprint/' + window.btoa(window.encodeURIComponent(JSON.stringify(_param))))
         } else {
-          window.open('#/billprint/' + window.btoa(window.encodeURIComponent(JSON.stringify({ id: Id, tempId: btn.printTemp, pageId: btn.$MenuID || '', dataM: sessionStorage.getItem('dataM') }))))
+          let _param = { id: Id, tempId: btn.printTemp, pageId: btn.$MenuID || '', dataM: sessionStorage.getItem('dataM')}
+          let item = data[0]
+
+          Object.keys(item).forEach(key => {
+            if (/^\$/.test(key)) return
+            if (typeof(item[key]) !== 'string' && typeof(item[key]) !== 'number') return
+            if (typeof(item[key]) === 'string' && item[key].length > 50) return
+            if (['id', 'tempid', 'pageid', 'datam'].includes(key.toLowerCase())) return
+
+            _param[key.toLowerCase()] = item[key]
+          })
+
+          window.open('#/billprint/' + window.btoa(window.encodeURIComponent(JSON.stringify(_param))))
         }
       }
     } else if (btn.pageTemplate === 'billprintTemp') {
@@ -234,25 +270,52 @@
       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}`
-      let url = '#/pay/' +  window.btoa(window.encodeURIComponent(_p))
-      _name = '鏀粯'
-      
-      confirm({
-        title: '璇峰湪浠樻椤甸潰瀹屾垚璁㈠崟鏀粯銆�',
-        content: '',
-        className: 'pay-query',
-        okText: '鏀粯鎴愬姛',
-        cancelText: '鏀粯閬囧埌闂',
-        onOk() {
-          // 鏀粯鍚庡埛鏂扮晫闈�
-          MKEmitter.emit('reloadMenuView', btn.$MenuID)
-        },
-        onCancel() {
-          MKEmitter.emit('refreshByButtonResult', btn.$menuId, 'grid', btn)
-        },
-      })
-      window.open(url)
+      let appId = ''
+      let merchId = ''
+
+      if (btn.wxApp) {
+        appId = btn.wxApp
+        if (!window.GLOB.WXApps || window.GLOB.WXApps.findIndex(item => item.appId === btn.wxApp) === -1) {
+          notification.warning({
+            top: 92,
+            message: '鎸夐挳鍏宠仈搴旂敤涓嶅湪鍙敤鍒楄〃涓紝璇烽噸鏂颁繚瀛樻寜閽厤缃紒',
+            duration: 5
+          })
+          return
+        }
+      }
+      if (btn.wxMerch) {
+        merchId = btn.wxMerch
+        if (!window.GLOB.WXApps || window.GLOB.WXApps.findIndex(item => item.appId === btn.wxMerch) === -1) {
+          notification.warning({
+            top: 92,
+            message: '鎸夐挳鍏宠仈鍟嗘埛涓嶅湪鍙敤鍒楄〃涓紝璇烽噸鏂颁繚瀛樻寜閽厤缃紒',
+            duration: 5
+          })
+          return
+        }
+      }
+
+      if (btn.payMode === 'system' || btn.payMode === 'inner') {
+        this.prequest(Id, data[0] || {}, appId, merchId)
+      } else {
+        confirm({
+          title: '璇峰湪浠樻椤甸潰瀹屾垚璁㈠崟鏀粯銆�',
+          content: '',
+          className: 'pay-query',
+          okText: '鏀粯鎴愬姛',
+          cancelText: '鏀粯閬囧埌闂',
+          onOk() {
+            // 鏀粯鍚庡埛鏂扮晫闈�
+            MKEmitter.emit('reloadMenuView', btn.$MenuID)
+          },
+          onCancel() {
+            MKEmitter.emit('refreshByButtonResult', btn.$menuId, 'grid', btn)
+          },
+        })
+
+        window.open('#/pay/' + window.btoa(window.encodeURIComponent(JSON.stringify({ ID: Id, appId, merchId }))))
+      }
     } else if (btn.pageTemplate === 'custom') {
       let url = btn.url
       if (window.GLOB.systemType === 'production') {
@@ -304,14 +367,305 @@
       window.open(url)
     }
 
-    if (window.GLOB.systemType === 'production') {
-      MKEmitter.emit('queryTrigger', {menuId: btn.uuid, name: _name})
+    if (window.GLOB.systemType === 'production') { // positecgroup
+      MKEmitter.emit('queryTrigger', {menuId: btn.uuid, name: btn.label})
+    }
+  }
+
+  prequest = (ID, data, appId, merchId) => {
+    const { btn, BID } = this.props
+
+    let param = null
+    if (btn.payMode === 'inner') {
+      param = {
+        func: btn.innerFunc || '',
+        BID: BID || '',
+        username: sessionStorage.getItem('User_Name') || '',
+        fullname: sessionStorage.getItem('Full_Name') || '',
+        dataM: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+        ID: ID
+      }
+    } else if (window.backend && window.GLOB.CacheData.has('sql_' + btn.uuid)) {
+      param = this.getbackParam(ID, data)
+    } else {
+      let sql = this.getSysDeclareSql(ID, data)
+
+      param = {
+        func: 'sPC_TableData_InUpDe',
+        BID: BID || '',
+        exec_type: window.GLOB.execType || 'y',
+        timestamp: moment().format('YYYY-MM-DD HH:mm:ss')
+      }
+
+      param.secretkey = Utils.encrypt('', param.timestamp)
+      param.LText = Utils.formatOptions(sql, param.exec_type)
+
+      if (btn.output) {
+        param.key_back_type = 'Y'
+      }
+
+      if (window.GLOB.mkHS) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
+        param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
+      }
+
+      param.menuname = btn.logLabel
+
+      if (window.GLOB.probation) {
+        param.s_debug_type = 'Y'
+      }
+    }
+
+    this.setState({loading: true})
+    Api.genericInterface(param).then(res => {
+      this.setState({loading: false})
+      if (res.status) {
+        let id = ID
+        if (btn.output) {
+          id = res.mk_b_id || res[btn.output] || ID
+        }
+
+        confirm({
+          title: '璇峰湪浠樻椤甸潰瀹屾垚璁㈠崟鏀粯銆�',
+          content: '',
+          className: 'pay-query',
+          okText: '鏀粯鎴愬姛',
+          cancelText: '鏀粯閬囧埌闂',
+          onOk() {
+            // 鏀粯鍚庡埛鏂扮晫闈�
+            MKEmitter.emit('reloadMenuView', btn.$MenuID)
+          },
+          onCancel() {
+            MKEmitter.emit('refreshByButtonResult', btn.$menuId, 'grid', btn)
+          },
+        })
+
+        window.open('#/pay/' + window.btoa(window.encodeURIComponent(JSON.stringify({ ID: id, appId, merchId }))))
+      } else {
+        this.execError(res)
+      }
+    })
+  }
+
+  getbackParam = (ID, data) => {
+    const { columns, btn, BID } = this.props
+
+    let ex = window.GLOB.CacheData.get('sql_' + btn.uuid)
+    let exps = []
+    let values = {
+      time_id: Utils.getguid(),
+      roleid: sessionStorage.getItem('role_id') || '',
+      mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
+      mk_organization: sessionStorage.getItem('organization') || '',
+      mk_user_type: sessionStorage.getItem('mk_user_type') || '',
+      mk_nation: sessionStorage.getItem('nation') || '',
+      mk_province: sessionStorage.getItem('province') || '',
+      mk_city: sessionStorage.getItem('city') || '',
+      mk_district: sessionStorage.getItem('district') || '',
+      mk_address: sessionStorage.getItem('address') || '',
+      id: ID || '',
+      bid: BID || '',
+      typename: 'admin',
+      datam: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_begin: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_end: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+    }
+  
+    if (window.GLOB.externalDatabase !== null) {
+      values.db = window.GLOB.externalDatabase
+    }
+
+    ex.reps.forEach(n => {
+      let key = n.toLowerCase()
+      if (values.hasOwnProperty(key)) {
+        exps.push({
+          key: n,
+          value: values[key]
+        })
+      }
+    })
+
+    let _data = {}
+    Object.keys(data).forEach(key => {
+      _data[key.toLowerCase()] = data[key]
+    })
+  
+    columns.forEach(col => {
+      if (!ex.reps.includes(col.field)) return
+      if (!col.datatype) return
+
+      let _key = col.field.toLowerCase()
+      let _val = _data.hasOwnProperty(_key) ? _data[_key] : ''
+
+      if (/^date/ig.test(col.datatype) && !_val) {
+        _val = '1949-10-01'
+      }
+
+      exps.push({
+        key: 'mk_' + col.field + '_mk',
+        value: _val
+      })
+    })
+
+    let md5_id = ''
+    if (window.GLOB.probation) {
+      md5_id = md5(ex.id + JSON.stringify(exps) + Math.floor(new Date().getTime() / 600000))
+      md5_id = moment().format('YYYYMMDDHHmmss') + md5_id.slice(-18)
+    }
+
+    return {
+      $backend: true,
+      $type: 's_TableData_InUpDe',
+      data: [{
+        id: ex.id,
+        menuname: btn.logLabel || '',
+        exps: exps,
+        md5_id: md5_id
+      }]
+    }
+  }
+
+  getSysDeclareSql = (ID, data) => {
+    const { columns, btn, BID } = this.props
+
+    // 绯荤粺鍙橀噺
+    let _vars = ['tbid', 'errorcode', 'retmsg', 'username', 'fullname', 'roleid', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'bid']
+    let _declare = []
+    let _initVal = []
+  
+    let _data = {}
+    Object.keys(data).forEach(key => {
+      _data[key.toLowerCase()] = data[key]
+    })
+  
+    columns.forEach(col => {
+      let _key = col.field.toLowerCase()
+
+      if (_vars.includes(_key)) return
+
+      _declare.push(`@${_key} ${col.datatype}`)
+
+      let _val = _data.hasOwnProperty(_key) ? _data[_key] : ''
+
+      if (/^date/ig.test(col.datatype) && !_val) {
+        _val = '1949-10-01'
+      }
+
+      if (/'/.test(_val)) {
+        _val = _val.replace(/'/ig, '"')
+      }
+
+      _initVal.push(`@${_key}='${_val}'`)
+    })
+  
+    // 鍙橀噺澹版槑
+    _declare = _declare.join(',')
+    if (_declare) {
+      _declare = ',' + _declare
+    }
+
+    let _sql = `/* 绯荤粺鐢熸垚 */
+      Declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000), @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@bid nvarchar(50),@tbid nvarchar(50)${_declare}
+    `
+  
+    let userName = sessionStorage.getItem('User_Name') || ''
+    let fullName = sessionStorage.getItem('Full_Name') || ''
+    let RoleID = sessionStorage.getItem('role_id') || ''
+    let departmentcode = sessionStorage.getItem('departmentcode') || ''
+    let organization = sessionStorage.getItem('organization') || ''
+    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+    let nation = sessionStorage.getItem('nation') || ''
+    let province = sessionStorage.getItem('province') || ''
+    let city = sessionStorage.getItem('city') || ''
+    let district = sessionStorage.getItem('district') || ''
+    let address = sessionStorage.getItem('address') || ''
+  
+    // 鍒濆鍖栧嚟璇佸強鐢ㄦ埛淇℃伅瀛楁
+    _sql += `
+      /* 鐢ㄦ埛淇℃伅鍒濆鍖栬祴鍊� */
+      select @ErrorCode='',@retmsg='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}', @bid='${BID}'
+    `
+    _sql += `
+      /* 鏄剧ず鍒楀彉閲忚祴鍊� */
+      select ${_initVal.join(',')}
+    `
+
+    btn.verify.scripts.forEach(item => {
+      if (item.status === 'false') return
+
+      _sql += `
+      ${item.sql}
+      `
+    })
+
+    if (btn.output) {
+      _sql += `
+        aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg,${btn.output} as mk_b_id`
+    } else {
+      _sql += `
+        aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
+    }
+
+    _sql = _sql.replace(/@ID@/ig, `'${ID || ''}'`)
+    _sql = _sql.replace(/@BID@/ig, `'${BID || ''}'`)
+    _sql = _sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
+    _sql = _sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
+    _sql = _sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
+    _sql = _sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+    _sql = _sql.replace(/@lang@/ig, `'${sessionStorage.getItem('lang')}'`)
+    _sql = _sql.replace(/@typename@/ig, `'admin'`)
+
+    if (window.GLOB.externalDatabase !== null) {
+      _sql = _sql.replace(/@db@/ig, window.GLOB.externalDatabase)
+    }
+
+    if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺
+      _sql = _sql.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, `'Y'`)
+    } else {
+      _sql = _sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`)
+    }
+
+    if (window.GLOB.debugger === true) {
+      window.mkInfo('%c' + btn.logLabel, 'color: blue')
+      window.mkInfo(_sql)
+    }
+
+    return _sql
+  }
+
+  execError = (res) => {
+    const { btn } = this.props
+    const { dict } = this.state
+
+    if (!['LoginError', 'C', '-2', 'E', 'N', 'F', 'NM'].includes(res.ErrCode)) {
+      res.ErrCode = 'E'
+    }
+
+    if (res.ErrCode === 'E') {
+      Modal.error({
+        title: res.message || dict['exc_fail'] || '鎵ц澶辫触锛�',
+        okText: dict['got_it'] || '鐭ラ亾浜�'
+      })
+    } else if (res.ErrCode === 'N') {
+      notification.error({
+        top: 92,
+        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 || dict['exc_fail'] || '鎵ц澶辫触锛�',
+        duration: btn.verify && btn.verify.ftime ? btn.verify.ftime : 10
+      })
+    } else if (res.ErrCode === 'NM') {
+      message.error(res.message || dict['exc_fail'] || '鎵ц澶辫触锛�')
     }
   }
 
   render() {
     const { btn, name } = this.props
-    const { disabled, hidden } = this.state
+    const { disabled, hidden, loading } = this.state
 
     if (hidden) return null
 
@@ -331,6 +685,7 @@
         id={'button' + btn.uuid}
         title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
         style={btn.style || null}
+        loading={loading}
         disabled={disabled}
         className={btn.hover || ''}
         onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
diff --git a/src/tabviews/zshare/actionList/normalbutton/index.jsx b/src/tabviews/zshare/actionList/normalbutton/index.jsx
index 8f0c450..ed8e372 100644
--- a/src/tabviews/zshare/actionList/normalbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -48,7 +48,6 @@
     dict: window.GLOB.dict
   }
 
-  moduleParams = null
   preCallback = null
 
   UNSAFE_componentWillMount () {
@@ -225,7 +224,7 @@
 
     this.setState({autoMatic: type === 'autoMatic'})
 
-    let _this = this
+    let that = this
     let data = record || selectedData || []
 
     let valid = this.checkBtnData(data)
@@ -248,11 +247,11 @@
         cancelText: dict['cancel'] || '鍙栨秷',
         onOk() {
           return new Promise(resolve => {
-            _this.execSubmit(data, resolve)
+            that.execSubmit(data, resolve)
           })
         },
         onCancel() {
-          _this.setState({loading: false})
+          that.setState({loading: false})
         }
       })
     } else if (btn.OpenType === 'exec') {
@@ -308,7 +307,7 @@
       }
     }
 
-    if (window.GLOB.systemType === 'production') {
+    if (window.GLOB.systemType === 'production') { // positecgroup
       let _change = {
         prompt: '鎻愮ず妗�',
         exec: '鐩存帴鎵ц',
@@ -332,7 +331,7 @@
       return
     }
 
-    let _this = this
+    let that = this
     let data = selectedData || []
 
     let valid = this.checkBtnData(data)
@@ -360,12 +359,12 @@
         cancelText: dict['cancel'] || '鍙栨秷',
         onOk() {
           return new Promise(resolve => {
-            _this.execSubmit(data, resolve)
+            that.execSubmit(data, resolve)
           })
         },
         onCancel() {
           callback()
-          _this.setState({loading: false})
+          that.setState({loading: false})
         }
       })
     } else if (btn.OpenType === 'exec') {
@@ -459,8 +458,8 @@
       
       let primaryId = ''
 
-      if ((btn.Ot === 'requiredSgl' || btn.Ot === 'requiredOnce') && setting.primaryKey) {
-        let ids = data.map(d => { return d[setting.primaryKey] || ''})
+      if (btn.Ot === 'requiredSgl' || btn.Ot === 'requiredOnce') {
+        let ids = data.map(d => d.$$uuid)
         ids = ids.filter(Boolean)
         primaryId = ids.join(',')
       }
@@ -469,11 +468,11 @@
         param.ID = primaryId
 
         if (retmsg) {
-          const { sql, callbacksql } = getSysDefaultSql(btn, setting, '', param, data[0], columns, retmsg, this.moduleParams) // 鏁版嵁婧�
+          const { sql, callbacksql } = getSysDefaultSql(btn, setting, '', param, data[0], columns, retmsg) // 鏁版嵁婧�
           param.LText = sql
           param.$callbacksql = callbacksql
         } else {
-          param.LText = getSysDefaultSql(btn, setting, '', param, data[0], columns, false, this.moduleParams) // 鏁版嵁婧�
+          param.LText = getSysDefaultSql(btn, setting, '', param, data[0], columns, false) // 鏁版嵁婧�
           if (btn.output) {
             param.key_back_type = 'Y'
           }
@@ -493,23 +492,14 @@
         param.LText = Utils.formatOptions(param.LText, param.exec_type)
       } else if (btn.OpenType === 'pop' || btn.OpenType === 'formSubmit' || btn.OpenType === 'form') { // 琛ㄥ崟
         if (btn.sqlType === 'insert') { // 绯荤粺鍑芥暟娣诲姞鏃讹紝鐢熸垚uuid
-          primaryId = ''
-
-          if (formdata && setting.primaryKey) { // 琛ㄥ崟涓瓨鍦ㄤ富閿瓧娈碉紝涓婚敭鍊间互琛ㄥ崟涓殑鍊间负鍑�
-            let _form = formdata.filter(_form => _form.key === setting.primaryKey)[0]
-            if (_form) {
-              primaryId = _form.value
-            }
-          }
-
-          param.ID = primaryId || Utils.getguid()
+          param.ID = Utils.getguid()
 
           if (retmsg) {
-            const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, retmsg, this.moduleParams) // 鏁版嵁婧�
+            const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, retmsg) // 鏁版嵁婧�
             param.LText = sql
             param.$callbacksql = callbacksql
           } else {
-            param.LText = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, false, this.moduleParams) // 鏁版嵁婧�
+            param.LText = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, false) // 鏁版嵁婧�
             if (btn.output) {
               param.key_back_type = 'Y'
             }
@@ -531,11 +521,11 @@
           param.ID = primaryId
 
           if (retmsg) {
-            const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, retmsg, this.moduleParams) // 鏁版嵁婧�
+            const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, retmsg) // 鏁版嵁婧�
             param.LText = sql
             param.$callbacksql = callbacksql
           } else {
-            param.LText = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, false, this.moduleParams) // 鏁版嵁婧�
+            param.LText = getSysDefaultSql(btn, setting, formdata, param, data[0], columns, false) // 鏁版嵁婧�
             if (btn.output) {
               param.key_back_type = 'Y'
             }
@@ -597,11 +587,11 @@
           param.ID = primaryId
 
           if (retmsg) {
-            const { sql, callbacksql } = getSysDefaultSql(btn, setting, '', param, cell, columns, retmsg, this.moduleParams) // 鏁版嵁婧�
+            const { sql, callbacksql } = getSysDefaultSql(btn, setting, '', param, cell, columns, retmsg) // 鏁版嵁婧�
             param.LText = sql
             param.$callbacksql = callbacksql
           } else {
-            param.LText = getSysDefaultSql(btn, setting, '', param, cell, columns, false, this.moduleParams) // 鏁版嵁婧�
+            param.LText = getSysDefaultSql(btn, setting, '', param, cell, columns, false) // 鏁版嵁婧�
             if (btn.output) {
               param.key_back_type = 'Y'
             }
@@ -637,11 +627,11 @@
             param.ID = Utils.getguid()
 
             if (retmsg) {
-              const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, cell, columns, retmsg, this.moduleParams) // 鏁版嵁婧�
+              const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, cell, columns, retmsg) // 鏁版嵁婧�
               param.LText = sql
               param.$callbacksql = callbacksql
             } else {
-              param.LText = getSysDefaultSql(btn, setting, formdata, param, cell, columns, false, this.moduleParams) // 鏁版嵁婧�
+              param.LText = getSysDefaultSql(btn, setting, formdata, param, cell, columns, false) // 鏁版嵁婧�
               if (btn.output) {
                 param.key_back_type = 'Y'
               }
@@ -663,11 +653,11 @@
             param.ID = primaryId
 
             if (retmsg) {
-              const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, cell, columns, retmsg, this.moduleParams) // 鏁版嵁婧�
+              const { sql, callbacksql } = getSysDefaultSql(btn, setting, formdata, param, cell, columns, retmsg) // 鏁版嵁婧�
               param.LText = sql
               param.$callbacksql = callbacksql
             } else {
-              param.LText = getSysDefaultSql(btn, setting, formdata, param, cell, columns, false, this.moduleParams) // 鏁版嵁婧�
+              param.LText = getSysDefaultSql(btn, setting, formdata, param, cell, columns, false) // 鏁版嵁婧�
               if (btn.output) {
                 param.key_back_type = 'Y'
               }
@@ -718,6 +708,464 @@
     return _params
   }
 
+  getBackSystemParam = (data, formdata) => {
+    const { btn } = this.props
+
+    let ex = window.GLOB.CacheData.get('sql_' + btn.uuid)
+    let _params = []
+
+    if (btn.Ot === 'notRequired' || btn.Ot === 'requiredSgl' || btn.Ot === 'requiredOnce') {
+      let primaryId = ''
+      let cell = null
+
+      if (btn.Ot === 'requiredSgl' || btn.Ot === 'requiredOnce') {
+        primaryId = data.map(d => d.$$uuid).filter(Boolean).join(',')
+        cell = data[0]
+      }
+
+      if (btn.OpenType === 'pop' || btn.OpenType === 'formSubmit' || btn.OpenType === 'form') { // 琛ㄥ崟
+        if (btn.sqlType === 'insert') { // 绯荤粺鍑芥暟娣诲姞鏃讹紝鐢熸垚uuid
+          primaryId = Utils.getguid()
+        }
+      }
+
+      let exp = this.getExps(ex, formdata, cell, primaryId, btn.$process)
+
+      if (ex.reps.includes('mk_check_begin')) {
+        exp.$unCheckParam = fromJS(exp).toJS()
+
+        exp.data[0].exps.push({
+          key: 'mk_check_begin',
+          value: ''
+        }, {
+          key: 'mk_check_end',
+          value: ''
+        })
+        exp.$unCheckParam.data[0].exps.push({
+          key: 'mk_check_begin',
+          value: 'Y'
+        }, {
+          key: 'mk_check_end',
+          value: 'Y'
+        })
+      } else if (btn.procMode === 'system' && btn.callbackType === 'script') {
+        let _backex = window.GLOB.CacheData.get('sql_back_' + btn.uuid)
+        exp.$backParam = this.getExps(_backex, formdata, cell, primaryId)
+      }
+
+      _params.push(exp)
+    } else if (btn.Ot === 'required') {
+      _params = data.map((cell, index) => {
+        let primaryId = cell.$$uuid || ''
+
+        if (btn.OpenType === 'pop') { // 琛ㄥ崟
+          if (index !== 0) {
+            let _cell = {}
+            Object.keys(cell).forEach(key => {
+              _cell[key.toLowerCase()] = cell[key]
+            })
+            formdata = formdata.map(_data => {
+              if (_data.readin && _cell.hasOwnProperty(_data.key.toLowerCase())) {
+                _data.value = _cell[_data.key.toLowerCase()]
+              }
+              return _data
+            })
+          }
+
+          if (btn.sqlType === 'insert') { // 绯荤粺鍑芥暟娣诲姞鏃讹紝鐢熸垚uuid
+            primaryId = Utils.getguid()
+          }
+        }
+        let exp = this.getExps(ex, formdata, cell, primaryId, btn.$process)
+        if (ex.reps.includes('mk_check_begin')) {
+          exp.$unCheckParam = fromJS(exp).toJS()
+  
+          exp.data[0].exps.push({
+            key: 'mk_check_begin',
+            value: ''
+          }, {
+            key: 'mk_check_end',
+            value: ''
+          })
+          exp.$unCheckParam.data[0].exps.push({
+            key: 'mk_check_begin',
+            value: 'Y'
+          }, {
+            key: 'mk_check_end',
+            value: 'Y'
+          })
+        } else if (btn.procMode === 'system' && btn.callbackType === 'script') {
+          let _backex = window.GLOB.CacheData.get('sql_back_' + btn.uuid)
+          exp.$backParam = this.getExps(_backex, formdata, cell, primaryId)
+        }
+
+        return exp
+      })
+    }
+
+    return _params
+  }
+
+  getExps = (ex, formdata, cell, id, process) => {
+    const { columns, BID, btn } = this.props
+    let exps = []
+    let values = {
+      time_id: Utils.getguid(),
+      roleid: sessionStorage.getItem('role_id') || '',
+      mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
+      mk_organization: sessionStorage.getItem('organization') || '',
+      mk_user_type: sessionStorage.getItem('mk_user_type') || '',
+      mk_nation: sessionStorage.getItem('nation') || '',
+      mk_province: sessionStorage.getItem('province') || '',
+      mk_city: sessionStorage.getItem('city') || '',
+      mk_district: sessionStorage.getItem('district') || '',
+      mk_address: sessionStorage.getItem('address') || '',
+      id: id || '',
+      bid: BID || '',
+      typename: 'admin',
+      datam: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_begin: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_end: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      // mk_check_begin: '',
+      // mk_check_end: ''
+    }
+
+    if (window.GLOB.externalDatabase !== null) {
+      values.db = window.GLOB.externalDatabase
+    }
+
+    let formkeys = []
+    formdata && formdata.forEach(form => {
+      // if (!ex.reps.includes(form.key)) return
+
+      formkeys.push(form.key)
+
+      let val = form.value
+      if (form.type === 'number' || form.type === 'rate') {
+        if (isNaN(val)) {
+          val = 0
+        }
+      } else if (['date', 'datemonth'].includes(form.type)) {
+        val = val || '1949-10-01'
+      }
+
+      exps.push({
+        key: 'mk_' + form.key + '_mk',
+        value: val
+      })
+    })
+
+    if (cell && columns && columns.length > 0) {
+      let datavars = {}
+
+      Object.keys(cell).forEach(key => {
+        datavars[key.toLowerCase()] = cell[key]
+      })
+  
+      columns.forEach(col => {
+        if (!ex.reps.includes(col.field) || formkeys.includes(col.field)) return
+        if (!col.datatype) return
+
+        let _key = col.field.toLowerCase()
+        let _val = datavars.hasOwnProperty(_key) ? datavars[_key] : ''
+
+        if (/^date/ig.test(col.datatype) && !_val) {
+          _val = '1949-10-01'
+        }
+
+        exps.push({
+          key: 'mk_' + col.field + '_mk',
+          value: _val
+        })
+      })
+    }
+
+    ex.reps.forEach(n => {
+      let key = n.toLowerCase()
+      if (values.hasOwnProperty(key)) {
+        exps.push({
+          key: n,
+          value: values[key]
+        })
+      }
+    })
+
+    if (process && btn.verify.workFlow === 'true') {
+      let flow = window.GLOB.UserCacheMap.get(btn.$flowId)
+      let node = null
+      let line = null
+      let target = null
+      let status = 0
+      let statusName = ''
+      let detailId = ''
+      let sign = ''
+      let error = ''
+      let userid = sessionStorage.getItem('UserID') || ''
+      let checkIds = []
+      let checkUsers = []
+      let noticeIds = []
+      let work_grade = sessionStorage.getItem('work_grade') || 0
+      let departmentcode = sessionStorage.getItem('departmentcode') || ''
+      let _data = cell || {}
+      let msg = ''
+  
+      if (btn.verify.flowType === 'start') {
+        target = flow ? flow.cells.filter(cell => cell.mknode === 'start')[0] : ''
+  
+        if (target) {
+          detailId = target.id
+          status = target.mkdata.status
+          statusName = target.mkdata.statusName
+        } else {
+          error = '宸ヤ綔娴佹棤寮�濮嬭妭鐐�'
+        }
+      } else if (_data.works_flow_param) {
+        try {
+          node = JSON.parse(window.decodeURIComponent(window.atob(_data.works_flow_param)))
+        } catch (e) {
+          node = null
+        }
+  
+        if (node) {
+          let lines = flow ? flow.cells.filter(cell => cell.shape === 'edge' && cell.source.cell === node.id) : []
+          if (btn.verify.flowType === 'reject') {
+            line = lines.filter(cell => cell.mkdata.flowType === 'reject' || cell.mknode === 'startEdge')[0]
+          } else {
+            lines = lines.filter(cell => cell.mkdata.flowType !== 'reject' && cell.mknode !== 'startEdge')
+  
+            if (lines.length === 0) {
+              error = '鏃犲彲鎵ц鐨勬祦绋嬪垎鏀�'
+            } else {
+              let branchKey = btn.verify.flowBranch ? btn.verify.flowBranch.toLowerCase() : ''
+  
+              formdata && formdata.forEach(form => {
+                let _key = form.key.toLowerCase()
+                _data[_key] = form.value
+              })
+  
+              if (!branchKey) {
+                lines.forEach(line => {
+                  if (line.mkdata.execCondition === 'open') {
+                    error = '鎸夐挳鏈缃祦绋嬫帶鍒跺瓧娈点��'
+                  }
+                })
+                if (!error) {
+                  lines = lines.filter(cell => {
+                    if (cell.mkdata.seniorCondition === 'open' && !line) {
+                      cell.mkdata.seniorbers && cell.mkdata.seniorbers.forEach(per => {
+                        if (per.worker_id === userid) {
+                          line = cell
+                        }
+                      })
+                      return false
+                    }
+                    return true
+                  })
+
+                  if (!line) {
+                    line = lines[0]
+                  }
+                }
+              } else if (!_data.hasOwnProperty(branchKey)) {
+                error = '淇℃伅涓棤娴佺▼鎺у埗瀛楁銆�'
+              } else {
+                let _def_lines = []
+                let _equ_lines = []
+                let _unequ_lines = []
+                let _or_lines = []
+                let branchVal = _data[branchKey]
+  
+                if (branchVal && typeof(branchVal) === 'string' && !isNaN(branchVal)) {
+                  branchVal = +branchVal
+                }
+  
+                lines.forEach(item => {
+                  if (item.mkdata.execCondition !== 'open') {
+                    _def_lines.push(item)
+                  } else {
+                    if (item.mkdata.match === '=') {
+                      if (item.mkdata.matchVal === branchVal + '') {
+                        _equ_lines.push(item)
+                      }
+                    } else if (item.mkdata.match === '!=') {
+                      if (item.mkdata.matchVal !== branchVal + '') {
+                        _unequ_lines.push(item)
+                      }
+                    } else {
+                      if (item.mkdata.match === '<') {
+                        if (item.mkdata.matchVal < branchVal) {
+                          _or_lines.push({...item, dist: Math.abs(item.mkdata.matchVal - branchVal)})
+                        }
+                      } else if (item.mkdata.match === '>') {
+                        if (item.mkdata.matchVal > branchVal) {
+                          _or_lines.push({...item, dist: Math.abs(item.mkdata.matchVal - branchVal)})
+                        }
+                      } else if (item.mkdata.match === '<=') {
+                        if (item.mkdata.matchVal <= branchVal) {
+                          _or_lines.push({...item, dist: Math.abs(item.mkdata.matchVal - branchVal)})
+                        }
+                      } else if (item.mkdata.match === '>=') {
+                        if (item.mkdata.matchVal >= branchVal) {
+                          _or_lines.push({...item, dist: Math.abs(item.mkdata.matchVal - branchVal)})
+                        }
+                      }
+                    }
+                  }
+                })
+  
+                _or_lines.sort((a, b) => a.dist - b.dist)
+  
+                let _lines = [..._equ_lines, ..._or_lines, ..._unequ_lines, ..._def_lines]
+  
+                _lines = _lines.filter(cell => {
+                  if (cell.mkdata.seniorCondition === 'open' && !line) {
+                    cell.mkdata.seniorbers && cell.mkdata.seniorbers.forEach(per => {
+                      if (per.worker_id === userid) {
+                        line = cell
+                      }
+                    })
+                    return false
+                  }
+                  return true
+                })
+                
+                if (!line) {
+                  line = _lines[0]
+                }
+              }
+            }
+          }
+        } else {
+          error = '琛屼俊鎭腑宸ヤ綔娴佸弬鏁版棤娉曡В鏋�'
+        }
+        
+        if (line) {
+          detailId = line.id
+          status = line.mkdata.status
+          statusName = line.mkdata.statusName
+          sign = line.mkdata.seniorSign || ''
+          target = flow.cells.filter(cell => cell.id === line.target.cell)[0]
+  
+          line.mkdata.members && line.mkdata.members.forEach(item => {
+            if (line.mkdata.approver === 'departmentManager') {
+              if (item.job_type === 'manage' && departmentcode === item.parentIds[1]) {
+                checkIds.push(item.worker_id)
+                checkUsers.push(item)
+              }
+            } else if (line.mkdata.approver === 'directManager') {
+              if (departmentcode === item.parentIds[1] && item.work_grade > work_grade) {
+                checkIds.push(item.worker_id)
+                checkUsers.push(item)
+              }
+            } else {
+              checkIds.push(item.worker_id)
+              checkUsers.push(item)
+            }
+          })
+          line.mkdata.copys && line.mkdata.copys.forEach(item => {
+            noticeIds.push(item.worker_id)
+          })
+  
+          if (!target) {
+            error = '鏈煡璇㈠埌宸ヤ綔娴佺洰鏍囪妭鐐�'
+          } else if (checkIds.length === 0 && !['startEdge', 'endEdge', 'throughEdge'].includes(line.mknode)) {
+            error = '鏈幏鍙栧埌涓嬩竴姝ュ鎵逛汉'
+          } else if (line.approvalMethod === 'countersign' && (!node.checkIds || !node.checkIds.includes(userid))) {
+            error = '褰撳墠鐢ㄦ埛涓嶅湪瀹℃壒浜哄垪琛ㄤ腑'
+          }
+        } else if (!error) {
+          error = '宸ヤ綔娴佷腑鏃犲搴旀祦绋�'
+        }
+      } else {
+        error = '琛屼俊鎭腑鏃犲伐浣滄祦鍙傛暟'
+      }
+
+      if (error) {
+        status = 0
+        statusName = '寮傚父'
+      } else if (target) {
+        let label = target.attrs && target.attrs.text && target.attrs.text.text ? target.attrs.text.text : ''
+        msg = {...target.mkdata, label: label, id: target.id, checkIds: [], checkUsers: []}
+        msg = window.btoa(window.encodeURIComponent(JSON.stringify(msg)))
+      }
+  
+      if (btn.verify.flowType === 'start') {
+        exps.push(
+          { key: 'works_flow_error', value: error },
+          { key: 'works_flow_code', value: flow ? flow.flow_code : '' },
+          { key: 'works_flow_name', value: flow ? flow.flow_name : '' },
+          { key: 'works_flow_param', value: msg },
+          { key: 'works_flow_detail_id', value: detailId },
+          { key: 'status', value: status },
+          { key: 'statusname', value: statusName },
+          { key: 'work_group', value: sessionStorage.getItem('work_group') || '' },
+          { key: 'work_grade', value: sessionStorage.getItem('work_grade') || 0 },
+          // { key: 'start_type', value: '寮�濮�' },
+        )
+      } else {
+        let works_flow_countersign = ''
+        let works_flow_sign_values = ''
+        let works_flow_sign_field = ''
+        let works_flow_sign_label = ''
+        let works_begin_branch = ''
+        if (line.approvalMethod === 'countersign' && node.checkIds.length > 1) {
+          works_flow_countersign = 'Y'
+          let mark = line.mark || '宸插鏍�'
+          let fields = ['statuscharone', 'statuschartwo', 'statuscharthree', 'statuscharfour', 'statuscharfive']
+          node.checkUsers.forEach((user, index) => {
+            if (user.worker_id === userid) {
+              works_flow_sign_field = fields[index]
+              works_flow_sign_label = `${user.parentNames[2] || ''}${user.workername || ''}${mark}`
+            } else {
+              works_flow_sign_values += `${user.parentNames[2] || ''}${user.workername || ''}${mark}`
+            }
+          })
+        } else {
+          works_begin_branch = line.mknode === 'startEdge' ? 'Y' : ''
+        }
+
+        exps.push(
+          { key: 'works_flow_error', value: error },
+          { key: 'works_flow_countersign', value: works_flow_countersign },
+          { key: 'works_flow_sign_values', value: works_flow_sign_values },
+          { key: 'works_begin_branch', value: works_begin_branch },
+          { key: 'works_flow_sign_field', value: works_flow_sign_field },
+          { key: 'works_flow_sign_label', value: works_flow_sign_label },
+          { key: 'works_flow_code', value: flow ? flow.flow_code : '' },
+          { key: 'works_flow_name', value: flow ? flow.flow_name : '' },
+          { key: 'works_flow_param', value: msg },
+          { key: 'works_flow_detail_id', value: detailId },
+          { key: 'status', value: status },
+          { key: 'statusname', value: statusName },
+          { key: 'work_group', value: sessionStorage.getItem('work_group') || '' },
+          { key: 'work_grade', value: sessionStorage.getItem('work_grade') || 0 },
+          // { key: 'check_type', value: btn.verify.flowType === 'reject' ? '椹冲洖' : '瀹℃牳' },
+          // { key: 'notice_type', value: '鎶勯��' },
+          { key: 'check_userids', value: checkIds.join(',') },
+          { key: 'notice_userids', value: noticeIds.join(',') },
+          { key: 'works_flow_sign', value: sign },
+        )
+      }
+    }
+
+    let md5_id = ''
+    if (window.GLOB.probation) {
+      md5_id = md5(ex.id + JSON.stringify(exps) + Math.floor(new Date().getTime() / 600000))
+      md5_id = moment().format('YYYYMMDDHHmmss') + md5_id.slice(-18)
+    }
+
+    return {
+      $backend: true,
+      $type: 's_TableData_InUpDe',
+      data: [{
+        id: ex.id,
+        menuname: btn.logLabel || '',
+        exps: exps,
+        md5_id: md5_id
+      }]
+    }
+  }
+
   getInnerParam = (data, formdata, retmsg) => {
     const { setting, btn, columns } = this.props
     let _params = []
@@ -744,7 +1192,7 @@
       let primaryId = ''
 
       if ((btn.Ot === 'requiredSgl' || btn.Ot === 'requiredOnce') && setting.primaryKey) {
-        let ids = data.map(d => { return d[setting.primaryKey] || ''})
+        let ids = data.map(d => d.$$uuid)
         ids = ids.filter(Boolean)
         primaryId = ids.join(',')
 
@@ -763,7 +1211,10 @@
         param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
       }
 
-      if (retmsg) {
+      if (btn.callbackType === 'script' && window.backend && window.GLOB.CacheData.has('sql_back_' + btn.uuid)) {
+        let _backex = window.GLOB.CacheData.get('sql_back_' + btn.uuid)
+        param.$backParam = this.getExps(_backex, formdata, data[0], primaryId)
+      } else if (retmsg) {
         param.$callbacksql = this.getSysDeclareSql(btn, formdata, data[0], columns, this.props.BID)
       }
 
@@ -786,7 +1237,7 @@
           param.dataM = sessionStorage.getItem('dataM') === 'true' ? 'Y' : ''
         }
 
-        let primaryId = setting.primaryKey ? cell[setting.primaryKey] || '' : ''
+        let primaryId = cell.$$uuid || ''
 
         if (btn.OpenType === 'pop') { // 琛ㄥ崟
           if (index !== 0) {
@@ -816,7 +1267,10 @@
           param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
         }
 
-        if (retmsg) {
+        if (btn.callbackType === 'script' && window.backend && window.GLOB.CacheData.has('sql_back_' + btn.uuid)) {
+          let _backex = window.GLOB.CacheData.get('sql_back_' + btn.uuid)
+          param.$backParam = this.getExps(_backex, formdata, cell, primaryId)
+        } else if (retmsg) {
           param.$callbacksql = this.getSysDeclareSql(btn, formdata, cell, columns, this.props.BID)
         }
 
@@ -1006,53 +1460,10 @@
    * @description 鎸夐挳鎻愪氦鎵ц
    */
   execSubmit = (data, _resolve, formdata, force) => {
-    const { setting, btn } = this.props
-    this.moduleParams = null
+    const { btn } = this.props
 
     if (btn.preButton && !force) {
       this.trigger(btn.preButton, data, _resolve, formdata, 0)
-    } else if (btn.verify && btn.verify.invalid === 'true' && setting.dataresource) {
-      MKEmitter.emit('queryModuleParam', btn.$menuId, (param) => {
-        let datasource = setting.dataresource
-        let customScript = setting.customScript || ''
-        let allSearch = Utils.getAllSearchOptions(param.search)
-
-        let regoptions = allSearch.map(item => {
-          return {
-            reg: new RegExp('@' + item.key + '@', 'ig'),
-            value: `'${item.value}'`
-          }
-        })
-
-        regoptions.push({
-          reg: new RegExp('@userName@', 'ig'),
-          value: `'${sessionStorage.getItem('User_Name') || ''}'`
-        }, {
-          reg: new RegExp('@fullName@', 'ig'),
-          value: `'${sessionStorage.getItem('Full_Name') || ''}'`
-        }, {
-          reg: new RegExp('@orderBy@', 'ig'),
-          value: setting.order
-        }, {
-          reg: new RegExp('@pageSize@', 'ig'),
-          value: 10
-        }, {
-          reg: new RegExp('@pageIndex@', 'ig'),
-          value: 1
-        })
-
-        regoptions.forEach(item => {
-          datasource = datasource.replace(item.reg, item.value)
-          customScript = customScript.replace(item.reg, item.value)
-        })
-
-        this.moduleParams = {
-          datasource,
-          customScript
-        }
-
-        this.execRealSubmit(data, _resolve, formdata)
-      })
     } else {
       this.execRealSubmit(data, _resolve, formdata)
     }
@@ -1110,7 +1521,9 @@
     if (btn.intertype === 'system' || btn.intertype === 'inner') { // 绯荤粺鎺ュ彛
       let params = []
 
-      if (btn.intertype === 'system') {
+      if (btn.intertype === 'system' && window.backend && window.GLOB.CacheData.has('sql_' + btn.uuid)) {
+        params = this.getBackSystemParam(data, formdata)
+      } else if (btn.intertype === 'system') {
         params = this.getSystemParam(data, formdata)
         if (btn.returnValue === 'true') {
           params = params.map(item => {
@@ -1170,6 +1583,14 @@
           _resolve()
         })
       } else if (params.length <= 20 && btn.execType !== 'single') {
+        if (window.backend && params[0].$backend && (!btn.verify || (btn.verify.printEnable !== 'true' && !btn.output))) {
+          params = [{
+            $backend: true,
+            $type: 's_TableData_InUpDe',
+            data: params.map(item => item.data[0])
+          }]
+        }
+
         let deffers = params.map((param, i) => {
           return new Promise(resolve => {
             setTimeout(() => {
@@ -1217,7 +1638,9 @@
       /** *********************璋冪敤澶栭儴鎺ュ彛************************* */
       let _params = [] // 璇锋眰鍙傛暟鏁扮粍
 
-      if (btn.procMode === 'system') {
+      if (btn.procMode === 'system' && window.backend && window.GLOB.CacheData.has('sql_' + btn.uuid)) {
+        _params = this.getBackSystemParam(data, formdata)
+      } else if (btn.procMode === 'system') {
         _params = this.getSystemParam(data, formdata, true)
         _params = _params.map(item => {
           item.script_type = 'Y'
@@ -1238,7 +1661,9 @@
     } else if (btn.intertype === 'custom') { // 绯荤粺鎺ュ彛
       let params = []
 
-      if (btn.procMode === 'system') {
+      if (btn.procMode === 'system' && window.backend && window.GLOB.CacheData.has('sql_' + btn.uuid)) {
+        params = this.getBackSystemParam(data, formdata)
+      } else if (btn.procMode === 'system') {
         params = this.getSystemParam(data, formdata, true)
         params = params.map(item => {
           item.script_type = 'Y'
@@ -1274,13 +1699,15 @@
       BID: param.BID || '',
       ID: param.ID || '',
       callbacksql: param.$callbacksql || '',
-      mk_api_key: ''
+      mk_api_key: '',
+      backParam: param.$backParam || ''
     }
 
     if (!record.ID && btn.Ot !== 'notRequired' && param[setting.primaryKey]) {
       record.ID = param[setting.primaryKey]
     }
 
+    delete param.$backParam
     delete param.$callbacksql
 
     if (param.$pice) {
@@ -1290,7 +1717,7 @@
 
       this.customOuterRequest(params, param, record, _resolve)
       return
-    } else if (!param.func) {
+    } else if (!param.func && !param.$backend) {
       this.customOuterRequest(params, param, record, _resolve)
       return
     }
@@ -1344,7 +1771,7 @@
   // Api.directRequest('http://localhost:3001/test.xml', 'get', null, 'true').then(res => {
   //   let $x2js = new x2js()
   //   let jsonObj = $x2js.xml2js(res);
-  //   console.info(jsonObj)
+  //   window.mkInfo(jsonObj)
   // })
 
   /**
@@ -1386,7 +1813,21 @@
       method: btn.method || 'post'
     }
 
-    if (btn.cross === 'true') {
+    if (btn.ContentType) {
+      _params.headers = {
+        'Content-Type': btn.ContentType
+      }
+    }
+
+    if (btn.$outerScript) {
+      if (JSON.stringify(param) !== '{}') {
+        if (btn.stringify === 'qs') {
+          _params.data = qs.stringify(param)
+        } else {
+          _params.data = param
+        }
+      }
+    } else if (btn.cross === 'true') {
       if (JSON.stringify(param) !== '{}') {
         if (btn.stringify === 'qs') {
           _params.data = qs.stringify(param)
@@ -1420,13 +1861,7 @@
       _params.method = 'post'
     }
 
-    if (btn.ContentType) {
-      _params.headers = {
-        'Content-Type': btn.ContentType
-      }
-    }
-
-    Api.directRequest(_params).then(res => {
+    Api.directRequest(_params, btn.$outerScript, 'outer').then(res => {
       if (typeof(res) !== 'object') {
         let error = '鏈煡鐨勮繑鍥炵粨鏋滐紒'
 
@@ -1493,6 +1928,8 @@
         _resolve()
       }
       return
+    } else if (btn.callbackType === 'script' && record.backParam) {
+      param = this.getCallBackendParam(result, record)
     } else if (btn.callbackType === 'script' || btn.callbackType === 'default') {
       param = this.getCallBackSql(result, record)
     } else if (btn.callbackType === 'func') {
@@ -1556,6 +1993,108 @@
     })
   }
 
+  getCallBackendParam = (result, record) => {
+    const { btn } = this.props
+    let lines = []
+    let tables = []
+    let param = fromJS(record.backParam).toJS()
+
+    btn.verify.cbScripts.forEach(script => {
+      if (script.status === 'false') return
+
+      if (/\s#[a-z0-9_]+(\s|\()/ig.test(script.sql)) {
+        tables.push(...script.sql.match(/\s#[a-z0-9_]+(\s|\()/ig))
+      }
+    })
+
+    tables = tables.map(tb => tb.replace(/\s|\(/g, ''))
+
+    if (result.$ErrCode) {
+      delete result.$ErrCode
+      delete result.$ErrMesg
+    }
+
+    let getDefaultSql = (obj, tb, bid, level) => {
+      let vals = {}
+      let subObjs = []
+      let id = Utils.getuuid()
+
+      delete obj.$$key
+
+      Object.keys(obj).forEach(key => {
+        let val = obj[key]
+        if (val === null || val === undefined) return
+        if (typeof(val) === 'object') {
+          if (Array.isArray(val)) {
+            val.forEach(item => {
+              if (typeof(item) !== 'object' || Array.isArray(item)) return
+              if (Object.keys(item).length === 0) return
+
+              Object.keys(item).forEach(k => {
+                if (item[k] === null) {
+                  item[k] = ''
+                }
+              })
+              item.$$key = tb + '_' + key
+              subObjs.push(item)
+            })
+          } else if (Object.keys(val).length > 0) {
+            val.$$key = tb + '_' + key
+            subObjs.push(val)
+          }
+        } else {
+          if (typeof(val) === 'string') {
+            val = val.replace(/'/ig, '"')
+          } else {
+            val = val + ''
+          }
+          vals[key] = val
+        }
+      })
+
+      vals.mk_level = level
+      vals.mk_id = id
+      vals.mk_bid = bid
+
+      let isnew = true
+      lines.forEach(line => {
+        if (line.tb === tb) {
+          line.values.push(vals)
+          isnew = false
+        }
+      })
+      if (isnew) {
+        lines.push({
+          tb: tb,
+          type: tables.includes('#' + tb) ? '01' : '02',
+          values: [vals]
+        })
+      }
+
+      subObjs.forEach(item => {
+        getDefaultSql(item, item.$$key, id, level + 1)
+      })
+    }
+    
+    getDefaultSql(result, btn.cbTable, '', 1)
+
+    param.data[0].exps.push({
+      key: 'mk_outer_params',  // 鍥炶皟鑴氭湰鐨勬暟鎹浛鎹�
+      value: lines
+    })
+
+    let md5_id = ''
+    if (window.GLOB.probation) {
+      md5_id = md5('back_' + btn.uuid + JSON.stringify(param.data[0].exps) + Math.floor(new Date().getTime() / 600000))
+      md5_id = moment().format('YYYYMMDDHHmmss') + md5_id.slice(-18)
+    }
+
+    param.data[0].md5_id = md5_id
+    param.data[0].menuname = btn.logLabel + '(鍥炶皟)'
+
+    return param
+  }
+
   getCallBackSql = (result, record) => {
     const { btn } = this.props
     let lines = []
@@ -1606,10 +2145,15 @@
           if (Array.isArray(val)) {
             val.forEach(item => {
               if (typeof(item) !== 'object' || Array.isArray(item)) return
-              if (Object.keys(item).length > 0) {
-                item.$$key = tb + '_' + key
-                subObjs.push(item)
-              }
+              if (Object.keys(item).length === 0) return
+
+              Object.keys(item).forEach(k => {
+                if (item[k] === null) {
+                  item[k] = ''
+                }
+              })
+              item.$$key = tb + '_' + key
+              subObjs.push(item)
             })
           } else if (Object.keys(val).length > 0) {
             val.$$key = tb + '_' + key
@@ -1723,8 +2267,8 @@
       }
 
       if (window.GLOB.debugger === true) {
-        console.info('%c' + btn.logLabel + '(鍥炶皟)', 'color: blue')
-        console.info(sql.replace(/\n\s{8}/ig, '\n'))
+        window.mkInfo('%c' + btn.logLabel + '(鍥炶皟)', 'color: blue')
+        window.mkInfo(sql.replace(/\n\s{8}/ig, '\n'))
       }
 
       param.LText = sql
@@ -1758,7 +2302,7 @@
           `)}
         `))
         sql = sql.join('')
-        console.info(sql.replace(/\n\s{10}/ig, '\n'))
+        window.mkInfo(sql.replace(/\n\s{10}/ig, '\n'))
       }
     }
 
@@ -1825,7 +2369,7 @@
           msg = msg.replace(/\n|\r/ig, '<br/>')
           msg = <span dangerouslySetInnerHTML={{__html: msg}}></span>
         }
-        const _this = this
+        const that = this
         confirm({
           title: window.GLOB.dict['exec_sure'] || '璇风‘璁�',
           content: msg,
@@ -1835,16 +2379,16 @@
             return new Promise(resolve => {
               Api.genericInterface(unCheckParam).then(result => {
                 if (result.status) {
-                  _this.triggerNote(result, param.ID) // 娑堟伅
+                  that.triggerNote(result, param.ID) // 娑堟伅
           
                   if (params.length === 0) {
-                    _this.execSuccess(result)
+                    that.execSuccess(result)
                     _resolve()
                   } else {
-                    _this.checkLoopRequest(params, _resolve)
+                    that.checkLoopRequest(params, _resolve)
                   }
                 } else {
-                  _this.execError(result)
+                  that.execError(result)
                   _resolve()
                 }
                 resolve()
@@ -1852,7 +2396,7 @@
             })
           },
           onCancel() {
-            _this.execError(res)
+            that.execError(res)
             _resolve()
           }
         })
@@ -1882,16 +2426,18 @@
     let record = {
       BID: param.BID || '',
       ID: param.ID || '',
-      callbacksql: param.$callbacksql || ''
+      callbacksql: param.$callbacksql || '',
+      backParam: param.$backParam || ''
     }
 
     if (!record.ID && btn.Ot !== 'notRequired' && param[setting.primaryKey]) {
       record.ID = param[setting.primaryKey]
     }
 
+    delete param.$backParam
     delete param.$callbacksql
 
-    if (!param.func) {
+    if (!param.func && !param.$backend) {
       this.outerOuterRequest(params, param, record, _resolve)
       return
     }
@@ -2045,6 +2591,8 @@
         _resolve()
       }
       return
+    } else if (btn.callbackType === 'script' && record.backParam) {
+      param = this.getCallBackendParam(result, record)
     } else if (btn.callbackType === 'script' || btn.callbackType === 'default') {
       param = this.getCallBackSql(result, record)
     } else if (btn.callbackType === 'func' || btn.callbackFunc) {
@@ -2170,6 +2718,7 @@
               _resolve()
             } else {
               if (params.length === 0) {
+                this.clearBackCache()
                 this.execSuccess(res)
                 _resolve()
               } else {
@@ -2191,6 +2740,7 @@
               _resolve()
             } else {
               if (params.length === 0) {
+                this.clearBackCache()
                 this.execSuccess(res)
                 _resolve()
               } else {
@@ -2207,6 +2757,7 @@
           _resolve()
         } else {
           if (params.length === 0) {
+            this.clearBackCache()
             this.execSuccess(re)
             _resolve()
           } else {
@@ -2215,6 +2766,34 @@
         }
       })
     }
+  }
+
+  clearBackCache = () => {
+    if (!window.GLOB.backend) return
+
+    Api.cacheInterface({userid: sessionStorage.getItem('UserID') || '', LoginUID: sessionStorage.getItem('LoginUID') || ''}).then(res => {
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message || '缂撳瓨娓呯┖澶辫触锛�',
+          duration: 5
+        })
+      } else if (window.GLOB.localSystemApi) {
+        Api.cacheInterface({
+          userid: sessionStorage.getItem('LocalUserID') || sessionStorage.getItem('UserID') || '',
+          LoginUID: sessionStorage.getItem('LocalLoginUID') || sessionStorage.getItem('LoginUID') || '',
+          rduri: window.GLOB.localSystemApi.replace('dostars', 'excache')
+        }).then(result => {
+          if (!result.status) {
+            notification.warning({
+              top: 92,
+              message: result.message || '缂撳瓨娓呯┖澶辫触锛�',
+              duration: 5
+            })
+          }
+        })
+      }
+    })
   }
 
   /**
@@ -2289,9 +2868,9 @@
         res.ErrCode = '-1'
       }
     }
-    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, '')
+    if (/@close_tab@|@close_popup@|@goback@|@no_target_menu@|@open_target_menu@/i.test(res.message)) {
+      sign = res.message.match(/@close_tab@|@close_popup@|@goback@|@no_target_menu@|@open_target_menu@/i)[0].toLowerCase()
+      res.message = res.message.replace(/@close_tab@|@close_popup@|@goback@|@no_target_menu@|@open_target_menu@/i, '')
     }
 
     let id = ''
@@ -2359,12 +2938,8 @@
       tabId = btn.refreshTab[btn.refreshTab.length - 1]
     }
 
-    // if (btn.formCache === 'clear') { // 娓呴櫎琛ㄥ崟缂撳瓨
-    //   window.GLOB.CacheMap = new Map()
-    // }
-
     if (tabId && btn.$MenuID === tabId) { // 鍒锋柊褰撳墠鑿滃崟鏃讹紝鍋滄鍏朵粬鎿嶄綔
-      MKEmitter.emit('reloadMenuView', tabId, 'table')
+      MKEmitter.emit('reloadMenuView', tabId)
       return
     }
 
@@ -2406,7 +2981,7 @@
     }
 
     if (tabId) {
-      MKEmitter.emit('reloadMenuView', tabId, 'table')
+      MKEmitter.emit('reloadMenuView', tabId)
     }
     
     if (btn.switchTab && btn.switchTab.length > 0) {
@@ -2552,10 +3127,30 @@
   }
 
   sendWxMessage = (verify, id) => {
-    if (!window.GLOB.nginx) {
+    let domain = window.GLOB.baseurl
+    let appId = window.GLOB.WXAppID || ''
+
+    if (verify.wxAppId && verify.wxAppId !== appId) {
+      appId = verify.wxAppId
+      if (!window.GLOB.WXApps || window.GLOB.WXApps.findIndex(item => item.appId === verify.wxAppId) === -1) {
+        notification.warning({
+          top: 92,
+          message: '鎸夐挳鍏宠仈鍏紬鍙蜂笉鍦ㄥ彲鐢ㄥ垪琛ㄤ腑锛岃閲嶆柊淇濆瓨鎸夐挳閰嶇疆锛�',
+          duration: 5
+        })
+        return
+      }
+    }
+    
+    if (['8IFltwzyKcu15iA8fqSyb6m-pMa88a3ZTu0No3vDHgo', 'LOB-bbt9jVncGh7IOAUdESh1Sgzcbt62UwOqSqcK9ok'].includes(verify.wxTemplateId) && window.GLOB.sysType !== 'cloud') {
+      domain = 'https://cloud.mk9h.cn/'
+      appId = 'wx4d8a34c8d4494872'
+    }
+
+    if (!appId) {
       notification.warning({
         top: 92,
-        message: 'nginx鏈嶅姟灏氭湭寮�鍚紝涓嶅彲鍙戦�佹ā鏉挎秷鎭��',
+        message: '灏氭湭娣诲姞鍏紬鍙稩D锛屼笉鍙彂閫佹ā鏉挎秷鎭��',
         duration: 5
       })
       return
@@ -2569,13 +3164,6 @@
     param.LText = Utils.getuuid()
     param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
     param.secretkey = Utils.encrypt(param.LText, param.timestamp)
-
-    let domain1 = ''
-    let domain2 = ''
-    if (['8IFltwzyKcu15iA8fqSyb6m-pMa88a3ZTu0No3vDHgo', 'LOB-bbt9jVncGh7IOAUdESh1Sgzcbt62UwOqSqcK9ok'].includes(verify.wxTemplateId) && window.GLOB.sysType !== 'cloud') {
-      domain1 = 'https://cloud.mk9h.cn/'
-      domain2 = 'https://cloud.mk9h.cn:8443/'
-    }
 
     Api.genericInterface(param).then(res => {
       // res.send_data = [{openid: 'o2E7gvoSFvQRG7I8_gZxf4y3ONkQ', send_id: Utils.getuuid(), p1: '010000000001', p2: '鏄庣', p3: 'dddd', p4: '椤洪', p5: '鎴愬姛'}]
@@ -2639,62 +3227,63 @@
         return m
       })
 
-      Api.wxAccessToken(domain1).then(res => {
-        if (!res.oa_access_token) return
-  
-        params.forEach(n => {
-          Api.wxNginxRequest(`${domain2}cgi-bin/message/template/send?access_token=${res.oa_access_token}`, 'post', JSON.stringify(n)).then(re => {
-            if (verify.wxNoteCallback === 'true') {
-              let msg = re.errmsg || ''
+      // cgi-bin/message/template/send
+      params.forEach(n => {
+        Api.directRequest({
+          url: domain + 'wechat/send?appid=' + appId,
+          method: 'post',
+          data: JSON.stringify(n)
+        }).then(re => {
+          if (verify.wxNoteCallback === 'true') {
+            let msg = re.errmsg || ''
 
-              if (msg.length > 50) {
-                msg = msg.substr(0, 50)
-              }
-
-              let _p = {
-                func: 's_get_sms_weixin_local_suc_err',
-                upid: id,
-                send_id: n.client_msg_id || '',
-                status_result: re.errcode === 0 ? 'S' : 'E',
-                errcode: re.errcode,
-                msg_result: msg
-              }
-
-              _p.LText = Utils.getuuid()
-              _p.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-              _p.secretkey = Utils.encrypt(_p.LText, _p.timestamp)
-
-              Api.genericInterface(_p).then(result => {
-                if (!result.status) {
-                  notification.warning({
-                    top: 92,
-                    message: result.message,
-                    duration: 5
-                  })
-                }
-              })
-            } else if (re.errcode !== 0 && re.errmsg) {
-              let msgs = [
-                {errcode: -1, errmsg: '绯荤粺绻佸繖锛岃绋嶅�欏啀璇�'},
-                {errcode: 40001, errmsg: 'access_token 鏃犳晥'},
-                {errcode: 40003, errmsg: '涓嶅悎娉曠殑 OpenID'},
-                {errcode: 40014, errmsg: '涓嶅悎娉曠殑 access_token'},
-                {errcode: 40033, errmsg: '涓嶅悎娉曠殑璇锋眰瀛楃'},
-                {errcode: 43004, errmsg: '闇�瑕佹帴鏀惰�呭叧娉�'},
-                {errcode: 43019, errmsg: '闇�瑕佸皢鎺ユ敹鑰呬粠榛戝悕鍗曚腑绉婚櫎'},
-                {errcode: 50005, errmsg: '鐢ㄦ埛鏈叧娉ㄥ叕浼楀彿'}
-              ]
-
-              let msg = msgs.filter(m => m.errcode === re.errcode)[0]
-              msg = msg || re
-
-              notification.warning({
-                top: 92,
-                message: msg.errmsg,
-                duration: 5
-              })
+            if (msg.length > 50) {
+              msg = msg.substr(0, 50)
             }
-          })
+
+            let _p = {
+              func: 's_get_sms_weixin_local_suc_err',
+              upid: id,
+              send_id: n.client_msg_id || '',
+              status_result: re.errcode === 0 ? 'S' : 'E',
+              errcode: re.errcode,
+              msg_result: msg
+            }
+
+            _p.LText = Utils.getuuid()
+            _p.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+            _p.secretkey = Utils.encrypt(_p.LText, _p.timestamp)
+
+            Api.genericInterface(_p).then(result => {
+              if (!result.status) {
+                notification.warning({
+                  top: 92,
+                  message: result.message,
+                  duration: 5
+                })
+              }
+            })
+          } else if (re.errcode !== 0 && re.errmsg) {
+            let msgs = [
+              {errcode: -1, errmsg: '绯荤粺绻佸繖锛岃绋嶅�欏啀璇�'},
+              {errcode: 40001, errmsg: 'access_token 鏃犳晥'},
+              {errcode: 40003, errmsg: '涓嶅悎娉曠殑 OpenID'},
+              {errcode: 40014, errmsg: '涓嶅悎娉曠殑 access_token'},
+              {errcode: 40033, errmsg: '涓嶅悎娉曠殑璇锋眰瀛楃'},
+              {errcode: 43004, errmsg: '闇�瑕佹帴鏀惰�呭叧娉�'},
+              {errcode: 43019, errmsg: '闇�瑕佸皢鎺ユ敹鑰呬粠榛戝悕鍗曚腑绉婚櫎'},
+              {errcode: 50005, errmsg: '鐢ㄦ埛鏈叧娉ㄥ叕浼楀彿'}
+            ]
+
+            let msg = msgs.filter(m => m.errcode === re.errcode)[0]
+            msg = msg || re
+
+            notification.warning({
+              top: 92,
+              message: msg.errmsg,
+              duration: 5
+            })
+          }
         })
       })
     })
@@ -3016,9 +3605,9 @@
       if (!res.message) {
         res.ErrCode = '-1'
       }
-    } else if (/@close_tab@|@close_popup@|@goback@/i.test(res.message)) {
-      sign = res.message.match(/@close_tab@|@close_popup@|@goback@/i)[0].toLowerCase()
-      res.message = res.message.replace(/@close_tab@|@close_popup@|@goback@/i, '')
+    } else if (/@close_tab@|@close_popup@|@goback@|@open_target_menu@/i.test(res.message)) {
+      sign = res.message.match(/@close_tab@|@close_popup@|@goback@|@open_target_menu@/i)[0].toLowerCase()
+      res.message = res.message.replace(/@close_tab@|@close_popup@|@goback@|@open_target_menu@/i, '')
     }
 
     if (res.ErrCode === 'E') {
@@ -3091,7 +3680,7 @@
         tabId = btn.refreshTab[btn.refreshTab.length - 1]
       }
       if (tabId && btn.$MenuID === tabId) { // 鍒锋柊褰撳墠鑿滃崟鏃讹紝鍋滄鍏朵粬鎿嶄綔
-        MKEmitter.emit('reloadMenuView', tabId, 'table')
+        MKEmitter.emit('reloadMenuView', tabId)
         return
       }
 
@@ -3123,7 +3712,7 @@
       }
 
       if (tabId) {
-        MKEmitter.emit('reloadMenuView', tabId, 'table')
+        MKEmitter.emit('reloadMenuView', tabId)
       }
     }
 
@@ -3147,6 +3736,35 @@
 
     if (window.GLOB.breakpoint) {
       MKEmitter.emit('refreshDebugTable')
+    }
+
+    if (sign === '@open_target_menu@' && btn.openmenu && Array.isArray(btn.openmenu) && btn.openmenu.length > 0) {
+      let id = ''
+      if (this.state.selines && this.state.selines.length > 0 && btn.Ot !== 'notRequired') {
+        if (btn.Ot === 'requiredOnce') {
+          id = this.state.selines.map(d => d.$$uuid).filter(Boolean).join(',')
+        } else {
+          id = this.state.selines[0].$$uuid
+        }
+      }
+
+      let menuId = btn.openmenu.slice(-1)[0]
+      let menu = null
+
+      if (window.GLOB.mkThdMenus.has(menuId)) {
+        menu = {...window.GLOB.mkThdMenus.get(menuId), param: { $BID: id || '' }}
+      } else if (btn.MenuID) {
+        menu = {
+          MenuID: btn.MenuID,
+          MenuName: btn.MenuName,
+          type: btn.tabType,
+          param: { $BID: id || '' }
+        }
+      }
+
+      if (menu) {
+        MKEmitter.emit('modifyTabs', menu, true)
+      }
     }
 
     if (btn.execError === 'popclose' && btn.$tabId) { // 鏍囩鍏抽棴鍒锋柊
@@ -3283,7 +3901,7 @@
   modelconfirm = () => {
     const { BID } = this.props
     const { btnconfig, selines, dict } = this.state
-    let _this = this
+    let that = this
 
     let result = []
     let _data = {}
@@ -3431,12 +4049,12 @@
         cancelText: dict['cancel'] || '鍙栨秷',
         onOk() {
           return new Promise(resolve => {
-            _this.execSubmit(selines, resolve, result)
+            that.execSubmit(selines, resolve, result)
           })
         },
         onCancel() {
-          _this.preCallback && _this.preCallback()
-          _this.setState({ loading: false })
+          that.preCallback && that.preCallback()
+          that.setState({ loading: false })
         }
       })
     }
diff --git a/src/tabviews/zshare/actionList/popupbutton/index.jsx b/src/tabviews/zshare/actionList/popupbutton/index.jsx
index c6a9e99..8ef0d17 100644
--- a/src/tabviews/zshare/actionList/popupbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/popupbutton/index.jsx
@@ -184,7 +184,7 @@
       visible: true
     })
 
-    if (window.GLOB.systemType === 'production') {
+    if (window.GLOB.systemType === 'production') { // positecgroup
       MKEmitter.emit('queryTrigger', {menuId: btn.uuid, name: '寮圭獥锛堟爣绛撅級'})
     }
   }
diff --git a/src/tabviews/zshare/actionList/printbutton/index.jsx b/src/tabviews/zshare/actionList/printbutton/index.jsx
index 6d2e96c..fd2771a 100644
--- a/src/tabviews/zshare/actionList/printbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -8,6 +8,7 @@
 import Utils from '@/utils/utils.js'
 import asyncSpinComponent from '@/utils/asyncSpinComponent'
 import { updateForm } from '@/utils/utils-update.js'
+import UtilsDM from '@/utils/utils-datamanage.js'
 import MKEmitter from '@/utils/events.js'
 import MkIcon from '@/components/mk-icon'
 // import './index.scss'
@@ -150,7 +151,7 @@
 
     this.setState({autoMatic: type === 'autoMatic'})
 
-    let _this = this
+    let that = this
     let data = record || selectedData || []
 
     if (btn.Ot !== 'notRequired' && data.length === 0) {
@@ -194,17 +195,17 @@
         okText: dict['ok'] || '纭畾',
         cancelText: dict['cancel'] || '鍙栨秷',
         onOk() {
-          _this.triggerPrint(data)
+          that.triggerPrint(data)
         },
         onCancel() {
-          _this.setState({ loading: false })
+          that.setState({ loading: false })
         }
       })
     } else {
       this.triggerPrint(data)
     }
 
-    if (window.GLOB.systemType === 'production') {
+    if (window.GLOB.systemType === 'production') { // positecgroup
       MKEmitter.emit('queryTrigger', {menuId: btn.uuid, name: '鏍囩鎵撳嵃'})
     }
   }
@@ -922,7 +923,7 @@
           Promise.all(deffers).then(result => {
             let errorMsg = ''
             result.forEach(res => {
-              if (!res.status) {
+              if (!res.status && !errorMsg) {
                 errorMsg = res
               }
             })
@@ -947,6 +948,65 @@
    */
   getDefaultSql = (formlist, data, ID) => {
     const { BID, btn, columns } = this.props
+
+    if (window.backend && window.GLOB.CacheData.has('sql_' + btn.uuid)) {
+      let setting = {...btn.verify.setting}
+      setting.interType = 'system'
+      setting.uuid = btn.uuid
+
+      let _param = UtilsDM.getQueryDataParams(setting, [], setting.order, 1, 9999, BID, ID)
+      let item = window.GLOB.CacheData.get('sql_' + btn.uuid)
+
+      _param.data[0].exps = _param.data[0].exps.filter(n => n.key !== 'mk_search')
+      let formkeys = []
+
+      formlist.forEach(form => {
+        if (!item.reps.includes(form.key)) return
+
+        formkeys.push(form.key)
+
+        let val = form.value
+        if (form.type === 'number' || form.type === 'rate') {
+          if (isNaN(val)) {
+            val = 0
+          }
+        } else if (['date', 'datemonth'].includes(form.type)) {
+          val = val || '1949-10-01'
+        }
+
+        _param.data[0].exps.push({
+          key: 'mk_' + form.key + '_mk',
+          value: val
+        })
+      })
+
+      if (data && columns && columns.length > 0) {
+        let datavars = {}
+  
+        Object.keys(data).forEach(key => {
+          datavars[key.toLowerCase()] = data[key]
+        })
+    
+        columns.forEach(col => {
+          if (!item.reps.includes(col.field) || formkeys.includes(col.field)) return
+          if (!col.datatype) return
+  
+          let _key = col.field.toLowerCase()
+          let _val = datavars.hasOwnProperty(_key) ? datavars[_key] : ''
+  
+          if (/^date/ig.test(col.datatype) && !_val) {
+            _val = '1949-10-01'
+          }
+
+          _param.data[0].exps.push({
+            key: 'mk_' + col.field + '_mk',
+            value: _val
+          })
+        })
+      }
+
+      return _param
+    }
 
     let arrFields = btn.verify.columns.map(col => col.field).join(',')
 
@@ -1036,8 +1096,6 @@
     // 鑾峰彇瀛楁閿�煎
     formlist.forEach(form => {
       let _key = form.key.toLowerCase()
-
-      if (_vars.includes(_key)) return
 
       _vars.push(_key)
 
@@ -1160,8 +1218,8 @@
 
     // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
     if (window.GLOB.debugger === true) {
-      _customScript && console.info(`${btn.logLabel ? `/*${btn.logLabel} 鑷畾涔夎剼鏈�*/\n` : ''}${LText ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${_customScript}`)
-      LText && console.info(`${btn.logLabel ? `/*${btn.logLabel} 鏁版嵁婧�*/\n` : ''}` + LText.replace(/\n\s{8}/ig, '\n'))
+      _customScript && window.mkInfo(`${btn.logLabel ? `/*${btn.logLabel} 鑷畾涔夎剼鏈�*/\n` : ''}${LText ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${_customScript}`)
+      LText && window.mkInfo(`${btn.logLabel ? `/*${btn.logLabel} 鏁版嵁婧�*/\n` : ''}` + LText.replace(/\n\s{8}/ig, '\n'))
     }
 
     if (btn.logLabel) {
@@ -1435,8 +1493,13 @@
           if (item.Field) {
             fields.push(item.Field)
             // 鏉$爜浜岀淮鐮佸瓧娈典笉鍙负绌�
-            if (item.Type === 'qrcode' || item.Type === 'barcode') {
+            if (item.Type === 'barcode') {
               nonEFields.push(item.Field)
+            }
+          } else if (!item.Value) {
+            // 鏉$爜浜岀淮鐮佸唴瀹逛笉鍙负绌�
+            if (item.Type === 'barcode') {
+              error = '妯℃澘涓潯鐮�/浜岀淮鐮佸唴瀹逛笉鍙负绌猴紒'
             }
           }
 
@@ -2108,7 +2171,7 @@
 
   modelconfirm = () => {
     const { btnconfig, selines, dict } = this.state
-    let _this = this
+    let that = this
     let result = []
     let _data = {}
     let BData = {}
@@ -2254,10 +2317,10 @@
         okText: dict['ok'] || '纭畾',
         cancelText: dict['cancel'] || '鍙栨秷',
         onOk() {
-          _this.triggerPrint(selines, result)
+          that.triggerPrint(selines, result)
         },
         onCancel() {
-          _this.setState({ loading: false })
+          that.setState({ loading: false })
         }
       })
     }
diff --git a/src/tabviews/zshare/actionList/tabbutton/index.jsx b/src/tabviews/zshare/actionList/tabbutton/index.jsx
index 94322e0..e6c76ac 100644
--- a/src/tabviews/zshare/actionList/tabbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/tabbutton/index.jsx
@@ -213,7 +213,7 @@
       MKEmitter.emit('openNewTab')
     }
 
-    if (window.GLOB.systemType === 'production') {
+    if (window.GLOB.systemType === 'production') { // positecgroup
       MKEmitter.emit('queryTrigger', {menuId: btn.uuid, name: '鏍囩椤�'})
     }
   }
@@ -300,7 +300,7 @@
       MKEmitter.emit('openNewTab')
     }
 
-    if (window.GLOB.systemType === 'production') {
+    if (window.GLOB.systemType === 'production') { // positecgroup
       MKEmitter.emit('queryTrigger', {menuId: btn.uuid, name: '鏍囩椤�'})
     }
   }
diff --git a/src/tabviews/zshare/fileupload/index.jsx b/src/tabviews/zshare/fileupload/index.jsx
index ebf75f0..e061bd3 100644
--- a/src/tabviews/zshare/fileupload/index.jsx
+++ b/src/tabviews/zshare/fileupload/index.jsx
@@ -1,10 +1,8 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import moment from 'moment'
 import { Upload, Button, Progress, notification } from 'antd'
 import { UploadOutlined } from '@ant-design/icons'
-import SparkMD5 from 'spark-md5'
 
 import Api from '@/api'
 import MKEmitter from '@/utils/events.js'
@@ -195,44 +193,6 @@
     })
   }
 
-  shardupload = (param, file_name) => {
-    let form = new FormData()
-
-    form.append('file', param.binary)
-    form.append('fileMd5', param.fileMd5)
-    form.append('shardingMd5', param.fileMd5)
-    form.append('baseDomain', window.GLOB.baseurl)
-    form.append('rootPath', 'Content/images/upload/')
-    form.append('fileName', param.fileName)
-    form.append('fileExt', param.fileType)
-    form.append('shardingCnt', 1)
-    form.append('shardingNo', 1)
-    form.append('LoginUID', sessionStorage.getItem('LoginUID') || '')
-    form.append('UserID', sessionStorage.getItem('UserID') || '')
-
-    Api.getLargeFileUpload(form).then(res => {
-      if (res.status) {
-        if (res.urlPath) {
-          this.onUpdate(res.urlPath, file_name)
-        } else {
-          this.onFail()
-        }
-        this.setState({
-          percent: 100
-        }, () => {
-          setTimeout(() => {
-            this.setState({
-              showprogress: false,
-              percent: 0
-            })
-          }, 200)
-        })
-      } else {
-        this.onFail(res.message)
-      }
-    })
-  }
-
   getuuid = () => {
     let uuid = []
     let _options = '0123456789abcdefghigklmnopqrstuv'
@@ -406,49 +366,31 @@
       return false
     }
 
-    // 鍏煎鎬х殑澶勭悊
-    let spark = new SparkMD5.ArrayBuffer()         // 瀵筧rrayBuffer鏁版嵁杩涜md5鍔犲瘑锛屼骇鐢熶竴涓猰d5瀛楃涓�
-    let totalFileReader = new FileReader()         // 鐢ㄤ簬璁$畻鍑烘�绘枃浠剁殑fileMd5
-    let param = {}
+    let form = new FormData()
 
-    param.fileName = file.name.replace(/\.{1}[^.]*$/ig, '')  // 鏂囦欢鍚嶏紙鍘婚櫎鍚庣紑鍚嶏級
-    param.fileType = file.name.replace(/^.*\.{1}/ig, '')     // 鏂囦欢绫诲瀷
+    form.append('file', file)
 
-    if (!/^[A-Za-z0-9]+$/.test(param.fileName)) {            // 鏂囦欢鍚嶇О鍚湁鑻辨枃鍙婃暟瀛椾箣澶栧瓧绗︽椂锛屽悕绉扮郴缁熺敓鎴�
-      param.fileName = moment().format('YYYYMMDDHHmmss') + this.getuuid()
-    }
-
-    totalFileReader.readAsArrayBuffer(file)
-    totalFileReader.onload = (e) => {   // 瀵规暣涓猼otalFile鐢熸垚md5
-      spark.append(e.target.result)
-      param.fileMd5 = spark.end()       // 璁$畻鏁翠釜鏂囦欢鐨刦ileMd5
-      param.binary = file
-
-      let _param = new FormData()
-      _param.append('fileMd5', param.fileMd5)
-      
-      Api.getFilePreUpload(_param).then(res => {
-        if (res.status && res.urlPath) {
+    Api.getFileUpload(form).then(res => {
+      if (res.status) {
+        if (res.urlPath) {
           this.onUpdate(res.urlPath, file_name)
-          this.setState({
-            percent: 100
-          }, () => {
-            setTimeout(() => {
-              this.setState({
-                showprogress: false,
-                percent: 0
-              })
-            }, 200)
-          })
         } else {
-          this.shardupload(param, file_name)
+          this.onFail()
         }
-      })
-    }
-
-    totalFileReader.onerror = () => {
-      this.onFail('鏂囦欢璇诲彇澶辫触锛�')
-    }
+        this.setState({
+          percent: 100
+        }, () => {
+          setTimeout(() => {
+            this.setState({
+              showprogress: false,
+              percent: 0
+            })
+          }, 200)
+        })
+      } else {
+        this.onFail(res.message)
+      }
+    })
 
     return false
   }
diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx
index d7d6c61..5d4e1e1 100644
--- a/src/tabviews/zshare/mutilform/index.jsx
+++ b/src/tabviews/zshare/mutilform/index.jsx
@@ -4,6 +4,7 @@
 import { Form, Row, Col, notification, Tooltip, Rate } from 'antd'
 import { QuestionCircleOutlined, StarFilled } from '@ant-design/icons'
 import moment from 'moment'
+import md5 from 'md5'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
@@ -69,11 +70,18 @@
     let fieldMap = new Map()
     let check = action.setting.formType === 'check'
 
-    if (this.props.data) {
+    if (this.props.data && !this.props.data.$$empty) {
       Object.keys(this.props.data).forEach(key => {
         data[key.toLowerCase()] = this.props.data[key]
       })
+    } else if (action.uuid && sessionStorage.getItem('local_' + action.uuid)) {
+      let _data = JSON.parse(sessionStorage.getItem('local_' + action.uuid))
+
+      Object.keys(_data).forEach(key => {
+        data[key.toLowerCase()] = _data[key]
+      })
     }
+
     if (this.props.BData) {
       Object.keys(this.props.BData).forEach(key => {
         BData[key.toLowerCase()] = this.props.BData[key]
@@ -133,6 +141,8 @@
       } else if (item.type === 'datetime') {
         item.type = 'date'
         item.precision = 'second'
+      } else if (item.type === 'fileupload') {
+        item.fieldlength = item.fieldlength || 512
       }
 
       if (!item.field || !['text', 'number', 'switch', 'check', 'rate', 'select', 'popSelect', 'link', 'cascader', 'linkMain', 'funcvar', 'date', 'datemonth', 'radio', 'checkbox', 'checkcard', 'fileupload', 'textarea', 'multiselect', 'brafteditor', 'color', 'vercode'].includes(item.type)) return false
@@ -146,6 +156,7 @@
 
       // 鏁版嵁鑷姩濉厖
       let readin = item.readin !== 'false'
+      item.local = item.readin === 'local'
       item.readin = item.readin !== 'false' && item.readin !== 'top'
       item.readonly = check || item.readonly === 'true'
       item.writein = item.writein !== 'false'
@@ -774,7 +785,7 @@
   resetFocus = (id, field) => {
     const { action } = this.props
 
-    if (id !== action.uuid) return
+    if (id !== action.uuid.replace(/_pop$/, '')) return
 
     let focusId = ''
 
@@ -843,7 +854,9 @@
   }
 
   getFormData = (deForms) => {
-    if (deForms.length === 1) {
+    if (window.backend && window.GLOB.CacheData.has('sql_' + md5(this.props.action.uuid.replace(/_pop$/, '') + deForms[0].uuid))) {
+      this.improveBackActionForm(deForms)
+    } else if (deForms.length === 1) {
       this.improveSimpleActionForm(deForms)
     } else if (!window.GLOB.mkHS && window.GLOB.sysType === 'local' && window.GLOB.systemType !== 'production') {
       this.improveSimpleActionForm(deForms)
@@ -852,6 +865,115 @@
     }
   }
 
+  /**
+   * @description 鑾峰彇涓嬫媺琛ㄥ崟閫夐」淇℃伅
+   */
+  improveBackActionForm = (deForms) => {
+    const { BID, action } = this.props
+
+    let sysvals = {
+      mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
+      mk_organization: sessionStorage.getItem('organization') || '',
+      mk_user_type: sessionStorage.getItem('mk_user_type') || '',
+      id: this.state.ID || '',
+      bid: BID || '',
+      datam: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_begin: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      datam_end: sessionStorage.getItem('dataM') === 'true' ? 'Y' : ''
+    }
+    if (window.GLOB.externalDatabase !== null) {
+      sysvals.db = window.GLOB.externalDatabase
+    }
+
+    let deffers = []
+    let mainItems = []  // 浜戠鎴栧崟鐐规暟鎹�
+    let localItems = [] // 鏈湴鏁版嵁
+    let cache = action.setting.cache !== 'false' && !action.$cache
+    let skip = false
+
+    deForms.forEach(item => {
+      let ex = window.GLOB.CacheData.get('sql_' + md5(action.uuid.replace(/_pop$/, '') + item.uuid))
+      
+      if (!ex) {
+        notification.warning({
+          top: 92,
+          message: '琛ㄥ崟锛�' + item.label + '锛夋棤鍙墽琛岃剼鏈��',
+          duration: 5
+        })
+        return
+      }
+      
+      let exps = []
+      ex.reps.forEach(n => {
+        let key = n.toLowerCase()
+        if (sysvals.hasOwnProperty(key)) {
+          exps.push({
+            key: n,
+            value: sysvals[key]
+          })
+        }
+      })
+
+      let cell = {
+        id: ex.id,
+        menuname: item.label + '锛堣〃鍗曪級',
+        exps: exps,
+        md5_id: ''
+      }
+
+      if (item.database === 'sso' && window.GLOB.mainSystemApi) {
+        mainItems.push(cell)
+      } else {
+        localItems.push(cell)
+      }
+    })
+
+    if (localItems.length) {
+      deffers.push({
+        $backend: true,
+        $type: 's_Get_SelectedList',
+        data: localItems
+      })
+    }
+
+    if (mainItems.length) {
+      deffers.push({
+        $backend: true,
+        $type: 's_Get_SelectedList',
+        data: mainItems,
+        rduri: window.GLOB.mainSystemApi
+      })
+    }
+
+    if (!deffers.length) return
+
+    deffers = deffers.map(item => {
+      return new Promise(resolve => {
+        Api.getSystemCacheConfig(item, cache).then(res => {
+          if (!res.status) {
+            notification.warning({
+              top: 92,
+              message: res.message,
+              duration: 5
+            })
+            skip = true
+          }
+          resolve(res)
+        })
+      })
+    })
+
+    Promise.all(deffers).then(response => {
+      let result = {...response[0], ...(response[1] || {})}
+
+      delete result.ErrCode
+      delete result.ErrMesg
+      delete result.message
+      delete result.status
+
+      this.resetFormList(result, skip)
+    })
+  }
   /**
    * @description 鑾峰彇涓嬫媺琛ㄥ崟閫夐」淇℃伅
    */
@@ -876,7 +998,7 @@
         sql = sql.replace(/@BID@/ig, `'${BID}'`)
 
         if (window.GLOB.debugger === true) {
-          console.info(sql)
+          window.mkInfo(sql)
         }
 
         sql = sql.replace(/%/ig, ' mpercent ')
@@ -890,7 +1012,7 @@
         sql = sql.replace(/@BID@/ig, `'${BID}'`)
 
         if (window.GLOB.debugger === true) {
-          console.info(sql)
+          window.mkInfo(sql)
         }
 
         sql = sql.replace(/%/ig, ' mpercent ')
@@ -1014,7 +1136,7 @@
       param.LText = param.LText.replace(/@BID@/ig, `'${this.props.BID || ''}'`)
 
       if (window.GLOB.debugger) {
-        console.info(param.LText)
+        window.mkInfo(param.LText)
       }
 
       if (window.GLOB.execType === 'x') {
@@ -1379,6 +1501,7 @@
   }
 
   handleConfirm = (formId) => {
+    const { action } = this.props
     const { formlist, send_type, timestamp, n_id } = this.state
 
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
@@ -1390,6 +1513,7 @@
         }
         let forms = []
         let record = {...this.record, ...values}
+        let locals = null
 
         formlist.forEach(item => {
           if (!item.field || ['hint', 'split', 'formula'].includes(item.type)) return
@@ -1486,12 +1610,21 @@
               value: n_id || ''
             })
           }
+
+          if (item.local) {
+            locals = locals || {}
+            locals[item.field] = _item.value
+          }
     
           forms.push(_item)
         })
 
         this.submitId = formId || ''
 
+        if (locals) {
+          sessionStorage.setItem('local_' + action.uuid, JSON.stringify(locals))
+        }
+
         resolve(forms)
       })
     })
diff --git a/src/tabviews/zshare/mutilform/index.scss b/src/tabviews/zshare/mutilform/index.scss
index baebc0a..0f49c85 100644
--- a/src/tabviews/zshare/mutilform/index.scss
+++ b/src/tabviews/zshare/mutilform/index.scss
@@ -104,11 +104,6 @@
       min-width: 100px;
     }
   }
-  .normal-braft-editor {
-    border: 1px solid #d9d9d9;
-    border-radius: 4px;
-    overflow-x: hidden;
-  }
   p {
     color: #1890ff;
     font-size: 15px;
diff --git a/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx b/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx
index a7dc070..a73b13c 100644
--- a/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx
+++ b/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx
@@ -28,6 +28,8 @@
       selectKeys = config.initval ? config.initval.split(',') : []
       initlength = selectKeys.length
       selectKeys = this.filterVals(config.options, selectKeys)
+    } else if (config.options[0] && typeof(config.options[0].$value) === 'number' && /^([0-9]|[1-9]\d{0,2})$/.test(config.initval)) {
+      selectKeys = +config.initval
     }
 
     if (!config.selectStyle && config.backgroundColor) {
diff --git a/src/tabviews/zshare/mutilform/mkInput/index.jsx b/src/tabviews/zshare/mutilform/mkInput/index.jsx
index cad739c..9bdbbcf 100644
--- a/src/tabviews/zshare/mutilform/mkInput/index.jsx
+++ b/src/tabviews/zshare/mutilform/mkInput/index.jsx
@@ -85,7 +85,9 @@
     let val = e.target.value
     let submit = /\n/g.test(val)
 
-    val = val.replace(/\n/g, '')
+    if (submit) {
+      val = val.replace(/\n|'/g, '')
+    }
 
     if (submit && /^\s+$/.test(val)) {
       submit = false
diff --git a/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx b/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx
index 4d3b9a4..4b967e2 100644
--- a/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx
+++ b/src/tabviews/zshare/mutilform/mkPopSelect/index.jsx
@@ -121,61 +121,128 @@
       loading: true
     })
 
-    let param = {
-      func: 'sPC_Get_TableData',
-      obj_name: 'data',
-      exec_type: window.GLOB.execType || 'y',
-      arr_field: arr_field,
-      default_sql: 'true',
-      custom_script: '',
-      menuname: config.label
-    }
+    let param = null
+    if (window.backend && window.GLOB.CacheData.has('sql_' + config.uuid)) {
+      let ex = window.GLOB.CacheData.get('sql_' + config.uuid)
+      let sysvals = {
+        time_id: Utils.getguid(),
+        mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
+        mk_organization: sessionStorage.getItem('organization') || '',
+        mk_user_type: sessionStorage.getItem('mk_user_type') || '',
+        id: ID || '',
+        bid: BID || '',
+        datam: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+        datam_begin: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+        datam_end: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+        orderby: orderBy || config.order || '',
+        pagesize: config.laypage === 'true' ? pageSize : '9999',
+        pageindex: pageIndex
+      }
+      if (window.GLOB.externalDatabase !== null) {
+        sysvals.db = window.GLOB.externalDatabase
+      }
 
-    let sql = ''
-    let DateCount = ''
-    let _search = ''
-    let _orderBy = orderBy || config.order || ''
-    let _datasource = config.dataSource
+      let exps = []
 
-    if (config.searchKey && searchKey) {
-      let fields = config.searchKey.split(',').map(field => field + ` like '%${searchKey}%'`)
-      _search = 'where ' + fields.join(' OR ')
-    }
+      if (config.searchKey) {
+        if (!searchKey) {
+          exps.push({
+            key: 'mk_search',
+            value: []
+          })
+        } else {
+          exps.push({
+            key: 'mk_search',
+            value: [{
+              key: config.searchKey,
+              match: '01',
+              type: /,/.test(config.searchKey) ? 'text_or' : 'text',
+              value: searchKey
+            }]
+          })
+        }
+        config.searchKey.split(',').forEach(key => {
+          sysvals[key.toLowerCase()] = searchKey || ''
+        })
+      }
 
-    _datasource = _datasource.replace(/@BID@/ig, `'${BID || ''}'`)
-    _datasource = _datasource.replace(/@ID@/ig, `'${ID || ''}'`)
-
-    if (config.laypage === 'true') {
-      sql = `/*system_query*/select top ${pageSize} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${_orderBy}) as rows from ${_datasource} ${_search}) tmptable where rows > ${pageSize * (pageIndex - 1)} order by tmptable.rows `
-      DateCount = `/*system_query*/select count(1) as total from ${_datasource} ${_search}`
-    } else if (_orderBy) {
-      sql = `/*system_query*/select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${_orderBy}) as rows from ${_datasource} ${_search}) tmptable order by tmptable.rows `
-    } else {
-      sql = `/*system_query*/select ${arr_field} from ${_datasource} ${_search}  `
-    }
-
-    let departmentcode = sessionStorage.getItem('departmentcode') || ''
-    let organization = sessionStorage.getItem('organization') || ''
-    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+      ex.reps.forEach(n => {
+        let key = n.toLowerCase()
+        if (sysvals.hasOwnProperty(key)) {
+          exps.push({
+            key: n,
+            value: sysvals[key]
+          })
+        }
+      })
     
-    sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)
-      Select @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}'
-      ${sql}`
-
-    // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
-    if (window.GLOB.debugger === true) {
-      console.info(`/*${config.label} 鏁版嵁婧�*/\n` + sql.replace(/\n\s{6}/ig, '\n'))
-      DateCount && console.info(`/*${config.label} 鎬绘暟鏌ヨ*/\n` + DateCount.replace(/\n\s{6}/ig, '\n'))
+      param = {
+        $backend: true,
+        $type: 's_Get_TableData',
+        data: [{
+          id: ex.id,
+          menuname: config.label || '',
+          exps: exps,
+          md5_id: ''
+        }]
+      }
+    } else {
+      param = {
+        func: 'sPC_Get_TableData',
+        obj_name: 'data',
+        exec_type: window.GLOB.execType || 'y',
+        arr_field: arr_field,
+        default_sql: 'true',
+        custom_script: '',
+        menuname: config.label
+      }
+  
+      let sql = ''
+      let DateCount = ''
+      let _search = ''
+      let _orderBy = orderBy || config.order || ''
+      let _datasource = config.dataSource
+  
+      if (config.searchKey && searchKey) {
+        let fields = config.searchKey.split(',').map(field => field + ` like '%${searchKey}%'`)
+        _search = 'where ' + fields.join(' OR ')
+      }
+  
+      _datasource = _datasource.replace(/@BID@/ig, `'${BID || ''}'`)
+      _datasource = _datasource.replace(/@ID@/ig, `'${ID || ''}'`)
+  
+      if (config.laypage === 'true') {
+        sql = `/*system_query*/select top ${pageSize} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${_orderBy}) as rows from ${_datasource} ${_search}) tmptable where rows > ${pageSize * (pageIndex - 1)} order by tmptable.rows `
+        DateCount = `/*system_query*/select count(1) as total from ${_datasource} ${_search}`
+      } else if (_orderBy) {
+        sql = `/*system_query*/select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${_orderBy}) as rows from ${_datasource} ${_search}) tmptable order by tmptable.rows `
+      } else {
+        sql = `/*system_query*/select ${arr_field} from ${_datasource} ${_search}  `
+      }
+  
+      let departmentcode = sessionStorage.getItem('departmentcode') || ''
+      let organization = sessionStorage.getItem('organization') || ''
+      let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+      
+      sql = `declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)
+        Select @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}'
+        ${sql}`
+  
+      // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
+      if (window.GLOB.debugger === true) {
+        window.mkInfo(`/*${config.label} 鏁版嵁婧�*/\n` + sql.replace(/\n\s{6}/ig, '\n'))
+        DateCount && window.mkInfo(`/*${config.label} 鎬绘暟鏌ヨ*/\n` + DateCount.replace(/\n\s{6}/ig, '\n'))
+      }
+  
+      param.LText = Utils.formatOptions(sql, param.exec_type)
+      param.DateCount = Utils.formatOptions(DateCount, param.exec_type)
+  
+      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+      param.secretkey = Utils.encrypt('', param.timestamp)
+  
+      param.username = sessionStorage.getItem('User_Name') || ''
+      param.fullname = sessionStorage.getItem('Full_Name') || ''
     }
-
-    param.LText = Utils.formatOptions(sql, param.exec_type)
-    param.DateCount = Utils.formatOptions(DateCount, param.exec_type)
-
-    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-    param.secretkey = Utils.encrypt('', param.timestamp)
-
-    param.username = sessionStorage.getItem('User_Name') || ''
-    param.fullname = sessionStorage.getItem('Full_Name') || ''
 
     Api.genericInterface(param).then(result => {
       if (result.status) {
diff --git a/src/tabviews/zshare/settingcomponent/index.jsx b/src/tabviews/zshare/settingcomponent/index.jsx
index 77e2230..dd87d2c 100644
--- a/src/tabviews/zshare/settingcomponent/index.jsx
+++ b/src/tabviews/zshare/settingcomponent/index.jsx
@@ -316,9 +316,14 @@
         })
       } else if (!links.includes(item.verify.linkUrl)) {
         links.push(item.verify.linkUrl)
+      }
+    })
 
-        let socket = null
-        socket = new WebSocket('ws://' + item.verify.linkUrl)
+    if (links.length === 0) return
+
+    let defers = links.map(link => {
+      return new Promise((resolve) => {
+        let socket = new WebSocket('ws://' + link)
         // 鎵撳紑Socket
         socket.onopen = () =>{
           let request  = {
@@ -360,29 +365,39 @@
               })
             }
 
-            window.GLOB.UserCacheMap.set(item.verify.linkUrl, _printers)
-          } else if (data && data.cmd === 'getPrinters') {
-            notification.warning({
-              top: 92,
-              message: data.message,
-              duration: 5
-            })
+            resolve({status: true, printers: _printers})
+          } else if (data && data.cmd === 'getPrinters' && data.message) {
+            resolve({status: false, printers: null, message: data.message})
           }
         }
 
         socket.onerror = () => {
-          let tool = item.verify.linkUrl
-          if (item.verify.linkUrl === '127.0.0.1:13529') {
+          let tool = link
+
+          if (link === '127.0.0.1:13529') {
             tool = '鏄庣閫氳缁勪欢'
-          } else if (item.verify.linkUrl === '127.0.0.1:13528') {
+          } else if (link === '127.0.0.1:13528') {
             tool = 'CAINIAO鎵撳嵃缁勪欢'
           }
-          notification.warning({
-            top: 92,
-            message: '鏃犳硶杩炴帴鍒�: ' + tool,
-            duration: 5
-          })
+
+          resolve({status: false, printers: null, message: '鏃犳硶杩炴帴鍒�: ' + tool})
+          
         }
+      })
+    })
+
+    Promise.all(defers).then(results => {
+      let res = results.filter(item => item.status)[0]
+      if (res) {
+        links.forEach(link => {
+          window.GLOB.UserCacheMap.set(link, res.printers)
+        })
+      } else {
+        notification.warning({
+          top: 92,
+          message: results[0].message,
+          duration: 5
+        })
       }
     })
   }
diff --git a/src/tabviews/zshare/topSearch/index.jsx b/src/tabviews/zshare/topSearch/index.jsx
index f169891..8d6fe6d 100644
--- a/src/tabviews/zshare/topSearch/index.jsx
+++ b/src/tabviews/zshare/topSearch/index.jsx
@@ -48,6 +48,8 @@
     let fieldMap = new Map()
     let mainItems = []  // 浜戠鎴栧崟鐐规暟鎹�
     let localItems = [] // 鏈湴鏁版嵁
+    let backMItems = [] // 浜戠鎴栧崟鐐规暟鎹�
+    let backLItems = [] // 鏈湴鏁版嵁
     let deForms = []    // 娴嬭瘯绯荤粺锛屽崟涓姹�
     let advanceValues = []
     let linkFields = {}
@@ -55,6 +57,22 @@
     let forbid = false // header涓笉璁剧疆楂樼骇鎼滅储
     let _setting = {showAdv: false, show: false, style: null}
     let BID = this.props.BID
+    let sysvals = {}
+
+    if (window.backend) {
+      sysvals = {
+        mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
+        mk_organization: sessionStorage.getItem('organization') || '',
+        mk_user_type: sessionStorage.getItem('mk_user_type') || '',
+        bid: BID || '',
+        datam: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+        datam_begin: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+        datam_end: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+      }
+      if (window.GLOB.externalDatabase !== null) {
+        sysvals.db = window.GLOB.externalDatabase
+      }
+    }
     
     if (config.wrap) {
       _setting.show = config.wrap.show !== 'false'
@@ -188,43 +206,77 @@
 
         // 鏁版嵁婧愭煡璇㈣鍙�
         if (item.resourceType === '1' && item.dataSource) {
-          let _option = Utils.getSelectQueryOptions(item)
-          let _declare = `Declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)  select @mk_departmentcode='${sessionStorage.getItem('departmentcode') || ''}',@mk_organization='${sessionStorage.getItem('organization') || ''}',@mk_user_type='${sessionStorage.getItem('mk_user_type') || ''}'\n`
+          if (window.backend && window.GLOB.CacheData.has('sql_' + item.uuid)) {
+            let ex = window.GLOB.CacheData.get('sql_' + item.uuid)
+            let exps = []
 
-          let exec = true
-          if (item.checkBid) {
-            item.sql = _declare + _option.sql
-            item.arr_field = _option.field
+            ex.reps.forEach(n => {
+              let key = n.toLowerCase()
+              if (sysvals.hasOwnProperty(key)) {
+                exps.push({
+                  key: n,
+                  value: sysvals[key]
+                })
+              }
+            })
 
-            exec = !!BID
-          }
+            let cell = {
+              id: ex.id,
+              exps: exps,
+              menuname: item.label + '锛堟悳绱級',
+              md5_id: ''
+            }
+            if (item.checkBid) {
+              item.sqlId = ex.id
+              item.exps = exps
+            }
 
-          if (exec) {
-            let _sql = _option.sql.replace(/@BID@/ig, `'${BID || ''}'`)
+            if (item.checkBid && !BID) {
+
+            } else if (item.database === 'sso' && window.GLOB.mainSystemApi) {
+              backMItems.push(cell)
+            } else {
+              backLItems.push(cell)
+            }
+          } else {
+            let _option = Utils.getSelectQueryOptions(item)
+            let _declare = `Declare @mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20)  select @mk_departmentcode='${sessionStorage.getItem('departmentcode') || ''}',@mk_organization='${sessionStorage.getItem('organization') || ''}',@mk_user_type='${sessionStorage.getItem('mk_user_type') || ''}'\n`
   
-            if (window.GLOB.debugger === true) {
-              console.info(_declare + _sql)
+            let exec = true
+            if (item.checkBid) {
+              item.sql = _declare + _option.sql
+              item.arr_field = _option.field
+  
+              exec = !!BID
             }
   
-            // 娴嬭瘯绯荤粺鍗曚釜璇锋眰
-            if (!window.GLOB.mkHS && window.GLOB.sysType === 'local' && !window.GLOB.systemType) {
-              deForms.push({
-                ...item,
-                arr_field: _option.field,
-                data_sql: Utils.formatOptions(_declare + _sql, window.GLOB.execType)
-              })
-            } else { // 鍚堝苟璇锋眰锛屽尯鍒嗘湰鍦板強绯荤粺
-              _sql = _sql.replace(/%/ig, ' mpercent ')
-              if (item.database === 'sso') {
-                if (mainItems.length === 0) {
-                  _sql = _declare + _sql
+            if (exec) {
+              let _sql = _option.sql.replace(/@BID@/ig, `'${BID || ''}'`)
+    
+              if (window.GLOB.debugger === true) {
+                window.mkInfo(_declare + _sql)
+              }
+    
+              // 娴嬭瘯绯荤粺鍗曚釜璇锋眰
+              if (!window.GLOB.mkHS && window.GLOB.sysType === 'local' && !window.GLOB.systemType) {
+                deForms.push({
+                  ...item,
+                  arr_field: _option.field,
+                  data_sql: Utils.formatOptions(_declare + _sql, window.GLOB.execType)
+                })
+              } else { // 鍚堝苟璇锋眰锛屽尯鍒嗘湰鍦板強绯荤粺
+                _sql = _sql.replace(/%/ig, ' mpercent ')
+                if (item.database === 'sso') {
+                  if (mainItems.length === 0) {
+                    _sql = _declare + _sql
+                  }
+                  mainItems.push(`select '${item.field}' as obj_name,'${_option.field}' as arr_field,'${window.btoa(window.encodeURIComponent(_sql))}' as LText`)
+                } else {
+                  if (localItems.length === 0) {
+                    _sql = _declare + _sql
+                  }
+                  localItems.push(`select '${item.field}' as obj_name,'${_option.field}' as arr_field,'${window.btoa(window.encodeURIComponent(_sql))}' as LText`)
                 }
-                mainItems.push(`select '${item.field}' as obj_name,'${_option.field}' as arr_field,'${window.btoa(window.encodeURIComponent(_sql))}' as LText`)
-              } else {
-                if (localItems.length === 0) {
-                  _sql = _declare + _sql
-                }
-                localItems.push(`select '${item.field}' as obj_name,'${_option.field}' as arr_field,'${window.btoa(window.encodeURIComponent(_sql))}' as LText`)
               }
             }
           }
@@ -296,7 +348,9 @@
       advanceValues,
       searchlist: _list
     }, () => {
-      if (!window.GLOB.mkHS && window.GLOB.sysType === 'local' && window.GLOB.systemType !== 'production') {
+      if (window.backend && (backMItems.length > 0 || backLItems.length > 0)) {
+        this.improveBackSearch(backMItems, backLItems, false)
+      } else if (!window.GLOB.mkHS && window.GLOB.sysType === 'local' && window.GLOB.systemType !== 'production') {
         this.improveSimpleSearch(deForms, false, null, BID)
       } else if (mainItems.length > 0 || localItems.length > 0) {
         this.improveSearch(mainItems, localItems, BID)
@@ -337,19 +391,41 @@
 
   resetOptions = (BID) => {
     let deForms = []
+    let backMItems = [] // 浜戠鎴栧崟鐐规暟鎹�
+    let backLItems = [] // 鏈湴鏁版嵁
     let searchlist = fromJS(this.state.searchlist).toJS().map(item => {
       if (item.checkBid) {
-        let sql = item.sql.replace(/@BID@/ig, `'${BID || ''}'`)
-  
-        if (window.GLOB.debugger === true) {
-          console.info(sql)
-        }
+        if (window.backend && item.sqlId) {
+          let cell = {
+            id: item.sqlId,
+            menuname: item.label + '锛堟悳绱級',
+            md5_id: '',
+            exps: item.exps.map(n => {
+              if (n.key === 'BID') {
+                n.value = BID
+              }
+              return n
+            })
+          }
 
-        deForms.push({
-          ...item,
-          arr_field: item.arr_field,
-          data_sql: Utils.formatOptions(sql, window.GLOB.execType)
-        })
+          if (item.database === 'sso' && window.GLOB.mainSystemApi) {
+            backMItems.push(cell)
+          } else {
+            backLItems.push(cell)
+          }
+        } else {
+          let sql = item.sql.replace(/@BID@/ig, `'${BID || ''}'`)
+    
+          if (window.GLOB.debugger === true) {
+            window.mkInfo(sql)
+          }
+  
+          deForms.push({
+            ...item,
+            arr_field: item.arr_field,
+            data_sql: Utils.formatOptions(sql, window.GLOB.execType)
+          })
+        }
       } else if (item.checkShift) {
         let d = ''
         if (window.GLOB.CacheData.has(item.$supId)) {
@@ -387,7 +463,9 @@
       return item
     })
 
-    if (deForms.length > 0) {
+    if (window.backend && (backMItems.length > 0 || backLItems.length > 0)) {
+      this.improveBackSearch(backMItems, backLItems, true, searchlist)
+    } else if (deForms.length > 0) {
       this.improveSimpleSearch(deForms, true, searchlist, BID)
     } else {
       this.setState({
@@ -532,6 +610,54 @@
       delete result.status
 
       this.resetSearch(result, false)
+    })
+  }
+
+  // 鏌ヨ涓嬫媺鑿滃崟
+  improveBackSearch = (mainItems, localItems, trigger, searchlist) => {
+    let deffers = []
+    
+    if (localItems.length) {
+      deffers.push({
+        $backend: true,
+        $type: 's_Get_SelectedList',
+        data: localItems
+      })
+    }
+
+    if (mainItems.length) {
+      deffers.push({
+        $backend: true,
+        $type: 's_Get_SelectedList',
+        data: mainItems,
+        rduri: window.GLOB.mainSystemApi
+      })
+    }
+
+    deffers = deffers.map(item => {
+      return new Promise(resolve => {
+        Api.getSystemCacheConfig(item).then(res => {
+          if (!res.status) {
+            notification.warning({
+              top: 92,
+              message: res.message,
+              duration: 5
+            })
+          }
+          resolve(res)
+        })
+      })
+    })
+
+    Promise.all(deffers).then(response => {
+      let result = {...response[0], ...(response[1] || {})}
+
+      delete result.ErrCode
+      delete result.ErrMesg
+      delete result.message
+      delete result.status
+
+      this.resetSearch(result, trigger, searchlist)
     })
   }
 
@@ -1049,7 +1175,7 @@
         }
 
         if (typeof(val) === 'string') {
-          val = val.replace(/(^\s*|\s*$)/ig, '')
+          val = val.replace(/(^\s+|\s+$)/ig, '').replace(/\t+|\v+/g, '')
         }
 
         search.push({
diff --git a/src/templates/comtableconfig/index.jsx b/src/templates/comtableconfig/index.jsx
index fc3b441..4768e78 100644
--- a/src/templates/comtableconfig/index.jsx
+++ b/src/templates/comtableconfig/index.jsx
@@ -689,13 +689,13 @@
   cancelConfig = () => {
     // const { config, originMenu } = this.state
 
-    // let _this = this
+    // let that = this
 
     // if (config.isAdd) {
     //   confirm({
     //     content: '鑿滃崟灏氭湭鎻愪氦锛岀‘瀹氭斁寮冧繚瀛樺悧锛�',
     //     onOk() {
-    //       _this.props.handleView()
+    //       that.props.handleView()
     //     },
     //     onCancel() {}
     //   })
diff --git a/src/templates/comtableconfig/updatetable/index.jsx b/src/templates/comtableconfig/updatetable/index.jsx
index ed03667..f61593a 100644
--- a/src/templates/comtableconfig/updatetable/index.jsx
+++ b/src/templates/comtableconfig/updatetable/index.jsx
@@ -29,7 +29,7 @@
 
   trigger = () => {
     const { config } = this.props
-    const _this = this
+    const that = this
 
     if (!config.enabled) {
       notification.warning({
@@ -45,7 +45,7 @@
       content: '',
       onOk() {
         return new Promise(resolve => {
-          _this.execUpdate(resolve)
+          that.execUpdate(resolve)
         })
       },
       onCancel() {}
@@ -429,6 +429,40 @@
   
                 if (_LongParam) {
                   _LongParam.uuid = item.uuid
+
+                  if (_LongParam.fields && _LongParam.fields.length === 0 && _LongParam.groups && _LongParam.groups.length > 0) {
+                    _LongParam.groups.forEach(group => {
+                      if (group.sublist && group.sublist.length > 0) {
+                        _LongParam.fields.push({
+                          uuid: Utils.getuuid(),
+                          label: group.label,
+                          field: '',
+                          type: 'split'
+                        })
+                        _LongParam.fields.push(...group.sublist)
+                      }
+                    })
+                  }
+
+                  let span = _LongParam.setting && _LongParam.setting.cols ? (24 / _LongParam.setting.cols) : 12
+                  if (![24, 12, 8].includes(span)) {
+                    span = 12
+                  }
+
+                  if (_LongParam.fields) {
+                    _LongParam.fields = _LongParam.fields.map(n => {
+                      if (!n.span && n.type !== 'split') {
+                        if (['textarea', 'hint', 'checkcard', 'brafteditor'].includes(n.type)) {
+                          n.span = 24
+                        } else {
+                          n.span = span
+                        }
+                      }
+
+                      return n
+                    })
+                  }
+
                   resolve(_LongParam)
                 } else {
                   resolve({uuid: item.uuid, $empty: true})
@@ -577,7 +611,7 @@
 
   saveConfig = (_resolve, _config, errors) => {
     let err = errors.join('锛�')
-    let _this = this
+    let that = this
 
     if (err) {
       _resolve()
@@ -586,7 +620,7 @@
         content: '',
         onOk() {
           return new Promise(resolve => {
-            _this.saveNewMenu(resolve, _config)
+            that.saveNewMenu(resolve, _config)
           })
         },
         onCancel() {}
diff --git a/src/templates/modalconfig/dragelement/card.jsx b/src/templates/modalconfig/dragelement/card.jsx
index da672eb..7e46955 100644
--- a/src/templates/modalconfig/dragelement/card.jsx
+++ b/src/templates/modalconfig/dragelement/card.jsx
@@ -101,7 +101,7 @@
   } else if (card.type === 'textarea') {
     formItem = (<TextArea value={card.initval} placeholder={card.placeholder || ''} autoSize={{ minRows: 2, maxRows: 6 }} />)
   } else if (card.type === 'brafteditor') {
-    formItem = (<Editor />)
+    formItem = (<Editor config={{contHeidht: card.contHeidht}}/>)
   } else if (card.type === 'fileupload') {
     formItem = (<Button style={{marginTop: '3px'}}><UploadOutlined /> 鐐瑰嚮涓婁紶 </Button>)
   } else if (card.type === 'funcvar') {
diff --git a/src/templates/modalconfig/dragelement/index.scss b/src/templates/modalconfig/dragelement/index.scss
index e19cce3..3106857 100644
--- a/src/templates/modalconfig/dragelement/index.scss
+++ b/src/templates/modalconfig/dragelement/index.scss
@@ -113,10 +113,6 @@
           min-width: 100px;
         }
       }
-      .normal-braft-editor {
-        border: 1px solid #d9d9d9;
-        border-radius: 4px;
-      }
     }
     .ant-form-item-control-wrapper::after {
       content: '';
diff --git a/src/templates/modalconfig/index.jsx b/src/templates/modalconfig/index.jsx
index cabfc7d..bbe3611 100644
--- a/src/templates/modalconfig/index.jsx
+++ b/src/templates/modalconfig/index.jsx
@@ -280,15 +280,15 @@
    * @description 琛ㄥ崟鍒犻櫎骞跺埛鏂�
    */
   closeForm = (card) => {
-    let _this = this
+    let that = this
 
     confirm({
       content: `纭畾鍒犻櫎${card.label ? `<<${card.label}>>` : ''}鍚楋紵`,
       onOk() {
-        let _config = fromJS(_this.state.config).toJS()
+        let _config = fromJS(that.state.config).toJS()
         _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid))
 
-        _this.setState({
+        that.setState({
           config: _config,
         })
       },
@@ -379,14 +379,14 @@
 
   cancelConfig = () => {
     // const { config, originConfig } = this.state
-    // let _this = this
+    // let that = this
 
     // let isOrigin = config.fields.filter(item => item.origin).length > 0
     // if (isOrigin) {
     //   confirm({
     //     content: '灏氭湭鎻愪氦锛岀‘瀹氭斁寮冧繚瀛樺悧锛�',
     //     onOk() {
-    //       _this.handleViewBack()
+    //       that.handleViewBack()
     //     },
     //     onCancel() {}
     //   })
@@ -455,7 +455,7 @@
 
   changecols = (type) => {
     let config = fromJS(this.state.config).toJS()
-    let _this = this
+    let that = this
 
     config.fields = config.fields.map(item => {
       item.labelwidth = 33.3
@@ -481,7 +481,7 @@
     confirm({
       content: `纭畾鍒囨崲涓�${type}鍒楀悧锛焋,
       onOk() {
-        _this.setState({config})
+        that.setState({config})
       },
       onCancel() {}
     })
@@ -557,13 +557,13 @@
   }
 
   clearConfig = () => {
-    const _this = this
+    const that = this
     let _config = {...this.state.config, fields: []}
 
     confirm({
       content: '纭畾娓呯┖琛ㄥ崟鍚楋紵',
       onOk() {
-        _this.setState({ config: _config })
+        that.setState({ config: _config })
       },
       onCancel() {}
     })
diff --git a/src/templates/sharecomponent/actioncomponent/index.jsx b/src/templates/sharecomponent/actioncomponent/index.jsx
index 96961c4..62be8b1 100644
--- a/src/templates/sharecomponent/actioncomponent/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/index.jsx
@@ -280,12 +280,12 @@
    */
   deleteElement = (card) => {
     const { config } = this.props
-    let _this = this
+    let that = this
 
     confirm({
       content: `纭畾鍒犻櫎 - ${card.label} 锛焋,
       onOk() {
-        let _actionlist = fromJS(_this.state.actionlist).toJS()
+        let _actionlist = fromJS(that.state.actionlist).toJS()
 
         _actionlist = _actionlist.filter(item => item.uuid !== card.uuid)
 
@@ -313,10 +313,10 @@
           card: card
         }
 
-        _this.setState({
+        that.setState({
           actionlist: _actionlist
         }, () => {
-          _this.props.updateaction({...config, action: _actionlist, gridBtn: _gridBtn}, '', delcard)
+          that.props.updateaction({...config, action: _actionlist, gridBtn: _gridBtn}, '', delcard)
         })
       },
       onCancel() {}
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
index f0d8651..bfc57cb 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
@@ -1,4 +1,4 @@
-import React, {Component} from 'react'
+import React, { Component } from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
 import { Form, Row, Col, Button, notification, Modal, Tooltip, Radio, Select, Switch } from 'antd'
@@ -22,8 +22,7 @@
     editItem: null,
     usefulfields: null,
     loading: false,
-    skip: false,
-    verifySql: ''
+    skip: false
   }
 
   UNSAFE_componentWillMount () {
@@ -37,26 +36,12 @@
   }
 
   resetfield = (columns) => {
-    const { btn } = this.props
     columns = columns.filter(item => item.import !== 'false')
     let fields = columns.map(item => item.Column)
 
     fields.push('jskey')
-
-    let _dec = columns.map(item => item.Column + ' ' + item.type).join(',')
-    let sheet = btn.sheet.replace(/(.*)\.(.*)\.|@db@/ig, '')
-
-    if (_dec) {
-      _dec += ','
-    }
-
-    let _sql = `create table #${sheet} (${_dec}jskey nvarchar(50),BID nvarchar(50) )
-      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@ErrorCode nvarchar(50), @retmsg nvarchar(4000),@tbid Nvarchar(512)
-      Select @ErrorCode='', @retmsg=''
-    `
     
     this.setState({
-      verifySql: _sql,
       usefulfields: fields.join(', ')
     })
   }
@@ -81,7 +66,7 @@
   }
 
   handleConfirm = () => {
-    const { type, btn, workFlow } = this.props
+    const { type, btn, workFlow, usefulfields } = this.props
     const { editItem, skip } = this.state
 
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
@@ -115,12 +100,6 @@
         let pass = checkSQL(values.sql, 'customscript')
 
         if (!pass) return
-
-        let sheet = btn.sheet.replace(/(.*)\.(.*)\.|@db@/ig, '')
-        let tail = `
-          drop table #${sheet}
-          aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg
-        `
 
         let _initCustomScript = '' // 鍒濆鍖栬剼鏈�
         let _prevCustomScript = '' // 榛樿sql鍓嶆墽琛岃剼鏈�
@@ -165,8 +144,71 @@
             `
           }
         }
+        
+        let sheet = btn.sheet.replace(/(.*)\.(.*)\.|@db@/ig, '')
+        let fields = []
+        let _dec = []
+        let vals = []
 
-        let sql = this.state.verifySql + _initCustomScript + _prevCustomScript + _backCustomScript + tail
+        usefulfields.forEach(col => {
+          if (col.import === 'false') return
+
+          fields.push(col.Column)
+          _dec.push(col.Column + ' ' + col.type)
+
+          let val = ''
+          if (col.import === 'init') {
+            if (/^Nvarchar/ig.test(col.type)) {
+              val = ''
+            } else if (/^Decimal/ig.test(col.type) || /^int/ig.test(col.type)) {
+              val = 0
+            } else if (col.type === 'date') {
+              val = '1949-10-01'
+            } else if (col.type === 'datetime') {
+              val = '1949-10-01 00:00:00'
+            }
+          } else if (/^Nvarchar/ig.test(col.type)) {
+            val = 'mk'
+          } else if (/^Decimal/ig.test(col.type) || /^int/ig.test(col.type)) {
+            val = 1
+          } else if (col.type === 'date') {
+            val = '1949-10-01'
+          } else if (col.type === 'datetime') {
+            val = '1949-10-01 00:00:00'
+          }
+
+          vals.push(`'${val}'`)
+        })
+
+        vals.push(`'${new Date().getTime()}000010'`)
+        vals.push(`'bid'`)
+        vals =  `Select ${vals.join(',')}`
+
+        fields.push('jskey')
+        fields = fields.join(',')
+        
+        _dec = _dec.join(',')
+        _dec = _dec ? _dec + ',' : ''
+
+        let sql = `create table #${sheet} (${_dec}jskey nvarchar(50),BID nvarchar(50) )
+          Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@ErrorCode nvarchar(50), @retmsg nvarchar(4000),@tbid Nvarchar(512)
+          Select @ErrorCode='', @retmsg='', @UserName='', @FullName='', @RoleID='', @mk_departmentcode='', @mk_organization='', @mk_user_type='', @mk_nation='', @mk_province='', @mk_city='', @mk_district='', @mk_address=''
+        
+          ${_initCustomScript}
+
+          Insert into #${sheet} (${fields},BID)
+
+          /* excel鏁版嵁*/
+          ${vals}
+
+          ${_prevCustomScript}
+
+          ${_backCustomScript}
+
+          drop table #${sheet}
+          aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg
+        `
+
         sql = sql.replace(/@\$|\$@/ig, '').replace(/\$check@|@check\$/ig, '').replace(/@datam@/ig, `''`).replace(/@typename@/ig, `'debug'`)
         
         if (workFlow === 'true') {
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
index be7041f..f22a3ef 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -596,18 +596,18 @@
 
   clearField = () => {
     const { verify } = this.state
-    const _this = this
+    const that = this
 
     confirm({
       content: `纭畾娓呯┖Excel鍒楀悧锛焋,
       onOk() {
-        _this.setState({
+        that.setState({
           verify: {
             ...verify,
             columns: []
           }
         }, () => {
-          _this.resetUniqueColumns()
+          that.resetUniqueColumns()
         })
       },
       onCancel() {}
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
index 3f2c50d..36f6164 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
@@ -210,7 +210,7 @@
           </Col>
           <Col span={10}>
             <Form.Item label="鎶ラ敊瀛楁" style={{margin: 0, whiteSpace: 'nowrap'}}>
-              errorcode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT銆丆NT銆�-2NT锛�, retmsg
+              errorcode, retmsg
             </Form.Item>
           </Col>
           <Col span={24} className="sqlfield">
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
index 7b23dda..502137b 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -810,12 +810,12 @@
 
   clearField = () => {
     const { verify } = this.state
-    const _this = this
+    const that = this
 
     confirm({
       content: `纭畾娓呯┖Excel鍒楀悧锛焋,
       onOk() {
-        _this.setState({
+        that.setState({
           verify: {
             ...verify,
             columns: []
diff --git a/src/templates/sharecomponent/actioncomponent/verifypay/customscript/index.jsx b/src/templates/sharecomponent/actioncomponent/verifypay/customscript/index.jsx
new file mode 100644
index 0000000..1704f52
--- /dev/null
+++ b/src/templates/sharecomponent/actioncomponent/verifypay/customscript/index.jsx
@@ -0,0 +1,224 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { fromJS } from 'immutable'
+import { Form, Row, Col, Button, notification, Tooltip, Select, Switch } from 'antd'
+
+import Utils from '@/utils/utils.js'
+import { checkSQL } from '@/utils/utils-custom.js'
+import CodeMirror from '@/templates/zshare/codemirror'
+// import './index.scss'
+
+class CustomForm extends Component {
+  static propTpyes = {
+    scripts: PropTypes.array,
+    columns: PropTypes.any,
+    systemScripts: PropTypes.array,
+    scriptsChange: PropTypes.func
+  }
+
+  state = {
+    editItem: null,
+    usefulfields: null,
+    loading: false,
+    skip: false
+  }
+
+  UNSAFE_componentWillMount () {
+    this.resetfield()
+  }
+
+  resetfield = () => {
+    const { columns } = this.props
+    let fields = columns.map(item => item.field)
+
+    this.setState({
+      usefulfields: fields.join(', ')
+    })
+  }
+
+  edit = (record) => {
+    this.setState({
+      editItem: record
+    })
+
+    this.props.form.setFieldsValue({
+      sql: record.sql
+    })
+  }
+
+  handleConfirm = () => {
+    const { type, scripts } = this.props
+    const { editItem, skip } = this.state
+
+    // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
+    this.props.form.validateFieldsAndScroll((err, values) => {
+      if (err) return
+
+      if (!values.sql || /^[\s\n]+$/.test(values.sql)) {
+        notification.warning({
+          top: 92,
+          message: '璇疯緭鍏ql!',
+          duration: 5
+        })
+        return
+      }
+      
+      values.uuid = editItem ? editItem.uuid : ''
+
+      if (type === 'fullscreen' && editItem) {
+        values.status = editItem.status || 'true'
+      }
+
+      let pass = checkSQL(values.sql, 'customscript')
+
+      if (!pass) return
+
+      let _scripts = fromJS(scripts).toJS()
+
+      if (values.uuid) {
+        _scripts = _scripts.map(item => {
+          if (values.uuid === item.uuid) {
+            return values
+          }
+          return item
+        })
+      } else {
+        values.uuid = Utils.getuuid()
+
+        _scripts.push(values)
+      }
+
+      if (skip) {
+        this.setState({
+          skip: false,
+          editItem: null
+        })
+        this.props.scriptsChange(_scripts, null, null, values)
+        this.props.form.setFieldsValue({
+          sql: ''
+        })
+      } else {
+        this.setState({loading: true})
+        this.props.scriptsChange(_scripts, () => {
+          this.setState({
+            loading: false,
+            editItem: null
+          })
+  
+          this.props.form.setFieldsValue({
+            sql: ''
+          })
+        }, () => {
+          this.setState({loading: false})
+        }, values)
+      }
+    })
+  }
+
+  handleCancel = () => {
+    this.setState({
+      editItem: null
+    })
+    
+    this.props.form.setFieldsValue({
+      sql: ''
+    })
+  }
+
+  selectScript = (value, option) => {
+    let _sql = this.props.form.getFieldValue('sql')
+    if (/^\s+$/.test(_sql)) {
+      _sql = ''
+    }
+    if (_sql) {
+      _sql = _sql + ` 
+
+      `
+    }
+
+    _sql = _sql.replace(/\s{6}$/, '')
+    _sql = _sql + `/*${option.props.children}*/
+    `
+    _sql = _sql.replace(/\s{4}$/, '')
+    _sql = _sql + value
+
+    this.props.form.setFieldsValue({
+      sql: _sql
+    })
+  }
+
+  render() {
+    const { systemScripts, type } = this.props
+    const { usefulfields, editItem, skip } = this.state
+    const { getFieldDecorator } = this.props.form
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
+    return (
+      <Form {...formItemLayout} className="verify-form" id="verify-excelin-custom-scripts">
+        <Row gutter={24}>
+          {!type ? <Col span={8}>
+            <Form.Item label="鎶ラ敊瀛楁" style={{margin: 0, whiteSpace: 'nowrap'}}>
+              errorcode, retmsg
+            </Form.Item>
+          </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, 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>,&nbsp;
+              {usefulfields}
+            </Form.Item>
+          </Col> : null}
+          {!type ? <Col span={8}>
+            <Form.Item style={{marginBottom: 0}} label="蹇嵎娣诲姞">
+              <Select
+                showSearch
+                filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
+                onSelect={this.selectScript}
+                getPopupContainer={() => document.getElementById('verify-excelin-custom-scripts')}
+              >
+                <Select.Option key="debugger" value={`z_debug: select @ErrorCode='E',@retmsg='娴嬭瘯鏂偣' goto aaa`}>
+                  娴嬭瘯鏂偣
+                </Select.Option>
+                {systemScripts.map((option, i) =>
+                  <Select.Option key={i} value={option.value}>
+                    {option.name}
+                  </Select.Option>
+                )}
+              </Select>
+            </Form.Item>
+          </Col> : null}
+          <Col span={5} className="add" style={{paddingTop: '2px', whiteSpace: 'nowrap'}}>
+            <Button onClick={this.handleConfirm} loading={this.state.loading} className="mk-green" style={{marginBottom: 15, marginLeft: 40}}>
+            {type === 'fullscreen' && !editItem ? '娣诲姞' : '淇濆瓨'}
+            </Button>
+            <Button onClick={this.handleCancel} style={{marginBottom: 15, marginLeft: 10}}>
+              鍙栨秷
+            </Button>
+          </Col>
+          <Col span={3} className="forced" style={{paddingTop: '12px', fontSize: '12px', whiteSpace: 'nowrap'}}>
+            寮哄埗淇濆瓨锛�
+            <Switch checked={skip} size="small" onChange={() => this.setState({skip: !skip})}/>
+          </Col>
+          <Col span={24} className="sql">
+            <Form.Item label="sql" required>
+              {getFieldDecorator('sql', {
+                initialValue: ''
+              })(<CodeMirror />)}
+            </Form.Item>
+          </Col>
+        </Row>
+      </Form>
+    )
+  }
+}
+
+export default Form.create()(CustomForm)
\ No newline at end of file
diff --git a/src/templates/sharecomponent/actioncomponent/verifypay/customscript/index.scss b/src/templates/sharecomponent/actioncomponent/verifypay/customscript/index.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/templates/sharecomponent/actioncomponent/verifypay/customscript/index.scss
diff --git a/src/templates/sharecomponent/actioncomponent/verifypay/index.jsx b/src/templates/sharecomponent/actioncomponent/verifypay/index.jsx
new file mode 100644
index 0000000..0aab183
--- /dev/null
+++ b/src/templates/sharecomponent/actioncomponent/verifypay/index.jsx
@@ -0,0 +1,516 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Form, Tabs, Row, Col, Button, Popconfirm, notification, Modal, message, InputNumber, Typography } from 'antd'
+import { EditOutlined, StopOutlined, CheckCircleOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
+import moment from 'moment'
+
+import Api from '@/api'
+import Utils from '@/utils/utils.js'
+
+import CustomScript from './customscript'
+import asyncComponent from '@/utils/asyncComponent'
+import MKEmitter from '@/utils/events.js'
+import './index.scss'
+
+const { TabPane } = Tabs
+const { confirm } = Modal
+const { Paragraph } = Typography
+
+const EditTable = asyncComponent(() => import('@/templates/zshare/editTable'))
+const FullScripts = asyncComponent(() => import('@/templates/zshare/verifycard/fullScripts'))
+
+class VerifyPay extends Component {
+  static propTpyes = {
+    columns: PropTypes.array,  // 鏄剧ず鍒�
+    card: PropTypes.object,
+  }
+
+  state = {
+    verify: null,
+    oriVerify: null,
+    defaultSql: '',
+    systemScripts: [],
+    scriptsColumns: [
+      {
+        title: 'SQL',
+        dataIndex: 'sql',
+        width: '60%',
+        render: (text) => {
+          let title = text.match(/^\s*\/\*.+\*\//)
+          title = title && title[0] ? title[0] : ''
+          let _text = title ? text.replace(title, '') : text
+
+          return (
+            <div>
+              {title ? <span style={{color: '#a50'}}>{title}<span style={{fontSize: '12px', marginLeft: '5px'}}>{_text.length}</span></span> : null}
+              <Paragraph copyable={{ text: text }} ellipsis={{ rows: 4, expandable: true }}>{_text}</Paragraph>
+            </div>
+          )
+        }
+      },
+      {
+        title: '鐘舵��',
+        dataIndex: 'status',
+        width: '10%',
+        render: (text, record) => record.status === 'false' ?
+          (
+            <div style={{color: '#ff4d4f'}}>
+              绂佺敤
+              <StopOutlined style={{marginLeft: '5px'}} />
+            </div>
+          ) :
+          (
+            <div style={{color: '#26C281'}}>
+              鍚敤
+              <CheckCircleOutlined style={{marginLeft: '5px'}}/>
+            </div>
+          )
+      },
+      {
+        title: '鎿嶄綔',
+        align: 'center',
+        width: '140px',
+        dataIndex: 'operation',
+        render: (text, record) =>
+          (<div style={{textAlign: 'center'}}>
+            <span className="operation-btn" title="缂栬緫" onClick={() => this.handleEdit(record)} style={{color: '#1890ff'}}><EditOutlined /></span>
+            <span className="operation-btn" title="鐘舵�佸垏鎹�" onClick={() => this.handleStatus(record)} style={{color: '#8E44AD'}}><SwapOutlined /></span>
+            <Popconfirm
+              overlayClassName="popover-confirm"
+              title="纭畾鍒犻櫎鍚�?"
+              onConfirm={() => this.handleDelete(record)
+            }>
+              <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span>
+            </Popconfirm>
+          </div>)
+      }
+    ]
+  }
+
+  UNSAFE_componentWillMount() {
+    const { card, columns } = this.props
+    let _verify = fromJS(card.verify || {}).toJS()
+
+    _verify.scripts = _verify.scripts || []
+
+    let sysfields = ['UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'tbid', 'bid']
+    let _declare = ['@UserName nvarchar(50)', '@FullName nvarchar(50)', '@RoleID nvarchar(512)', '@mk_departmentcode nvarchar(512)', '@mk_organization nvarchar(512)', '@mk_user_type nvarchar(20)', '@mk_nation nvarchar(50)', '@mk_province nvarchar(50)', '@mk_city nvarchar(50)', '@mk_district nvarchar(50)', '@mk_address nvarchar(100)', '@ErrorCode nvarchar(50)', '@retmsg nvarchar(4000)', '@bid nvarchar(50)', '@tbid nvarchar(50)']
+    let _select = ['@UserName=\'\'', '@FullName=\'\'', '@RoleID=\'\'', '@mk_departmentcode=\'\'', '@mk_organization=\'\'', '@mk_user_type=\'\'', '@mk_nation=\'\'', '@mk_province=\'\'', '@mk_city=\'\'', '@mk_district=\'\'', '@mk_address=\'\'', '@ErrorCode=\'\'', '@retmsg=\'\'', '@bid=\'\'']
+    
+    sysfields = sysfields.map(field => field.toLowerCase())
+    columns.forEach(_f => {
+      if (sysfields.includes(_f.field.toLowerCase())) return
+
+      if (/decimal|int/ig.test(_f.datatype)) {
+        _select.push(`@${_f.field}=1`)
+      } else if (/date/ig.test(_f.datatype)) {
+        _select.push(`@${_f.field}='1949-10-01'`)
+      } else {
+        _select.push(`@${_f.field}=''`)
+      }
+
+      _declare.push(`@${_f.field} ${_f.datatype}`)
+    })
+
+    let _sql = `Declare ${_declare.join(', ')}
+      Select ${_select.join(', ')}
+    `
+
+    this.setState({
+      defaultSql: _sql,
+      verify: _verify,
+      oriVerify: fromJS(_verify).toJS()
+    })
+  }
+
+  componentDidMount () {
+    this.getsysScript()
+  }
+
+  getsysScript = () => {
+    if (sessionStorage.getItem('mk_sys_scripts')) {
+      this.setState({
+        systemScripts: JSON.parse(sessionStorage.getItem('mk_sys_scripts'))
+      })
+      return
+    }
+    
+    let _scriptSql = `Select distinct func+Remark as funcname,longparam, s.Sort from聽 s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort`
+
+    _scriptSql = Utils.formatOptions(_scriptSql, 'x')
+
+    let _sParam = {
+      func: 'sPC_Get_SelectedList',
+      LText: _scriptSql,
+      obj_name: 'data',
+      arr_field: 'funcname,longparam',
+      exec_type: 'x'
+    }
+    
+    _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    _sParam.secretkey = Utils.encrypt('', _sParam.timestamp)
+    _sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 浜戠鏁版嵁楠岃瘉
+    
+    Api.getCloudConfig(_sParam).then(res => {
+      if (res.status) {
+        let _scripts = res.data.map(item => {
+          return {
+            name: item.funcname,
+            value: window.decodeURIComponent(window.atob(item.longparam))
+          }
+        })
+
+        sessionStorage.setItem('mk_sys_scripts', JSON.stringify(_scripts))
+
+        this.setState({
+          systemScripts: _scripts
+        })
+      } else {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  scriptsChange = (scripts, resolve, reject, values) => {
+    const { card } = this.props
+    const { defaultSql } = this.state
+
+    let verify = fromJS(this.state.verify).toJS()
+    verify.scripts = scripts
+
+    let sql = defaultSql
+
+    scripts.forEach(item => {
+      if (item.status === 'false') return
+
+      sql += `
+      ${item.sql}
+      `
+    })
+
+    if (card.output) {
+      sql += `
+        aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg,${card.output} as mk_b_id`
+    } else {
+      sql += `
+        aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
+    }
+
+    sql = sql.replace(/@\$|\$@/ig, '')
+    sql = sql.replace(/@datam@/ig, `''`)
+    sql = sql.replace(/@typename@/ig, `'debug'`)
+      
+    if (resolve) {
+      Api.sDebug(sql).then(res => {
+        if (res.status || res.ErrCode === '-2') {
+          resolve()
+          values && MKEmitter.emit('editLineId', values.uuid)
+
+          this.setState({ verify })
+        } else {
+          reject()
+  
+          Modal.error({
+            title: res.message
+          })
+        }
+      })
+    } else {
+      values && MKEmitter.emit('editLineId', values.uuid)
+
+      this.setState({ verify })
+    }
+  }
+
+  handleDelete = (record) => {
+    const { verify } = this.state
+
+    verify.scripts = verify.scripts.filter(item => item.uuid !== record.uuid)
+
+    this.setState({ verify: verify })
+  }
+
+  handleEdit = (record) => {
+    this.scriptsForm.edit(record)
+    let node = document.getElementById('mk-pay-script')
+
+    if (node && node.scrollTop) {
+      let inter = Math.ceil(node.scrollTop / 10)
+
+      let timer = setInterval(() => {
+        if (node.scrollTop - inter > 0) {
+          node.scrollTop = node.scrollTop - inter
+        } else {
+          node.scrollTop = 0
+          clearInterval(timer)
+        }
+      }, 10)
+    }
+  }
+
+  handleStatus = (record) => {
+    let verify = fromJS(this.state.verify).toJS()
+    record.status = record.status === 'false' ? 'true' : 'false'
+
+    verify.scripts = verify.scripts.map(item => {
+      if (item.uuid === record.uuid) {
+        return record
+      } else {
+        return item
+      }
+    })
+
+    this.setState({
+      verify: verify
+    })
+  }
+
+  handleConfirm = () => {
+    const { verify } = this.state
+    // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
+    return new Promise((resolve, reject) => {
+      if (verify.scripts.length === 0) {
+        notification.warning({
+          top: 92,
+          message: '浣跨敤绯荤粺鍑芥暟锛岄渶瑕佹坊鍔犺嚜瀹氫箟鑴氭湰锛�',
+          duration: 5
+        })
+        return
+      }
+
+      let _loading = false
+      if (this.scriptsForm && this.scriptsForm.state.editItem) {
+        _loading = true
+      } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) {
+        _loading = true
+      }
+
+      if (_loading) {
+        confirm({
+          content: `瀛樺湪鏈繚瀛橀」锛岀‘瀹氭彁浜ゅ悧锛焋,
+          onOk() {
+            resolve(verify)
+          },
+          onCancel() {}
+        })
+      } else {
+        resolve(verify)
+      }
+    })
+  }
+
+  handleCancel = () => {
+    const { verify, oriVerify } = this.state
+    // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
+    return new Promise((resolve, reject) => {
+      if (!is(fromJS(verify), fromJS(oriVerify))) {
+        confirm({
+          content: '楠岃瘉淇℃伅宸蹭慨鏀癸紝纭畾鍙栨秷鍚楋紵',
+          onOk() {
+            resolve()
+          },
+          onCancel() {}
+        })
+      } else {
+        resolve()
+      }
+    })
+  }
+
+  showError = (errorType) => {
+    if (errorType === 'S') {
+      notification.success({
+        top: 92,
+        message: '鎵ц鎴愬姛锛�',
+        duration: 2
+      })
+    } else if (errorType === 'Y') {
+      Modal.success({
+        title: '鎵ц鎴愬姛锛�'
+      })
+    } else if (errorType === 'F') {
+      notification.error({
+        className: 'notification-custom-error',
+        top: 92,
+        message: '鎵ц澶辫触锛�',
+        duration: 10
+      })
+    } else if (errorType === 'N') {
+      notification.error({
+        top: 92,
+        message: '鎵ц澶辫触锛�',
+        duration: 10
+      })
+    } else if (errorType === 'E') {
+      Modal.error({
+        title: '鎵ц澶辫触锛�'
+      })
+    } else if (errorType === 'NM') {
+      message.error('鎵ц澶辫触锛�')
+    }
+  }
+
+  timeChange = (val, type) => {
+    const { verify } = this.state
+
+    this.setState({
+      verify: {...verify, [type]: val}
+    })
+  }
+
+  render() {
+    const { card, columns } = this.props
+    const { verify, scriptsColumns } = this.state
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
+    return (
+      <div>
+        {card.label ? <div className="mk-com-name">{card.label} - 楠岃瘉淇℃伅</div> : null}
+        <Tabs className="pay-verify-card-box">
+          <TabPane tab={
+            <span>
+              鑷畾涔夎剼鏈�
+              {verify.scripts.length ? <span className="count-tip">{verify.scripts.length}</span> : null}
+            </span>
+          } key="scripts" id="mk-pay-script">
+            <FullScripts
+              scripts={verify.scripts}
+              getScriptsFullForm={() => this.scriptsFullForm}
+              getScriptsForm={() => this.scriptsForm}
+              handleStatus={this.handleStatus}
+              handleDelete={this.handleDelete}
+            >
+              <CustomScript
+                type="fullscreen"
+                columns={columns}
+                scripts={verify.scripts}
+                systemScripts={this.state.systemScripts}
+                scriptsChange={this.scriptsChange}
+                wrappedComponentRef={(inst) => this.scriptsFullForm = inst}
+              />
+            </FullScripts>
+            <CustomScript
+              columns={columns}
+              scripts={verify.scripts}
+              systemScripts={this.state.systemScripts}
+              scriptsChange={this.scriptsChange}
+              wrappedComponentRef={(inst) => this.scriptsForm = inst}
+            />
+            <EditTable actions={['move']} data={verify.scripts} columns={scriptsColumns} onChange={(scripts) => {this.setState({verify: {...verify, scripts}})}}/>
+          </TabPane>
+          <TabPane tab="淇℃伅鎻愮ず" key="tip">
+            <Form {...formItemLayout}>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> S </span>
+                    <Button onClick={() => {this.showError('S')}} type="primary" size="small">
+                      鏌ョ湅
+                    </Button>
+                  </Form.Item>
+                </Col>
+                <Col span={8}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
+                    <InputNumber defaultValue={verify.stime || 2} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'stime')}} />
+                  </Form.Item>
+                </Col>
+              </Row>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> Y </span>
+                    <Button onClick={() => {this.showError('Y')}} type="primary" size="small">
+                      鏌ョ湅
+                    </Button>
+                  </Form.Item>
+                </Col>
+              </Row>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -1 </span>
+                    鎵ц鎴愬姛鏃犳彁绀恒��
+                  </Form.Item>
+                </Col>
+              </Row>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> N </span>
+                    <Button onClick={() => {this.showError('N')}} type="primary" size="small">
+                      鏌ョ湅
+                    </Button>
+                  </Form.Item>
+                </Col>
+                <Col span={8}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
+                    <InputNumber defaultValue={verify.ntime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} />
+                  </Form.Item>
+                </Col>
+              </Row>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> F </span>
+                    <Button onClick={() => {this.showError('F')}} type="primary" size="small">
+                      鏌ョ湅
+                    </Button>
+                  </Form.Item>
+                </Col>
+                <Col span={8}>
+                  <Form.Item label="鍋滅暀鏃堕棿">
+                    <InputNumber defaultValue={verify.ftime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} />
+                  </Form.Item>
+                </Col>
+              </Row>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> E </span>
+                    <Button onClick={() => {this.showError('E')}} type="primary" size="small">
+                      鏌ョ湅
+                    </Button>
+                  </Form.Item>
+                </Col>
+              </Row>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> NM </span>
+                    <Button onClick={() => {this.showError('NM')}} type="primary" size="small">
+                      鏌ョ湅
+                    </Button>
+                  </Form.Item>
+                </Col>
+              </Row>
+              <Row gutter={24}>
+                <Col offset={6} span={6}>
+                  <Form.Item label="鎻愮ず缂栫爜">
+                    <span className="errorval"> -2 </span>
+                    鎵ц澶辫触鏃犳彁绀�
+                  </Form.Item>
+                </Col>
+              </Row>
+            </Form>
+          </TabPane>
+        </Tabs>
+      </div>
+    )
+  }
+}
+
+export default Form.create()(VerifyPay)
\ No newline at end of file
diff --git a/src/templates/sharecomponent/actioncomponent/verifypay/index.scss b/src/templates/sharecomponent/actioncomponent/verifypay/index.scss
new file mode 100644
index 0000000..ad27818
--- /dev/null
+++ b/src/templates/sharecomponent/actioncomponent/verifypay/index.scss
@@ -0,0 +1,84 @@
+.pay-verify-card-box {
+  .ant-tabs-nav-scroll {
+    text-align: center;
+  }
+  .ant-tabs-content {
+    min-height: 40vh;
+  }
+  table tr td {
+    word-wrap: break-word;
+    word-break: break-word;
+  }
+  .count-tip {
+    position: absolute;
+    top: 0px;
+    color: #1890ff;
+    font-size: 12px;
+  }
+  .verify-form {
+    .sql {
+      .ant-col-sm-8 {
+        width: 10.5%;
+      }
+      .ant-col-sm-16 {
+        width: 89.5%;
+        padding-top: 4px;
+      }
+      .CodeMirror {
+        height: 350px;
+      }
+    }
+    .sqlfield {
+      .ant-form-item {
+        margin-bottom: 5px;
+      }
+      .ant-form-item-control {
+        line-height: 24px;
+      }
+      .ant-form-item-label {
+        line-height: 25px;
+      }
+      .ant-form-item-children {
+        line-height: 22px;
+      }
+      .ant-col-sm-8 {
+        width: 10.5%;
+      }
+      .ant-col-sm-16 {
+        width: 89.5%;
+      }
+    }
+    .ant-form-explain {
+      white-space: nowrap;
+    }
+  }
+  .errorval {
+    display: inline-block;
+    width: 30px;
+  }
+  .operation-btn {
+    display: inline-block;
+    font-size: 16px;
+    padding: 0 5px;
+    cursor: pointer;
+  }
+  .ant-tabs-tabpane {
+    position: relative;
+    .excel-col-add {
+      position: relative;
+      float: right;
+      right: -9px;
+      margin-right: 10px;
+      top: 10px;
+      z-index: 1;
+    }
+  }
+  .full-scripts {
+    position: absolute;
+    right: 24px;
+    top: 0px;
+    font-size: 16px;
+    color: #1890ff;
+    z-index: 1;
+  }
+}
\ No newline at end of file
diff --git a/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
index 5e80f9d..c4af547 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
@@ -247,6 +247,8 @@
 
         if (/decimal|int/ig.test(_f.datatype)) {
           _select.push(`@${_f.field}=1`)
+        } else if (/date/ig.test(_f.datatype)) {
+          _select.push(`@${_f.field}='1949-10-01'`)
         } else {
           _select.push(`@${_f.field}=''`)
         }
diff --git a/src/templates/sharecomponent/cardcomponent/index.jsx b/src/templates/sharecomponent/cardcomponent/index.jsx
index 795eb4c..aab7e55 100644
--- a/src/templates/sharecomponent/cardcomponent/index.jsx
+++ b/src/templates/sharecomponent/cardcomponent/index.jsx
@@ -270,7 +270,7 @@
 
   deletedetail = (cell) => {
     const { card } = this.props
-    let _this = this
+    let that = this
 
     confirm({
       content: `纭畾鍒犻櫎 - ${cell.content} 锛焋,
@@ -279,22 +279,22 @@
 
         _details = _details.filter(item => item.uuid !== cell.uuid)
 
-        _this.plotChange({details: _details})
+        that.plotChange({details: _details})
       },
       onCancel() {}
     })
   }
 
   deleteElem = (type) => {
-    let _this = this
+    let that = this
 
     confirm({
       content: '纭畾鍒犻櫎锛�',
       onOk() {
-        let _subelement = fromJS(_this.props.card.subelement).toJS()
+        let _subelement = fromJS(that.props.card.subelement).toJS()
         _subelement = _subelement.filter(_type => _type !== type)
 
-        _this.plotChange({subelement: _subelement})
+        that.plotChange({subelement: _subelement})
       },
       onCancel() {}
     })
diff --git a/src/templates/sharecomponent/chartgroupcomponent/index.jsx b/src/templates/sharecomponent/chartgroupcomponent/index.jsx
index 4c90686..2c18248 100644
--- a/src/templates/sharecomponent/chartgroupcomponent/index.jsx
+++ b/src/templates/sharecomponent/chartgroupcomponent/index.jsx
@@ -203,13 +203,13 @@
    */
   deletechart = (plot) => {
     const { config } = this.props
-    let _this = this
+    let that = this
 
     confirm({
       content: `纭畾鍒犻櫎 ${plot.title} 锛焋,
       onOk() {
-        let _chartlist = fromJS(_this.state.chartlist).toJS()
-        let _chartview = _this.state.chartview
+        let _chartlist = fromJS(that.state.chartlist).toJS()
+        let _chartview = that.state.chartview
 
         _chartlist = _chartlist.filter(item => item.uuid !== plot.uuid)
 
@@ -217,11 +217,11 @@
           _chartview = _chartlist[0].uuid
         }
 
-        _this.setState({
+        that.setState({
           chartlist: _chartlist,
           chartview: _chartview
         })
-        _this.props.updatechartgroup({...config, charts: _chartlist}, _chartview)
+        that.props.updatechartgroup({...config, charts: _chartlist}, _chartview)
       },
       onCancel() {}
     })
diff --git a/src/templates/sharecomponent/columncomponent/index.jsx b/src/templates/sharecomponent/columncomponent/index.jsx
index f390b59..e488a3d 100644
--- a/src/templates/sharecomponent/columncomponent/index.jsx
+++ b/src/templates/sharecomponent/columncomponent/index.jsx
@@ -280,12 +280,12 @@
    */
   deleteElement = (card) => {
     const { config } = this.props
-    let _this = this
+    let that = this
 
     confirm({
       content: `纭畾鍒犻櫎 - ${card.label} 锛焋,
       onOk() {
-        let _columnlist = fromJS(_this.state.columnlist).toJS()
+        let _columnlist = fromJS(that.state.columnlist).toJS()
 
         _columnlist = _columnlist.filter(item => item.uuid !== card.uuid)
 
@@ -351,10 +351,10 @@
           }
         }
 
-        _this.setState({
+        that.setState({
           columnlist: _columnlist
         }, ()=> {
-          _this.props.updatecolumn({...config, columns: _columnlist})
+          that.props.updatecolumn({...config, columns: _columnlist})
         })
       },
       onCancel() {}
diff --git a/src/templates/sharecomponent/fieldscomponent/index.jsx b/src/templates/sharecomponent/fieldscomponent/index.jsx
index 52d7eb1..550b5f6 100644
--- a/src/templates/sharecomponent/fieldscomponent/index.jsx
+++ b/src/templates/sharecomponent/fieldscomponent/index.jsx
@@ -146,9 +146,20 @@
     if (type === 'search') {
       // 娣诲姞鎼滅储鏉′欢锛屽瓧娈甸泦涓瓨鍦ㄦ悳绱㈡潯浠跺瓧娈碉紝浣跨敤鎼滅储鏉′欢瀵硅薄鏇挎崲瀛楁闆嗭紝璁剧疆鏁版嵁绫诲瀷
       config.search.forEach(item => {
-        if (item.field && columns.has(item.field.toLowerCase())) {
-          let _datatype = columns.get(item.field.toLowerCase()).datatype
-          columns.set(item.field.toLowerCase(), {...item, origin: true, datatype: _datatype})
+        if (item.field) {
+          if (/,/.test(item.field)) {
+            item.field.split(',').forEach(n => {
+              if (columns.has(n.toLowerCase())) {
+                let _datatype = columns.get(n.toLowerCase()).datatype
+                columns.set(n.toLowerCase(), {...item, field: n, origin: true, datatype: _datatype})
+              }
+            })
+          } else {
+            if (columns.has(item.field.toLowerCase())) {
+              let _datatype = columns.get(item.field.toLowerCase()).datatype
+              columns.set(item.field.toLowerCase(), {...item, origin: true, datatype: _datatype})
+            }
+          }
         }
       })
     } else if (type === 'columns') {
@@ -192,13 +203,6 @@
     }
 
     let config = fromJS(this.props.config).toJS()
-
-    // 鑾峰彇宸查�夊瓧娈甸泦鍚�
-    let cards = selectCards
-    let columnsMap = new Map()
-    cards.forEach(card => {
-      columnsMap.set(card.field.toLowerCase(), card)
-    })
 
     let items = []
     let keys = []
diff --git a/src/templates/sharecomponent/searchcomponent/index.jsx b/src/templates/sharecomponent/searchcomponent/index.jsx
index 37498c6..c861729 100644
--- a/src/templates/sharecomponent/searchcomponent/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/index.jsx
@@ -247,19 +247,19 @@
    */
   deleteElement = (card) => {
     const { config } = this.props
-    let _this = this
+    let that = this
 
     confirm({
       content: `纭畾鍒犻櫎 - ${card.label} 锛焋,
       onOk() {
-        let _searchlist = fromJS(_this.state.searchlist).toJS()
+        let _searchlist = fromJS(that.state.searchlist).toJS()
 
         _searchlist = _searchlist.filter(item => item.uuid !== card.uuid)
 
-        _this.setState({
+        that.setState({
           searchlist: _searchlist
         }, () => {
-          _this.props.updatesearch({...config, search: _searchlist})
+          that.props.updatesearch({...config, search: _searchlist})
         })
       },
       onCancel() {}
diff --git a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
index 0979803..c2871bb 100644
--- a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
@@ -283,7 +283,7 @@
     } else if (type === 'dateweek' || type === 'daterange' || type === 'range') {
       reOptions.match = matchReg.class5
     } else if (type === 'checkcard') {
-      if (this.record.multiple === 'false') {
+      if (this.record.multiple === 'false' || this.record.multiple === 'dropdown') {
         reOptions.match = matchReg.class1
       } else if (this.record.multiple === 'true') {
         reOptions.match = matchReg.class3
@@ -692,7 +692,7 @@
       fields.push(
         <Col span={span} key={index}>
           <Form.Item className={className} extra={extra} label={item.tooltip ?
-            <Tooltip placement="topLeft" title={item.tooltip}>
+            <Tooltip placement="topLeft" title={<div onClick={(e) => e.stopPropagation()}>{item.tooltip}</div>}>
               <QuestionCircleOutlined className="mk-form-tip" />
               {item.label}
             </Tooltip> : item.label
diff --git a/src/templates/sharecomponent/settingcomponent/index.jsx b/src/templates/sharecomponent/settingcomponent/index.jsx
index 6d9bb70..8657cbe 100644
--- a/src/templates/sharecomponent/settingcomponent/index.jsx
+++ b/src/templates/sharecomponent/settingcomponent/index.jsx
@@ -93,7 +93,7 @@
 
   resetSetting = (s, ori) => {
     let setting = fromJS(s).toJS()
-    let maxScript = 0
+    // let maxScript = 0
 
     setting.show = ori.show || 'true'
     setting.advanceType = ori.advanceType || 'modal'
@@ -103,43 +103,43 @@
     setting.searchLwidth = ori.searchLwidth !== undefined ? ori.searchLwidth : 33.3
     setting.resetContrl = ori.resetContrl || 'init'
 
-    if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-      window.GLOB.funcs.forEach(m => {
-        let reg = new RegExp('\\$ex@' + m.func_code + '@ex\\$', 'ig')
-        setting.scripts.forEach(item => {
-          item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
+    // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+    //   window.GLOB.funcs.forEach(m => {
+    //     let reg = new RegExp('\\$ex@' + m.func_code + '@ex\\$', 'ig')
+    //     setting.scripts.forEach(item => {
+    //       item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
 
-          if (item.status === 'false') return
+    //       if (item.status === 'false') return
 
-          if (/exec\s/ig.test(item.sql)) {
-            maxScript = 1000
-          } else if (item.sql.length > maxScript) {
-            maxScript = item.sql.length
-          }
-        })
-        setting.preScripts.forEach(item => {
-          item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
-        })
-        setting.cbScripts.forEach(item => {
-          item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
-        })
-        if (setting.dataresource) {
-          setting.dataresource = setting.dataresource.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
-        }
-      })
-    } else {
-      setting.scripts.forEach(item => {
-        if (item.status === 'false') return
+    //       if (/exec\s/ig.test(item.sql)) {
+    //         maxScript = 1000
+    //       } else if (item.sql.length > maxScript) {
+    //         maxScript = item.sql.length
+    //       }
+    //     })
+    //     setting.preScripts.forEach(item => {
+    //       item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
+    //     })
+    //     setting.cbScripts.forEach(item => {
+    //       item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
+    //     })
+    //     if (setting.dataresource) {
+    //       setting.dataresource = setting.dataresource.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
+    //     }
+    //   })
+    // } else {
+    //   setting.scripts.forEach(item => {
+    //     if (item.status === 'false') return
 
-        if (/exec\s/ig.test(item.sql)) {
-          maxScript = 1000
-        } else if (item.sql.length > maxScript) {
-          maxScript = item.sql.length
-        }
-      })
-    }
+    //     if (/exec\s/ig.test(item.sql)) {
+    //       maxScript = 1000
+    //     } else if (item.sql.length > maxScript) {
+    //       maxScript = item.sql.length
+    //     }
+    //   })
+    // }
 
-    setting.maxScript = maxScript
+    // setting.maxScript = maxScript
 
     return setting
   }
diff --git a/src/templates/sharecomponent/settingcomponent/settingform/index.jsx b/src/templates/sharecomponent/settingcomponent/settingform/index.jsx
index 8c0ab17..ff665b9 100644
--- a/src/templates/sharecomponent/settingcomponent/settingform/index.jsx
+++ b/src/templates/sharecomponent/settingcomponent/settingform/index.jsx
@@ -79,17 +79,17 @@
 
     let status = fromJS(_setting).toJS()
 
-    if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-      window.GLOB.funcs.forEach(m => {
-        let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig')
-        _scripts.forEach(item => {
-          item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
-        })
-        if (_setting.dataresource) {
-          _setting.dataresource = _setting.dataresource.replace(reg, `$ex@${m.func_code}@ex$`)
-        }
-      })
-    }
+    // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+    //   window.GLOB.funcs.forEach(m => {
+    //     let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig')
+    //     _scripts.forEach(item => {
+    //       item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
+    //     })
+    //     if (_setting.dataresource) {
+    //       _setting.dataresource = _setting.dataresource.replace(reg, `$ex@${m.func_code}@ex$`)
+    //     }
+    //   })
+    // }
 
     this.setState({
       setting: _setting,
diff --git a/src/templates/sharecomponent/settingcomponent/settingform/utils.jsx b/src/templates/sharecomponent/settingcomponent/settingform/utils.jsx
index 846ae2f..74025d2 100644
--- a/src/templates/sharecomponent/settingcomponent/settingform/utils.jsx
+++ b/src/templates/sharecomponent/settingcomponent/settingform/utils.jsx
@@ -26,25 +26,25 @@
       _dataresource = ''
     }
 
-    if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-      window.GLOB.funcs.forEach(item => {
-        let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig')
-        _dataresource = _dataresource.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
-        _customScript = _customScript.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
-      })
-    }
+    // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+    //   window.GLOB.funcs.forEach(item => {
+    //     let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig')
+    //     _dataresource = _dataresource.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
+    //     _customScript = _customScript.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
+    //   })
+    // }
     
     _dataresource = _dataresource.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id|datam|upid)@/ig, `'1949-10-01 15:00:00'`)
     _customScript = _customScript.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id|datam|upid)@/ig, `'1949-10-01 15:00:00'`)
     _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
     _customScript = _customScript.replace(/@\$|\$@/ig, '')
-    _dataresource = _dataresource.replace(/@select\$|\$select@/ig, '')
-    _customScript = _customScript.replace(/@select\$|\$select@/ig, '')
+    // _dataresource = _dataresource.replace(/@select\$|\$select@/ig, '')
+    // _customScript = _customScript.replace(/@select\$|\$select@/ig, '')
     // _dataresource = _dataresource.replace(/@sum\$|\$sum@/ig, '')
-    _customScript = _customScript.replace(/@sum\$|\$sum@/ig, '')
+    // _customScript = _customScript.replace(/@sum\$|\$sum@/ig, '')
 
-    _dataresource = _dataresource.replace(/\$sum@/ig, '/*$sum@')
-    _dataresource = _dataresource.replace(/@sum\$/ig, '@sum$*/')
+    // _dataresource = _dataresource.replace(/\$sum@/ig, '/*$sum@')
+    // _dataresource = _dataresource.replace(/@sum\$/ig, '@sum$*/')
 
     // 澶栬仈鏁版嵁搴撴浛鎹�
     if (window.GLOB.externalDatabase !== null) {
diff --git a/src/templates/sharecomponent/tabscomponent/index.jsx b/src/templates/sharecomponent/tabscomponent/index.jsx
index a95725d..73c4dba 100644
--- a/src/templates/sharecomponent/tabscomponent/index.jsx
+++ b/src/templates/sharecomponent/tabscomponent/index.jsx
@@ -219,7 +219,7 @@
    */
   deleteElement = (card, group) => {
     const { config } = this.props
-    let _this = this
+    let that = this
     let tabgroups = fromJS(this.state.tabgroups).toJS()
 
     confirm({
@@ -243,10 +243,10 @@
           return _group
         })
 
-        _this.setState({
+        that.setState({
           tabgroups: tabgroups
         }, () => {
-          _this.props.updatetabs({...config, tabgroups: tabgroups})
+          that.props.updatetabs({...config, tabgroups: tabgroups})
         })
       },
       onCancel() {}
@@ -258,7 +258,7 @@
    */
   addTabGroup = () => {
     const { config } = this.props
-    let _this = this
+    let that = this
     let _tabgroups = fromJS(this.state.tabgroups).toJS()
 
     confirm({
@@ -275,10 +275,10 @@
           sublist:[]
         })
 
-        _this.setState({
+        that.setState({
           tabgroups: _tabgroups
         }, () => {
-          _this.props.updatetabs({...config, tabgroups: _tabgroups})
+          that.props.updatetabs({...config, tabgroups: _tabgroups})
         })
       },
       onCancel() {}
@@ -290,7 +290,7 @@
    */
   delTabGroup = (group) => {
     const { config } = this.props
-    let _this = this
+    let that = this
     let _tabgroups = fromJS(this.state.tabgroups).toJS()
 
     confirm({
@@ -298,10 +298,10 @@
       onOk() {
         _tabgroups = _tabgroups.filter(_group => _group.uuid !== group.uuid)
 
-        _this.setState({
+        that.setState({
           tabgroups: _tabgroups
         }, () => {
-          _this.props.updatetabs({...config, tabgroups: _tabgroups}, group.sublist)
+          that.props.updatetabs({...config, tabgroups: _tabgroups}, group.sublist)
         })
       },
       onCancel() {}
diff --git a/src/templates/sharecomponent/treesettingcomponent/index.jsx b/src/templates/sharecomponent/treesettingcomponent/index.jsx
index 055a295..51faa23 100644
--- a/src/templates/sharecomponent/treesettingcomponent/index.jsx
+++ b/src/templates/sharecomponent/treesettingcomponent/index.jsx
@@ -43,17 +43,17 @@
       loading: true
     })
     this.settingRef.handleConfirm().then(res => {
-      if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-        window.GLOB.funcs.forEach(m => {
-          let reg = new RegExp('\\$ex@' + m.func_code + '@ex\\$', 'ig')
-          res.scripts.forEach(item => {
-            item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
-          })
-          if (res.dataresource) {
-            res.dataresource = res.dataresource.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
-          }
-        })
-      }
+      // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+      //   window.GLOB.funcs.forEach(m => {
+      //     let reg = new RegExp('\\$ex@' + m.func_code + '@ex\\$', 'ig')
+      //     res.scripts.forEach(item => {
+      //       item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
+      //     })
+      //     if (res.dataresource) {
+      //       res.dataresource = res.dataresource.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
+      //     }
+      //   })
+      // }
       this.setState({
         visible: false,
         loading: false
diff --git a/src/templates/sharecomponent/treesettingcomponent/settingform/index.jsx b/src/templates/sharecomponent/treesettingcomponent/settingform/index.jsx
index 46b7486..ba10535 100644
--- a/src/templates/sharecomponent/treesettingcomponent/settingform/index.jsx
+++ b/src/templates/sharecomponent/treesettingcomponent/settingform/index.jsx
@@ -32,17 +32,17 @@
     let _setting = fromJS(config.setting).toJS()
     let _scripts = _setting.scripts || []
 
-    if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-      window.GLOB.funcs.forEach(m => {
-        let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig')
-        _scripts.forEach(item => {
-          item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
-        })
-        if (_setting.dataresource) {
-          _setting.dataresource = _setting.dataresource.replace(reg, `$ex@${m.func_code}@ex$`)
-        }
-      })
-    }
+    // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+    //   window.GLOB.funcs.forEach(m => {
+    //     let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig')
+    //     _scripts.forEach(item => {
+    //       item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
+    //     })
+    //     if (_setting.dataresource) {
+    //       _setting.dataresource = _setting.dataresource.replace(reg, `$ex@${m.func_code}@ex$`)
+    //     }
+    //   })
+    // }
 
     this.setState({
       setting: _setting,
diff --git a/src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx b/src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx
index 7d91a7c..a540544 100644
--- a/src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx
+++ b/src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx
@@ -27,13 +27,13 @@
       _dataresource = ''
     }
 
-    if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-      window.GLOB.funcs.forEach(item => {
-        let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig')
-        _dataresource = _dataresource.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
-        _customScript = _customScript.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
-      })
-    }
+    // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+    //   window.GLOB.funcs.forEach(item => {
+    //     let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig')
+    //     _dataresource = _dataresource.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
+    //     _customScript = _customScript.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
+    //   })
+    // }
     
     _dataresource = _dataresource.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'1949-10-01 15:00:00'`)
     _customScript = _customScript.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'1949-10-01 15:00:00'`)
diff --git a/src/templates/subtableconfig/index.jsx b/src/templates/subtableconfig/index.jsx
index 8e48352..ceb6a74 100644
--- a/src/templates/subtableconfig/index.jsx
+++ b/src/templates/subtableconfig/index.jsx
@@ -588,13 +588,13 @@
   cancelConfig = () => {
     // const { config, originConfig } = this.state
 
-    // let _this = this
+    // let that = this
 
     // if (originConfig.isAdd) {
     //   confirm({
     //     content: '鑿滃崟灏氭湭鎻愪氦锛岀‘瀹氭斁寮冧繚瀛樺悧锛�',
     //     onOk() {
-    //       _this.handleViewBack()
+    //       that.handleViewBack()
     //     },
     //     onCancel() {}
     //   })
diff --git a/src/templates/treepageconfig/index.jsx b/src/templates/treepageconfig/index.jsx
index af0d67b..f6df00d 100644
--- a/src/templates/treepageconfig/index.jsx
+++ b/src/templates/treepageconfig/index.jsx
@@ -444,13 +444,13 @@
    */
   cancelConfig = () => {
     // const { config, originMenu } = this.state
-    // let _this = this
+    // let that = this
 
     // if (config.isAdd) {
     //   confirm({
     //     content: '鑿滃崟灏氭湭鎻愪氦锛岀‘瀹氭斁寮冧繚瀛樺悧锛�',
     //     onOk() {
-    //       _this.props.handleView()
+    //       that.props.handleView()
     //     },
     //     onCancel() {}
     //   })
diff --git a/src/templates/treepageconfig/updatetable/index.jsx b/src/templates/treepageconfig/updatetable/index.jsx
index 8de0cea..35b911b 100644
--- a/src/templates/treepageconfig/updatetable/index.jsx
+++ b/src/templates/treepageconfig/updatetable/index.jsx
@@ -29,7 +29,7 @@
 
   trigger = () => {
     const { config } = this.props
-    const _this = this
+    const that = this
 
     if (!config.enabled) {
       notification.warning({
@@ -45,7 +45,7 @@
       content: '',
       onOk() {
         return new Promise(resolve => {
-          _this.execUpdate(resolve)
+          that.execUpdate(resolve)
         })
       },
       onCancel() {}
@@ -637,7 +637,7 @@
 
   saveConfig = (_resolve, _config, errors) => {
     let err = errors.join('锛�')
-    let _this = this
+    let that = this
 
     if (err) {
       _resolve()
@@ -646,7 +646,7 @@
         content: '',
         onOk() {
           return new Promise(resolve => {
-            _this.saveNewMenu(resolve, _config)
+            that.saveNewMenu(resolve, _config)
           })
         },
         onCancel() {}
diff --git a/src/templates/zshare/editTable/index.jsx b/src/templates/zshare/editTable/index.jsx
index b14d57a..777fb99 100644
--- a/src/templates/zshare/editTable/index.jsx
+++ b/src/templates/zshare/editTable/index.jsx
@@ -385,14 +385,14 @@
   }
 
   clear = () => {
-    const _this = this
+    const that = this
     
     confirm({
       title: '纭畾娓呯┖鍒楄〃鍚楋紵',
       content: '',
       onOk() {
-        _this.setState({ data: [], editingKey: '' }, () => {
-          _this.props.onChange([])
+        that.setState({ data: [], editingKey: '' }, () => {
+          that.props.onChange([])
         })
       },
       onCancel() {}
diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx
index 286fddb..b494bb7 100644
--- a/src/templates/zshare/formconfig.jsx
+++ b/src/templates/zshare/formconfig.jsx
@@ -1915,7 +1915,7 @@
       type: 'radio',
       key: 'readin',
       label: '鑷姩濉厖',
-      tooltip: '灏嗚〃鏍奸�変腑鐨勬暟鎹嚜鍔ㄥ~鍏呭埌琛ㄥ崟涓�傛敞锛氬湪鎵归噺鎿嶄綔鏃讹紝濡傛兂瑕佹墍閫夎锛堝綋鍓嶅瓧娈碉級鍏ㄩ儴淇敼璇疯涓哄惁鎴栭琛屻��',
+      tooltip: '灏嗚〃鏍奸�変腑鐨勬暟鎹嚜鍔ㄥ~鍏呭埌琛ㄥ崟涓�傛敞锛氬湪鎵归噺鎿嶄綔鏃讹紝濡傛兂瑕佹墍閫夎锛堝綋鍓嶅瓧娈碉級鍏ㄩ儴淇敼璇疯涓哄惁鎴栭琛岋紱浣跨敤鈥滅紦瀛樷�濇椂锛屽皢鍦ㄦ湰鍦颁繚瀛樹笌璇诲彇琛ㄥ崟淇℃伅锛岄�夎鏃朵娇鐢ㄨ淇℃伅濉厖銆�',
       initVal: card.readin || 'true',
       options: [{
         value: 'true',
@@ -1926,6 +1926,9 @@
       }, {
         value: 'top',
         text: '棣栬'
+      }, {
+        value: 'local',
+        text: '缂撳瓨'
       }]
     },
     {
@@ -2523,6 +2526,18 @@
     },
     {
       type: 'number',
+      key: 'contHeidht',
+      label: '楂樺害',
+      min: 1,
+      max: 2000,
+      precision: 1,
+      initVal: card.contHeidht,
+      tooltip: '瀵屾枃鏈紪杈戝尯鐨勯珮搴︼紝灏忎簬100鏃朵负绐楀彛鐨勭櫨鍒嗘瘮銆�',
+      required: false,
+      forbid: appType === 'mob'
+    },
+    {
+      type: 'number',
       key: 'labelwidth',
       min: 1,
       max: 100,
diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx
index 8fe2851..8867247 100644
--- a/src/templates/zshare/modalform/index.jsx
+++ b/src/templates/zshare/modalform/index.jsx
@@ -41,7 +41,7 @@
   hint: ['label', 'field', 'type', 'blacklist', 'supField', 'message', 'span', 'labelwidth', 'splitline', 'marginTop', 'marginBottom'],
   split: ['label', 'type', 'marginTop', 'marginBottom', 'splitline', 'splitctrl', 'supField', 'opacity'],
   formula: ['label', 'type', 'marginTop', 'marginBottom', 'splitline', 'supField', 'span', 'labelwidth', 'formula', 'eval', 'postfix'],
-  brafteditor: ['required', 'hidelabel', 'hidden', 'readin', 'fieldlength', 'readonly', 'span', 'labelwidth', 'tooltip', 'extra', 'encryption', 'marginTop', 'marginBottom'],
+  brafteditor: ['required', 'hidelabel', 'hidden', 'readin', 'fieldlength', 'readonly', 'span', 'labelwidth', 'tooltip', 'extra', 'encryption', 'marginTop', 'marginBottom', 'contHeidht'],
   funcvar: ['span', 'labelwidth', 'splitline', 'marginTop', 'marginBottom'],
   linkMain: ['readonly', 'required', 'hidden','declare', 'span', 'labelwidth', 'tooltip', 'interception', 'extra', 'place', 'marginTop', 'marginBottom'],
   popSelect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'place', 'enter', 'dataSource', 'columns', 'primaryKey', 'order', 'controlField', 'laypage', 'onload', 'searchKey', 'showField', 'popWidth'],
diff --git a/src/templates/zshare/pasteform/index.jsx b/src/templates/zshare/pasteform/index.jsx
index f3c3d6b..2a9a5b4 100644
--- a/src/templates/zshare/pasteform/index.jsx
+++ b/src/templates/zshare/pasteform/index.jsx
@@ -56,14 +56,14 @@
             }
           } catch (e) {
             // 閫氳繃sql璇彞娣诲姞瀛楁闆�
-            if (/[a-zA-Z0-9_]+\s+(nvarchar\(\d+\)|Decimal\(18,\d+\)|Int)/ig.test(values.config)) {
+            if (/[a-zA-Z0-9_]+\s+(nvarchar\(\d+\)|Decimal\(18,\d+\)|Int|datetime|date)/ig.test(values.config)) {
               _config = {
                 key: 'datasourcefield',
                 type: 'array',
                 data: []
               }
 
-              let list = values.config.match(/[a-zA-Z0-9_]+\s+(nvarchar\(\d+\)|Decimal\(18,\d+\)|Int)/ig)
+              let list = values.config.match(/[a-zA-Z0-9_]+\s+(nvarchar\(\d+\)|Decimal\(18,\d+\)|Int|datetime|date)/ig)
 
               list.forEach(item => {
                 _config.data.unshift({
diff --git a/src/templates/zshare/verifycard/baseform/index.jsx b/src/templates/zshare/verifycard/baseform/index.jsx
index d67515e..cbfc412 100644
--- a/src/templates/zshare/verifycard/baseform/index.jsx
+++ b/src/templates/zshare/verifycard/baseform/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
-import { Form, Row, Col, Select, Radio, Tooltip, Input } from 'antd'
+import { Form, Row, Col, Select, Radio, Tooltip, Input, message } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 
 import Api from '@/api'
@@ -25,61 +25,65 @@
   state = {
     wxTemps: [],
     selectTemp: null,
-    miniTemps: []
+    WXApps: null
   }
 
   componentDidMount() {
-    let wxTemps = sessionStorage.getItem('wxTemplates')
+    const { appType, verify } = this.props
 
-    if (window.GLOB.WXAppID && window.GLOB.nginx && !wxTemps) {
-      Api.wxAccessToken().then(res => {
-        let wxtoken = res.oa_access_token || ''
-        // let minitoken = res.mini_access_token || ''
-  
-        if (wxtoken) {
-          Api.wxNginxRequest(`cgi-bin/template/get_all_private_template?access_token=${wxtoken}`, 'get').then(res => {
-            let temps = []
-            if (res.template_list) {
-              temps = res.template_list.filter(item => {
-                if (!item.primary_industry || sysTempsIds.includes(item.template_id)) return false
-                if (item.content) {
-                  item.content = item.content.replace('{{first.DATA}}\n', '').replace('\n{{remark.DATA}}', '')
-                }
+    let appId = window.GLOB.WXAppID || ''
 
-                return true
-              })
-            }
-            
-            sessionStorage.setItem('wxTemplates', JSON.stringify(temps))
-            localStorage.setItem('wxTemplates', JSON.stringify(temps))
+    if (window.GLOB.WXApps && !appType) {
+      let apps = window.GLOB.WXApps.filter(app => app.appType === 'public')
 
-            localStorage.removeItem('wxTemplates')
+      if (apps.length > 0) {
+        this.setState({WXApps: apps})
+      }
 
-            this.resetTemps(temps)
-          })
-        } else {
-          sessionStorage.setItem('wxTemplates', JSON.stringify([]))
-          localStorage.setItem('wxTemplates', JSON.stringify([]))
+      if (verify.wxAppId && apps.findIndex(item => item.appId === verify.wxAppId) > -1) {
+        appId = verify.wxAppId
+      }
+    }
 
-          localStorage.removeItem('wxTemplates')
-        }
-        // if (minitoken) {
-        //   Api.wxNginxRequest(`wxaapi/newtmpl/gettemplate?access_token=${minitoken}`, 'get').then(res => {
-        //     if (res.errmsg === 'ok' && res.data) {
-        //       sessionStorage.setItem('wxMiniTemplates', JSON.stringify(res.data))
-        //     } else {
-        //       sessionStorage.setItem('wxMiniTemplates', JSON.stringify([]))
-        //     }
-        //   })
-        // } else {
-        //   sessionStorage.setItem('wxMiniTemplates', JSON.stringify([]))
-        // }
-      })
+    let wxTemps = sessionStorage.getItem('wxTemplates' + appId)
+
+    if (appId && !wxTemps) {
+      if (verify.wxNote === 'true') {
+        this.getTemps(appId)
+      }
     } else if (wxTemps) {
       wxTemps = JSON.parse(wxTemps)
 
       this.resetTemps(wxTemps)
+    } else {
+      this.resetTemps([])
     }
+  }
+
+  getTemps = (appId) => {
+    // cgi-bin/template/get_all_private_template
+    Api.directRequest({
+      url: window.GLOB.baseurl + 'wechat/get_all_private_template?appid=' + appId,
+      method: 'get',
+    }).then(res => {
+      let temps = []
+      if (res.template_list) {
+        temps = res.template_list.filter(item => {
+          if (!item.content || item.content.length < 25 || sysTempsIds.includes(item.template_id)) return false
+          if (item.content) {
+            item.content = item.content.replace('{{first.DATA}}\n', '').replace('\n{{remark.DATA}}', '')
+          }
+
+          return true
+        })
+      } else if (res.errcode && res.errmsg) {
+        message.warning(res.errcode + ': ' + res.errmsg)
+      }
+      
+      sessionStorage.setItem('wxTemplates' + appId, JSON.stringify(temps))
+
+      this.resetTemps(temps)
+    })
   }
 
   resetTemps = (wxTemps) => {
@@ -102,14 +106,14 @@
         content: '璁㈠崟绫诲瀷锛歿{keyword1.DATA}}\n璁㈠崟鍙凤細{{keyword2.DATA}}\n璁㈠崟鐘舵�侊細{{keyword3.DATA}}',
         example: '璁㈠崟绫诲瀷锛氶��绉熺敵璇穃r\n璁㈠崟鍙凤細TZ16101909\r\n璁㈠崟鐘舵�侊細寰呭彇璐�'
       },
-      {
-        template_id: 'mk_category_temp',
-        title: '绫荤洰妯℃澘',
-        primary_industry: '',
-        deputy_industry: '',
-        content: '',
-        example: ''
-      }
+      // {
+      //   template_id: 'mk_category_temp',
+      //   title: '绫荤洰妯℃澘',
+      //   primary_industry: '',
+      //   deputy_industry: '',
+      //   content: '',
+      //   example: ''
+      // }
     ]
     
     let _wxTemps = [...wxTemps, ...sysTemps]
@@ -181,6 +185,7 @@
       delete _verify.pre_func
     }
     if (_verify.wxNote !== 'true') {
+      delete _verify.wxAppId
       delete _verify.wxTemplateId
       delete _verify.wxNoteLink
       delete _verify.wxNoteLinkUrl
@@ -197,6 +202,18 @@
     }
 
     this.props.onChange(_verify)
+
+    if (key === 'wxNote' && value === 'true' && window.GLOB.WXAppID) {
+      let wxTemps = sessionStorage.getItem('wxTemplates' + window.GLOB.WXAppID)
+
+      if (wxTemps) {
+        wxTemps = JSON.parse(wxTemps)
+
+        this.resetTemps(wxTemps)
+      } else {
+        this.getTemps(window.GLOB.WXAppID)
+      }
+    }
   }
 
   onNoteCodeChange = (val, option) => {
@@ -231,7 +248,7 @@
 
     let keys = []
     if (option.props.content) {
-      keys = option.props.content.match(/{{[a-zA-Z0-9]+\.DATA}}/g)
+      keys = option.props.content.match(/{{[a-zA-Z0-9_]+\.DATA}}/g)
       keys = keys.map(key => key.replace(/{{|\.DATA}}/g, ''))
     }
 
@@ -260,6 +277,45 @@
     this.setState({selectTemp})
 
     this.props.onChange(_verify)
+  }
+
+  onWxAppChange = (val) => {
+    const { verify } = this.props
+
+    let _verify = {...verify, wxAppId: val, wxNote: 'false'}
+
+    delete _verify.wxTemplateId
+    delete _verify.wxNoteLink
+    delete _verify.wxNoteLinkUrl
+    delete _verify.wxNoteMiniId
+    delete _verify.wxNoteLinkMenuId
+    delete _verify.wxNoteCallback
+    delete _verify.wxCustomTempId
+
+    _verify.wxNoteKeys = null
+    
+    if (this.state.selectTemp) {
+      this.setState({selectTemp: null})
+    }
+
+    let _verify_ = fromJS(_verify).toJS()
+    _verify_.wxNote = 'true'
+
+    this.props.onChange(_verify)
+
+    setTimeout(() => {
+      this.props.onChange(_verify_)
+
+      let wxTemps = sessionStorage.getItem('wxTemplates' + val)
+
+      if (wxTemps) {
+        wxTemps = JSON.parse(wxTemps)
+
+        this.resetTemps(wxTemps)
+      } else {
+        this.getTemps(val)
+      }
+    }, 20)
   }
 
   onWxNoteKeyChange = (key, val) => {
@@ -300,7 +356,7 @@
 
   render() {
     const { unionFields, verify, notes, emailCodes, card, appType, columns, fields } = this.props
-    const { wxTemps, selectTemp } = this.state
+    const { wxTemps, selectTemp, WXApps } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -337,6 +393,16 @@
   
         _columns.push(col)
       })
+    }
+
+    let miniable = ''
+    if (window.GLOB.WXApps) {
+      let apps = window.GLOB.WXApps.filter(app => app.appType === 'miniProgram')
+
+      if (apps.length > 1) {
+        miniable = apps.map(app => `${app.appId}锛�${app.appName}锛塦)
+        miniable = miniable.join('锛�')
+      }
     }
 
     return (
@@ -636,7 +702,7 @@
           <Col span={24}></Col>
           <Col span={8}>
             <Form.Item label={
-              <Tooltip placement="bottomLeft" title={'璇峰湪鏈嶅姟鍣ㄥ畬鎴愬叕浼楀彿閰嶇疆銆�'}>
+              <Tooltip placement="bottomLeft" title="璇峰湪鏈嶅姟鍣ㄥ畬鎴愬叕浼楀彿閰嶇疆銆�">
                 <QuestionCircleOutlined className="mk-form-tip" />
                 鍏紬鍙锋秷鎭�
               </Tooltip>
@@ -647,6 +713,22 @@
               </Radio.Group>
             </Form.Item>
           </Col>
+          {verify.wxNote === 'true' && WXApps ? <Col span={8}>
+            <Form.Item label={
+              <Tooltip placement="bottomLeft" title="璇烽�夋嫨鍙戦�佹秷鎭殑鍏紬鍙枫��">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鍏紬鍙�
+              </Tooltip>
+            } required>
+              <Select value={verify.wxAppId || window.GLOB.WXAppID} onSelect={this.onWxAppChange}>
+                {WXApps.map(option =>
+                  <Select.Option key={option.appId} value={option.appId}>
+                    {option.appName}
+                  </Select.Option>
+                )}
+              </Select>
+            </Form.Item>
+          </Col> : null}
           {verify.wxNote === 'true' ? <Col span={8}>
             <Form.Item label="娑堟伅妯℃澘" required>
               <Select value={verify.wxTemplateId} onSelect={this.onWxTemplateChange}>
@@ -692,7 +774,7 @@
           </Col> : null}
           {verify.wxNoteLink === 'miniProgram' ? <Col span={8}>
             <Form.Item label={
-              <Tooltip placement="top" title="鍙寚瀹氳烦杞皬绋嬪簭鐨処D锛屾湭璁剧疆鏃堕粯璁や娇鐢ㄩ厤缃枃浠朵腑鐨勫皬绋嬪簭ID銆�">
+              <Tooltip placement="top" title={'鍙寚瀹氳烦杞皬绋嬪簭鐨処D锛屾湭璁剧疆鏃堕粯璁や娇鐢ㄩ厤缃枃浠朵腑鐨勫皬绋嬪簭ID銆�' + miniable}>
                 <QuestionCircleOutlined className="mk-form-tip" />
                 灏忕▼搴廔D
               </Tooltip>
diff --git a/src/templates/zshare/verifycard/callbackcustomscript/index.jsx b/src/templates/zshare/verifycard/callbackcustomscript/index.jsx
index 9105198..7a33ed3 100644
--- a/src/templates/zshare/verifycard/callbackcustomscript/index.jsx
+++ b/src/templates/zshare/verifycard/callbackcustomscript/index.jsx
@@ -116,12 +116,12 @@
 
         let sql = this.props.initsql +  _prevCustomScript + _backCustomScript + tail
 
-        if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-          window.GLOB.funcs.forEach(item => {
-            let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig')
-            sql = sql.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
-          })
-        }
+        // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+        //   window.GLOB.funcs.forEach(item => {
+        //     let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig')
+        //     sql = sql.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
+        //   })
+        // }
 
         // 鏁版嵁鏉冮檺
         sql = sql.replace(/@\$|\$@/ig, '').replace(/\$check@|@check\$/ig, '')
diff --git a/src/templates/zshare/verifycard/customform/index.jsx b/src/templates/zshare/verifycard/customform/index.jsx
index 345b9f6..efca89b 100644
--- a/src/templates/zshare/verifycard/customform/index.jsx
+++ b/src/templates/zshare/verifycard/customform/index.jsx
@@ -76,12 +76,12 @@
           end
           aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
 
-        if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-          window.GLOB.funcs.forEach(item => {
-            let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig')
-            sql = sql.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
-          })
-        }
+        // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+        //   window.GLOB.funcs.forEach(item => {
+        //     let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig')
+        //     sql = sql.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
+        //   })
+        // }
         
         // 鏁版嵁鏉冮檺
         sql = sql.replace(/@\$|\$@/ig, '')
diff --git a/src/templates/zshare/verifycard/customscript/index.jsx b/src/templates/zshare/verifycard/customscript/index.jsx
index eb193a5..d371c52 100644
--- a/src/templates/zshare/verifycard/customscript/index.jsx
+++ b/src/templates/zshare/verifycard/customscript/index.jsx
@@ -183,12 +183,12 @@
 
         sql += _backCustomScript + tail
 
-        if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-          window.GLOB.funcs.forEach(item => {
-            let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig')
-            sql = sql.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
-          })
-        }
+        // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+        //   window.GLOB.funcs.forEach(item => {
+        //     let reg = new RegExp('\\$ex@' + item.func_code + '@ex\\$', 'ig')
+        //     sql = sql.replace(reg, `/*$ex@${item.func_code}-begin*/\n${item.key_sql}\n/*@ex$-end*/`)
+        //   })
+        // }
 
         // 鏁版嵁鏉冮檺
         sql = sql.replace(/@\$|\$@/ig, '').replace(/\$check@|@check\$/ig, '')
@@ -204,14 +204,19 @@
           sql = sql.replace(/@statusname@/ig, `'寮�濮�'`)
           sql = sql.replace(/@work_group@/ig, `'work_group'`)
           sql = sql.replace(/@work_grade@/ig, '0')
-          sql = sql.replace(/@start_type@/ig, `'寮�濮�'`)
-          sql = sql.replace(/@check_type@/ig, `'瀹℃牳'`)
-          sql = sql.replace(/@notice_type@/ig, `'鎶勯��'`)
-
-          sql = sql.replace(/@check_userids@/ig, `''`)
-          sql = sql.replace(/@notice_userids@/ig, `''`)
           
-          sql = sql.replace(/@works_flow_sign@/ig, `''`)
+          
+          if (flowType === 'start') {
+            sql = sql.replace(/@start_type@/ig, `'寮�濮�'`)
+          } else {
+            sql = sql.replace(/@check_type@/ig, `'瀹℃牳'`)
+            sql = sql.replace(/@notice_type@/ig, `'鎶勯��'`)
+
+            sql = sql.replace(/@check_userids@/ig, `''`)
+            sql = sql.replace(/@notice_userids@/ig, `''`)
+
+            sql = sql.replace(/@works_flow_sign@/ig, `''`)
+          }
         }
         
         if (skip) {
@@ -328,7 +333,7 @@
   }
 
   render() {
-    const { formfields, colfields, systemScripts, btn, type, workFlow } = this.props
+    const { formfields, colfields, systemScripts, btn, type, workFlow, flowType } = this.props
     const { getFieldDecorator } = this.props.form
     const { editItem, skip } = this.state
     const formItemLayout = {
@@ -360,7 +365,7 @@
           {!_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, 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}
+              {window.GLOB.process && workFlow === 'true' ? <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={`宸ヤ綔娴佸彉閲忥紝璇锋寜鐓xxx@鏍煎紡浣跨敤${flowType !== 'start' ? '锛寃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, {flowType === 'start' ? '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>
               {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/fullScripts/index.jsx b/src/templates/zshare/verifycard/fullScripts/index.jsx
index 0fee3ee..b5433c1 100644
--- a/src/templates/zshare/verifycard/fullScripts/index.jsx
+++ b/src/templates/zshare/verifycard/fullScripts/index.jsx
@@ -69,7 +69,7 @@
                 position = <span style={{color: 'orange'}}>鍒濆鍖�</span>
               } else if (item.position === 'front') {
                 position = <span style={{color: '#26C281'}}>sql鍓�</span>
-              } else {
+              } else if (item.position === 'back') {
                 position = <span style={{color: '#1890ff'}}>sql鍚�</span>
               }
 
diff --git a/src/templates/zshare/verifycard/index.jsx b/src/templates/zshare/verifycard/index.jsx
index 9e50ea7..9113732 100644
--- a/src/templates/zshare/verifycard/index.jsx
+++ b/src/templates/zshare/verifycard/index.jsx
@@ -663,20 +663,20 @@
       _verify.printTempId = ''
     }
 
-    if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-      window.GLOB.funcs.forEach(m => {
-        let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig')
-        _verify.customverifys.forEach(item => {
-          item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
-        })
-        _verify.scripts.forEach(item => {
-          item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
-        })
-        _verify.cbScripts.forEach(item => {
-          item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
-        })
-      })
-    }
+    // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+    //   window.GLOB.funcs.forEach(m => {
+    //     let reg = new RegExp(`\\/\\*\\$ex@${m.func_code}-begin\\*\\/[\\s\\S]+\\/\\*@ex\\$-end\\*\\/`, 'ig')
+    //     _verify.customverifys.forEach(item => {
+    //       item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
+    //     })
+    //     _verify.scripts.forEach(item => {
+    //       item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
+    //     })
+    //     _verify.cbScripts.forEach(item => {
+    //       item.sql = item.sql.replace(reg, `$ex@${m.func_code}@ex$`)
+    //     })
+    //   })
+    // }
 
     _verify.customverifys.forEach((item, i) => {
       item.$index = i + 1
@@ -695,11 +695,19 @@
       activeKey = 'cbScripts'
     }
 
+    let oriVerify = fromJS(_verify).toJS()
+
+    if (_verify.wxAppId) {
+      if (!window.GLOB.WXApps || window.GLOB.WXApps.filter(app => app.appType === 'public').length === 0) {
+        delete _verify.wxAppId
+      }
+    }
+
     this.setState({
       activeKey: activeKey,
       verifyInter: verifyInter,
       verify: _verify,
-      oriVerify: fromJS(_verify).toJS()
+      oriVerify: oriVerify
     })
 
     if (card.intertype === 'inner') return
@@ -817,6 +825,8 @@
         if (_f.datatype) { // 鑷畾涔夊瓧娈�
           if (/decimal|int/ig.test(_f.datatype)) {
             _select.push(`@${_f.field}=1`)
+          } else if (/date/ig.test(_f.datatype)) {
+            _select.push(`@${_f.field}='1949-10-01'`)
           } else {
             _select.push(`@${_f.field}=''`)
           }
@@ -1157,7 +1167,6 @@
   }
 
   orderSql = (record) => {
-    let _ModularDetailCode = ''
     let _lpline = ''
     if (record.TypeCharOne === 'Lp') {
       if (record.linkField.toLowerCase() === 'bid') {
@@ -1165,17 +1174,20 @@
       } else {
         _lpline = `set @ModularDetailCode= 'Lp'+ right('${record.mark || this.props.card.uuid}'+@${record.linkField.toLowerCase()},48)`
       }
-      _ModularDetailCode = '@ModularDetailCode'
     } else if (record.TypeCharOne === 'BN') {
-      _ModularDetailCode = `'${record.TypeCharOne}'`
+      if (record.linkField.toLowerCase() === 'bid') {
+        _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
+      } else {
+        _lpline = `set @ModularDetailCode= 'BN'+ right(@${record.linkField.toLowerCase()},48)`
+      }
     } else {
-      _ModularDetailCode = `'${record.ModularDetailCode}'`
+      _lpline = `set @ModularDetailCode= right('${record.ModularDetailCode}',50)`
     }
 
     let sql = `select @BillCode='', @${record.field}='', @ModularDetailCode=''
     ${_lpline}
     exec s_get_BillCode
-      @ModularDetailCode=${_ModularDetailCode},
+      @ModularDetailCode=@ModularDetailCode,
       @Type=${record.Type},
       @TypeCharOne='${record.TypeCharOne}',
       @TypeCharTwo ='${record.TypeCharTwo}',
@@ -1583,20 +1595,20 @@
         msg = '鑷畾涔夎剼鏈�'
       }
 
-      if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
-        window.GLOB.funcs.forEach(m => {
-          let reg = new RegExp('\\$ex@' + m.func_code + '@ex\\$', 'ig')
-          verify.customverifys.forEach(item => {
-            item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
-          })
-          verify.scripts.forEach(item => {
-            item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
-          })
-          verify.cbScripts.forEach(item => {
-            item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
-          })
-        })
-      }
+      // if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
+      //   window.GLOB.funcs.forEach(m => {
+      //     let reg = new RegExp('\\$ex@' + m.func_code + '@ex\\$', 'ig')
+      //     verify.customverifys.forEach(item => {
+      //       item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
+      //     })
+      //     verify.scripts.forEach(item => {
+      //       item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
+      //     })
+      //     verify.cbScripts.forEach(item => {
+      //       item.sql = item.sql.replace(reg, `/*$ex@${m.func_code}-begin*/\n${m.key_sql}\n/*@ex$-end*/`)
+      //     })
+      //   })
+      // }
 
       delete verify.limitInvalid
       delete verify.limitText
diff --git a/src/utils/sqlFormatter.js b/src/utils/sqlFormatter.js
index 0dd99e8..e14e46b 100644
--- a/src/utils/sqlFormatter.js
+++ b/src/utils/sqlFormatter.js
@@ -247,43 +247,43 @@
 	    };
  
 	    Formatter.prototype.getFormattedQueryFromTokens = function getFormattedQueryFromTokens() {
-	        var _this = this;
+	        var that = this;
 	        var formattedQuery = "";
 	        this.tokens.forEach(function (token, index) {
-	            _this.index = index;
+	            that.index = index;
 	            if (token.type === _tokenTypes2["default"].WHITESPACE) {
 	                // ignore (we do our own whitespace formatting)
 	            } else if (token.type === _tokenTypes2["default"].LINE_COMMENT) {
-	                formattedQuery = _this.formatLineComment(token, formattedQuery);
+	                formattedQuery = that.formatLineComment(token, formattedQuery);
 	            } else if (token.type === _tokenTypes2["default"].BLOCK_COMMENT) {
-	                formattedQuery = _this.formatBlockComment(token, formattedQuery);
+	                formattedQuery = that.formatBlockComment(token, formattedQuery);
 	            } else if (token.type === _tokenTypes2["default"].RESERVED_TOPLEVEL) {
-	                formattedQuery = _this.formatToplevelReservedWord(token, formattedQuery);
-	                _this.previousReservedWord = token;
+	                formattedQuery = that.formatToplevelReservedWord(token, formattedQuery);
+	                that.previousReservedWord = token;
 	            } else if (token.type === _tokenTypes2["default"].RESERVED_NEWLINE) {
-	                formattedQuery = _this.formatNewlineReservedWord(token, formattedQuery);
-	                _this.previousReservedWord = token;
+	                formattedQuery = that.formatNewlineReservedWord(token, formattedQuery);
+	                that.previousReservedWord = token;
 	            }else if (token.type === _tokenTypes2["default"].RESERVED) {
-	                formattedQuery = _this.formatWithSpaces(token, formattedQuery);
-	                _this.previousReservedWord = token;
+	                formattedQuery = that.formatWithSpaces(token, formattedQuery);
+	                that.previousReservedWord = token;
 	            } else if (token.type === _tokenTypes2["default"].OPEN_PAREN) {
-	                formattedQuery = _this.formatOpeningParentheses(token, formattedQuery);
+	                formattedQuery = that.formatOpeningParentheses(token, formattedQuery);
 	            } else if (token.type === _tokenTypes2["default"].CLOSE_PAREN) {
-	                formattedQuery = _this.formatClosingParentheses(token, formattedQuery);
+	                formattedQuery = that.formatClosingParentheses(token, formattedQuery);
 	            } else if (token.type === _tokenTypes2["default"].PLACEHOLDER) {
-	                formattedQuery = _this.formatPlaceholder(token, formattedQuery);
+	                formattedQuery = that.formatPlaceholder(token, formattedQuery);
 	            }   else if (token.value === '$') {
-	                formattedQuery = _this.formatNewWithSpaces(token, formattedQuery);
+	                formattedQuery = that.formatNewWithSpaces(token, formattedQuery);
 	            } else if (token.value === ",") {
-	                formattedQuery = _this.formatComma(token, formattedQuery);
+	                formattedQuery = that.formatComma(token, formattedQuery);
 	            } else if (token.value === ":") {
-	                formattedQuery = _this.formatWithSpaceAfter(token, formattedQuery);
+	                formattedQuery = that.formatWithSpaceAfter(token, formattedQuery);
 	            } else if (token.value === ".") {
-	                formattedQuery = _this.formatWithoutSpaces(token, formattedQuery);
+	                formattedQuery = that.formatWithoutSpaces(token, formattedQuery);
 	            } else if (token.value === ";") {
-	                formattedQuery = _this.formatQuerySeparator(token, formattedQuery);
+	                formattedQuery = that.formatQuerySeparator(token, formattedQuery);
 	            } else {
-	                formattedQuery = _this.formatWithSpaces(token, formattedQuery);
+	                formattedQuery = that.formatWithSpaces(token, formattedQuery);
 	            }
 	        });
 	        return formattedQuery;
@@ -545,10 +545,10 @@
 	    };
  
 	    Tokenizer.prototype.createParenRegex = function createParenRegex(parens) {
-	        var _this = this;
+	        var that = this;
  
 	        return new RegExp("^(" + parens.map(function (p) {
-	            return _this.escapeParen(p);
+	            return that.escapeParen(p);
 	        }).join("|") + ")", "i");
 	    };
  
@@ -669,13 +669,13 @@
 	    };
  
 	    Tokenizer.prototype.getStringNamedPlaceholderToken = function getStringNamedPlaceholderToken(input) {
-	        var _this2 = this;
+	        var that2 = this;
  
 	        return this.getPlaceholderTokenWithKey({
 	            input: input,
 	            regex: this.STRING_NAMED_PLACEHOLDER_REGEX,
 	            parseKey: function parseKey(v) {
-	                return _this2.getEscapedPlaceholderKey({ key: v.slice(2, -1), quoteChar: v.slice(-1) });
+	                return that2.getEscapedPlaceholderKey({ key: v.slice(2, -1), quoteChar: v.slice(-1) });
 	            }
 	        });
 	    };
diff --git a/src/utils/utils-custom.js b/src/utils/utils-custom.js
index 1141a14..3a6e6de 100644
--- a/src/utils/utils-custom.js
+++ b/src/utils/utils-custom.js
@@ -1,4 +1,5 @@
 import md5 from 'md5'
+import { fromJS } from 'immutable'
 import { notification } from 'antd'
 
 export default class MenuUtils {
@@ -703,10 +704,6 @@
   * @return {String}  item 缁勪欢淇℃伅
   */
   static resetComponentConfig = (item, appType, commonId) => {
-    if (item.type === 'navbar') {
-      return item
-    }
-
     if (item.subtype === 'tablecard') { // 鍏煎
       item.type = 'card'
     }
@@ -724,7 +721,22 @@
       item.name = item.setting.name
     }
 
-    if (item.type === 'menubar') {
+    if (item.columns) {
+      item.columns = item.columns.map(cell => {
+        cell.uuid = this.getuuid()
+        return cell
+      })
+    }
+
+    if (item.type === 'navbar') {
+      if (appType === 'mob') {
+        item.menus.forEach(menu => {
+          menu.MenuID = this.getuuid()
+        })
+        item.wrap.MenuNo = item.wrap.MenuNo + sign
+      }
+      return item
+    } else if (item.type === 'menubar') {
       item.subMenus = item.subMenus.map(cell => {
         cell.uuid = this.getuuid()
         return cell
@@ -923,12 +935,6 @@
       }
     } else if (item.search) {
       item.search = item.search.map(cell => {
-        cell.uuid = this.getuuid()
-        return cell
-      })
-    }
-    if (item.columns) {
-      item.columns = item.columns.map(cell => {
         cell.uuid = this.getuuid()
         return cell
       })
@@ -1739,6 +1745,115 @@
 }
 
 /**
+ * @description 鑾峰彇鍙戦�佸閮ㄦ秷鎭�
+ */
+export function getOutMessage (config) {
+  let message = 'false'
+
+  let filterBtn = (cell) => {
+    if (['pop', 'exec', 'form', 'prompt', 'formSubmit'].includes(cell.OpenType) && cell.verify) {
+      if (cell.verify.noteEnable === 'true' || cell.verify.wxNote === 'true' || cell.verify.emailEnable === 'true') {
+        message = 'true'
+      }
+    }
+  }
+
+  let traversal = (components) => {
+    if (!components || message === 'true') return
+
+    components.forEach(item => {
+      if (item.type === 'tabs') {
+        item.subtabs.forEach(tab => {
+          traversal(tab.components)
+        })
+      } else if (item.type === 'group') {
+        traversal(item.components)
+      } else {
+        if (item.action) {
+          item.action.forEach(cell => {
+            if (cell.OpenType === 'popview') {
+              if (cell.config) {
+                traversal(cell.config.components)
+              }
+            } else {
+              filterBtn(cell)
+            }
+          })
+        }
+
+        if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
+          item.subcards.forEach(card => {
+            card.elements && card.elements.forEach(cell => {
+              if (cell.eleType !== 'button') return
+              
+              if (cell.OpenType === 'popview') {
+                if (cell.config) {
+                  traversal(cell.config.components)
+                }
+              } else {
+                filterBtn(cell)
+              }
+            })
+            card.backElements && card.backElements.forEach(cell => {
+              if (cell.eleType !== 'button') return
+              
+              if (cell.OpenType === 'popview') {
+                if (cell.config) {
+                  traversal(cell.config.components)
+                }
+              } else {
+                filterBtn(cell)
+              }
+            })
+          })
+        } else if (item.type === 'balcony') {
+          item.elements && item.elements.forEach(cell => {
+            if (cell.eleType !== 'button') return
+            
+            if (cell.OpenType === 'popview') {
+              if (cell.config) {
+                traversal(cell.config.components)
+              }
+            } else {
+              filterBtn(cell)
+            }
+          })
+        } else if (item.type === 'table') {
+          let loopCol = (cols) => {
+            cols.forEach(col => {
+              if (col.type === 'colspan') {
+                loopCol(col.subcols)
+              } else if (col.type === 'custom') {
+                col.elements.forEach(cell => {
+                  if (cell.eleType !== 'button') return
+                  
+                  if (cell.OpenType === 'popview') {
+                    if (cell.config) {
+                      traversal(cell.config.components)
+                    }
+                  } else {
+                    filterBtn(cell)
+                  }
+                })
+              }
+            })
+          }
+          loopCol(item.cols)
+        } else if (item.type === 'form') {
+          item.subcards.forEach(group => {
+            filterBtn(group.subButton)
+          })
+        }
+      }
+    })
+  }
+
+  traversal(config.components)
+
+  return message
+}
+
+/**
  * @description 妫�娴嬬粍浠跺唴瀹�
  */
 export function checkComponent (card) {
@@ -1835,6 +1950,33 @@
     }
 
     if (['exec', 'prompt', 'pop', 'form', 'formSubmit'].includes(cell.OpenType)) {
+      if (cell.Ot !== 'requiredOnce' && ['pop', 'form'].includes(cell.OpenType) && cell.verify && cell.verify.uniques && cell.verify.uniques.length > 0) {
+        let forms = ['BID']
+    
+        if (cell.OpenType === 'form') {
+          forms.push(cell.field)
+        } else if (cell.modal && cell.modal.fields.length > 0) {
+          cell.modal.fields.forEach(n => {
+            if (!n.field) return
+            forms.push(n.field)
+          })
+        }
+        let emptys = []
+        cell.verify.uniques.forEach(m => {
+          if (m.status === 'false') return
+
+          m.field.split(',').forEach(n => {
+            if (!forms.includes(n)) {
+              emptys.push(n)
+            }
+          })
+        })
+
+        if (emptys.length) {
+          errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濆敮涓�鎬ч獙璇佸瓧娈�${emptys.join('銆�')}锛屽湪琛ㄥ崟涓笉瀛樺湪锛乣})
+        }
+      }
+
       if (cell.OpenType === 'form' && cell.formType === 'count_line') return
      
       if (cell.intertype === 'system') {
@@ -1842,21 +1984,27 @@
           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)) {
+        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 === 'funcbutton') {
+      if (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.funcType === 'refund' || cell.funcType === 'pay') && cell.payMode === 'system' && (!cell.verify || !cell.verify.scripts || cell.verify.scripts.filter(item => item.status !== 'false').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}鈥濋〉闈㈢被鍨嬭缃敊璇紒`})
+      } else if (cell.pageTemplate === 'pay' && cell.payMode === 'system' && (!cell.verify || !cell.verify.scripts || cell.verify.scripts.filter(item => item.status !== 'false').length === 0)) {
+        errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濋渶娣诲姞鑷畾涔夎剼鏈紒`})
       }
     }
   }
@@ -1973,10 +2121,18 @@
   let _quot = sql.match(/'{1}/g)
   let _lparen = sql.match(/\({1}/g)
   let _rparen = sql.match(/\){1}/g)
+  let _ch_b = sql.match(/\$check@/ig)
+  let _ch_d = sql.match(/@check\$/ig)
+  let _m_b = sql.match(/\$@/ig)
+  let _m_d = sql.match(/@\$/ig)
 
   _quot = _quot ? _quot.length : 0
   _lparen = _lparen ? _lparen.length : 0
   _rparen = _rparen ? _rparen.length : 0
+  _ch_b = _ch_b ? _ch_b.length : 0
+  _ch_d = _ch_d ? _ch_d.length : 0
+  _m_b = _m_b ? _m_b.length : 0
+  _m_d = _m_d ? _m_d.length : 0
 
   if (_quot % 2 !== 0) {
     notification.warning({
@@ -1989,6 +2145,20 @@
     notification.warning({
       top: 92,
       message: 'sql涓�()蹇呴』鎴愬鍑虹幇',
+      duration: 5
+    })
+    return false
+  } else if (_ch_b !== _ch_d) {
+    notification.warning({
+      top: 92,
+      message: 'sql涓� $check@ 涓� @check$ 蹇呴』鎴愬鍑虹幇',
+      duration: 5
+    })
+    return false
+  } else if (_m_b !== _m_d) {
+    notification.warning({
+      top: 92,
+      message: 'sql涓� $@ 涓� @$ 蹇呴』鎴愬鍑虹幇',
       duration: 5
     })
     return false
@@ -2050,13 +2220,20 @@
       duration: 5
     })
     return false
+  } else if (/\sdecimal\(8,/ig.test(sql)) {
+    notification.warning({
+      top: 92,
+      message: `涓嶅彲浣跨敤 decimal(8`,
+      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 = []
     list.forEach(str => {
       str = str.replace(/^\s/, '')
       let strs = str.match(/(\s|=)[a-z0-9_]+\./ig)
-      if (strs.length === 2 && (strs[0].replace(/\s|\./g, '') === strs[1].replace(/\s|\./g, ''))) {
+      if (strs.length === 2 && (strs[0].replace(/\s|\.|=/g, '') === strs[1].replace(/\s|\.|=/g, ''))) {
         errors.push(str)
       }
     })
@@ -2831,4 +3008,3314 @@
   }
 
   traversal(config.components)
+}
+
+/**
+ * @description 鑾峰彇鎵ц鑴氭湰
+ */
+export function getAllSqls (conf) {
+  let config = fromJS(conf).toJS()
+
+  let sqls = []
+  let urlFields = config.urlFields
+  let appType = sessionStorage.getItem('appType')
+  let process = config.process === 'true'
+  let sysVars = ['loginuid', 'sessionuid', 'userid', 'appkey', 'lang', 'username', 'fullname', 'menuname']
+
+  if (urlFields) {
+    urlFields = urlFields.map(n => n.toLowerCase())
+  }
+
+let callback = `
+COMMIT TRAN
+set NOCOUNT ON
+RETURN
+END TRY
+BEGIN CATCH
+  ROLLBACK TRAN
+  DECLARE @ErrorMessage NVARCHAR(4000);
+  DECLARE @ErrorSeverity INT;
+  DECLARE @ErrorState INT;
+
+  set @ErrorCode=cast(ERROR_NUMBER() as nvarchar(50))
+  set @retmsg=ERROR_MESSAGE();
+  select @ErrorMessage=ERROR_MESSAGE(), @ErrorSeverity=ERROR_SEVERITY(), @ErrorState=ERROR_STATE();
+
+  RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
+END CATCH
+
+aaa:
+select @ErrorCode as ErrorCode,@retmsg as retmsg
+GOTO_RETURN:
+  ROLLBACK TRAN`
+
+  let filterComponent = (components, mainSearch, label = '') => {
+    components.forEach(item => {
+      item.$menuname = (config.MenuName || '') + label + '-' + (item.name || '')
+
+      if (item.type === 'tabs') {
+        item.subtabs.forEach(tab => {
+          let _mainSearch = mainSearch || []
+
+          if (appType !== 'mob') {
+            tab.components.forEach(com => {
+              if (com.type !== 'search') return
+        
+              _mainSearch = com.search || []
+            })
+          }
+          filterComponent(tab.components, _mainSearch, label)
+        })
+      } else if (item.type === 'group') {
+        filterComponent(item.components, mainSearch, label)
+      } else {
+        if (item.wrap && item.setting) {
+          if (item.wrap.datatype === 'public' || item.wrap.datatype === 'static') {
+            item.setting.interType = 'other'
+          }
+        }
+
+        if (appType === 'mob' && item.type !== 'search' && item.type !== 'topbar' && item.search && item.search.length > 0) {
+          item.search = []
+        }
+        if (appType !== 'mob' && item.search && item.search.length > 0) {
+          item.search.forEach(cell => {
+            if (['select', 'link', 'multiselect', 'checkcard', 'radio'].includes(cell.type) && cell.resourceType === '1' && cell.dataSource) {
+              let msg = getFormSql(cell, '鎼滅储')
+      
+              sqls.push({uuid: md5(item.uuid + cell.uuid), type: 'sForm', ...msg})
+            }
+          })
+        }
+
+        if (item.subtype === 'tablecard') { // 鍏煎
+          item.type = 'card'
+        }
+
+        if (item.setting && item.setting.interType === 'system') {
+          if (item.format === 'object') {
+            item.setting.laypage = 'false'
+            item.setting.$top = true
+          }
+          item.setting.$name = item.$menuname || ''
+
+          let msg = getDataSource(item, mainSearch)
+
+          sqls.push({uuid: item.uuid, type: 'datasource', ...msg})
+        } else if (item.setting && item.setting.useMSearch === 'true') {
+          let searches = item.search || []
+          if (mainSearch.length > 0) {
+            searches = [...searches, ...mainSearch]
+          }
+          item.$searches = fromJS(searches).toJS()
+        }
+
+        item.action && item.action.forEach(cell => {
+          if (cell.hidden === 'true') return false
+          
+          resetButton(item, cell)
+        })
+
+        if (item.type === 'table') {
+          let getCols = (cols) => {
+            cols.forEach(col => {
+              if (col.type === 'action') {
+                col.type = 'custom'
+              }
+              if (col.type === 'colspan') {
+                getCols(col.subcols || [])
+              } else if (col.type === 'custom') {
+                col.elements.forEach(cell => {
+                  if (cell.eleType !== 'button' || cell.hidden === 'true') return
+                  
+                  resetButton(item, cell)
+                })
+              } else if (item.subtype === 'editable' && col.editable === 'true') {
+                if (col.editType === 'select' && col.resourceType === '1') {
+                  let msg = getFormSql(col, '琛ㄥ崟')
+        
+                  sqls.push({uuid: col.uuid, type: 'tbForm', ...msg})
+                } else if (col.editType === 'popSelect') {
+                  if (col.pops) {
+                    col.pops.forEach(n => {
+                      let msg = getPopSelectSql(n)
+        
+                      sqls.push({uuid: n.uuid, type: 'popSource', ...msg})
+                    })
+                  } else {
+                    let msg = getPopSelectSql(col)
+        
+                    sqls.push({uuid: col.uuid, type: 'popSource', ...msg})
+                  }
+                }
+              }
+            })
+          }
+          
+          getCols(item.cols)
+  
+          if (item.subtype === 'editable' && item.submit.intertype === 'system') {
+            item.submit.logLabel = item.$menuname + '-鎻愪氦'
+            let msg = getEditTableSql(item.submit, item.cols, item.columns, item.setting)
+
+            sqls.push({uuid: 'submit_' + item.uuid, type: 'editable', ...msg})
+          }
+        } else if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
+          item.subcards && item.subcards.forEach(card => {
+            card.elements && card.elements.forEach(cell => {
+              if (cell.eleType !== 'button' || cell.hidden === 'true') return
+              
+              resetButton(item, cell)
+            })
+  
+            if (!card.backElements || card.backElements.length === 0) return
+  
+            card.backElements.forEach(cell => {
+              if (cell.eleType !== 'button' || cell.hidden === 'true') return
+              
+              resetButton(item, cell, true)
+            })
+          })
+        } else if (item.type === 'balcony') {
+          item.elements.forEach(cell => {
+            if (cell.eleType !== 'button' || cell.hidden === 'true') return
+            
+            resetButton(item, cell)
+          })
+        } else if (item.type === 'form') {
+          item.subcards.forEach(group => {
+            group.subButton.OpenType = 'formSubmit'
+            if (!group.subButton.Ot) {
+              group.subButton.Ot = item.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
+            }
+            group.subButton.uuid = group.uuid
+            group.subButton.modal = {
+              fields: group.fields
+            }
+
+            resetButton(item, group.subButton)
+          })
+        } else if (item.type === 'module' && item.subtype === 'invoice') {
+          if (item.buyer.setting && item.buyer.setting.interType === 'system') {
+            let msg = getDataSource(item.buyer, [])
+            
+            sqls.push({uuid: item.uuid + 'buyer', type: 'datasource', ...msg})
+          }
+
+          if (item.detail.setting && item.detail.setting.interType === 'system') {
+            let _msg = getDataSource(item.detail, [])
+  
+            sqls.push({uuid: item.uuid + 'detail', type: 'datasource', ..._msg})
+          }
+
+          let btnmsg = getInvoicePreSql(item.billSaveBtn, item.$menuname + '-' + item.billSaveBtn.label)
+
+          sqls.push({uuid: item.uuid + item.billSaveBtn.type, type: 'button', ...btnmsg})
+
+          let _btnmsg = getInvoicePreSql(item.billOutBtn, item.$menuname + '-'  + item.billOutBtn.label)
+
+          sqls.push({uuid: item.uuid + item.billOutBtn.type, type: 'button', ..._btnmsg})
+
+          let backmsg = getInvoiceSysBackSql(item.billOutBtn, item.$menuname + '-'  + item.billOutBtn.label + '(鍥炶皟)')
+
+          sqls.push({uuid: item.uuid + 'billback', type: 'btnCallBack', ...backmsg})
+        }
+      }
+    })
+  }
+
+  let resetButton = (item, cell, isback) => {
+    cell.logLabel = item.$menuname + '-' + cell.label
+
+    if (['exec', 'prompt', 'pop', 'form', 'formSubmit'].includes(cell.OpenType)) {
+      if (cell.intertype === 'system' || cell.procMode === 'system') { // 绯荤粺鎺ュ彛
+        if (cell.verify && cell.verify.linkEnable === 'true' && /@/.test(cell.verify.linkUrl)) {
+          cell.returnValue = 'true'
+        }
+        if (item.subtype === 'dualdatacard' && isback) {
+          let _item = fromJS(item).toJS()
+          _item.columns = _item.subColumns || []
+          _item.setting.primaryKey = _item.setting.subKey
+
+          let msg = getSysDefaultSql(cell, _item)
+
+          sqls.push({uuid: cell.uuid, type: 'button', ...msg})
+        } else {
+          let msg = getSysDefaultSql(cell, item)
+
+          sqls.push({uuid: cell.uuid, type: 'button', ...msg})
+        }
+      }
+      if (cell.callbackType === 'script' && cell.verify && cell.verify.cbScripts) {
+        if (item.subtype === 'dualdatacard' && isback) {
+          let _item = fromJS(item).toJS()
+          _item.columns = _item.subColumns || []
+          
+          let msg = getSysBackSql(cell, _item)
+
+          sqls.push({uuid: 'back_' + cell.uuid, type: 'btnCallBack', ...msg})
+        } else {
+          let msg = getSysBackSql(cell, item)
+
+          sqls.push({uuid: 'back_' + cell.uuid, type: 'btnCallBack', ...msg})
+        }
+      }
+      if (['pop', 'formSubmit'].includes(cell.OpenType) && cell.modal && cell.modal.fields) {
+        cell.modal.fields.forEach(form => {
+          // 鏁版嵁婧恠ql璇彞锛岄澶勭悊锛屾潈闄愰粦鍚嶅崟瀛楁璁剧疆涓洪殣钘忚〃鍗�
+          if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(form.type) && form.resourceType === '1') {
+            let msg = getFormSql(form, '琛ㄥ崟')
+
+            sqls.push({uuid: md5(cell.uuid + form.uuid), type: 'form', ...msg})
+          } else if (form.type === 'popSelect') {
+            let msg = getPopSelectSql(form)
+        
+            sqls.push({uuid: form.uuid, type: 'popSource', ...msg})
+          }
+        })
+      }
+    } else if (cell.OpenType === 'excelIn') {
+      if (cell.intertype === 'system') {
+        let msg = getExcelInSql(cell)
+
+        sqls.push({uuid: cell.uuid, type: 'excelIn', ...msg})
+      }
+    } else if (cell.OpenType === 'excelOut') {
+      if (cell.intertype === 'system' && cell.verify && cell.verify.dataType === 'custom') {
+        let msg = getExcelOutSql(cell, item)
+
+        sqls.push({uuid: cell.uuid, type: 'excelOut', ...msg})
+      } else if (cell.intertype === 'system' && cell.verify && item.subtype === 'dualdatacard' && item.setting && item.setting.interType === 'system') {
+        let msg = getDoubleExcelOutSql(cell, item)
+
+        sqls.push({uuid: cell.uuid, type: 'excelOut', ...msg})
+      }
+    } else if (cell.OpenType === 'funcbutton') {
+      if (cell.funcType === 'print') {
+        if (cell.intertype === 'system' && cell.verify && cell.verify.dataType === 'custom') {
+          let msg = getPrintSql(cell, item)
+  
+          sqls.push({uuid: cell.uuid, type: 'print', ...msg})
+        }
+        if (cell.execMode === 'pop' && cell.modal && cell.modal.fields) {
+          cell.modal.fields.forEach(form => {
+            // 鏁版嵁婧恠ql璇彞锛岄澶勭悊锛屾潈闄愰粦鍚嶅崟瀛楁璁剧疆涓洪殣钘忚〃鍗�
+            if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(form.type) && form.resourceType === '1') {
+              let msg = getFormSql(form, '琛ㄥ崟')
+    
+              sqls.push({uuid: md5(cell.uuid + form.uuid), type: 'form', ...msg})
+            } else if (form.type === 'popSelect') {
+              let msg = getPopSelectSql(form)
+          
+              sqls.push({uuid: form.uuid, type: 'popSource', ...msg})
+            }
+          })
+        }
+      } else if ((cell.funcType === 'refund' || cell.funcType === 'pay') && cell.payMode === 'system') {
+        let msg = getPaySql(cell, item)
+
+        sqls.push({uuid: cell.uuid, type: 'pay', ...msg})
+      }
+    } else if (cell.OpenType === 'innerpage' || cell.OpenType === 'outerpage') {
+      if (cell.pageTemplate === 'pay' && cell.payMode === 'system') {
+        let msg = getPaySql(cell, item)
+
+        sqls.push({uuid: cell.uuid, type: 'pay', ...msg})
+      }
+    } else if (cell.OpenType === 'popview') {
+      if (cell.config && cell.config.components) {
+        let _mainSearch = []
+
+        if (appType === 'mob') {
+          cell.config.components.forEach(item => {
+            if (item.type === 'search' && item.wrap.field) {
+              _mainSearch.push({
+                type: 'text',
+                label: item.wrap.label,
+                field: item.wrap.field,
+                match: item.wrap.match,
+                required: item.wrap.required,
+                value: item.wrap.initval || ''
+              })
+            }
+          })
+        } else {
+          cell.config.components.forEach(component => {
+            if (component.type !== 'search') return
+
+            _mainSearch = component.search || []
+          })
+        }
+
+        filterComponent(cell.config.components, _mainSearch, '-' + cell.label)
+      }
+    }
+  }
+
+  let getSearches = (searches) => {
+    let sFields = []
+    searches.forEach(item => {
+      if (!item.field) return
+  
+      if (item.type === 'group') {
+        sFields.push(item.field)
+        sFields.push(item.datefield)
+        sFields.push(item.datefield + '1')
+      } else if (item.type === 'date') {
+        if (sFields.includes(item.field)) {
+          sFields.push(item.field + '1')
+        } else {
+          sFields.push(item.field)
+        }
+      } else if (item.type === 'dateweek') {
+        sFields.push(item.field)
+        sFields.push(item.field + '1')
+      } else if (item.type === 'range') {
+        sFields.push(item.field)
+        sFields.push(item.field + '1')
+      } else if (item.type === 'datemonth') {
+        if (item.match === '=') {
+          sFields.push(item.field)
+        } else {
+          sFields.push(item.field)
+          sFields.push(item.field + '1')
+        }
+      } else if (item.type === 'daterange') {
+        if (/,/.test(item.field)) {
+          sFields.push(item.field.split(',')[0])
+          sFields.push(item.field.split(',')[1])
+        } else {
+          sFields.push(item.field)
+          sFields.push(item.field + '1')
+        }
+      } else if (item.type === 'text' || item.type === 'select') {
+        item.field.split(',').forEach(field => {
+          sFields.push(field)
+        })
+      } else {
+        sFields.push(item.field)
+      }
+    })
+  
+    return sFields
+  }
+
+  let getSysDefaultSql = (btn, component) => {
+    let primaryId = '@ID@'
+    let BID = '@BID@'
+    let verify = btn.verify || {}
+    let _actionType = null
+    let setting = component.setting || {}
+    let columns = component.columns || []
+    let primaryKey = setting.primaryKey || 'id'
+    let colreps = [] // 寰呮浛鎹㈠彉閲忛泦
+
+    if (verify.invalid === 'true') {
+      if (component.wrap && (component.wrap.datatype === 'static' || component.wrap.datatype === 'public')) {
+        verify.invalid = 'false'
+      } else if (setting.maxScript && setting.maxScript >= 300) {
+        verify.invalid = 'false'
+      } else if (!setting.dataresource) {
+        verify.invalid = 'false'
+      } else if (btn.intertype !== 'system' && btn.procMode !== 'system') {
+        verify.invalid = 'false'
+      } else if (btn.sqlType === 'insert') {
+        verify.invalid = 'false'
+      } else if (btn.Ot === 'notRequired') {
+        verify.invalid = 'false'
+      }
+    }
+    if (verify.uniques && verify.uniques.length > 0 && btn.Ot === 'requiredOnce') {
+      if (component.wrap && (component.wrap.datatype === 'static' || component.wrap.datatype === 'public')) {
+        verify.uniques = []
+      }
+    }
+  
+    if (verify.default !== 'false') { // 鍒ゆ柇鏄惁浣跨敤榛樿sql
+      _actionType = btn.sqlType
+    }
+  
+    let _initCustomScript = '' // 鍒濆鍖栬剼鏈�
+    let _prevCustomScript = '' // 榛樿sql鍓嶆墽琛岃剼鏈�
+    let _backCustomScript = '' // 榛樿sql鍚庢墽琛岃剼鏈�
+  
+    verify.scripts && verify.scripts.forEach(item => {
+      if (item.status === 'false') return
+  
+      if (item.position === 'init') {
+        _initCustomScript += `
+        /* 鑷畾涔夎剼鏈� */
+        ${item.sql}
+        `
+      } else if (item.position === 'front') {
+        _prevCustomScript += `
+        /* 鑷畾涔夎剼鏈� */
+        ${item.sql}
+        `
+      } else {
+        _backCustomScript += `
+        /* 鑷畾涔夎剼鏈� */
+        ${item.sql}
+        `
+      }
+    })
+  
+    // 闇�瑕佸0鏄庣殑鍙橀噺闆�
+    let _vars = ['tbid', 'errorcode', 'retmsg', 'billcode', 'bvoucher', 'fibvoucherdate', 'fiyear', 'username', 'fullname', 'modulardetailcode', 'roleid', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'mk_deleted', 'bid']
+  
+    let _sql = ''
+  
+    let _initFormfields = []
+    let _declares = []
+
+    let formdata = null
+    let formkeys = []
+    if (btn.OpenType === 'pop' || btn.OpenType === 'formSubmit') {
+      formdata = []
+      if (btn.modal && btn.modal.fields) {
+        btn.modal.fields.forEach(item => {
+          if (!item.field) return
+          
+          let _item = {
+            key: item.field,
+            fieldlen: item.fieldlength || 50,
+            writein: item.writein !== 'false',
+            type: item.type,
+            isconst: item.constant === 'true'
+          }
+
+          if (_item.type === 'datemonth') {
+            _item.type = 'text'
+          } else if (_item.type === 'number' || _item.type === 'rate') {
+            _item.fieldlen = item.decimal || 0
+          } else if (_item.type === 'date') {
+            _item.type = item.declareType === 'nvarchar(50)' ? 'text' : 'date'
+          } else if (_item.type === 'datetime') {
+            _item.type = 'date'
+          } else if (item.declare === 'decimal') {
+            _item.type = 'number'
+            _item.fieldlen = item.decimal || 0
+          }
+    
+          formdata.push(_item)
+        })
+      }
+    } else if (btn.OpenType === 'form') {
+      formdata = []
+
+      let item = {
+        type: 'text',
+        readin: true,
+        writein: true,
+        fieldlen: 50,
+        key: btn.field
+      }
+      if (btn.formType === 'counter') {
+        item.type = 'number'
+        item.fieldlen = 0
+      } else if (btn.formType === 'switch' || btn.formType === 'radio') {
+        if (typeof(btn.openVal) === 'number') {
+          item.type = 'number'
+          item.fieldlen = 0
+        }
+      }
+      formdata.push(item)
+    }
+
+    // 鑾峰彇瀛楁閿�煎
+    formdata && formdata.forEach(form => {
+      let _key = form.key.toLowerCase()
+
+      if (!formkeys.includes(_key)) {
+        formkeys.push(_key)
+        if (form.type === 'number' || form.type === 'rate') {
+          _initFormfields.push(`@${_key}=@mk_${_key}_mk@`)
+        } else if (form.type === 'date') {
+          _initFormfields.push(`@${_key}='@mk_${_key}_mk@'`)
+        } else if (form.type === 'select' || form.type === 'link' || form.type === 'radio') {
+          _initFormfields.push(`@${_key}='@mk_${_key}_mk@'`)
+        } else if (form.isconst) {
+          _initFormfields.push(`@${_key}=N'@mk_${_key}_mk@'`)
+        } else {
+          _initFormfields.push(`@${_key}='@mk_${_key}_mk@'`)
+        }
+      }
+      
+      if (!_vars.includes(_key)) {
+        _vars.push(_key)
+  
+        if (form.fieldlen && form.fieldlen > 4000) {
+          form.fieldlen = 'max'
+        }
+  
+        let _type = `nvarchar(${form.fieldlen})`
+  
+        if (form.type.match(/date/ig)) {
+          _type = 'datetime'
+        } else if (form.type === 'number') {
+          _type = `decimal(18,${form.fieldlen})`
+        } else if (form.type === 'rate') {
+          _type = `decimal(18,2)`
+        }
+  
+        _declares.push(`@${_key} ${_type}`)
+      }
+    })
+  
+    // 琛ㄥ崟鍙橀噺璧嬪��
+    if (_initFormfields.length > 0) {
+      _sql += `
+        /* 琛ㄥ崟鍙橀噺璧嬪�� */
+        select ${_initFormfields.join(',')}
+        `
+    }
+    if (btn.Ot !== 'notRequired' && columns.length > 0) {
+      _sql += '@mk_cols_values@'
+    }
+
+    // 鍘婚櫎绂佺敤鐨勯獙璇�
+    if (verify.contrasts) {
+      verify.contrasts = verify.contrasts.filter(item => item.status !== 'false')
+    }
+    if (verify.uniques) {
+      verify.uniques = verify.uniques.filter(item => item.status !== 'false')
+    }
+    if (verify.customverifys) {
+      verify.customverifys = verify.customverifys.filter(item => item.status !== 'false')
+    }
+    if (verify.billcodes) {
+      verify.billcodes = verify.billcodes.filter(item => item.status !== 'false')
+    }
+  
+    if (_initCustomScript) {
+      _sql += _initCustomScript
+    }
+  
+    // 鍚敤璐︽湡楠岃瘉
+    if (verify.accountdate === 'true') {
+      let orgcode = `''`
+      let date = `''`
+      if (verify.accountfield) {
+        orgcode = '@' + verify.accountfield
+      }
+      if (verify.voucherdate) {
+        date = '@' + verify.voucherdate
+      }
+  
+      _sql += `
+        /* 璐︽湡楠岃瘉 */
+        exec s_FIBVoucherDateCheck @OrgCode=${orgcode},@FIBVoucherDate=${date},@ErrorCode=@ErrorCode OUTPUT,@retmsg=@retmsg OUTPUT
+        if @ErrorCode!=''
+          GOTO aaa
+        `
+    }
+  
+    // 澶辨晥楠岃瘉锛屾坊鍔犳暟鎹椂涓嶇敤
+    if (verify.invalid === 'true') {
+      let datasource = setting.dataresource
+      let customScript = setting.customScript || ''
+
+      let regoptions = [{
+        reg: new RegExp('@orderBy@', 'ig'),
+        value: setting.order || primaryKey
+      }, {
+        reg: new RegExp('@pageSize@', 'ig'),
+        value: 1
+      }, {
+        reg: new RegExp('@pageIndex@', 'ig'),
+        value: 1
+      }]
+
+      regoptions.forEach(item => {
+        datasource = datasource.replace(item.reg, item.value)
+        customScript = customScript.replace(item.reg, item.value)
+      })
+  
+      if (customScript) {
+        _sql += `
+        /* 鏁版嵁婧愯嚜瀹氫箟鑴氭湰锛岃娉ㄦ剰鍙橀噺瀹氫箟鏄惁閲嶅 */
+        ${customScript}
+        `
+      }
+  
+      if (btn.Ot === 'requiredOnce') {
+        _sql += `
+        /* 澶辨晥楠岃瘉 */
+        select @tbid='', @ErrorCode='',@retmsg=''
+        select @tbid='X' from ${datasource} right join (select ID from  dbo.SplitComma(@ID@)) sp
+        on tb.${primaryKey} =sp.id where tb.${primaryKey} is null
+
+        If @tbid!=''
+        Begin
+          select @ErrorCode='E',@retmsg='鏁版嵁宸插け鏁�'
+          goto aaa
+        end
+        `
+      } else {
+        _sql += `
+        /* 澶辨晥楠岃瘉 */
+        select @tbid='', @ErrorCode='',@retmsg=''
+        select @tbid=${primaryKey} from ${datasource} where ${primaryKey}=@ID@
+        If @tbid=''
+        Begin
+          select @ErrorCode='E',@retmsg='鏁版嵁宸插け鏁�'
+          goto aaa
+        end
+        `
+      }
+    }
+  
+    // 姣旇緝楠岃瘉
+    if (verify.contrasts && verify.contrasts.length > 0) {
+      verify.contrasts.forEach(item => {
+        _sql += `
+        /* 姣旇緝楠岃瘉 */
+        If ${item.frontfield} ${item.operator} ${item.backfield}
+        Begin
+          select @ErrorCode='${item.errorCode}',@retmsg='${item.errmsg}'
+            goto aaa
+        end
+        `
+      })
+    }
+    
+    // 鑷畾涔夐獙璇�
+    verify.customverifys && verify.customverifys.forEach(item => {        
+      _sql += `
+        /* 鑷畾涔夐獙璇� */
+        select @tbid='', @ErrorCode='',@retmsg=''
+        select top 1 @tbid='X' from (${item.sql}) a
+        If @tbid ${item.result === 'true' ? '!=' : '='}''
+        Begin
+          select @ErrorCode='${item.errorCode}',@retmsg='${item.errmsg}'
+          goto aaa
+        end
+        `
+    })
+  
+    // 鍗曞彿鐢熸垚锛屼娇鐢ㄤ笂绾d锛圔ID锛夋垨鍒楄〃鏁版嵁锛屽0鏄庡彉閲忥紙妫�楠岋級
+    let _billcodesSql  = ''
+    if (formdata && verify.billcodes && verify.billcodes.length > 0) {
+      verify.billcodes.forEach(item => {
+        let _key = item.field.toLowerCase()
+        let _linkKey = item.linkField ? item.linkField.toLowerCase() : ''
+  
+        if (!formkeys.includes(_key)) return // 琛ㄥ崟涓笉鍚崟鍙风敓鎴愬瓧娈�
+  
+        let _lpline = ''
+        if (item.TypeCharOne === 'Lp') {
+          if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
+            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@BID@,48)`
+          } else {
+            _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${_linkKey},48)`
+          }
+        } else if (item.TypeCharOne === 'BN') {
+          if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
+            _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
+          } else {
+            _lpline = `set @ModularDetailCode= 'BN'+ right(@${_linkKey},48)`
+          }
+        } else {
+          _lpline = `set @ModularDetailCode= right('${item.ModularDetailCode}',50)`
+        }
+  
+        _billcodesSql += `
+        /* 鍗曞彿鐢熸垚 */
+        select @BillCode='', @${_key}='', @ModularDetailCode=''
+        ${_lpline}
+        exec s_get_BillCode
+          @ModularDetailCode=@ModularDetailCode,
+          @Type=${item.Type},
+          @TypeCharOne='${item.TypeCharOne}',
+          @TypeCharTwo ='${item.TypeCharTwo}',
+          @BillCode =@BillCode output,
+          @ErrorCode =@ErrorCode output, 
+          @retmsg=@retmsg output
+        if @ErrorCode!=''
+          goto aaa
+        set @${_key}=@BillCode
+        `
+      })
+  
+      if (_actionType !== 'insertOrUpdate') {
+        _sql += _billcodesSql
+      }
+    }
+  
+    // 鍞竴鎬ч獙璇侊紝蹇呴』瀛樺湪琛ㄥ崟锛堣〃鍗曞瓨鍦ㄦ椂锛屼富閿潎涓哄崟鍊硷級,蹇呴』濉啓鏁版嵁婧愶紝澶氳鎷兼帴鏃朵笉鍙敤
+    if (formdata && verify.uniques && verify.uniques.length > 0 && btn.Ot !== 'requiredOnce') {
+      verify.uniques.forEach(item => {
+        let _fieldValue = []                     // 琛ㄥ崟閿�煎field=value
+        let _value = []                          // 琛ㄥ崟鍊硷紝鐢ㄤ簬閿欒鎻愮ず
+        let _labels = item.fieldlabel.split(',') // 琛ㄥ崟鎻愮ず鏂囧瓧
+        let arr = [] // 楠岃瘉涓婚敭
+
+        item.field.split(',').forEach((_field, index) => {
+          let _key = _field.toLowerCase()
+          let _val = ''
+          let _val2 = ''
+  
+          arr.push(_key)
+          if (_key === 'bid') { // 琛ㄥ崟涓病鏈塨id鍒欎娇鐢ㄧ郴缁焍id鍙橀噺
+            _val = BID
+          } else {
+            _val = `'@mk_${_key}_mk@'`
+          }
+
+          _fieldValue.push(`${_key}=${_val}`)
+
+          if (_key === 'bid') { // 琛ㄥ崟涓病鏈塨id鍒欎娇鐢ㄧ郴缁焍id鍙橀噺
+            _val2 = `' + ${BID} + '`
+          } else {
+            _val2 = `@mk_${_key}_mk@`
+          }
+
+          _value.push(`${_labels[index] || ''}锛�${_val2}`)
+        })
+  
+        if (!arr.includes(primaryKey.toLowerCase())) {
+          _fieldValue.push(`${primaryKey} !=${primaryId}`)
+        }
+  
+        _sql += `
+        /* 鍞竴鎬ч獙璇� */
+        select @tbid='', @ErrorCode='',@retmsg=''
+        select @tbid='X' from ${btn.sql} where ${_fieldValue.join(' and ')}${item.verifyType === 'logic' ? ' and deleted=0' : ''}
+        If @tbid!=''
+        Begin
+          select @ErrorCode='${item.errorCode}',@retmsg='${_value.join(', ')} 宸插瓨鍦�'
+          goto aaa
+        end
+        `
+      })
+    } else if (verify.uniques && verify.uniques.length > 0 && btn.Ot === 'requiredOnce' && setting.dataresource) {
+      let datasource = setting.dataresource
+      if (/\s/.test(datasource)) { // 鎷兼帴鍒悕
+        if (!/tb$/.test(datasource)) {
+          datasource = '(' + datasource + ') tb'
+        }
+      } else {
+        datasource = datasource + ' tb'
+      }
+  
+      if (setting.customScript) {
+        _sql += `
+        /* 鏁版嵁婧愯嚜瀹氫箟鑴氭湰锛岃娉ㄦ剰鍙橀噺瀹氫箟鏄惁閲嶅 */
+        ${setting.customScript}
+        `
+      }
+  
+      verify.uniques.forEach(item => {
+        _sql += `
+        /* 鍚岀被鏁版嵁楠岃瘉 */
+        Set @tbid=''
+
+        Select top 1 @tbid='X' from (select distinct ${item.field},1 as n from ${datasource} inner join (select ID from  dbo.SplitComma(@ID@)) sp on tb.${primaryKey}=sp.ID ) a having sum(n)>1
+
+        If @tbid!=''
+        Begin
+          Set @ErrorCode='E' Set @retmsg='${item.fieldlabel} 鍊间笉鍞竴'
+          goto aaa
+        end
+        `
+      })
+    }
+  
+    let hasvoucher = false
+  
+    // 鍑瘉-鏄剧ず鍒椾腑閫夊彇,蹇呴』閫夎
+    if (verify.voucher && verify.voucher.enabled && btn.Ot !== 'requiredOnce') {
+      let _voucher = verify.voucher
+  
+      hasvoucher = true
+  
+      _sql += `
+        /* 鍒涘缓鍑瘉 */
+        exec s_BVoucher_Create
+          @Bill ='0',
+          @BVoucherType ='${_voucher.BVoucherType}',
+          @VoucherTypeOne ='${_voucher.VoucherTypeOne}',
+          @VoucherTypeTwo ='${_voucher.VoucherTypeTwo}',
+          @Type =${_voucher.Type},
+          @UserID=@UserID@,
+          @Username=@Username,
+          @FullName=@FullName,
+          @BVoucher =@BVoucher OUTPUT ,
+          @FIBVoucherDate =@FIBVoucherDate OUTPUT ,
+          @FiYear =@FiYear OUTPUT ,
+          @ErrorCode =@ErrorCode OUTPUT, 
+          @retmsg=@retmsg OUTPUT
+        if @ErrorCode!=''
+          GOTO aaa
+        `
+    }
+  
+    let _insertsql = ''
+    if (_actionType === 'insert' || _actionType === 'insertOrUpdate') { // 娣诲姞璇彞
+      let keys = []
+      let values = []
+  
+      formdata.forEach(item => {
+        if (item.writein === false) return
+        let _key = item.key.toLowerCase()
+  
+        keys.push(_key)
+        values.push('@' + _key)
+      })
+  
+      if (!keys.includes(primaryKey.toLowerCase())) {
+        keys.push(primaryKey.toLowerCase())
+        values.push(primaryId)
+      }
+      if (!keys.includes('createuserid')) {
+        keys.push('createuserid')
+        values.push('@userid@')
+      }
+      if (!keys.includes('createuser')) {
+        keys.push('createuser')
+        values.push('@username')
+      }
+      if (!keys.includes('createstaff')) {
+        keys.push('createstaff')
+        values.push('@fullname')
+      }
+      if (!keys.includes('bid')) {
+        keys.push('bid')
+        values.push('@BID@')
+      }
+  
+      if (!keys.includes('typename')) {
+        keys.push('typename')
+        values.push('@typename@')
+      }
+  
+      keys = keys.join(',')
+      values = values.join(',')
+      _insertsql = `insert into ${btn.sql} (${keys}) select ${values};`
+    }
+  
+    let _updatesql = ''
+    if (_actionType === 'update' || _actionType === 'audit' || _actionType === 'insertOrUpdate') { // 淇敼璇彞
+      let _form = []
+      let _arr = []
+  
+      formdata.forEach(item => {
+        if (item.writein === false) return
+        let _key = item.key.toLowerCase()
+        
+        _arr.push(_key)
+        _form.push(_key + '=@' + _key)
+      })
+  
+      if (_actionType === 'audit') {
+        if (!_arr.includes('submitdate')) {
+          _form.push('submitdate=getdate()')
+        }
+        if (!_arr.includes('submituser')) {
+          _form.push('submituser=@username')
+        }
+        if (!_arr.includes('submitstaff')) {
+          _form.push('submitstaff=@fullname')
+        }
+        if (!_arr.includes('submituserid')) {
+          _form.push('submituserid=@userid@')
+        }
+      } else {
+        if (!_arr.includes('modifydate')) {
+          _form.push('modifydate=getdate()')
+        }
+        if (!_arr.includes('modifyuser')) {
+          _form.push('modifyuser=@username')
+        }
+        if (!_arr.includes('modifystaff')) {
+          _form.push('modifystaff=@fullname')
+        }
+        if (!_arr.includes('modifyuserid')) {
+          _form.push('modifyuserid=@userid@')
+        }
+      }
+      
+      if (hasvoucher) {
+        if (!_arr.includes('bvoucher')) {
+          _form.push('BVoucher=@BVoucher')
+        }
+        if (!_arr.includes('fibvoucherdate')) {
+          _form.push('FIBVoucherDate=@FIBVoucherDate')
+        }
+        if (!_arr.includes('fiyear')) {
+          _form.push('FiYear=@FiYear')
+        }
+      }
+      if (!_arr.includes('typename')) {
+        _form.push('typename=@typename@')
+      }
+      _form = _form.join(',')
+  
+      let _ID = '=@ID@'
+      if (btn.Ot === 'requiredOnce') {
+        _ID = ' in (select ID from  dbo.SplitComma(@ID@))'
+      }
+  
+      _updatesql = `update ${btn.sql} set ${_form} where ${primaryKey}${_ID};`
+    }
+  
+    if (_prevCustomScript) {
+      _sql += _prevCustomScript
+    }
+  
+    // 娣诲姞銆佷慨鏀广�侀�昏緫鍒犻櫎銆佺墿鐞嗗垹闄�
+    if (_actionType === 'insert') {
+      _sql += `
+        /* 榛樿sql */
+        ${_insertsql}`
+    } else if (_actionType === 'update' || _actionType === 'audit') {
+      _sql += `
+        /* 榛樿sql */
+        ${_updatesql}`
+    } else if (_actionType === 'LogicDelete') { // 閫昏緫鍒犻櫎
+      let _ID = '=@ID@'
+      if (btn.Ot === 'requiredOnce') {
+        _ID = ' in (select ID from  dbo.SplitComma(@ID@))'
+      }
+  
+      _sql += `
+        /* 榛樿sql */
+        update ${btn.sql} set deleted=@mk_deleted,modifydate=getdate(),modifyuser=@username,modifystaff=@fullname,modifyuserid=@userid@ where ${primaryKey}${_ID};`
+    
+    } else if (_actionType === 'delete') {      // 鐗╃悊鍒犻櫎
+      let _msg = ''
+      if (columns && columns.length > 0 && btn.Ot !== 'notRequired') {
+        let _index = 0
+        columns.forEach(col => {
+          if (_index >= 4 || col.field === primaryKey) return
+
+          colreps.push(col.field)
+
+          _msg += col.label + `=@mk_${col.field}_mk@,`
+          _index++
+        })
+      }
+  
+      let _ID = '=@ID@'
+      if (btn.Ot === 'requiredOnce') {
+        _ID = ' in (select ID from  dbo.SplitComma(@ID@))'
+      }
+  
+      _sql += `
+        /* 榛樿sql */
+        insert into snote (remark,createuserid,CreateUser,CreateStaff,typename) select left('鍒犻櫎琛�:${btn.sql} 鏁版嵁: ${_msg}${primaryKey}='+@ID@,200),@userid@,@username,@fullname,@typename@
+        delete ${btn.sql} where ${primaryKey}${_ID};`
+    } else if (_actionType === 'insertOrUpdate') {
+      _sql += `
+        /* 榛樿sql */
+        select @tbid=''
+        select @tbid='X' from ${btn.sql} where ${primaryKey}=@ID@
+        if @tbid=''
+          begin
+          ${_billcodesSql}
+          ${_insertsql}
+          end
+        else
+          begin
+          ${_updatesql}
+          end
+      `
+    }
+  
+    if (verify.workFlow === 'true' && verify.flowSql === 'true' && process) {
+      if (verify.flowType === 'start') {
+        _sql += `
+          /* 宸ヤ綔娴佸紓甯竤ql */
+          if @works_flow_error@ != ''
+          select @ErrorCode='E',@retmsg=@works_flow_error@ goto aaa
+
+          /* 宸ヤ綔娴侀粯璁ql */
+          insert into s_my_works_flow (works_flow_id,works_flow_code,works_flow_name,works_flow_param,status,statusname,work_group,works_flow_detail_id,work_grade,bid,createuserid,CreateUser,CreateStaff,upid)
+          select @ID@,@works_flow_code@,@works_flow_name@,@works_flow_param@,@status@,@statusname@,@work_group@,@works_flow_detail_id@,@work_grade@,@bid@,@UserID@,@UserName,@FullName,@time_id@
+          insert into s_my_works_flow_log (works_flow_id,works_flow_code,works_flow_name,works_flow_param,status,statusname,works_flow_detail_id,work_group,work_grade,bid,createuserid,CreateUser,CreateStaff,upid)
+          select @ID@,@works_flow_code@,@works_flow_name@ ,@works_flow_param@,@status@,@statusname@,@works_flow_detail_id@,@work_group@,@work_grade@,@bid@,@UserID@,@UserName,@FullName,@time_id@
+          insert into s_my_works_flow_notice (works_flow_id,works_flow_code,works_flow_detail_id,userid,notice_type,createuserid,CreateUser,CreateStaff,upid)
+          select @ID@,@works_flow_code@,@works_flow_detail_id@,@userid@,@start_type@,@userid@,@UserName,@FullName,@time_id@
+          insert into s_my_works_flow_role (works_flow_id,works_flow_code,userid,works_flow_detail_id,createuserid,CreateUser,CreateStaff,upid,typecharone)
+          select @ID@,@works_flow_code@,@userid@,@works_flow_detail_id@,@userid@,@UserName,@FullName,@time_id@,'begin'
+        `
+      } else {
+        let field = '@works_flow_sign_field@'
+        let label = '@works_flow_sign_label@'
+
+        _sql += `
+          /* 宸ヤ綔娴佸紓甯竤ql */
+          if @works_flow_error@ != ''
+          select @ErrorCode='E',@retmsg=@works_flow_error@ goto aaa
+
+          if @works_flow_countersign@ = 'Y'
+          begin
+              /* 宸ヤ綔娴侀粯璁ql锛堜細绛撅級 */
+              declare @works_flow_statuscharone nvarchar(50),@works_flow_statuschartwo nvarchar(50),@works_flow_statuscharthree nvarchar(50),@works_flow_statuscharfour nvarchar(50),@works_flow_statuscharfive nvarchar(50),@works_flow_key_id nvarchar(50),@works_flow_key_status nvarchar(20),@s_my_works_flow_log_param  nvarchar(max),@s_my_works_flow_log_status int,@s_my_works_flow_log_statusname nvarchar(50),@s_my_works_flow_log_detail_id  nvarchar(50)
+              select @works_flow_statuscharone='',@works_flow_statuschartwo='',@works_flow_statuscharthree='',@works_flow_statuscharfour='',@works_flow_statuscharfive='',@works_flow_key_id='',@works_flow_key_status ='',@s_my_works_flow_log_param='',@s_my_works_flow_log_status=0,@s_my_works_flow_log_statusname='',@s_my_works_flow_log_detail_id=''
+
+              select @works_flow_statuscharone=statuscharone,@works_flow_statuschartwo=statuschartwo,@works_flow_statuscharthree=statuscharthree,@works_flow_statuscharfour=statuscharfour,@works_flow_statuscharfive=statuscharfive,@works_flow_key_id=id,@s_my_works_flow_log_param=works_flow_param,@s_my_works_flow_log_status=status,@s_my_works_flow_log_statusname=statusname,@s_my_works_flow_log_detail_id=works_flow_detail_id
+              from s_my_works_flow where works_flow_id=@ID@ and works_flow_code=@works_flow_code@ and deleted=0
+
+              if @works_flow_statuscharone + @works_flow_statuschartwo + @works_flow_statuscharthree + @works_flow_statuscharfour + @works_flow_statuscharfive = @works_flow_sign_values@
+              begin
+                  set @works_flow_key_status='Y'
+              end
+
+              if @works_flow_key_status='Y'
+              begin
+                  update s_my_works_flow set ${field}=${label},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 : ''}
+                  where id=@works_flow_key_id
+
+                  insert into s_my_works_flow_log (works_flow_id,works_flow_code,works_flow_name,works_flow_param,status,statusname,works_flow_detail_id,work_group,work_grade,bid,createuserid,CreateUser,CreateStaff,upid${verify.flowRemark ? ',remark' : ''},${field})
+                  select @ID@,@works_flow_code@,@works_flow_name@ ,@works_flow_param@,@status@,@statusname@,@works_flow_detail_id@,@work_group@,@work_grade@,@bid@,@UserID@,@UserName,@FullName,@time_id@${verify.flowRemark ? ',@' + verify.flowRemark : ''},${label}
+                  
+                  update s_my_works_flow_role set deleted=10,modifydate=getdate(),upid=@time_id@,modifyuserid=@userid@,modifyuser=@username,modifystaff=@fullname 
+                  where works_flow_id=@ID@ and works_flow_code=@works_flow_code@ and deleted=0
+
+                  if @check_userids@ != ''
+                  begin
+                      insert into s_my_works_flow_role (works_flow_id,works_flow_code,userid,works_flow_detail_id,createuserid,CreateUser,CreateStaff,upid)
+                      select @ID@,@works_flow_code@,ID,@works_flow_detail_id@,@userid@,@UserName,@FullName,@time_id@ from dbo.SplitComma(@check_userids@)
+                      insert into s_my_works_flow_notice (works_flow_id,works_flow_code,works_flow_detail_id,userid,notice_type,createuserid,CreateUser,CreateStaff,upid)
+                      select @ID@,@works_flow_code@,@works_flow_detail_id@,ID,@check_type@,@userid@,@UserName,@FullName,@time_id@ from dbo.SplitComma(@check_userids@)
+                  end
+                  if @notice_userids@ != ''
+                  begin
+                      update n
+                      set deleted=10,modifydate=getdate(),upid=@time_id@,modifyuserid=@userid@,modifyuser=@username,modifystaff=@fullname 
+                      from (select * from s_my_works_flow_notice where works_flow_id=@ID@ and works_flow_code=@works_flow_code@ and deleted=0) n
+                      inner join (select ID from dbo.SplitComma(@notice_userids@)) s
+                      on n.userid = s.id
+                      insert into s_my_works_flow_notice (works_flow_id,works_flow_code,works_flow_detail_id,userid,notice_type,createuserid,CreateUser,CreateStaff,upid)
+                      select @ID@,@works_flow_code@,@works_flow_detail_id@,ID,@notice_type@,@userid@,@UserName,@FullName,@time_id@ from dbo.SplitComma(@notice_userids@)
+                  end
+              end
+              else
+              begin
+                  update s_my_works_flow set ${field}=${label},modifydate=getdate(),upid=@time_id@,modifyuserid=@userid@,modifyuser=@username,modifystaff=@fullname${verify.flowRemark ? ',remark=@' + verify.flowRemark : ''}
+                  where id =@works_flow_key_id
+
+                  insert into s_my_works_flow_log (works_flow_id,works_flow_code,works_flow_name,works_flow_param,status,statusname,works_flow_detail_id,work_group,work_grade,bid,createuserid,CreateUser,CreateStaff,upid${verify.flowRemark ? ',remark' : ''},${field})
+                  select @ID@,@works_flow_code@,@works_flow_name@ ,@s_my_works_flow_log_param,@s_my_works_flow_log_status,@s_my_works_flow_log_statusname,@s_my_works_flow_log_detail_id,@work_group@,@work_grade@,@bid@,@UserID@,@UserName,@FullName,@time_id@${verify.flowRemark ? ',@' + verify.flowRemark : ''},${label}
+                
+                  update s_my_works_flow_role set deleted=10,modifydate=getdate(),upid=@time_id@,modifyuserid=@userid@,modifyuser=@username,modifystaff=@fullname 
+                  where works_flow_id=@ID@ and works_flow_code=@works_flow_code@ and deleted=0 and userid =@userid@
+              end
+          end
+          else
+          begin
+              /* 宸ヤ綔娴侀粯璁ql锛堟垨绛撅級 */
+              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 and userid =@userid@
+
+              if @retmsg =''
+              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 !=''
+                  begin
+                      select @ErrorCode='E', @retmsg='褰撳墠鍗曟嵁宸插鏍革紝璇峰埛鏂板悗閲嶈瘯'
+                      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 
+
+              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 : ''}
+              where works_flow_id=@ID@ and works_flow_code=@works_flow_code@ and deleted=0
+              insert into s_my_works_flow_log (works_flow_id,works_flow_code,works_flow_name,works_flow_param,status,statusname,works_flow_detail_id,work_group,work_grade,bid,createuserid,CreateUser,CreateStaff,upid${verify.flowRemark ? ',remark' : ''})
+              select @ID@,@works_flow_code@,@works_flow_name@ ,@works_flow_param@,@status@,@statusname@,@works_flow_detail_id@,@work_group@,@work_grade@,@bid@,@UserID@,@UserName,@FullName,@time_id@${verify.flowRemark ? ',@' + verify.flowRemark : ''}
+
+              if @works_begin_branch@ = 'Y'
+              begin
+                  update s_my_works_flow_role set deleted=0,modifydate=getdate(),upid=@time_id@,modifyuserid=@userid@,modifyuser=@username,modifystaff=@fullname
+                  where works_flow_id=@ID@ and works_flow_code=@works_flow_code@ and typecharone='begin'
+              end
+              else
+              begin
+                  update s_my_works_flow_role set deleted=10,modifydate=getdate(),upid=@time_id@,modifyuserid=@userid@,modifyuser=@username,modifystaff=@fullname 
+                  where works_flow_id=@ID@ and works_flow_code=@works_flow_code@ and deleted=0
+              end
+
+              if @check_userids@ != ''
+              begin
+                  insert into s_my_works_flow_role (works_flow_id,works_flow_code,userid,works_flow_detail_id,createuserid,CreateUser,CreateStaff,upid)
+                  select @ID@,@works_flow_code@,ID,@works_flow_detail_id@,@userid@,@UserName,@FullName,@time_id@ from dbo.SplitComma(@check_userids@)
+                  insert into s_my_works_flow_notice (works_flow_id,works_flow_code,works_flow_detail_id,userid,notice_type,createuserid,CreateUser,CreateStaff,upid)
+                  select @ID@,@works_flow_code@,@works_flow_detail_id@,ID,@check_type@,@userid@,@UserName,@FullName,@time_id@ from dbo.SplitComma(@check_userids@)
+              end
+              if @notice_userids@ != ''
+              begin
+                  update n
+                  set deleted=10,modifydate=getdate(),upid=@time_id@,modifyuserid=@userid@,modifyuser=@username,modifystaff=@fullname 
+                  from (select * from s_my_works_flow_notice where works_flow_id=@ID@ and works_flow_code=@works_flow_code@ and deleted=0) n
+                  inner join (select ID from dbo.SplitComma(@notice_userids@)) s
+                  on n.userid = s.id
+                  insert into s_my_works_flow_notice (works_flow_id,works_flow_code,works_flow_detail_id,userid,notice_type,createuserid,CreateUser,CreateStaff,upid)
+                  select @ID@,@works_flow_code@,@works_flow_detail_id@,ID,@notice_type@,@userid@,@UserName,@FullName,@time_id@ from dbo.SplitComma(@notice_userids@)
+              end
+          end
+        `
+      }
+
+      if (_backCustomScript) {
+        _sql += _backCustomScript
+      }
+    } else if (_backCustomScript) {
+      _sql += _backCustomScript
+    }
+
+    if (verify.workFlow === 'true' && process) {
+      if (verify.flowType === 'start') {
+        _sql = _sql.replace(/@start_type@/ig, `'寮�濮�'`)
+        // works_flow_error       娴佺▼閿欒
+        let worksReFields = ['works_flow_error', 'works_flow_code', 'works_flow_name', 'works_flow_param', 'works_flow_detail_id', 'status', 'statusname', 'work_group', 'work_grade']
+        worksReFields.forEach(n => {
+          _sql = _sql.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+        })
+      } else {
+        _sql = _sql.replace(/@check_type@/ig, verify.flowType === 'reject' ? `'椹冲洖'` : `'瀹℃牳'`)
+        _sql = _sql.replace(/@notice_type@/ig, `'鎶勯��'`)
+        // works_flow_error       娴佺▼閿欒
+        // works_flow_countersign 浼氱/鎴栫鏍囪 浼氱涓� Y
+        // works_begin_branch     椹冲洖鑷冲紑濮嬪垎鏀紙line.mknode === 'startEdge'锛�
+        // works_flow_sign_field  浼氱 鏍囪瀛楁 statuscharone/statuschartwo/statuscharthree/statuscharfour/statuscharfive
+        // works_flow_sign_label  浼氱 鏍囪鍊�   ***/***/宸插鏍�
+        // works_flow_sign_values 浼氱鏍囪鎷兼帴鍊硷紙闄ゆ湰浜哄锛�
+        let worksReFields = ['works_flow_error', 'works_flow_countersign', 'works_flow_sign_values', 'works_begin_branch', 'works_flow_sign_label', 'works_flow_code', 'works_flow_name', 'works_flow_param', 'works_flow_detail_id', 'status', 'statusname', 'work_group', 'work_grade', 'check_userids', 'notice_userids', 'works_flow_sign']
+        worksReFields.forEach(n => {
+          _sql = _sql.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+        })
+      }
+    }
+  
+    // if (btn.procMode === 'system' || btn.returnValue === 'true') {
+    //   _sql += `
+    //     aaa: if @ErrorCode!=''
+    //     insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@`
+    // } else if (btn.output) {
+    //   _sql += `
+    //     aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg,${btn.output} as mk_b_id`
+    // } else {
+    //   _sql += `
+    //     aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
+    // }
+
+    if (/@ErrorCode='(ENT|NNT|FNT|NMNT|CNT|-2NT)'/ig.test(_sql)) {
+      _sql = _sql.replace(/@ErrorCode='(ENT|NNT|FNT|NMNT|CNT|-2NT)'[\S\s]+\sgoto\s+aaa($|\s)/ig, (word) => {
+        return word.replace(/goto aaa/, 'goto mk_ent')
+      })
+      _sql += `
+          if 1=2
+          begin
+            mk_ent:
+            set @ErrorCode=left(@ErrorCode,1)
+          end
+        `
+    }
+
+    if (btn.procMode === 'system' || btn.returnValue === 'true') {
+      _sql += callback
+    } else if (btn.output) {
+      _sql += `
+        select @ErrorCode as ErrorCode,@retmsg as retmsg,${btn.output} as mk_b_id
+        ${callback}
+        `
+    } else {
+      _sql += `
+        select @ErrorCode as ErrorCode,@retmsg as retmsg
+        ${callback}
+        `
+    }
+
+    let syses = ['UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address']
+
+    // 娣诲姞鏁版嵁涓瓧娈碉紝琛ㄥ崟鍊间紭鍏�(鎸夐挳涓嶉�夎鎴栧琛屾嫾鎺ユ椂璺宠繃)
+    if (btn.Ot !== 'notRequired' && columns.length > 0) {
+      let _initColfields = []
+      columns.forEach(col => {
+        let _key = col.field.toLowerCase()
+
+        if (formkeys.includes(_key) || !new RegExp('@' + _key + '[^0-9a-z_@]', 'ig').test(_sql)) return
+        // if (_key === 'id' && !/@id[^0-9a-z_@]/ig.test(_sql)) return
+
+        colreps.push(col.field)
+  
+        if (col.type === 'number') {
+          _initColfields.push(`@${_key}=@mk_${_key}_mk@`)
+        } else {
+          _initColfields.push(`@${_key}='@mk_${_key}_mk@'`)
+        }
+        
+        if (!_vars.includes(_key)) {
+          _declares.push(`@${_key} ${col.datatype || 'nvarchar(50)'}`)
+        }
+      })
+
+      // 鏄剧ず鍒楀彉閲忚祴鍊�
+      if (_initColfields.length > 0) {
+        _sql = _sql.replace('@mk_cols_values@', `
+          /* 鏄剧ず鍒楀彉閲忚祴鍊� */
+          select ${_initColfields.join(',')}
+        `)
+      } else {
+        _sql = _sql.replace('@mk_cols_values@', '')
+      }
+    }
+
+    let reps = []
+    let decSql = [`@tbid nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@BillCode nvarchar(50),@BVoucher nvarchar(50),@FIBVoucherDate nvarchar(50), @FiYear nvarchar(50),@ModularDetailCode nvarchar(50),@mk_deleted int,@bid nvarchar(50)`]
+    let secSql = [`@ErrorCode='S',@retmsg='', @BillCode='',@BVoucher='',@FIBVoucherDate='',@FiYear='',@ModularDetailCode='', @mk_deleted=1, @bid=@BID@`]
+
+    syses.forEach(s => {
+      if (new RegExp('@' + s + '[^0-9a-z_]', 'ig').test(_sql)) {
+        if (['RoleID', 'mk_departmentcode', 'mk_organization'].includes(s)) {
+          decSql.push(`@${s} nvarchar(512)`)
+        } else if (['mk_address'].includes(s)) {
+          decSql.push(`@mk_address nvarchar(100)`)
+        } else {
+          decSql.push(`@${s} nvarchar(50)`)
+        }
+        secSql.push(`@${s}=@${s}@`)
+        reps.push(s)
+      }
+    })
+
+    decSql = [...decSql, ..._declares]
+
+    // INSERT INTO s_paas_api_log (appkey,api_name,api_count,menuname,createuserid,createuser,createstaff,cdefine1,cdefine2) 
+    // SELECT @appkey@,'sPC_TableData_InUpDe',1,@menuname@,@UserID@,@username@,@fullname@,@SessionUid@,@LoginUID@
+    _sql = `/* ${btn.logLabel} */
+        BEGIN TRY 
+        begin TRAN
+
+        Declare ${decSql.join(',')}
+        /* 鍑瘉鍙婄敤鎴蜂俊鎭垵濮嬪寲璧嬪�� */
+        select ${secSql.join(',')}
+        ${_sql}
+    `
+
+    let regs = ['ID', 'BID', 'time_id', 'datam', 'typename']
+
+    regs.forEach(s => {
+      if (new RegExp('@' + s + '@', 'ig').test(_sql)) {
+        reps.push(s)
+      }
+    })
+
+    let map = new Map()
+    reps.push(...sysVars)
+    reps = reps.filter(n => {
+      if (map.has(n.toLowerCase())) {
+        return false
+      }
+
+      map.set(n.toLowerCase(), true)
+
+      return true
+    })
+
+    reps.forEach(n => {
+      _sql = _sql.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+    })
+
+    if (/\$@/ig.test(_sql)) {
+      _sql = _sql.replace(/\$@/ig, '@datam_begin@').replace(/@\$/ig, '@datam_end@')
+      reps.push('datam_begin', 'datam_end')
+    }
+    if (btn.procMode === 'system') {
+      if (/\$check@|@check\$/ig.test(_sql)) {
+        _sql = _sql.replace(/\$check@|@check\$/ig, '')
+      }
+    } else {
+      if (/\$check@|@check\$/ig.test(_sql)) {
+        _sql = _sql.replace(/\$check@/ig, '@mk_check_begin@').replace(/@check\$/ig, '@mk_check_end@')
+        reps.push('mk_check_begin', 'mk_check_end')
+      }
+    }
+    if (/@db@/ig.test(_sql)) {
+      reps.push('db')
+    }
+
+    _sql = _sql.replace(/\n\x20{8,10}/g, '\n').replace(/\n{3,}/g, '\n\n').replace(/^\s+|\s+$/g, '').replace(/\t+|\v+/g, '')
+
+    reps = reps.filter(n => {
+      if (sysVars.includes(n.toLowerCase())) {
+        return false
+      }
+
+      return true
+    })
+
+    colreps = Array.from(new Set(colreps))
+    reps = [...reps, ...colreps]
+    
+    return { LText: _sql, md5: md5(_sql), reps }
+  }
+
+  let getSysBackSql = (btn, component) => {
+    let verify = btn.verify || {}
+    let columns = component.columns || []
+    let colreps = [] // 寰呮浛鎹㈠彉閲忛泦
+    let _prev = ''
+    let _back = ''
+    let tables = []
+    let reps = []
+
+    verify.cbScripts.forEach(script => {
+      if (script.status === 'false') return
+
+      if (/\s#[a-z0-9_]+(\s|\()/ig.test(script.sql)) {
+        tables.push(...script.sql.match(/\s#[a-z0-9_]+(\s|\()/ig))
+      }
+
+      if (script.position === 'front') {
+        _prev += `
+          /* 鑷畾涔夎剼鏈� */
+          ${script.sql}
+        `
+      } else {
+        _back += `
+          /* 鑷畾涔夎剼鏈� */
+          ${script.sql}
+        `
+      }
+    })
+
+    tables = tables.map(tb => tb.replace(/\s|\(/g, ''))
+  
+    // 闇�瑕佸0鏄庣殑鍙橀噺闆�
+    let _vars = ['tbid', 'errorcode', 'retmsg', 'billcode', 'bvoucher', 'fibvoucherdate', 'fiyear', 'username', 'fullname', 'modulardetailcode', 'roleid', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'mk_deleted', 'bid']
+  
+    let _sql = ''
+  
+    let _initFormfields = []
+    let _declares = []
+
+    let formdata = null
+    let formkeys = []
+    if (btn.OpenType === 'pop' || btn.OpenType === 'formSubmit') {
+      formdata = []
+      if (btn.modal && btn.modal.fields) {
+        btn.modal.fields.forEach(item => {
+          if (!item.field) return
+          
+          let _item = {
+            key: item.field,
+            fieldlen: item.fieldlength || 50,
+            writein: item.writein !== 'false',
+            type: item.type,
+            isconst: item.constant === 'true'
+          }
+    
+          if (_item.type === 'datemonth') {
+            _item.type = 'text'
+          } else if (_item.type === 'number' || _item.type === 'rate') {
+            _item.fieldlen = item.decimal || 0
+          } else if (_item.type === 'date') {
+            _item.type = item.declareType === 'nvarchar(50)' ? 'text' : 'date'
+          } else if (_item.type === 'datetime') {
+            _item.type = 'date'
+          } else if (item.declare === 'decimal') {
+            _item.type = 'number'
+            _item.fieldlen = item.decimal || 0
+          }
+    
+          formdata.push(_item)
+        })
+      }
+    } else if (btn.OpenType === 'form') {
+      formdata = []
+
+      let item = {
+        type: 'text',
+        readin: true,
+        writein: true,
+        fieldlen: 50,
+        key: btn.field
+      }
+      if (btn.formType === 'counter') {
+        item.type = 'number'
+        item.fieldlen = 0
+      } else if (btn.formType === 'switch' || btn.formType === 'radio') {
+        if (typeof(btn.openVal) === 'number') {
+          item.type = 'number'
+          item.fieldlen = 0
+        }
+      }
+      formdata.push(item)
+    }
+
+    // 鑾峰彇瀛楁閿�煎
+    formdata && formdata.forEach(form => {
+      let _key = form.key.toLowerCase()
+
+      if (!formkeys.includes(_key)) {
+        formkeys.push(_key)
+        if (form.type === 'number' || form.type === 'rate') {
+          _initFormfields.push(`@${_key}=@mk_${_key}_mk@`)
+        } else if (form.type === 'date') {
+          _initFormfields.push(`@${_key}='@mk_${_key}_mk@'`)
+        } else if (form.type === 'select' || form.type === 'link' || form.type === 'radio') {
+          _initFormfields.push(`@${_key}='@mk_${_key}_mk@'`)
+        } else if (form.isconst) {
+          _initFormfields.push(`@${_key}=N'@mk_${_key}_mk@'`)
+        } else {
+          _initFormfields.push(`@${_key}='@mk_${_key}_mk@'`)
+        }
+      }
+      
+      if (!_vars.includes(_key)) {
+        _vars.push(_key)
+  
+        if (form.fieldlen && form.fieldlen > 4000) {
+          form.fieldlen = 'max'
+        }
+  
+        let _type = `nvarchar(${form.fieldlen})`
+  
+        if (form.type.match(/date/ig)) {
+          _type = 'datetime'
+        } else if (form.type === 'number') {
+          _type = `decimal(18,${form.fieldlen})`
+        } else if (form.type === 'rate') {
+          _type = `decimal(18,2)`
+        }
+  
+        _declares.push(`@${_key} ${_type}`)
+      }
+    })
+  
+    // 琛ㄥ崟鍙橀噺璧嬪��
+    if (_initFormfields.length > 0) {
+      _sql += `
+        /* 琛ㄥ崟鍙橀噺璧嬪�� */
+        select ${_initFormfields.join(',')}
+        `
+    }
+
+    let testSql = _prev + _back + (btn.output || '')
+
+    // 娣诲姞鏁版嵁涓瓧娈碉紝琛ㄥ崟鍊间紭鍏�(鎸夐挳涓嶉�夎鎴栧琛屾嫾鎺ユ椂璺宠繃)
+    if (btn.Ot !== 'notRequired' && columns.length > 0) {
+      let _initColfields = []
+      columns.forEach(col => {
+        let _key = col.field.toLowerCase()
+
+        if (formkeys.includes(_key) || !new RegExp('@' + _key + '[^0-9a-z_@]', 'ig').test(testSql)) return
+        // if (_key === 'id' && !/@id[^0-9a-z_@]/ig.test(testSql)) return
+
+        colreps.push(col.field)
+  
+        if (col.type === 'number') {
+          _initColfields.push(`@${_key}=@mk_${_key}_mk@`)
+        } else {
+          _initColfields.push(`@${_key}='@mk_${_key}_mk@'`)
+        }
+        
+        if (!_vars.includes(_key)) {
+          _declares.push(`@${_key} ${col.datatype || 'nvarchar(50)'}`)
+        }
+      })
+
+      // 鏄剧ず鍒楀彉閲忚祴鍊�
+      if (_initColfields.length > 0) {
+        _sql += `
+          /* 鏄剧ず鍒楀彉閲忚祴鍊� */
+          select ${_initColfields.join(',')}
+        `
+      }
+    }
+
+    _sql += `
+        ${_prev}
+        /* 澶栭儴鎺ュ彛鍏ュ弬 */
+        @mk_outer_params@
+        ${_back}
+        `
+
+    // if (btn.output) {
+    //   _sql += `
+    //     aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg,${btn.output} as mk_b_id`
+    // } else {
+    //   _sql += `
+    //     aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
+    // }
+    if (/@ErrorCode='(ENT|NNT|FNT|NMNT|CNT|-2NT)'/ig.test(_sql)) {
+      _sql = _sql.replace(/@ErrorCode='(ENT|NNT|FNT|NMNT|CNT|-2NT)'[\S\s]+\sgoto\s+aaa($|\s)/ig, (word) => {
+        return word.replace(/goto aaa/, 'goto mk_ent')
+      })
+      _sql += `
+          if 1=2
+          begin
+            mk_ent:
+            set @ErrorCode=left(@ErrorCode,1)
+          end
+        `
+    }
+    if (btn.output) {
+      _sql += `
+        select @ErrorCode as ErrorCode,@retmsg as retmsg,${btn.output} as mk_b_id
+        ${callback}
+        `
+    } else {
+      _sql += `
+        select @ErrorCode as ErrorCode,@retmsg as retmsg
+        ${callback}
+        `
+    }
+
+    let syses = ['tbid', 'BillCode', 'BVoucher', 'FIBVoucherDate', 'FiYear', 'ModularDetailCode', 'mk_deleted', 'bid', 'UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address']
+    let decSql = [`@ErrorCode nvarchar(50),@retmsg nvarchar(4000)`]
+    let secSql = [`@ErrorCode='S',@retmsg=''`]
+  
+    syses.forEach(s => {
+      if (new RegExp('@' + s + '[^0-9a-z_]', 'ig').test(_sql)) {
+        if (['RoleID', 'mk_departmentcode', 'mk_organization'].includes(s)) {
+          decSql.push(`@${s} nvarchar(512)`)
+        } else if (['mk_address'].includes(s)) {
+          decSql.push(`@mk_address nvarchar(100)`)
+        } else if (['mk_deleted'].includes(s)) {
+          secSql.push(`@mk_deleted int`)
+        } else {
+          decSql.push(`@${s} nvarchar(50)`)
+        }
+        if (['tbid', 'BillCode', 'BVoucher', 'FIBVoucherDate', 'FiYear', 'ModularDetailCode'].includes(s)) {
+          secSql.push(`@${s}=''`)
+        } else if (['mk_deleted'].includes(s)) {
+          secSql.push(`@mk_deleted=1`)
+        } else if (['bid'].includes(s)) {
+          secSql.push(`@bid=@BID@`)
+        } else {
+          secSql.push(`@${s}=@${s}@`)
+          reps.push(s)
+        }
+      }
+    })
+
+    decSql = [...decSql, ..._declares]
+
+    _sql = `/* ${btn.logLabel}(鍥炶皟) */
+        BEGIN TRY 
+        begin TRAN
+
+        Declare ${decSql.join(',')}
+        /* 鍒濆鍖栬祴鍊� */
+        select ${secSql.join(',')}
+        ${_sql}
+    `
+
+    let regs = ['ID', 'BID', 'time_id', 'datam', 'typename']
+
+    regs.forEach(s => {
+      if (new RegExp('@' + s + '@', 'ig').test(_sql)) {
+        reps.push(s)
+      }
+    })
+
+    let map = new Map()
+    reps.push(...sysVars)
+    reps = reps.filter(n => {
+      if (map.has(n.toLowerCase())) {
+        return false
+      }
+
+      map.set(n.toLowerCase(), true)
+
+      return true
+    })
+
+    reps.forEach(n => {
+      _sql = _sql.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+    })
+
+    if (/\$@/ig.test(_sql)) {
+      _sql = _sql.replace(/\$@/ig, '@datam_begin@').replace(/@\$/ig, '@datam_end@')
+      reps.push('datam_begin', 'datam_end')
+    }
+    if (/@db@/ig.test(_sql)) {
+      reps.push('db')
+    }
+
+    _sql = _sql.replace(/\n\x20{8,10}/g, '\n').replace(/\n{3,}/g, '\n\n').replace(/^\s+|\s+$/g, '').replace(/\t+|\v+/g, '')
+
+    reps = reps.filter(n => {
+      if (sysVars.includes(n.toLowerCase())) {
+        return false
+      }
+
+      return true
+    })
+
+    reps = [...reps, ...colreps]
+
+    return { LText: _sql, md5: md5(_sql), reps, tbs: tables }
+  }
+
+  let getDataSource = (item, mainSearch = [], type) => {
+    let searches = item.search || []
+    if (item.setting.useMSearch === 'true' && mainSearch.length > 0) {
+      searches = [...searches, ...mainSearch]
+    }
+    item.$searches = fromJS(searches).toJS()
+    let sFields = getSearches(searches)
+
+    let _columns = []
+    if (item.subtype === 'dualdatacard') {
+      _columns = [...item.columns, ...item.subColumns]
+    } else if (item.columns) {
+      _columns = [...item.columns]
+    }
+
+    let arr_field = _columns.map(col => col.field).join(',')
+
+    let _customScript = ''
+    let _tailScript = ''
+    let _dataresource = ''
+    item.scripts && item.scripts.forEach(script => {
+      if (script.status === 'false') return
+      if (script.position !== 'back') {
+        _customScript += `
+        ${script.sql}
+        `
+      } else {
+        _tailScript += `
+        ${script.sql}
+        `
+      }
+    })
+
+    // if (_customScript || _tailScript) {
+    //   _tailScript += `${_tailScript}
+    //     aaa:
+    //     if @ErrorCode!=''
+    //       insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@
+    //   `
+    // }
+
+    let _search = ''
+    if (item.setting.execute !== 'false') {
+      _dataresource = item.setting.dataresource || ''
+      _search = '@mk_search@'
+    }
+
+    if (type === 'print') {
+      _search = ''
+    }
+
+    if (/\s/.test(_dataresource) && !/\)\s+tb$/.test(_dataresource)) {
+      _dataresource = '(' + _dataresource + ') tb'
+    }
+
+    item.setting.dataresource = _dataresource
+    item.setting.customScript = _customScript
+
+    let testSql = _dataresource + _customScript + _tailScript
+    
+    let decSql = [`@ErrorCode nvarchar(50),@retmsg nvarchar(4000)`]
+    let secSql = [`@ErrorCode='S',@retmsg =''`]
+
+    let reps = []
+
+    let syses = ['UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address']
+    syses.forEach(s => {
+      if (new RegExp('@' + s + '[^0-9a-z_]', 'ig').test(testSql)) {
+        if (['RoleID', 'mk_departmentcode', 'mk_organization'].includes(s)) {
+          decSql.push(`@${s} nvarchar(512)`)
+        } else if (['mk_address'].includes(s)) {
+          decSql.push(`@mk_address nvarchar(100)`)
+        } else {
+          decSql.push(`@${s} nvarchar(50)`)
+        }
+        secSql.push(`@${s}=@${s}@`)
+        reps.push(s)
+      }
+    })
+
+    decSql = `declare ${decSql.join(',')}${type === 'print' ? '@mk_print_declare@' : ''}
+      select ${secSql.join(',')}${type === 'print' ? '@mk_print_select@' : ''}`
+
+    // 涓嶉渶瑕佸崟寮曞彿锛歰rderBy銆乸ageSize銆乸ageIndex銆乨b
+    let regs = [...sFields, 'orderBy', 'pageSize', 'pageIndex', 'ID', 'BID', 'time_id', 'datam', 'typename']
+
+    if (item.hasExtend) {
+      regs.push('mk_time')
+    }
+    if (item.type === 'calendar') {
+      regs.push('mk_year')
+    }
+    if (window.GLOB.getLocation) {
+      regs.push('mk_longitude', 'mk_latitude')
+    }
+    if (urlFields) {
+      regs.push(...urlFields)
+    }
+    if (process) {
+      regs.push('works_flow_code')
+    }
+
+    regs.forEach(s => {
+      if (new RegExp('@' + s + '@', 'ig').test(testSql)) {
+        reps.push(s)
+      }
+    })
+
+    let LText = ''
+    let DateCount = ''
+    if (_dataresource) {
+      /*system_query*/
+      if (/@pageSize@|@orderBy@|@mk_total/i.test(testSql)) {
+        LText = `select ${arr_field} from ${_dataresource} ${_search} `
+      } else if (item.setting.laypage === 'true' && item.setting.order) {
+        LText = `select top @pageSize@ ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by @orderBy@) as rows from ${_dataresource} ${_search}) tmptable where rows > @pageSize@ * (@pageIndex@ - 1) order by tmptable.rows `
+        reps.push('pageSize', 'orderBy', 'pageIndex')
+        if (item.subtype === 'dualdatacard') {
+          DateCount = `select count(1) as total from (select distinct ${item.setting.primaryKey || 'ID'} from ${_dataresource} ${_search})a`
+        } else {
+          DateCount = `select count(1) as total from ${_dataresource} ${_search}`
+        }
+      } else if (item.setting.$top) {
+        if (item.setting.order) {
+          LText = `select top 1 ${arr_field} from ${_dataresource} ${_search} order by @orderBy@ `
+          reps.push('orderBy')
+        } else {
+          LText = `select top 1 ${arr_field} from ${_dataresource} ${_search}  `
+        }
+      } else if (item.setting.$fixOrder) {
+        LText = `select ${arr_field} from ${_dataresource} ${_search} order by ${item.setting.order} `
+      } else if (item.setting.order) {
+        LText = `select ${arr_field} from ${_dataresource} ${_search} order by @orderBy@ `
+        reps.push('orderBy')
+      } else {
+        LText = `select ${arr_field} from ${_dataresource} ${_search}  `
+      }
+    }
+
+    let sub_name = ''
+    let tabid = ''
+    let parid = ''
+    let sub_field = ''
+
+    if (item.subtype === 'dualdatacard') {
+      arr_field = item.columns.map(col => col.field).join(',')
+      sub_name = item.setting.subdata
+      tabid = item.setting.primaryKey || ''
+      parid = item.setting.subBID || ''
+      sub_field = item.subColumns.map(col => col.field).join(',')
+    }
+
+    // INSERT INTO s_paas_api_log (appkey,api_name,api_count,menuname,createuserid,createuser,createstaff,cdefine1,cdefine2) 
+    // SELECT @appkey@,'sPC_Get_TableData',1,@menuname@,@UserID@,@username@,@fullname@,@SessionUid@,@LoginUID@
+    let sql = ''
+    let e_sql = `select ${_columns.map(col => col.field).join(',')} from (select ${_columns.map(col => /date/ig.test(col.datatype) ? `'1949-10-01' as ${col.field}` : `'0' as ${col.field}`).join(',')}) a where ${item.setting.primaryKey || 'ID'} != '0'`
+    if (DateCount) {
+      e_sql += `
+      select 0 as total
+      `
+    }
+
+    if (item.setting.transact === 'true' && !/BEGIN\s+TRY\s+begin\s+TRAN/.test(_customScript)) {
+      sql = `/* ${item.setting.$name} */
+        BEGIN TRY 
+        begin TRAN
+
+        SELECT obj_name='@mk_obj_name@',prm_field='',str_field='',
+        arr_field='${arr_field}',tabid='${tabid}',parid='${parid}',sub_name='${sub_name}',sub_field='${sub_field}'
+      `
+
+      _tailScript = `${_tailScript}
+        select @ErrorCode as ErrorCode,@retmsg as retmsg
+
+        COMMIT TRAN
+        set NOCOUNT ON
+        RETURN
+        END TRY
+        BEGIN CATCH
+          ROLLBACK TRAN
+          DECLARE @ErrorMessage NVARCHAR(4000);
+          DECLARE @ErrorSeverity INT;
+          DECLARE @ErrorState INT;
+
+          set @ErrorCode=cast(ERROR_NUMBER() as nvarchar(50))
+          set @retmsg=ERROR_MESSAGE();
+          select @ErrorMessage=ERROR_MESSAGE(), @ErrorSeverity=ERROR_SEVERITY(), @ErrorState=ERROR_STATE();
+
+          RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
+        END CATCH
+
+        aaa:
+        ${e_sql}
+        select @ErrorCode as ErrorCode,@retmsg as retmsg
+        GOTO_RETURN:
+          ROLLBACK TRAN
+      `
+    } else {
+      sql = `/* ${item.setting.$name} */
+        SELECT obj_name='@mk_obj_name@',prm_field='',str_field='',
+        arr_field='${arr_field}',tabid='${tabid}',parid='${parid}',sub_name='${sub_name}',sub_field='${sub_field}'
+      `
+
+      let tail = 'aaa:'
+      if (/\sgoto\s+aaa([^0-9a-z_]|$)/ig.test(_customScript) && !/BEGIN\s+TRY\s+begin\s+TRAN/.test(_customScript)) {
+        tail = `if 1=2
+        begin
+          aaa:
+          ${e_sql}
+        end`
+      }
+
+      _tailScript = `${_tailScript}
+        ${tail}
+          select @ErrorCode as ErrorCode,@retmsg as retmsg
+      `
+    }
+
+    if (DateCount) {
+      sql += `UNION ALL
+        SELECT obj_name='DateCount',prm_field='total',str_field='',
+        arr_field='',tabid='',parid='',sub_name='',sub_field=''
+      `
+    }
+    // sql += `UNION ALL
+    //     SELECT obj_name='mk_error_code',prm_field='ErrorCode,retmsg',str_field='',
+    //     arr_field='',tabid='',parid='',sub_name='',sub_field=''
+    //   `
+    sql += `
+      ${decSql}
+      ${_customScript}
+      ${LText}
+      ${DateCount}
+      ${_tailScript}
+    `
+
+    let map = new Map()
+    reps.push(...sysVars)
+    reps = reps.filter(n => {
+      if (map.has(n.toLowerCase())) {
+        return false
+      }
+
+      map.set(n.toLowerCase(), true)
+
+      return true
+    })
+    
+    reps.forEach(n => {
+      if (['orderBy', 'pageSize', 'pageIndex'].includes(n)) return
+
+      sql = sql.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+    })
+    if (/\$@/ig.test(sql)) {
+      sql = sql.replace(/\$@/ig, '@datam_begin@').replace(/@\$/ig, '@datam_end@')
+      reps.push('datam_begin', 'datam_end')
+    }
+    if (/@db@/ig.test(sql)) {
+      reps.push('db')
+    }
+    reps.push('mk_obj_name')
+
+    sql = sql.replace(/\n\x20{6,8}/g, '\n').replace(/\n{3,}/g, '\n\n').replace(/^\s+|\s+$/g, '').replace(/\t+|\v+/g, '')
+
+    reps = reps.filter(n => {
+      if (sysVars.includes(n.toLowerCase())) {
+        return false
+      }
+
+      return true
+    })
+
+    return {LText: sql, md5: md5(sql), reps, luser: /@userid@/ig.test(testSql)}
+  }
+
+  let getExcelInSql = (item) => {
+    let btn = item.verify
+    let sheet = item.sheet.replace(/@db@/ig, '')
+    let database = ''
+    if (/@db@/ig.test(item.sheet)) {
+      database = '@db@'
+    }
+  
+    let sql = ''
+    
+    let _initCustomScript = '' // 鍒濆鍖栬剼鏈�
+    let _prevCustomScript = '' // 榛樿sql鍓嶆墽琛岃剼鏈�
+    let _backCustomScript = '' // 榛樿sql鍚庢墽琛岃剼鏈�
+    let _regs = [
+      {reg: new RegExp('(^|\\s)@' + sheet + '(\\s|$)', 'ig'), value: ` #${sheet} `},
+      {reg: new RegExp('(^|\\s)@' + sheet + '\\(', 'ig'), value: ` #${sheet}(`},
+      {reg: new RegExp('(^|\\s)@' + sheet + '\\)', 'ig'), value: ` #${sheet})`},
+    ]
+
+    btn.scripts && btn.scripts.forEach(script => {
+      if (script.status === 'false') return
+
+      let _sql = script.sql
+
+      _regs.forEach(item => {
+        _sql = _sql.replace(item.reg, item.value)
+      })
+
+      if (script.position === 'init') {
+        _initCustomScript += `
+          /* 鑷畾涔夎剼鏈� */
+          ${_sql}
+        `
+      } else if (script.position === 'front') {
+        _prevCustomScript += `
+          /* 鑷畾涔夎剼鏈� */
+          ${_sql}
+        `
+      } else {
+        _backCustomScript += `
+          /* 鑷畾涔夎剼鏈� */
+          ${_sql}
+        `
+      }
+    })
+
+    let _uniquesql = ''
+    if (btn.uniques && btn.uniques.length > 0) {
+      let textFields = []
+      let numberFields = []
+      let dateFields = []
+      btn.columns.forEach((col) => {
+        if (/Nvarchar/ig.test(col.type)) {
+          textFields.push(col.Column)
+        } else if (/Decimal|int/ig.test(col.type)) {
+          numberFields.push(col.Column)
+        } else if (/date/ig.test(col.type)) {
+          dateFields.push(col.Column)
+        }
+      })
+      btn.uniques.forEach(unique => {
+        if (unique.status === 'false' || !unique.verifyType) return
+
+        let _fields = unique.field.split(',')
+        let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
+        _fields_ = _fields_.join(' and ')
+
+        let _where = []
+        _fields.forEach(f => {
+          if (textFields.includes(f)) {
+            _where.push(`${f}!=''`)
+          } else if (numberFields.includes(f)) {
+            _where.push(`${f}!=0`)
+          } else if (dateFields.includes(f)) {
+            _where.push(`${f}>'1949-10-01'`)
+          }
+        })
+        _where = _where.length ? `where ${_where.join(' and ')} ` : ''
+
+        if (unique.verifyType === 'logic' || unique.verifyType === 'logic_temp') {
+          _fields_ += ' and b.deleted=0'
+        }
+
+        let _afields = []
+        _fields = _fields.map(f => {
+          if (numberFields.includes(f)) {
+            _afields.push(`cast(a.${f} as nvarchar(50))`)
+            return `cast(${f} as nvarchar(50))`
+          } else if (dateFields.includes(f)) {
+            _afields.push(`CONVERT(nvarchar(50), a.${f}, 21)`)
+            return `CONVERT(nvarchar(50), ${f}, 21)`
+          }
+          _afields.push(`a.${f}`)
+
+          return f
+        })
+
+        _uniquesql += `
+          /* 閲嶅鎬ч獙璇� */
+          Set @tbid=''
+          Select top 1 @tbid=${_fields.join('+\' \'+')} from (select 1 as n,${unique.field} from #${sheet} ) a group by ${unique.field} having sum(n)>1
+
+          If @tbid!=''
+          Begin
+            select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 閲嶅'
+            goto aaa
+          end
+
+          ${unique.verifyType.indexOf('temp') === -1 ? `Set @tbid=''
+          Select top 1 @tbid=${_afields.join('+\' \'+')} from ${_where ? `(select * from #${sheet} ${_where})` : `#${sheet}`} a Inner join ${sheet} b on ${_fields_}
+
+          If @tbid!=''
+          Begin
+            select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 涓庡凡鏈夋暟鎹噸澶�'
+            goto aaa
+          end` : ''}
+        `
+      })
+    }
+
+    let declarefields = []
+    let fields = []
+
+    btn.columns.forEach(col => {
+      if (col.import === 'false') return
+      
+      if (col.type === 'date') {
+        declarefields.push(`${col.Column} Nvarchar(50)`)
+      } else {
+        declarefields.push(`${col.Column} ${col.type}`)
+      }
+      fields.push(col.Column)
+    })
+
+    fields = fields.join(',')
+
+    let _insert = ''
+    if (btn.default !== 'false') {
+      _insert = `
+        /* 榛樿sql */
+        Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid) 
+        Select ${fields},@UserID@,@username,@fullname,@BID@ From #${sheet}
+      `
+    }
+
+    sql = `/* ${item.logLabel} */
+      BEGIN TRY
+      begin TRAN
+
+      create table #${sheet} (${declarefields.join(',')},jskey nvarchar(50),BID nvarchar(50))
+      Declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)@mk_init_declare@
+
+      Select @ErrorCode='S',@retmsg=''@mk_init_select@
+      ${_initCustomScript}
+
+      Insert into #${sheet} (${fields},jskey,BID)
+
+      /* excel鏁版嵁*/
+      @mk_excel_data@
+
+      ${_uniquesql}
+      ${_prevCustomScript}
+      ${_insert}`
+
+    let mk_ent = ''
+    if (/@ErrorCode='(ENT|NNT|FNT|NMNT|CNT|-2NT)'/ig.test(sql + _backCustomScript)) {
+      mk_ent = `
+          if 1=2
+          begin
+            mk_ent:
+            set @ErrorCode=left(@ErrorCode,1)
+          end
+        `
+    }
+
+    if (btn.workFlow === 'true' && process) {
+      if (btn.flowSql === 'true') {
+        sql += `
+        /* 宸ヤ綔娴佸紓甯竤ql */
+        if @works_flow_error@ != ''
+        select @ErrorCode='E',@retmsg=@works_flow_error@ goto aaa
+
+        /* 宸ヤ綔娴侀粯璁ql */
+        insert into s_my_works_flow (works_flow_id,works_flow_code,works_flow_name,works_flow_param,status,statusname,work_group,works_flow_detail_id,work_grade,bid,createuserid,CreateUser,CreateStaff,upid)
+        select jskey,@works_flow_code@,@works_flow_name@,@works_flow_param@,@status@,@statusname@,@work_group@,@works_flow_detail_id@,@work_grade@,@bid@,@UserID@,@UserName,@FullName,@time_id@
+        from #${sheet}
+
+        insert into s_my_works_flow_log (works_flow_id,works_flow_code,works_flow_name,works_flow_param,status,statusname,works_flow_detail_id,work_group,work_grade,bid,createuserid,CreateUser,CreateStaff,upid)
+        select jskey,@works_flow_code@,@works_flow_name@ ,@works_flow_param@,@status@,@statusname@,@works_flow_detail_id@,@work_group@,@work_grade@,@bid@,@UserID@,@UserName,@FullName,@time_id@
+        from #${sheet}
+
+        insert into s_my_works_flow_notice (works_flow_id,works_flow_code,works_flow_detail_id,userid,notice_type,createuserid,CreateUser,CreateStaff,upid)
+        select jskey,@works_flow_code@,@works_flow_detail_id@,@userid@,@start_type@,@userid@,@UserName,@FullName,@time_id@
+        from #${sheet}
+
+        insert into s_my_works_flow_role (works_flow_id,works_flow_code,userid,works_flow_detail_id,createuserid,CreateUser,CreateStaff,upid,typecharone)
+        select jskey,@works_flow_code@,@userid@,@works_flow_detail_id@,@userid@,@UserName,@FullName,@time_id@,'begin'
+        from #${sheet}
+        `
+      }
+
+      sql += `
+        ${_backCustomScript}
+
+        drop table #${sheet}
+        ${mk_ent}
+        select @ErrorCode as ErrorCode,@retmsg as retmsg
+        ${callback}`
+
+      sql = sql.replace(/@start_type@/ig, `'寮�濮�'`)
+      // works_flow_error       娴佺▼閿欒
+      let worksReFields = ['works_flow_error', 'works_flow_code', 'works_flow_name', 'works_flow_param', 'works_flow_detail_id', 'status', 'statusname', 'work_group', 'work_grade']
+      worksReFields.forEach(n => {
+        sql = sql.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+      })
+    } else {
+      sql += `
+        ${_backCustomScript}
+
+        drop table #${sheet}
+        ${mk_ent}
+        select @ErrorCode as ErrorCode,@retmsg as retmsg
+        ${callback}`
+    }
+
+    if (/@ErrorCode='(ENT|NNT|FNT|NMNT|CNT|-2NT)'/ig.test(sql)) {
+      sql = sql.replace(/@ErrorCode='(ENT|NNT|FNT|NMNT|CNT|-2NT)'[\S\s]+\sgoto\s+aaa($|\s)/ig, (word) => {
+        return word.replace(/goto aaa/, 'goto mk_ent')
+      })
+    }
+
+    let reps = []
+    let decSql = []
+    let secSql = []
+
+    let syses = ['UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address']
+    syses.forEach(s => {
+      if (new RegExp('@' + s + '[^0-9a-z_]', 'ig').test(sql)) {
+        if (['RoleID', 'mk_departmentcode', 'mk_organization'].includes(s)) {
+          decSql.push(`@${s} nvarchar(512)`)
+        } else if (['mk_address'].includes(s)) {
+          decSql.push(`@mk_address nvarchar(100)`)
+        } else {
+          decSql.push(`@${s} nvarchar(50)`)
+        }
+        secSql.push(`@${s}=@${s}@`)
+        reps.push(s)
+      }
+    })
+
+    decSql = decSql.length ? `,${decSql.join(',')}` : ''
+    secSql = secSql.length ? `,${secSql.join(',')}` : ''
+
+    sql = sql.replace(/@mk_init_declare@/ig, decSql)
+    sql = sql.replace(/@mk_init_select@/ig, secSql)
+
+    let regs = ['ID', 'BID', 'time_id', 'datam', 'typename']
+    
+    regs.forEach(s => {
+      if (new RegExp('@' + s + '@', 'ig').test(sql)) {
+        reps.push(s)
+      }
+    })
+
+    let map = new Map()
+    reps.push(...sysVars)
+    reps = reps.filter(n => {
+      if (map.has(n.toLowerCase())) {
+        return false
+      }
+
+      map.set(n.toLowerCase(), true)
+
+      return true
+    })
+
+    reps.forEach(n => {
+      sql = sql.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+    })
+
+    if (/\$@/ig.test(sql)) {
+      sql = sql.replace(/\$@/ig, '@datam_begin@').replace(/@\$/ig, '@datam_end@')
+      reps.push('datam_begin', 'datam_end')
+    }
+    if (/\$check@|@check\$/ig.test(sql)) {
+      sql = sql.replace(/\$check@/ig, '@mk_check_begin@').replace(/@check\$/ig, '@mk_check_end@')
+      reps.push('mk_check_begin', 'mk_check_end')
+    }
+    if (/@db@/ig.test(sql)) {
+      reps.push('db')
+    }
+
+    sql = sql.replace(/\n\x20{6,10}/g, '\n').replace(/\n{3,}/g, '\n\n').replace(/^\s+|\s+$/g, '').replace(/\t+|\v+/g, '')
+
+    reps = reps.filter(n => {
+      if (sysVars.includes(n.toLowerCase())) {
+        return false
+      }
+
+      return true
+    })
+
+    return {LText: sql, md5: md5(sql), reps}
+  }
+
+  let getEditTableSql = (btn, cols, columns, setting) => {
+    let sheet = btn.sheet.replace(/@db@/ig, '')
+    let database = ''
+    if (/@db@/ig.test(btn.sheet)) {
+      database = '@db@'
+    }
+  
+    let forms = []
+    let _forms = {}
+    let index = 0
+
+    let getColumns = (cols) => {
+      cols.forEach(item => {
+        if (item.type === 'colspan') {
+          getColumns(item.subcols)
+        } else if (item.editable === 'true') {
+          item.$sort = index
+          _forms[item.field] = item
+          index++
+        }
+      })
+    }
+
+    getColumns(cols)
+
+    columns.forEach(item => {
+      if (item.field === setting.primaryKey) return
+
+      if (_forms[item.field]) {
+        let _item = {..._forms[item.field]}
+        if (_item.editType === 'date') {
+          _item.datatype = _item.declareType || 'datetime'
+        } else {
+          _item.datatype = item.datatype
+        }
+
+        forms.push(_item)
+      } else {
+        forms.push({...item, $sort: 999})
+      }
+    })
+
+    forms.sort((a, b) => a.$sort - b.$sort)
+
+    let sql = ''
+  
+    let _initCustomScript = '' // 鍒濆鍖栬剼鏈�
+    let _prevCustomScript = '' // 榛樿sql鍓嶆墽琛岃剼鏈�
+    let _backCustomScript = '' // 榛樿sql鍚庢墽琛岃剼鏈�
+    let _regs = [
+      {reg: new RegExp('(^|\\s)@' + sheet + '(\\s|$)', 'ig'), value: ` #${sheet} `},
+      {reg: new RegExp('(^|\\s)@' + sheet + '\\(', 'ig'), value: ` #${sheet}(`},
+      {reg: new RegExp('(^|\\s)@' + sheet + '\\)', 'ig'), value: ` #${sheet})`},
+    ]
+
+    btn.scripts && btn.scripts.forEach(script => {
+      if (script.status === 'false') return
+
+      let _sql = script.sql
+
+      _regs.forEach(item => {
+        _sql = _sql.replace(item.reg, item.value)
+      })
+
+      if (script.position === 'init') {
+        _initCustomScript += `
+          /* 鑷畾涔夎剼鏈� */
+          ${_sql}
+        `
+      } else if (script.position === 'front') {
+        _prevCustomScript += `
+          /* 鑷畾涔夎剼鏈� */
+          ${_sql}
+        `
+      } else {
+        _backCustomScript += `
+          /* 鑷畾涔夎剼鏈� */
+          ${_sql}
+        `
+      }
+    })
+
+    let _uniquesql = ''
+    if (btn.uniques && btn.uniques.length > 0) {
+      let textFields = []
+      let numberFields = []
+      let dateFields = []
+      columns.forEach((col) => {
+        if (/Nvarchar/ig.test(col.datatype)) {
+          textFields.push(col.field)
+        } else if (/Decimal|int/ig.test(col.datatype)) {
+          numberFields.push(col.field)
+        } else if (/date/ig.test(col.datatype)) {
+          dateFields.push(col.field)
+        }
+      })
+      btn.uniques.forEach(unique => {
+        if (unique.status === 'false' || !unique.verifyType) return
+
+        let _fields = unique.field.split(',')
+        let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
+        _fields_ = _fields_.join(' and ')
+
+        let _where = []
+        _fields.forEach(f => {
+          if (textFields.includes(f)) {
+            _where.push(`${f}!=''`)
+          } else if (numberFields.includes(f)) {
+            _where.push(`${f}!=0`)
+          } else if (dateFields.includes(f)) {
+            _where.push(`${f}>'1949-10-01'`)
+          }
+        })
+        _where = _where.length ? `where ${_where.join(' and ')} ` : ''
+
+        if (unique.verifyType === 'logic' || unique.verifyType === 'logic_temp') {
+          _fields_ += ' and b.deleted=0'
+        }
+
+        let _afields = []
+        _fields = _fields.map(f => {
+          if (numberFields.includes(f)) {
+            _afields.push(`cast(a.${f} as nvarchar(50))`)
+            return `cast(${f} as nvarchar(50))`
+          } else if (dateFields.includes(f)) {
+            _afields.push(`CONVERT(nvarchar(50), a.${f}, 21)`)
+            return `CONVERT(nvarchar(50), ${f}, 21)`
+          }
+          _afields.push(`a.${f}`)
+
+          return f
+        })
+
+        _uniquesql += `
+          /* 閲嶅鎬ч獙璇� */
+          Set @tbid=''
+          Select top 1 @tbid=${_fields.join('+\' \'+')} from (select 1 as n,${unique.field} from #${sheet} ) a group by ${unique.field} having sum(n)>1
+          
+          If @tbid!=''
+          Begin
+            select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 閲嶅'
+            goto aaa
+          end
+          
+          ${unique.verifyType.indexOf('temp') === -1 ? `Set @tbid=''
+          Select top 1 @tbid=${_afields.join('+\' \'+')} from ${_where ? `(select * from #${sheet} ${_where})` : `#${sheet}`} a Inner join ${sheet} b on ${_fields_}
+          
+          If @tbid!=''
+          Begin
+            select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 涓庡凡鏈夋暟鎹噸澶�'
+            goto aaa
+          end` : ''}
+        `
+      })
+    }
+
+    let declarefields = []
+    let fields = []
+
+    forms.forEach(col => {
+      let key = col.field.toLowerCase()
+      if (key === 'jskey' || key === 'bid' || key === 'data_type') return
+
+      declarefields.push(`${col.field} ${col.datatype}`)
+      fields.push(col.field)
+    })
+
+    fields = fields.join(',')
+
+    let _insert = ''
+    if (btn.default !== 'false') {
+      _insert = `
+        /* 榛樿sql */
+        Insert into ${database}${sheet} (${fields},createuserid,createuser,createstaff,bid) 
+        Select ${fields},@UserID@,@username,@fullname,@BID@ From #${sheet}
+      `
+    }
+
+    sql = `/* ${btn.logLabel} */
+      BEGIN TRY
+      begin TRAN
+
+      create table #${sheet} (${declarefields.join(',')},jskey nvarchar(50),data_type nvarchar(50),BID nvarchar(256))
+      Declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)@mk_init_declare@
+      Select @ErrorCode='S',@retmsg=''@mk_init_select@
+
+      ${_initCustomScript}
+      Insert into #${sheet} (${fields},jskey,data_type,BID)
+
+      /* table鏁版嵁*/
+      @mk_excel_data@
+
+      ${_uniquesql}
+      ${_prevCustomScript}
+      ${_insert}
+      ${_backCustomScript}
+
+      drop table #${sheet}
+
+      select @ErrorCode as ErrorCode,@retmsg as retmsg
+      ${callback}`
+  
+    let reps = []
+    let decSql = []
+    let secSql = []
+
+    let syses = ['UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address']
+    syses.forEach(s => {
+      if (new RegExp('@' + s + '[^0-9a-z_]', 'ig').test(sql)) {
+        if (['RoleID', 'mk_departmentcode', 'mk_organization'].includes(s)) {
+          decSql.push(`@${s} nvarchar(512)`)
+        } else if (['mk_address'].includes(s)) {
+          decSql.push(`@mk_address nvarchar(100)`)
+        } else {
+          decSql.push(`@${s} nvarchar(50)`)
+        }
+        secSql.push(`@${s}=@${s}@`)
+        reps.push(s)
+      }
+    })
+
+    decSql = decSql.length ? `,${decSql.join(',')}` : ''
+    secSql = secSql.length ? `,${secSql.join(',')}` : ''
+
+    sql = sql.replace(/@mk_init_declare@/ig, decSql)
+    sql = sql.replace(/@mk_init_select@/ig, secSql)
+
+    let regs = ['BID', 'time_id', 'datam', 'typename']
+    
+    regs.forEach(s => {
+      if (new RegExp('@' + s + '@', 'ig').test(sql)) {
+        reps.push(s)
+      }
+    })
+
+    let map = new Map()
+    reps.push(...sysVars)
+    reps = reps.filter(n => {
+      if (map.has(n.toLowerCase())) {
+        return false
+      }
+
+      map.set(n.toLowerCase(), true)
+
+      return true
+    })
+
+    reps.forEach(n => {
+      sql = sql.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+    })
+
+    if (/\$@/ig.test(sql)) {
+      sql = sql.replace(/\$@/ig, '@datam_begin@').replace(/@\$/ig, '@datam_end@')
+      reps.push('datam_begin', 'datam_end')
+    }
+    if (/@db@/ig.test(sql)) {
+      reps.push('db')
+    }
+
+    sql = sql.replace(/\n\x20{6,10}/g, '\n').replace(/\n{3,}/g, '\n\n').replace(/^\s+|\s+$/g, '').replace(/\t+|\v+/g, '')
+
+    reps = reps.filter(n => {
+      if (sysVars.includes(n.toLowerCase())) {
+        return false
+      }
+
+      return true
+    })
+
+    return {LText: sql, md5: md5(sql), reps}
+  }
+
+  let getExcelOutSql = (btn, component) => {
+    let item = {setting: {}, columns: [], search: [], useMSearch: 'false'}
+
+    btn.verify.columns.forEach(col => {
+      if (col.output === 'false' || !col.Column || col.Column === '$Index') return
+      item.columns.push({
+        field: col.Column
+      })
+    })
+
+    if (btn.verify.useSearch !== 'false') {
+      item.search = component.$searches
+    }
+
+    item.setting.interType = 'system'
+    item.setting.execute = btn.verify.defaultSql || 'true'
+    item.setting.dataresource = btn.verify.dataresource || ''
+    item.setting.queryType = btn.verify.queryType
+    item.setting.laypage = btn.pagination
+    item.setting.order = btn.verify.order || ''
+    item.setting.$name = btn.logLabel || ''
+
+    if (btn.Ot === 'requiredOnce') {
+      item.setting.primaryKey = btn.verify.primaryKey || component.setting.primaryKey || 'ID'
+    }
+
+    item.scripts = btn.verify.scripts || []
+
+    let msg = getDataSource(item, [])
+
+    return msg
+  }
+
+  let getDoubleExcelOutSql = (btn, component) => {
+    let item = fromJS(component).toJS()
+    item.search = item.$searches || []
+    item.subtype = 'datacard'
+    item.columns = [...item.columns, ...item.subColumns]
+
+    item.setting.laypage = btn.pagination
+    item.setting.$name = btn.logLabel || ''
+
+    let msg = getDataSource(item, [])
+
+    return msg
+  }
+
+  let getPrintSql = (btn, component) => {
+    let item = {setting: {}, columns: btn.verify.columns || [], search: [], useMSearch: 'false'}
+
+    item.setting.interType = 'system'
+    item.setting.execute = btn.verify.setting.defaultSql || 'true'
+    item.setting.dataresource = btn.verify.setting.dataresource || ''
+    item.setting.queryType = btn.verify.setting.queryType
+    item.setting.laypage = 'false'
+    item.setting.order = btn.verify.setting.order || ''
+    item.setting.$name = btn.logLabel || ''
+    item.setting.transact = 'true'
+    item.setting.$fixOrder = true
+
+    item.scripts = btn.verify.scripts || []
+
+    let msg = getDataSource(item, [], 'print')
+
+    msg.LText = msg.LText.replace(/@mk_obj_name@/ig, 'data')
+    msg.reps = msg.reps.filter(n => n !== 'mk_obj_name')
+
+    let formkeys = []
+    let colreps = []
+    let _declares = []
+    let _init = []
+    if (btn.execMode === 'pop' && btn.modal && btn.modal.fields) {
+      btn.modal.fields.forEach(item => {
+        if (!item.field) return
+        let _key = item.field.toLowerCase()
+
+        if (!new RegExp('@' + _key + '[^0-9a-z_]', 'ig').test(msg.LText)) return
+
+        formkeys.push(_key)
+        colreps.push(item.field)
+        
+        let _item = {
+          key: item.field,
+          fieldlen: item.fieldlength || 50,
+          writein: item.writein !== 'false',
+          type: item.type,
+          isconst: item.constant === 'true'
+        }
+  
+        if (_item.type === 'datemonth') {
+          _item.type = 'text'
+        } else if (_item.type === 'number' || _item.type === 'rate') {
+          _item.fieldlen = item.decimal || 0
+        } else if (_item.type === 'date') {
+          _item.type = item.declareType === 'nvarchar(50)' ? 'text' : 'date'
+        } else if (_item.type === 'datetime') {
+          _item.type = 'date'
+        } else if (item.declare === 'decimal') {
+          _item.type = 'number'
+          _item.fieldlen = item.decimal || 0
+        }
+  
+        if (_item.type === 'number' || _item.type === 'rate') {
+          _init.push(`@${_key}=@mk_${_key}_mk@`)
+        } else if (_item.type === 'date') {
+          _init.push(`@${_key}='@mk_${_key}_mk@'`)
+        } else if (_item.type === 'select' || _item.type === 'link' || _item.type === 'radio') {
+          _init.push(`@${_key}='@mk_${_key}_mk@'`)
+        } else if (_item.isconst) {
+          _init.push(`@${_key}=N'@mk_${_key}_mk@'`)
+        } else {
+          _init.push(`@${_key}='@mk_${_key}_mk@'`)
+        }
+
+        if (_item.fieldlen && _item.fieldlen > 4000) {
+          _item.fieldlen = 'max'
+        }
+  
+        let _type = `nvarchar(${_item.fieldlen})`
+  
+        if (_item.type.match(/date/ig)) {
+          _type = 'datetime'
+        } else if (_item.type === 'number') {
+          _type = `decimal(18,${_item.fieldlen})`
+        } else if (_item.type === 'rate') {
+          _type = `decimal(18,2)`
+        }
+  
+        _declares.push(`@${_key} ${_type}`)
+      })
+    }
+
+    // 娣诲姞鏁版嵁涓瓧娈碉紝琛ㄥ崟鍊间紭鍏�(鎸夐挳涓嶉�夎鎴栧琛屾嫾鎺ユ椂璺宠繃)
+    if (btn.Ot !== 'notRequired' && component.columns.length > 0) {
+      component.columns.forEach(col => {
+        let _key = col.field.toLowerCase()
+
+        if (formkeys.includes(_key) || !new RegExp('@' + _key + '[^0-9a-z_@]', 'ig').test(msg.LText)) return
+        // if (_key === 'id' && !/@id[^0-9a-z_@]/ig.test(msg.LText)) return
+
+        colreps.push(col.field)
+  
+        if (col.type === 'number') {
+          _init.push(`@${_key}=@mk_${_key}_mk@`)
+        } else {
+          _init.push(`@${_key}='@mk_${_key}_mk@'`)
+        }
+        
+        _declares.push(`@${_key} ${col.datatype || 'nvarchar(50)'}`)
+      })
+    }
+
+    _declares = _declares.length ? ',' + _declares.join(',') : ''
+    _init = _init.length ? ',' + _init.join(',') : ''
+
+    msg.LText = msg.LText.replace('@mk_print_declare@', _declares)
+    msg.LText = msg.LText.replace('@mk_print_select@', _init)
+
+    msg.reps = [...msg.reps, ...colreps]
+
+    return msg
+  }
+
+  let getPaySql = (btn, component) => {
+    let _sql = `/* ${btn.logLabel} */
+      BEGIN TRY
+      begin TRAN
+
+      Declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid nvarchar(50)@mk_init_declare@
+      Select @ErrorCode='S',@retmsg=''@mk_init_select@
+      `
+
+    btn.verify.scripts.forEach(item => {
+      if (item.status === 'false') return
+
+      _sql += `
+      ${item.sql}
+      `
+    })
+
+    if (btn.output) {
+      _sql += `
+        select @ErrorCode as ErrorCode,@retmsg as retmsg,${btn.output} as mk_b_id
+        ${callback}`
+    } else {
+      _sql += `
+        select @ErrorCode as ErrorCode,@retmsg as retmsg
+        ${callback}`
+    }
+    
+    let reps = []
+    let decSql = []
+    let secSql = []
+
+    let syses = ['UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'BID']
+    syses.forEach(s => {
+      if (new RegExp('@' + s + '[^0-9a-z_]', 'ig').test(_sql)) {
+        if (['RoleID', 'mk_departmentcode', 'mk_organization'].includes(s)) {
+          decSql.push(`@${s} nvarchar(512)`)
+        } else if (['mk_address'].includes(s)) {
+          decSql.push(`@mk_address nvarchar(100)`)
+        } else {
+          decSql.push(`@${s} nvarchar(50)`)
+        }
+        secSql.push(`@${s}=@${s}@`)
+        reps.push(s)
+      }
+    })
+
+    let regs = ['ID', 'time_id', 'datam', 'typename']
+
+    regs.forEach(s => {
+      if (new RegExp('@' + s + '@', 'ig').test(_sql)) {
+        reps.push(s)
+      }
+    })
+
+    syses = syses.map(n => n.toLowerCase())
+    syses.push('tbid')
+
+    let colreps = []
+    component.columns.forEach(col => {
+      let _key = col.field.toLowerCase()
+
+      if (syses.includes(_key) || !new RegExp('@' + _key + '[^0-9a-z_@]', 'ig').test(_sql)) return
+      // if (_key === 'id' && !/@id[^0-9a-z_@]/ig.test(_sql)) return
+
+      colreps.push(col.field)
+      
+      decSql.push(`@${col.field} ${col.datatype || 'nvarchar(50)'}`)
+
+      if (col.type === 'number') {
+        secSql.push(`@${col.field}=@mk_${col.field}_mk@`)
+      } else {
+        secSql.push(`@${col.field}='@mk_${col.field}_mk@'`)
+      }
+    })
+
+    decSql = decSql.length ? `,${decSql.join(',')}` : ''
+    secSql = secSql.length ? `,${secSql.join(',')}` : ''
+
+    _sql = _sql.replace(/@mk_init_declare@/ig, decSql)
+    _sql = _sql.replace(/@mk_init_select@/ig, secSql)
+
+    let map = new Map()
+    reps.push(...sysVars)
+    reps = reps.filter(n => {
+      if (map.has(n.toLowerCase())) {
+        return false
+      }
+
+      map.set(n.toLowerCase(), true)
+
+      return true
+    })
+
+    reps.forEach(n => {
+      _sql = _sql.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+    })
+
+    if (/\$@/ig.test(_sql)) {
+      _sql = _sql.replace(/\$@/ig, '@datam_begin@').replace(/@\$/ig, '@datam_end@')
+      reps.push('datam_begin', 'datam_end')
+    }
+    if (/@db@/ig.test(_sql)) {
+      reps.push('db')
+    }
+
+    _sql = _sql.replace(/\n\x20{6,8}/g, '\n').replace(/\n{3,}/g, '\n\n').replace(/^\s+|\s+$/g, '').replace(/\t+|\v+/g, '')
+
+    reps = reps.filter(n => {
+      if (sysVars.includes(n.toLowerCase())) {
+        return false
+      }
+
+      return true
+    })
+
+    reps = [...reps, ...colreps]
+
+    return {LText: _sql, md5: md5(_sql), reps}
+  }
+
+  let getFormSql = (item, tname) => {
+    let arrfield = [item.valueField, item.valueText]
+
+    if (item.type === 'checkcard') {
+      arrfield = item.fields ? item.fields.map(f => f.field) : []
+      arrfield.push(item.cardValField)
+      if (item.urlField) {
+        arrfield.push(item.urlField)
+      } else if (item.colorField) {
+        arrfield.push(item.colorField)
+      } else if (item.parentField) {
+        arrfield.push(item.parentField)
+      }
+    }
+
+    if (item.linkField) {
+      arrfield.push(item.linkField)
+    }
+    if (['select', 'radio', 'link', 'checkcard'].includes(item.type) && item.linkSubField && item.linkSubField.length > 0) {
+      arrfield.push(...item.linkSubField)
+    } else if (item.type === 'text' && item.editType === 'select' && item.linkSubField && item.linkSubField.length > 0) { // 鍙紪杈戣〃
+      arrfield.push(...item.linkSubField)
+    }
+    if (item.disableField) {
+      arrfield.push(item.disableField)
+    }
+
+    arrfield = Array.from(new Set(arrfield))
+
+    let _datasource = item.dataSource
+    let sql = ''
+
+    if (/\s/.test(_datasource)) { // 鎷兼帴鍒悕
+      _datasource = '(' + _datasource + ') tb'
+    }
+
+    arrfield = arrfield.join(',')
+
+    if (item.orderBy) {
+      sql = `select distinct ${arrfield},${item.orderBy} as orderfield from ${_datasource} order by orderfield ${item.orderType}`
+    } else {
+      sql = `select distinct ${arrfield} from ${_datasource}`
+    }
+
+    let reps = []
+
+    let decSql = []
+    let secSql = []
+
+    let syses = ['mk_departmentcode', 'mk_organization', 'mk_user_type']
+    syses.forEach(s => {
+      if (new RegExp('@' + s + '[^0-9a-z_]', 'ig').test(sql)) {
+        if (['mk_departmentcode', 'mk_organization'].includes(s)) {
+          decSql.push(`@${s} nvarchar(512)`)
+        } else {
+          decSql.push(`@${s} nvarchar(20)`)
+        }
+        secSql.push(`@${s}=@${s}@`)
+        reps.push(s)
+      }
+    })
+
+    decSql = decSql.join(',')
+    secSql = secSql.join(',')
+    decSql = decSql ? `Declare ${decSql} select ${secSql}` : ''
+
+    sql = `/* ${item.label}锛�${tname}锛� */
+      SELECT obj_name='${item.field}',prm_field='',str_field='',
+      arr_field='${arrfield}',tabid='',parid='',sub_name='',sub_field=''
+
+      ${decSql}
+      ${sql}
+
+      select 'S' as ErrorCode,'' as retmsg
+    `
+
+    let regs = ['ID', 'BID', 'datam']
+
+    regs.forEach(s => {
+      if (new RegExp('@' + s + '@', 'ig').test(sql)) {
+        reps.push(s)
+      }
+    })
+
+    reps.push(...sysVars)
+
+    reps.forEach(n => {
+      sql = sql.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+    })
+
+    if (/\$@/ig.test(sql)) {
+      sql = sql.replace(/\$@/ig, '@datam_begin@').replace(/@\$/ig, '@datam_end@')
+      reps.push('datam_begin', 'datam_end')
+    }
+    if (/@db@/ig.test(sql)) {
+      reps.push('db')
+    }
+
+    // reps.push('mk_obj_name')
+
+    sql = sql.replace(/\n\x20{6,8}/g, '\n').replace(/\n{3,}/g, '\n\n').replace(/^\s+|\s+$/g, '').replace(/\t+|\v+/g, '')
+
+    reps = reps.filter(n => {
+      if (sysVars.includes(n.toLowerCase())) {
+        return false
+      }
+
+      return true
+    })
+
+    return {LText: sql, md5: md5(sql), reps}
+  }
+
+  let getPopSelectSql = (item) => {
+    let arrfield = item.columns.map(f => f.field)
+  
+    if (item.linkSubField && item.linkSubField.length > 0) {
+      item.linkSubField.forEach(n => {
+        if (!arrfield.includes(n)) {
+          arrfield.push(n)
+        }
+      })
+    }
+
+    arrfield = arrfield.join(',')
+    if (/\s/.test(item.dataSource)) { // 鎷兼帴鍒悕
+      item.dataSource = '(' + item.dataSource + ') tb'
+    }
+
+    let LText = ''
+    let DateCount = ''
+    let _search = ''
+    let reps = []
+    let sFields = []
+
+    if (item.searchKey) {
+      _search = '@mk_search@'
+      sFields = item.searchKey.split(',')
+    }
+
+    // 涓嶉渶瑕佸崟寮曞彿锛歰rderBy銆乸ageSize銆乸ageIndex銆乨b
+    let regs = [...sFields, 'orderBy', 'pageSize', 'pageIndex', 'ID', 'BID', 'time_id', 'datam']
+
+    regs.forEach(s => {
+      if (new RegExp('@' + s + '@', 'ig').test(item.dataSource)) {
+        reps.push(s)
+      }
+    })
+
+    let decSql = []
+    let secSql = []
+
+    let syses = ['mk_departmentcode', 'mk_organization', 'mk_user_type']
+    syses.forEach(s => {
+      if (new RegExp('@' + s + '[^0-9a-z_]', 'ig').test(item.dataSource)) {
+        if (['mk_departmentcode', 'mk_organization'].includes(s)) {
+          decSql.push(`@${s} nvarchar(512)`)
+        } else {
+          decSql.push(`@${s} nvarchar(20)`)
+        }
+        secSql.push(`@${s}=@${s}@`)
+        reps.push(s)
+      }
+    })
+
+    decSql = decSql.join(',')
+    secSql = secSql.join(',')
+    decSql = decSql ? `Declare ${decSql} select ${secSql}` : ''
+
+    if (item.laypage === 'true') {
+      /*system_query*/
+      LText = `select top @pageSize@ ${arrfield} from (select ${arrfield} ,ROW_NUMBER() over(order by @orderBy@) as rows from ${item.dataSource} ${_search}) tmptable where rows > @pageSize@ * (@pageIndex@ - 1) order by tmptable.rows `
+      DateCount = `select count(1) as total from ${item.dataSource} ${_search}`
+
+      reps.push('pageSize', 'orderBy', 'pageIndex')
+    } else {
+      LText = `select ${arrfield} from ${item.dataSource} ${_search} order by @orderBy@ `
+      reps.push('orderBy')
+    }
+
+    let sql = `SELECT obj_name='data',prm_field='',str_field='',
+      arr_field='${arrfield}',tabid='',parid='',sub_name='',sub_field=''
+      `
+
+    if (DateCount) {
+      sql += `UNION ALL
+        SELECT obj_name='DateCount',prm_field='total',str_field='',
+        arr_field='',tabid='',parid='',sub_name='',sub_field=''
+      `
+    }
+
+    sql += `
+      ${decSql}
+      ${LText}
+      ${DateCount}
+
+      select 'S' as ErrorCode,'' as retmsg
+    `
+
+    let map = new Map()
+    reps.push(...sysVars)
+    reps = reps.filter(n => {
+      if (map.has(n.toLowerCase())) {
+        return false
+      }
+
+      map.set(n.toLowerCase(), true)
+
+      return true
+    })
+
+    reps.forEach(n => {
+      if (['orderBy', 'pageSize', 'pageIndex'].includes(n)) return
+
+      sql = sql.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+    })
+    if (/\$@/ig.test(sql)) {
+      sql = sql.replace(/\$@/ig, '@datam_begin@').replace(/@\$/ig, '@datam_end@')
+      reps.push('datam_begin', 'datam_end')
+    }
+    if (/@db@/ig.test(sql)) {
+      reps.push('db')
+    }
+
+    sql = sql.replace(/\n\x20{6,8}/g, '\n').replace(/\n{3,}/g, '\n\n').replace(/^\s+|\s+$/g, '').replace(/\t+|\v+/g, '')
+
+    reps = reps.filter(n => {
+      if (sysVars.includes(n.toLowerCase())) {
+        return false
+      }
+
+      return true
+    })
+
+    return {LText: sql, md5: md5(sql), reps}
+  }
+
+  let getInvoicePreSql = (btn, logLabel) => {
+    let reps = []
+    let sysVars = ['loginuid', 'sessionuid', 'userid', 'appkey', 'lang', 'username', 'fullname', 'menuname']
+    let _script = ''
+    btn.scripts.forEach(item => {
+      if (item.status === 'false') return
+      _script += `
+      ${item.sql}
+      `
+    })
+
+    _script = _script.replace(/@typename@/ig, `'admin'`)
+    
+    let regs = ['ID', 'BID', 'time_id', 'datam', ...sysVars]
+
+    regs.forEach(s => {
+      if (new RegExp('@' + s + '@', 'ig').test(_script)) {
+        reps.push(s)
+      }
+    })
+
+    reps.forEach(n => {
+      _script = _script.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+    })
+    if (/\$@/ig.test(_script)) {
+      _script = _script.replace(/\$@/ig, '@datam_begin@').replace(/@\$/ig, '@datam_end@')
+      reps.push('datam_begin', 'datam_end')
+    }
+    if (/@db@/ig.test(_script)) {
+      reps.push('db')
+    }
+
+    let syses = ['UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'bid']
+    let decSql = []
+    let secSql = []
+  
+    syses.forEach(s => {
+      if (new RegExp('@' + s + '[^0-9a-z_]', 'ig').test(_script)) {
+        if (['RoleID', 'mk_departmentcode', 'mk_organization'].includes(s)) {
+          decSql.push(`@${s} nvarchar(512)`)
+        } else if (['mk_address'].includes(s)) {
+          decSql.push(`@mk_address nvarchar(100)`)
+        } else {
+          decSql.push(`@${s} nvarchar(50)`)
+        }
+        secSql.push(`@${s}='@${s}@'`)
+        reps.push(s)
+      }
+    })
+    decSql = decSql.join(',')
+    secSql = secSql.join(',')
+
+    let sql = `/* ${logLabel} */
+      BEGIN TRY 
+      begin TRAN
+
+      Declare @ErrorCode nvarchar(50), @retmsg nvarchar(4000), @account_id nvarchar(50), @account_year_id nvarchar(50), @account_code nvarchar(50), @account_year_code nvarchar(50), @tbid nvarchar(50)${decSql ? ',' + decSql : ''}
+
+      Select @ErrorCode='S', @retmsg='', @account_id='@account_id@', @account_year_id='@account_year_id@', @account_code='@account_code@', @account_year_code='@account_year_code@'${secSql ? ',' + secSql : ''}
+
+      /* 鍙戠エ涓昏〃瀛楁 */
+      Declare @invoice_type Nvarchar(50), @from_to_name Nvarchar(50), @from_to_tax_no Nvarchar(50), @from_to_addr Nvarchar(100), @from_to_tel Nvarchar(50), @from_to_bank_name Nvarchar(50), @from_to_account_no Nvarchar(50), @from_to_mob Nvarchar(50), @from_to_email Nvarchar(50), @from_to_code Nvarchar(50), @orgname Nvarchar(50), @tax_no Nvarchar(50), @addr Nvarchar(100), @tel Nvarchar(50), @bank_name Nvarchar(50), @account_no Nvarchar(50), @remark Nvarchar(512), @payee Nvarchar(50), @reviewer Nvarchar(50), @drawer Nvarchar(50), @io Nvarchar(50), @orgcode Nvarchar(50), @total_net_amount Decimal(18,2), @total_tax Decimal(18,2), @total_amount Decimal(18,2), @business_type Nvarchar(20)
+
+      Select @invoice_type='@invoice_type@', @from_to_name='@from_to_name@', @from_to_tax_no='@from_to_tax_no@', @from_to_addr='@from_to_addr@', @from_to_tel='@from_to_tel@', @from_to_bank_name='@from_to_bank_name@', @from_to_account_no='@from_to_account_no@', @from_to_mob='@from_to_mob@', @from_to_email='@from_to_email@', @from_to_code='@from_to_code@', @orgname='@orgname@', @tax_no='@tax_no@', @addr='@addr@', @tel='@tel@', @bank_name='@bank_name@', @account_no='@account_no@', @remark='@remark@', @payee='@payee@', @reviewer='@reviewer@', @drawer='@drawer@', @io='@io@', @orgcode='@orgcode@', @total_net_amount=@total_net_amount@, @total_tax=@total_tax@, @total_amount=@total_amount@, @business_type='@business_type@'
+
+      /* 鍙戠エ鏄庣粏涓存椂琛� */
+
+      Declare @details_list table (productcode Nvarchar(50), productname Nvarchar(50), spec Nvarchar(50), unit Nvarchar(50), bill_count Decimal(18,10), unitprice Decimal(18,10), amount_line Decimal(18,2), tax_classify_code Nvarchar(50), tax_classify_name Nvarchar(50), tax_rate Decimal(18,2), tax_amount Decimal(18,2), free_tax_mark Nvarchar(50), vat_special_management Nvarchar(50), invoice_lp Nvarchar(50), tax_item Nvarchar(50), tax_method Nvarchar(50), jskey Nvarchar(50), data_type Nvarchar(50))
+
+      Insert into @details_list (productcode, productname, spec, unit, bill_count, unitprice, amount_line, tax_classify_code, tax_classify_name, tax_rate, tax_amount, free_tax_mark, vat_special_management, invoice_lp, tax_item, tax_method, jskey, data_type)
+
+      @mk_excel_data@
+
+      /* 鑷畾涔夎剼鏈� */
+      ${_script}
+      `
+
+    if (btn.type === 'billout') {
+      sql += callback
+    } else {
+      sql += `
+        select @ErrorCode as ErrorCode,@retmsg as retmsg
+        ${callback}
+        `
+    }
+
+    reps = reps.filter(n => {
+      if (sysVars.includes(n.toLowerCase())) {
+        return false
+      }
+
+      return true
+    })
+
+    sql = sql.replace(/\n\x20{6,8}/g, '\n').replace(/\n{3,}/g, '\n\n').replace(/^\s+|\s+$/g, '').replace(/\t+|\v+/g, '')
+
+    return {LText: sql, md5: md5(sql), reps}
+  }
+
+  let getInvoiceSysBackSql = (btn, logLabel) => {
+    let _prev = ''
+    let _back = ''
+    let tables = []
+    let reps = []
+
+    btn.cbScripts.forEach(script => {
+      if (script.status === 'false') return
+
+      if (/\s#[a-z0-9_]+(\s|\()/ig.test(script.sql)) {
+        tables.push(...script.sql.match(/\s#[a-z0-9_]+(\s|\()/ig))
+      }
+
+      if (script.position === 'front') {
+        _prev += `
+        /* 鑷畾涔夎剼鏈� */
+        ${script.sql}
+        `
+      } else {
+        _back += `
+        /* 鑷畾涔夎剼鏈� */
+        ${script.sql}
+        `
+      }
+    })
+
+    tables = tables.map(tb => tb.replace(/\s|\(/g, ''))
+
+    let syses = ['UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'bid']
+    let decSql = []
+    let secSql = []
+    let testSql = _prev + _back
+
+    _prev = _prev.replace(/@typename@/ig, `'admin'`)
+    _back = _back.replace(/@typename@/ig, `'admin'`)
+
+    let regs = ['ID', 'BID', 'time_id', 'datam', ...sysVars]
+
+    regs.forEach(s => {
+      if (new RegExp('@' + s + '@', 'ig').test(testSql)) {
+        reps.push(s)
+      }
+    })
+
+    reps.forEach(n => {
+      _prev = _prev.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+      _back = _back.replace(new RegExp('@' + n + '@', 'ig'), `'@${n}@'`)
+    })
+    if (/\$@/ig.test(testSql)) {
+      _prev = _prev.replace(/\$@/ig, '@datam_begin@').replace(/@\$/ig, '@datam_end@')
+      _back = _back.replace(/\$@/ig, '@datam_begin@').replace(/@\$/ig, '@datam_end@')
+      reps.push('datam_begin', 'datam_end')
+    }
+    if (/@db@/ig.test(testSql)) {
+      reps.push('db')
+    }
+  
+    syses.forEach(s => {
+      if (new RegExp('@' + s + '[^0-9a-z_]', 'ig').test(testSql)) {
+        if (['RoleID', 'mk_departmentcode', 'mk_organization'].includes(s)) {
+          decSql.push(`@${s} nvarchar(512)`)
+        } else if (['mk_address'].includes(s)) {
+          decSql.push(`@mk_address nvarchar(100)`)
+        } else {
+          decSql.push(`@${s} nvarchar(50)`)
+        }
+        secSql.push(`@${s}='@${s}@'`)
+        reps.push(s)
+      }
+    })
+    decSql = decSql.join(',')
+    secSql = secSql.join(',')
+  
+    // 闇�瑕佸0鏄庣殑鍙橀噺闆�
+
+    let _sql = `/* ${logLabel} */
+      BEGIN TRY 
+      begin TRAN
+
+      Declare @ErrorCode nvarchar(50), @retmsg nvarchar(4000), @account_id nvarchar(50), @account_year_id nvarchar(50), @account_code nvarchar(50), @account_year_code nvarchar(50), @tbid nvarchar(50)${decSql ? ',' + decSql : ''}
+
+      Select @ErrorCode='S', @retmsg='', @account_id='@account_id@', @account_year_id='@account_year_id@', @account_code='@account_code@', @account_year_code='@account_year_code@'${secSql ? ',' + secSql : ''}
+
+      ${_prev}
+      /* 澶栭儴鎺ュ彛鍏ュ弬 */
+      @mk_outer_params@
+      ${_back}
+      select @ErrorCode as ErrorCode,@retmsg as retmsg
+      ${callback}
+      `
+
+    _sql = _sql.replace(/\n\x20{6,8}/g, '\n').replace(/\n{3,}/g, '\n\n').replace(/^\s+|\s+$/g, '').replace(/\t+|\v+/g, '')
+
+    reps = reps.filter(n => {
+      if (sysVars.includes(n.toLowerCase())) {
+        return false
+      }
+
+      return true
+    })
+
+    return { LText: _sql, md5: md5(_sql), reps, tbs: tables }
+  }
+
+  let _mainSearch = []
+
+  if (appType === 'mob') {
+    let search = []
+    let ms = null
+    config.components.forEach(item => {
+      if (item.type === 'topbar' && item.wrap.type !== 'navbar' && item.search) {
+        ms = item.search
+      } else if (item.type === 'search' && item.wrap.field) {
+        search.push({
+          type: 'text',
+          field: item.wrap.field,
+        })
+      }
+    })
+
+    if (ms) {
+      if (ms.setting.type === 'search') {
+        search.push({
+          type: 'text',
+          field: ms.setting.field,
+        })
+      }
+      search.push(...ms.fields)
+
+      ms.groups.forEach(group => {
+        if (group.setting.type === 'search') {
+          search.push({
+            type: 'text',
+            field: group.setting.field,
+          })
+        }
+        search.push(...group.fields)
+      })
+
+      if (search.length > 0) {
+        search.forEach(cell => {
+          if (['select', 'link', 'multiselect', 'checkcard', 'radio'].includes(cell.type) && cell.resourceType === '1' && cell.dataSource) {
+            let msg = getFormSql(cell, '鎼滅储')
+    
+            sqls.push({uuid: cell.uuid, type: 'sForm', ...msg})
+          }
+        })
+      }
+    }
+
+    if (search.length > 0) {
+      _mainSearch = search
+    }
+  } else {
+    config.components.forEach(component => {
+      if (component.type !== 'search') return
+
+      _mainSearch = component.search || []
+    })
+  }
+
+  if (config.interfaces && config.interfaces.length > 0) {
+    config.interfaces.forEach(m => {
+      if (m.status !== 'true' || m.setting.interType !== 'system') return false
+
+      m.setting.laypage = 'false'
+      m.setting.$top = true
+      m.setting.$name = (config.MenuName || '') + '-' + (m.name || '')
+
+      let msg = getDataSource(m, _mainSearch)
+
+      sqls.push({uuid: m.uuid, type: 'interface', ...msg})
+    })
+  }
+
+  filterComponent(config.components, _mainSearch)
+
+  return sqls
 }
\ No newline at end of file
diff --git a/src/utils/utils-datamanage.js b/src/utils/utils-datamanage.js
index 0415658..5b0c6e2 100644
--- a/src/utils/utils-datamanage.js
+++ b/src/utils/utils-datamanage.js
@@ -5,6 +5,134 @@
 import MKEmitter from '@/utils/events.js'
 import Utils from './utils.js'
 
+const getBackendQueryParam = (setting, search, orderBy, pageIndex, pageSize, id, BID, year, dataName) => {
+  let item = window.GLOB.CacheData.get('sql_' + setting.uuid)
+
+  let searchKeys = null
+  if (setting.dataresource) {
+    searchKeys = []
+
+    if (search.length && setting.queryType !== 'statistics') {
+      searchKeys = Utils.getSearchkeys(search)
+    }
+
+    if (id) {
+      if (/^excel:/.test(id)) {
+        id = id.replace(/^excel:/, '')
+        searchKeys.push({
+          key: setting.primaryKey || 'ID',
+          match: '',
+          type: 'text_in',
+          value: id
+        })
+      } else {
+        searchKeys.push({
+          key: setting.primaryKey || 'ID',
+          match: '03',
+          type: 'text',
+          value: id
+        })
+      }
+    }
+  }
+
+  let values = {
+    time_id: Utils.getguid(),
+    roleid: sessionStorage.getItem('role_id') || '',
+    mk_departmentcode: sessionStorage.getItem('departmentcode') || '',
+    mk_organization: sessionStorage.getItem('organization') || '',
+    mk_user_type: sessionStorage.getItem('mk_user_type') || '',
+    mk_nation: sessionStorage.getItem('nation') || '',
+    mk_province: sessionStorage.getItem('province') || '',
+    mk_city: sessionStorage.getItem('city') || '',
+    mk_district: sessionStorage.getItem('district') || '',
+    mk_address: sessionStorage.getItem('address') || '',
+    orderby: orderBy || '',
+    pagesize: setting.laypage ? pageSize : '9999',
+    pageindex: pageIndex,
+    id: id || '',
+    bid: BID || '',
+    typename: 'admin',
+    datam: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+    datam_begin: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+    datam_end: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
+    mk_obj_name: dataName || 'data'
+  }
+
+  if (setting.hasExtend) {
+    values.mk_time = setting.extendTime
+  }
+  if (setting.$re_year) {
+    values.mk_year = year
+  }
+  if (window.GLOB.externalDatabase !== null) {
+    values.db = window.GLOB.externalDatabase
+  }
+  if (item.works_flow_code) {
+    values.works_flow_code = item.works_flow_code
+  }
+
+  item.urlkeys && item.urlkeys.forEach(key => {
+    values[key] = item.urlparam[key]
+  })
+
+  let allSearch = Utils.getAllSearchOptions(search)
+
+  allSearch.forEach(cell => {
+    values[cell.key.toLowerCase()] = cell.value
+  })
+
+  let exps = []
+
+  if (searchKeys) {
+    exps.push({
+      key: 'mk_search',
+      value: searchKeys
+    })
+  }
+
+  item.reps.forEach(n => {
+    let key = n.toLowerCase()
+    if (values.hasOwnProperty(key)) {
+      exps.push({
+        key: n,
+        value: values[key]
+      })
+    }
+  })
+
+  let md5_id = ''
+  if (window.GLOB.probation) {
+    md5_id = md5(item.id + JSON.stringify(exps) + Math.floor(new Date().getTime() / 600000))
+    md5_id = moment().format('YYYYMMDDHHmmss') + md5_id.slice(-18)
+  }
+
+  let cell = {
+    id: item.id,
+    menuname: setting.$name || '',
+    exps: exps,
+    md5_id: md5_id
+  }
+
+  if (dataName) {
+    cell.dataName = dataName
+    cell.luser = item.luser
+    return cell
+  }
+
+  let param = {
+    $backend: true,
+    $type: 's_Get_TableData',
+    data: [cell]
+  }
+
+  if (setting.database === 'sso' && window.GLOB.mainSystemApi) {
+    param.rduri = window.GLOB.mainSystemApi
+  }
+
+  return param
+}
+
 export default class DataUtils {
   /**
    * @description 鏁版嵁婧愮粺涓�鏌ヨ
@@ -13,17 +141,23 @@
     let param = null
 
     if (setting.interType === 'system') {
-      param = this.getDefaultQueryParam(setting, search, orderBy, pageIndex, pageSize, id, BID, year)
+      if (window.backend && window.GLOB.CacheData.has('sql_' + setting.uuid)) {
+        param = getBackendQueryParam(setting, search, orderBy, pageIndex, pageSize, id, BID, year)
+      } else {
+        param = this.getDefaultQueryParam(setting, search, orderBy, pageIndex, pageSize, id, BID, year)
+        param.BID = BID || ''
+        param.dataM = sessionStorage.getItem('dataM') === 'true' ? 'Y' : ''
+      }
     } else {
       param = this.getCustomQueryParam(setting, search, orderBy, pageIndex, pageSize, id, year)
-    }
 
-    if (BID) {
-      param.BID = BID
-    }
-    // 鏁版嵁绠$悊鏉冮檺
-    if (sessionStorage.getItem('dataM') === 'true') {
-      param.dataM = 'Y'
+      if (BID) {
+        param.BID = BID
+      }
+      // 鏁版嵁绠$悊鏉冮檺
+      if (sessionStorage.getItem('dataM') === 'true') {
+        param.dataM = 'Y'
+      }
     }
 
     return param
@@ -142,9 +276,9 @@
       { reg: /@orderBy@/ig, value: orderBy },
       { reg: /@pageSize@/ig, value: setting.laypage ? pageSize : '9999' },
       { reg: /@pageIndex@/ig, value: pageIndex},
-      { reg: /@select\$|\$select@/ig, value: ''},
-      { reg: /\$sum@/ig, value: '/*'},
-      { reg: /@sum\$/ig, value: '*/'},
+      // { reg: /@select\$|\$select@/ig, value: ''},
+      // { reg: /\$sum@/ig, value: '/*'},
+      // { reg: /@sum\$/ig, value: '*/'},
       { reg: /@ID@/ig, value: `'${id || ''}'`},
       { reg: /@BID@/ig, value: `'${BID || ''}'`},
       { reg: /@LoginUID@/ig, value: `'${sessionStorage.getItem('LoginUID') || ''}'`},
@@ -156,10 +290,10 @@
     )
 
     if (setting.hasExtend) {
-      regoptions.push({ reg: /@mk_time@/ig, value: setting.extendTime })
+      regoptions.push({ reg: /@mk_time@/ig, value: `'${setting.extendTime}'` })
     }
     if (setting.$re_year) {
-      regoptions.push({ reg: /@mk_year@/ig, value: year })
+      regoptions.push({ reg: /@mk_year@/ig, value: `'${year}'` })
     }
 
     regoptions.forEach(item => {
@@ -280,9 +414,9 @@
 
     // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
     if (window.GLOB.debugger === true) {
-      _customScript && console.info(`${setting.$name ? `/*${setting.$name} 鑷畾涔夎剼鏈�*/\n` : ''}${LText ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${_customScript}`)
-      LText && console.info(`${setting.$name ? `/*${setting.$name} 鏁版嵁婧�*/\n` : ''}` + LText.replace(/\n\s{8}/ig, '\n'))
-      DateCount && console.info(`${setting.$name ? `/*${setting.$name} 鎬绘暟鏌ヨ*/\n` : ''}` + DateCount.replace(/\n\s{8}/ig, '\n'))
+      _customScript && window.mkInfo(`${setting.$name ? `/*${setting.$name} 鑷畾涔夎剼鏈�*/\n` : ''}${LText ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${_customScript}`)
+      LText && window.mkInfo(`${setting.$name ? `/*${setting.$name} 鏁版嵁婧�*/\n` : ''}` + LText.replace(/\n\s{8}/ig, '\n'))
+      DateCount && window.mkInfo(`${setting.$name ? `/*${setting.$name} 鎬绘暟鏌ヨ*/\n` : ''}` + DateCount.replace(/\n\s{8}/ig, '\n'))
     }
 
     if (setting.$name) {
@@ -375,9 +509,9 @@
       { reg: /@orderBy@/ig, value: orderBy },
       { reg: /@pageSize@/ig, value: 999999 },
       { reg: /@pageIndex@/ig, value: 1},
-      { reg: /\$select@/ig, value: '/*'},
-      { reg: /@select\$/ig, value: '*/'},
-      { reg: /@sum\$|\$sum@/ig, value: ''},
+      // { reg: /\$select@/ig, value: '/*'},
+      // { reg: /@select\$/ig, value: '*/'},
+      // { reg: /@sum\$|\$sum@/ig, value: ''},
       { reg: /@ID@/ig, value: `''`},
       { reg: /@BID@/ig, value: `'${BID || ''}'`},
       { reg: /@LoginUID@/ig, value: `'${sessionStorage.getItem('LoginUID') || ''}'`},
@@ -419,8 +553,8 @@
 
     // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
     if (window.GLOB.debugger === true) {
-      _customScript &&  console.info(`${setting.$name ? `/*${setting.$name} 鑷畾涔夎剼鏈� 缁熻鏌ヨ*/\n` : ''}${LText ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${_customScript}`)
-      LText &&  console.info(`${setting.$name ? `/*${setting.$name} 鏁版嵁婧� 缁熻鏌ヨ*/\n` : ''}` + LText.replace(/\n\s{8}/ig, '\n'))
+      _customScript && window.mkInfo(`${setting.$name ? `/*${setting.$name} 鑷畾涔夎剼鏈� 缁熻鏌ヨ*/\n` : ''}${LText ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${_customScript}`)
+      LText && window.mkInfo(`${setting.$name ? `/*${setting.$name} 鏁版嵁婧� 缁熻鏌ヨ*/\n` : ''}` + LText.replace(/\n\s{8}/ig, '\n'))
     }
 
     if (setting.$name) {
@@ -497,8 +631,17 @@
 /**
  * @description 鐢熸垚鍗曚釜缁勪欢sPC_Get_structured_data璇锋眰鍙傛暟
  */
-export function getStructDefaultParam (component, searchlist, first) {
+export function getStructDefaultParam (component, searchlist, first, BID) {
   const { columns, setting, dataName, format, uuid } = component
+
+  if (window.backend && window.GLOB.CacheData.has('sql_' + uuid)) {
+    if (first) {
+      let item = window.GLOB.CacheData.get('sql_' + uuid)
+      window.GLOB.CacheData.set('first_' + item.id, uuid)
+    }
+
+    return getBackendQueryParam(setting, searchlist, setting.order, 1, 1000, '', BID, '', dataName)
+  }
 
   let _dataresource = setting.dataresource
   let _customScript = setting.customScript
@@ -555,7 +698,7 @@
 
   return {
     uuid: uuid,
-    name: dataName,
+    dataName: dataName,
     $name: setting.$name,
     columns: columns,
     par_tablename: '',
@@ -572,6 +715,39 @@
  * @description 鐢熸垚sPC_Get_structured_data璇锋眰鍙傛暟
  */
 export function getStructuredParams (params, config, BID) {
+  if (window.backend && params[0].exps) {
+    let param = {
+      $backend: true,
+      $type: 's_Get_structured_data',
+      data: params.map(item => {
+        let cell = {...item}
+
+        delete cell.dataName
+        delete cell.luser
+
+        return cell
+      })
+    }
+
+    if (config.cacheUseful === 'true') {
+      param.time_limit = config.cacheTime
+
+      if (config.timeUnit === 'day') {
+        param.time_limit = param.time_limit * 1440
+      } else if (config.timeUnit === 'hour') {
+        param.time_limit = param.time_limit * 60
+      }
+
+      if (params.findIndex(item => item.luser) > -1) {
+        param.data_md5 = md5(window.GLOB.appkey + params[0].id + sessionStorage.getItem('UserID'))
+      } else {
+        param.data_md5 = md5(window.GLOB.appkey + params[0].id)
+      }
+    }
+
+    return param
+  }
+
   let LText_field = []
   let diffUser = false
 
@@ -606,14 +782,14 @@
 
     // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
     if (window.GLOB.debugger === true) {
-      _script && console.info(`${item.$name ? `/*${item.$name} 鑷畾涔夎剼鏈紙鍚屾鏌ヨ锛�*/\n` : ''}${_sql ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${_script}`)
-      _sql && console.info(`${item.$name ? `/*${item.$name} 鏁版嵁婧愶紙鍚屾鏌ヨ锛�*/\n` : ''}` + _sql)
+      _script && window.mkInfo(`${item.$name ? `/*${item.$name} 鑷畾涔夎剼鏈紙鍚屾鏌ヨ锛�*/\n` : ''}${_sql ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${_script}`)
+      _sql && window.mkInfo(`${item.$name ? `/*${item.$name} 鏁版嵁婧愶紙鍚屾鏌ヨ锛�*/\n` : ''}` + _sql)
     }
 
     item.columns.forEach(cell => {
-      LText_field.push(`Select '${item.name}' as tablename,'${cell.field}' as fieldname,'${cell.datatype}' as field_type`)
+      LText_field.push(`Select '${item.dataName}' as tablename,'${cell.field}' as fieldname,'${cell.datatype}' as field_type`)
     })
-    return `Select '${item.name}' as tablename,'${window.btoa(window.encodeURIComponent(_sql))}' as LText,'${window.btoa(window.encodeURIComponent(_script))}' as Lcustomize,'${item.type}' as table_type,'${item.primaryKey}' as primary_key,'${item.par_tablename}' as par_tablename,'${item.foreign_key}' as foreign_key,'${index}' as Sort`
+    return `Select '${item.dataName}' as tablename,'${window.btoa(window.encodeURIComponent(_sql))}' as LText,'${window.btoa(window.encodeURIComponent(_script))}' as Lcustomize,'${item.type}' as table_type,'${item.primaryKey}' as primary_key,'${item.par_tablename}' as par_tablename,'${item.foreign_key}' as foreign_key,'${index}' as Sort`
   })
 
   let param = {
diff --git a/src/utils/utils.js b/src/utils/utils.js
index 2b7f1d6..cc69ca5 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -71,6 +71,7 @@
       uuid.push(_options.substr(Math.floor(Math.random() * 0x20), 1))
     }
     uuid = timestamp + uuid.join('')
+    uuid = uuid.replace(/minke/ig, 'mnkie')
     return uuid
   }
 
@@ -416,7 +417,11 @@
           item.$first = true
         }
       }
-      
+
+      if (window.backend && ['select', 'link', 'multiselect', 'checkcard', 'radio'].includes(item.type) && item.resourceType === '1') {
+        item.uuid = md5(config.uuid + item.uuid)
+      }
+
       item.oriInitval = item.initval
 
       if (values) {
@@ -710,6 +715,157 @@
     })
 
     return searchText.join(' AND ')
+  }
+
+  static getSearchkeys (searches) {
+    let searchText = []
+    let matchs = {
+      'like': '01',
+      'not like': '02',
+      '=': '03',
+      '>': '04',
+      '<': '05',
+      '>=': '06',
+      '<=': '07',
+    }
+
+    searches.forEach(item => {
+      if (item.forbid || !item.value) return
+
+      let cell = {
+        key: item.key,
+        match: item.match,
+        type: 'text',
+        value: item.value
+      }
+      
+      if (item.type === 'text' || item.type === 'select') { // 缁煎悎鎼滅储锛屾枃鏈垨涓嬫媺锛屾墍鏈夊瓧娈垫嫾鎺�
+        if (/,/.test(item.key)) {
+          cell.type = 'text_or'
+        }
+      } else if (item.type === 'multi') {
+        cell.type = 'text_multi'
+      } else if (item.type === 'date') {
+        let _val = item.value
+        let timetail = ''
+
+        if (item.match === '<' || item.match === '<=') { // 鏃堕棿涓�<=鏃讹紝鍖归厤鍚庝竴澶╃殑0鐐癸紝鍖归厤鏂瑰紡涓�<
+          cell.match = '<'
+          if (item.precision === 'day') {
+            _val = moment(_val, 'YYYY-MM-DD').add(1, 'days').format('YYYY-MM-DD')
+          }
+        }
+        if (item.match === '=') {
+          timetail = ''
+        } else if (item.precision === 'day') {
+          timetail = ' 00:00:00.000'
+        } else if (item.precision === 'hour') {
+          timetail = ':00:00.000'
+        } else if (item.precision === 'minute') {
+          timetail = ':00.000'
+        } else if (item.precision === 'second') {
+          timetail = '.000'
+        }
+
+        cell.value = _val + timetail
+      }
+      
+      if (item.type === 'datemonth') { // 鏈�-杩囨护鏉′欢锛屼粠鏈堝紑濮嬭嚦缁撴潫锛岀粨鏉熸椂闂翠负鏈堟湯鍔犱竴澶╃殑0鐐癸紝鏂瑰紡涓�<
+        if (item.match === '=') {
+          searchText.push(cell)
+        } else {
+          let _startval = moment(item.value, 'YYYY-MM').startOf('month').format('YYYY-MM-DD') + ' 00:00:00.000'
+          let _endval = moment(item.value, 'YYYY-MM').endOf('month').add(1, 'days').format('YYYY-MM-DD') + ' 00:00:00.000'
+  
+          searchText.push({
+            key: item.key,
+            match: '>=',
+            type: 'text',
+            value: _startval
+          }, {
+            key: item.key,
+            match: '<',
+            type: 'text',
+            value: _endval
+          })
+        }
+      } else if (item.type === 'dateweek') { // 鍛�-杩囨护鏉′欢
+        let _startval = moment(item.value, 'YYYY-MM-DD' ).startOf('week').format('YYYY-MM-DD') + ' 00:00:00.000'
+        let _endval = moment(item.value, 'YYYY-MM-DD').endOf('week').add(1, 'days').format('YYYY-MM-DD') + ' 00:00:00.000'
+
+        searchText.push({
+          key: item.key,
+          match: '>=',
+          type: 'text',
+          value: _startval
+        }, {
+          key: item.key,
+          match: '<',
+          type: 'text',
+          value: _endval
+        })
+      } else if (item.type === 'daterange') {
+        let val = item.value.split(',')
+        let _startval = ''
+        let _endval = ''
+
+        if (item.precision === 'day') {
+          _startval = val[0] + ' 00:00:00.000'
+          _endval = moment(val[1], 'YYYY-MM-DD').add(1, 'days').format('YYYY-MM-DD') + ' 00:00:00.000'
+        } else if (item.precision === 'hour') {
+          _startval = val[0] + ':00:00.000'
+          _endval = val[1] + ':00:00.000'
+        } else if (item.precision === 'minute') {
+          _startval = val[0] + ':00.000'
+          _endval = val[1] + ':00.000'
+        } else if (item.precision === 'second') {
+          _startval = val[0] + '.000'
+          _endval = val[1] + '.000'
+        }
+
+        let _skey = item.key
+        let _ekey = item.key
+
+        if (/,/.test(item.key)) {
+          _skey = item.key.split(',')[0]
+          _ekey = item.key.split(',')[1]
+        }
+
+        searchText.push({
+          key: _skey,
+          match: '>=',
+          type: 'text',
+          value: _startval
+        }, {
+          key: _ekey,
+          match: '<',
+          type: 'text',
+          value: _endval
+        })
+      } else if (item.type === 'range') {
+        let val = item.value.split(',')
+
+        searchText.push({
+          key: item.key,
+          match: '>=',
+          type: 'text',
+          value: val[0] || -999999999
+        }, {
+          key: item.key,
+          match: '<=',
+          type: 'text',
+          value: val[1] || 999999999
+        })
+      } else {
+        searchText.push(cell)
+      }
+    })
+
+    searchText.forEach(item => {
+      item.match = matchs[item.match] || '01'
+    })
+
+    return searchText
   }
 
   /**
@@ -1340,8 +1496,8 @@
     sql = sql.replace(/\n\s{6}/ig, '\n')
 
     if (window.GLOB.debugger === true) {
-      console.info('%c' + item.logLabel, 'color: blue')
-      console.info(sql)
+      window.mkInfo('%c' + item.logLabel, 'color: blue')
+      window.mkInfo(sql)
     }
   } else {
     for(let i = 0; i < _Ltext.length; i += 20) {
@@ -1585,8 +1741,8 @@
     sql = sql.replace(/\n\s{6}/ig, '\n')
 
     if (window.GLOB.debugger === true) {
-      console.info('%c' + btn.logLabel, 'color: blue')
-      console.info(sql)
+      window.mkInfo('%c' + btn.logLabel, 'color: blue')
+      window.mkInfo(sql)
     }
   } else {
     for(let i = 0; i < _Ltext.length; i += 20) {
@@ -1615,7 +1771,7 @@
  * @return {Array}   columns   鏄剧ず鍒�
  * @return {Boolean} retmsg    鏄惁闇�瑕佹暟鎹繑鍥�
  */
-export function getSysDefaultSql (btn, setting, formdata, param, data, columns, retmsg = false, moduleParams) {
+export function getSysDefaultSql (btn, setting, formdata, param, data, columns, retmsg = false) {
   let primaryId = param.ID
   let BID = param.BID || ''
   let verify = btn.verify || {}
@@ -1864,9 +2020,31 @@
   }
 
   // 澶辨晥楠岃瘉锛屾坊鍔犳暟鎹椂涓嶇敤
-  if (verify.invalid === 'true' && moduleParams && moduleParams.dataresource) {
-    let datasource = moduleParams.dataresource
-    let customScript = moduleParams.customScript || ''
+  if (verify.invalid === 'true' && setting.dataresource) {
+    let datasource = setting.dataresource
+    let customScript = setting.customScript || ''
+
+    let regoptions = [{
+      reg: new RegExp('@userName@', 'ig'),
+      value: `'${sessionStorage.getItem('User_Name') || ''}'`
+    }, {
+      reg: new RegExp('@fullName@', 'ig'),
+      value: `'${sessionStorage.getItem('Full_Name') || ''}'`
+    }, {
+      reg: new RegExp('@orderBy@', 'ig'),
+      value: setting.order || primaryKey
+    }, {
+      reg: new RegExp('@pageSize@', 'ig'),
+      value: 1
+    }, {
+      reg: new RegExp('@pageIndex@', 'ig'),
+      value: 1
+    }]
+
+    regoptions.forEach(item => {
+      datasource = datasource.replace(item.reg, item.value)
+      customScript = customScript.replace(item.reg, item.value)
+    })
 
     if (customScript) {
       _sql += `
@@ -1941,7 +2119,6 @@
 
       if (!keys.includes(_key)) return // 琛ㄥ崟涓笉鍚崟鍙风敓鎴愬瓧娈�
 
-      let _ModularDetailCode = ''
       let _lpline = ''
       if (item.TypeCharOne === 'Lp') {
         if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
@@ -1949,33 +2126,29 @@
         } else {
           _lpline = `set @ModularDetailCode= 'Lp'+ right('${item.mark || btn.uuid}'+@${_linkKey},48)`
         }
-        _ModularDetailCode = '@ModularDetailCode'
       } else if (item.TypeCharOne === 'BN') {
-        let _val = ''
         if (_linkKey === 'bid' && BID) { // 鏇挎崲bid
-          _val = BID
-        } else if (_data.hasOwnProperty(_linkKey)) {
-          _val = _data[_linkKey]
+          _lpline = `set @ModularDetailCode= 'BN'+ right(@BID@,48)`
+        } else {
+          _lpline = `set @ModularDetailCode= 'BN'+ right(@${_linkKey},48)`
         }
-        _ModularDetailCode = `'${item.TypeCharOne + _val}'`
       } else {
-        _ModularDetailCode = `'${item.ModularDetailCode}'`
+        _lpline = `set @ModularDetailCode= right('${item.ModularDetailCode}',50)`
       }
 
-      let _declare = ''
+      // let _declare = ''
 
-      if (!_vars.includes(_key)) {
-        _declare = `Declare @${_key} nvarchar(50)`
-        _vars.push(_key)
-      }
+      // if (!_vars.includes(_key)) {
+      //   _declare = `Declare @${_key} nvarchar(50)`
+      //   _vars.push(_key)
+      // }
 
       _billcodesSql += `
       /* 鍗曞彿鐢熸垚 */
-      ${_declare}
       select @BillCode='', @${_key}='', @ModularDetailCode=''
       ${_lpline}
       exec s_get_BillCode
-        @ModularDetailCode=${_ModularDetailCode},
+        @ModularDetailCode=@ModularDetailCode,
         @Type=${item.Type},
         @TypeCharOne='${item.TypeCharOne}',
         @TypeCharTwo ='${item.TypeCharTwo}',
@@ -2014,11 +2187,6 @@
         _value.push(`${_labels[index] || ''}锛�${_val || ''}`)
       })
 
-      let _verifyType = ''
-      if (item.verifyType === 'logic') {
-        _verifyType = ' and deleted=0'
-      }
-
       if (!arr.includes(primaryKey.toLowerCase())) {
         _fieldValue.push(`${primaryKey} !='${primaryId}'`)
       }
@@ -2026,7 +2194,7 @@
       _sql += `
       /* 鍞竴鎬ч獙璇� */
       select @tbid='', @ErrorCode='',@retmsg=''
-      select @tbid='X' from ${btn.sql} where ${_fieldValue.join(' and ')}${_verifyType}
+      select @tbid='X' from ${btn.sql} where ${_fieldValue.join(' and ')}${item.verifyType === 'logic' ? ' and deleted=0' : ''}
       If @tbid!=''
       Begin
         select @ErrorCode='${item.errorCode}',@retmsg='${_value.join(', ')} 宸插瓨鍦�'
@@ -2233,7 +2401,7 @@
     if (data && columns && columns.length > 0 && btn.Ot !== 'notRequired') {
       let _index = 0
       columns.forEach(col => {
-        if (!col.field || col.Hide === 'true' || _index >= 4) return
+        if (!col.field || col.Hide === 'true' || _index >= 4 || col.field === primaryKey) return
         _msg += col.label + '=' + data[col.field] + ','
         _index++
       })
@@ -2627,14 +2795,17 @@
       _sql += _backCustomScript
     }
 
-    _sql = _sql.replace(/@works_flow_sign@/ig, `'${sign}'`)
+    if (verify.flowType === 'start') {
+      _sql = _sql.replace(/@start_type@/ig, `'寮�濮�'`)
+    } else {
+      _sql = _sql.replace(/@works_flow_sign@/ig, `'${sign}'`)
 
-    _sql = _sql.replace(/@check_userids@/ig, `'${checkIds.join(',')}'`)
-    _sql = _sql.replace(/@notice_userids@/ig, `'${noticeIds.join(',')}'`)
+      _sql = _sql.replace(/@check_type@/ig, verify.flowType === 'reject' ? `'椹冲洖'` : `'瀹℃牳'`)
+      _sql = _sql.replace(/@notice_type@/ig, `'鎶勯��'`)
 
-    _sql = _sql.replace(/@start_type@/ig, `'寮�濮�'`)
-    _sql = _sql.replace(/@check_type@/ig, verify.flowType === 'reject' ? `'椹冲洖'` : `'瀹℃牳'`)
-    _sql = _sql.replace(/@notice_type@/ig, `'鎶勯��'`)
+      _sql = _sql.replace(/@check_userids@/ig, `'${checkIds.join(',')}'`)
+      _sql = _sql.replace(/@notice_userids@/ig, `'${noticeIds.join(',')}'`)
+    }
 
     _sql = _sql.replace(/@works_flow_code@/ig, `'${flow.flow_code}'`)
     _sql = _sql.replace(/@works_flow_name@/ig, `'${flow.flow_name}'`)
@@ -2701,8 +2872,8 @@
   }
 
   if (window.GLOB.debugger === true) {
-    console.info('%c' + btn.logLabel, 'color: blue')
-    console.info(_sql)
+    window.mkInfo('%c' + btn.logLabel, 'color: blue')
+    window.mkInfo(_sql)
   }
 
   if (retmsg) {
@@ -2799,23 +2970,23 @@
 /**
  * @description 鐢熸垚鏇挎崲鍑芥暟鍒楄〃
  */
-export function setGLOBFuncs () {
-  window.GLOB.funcs = []
-  if (!window.GLOB.IndexDB) {
-    return
-  }
+// export function setGLOBFuncs () {
+//   window.GLOB.funcs = []
+//   if (!window.GLOB.IndexDB) {
+//     return
+//   }
 
-  let objectStore = window.GLOB.IndexDB.transaction('funcs').objectStore('funcs')
+//   let objectStore = window.GLOB.IndexDB.transaction('funcs').objectStore('funcs')
 
-  objectStore.openCursor().onsuccess = (event) => {
-    let cursor = event.target.result
+//   objectStore.openCursor().onsuccess = (event) => {
+//     let cursor = event.target.result
 
-    if (cursor) {
-      window.GLOB.funcs.push({
-        func_code: cursor.value.func_code,
-        key_sql: window.decodeURIComponent(window.atob(cursor.value.key_sql))
-      })
-      cursor.continue()
-    }
-  }
-}
\ No newline at end of file
+//     if (cursor) {
+//       window.GLOB.funcs.push({
+//         func_code: cursor.value.func_code,
+//         key_sql: window.decodeURIComponent(window.atob(cursor.value.key_sql))
+//       })
+//       cursor.continue()
+//     }
+//   }
+// }
\ No newline at end of file
diff --git a/src/views/appcheck/index.jsx b/src/views/appcheck/index.jsx
index 3154996..0351a5a 100644
--- a/src/views/appcheck/index.jsx
+++ b/src/views/appcheck/index.jsx
@@ -84,6 +84,10 @@
               }
               cell.copyright = _param.copyright || ''
               cell.logo = _param.logo || ''
+              cell.wxAppId = _param.wxAppId || ''
+              cell.wxAppName = _param.wxAppName || ''
+              cell.wxMerchId = _param.wxMerchId || ''
+              cell.wxMerchName = _param.wxMerchName || ''
             }
 
             return cell
@@ -193,6 +197,10 @@
                     </Col>
                     <Col span={12}>
                       <div className="app-item">
+                        {item.wxAppName || item.wxMerchName ? <>
+                          <div className="label">鍏宠仈搴旂敤:</div>
+                          <div className="content">{`${item.wxAppName}${item.wxAppName && item.wxMerchName ? ' / ' + item.wxMerchName : item.wxMerchName || ''}`}</div>
+                        </> : null}
                       </div>
                     </Col>
                     <Col span={12}>
@@ -238,7 +246,7 @@
                     </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>
+                    <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}${item.wxAppId ? '/' + item.wxAppId : ''}` }}></Paragraph>
                   </div>
                 </div>
               )
diff --git a/src/views/appmanage/index.jsx b/src/views/appmanage/index.jsx
index 21ccb4b..c352ad1 100644
--- a/src/views/appmanage/index.jsx
+++ b/src/views/appmanage/index.jsx
@@ -377,7 +377,7 @@
   }
 
   deleteTran = (record) => {
-    const _this = this
+    const that = this
 
     let param = {
       func: 's_sVersion_del',
@@ -395,7 +395,7 @@
                 message: '鎿嶄綔鎴愬姛锛�',
                 duration: 3
               })
-              _this.getTransList()
+              that.getTransList()
             } else {
               notification.warning({
                 top: 92,
@@ -414,7 +414,7 @@
   }
 
   enableTran = (record) => {
-    const _this = this
+    const that = this
 
     let param = {
       func: 's_sVersion_sub',
@@ -432,7 +432,7 @@
                 message: '鎿嶄綔鎴愬姛锛�',
                 duration: 3
               })
-              _this.getTransList()
+              that.getTransList()
             } else {
               Modal.error({
                 title: result.message,
@@ -485,6 +485,10 @@
               cell.share_des = _param.share_des || '' // 鍒嗕韩鎻忚堪
               cell.share_url = _param.share_url || '' // 鍒嗕韩鍥剧墖
               cell.share_link = _param.share_link || '' // 鍒嗕韩閾炬帴
+              cell.wxAppId = _param.wxAppId || ''
+              cell.wxAppName = _param.wxAppName || ''
+              cell.wxMerchId = _param.wxMerchId || ''
+              cell.wxMerchName = _param.wxMerchName || ''
 
               if (cell.adapter && (cell.adapter === 'true' || cell.adapter === 'false')) {
                 cell.adapter = ''
@@ -597,7 +601,7 @@
   }
 
   deleteApp = (record) => {
-    const _this = this
+    const that = this
 
     confirm({
       content: '纭畾鍒犻櫎銆�' + record.remark + '銆嬪悧锛�',
@@ -617,12 +621,12 @@
                 duration: 5
               })
 
-              _this.setState({
+              that.setState({
                 selectApp: null,
                 selectSubApp: null,
                 loading: true
               })
-              _this.getAppList()
+              that.getAppList()
             } else {
               if (result.message.indexOf('kei_no宸茶鑿滃崟浣跨敤锛屼笉鍙垹闄�') > -1) {
                 result.message = 'kei_no宸茶鑿滃崟浣跨敤锛屼笉鍙垹闄�'
@@ -645,7 +649,7 @@
   
   deleteSubApp = (record) => {
     const { selectApp } = this.state
-    const _this = this
+    const that = this
 
     let param = {
       func: 's_kei_addupt',
@@ -672,7 +676,11 @@
     })
 
     // 瀛愬簲鐢↖D銆乼ypename銆佸簲鐢↖D銆丆loudUserID銆乤ppkey銆乴ogin_types(鏄惁闇�瑕佺櫥褰曪紝宸插純鐢�)銆乴ink_type(鏄惁浣跨敤鐭繛鎺ワ紝宸插純鐢�)銆乺ole_type(鏄惁浣跨敤瑙掕壊绠$悊)銆乴ang銆乧ss(鐨偆)銆乼itle(鏍囬)銆乫avicon(鍥炬爣)銆乽ser_binding(鐢ㄦ埛缁戝畾)銆乻ms_id(鐭俊妯℃澘ID)銆佽嚜瀹氫箟
-    param.LText = sublist.map(item => `select '${item.ID}','${item.typename}','${selectApp.ID}','${sessionStorage.getItem('CloudUserID') || ''}','${window.GLOB.appkey || ''}','false','false','${item.role_type || 'true'}','${item.lang || 'zh-CN'}','${item.css || ''}','${item.title || ''}','${item.favicon || ''}','${item.user_binding || 'false'}','','${window.btoa(window.encodeURIComponent(JSON.stringify({userbind: item.userbind || '', instantMessage: item.instantMessage || '', apptype: item.apptype || '', delay: item.delay || 0, statusBarColor: item.statusBarColor || 'black', topHeight: item.topHeight || '', sysBgColor: item.sysBgColor || '#ffffff', direction: item.direction || 'vertical', adapter: item.adapter || '', share: item.share || '', share_des: item.share_des || '', share_url: item.share_url || '', share_link: item.share_link || ''})))}'`)
+    param.LText = sublist.map(item => {
+      let _par = this.getCusParam(item)
+
+      return `select '${item.ID}','${item.typename}','${selectApp.ID}','${sessionStorage.getItem('CloudUserID') || ''}','${window.GLOB.appkey || ''}','false','false','${item.role_type || 'true'}','${item.lang || 'zh-CN'}','${item.css || ''}','${item.title || ''}','${item.favicon || ''}','${item.user_binding || 'false'}','','${window.btoa(window.encodeURIComponent(JSON.stringify(_par)))}'`
+    })
     param.LText = param.LText.join(' union all ')
     param.LText = Utils.formatOptions(param.LText, 'x')
     
@@ -688,11 +696,11 @@
                 duration: 5
               })
       
-              _this.setState({
+              that.setState({
                 selectSubApp: null,
                 loading: true
               })
-              _this.getAppList()
+              that.getAppList()
             } else {
               notification.warning({
                 top: 92,
@@ -813,7 +821,7 @@
       }
     })
 
-    const _this = this
+    const that = this
 
     confirm({
       content: '纭畾瑕佹墽琛屽悧锛�',
@@ -849,10 +857,10 @@
                 message: '鎵ц鎴愬姛銆�',
                 duration: 3
               })
-              _this.setState({
+              that.setState({
                 scriptIndex: 1
               }, () => {
-                _this.getScriptList()
+                that.getScriptList()
               })
             }
             resolve()
@@ -948,7 +956,11 @@
           return item
         })
 
-        param.LText = selectApp.sublist.map(item => `select '${item.ID}','${item.typename}','${selectApp.ID}','${sessionStorage.getItem('CloudUserID') || ''}','${window.GLOB.appkey || ''}','false','false','${item.role_type || 'true'}','${item.lang || 'zh-CN'}','${item.css || ''}','${item.title || ''}','${item.favicon || ''}','${item.user_binding || 'false'}','','${window.btoa(window.encodeURIComponent(JSON.stringify({userbind: item.userbind || '', instantMessage: item.instantMessage || '', apptype: item.apptype || '', delay: item.delay || 0, statusBarColor: item.statusBarColor || 'black', topHeight: item.topHeight || '', sysBgColor: item.sysBgColor || '#ffffff', direction: item.direction || 'vertical', adapter: item.adapter || '', share: item.share || '', share_des: item.share_des || '', share_url: item.share_url || '', share_link: item.share_link || ''})))}'`)
+        param.LText = selectApp.sublist.map(item => {
+          let _par = this.getCusParam(item)
+    
+          return `select '${item.ID}','${item.typename}','${selectApp.ID}','${sessionStorage.getItem('CloudUserID') || ''}','${window.GLOB.appkey || ''}','false','false','${item.role_type || 'true'}','${item.lang || 'zh-CN'}','${item.css || ''}','${item.title || ''}','${item.favicon || ''}','${item.user_binding || 'false'}','','${window.btoa(window.encodeURIComponent(JSON.stringify(_par)))}'`
+        })
         param.LText = param.LText.join(' union all ')
         param.LText = Utils.formatOptions(param.LText, 'x')
       }
@@ -985,6 +997,56 @@
         })
       })
     })
+  }
+
+  getCusParam = (item) => {
+    let _par = {
+      sysBgColor: item.sysBgColor || '#ffffff'
+    }
+    if (item.userbind) {
+      _par.userbind = item.userbind
+    }
+    if (item.instantMessage) {
+      _par.instantMessage = item.instantMessage
+    }
+    if (item.apptype) {
+      _par.apptype = item.apptype
+    }
+    if (item.topHeight) {
+      _par.topHeight = item.topHeight
+    }
+    if (item.typename === 'pad') {
+      _par.direction = item.direction || 'vertical'
+    }
+    if (item.typename !== 'pc') {
+      _par.statusBarColor = item.statusBarColor || 'black'
+      _par.delay = item.delay || 0
+    }
+    if (item.adapter) {
+      _par.adapter = item.adapter
+    }
+    if (item.share) {
+      _par.share = item.share
+    }
+    if (item.share_des) {
+      _par.share_des = item.share_des
+    }
+    if (item.share_url) {
+      _par.share_url = item.share_url
+    }
+    if (item.share_link) {
+      _par.share_link = item.share_link
+    }
+    if (item.wxAppId) {
+      _par.wxAppId = item.wxAppId
+      _par.wxAppName = item.wxAppName || item.wxAppId
+    }
+    if (item.wxMerchId) {
+      _par.wxMerchId = item.wxMerchId
+      _par.wxMerchName = item.wxMerchName || item.wxMerchId
+    }
+
+    return _par
   }
 
   submitSubCard = () => {
@@ -1041,7 +1103,11 @@
         return item
       })
 
-      param.LText = sublist.map(item => `select '${item.ID}','${item.typename}','${selectApp.ID}','${sessionStorage.getItem('CloudUserID') || ''}','${window.GLOB.appkey || ''}','false','false','${item.role_type || 'true'}','${item.lang || 'zh-CN'}','${item.css || ''}','${item.title || ''}','${item.favicon || ''}','${item.user_binding || 'false'}','','${window.btoa(window.encodeURIComponent(JSON.stringify({userbind: item.userbind || '', instantMessage: item.instantMessage || '', apptype: item.apptype || '', delay: item.delay || 0, statusBarColor: item.statusBarColor || 'black', topHeight: item.topHeight || '', sysBgColor: item.sysBgColor || '#ffffff', direction: item.direction || 'vertical', adapter: item.adapter || '', share: item.share || '', share_des: item.share_des || '', share_url: item.share_url || '', share_link: item.share_link || ''})))}'`)
+      param.LText = sublist.map(item => {
+        let _par = this.getCusParam(item)
+
+        return `select '${item.ID}','${item.typename}','${selectApp.ID}','${sessionStorage.getItem('CloudUserID') || ''}','${window.GLOB.appkey || ''}','false','false','${item.role_type || 'true'}','${item.lang || 'zh-CN'}','${item.css || ''}','${item.title || ''}','${item.favicon || ''}','${item.user_binding || 'false'}','','${window.btoa(window.encodeURIComponent(JSON.stringify(_par)))}'`
+      })
       param.LText = param.LText.join(' union all ')
       param.LText = Utils.formatOptions(param.LText, 'x')
 
@@ -1188,8 +1254,10 @@
                     </Col>
                     <Col span={12}>
                       <div className="app-item">
-                        {/* <div className="label">鐨偆:</div>
-                        <div className="content" style={{color: color}}>{css}</div> */}
+                        {item.wxAppName || item.wxMerchName ? <>
+                          <div className="label">鍏宠仈搴旂敤:</div>
+                          <div className="content">{`${item.wxAppName}${item.wxAppName && item.wxMerchName ? ' / ' + item.wxMerchName : item.wxMerchName || ''}`}</div>
+                        </> : null}
                       </div>
                     </Col>
                     <Col span={12}>
@@ -1234,7 +1302,7 @@
                     <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>
+                    <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}${item.wxAppId ? '/' + item.wxAppId : ''}` }}></Paragraph>
                   </div>
                 </div>
               )
@@ -1285,7 +1353,7 @@
         </Modal>
         <Modal
           title={subVisible === 'plus' ? '娣诲姞瀛愬簲鐢�' : '缂栬緫瀛愬簲鐢�'}
-          width={'850px'}
+          width={'970px'}
           maskClosable={false}
           visible={subVisible !== false}
           onCancel={() => this.setState({subVisible: false, confirmloading: false})}
diff --git a/src/views/appmanage/submutilform/index.jsx b/src/views/appmanage/submutilform/index.jsx
index de2a0a2..369b47f 100644
--- a/src/views/appmanage/submutilform/index.jsx
+++ b/src/views/appmanage/submutilform/index.jsx
@@ -20,7 +20,9 @@
   state = {
     typename: 'mob',
     adapters: [],
-    exts: []
+    exts: [],
+    WXApps: null,
+    WXMerchs: null
   }
 
   UNSAFE_componentWillMount() {
@@ -37,6 +39,12 @@
       typename = card.typename || 'mob'
       adapters = card.adapter ? card.adapter.split(',') : []
 
+      if (!adapters.includes('fbdH5')) {
+        adapters.unshift('H5')
+      }
+
+      adapters = adapters.filter(n => n !== 'fbdH5')
+
       if (typename !== 'pc') {
         if (card.user_binding === 'true') {
           exts.push('user_binding')
@@ -45,9 +53,26 @@
           exts.push('share')
         }
       }
+    } else {
+      adapters = ['H5']
     }
 
-    this.setState({typename, adapters, exts, langs: _langs})
+    let WXApps = null
+    let WXMerchs = null
+    if (window.GLOB.WXApps) {
+      WXApps = window.GLOB.WXApps.filter(app => app.appType === 'public')
+
+      if (WXApps.length === 0) {
+        WXApps = null
+      }
+      WXMerchs = window.GLOB.WXApps.filter(app => app.appType === 'merchant')
+
+      if (WXMerchs.length === 0) {
+        WXMerchs = null
+      }
+    }
+
+    this.setState({typename, adapters, exts, langs: _langs, WXApps, WXMerchs})
   }
 
   /**
@@ -57,12 +82,26 @@
     return new Promise(resolve => {
       this.props.form.validateFieldsAndScroll((err, values) => {
         if (!err) {
+          if (values.adapter) {
+            if (!values.adapter.includes('H5')) {
+              values.adapter.unshift('fbdH5')
+            }
+          }
+
           values.adapter = values.adapter ? values.adapter.join(',') : ''
 
           if (values.exts) {
             values.user_binding = values.exts.includes('user_binding') ? 'true' : 'false'
             values.share = values.exts.includes('share') ? 'true' : 'false'
             delete values.exts
+          }
+          if (values.wxAppId) {
+            let app = window.GLOB.WXApps.filter(app => app.appType === 'public' && values.wxAppId === app.appId)[0]
+            values.wxAppName = app ? app.appName : values.wxAppId
+          }
+          if (values.wxMerchId) {
+            let app = window.GLOB.WXApps.filter(app => app.appType === 'merchant' && values.wxMerchId === app.appId)[0]
+            values.wxMerchName = app ? app.appName : values.wxMerchId
           }
 
           resolve(values)
@@ -89,7 +128,7 @@
   render() {
     const { card, type } = this.props
     const { getFieldDecorator } = this.props.form
-    const { typename, adapters, exts, langs } = this.state
+    const { typename, adapters, exts, langs, WXApps, WXMerchs } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -171,6 +210,7 @@
                 initialValue: adapters
               })(
                 <Checkbox.Group onChange={this.onAdapterChange}>
+                  <Checkbox value="H5">H5</Checkbox>
                   <Checkbox value="app">app</Checkbox>
                   <Checkbox value="weixin">鍏紬鍙�</Checkbox>
                   <Checkbox value="wxmini">灏忕▼搴�</Checkbox>
@@ -178,6 +218,38 @@
               )}
             </Form.Item>
           </Col> : null}
+          {WXApps ? <Col span={12}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="鐢ㄦ埛鍙�氳繃姝ゅ叕浼楀彿杩涜鏀粯銆侀��娆俱�佹巿鏉冪櫥褰曘��">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鍏宠仈搴旂敤
+              </Tooltip>
+            }>
+              {getFieldDecorator('wxAppId', {
+                initialValue: card ? card.wxAppId : ''
+              })(
+                <Select allowClear>
+                  {WXApps.map(item => <Select.Option key={item.appId} value={item.appId}>{item.appName}</Select.Option>)}
+                </Select>
+              )}
+            </Form.Item>
+          </Col> : null}
+          {WXMerchs ? <Col span={12}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="鐢ㄦ埛鍙�氳繃姝ゅ晢鎴峰彿杩涜鏀粯鍙婇��娆俱��">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鍏宠仈鍟嗘埛
+              </Tooltip>
+            }>
+              {getFieldDecorator('wxMerchId', {
+                initialValue: card ? card.wxMerchId : ''
+              })(
+                <Select allowClear>
+                  {WXMerchs.map(item => <Select.Option key={item.appId} value={item.appId}>{item.appName}</Select.Option>)}
+                </Select>
+              )}
+            </Form.Item>
+          </Col> : null}
           {typename !== 'pc' && (adapters.includes('weixin') || adapters.includes('wxmini')) ? <Col span={12}>
             <Form.Item label={
               <Tooltip placement="topLeft" title="鍦ㄥ叕浼楀彿鎴栧皬绋嬪簭涓紝鍙坊鍔犵粦瀹氱郴缁熺敤鎴枫�佽嚜瀹氫箟鍒嗕韩绛夊姛鑳斤紝鑷畾涔夊垎浜缃悗锛屽綋鍓嶅瓙搴旂敤灏嗛粯璁や娇鐢ㄦ鍒嗕韩閾炬帴銆�">
diff --git a/src/views/appmanage/transmenu/index.jsx b/src/views/appmanage/transmenu/index.jsx
index 101ddeb..52f0433 100644
--- a/src/views/appmanage/transmenu/index.jsx
+++ b/src/views/appmanage/transmenu/index.jsx
@@ -313,6 +313,8 @@
         }
       }
 
+      delete config.tbkey
+      
       config.uuid = values.slice(0, 24) + tail
       config.MenuID = config.uuid
       config.open_edition = ''
diff --git a/src/views/basedesign/updateFormTab/index.jsx b/src/views/basedesign/updateFormTab/index.jsx
index d17db4b..a70d45b 100644
--- a/src/views/basedesign/updateFormTab/index.jsx
+++ b/src/views/basedesign/updateFormTab/index.jsx
@@ -28,7 +28,7 @@
 
   trigger = () => {
     const { config, menu, btnTab } = this.props
-    const _this = this
+    const that = this
 
     if (!config || !menu || !menu.LongParam) {
       notification.warning({
@@ -78,7 +78,7 @@
       content: '',
       onOk() {
         return new Promise(resolve => {
-          _this.execUpdate(resolve, _config)
+          that.execUpdate(resolve, _config)
         })
       },
       onCancel() {}
diff --git a/src/views/billprint/index.jsx b/src/views/billprint/index.jsx
index 9346380..25fbfea 100644
--- a/src/views/billprint/index.jsx
+++ b/src/views/billprint/index.jsx
@@ -2,6 +2,7 @@
 import { is, fromJS } from 'immutable'
 import { Col, Row, Spin, notification, Button, Modal } from 'antd'
 import moment from 'moment'
+import md5 from 'md5'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
@@ -65,6 +66,7 @@
         let param = JSON.parse(window.decodeURIComponent(window.atob(params.param)))
   
         sessionStorage.setItem('dataM', param.dataM || '')
+
         this.setState({
           BID: param.id || '',
           tempId: param.tempId,
@@ -90,7 +92,7 @@
   }
 
   componentDidMount() {
-    const _this = this
+    const that = this
 
     if (window.GLOB.sysType !== 'cloud') {
       Object.defineProperty(window, 'debugger', {
@@ -118,7 +120,7 @@
             window.GLOB.breakpoint = value + ''
             sessionStorage.setItem('breakpoint', value)
           }
-          _this.debugChange()
+          that.debugChange()
         }
       })
     }
@@ -144,7 +146,7 @@
         window.GLOB.breakpoint = false
         sessionStorage.removeItem('breakpoint')
         
-        _this.debugChange()
+        that.debugChange()
       }
     }
   }
@@ -302,6 +304,22 @@
         let _pars = []
 
         config.components = config.components.filter(item => !['tabs', 'search'].includes(item.type))
+
+        if (window.backend && config.allSqls) {
+          let urlparam = urlParam || {}
+          let keys = Object.keys(urlparam)
+          config.allSqls.forEach(item => {
+            item.id = md5(window.GLOB.appkey + item.v_id)
+            if (item.type === 'datasource' || item.type === 'excelOut') {
+              item.urlkeys = keys
+              item.urlparam = urlparam
+              if (config.flow_code) {
+                item.works_flow_code = config.flow_code
+              }
+            }
+            window.GLOB.CacheData.set('sql_' + item.uuid, item)
+          })
+        }
 
         let userName = sessionStorage.getItem('User_Name') || ''
         let fullName = sessionStorage.getItem('Full_Name') || ''
@@ -487,6 +505,8 @@
             component.setting.sync = 'false'
             return component
           }
+
+          component.setting.uuid = component.uuid
     
           let _customScript = ''
           let _tailScript = ''
@@ -532,11 +552,17 @@
     
           component.setting.customScript = _customScript // 鏁寸悊鍚庤嚜瀹氫箟鑴氭湰
           component.setting.tailScript = _tailScript     // 鍚庣疆鑷畾涔夎剼鏈�
+
+          if (window.backend && config.allSqls) {
+            component.setting.sync = 'false'
+          } else if (_tailScript) {
+            component.setting.sync = 'false'
+          }
+          component.dataName = 'mk' + component.uuid.slice(-18)
     
           // floor    缁勪欢鐨勫眰绾�
           // pageable 鏄惁鍒嗛〉锛岀粍浠跺睘鎬э紝涓嶅垎椤电殑缁勪欢鎵嶅彲浠ョ粺涓�鏌ヨ
           if (component.setting.sync === 'true') {
-            component.dataName = 'mk' + component.uuid.slice(-18)
             let param = this.getDefaultParam(component)
             _pars.push(param)
           } else if (component.subtype !== 'dualdatacard') {
@@ -554,8 +580,29 @@
         _pars = this.getFormatParam(_pars, config.MenuName)
 
         if (_pars) {
-          _pars.componentId = 'union'
+          _pars.componentId = ''
           params.unshift(_pars)
+        } else if (window.backend && config.allSqls && params.length > 0) {
+          let data = []
+          params = params.filter(item => {
+            if (!item.$backend || item.public) return true
+
+            item.data[0].exps.forEach(cell => {
+              if (cell.key === 'mk_obj_name') {
+                cell.value = 'mk' + item.componentId.slice(-18)
+              }
+            })
+            data.push(item.data[0])
+            return false
+          })
+          if (data.length > 0) {
+            params.push({
+              $backend: true,
+              $type: 's_Get_TableData',
+              componentId: '',
+              data
+            })
+          }
         }
 
         if (config.everyPCount && !config.printPage) { // 鍏煎
@@ -682,6 +729,8 @@
         }
         return
       }
+
+      inter.setting.uuid = inter.uuid
 
       let _customScript = ''
       let _tailScript = ''
@@ -838,8 +887,8 @@
 
       // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
       if (window.GLOB.debugger === true) {
-        _script && console.info(`${_sql ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${_script}`)
-        _sql &&  console.info(_sql)
+        _script && window.mkInfo(`${_sql ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${_script}`)
+        _sql && window.mkInfo(_sql)
       }
 
       item.columns.forEach(cell => {
@@ -876,11 +925,13 @@
       return new Promise(resolve => {
         Api.genericInterface(item).then(res => {
           if (!res.status) {
-            notification.warning({
-              top: 92,
-              message: res.message,
-              duration: 5
-            })
+            if (res.ErrCode !== '-2') {
+              notification.warning({
+                top: 92,
+                message: res.message,
+                duration: 5
+              })
+            }
             resolve()
           } else {
             let _data = { $$empty: true }
@@ -911,7 +962,6 @@
 
     let deffers = params.map(item => {
       let componentId = item.componentId
-      let ispublic = item.public
       delete item.componentId
       delete item.public
       return new Promise(resolve => {
@@ -922,7 +972,7 @@
             }
             if (res.ErrCode === 'version_up') {
               this.reloadTabs()
-            } else {
+            } else if (res.ErrCode !== '-2') {
               notification.warning({
                 top: 92,
                 message: res.message,
@@ -933,13 +983,12 @@
           } else {
             res.componentId = componentId
 
-            if (ispublic) {
-              let _data = { $$empty: true }
-              if (res.data && res.data[0]) {
-                _data = res.data[0]
-              }
-              window.GLOB.CacheData.set(componentId, _data)
+            let _data = { $$empty: true }
+            if (res.data && res.data[0]) {
+              _data = res.data[0]
             }
+            window.GLOB.CacheData.set(componentId, _data)
+
             resolve(res)
           }
         })
@@ -962,7 +1011,7 @@
         _results.forEach(res => {
           if ((res.componentId === item.uuid || res.componentId === item.componentId) && res.data) {
             item.dataArray = fromJS(res.data).toJS()
-          } else if (res.componentId === 'union' && res[item.dataName]) {
+          } else if (res[item.dataName]) {
             let data = res[item.dataName]
             if (!Array.isArray(data)) {
               data = [data]
@@ -994,63 +1043,79 @@
         }
       }
 
-      while (!over) {
-        let page = []
-        let count = 0
-        let _pageover = false
-
-        comps.forEach(comp => {
-          let item = fromJS(comp).toJS()
-
-          if (item.wrap.printType === 'headerOrfooter') { // 椤电湁椤佃剼
-            item.data = item.dataArray || null
-            setData(item)
-            page.push(item)
-            comp.added = true
-          }
-
-          if (_pageover) return
-
-          if (item.$page && comp.dataArray.length > 0) {
-            item.data = []
-
-            while (count + 1 <= limit && comp.dataArray.length > 0) {
-              item.data.push(comp.dataArray.shift())
-              count++
-            }
-
-            if (count >= limit || comp.dataArray.length > 0) {
-              _pageover = true
-            }
-
-            if (comp.dataArray.length === 0) {
+      if (this.state.config.printPage === 'custom' && this.state.config.printScripts) {
+        try {
+          // eslint-disable-next-line
+          let func = new Function('components', 'pages', 'notification', this.state.config.printScripts)
+          func(comps, pages, notification)
+        } catch (e) {
+          console.warn(e)
+    
+          notification.warning({
+            top: 92,
+            message: '鑷畾涔夎剼鏈墽琛岄敊璇紒',
+            duration: 5
+          })
+        }
+      } else {
+        while (!over) {
+          let page = []
+          let count = 0
+          let _pageover = false
+  
+          comps.forEach(comp => {
+            let item = fromJS(comp).toJS()
+  
+            if (item.wrap.printType === 'headerOrfooter') { // 椤电湁椤佃剼
+              item.data = item.dataArray || null
+              setData(item)
+              page.push(item)
               comp.added = true
             }
-
-            setData(item)
-            page.push(item)
-          } else if (!comp.added) {
-            if (item.wrap.printHeight) {
-              count += item.wrap.printHeight
-              if (count >= limit) {
-                _pageover = true
-                return
+  
+            if (_pageover) return
+  
+            if (item.$page && comp.dataArray.length > 0) {
+              item.data = []
+  
+              while (count + 1 <= limit && comp.dataArray.length > 0) {
+                item.data.push(comp.dataArray.shift())
+                count++
               }
+  
+              if (count >= limit || comp.dataArray.length > 0) {
+                _pageover = true
+              }
+  
+              if (comp.dataArray.length === 0) {
+                comp.added = true
+              }
+  
+              setData(item)
+              page.push(item)
+            } else if (!comp.added) {
+              if (item.wrap.printHeight) {
+                count += item.wrap.printHeight
+                if (count >= limit) {
+                  _pageover = true
+                  return
+                }
+              }
+  
+              item.data = item.dataArray || null
+  
+              setData(item)
+              page.push(item)
+              comp.added = true
             }
-
-            item.data = item.dataArray || null
-
-            setData(item)
-            page.push(item)
-            comp.added = true
+          })
+  
+          pages.push(page)
+          pageIndex++
+  
+          if (pageIndex >= 2000 || comps.findIndex(comp => !comp.added) === -1) {
+            over = true
           }
-        })
-
-        pages.push(page)
-        pageIndex++
-
-        if (pageIndex >= 2000 || comps.findIndex(comp => !comp.added) === -1) {
-          over = true
         }
       }
 
@@ -1091,6 +1156,14 @@
   reloadTabs = () => {
     if (this.reloading) return
 
+    let time = new Date().getTime()
+
+    let oldTime = sessionStorage.getItem('mk_reloadTabs')
+    
+    if (oldTime && time - oldTime < 180000) return
+
+    sessionStorage.setItem('mk_reloadTabs', time)
+
     this.reloading = true
 
     Api.getAppVersion(true).then(() => {
diff --git a/src/views/billprint/index.scss b/src/views/billprint/index.scss
index 3ad6384..9616d80 100644
--- a/src/views/billprint/index.scss
+++ b/src/views/billprint/index.scss
@@ -57,6 +57,9 @@
       display: none!important;
     }
   }
+  .braft-content p {
+    margin: 0px!important;
+  }
   .ant-table-thead > tr > th {
     color: rgba(0,0,0,1);
     background: transparent!important;
diff --git a/src/views/design/header/editfirstmenu/index.jsx b/src/views/design/header/editfirstmenu/index.jsx
index 4d1b286..add92a2 100644
--- a/src/views/design/header/editfirstmenu/index.jsx
+++ b/src/views/design/header/editfirstmenu/index.jsx
@@ -92,7 +92,7 @@
       return
     }
     
-    let _this = this
+    let that = this
     confirm({
       title: `纭畾鍒犻櫎鑿滃崟銆�${item.MenuName}銆嬪悧锛焋,
       content: '',
@@ -103,7 +103,7 @@
         }
         return Api.getCloudConfig(param).then(res => {
           if (res.status) {
-            _this.props.reload()
+            that.props.reload()
           } else {
             notification.warning({
               top: 92,
diff --git a/src/views/design/header/index.jsx b/src/views/design/header/index.jsx
index e509575..20ba503 100644
--- a/src/views/design/header/index.jsx
+++ b/src/views/design/header/index.jsx
@@ -33,13 +33,13 @@
 
   logout = () => {
     // 閫�鍑虹櫥褰�
-    let _this = this
+    let that = this
     confirm({
       title: '鎮ㄧ‘瀹氳閫�鍑哄悧?',
       content: '',
       onOk() {
         sessionStorage.clear()
-        _this.props.history.replace('/login')
+        that.props.history.replace('/login')
         window.location.reload()
       },
       onCancel() {}
@@ -158,6 +158,9 @@
               } catch (e) {
                 trdItem.PageParam = {OpenType: 'newtab'}
               }
+              if (trdItem.PageParam.Template === 'RolePermission' || trdItem.PageParam.Template === 'NewPage') {
+                trdItem.PageParam.backend = 'level1'
+              }
 
               if (trdItem.type === 'CustomPage' && window.GLOB.memberLevel < 20) { // 浼氬憳绛夌骇澶т簬绛変簬20鏃讹紝鏈夌紪杈戞潈闄�
                 trdItem.forbidden = true
@@ -233,69 +236,69 @@
     }, () => {})
   }
 
-  setSystemFuncs = () => {
-    if (!window.GLOB.IndexDB) {
-      return
-    }
-    this.getfuncTime().then(res => {
-      Api.getSystemFuncs(res.createDate).then(result => {
-        if (!result.status) {
-          notification.error({
-            top: 92,
-            message: result.message,
-            duration: 10
-          })
-        } else if (result.func_detail && result.func_detail.length > 0) {
-          this.writeFuncs(result.func_detail)
-        }
-      })
-    })
-  }
+  // setSystemFuncs = () => {
+  //   if (!window.GLOB.IndexDB) {
+  //     return
+  //   }
+  //   this.getfuncTime().then(res => {
+  //     Api.getSystemFuncs(res.createDate).then(result => {
+  //       if (!result.status) {
+  //         notification.error({
+  //           top: 92,
+  //           message: result.message,
+  //           duration: 10
+  //         })
+  //       } else if (result.func_detail && result.func_detail.length > 0) {
+  //         this.writeFuncs(result.func_detail)
+  //       }
+  //     })
+  //   })
+  // }
 
-  writeFuncs = (funcs) => {
-    let shim = +sessionStorage.getItem('sys_time_shim')
-    let timestamp = moment().add(shim, 'seconds').format('YYYY-MM-DD HH:mm:ss')
+  // writeFuncs = (funcs) => {
+  //   let shim = +sessionStorage.getItem('sys_time_shim')
+  //   let timestamp = moment().add(shim, 'seconds').format('YYYY-MM-DD HH:mm:ss')
 
-    let objectStore = window.GLOB.IndexDB.transaction(['funcs'], 'readwrite').objectStore('funcs')
+  //   let objectStore = window.GLOB.IndexDB.transaction(['funcs'], 'readwrite').objectStore('funcs')
 
-    objectStore.clear()
+  //   objectStore.clear()
 
-    funcs.forEach(item => {
-      if (!item.key_sql) return
-      item.id = item.func_code
-      objectStore.add(item)
-    })
+  //   funcs.forEach(item => {
+  //     if (!item.key_sql) return
+  //     item.id = item.func_code
+  //     objectStore.add(item)
+  //   })
 
-    let funcStore = window.GLOB.IndexDB.transaction(['version'], 'readwrite').objectStore('version')
-    funcStore.put({id: 'funcs', version: '1.0', createDate: timestamp})
-  }
+  //   let funcStore = window.GLOB.IndexDB.transaction(['version'], 'readwrite').objectStore('version')
+  //   funcStore.put({id: 'funcs', version: '1.0', createDate: timestamp})
+  // }
 
-  getfuncTime = () => {
-    return new Promise((resolve, reject) => {
-      let objectStore = window.GLOB.IndexDB.transaction(['version'], 'readwrite').objectStore('version')
-      let request = objectStore.get('funcs')
+  // getfuncTime = () => {
+  //   return new Promise((resolve, reject) => {
+  //     let objectStore = window.GLOB.IndexDB.transaction(['version'], 'readwrite').objectStore('version')
+  //     let request = objectStore.get('funcs')
 
-      request.onerror = (event) => {
-        console.warn(event)
-        reject()
-      }
+  //     request.onerror = (event) => {
+  //       console.warn(event)
+  //       reject()
+  //     }
 
-      request.onsuccess = () => {
-        if (request.result) {
-          resolve(request.result)
-        } else {
-          let add = objectStore.add({id: 'funcs', version: '1.0', createDate: '1970-01-01 14:59:09.000'})
+  //     request.onsuccess = () => {
+  //       if (request.result) {
+  //         resolve(request.result)
+  //       } else {
+  //         let add = objectStore.add({id: 'funcs', version: '1.0', createDate: '1970-01-01 14:59:09.000'})
   
-          add.onerror = () => {
-            reject()
-          }
-          add.onsuccess = () => {
-            resolve({id: 'funcs', version: '1.0', createDate: '1970-01-01 14:59:09.000'})
-          }
-        }
-      }
-    })
-  }
+  //         add.onerror = () => {
+  //           reject()
+  //         }
+  //         add.onsuccess = () => {
+  //           resolve({id: 'funcs', version: '1.0', createDate: '1970-01-01 14:59:09.000'})
+  //         }
+  //       }
+  //     }
+  //   })
+  // }
 
   getSmStemp = () => {
     if (!sessionStorage.getItem('msgTemplate')) {
@@ -344,10 +347,6 @@
     window.addEventListener('storage', (e) => {
       if (e.key === 'menuUpdate') {
         this.reload()
-      } else if (e.key === 'wxTemplates') {
-        if (e.newValue) {
-          sessionStorage.setItem('wxTemplates', e.newValue)
-        }
       }
     })
     MKEmitter.addListener('mkUpdateMenuList', this.reload)
@@ -385,7 +384,6 @@
       }, 100)
 
       setTimeout(() => {
-        // positecgroup
         // this.setSystemFuncs()
         this.getSmStemp()
       }, 500)
diff --git a/src/views/design/header/transmenu/index.jsx b/src/views/design/header/transmenu/index.jsx
index 4a278f6..805f411 100644
--- a/src/views/design/header/transmenu/index.jsx
+++ b/src/views/design/header/transmenu/index.jsx
@@ -422,6 +422,8 @@
         config.style = config.style || {}
       }
 
+      delete config.tbkey
+
       config.enabled = false
       config.MenuName = menu.label
       config.fstMenuId = menu.fstMenuId || ''
@@ -677,6 +679,8 @@
         config.style = config.style || {}
       }
 
+      delete config.tbkey
+      
       config.enabled = false
       config.MenuNo = temp.PrintTempNO || ''
       config.MenuName = temp.PrintTempName || ''
diff --git a/src/views/design/index.jsx b/src/views/design/index.jsx
index f965c69..080b267 100644
--- a/src/views/design/index.jsx
+++ b/src/views/design/index.jsx
@@ -6,7 +6,7 @@
 
 import Header from './header'
 import Sidemenu from './sidemenu'
-import { setGLOBFuncs } from '@/utils/utils.js'
+// import { setGLOBFuncs } from '@/utils/utils.js'
 
 import '@/assets/css/design.scss'
 import './index.scss'
@@ -34,7 +34,7 @@
       window.GLOB.breakpoint = false
       window.GLOB.designView = true
       sessionStorage.removeItem('breakpoint')
-      setGLOBFuncs()
+      // setGLOBFuncs()
     }
   }
 
diff --git a/src/views/design/sidemenu/index.jsx b/src/views/design/sidemenu/index.jsx
index 7f9b43f..c8a061f 100644
--- a/src/views/design/sidemenu/index.jsx
+++ b/src/views/design/sidemenu/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import { is, fromJS } from 'immutable'
 import { Menu, Popover, Modal, notification } from 'antd'
-import { EditOutlined, PlusOutlined, SettingOutlined, ApiOutlined } from '@ant-design/icons'
+import { EditOutlined, PlusOutlined, SettingOutlined, ApiOutlined, SoundOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import asyncComponent from '@/utils/asyncComponent'
@@ -326,7 +326,7 @@
                 {item.children.map(cell => {
                   return (
                     <Menu.Item key={cell.MenuID}>
-                      <span className={'editable-menu-item ' + (cell.up_action ? 'unupdate' : '')} onDoubleClick={() => this.editmenu(cell)}>{cell.PageParam && cell.PageParam.interfaces === 'true' ? <ApiOutlined title="鑿滃崟涓娇鐢ㄤ簡澶栭儴鎺ュ彛" /> : null}{cell.MenuName}</span>
+                      <span className={'editable-menu-item ' + (cell.up_action ? 'unupdate' : '') + (window.backend && window.GLOB.systemType !== 'production' && cell.PageParam.backend !== 'level1' ? ' unbackend' : '')} onDoubleClick={() => this.editmenu(cell)}>{cell.PageParam.interfaces === 'true' ? <ApiOutlined title="鑿滃崟涓娇鐢ㄤ簡澶栭儴鎺ュ彛" /> : null}{cell.PageParam.msg === 'true' ? <SoundOutlined title="鑿滃崟涓彂閫佷簡娑堟伅" /> : null}{cell.MenuName}</span>
                     </Menu.Item>
                   )
                 })}
diff --git a/src/views/design/sidemenu/index.scss b/src/views/design/sidemenu/index.scss
index 3521e56..8c978da 100644
--- a/src/views/design/sidemenu/index.scss
+++ b/src/views/design/sidemenu/index.scss
@@ -23,11 +23,31 @@
         top: 11px;
         color: orange;
       }
+      .anticon-sound {
+        position: absolute;
+        left: 25px;
+        top: 11px;
+        color: orange;
+      }
+      .anticon-api + .anticon-sound {
+        left: 5px;
+      }
     }
 
     .editable-menu-item.unupdate {
       color: orange;
     }
+    .editable-menu-item.unbackend::before {
+      content: '';
+      display: block;
+      position: absolute;
+      width: 4px;
+      height: 4px;
+      background-color: orange;
+      border-radius: 4px;
+      top: 10px;
+      left: 42px;
+    }
   }
   .ant-menu-sub.ant-menu-inline {
     position: relative;
diff --git a/src/views/design/sidemenu/thdmenuplus/index.jsx b/src/views/design/sidemenu/thdmenuplus/index.jsx
index a159c98..e657796 100644
--- a/src/views/design/sidemenu/thdmenuplus/index.jsx
+++ b/src/views/design/sidemenu/thdmenuplus/index.jsx
@@ -246,6 +246,8 @@
 
           config.components = MenuUtils.resetConfig(config.components, commonId)
           config.enabled = false
+          
+          delete config.tbkey
 
           param.LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(config)))
         }
diff --git a/src/views/interface/history/index.jsx b/src/views/interface/history/index.jsx
index 2b3bdb6..4d313e6 100644
--- a/src/views/interface/history/index.jsx
+++ b/src/views/interface/history/index.jsx
@@ -43,13 +43,13 @@
   }
 
   clear = () => {
-    const _this = this
+    const that = this
     confirm({
       content: 'Are you sure you want to clear all your history requests?',
       onOk() {
         Api.clearInterfaces()
 
-        _this.setState({list: [], historys: []})
+        that.setState({list: [], historys: []})
       },
       onCancel() {}
     })
diff --git a/src/views/interface/index.jsx b/src/views/interface/index.jsx
index 3d88456..f13789e 100644
--- a/src/views/interface/index.jsx
+++ b/src/views/interface/index.jsx
@@ -1,4 +1,5 @@
-import React, {Component} from 'react'
+import React, { Component } from 'react'
+import { withRouter } from 'react-router'
 
 import Header from './header'
 import History from './history'
@@ -7,7 +8,16 @@
 import './index.scss'
 
 class Interface extends Component {
+  componentDidMount () {
+    if (!sessionStorage.getItem('UserID') || /^visitor/.test(sessionStorage.getItem('UserID'))) {
+      this.props.history.replace('/login')
+      return
+    }
+  }
   render () {
+    if (!sessionStorage.getItem('UserID') || /^visitor/.test(sessionStorage.getItem('UserID'))) {
+      return null
+    }
     return (
       <div className="interface-view">
         <Header key="header"/>
@@ -18,4 +28,4 @@
   }
 }
 
-export default Interface
\ No newline at end of file
+export default withRouter(Interface)
\ No newline at end of file
diff --git a/src/views/interface/workspace/request/index.jsx b/src/views/interface/workspace/request/index.jsx
index 33f2c1e..a73885e 100644
--- a/src/views/interface/workspace/request/index.jsx
+++ b/src/views/interface/workspace/request/index.jsx
@@ -226,6 +226,9 @@
     param.sign = md5(values)
     param.t = param.t || new Date().getTime()
 
+    window.mkInfo(values)
+    window.mkInfo(param.sign)
+
     return param
   }
 
diff --git a/src/views/login/loginform.jsx b/src/views/login/loginform.jsx
index 4f4d150..0a245cf 100644
--- a/src/views/login/loginform.jsx
+++ b/src/views/login/loginform.jsx
@@ -39,6 +39,7 @@
     verdisabled: false,
     hasScan: false,
     timeout: false,
+    vispwd: window.GLOB.vispwd,
     wayLabels: {},
     dict: window.GLOB.dict,
     users: [],
@@ -102,14 +103,14 @@
       users = []
     }
 
-    if (users[0]) {
+    if (users[0] && activeKey === 'uname_pwd') {
       _user = users[0]
     }
 
     this.setState({
       users: users,
-      username: activeKey === 'uname_pwd' && _user ? _user.username : '',
-      password: activeKey === 'uname_pwd' && _user ? _user.password : '',
+      username: _user ? _user.username : '',
+      password: _user ? _user.password : '',
       smsId: smsId,
       loginWays: _loginWays,
       activeKey,
@@ -441,7 +442,7 @@
   render() {
     const { langList } = this.props
     const { getFieldDecorator } = this.props.form
-    const { activeKey, verdisabled, delay, loginWays, remember, scanId, timeout, hasScan, users, wayLabels, dict, lang } = this.state
+    const { activeKey, verdisabled, delay, loginWays, remember, scanId, timeout, hasScan, users, wayLabels, dict, lang, vispwd } = this.state
 
     return (
       <Form className="login-form" id="login-form" onSubmit={this.handleSubmit}>
@@ -482,7 +483,7 @@
                   message: dict['password_required'] || '璇疯緭鍏ュ瘑鐮�',
                 }
               ]
-            })(<Input.Password placeholder={dict['password'] || '瀵嗙爜'} prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />} />)}
+            })(<Input.Password placeholder={dict['password'] || '瀵嗙爜'} visibilityToggle={vispwd} prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />} />)}
           </Form.Item>
           {window.GLOB.keepKey ? <Form.Item className="minline">
             {getFieldDecorator('remember', {
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index f453d28..4b91a51 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -10,10 +10,10 @@
 import md5 from 'md5'
 
 import Api from '@/api'
-import Utils, { setGLOBFuncs } from '@/utils/utils.js'
+import Utils from '@/utils/utils.js'
 import { langs } from '@/store/options'
 import MKEmitter from '@/utils/events.js'
-import { getTables, getFuncsAndInters, getLangTrans } from '@/utils/utils-custom.js'
+import { getTables, getFuncsAndInters, getOutMessage, getLangTrans, getAllSqls } from '@/utils/utils-custom.js'
 import asyncComponent from '@/utils/asyncComponent'
 
 import '@/assets/css/design.scss'
@@ -98,7 +98,7 @@
 
       sessionStorage.setItem('MenuType', param.MenuType || 'custom')
 
-      if (param.MenuType === 'billPrint' && param.lang) {
+      if (param.lang) {
         sessionStorage.setItem('lang', param.lang)
       }
 
@@ -133,7 +133,7 @@
     MKEmitter.addListener('changeEditMenu', this.changeEditMenu)
     setTimeout(() => {
       this.getRoleFields()
-      setGLOBFuncs()
+      // setGLOBFuncs()
     }, 1000)
 
     document.onkeydown = (event) => {
@@ -780,6 +780,8 @@
     } else if (this.checklog()) {
       if (sessionStorage.getItem('langList') && !config.trans) {
 
+      } else if (config.enabled && !config.allSqls) {
+
       } else {
         notification.success({
           top: 92,
@@ -804,6 +806,52 @@
       } else if (!config.enabled && config.force && _pass) {
         config.enabled = true
         delete config.force
+      }
+
+      let long_data = ''
+      if (config.enabled) {
+        let sqls = getAllSqls(config)
+        let _t = moment().format('YYYYMMDDHHmmss')
+        let getguid = () => {
+          let uuid = ''
+          for (let i = 0; i < 18; i++) {
+            uuid += String.fromCharCode(Math.floor(Math.random() * 26) + 65)
+          }
+          uuid = uuid.replace(/minke/ig, 'MNKIE')
+          return uuid
+        }
+
+        long_data = []
+        let oriIds = {}
+        if (config.allSqls) {
+          config.allSqls.forEach(item => {
+            if (!item.md5) return
+            oriIds[item.uuid + item.md5] = item.v_id
+          })
+        }
+        
+        config.allSqls = sqls.map(item => {
+          let v_id = _t + getguid()
+
+          if (oriIds[item.uuid + item.md5]) {
+            v_id = oriIds[item.uuid + item.md5]
+          }
+          
+          long_data.push(`${md5(window.GLOB.appkey + v_id)},${item.uuid},${v_id},${window.btoa(window.encodeURIComponent(item.LText))}`)
+          
+          return {
+            uuid: item.uuid,
+            v_id: v_id,
+            type: item.type,
+            reps: item.reps,
+            md5: item.md5 || '',
+            luser: item.luser === true
+          }
+        })
+
+        long_data = long_data.join(';')
+      } else {
+        delete config.allSqls
       }
 
       if (config.cacheUseful !== 'true') {
@@ -845,11 +893,14 @@
       } else {
         let urlparam = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
         urlparam.type = 'admin'
+        urlparam.lang = sessionStorage.getItem('lang')
+
         url = window.btoa(window.encodeURIComponent(JSON.stringify(urlparam)))
         config.tbkey = key
       }
 
       let interfaces = getFuncsAndInters(config)
+      let msg = getOutMessage(config)
       let urlFields = config.urlFields ? config.urlFields.join(',') : ''
       let langSql = getLangTrans(config)
 
@@ -863,10 +914,9 @@
         EasyCode: config.easyCode || '',
         Template: 'CustomPage',
         MenuName: config.MenuName || '',
-        PageParam: JSON.stringify({Template: 'CustomPage', OpenType: config.OpenType || 'newtab', hidden: config.hidden || 'false', menuColor: config.menuColor || '', interfaces, urlFields}),
+        PageParam: JSON.stringify({Template: 'CustomPage', OpenType: config.OpenType || 'newtab', hidden: config.hidden || 'false', menuColor: config.menuColor || '', interfaces, msg, backend: 'level1', urlFields}),
         open_edition: config.open_edition,
-        // LText: '',
-        // LTexttb: '',
+        long_data: long_data,
         debug_md5: key,
         debug_url: url,
         debug_list: window.btoa(tbs),
@@ -1274,8 +1324,8 @@
                     <StyleCombControlButton menu={config} />
                     <PasteController insert={this.insert} />
                     {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
-                    <Button type="primary" id="save-config" className={needUpdate ? 'update-tip' : ''} onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
-                    <Button type="default" onClick={this.closeView}>鍏抽棴</Button>
+                    <Button type="primary" id="save-config" disabled={!config} className={needUpdate ? 'update-tip' : ''} onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
+                    <Button type="default" disabled={menuloading} onClick={this.closeView}>鍏抽棴</Button>
                   </div>
                 } style={{ width: '100%' }}>
                   {config && !comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : <Spin className="loading-config" size="large" />}
diff --git a/src/views/menudesign/index.scss b/src/views/menudesign/index.scss
index 74d1cf2..5521e68 100644
--- a/src/views/menudesign/index.scss
+++ b/src/views/menudesign/index.scss
@@ -17,6 +17,13 @@
     top: calc(50vh - 70px);
     z-index: 10;
   }
+  .mini-radio {
+    white-space: nowrap;
+    span.ant-radio + * {
+      padding-right: 0px;
+      padding-left: 4px;
+    }
+  }
   .mk-hidden {
     text-decoration: line-through!important;
     span {
@@ -179,7 +186,10 @@
       > .ant-card {
         >.ant-card-head {
           margin-bottom: 0px;
-          position: relative;
+          position: sticky;
+          top: 0px;
+          z-index: 10;
+          background: #ffffff;
           .ant-card-head-title {
             color: #1890ff;
             padding: 5px 0;
diff --git a/src/views/menudesign/popview/index.jsx b/src/views/menudesign/popview/index.jsx
index 394ca23..496f116 100644
--- a/src/views/menudesign/popview/index.jsx
+++ b/src/views/menudesign/popview/index.jsx
@@ -284,7 +284,7 @@
                 <PasteController insert={this.insert} />
                 <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} />
                 <Button type="primary" id="save-pop-config" onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
-                <Button type="default" onClick={this.closeView}>杩斿洖</Button>
+                <Button type="default" disabled={menuloading} onClick={this.closeView}>杩斿洖</Button>
               </div>
             } style={{ width: '100%' }}>
               {!comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
diff --git a/src/views/menudesign/popview/index.scss b/src/views/menudesign/popview/index.scss
index 2ea36fa..02b8796 100644
--- a/src/views/menudesign/popview/index.scss
+++ b/src/views/menudesign/popview/index.scss
@@ -123,7 +123,10 @@
       > .ant-card {
         >.ant-card-head {
           margin-bottom: 0px;
-          position: relative;
+          position: sticky;
+          top: 0px;
+          z-index: 10;
+          background: #ffffff;
           .ant-card-head-title {
             color: #1890ff;
             padding: 5px 0;
diff --git a/src/views/menudesign/printmenuform/index.jsx b/src/views/menudesign/printmenuform/index.jsx
index 5809dcd..5aff337 100644
--- a/src/views/menudesign/printmenuform/index.jsx
+++ b/src/views/menudesign/printmenuform/index.jsx
@@ -1,14 +1,20 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Row, Col, InputNumber, Select, Radio, Tooltip, Input } from 'antd'
+import { Form, Row, Col, InputNumber, Select, Radio, Tooltip, Input, Modal } from 'antd'
 import { QuestionCircleOutlined, EditOutlined } from '@ant-design/icons'
 
+import CodeMirror from '@/templates/zshare/codemirror'
 // import './index.scss'
 
 class MainSearch extends Component {
   static propTpyes = {
     config: PropTypes.object,
     updateConfig: PropTypes.func
+  }
+
+  state = {
+    visible: false,
+    printScripts: ''
   }
 
   selectChange = (key, value) => {
@@ -76,9 +82,22 @@
     })
   }
 
+  onScriptChange = (val) => {
+    this.setState({printScripts: val})
+  }
+
+  submit = () => {
+    const { config } = this.props
+    const { printScripts } = this.state
+
+    this.setState({visible: false})
+    this.props.updateConfig({...config, printScripts})
+  }
+
   render() {
     const { config } = this.props
     const { getFieldDecorator } = this.props.form
+    const { visible, printScripts } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -91,186 +110,206 @@
     }
 
     return (
-      <Form {...formItemLayout}>
-        <Row>
-          <Col span={24}>
-            <Form.Item label="鑿滃崟鍚嶇О">
-              <span style={{display: 'inline-block', wordBreak: 'break-all', lineHeight: 1.5}}>
-                {config.MenuName}
-              </span>
-            </Form.Item>
-          </Col>
-          <Col span={24}>
-            <Form.Item label="鑿滃崟鍙傛暟">
-              <span style={{display: 'inline-block', wordBreak: 'break-all', lineHeight: 1.5}}>
-                {config.MenuNo}
-              </span>
-            </Form.Item>
-          </Col>
-          <Col span={24}>
-            <Form.Item label="鎵撳嵃灏哄">
-              {getFieldDecorator('pageSize', {
-                initialValue: config.pageSize || 'A4',
-                rules: [
-                  {
-                    required: true,
-                    message: '璇烽�夋嫨鎵撳嵃灏哄!'
-                  }
-                ]
-              })(
-                <Select onChange={(val) => this.selectChange('pageSize', val)}>
-                  <Select.Option value="A3">A3</Select.Option>
-                  <Select.Option value="A4">A4</Select.Option>
-                  <Select.Option value="A5">A5</Select.Option>
-                </Select>
-              )}
-            </Form.Item>
-          </Col>
-          <Col span={24}>
-            <Form.Item label="鎵撳嵃甯冨眬">
-              {getFieldDecorator('pageLayout', {
-                initialValue: config.pageLayout || 'vertical',
-                rules: [
-                  {
-                    required: true,
-                    message: '璇烽�夋嫨鎵撳嵃甯冨眬!'
-                  }
-                ]
-              })(
-                <Radio.Group onChange={(e) => this.selectChange('pageLayout', e.target.value)}>
-                  <Radio value="vertical">绾靛悜</Radio>
-                  <Radio value="horizontal">妯悜</Radio>
-                </Radio.Group>
-              )}
-            </Form.Item>
-          </Col>
-          <Col span={24}>
-            <Form.Item label="鎵撳嵃杈硅窛">
-              {getFieldDecorator('pagePadding', {
-                initialValue: config.pagePadding || 'default',
-                rules: [
-                  {
-                    required: true,
-                    message: '璇烽�夋嫨鎵撳嵃杈硅窛!'
-                  }
-                ]
-              })(
-                <Radio.Group onChange={(e) => this.selectChange('pagePadding', e.target.value)}>
-                  <Radio value="default">榛樿</Radio>
-                  <Radio value="without">鏃�</Radio>
-                </Radio.Group>
-              )}
-            </Form.Item>
-          </Col>
-          <Col span={24}>
-            <Form.Item label="椤甸潰甯冨眬">
-              {getFieldDecorator('printPage', {
-                initialValue: config.printPage || 'auto'
-              })(
-                <Radio.Group onChange={(e) => this.selectChange('printPage', e.target.value)}>
-                  <Radio value="auto">鑷�傚簲</Radio>
-                  <Radio value="page">鍒嗛〉</Radio>
-                </Radio.Group>
-              )}
-            </Form.Item>
-          </Col>
-          {config.printPage === 'page' ? <Col span={24}>
-            <Form.Item label="姣忛〉鏁�(鏉�)">
-              {getFieldDecorator('everyPCount', {
-                initialValue: config.everyPCount || 15,
-                rules: [
-                  {
-                    required: true,
-                    message: '璇疯緭鍏ユ瘡椤垫暟!'
-                  }
-                ]
-              })(<InputNumber min={1} max={1000} precision={1} onChange={(val) => this.selectChange('everyPCount', val)}/>)}
-            </Form.Item>
-          </Col> : null}
-          <Col span={24}>
-            <Form.Item label={
-              <Tooltip placement="topLeft" title="閽堝涓嶈鍒欑焊寮狅紝鍙嚜瀹氫箟璁剧疆鎵撳嵃楂樺害鍜屽搴︼紝娉細鍚屾椂璁剧疆鎵撳嵃瀹藉害鍜岄珮搴﹀悗鏂瑰彲鐢熸晥銆�">
-                <QuestionCircleOutlined className="mk-form-tip" />
-                鑷畾涔�
-              </Tooltip>
-            }>
-              {getFieldDecorator('printCustom', {
-                initialValue: config.printCustom || 'false'
-              })(
-                <Radio.Group onChange={(e) => this.selectChange('printCustom', e.target.value)}>
-                  <Radio value="false">涓嶅惎鐢�</Radio>
-                  <Radio value="true">鍚敤</Radio>
-                </Radio.Group>
-              )}
-            </Form.Item>
-          </Col>
-          {config.printCustom === 'true' ? <Col span={24}>
-            <Form.Item label="鎵撳嵃瀹藉害">
-              {getFieldDecorator('printWidth', {
-                initialValue: config.printWidth || ''
-              })(<InputNumber min={10} max={9999} precision={0} onChange={(val) => this.selectChange('printWidth', val)}/>)}
-            </Form.Item>
-          </Col> : null}
-          {config.printCustom === 'true' ? <Col span={24}>
-            <Form.Item label="鎵撳嵃楂樺害">
-              {getFieldDecorator('printHeight', {
-                initialValue: config.printHeight || ''
-              })(<InputNumber min={10} max={9999} precision={0} onChange={(val) => this.selectChange('printHeight', val)}/>)}
-            </Form.Item>
-          </Col> : null}
-          <Col span={24}>
-            <Form.Item label="鍥炶皟">
-              {getFieldDecorator('callback', {
-                initialValue: config.callback || 'false'
-              })(
-                <Radio.Group onChange={(e) => this.selectChange('callback', e.target.value)}>
-                  <Radio value="false">涓嶅惎鐢�</Radio>
-                  <Radio value="true">鍚敤</Radio>
-                </Radio.Group>
-              )}
-            </Form.Item>
-          </Col>
-          {config.callback === 'true' ? <Col span={24}>
-            <Form.Item label={
-              <Tooltip placement="topLeft" title="鍥炶皟鍑芥暟鎵ц鎴愬姛鍚庨粯璁や細鍒锋柊婧愯彍鍗曢〉锛岃繑鍥炰俊鎭紙@retmsg锛変腑鍚湁锛園no_target_menu@锛夊彲闃绘姝ら」鍒锋柊銆�">
-                <QuestionCircleOutlined className="mk-form-tip" />
-                鍥炶皟鍑芥暟
-              </Tooltip>
-            }>
-              s_print_proc <EditOutlined style={{cursor: 'pointer'}} onClick={() => {window.open('#/proc/s_print_proc')}}/>
-            </Form.Item>
-          </Col> : null}
-          {config.callback === 'true' ? <Col span={24}>
-            <Form.Item label="鍥炶皟鍙傛暟">
-              {getFieldDecorator('callNo', {
-                initialValue: config.callNo || '',
-                rules: [
-                  {
-                    required: true,
-                    message: '璇峰~鍐欏洖璋冨弬鏁�!'
-                  },
-                  {
-                    pattern: /^[a-zA-Z0-9_]+$/,
-                    message: '鍥炶皟鍙傛暟鍙彲浣跨敤瀛楁瘝銆佹暟瀛椾互鍙奯'
-                  }
-                ]
-              })(<Input onChange={(e) => this.selectChange('callNo', e.target.value)}/>)}
-            </Form.Item>
-          </Col> : null}
-          <Col span={24}>
-            <Form.Item label={
-              <Tooltip placement="topLeft" title="鍙嚜瀹氫箟鍦ㄦ祻瑙堝櫒鏍囬鏍忎腑鏄剧ず鐨勭綉椤垫爣棰樸��">
-                <QuestionCircleOutlined className="mk-form-tip" />
-                缃戦〉鏍囬
-              </Tooltip>
-            }>
-              {getFieldDecorator('webTitle', {
-                initialValue: config.webTitle || ''
-              })(<Input onChange={(e) => this.selectChange('webTitle', e.target.value)}/>)}
-            </Form.Item>
-          </Col>
-        </Row>
-      </Form>
+      <>
+        <Form {...formItemLayout}>
+          <Row>
+            <Col span={24}>
+              <Form.Item label="鑿滃崟鍚嶇О">
+                <span style={{display: 'inline-block', wordBreak: 'break-all', lineHeight: 1.5}}>
+                  {config.MenuName}
+                </span>
+              </Form.Item>
+            </Col>
+            <Col span={24}>
+              <Form.Item label="鑿滃崟鍙傛暟">
+                <span style={{display: 'inline-block', wordBreak: 'break-all', lineHeight: 1.5}}>
+                  {config.MenuNo}
+                </span>
+              </Form.Item>
+            </Col>
+            <Col span={24}>
+              <Form.Item label="鎵撳嵃灏哄">
+                {getFieldDecorator('pageSize', {
+                  initialValue: config.pageSize || 'A4',
+                  rules: [
+                    {
+                      required: true,
+                      message: '璇烽�夋嫨鎵撳嵃灏哄!'
+                    }
+                  ]
+                })(
+                  <Select onChange={(val) => this.selectChange('pageSize', val)}>
+                    <Select.Option value="A3">A3</Select.Option>
+                    <Select.Option value="A4">A4</Select.Option>
+                    <Select.Option value="A5">A5</Select.Option>
+                  </Select>
+                )}
+              </Form.Item>
+            </Col>
+            <Col span={24}>
+              <Form.Item label="鎵撳嵃甯冨眬">
+                {getFieldDecorator('pageLayout', {
+                  initialValue: config.pageLayout || 'vertical',
+                  rules: [
+                    {
+                      required: true,
+                      message: '璇烽�夋嫨鎵撳嵃甯冨眬!'
+                    }
+                  ]
+                })(
+                  <Radio.Group onChange={(e) => this.selectChange('pageLayout', e.target.value)}>
+                    <Radio value="vertical">绾靛悜</Radio>
+                    <Radio value="horizontal">妯悜</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col>
+            <Col span={24}>
+              <Form.Item label="鎵撳嵃杈硅窛">
+                {getFieldDecorator('pagePadding', {
+                  initialValue: config.pagePadding || 'default',
+                  rules: [
+                    {
+                      required: true,
+                      message: '璇烽�夋嫨鎵撳嵃杈硅窛!'
+                    }
+                  ]
+                })(
+                  <Radio.Group onChange={(e) => this.selectChange('pagePadding', e.target.value)}>
+                    <Radio value="default">榛樿</Radio>
+                    <Radio value="without">鏃�</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col>
+            <Col span={24}>
+              <Form.Item label="椤甸潰甯冨眬">
+                {getFieldDecorator('printPage', {
+                  initialValue: config.printPage || 'auto'
+                })(
+                  <Radio.Group className="mini-radio" onChange={(e) => this.selectChange('printPage', e.target.value)}>
+                    <Radio value="auto">鑷�傚簲</Radio>
+                    <Radio value="page">鍒嗛〉</Radio>
+                    <Radio value="custom">鑷畾涔�</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col>
+            {config.printPage === 'custom' ? <Col span={24}>
+              <Form.Item label="鑷畾涔夎剼鏈�">
+                <EditOutlined style={{color: '#1890ff'}} onClick={() => this.setState({visible: true, printScripts: config.printScripts || ''})} />
+              </Form.Item>
+            </Col> : null}
+            {config.printPage === 'page' ? <Col span={24}>
+              <Form.Item label="姣忛〉鏁�(鏉�)">
+                {getFieldDecorator('everyPCount', {
+                  initialValue: config.everyPCount || 15,
+                  rules: [
+                    {
+                      required: true,
+                      message: '璇疯緭鍏ユ瘡椤垫暟!'
+                    }
+                  ]
+                })(<InputNumber min={1} max={1000} precision={1} onChange={(val) => this.selectChange('everyPCount', val)}/>)}
+              </Form.Item>
+            </Col> : null}
+            <Col span={24}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="閽堝涓嶈鍒欑焊寮狅紝鍙嚜瀹氫箟璁剧疆鎵撳嵃楂樺害鍜屽搴︼紝娉細鍚屾椂璁剧疆鎵撳嵃瀹藉害鍜岄珮搴﹀悗鏂瑰彲鐢熸晥銆�">
+                  <QuestionCircleOutlined className="mk-form-tip" />
+                  鑷畾涔�
+                </Tooltip>
+              }>
+                {getFieldDecorator('printCustom', {
+                  initialValue: config.printCustom || 'false'
+                })(
+                  <Radio.Group onChange={(e) => this.selectChange('printCustom', e.target.value)}>
+                    <Radio value="false">涓嶅惎鐢�</Radio>
+                    <Radio value="true">鍚敤</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col>
+            {config.printCustom === 'true' ? <Col span={24}>
+              <Form.Item label="鎵撳嵃瀹藉害">
+                {getFieldDecorator('printWidth', {
+                  initialValue: config.printWidth || ''
+                })(<InputNumber min={10} max={9999} precision={0} onChange={(val) => this.selectChange('printWidth', val)}/>)}
+              </Form.Item>
+            </Col> : null}
+            {config.printCustom === 'true' ? <Col span={24}>
+              <Form.Item label="鎵撳嵃楂樺害">
+                {getFieldDecorator('printHeight', {
+                  initialValue: config.printHeight || ''
+                })(<InputNumber min={10} max={9999} precision={0} onChange={(val) => this.selectChange('printHeight', val)}/>)}
+              </Form.Item>
+            </Col> : null}
+            <Col span={24}>
+              <Form.Item label="鍥炶皟">
+                {getFieldDecorator('callback', {
+                  initialValue: config.callback || 'false'
+                })(
+                  <Radio.Group onChange={(e) => this.selectChange('callback', e.target.value)}>
+                    <Radio value="false">涓嶅惎鐢�</Radio>
+                    <Radio value="true">鍚敤</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col>
+            {config.callback === 'true' ? <Col span={24}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="鍥炶皟鍑芥暟鎵ц鎴愬姛鍚庨粯璁や細鍒锋柊婧愯彍鍗曢〉锛岃繑鍥炰俊鎭紙@retmsg锛変腑鍚湁锛園no_target_menu@锛夊彲闃绘姝ら」鍒锋柊銆�">
+                  <QuestionCircleOutlined className="mk-form-tip" />
+                  鍥炶皟鍑芥暟
+                </Tooltip>
+              }>
+                s_print_proc <EditOutlined style={{cursor: 'pointer'}} onClick={() => {window.open('#/proc/s_print_proc')}}/>
+              </Form.Item>
+            </Col> : null}
+            {config.callback === 'true' ? <Col span={24}>
+              <Form.Item label="鍥炶皟鍙傛暟">
+                {getFieldDecorator('callNo', {
+                  initialValue: config.callNo || '',
+                  rules: [
+                    {
+                      required: true,
+                      message: '璇峰~鍐欏洖璋冨弬鏁�!'
+                    },
+                    {
+                      pattern: /^[a-zA-Z0-9_]+$/,
+                      message: '鍥炶皟鍙傛暟鍙彲浣跨敤瀛楁瘝銆佹暟瀛椾互鍙奯'
+                    }
+                  ]
+                })(<Input onChange={(e) => this.selectChange('callNo', e.target.value)}/>)}
+              </Form.Item>
+            </Col> : null}
+            <Col span={24}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="鍙嚜瀹氫箟鍦ㄦ祻瑙堝櫒鏍囬鏍忎腑鏄剧ず鐨勭綉椤垫爣棰樸��">
+                  <QuestionCircleOutlined className="mk-form-tip" />
+                  缃戦〉鏍囬
+                </Tooltip>
+              }>
+                {getFieldDecorator('webTitle', {
+                  initialValue: config.webTitle || ''
+                })(<Input onChange={(e) => this.selectChange('webTitle', e.target.value)}/>)}
+              </Form.Item>
+            </Col>
+          </Row>
+        </Form>
+        <Modal
+          title="鑷畾涔夎剼鏈�"
+          wrapClassName="normal-css-modal"
+          visible={visible}
+          width={800}
+          maskClosable={false}
+          onOk={this.submit}
+          onCancel={() => { this.setState({ visible: false })}}
+          destroyOnClose
+        >
+          <CodeMirror mode="text/javascript" theme="cobalt" value={printScripts} onChange={this.onScriptChange} />
+        </Modal>
+      </>
     )
   }
 }
diff --git a/src/views/mkiframe/index.jsx b/src/views/mkiframe/index.jsx
index 329ef36..4730c77 100644
--- a/src/views/mkiframe/index.jsx
+++ b/src/views/mkiframe/index.jsx
@@ -75,6 +75,7 @@
             } else {
               sessionStorage.clear()
               this.props.history.replace('/login')
+              window.location.reload()
             }
           })
         }
@@ -102,6 +103,7 @@
           sessionStorage.clear()
           sessionStorage.setItem('iframe', `/iframe/${menuId}/@loginuid@/${bid || ''}`)
           this.props.history.replace('/login')
+          window.location.reload()
         }
       })
     }
@@ -164,6 +166,14 @@
   reloadTabs = () => {
     if (this.reloading) return
 
+    let time = new Date().getTime()
+
+    let oldTime = sessionStorage.getItem('mk_reloadTabs')
+    
+    if (oldTime && time - oldTime < 180000) return
+
+    sessionStorage.setItem('mk_reloadTabs', time)
+
     this.reloading = true
 
     Api.getAppVersion(true).then(() => {
diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index dbf4105..a87df2d 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -9,9 +9,9 @@
 import md5 from 'md5'
 
 import Api from '@/api'
-import Utils, { setGLOBFuncs } from '@/utils/utils.js'
+import Utils from '@/utils/utils.js'
 import MKEmitter from '@/utils/events.js'
-import MenuUtils, { getTables, getFuncsAndInters, getLangTrans } from '@/utils/utils-custom.js'
+import MenuUtils, { getTables, getFuncsAndInters, getOutMessage, getLangTrans, getAllSqls } from '@/utils/utils-custom.js'
 import asyncComponent from '@/utils/asyncComponent'
 
 import '@/assets/css/design.scss'
@@ -74,7 +74,9 @@
     viewType: 'menu',
     view: '',
     eyeopen: false,
-    needUpdate: false
+    needUpdate: false,
+    appLoginId: '',
+    appHomeId: ''
   }
 
   UNSAFE_componentWillMount() {
@@ -120,6 +122,10 @@
           sessionStorage.removeItem('applangList')
         }
 
+        if (param.wxAppId) {
+          sessionStorage.setItem('wxAppId', param.wxAppId)
+        }
+
         this.getAppMessage(param.MenuID)
       } else if (param.type === 'view') {
         window.GLOB.winWidth = 420
@@ -135,10 +141,29 @@
           adapters = []
         }
 
+        let appLoginId = ''
+        let appHomeId = ''
+        if (sessionStorage.getItem('appViewList')) {
+          try {
+            let appMenus = JSON.parse(sessionStorage.getItem('appViewList'))
+            appMenus.forEach(item => {
+              if (item.keys_type === 'login') {
+                appLoginId = item.keys_id
+              } else if (item.keys_type === 'index') {
+                appHomeId = item.keys_id
+              }
+            })
+          } catch (e) {
+
+          }
+        }
+
         this.setState({
           adapters,
           MenuId: param.MenuID,
-          viewType: /^userbind/.test(param.MenuID) ? 'userbind' : 'menu'
+          viewType: /^userbind/.test(param.MenuID) ? 'userbind' : 'menu',
+          appLoginId: appLoginId,
+          appHomeId: appHomeId
         }, () => {
           this.getMenuParam(param)
         })
@@ -171,9 +196,14 @@
     MKEmitter.addListener('changePopview', this.initPopview)
     MKEmitter.addListener('triggerMenuSave', this.submitConfig)
     MKEmitter.addListener('changeEditMenu', this.changeEditMenu)
+
+    if (sessionStorage.getItem('wxAppId')) {
+      window.GLOB.WXAppID = sessionStorage.getItem('wxAppId')
+    }
+
     setTimeout(() => {
       this.getRoleFields()
-      setGLOBFuncs()
+      // setGLOBFuncs()
     }, 1000)
 
     document.onkeydown = (event) => {
@@ -1295,6 +1325,7 @@
 
     let traversal = (components) => {
       return components.map(item => {
+        item.miniStyle = ''
         if (item.style) {
           item.miniStyle = this.transferStyle(item.style)
         }
@@ -1310,12 +1341,18 @@
         }
 
         if (item.type === 'tabs') {
+          if (item.setting.backgroundColor) {
+            item.miniStyle += `--tabs-header-background: ${item.setting.backgroundColor};`
+          }
           item.subtabs.forEach(tab => {
             tab.components = traversal(tab.components)
           })
         } else if (item.type === 'group') {
           item.components = traversal(item.components)
         } else if (['card', 'carousel', 'timeline'].includes(item.type)) {
+          if (item.wrap.display === 'hidden') {
+            item.miniStyle += 'display:none;'
+          }
           item.subcards.forEach(card => {
             card.miniStyle = this.transferStyle(card.style)
             card.elements = card.elements.map(cell => {
@@ -1416,8 +1453,10 @@
       })
       return
     } else if (this.checklog()) {
-      if (sessionStorage.getItem('applangList') && !config.trans) {
+      if ((sessionStorage.getItem('applangList') && !config.trans) || (adapters.includes('wxmini') && !config.hasOwnProperty('miniStyle'))) {
 
+      } else if (config.enabled && !config.allSqls) {
+        
       } else {
         notification.success({
           top: 92,
@@ -1442,6 +1481,52 @@
       } else if (!config.enabled && config.force && _pass) {
         config.enabled = true
         delete config.force
+      }
+
+      let long_data = ''
+      if (config.enabled) {
+        let sqls = getAllSqls(config)
+        let _t = moment().format('YYYYMMDDHHmmss')
+        let getguid = () => {
+          let uuid = ''
+          for (let i = 0; i < 18; i++) {
+            uuid += String.fromCharCode(Math.floor(Math.random() * 26) + 65)
+          }
+          uuid = uuid.replace(/minke/ig, 'MNKIE')
+          return uuid
+        }
+
+        long_data = []
+        let oriIds = {}
+        if (config.allSqls) {
+          config.allSqls.forEach(item => {
+            if (!item.md5) return
+            oriIds[item.uuid + item.md5] = item.v_id
+          })
+        }
+        
+        config.allSqls = sqls.map(item => {
+          let v_id = _t + getguid()
+
+          if (oriIds[item.uuid + item.md5]) {
+            v_id = oriIds[item.uuid + item.md5]
+          }
+          
+          long_data.push(`${md5(window.GLOB.appkey + v_id)},${item.uuid},${v_id},${window.btoa(window.encodeURIComponent(item.LText))}`)
+          
+          return {
+            uuid: item.uuid,
+            v_id: v_id,
+            type: item.type,
+            reps: item.reps,
+            md5: item.md5 || '',
+            luser: item.luser === true
+          }
+        })
+
+        long_data = long_data.join(';')
+      } else {
+        delete config.allSqls
       }
 
       if (config.cacheUseful !== 'true') {
@@ -1486,7 +1571,7 @@
           typename: sessionStorage.getItem('typename') || '',
           adapter: sessionStorage.getItem('adapter') || '',
           sysBgColor: sessionStorage.getItem('sysBgColor') || '',
-          MenuName: config.MenuName || '',
+          MenuName: config.MenuName || ''
         }
 
         url = window.btoa(window.encodeURIComponent(JSON.stringify(urlparam)))
@@ -1497,6 +1582,9 @@
         roleParam.pass = true
       }
 
+      delete config.miniTitle
+      delete config.miniReloadUp
+
       config.components.forEach(item => {
         if (item.type === 'login') {
           roleParam.login = true
@@ -1504,6 +1592,13 @@
           config.loginview = true
         } else if (item.type === 'navbar') {
           config.tabview = true
+        } else if (item.type === 'topbar' && adapters.includes('wxmini')) {
+          if (item.wrap.minishow !== 'true') {
+            config.miniTitle = item.wrap.title || ''
+          }
+          if (item.wrap.reload === 'true') {
+            config.miniReloadUp = true
+          }
         }
       })
 
@@ -1529,7 +1624,10 @@
       menus_used_list = window.btoa(window.encodeURIComponent(menus_used_list || 'del'))
 
       let interfaces = getFuncsAndInters(config)
+      let msg = getOutMessage(config)
       roleParam.interfaces = interfaces
+      roleParam.msg = msg
+      roleParam.backend = 'level1'
       let langSql = getLangTrans(config)
 
       let param = {
@@ -1544,9 +1642,10 @@
         TypeCharOne: sessionStorage.getItem('kei_no'),
         Typename: sessionStorage.getItem('typename'),
         MenuName: config.MenuName || '',
-        PageParam: JSON.stringify({Template: 'webPage', interfaces}),
+        PageParam: JSON.stringify({Template: 'webPage', interfaces, msg}),
         open_edition: config.open_edition,
         menus_rolelist: window.btoa(window.encodeURIComponent(JSON.stringify(roleParam))),
+        long_data: long_data,
         // LText: '',
         // LTexttb: '',
         menus_used_list,
@@ -1933,6 +2032,8 @@
     param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
     param.secretkey = Utils.encrypt('', param.timestamp)
 
+    const that = this
+
     confirm({
       title: '纭畾璁剧疆鏈〉闈负棣栭〉鍚楋紵',
       content: '',
@@ -1946,6 +2047,10 @@
             })
           } else {
             sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
+
+            that.setState({
+              appHomeId: config.MenuID
+            })
           }
         })
       },
@@ -1993,6 +2098,7 @@
     param.secretkey = Utils.encrypt('', param.timestamp)
 
     let hasLogin = config.components.findIndex(item => item.type === 'login') > -1
+    const that = this
 
     confirm({
       title: '纭畾璁剧疆鏈〉闈负鐧诲綍椤靛悧锛�',
@@ -2007,6 +2113,10 @@
             })
           } else {
             sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
+
+            that.setState({
+              appLoginId: config.MenuID
+            })
           }
         })
       },
@@ -2071,7 +2181,7 @@
 
 
   render () {
-    const { view, viewType, comloading, loading, settingshow, controlshow, activeKey, MenuId, config, menuloading, adapters, eyeopen, needUpdate } = this.state
+    const { view, viewType, comloading, loading, settingshow, controlshow, activeKey, MenuId, config, menuloading, adapters, eyeopen, needUpdate, appLoginId, appHomeId } = this.state
 
     return (
       <div className={'mk-mob-view ' + viewType} id="mk-mob-design-view">
@@ -2126,7 +2236,7 @@
               {!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>
+              <Button type="primary" className={needUpdate ? 'update-tip' : ''} disabled={!config} onClick={this.submitConfig} id="save-config" loading={menuloading}>淇濆瓨</Button>
               {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
               <ArrowLeftOutlined title="鍚庨��" className="back-view" onClick={this.backView}/>
               {config ? <Debug config={config}/> : null}
@@ -2139,8 +2249,8 @@
               <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>
+              <Button className="mk-border-green set-home" disabled={MenuId === appHomeId} onClick={this.setHomeView}><HomeOutlined /> 璁句负棣栭〉</Button>
+              <Button className="mk-border-purple" disabled={MenuId === appLoginId} 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}
diff --git a/src/views/mobdesign/index.scss b/src/views/mobdesign/index.scss
index 3753c8f..6d6d812 100644
--- a/src/views/mobdesign/index.scss
+++ b/src/views/mobdesign/index.scss
@@ -171,25 +171,25 @@
     background-size: 100% 100%;
     padding: 25px 13px 40px;
     border-radius: 30px;
-    .main-search-edit-list {
-      .page-card > div > .ant-form-item {
-        display: flex;
-        >.ant-form-item-label {
-          width: 70px;
-        }
-        >.ant-form-item-control-wrapper {
-          flex: 1;
-        }
-        .ant-form-item-label > label::after {
-          content: ' ';
+    // .main-search-edit-list {
+    //   .page-card > div > .ant-form-item {
+    //     display: flex;
+    //     >.ant-form-item-label {
+    //       width: 70px;
+    //     }
+    //     >.ant-form-item-control-wrapper {
+    //       flex: 1;
+    //     }
+    //     .ant-form-item-label > label::after {
+    //       content: ' ';
           
-        }
-      }
-      .page-card.date .ant-form-item, .page-card.datemonth .ant-form-item {
-        // box-shadow: 0px 1px 1px #f0f0f0;
-        border-bottom: 1px solid #f0f0f0;
-      }
-    }
+    //     }
+    //   }
+    //   .page-card.date .ant-form-item, .page-card.datemonth .ant-form-item {
+    //     // box-shadow: 0px 1px 1px #f0f0f0;
+    //     border-bottom: 1px solid #f0f0f0;
+    //   }
+    // }
   }
   .menu-control {
     position: fixed;
@@ -323,7 +323,7 @@
     }
   }
   .menu-control {
-    .quote-wrap, .set-home, .set-login {
+    .quote-wrap, .set-home {
       display: none!important;
     }
   }
@@ -332,7 +332,3 @@
 body {
   overflow-y: hidden;
 }
-
-.user-component-wrap {
-  display: none!important;
-}
\ No newline at end of file
diff --git a/src/views/mobdesign/menuform/index.jsx b/src/views/mobdesign/menuform/index.jsx
index 49d4013..00b8042 100644
--- a/src/views/mobdesign/menuform/index.jsx
+++ b/src/views/mobdesign/menuform/index.jsx
@@ -20,6 +20,14 @@
 
   state = {}
 
+  componentDidMount() {
+    const { config } = this.props
+
+    if (config.getLocation === 'true') {
+      window.GLOB.getLocation = true
+    }
+  }
+
   // 涓�浜岀骇鑿滃崟鍒囨崲
   selectChange = (key, value, hex) => {
     if (key === 'cacheTime' || key === 'localCacheTime') {
@@ -36,6 +44,8 @@
       } else {
         delete _config.statusBarHexColor
       }
+    } else if (key === 'getLocation') {
+      window.GLOB.getLocation = value === 'true'
     }
 
     this.props.updateConfig(_config)
@@ -279,6 +289,23 @@
               )}
             </Form.Item>
           </Col> : null}
+          <Col span={24}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="寮�鍚悗鏁版嵁婧愪腑灏嗘浛鎹� @mk_longitude@銆丂mk_latitude@锛屽湪灏忕▼搴忎腑灏嗚幏鍙栫敤鎴锋墍鍦ㄧ粡绾害銆�">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                瀹氫綅
+              </Tooltip>
+            }>
+              {getFieldDecorator('getLocation', {
+                initialValue: config.getLocation || 'false'
+              })(
+                <Radio.Group onChange={(e) => {this.selectChange('getLocation', e.target.value)}}>
+                  <Radio value="true">寮�鍚�</Radio>
+                  <Radio value="false">涓嶅紑鍚�</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
           {adapters.includes('weixin') || adapters.includes('wxmini') ? <Col span={24}>
             <Form.Item label={
               <Tooltip placement="topLeft" title="浣跨敤榛樿鏃惰鍦ㄥ瓙搴旂敤璁剧疆鍒嗕韩淇℃伅锛屼娇鐢╱rl鍙傛暟浼氫娇鐢ㄤ笂椤靛弬鏁版浛鎹㈢浉搴斿瓧娈碉紙@field@锛夈�傛敞锛氫娇鐢ㄨ嚜瀹氫箟鎴杣rl鍙傛暟鏃朵細鍒嗕韩褰撳墠椤甸潰銆�">
diff --git a/src/views/pay/index.jsx b/src/views/pay/index.jsx
index 788a5c5..b01f691 100644
--- a/src/views/pay/index.jsx
+++ b/src/views/pay/index.jsx
@@ -17,54 +17,56 @@
   state = {
     orderId: '',
     orderNo: '',
-    appid: '',
-    logo: '',
-    name: '',
-    copyRight: '',
-    icp: '',
+    logo: window.GLOB.doclogo || '',
+    name: sessionStorage.getItem('Full_Name') || '',
+    copyRight: window.GLOB.copyRight || '',
+    icp: window.GLOB.ICP || '',
     total: '',
     unit: '',
     qrcode: '',
     second: 60,
     overdue: false,
-    overdone: false
+    overdone: false,
+    appId: '',
+    merchId: ''
   }
 
   UNSAFE_componentWillMount () {
-    let _urlparam = window.decodeURIComponent(window.atob(this.props.match.params.param))
-    let _params = {}
-    _urlparam.split('&').forEach(cell => {
-      let _cell = cell.split('=')
-      _params[_cell[0]] = _cell[1]
-    })
+    let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
 
-    if (!sessionStorage.getItem('LoginUID') && _params.LoginUID) {
-      sessionStorage.setItem('LoginUID', _params.LoginUID)
-    }
-    if (!sessionStorage.getItem('UserID') && _params.userid) {
-      sessionStorage.setItem('UserID', _params.userid)
-    }
+    let appId = param.appId || window.GLOB.WXAppID || window.GLOB.WXminiAppID || ''
+    let merchId = param.merchId || window.GLOB.WXMerchID || ''
 
     this.setState({
-      orderId: _params.ID,
-      logo: _params.logo,
-      name: _params.name,
-      copyRight: _params.copyRight,
-      icp: _params.icp
+      orderId: param.ID,
+      appId: appId,
+      merchId: merchId
     })
 
-    if (_params.ID) {
-      this.getOrder(_params.ID)
-    } else {
+    if (param.ID && appId && merchId) {
+      this.getOrder(param.ID, appId, merchId)
+    } else if (!param.ID) {
       notification.warning({
         top: 92,
         message: '鏈幏鍙栧埌璁㈠崟ID锛�',
         duration: 5
       })
+    } else if (!appId) {
+      notification.warning({
+        top: 92,
+        message: '鏈幏鍙栧埌搴旂敤ID锛�',
+        duration: 5
+      })
+    } else if (!merchId) {
+      notification.warning({
+        top: 92,
+        message: '鏈幏鍙栧埌鍟嗘埛鍙凤紒',
+        duration: 5
+      })
     }
   }
 
-  getOrder = (Id) => {
+  getOrder = (Id, appId, merchId) => {
     let param = {
       func: 's_get_weixin_pay_native',
       ID: Id
@@ -85,7 +87,6 @@
         }
 
         this.setState({
-          appid: res.appid,
           orderNo: res.out_trade_no,
           total: _total,
           unit: res.amount && res.amount.currency === 'CNY' ? '鍏�' : '鍏�',
@@ -114,19 +115,12 @@
             duration: 5
           })
           return
-        } else if (!res.appid) {
-          notification.warning({
-            top: 10,
-            message: '鏈幏鍙栧埌搴旂敤ID锛�',
-            duration: 5
-          })
-          return
         }
 
-        Api.getWxNativePay({ 'out_biz_no': res.out_trade_no, 'out_open_id': res.appid }).then(result => {
-          if (result.qrcode) {
+        Api.getWxNativePay({ 'out_biz_no': res.out_trade_no, app_id: appId, mchid: merchId }).then(result => {
+          if (result.status && result.code_url) {
             this.setState({
-              qrcode: result.qrcode
+              qrcode: result.code_url
             })
             setTimeout(this.resetSecond, 1000)
           } else {
@@ -135,7 +129,7 @@
             })
             notification.warning({
               top: 10,
-              message: result.msg || '鏈幏鍙栧埌鏀粯鐮侊紒',
+              message: result.message || '鏈幏鍙栧埌鏀粯鐮侊紒',
               duration: 5
             })
           }
@@ -198,7 +192,7 @@
   }
 
   resetQrcode = () => {
-    const { appid, orderNo } = this.state
+    const { orderNo, appId, merchId } = this.state
 
     if (!orderNo) {
       notification.warning({
@@ -207,12 +201,26 @@
         duration: 5
       })
       return
+    } else if (!appId) {
+      notification.warning({
+        top: 10,
+        message: '鏈幏鍙栧埌搴旂敤ID锛�',
+        duration: 5
+      })
+      return
+    } else if (!merchId) {
+      notification.warning({
+        top: 10,
+        message: '鏈幏鍙栧埌鍟嗘埛鍙凤紒',
+        duration: 5
+      })
+      return
     }
 
-    Api.getWxNativePay({ 'out_biz_no': orderNo, 'out_open_id': appid }).then(result => {
-      if (result.qrcode) {
+    Api.getWxNativePay({ 'out_biz_no': orderNo, app_id: appId, mchid: merchId }).then(result => {
+      if (result.status && result.code_url) {
         this.setState({
-          qrcode: result.qrcode,
+          qrcode: result.code_url,
           overdue: false,
           second: 60
         })
@@ -220,16 +228,16 @@
       } else {
         notification.warning({
           top: 10,
-          message: result.msg || '鏈幏鍙栧埌鏀粯鐮侊紒',
+          message: result.message || '鏈幏鍙栧埌鏀粯鐮侊紒',
           duration: 5
         })
       }
     })
   }
 
-  onChange = () => {
+  // onChange = () => {
 
-  }
+  // }
 
   render () {
     const { logo, name, orderNo, icp, copyRight, total, unit, qrcode, second, overdue, overdone } = this.state
@@ -251,17 +259,8 @@
                 {!overdone ? <div className="qrcode-box">
                   {!overdue ? <p>璺濈浜岀淮鐮佽繃鏈熻繕鍓�<span>{second}</span>绉掞紝杩囨湡鍚庤鍒锋柊椤甸潰閲嶆柊鑾峰彇浜岀淮鐮併��</p> : null}
                   {overdue ? <p className="overdue">浜岀淮鐮佸凡杩囨湡锛�<span onClick={this.resetQrcode}>鍒锋柊</span>椤甸潰閲嶆柊鑾峰彇浜岀淮鐮併��</p> : null}
-                  <QRCode
-                    value={qrcode}
-                    size={250}
-                    fgColor="#000000"
-                    // imageSettings={{
-                    //   src: '',
-                    //   height: 60,
-                    //   width: 60,
-                    //   excavate: true
-                    // }}
-                  />
+                  <QRCode value={qrcode} size={250} fgColor="#000000"/>
+                  {!overdue && !qrcode ? <div className="qr-mask"></div> : null}
                   {overdue ? <div className="overdue-mask"><p onClick={this.resetQrcode}>鑾峰彇澶辫触 鐐瑰嚮閲嶆柊鑾峰彇浜岀淮鐮�</p></div> : null}
                   <div className="qrcode-tip">
                     <img src={WeiXinScan} alt=""/>
diff --git a/src/views/pay/index.scss b/src/views/pay/index.scss
index b69ffac..e2fa10d 100644
--- a/src/views/pay/index.scss
+++ b/src/views/pay/index.scss
@@ -101,6 +101,14 @@
             cursor: pointer;
           }
         }
+        .qr-mask {
+          position: absolute;
+          width: 240px;
+          height: 240px;
+          top: 45px;
+          background: rgba(255, 255, 255, 0.95);
+          left: calc(50% - 120px);
+        }
         .qrcode-tip {
           background: #ff7674;
           width: 250px;
diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx
index b1abf07..0638e83 100644
--- a/src/views/pcdesign/index.jsx
+++ b/src/views/pcdesign/index.jsx
@@ -9,8 +9,8 @@
 import md5 from 'md5'
 
 import Api from '@/api'
-import Utils, { setGLOBFuncs } from '@/utils/utils.js'
-import { getTables, getFuncsAndInters, getLangTrans } from '@/utils/utils-custom.js'
+import Utils from '@/utils/utils.js'
+import { getTables, getFuncsAndInters, getOutMessage, getLangTrans, getAllSqls } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import MenuUtils from '@/utils/utils-custom.js'
 import asyncComponent from '@/utils/asyncComponent'
@@ -68,7 +68,9 @@
     eyeopen: false,
     view: '',
     popConfig: null,
-    needUpdate: false
+    needUpdate: false,
+    appLoginId: '',
+    appHomeId: ''
   }
 
   UNSAFE_componentWillMount() {
@@ -115,10 +117,33 @@
           sessionStorage.removeItem('applangList')
         }
 
+        if (param.wxAppId) {
+          sessionStorage.setItem('wxAppId', param.wxAppId)
+        }
+
         this.getAppMessage(param.MenuID)
       } else if (param.type === 'view') {
+        let appLoginId = ''
+        let appHomeId = ''
+        if (sessionStorage.getItem('appViewList')) {
+          try {
+            let appMenus = JSON.parse(sessionStorage.getItem('appViewList'))
+            appMenus.forEach(item => {
+              if (item.keys_type === 'login') {
+                appLoginId = item.keys_id
+              } else if (item.keys_type === 'index') {
+                appHomeId = item.keys_id
+              }
+            })
+          } catch (e) {
+
+          }
+        }
+
         this.setState({
-          MenuId: param.MenuID
+          MenuId: param.MenuID,
+          appLoginId: appLoginId,
+          appHomeId: appHomeId
         }, () => {
           this.getMenuParam(param)
         })
@@ -152,9 +177,13 @@
     MKEmitter.addListener('changeEditMenu', this.changeEditMenu)
     MKEmitter.addListener('triggerMenuSave', this.triggerMenuSave)
 
+    if (sessionStorage.getItem('wxAppId')) {
+      window.GLOB.WXAppID = sessionStorage.getItem('wxAppId')
+    }
+
     setTimeout(() => {
       this.getRoleFields()
-      setGLOBFuncs()
+      // setGLOBFuncs()
     }, 1000)
 
     document.onkeydown = (event) => {
@@ -1152,6 +1181,8 @@
     } else if (this.checklog()) {
       if (sessionStorage.getItem('applangList') && !config.trans) {
 
+      } else if (config.enabled && !config.allSqls) {
+        
       } else {
         notification.success({
           top: 92,
@@ -1176,6 +1207,52 @@
       } else if (!config.enabled && config.force && _pass) {
         config.enabled = true
         delete config.force
+      }
+
+      let long_data = ''
+      if (config.enabled) {
+        let sqls = getAllSqls(config)
+        let _t = moment().format('YYYYMMDDHHmmss')
+        let getguid = () => {
+          let uuid = ''
+          for (let i = 0; i < 18; i++) {
+            uuid += String.fromCharCode(Math.floor(Math.random() * 26) + 65)
+          }
+          uuid = uuid.replace(/minke/ig, 'MNKIE')
+          return uuid
+        }
+
+        long_data = []
+        let oriIds = {}
+        if (config.allSqls) {
+          config.allSqls.forEach(item => {
+            if (!item.md5) return
+            oriIds[item.uuid + item.md5] = item.v_id
+          })
+        }
+        
+        config.allSqls = sqls.map(item => {
+          let v_id = _t + getguid()
+
+          if (oriIds[item.uuid + item.md5]) {
+            v_id = oriIds[item.uuid + item.md5]
+          }
+          
+          long_data.push(`${md5(window.GLOB.appkey + v_id)},${item.uuid},${v_id},${window.btoa(window.encodeURIComponent(item.LText))}`)
+          
+          return {
+            uuid: item.uuid,
+            v_id: v_id,
+            type: item.type,
+            reps: item.reps,
+            md5: item.md5 || '',
+            luser: item.luser === true
+          }
+        })
+
+        long_data = long_data.join(';')
+      } else {
+        delete config.allSqls
       }
 
       if (config.cacheUseful !== 'true') {
@@ -1228,7 +1305,10 @@
       }
 
       let interfaces = getFuncsAndInters(config)
+      let msg = getOutMessage(config)
       roleParam.interfaces = interfaces
+      roleParam.msg = msg
+      roleParam.backend = 'level1'
       let langSql = getLangTrans(config)
 
       let param = {
@@ -1243,9 +1323,10 @@
         TypeCharOne: sessionStorage.getItem('kei_no'),
         Typename: 'pc',
         MenuName: config.MenuName || '',
-        PageParam: JSON.stringify({Template: 'webPage', interfaces}),
+        PageParam: JSON.stringify({Template: 'webPage', interfaces, msg}),
         menus_rolelist: window.btoa(window.encodeURIComponent(JSON.stringify(roleParam))),
         open_edition: config.open_edition,
+        long_data: long_data,
         // LText: '',
         // LTexttb: '',
         menus_used_list,
@@ -1617,6 +1698,8 @@
     param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
     param.secretkey = Utils.encrypt('', param.timestamp)
 
+    const that = this
+
     confirm({
       title: '纭畾璁剧疆鏈〉闈负棣栭〉鍚楋紵',
       content: '',
@@ -1630,6 +1713,10 @@
             })
           } else {
             sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
+
+            that.setState({
+              appHomeId: config.MenuID
+            })
           }
         })
       },
@@ -1677,6 +1764,7 @@
     param.secretkey = Utils.encrypt('', param.timestamp)
 
     let hasLogin = config.components.findIndex(item => item.type === 'login') > -1
+    const that = this
 
     confirm({
       title: '纭畾璁剧疆鏈〉闈负鐧诲綍椤靛悧锛�',
@@ -1691,6 +1779,10 @@
             })
           } else {
             sessionStorage.setItem('appViewList', JSON.stringify(appViewList))
+
+            that.setState({
+              appLoginId: config.MenuID
+            })
           }
         })
       },
@@ -1719,7 +1811,7 @@
   }
 
   render () {
-    const { view, loading, comloading, activeKey, settingshow, controlshow, MenuId, config, menuloading, eyeopen, needUpdate } = this.state
+    const { view, loading, comloading, activeKey, settingshow, controlshow, MenuId, config, menuloading, eyeopen, needUpdate, appLoginId, appHomeId } = this.state
 
     return (
       <>
@@ -1767,7 +1859,7 @@
                 {!controlshow ? <DoubleLeftOutlined onClick={() => {sessionStorage.setItem('controlshow', 'true'); this.setState({controlshow: true})}}/> : null}
               </div>
               <div className="wrap">
-                <Button type="primary" className={needUpdate ? 'update-tip' : ''} id="save-config" onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
+                <Button type="primary" className={needUpdate ? 'update-tip' : ''} disabled={!config} id="save-config" onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
                 {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                 <ArrowLeftOutlined title="鍚庨��" className="back-view" onClick={this.backView}/>
                 {config ? <Debug config={config}/> : null}
@@ -1780,8 +1872,8 @@
                 <PictureController/>
                 <Quotecomponent config={config} updateConfig={this.updateConfig}/>
                 <StyleCombControlButton menu={config} />
-                <Button className="mk-border-green" onClick={this.setHomeView}><HomeOutlined /> 璁句负棣栭〉</Button>
-                <Button className="mk-border-purple" onClick={this.setLoginView}><LoginOutlined/> 璁句负鐧诲綍椤�</Button>
+                <Button className="mk-border-green" disabled={MenuId === appHomeId} onClick={this.setHomeView}><HomeOutlined /> 璁句负棣栭〉</Button>
+                <Button className="mk-border-purple" disabled={MenuId === appLoginId} 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}
diff --git a/src/views/pcdesign/index.scss b/src/views/pcdesign/index.scss
index bb683f2..0d2b917 100644
--- a/src/views/pcdesign/index.scss
+++ b/src/views/pcdesign/index.scss
@@ -274,6 +274,3 @@
 body {
   overflow-y: hidden;
 }
-.user-component-wrap {
-  display: none!important;
-}
\ No newline at end of file
diff --git a/src/views/printTemplate/index.jsx b/src/views/printTemplate/index.jsx
index 75783b8..8374dff 100644
--- a/src/views/printTemplate/index.jsx
+++ b/src/views/printTemplate/index.jsx
@@ -767,7 +767,7 @@
   }
 
   deleteItem = () => {
-    const _this = this
+    const that = this
     const { editItemId, config } = this.state
 
     confirm({
@@ -777,13 +777,13 @@
       onOk() {
         config.elements = config.elements.filter(item => item.uuid !== editItemId)
 
-        _this.setState({
+        that.setState({
           config: config,
           editItemId: config.uuid,
           editItemType: config.type,
           formlist: getpageform(config)
         }, () => {
-          _this.resetview()
+          that.resetview()
         })
       },
       onCancel() {}
diff --git a/src/views/rolemanage/index.jsx b/src/views/rolemanage/index.jsx
index e030560..bb9d731 100644
--- a/src/views/rolemanage/index.jsx
+++ b/src/views/rolemanage/index.jsx
@@ -3,7 +3,7 @@
 import { Spin, notification, Button, Table, Modal, Tree, Input, Empty } from 'antd'
 import moment from 'moment'
 import md5 from 'md5'
-import { ApiOutlined } from '@ant-design/icons'
+import { ApiOutlined, SoundOutlined } from '@ant-design/icons'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
@@ -26,12 +26,13 @@
     columns: [
       {
         title: '鑿滃崟鍚嶇О', dataIndex: 'MenuName', key: 'MenuName', align: 'center', render: (text, record) => {
-          if (record.extra) {
-            return <span style={{color: '#1890ff'}}>{text}</span>
-          } else if (record.interfaces === 'true') {
-            return <span><ApiOutlined style={{color: 'orange', marginRight: '5px'}} title="鑿滃崟涓娇鐢ㄤ簡澶栭儴鎺ュ彛" />{text}</span>
+          let className = window.backend && record.backend !== 'level1' ? 'unbackend' : ''
+          if (record.extra || this.state.appKeys.includes(record.MenuID)) {
+            return <span className={className} style={{color: '#1890ff'}}>{text}</span>
+          } else if (record.interfaces === 'true' || record.msg === 'true') {
+            return <span className={className}>{record.interfaces === 'true' ? <ApiOutlined style={{color: 'orange', marginRight: '5px'}} title="鑿滃崟涓娇鐢ㄤ簡澶栭儴鎺ュ彛" /> : null}{record.msg === 'true' ? <SoundOutlined style={{color: 'orange', marginRight: '5px'}} title="鑿滃崟涓彂閫佷簡娑堟伅" /> : null}{text}</span>
           }
-          return text
+          return <span className={className}>{text}</span>
         }
       },
       {
@@ -74,7 +75,8 @@
     trees: null,
     expandedKeys: [],
     searchkey: '',
-    appViewList: []
+    appViewList: [],
+    appKeys: []
   }
 
   oriTrees = null
@@ -118,7 +120,9 @@
         })
         return
       }
-      this.setState({appViewList: result.data || []})
+
+      let data = result.data || []
+      this.setState({appViewList: data, appKeys: data.map(item => item.keys_id)})
     })
   }
 
@@ -154,9 +158,15 @@
               let pageParam = JSON.parse(window.decodeURIComponent(window.atob(item.menus_rolelist)))
               item.nodes = pageParam
               item.interfaces = pageParam.interfaces || 'false'
+              item.msg = pageParam.msg || 'false'
+              item.backend = pageParam.backend || ''
               
               if (pageParam.type) {
                 item.type = pageParam.type
+              }
+
+              if (item.type === 'navbar' || item.type === 'im') {
+                item.backend = 'level1'
               }
 
               if (pageParam.version !== '1.0') {
@@ -186,10 +196,10 @@
         })
 
         if (!im) {
-          menus.push({nodes: '', type: 'none', extra: true, MenuID: app.instantMessage, MenuName: '鍗虫椂閫氫俊'})
+          menus.push({nodes: '', type: 'none', backend: 'level1', extra: true, MenuID: app.instantMessage, MenuName: '鍗虫椂閫氫俊'})
         }
         if (!ub) {
-          menus.push({nodes: '', type: 'none', extra: true, MenuID: app.userbind, MenuName: '鐢ㄦ埛缁戝畾'})
+          menus.push({nodes: '', type: 'none', backend: 'level1', extra: true, MenuID: app.userbind, MenuName: '鐢ㄦ埛缁戝畾'})
         }
 
         this.setState({
@@ -406,7 +416,7 @@
 
   deleteMenu = (record) => {
     const { app, appViewList } = this.state
-    const _this = this
+    const that = this
 
     let param = {
       func: 'sPC_MainMenu_Del',
@@ -447,7 +457,7 @@
                 message: '鎿嶄綔鎴愬姛锛�',
                 duration: 3
               })
-              _this.getMenuList(true)
+              that.getMenuList(true)
 
               if (_param) {
                 Api.getCloudConfig(_param).then(res => {
@@ -458,7 +468,7 @@
                       duration: 5
                     })
                   } else {
-                    _this.setState({appViewList: _appViewList})
+                    that.setState({appViewList: _appViewList})
                   }
                 })
               }
@@ -679,12 +689,12 @@
   }
 
   initTree = () => {
-    const _this = this
+    const that = this
     confirm({
       content: '鏉冮檺鏍戜細閲嶆柊鐢熸垚锛岀‘瀹氭墽琛屽悧锛�',
       onOk() {
         return new Promise(resolve => {
-          _this.getMenuList(true, resolve)
+          that.getMenuList(true, resolve)
         })
       },
       onCancel() {}
@@ -692,13 +702,13 @@
   }
 
   syncTree = () => {
-    const _this = this
+    const that = this
 
     confirm({
       content: '鍚屾浼氭牴鎹彍鍗曞垹闄ゆ垨鏂板鑺傜偣锛岀‘瀹氭墽琛屽悧锛�',
       onOk() {
         return new Promise(resolve => {
-          _this.syncMenutree(resolve)
+          that.syncMenutree(resolve)
         })
       },
       onCancel() {}
@@ -707,7 +717,7 @@
 
   saveTree = () => {
     // const { trees } = this.state
-    const _this = this
+    const that = this
 
     // if (!trees || trees.length === 0) {
     //   notification.warning({
@@ -722,7 +732,7 @@
       content: '纭畾鎵ц鍚楋紵',
       onOk() {
         return new Promise(resolve => {
-          _this.execSave(resolve)
+          that.execSave(resolve)
         })
       },
       onCancel() {}
diff --git a/src/views/rolemanage/index.scss b/src/views/rolemanage/index.scss
index 41d5905..b1b6023 100644
--- a/src/views/rolemanage/index.scss
+++ b/src/views/rolemanage/index.scss
@@ -87,4 +87,18 @@
       margin-right: 0px;
     }
   }
+  .unbackend {
+    position: relative;
+  }
+  .unbackend::before {
+    content: '';
+    display: block;
+    position: absolute;
+    width: 4px;
+    height: 4px;
+    background-color: orange;
+    border-radius: 4px;
+    top: 0px;
+    left: -5px;
+  }
 }
diff --git a/src/views/tabledesign/index.jsx b/src/views/tabledesign/index.jsx
index 6dd9642..80aa91e 100644
--- a/src/views/tabledesign/index.jsx
+++ b/src/views/tabledesign/index.jsx
@@ -9,10 +9,10 @@
 import md5 from 'md5'
 
 import Api from '@/api'
-import Utils, { setGLOBFuncs } from '@/utils/utils.js'
+import Utils from '@/utils/utils.js'
 import { langs } from '@/store/options'
 import MKEmitter from '@/utils/events.js'
-import { getTables, getFuncsAndInters, getLangTrans } from '@/utils/utils-custom.js'
+import { getTables, getFuncsAndInters, getOutMessage, getLangTrans, getAllSqls } from '@/utils/utils-custom.js'
 import SourceElement from '@/templates/zshare/dragsource'
 import asyncComponent from '@/utils/asyncComponent'
 import Source from './source'
@@ -88,6 +88,10 @@
     try {
       let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
 
+      if (param.lang) {
+        sessionStorage.setItem('lang', param.lang)
+      }
+      
       this.setState({
         MenuId: param.MenuID,
         ParentId: param.ParentId || '',
@@ -117,7 +121,7 @@
     MKEmitter.addListener('triggerMenuSave', this.triggerMenuSave)
     setTimeout(() => {
       this.getRoleFields()
-      setGLOBFuncs()
+      // setGLOBFuncs()
     }, 1000)
 
     document.onkeydown = (event) => {
@@ -536,6 +540,8 @@
     } else if (this.checklog()) {
       if (sessionStorage.getItem('langList') && !config.trans) {
 
+      } else if (config.enabled && !config.allSqls) {
+
       } else {
         notification.success({
           top: 92,
@@ -560,6 +566,52 @@
       } else if (!config.enabled && config.force && _pass) {
         config.enabled = true
         delete config.force
+      }
+
+      let long_data = ''
+      if (config.enabled) {
+        let sqls = getAllSqls(config)
+        let _t = moment().format('YYYYMMDDHHmmss')
+        let getguid = () => {
+          let uuid = ''
+          for (let i = 0; i < 18; i++) {
+            uuid += String.fromCharCode(Math.floor(Math.random() * 26) + 65)
+          }
+          uuid = uuid.replace(/minke/ig, 'MNKIE')
+          return uuid
+        }
+
+        long_data = []
+        let oriIds = {}
+        if (config.allSqls) {
+          config.allSqls.forEach(item => {
+            if (!item.md5) return
+            oriIds[item.uuid + item.md5] = item.v_id
+          })
+        }
+        
+        config.allSqls = sqls.map(item => {
+          let v_id = _t + getguid()
+
+          if (oriIds[item.uuid + item.md5]) {
+            v_id = oriIds[item.uuid + item.md5]
+          }
+          
+          long_data.push(`${md5(window.GLOB.appkey + v_id)},${item.uuid},${v_id},${window.btoa(window.encodeURIComponent(item.LText))}`)
+          
+          return {
+            uuid: item.uuid,
+            v_id: v_id,
+            type: item.type,
+            reps: item.reps,
+            md5: item.md5 || '',
+            luser: item.luser === true
+          }
+        })
+
+        long_data = long_data.join(';')
+      } else {
+        delete config.allSqls
       }
 
       let tbs = []
@@ -589,11 +641,14 @@
         let urlparam = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
         urlparam.type = 'admin'
         urlparam.MenuType = 'BaseTable'
+        urlparam.lang = sessionStorage.getItem('lang')
+
         url = window.btoa(window.encodeURIComponent(JSON.stringify(urlparam)))
         config.tbkey = key
       }
 
       let interfaces = getFuncsAndInters(config)
+      let msg = getOutMessage(config)
       let urlFields = config.urlFields ? config.urlFields.join(',') : ''
       let langSql = getLangTrans(config)
 
@@ -607,10 +662,9 @@
         EasyCode: config.easyCode || '',
         Template: 'BaseTable',
         MenuName: config.MenuName || '',
-        PageParam: JSON.stringify({Template: 'BaseTable', OpenType: config.OpenType || 'newtab', hidden: config.hidden || 'false', menuColor: config.menuColor || '', interfaces, urlFields}),
+        PageParam: JSON.stringify({Template: 'BaseTable', OpenType: config.OpenType || 'newtab', hidden: config.hidden || 'false', menuColor: config.menuColor || '', interfaces, msg, backend: 'level1', urlFields}),
         open_edition: config.open_edition,
-        // LText: '',
-        // LTexttb: '',
+        long_data: long_data,
         debug_md5: key,
         debug_url: url,
         debug_list: window.btoa(tbs),
@@ -927,8 +981,8 @@
                     <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                     <PasteBaseTable type="page" insert={this.insert}/>
                     {config ? <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} /> : null}
-                    <Button type="primary" id="save-config" onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
-                    <Button type="default" onClick={this.closeView}>鍏抽棴</Button>
+                    <Button type="primary" id="save-config" disabled={!config} onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
+                    <Button type="default" disabled={menuloading} onClick={this.closeView}>鍏抽棴</Button>
                   </div>
                 } style={{ width: '100%' }}>
                   {config && !comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
diff --git a/src/views/tabledesign/index.scss b/src/views/tabledesign/index.scss
index a3be304..84954ae 100644
--- a/src/views/tabledesign/index.scss
+++ b/src/views/tabledesign/index.scss
@@ -138,7 +138,10 @@
       > .ant-card {
         >.ant-card-head {
           margin-bottom: 0px;
-          position: relative;
+          position: sticky;
+          top: 0px;
+          z-index: 10;
+          background: #ffffff;
           .ant-card-head-title {
             color: #1890ff;
             padding: 5px 0;
diff --git a/src/views/tabledesign/popview/index.jsx b/src/views/tabledesign/popview/index.jsx
index 05a7425..dbac3df 100644
--- a/src/views/tabledesign/popview/index.jsx
+++ b/src/views/tabledesign/popview/index.jsx
@@ -219,7 +219,7 @@
                 <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                 <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={config.enabled} onChange={this.onEnabledChange} />
                 <Button type="primary" id="save-pop-config" onClick={this.submitConfig} loading={menuloading}>淇濆瓨</Button>
-                <Button type="default" onClick={this.closeView}>杩斿洖</Button>
+                <Button type="default" disabled={menuloading} onClick={this.closeView}>杩斿洖</Button>
               </div>
             } style={{ width: '100%' }}>
               {!comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
diff --git a/src/views/tabledesign/popview/index.scss b/src/views/tabledesign/popview/index.scss
index 2ea36fa..02b8796 100644
--- a/src/views/tabledesign/popview/index.scss
+++ b/src/views/tabledesign/popview/index.scss
@@ -123,7 +123,10 @@
       > .ant-card {
         >.ant-card-head {
           margin-bottom: 0px;
-          position: relative;
+          position: sticky;
+          top: 0px;
+          z-index: 10;
+          background: #ffffff;
           .ant-card-head-title {
             color: #1890ff;
             padding: 5px 0;

--
Gitblit v1.8.0