From 8d66ff34fae5b048a6b7923cc75d34f13a08be9d Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期二, 02 八月 2022 11:42:43 +0800
Subject: [PATCH] Merge branch 'develop'

---
 src/menu/components/form/formaction/index.scss                                     |    2 
 src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx                     |    2 
 src/menu/components/timeline/normal-timeline/index.jsx                             |   93 
 src/tabviews/verupmanage/actionList/index.jsx                                      |   36 
 src/tabviews/zshare/mutilform/index.scss                                           |   19 
 src/menu/components/form/dragtitle/options.jsx                                     |   26 
 src/templates/sharecomponent/cardcomponent/index.scss                              |    1 
 src/views/menudesign/printmenuform/index.jsx                                       |   50 
 src/locales/zh-CN/model.js                                                         |    7 
 src/views/systemfunc/header/index.jsx                                              |   47 
 src/views/basedesign/menuform/index.jsx                                            |   34 
 src/templates/sharecomponent/tabscomponent/tabdragelement/card.jsx                 |    2 
 src/menu/components/table/edit-table/columns/editColumn/index.jsx                  |   13 
 src/tabviews/zshare/actionList/changeuserbutton/index.jsx                          |   90 
 src/menu/datasource/verifycard/index.jsx                                           |  136 
 src/assets/css/main.scss                                                           |   24 
 src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx                   |   34 
 src/menu/components/card/cardcellcomponent/index.jsx                               |  114 
 src/menu/components/form/tab-form/index.jsx                                        |  194 
 src/mob/searchconfig/searchdragelement/card.jsx                                    |    2 
 src/views/design/header/editfirstmenu/index.scss                                   |    0 
 src/tabviews/zshare/actionList/funcMegvii/index.jsx                                |  124 
 src/templates/modalconfig/dragelement/index.scss                                   |   22 
 src/views/menudesign/index.scss                                                    |   14 
 src/pc/components/login/normal-login/signform.jsx                                  |  217 
 src/menu/components/card/prop-card/index.jsx                                       |  330 
 src/templates/zshare/customscript/index.jsx                                        |   19 
 src/menu/components/tabs/paste/index.jsx                                           |    2 
 src/views/design/header/editfirstmenu/menuform/index.jsx                           |   85 
 package-lock.json                                                                  |  347 
 src/assets/css/viewstyle.scss                                                      |   61 
 src/views/design/sidemenu/menuform/index.scss                                      |    1 
 src/menu/datasource/verifycard/index.scss                                          |  103 
 src/tabviews/zshare/topSearch/index.jsx                                            |  245 
 src/menu/components/chart/chart-custom/index.jsx                                   |   65 
 src/menu/components/form/simple-form/options.jsx                                   |  174 
 src/menu/components/card/cardsimplecomponent/options.jsx                           |   62 
 src/menu/components/form/simple-form/index.jsx                                     |  399 
 src/tabviews/custom/components/table/edit-table/index.jsx                          |   52 
 src/tabviews/zshare/mutilform/mkCascader/index.scss                                |    0 
 src/api/index.js                                                                   |   75 
 src/mob/components/formdragelement/index.scss                                      |   46 
 src/views/mobdesign/menuform/index.scss                                            |   17 
 src/templates/treepageconfig/index.scss                                            |    2 
 src/mob/mobshell/card.jsx                                                          |    7 
 src/mob/components/tabs/antv-tabs/index.scss                                       |    3 
 src/tabviews/custom/components/carousel/cardItem/index.jsx                         |    4 
 src/views/pcdesign/index.jsx                                                       |   98 
 src/mob/components/formdragelement/index.jsx                                       |    4 
 src/mob/components/tabs/tabcomponents/card.jsx                                     |    7 
 src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx                  |   67 
 src/views/systemfunc/sidemenu/index.jsx                                            |   89 
 src/menu/components/card/cardsimplecomponent/index.jsx                             |    2 
 src/setupProxy.js                                                                  |   23 
 src/tabviews/custom/components/form/step-form/index.jsx                            |  126 
 src/templates/modalconfig/source.jsx                                               |   19 
 src/menu/components/share/copycomponent/index.jsx                                  |   21 
 src/views/systemfunc/sidemenu/config.jsx                                           |    0 
 src/views/systemfunc/sidemenu/index.scss                                           |  123 
 src/locales/en-US/mob.js                                                           |    1 
 src/menu/components/form/dragtitle/card.jsx                                        |    6 
 src/pc/modulesource/option.jsx                                                     |    2 
 src/templates/zshare/editTable/index.jsx                                           |    7 
 src/templates/sharecomponent/chartgroupcomponent/dragchartview/card.jsx            |    2 
 src/tabviews/zshare/normalTable/index.jsx                                          |   61 
 src/components/thawmenu/index.jsx                                                  |  133 
 src/menu/datasource/index.jsx                                                      |    9 
 src/views/design/sidemenu/menuelement/index.scss                                   |   13 
 src/menu/components/tree/antd-tree/index.jsx                                       |   64 
 src/tabviews/zshare/actionList/normalbutton/index.jsx                              |  363 
 src/menu/modulesource/option.jsx                                                   |    2 
 src/assets/mobimg/simple-form.png                                                  |    0 
 src/templates/calendarconfig/index.scss                                            |    2 
 src/views/design/sidemenu/menuelement/card.jsx                                     |   61 
 src/views/design/sidemenu/editthdmenu/index.scss                                   |   19 
 src/templates/sharecomponent/actioncomponent/actionform/index.jsx                  |   55 
 src/templates/zshare/pasteform/index.jsx                                           |   22 
 src/menu/pastecontroller/index.jsx                                                 |    2 
 src/mob/searchconfig/settingform/index.jsx                                         |   33 
 src/views/systemfunc/index.scss                                                    |    5 
 src/menu/components/share/clockcomponent/settingform/index.jsx                     |   14 
 src/tabviews/zshare/actionList/funcMegvii/index.scss                               |    4 
 src/tabviews/verupmanage/index.jsx                                                 |    4 
 src/menu/components/search/main-search/options.jsx                                 |   56 
 src/views/printTemplate/option.js                                                  |    4 
 src/menu/components/table/normal-table/options.jsx                                 |   52 
 src/components/header/index.jsx                                                    |   16 
 src/templates/formtabconfig/index.jsx                                              |    9 
 src/templates/zshare/verifycard/callbackcustomscript/index.jsx                     |   15 
 src/tabviews/custom/components/card/cardItem/index.jsx                             |   12 
 src/views/appmanage/scriptform/index.jsx                                           |    8 
 src/mob/components/topbar/normal-navbar/options.jsx                                |   78 
 src/menu/components/code/sandbox/index.jsx                                         |   66 
 src/components/normalform/modalform/mkTable/index.jsx                              |    6 
 src/menu/bgcontroller/index.jsx                                                    |   34 
 src/tabviews/custom/components/share/normalheader/index.jsx                        |    5 
 src/templates/sharecomponent/settingcomponent/settingform/utils.jsx                |   17 
 src/templates/modalconfig/index.scss                                               |    4 
 src/components/normalform/modalform/index.jsx                                      |    9 
 src/templates/zshare/verifycard/index.jsx                                          |  359 
 src/menu/components/share/sourcecomponent/index.jsx                                |   18 
 src/mob/components/navbar/normal-navbar/index.scss                                 |   18 
 src/tabviews/zshare/actionList/printbutton/index.jsx                               |  221 
 src/tabviews/custom/components/table/edit-table/normalTable/index.scss             |    6 
 src/templates/comtableconfig/index.scss                                            |    2 
 src/templates/sharecomponent/actioncomponent/index.jsx                             |    6 
 src/menu/components/editor/braft-editor/index.jsx                                  |   56 
 package.json                                                                       |    4 
 src/tabviews/zshare/topSearch/advanceform/index.jsx                                |    2 
 src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx             |   20 
 src/menu/components/chart/antv-bar/chartcompile/index.jsx                          |   92 
 src/mob/searchconfig/index.jsx                                                     |    4 
 src/assets/img/newpage.jpg                                                         |    0 
 src/menu/components/card/cardcellcomponent/elementform/index.jsx                   |   75 
 src/menu/components/tabs/antv-tabs/index.scss                                      |    3 
 src/views/systemfunc/index.jsx                                                     |   34 
 src/tabviews/zshare/actionList/newpagebutton/index.jsx                             |   86 
 src/views/design/sidemenu/index.jsx                                                |  426 
 src/tabviews/commontable/index.jsx                                                 |   38 
 src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.jsx  |    6 
 src/components/header/loginform.jsx                                                |    8 
 src/views/basedesign/index.scss                                                    |    7 
 src/menu/components/share/normalheader/index.scss                                  |    3 
 src/tabviews/custom/components/card/cardcellList/index.jsx                         |   99 
 src/tabviews/zshare/actionList/funczip/index.jsx                                   |  441 +
 src/views/design/sidemenu/menuelement/index.jsx                                    |    0 
 src/menu/components/carousel/data-card/options.jsx                                 |    7 
 src/menu/components/card/data-card/options.jsx                                     |   27 
 src/tabviews/custom/components/table/normal-table/index.jsx                        |   56 
 src/views/design/sidemenu/thdmenuplus/index.scss                                   |  137 
 src/tabviews/custom/components/table/edit-table/normalTable/index.jsx              |   36 
 src/menu/components/group/groupcomponents/card.jsx                                 |    7 
 src/tabviews/zshare/mutilform/index.jsx                                            |  110 
 src/menu/components/share/actioncomponent/actionform/index.jsx                     |  128 
 src/tabviews/zshare/cardcomponent/index.jsx                                        |   41 
 src/menu/popview/index.jsx                                                         |   32 
 src/tabviews/zshare/mutilform/mkDatePicker/index.jsx                               |    4 
 src/tabviews/treepage/index.jsx                                                    |   15 
 src/menu/components/timeline/normal-timeline/options.jsx                           |   39 
 src/views/design/header/editfirstmenu/menuform/index.scss                          |    0 
 src/tabviews/custom/components/chart/antv-scatter/index.jsx                        |   45 
 src/components/thawmenu/index.scss                                                 |    0 
 src/components/video/index.jsx                                                     |    9 
 src/templates/zshare/verifycard/billcodeform/index.jsx                             |    8 
 src/views/design/sidemenu/index.scss                                               |    8 
 src/tabviews/custom/components/form/simple-form/index.jsx                          |  309 
 src/tabviews/subtable/index.jsx                                                    |   22 
 src/menu/components/table/edit-table/index.jsx                                     |  147 
 src/tabviews/custom/components/card/table-card/index.jsx                           |   25 
 src/menu/components/search/main-search/dategroup/index.scss                        |    1 
 src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx                 |    4 
 src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx                     |   43 
 src/templates/comtableconfig/source.jsx                                            |    4 
 src/templates/sharecomponent/columncomponent/dragcolumn/card.jsx                   |    2 
 src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx              |   15 
 src/templates/subtableconfig/index.scss                                            |    2 
 src/mob/components/topbar/normal-navbar/index.jsx                                  |    4 
 src/templates/sharecomponent/actioncomponent/dragaction/index.jsx                  |    1 
 src/pc/components/login/normal-login/index.scss                                    |   93 
 src/mob/searchconfig/groupdragelement/card.jsx                                     |    2 
 src/tabviews/custom/components/code/sand-box/index.jsx                             |    5 
 src/menu/components/table/edit-table/columns/tableIn/index.jsx                     |    4 
 src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx   |   34 
 src/menu/components/card/table-card/index.jsx                                      |  238 
 src/templates/modalconfig/settingform/index.scss                                   |    8 
 src/templates/sharecomponent/searchcomponent/settingform/index.scss                |    0 
 src/templates/zshare/verifycard/baseform/index.scss                                |   26 
 src/mob/modulesource/option.jsx                                                    |    5 
 src/tabviews/custom/components/share/normalTable/index.scss                        |    8 
 src/views/design/header/editfirstmenu/index.jsx                                    |  217 
 src/templates/modalconfig/checkCard/index.scss                                     |   47 
 src/tabviews/zshare/actionList/excelInbutton/index.jsx                             |  115 
 public/options.json                                                                |   16 
 src/templates/modalconfig/checkCard/index.jsx                                      |  100 
 src/views/pcdesign/index.scss                                                      |   14 
 src/templates/calendarconfig/source.jsx                                            |    4 
 src/views/mobdesign/index.jsx                                                      |  107 
 src/menu/datasource/verifycard/columnform/index.jsx                                |    9 
 src/mob/colorsketch/index.jsx                                                      |    3 
 src/templates/zshare/modalform/datatable/index.jsx                                 |   45 
 src/menu/components/share/actioncomponent/actionform/index.scss                    |    5 
 src/menu/components/share/actioncomponent/formconfig.jsx                           |   88 
 src/tabviews/custom/components/group/normal-group/index.jsx                        |   54 
 src/tabviews/custom/components/carousel/prop-card/index.jsx                        |   23 
 src/templates/zshare/modalform/datatable/index.scss                                |    9 
 src/menu/components/card/cardcomponent/options.jsx                                 |    6 
 src/templates/sharecomponent/searchcomponent/searchform/index.jsx                  |   53 
 src/menu/components/form/simple-form/index.scss                                    |    8 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx |   14 
 src/views/mobdesign/menuform/index.jsx                                             |   54 
 src/templates/sharecomponent/searchcomponent/index.jsx                             |   84 
 src/tabviews/custom/components/share/normalheader/index.scss                       |    6 
 src/views/mobdesign/index.scss                                                     |   14 
 src/utils/utils.js                                                                 |  107 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx              |   13 
 src/index.js                                                                       |   21 
 src/views/sso/index.jsx                                                            |   19 
 src/menu/components/search/main-search/dragsearch/index.jsx                        |   58 
 src/tabviews/custom/components/timeline/normal-timeline/index.scss                 |   58 
 src/tabviews/custom/components/share/tabtransfer/index.jsx                         |   67 
 src/templates/sharecomponent/searchcomponent/dategroup/index.scss                  |    1 
 src/templates/sharecomponent/settingcomponent/settingform/index.scss               |  104 
 src/menu/modalconfig/index.scss                                                    |    3 
 src/templates/sharecomponent/searchcomponent/settingform/index.jsx                 |  151 
 src/menu/modalconfig/index.jsx                                                     |    4 
 src/tabviews/custom/components/card/balcony/index.jsx                              |   51 
 src/templates/zshare/verifycard/baseform/index.jsx                                 |  371 +
 src/utils/option.js                                                                |   25 
 src/views/systemfunc/header/index.scss                                             |   66 
 src/templates/zshare/modalform/index.jsx                                           |  111 
 src/tabviews/formtab/index.jsx                                                     |   12 
 src/tabviews/custom/components/editor/braft-editor/index.jsx                       |    5 
 src/menu/components/card/balcony/options.jsx                                       |    2 
 src/templates/zshare/verifycard/customscript/index.jsx                             |   29 
 src/templates/sharecomponent/cardcomponent/dragdetail/card.jsx                     |    2 
 src/menu/components/chart/antv-scatter/index.jsx                                   |  138 
 src/tabviews/zshare/actionList/funczip/index.scss                                  |   26 
 src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx  |   16 
 src/tabviews/zshare/mutilform/mkNumberInput/index.jsx                              |    1 
 public/README.txt                                                                  |    4 
 src/views/design/header/editfirstmenu/dragelement/itemtypes.js                     |    0 
 src/views/interface/header/index.jsx                                               |   11 
 src/tabviews/zshare/mutilform/mkCheckCard/index.scss                               |  172 
 src/mob/components/navbar/normal-navbar/menus/drags/card.jsx                       |    2 
 src/store/reducer.js                                                               |   20 
 src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx     |    8 
 src/pc/menushell/card.jsx                                                          |    7 
 src/menu/components/carousel/prop-card/index.jsx                                   |  244 
 src/menu/components/search/main-search/dragsearch/card.jsx                         |    8 
 src/menu/components/chart/antv-pie/index.jsx                                       |   94 
 src/menu/components/tabs/tabcomponents/card.jsx                                    |    7 
 src/templates/sharecomponent/treesettingcomponent/index.jsx                        |   15 
 src/menu/datasource/verifycard/utils.jsx                                           |   17 
 src/menu/components/card/cardsimplecomponent/node-wrap/index.jsx                   |    2 
 src/tabviews/custom/components/chart/antv-bar-line/index.jsx                       |   96 
 src/tabviews/custom/components/chart/antv-dashboard/index.jsx                      |   25 
 src/views/login/loginform.jsx                                                      |    2 
 src/menu/components/share/actioncomponent/dragaction/card.jsx                      |    2 
 src/tabviews/verupmanage/subtabtable/index.jsx                                     |    3 
 src/menu/components/form/tab-form/index.scss                                       |    5 
 src/templates/comtableconfig/index.jsx                                             |  271 
 src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx                   |   10 
 src/views/basedesign/index.jsx                                                     |  253 
 src/views/design/header/editfirstmenu/dragelement/card.jsx                         |    2 
 src/views/printTemplate/print.js                                                   |    1 
 src/tabviews/zshare/topSearch/index.scss                                           |   68 
 src/views/design/sidemenu/thdmenuform/index.scss                                   |    0 
 src/views/interface/workspace/request/index.jsx                                    |   10 
 src/tabviews/custom/components/form/simple-form/index.scss                         |   53 
 src/menu/components/share/actioncomponent/index.jsx                                |   22 
 src/views/design/sidemenu/editsecmenu/index.scss                                   |    0 
 src/templates/zshare/modalform/fieldtable/index.jsx                                |   32 
 src/tabviews/formtab/actionList/index.jsx                                          |    5 
 src/menu/components/group/paste/index.jsx                                          |    2 
 src/tabviews/custom/components/tree/antd-tree/index.jsx                            |   27 
 src/tabviews/zshare/actionList/popupbutton/index.jsx                               |   61 
 src/tabviews/custom/components/tabs/antv-tabs/index.jsx                            |    1 
 src/menu/components/share/searchcomponent/index.jsx                                |    8 
 src/templates/treepageconfig/index.jsx                                             |   35 
 src/menu/components/module/voucher/index.jsx                                       |   35 
 src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx              |   11 
 src/menu/components/form/formaction/index.jsx                                      |   15 
 src/menu/components/form/step-form/index.scss                                      |    5 
 src/views/billprint/index.jsx                                                      |  164 
 src/templates/formtabconfig/dragelement/card.jsx                                   |    2 
 src/tabviews/subtabtable/index.jsx                                                 |   25 
 src/views/menudesign/index.jsx                                                     |   87 
 src/tabviews/custom/components/card/data-card/index.jsx                            |   69 
 src/locales/zh-CN/mob.js                                                           |    1 
 src/templates/calendarconfig/index.jsx                                             |   31 
 src/tabviews/verupmanage/config.jsx                                                |    8 
 src/menu/stylecontroller/styleInput/index.jsx                                      |    2 
 src/router/index.js                                                                |    4 
 src/menu/components/card/data-card/index.jsx                                       |  279 
 src/menu/components/chart/antv-dashboard/index.jsx                                 |   77 
 src/views/appmanage/index.jsx                                                      |    2 
 src/menu/components/card/cardcellcomponent/elementform/index.scss                  |    4 
 src/templates/sharecomponent/searchcomponent/index.scss                            |   50 
 src/templates/sharecomponent/settingcomponent/index.jsx                            |   27 
 src/views/design/index.jsx                                                         |   34 
 src/templates/subtableconfig/source.jsx                                            |    4 
 src/assets/mobimg/moblogin.jpg                                                     |    0 
 src/mob/modalconfig/source.jsx                                                     |   20 
 src/tabviews/calendar/index.jsx                                                    |   32 
 src/views/design/header/editfirstmenu/dragelement/index.jsx                        |   19 
 src/templates/zshare/editcomponent/index.jsx                                       |    2 
 src/views/rolemanage/index.jsx                                                     |   17 
 src/tabviews/custom/components/carousel/data-card/index.jsx                        |   23 
 src/templates/zshare/verifycard/customform/index.jsx                               |   18 
 src/tabviews/custom/components/tree/antd-tree/index.scss                           |    4 
 src/templates/sharecomponent/settingcalcomponent/index.jsx                         |   15 
 src/menu/sysinterface/settingform/utils.jsx                                        |    4 
 src/views/design/sidemenu/menuform/index.jsx                                       |   24 
 src/tabviews/custom/components/chart/custom-chart/index.jsx                        |   45 
 src/menu/components/card/balcony/index.jsx                                         |  112 
 src/tabviews/zshare/actionList/tabbutton/index.jsx                                 |   86 
 src/menu/stylecontroller/index.jsx                                                 |  155 
 src/menu/components/card/cardcellcomponent/formconfig.jsx                          |   69 
 src/tabviews/zshare/topSearch/dategroup/index.scss                                 |    1 
 src/menu/components/card/cardcellcomponent/index.scss                              |   28 
 src/menu/components/table/edit-table/options.jsx                                   |   46 
 src/templates/modalconfig/index.jsx                                                |    4 
 src/templates/sharecomponent/searchcomponent/searchform/index.scss                 |    1 
 src/tabviews/custom/components/form/step-form/index.scss                           |    0 
 src/templates/sharecomponent/settingcalcomponent/verifycard/index.jsx              |    7 
 src/menu/components/share/sourcecomponent/index.scss                               |   24 
 src/mob/modalconfig/index.jsx                                                      |    7 
 src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx               |    4 
 src/templates/sharecomponent/actioncomponent/dragaction/card.jsx                   |    2 
 src/menu/components/form/formaction/formconfig.jsx                                 |   56 
 src/tabviews/custom/components/card/prop-card/index.jsx                            |   41 
 src/views/design/sidemenu/editsecmenu/index.jsx                                    |  252 
 src/mob/components/menubar/normal-menubar/index.jsx                                |   18 
 src/store/action-type.js                                                           |    3 
 src/tabviews/custom/components/chart/antv-pie/index.jsx                            |   27 
 src/tabviews/custom/components/timeline/normal-timeline/index.jsx                  |   84 
 src/templates/subtableconfig/index.jsx                                             |   31 
 src/templates/sharecomponent/treesettingcomponent/settingform/index.jsx            |    7 
 src/templates/zshare/modalform/index.scss                                          |    1 
 src/tabviews/custom/index.jsx                                                      |  227 
 src/views/design/sidemenu/menuelement/itemtypes.js                                 |    0 
 src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx            |    8 
 src/views/appmanage/submutilform/index.jsx                                         |   37 
 src/menu/components/card/cardcellcomponent/dragaction/index.scss                   |    5 
 src/tabviews/custom/components/form/tab-form/index.scss                            |    4 
 src/views/design/header/index.jsx                                                  |  238 
 src/menu/components/form/formaction/actionform/index.jsx                           |   47 
 src/tabviews/zshare/actionList/exceloutbutton/index.jsx                            |  128 
 src/views/design/sidemenu/thdmenuform/index.jsx                                    |   57 
 src/menu/components/card/cardcellcomponent/dragaction/card.jsx                     |   23 
 src/menu/components/chart/antv-bar/index.jsx                                       |  170 
 src/store/action.js                                                                |    8 
 src/tabviews/zshare/actionList/index.jsx                                           |   14 
 src/views/appmanage/submutilform/index.scss                                        |   20 
 src/menu/components/carousel/data-card/index.jsx                                   |  184 
 src/templates/zshare/verifycard/index.scss                                         |   16 
 src/mob/components/menubar/normal-menubar/menucomponent/index.jsx                  |    2 
 src/tabviews/scriptmanage/actionList/index.jsx                                     |    1 
 src/menu/components/form/step-form/index.jsx                                       |  167 
 src/tabviews/zshare/mutilform/mkCascader/index.jsx                                 |  150 
 src/tabviews/zshare/mutilform/mkCheckCard/index.jsx                                |  112 
 src/menu/components/share/normalheader/index.jsx                                   |   15 
 src/templates/modalconfig/settingform/index.jsx                                    |  257 
 src/pc/components/login/normal-login/loginform.jsx                                 |   87 
 src/tabviews/zshare/cardcomponent/index.scss                                       |   14 
 src/menu/components/search/main-search/index.jsx                                   |    8 
 src/components/normalform/modalform/mkCheckbox/index.jsx                           |    2 
 src/tabviews/scriptmanage/index.jsx                                                |    2 
 src/tabviews/zshare/actionList/funczip/mock.js                                     |   27 
 src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx        |   10 
 src/views/login/index.jsx                                                          |   54 
 src/menu/components/card/cardsimplecomponent/node-wrap/menus/columnform/index.jsx  |    2 
 src/utils/utils-datamanage.js                                                      |  220 
 src/menu/sysinterface/settingform/simplescript/index.jsx                           |   11 
 src/views/basedesign/menuform/index.scss                                           |    0 
 src/utils/utils-custom.js                                                          |   18 
 src/menu/components/share/searchcomponent/dragsearch/card.jsx                      |    4 
 src/pc/components/login/normal-login/options.jsx                                   |  247 
 src/menu/components/table/normal-table/columns/editColumn/index.jsx                |   13 
 src/menu/components/card/data-card/index.scss                                      |    8 
 src/menu/menushell/card.jsx                                                        |    7 
 src/templates/sharecomponent/settingcomponent/settingform/index.jsx                |  142 
 src/templates/modalconfig/dragelement/card.jsx                                     |   11 
 src/views/design/sidemenu/editthdmenu/index.jsx                                    |  314 
 src/views/interface/history/index.jsx                                              |   22 
 src/views/design/index.scss                                                        |   24 
 src/tabviews/zshare/mutilform/mkFormula/index.jsx                                  |   44 
 src/views/printTemplate/mutilform/index.jsx                                        |   11 
 src/components/normalform/modalform/mkRadio/index.jsx                              |    4 
 src/views/design/sidemenu/thdmenuplus/preview/index.scss                           |    0 
 src/menu/components/share/clockcomponent/index.jsx                                 |    2 
 src/tabviews/zshare/topSearch/advanceform/index.scss                               |   20 
 src/menu/components/table/normal-table/index.jsx                                   |  265 
 src/views/design/sidemenu/thdmenuplus/index.jsx                                    |  357 +
 src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx           |    4 
 src/views/design/header/editfirstmenu/dragelement/index.scss                       |   14 
 src/views/design/header/index.scss                                                 |   10 
 src/tabviews/zshare/mutilform/mkCascader/data.json                                 |  408 +
 src/menu/datasource/verifycard/customscript/index.jsx                              |   13 
 src/locales/en-US/model.js                                                         |    7 
 src/tabviews/custom/components/share/normalTable/index.jsx                         |   45 
 src/templates/modalconfig/dragelement/index.jsx                                    |    2 
 src/menu/components/form/step-form/options.jsx                                     |   21 
 src/tabviews/zshare/mutilform/mkFormula/index.scss                                 |    0 
 src/menu/components/search/main-search/index.scss                                  |   60 
 src/tabviews/custom/components/form/tab-form/index.jsx                             |   98 
 src/views/design/sidemenu/thdmenuplus/preview/index.jsx                            |    0 
 src/templates/zshare/formconfig.jsx                                                |  327 
 src/mob/components/formdragelement/card.jsx                                        |   76 
 src/pc/components/login/normal-login/index.jsx                                     |   91 
 /dev/null                                                                          |   17 
 src/tabviews/custom/components/card/cardcellList/index.scss                        |   20 
 392 files changed, 14,564 insertions(+), 5,876 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 95bceca..33515f6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,15 +4,6 @@
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
-    "@ahooksjs/use-request": {
-      "version": "2.8.15",
-      "resolved": "https://registry.npmjs.org/@ahooksjs/use-request/-/use-request-2.8.15.tgz",
-      "integrity": "sha512-xhVaM4fyIiAMdVFuuU5i3CFUdFa/IblF+fvITVMFaUEO3w/V5tVCAF6WIA3T03n1/RPuzRkA7Ao1PFtSGtGelw==",
-      "requires": {
-        "lodash.debounce": "^4.0.8",
-        "lodash.throttle": "^4.1.1"
-      }
-    },
     "@ant-design/colors": {
       "version": "3.2.2",
       "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-3.2.2.tgz",
@@ -1838,6 +1829,19 @@
         "lodash.uniq": "^4.5.0"
       }
     },
+    "@floating-ui/core": {
+      "version": "0.7.2",
+      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.7.2.tgz",
+      "integrity": "sha512-FRVAkSNU/vGXLIsgbggcs70GkXKEOXgBBbNpYPNHSaKsCAMMd00NrjbtKTesxkdv9xm9N3+XiDlcFGY6WnatBg=="
+    },
+    "@floating-ui/dom": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.5.2.tgz",
+      "integrity": "sha512-z1DnEa7F3d8Fm/eXSbii8UEGpcjZGkQaYYUI0WpEVgD3vBfebDW8j/3ysusxonuMexoigA+A3b/fYH7sEqiwyg==",
+      "requires": {
+        "@floating-ui/core": "^0.7.2"
+      }
+    },
     "@hapi/address": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.1.tgz",
@@ -2523,52 +2527,53 @@
       "integrity": "sha512-ael2f1onoPF3vF7YqHGWy7NnafzGu+yp88BbFbP0ydoCP2xGSUzmZVw0zakPTC040Id+JQ9WeFczujMkDy6jYQ=="
     },
     "@react-spring/animated": {
-      "version": "9.3.1",
-      "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.3.1.tgz",
-      "integrity": "sha512-23YaERZ++BwZ8F8PxPFqrpOwp/JZun1Pj6aHZtPAU42j5LycBRasT9XMw7Eyr7zNFhT+rl3R3wFfd4WX6Ax+UA==",
+      "version": "9.4.5",
+      "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.4.5.tgz",
+      "integrity": "sha512-KWqrtvJSMx6Fj9nMJkhTwM9r6LIriExDRV6YHZV9HKQsaolUFppgkOXpC+rsL1JEtEvKv6EkLLmSqHTnuYjiIA==",
       "requires": {
-        "@react-spring/shared": "~9.3.0",
-        "@react-spring/types": "~9.3.0"
+        "@react-spring/shared": "~9.4.5",
+        "@react-spring/types": "~9.4.5"
       }
     },
     "@react-spring/core": {
-      "version": "9.3.1",
-      "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.3.1.tgz",
-      "integrity": "sha512-8rmfmEHLHGtF1CUiXRn64YJqsXNxv2cGX8oNnBnsuoE33c48Zc34t2VIMB4R9q5zwIUCvDBGfiEenA8ZAPxqOQ==",
+      "version": "9.4.5",
+      "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.4.5.tgz",
+      "integrity": "sha512-83u3FzfQmGMJFwZLAJSwF24/ZJctwUkWtyPD7KYtNagrFeQKUH1I05ZuhmCmqW+2w1KDW1SFWQ43RawqfXKiiQ==",
       "requires": {
-        "@react-spring/animated": "~9.3.0",
-        "@react-spring/shared": "~9.3.0",
-        "@react-spring/types": "~9.3.0"
+        "@react-spring/animated": "~9.4.5",
+        "@react-spring/rafz": "~9.4.5",
+        "@react-spring/shared": "~9.4.5",
+        "@react-spring/types": "~9.4.5"
       }
     },
     "@react-spring/rafz": {
-      "version": "9.3.1",
-      "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.3.1.tgz",
-      "integrity": "sha512-fEBMCarGVl+/2kdO+g6Zig4F+3ymwmcGN8S71gb1c7Cbbxb87kviPz8EhshfIHoiLeJPGlqwcuGbxNmZbBamvA=="
+      "version": "9.4.5",
+      "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.4.5.tgz",
+      "integrity": "sha512-swGsutMwvnoyTRxvqhfJBtGM8Ipx6ks0RkIpNX9F/U7XmyPvBMGd3GgX/mqxZUpdlsuI1zr/jiYw+GXZxAlLcQ=="
     },
     "@react-spring/shared": {
-      "version": "9.3.1",
-      "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.3.1.tgz",
-      "integrity": "sha512-jhPpxzURGo6Nty90ex1lkxmZae7w/VAbnGmb/nXcYoZwSoNR+W2aAd00iXsh2ZGz6MgoJOsc495JeG3uC7Am8A==",
+      "version": "9.4.5",
+      "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.4.5.tgz",
+      "integrity": "sha512-JhMh3nFKsqyag0KM5IIM8BQANGscTdd0mMv3BXsUiMZrcjQTskyfnv5qxEeGWbJGGar52qr5kHuBHtCjQOzniA==",
       "requires": {
-        "@react-spring/rafz": "~9.3.0",
-        "@react-spring/types": "~9.3.0"
+        "@react-spring/rafz": "~9.4.5",
+        "@react-spring/types": "~9.4.5"
       }
     },
     "@react-spring/types": {
-      "version": "9.3.1",
-      "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.3.1.tgz",
-      "integrity": "sha512-W/YMJMX35XgGGzX0gKORBTwnvQ+1loDOFN3XlZkW5fgpEY+7VkRUpPyqPWXQr3n6lHrsLmHIGdpznqZi54ACTQ=="
+      "version": "9.4.5",
+      "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.4.5.tgz",
+      "integrity": "sha512-mpRIamoHwql0ogxEUh9yr4TP0xU5CWyZxVQeccGkHHF8kPMErtDXJlxyo0lj+telRF35XNihtPTWoflqtyARmg=="
     },
     "@react-spring/web": {
-      "version": "9.3.1",
-      "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.3.1.tgz",
-      "integrity": "sha512-sisZIgFGva/Z+xKWPSfXpukF0AP3kR9ALTxlHL87fVotMUCJX5vtH/YlVcywToEFwTHKt3MpI5Wy2M+vgVEeaw==",
+      "version": "9.4.5",
+      "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.4.5.tgz",
+      "integrity": "sha512-NGAkOtKmOzDEctL7MzRlQGv24sRce++0xAY7KlcxmeVkR7LRSGkoXHaIfm9ObzxPMcPHQYQhf3+X9jepIFNHQA==",
       "requires": {
-        "@react-spring/animated": "~9.3.0",
-        "@react-spring/core": "~9.3.0",
-        "@react-spring/shared": "~9.3.0",
-        "@react-spring/types": "~9.3.0"
+        "@react-spring/animated": "~9.4.5",
+        "@react-spring/core": "~9.4.5",
+        "@react-spring/shared": "~9.4.5",
+        "@react-spring/types": "~9.4.5"
       }
     },
     "@svgr/babel-plugin-add-jsx-attribute": {
@@ -2927,11 +2932,6 @@
         "reselect": "*"
       }
     },
-    "@types/resize-observer-browser": {
-      "version": "0.1.6",
-      "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.6.tgz",
-      "integrity": "sha512-61IfTac0s9jvNtBCpyo86QeaN8qqpMGHdK0uGKCCIy2dt5/Yk84VduHIdWAcmkC5QvdkPL0p5eWYgUZtHKKUVg=="
-    },
     "@types/shallowequal": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/@types/shallowequal/-/shallowequal-1.1.1.tgz",
@@ -3014,16 +3014,16 @@
       }
     },
     "@use-gesture/core": {
-      "version": "10.2.4",
-      "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.2.4.tgz",
-      "integrity": "sha512-fk1LjCBj43BKb8NE05qkdtPOR0ngA7PwgvEqfFap/h+s7QHi+JTv4/mtDQ4wI9zzem+Ry5EKrHS/cVdBehI4wA=="
+      "version": "10.2.15",
+      "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.2.15.tgz",
+      "integrity": "sha512-R8k5GHKR6J3n48K1xiWCBSnTsxmfiVCp+MYPMhFaoHT1/oIjrFA6SeMmWDl0REwP/CpBfNdQ0FwOo/0dGjPhwA=="
     },
     "@use-gesture/react": {
-      "version": "10.2.4",
-      "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.2.4.tgz",
-      "integrity": "sha512-CbqyRj+qNbRBOGmS8OWtaOa29fxEr7bKTYHvPuMQ1wsgQDh2/DqQxbp7cFxAg6WZ8oZjppDj/EkWnw22WpIIWQ==",
+      "version": "10.2.15",
+      "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.2.15.tgz",
+      "integrity": "sha512-Hdfp17a3iHDo33jasd8GIPlIjM4wxNzn1O9apNX2VrF7X2ewzXp4wCCQ4aPqsnyvBA1WhR8KHMrBS/XWQZxTHQ==",
       "requires": {
-        "@use-gesture/core": "10.2.4"
+        "@use-gesture/core": "10.2.15"
       }
     },
     "@webassemblyjs/ast": {
@@ -3329,28 +3329,36 @@
       "integrity": "sha512-LKQwcxVWbfJj+gtdHYeq+nqUIg3+NkYS7LCMZ3hMk1eZkFjJqG5RiPsXiYZV5vOQESUZwoY0e9k9Kz/GfhoVEw=="
     },
     "ahooks": {
-      "version": "2.10.14",
-      "resolved": "https://registry.npmjs.org/ahooks/-/ahooks-2.10.14.tgz",
-      "integrity": "sha512-axWa7VoAgu7bxA56dDl0CXW4rvaQmDBiov/d3tAy0x1YNYywYMKokL8TdLgJ5zO/oXGiWmG7BxlGOQGkqE/zkQ==",
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/ahooks/-/ahooks-3.4.1.tgz",
+      "integrity": "sha512-PMxCDO6JsFdNrAyN3cW1J/2qt/vy2EJ/9KhxGOxj41hJhQddjgaBJjZKf/FrrnZmL+3yGPioZtbC4C7q7ru3yA==",
       "requires": {
-        "@ahooksjs/use-request": "^2.8.14",
-        "@types/js-cookie": "^2.2.6",
+        "@types/js-cookie": "^2.x.x",
+        "ahooks-v3-count": "^1.0.0",
         "dayjs": "^1.9.1",
-        "intersection-observer": "^0.7.0",
-        "js-cookie": "^2.2.1",
-        "lodash.debounce": "^4.0.8",
-        "lodash.isequal": "^4.5.0",
-        "lodash.throttle": "^4.1.1",
+        "intersection-observer": "^0.12.0",
+        "js-cookie": "^2.x.x",
+        "lodash": "^4.17.21",
         "resize-observer-polyfill": "^1.5.1",
         "screenfull": "^5.0.0"
       },
       "dependencies": {
         "dayjs": {
-          "version": "1.10.7",
-          "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz",
-          "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig=="
+          "version": "1.11.3",
+          "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.3.tgz",
+          "integrity": "sha512-xxwlswWOlGhzgQ4TKzASQkUhqERI3egRNqgV4ScR8wlANA/A9tZ7miXa44vTTKEq5l7vWoL5G57bG3zA+Kow0A=="
+        },
+        "lodash": {
+          "version": "4.17.21",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+          "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
         }
       }
+    },
+    "ahooks-v3-count": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/ahooks-v3-count/-/ahooks-v3-count-1.0.0.tgz",
+      "integrity": "sha512-V7uUvAwnimu6eh/PED4mCDjE7tokeZQLKlxg9lCTMPhN+NjsSbtdacByVlR1oluXQzD3MOw55wylDmQo4+S9ZQ=="
     },
     "ajv": {
       "version": "6.10.2",
@@ -3570,32 +3578,31 @@
       }
     },
     "antd-mobile": {
-      "version": "5.0.0-rc.6",
-      "resolved": "https://registry.npmjs.org/antd-mobile/-/antd-mobile-5.0.0-rc.6.tgz",
-      "integrity": "sha512-D4y/Ofo8nyG1OZwpEbwPH9k4cY5DdBXhZIxZafQ58VGC8ZY792qS1ykml75KfY/57YXn0sBgdbFkoet4TiLPZg==",
+      "version": "5.14.2",
+      "resolved": "https://registry.npmjs.org/antd-mobile/-/antd-mobile-5.14.2.tgz",
+      "integrity": "sha512-qyd+afJc+tYwCdguW/DhjTFDzpM/TYmgXVcrqSu8+jvVyRva7VuLEquosRw3oxPpjOoJ/l+Ig+p07zPS8CDHXA==",
       "requires": {
-        "@react-spring/web": "^9.3.1",
-        "@types/resize-observer-browser": "^0.1.6",
-        "@use-gesture/react": "^10.2.4",
-        "ahooks": "^2.10.14",
+        "@floating-ui/dom": "^0.5.2",
+        "@react-spring/web": "^9.4.5",
+        "@use-gesture/react": "10.2.15",
+        "ahooks": "^3.4.1",
         "antd-mobile-icons": "^0.2.2",
         "antd-mobile-v5-count": "^1.0.1",
+        "big.js": "^6.1.1",
         "classnames": "^2.3.1",
-        "dayjs": "^1.10.7",
+        "dayjs": "^1.11.3",
         "lodash": "^4.17.21",
-        "rc-field-form": "^1.22.0",
-        "rc-tooltip": "^5.1.1",
-        "staged-components": "^1.1.2",
-        "use-async-memo": "^1.2.3"
+        "rc-field-form": "^1.26.7",
+        "react-is": "^17.0.2",
+        "staged-components": "^1.1.3",
+        "tslib": "^2.4.0",
+        "use-sync-external-store": "^1.1.0"
       },
       "dependencies": {
-        "@babel/runtime": {
-          "version": "7.16.5",
-          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz",
-          "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==",
-          "requires": {
-            "regenerator-runtime": "^0.13.4"
-          }
+        "big.js": {
+          "version": "6.2.0",
+          "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.0.tgz",
+          "integrity": "sha512-paIKvJiAaOYdLt6MfnvxkDo64lTOV257XYJyX3oJnJQocIclUn+48k6ZerH/c5FxWE6DGJu1TKDYis7tqHg9kg=="
         },
         "classnames": {
           "version": "2.3.1",
@@ -3603,68 +3610,24 @@
           "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
         },
         "dayjs": {
-          "version": "1.10.7",
-          "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz",
-          "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig=="
+          "version": "1.11.3",
+          "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.3.tgz",
+          "integrity": "sha512-xxwlswWOlGhzgQ4TKzASQkUhqERI3egRNqgV4ScR8wlANA/A9tZ7miXa44vTTKEq5l7vWoL5G57bG3zA+Kow0A=="
         },
         "lodash": {
           "version": "4.17.21",
           "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
           "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
         },
-        "rc-align": {
-          "version": "4.0.11",
-          "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.11.tgz",
-          "integrity": "sha512-n9mQfIYQbbNTbefyQnRHZPWuTEwG1rY4a9yKlIWHSTbgwI+XUMGRYd0uJ5pE2UbrNX0WvnMBA1zJ3Lrecpra/A==",
-          "requires": {
-            "@babel/runtime": "^7.10.1",
-            "classnames": "2.x",
-            "dom-align": "^1.7.0",
-            "lodash": "^4.17.21",
-            "rc-util": "^5.3.0",
-            "resize-observer-polyfill": "^1.5.1"
-          }
-        },
-        "rc-tooltip": {
-          "version": "5.1.1",
-          "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.1.1.tgz",
-          "integrity": "sha512-alt8eGMJulio6+4/uDm7nvV+rJq9bsfxFDCI0ljPdbuoygUscbsMYb6EQgwib/uqsXQUvzk+S7A59uYHmEgmDA==",
-          "requires": {
-            "@babel/runtime": "^7.11.2",
-            "rc-trigger": "^5.0.0"
-          }
-        },
-        "rc-trigger": {
-          "version": "5.2.10",
-          "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.2.10.tgz",
-          "integrity": "sha512-FkUf4H9BOFDaIwu42fvRycXMAvkttph9AlbCZXssZDVzz2L+QZ0ERvfB/4nX3ZFPh1Zd+uVGr1DEDeXxq4J1TA==",
-          "requires": {
-            "@babel/runtime": "^7.11.2",
-            "classnames": "^2.2.6",
-            "rc-align": "^4.0.0",
-            "rc-motion": "^2.0.0",
-            "rc-util": "^5.5.0"
-          }
-        },
-        "rc-util": {
-          "version": "5.16.1",
-          "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.16.1.tgz",
-          "integrity": "sha512-kSCyytvdb3aRxQacS/71ta6c+kBWvM1v8/2h9d/HaNWauc3qB8pLnF20PJ8NajkNN8gb+rR1l0eWO+D4Pz+LLQ==",
-          "requires": {
-            "@babel/runtime": "^7.12.5",
-            "react-is": "^16.12.0",
-            "shallowequal": "^1.1.0"
-          }
-        },
         "react-is": {
-          "version": "16.13.1",
-          "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
-          "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+          "version": "17.0.2",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+          "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
         },
-        "regenerator-runtime": {
-          "version": "0.13.9",
-          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
-          "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
+        "tslib": {
+          "version": "2.4.0",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+          "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
         }
       }
     },
@@ -9298,6 +9261,11 @@
         "schema-utils": "^1.0.0"
       }
     },
+    "file-saver": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
+      "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
+    },
     "filename-regex": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
@@ -10783,7 +10751,7 @@
     "immediate": {
       "version": "3.0.6",
       "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
-      "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
+      "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
     },
     "immer": {
       "version": "1.10.0",
@@ -10970,9 +10938,9 @@
       }
     },
     "intersection-observer": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.7.0.tgz",
-      "integrity": "sha512-Id0Fij0HsB/vKWGeBe9PxeY45ttRiBmhFyyt/geBdDHBYNctMRTE3dC1U3ujzz3lap+hVXlEcVaB56kZP/eEUg=="
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.12.0.tgz",
+      "integrity": "sha512-2Vkz8z46Dv401zTWudDGwO7KiGHNDkMv417T5ItcNYfmvHR/1qCTVBO9vwH8zZmQ0WkA/1ARwpysR9bsnop4NQ=="
     },
     "invariant": {
       "version": "2.2.4",
@@ -12467,14 +12435,14 @@
       }
     },
     "jszip": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.6.0.tgz",
-      "integrity": "sha512-jgnQoG9LKnWO3mnVNBnfhkh0QknICd1FGSrXcgrl67zioyJ4wgx25o9ZqwNtrROSflGBCGYnJfjrIyRIby1OoQ==",
+      "version": "3.10.0",
+      "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.0.tgz",
+      "integrity": "sha512-LDfVtOLtOxb9RXkYOwPyNBTQDL4eUbqahtoY6x07GiDJHwSYvn8sHHIw8wINImV3MqbMNve2gSuM1DDqEKk09Q==",
       "requires": {
         "lie": "~3.3.0",
         "pako": "~1.0.2",
         "readable-stream": "~2.3.6",
-        "set-immediate-shim": "~1.0.1"
+        "setimmediate": "^1.0.5"
       }
     },
     "killable": {
@@ -16806,34 +16774,34 @@
       }
     },
     "rc-field-form": {
-      "version": "1.22.0",
-      "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.22.0.tgz",
-      "integrity": "sha512-IQBNeF4i64lBNLz8HbfXqUpAnrpBtfu2xU6q/wXMfdQm1AfKjiHyMNOxmiA5ZKMOOQPi+YOSzDbictfQP94hUA==",
+      "version": "1.26.7",
+      "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.26.7.tgz",
+      "integrity": "sha512-CIb7Gw+DG9R+g4HxaDGYHhOjhjQoU2mGU4y+UM2+KQ3uRz9HrrNgTspGvNynn3UamsYcYcaPWZJmiJ6VklkT/w==",
       "requires": {
-        "@babel/runtime": "^7.8.4",
-        "async-validator": "^4.0.2",
+        "@babel/runtime": "^7.18.0",
+        "async-validator": "^4.1.0",
         "rc-util": "^5.8.0"
       },
       "dependencies": {
         "@babel/runtime": {
-          "version": "7.16.5",
-          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz",
-          "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==",
+          "version": "7.18.3",
+          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz",
+          "integrity": "sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==",
           "requires": {
             "regenerator-runtime": "^0.13.4"
           }
         },
         "async-validator": {
-          "version": "4.0.7",
-          "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.0.7.tgz",
-          "integrity": "sha512-Pj2IR7u8hmUEDOwB++su6baaRi+QvsgajuFB9j95foM1N2gy5HM4z60hfusIO0fBPG5uLAEl6yCJr1jNSVugEQ=="
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.1.1.tgz",
+          "integrity": "sha512-p4DO/JXwjs8klJyJL8Q2oM4ks5fUTze/h5k10oPPKMiLe1fj3G1QMzPHNmN1Py4ycOk7WlO2DcGXv1qiESJCZA=="
         },
         "rc-util": {
-          "version": "5.16.1",
-          "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.16.1.tgz",
-          "integrity": "sha512-kSCyytvdb3aRxQacS/71ta6c+kBWvM1v8/2h9d/HaNWauc3qB8pLnF20PJ8NajkNN8gb+rR1l0eWO+D4Pz+LLQ==",
+          "version": "5.21.5",
+          "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.21.5.tgz",
+          "integrity": "sha512-ip7HqX37Cy/RDl9MlrFp+FbcKnsWZ22sF5MS5eSpYLtg5MpC0TMqGb5ukBatoOhgjnLL+eJGR6e7YAJ/dhK09A==",
           "requires": {
-            "@babel/runtime": "^7.12.5",
+            "@babel/runtime": "^7.18.3",
             "react-is": "^16.12.0",
             "shallowequal": "^1.1.0"
           }
@@ -16965,46 +16933,6 @@
           "version": "16.13.1",
           "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
           "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
-        }
-      }
-    },
-    "rc-motion": {
-      "version": "2.4.4",
-      "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.4.4.tgz",
-      "integrity": "sha512-ms7n1+/TZQBS0Ydd2Q5P4+wJTSOrhIrwNxLXCZpR7Fa3/oac7Yi803HDALc2hLAKaCTQtw9LmQeB58zcwOsqlQ==",
-      "requires": {
-        "@babel/runtime": "^7.11.1",
-        "classnames": "^2.2.1",
-        "rc-util": "^5.2.1"
-      },
-      "dependencies": {
-        "@babel/runtime": {
-          "version": "7.16.5",
-          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz",
-          "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==",
-          "requires": {
-            "regenerator-runtime": "^0.13.4"
-          }
-        },
-        "rc-util": {
-          "version": "5.16.1",
-          "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.16.1.tgz",
-          "integrity": "sha512-kSCyytvdb3aRxQacS/71ta6c+kBWvM1v8/2h9d/HaNWauc3qB8pLnF20PJ8NajkNN8gb+rR1l0eWO+D4Pz+LLQ==",
-          "requires": {
-            "@babel/runtime": "^7.12.5",
-            "react-is": "^16.12.0",
-            "shallowequal": "^1.1.0"
-          }
-        },
-        "react-is": {
-          "version": "16.13.1",
-          "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
-          "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
-        },
-        "regenerator-runtime": {
-          "version": "0.13.9",
-          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
-          "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
         }
       }
     },
@@ -18920,11 +18848,6 @@
       "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
       "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
     },
-    "set-immediate-shim": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
-      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
-    },
     "set-value": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
@@ -19605,9 +19528,9 @@
       }
     },
     "staged-components": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/staged-components/-/staged-components-1.1.2.tgz",
-      "integrity": "sha512-Fzf0qhYau/zn1pEsZSZml0b8vvGvdC+xo71jM0TE8vtM/2VjRCGLWaPb3vH3csaLv4qcoXVMMcRIeSO+HTHehQ=="
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/staged-components/-/staged-components-1.1.3.tgz",
+      "integrity": "sha512-9EIswzDqjwlEu+ymkV09TTlJfzSbKgEnNteUnZSTxkpMgr5Wx2CzzA9WcMFWBNCldqVPsHVnRGGrApduq2Se5A=="
     },
     "static-extend": {
       "version": "0.1.2",
@@ -20836,11 +20759,6 @@
       "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
       "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
     },
-    "use-async-memo": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/use-async-memo/-/use-async-memo-1.2.3.tgz",
-      "integrity": "sha512-AjZ1Wy1vfOSlaxohqoLIpauV+jwph/p0N72PBzxeEcjrZ4Mf/4o1Vav4bLaAPYuHLJZo+4M/4TIcAk7XC6H98g=="
-    },
     "use-subscription": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.4.1.tgz",
@@ -20849,6 +20767,11 @@
         "object-assign": "^4.1.1"
       }
     },
+    "use-sync-external-store": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.1.0.tgz",
+      "integrity": "sha512-SEnieB2FPKEVne66NpXPd1Np4R1lTNKfjuy3XdIoPQKYBAFdzbzSZlSn1KJZUiihQLQC5Znot4SBz1EOTBwQAQ=="
+    },
     "util": {
       "version": "0.10.3",
       "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
diff --git a/package.json b/package.json
index 19c51c9..6e1cd73 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
     "@typescript-eslint/parser": "1.13.0",
     "@uiw/react-codemirror": "^2.2.1",
     "antd": "^3.26.20",
-    "antd-mobile": "^5.0.0-rc.6",
+    "antd-mobile": "^5.14.2",
     "axios": "^0.19.0",
     "babel-eslint": "10.0.2",
     "babel-jest": "^24.8.0",
@@ -45,6 +45,7 @@
     "eslint-plugin-react-hooks": "^1.6.1",
     "exceljs": "^4.2.1",
     "file-loader": "3.0.1",
+    "file-saver": "^2.0.5",
     "fs-extra": "7.0.1",
     "html-webpack-plugin": "4.0.0-beta.5",
     "html2canvas": "^1.0.0-rc.7",
@@ -60,6 +61,7 @@
     "js-table2excel": "^1.0.3",
     "jsbarcode": "^3.11.3",
     "jssha": "^3.2.0",
+    "jszip": "^3.10.0",
     "md5": "^2.2.1",
     "mini-css-extract-plugin": "0.5.0",
     "moment": "^2.24.0",
diff --git a/public/README.txt b/public/README.txt
index 96a1b4e..b3f88fd 100644
--- a/public/README.txt
+++ b/public/README.txt
@@ -10,7 +10,9 @@
 defaultApp        -- 榛樿搴旂敤锛岀郴缁熼粯璁ゆ墦寮�鏌愪釜瀛愬簲鐢ㄦ椂闇�濉啓搴旂敤缂栫爜
 defaultLang       -- 鎵撳紑鐨勫瓙搴旂敤璇█绫诲瀷锛岄粯璁や负zh-CN
 WXAppID           -- 浣跨敤鍏紬鍙锋椂锛岀粦瀹氱殑鍏紬鍙稩D
+WXminiAppID       -- 浣跨敤寰俊灏忕▼搴忔椂锛岀粦瀹氱殑灏忕▼搴廔D
 debugger          -- 鍊间负true鏃跺紑鍚皟璇曟ā寮忥紝寮�鍚悗绉诲姩绔瓙搴旂敤涓細鏈夋帶鍒跺彴
 licenseKey        -- 璁稿彲瀵嗛挜锛屽湪鍐呴儴缃戠粶涓娇鐢ㄧ郴缁熸椂锛屼細璺宠繃epc楠岃瘉
 probation         -- 璇曠敤鏈燂紙YYYY-MM-DD锛夛紝鍦ㄦ寮忕郴缁熶腑锛岃瘯鐢ㄦ湡鍐呰皟鐢ㄧ郴缁熸帴鍙g殑鑴氭湰浼氳褰曚笅鏉�
-keepPassword      -- 璁颁綇瀵嗙爜锛岄粯璁ゅ紑鍚紝褰撳�间负"false"鏃剁鐢�
\ No newline at end of file
+keepPassword      -- 璁颁綇瀵嗙爜锛岄粯璁ゅ紑鍚紝褰撳�间负"false"鏃剁鐢�
+platforms         -- 绉诲姩绔彲浣跨敤鐨勫钩鍙扮被鍨嬶紝榛樿涓� ["H5", "wechat", "android", "ios", "wxMiniProgram"] 鍒嗗埆浠h〃H5椤甸潰銆佸井淇″叕浼楀彿銆佸畨鍗揂PP銆佽嫻鏋淎PP銆佸井淇″皬绋嬪簭
\ No newline at end of file
diff --git a/public/options.json b/public/options.json
index fa76f1c..6595475 100644
--- a/public/options.json
+++ b/public/options.json
@@ -1,18 +1,20 @@
 {
-  "appId": "201912040924165801464FF1788654BC5AC73",
-  "appkey": "20191106103859640976D6E924E464D029CF0",
-  "mainSystemApi": "http://sso.mk9h.cn/cloud/webapi/dostars",
+  "appId": "202108312122504607B107A83F55B40C98CCF",
+  "appkey": "20210831212235413F287EC3BF489424496C8",
+  "mainSystemApi": "https://sso.mk9h.cn/cloud/webapi/dostars",
   "systemType": "",
   "externalDatabase": "false",
   "lineColor": "",
   "filter": "false",
-  "defaultApp": "mk",
+  "defaultApp": "mkindustry",
   "defaultLang": "zh-CN",
-  "WXAppID": "",
+  "WXAppID": "wx4d8a34c8d4494872",
+  "WXminiAppID": "",
   "debugger": false,
   "licenseKey": "",
   "probation": "",
   "keepPassword": "true",
-  "host": "http://qingqiumarket.cn",
-  "service": "MKWMS/"
+  "platforms": ["H5", "wechat", "android", "ios", "wxMiniProgram"],
+  "host": "http://demo.mk9h.cn",
+  "service": "erp_new/"
 }
\ No newline at end of file
diff --git a/src/api/index.js b/src/api/index.js
index bdaed71..74c1c5b 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -29,7 +29,7 @@
 axios.interceptors.request.use((config) => {
   if (config.url.includes('LoginAndRedirect') || config.url.includes('getjsonresult') || config.url.includes('wxNativePay')) {
     config.data = qs.stringify(config.data)
-  } else if (config.url.includes('Upload') || config.url.includes('doupload') || config.url.includes('dopreload')) {
+  } else if (config.url.includes('doupload') || config.url.includes('dopreload')) {
     config.headers = { 'Content-Type': 'multipart/form-data' }
   } else if (config.method === 'post' && config.data) {
     config.data = JSON.stringify(config.data)
@@ -108,6 +108,69 @@
   }
 
   /**
+   * @description 寰俊涓氬姟璇锋眰
+   */
+  wxAccessToken () {
+    let _url = document.location.origin + '/' + window.GLOB.service + 'wxpay/getaccesstoken'
+    if (process.env.NODE_ENV !== 'production') {
+      _url = document.location.origin + '/wxpay/getaccesstoken'
+    }
+
+    return new Promise(resolve => {
+      if (window.GLOB.accessToken.accessTime && (parseInt(new Date().getTime() / 1000) - window.GLOB.accessToken.accessTime < 30)) {
+        resolve(window.GLOB.accessToken)
+      } else {
+        window.GLOB.accessToken = {}
+        axios({
+          url: _url,
+          method: 'get'
+        }).then(res => {
+          if (res.oa_access_token || res.mini_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)
+        })
+      }
+    })
+  }
+
+  /**
+   * @description 寰俊涓氬姟璇锋眰
+   */
+  wxNginxRequest (url, method, param) {
+    let _url = window.GLOB.location + '/' + url
+    if (process.env.NODE_ENV === 'production') {
+      _url = document.location.origin + '/' + url
+    }
+    if (/^http:\/\/(qingqiumarket.cn|cloud.mk9h.cn|sso.mk9h.cn)/.test(_url)) {
+      _url = window.GLOB.location + ':8080/' + url
+      if (process.env.NODE_ENV === 'production') {
+        _url = document.location.origin + ':8080/' + url
+      }
+    } else if (/^https:\/\/(qingqiumarket.cn|cloud.mk9h.cn|sso.mk9h.cn)/.test(_url)) {
+      _url = window.GLOB.location + ':8443/' + url
+      if (process.env.NODE_ENV === 'production') {
+        _url = document.location.origin + ':8443/' + url
+      }
+    }
+    
+    if (param) {
+      return axios({
+        url: _url,
+        method,
+        data: param
+      })
+    }
+
+    return axios({
+      url: _url,
+      method
+    })
+  }
+
+  /**
    * @description 鐩存帴璇锋眰
    * @param {Object} param 鏌ヨ鍙婃彁浜ゅ弬鏁�
    */
@@ -178,7 +241,6 @@
 
     let url = '/webapi/dologon/s_visitor_login'
     if (window.GLOB.mainSystemApi) {
-      // url = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon/s_visitor_login')
       param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon/s_visitor_login')
     }
 
@@ -213,14 +275,12 @@
     if (isCloud) {
       param.debug = 'Y'
       if (options.cloudServiceApi) {
-        // url = options.cloudServiceApi.replace(/\/webapi(.*)/, '/webapi/dologon')
         param.rduri = options.cloudServiceApi.replace(/\/webapi(.*)/, '/webapi/dologon')
       }
     } else if (window.GLOB.mainSystemApi) {
       if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'production') {
         param.linkurl = window.GLOB.linkurl
       }
-      // url = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon')
       param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon')
     }
 
@@ -872,8 +932,13 @@
    * @description 鑾峰彇寰俊鏀粯浜岀淮鐮�
    */
   getWxNativePay (param) {
+    let _url = document.location.origin + '/' + window.GLOB.service + 'wxpay/wxNativePay'
+    if (process.env.NODE_ENV !== 'production') {
+      _url = document.location.origin + '/wxpay/wxNativePay'
+    }
+
     return axios({
-      url: '/wxpay/wxNativePay',
+      url: _url,
       method: 'post',
       data: param
     })
diff --git a/src/assets/css/main.scss b/src/assets/css/main.scss
index f7c2e2b..fa34e11 100644
--- a/src/assets/css/main.scss
+++ b/src/assets/css/main.scss
@@ -469,4 +469,28 @@
       display: none;
     }
   }
+}
+.mk-button-progress {
+  position: fixed!important;
+  top: 0px;
+  left: 0px;
+  z-index: 1100;
+  width: 100vw!important;
+  .ant-progress-outer {
+    .ant-progress-inner {
+      vertical-align: top;
+      background-color: transparent;
+      .ant-progress-bg {
+        height: 4px!important;
+        background-color: var(--mk-sys-color);
+      }
+    }
+  }
+}
+
+.video-wrap {
+  overflow: hidden;
+  .video-react .video-react-poster {
+    background-size: cover;
+  }
 }
\ No newline at end of file
diff --git a/src/assets/css/viewstyle.scss b/src/assets/css/viewstyle.scss
index 6c1f120..ef70846 100644
--- a/src/assets/css/viewstyle.scss
+++ b/src/assets/css/viewstyle.scss
@@ -426,6 +426,11 @@
       border-color: $color2;
     }
   }
+  .mk-time-line-wrap.system {
+    .mk-timeline-item-tail {
+      border-color: $color2;
+    }
+  }
   .custom-tab-form-box .mk-normal-form-title.mkbtn {
     .form-title {
       color: $color6;
@@ -495,128 +500,128 @@
 }
 
 body.mk-blue-black {
-  --antd-wave-shadow-color: #1890ff;
+  --mk-sys-color: #1890ff;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65), #e6f7ff, #bae7ff, #91d5ff, #69c0ff, #40a9ff, #1890ff, #096dd9, #0050b3, #003a8c, #002766);
   @include bgblack();
 }
 body.mk-blue-white {
-  --antd-wave-shadow-color: #1890ff;
+  --mk-sys-color: #1890ff;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #e6f7ff, #bae7ff, #91d5ff, #69c0ff, #40a9ff, #1890ff, #096dd9, #0050b3, #003a8c, #002766);
 }
 body.mk-red-black {
-  --antd-wave-shadow-color: #f5222d;
+  --mk-sys-color: #f5222d;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65), #fff1f0, #ffccc7, #ffa39e, #ff7875, #ff4d4f, #f5222d, #cf1322, #a8071a, #820014, #5c0011);
   @include bgblack();
 }
 body.mk-red-white {
-  --antd-wave-shadow-color: #f5222d;
+  --mk-sys-color: #f5222d;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff1f0, #ffccc7, #ffa39e, #ff7875, #ff4d4f, #f5222d, #cf1322, #a8071a, #820014, #5c0011);
 }
 body.mk-orange-red-black {
-  --antd-wave-shadow-color: #fa541c;
+  --mk-sys-color: #fa541c;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65), #fff2e8, #ffd8bf, #ffbb96, #ff9c6e, #ff7a45, #fa541c, #d4380d, #ad2102, #871400, #610b00);
   @include bgblack();
 }
 body.mk-orange-red-white {
-  --antd-wave-shadow-color: #fa541c;
+  --mk-sys-color: #fa541c;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff2e8, #ffd8bf, #ffbb96, #ff9c6e, #ff7a45, #fa541c, #d4380d, #ad2102, #871400, #610b00);
 }
 body.mk-orange-black {
-  --antd-wave-shadow-color: #fa8c16;
+  --mk-sys-color: #fa8c16;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65), #fff7e6, #ffe7ba, #ffd591, #ffc069, #ffa940, #fa8c16, #d46b08, #ad4e00, #873800, #612500);
   @include bgblack();
 }
 body.mk-orange-white {
-  --antd-wave-shadow-color: #fa8c16;
+  --mk-sys-color: #fa8c16;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff7e6, #ffe7ba, #ffd591, #ffc069, #ffa940, #fa8c16, #d46b08, #ad4e00, #873800, #612500);
 }
 body.mk-orange-yellow-black {
-  --antd-wave-shadow-color: #faad14;
+  --mk-sys-color: #faad14;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#fffbe6, #fff1b8, #ffe58f, #ffd666, #ffc53d, #faad14, #d48806, #ad6800, #874d00, #613400);
   @include bgblack();
 }
 body.mk-orange-yellow-white {
-  --antd-wave-shadow-color: #faad14;
+  --mk-sys-color: #faad14;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fffbe6, #fff1b8, #ffe58f, #ffd666, #ffc53d, #faad14, #d48806, #ad6800, #874d00, #613400);
 }
 body.mk-yellow-black {
-  --antd-wave-shadow-color: #fadb14;
+  --mk-sys-color: #fadb14;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#feffe6, #ffffb8, #fffb8f, #fff566, #ffec3d, #fadb14, #d4b106, #ad8b00, #876800, #614700);
   @include bgblack();
 }
 body.mk-yellow-white {
-  --antd-wave-shadow-color: #fadb14;
+  --mk-sys-color: #fadb14;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #feffe6, #ffffb8, #fffb8f, #fff566, #ffec3d, #fadb14, #d4b106, #ad8b00, #876800, #614700);
 }
 body.mk-yellow-green-black {
-  --antd-wave-shadow-color: #a0d911;
+  --mk-sys-color: #a0d911;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#fcffe6, #f4ffb8, #eaff8f, #d3f261, #bae637, #a0d911, #7cb305, #5b8c00, #3f6600, #254000);
   @include bgblack();
 }
 body.mk-yellow-green-white {
-  --antd-wave-shadow-color: #a0d911;
+  --mk-sys-color: #a0d911;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fcffe6, #f4ffb8, #eaff8f, #d3f261, #bae637, #a0d911, #7cb305, #5b8c00, #3f6600, #254000);
 }
 body.mk-green-black {
-  --antd-wave-shadow-color: #52c41a;
+  --mk-sys-color: #52c41a;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#f6ffed, #d9f7be, #b7eb8f, #95de64, #73d13d, #52c41a, #389e0d, #237804, #135200, #092b00);
   @include bgblack();
 }
 body.mk-green-white {
-  --antd-wave-shadow-color: #52c41a;
+  --mk-sys-color: #52c41a;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #f6ffed, #d9f7be, #b7eb8f, #95de64, #73d13d, #52c41a, #389e0d, #237804, #135200, #092b00);
 }
 body.mk-cyan-black {
-  --antd-wave-shadow-color: #13c2c2;
+  --mk-sys-color: #13c2c2;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#e6fffb, #b5f5ec, #87e8de, #5cdbd3, #36cfc9, #13c2c2, #08979c, #006d75, #00474f, #002329);
   @include bgblack();
 }
 body.mk-cyan-white {
-  --antd-wave-shadow-color: #13c2c2;
+  --mk-sys-color: #13c2c2;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #e6fffb, #b5f5ec, #87e8de, #5cdbd3, #36cfc9, #13c2c2, #08979c, #006d75, #00474f, #002329);
 }
 body.mk-blue-purple-black {
-  --antd-wave-shadow-color: #2f54eb;
+  --mk-sys-color: #2f54eb;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#f0f5ff, #d6e4ff, #adc6ff, #85a5ff, #597ef7, #2f54eb, #1d39c4, #10239e, #061178, #030852);
   @include bgblack();
 }
 body.mk-blue-purple-white {
-  --antd-wave-shadow-color: #2f54eb;
+  --mk-sys-color: #2f54eb;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #f0f5ff, #d6e4ff, #adc6ff, #85a5ff, #597ef7, #2f54eb, #1d39c4, #10239e, #061178, #030852);
 }
 body.mk-purple-black {
-  --antd-wave-shadow-color: #722ed1;
+  --mk-sys-color: #722ed1;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#f9f0ff, #efdbff, #d3adf7, #b37feb, #9254de, #722ed1, #531dab, #391085, #22075e, #120338);
   @include bgblack();
 }
 body.mk-purple-white {
-  --antd-wave-shadow-color: #722ed1;
+  --mk-sys-color: #722ed1;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #f9f0ff, #efdbff, #d3adf7, #b37feb, #9254de, #722ed1, #531dab, #391085, #22075e, #120338);
 }
 body.mk-magenta-black {
-  --antd-wave-shadow-color: #eb2f96;
+  --mk-sys-color: #eb2f96;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#fff0f6, #ffd6e7, #ffadd2, #ff85c0, #f759ab, #eb2f96, #c41d7f, #9e1068, #780650, #520339);
   @include bgblack();
 }
 body.mk-magenta-white {
-  --antd-wave-shadow-color: #eb2f96;
+  --mk-sys-color: #eb2f96;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff0f6, #ffd6e7, #ffadd2, #ff85c0, #f759ab, #eb2f96, #c41d7f, #9e1068, #780650, #520339);
 }
 body.mk-grass-green-black {
-  --antd-wave-shadow-color: #aeb303;
+  --mk-sys-color: #aeb303;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#f2efda, #e6de97, #d9d26c, #ccc845, #bfbf22, #aeb303, #838c00, #5c6600, #374000, #151a00);
   @include bgblack();
 }
 body.mk-grass-green-white {
-  --antd-wave-shadow-color: #aeb303;
+  --mk-sys-color: #aeb303;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #f2efda, #e6de97, #d9d26c, #ccc845, #bfbf22, #aeb303, #838c00, #5c6600, #374000, #151a00);
 }
 body.mk-deep-red-black {
-  --antd-wave-shadow-color: #c32539;
+  --mk-sys-color: #c32539;
   @include viewstyle(#000000, #434343,rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.65),#fff0f0, #f5cbcb, #e89b9e, #db7077, #cf4856, #c32539, #9c162c, #750b20, #4f0315, #29010c);
   @include bgblack();
 }
 body.mk-deep-red-white {
-  --antd-wave-shadow-color: #c32539;
+  --mk-sys-color: #c32539;
   @include viewstyle(#ffffff, #ffffff, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.65), #fff0f0, #f5cbcb, #e89b9e, #db7077, #cf4856, #c32539, #9c162c, #750b20, #4f0315, #29010c);
 }
diff --git a/src/assets/img/newpage.jpg b/src/assets/img/newpage.jpg
new file mode 100644
index 0000000..fa6e8d3
--- /dev/null
+++ b/src/assets/img/newpage.jpg
Binary files differ
diff --git a/src/assets/mobimg/moblogin.jpg b/src/assets/mobimg/moblogin.jpg
new file mode 100644
index 0000000..435228e
--- /dev/null
+++ b/src/assets/mobimg/moblogin.jpg
Binary files differ
diff --git a/src/assets/mobimg/simple-form.png b/src/assets/mobimg/simple-form.png
new file mode 100644
index 0000000..c1a9478
--- /dev/null
+++ b/src/assets/mobimg/simple-form.png
Binary files differ
diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index 3bfe710..240973e 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -405,6 +405,22 @@
     this.loginRef.handleConfirm().then(param => {
       Api.getusermsg(param.username, param.password, true).then(res => {
         if (res.status) {
+          this.setState({
+            loginLoading: false
+          })
+
+          if (res.modifydate) {
+            let s = (new Date().getTime() - new Date(res.modifydate).getTime()) / (1000 * 24 * 60 * 60)
+            if (!isNaN(s) && s > 90) {
+              Modal.warning({
+                width: 520,
+                title: <span>绯荤粺妫�娴嬪埌鎮ㄧ殑璐︽埛瀛樺湪椋庨櫓锛岃鍙婃椂鍒�<a target="_blank" rel="noopener noreferrer" href="https://cloud.mk9h.cn/admin/index.html">浜戜腑蹇�</a>淇敼瀵嗙爜锛�</span>,
+                okText: '鐭ラ亾浜�'
+              })
+              return
+            }
+          }
+
           sessionStorage.setItem('CloudUserID', res.UserID)
           sessionStorage.setItem('CloudLoginUID', res.LoginUID)
           sessionStorage.setItem('CloudUserName', res.UserName)
diff --git a/src/components/header/loginform.jsx b/src/components/header/loginform.jsx
index 6e066ec..899741a 100644
--- a/src/components/header/loginform.jsx
+++ b/src/components/header/loginform.jsx
@@ -16,7 +16,8 @@
     dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
     remember: false,
     username: '',
-    password: ''
+    password: '',
+    delay: +sessionStorage.getItem('mkDelay')
   }
 
   UNSAFE_componentWillMount () {
@@ -87,10 +88,13 @@
 
   render() {
     const { getFieldDecorator } = this.props.form
-    const { remember, username, password } = this.state
+    const { remember, username, password, delay } = this.state
 
     return (
       <Form style={{margin: '0px 10px'}}>
+        {delay > 1000 ? <Form.Item style={{marginBottom: '0px', marginTop: '-10px'}}>
+          鍗囩骇鍒�<a target="_blank" rel="noopener noreferrer" href="https://cloud.mk9h.cn/admin/index.html">浼佷笟鐗�</a>锛岃幏寰楁洿楂樻晥鐨勫紑鍙戜綋楠屻��
+        </Form.Item> : null}
         <Form.Item style={{marginBottom: '0px', height: '60px'}}>
           {getFieldDecorator('username', {
             rules: [{ required: true, message: this.state.dict['login.username.empty'] }],
diff --git a/src/components/normalform/modalform/index.jsx b/src/components/normalform/modalform/index.jsx
index 6586950..8bc59c5 100644
--- a/src/components/normalform/modalform/index.jsx
+++ b/src/components/normalform/modalform/index.jsx
@@ -263,7 +263,14 @@
       } else if (item.type === 'source') {
         content = (<SourceComponent type="" placement="right"/>)
       } else if (item.type === 'table') {
-        content = (<MKTable columns={item.columns || []} actions={item.actions || []}/>)
+        content = (<MKTable tip={item.tip || ''} columns={item.columns || []} actions={item.actions || []}/>)
+      } else if (item.type === 'hint') {
+        fields.push(
+          <Col span={24} key={index}>
+            <div style={{color: '#1890ff', borderBottom: '1px solid #e9e9e9', marginBottom: '15px', paddingLeft: '10px'}}>{item.label}</div>
+          </Col>
+        )
+        return
       }
 
       if (!content) return
diff --git a/src/components/normalform/modalform/mkCheckbox/index.jsx b/src/components/normalform/modalform/mkCheckbox/index.jsx
index e8d95c8..17f37d5 100644
--- a/src/components/normalform/modalform/mkCheckbox/index.jsx
+++ b/src/components/normalform/modalform/mkCheckbox/index.jsx
@@ -34,7 +34,7 @@
     const { value, options } = this.state
 
     return (
-      <Checkbox.Group defaultValue={value} onChange={this.onChange}>
+      <Checkbox.Group style={{whiteSpace: 'nowrap'}} defaultValue={value} onChange={this.onChange}>
         {options.map(option => <Checkbox key={option.value} title={option.label} disabled={option.disabled} value={option.value}>{option.label}</Checkbox>)}
       </Checkbox.Group>
     )
diff --git a/src/components/normalform/modalform/mkRadio/index.jsx b/src/components/normalform/modalform/mkRadio/index.jsx
index 212df13..088ed0e 100644
--- a/src/components/normalform/modalform/mkRadio/index.jsx
+++ b/src/components/normalform/modalform/mkRadio/index.jsx
@@ -80,10 +80,10 @@
   }
 
   render() {
-    const { value, options } = this.state
+    const { value, options, config } = this.state
 
     return (
-      <Radio.Group style={{whiteSpace: 'nowrap'}} value={value} onChange={this.onChange}>
+      <Radio.Group style={{whiteSpace: 'nowrap'}} disabled={config.disabled} value={value} onChange={this.onChange}>
         {options.map(option => <Radio key={option.value} disabled={option.disabled} value={option.value}>{option.label}</Radio>)}
       </Radio.Group>
     )
diff --git a/src/components/normalform/modalform/mkTable/index.jsx b/src/components/normalform/modalform/mkTable/index.jsx
index c5ae0e9..ae23f22 100644
--- a/src/components/normalform/modalform/mkTable/index.jsx
+++ b/src/components/normalform/modalform/mkTable/index.jsx
@@ -75,14 +75,14 @@
 
 class EditableCell extends Component {
   getInput = (form) => {
-    const { inputType, options, min, max, unlimit } = this.props
+    const { inputType, options, min, max, unlimit, allowClear } = this.props
 
     if (inputType === 'number' && unlimit) {
       return <InputNumber onPressEnter={() => this.getValue(form)} />
     } else if (inputType === 'number') {
       return <InputNumber min={min} max={max} precision={0} onPressEnter={() => this.getValue(form)} />
     } else if (inputType === 'color') {
-      return <ColorSketch />
+      return <ColorSketch allowClear={allowClear}/>
     } else if (inputType === 'icon') {
       return <MkEditIcon allowClear/>
     } else if (inputType === 'select') {
@@ -420,6 +420,7 @@
           unlimit: col.unlimit,
           required: col.required !== false ? true : false,
           title: col.title,
+          allowClear: col.allowClear === true,
           editing: this.isEditing(record),
           onSave: this.execSave,
         }),
@@ -452,6 +453,7 @@
               })}
             />
           </DndProvider>
+          {this.props.tip ? this.props.tip : null}
         </div>
       </EditableContext.Provider>
     )
diff --git a/src/components/thawmenu/index.jsx b/src/components/thawmenu/index.jsx
new file mode 100644
index 0000000..843b8da
--- /dev/null
+++ b/src/components/thawmenu/index.jsx
@@ -0,0 +1,133 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Modal, notification, Spin } from 'antd'
+import { UnlockOutlined } from '@ant-design/icons'
+
+import Api from '@/api'
+import MKEmitter from '@/utils/events.js'
+import TransferForm from '@/templates/zshare/basetransferform'
+
+class ThawMenu extends Component {
+  static propTpyes = {
+    ParentId: PropTypes.string,
+    Type: PropTypes.string
+  }
+
+  state = {
+    visible: false,
+    targetKeys: [],
+    menulist: null,
+    loading: false
+  }
+
+  trigger = () => {
+    this.setState({
+      visible: true,
+      targetKeys: [],
+      menulist: null,
+      loading: false
+    })
+
+    Api.getSystemConfig({
+      func: 'sPC_Get_FrozenMenu',
+      ParentID: this.props.ParentId,
+      TYPE: +this.props.Type
+    }).then(res => {
+      if (res.status) {
+        this.setState({
+          menulist: res.data.map(menu => {
+            return {
+              key: menu.MenuID,
+              title: menu.MenuName
+            }
+          })
+        })
+      } else {
+        this.setState({
+          menulist: []
+        })
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  submit = () => {
+    const { targetKeys } = this.state
+    // 涓夌骇鑿滃崟瑙i櫎鍐荤粨
+    if (targetKeys.length === 0) {
+      notification.warning({
+        top: 92,
+        message: this.state.dict['form.required.select'] + this.state.dict['model.menu'],
+        duration: 5
+      })
+      return
+    }
+
+    this.setState({
+      loading: true
+    })
+    let defers = targetKeys.map(item => {
+      return new Promise((resolve) => {
+        Api.getSystemConfig({
+          func: 'sPC_MainMenu_ReDel',
+          MenuID: item
+        }).then(res => {
+          if (res.status) {
+            resolve('')
+          } else {
+            resolve(res.message)
+          }
+        })
+      })
+    })
+    Promise.all(defers).then(res => {
+      let msg = res.filter(Boolean)[0]
+      if (msg) {
+        notification.error({
+          top: 92,
+          message: msg,
+          duration: 10
+        })
+      } else {
+        this.setState({
+          loading: false,
+          visible: false,
+          targetKeys: [],
+          thawmenulist: null
+        })
+
+        MKEmitter.emit('mkUpdateMenuList')
+      }
+    })
+  }
+
+  render() {
+    const { visible, menulist, loading } = this.state
+
+    return (
+      <>
+        <UnlockOutlined onClick={this.trigger} style={{color: 'orange'}}/>
+        <Modal
+          title="瑙e喕鑿滃崟"
+          visible={visible}
+          width={600}
+          onOk={this.submit}
+          confirmLoading={loading}
+          onCancel={() => this.setState({visible: false})}
+          destroyOnClose
+        >
+          {!menulist ?
+            <Spin style={{marginLeft: 'calc(50% - 22px)', marginTop: '70px', marginBottom: '70px'}} size="large" /> :
+            <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={menulist}/>
+          }
+        </Modal>
+      </>
+    )
+  }
+}
+
+export default ThawMenu
\ No newline at end of file
diff --git a/src/templates/menuconfig/editthdmenu/menuform/index.scss b/src/components/thawmenu/index.scss
similarity index 100%
copy from src/templates/menuconfig/editthdmenu/menuform/index.scss
copy to src/components/thawmenu/index.scss
diff --git a/src/components/video/index.jsx b/src/components/video/index.jsx
index fef570b..960bbbf 100644
--- a/src/components/video/index.jsx
+++ b/src/components/video/index.jsx
@@ -15,8 +15,9 @@
 
 class Video extends Component {
   static propTpyes = {
-    card: PropTypes.object,  // 鏉$爜璁剧疆
-    value: PropTypes.any,    // 鏉$爜鍊�
+    poster: PropTypes.string,
+    card: PropTypes.object,
+    value: PropTypes.any,
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -24,11 +25,11 @@
   }
 
   render() {
-    const { value, card } = this.props
+    const { value, card, poster } = this.props
 
     return (
       <div style={{overflow: 'hidden'}}>
-        <Player poster="" autoPlay={card.autoPlay === 'true'} aspectRatio={card.aspectRatio || '16:9'} loop={card.loop === 'true'}>
+        <Player startTime={card.startTime || 0} poster={poster || ''} currentTime={10} autoPlay={card.autoPlay === 'true'} aspectRatio={card.aspectRatio || '16:9'} loop={card.loop === 'true'}>
           <source src={value} />
           <BigPlayButton position="center" />
           <ControlBar>
diff --git a/src/index.js b/src/index.js
index 7383548..215706f 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,6 +2,7 @@
 import ReactDOM from 'react-dom'
 import Route from './router'
 import { Provider } from 'react-redux'
+import md5 from 'md5'
 import store from '@/store'
 import * as serviceWorker from './serviceWorker'
 import options, { styles } from '@/store/options.js'
@@ -71,6 +72,10 @@
     GLOB.probation = false
     GLOB.watermark = config.watermark !== false
     GLOB.keepKey = config.keepPassword !== 'false'
+    GLOB.WXAppID = config.WXAppID || ''
+    GLOB.WXminiAppID = config.WXminiAppID || ''
+    GLOB.accessToken = {}
+    GLOB.mkHS = false
 
     if (config.externalDatabase !== false && config.externalDatabase !== 'false' && config.externalDatabase !== undefined) {
       GLOB.externalDatabase = config.externalDatabase ? `[${config.externalDatabase}]..` : ''
@@ -101,7 +106,7 @@
 
       // GLOB.mainSystemApi = 'https://cloud.positecgroup.com/webapi/dostars'
 
-      GLOB.mainSystemApi = 'http://sso.mk9h.cn/cloud/webapi/dostars'
+      GLOB.mainSystemApi = 'https://sso.mk9h.cn/cloud/webapi/dostars'
 
       if (GLOB.watermark) {
         GLOB.dataFormat = true
@@ -221,6 +226,20 @@
       sessionStorage.setItem('lang', config.defaultLang !== 'en-US' ? 'zh-CN' : 'en-US')
     }
 
+    let _level = 10
+    let _Mlevel = sessionStorage.getItem('Member_Level')
+
+    if (_Mlevel) {
+      if (_Mlevel === md5('mksoft' + GLOB.appkey + new Date().getFullYear() + new Date().getMonth() + 10)) {
+        _level = 10
+      } else if (_Mlevel === md5('mksoft' + GLOB.appkey + new Date().getFullYear() + new Date().getMonth() + 20)) {
+        _level = 20
+      } else if (_Mlevel === md5('mksoft' + GLOB.appkey + new Date().getFullYear() + new Date().getMonth() + 30)) {
+        _level = 30
+      }
+    }
+    GLOB.memberLevel = _level
+
     Object.defineProperty(GLOB, 'appId', {
       writable: false,
       value: GLOB.appId
diff --git a/src/locales/en-US/mob.js b/src/locales/en-US/mob.js
index f01e7e8..a284d0c 100644
--- a/src/locales/en-US/mob.js
+++ b/src/locales/en-US/mob.js
@@ -20,7 +20,6 @@
   'mob.component': '缁勪欢',
   'mob.status.open': '鍚敤',
   'mob.status.change': '鍒囨崲',
-  'mob.status.forbidden': '绂佺敤',
   'mob.basemsg': '鍩烘湰淇℃伅',
   'mob.query.delete': '纭畾鍒犻櫎鍚楋紵',
   'mob.logout.hint': '鎮ㄧ‘瀹氳閫�鍑哄悧?',
diff --git a/src/locales/en-US/model.js b/src/locales/en-US/model.js
index 12c2d81..14aaded 100644
--- a/src/locales/en-US/model.js
+++ b/src/locales/en-US/model.js
@@ -41,15 +41,12 @@
   'model.menu.level1': 'Level 1 menu',
   'model.menu.level2': 'Level 2 menu',
   'model.menu.level3': 'Level 3 menu',
-  'model.menu.close': 'Are you sure to delete the menu <<@M>> ?',
-  'model.menu.resetorder': 'Are you sure to adjust the menu sequence ?',
   'model.menu.basemsg': 'Please complete the basic information !',
   'header.menu.basedata': 'The basic information',
   'header.menu.table.add': 'Add tables',
   'header.menu.config.placeholder': 'Configuration has been modified, do you want to save configuration information ?',
   'header.menu.config.notsave': 'The menu has not been saved, please save the menu configuration first锛�',
   'header.menu.config.update': 'Menu configuration has been modified, please save锛�',
-  'model.menu.presave': 'Menu order has been adjusted, Please save!',
   'header.menu.form': 'The form',
   'header.menu.group.add': 'Add a group',
   'header.menu.search': 'Search',
@@ -88,7 +85,6 @@
   'model.form.text': 'Text',
   'header.form.description': '鎻忚堪',
   'model.form.textarea': 'Multiline text',
-  'header.form.fileupload': '鏂囦欢涓婁紶',
   'header.form.funcvar': '鍑芥暟鍙橀噺',
   'model.form.picture': 'Picture',
   'model.form.number': 'Number',
@@ -99,8 +95,6 @@
   'model.form.href': 'Link',
   'model.form.link': 'Linkage menu',
   'model.form.linkform': 'Linkage form',
-  'model.form.dateday': 'Date(Day)',
-  'model.form.dateweek': 'Date(Week)',
   'model.form.datemonth': 'Date(Month)',
   'model.form.daterange': 'Date(Range)',
   'model.form.dategroup': 'Date(Group)',
@@ -154,7 +148,6 @@
   'model.form.color': 'Color',
   'model.query.delete': '纭畾鍒犻櫎鍚�?',
   'header.form.status.change': '鐘舵�佸垏鎹�',
-  'model.status.forbidden': '绂佺敤',
   'model.status.open': '鍚敤',
   'model.form.funcbutton': 'Function button',
   'model.form.execMode': 'Mode',
diff --git a/src/locales/zh-CN/mob.js b/src/locales/zh-CN/mob.js
index 414cea3..b7f44ec 100644
--- a/src/locales/zh-CN/mob.js
+++ b/src/locales/zh-CN/mob.js
@@ -20,7 +20,6 @@
   'mob.component': '缁勪欢',
   'mob.status.open': '鍚敤',
   'mob.status.change': '鍒囨崲',
-  'mob.status.forbidden': '绂佺敤',
   'mob.basemsg': '鍩烘湰淇℃伅',
   'mob.query.delete': '纭畾鍒犻櫎鍚楋紵',
   'mob.logout.hint': '鎮ㄧ‘瀹氳閫�鍑哄悧?',
diff --git a/src/locales/zh-CN/model.js b/src/locales/zh-CN/model.js
index 59648cb..bdb362a 100644
--- a/src/locales/zh-CN/model.js
+++ b/src/locales/zh-CN/model.js
@@ -41,15 +41,12 @@
   'model.menu.level1': '涓�绾ц彍鍗�',
   'model.menu.level2': '浜岀骇鑿滃崟',
   'model.menu.level3': '涓夌骇鑿滃崟',
-  'model.menu.close': '纭畾鍒犻櫎銆夽M銆嬭彍鍗曞悧锛�',
-  'model.menu.resetorder': '纭璋冩暣鑿滃崟椤哄簭鍚楋紵',
   'model.menu.basemsg': '璇峰畬鍠勮彍鍗曞熀鏈俊鎭紒',
   'header.menu.basedata': '鍩烘湰淇℃伅',
   'header.menu.table.add': '娣诲姞琛ㄥ悕',
   'header.menu.config.placeholder': '閰嶇疆宸蹭慨鏀癸紝鏄惁淇濆瓨閰嶇疆淇℃伅锛�',
   'header.menu.config.notsave': '鑿滃崟灏氭湭淇濆瓨锛岃鍏堜繚瀛樿彍鍗曢厤缃紒',
   'header.menu.config.update': '鑿滃崟閰嶇疆宸蹭慨鏀癸紝璇蜂繚瀛橈紒',
-  'model.menu.presave': '鑿滃崟椤哄簭宸茶皟鏁达紝璇蜂繚瀛橈紒',
   'header.menu.form': '琛ㄥ崟',
   'header.menu.group.add': '娣诲姞鍒嗙粍',
   'header.menu.search': '鎼滅储',
@@ -88,7 +85,6 @@
   'model.form.text': '鏂囨湰',
   'header.form.description': '鎻忚堪',
   'model.form.textarea': '澶氳鏂囨湰',
-  'header.form.fileupload': '鏂囦欢涓婁紶',
   'header.form.funcvar': '鍑芥暟鍙橀噺',
   'model.form.picture': '鍥剧墖',
   'model.form.number': '鏁板瓧',
@@ -99,8 +95,6 @@
   'model.form.href': '閾炬帴',
   'model.form.link': '鑱斿姩鑿滃崟',
   'model.form.linkform': '鍏宠仈琛ㄥ崟',
-  'model.form.dateday': '鏃ユ湡锛堝ぉ锛�',
-  'model.form.dateweek': '鏃ユ湡锛堝懆锛�',
   'model.form.datemonth': '鏃ユ湡锛堟湀锛�',
   'model.form.daterange': '鏃ユ湡锛堝尯闂达級',
   'model.form.dategroup': '鏃ユ湡锛堢粍鍚堬級',
@@ -154,7 +148,6 @@
   'model.form.color': '棰滆壊',
   'model.query.delete': '纭畾鍒犻櫎鍚�?',
   'header.form.status.change': '鐘舵�佸垏鎹�',
-  'model.status.forbidden': '绂佺敤',
   'model.status.open': '鍚敤',
   'model.form.funcbutton': '鍔熻兘鎸夐挳',
   'model.form.execMode': '鎵ц鏂瑰紡',
diff --git a/src/menu/bgcontroller/index.jsx b/src/menu/bgcontroller/index.jsx
index 9a0f560..ba87f28 100644
--- a/src/menu/bgcontroller/index.jsx
+++ b/src/menu/bgcontroller/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Form, Select } from 'antd'
+import { Form, Select, Input } from 'antd'
 
 import asyncComponent from '@/utils/asyncComponent'
 import './index.scss'
@@ -17,6 +17,7 @@
   }
 
   state = {
+    background: '',
     backgroundColor: '',
     backgroundImage: '',
     backgroundSize: '',
@@ -34,6 +35,7 @@
     }
 
     this.setState({
+      background: config.style.background || '',
       backgroundColor: config.style.backgroundColor,
       backgroundImage: bgImg,
       backgroundSize: config.style.backgroundSize || '100%',
@@ -96,8 +98,33 @@
     this.props.updateConfig(config)
   }
 
+  changeBackground = (val) => {
+    this.setState({
+      background: val,
+    })
+
+    if (!val || /(^linear-gradient|^radial-gradient)\(.*\)$/.test(val)) {
+      let config = fromJS(this.props.config).toJS()
+      config.style.background = val
+
+      delete config.style.backgroundColor
+      delete config.style.backgroundImage
+
+      if (!val) {
+        delete config.style.background
+      }
+
+      this.setState({
+        backgroundImage: '',
+        backgroundColor: ''
+      })
+
+      this.props.updateConfig(config)
+    }
+  }
+
   render () {
-    const { backgroundColor, backgroundImage, backgroundSize, backgroundRepeat } = this.state
+    const { backgroundColor, backgroundImage, backgroundSize, backgroundRepeat, background } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -115,6 +142,9 @@
           <Form.Item className="color-control" colon={false} label="棰滆壊">
             <ColorSketch value={backgroundColor} onChange={this.changeBackgroundColor} />
           </Form.Item>
+          {window.develop === true ? <Form.Item colon={false} label="棰滆壊">
+            <Input value={background} onChange={(e) => this.changeBackground(e.target.value)} />
+          </Form.Item> : null}
           <Form.Item colon={false} label="鍥剧墖">
             <SourceComponent value={backgroundImage} type="" placement="right" onChange={this.imgChange}/>
           </Form.Item>
diff --git a/src/menu/components/card/balcony/index.jsx b/src/menu/components/card/balcony/index.jsx
index 7901247..6314c83 100644
--- a/src/menu/components/card/balcony/index.jsx
+++ b/src/menu/components/card/balcony/index.jsx
@@ -72,10 +72,8 @@
           return elem
         })
       }
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+
+      this.updateComponent(_card)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -104,15 +102,82 @@
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+    card.btnlog = []
+
+    if (window.GLOB.styling && card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌�
+      this.setState({
+        card: card
+      })
+  
+      this.props.updateConfig(card)
+      return
+    }
+
+    card.errors = []
+
+    if (card.wrap.datatype === 'static') {
+      let supModule = card.wrap.linkType === 'static' ? '' : 'has'
+
+      card.elements.forEach(cell => {
+        if (cell.eleType === 'button') {
+          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+            if (!cell.modal || cell.modal.fields.length === 0) {
+              card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+            } else if (!supModule) {
+              cell.modal.fields.forEach(m => {
+                if (m.type === 'linkMain') {
+                  card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                }
+              })
+            }
+          }
+        } else if (cell.datatype === 'dynamic' && cell.field) {
+          card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+        }
+      })
+    } else {
+      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+      } else if (!card.setting.primaryKey) {
+        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+      }
+
+      let supModule = card.wrap.linkType === 'static' ? '' : 'has'
+
+      let columns = card.columns.map(c => c.field)
+      let lowcols = card.columns.map(c => c.field.toLowerCase())
+
+      card.elements.forEach(cell => {
+        if (cell.eleType === 'button') {
+          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+            if (!cell.modal || cell.modal.fields.length === 0) {
+              card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+            } else {
+              cell.modal.fields.forEach(m => {
+                if (m.type === 'linkMain' && !supModule) {
+                  card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                } else if (m.field && card.wrap.linkType !== 'sync' && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+                  card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+                }
+              })
+            }
+          }
+        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+          card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+        }
+      })
+    }
+
     this.setState({
-      card: component
+      card: card
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
-
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   updateCard = (elements) => {
@@ -120,11 +185,7 @@
 
     let _card = {...card, elements: elements}
 
-    this.setState({
-      card: _card,
-    })
-
-    this.props.updateConfig(_card)
+    this.updateComponent(_card)
   }
 
   changeStyle = () => {
@@ -140,11 +201,7 @@
 
     let _card = {...card, style}
 
-    this.setState({
-      card: _card
-    })
-    
-    this.props.updateConfig(_card)
+    this.updateComponent(_card)
   }
 
   addElement = () => {
@@ -230,7 +287,20 @@
         </Popover>
         {card.wrap.checkAll === 'show' ? <div className="check-all"><Checkbox>鍏ㄩ��</Checkbox></div> : null}
         <CardCellComponent cards={card} cardCell={card} elements={card.elements} updateElement={this.updateCard}/>
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/card/balcony/options.jsx b/src/menu/components/card/balcony/options.jsx
index 77696ba..2beceb4 100644
--- a/src/menu/components/card/balcony/options.jsx
+++ b/src/menu/components/card/balcony/options.jsx
@@ -81,7 +81,7 @@
       type: 'cascader',
       field: 'supModule',
       label: '涓婄骇缁勪欢',
-      initval: wrap.supModule || '',
+      initval: wrap.supModule || [],
       // tooltip: '褰撲笂绾х粍浠朵笉瀛樺湪鎴栨病鏈夋潈闄愭椂锛屽綋鍓嶇粍浠朵笉鏄剧ず銆�',
       required: true,
       options: supmodules
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
index 480b17c..bc181b0 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
@@ -83,7 +83,18 @@
         <div className={'ant-mk-text line' + (card.height || '')} style={{height: card.innerHeight || 'auto'}}>{val}</div>
       )
     } else if (card.eleType === 'icon') {
-      return (<MkIcon type={card.icon}/>)
+      let fontSize = 14
+      let lineHeight = 1.5
+
+      if (card.style.fontSize) {
+        fontSize = parseInt(card.style.fontSize)
+      }
+      if (card.style.lineHeight) {
+        lineHeight = parseFloat(card.style.lineHeight)
+      }
+
+      let innerHeight = fontSize * lineHeight
+      return (<MkIcon style={{height: innerHeight}} className="ant-mk-icon" type={card.icon}/>)
     } else if (card.eleType === 'slider') {
       let val = card.value ? (card.value / card.maxValue) * 100 : 30
       return <MkProgress value={val} config={card}/>
@@ -96,9 +107,10 @@
       // )
     } else if (card.eleType === 'picture') {
       let _imagestyle = {}
+      let url = card.url !== '@icon@' ? card.url : sessionStorage.getItem('CloudAvatar')
 
-      if (card.url) {
-        _imagestyle = {backgroundImage: `url('${card.url}')`}
+      if (url) {
+        _imagestyle = {backgroundImage: `url('${url}')`}
       } else {
         let index = card.uuid.match(/\d{1}/g)
         index = index.slice(-1)[0] % 5
@@ -140,9 +152,10 @@
         </div>
       )
     } else if (card.eleType === 'video') {
+      _style.overflow = 'hidden'
       return (
-        <div>
-          <Video card={card} value={card.url || 'http://qingqiumarket.cn/mkwms/Content/images/upload/20210104/trailer.mp4'}/>
+        <div className="video-wrap">
+          <Video card={card} poster={card.posterUrl || ''} value={card.url || 'http://qingqiumarket.cn/mkwms/Content/images/upload/20210104/trailer.mp4'}/>
         </div>
       )
     } else if (card.eleType === 'currentDate') {
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/index.scss b/src/menu/components/card/cardcellcomponent/dragaction/index.scss
index ab11c7e..c7c3f27 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/index.scss
+++ b/src/menu/components/card/cardcellcomponent/dragaction/index.scss
@@ -1,4 +1,5 @@
 .card-detail-row {
+  line-height: 1.5;
   .ant-mk-text {
     font-style: inherit;
     font-weight: inherit;
@@ -122,6 +123,10 @@
     background-position: center center;
     background-repeat: no-repeat;
   }
+  .ant-mk-icon {
+    vertical-align: top;
+    line-height: inherit;
+  }
   .ant-switch-large {
     min-width: 60px;
     height: 30px;
diff --git a/src/menu/components/card/cardcellcomponent/elementform/index.jsx b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
index 9e5c2c1..2e2b905 100644
--- a/src/menu/components/card/cardcellcomponent/elementform/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
@@ -15,10 +15,10 @@
 
 const cardTypeOptions = {
   sequence: ['eleType', 'width'],
-  text: ['eleType', 'datatype', 'format', 'width', 'height', 'prefix', 'postfix', 'link', 'anchors', 'noValue', 'bgImage', 'fixStyle'],
+  text: ['eleType', 'datatype', 'format', 'width', 'height', 'prefix', 'postfix', 'link', 'anchors', 'noValue', 'bgImage', 'fixStyle', 'copyable'],
   number: ['eleType', 'datatype', 'format', 'width', 'height', 'prefix', 'postfix', 'noValue', 'fixStyle'],
   picture: ['eleType', 'datatype', 'width', 'lenWidRadio', 'maxWidth', 'link', 'noValue'],
-  video: ['eleType', 'datatype', 'width', 'aspectRatio', 'autoPlay', 'loop', 'noValue'],
+  video: ['eleType', 'datatype', 'width', 'aspectRatio', 'autoPlay', 'loop', 'startTime', 'noValue', 'posterType'],
   icon: ['eleType', 'icon', 'datatype', 'width'],
   slider: ['eleType', 'datatype', 'width', 'color', 'maxValue', 'showInfo', 'showType', 'strokeWidth', 'strokeLinecap', 'trailColor'],
   splitline: ['eleType', 'color', 'width', 'borderWidth'],
@@ -49,7 +49,7 @@
 
   UNSAFE_componentWillMount () {
     const { card, config } = this.props
-    let _options = this.getOptions(card.eleType, card.datatype, card.link, (card.showType || 'line'), card.showInfo, card.fixStyle || '')
+    let _options = this.getOptions(card.eleType, card.datatype, card.link, (card.showType || 'line'), card.showInfo, card.fixStyle || '', card.posterType || '')
     
     this.setState({
       link: card.link,
@@ -58,10 +58,11 @@
       showType: card.showType || 'line',
       showInfo: card.showInfo || 'false',
       fixStyle: card.fixStyle || '',
+      posterType: card.posterType || '',
       formlist: this.props.formlist.map(item => {
         item.hidden = !_options.includes(item.key)
 
-        if (item.key === 'field' || item.key === 'linkurl' || item.key === 'bgImage') {
+        if (item.key === 'field' || item.key === 'linkurl' || item.key === 'bgImage' || item.key === 'posterField') {
           item.options = []
           config.columns.forEach(col => {
             let label = col.label
@@ -83,6 +84,9 @@
         } else if (item.key === 'value' && card.eleType === 'slider') {
           item.type = 'number'
           item.label = '鍊�'
+        } else if (item.key === 'value' && card.eleType === 'text') {
+          item.type = 'textarea'
+          item.label = '鍐呭'
         } else if (item.key === 'format') {
           if (card.eleType === 'text') {
             item.options = item.oriOptions.filter(op => !['percent', 'thdSeparator', 'abs'].includes(op.value))
@@ -101,7 +105,7 @@
     })
   }
 
-  getOptions = (eleType, datatype, link, showType, showInfo, fixStyle) => {
+  getOptions = (eleType, datatype, link, showType, showInfo, fixStyle, posterType) => {
     let _options = fromJS(cardTypeOptions[eleType]).toJS() // 閫夐」鍒楄〃
     
     if (['text', 'number', 'picture', 'slider', 'barcode', 'qrcode', 'video'].includes(eleType)) {
@@ -114,6 +118,13 @@
         _options.push('url')
       } else {
         _options.push('value')
+      }
+      if (eleType === 'video' && posterType) {
+        if (posterType === 'dynamic') {
+          _options.push('posterField')
+        } else {
+          _options.push('posterUrl')
+        }
       }
 
       if (['text', 'picture'].includes(eleType) && link) {
@@ -152,10 +163,10 @@
    */
   selectChange = (key, value, option) => {
     const { card, config } = this.props
-    const { datatype, eleType, showType, showInfo, fixStyle } = this.state
+    const { datatype, eleType, showType, showInfo, fixStyle, posterType } = this.state
 
     if (key === 'eleType') {
-      let _options = this.getOptions(value, datatype, '', showType, showInfo, fixStyle)
+      let _options = this.getOptions(value, datatype, '', showType, showInfo, fixStyle, posterType)
       
       let _formlist = this.state.formlist.map(item => {
         item.hidden = !_options.includes(item.key)
@@ -184,6 +195,9 @@
           if (value === 'slider') {
             item.type = 'number'
             item.label = '鍊�'
+          } else if (value === 'text') {
+            item.type = 'textarea'
+            item.label = '鍐呭'
           } else {
             item.type = 'text'
             item.label = '鍐呭'
@@ -198,6 +212,8 @@
           item.required = value !== 'qrcode'
         } else if (item.key === 'showInfo') {
           item.initVal = showInfo
+        } else if (item.key === 'posterType') {
+          item.initVal = posterType
         } else if (item.key === 'fixStyle') {
           item.initVal = fixStyle
         }
@@ -229,7 +245,7 @@
         this.props.form.setFieldsValue({value: option.props.title})
       }
     } else if (key === 'link') {
-      let _options = this.getOptions(eleType, datatype, value, showType, showInfo, fixStyle)
+      let _options = this.getOptions(eleType, datatype, value, showType, showInfo, fixStyle, posterType)
       this.setState({
         link: value,
         formlist: this.state.formlist.map(item => {
@@ -244,11 +260,11 @@
   }
 
   onChange = (e, key) => {
-    const { eleType, datatype, link, showType, showInfo, fixStyle } = this.state
+    const { eleType, datatype, link, showType, showInfo, fixStyle, posterType } = this.state
     let value = e.target.value
 
     if (key === 'datatype') {
-      let _options = this.getOptions(eleType, value, link, showType, showInfo, fixStyle)
+      let _options = this.getOptions(eleType, value, link, showType, showInfo, fixStyle, posterType)
 
       this.setState({
         datatype: value,
@@ -259,7 +275,7 @@
         })
       })
     } else if (key === 'link') {
-      let _options = this.getOptions(eleType, datatype, value, showType, showInfo, fixStyle)
+      let _options = this.getOptions(eleType, datatype, value, showType, showInfo, fixStyle, posterType)
       this.setState({
         link: value,
         formlist: this.state.formlist.map(item => {
@@ -271,7 +287,7 @@
         })
       })
     } else if (key === 'showInfo') {
-      let _options = this.getOptions(eleType, datatype, link, showType, value, fixStyle)
+      let _options = this.getOptions(eleType, datatype, link, showType, value, fixStyle, posterType)
       this.setState({
         showInfo: value,
         formlist: this.state.formlist.map(item => {
@@ -283,7 +299,7 @@
       this.setState({
         showType: value
       }, () => {
-        let _options = this.getOptions(eleType, datatype, link, value, showInfo, fixStyle)
+        let _options = this.getOptions(eleType, datatype, link, value, showInfo, fixStyle, posterType)
         this.setState({
           formlist: this.state.formlist.map(item => {
             item.hidden = !_options.includes(item.key)
@@ -295,7 +311,19 @@
       this.setState({
         fixStyle: value
       }, () => {
-        let _options = this.getOptions(eleType, datatype, link, showType, showInfo, value)
+        let _options = this.getOptions(eleType, datatype, link, showType, showInfo, value, posterType)
+        this.setState({
+          formlist: this.state.formlist.map(item => {
+            item.hidden = !_options.includes(item.key)
+            return item
+          })
+        })
+      })
+    } else if (key === 'posterType') {
+      this.setState({
+        posterType: value
+      }, () => {
+        let _options = this.getOptions(eleType, datatype, link, showType, showInfo, fixStyle, value)
         this.setState({
           formlist: this.state.formlist.map(item => {
             item.hidden = !_options.includes(item.key)
@@ -361,13 +389,9 @@
                   {
                     required: item.readonly ? false : !!item.required,
                     message: this.props.dict['form.required.input'] + item.label + '!'
-                  },
-                  {
-                    max: formRule.input.max,
-                    message: formRule.input.message
                   }
                 ]
-              })(<TextArea rows={2} disabled={item.readonly} placeholder={item.placeholder || ''} />)}
+              })(<TextArea autoSize={{minRows: 2}} disabled={item.readonly} placeholder={item.placeholder || ''} />)}
             </Form.Item>
           </Col>
         )
@@ -490,9 +514,18 @@
           </Col>
         )
       } else if (item.type === 'file') {
+        let type = this.state.eleType
+        if (item.key === 'posterUrl') {
+          type = 'picture'
+        }
         fields.push(
           <Col span={12} key={index}>
-            <Form.Item label={item.label}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" title={item.tooltip}>
+                <QuestionCircleOutlined className="mk-form-tip" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
               {getFieldDecorator(item.key, {
                 initialValue: item.initVal,
                 rules: [
@@ -502,7 +535,7 @@
                   }
                 ]
               })(
-                <SourceComponent type={this.state.eleType} />
+                <SourceComponent type={type} />
               )}
             </Form.Item>
           </Col>
diff --git a/src/menu/components/card/cardcellcomponent/elementform/index.scss b/src/menu/components/card/cardcellcomponent/elementform/index.scss
index 2fc1e1b..090ce2d 100644
--- a/src/menu/components/card/cardcellcomponent/elementform/index.scss
+++ b/src/menu/components/card/cardcellcomponent/elementform/index.scss
@@ -2,11 +2,11 @@
   min-height: 190px;
 
   >.ant-row {
-    >.ant-col {
+    >.ant-col:not(.textarea) {
       height: 65px;
     }
     .ant-col.textarea {
-      height: 80px;
+      min-height: 80px;
       .ant-form-item-label {
         width: 14.2%;
       }
diff --git a/src/menu/components/card/cardcellcomponent/formconfig.jsx b/src/menu/components/card/cardcellcomponent/formconfig.jsx
index 863b7e1..2e65cfb 100644
--- a/src/menu/components/card/cardcellcomponent/formconfig.jsx
+++ b/src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -43,16 +43,8 @@
     }
   }
 
-  let dataTypes = [
-    { value: 'dynamic', text: '鍔ㄦ��' },
-    { value: 'static', text: '闈欐��' }
-  ]
   let tooltip = ''
   if (cardCell.$cardType === 'extendCard') {
-    // card.datatype = 'static'
-    // dataTypes = [
-    //   { value: 'static', text: '闈欐��' }
-    // ]
     tooltip = '鍦ㄦ墿灞曞崱鐗囦腑锛屽姩鎬佹暟鎹樉绀哄�间负鑾峰彇鍒扮殑绗竴琛屾暟鎹��'
   }
 
@@ -79,7 +71,10 @@
       initVal: card.datatype || 'static',
       tooltip,
       required: true,
-      options: dataTypes
+      options: [
+        { value: 'dynamic', text: '鍔ㄦ��' },
+        { value: 'static', text: '闈欐��' }
+      ]
     },
     {
       type: 'select',
@@ -95,13 +90,14 @@
       min: 0,
       label: '鍐呭',
       initVal: card.value || '',
-      tooltip: '鏂囨湰绫诲瀷锛屼細鏇挎崲鍐呭涓殑@username@銆丂fullName@銆丂login_city@銆�',
+      tooltip: '鏂囨湰绫诲瀷锛屼細鏇挎崲鍐呭涓殑@username@銆丂fullName@銆丂mk_city@銆丂appname@銆�',
       required: true
     },
     {
       type: 'file',
       key: 'url',
       label: '鍥剧墖/鏂囦欢',
+      tooltip: '浣跨敤闈欐�佸浘鐗囨椂锛孈icon@浠h〃澶村儚銆�',
       initVal: card.url || '',
       maxfile: 1,
       required: true
@@ -129,6 +125,42 @@
       ]
     },
     {
+      type: 'number',
+      key: 'startTime',
+      precision: 0,
+      label: '寮�濮嬫椂闂�',
+      initVal: card.startTime || 0,
+      tooltip: '瑙嗛寮�濮嬫挱鏀剧殑鏃堕棿锛岀敤浜庤皟鏁磋棰戝垵濮嬪寲灞曠ず鐨勭晫闈€��',
+      required: false
+    },
+    {
+      type: 'radio',
+      key: 'posterType',
+      label: '棰勮鍥�',
+      initVal: card.posterType || '',
+      required: false,
+      options: [
+        { value: '', text: '鏃�' },
+        { value: 'dynamic', text: '鍔ㄦ��' },
+        { value: 'static', text: '闈欐��' }
+      ]
+    },
+    {
+      type: 'file',
+      key: 'posterUrl',
+      label: '棰勮鍦板潃',
+      initVal: card.posterUrl || '',
+      maxfile: 1,
+      required: true
+    },
+    {
+      type: 'select',
+      key: 'posterField',
+      label: '棰勮鍦板潃',
+      initVal: card.posterField || '',
+      required: true
+    },
+    {
       type: 'select',
       key: 'format',
       label: '鏍煎紡鍖�',
@@ -141,6 +173,8 @@
         { value: 'thdSeparator', text: '鍗冨垎浣�' },
         { value: 'abs', text: '缁濆鍊�' },
         { value: 'YYYY-MM-DD', text: 'YYYY-MM-DD' },
+        { value: 'YYYY-MM-DD HH:mm', text: 'YYYY-MM-DD HH:mm' },
+        { value: 'YYYY-MM-DD HH:mm:ss', text: 'YYYY-MM-DD HH:mm:ss' },
         { value: 'MM鏈圖D鏃�', text: 'MM鏈圖D鏃�' },
         { value: 'YYYY骞碝M鏈圖D鏃�', text: 'YYYY骞碝M鏈圖D鏃�' },
         { value: 'HH:mm', text: '鏃跺垎锛堜緥锛�16:57锛�' },
@@ -311,7 +345,7 @@
       min: 1,
       max: 10,
       label: '楂樺害(琛�)',
-      initVal: card.height,
+      initVal: card.height !== undefined ? card.height : 1,
       tooltip: '鍐呭鏄剧ず琛屾暟锛屽�间负绌烘椂楂樺害鑷�傚簲锛屾敞锛氳嚜閫傚簲楂樺害浠呭湪璁剧疆鍗$墖楂樺害鍚庢湁鏁堛��',
       required: false
     },
@@ -330,6 +364,7 @@
       key: 'anchors',
       label: '璺宠浆閿氱偣',
       initVal: card.anchors || [],
+      tooltip: sessionStorage.getItem('appType') === 'mob' ? '娉細灏忕▼搴忎腑鏃犳晥' : '',
       required: false,
       options: anchors
     },
@@ -556,6 +591,18 @@
       ]
     },
     {
+      type: 'radio',
+      key: 'copyable',
+      label: '鍙鍒�',
+      initVal: card.copyable || 'false',
+      tooltip: '鍏冪礌鏄惁鍙鍒讹紝澶嶅埗鍐呭涓嶅寘鎷墠缂�涓庡悗缂�銆�',
+      required: false,
+      options: [
+        { value: 'true', text: '鏄�' },
+        { value: 'false', text: '鍚�' }
+      ]
+    },
+    {
       type: 'number',
       key: 'fixSize',
       min: 10,
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index c3a5a91..380ef62 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -157,6 +157,8 @@
       }
     } else if (element.eleType === 'picture') {
       options = ['border', 'margin']
+    } else if (element.eleType === 'text') {
+      options[0] = 'font2'
     } else if (element.eleType === 'slider') {
       options = ['padding', 'margin']
     } else if (element.eleType === 'splitline') {
@@ -312,7 +314,17 @@
       menulist = []
     }
 
-    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, cards.uuid) || []
+    let supId = ''
+    if (cards.setting && cards.setting.supModule) {
+      let pid = cards.setting.supModule[cards.setting.supModule.length - 1]
+      if (pid && pid !== 'empty') {
+        supId = pid
+      } else {
+        supId = ''
+      }
+    }
+
+    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, cards.uuid, supId) || []
     let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, cards.uuid) || []
 
     this.setState({
@@ -415,14 +427,17 @@
     this.actionFormRef.handleConfirm().then(res => {
       let _elements = elements.map(cell => {
         if (cell.uuid === res.uuid) {
-          res = {...cell, ...res}
+          res.eleType = cell.eleType || null
+          res.style = cell.style || null
+          res.modal = cell.modal || null
+          // res = {...cell, ...res}
 
-          if (!res.control) {
-            delete res.controlField
-            delete res.controlVal
-          }
+          // if (!res.control) {
+          //   delete res.controlField
+          //   delete res.controlVal
+          // }
           
-          delete res.focus
+          // delete res.focus
 
           if (res.OpenType === 'form') {
             if (cell.OpenType !== 'form') {
@@ -458,7 +473,7 @@
    * @description 鎸夐挳鍒犻櫎
    */
   deleteElement = (card) => {
-    const { cards, cardCell, side } = this.props
+    const { cardCell, side } = this.props
     const { dict, elements, appType } = this.state
     let _this = this
 
@@ -471,7 +486,7 @@
           card.$parentId = cardCell.uuid
           card.$side = side || ''
 
-          MKEmitter.emit('logButton', cards.uuid, card)
+          // MKEmitter.emit('logButton', cards.uuid, card)
         }
 
         _this.setState({
@@ -497,6 +512,7 @@
       profVisible: true,
       card: element
     })
+    MKEmitter.emit('modalStatus', '楠岃瘉淇℃伅')
   }
 
   /**
@@ -520,6 +536,8 @@
       }, () => {
         this.props.updateElement(_elements)
       })
+
+      MKEmitter.emit('modalStatus', false)
     })
   }
 
@@ -544,6 +562,8 @@
     } else if (btn.OpenType === 'popview') {
       MKEmitter.emit('changePopview', cards, btn)
     } else if (btn.OpenType === 'innerpage' && btn.pageTemplate === 'linkpage') {
+      MKEmitter.emit('changeEditMenu', {MenuID: btn.linkmenu})
+    } else if (btn.OpenType === 'funcbutton' && (btn.funcType === 'copyurl' || btn.funcType === 'scan') && btn.linkmenu) {
       MKEmitter.emit('changeEditMenu', {MenuID: btn.linkmenu})
     } else {
       this.handleElement(item)
@@ -630,6 +650,44 @@
     })
   }
 
+  getVerify = (card) => {
+    const { cards } = this.props
+    const { dict } = this.state
+
+    if (!card) return null
+
+    if (['pop', 'prompt', 'exec'].includes(card.OpenType)) {
+      return <VerifyCard
+        card={card}
+        dict={dict}
+        config={cards}
+        columns={cards.columns}
+        wrappedComponentRef={(inst) => this.verifyRef = inst}
+      />
+    } else if (card.OpenType === 'excelIn') {
+      return <VerifyExcelIn
+        card={card}
+        dict={dict}
+        columns={cards.columns}
+        wrappedComponentRef={(inst) => this.verifyRef = inst}
+      />
+    } else if (card.OpenType === 'excelOut') {
+      return <VerifyExcelOut
+        card={card}
+        dict={dict}
+        config={cards}
+        wrappedComponentRef={(inst) => this.verifyRef = inst}
+      />
+    } else if (card.OpenType === 'funcbutton' && card.funcType === 'print') {
+      return <VerifyPrint
+        card={card}
+        dict={dict}
+        columns={cards.columns}
+        wrappedComponentRef={(inst) => this.verifyRef = inst}
+      />
+    }
+  }
+
   render() {
     const { cards, cardCell } = this.props
     const { elements, visible, actvisible, profVisible, card, dict, record } = this.state
@@ -673,7 +731,7 @@
           <Modal
             title="鎸夐挳路缂栬緫"
             visible={actvisible}
-            width={800}
+            width={850}
             maskClosable={false}
             onCancel={this.editModalCancel}
             footer={[
@@ -707,46 +765,16 @@
               if (this.verifyRef.handleCancel) {
                 this.verifyRef.handleCancel().then(() => {
                   this.setState({ profVisible: false })
+                  MKEmitter.emit('modalStatus', false)
                 })
               } else {
                 this.setState({ profVisible: false })
+                MKEmitter.emit('modalStatus', false)
               }
             }}
             destroyOnClose
           >
-            {card && !card.execMode && card.OpenType !== 'excelIn' && card.OpenType !== 'excelOut' ?
-              <VerifyCard
-                card={card}
-                dict={dict}
-                config={cards}
-                columns={cards.columns}
-                wrappedComponentRef={(inst) => this.verifyRef = inst}
-              /> : null
-            }
-            {card && card.execMode ?
-              <VerifyPrint
-                card={card}
-                dict={dict}
-                columns={cards.columns}
-                wrappedComponentRef={(inst) => this.verifyRef = inst}
-              /> : null
-            }
-            {card && card.OpenType === 'excelIn' ?
-              <VerifyExcelIn
-                card={card}
-                dict={dict}
-                columns={cards.columns}
-                wrappedComponentRef={(inst) => this.verifyRef = inst}
-              /> : null
-            }
-            {card && card.OpenType === 'excelOut' ?
-              <VerifyExcelOut
-                card={card}
-                dict={dict}
-                config={cards}
-                wrappedComponentRef={(inst) => this.verifyRef = inst}
-              /> : null
-            }
+            {this.getVerify(card)}
           </Modal>
         </div>
       </div>
diff --git a/src/menu/components/card/cardcellcomponent/index.scss b/src/menu/components/card/cardcellcomponent/index.scss
index df43e0a..d7a9616 100644
--- a/src/menu/components/card/cardcellcomponent/index.scss
+++ b/src/menu/components/card/cardcellcomponent/index.scss
@@ -30,3 +30,31 @@
     box-shadow: 0px 0px 2px #1890ff;
   }
 }
+.model-table-action-verify-modal {
+  .ant-modal {
+    top: 50px;
+    padding-bottom: 5px;
+    .ant-modal-body {
+      max-height: calc(100vh - 190px);
+      min-height: calc(100vh - 300px);
+      overflow-y: auto;
+      .ant-empty {
+        margin: 5vh 8px;
+      }
+    }
+    .ant-modal-body::-webkit-scrollbar {
+      width: 7px;
+    }
+    .ant-modal-body::-webkit-scrollbar-thumb {
+      border-radius: 5px;
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+      background: rgba(0, 0, 0, 0.13);
+    }
+    .ant-modal-body::-webkit-scrollbar-track {
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
+      border-radius: 3px;
+      border: 1px solid rgba(0, 0, 0, 0.07);
+      background: rgba(0, 0, 0, 0);
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/menu/components/card/cardcomponent/options.jsx b/src/menu/components/card/cardcomponent/options.jsx
index dfbcf7c..d36487f 100644
--- a/src/menu/components/card/cardcomponent/options.jsx
+++ b/src/menu/components/card/cardcomponent/options.jsx
@@ -154,10 +154,10 @@
       initval: setting.open || 'blank',
       required: false,
       options: [
-        {value: 'blank', label: '鏂扮獥鍙�'},
-        {value: 'self', label: '褰撳墠绐楀彛'},
+        {value: 'blank', label: appType !== 'mob' ? '鏂扮獥鍙�' : '鏂伴〉闈�'},
+        {value: 'self', label: appType !== 'mob' ? '褰撳墠绐楀彛' : '褰撳墠椤甸潰'},
       ],
-      forbid: appType !== 'pc'
+      forbid: appType !== 'pc' && appType !== 'mob'
     },
     {
       type: 'radio',
diff --git a/src/menu/components/card/cardsimplecomponent/index.jsx b/src/menu/components/card/cardsimplecomponent/index.jsx
index 07f6588..eea36ff 100644
--- a/src/menu/components/card/cardsimplecomponent/index.jsx
+++ b/src/menu/components/card/cardsimplecomponent/index.jsx
@@ -151,7 +151,7 @@
           })
         }
       })
-      return getTableSetting(card.setting, cards.columns, buttons)
+      return getTableSetting(card.setting, cards.columns, buttons, cards.action)
     } else {
       return getCarouselSetting(card.setting, cards.subtype === 'propcard')
     }
diff --git a/src/menu/components/card/cardsimplecomponent/node-wrap/index.jsx b/src/menu/components/card/cardsimplecomponent/node-wrap/index.jsx
index e39387d..1b1c12f 100644
--- a/src/menu/components/card/cardsimplecomponent/node-wrap/index.jsx
+++ b/src/menu/components/card/cardsimplecomponent/node-wrap/index.jsx
@@ -53,7 +53,7 @@
           title="鑺傜偣缁�"
           wrapClassName="nodes-field-modal"
           visible={visible}
-          width={900}
+          width={950}
           maskClosable={false}
           onOk={this.submit}
           onCancel={() => { this.setState({ visible: false })}}
diff --git a/src/menu/components/card/cardsimplecomponent/node-wrap/menus/columnform/index.jsx b/src/menu/components/card/cardsimplecomponent/node-wrap/menus/columnform/index.jsx
index 478ed52..8b50c97 100644
--- a/src/menu/components/card/cardsimplecomponent/node-wrap/menus/columnform/index.jsx
+++ b/src/menu/components/card/cardsimplecomponent/node-wrap/menus/columnform/index.jsx
@@ -61,7 +61,7 @@
           <Col span={8}>
             <Form.Item label="棰滆壊">
               {getFieldDecorator('color', {
-                initialValue: '',
+                initialValue: '#e8e8e8',
                 rules: [
                   {
                     required: true,
diff --git a/src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx b/src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx
index 13230b0..31a0452 100644
--- a/src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx
+++ b/src/menu/components/card/cardsimplecomponent/node-wrap/menus/index.jsx
@@ -27,7 +27,7 @@
         editable: true,
         unique: true,
         required: false,
-        width: '35%'
+        width: '25%'
       },
       {
         title: '棰滆壊',
@@ -35,7 +35,8 @@
         inputType: 'color',
         editable: true,
         required: true,
-        width: '35%'
+        width: '25%',
+        render: (text, record) => <span style={{display: 'inline-block', width: '40px', height: '25px', background: text}}></span>
       },
       {
         title: '鍥炬爣',
@@ -43,9 +44,19 @@
         inputType: 'icon',
         editable: true,
         required: false,
-        width: '35%',
+        width: '25%',
         render: (text, record) => record.icon ? <MkIcon type={record.icon}/> : ''
-      }
+      },
+      {
+        title: '杩炴帴绾�',
+        dataIndex: 'linecolor',
+        inputType: 'color',
+        editable: true,
+        required: false,
+        allowClear: true,
+        width: '25%',
+        render: (text, record) => text ? <span style={{display: 'inline-block', width: '40px', height: '25px', background: text}}></span> : null
+      },
     ]
   }
 
@@ -77,6 +88,7 @@
     return (
       <div style={{minHeight: '250px'}}>
         <ColumnForm menus={menus} columnChange={this.columnChange}/>
+        <p style={{position: 'absolute', fontSize: '12px', transform: 'translate(0px, -20px)'}}>杩炴帴绾垮湪妯悜鏃堕棿杞翠腑鏈夋晥</p>
         <EditTable actions={['edit', 'move', 'copy', 'del']} type={'timenodes'} data={menus} columns={columns} onChange={this.changeColumns}/>
       </div>
     )
diff --git a/src/menu/components/card/cardsimplecomponent/options.jsx b/src/menu/components/card/cardsimplecomponent/options.jsx
index 28680d5..7b397d1 100644
--- a/src/menu/components/card/cardsimplecomponent/options.jsx
+++ b/src/menu/components/card/cardsimplecomponent/options.jsx
@@ -1,7 +1,7 @@
 /**
  * @description tablecard setting琛ㄥ崟閰嶇疆淇℃伅
  */
-export function getTableSetting (setting, columns, buttons = []) {
+export function getTableSetting (setting, columns, buttons = [], action = []) {
   let _columns = columns.map(item => ({value: item.field, label: item.label}))
   _columns.push({value: '$Index', label: '搴忓彿锛堝墠绔級'})
   let appType = sessionStorage.getItem('appType')
@@ -111,6 +111,18 @@
       ],
     },
     {
+      type: 'radio',
+      field: 'open',
+      label: '鎵撳紑鏂瑰紡',
+      initval: setting.open || 'blank',
+      required: false,
+      options: [
+        {value: 'blank', label: appType !== 'mob' ? '鏂扮獥鍙�' : '鏂伴〉闈�'},
+        {value: 'self', label: appType !== 'mob' ? '褰撳墠绐楀彛' : '褰撳墠椤甸潰'},
+      ],
+      forbid: appType !== 'pc' && appType !== 'mob'
+    },
+    {
       type: appType ? 'select' : 'cascader',
       field: 'menu',
       label: '鍏宠仈鑿滃崟',
@@ -129,24 +141,24 @@
       span: 24
     },
     {
-      type: 'radio',
-      field: 'open',
-      label: '鎵撳紑鏂瑰紡',
-      initval: setting.open || 'blank',
-      required: false,
-      options: [
-        {value: 'blank', label: '鏂扮獥鍙�'},
-        {value: 'self', label: '褰撳墠绐楀彛'},
-      ],
-      forbid: appType !== 'pc'
-    },
-    {
       type: 'select',
       field: 'linkbtn',
       label: '鍏宠仈鎸夐挳',
       initval: setting.linkbtn || '',
       required: true,
       options: buttons
+    },
+    {
+      type: 'radio',
+      field: 'swipe',
+      label: '婊戝姩鎸夐挳',
+      initval: setting.swipe || 'true',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄剧ず'},
+        {value: 'false', label: '涓嶆樉绀�'},
+      ],
+      forbid: action.length === 0 || appType !== 'mob'
     }
   ]
 
@@ -224,25 +236,16 @@
       options: appType ? appmenulist : menulist,
     },
     {
-      type: 'textarea',
-      field: 'linkurl',
-      label: '閾炬帴',
-      initval: setting.linkurl || '',
-      required: true,
-      options: [],
-      span: 24
-    },
-    {
       type: 'radio',
       field: 'open',
       label: '鎵撳紑鏂瑰紡',
       initval: setting.open || 'blank',
       required: false,
       options: [
-        {value: 'blank', label: '鏂扮獥鍙�'},
-        {value: 'self', label: '褰撳墠绐楀彛'},
+        {value: 'blank', label: appType !== 'mob' ? '鏂扮獥鍙�' : '鏂伴〉闈�'},
+        {value: 'self', label: appType !== 'mob' ? '褰撳墠绐楀彛' : '褰撳墠椤甸潰'},
       ],
-      forbid: appType !== 'pc'
+      forbid: appType !== 'pc' && appType !== 'mob'
     },
     {
       type: 'radio',
@@ -255,6 +258,15 @@
         {value: 'false', label: '鍚�'},
       ],
     },
+    {
+      type: 'textarea',
+      field: 'linkurl',
+      label: '閾炬帴',
+      initval: setting.linkurl || '',
+      required: true,
+      options: [],
+      span: 24
+    },
   ]
 
   return cardSettingForm
diff --git a/src/menu/components/card/data-card/index.jsx b/src/menu/components/card/data-card/index.jsx
index 08c4749..67eea0f 100644
--- a/src/menu/components/card/data-card/index.jsx
+++ b/src/menu/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 { Popover, Modal, Pagination, notification } from 'antd'
+import { Popover, Modal, Pagination } from 'antd'
 import { PlusOutlined, PlusCircleOutlined, PlusSquareOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
 
 import asyncComponent from '@/utils/asyncComponent'
@@ -16,7 +16,7 @@
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const CardComponent = asyncComponent(() => import('../cardcomponent'))
 const MobPagination = asyncIconComponent(() => import('@/menu/components/share/mobPagination'))
-const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
+// const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 const PasteComponent = asyncIconComponent(() => import('@/components/paste'))
@@ -113,10 +113,7 @@
         })
       }
 
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+      this.updateComponent(_card)
     } else {
       let _card = fromJS(card).toJS()
       _card.action = _card.action || [] // 鍏煎
@@ -150,7 +147,7 @@
   componentDidMount () {
     MKEmitter.addListener('submitStyle', this.getStyle)
     MKEmitter.addListener('submitModal', this.handleSave)
-    MKEmitter.addListener('logButton', this.logButton)
+    // MKEmitter.addListener('logButton', this.logButton)
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -166,35 +163,142 @@
     }
     MKEmitter.removeListener('submitStyle', this.getStyle)
     MKEmitter.removeListener('submitModal', this.handleSave)
-    MKEmitter.removeListener('logButton', this.logButton)
+    // MKEmitter.removeListener('logButton', this.logButton)
   }
 
-  logButton = (id, item) => {
-    const { card } = this.state
+  // logButton = (id, item) => {
+  //   const { card } = this.state
 
-    if (id !== card.uuid) return
+  //   if (id !== card.uuid) return
 
-    let btnlog = card.btnlog || []
-    btnlog.push(item)
+  //   let btnlog = card.btnlog || []
+  //   btnlog.push(item)
 
-    this.setState({
-      card: {...card, btnlog}
-    })
-    this.props.updateConfig({...card, btnlog})
-  }
+  //   this.updateComponent({...card, btnlog})
+  // }
   
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
-    this.setState({
-      card: component
+  updateComponent = (card) => {
+    const { appType } = this.state
+
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+    card.btnlog = []
+
+    if (window.GLOB.styling && card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌�
+      this.setState({
+        card: card
+      })
+  
+      this.props.updateConfig(card)
+      return
+    }
+
+    card.errors = []
+
+    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+    } else if (!card.setting.primaryKey) {
+      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+    } else if (card.wrap.supType !== 'multi' && !card.setting.supModule) {
+      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+    }
+
+    let supModule = ''
+    if (card.wrap.supType === 'multi') { // 鏁版嵁鍗″涓婄骇缁勪欢
+      if (card.supNodes && card.supNodes[0]) {
+        supModule = card.supNodes[0].componentId
+      }
+    } else if (card.setting.supModule) {
+      supModule = card.setting.supModule[card.setting.supModule.length - 1] || ''
+      if (supModule === 'empty') {
+        supModule = ''
+      }
+    }
+
+    let columns = card.columns.map(c => c.field)
+    let lowcols = card.columns.map(c => c.field.toLowerCase())
+
+    card.action.forEach(cell => {
+      if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+        if (!cell.modal || cell.modal.fields.length === 0) {
+          card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+        } else {
+          cell.modal.fields.forEach(m => {
+            if (m.type === 'linkMain' && !supModule) {
+              card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+            } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+              card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+            }
+          })
+        }
+      }
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
+    card.subcards.forEach((item, i) => {
+      let linkbtn = item.setting.linkbtn || ''
+      item.elements.forEach(cell => {
+        if (cell.eleType === 'button') {
+          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+            if (!cell.modal || cell.modal.fields.length === 0) {
+              card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+            } else {
+              cell.modal.fields.forEach(m => {
+                if (m.type === 'linkMain' && !supModule) {
+                  card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+                  card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+                }
+              })
+            }
+          }
+          if (linkbtn && linkbtn === cell.uuid) {
+            linkbtn = ''
+          }
+        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+          card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+        }
+      })
 
-    this.props.updateConfig(component)
+      if (item.setting.type === 'multi' && appType !== 'mob') {
+        item.backElements.forEach(cell => {
+          if (cell.eleType === 'button') {
+            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+              if (!cell.modal || cell.modal.fields.length === 0) {
+                card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+              } else {
+                cell.modal.fields.forEach(m => {
+                  if (m.type === 'linkMain' && !supModule) {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                  } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+                  }
+                })
+              }
+            }
+            if (linkbtn && linkbtn === cell.uuid) {
+              linkbtn = ''
+            }
+          } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+            card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+          }
+        })
+      }
+
+      if (linkbtn) {
+        card.errors.push({ level: 1, detail: `绗�${i + 1}寮犲崱鐗囦腑缁戝畾鎸夐挳宸插垹闄})
+      }
+    })
+
+    this.setState({
+      card: card
+    })
+
+    this.props.updateConfig(card)
   }
 
   /**
@@ -212,9 +316,7 @@
       card.action = card.action.filter(item => item.uuid !== btn.uuid)
     }
 
-    this.setState({card})
-
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   /**
@@ -230,12 +332,11 @@
       onOk() {
         card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
 
-        if (card.btnlog) {
-          card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
-        }
+        // if (card.btnlog) {
+        //   card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
+        // }
 
-        _this.setState({card})
-        _this.props.updateConfig(card)
+        _this.updateComponent(card)
 
         if (appType === 'mob') return
 
@@ -272,12 +373,8 @@
     if (comIds.length !== 1 || comIds[0] !== card.uuid) return
 
     let _card = {...card, style}
-
-    this.setState({
-      card: _card
-    })
     
-    this.props.updateConfig(_card)
+    this.updateComponent(_card)
   }
 
   addSearch = (copy) => {
@@ -373,52 +470,49 @@
       return cell
     })
 
-    this.setState({card})
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
-  handleLog = (type, logs, item) => {
-    let card = fromJS(this.state.card).toJS()
+  // handleLog = (type, logs, item) => {
+  //   let card = fromJS(this.state.card).toJS()
 
-    if (type === 'revert') {
-      let done = false
-      if (item.$parentId) {
-        card.subcards.forEach(col => {
-          if (item.$parentId === col.uuid) {
-            if (item.$side !== 'back') {
-              col.elements = col.elements ? [...col.elements, item] : [item]
-            } else {
-              col.backElements = col.backElements ? [...col.backElements, item] : [item]
-            }
-            done = true
-          }
-        })
-      }
+  //   if (type === 'revert') {
+  //     let done = false
+  //     if (item.$parentId) {
+  //       card.subcards.forEach(col => {
+  //         if (item.$parentId === col.uuid) {
+  //           if (item.$side !== 'back') {
+  //             col.elements = col.elements ? [...col.elements, item] : [item]
+  //           } else {
+  //             col.backElements = col.backElements ? [...col.backElements, item] : [item]
+  //           }
+  //           done = true
+  //         }
+  //       })
+  //     }
 
-      if (!done) {
-        card.action = card.action ? [...card.action, item] : [item]
-      }
+  //     if (!done) {
+  //       card.action = card.action ? [...card.action, item] : [item]
+  //     }
 
-      card.btnlog = logs
+  //     card.btnlog = logs
 
-      this.setState({ card })
-      this.props.updateConfig(card)
-      notification.success({
-        top: 92,
-        message: '鎭㈠鎴愬姛锛�',
-        duration: 2
-      })
-    } else {
-      card.btnlog = logs
-      this.setState({ card })
-      this.props.updateConfig(card)
-      notification.success({
-        top: 92,
-        message: '娓呴櫎鎴愬姛锛�',
-        duration: 2
-      })
-    }
-  }
+  //     this.updateComponent(card)
+  //     notification.success({
+  //       top: 92,
+  //       message: '鎭㈠鎴愬姛锛�',
+  //       duration: 2
+  //     })
+  //   } else {
+  //     card.btnlog = logs
+  //     this.updateComponent(card)
+  //     notification.success({
+  //       top: 92,
+  //       message: '娓呴櫎鎴愬姛锛�',
+  //       duration: 2
+  //     })
+  //   }
+  // }
 
   addCard = (copy) => {
     let card = fromJS(this.state.card).toJS()
@@ -449,9 +543,8 @@
     }
 
     card.subcards.push(newcard)
-    
-    this.setState({card})
-    this.props.updateConfig(card)
+
+    this.updateComponent(card)
   }
 
   move = (item, direction) => {
@@ -470,14 +563,13 @@
 
     card.subcards.splice(hoverIndex, 0, ...card.subcards.splice(dragIndex, 1))
 
-    this.setState({card})
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   getWrapForms = () => {
     const { card } = this.state
-
-    return getWrapForm(card.wrap, card.subtype, card.columns, card.uuid, card.supNodes)
+    
+    return getWrapForm(card.wrap, card.subtype, card.columns, card.uuid, card.supNodes, card.setting)
   }
 
   updateWrap = (res) => {
@@ -515,7 +607,7 @@
       res.setting.width = res.setting.width || 6
 
       let copyBtns = []
-      let mobtypes = ['pop', 'prompt', 'exec', 'innerpage']
+      let mobtypes = ['pop', 'prompt', 'exec', 'innerpage', 'funcbutton']
 
       let elements = []
       res.elements && res.elements.forEach(cell => {
@@ -659,7 +751,7 @@
             <CopyComponent type="datacard" card={card}/>
             <PasteComponent options={['action', 'search', 'form', 'cardcell']} updateConfig={this.pasteComponent} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
-            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
+            {/* <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} /> */}
             <UserComponent config={card}/>
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} />
             <SettingComponent config={card} updateConfig={this.updateComponent} />
@@ -674,7 +766,20 @@
         <div style={{clear: 'both'}}></div>
         {card.wrap.pagestyle === 'page' && card.setting.laypage === 'true' && appType !== 'mob' ? <Pagination total={85} size="small" showTotal={total => `鍏� ${total} 鏉} pageSize={20} defaultCurrent={1}/> : null}
         {card.wrap.pagestyle === 'page' && card.setting.laypage === 'true' && appType === 'mob' ? <MobPagination /> : null}
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/card/data-card/index.scss b/src/menu/components/card/data-card/index.scss
index c49a471..bf029bb 100644
--- a/src/menu/components/card/data-card/index.scss
+++ b/src/menu/components/card/data-card/index.scss
@@ -133,11 +133,13 @@
 }
 .menu-data-card-edit-box.mob {
   .model-menu-action-list {
-    position: absolute;
-    top: 5px;
-    right: 0px;
+    // position: absolute;
+    // top: 5px;
+    // right: 0px;
+    // padding-top: 5px;
     .page-card {
       line-height: 40px;
+      margin-top: 5px;
     }
   }
 }
diff --git a/src/menu/components/card/data-card/options.jsx b/src/menu/components/card/data-card/options.jsx
index 913aba8..64bbde6 100644
--- a/src/menu/components/card/data-card/options.jsx
+++ b/src/menu/components/card/data-card/options.jsx
@@ -4,10 +4,11 @@
 /**
  * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
  */
-export default function (wrap, subtype, columns = [], id = '', supNodes = []) {
+export default function (wrap, subtype, columns = [], id = '', supNodes = [], setting) {
   let appType = sessionStorage.getItem('appType')
   let MenuType = ''
   let menu = fromJS(window.GLOB.customMenu).toJS()
+  let laypage = setting && setting.laypage !== 'false'
 
   if (menu.parentId === 'BillPrintTemp') {
     MenuType = 'billPrint'
@@ -115,10 +116,14 @@
       initval: wrap.pagestyle || 'page',
       tooltip: '鏁版嵁婧愰�夋嫨鍒嗛〉鏃舵湁鏁堛�傛敞锛氭粦鍔ㄥ姞杞藉彧鏈夌涓�涓湁鏁�',
       required: false,
+      disabled: !laypage,
       options: [
         {value: 'page', label: '椤电爜'},
         {value: 'switch', label: '宸﹀彸鍒囨崲', forbid: appType === 'mob'},
         {value: 'slide', label: '婊戝姩鍔犺浇', forbid: appType !== 'mob'},
+      ],
+      controlFields: [
+        {field: 'slidetip', values: ['slide']},
       ],
       forbid: !(subtype === 'datacard' || (subtype === 'tablecard' && appType === 'mob'))
     },
@@ -168,7 +173,8 @@
         {value: 'false', label: '鏃�'},
         {value: 'init', label: '鍒濆鍖�'},
         {value: 'always', label: '鏁版嵁鍔犺浇'},
-      ]
+      ],
+      forbid: subtype === 'tablecard'
     },
     {
       type: 'select',
@@ -183,8 +189,8 @@
         {value: 'backFont', label: '鑳屾櫙+鏂囧瓧'},
         {value: 'font', label: '鏂囧瓧'},
         ...(subtype === 'datacard' && appType === 'mob' ? [{value: 'check', label: '鍕鹃��'}] : [])
-      ]
-      // forbid: subtype !== 'propcard'
+      ],
+      forbid: subtype === 'tablecard'
     },
     // {
     //   type: 'radio',
@@ -387,9 +393,9 @@
     {
       type: 'text',
       field: 'controlVal',
-      label: '鎺у埗鍊�',
+      label: '绂佺敤鍊�',
       initval: wrap.controlVal || '',
-      tooltip: '褰撳瓧娈靛�间笌鎺у埗鍊肩浉绛夋椂锛岃鏁版嵁浼氱鐢紝澶氫釜鍊肩敤閫楀彿鍒嗛殧銆�',
+      tooltip: '褰撳瓧娈靛�间笌绂佺敤鍊肩浉绛夋椂锛岃鏁版嵁浼氱鐢紝澶氫釜鍊肩敤閫楀彿鍒嗛殧銆�',
       required: false,
       forbid: subtype !== 'datacard'
     },
@@ -431,6 +437,15 @@
       forbid: !!appType
     },
     {
+      type: 'text',
+      field: 'slidetip',
+      label: '搴曢儴鎻愮ず',
+      initval: wrap.slidetip || wrap.slidetip === '' ? wrap.slidetip : '娌℃湁鏇村浜�',
+      tooltip: '婊戝姩鍔犺浇鑷冲簳閮ㄦ椂鐨勬彁绀轰俊鎭��',
+      required: false,
+      forbid: !laypage || appType !== 'mob' || subtype === 'propcard'
+    },
+    {
       type: 'table',
       field: 'supNodes',
       label: '涓婄骇缁勪欢',
diff --git a/src/menu/components/card/prop-card/index.jsx b/src/menu/components/card/prop-card/index.jsx
index 2d82ac0..9e382eb 100644
--- a/src/menu/components/card/prop-card/index.jsx
+++ b/src/menu/components/card/prop-card/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Popover, Modal, notification } from 'antd'
+import { Popover, Modal } from 'antd'
 import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
 
 import asyncComponent from '@/utils/asyncComponent'
@@ -17,7 +17,7 @@
 const CardComponent = asyncComponent(() => import('../cardcomponent'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const PasteComponent = asyncIconComponent(() => import('@/components/paste'))
-const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
+// const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
@@ -100,10 +100,7 @@
           return scard
         })
       }
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+      this.updateComponent(_card)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -113,7 +110,7 @@
 
   componentDidMount () {
     MKEmitter.addListener('submitStyle', this.getStyle)
-    MKEmitter.addListener('logButton', this.logButton)
+    // MKEmitter.addListener('logButton', this.logButton)
     MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
   }
 
@@ -129,7 +126,7 @@
       return
     }
     MKEmitter.removeListener('submitStyle', this.getStyle)
-    MKEmitter.removeListener('logButton', this.logButton)
+    // MKEmitter.removeListener('logButton', this.logButton)
     MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle)
   }
 
@@ -150,32 +147,175 @@
     })
   }
 
-  logButton = (id, item) => {
-    const { card } = this.state
+  // 鎸夐挳鍘嗗彶璁板綍
+  // logButton = (id, item) => {
+  //   const { card } = this.state
 
-    if (id !== card.uuid) return
+  //   if (id !== card.uuid) return
 
-    let btnlog = card.btnlog || []
-    btnlog.push(item)
+  //   let btnlog = card.btnlog || []
+  //   btnlog.push(item)
 
-    this.setState({
-      card: {...card, btnlog}
-    })
-    this.props.updateConfig({...card, btnlog})
-  }
+  //   this.updateComponent({...card, btnlog})
+  // }
 
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
+  updateComponent = (card) => {
+    const { appType } = this.state
+
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+    card.btnlog = []
+
+    if (window.GLOB.styling && card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌�
+      this.setState({
+        card: card
+      })
+  
+      this.props.updateConfig(card)
+      return
+    }
+
+    card.errors = []
+
+    if (card.subcards.length === 0) {
+      card.errors.push({ level: 0, detail: '鍗$墖涓嶅彲涓虹┖锛�'})
+    }
+
+    if (card.wrap.datatype === 'static') {
+      let supModule = card.wrap.supModule ? card.wrap.supModule[card.wrap.supModule.length - 1] : ''
+      card.subcards.forEach((item, i) => {
+        let linkbtn = item.setting.linkbtn || ''
+
+        item.elements.forEach(cell => {
+          if (cell.eleType === 'button') {
+            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+              if (!cell.modal || cell.modal.fields.length === 0) {
+                card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+              } else if (!supModule) {
+                cell.modal.fields.forEach(m => {
+                  if (m.type === 'linkMain') {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                  }
+                })
+              }
+            }
+            if (linkbtn && linkbtn === cell.uuid) {
+              linkbtn = ''
+            }
+          } else if (cell.datatype === 'dynamic' && cell.field) {
+            card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+          }
+        })
+
+        if (item.setting.type === 'multi' && appType !== 'mob') {
+          item.backElements.forEach(cell => {
+            if (cell.eleType === 'button') {
+              if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+                if (!cell.modal || cell.modal.fields.length === 0) {
+                  card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+                } else if (!supModule) {
+                  cell.modal.fields.forEach(m => {
+                    if (m.type === 'linkMain') {
+                      card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                    }
+                  })
+                }
+              }
+              if (linkbtn && linkbtn === cell.uuid) {
+                linkbtn = ''
+              }
+            } else if (cell.datatype === 'dynamic' && cell.field) {
+              card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+            }
+          })
+        }
+
+        if (linkbtn) {
+          card.errors.push({ level: 1, detail: `绗�${i + 1}寮犲崱鐗囦腑缁戝畾鎸夐挳宸插垹闄})
+        }
+      })
+    } else {
+      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+      } else if (!card.setting.primaryKey) {
+        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+      } else if (!card.setting.supModule) {
+        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+      }
+
+      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
+      if (supModule === 'empty') {
+        supModule = ''
+      }
+      let columns = card.columns.map(c => c.field)
+      let lowcols = card.columns.map(c => c.field.toLowerCase())
+
+      card.subcards.forEach((item, i) => {
+        let linkbtn = item.setting.linkbtn || ''
+        item.elements.forEach(cell => {
+          if (cell.eleType === 'button') {
+            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+              if (!cell.modal || cell.modal.fields.length === 0) {
+                card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+              } else {
+                cell.modal.fields.forEach(m => {
+                  if (m.type === 'linkMain' && !supModule) {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                  } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+                  }
+                })
+              }
+            }
+            if (linkbtn && linkbtn === cell.uuid) {
+              linkbtn = ''
+            }
+          } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+            card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+          }
+        })
+
+        if (item.setting.type === 'multi' && appType !== 'mob') {
+          item.backElements.forEach(cell => {
+            if (cell.eleType === 'button') {
+              if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+                if (!cell.modal || cell.modal.fields.length === 0) {
+                  card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+                } else {
+                  cell.modal.fields.forEach(m => {
+                    if (m.type === 'linkMain' && !supModule) {
+                      card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                    } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+                      card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+                    }
+                  })
+                }
+              }
+              if (linkbtn && linkbtn === cell.uuid) {
+                linkbtn = ''
+              }
+            } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+              card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+            }
+          })
+        }
+
+        if (linkbtn) {
+          card.errors.push({ level: 1, detail: `绗�${i + 1}寮犲崱鐗囦腑缁戝畾鎸夐挳宸插垹闄})
+        }
+      })
+    }
+
     this.setState({
-      card: component
+      card: card
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
-
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   /**
@@ -189,9 +329,7 @@
       return item
     })
 
-    this.setState({card})
-
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   /**
@@ -207,12 +345,11 @@
       onOk() {
         card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
 
-        if (card.btnlog) {
-          card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
-        }
+        // if (card.btnlog) {
+        //   card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
+        // }
 
-        _this.setState({card})
-        _this.props.updateConfig(card)
+        _this.updateComponent(card)
 
         if (appType === 'mob') return
 
@@ -249,12 +386,8 @@
     if (comIds.length !== 1 || comIds[0] !== card.uuid) return
 
     let _card = {...card, style}
-
-    this.setState({
-      card: _card
-    })
     
-    this.props.updateConfig(_card)
+    this.updateComponent(_card)
   }
 
   addCard = (copy) => {
@@ -292,59 +425,56 @@
     }
 
     card.subcards.push(newcard)
-    
-    this.setState({card})
-    this.props.updateConfig(card)
+
+    this.updateComponent(card)
   }
 
-  handleLog = (type, logs, item) => {
-    let card = fromJS(this.state.card).toJS()
+  // handleLog = (type, logs, item) => {
+  //   let card = fromJS(this.state.card).toJS()
 
-    if (type === 'revert') {
-      let done = false
-      if (item.$parentId) {
-        card.subcards.forEach(col => {
-          if (item.$parentId === col.uuid) {
-            if (item.$side !== 'back') {
-              col.elements = col.elements ? [...col.elements, item] : [item]
-            } else {
-              col.backElements = col.backElements ? [...col.backElements, item] : [item]
-            }
-            done = true
-          }
-        })
-      }
+  //   if (type === 'revert') {
+  //     let done = false
+  //     if (item.$parentId) {
+  //       card.subcards.forEach(col => {
+  //         if (item.$parentId === col.uuid) {
+  //           if (item.$side !== 'back') {
+  //             col.elements = col.elements ? [...col.elements, item] : [item]
+  //           } else {
+  //             col.backElements = col.backElements ? [...col.backElements, item] : [item]
+  //           }
+  //           done = true
+  //         }
+  //       })
+  //     }
 
-      card.btnlog = logs
+  //     card.btnlog = logs
 
-      this.setState({ card: {...card, subcards: []} }, () => {
-        this.setState({ card })
-        this.props.updateConfig(card)
-      })
-      if (!done) {
-        notification.warning({
-          top: 92,
-          message: '闄勫睘鍗$墖宸插垹闄わ紒',
-          duration: 2
-        })
-      } else {
-        notification.success({
-          top: 92,
-          message: '鎭㈠鎴愬姛锛�',
-          duration: 2
-        })
-      }
-    } else {
-      card.btnlog = logs
-      this.setState({ card })
-      this.props.updateConfig(card)
-      notification.success({
-        top: 92,
-        message: '娓呴櫎鎴愬姛锛�',
-        duration: 2
-      })
-    }
-  }
+  //     this.setState({ card: {...card, subcards: []} }, () => {
+  //       this.updateComponent(card)
+  //     })
+  //     if (!done) {
+  //       notification.warning({
+  //         top: 92,
+  //         message: '闄勫睘鍗$墖宸插垹闄わ紒',
+  //         duration: 2
+  //       })
+  //     } else {
+  //       notification.success({
+  //         top: 92,
+  //         message: '鎭㈠鎴愬姛锛�',
+  //         duration: 2
+  //       })
+  //     }
+  //   } else {
+  //     card.btnlog = logs
+  //     this.updateComponent(card)
+  //     notification.success({
+  //       top: 92,
+  //       message: '娓呴櫎鎴愬姛锛�',
+  //       duration: 2
+  //     })
+  //   }
+  // }
 
   move = (item, direction) => {
     let card = fromJS(this.state.card).toJS()
@@ -362,8 +492,7 @@
 
     card.subcards.splice(hoverIndex, 0, ...card.subcards.splice(dragIndex, 1))
 
-    this.setState({card})
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   pasteComponent = (res, resolve) => {
@@ -377,7 +506,7 @@
     res.setting.width = res.setting.width || 6
 
     let copyBtns = []
-    let mobtypes = ['pop', 'prompt', 'exec', 'innerpage']
+    let mobtypes = ['pop', 'prompt', 'exec', 'innerpage', 'funcbutton']
 
     let elements = []
     res.elements && res.elements.forEach(cell => {
@@ -447,8 +576,12 @@
   updateWrap = (res) => {
     let _card = {...this.state.card, wrap: res}
 
-    if (res.supModule && res.supModule.length > 0) {
-      _card.setting.supModule = res.supModule
+    if (res.datatype === 'static') {
+      if (res.supModule && res.supModule.length > 0) {
+        _card.setting.supModule = res.supModule
+      } else {
+        _card.setting.supModule = ''
+      }
     }
     if (res.layout === 'flex') {
       _card.wrap.pagestyle = 'page'
@@ -481,7 +614,7 @@
             <CopyComponent type="propcard" card={card}/>
             <PasteComponent options={['cardcell']} updateConfig={this.pasteComponent} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
-            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
+            {/* <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} /> */}
             <ClockComponent config={card} updateConfig={this.updateComponent}/>
             <UserComponent config={card}/>
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} />
@@ -494,7 +627,20 @@
         <div className={(card.wrap.layout || 'grid') + '-layout float-' + (card.wrap.cardFloat || 'left')}>
           {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
         </div>
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/card/table-card/index.jsx b/src/menu/components/card/table-card/index.jsx
index ccf15bc..50f198d 100644
--- a/src/menu/components/card/table-card/index.jsx
+++ b/src/menu/components/card/table-card/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Popover, Modal, Pagination, notification } from 'antd'
+import { Popover, Modal, Pagination } from 'antd'
 import { PlusOutlined, PlusCircleOutlined, PlusSquareOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
 
 import asyncComponent from '@/utils/asyncComponent'
@@ -18,7 +18,7 @@
 const MobPagination = asyncIconComponent(() => import('@/menu/components/share/mobPagination'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const PasteComponent = asyncIconComponent(() => import('@/components/paste'))
-const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
+// const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
 const ActionComponent = asyncComponent(() => import('@/menu/components/share/actioncomponent'))
@@ -104,10 +104,8 @@
           })
         }
       }
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+
+      this.updateComponent(_card)
     } else {
       let _card = fromJS(card).toJS()
       if (!_card.action) {
@@ -140,7 +138,7 @@
 
   componentDidMount () {
     MKEmitter.addListener('submitStyle', this.getStyle)
-    MKEmitter.addListener('logButton', this.logButton)
+    // MKEmitter.addListener('logButton', this.logButton)
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -155,35 +153,95 @@
       return
     }
     MKEmitter.removeListener('submitStyle', this.getStyle)
-    MKEmitter.removeListener('logButton', this.logButton)
+    // MKEmitter.removeListener('logButton', this.logButton)
   }
 
-  logButton = (id, item) => {
-    const { card } = this.state
+  // logButton = (id, item) => {
+  //   const { card } = this.state
 
-    if (id !== card.uuid) return
+  //   if (id !== card.uuid) return
 
-    let btnlog = card.btnlog || []
-    btnlog.push(item)
+  //   let btnlog = card.btnlog || []
+  //   btnlog.push(item)
 
-    this.setState({
-      card: {...card, btnlog}
-    })
-    this.props.updateConfig({...card, btnlog})
-  }
+  //   this.updateComponent({...card, btnlog})
+  // }
 
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
-    this.setState({
-      card: component
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+    card.btnlog = []
+
+    if (window.GLOB.styling && card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌�
+      this.setState({
+        card: card
+      })
+  
+      this.props.updateConfig(card)
+      return
+    }
+
+    card.errors = []
+
+    if (card.subcards.length === 0) {
+      card.errors.push({ level: 0, detail: '鍗$墖涓嶅彲涓虹┖锛�'})
+    }
+
+    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+    } else if (!card.setting.primaryKey) {
+      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+    } else if (!card.setting.supModule) {
+      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+    }
+
+    let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
+    if (supModule === 'empty') {
+      supModule = ''
+    }
+    let columns = card.columns.map(c => c.field)
+    let lowcols = card.columns.map(c => c.field.toLowerCase())
+
+    card.subcards.forEach((item, i) => {
+      let linkbtn = item.setting.linkbtn || ''
+      item.elements.forEach(cell => {
+        if (cell.eleType === 'button') {
+          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+            if (!cell.modal || cell.modal.fields.length === 0) {
+              card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+            } else {
+              cell.modal.fields.forEach(m => {
+                if (m.type === 'linkMain' && !supModule) {
+                  card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+                  card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+                }
+              })
+            }
+          }
+          if (linkbtn && linkbtn === cell.uuid) {
+            linkbtn = ''
+          }
+        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+          card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+        }
+      })
+
+      if (linkbtn) {
+        card.errors.push({ level: 1, detail: `绗�${i + 1}寮犲崱鐗囦腑缁戝畾鎸夐挳宸插垹闄})
+      }
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
+    this.setState({
+      card: card
+    })
 
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   /**
@@ -197,9 +255,7 @@
       return item
     })
 
-    this.setState({card})
-
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   /**
@@ -215,12 +271,11 @@
       onOk() {
         card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
 
-        if (card.btnlog) {
-          card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
-        }
+        // if (card.btnlog) {
+        //   card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
+        // }
 
-        _this.setState({card})
-        _this.props.updateConfig(card)
+        _this.updateComponent(card)
 
         if (appType === 'mob') return
 
@@ -253,11 +308,7 @@
 
     let _card = {...card, style}
 
-    this.setState({
-      card: _card
-    })
-    
-    this.props.updateConfig(_card)
+    this.updateComponent(_card)
   }
 
   addCard = (copy) => {
@@ -287,9 +338,8 @@
     }
 
     card.subcards.push(newcard)
-    
-    this.setState({card})
-    this.props.updateConfig(card)
+
+    this.updateComponent(card)
   }
 
   addSearch = (copy) => {
@@ -317,52 +367,50 @@
     MKEmitter.emit('addSearch', card.uuid, newcard)
   }
 
-  handleLog = (type, logs, item) => {
-    let card = fromJS(this.state.card).toJS()
+  // handleLog = (type, logs, item) => {
+  //   let card = fromJS(this.state.card).toJS()
 
-    if (type === 'revert') {
-      let done = false
-      if (item.$parentId) {
-        card.subcards.forEach(col => {
-          if (item.$parentId === col.uuid) {
-            if (item.$side !== 'back') {
-              col.elements = col.elements ? [...col.elements, item] : [item]
-            } else {
-              col.backElements = col.backElements ? [...col.backElements, item] : [item]
-            }
-            done = true
-          }
-        })
-      }
+  //   if (type === 'revert') {
+  //     let done = false
+  //     if (item.$parentId) {
+  //       card.subcards.forEach(col => {
+  //         if (item.$parentId === col.uuid) {
+  //           if (item.$side !== 'back') {
+  //             col.elements = col.elements ? [...col.elements, item] : [item]
+  //           } else {
+  //             col.backElements = col.backElements ? [...col.backElements, item] : [item]
+  //           }
+  //           done = true
+  //         }
+  //       })
+  //     }
 
-      card.btnlog = logs
+  //     card.btnlog = logs
 
-      this.setState({ card })
-      this.props.updateConfig(card)
-      if (!done) {
-        notification.warning({
-          top: 92,
-          message: '闄勫睘鍗$墖宸插垹闄わ紒',
-          duration: 2
-        })
-      } else {
-        notification.success({
-          top: 92,
-          message: '鎭㈠鎴愬姛锛�',
-          duration: 2
-        })
-      }
-    } else {
-      card.btnlog = logs
-      this.setState({ card })
-      this.props.updateConfig(card)
-      notification.success({
-        top: 92,
-        message: '娓呴櫎鎴愬姛锛�',
-        duration: 2
-      })
-    }
-  }
+  //     this.updateComponent(card)
+  //     if (!done) {
+  //       notification.warning({
+  //         top: 92,
+  //         message: '闄勫睘鍗$墖宸插垹闄わ紒',
+  //         duration: 2
+  //       })
+  //     } else {
+  //       notification.success({
+  //         top: 92,
+  //         message: '鎭㈠鎴愬姛锛�',
+  //         duration: 2
+  //       })
+  //     }
+  //   } else {
+  //     card.btnlog = logs
+  //     this.updateComponent(card)
+  //     notification.success({
+  //       top: 92,
+  //       message: '娓呴櫎鎴愬姛锛�',
+  //       duration: 2
+  //     })
+  //   }
+  // }
 
   move = (item, direction) => {
     let card = fromJS(this.state.card).toJS()
@@ -380,14 +428,13 @@
 
     card.subcards.splice(hoverIndex, 0, ...card.subcards.splice(dragIndex, 1))
 
-    this.setState({card})
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   getWrapForms = () => {
     const { card } = this.state
 
-    return getWrapForm(card.wrap, card.subtype)
+    return getWrapForm(card.wrap, card.subtype, null, null, null, card.setting)
   }
 
   updateWrap = (res) => {
@@ -406,7 +453,7 @@
       res.setting.width = res.setting.width || 6
 
       let copyBtns = []
-      let mobtypes = ['pop', 'prompt', 'exec', 'innerpage']
+      let mobtypes = ['pop', 'prompt', 'exec', 'innerpage', 'funcbutton']
 
       let elements = []
       res.elements && res.elements.forEach(cell => {
@@ -550,7 +597,7 @@
             <CopyComponent type="tablecard" card={card}/>
             <PasteComponent options={['cardcell', 'search', 'form']} updateConfig={this.pasteComponent} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
-            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
+            {/* <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} /> */}
             <UserComponent config={card}/>
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} />
             {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
@@ -564,7 +611,20 @@
         </div>
         {card.setting.laypage === 'true' && card.wrap.pagestyle !== 'slide' && appType !== 'mob' ? <Pagination size="small" total={50} /> : null}
         {card.setting.laypage === 'true' && card.wrap.pagestyle !== 'slide' && appType === 'mob' ? <MobPagination /> : null}
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/carousel/data-card/index.jsx b/src/menu/components/carousel/data-card/index.jsx
index 60e2e24..b9a5cf4 100644
--- a/src/menu/components/carousel/data-card/index.jsx
+++ b/src/menu/components/carousel/data-card/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Popover, Modal, notification } from 'antd'
+import { Popover, Modal } from 'antd'
 import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
 
 import asyncComponent from '@/utils/asyncComponent'
@@ -15,7 +15,7 @@
 const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const CardSimpleComponent = asyncComponent(() => import('@/menu/components/card/cardsimplecomponent'))
-const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
+// const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 
@@ -87,10 +87,7 @@
         })
       }
 
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+      this.updateComponent(_card)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -100,7 +97,7 @@
 
   componentDidMount () {
     MKEmitter.addListener('submitStyle', this.getStyle)
-    MKEmitter.addListener('logButton', this.logButton)
+    // MKEmitter.addListener('logButton', this.logButton)
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -115,35 +112,84 @@
       return
     }
     MKEmitter.removeListener('submitStyle', this.getStyle)
-    MKEmitter.removeListener('logButton', this.logButton)
+    // MKEmitter.removeListener('logButton', this.logButton)
   }
 
-  logButton = (id, item) => {
-    const { card } = this.state
+  // logButton = (id, item) => {
+  //   const { card } = this.state
 
-    if (id !== card.uuid) return
+  //   if (id !== card.uuid) return
 
-    let btnlog = card.btnlog || []
-    btnlog.push(item)
+  //   let btnlog = card.btnlog || []
+  //   btnlog.push(item)
 
-    this.setState({
-      card: {...card, btnlog}
-    })
-    this.props.updateConfig({...card, btnlog})
-  }
+  //   this.updateComponent({...card, btnlog})
+  // }
   
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
-    this.setState({
-      card: component
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+    card.btnlog = []
+
+    if (window.GLOB.styling && card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌�
+      this.setState({
+        card: card
+      })
+  
+      this.props.updateConfig(card)
+      return
+    }
+
+    card.errors = []
+
+    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+    } else if (!card.setting.primaryKey) {
+      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+    } else if (!card.setting.supModule) {
+      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+    }
+
+    let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
+    if (supModule === 'empty') {
+      supModule = ''
+    }
+
+    let columns = card.columns.map(c => c.field)
+    let lowcols = card.columns.map(c => c.field.toLowerCase())
+
+    card.subcards.forEach((item, i) => {
+      item.elements.forEach(cell => {
+        if (cell.eleType === 'button') {
+          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+            if (!cell.modal || cell.modal.fields.length === 0) {
+              card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+            } else {
+              cell.modal.fields.forEach(m => {
+                if (m.type === 'linkMain' && !supModule) {
+                  card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+                  card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+                }
+              })
+            }
+          }
+        } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+          card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+        }
+      })
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
+    this.setState({
+      card: card
+    })
 
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   /**
@@ -157,9 +203,7 @@
       return item
     })
 
-    this.setState({card})
-
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   /**
@@ -175,12 +219,11 @@
       onOk() {
         card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
 
-        if (card.btnlog) {
-          card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
-        }
+        // if (card.btnlog) {
+        //   card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
+        // }
 
-        _this.setState({card})
-        _this.props.updateConfig(card)
+        _this.updateComponent(card)
 
         if (appType === 'mob') return
 
@@ -213,44 +256,38 @@
 
     let _card = {...card, style}
 
-    this.setState({
-      card: _card
-    })
-    
-    this.props.updateConfig(_card)
+    this.updateComponent(_card)
   }
 
-  handleLog = (type, logs, item) => {
-    let card = fromJS(this.state.card).toJS()
+  // handleLog = (type, logs, item) => {
+  //   let card = fromJS(this.state.card).toJS()
 
-    if (type === 'revert') {
-      card.subcards.forEach(col => {
-        col.elements = [...col.elements, item]
-        if (item.$parentId === col.uuid) {
-          col.elements = [...col.elements, item]
-        }
-      })
+  //   if (type === 'revert') {
+  //     card.subcards.forEach(col => {
+  //       col.elements = [...col.elements, item]
+  //       if (item.$parentId === col.uuid) {
+  //         col.elements = [...col.elements, item]
+  //       }
+  //     })
 
-      card.btnlog = logs
+  //     card.btnlog = logs
 
-      this.setState({ card })
-      this.props.updateConfig(card)
-      notification.success({
-        top: 92,
-        message: '鎭㈠鎴愬姛锛�',
-        duration: 2
-      })
-    } else {
-      card.btnlog = logs
-      this.setState({ card })
-      this.props.updateConfig(card)
-      notification.success({
-        top: 92,
-        message: '娓呴櫎鎴愬姛锛�',
-        duration: 2
-      })
-    }
-  }
+  //     this.updateComponent(card)
+  //     notification.success({
+  //       top: 92,
+  //       message: '鎭㈠鎴愬姛锛�',
+  //       duration: 2
+  //     })
+  //   } else {
+  //     card.btnlog = logs
+  //     this.updateComponent(card)
+  //     notification.success({
+  //       top: 92,
+  //       message: '娓呴櫎鎴愬姛锛�',
+  //       duration: 2
+  //     })
+  //   }
+  // }
 
   getWrapForms = () => {
     const { card } = this.state
@@ -282,7 +319,7 @@
             </NormalForm>
             <CopyComponent type="datacard" card={card}/>
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
-            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog}/>
+            {/* <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog}/> */}
             <UserComponent config={card}/>
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)}/>
             <SettingComponent config={card} updateConfig={this.updateComponent}/>
@@ -291,7 +328,20 @@
           <ToolOutlined/>
         </Popover>
         <CardSimpleComponent cards={card} card={card.subcards[0]} updateElement={this.updateCard} deleteElement={this.deleteCard}/>
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/carousel/data-card/options.jsx b/src/menu/components/carousel/data-card/options.jsx
index 36441fe..37104ad 100644
--- a/src/menu/components/carousel/data-card/options.jsx
+++ b/src/menu/components/carousel/data-card/options.jsx
@@ -59,7 +59,10 @@
       required: false,
       options: [
         {value: 'false', label: '鍚�'},
-        {value: 'true', label: '鏄�'},
+        {value: 'true', label: '鏄�'}
+      ],
+      controlFields: [
+        {field: 'speed', values: ['true']}
       ]
     },
     {
@@ -67,7 +70,7 @@
       field: 'speed',
       label: '鏃堕棿闂撮殧',
       initval: wrap.speed || 3,
-      tooltip: '浣跨敤鑷姩鍒囨崲鏃舵湁鏁堬紝榛樿涓�3绉�',
+      tooltip: '榛樿涓�3绉�',
       min: 1,
       max: 100,
       precision: 0,
diff --git a/src/menu/components/carousel/prop-card/index.jsx b/src/menu/components/carousel/prop-card/index.jsx
index db36e4d..910f5e9 100644
--- a/src/menu/components/carousel/prop-card/index.jsx
+++ b/src/menu/components/carousel/prop-card/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Popover, Modal, notification, Carousel } from 'antd'
+import { Popover, Modal, Carousel } from 'antd'
 import { PlusOutlined, SettingOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
 
 import asyncComponent from '@/utils/asyncComponent'
@@ -17,7 +17,7 @@
 const CardSimpleComponent = asyncComponent(() => import('@/menu/components/card/cardsimplecomponent'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
-const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
+// const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 
 const { confirm } = Modal
@@ -85,10 +85,8 @@
           return scard
         })
       }
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+ 
+      this.updateComponent(_card)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -98,7 +96,7 @@
 
   componentDidMount () {
     MKEmitter.addListener('submitStyle', this.getStyle)
-    MKEmitter.addListener('logButton', this.logButton)
+    // MKEmitter.addListener('logButton', this.logButton)
     MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
   }
 
@@ -114,7 +112,7 @@
       return
     }
     MKEmitter.removeListener('submitStyle', this.getStyle)
-    MKEmitter.removeListener('logButton', this.logButton)
+    // MKEmitter.removeListener('logButton', this.logButton)
     MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle)
   }
 
@@ -135,32 +133,106 @@
     })
   }
 
-  logButton = (id, item) => {
-    const { card } = this.state
+  // logButton = (id, item) => {
+  //   const { card } = this.state
 
-    if (id !== card.uuid) return
+  //   if (id !== card.uuid) return
 
-    let btnlog = card.btnlog || []
-    btnlog.push(item)
+  //   let btnlog = card.btnlog || []
+  //   btnlog.push(item)
 
-    this.setState({
-      card: {...card, btnlog}
-    })
-    this.props.updateConfig({...card, btnlog})
-  }
+  //   this.updateComponent({...card, btnlog})
+  // }
 
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+    card.btnlog = []
+
+    if (window.GLOB.styling && card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌�
+      this.setState({
+        card: card
+      })
+  
+      this.props.updateConfig(card)
+      return
+    }
+
+    card.errors = []
+
+    if (card.subcards.length === 0) {
+      card.errors.push({ level: 0, detail: '鍗$墖涓嶅彲涓虹┖锛�'})
+    }
+
+    if (card.wrap.datatype === 'static') {
+      card.subcards.forEach(item => {
+        item.elements.forEach(cell => {
+          if (cell.eleType === 'button') {
+            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+              if (!cell.modal || cell.modal.fields.length === 0) {
+                card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+              } else {
+                cell.modal.fields.forEach(m => {
+                  if (m.type === 'linkMain') {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                  }
+                })
+              }
+            }
+          } else if (cell.datatype === 'dynamic' && cell.field) {
+            card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+          }
+        })
+      })
+    } else {
+      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+      } else if (!card.setting.primaryKey) {
+        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+      } else if (!card.setting.supModule) {
+        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+      }
+
+      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
+      if (supModule === 'empty') {
+        supModule = ''
+      }
+      let columns = card.columns.map(c => c.field)
+      let lowcols = card.columns.map(c => c.field.toLowerCase())
+
+      card.subcards.forEach((item, i) => {
+        item.elements.forEach(cell => {
+          if (cell.eleType === 'button') {
+            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+              if (!cell.modal || cell.modal.fields.length === 0) {
+                card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+              } else {
+                cell.modal.fields.forEach(m => {
+                  if (m.type === 'linkMain' && !supModule) {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                  } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+                  }
+                })
+              }
+            }
+          } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+            card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+          }
+        })
+      })
+    }
+
     this.setState({
-      card: component
+      card: card
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
-
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   /**
@@ -174,9 +246,7 @@
       return item
     })
 
-    this.setState({card})
-
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   /**
@@ -192,12 +262,11 @@
       onOk() {
         card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
 
-        if (card.btnlog) {
-          card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
-        }
+        // if (card.btnlog) {
+        //   card.btnlog = card.btnlog.filter(c => c.$parentId !== cell.uuid)
+        // }
 
-        _this.setState({card})
-        _this.props.updateConfig(card)
+        _this.updateComponent(card)
 
         if (appType === 'mob') return
 
@@ -229,12 +298,8 @@
     if (comIds.length !== 1 || comIds[0] !== card.uuid) return
 
     let _card = {...card, style}
-
-    this.setState({
-      card: _card
-    })
     
-    this.props.updateConfig(_card)
+    this.updateComponent(_card)
   }
 
   addCard = () => {
@@ -257,55 +322,52 @@
     }
 
     card.subcards.push(newcard)
-    
-    this.setState({card})
-    this.props.updateConfig(card)
+
+    this.updateComponent(card)
   }
 
-  handleLog = (type, logs, item) => {
-    let card = fromJS(this.state.card).toJS()
+  // handleLog = (type, logs, item) => {
+  //   let card = fromJS(this.state.card).toJS()
 
-    if (type === 'revert') {
-      let done = false
-      if (item.$parentId) {
-        card.subcards.forEach(col => {
-          if (item.$parentId === col.uuid) {
-            col.elements = [...col.elements, item]
-            done = true
-          }
-        })
-      }
+  //   if (type === 'revert') {
+  //     let done = false
+  //     if (item.$parentId) {
+  //       card.subcards.forEach(col => {
+  //         if (item.$parentId === col.uuid) {
+  //           col.elements = [...col.elements, item]
+  //           done = true
+  //         }
+  //       })
+  //     }
 
-      card.btnlog = logs
+  //     card.btnlog = logs
 
-      this.setState({ card: {...card, subcards: []} }, () => {
-        this.setState({ card })
-        this.props.updateConfig(card)
-      })
-      if (!done) {
-        notification.warning({
-          top: 92,
-          message: '闄勫睘鍗$墖宸插垹闄わ紒',
-          duration: 2
-        })
-      } else {
-        notification.success({
-          top: 92,
-          message: '鎭㈠鎴愬姛锛�',
-          duration: 2
-        })
-      }
-    } else {
-      card.btnlog = logs
-      this.setState({ card })
-      this.props.updateConfig(card)
-      notification.success({
-        top: 92,
-        message: '娓呴櫎鎴愬姛锛�',
-        duration: 2
-      })
-    }
-  }
+  //     this.setState({ card: {...card, subcards: []} }, () => {
+  //       this.updateComponent(card)
+  //     })
+  //     if (!done) {
+  //       notification.warning({
+  //         top: 92,
+  //         message: '闄勫睘鍗$墖宸插垹闄わ紒',
+  //         duration: 2
+  //       })
+  //     } else {
+  //       notification.success({
+  //         top: 92,
+  //         message: '鎭㈠鎴愬姛锛�',
+  //         duration: 2
+  //       })
+  //     }
+  //   } else {
+  //     card.btnlog = logs
+  //     this.updateComponent(card)
+  //     notification.success({
+  //       top: 92,
+  //       message: '娓呴櫎鎴愬姛锛�',
+  //       duration: 2
+  //     })
+  //   }
+  // }
 
   move = (item, direction) => {
     let card = fromJS(this.state.card).toJS()
@@ -324,9 +386,8 @@
     card.subcards.splice(hoverIndex, 0, ...card.subcards.splice(dragIndex, 1))
 
     this.setState({card: {...card, subcards: []}}, () => {
-      this.setState({card})
+      this.updateComponent(card)
     })
-    this.props.updateConfig(card)
   }
 
   getWrapForms = () => {
@@ -361,7 +422,7 @@
             <CopyComponent type="propcard" card={card}/>
             <PasteComponent config={card} options={['cardcell']} updateConfig={this.updateComponent} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
-            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
+            {/* <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} /> */}
             <UserComponent config={card}/>
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} />
             {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
@@ -373,7 +434,20 @@
         {card.subcards.length > 0 ? <Carousel dotPosition={card.wrap.dotPosition || 'bottom'} effect={card.wrap.effect || 'scrollx'}>
           {card.subcards.map((subcard) => (<CardSimpleComponent key={subcard.uuid} cards={card} card={subcard} move={this.move} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
         </Carousel> : null}
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>  
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
index 784141f..8a3a691 100644
--- a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
@@ -258,6 +258,8 @@
     }])
   }
 
+  let _label = card.label || 'false'
+
   return [
     {
       type: 'radio',
@@ -389,7 +391,7 @@
       type: labelOptions.length > 20 ? 'select' : 'radio',
       key: 'label',
       label: '鏍囨敞',
-      initVal: card.label || 'false',
+      initVal: _label,
       tooltip: '鍥惧舰鑺傜偣澶勭殑鏁板�笺��',
       required: false,
       options: labelOptions
@@ -400,6 +402,7 @@
       initVal: card.labelColor || 'system',
       tooltip: '浣跨敤绯荤粺鑹叉椂锛屼娇鐢ㄨ壊绯婚�夐」璁剧疆鐨勭郴缁熼鑹诧紝浣跨敤鑷畾涔変负棰滆壊璁剧疆涓畾涔夌殑鍥惧舰棰滆壊銆�',
       required: false,
+      hidden: _label !== 'true',
       options: [{
         value: 'system',
         text: '绯荤粺'
@@ -407,20 +410,21 @@
         value: 'custom',
         text: '鑷畾涔�'
       }]
-    // }, {
-    //   type: 'radio',
-    //   key: 'offset',
-    //   label: '鏍囨敞浣嶇疆',
-    //   initVal: card.offset || 'outer',
-    //   required: false,
-    //   options: [{
-    //     value: 'outer',
-    //     text: '澶栭儴'
-    //   }, {
-    //     value: 'inner',
-    //     text: '鍐呴儴'
-    //   }],
-    //   forbid: card.chartType !== 'bar'
+    }, {
+      type: 'radio',
+      key: 'labelValue',
+      label: '鏍囨敞鍊�',
+      initVal: card.labelValue || 'default',
+      tooltip: '鏍囨敞鍊肩殑鏄剧ず瑙勫垯銆�',
+      required: false,
+      hidden: _label === 'false',
+      options: [{
+        value: 'default',
+        text: '榛樿'
+      }, {
+        value: 'zero',
+        text: '闅愯棌 0 鍊�'
+      }],
     }, {
       type: 'radio',
       key: 'adjust',
@@ -568,6 +572,15 @@
       initVal: card.max,
       required: false
     }, {
+      type: 'number',
+      key: 'XLimit',
+      min: 2,
+      label: '瀛楃闄愬埗',
+      tooltip: 'X杞存渶澶у瓧绗﹂檺鍒躲��',
+      initVal: card.XLimit || 11,
+      forbid: appType === 'mob',
+      required: false
+    }, {
       type: 'color',
       key: 'color',
       label: '鑹茬郴',
diff --git a/src/menu/components/chart/antv-bar/chartcompile/index.jsx b/src/menu/components/chart/antv-bar/chartcompile/index.jsx
index accb869..61f053f 100644
--- a/src/menu/components/chart/antv-bar/chartcompile/index.jsx
+++ b/src/menu/components/chart/antv-bar/chartcompile/index.jsx
@@ -286,7 +286,7 @@
     if (key === 'datatype') {
       this.setState({
         datatype: val,
-        formlist: formlist.map(item => {
+        formlist: fromJS(formlist).toJS().map(item => {
           if (['Yaxis'].includes(item.key)) {
             item.hidden = val === 'statistics'
           } else if (['InfoType', 'InfoValue'].includes(item.key)) {
@@ -295,6 +295,26 @@
           return item
         })
       })
+    } else if (key === 'label') {
+      this.setState({formlist: fromJS(formlist).toJS().map(cell => {
+        if (!['labelColor', 'labelValue'].includes(cell.key)) return cell
+        
+        if (cell.key === 'labelColor') {
+          if (val !== 'true') {
+            cell.hidden = true
+          } else {
+            cell.hidden = false
+          }
+        } else {
+          if (val === 'false') {
+            cell.hidden = true
+          } else {
+            cell.hidden = false
+          }
+        }
+
+        return cell
+      })})
     }
   }
 
@@ -477,17 +497,39 @@
         if (!err) {
           let _plot = {...plot, ...values}
 
-          if (values.datatype === 'statistics' || values.datatype !== plot.datatype) {
-            _plot.enabled = 'false'
-            _plot.customs = []
-          } else if (!values.Yaxis || !plot.Yaxis || !is(fromJS(values.Yaxis), fromJS(plot.Yaxis))) {
-            _plot.enabled = 'false'
-            _plot.customs = []
-            _plot.colors = null
-          }
-
           if (values.datatype !== plot.datatype) {
             _plot.colors = null
+          }
+          if (values.datatype === 'statistics') {
+            _plot.enabled = 'false'
+            _plot.customs = []
+            delete _plot.Yaxis
+          } else if (!is(fromJS(values.Yaxis), fromJS(plot.Yaxis || []))) {
+            _plot.enabled = 'false'
+            _plot.colors = null
+
+            let labels = {}
+            config.columns.forEach(col => {
+              labels[col.field] = col.label
+            })
+  
+            let cus = {}
+            _plot.customs && _plot.customs.forEach(m => {
+              cus[m.type] = m
+            })
+            _plot.customs = _plot.Yaxis.map((item, i) => {
+              if (cus[item]) return cus[item]
+              
+              return {
+                uuid: Utils.getuuid(),
+                type: item,
+                name: labels[item] || item,
+                axis: i === 0 ? 'true' : 'false',
+                label: 'false',
+                title: 'true',
+                shape: _plot.chartType === 'bar' && i === 0 ? ['bar', 'rect'] : ['line', 'smooth']
+              }
+            })
           }
 
           this.setState({
@@ -560,22 +602,29 @@
         if (!err) {
           let _plot = {...plot, ...values}
 
-          if (values.datatype === 'statistics' || values.datatype !== plot.datatype) {
-            _plot.enabled = 'false'
-            _plot.customs = []
-          } else if (!values.Yaxis || !plot.Yaxis || !is(fromJS(values.Yaxis), fromJS(plot.Yaxis))) {
-            _plot.enabled = 'false'
-            _plot.customs = []
-            _plot.colors = null
-          }
-
           let labels = {}
           config.columns.forEach(col => {
             labels[col.field] = col.label
           })
 
-          if (values.datatype !== 'statistics' && (!_plot.customs || _plot.customs.length === 0)) {
+          if (values.datatype !== plot.datatype) {
+            _plot.colors = null
+          }
+          if (values.datatype === 'statistics') {
+            _plot.enabled = 'false'
+            _plot.customs = []
+            delete _plot.Yaxis
+          } else if (!is(fromJS(values.Yaxis), fromJS(plot.Yaxis || []))) {
+            _plot.enabled = 'false'
+            _plot.colors = null
+
+            let cus = {}
+            _plot.customs && _plot.customs.forEach(m => {
+              cus[m.type] = m
+            })
             _plot.customs = _plot.Yaxis.map((item, i) => {
+              if (cus[item]) return cus[item]
+              
               return {
                 uuid: Utils.getuuid(),
                 type: item,
@@ -587,7 +636,8 @@
               }
             })
           }
-          if (values.datatype !== plot.datatype || !_plot.colors) {
+
+          if (!_plot.colors) {
             _plot.colors = []
             if (_plot.datatype === 'query') {
               let limit = chartColors.length
diff --git a/src/menu/components/chart/antv-bar/index.jsx b/src/menu/components/chart/antv-bar/index.jsx
index 21cae5e..ca919d0 100644
--- a/src/menu/components/chart/antv-bar/index.jsx
+++ b/src/menu/components/chart/antv-bar/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Popover, notification } from 'antd'
+import { Popover } from 'antd'
 import { PlusCircleOutlined, PlusSquareOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
 import { Chart } from '@antv/g2'
 import DataSet from '@antv/data-set'
@@ -18,7 +18,7 @@
 
 const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
 const ChartCompileForm = asyncIconComponent(() => import('./chartcompile'))
-const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
+// const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
@@ -114,10 +114,8 @@
           return col
         })
       }
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+
+      this.updateComponent(_card, true)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -127,6 +125,7 @@
 
   componentDidMount () {
     MKEmitter.addListener('submitStyle', this.getStyle)
+    MKEmitter.addListener('plusSearch', this.plusSearch)
     MKEmitter.addListener('tabsChange', this.handleTabsChange)
     setTimeout(() => {
       this.viewrender()
@@ -145,6 +144,7 @@
       return
     }
     MKEmitter.removeListener('submitStyle', this.getStyle)
+    MKEmitter.removeListener('plusSearch', this.plusSearch)
     MKEmitter.removeListener('tabsChange', this.handleTabsChange)
   }
 
@@ -788,13 +788,17 @@
       }
     }
 
-    const view2 = chart.createView({
-      region: {
-        start: { x: 0, y: 0 },
-        end: { x: 1, y: 1 }
-      },
-      padding
-    })
+    let view2 = chart // 鏃犵嫭绔嬫煴鐘跺浘鏃朵笉鍋氬垎闈�
+
+    if (Bar_axis.length) {
+      view2 = chart.createView({
+        region: {
+          start: { x: 0, y: 0 },
+          end: { x: 1, y: 1 }
+        },
+        padding
+      })
+    }
 
     view2.data(dv.rows)
 
@@ -1210,26 +1214,65 @@
     }
   }
 
-  updateComponent = (component) => {
-    const card = fromJS(this.state.card).toJS()
-    if (!is(fromJS(component.plot), fromJS(card.plot)) || !is(fromJS(component.style), fromJS(card.style)) || !is(fromJS(component.search), fromJS(card.search))) {
-      let _element = document.getElementById(card.uuid + 'canvas')
-      if (_element) {
-        _element.innerHTML = ''
+  updateComponent = (card, init) => {
+    if (!init) {
+      if (!is(fromJS({plot: card.plot, style: card.style, search: card.search}), fromJS({plot: this.state.card.plot, style: this.state.card.style, search: this.state.card.search}))) {
+        let _element = document.getElementById(this.state.card.uuid + 'canvas')
+        if (_element) {
+          _element.innerHTML = ''
+        }
+        this.$timer && clearTimeout(this.$timer)
+        this.$timer = setTimeout(() => {
+          this.viewrender()
+        }, 150)
       }
-      this.$timer && clearTimeout(this.$timer)
-      this.$timer = setTimeout(() => {
-        this.viewrender()
-      }, 150)
     }
 
-    component.width = component.plot.width
-    component.name = component.plot.name
+    card.width = card.plot.width
+    card.name = card.plot.name
+    card.btnlog = []
+    card.errors = []
+
+    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+    } else if (!card.setting.primaryKey) {
+      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+    } else if (!card.setting.supModule) {
+      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+    }
     
+    let columns = card.columns.map(c => c.field)
+    if (!card.plot.Xaxis) {
+      card.errors.push({ level: 0, detail: '鍧愭爣杞村皻鏈缃紒'})
+    } else if (card.plot.datatype === 'query') {
+      if (!columns.includes(card.plot.Xaxis)) {
+        card.errors.push({ level: 1, detail: 'X杞村湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+      }
+      if (card.plot.Yaxis) {
+        card.plot.Yaxis.forEach(m => {
+          if (!columns.includes(m)) {
+            card.errors.push({ level: 1, detail: `Y杞翠腑瀛楁鈥�${m}鈥濆凡澶辨晥`})
+          }
+        })
+      }
+    } else if (card.plot.datatype === 'statistics') {
+      if (!columns.includes(card.plot.Xaxis)) {
+        card.errors.push({ level: 1, detail: 'X杞村湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+      }
+      if (!columns.includes(card.plot.InfoType)) {
+        card.errors.push({ level: 1, detail: '鍥捐〃涓粺璁$被鍨嬪瓧娈靛凡澶辨晥'})
+      }
+      if (!columns.includes(card.plot.InfoValue)) {
+        card.errors.push({ level: 1, detail: '鍥捐〃涓粺璁″�煎瓧娈靛凡澶辨晥'})
+      }
+    }
+
     this.setState({
-      card: component
+      card: card
     })
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   addSearch = () => {
@@ -1249,6 +1292,16 @@
 
     // 娉ㄥ唽浜嬩欢-娣诲姞鎼滅储
     MKEmitter.emit('addSearch', card.uuid, newcard)
+  }
+
+  plusSearch = (uuid, search, type) => {
+    const { card } = this.state
+    if (card.uuid !== uuid || type !== 'simple') return
+
+    search.uuid = Utils.getuuid()
+    search.focus = true
+
+    MKEmitter.emit('addSearch', card.uuid, search)
   }
 
   addButton = () => {
@@ -1295,31 +1348,29 @@
     this.updateComponent(_card)
   }
 
-  handleLog = (type, logs, item) => {
-    let card = fromJS(this.state.card).toJS()
+  // handleLog = (type, logs, item) => {
+  //   let card = fromJS(this.state.card).toJS()
 
-    if (type === 'revert') {
-      card.action = card.action ? [...card.action, item] : [item]
-      card.btnlog = logs
+  //   if (type === 'revert') {
+  //     card.action = card.action ? [...card.action, item] : [item]
+  //     card.btnlog = logs
 
-      this.setState({ card })
-      this.props.updateConfig(card)
-      notification.success({
-        top: 92,
-        message: '鎭㈠鎴愬姛锛�',
-        duration: 2
-      })
-    } else {
-      card.btnlog = logs
-      this.setState({ card })
-      this.props.updateConfig(card)
-      notification.success({
-        top: 92,
-        message: '娓呴櫎鎴愬姛锛�',
-        duration: 2
-      })
-    }
-  }
+  //     this.updateComponent(card)
+  //     notification.success({
+  //       top: 92,
+  //       message: '鎭㈠鎴愬姛锛�',
+  //       duration: 2
+  //     })
+  //   } else {
+  //     card.btnlog = logs
+  //     this.updateComponent(card)
+  //     notification.success({
+  //       top: 92,
+  //       message: '娓呴櫎鎴愬姛锛�',
+  //       duration: 2
+  //     })
+  //   }
+  // }
 
   clickComponent = (e) => {
     if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
@@ -1340,9 +1391,9 @@
             {appType !== 'mob' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton}/> : null}
             <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/>
             <CopyComponent type="line" card={card}/>
-            <PasteComponent config={card} options={['action']} updateConfig={this.updateComponent} />
+            <PasteComponent config={card} options={['action', 'search']} updateConfig={this.updateComponent} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
-            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
+            {/* <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} /> */}
             <ClockComponent config={card} updateConfig={this.updateComponent}/>
             <UserComponent config={card}/>
             <DeleteOutlined className="close" title="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
@@ -1358,7 +1409,20 @@
           config={card}
           updateaction={this.updateComponent}
         /> : null}
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/chart/antv-dashboard/index.jsx b/src/menu/components/chart/antv-dashboard/index.jsx
index 58d1a55..71c92d2 100644
--- a/src/menu/components/chart/antv-dashboard/index.jsx
+++ b/src/menu/components/chart/antv-dashboard/index.jsx
@@ -67,12 +67,13 @@
   state = {
     dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
     card: null,
-    ismob: sessionStorage.getItem('appType') === 'mob',
+    appType: sessionStorage.getItem('appType'),
     eventListener: null
   }
 
   UNSAFE_componentWillMount () {
-    const { card, ismob } = this.props
+    const { card } = this.props
+    const { appType } = this.state
 
     if (card.isNew) {
       let _plot = null
@@ -105,7 +106,7 @@
         }
       }
 
-      if (ismob) {
+      if (appType === 'mob') {
         _plot.width = 24
       }
 
@@ -132,7 +133,6 @@
         search: [],
         action: [],
         plot: _plot,
-        btnlog: [],
       }
 
       if (card.config) {
@@ -148,10 +148,7 @@
         _card.scripts = config.scripts
       }
 
-      this.props.updateConfig(_card)
-      this.setState({
-        card: _card
-      })
+      this.updateComponent(_card, true)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -467,27 +464,46 @@
     chart.render()
   }
 
-  updateComponent = (component) => {
-    const card = fromJS(this.state.card).toJS()
-
-    if (!is(fromJS(component.plot), fromJS(card.plot)) || !is(fromJS(component.style), fromJS(card.style)) || !is(fromJS(component.search), fromJS(card.search))) {
-      let _element = document.getElementById(card.uuid + 'dashboard')
-      if (_element) {
-        _element.innerHTML = ''
+  updateComponent = (card, init) => {
+    if (!init) {
+      if (!is(fromJS({plot: card.plot, style: card.style}), fromJS({plot: this.state.card.plot, style: this.state.card.style}))) {
+        let _element = document.getElementById(this.state.card.uuid + 'dashboard')
+        if (_element) {
+          _element.innerHTML = ''
+        }
+        this.$timer && clearTimeout(this.$timer)
+        this.$timer = setTimeout(() => {
+          this.viewrender()
+        }, 150)
       }
-      this.$timer && clearTimeout(this.$timer)
-      this.$timer = setTimeout(() => {
-        this.viewrender()
-      }, 150)
     }
 
-    component.width = component.plot.width
-    component.name = component.plot.name
+    card.width = card.plot.width
+    card.name = card.plot.name
+
+    card.errors = []
+
+    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+    } else if (!card.setting.primaryKey) {
+      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+    } else if (!card.setting.supModule) {
+      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+    }
+    
+    let columns = card.columns.map(c => c.field)
+    if (!card.plot.valueField) {
+      card.errors.push({ level: 0, detail: '鏄剧ず鍊煎皻鏈缃紒'})
+    } else if (!columns.includes(card.plot.valueField)) {
+      card.errors.push({ level: 1, detail: '鏄剧ず鍊煎湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+    }
     
     this.setState({
-      card: component
+      card: card
     })
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   changeStyle = () => {
@@ -534,7 +550,20 @@
         </Popover>
         <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
         <div className="canvas" id={card.uuid + 'dashboard'} ref={ref => this.wrap = ref}></div>
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
index 494a36f..fbdeeee 100644
--- a/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
@@ -261,7 +261,7 @@
     {
       type: 'radio',
       key: 'label',
-      label: '鏍囩',
+      label: '鏍囨敞',
       initVal: card.label || 'false',
       required: false,
       options: [{
diff --git a/src/menu/components/chart/antv-pie/index.jsx b/src/menu/components/chart/antv-pie/index.jsx
index 2d34e00..c6fa78b 100644
--- a/src/menu/components/chart/antv-pie/index.jsx
+++ b/src/menu/components/chart/antv-pie/index.jsx
@@ -32,12 +32,13 @@
   state = {
     dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
     card: null,
-    ismob: sessionStorage.getItem('appType') === 'mob',
+    appType: sessionStorage.getItem('appType'),
     eventListener: null
   }
 
   UNSAFE_componentWillMount () {
-    const { card, ismob } = this.props
+    const { card } = this.props
+    const { appType } = this.state
 
     if (card.isNew) {
       let _plot = {
@@ -48,7 +49,7 @@
         name: card.name
       }
 
-      if (ismob) {
+      if (appType === 'mob') {
         _plot.width = 24
       }
 
@@ -97,16 +98,15 @@
         _card.columns = config.columns
         _card.scripts = config.scripts
 
-        _card.search = config.search.map(col => {
-          col.uuid = Utils.getuuid()
-          return col
-        })
+        if (appType !== 'mob') {
+          _card.search = config.search.map(col => {
+            col.uuid = Utils.getuuid()
+            return col
+          })
+        }
       }
 
-      this.props.updateConfig(_card)
-      this.setState({
-        card: _card
-      })
+      this.updateComponent(_card, true)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -599,27 +599,50 @@
     chart.render()
   }
 
-  updateComponent = (component) => {
-    const card = fromJS(this.state.card).toJS()
-
-    if (!is(fromJS(component.plot), fromJS(card.plot)) || !is(fromJS(component.style), fromJS(card.style)) || !is(fromJS(component.search), fromJS(card.search))) {
-      let _element = document.getElementById(card.uuid + 'canvas')
-      if (_element) {
-        _element.innerHTML = ''
+  updateComponent = (card, init) => {
+    if (!init) {
+      if (!is(fromJS({plot: card.plot, style: card.style, search: card.search}), fromJS({plot: this.state.card.plot, style: this.state.card.style, search: this.state.card.search}))) {
+        let _element = document.getElementById(card.uuid + 'canvas')
+        if (_element) {
+          _element.innerHTML = ''
+        }
+        this.$timer && clearTimeout(this.$timer)
+        this.$timer = setTimeout(() => {
+          this.viewrender()
+        }, 150)
       }
-      this.$timer && clearTimeout(this.$timer)
-      this.$timer = setTimeout(() => {
-        this.viewrender()
-      }, 150)
     }
 
-    component.width = component.plot.width
-    component.name = component.plot.name
+    card.width = card.plot.width
+    card.name = card.plot.name
+    card.errors = []
+
+    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+    } else if (!card.setting.primaryKey) {
+      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+    } else if (!card.setting.supModule) {
+      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+    }
+    
+    let columns = card.columns.map(c => c.field)
+    if (!card.plot.Xaxis) {
+      card.errors.push({ level: 0, detail: '鍚嶇О瀛楁灏氭湭璁剧疆锛�'})
+    } else {
+      if (!columns.includes(card.plot.Xaxis)) {
+        card.errors.push({ level: 1, detail: '鍚嶇О瀛楁鍦ㄥ瓧娈甸泦涓笉瀛樺湪'})
+      }
+      if (!columns.includes(card.plot.Yaxis)) {
+        card.errors.push({ level: 1, detail: '鍊煎瓧娈靛湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+      }
+    }
     
     this.setState({
-      card: component
+      card: card
     })
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   addSearch = () => {
@@ -665,14 +688,14 @@
   }
 
   render() {
-    const { card, ismob } = this.state
+    const { card, appType } = this.state
     let _style = resetStyle(card.style)
 
     return (
       <div className="menu-pie-chart-edit-box" style={{..._style, height: card.plot.height || 400}} onClick={this.clickComponent} id={card.uuid}>
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
-            {!ismob ? <PlusCircleOutlined className="plus" title="娣诲姞鎼滅储" onClick={this.addSearch}/> : null}
+            {appType !== 'mob' ? <PlusCircleOutlined className="plus" title="娣诲姞鎼滅储" onClick={this.addSearch}/> : null}
             <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/>
             <CopyComponent type="pie" card={card}/>
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
@@ -686,7 +709,20 @@
         </Popover>
         <NormalHeader config={card} updateComponent={this.updateComponent}/>
         <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/chart/antv-scatter/index.jsx b/src/menu/components/chart/antv-scatter/index.jsx
index 30e9268..7b9242f 100644
--- a/src/menu/components/chart/antv-scatter/index.jsx
+++ b/src/menu/components/chart/antv-scatter/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Popover, notification } from 'antd'
+import { Popover } from 'antd'
 import { ToolOutlined, DeleteOutlined, FontColorsOutlined, PlusCircleOutlined, PlusSquareOutlined } from '@ant-design/icons'
 import { Chart } from '@antv/g2'
 
@@ -16,7 +16,7 @@
 
 const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
 const ChartCompileForm = asyncIconComponent(() => import('./chartcompile'))
-const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
+// const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
 const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
@@ -102,10 +102,8 @@
           return col
         })
       }
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+
+      this.updateComponent(_card, true)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -115,6 +113,7 @@
 
   componentDidMount () {
     MKEmitter.addListener('submitStyle', this.getStyle)
+    MKEmitter.addListener('plusSearch', this.plusSearch)
     MKEmitter.addListener('tabsChange', this.handleTabsChange)
     setTimeout(() => {
       this.ponitrender()
@@ -133,6 +132,7 @@
       return
     }
     MKEmitter.removeListener('submitStyle', this.getStyle)
+    MKEmitter.removeListener('plusSearch', this.plusSearch)
     MKEmitter.removeListener('tabsChange', this.handleTabsChange)
   }
 
@@ -247,27 +247,50 @@
     chart.render()
   }
 
-  updateComponent = (component) => {
-    const card = fromJS(this.state.card).toJS()
-
-    if (!is(fromJS(component.plot), fromJS(card.plot)) || !is(fromJS(component.style), fromJS(card.style)) || !is(fromJS(component.search), fromJS(card.search))) {
-      let _element = document.getElementById(card.uuid + 'canvas')
-      if (_element) {
-        _element.innerHTML = ''
+  updateComponent = (card, init) => {
+    if (!init) {
+      if (!is(fromJS({plot: card.plot, style: card.style, search: card.search}), fromJS({plot: this.state.card.plot, style: this.state.card.style, search: this.state.card.search}))) {
+        let _element = document.getElementById(card.uuid + 'canvas')
+        if (_element) {
+          _element.innerHTML = ''
+        }
+        this.$timer && clearTimeout(this.$timer)
+        this.$timer = setTimeout(() => {
+          this.ponitrender()
+        }, 150)
       }
-      this.$timer && clearTimeout(this.$timer)
-      this.$timer = setTimeout(() => {
-        this.ponitrender()
-      }, 150)
     }
 
-    component.width = component.plot.width
-    component.name = component.plot.name
+    card.width = card.plot.width
+    card.name = card.plot.name
+    card.errors = []
+
+    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+    } else if (!card.setting.primaryKey) {
+      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+    } else if (!card.setting.supModule) {
+      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+    }
     
+    let columns = card.columns.map(c => c.field)
+    if (!card.plot.Xaxis) {
+      card.errors.push({ level: 0, detail: '鍧愭爣杞村皻鏈缃紒'})
+    } else {
+      if (!columns.includes(card.plot.Xaxis)) {
+        card.errors.push({ level: 1, detail: 'X杞村湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+      }
+      if (!columns.includes(card.plot.Yaxis)) {
+        card.errors.push({ level: 1, detail: 'Y杞村湪瀛楁闆嗕腑涓嶅瓨鍦�'})
+      }
+    }
+
     this.setState({
-      card: component
+      card: card
     })
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   addSearch = () => {
@@ -287,6 +310,16 @@
 
     // 娉ㄥ唽浜嬩欢-娣诲姞鎼滅储
     MKEmitter.emit('addSearch', card.uuid, newcard)
+  }
+
+  plusSearch = (uuid, search, type) => {
+    const { card } = this.state
+    if (card.uuid !== uuid || type !== 'simple') return
+
+    search.uuid = Utils.getuuid()
+    search.focus = true
+
+    MKEmitter.emit('addSearch', card.uuid, search)
   }
 
   addButton = () => {
@@ -333,31 +366,29 @@
     this.updateComponent(_card)
   }
 
-  handleLog = (type, logs, item) => {
-    let card = fromJS(this.state.card).toJS()
+  // handleLog = (type, logs, item) => {
+  //   let card = fromJS(this.state.card).toJS()
 
-    if (type === 'revert') {
-      card.action = card.action ? [...card.action, item] : [item]
-      card.btnlog = logs
+  //   if (type === 'revert') {
+  //     card.action = card.action ? [...card.action, item] : [item]
+  //     card.btnlog = logs
 
-      this.setState({ card })
-      this.props.updateConfig(card)
-      notification.success({
-        top: 92,
-        message: '鎭㈠鎴愬姛锛�',
-        duration: 2
-      })
-    } else {
-      card.btnlog = logs
-      this.setState({ card })
-      this.props.updateConfig(card)
-      notification.success({
-        top: 92,
-        message: '娓呴櫎鎴愬姛锛�',
-        duration: 2
-      })
-    }
-  }
+  //     this.updateComponent(card)
+  //     notification.success({
+  //       top: 92,
+  //       message: '鎭㈠鎴愬姛锛�',
+  //       duration: 2
+  //     })
+  //   } else {
+  //     card.btnlog = logs
+  //     this.updateComponent(card)
+  //     notification.success({
+  //       top: 92,
+  //       message: '娓呴櫎鎴愬姛锛�',
+  //       duration: 2
+  //     })
+  //   }
+  // }
 
   clickComponent = (e) => {
     if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') {
@@ -378,9 +409,9 @@
             {appType !== 'mob' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton}/> : null}
             <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/>
             <CopyComponent type="line" card={card}/>
-            <PasteComponent config={card} options={['action']} updateConfig={this.updateComponent}/>
+            <PasteComponent config={card} options={['action', 'search']} updateConfig={this.updateComponent}/>
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
-            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog}/>
+            {/* <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog}/> */}
             <ClockComponent config={card} updateConfig={this.updateComponent}/>
             <UserComponent config={card}/>
             <DeleteOutlined className="close" title="delete" onClick={() => this.props.deletecomponent(card.uuid)}/>
@@ -392,7 +423,20 @@
         <NormalHeader config={card} updateComponent={this.updateComponent}/>
         <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
         {appType !== 'mob' ? <ActionComponent type="chart" config={card} updateaction={this.updateComponent}/> : null}
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/chart/chart-custom/index.jsx b/src/menu/components/chart/chart-custom/index.jsx
index 46ced3e..57d124c 100644
--- a/src/menu/components/chart/chart-custom/index.jsx
+++ b/src/menu/components/chart/chart-custom/index.jsx
@@ -90,10 +90,8 @@
           return col
         })
       }
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+
+      this.updateComponent(_card, true)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -176,28 +174,40 @@
     }
   }
 
-  updateComponent = (component) => {
-    const card = fromJS(this.state.card).toJS()
-    if (!is(fromJS(component.plot), fromJS(card.plot)) || !is(fromJS(component.style), fromJS(card.style)) || !is(fromJS(component.search), fromJS(card.search))) {
-      let _element = document.getElementById(card.uuid + 'canvas')
-      if (_element) {
-        _element.innerHTML = ''
-        _element.removeAttribute('_echarts_instance_')
-        _element.removeAttribute('style')
+  updateComponent = (card, init) => {
+    if (!init) {
+      if (!is(fromJS({plot: card.plot, style: card.style, search: card.search}), fromJS({plot: this.state.card.plot, style: this.state.card.style, search: this.state.card.search}))) {
+        let _element = document.getElementById(card.uuid + 'canvas')
+        if (_element) {
+          _element.innerHTML = ''
+          _element.removeAttribute('_echarts_instance_')
+          _element.removeAttribute('style')
+        }
+        this.$timer && clearTimeout(this.$timer)
+        this.$timer = setTimeout(() => {
+          this.viewrender()
+        }, 150)
       }
-      this.$timer && clearTimeout(this.$timer)
-      this.$timer = setTimeout(() => {
-        this.viewrender()
-      }, 150)
     }
 
-    component.width = component.plot.width
-    component.name = component.plot.name
+    card.width = card.plot.width
+    card.name = card.plot.name
+    card.errors = []
+
+    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+    } else if (!card.setting.primaryKey) {
+      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+    } else if (!card.setting.supModule) {
+      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+    }
     
     this.setState({
-      card: component
+      card: card
     })
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   addSearch = () => {
@@ -263,7 +273,20 @@
         </Popover>
         <NormalHeader config={card} updateComponent={this.updateComponent}/>
         <div className="canvas" id={card.uuid + 'canvas'} ref={ref => this.wrap = ref}></div>
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/code/sandbox/index.jsx b/src/menu/components/code/sandbox/index.jsx
index 5e9f004..292bada 100644
--- a/src/menu/components/code/sandbox/index.jsx
+++ b/src/menu/components/code/sandbox/index.jsx
@@ -51,7 +51,7 @@
         name: card.name,
         subtype: card.subtype,
         setting: { interType: 'system' },
-        wrap: { name: card.name, width: card.width || 24, encryption: 'true' },
+        wrap: { name: card.name, datatype: 'dynamic', width: card.width || 24, encryption: 'true' },
         style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
         columns: [],
         scripts: [],
@@ -75,10 +75,7 @@
         _card.scripts = config.scripts
       }
       
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+      this.updateComponent(_card)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -107,15 +104,29 @@
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+
+    card.errors = []
+
+    if (card.wrap.datatype !== 'static') {
+      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+      } else if (!card.setting.primaryKey) {
+        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+      } else if (!card.setting.supModule) {
+        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+      }
+    }
+
     this.setState({
-      card: component
+      card: card
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
-
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   changeStyle = () => {
@@ -130,22 +141,8 @@
     if (comIds[0] !== card.uuid || comIds.length !== 1) return
 
     let _card = {...card, style}
-
-    this.setState({
-      card: _card
-    })
     
-    this.props.updateConfig(_card)
-  }
-
-  /**
-   * @description 鏇存柊鎼滅储鏉′欢閰嶇疆淇℃伅
-   */
-  updateconfig = (config) => {
-    this.setState({
-      card: config
-    })
-    this.props.updateConfig(config)
+    this.updateComponent(_card)
   }
 
   getWrapForms = () => {
@@ -155,7 +152,7 @@
   }
 
   updateWrap = (res) => {
-    this.updateconfig({...this.state.card, wrap: res})
+    this.updateComponent({...this.state.card, wrap: res})
   }
 
   clickComponent = (e) => {
@@ -188,7 +185,20 @@
           <ToolOutlined />
         </Popover>
         <CodeContent name={card.name} html={card.html} css={card.css} js={card.js}/>
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/editor/braft-editor/index.jsx b/src/menu/components/editor/braft-editor/index.jsx
index 77f9713..a9300dc 100644
--- a/src/menu/components/editor/braft-editor/index.jsx
+++ b/src/menu/components/editor/braft-editor/index.jsx
@@ -48,7 +48,7 @@
         name: card.name,
         subtype: card.subtype,
         setting: { interType: 'system' },
-        wrap: { name: card.name, width: card.width || 24, encryption: 'true', minHeight: 100 },
+        wrap: { name: card.name, datatype: 'dynamic', width: card.width || 24, encryption: 'true', minHeight: 100 },
         style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
         headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
         columns: [],
@@ -69,11 +69,8 @@
         _card.columns = config.columns
         _card.scripts = config.scripts
       }
-      
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+
+      this.updateComponent(_card)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -102,15 +99,29 @@
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+
+    card.errors = []
+
+    if (card.wrap.datatype !== 'static') {
+      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+      } else if (!card.setting.primaryKey) {
+        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+      } else if (!card.setting.supModule) {
+        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+      }
+    }
+
     this.setState({
-      card: component
+      card: card
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
-
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   changeStyle = () => {
@@ -130,12 +141,8 @@
     } else {
       return
     }
-
-    this.setState({
-      card: _card
-    })
     
-    this.props.updateConfig(_card)
+    this.updateComponent(_card)
   }
 
   getWrapForms = () => {
@@ -186,7 +193,20 @@
           value={card.wrap.datatype !== 'static' ? '<p class="empty-content">瀵屾枃鏈�</p>' : card.html}
           encryption="false"
         />
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/form/dragtitle/card.jsx b/src/menu/components/form/dragtitle/card.jsx
index 78301dd..63a8d4b 100644
--- a/src/menu/components/form/dragtitle/card.jsx
+++ b/src/menu/components/form/dragtitle/card.jsx
@@ -9,6 +9,7 @@
 import './index.scss'
 
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
+const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 
 const Card = ({ id, card, active, moveCard, findCard, closeCard, selectCard, updateGroup }) => {
   const originalIndex = findCard(id).index
@@ -32,7 +33,7 @@
       }
     }
   })
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   const close = () => {
     closeCard(id)
@@ -42,7 +43,7 @@
     selectCard(id)
   }
 
-  const getForms = () =>{
+  const getForms = () => {
     return getForm(card)
   }
 
@@ -73,6 +74,7 @@
         <NormalForm title="鍒嗙粍缂栬緫" width={850} update={updateSetting} getForms={getForms}>
           <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
         </NormalForm>
+        <CopyComponent type="formgroup" card={card}/>
         <CloseOutlined className="close" type="close" onClick={close} />
       </div>
     } trigger="hover">
diff --git a/src/menu/components/form/dragtitle/options.jsx b/src/menu/components/form/dragtitle/options.jsx
index 39849e5..b367eab 100644
--- a/src/menu/components/form/dragtitle/options.jsx
+++ b/src/menu/components/form/dragtitle/options.jsx
@@ -46,6 +46,18 @@
     },
     {
       type: 'radio',
+      field: 'cache',
+      label: '閫夐」鏌ヨ',
+      initval: group.setting.cache || 'true',
+      tooltip: '闇�瑕侀�氳繃鏁版嵁婧愭煡璇㈢殑閫夐」锛屾槸鍚︿娇鐢ㄧ紦瀛樸��',
+      required: false,
+      options: [
+        {value: 'true', label: '缂撳瓨'},
+        {value: 'false', label: '瀹炴椂'},
+      ]
+    },
+    {
+      type: 'radio',
       field: 'align',
       label: '琛ㄥ崟鎺掑垪',
       initval: group.setting.align || 'left_right',
@@ -58,6 +70,20 @@
     },
     {
       type: 'radio',
+      field: 'verticalSpace',
+      label: '绔栧悜闂撮殭',
+      initval: group.setting.verticalSpace || 'normal',
+      tooltip: '姝e父闂撮殭浼氶鐣欏嚭鎶ラ敊淇℃伅鐨勪綅缃紝闃叉琛ㄥ崟浣嶇疆鍙戠敓鍙樺寲銆�',
+      required: false,
+      options: [
+        {value: 'normal', label: '姝e父'},
+        {value: 'middle', label: '涓�'},
+        {value: 'small', label: '灏�'},
+      ],
+      forbid: appType === 'mob'
+    },
+    {
+      type: 'radio',
       field: 'prevEnable',
       label: '涓婁竴姝�',
       initval: group.prevButton ? group.prevButton.enable || 'false' : 'false',
diff --git a/src/menu/components/form/formaction/actionform/index.jsx b/src/menu/components/form/formaction/actionform/index.jsx
index 319f771..a49f945 100644
--- a/src/menu/components/form/formaction/actionform/index.jsx
+++ b/src/menu/components/form/formaction/actionform/index.jsx
@@ -21,6 +21,7 @@
     formlist: null,  // 琛ㄥ崟淇℃伅
     interType: null, // 鎺ュ彛绫诲瀷锛氬唴閮ㄣ�佸閮�
     procMode: null,  // 鍙傛暟鏂瑰紡
+    linkmenu: null
   }
 
   
@@ -30,11 +31,12 @@
     let _intertype = card.intertype || 'system'  // 鎺ュ彛绫诲瀷
     let _procMode = card.procMode || 'system'    // 鍙傛暟璇锋眰鏂瑰紡
 
-    let _options = this.getOptions(_intertype, _procMode)
+    let _options = this.getOptions(_intertype, _procMode, card.linkmenu)
 
     this.setState({
       interType: _intertype,
       procMode: _procMode,
+      linkmenu: card.linkmenu,
       formlist: this.props.formlist.map(item => {
         if (item.key === 'innerFunc' && _procMode === 'inner') {
           item.required = true
@@ -46,7 +48,7 @@
     })
   }
 
-  getOptions = (_intertype, _procMode) => {
+  getOptions = (_intertype, _procMode, linkmenu) => {
     const { card } = this.props
 
     if (card.type === 'prev') {
@@ -54,7 +56,7 @@
     } else if (card.type === 'next') {
       return ['type', 'label', 'enable']
     }
-    let _options = ['type', 'label', 'intertype', 'syncComponent', 'anchors', 'linkmenu', 'open', 'enable', 'output', 'reload'] // 閫夐」鍒楄〃
+    let _options = ['type', 'label', 'intertype', 'Ot', 'execSuccess', 'syncComponent', 'anchors', 'linkmenu', 'enable', 'output', 'reload'] // 閫夐」鍒楄〃
     
     if (_intertype === 'custom') {
       _options.pop()
@@ -71,6 +73,10 @@
     } else {
       _options.push('sql', 'sqlType')
     }
+    
+    if (linkmenu && linkmenu !== 'goback') {
+      _options.push('open')
+    }
 
     return _options
   }
@@ -82,10 +88,10 @@
    * 3銆佸垏鎹㈡爣绛剧被鍨嬶紝閲嶇疆鍙�夋爣绛�
    */
   optionChange = (key, value) => {
-    const { procMode } = this.state
+    const { procMode, linkmenu } = this.state
 
     if (key === 'intertype') {
-      let _options = this.getOptions(value, procMode)
+      let _options = this.getOptions(value, procMode, linkmenu)
 
       this.setState({
         interType: value,
@@ -101,7 +107,7 @@
         })
       })
     } else if (key === 'procMode') {
-      let _options = this.getOptions(this.state.interType, value)
+      let _options = this.getOptions(this.state.interType, value, linkmenu)
 
       this.setState({
         procMode: value,
@@ -111,6 +117,16 @@
           if (item.key === 'innerFunc') {
             item.required = true
           }
+          return item
+        })
+      })
+    } else if (key === 'linkmenu') {
+      let _options = this.getOptions(this.state.interType, procMode, value)
+
+      this.setState({
+        linkmenu: value,
+        formlist: this.state.formlist.map(item => {
+          item.hidden = !_options.includes(item.key)
           return item
         })
       })
@@ -144,6 +160,7 @@
 
   getFields() {
     const { getFieldDecorator } = this.props.form
+    const { interType } = this.state
     const fields = []
 
     this.state.formlist.forEach((item, index) => {
@@ -169,6 +186,24 @@
             max: formRule.func.max,
             message: formRule.func.maxMessage
           }]
+        } else if (item.key === 'output') {
+          if (interType === '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 = [{
             max: formRule.input.max,
diff --git a/src/menu/components/form/formaction/formconfig.jsx b/src/menu/components/form/formaction/formconfig.jsx
index 5700279..e406576 100644
--- a/src/menu/components/form/formaction/formconfig.jsx
+++ b/src/menu/components/form/formaction/formconfig.jsx
@@ -31,9 +31,7 @@
     } else {
       menulist = []
     }
-    if (appType === 'mob') {
-      menulist.push({value: 'goback', text: '杩斿洖锛堜笂涓�椤碉級'})
-    }
+    menulist.push({value: 'goback', text: '杩斿洖锛堜笂涓�椤碉級'})
   } else {
     menulist = sessionStorage.getItem('fstMenuList')
     if (menulist) {
@@ -244,12 +242,43 @@
       readonly: false
     },
     {
+      type: 'radio',
+      key: 'Ot',
+      label: '琛岃缃�',
+      initVal: card.Ot,
+      required: true,
+      options: [{
+        value: 'notRequired',
+        text: '涓嶉�夋嫨琛�'
+      }, {
+        value: 'requiredSgl',
+        text: '閫夋嫨鍗曡'
+      }]
+    },
+    {
+      type: 'select',
+      key: 'execSuccess',
+      label: '鎴愬姛鍚�',
+      initVal: card.execSuccess || 'grid',
+      required: true,
+      options: [{
+        value: 'never',
+        text: '涓嶅埛鏂�'
+      }, {
+        value: 'grid',
+        text: '鍒锋柊褰撳墠缁勪欢'
+      }, {
+        value: 'mainline',
+        text: '鍒锋柊涓婄骇缁勪欢 - 琛�'
+      }]
+    },
+    {
       type: (appType === 'pc' || appType === 'mob') ? 'select' : 'cascader',
       key: 'linkmenu',
       label: '涓嬩竴姝ユ搷浣�',
       tooltip: '鎵ц鎴愬姛鍚庨渶瑕佹墦寮�鐨勮彍鍗曘��',
       initVal: card.linkmenu,
-      help: '鍙繑鍥炰笂涓�椤点��',
+      help: appType === 'pc' || appType === 'mob' ? '鍙繑鍥炰笂涓�椤点��' : null,
       required: false,
       allowClear: true,
       options: menulist
@@ -258,7 +287,7 @@
       type: 'text',
       key: 'output',
       label: '杩斿洖鍊�',
-      tooltip: '鎵ц鎴愬姛鍚庣殑杩斿洖鍊笺�備緥濡傦細@id',
+      tooltip: '鎵ц鎴愬姛鍚庣殑杩斿洖鍊笺�傜郴缁熷嚱鏁板彲鎸囧畾杩斿洖鐨勫彉閲忥紙浠绗﹀紑澶达紝濡侤id锛夛紱鑷畾涔夊嚱鏁板彲鎸囧畾杩斿洖瀛楁锛堝id锛夈��',
       initVal: card.output || '',
       required: false
     },
@@ -268,21 +297,18 @@
       label: '鎵撳紑鏂瑰紡',
       initVal: card.open || 'blank',
       required: false,
-      forbid: appType !== 'pc',
-      options: [{
-        value: 'blank',
-        text: '鏂扮獥鍙�'
-      }, {
-        value: 'self',
-        text: '褰撳墠绐楀彛'
-      }]
+      forbid: appType !== 'pc' && appType !== 'mob',
+      options: [
+        {value: 'blank', text: appType !== 'mob' ? '鏂扮獥鍙�' : '鏂伴〉闈�'},
+        {value: 'self', text: appType !== 'mob' ? '褰撳墠绐楀彛' : '褰撳墠椤甸潰'},
+      ]
     },
     {
       type: 'cascader',
       key: 'syncComponent',
       label: '鍚屾鍒锋柊',
       initVal: card.syncComponent,
-      tooltip: '鎵ц鎴愬姛鍚庨渶瑕佸埛鏂扮殑缁勪欢銆�',
+      tooltip: '鎵ц鎴愬姛鍚庨渶瑕佸埛鏂扮殑缁勪欢銆傛敞锛氶�夋嫨褰撳墠缁勪欢鐨勪笂绾х粍浠舵棤鏁堛��',
       required: false,
       options: modules
     },
@@ -291,7 +317,7 @@
       key: 'anchors',
       label: '璺宠浆閿氱偣',
       initVal: card.anchors || [],
-      tooltip: '鎵ц鎴愬姛鍚庯紝闇�瑕佽烦杞殑閿氱偣',
+      tooltip: '鎵ц鎴愬姛鍚庯紝闇�瑕佽烦杞殑閿氱偣銆�' + (appType === 'mob' ? '娉細灏忕▼搴忎腑鏃犳晥' : ''),
       required: false,
       options: anchors
     },
diff --git a/src/menu/components/form/formaction/index.jsx b/src/menu/components/form/formaction/index.jsx
index 35ebf53..5460f4f 100644
--- a/src/menu/components/form/formaction/index.jsx
+++ b/src/menu/components/form/formaction/index.jsx
@@ -101,8 +101,17 @@
       <p style={{marginBottom: '5px'}}>{this.state.dict['model.tooltip.func.innerface'].replace('@ableField', ableField)}</p>
     </div>
 
-    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid) || []
+    let supId = ''
+    if (config.wrap.linkType === 'sup') {
+      supId = config.wrap.supModule[config.wrap.supModule.length - 1]
+    }
+
+    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid, supId) || []
     let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, config.uuid) || []
+
+    if (card.type === 'submit' && !card.Ot) {
+      card.Ot = config.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
+    }
 
     this.setState({
       visible: true,
@@ -158,6 +167,7 @@
     this.setState({
       profVisible: true
     })
+    MKEmitter.emit('modalStatus', '楠岃瘉淇℃伅')
   }
 
   /**
@@ -173,6 +183,7 @@
         profVisible: false
       })
       this.props.updateconfig(group)
+      MKEmitter.emit('modalStatus', false)
     })
   }
 
@@ -257,9 +268,11 @@
             if (this.verifyRef.handleCancel) {
               this.verifyRef.handleCancel().then(() => {
                 this.setState({ profVisible: false })
+                MKEmitter.emit('modalStatus', false)
               })
             } else {
               this.setState({ profVisible: false })
+              MKEmitter.emit('modalStatus', false)
             }
           }}
           destroyOnClose
diff --git a/src/menu/components/form/formaction/index.scss b/src/menu/components/form/formaction/index.scss
index 88793fc..d58f09a 100644
--- a/src/menu/components/form/formaction/index.scss
+++ b/src/menu/components/form/formaction/index.scss
@@ -4,6 +4,7 @@
   padding-bottom: 10px;
 
   .prev {
+    color: rgba(0, 0, 0, 0.85);
     height: auto;
   }
   .submit {
@@ -11,6 +12,7 @@
     height: auto;
   }
   .skip {
+    color: rgba(0, 0, 0, 0.85);
     float: right;
     height: auto;
   }
diff --git a/src/menu/components/form/normal-form/index.jsx b/src/menu/components/form/simple-form/index.jsx
similarity index 67%
copy from src/menu/components/form/normal-form/index.jsx
copy to src/menu/components/form/simple-form/index.jsx
index e10544c..866a334 100644
--- a/src/menu/components/form/normal-form/index.jsx
+++ b/src/menu/components/form/simple-form/index.jsx
@@ -18,12 +18,12 @@
 import './index.scss'
 
 const ModalForm = asyncComponent(() => import('@/templates/zshare/modalform'))
-const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
+const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const CardComponent = asyncComponent(() => import('@/templates/modalconfig/dragelement'))
 const MobCardComponent = asyncComponent(() => import('@/mob/components/formdragelement'))
-const FormTitle = asyncComponent(() => import('../dragtitle'))
 const FormAction = asyncComponent(() => import('../formaction'))
+const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
 const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
@@ -31,7 +31,7 @@
 
 const { confirm } = Modal
 
-class PropCardEditComponent extends Component {
+class SimpleFormComponent extends Component {
   static propTpyes = {
     card: PropTypes.object,
     deletecomponent: PropTypes.func,
@@ -43,7 +43,6 @@
     appType: sessionStorage.getItem('appType'),
     card: null,
     back: false,
-    group: null,
     showField: false,
     visible: false,
     editform: null,
@@ -68,20 +67,18 @@
         width: card.width || 24,
         name: card.name,
         subtype: card.subtype,
-        setting: { },
-        wrap: { name: card.name, width: card.width || 24, datatype: 'static', groupLabel: 'show', color: '#1890ff' },
+        setting: { interType: 'system' },
+        wrap: { name: card.name, width: card.width || 24, datatype: 'static' },
         style: { marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px' },
+        headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' },
         columns: [],
         scripts: [],
         subcards: [{
           uuid: Utils.getuuid(),
-          setting: {title: '绗竴姝�', align: 'left_right'},
-          sort: 1,
+          setting: {title: '绌�', align: 'left_right', enable: 'true'},
           style: {},
           fields: [],
-          prevButton: {label: '涓婁竴姝�', type: 'prev', enable: 'false', style: {marginRight: '15px', paddingTop: '5px', paddingBottom: '5px'}},
-          subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
-          nextButton: {label: '璺宠繃', type: 'next', enable: 'false', style: {paddingTop: '5px', paddingBottom: '5px'}}
+          subButton: {label: '鎻愪氦', type: 'submit', intertype: 'system', reload: 'false', sqlType: 'update', sql: '', Ot: 'notRequired', execSuccess: 'never', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
         }]
       }
 
@@ -105,16 +102,11 @@
           return scard
         })
       }
-      this.setState({
-        card: _card,
-        group: _card.subcards[0] || null
-      })
-      this.props.updateConfig(_card)
+      this.updateComponent(_card)
     } else {
       let _card = fromJS(card).toJS()
       this.setState({
-        card: _card,
-        group: _card.subcards[0] || null
+        card: _card
       })
     }
   }
@@ -159,15 +151,55 @@
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+    card.errors = []
+
+    if (card.wrap.datatype !== 'static') {
+      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+      } else if (!card.setting.primaryKey) {
+        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+      } else if (!card.setting.supModule) {
+        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+      }
+
+      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
+      if (supModule === 'empty') {
+        supModule = ''
+      }
+      let columns = card.columns.map(c => c.field)
+      let lowcols = card.columns.map(c => c.field.toLowerCase())
+
+      card.subcards.forEach(item => {
+        item.fields.forEach(m => {
+          if (m.type === 'linkMain' && !supModule) {
+            card.errors.push({ level: 1, detail: `鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+          } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+            card.errors.push({ level: 1, detail: `琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+          }
+        })
+      })
+    } else {
+      let supModule = card.wrap.supModule ? card.wrap.supModule[card.wrap.supModule.length - 1] : ''
+
+      card.subcards.forEach(item => {
+        item.fields.forEach(m => {
+          if (m.type === 'linkMain' && !supModule) {
+            card.errors.push({ level: 1, detail: `鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+          }
+        })
+      })
+    }
+
     this.setState({
-      card: component
+      card: card
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
-
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   /**
@@ -181,9 +213,7 @@
       return item
     })
 
-    this.setState({card})
-
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   changeStyle = () => {
@@ -193,18 +223,18 @@
   }
 
   getStyle = (comIds, style) => {
-    const { card, group } = this.state
+    const { card } = this.state
 
     if (comIds[0] === 'form') {
-      let Index = group.fields.findIndex(n => n.uuid === comIds[1])
+      let Index = card.subcards[0].fields.findIndex(n => n.uuid === comIds[1])
 
       if (Index === -1) return
       
-      let _group = fromJS(group).toJS()
+      let _card = fromJS(card).toJS()
 
-      _group.fields[Index].style = style
+      _card.subcards[0].fields[Index].style = style
 
-      this.updateGroup(_group)
+      this.updateComponent(_card)
 
       return
     }
@@ -213,107 +243,32 @@
 
     let _card = {...card, style}
 
-    this.setState({
-      card: _card
-    })
-    
-    this.props.updateConfig(_card)
+    this.updateComponent(_card)
   }
 
-  addCard = () => {
+  updateGroup = (res) => {
     let card = fromJS(this.state.card).toJS()
 
-    let newcard = {
-      uuid: Utils.getuuid(),
-      setting: { title: `绗�${card.subcards.length + 1}姝, align: 'left_right' },
-      sort: card.subcards.length + 1,
-      style: {},
-      fields: [],
-      prevButton: {label: '涓婁竴姝�', type: 'prev', enable: 'false', style: {marginRight: '15px', paddingTop: '5px', paddingBottom: '5px'}},
-      subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
-      nextButton: {label: '璺宠繃', type: 'next', enable: 'false', style: {paddingTop: '5px', paddingBottom: '5px'}}
-    }
+    card.subcards[0] = res
 
-    card.subcards.push(newcard)
-    
-    this.setState({
-      card,
-      group: newcard
-    })
-    this.props.updateConfig(card)
-  }
-
-  changecards = (list) => {
-    let card = fromJS(this.state.card).toJS()
-    card.subcards = list.map((item, index) => {
-      item.sort = index + 1
-      return item
-    })
-
-    this.setState({card})
-    this.props.updateConfig(card)
-  }
-
-  selectGroup = (item) => {
-    this.setState({
-      group: item
-    })
-  }
-
-  changeGroup = (item) => {
-    this.updateGroup(item)
-  }
-
-  closeGroup = (cell) => {
-    const { group } = this.state
-    let card = fromJS(this.state.card).toJS()
-    const _this = this
-
-    confirm({
-      content: '纭畾鍒犻櫎鍒嗙粍鍚楋紵',
-      onOk() {
-        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
-        let _group = group
-
-        if (group.uuid === cell.uuid) {
-          _group = card.subcards[0] || null
-        }
-
-        _this.setState({card, group: _group})
-        _this.props.updateConfig(card)
-      },
-      onCancel() {}
-    })
-  }
-
-  updateGroup = (group) => {
-    let card = fromJS(this.state.card).toJS()
-
-    card.subcards = card.subcards.map(item => {
-      if (item.uuid === group.uuid) {
-        return group
-      }
-      return item
-    })
-
-    this.setState({card, group})
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   plusFields = (items) => {
-    let _group = fromJS(this.state.group).toJS()
+    const { card } = this.state
 
-    _group.fields.push(...items)
+    let _card = fromJS(card).toJS()
 
-    this.updateGroup(_group)
+    _card.subcards[0].fields.push(...items)
+
+    this.updateComponent(_card)
   }
-
+  
   changecols = (type) => {
     let card = fromJS(this.state.card).toJS()
-    let config = fromJS(this.state.group).toJS()
     let _this = this
 
-    config.fields = config.fields.map(item => {
+    card.subcards[0].fields = card.subcards[0].fields.map(item => {
       item.labelwidth = 33.3
       item.span = 24
       if (['textarea','split','hint','checkcard','brafteditor'].includes(item.type)) {
@@ -337,59 +292,35 @@
     confirm({
       content: `纭畾鍒囨崲涓�${type}鍒楀悧锛焋,
       onOk() {
-        card.subcards = card.subcards.map(item => {
-          if (item.uuid === config.uuid) {
-            return config
-          }
-          return item
-        })
-        _this.setState({group: config, card})
-        _this.props.updateConfig(card)
+        _this.updateComponent(card)
       },
       onCancel() {}
     })
   }
 
   handleList = (list, newcard) => {
-    let group = fromJS(this.state.group).toJS()
     let card = fromJS(this.state.card).toJS()
 
-    group.fields = list
+    card.subcards[0].fields = list
 
-    card.subcards = card.subcards.map(item => {
-      if (item.uuid === group.uuid) {
-        return group
-      }
-      return item
-    })
-
-    this.setState({card, group}, () => {
+    this.setState({}, () => {
       if (newcard) {
         this.handleForm(newcard)
       }
     })
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   closeForm = (cell) => {
-    let group = fromJS(this.state.group).toJS()
     let card = fromJS(this.state.card).toJS()
     let _this = this
 
-    group.fields = group.fields.filter(item => item.uuid !== cell.uuid)
-
-    card.subcards = card.subcards.map(item => {
-      if (item.uuid === group.uuid) {
-        return group
-      }
-      return item
-    })
+    card.subcards[0].fields = card.subcards[0].fields.filter(item => item.uuid !== cell.uuid)
 
     confirm({
       content: `纭畾鍒犻櫎<<${cell.label}>>鍚楋紵`,
       onOk() {
-        _this.setState({card, group})
-        _this.props.updateConfig(card)
+        _this.updateComponent(card)
       },
       onCancel() {}
     })
@@ -397,8 +328,8 @@
 
   addForm = () => {
     const { appType } = this.state
-    let group = fromJS(this.state.group).toJS()
-    let lastItem = group.fields[group.fields.length - 1]
+    let card = fromJS(this.state.card).toJS()
+    let lastItem = card.subcards[0].fields[card.subcards[0].fields.length - 1]
     let span = appType === 'mob' ? 24 : 12
     if (lastItem && lastItem.span) {
       span = lastItem.span
@@ -422,26 +353,25 @@
       focus: true
     }
 
-    group.fields.push(newcard)
+    card.subcards[0].fields.push(newcard)
 
-    this.setState({group}, () => {
+    this.setState({card}, () => {
       this.handleForm(newcard)
     })
   }
 
   editModalCancel = () => {
-    let group = fromJS(this.state.group).toJS()
-    group.fields = group.fields.filter(item => !item.focus)
+    let card = fromJS(this.state.card).toJS()
+    card.subcards[0].fields = card.subcards[0].fields.filter(item => !item.focus)
 
-    this.setState({group, visible: false, editform: null})
-    this.updateGroup(group)
+    this.setState({card, visible: false, editform: null})
   }
 
   /**
    * @description 琛ㄥ崟缂栬緫
    */
   handleForm = (_item) => {
-    const { card, group, appType } = this.state
+    const { card, appType } = this.state
     let _form = fromJS(_item).toJS()
     let _inputfields = []
     let _tabfields = []
@@ -456,7 +386,7 @@
     let _inputIndex = 1
     let _tabIndex = 1
     let _linkIndex = 1
-    group.fields.forEach((item, i) => {
+    card.subcards[0].fields.forEach((item, i) => {
       if (_form.uuid === item.uuid) {
         index = i
       }
@@ -473,8 +403,7 @@
         })
         _inputIndex++
       }
-
-      if (_item.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
+      if (_form.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) {
         _tabfields.push({
           field: item.field,
           label: _tabIndex + '銆�' + label
@@ -495,13 +424,14 @@
         uniq.set(item.field, true)
 
         _linkableFields.push({
-          field: item.field,
-          label: _linkIndex + '銆�' + item.label + ' (琛ㄥ崟)'
+          value: item.field,
+          text: _linkIndex + '銆�' + item.label + ' (琛ㄥ崟)'
         })
         _linksupFields.push({
-          field: item.field,
-          label: _linkIndex + '銆�' + label
+          value: item.field,
+          text: _linkIndex + '銆�' + label
         })
+
         _linkIndex++
       }
     })
@@ -510,9 +440,9 @@
 
     if (index !== null) {
       if (index === 0) {
-        standardform = group.fields[index + 1] || null
+        standardform = card.subcards[0].fields[index + 1] || null
       } else {
-        standardform = group.fields[index - 1] || null
+        standardform = card.subcards[0].fields[index - 1] || null
       }
     }
 
@@ -554,10 +484,10 @@
    */
   handleSubmit = () => {
     this.formRef.handleConfirm().then(res => {
-      let _config = fromJS(this.state.group).toJS()
+      let _config = fromJS(this.state.card).toJS()
       let fieldrepet = false // 瀛楁閲嶅
 
-      _config.fields = _config.fields.map(item => {
+      _config.subcards[0].fields = _config.subcards[0].fields.map(item => {
         if (item.uuid !== res.uuid && res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
           fieldrepet = true
         }
@@ -592,10 +522,10 @@
           LText: res.dataSource
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
         
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
 
         if (window.GLOB.mainSystemApi && res.database === 'sso') {
@@ -609,7 +539,7 @@
               editform: null,
               visible: false
             })
-            this.updateGroup(_config)
+            this.updateComponent(_config)
           } else {
             this.setState({sqlVerifing: false})
             
@@ -623,16 +553,48 @@
           editform: null,
           visible: false
         })
-        this.updateGroup(_config)
+        this.updateComponent(_config)
       }
     })
   }
 
   pasteForm = (res) => {
-    let _config = fromJS(this.state.group).toJS()
+    let _config = fromJS(this.state.card).toJS()
+
+    if (res.subButton) {
+      let _this = this
+
+      _config.subcards[0].setting.focus = res.focus
+      _config.subcards[0].setting.cache = res.cache
+      _config.subcards[0].setting.align = res.align
+      _config.subcards[0].setting.enable = res.enable
+      _config.subcards[0].setting.verticalSpace = res.verticalSpace || ''
+      _config.wrap.focus = res.focus
+      _config.wrap.cache = res.cache
+      _config.wrap.align = res.align
+      _config.wrap.enable = res.enable
+      _config.wrap.verticalSpace = res.verticalSpace || ''
+
+      _config.subcards[0].subButton = res.subButton
+      
+      _config.subcards[0].fields = res.fields.map(item => {
+        item.uuid = Utils.getuuid()
+        return item
+      })
+
+      confirm({
+        content: `鏇挎崲琛ㄥ崟鍙婃寜閽厤缃紵`,
+        onOk() {
+          _this.updateComponent(_config)
+        },
+        onCancel() {}
+      })
+      return
+    }
+
     let fieldrepet = false // 瀛楁閲嶅
 
-    _config.fields.forEach(item => {
+    _config.subcards[0].fields.forEach(item => {
       if (res.field && item.field && item.field.toLowerCase() === res.field.toLowerCase()) {
         fieldrepet = true
       }
@@ -646,9 +608,9 @@
       })
       return
     }
-    _config.fields.push(res)
+    _config.subcards[0].fields.push(res)
 
-    this.updateGroup(_config)
+    this.updateComponent(_config)
 
     this.handleForm(res)
 
@@ -664,7 +626,38 @@
   }
 
   updateWrap = (res) => {
-    this.updateComponent({...this.state.card, wrap: res})
+    let _card = {...this.state.card, wrap: res}
+
+    if (res.datatype === 'static') {
+      if (res.supModule && res.supModule.length > 0) {
+        _card.setting.supModule = res.supModule
+      } else {
+        _card.setting.supModule = ''
+      }
+    }
+
+    _card.subcards[0].setting.focus = _card.wrap.focus
+    _card.subcards[0].setting.cache = _card.wrap.cache
+    _card.subcards[0].setting.align = _card.wrap.align
+    _card.subcards[0].setting.enable = _card.wrap.enable
+    _card.subcards[0].setting.verticalSpace = _card.wrap.verticalSpace
+
+    this.updateComponent(_card)
+  }
+
+  clearGroup = () => {
+    let card = fromJS(this.state.card).toJS()
+    let _this = this
+
+    card.subcards[0].fields = []
+
+    confirm({
+      content: `纭畾娓呯┖琛ㄥ崟鍚楋紵`,
+      onOk() {
+        _this.updateComponent(card)
+      },
+      onCancel() {}
+    })
   }
 
   clickComponent = (e) => {
@@ -675,18 +668,18 @@
   }
 
   render() {
-    const { card, dict, group, appType } = this.state
+    const { card, dict, appType } = this.state
 
     return (
-      <div className="menu-normal-form-edit-box" style={resetStyle(card.style)} onClick={this.clickComponent} id={card.uuid}>
+      <div className="menu-simple-form-edit-box" style={resetStyle(card.style)} onClick={this.clickComponent} id={card.uuid}>
+        <NormalHeader config={card} updateComponent={this.updateComponent}/>
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
-            <PlusOutlined className="plus" title="娣诲姞鍒嗙粍" onClick={this.addCard}/>
             <NormalForm title="琛ㄥ崟璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
-            <CopyComponent type="stepform" card={card}/>
-            <PasteComponent config={card} options={['form']} updateConfig={this.pasteForm} />
+            <CopyComponent type="simpleform" card={card}/>
+            <PasteComponent config={card} options={['form', 'formgroup']} updateConfig={this.pasteForm} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
             <UserComponent config={card}/>
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} />
@@ -696,17 +689,10 @@
         } trigger="hover">
           <ToolOutlined />
         </Popover>
-        <FormTitle
-          list={card.subcards}
-          selectId={group ? group.uuid : ''}
-          handleList={this.changecards}
-          handleGroup={this.changeGroup}
-          closeGroup={this.closeGroup}
-          selectGroup={this.selectGroup}
-        />
-        {group ? <div className="form-area">
+        <div className="form-area">
           <PlusOutlined className="plus" title="娣诲姞琛ㄥ崟" onClick={this.addForm}/>
-          <FieldsComponent config={group} type="form" plusFields={this.plusFields} />
+          <FieldsComponent config={card.subcards[0]} type="form" plusFields={this.plusFields} />
+          <span style={{color: 'red', marginLeft: '30px', cursor: 'pointer'}} onClick={this.clearGroup}>娓呯┖</span>
           <Switch checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
           {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1鍒�</Button> : null}
           {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2鍒�</Button> : null}
@@ -714,24 +700,37 @@
           {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(4)}>4鍒�</Button> : null}
           <div style={{clear: 'both'}}></div>
           {appType !== 'mob' ? <CardComponent
-            list={group.fields}
-            setting={group.setting}
+            list={card.subcards[0].fields}
+            setting={card.subcards[0].setting}
             showField={this.state.showField}
             placeholder={dict['header.form.modal.placeholder']}
             handleList={this.handleList}
             handleForm={this.handleForm}
             closeForm={this.closeForm}
           /> : <MobCardComponent
-            list={group.fields}
-            setting={group.setting}
+            list={card.subcards[0].fields}
+            setting={card.subcards[0].setting}
             showField={this.state.showField}
             handleList={this.handleList}
             handleForm={this.handleForm}
             closeForm={this.closeForm}
           />}
-          <FormAction config={card} group={group} updateconfig={this.updateGroup}/>
-        </div> : null}
-        <div className="component-name"><div className="center">{card.name}</div></div>
+          <FormAction config={card} group={card.subcards[0]} updateconfig={this.updateGroup}/>
+        </div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
         <Modal
           title={this.state.dict['model.edit']}
           visible={this.state.visible}
@@ -756,4 +755,4 @@
   }
 }
 
-export default PropCardEditComponent
\ No newline at end of file
+export default SimpleFormComponent
\ No newline at end of file
diff --git a/src/menu/components/form/normal-form/index.scss b/src/menu/components/form/simple-form/index.scss
similarity index 90%
copy from src/menu/components/form/normal-form/index.scss
copy to src/menu/components/form/simple-form/index.scss
index ff50139..c02b072 100644
--- a/src/menu/components/form/normal-form/index.scss
+++ b/src/menu/components/form/simple-form/index.scss
@@ -1,4 +1,4 @@
-.menu-normal-form-edit-box {
+.menu-simple-form-edit-box {
   position: relative;
   box-sizing: border-box;
   background: #ffffff;
@@ -32,10 +32,10 @@
     position: relative;
     background: #ffffff;
     border-radius: 2px;
-    margin-bottom: 15px;
   }
   .form-area {
     position: relative;
+    padding-top: 15px;
     .page-card {
       background: transparent;
     }
@@ -68,6 +68,10 @@
       padding-top: 10px;
       padding-bottom: 30px;
     }
+    .modal-fields-row:not(.mob-form) {
+      padding-left: 10px;
+      padding-right: 10px;
+    }
     .am-list-item {
       background-color: transparent;
     }
diff --git a/src/menu/components/form/simple-form/options.jsx b/src/menu/components/form/simple-form/options.jsx
new file mode 100644
index 0000000..4e25a6c
--- /dev/null
+++ b/src/menu/components/form/simple-form/options.jsx
@@ -0,0 +1,174 @@
+import { fromJS } from 'immutable'
+import MenuUtils from '@/utils/utils-custom.js'
+
+/**
+ * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
+ */
+export default function (config) {
+  let appType = sessionStorage.getItem('appType')
+  let roleList = sessionStorage.getItem('sysRoles')
+  let wrap = config.wrap
+
+  if (roleList) {
+    try {
+      roleList = JSON.parse(roleList)
+    } catch (e) {
+      roleList = []
+    }
+  } else {
+    roleList = []
+  }
+
+  let fields = [{field: '', label: '绌�'}]
+
+  if (appType === 'mob') {
+    config.subcards[0].fields.forEach(f => {
+      if (f.field && ['select', 'text', 'number'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
+        fields.push(f)
+      }
+    })
+  } else {
+    config.subcards[0].fields.forEach(f => {
+      if (f.field && ['select', 'link', 'text', 'number'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
+        fields.push(f)
+      }
+    })
+  }
+
+  let modules = []
+  let menu = fromJS(window.GLOB.customMenu).toJS()
+  modules = MenuUtils.getSupModules(menu.components, config.uuid) || []
+
+  const wrapForm = [
+    {
+      type: 'text',
+      field: 'title',
+      label: '鏍囬',
+      initval: wrap.title || '',
+      required: false
+    },
+    {
+      type: 'text',
+      field: 'name',
+      label: '缁勪欢鍚嶇О',
+      initval: wrap.name || '',
+      tooltip: '鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�',
+      required: true
+    },
+    {
+      type: 'number',
+      field: 'width',
+      label: '瀹藉害',
+      initval: wrap.width || 24,
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
+      min: 1,
+      max: 24,
+      precision: 0,
+      required: true
+    },
+    {
+      type: 'radio',
+      field: 'datatype',
+      label: '鏁版嵁鏉ユ簮',
+      initval: wrap.datatype || 'static',
+      tooltip: '鍒濆鍊兼潵婧愪簬鏁版嵁婧愭垨琛ㄥ崟榛樿鍊笺��',
+      required: false,
+      options: [
+        {value: 'dynamic', label: '鍔ㄦ��'},
+        {value: 'static', label: '闈欐��'},
+      ],
+      controlFields: [
+        {field: 'supModule', values: ['static']},
+      ]
+    },
+    {
+      type: 'select',
+      field: 'focus',
+      label: '鐒︾偣',
+      initval: wrap.focus || '',
+      required: false,
+      options: fields
+    },
+    {
+      type: 'radio',
+      field: 'cache',
+      label: '閫夐」鏌ヨ',
+      initval: wrap.cache || 'true',
+      tooltip: '闇�瑕侀�氳繃鏁版嵁婧愭煡璇㈢殑閫夐」锛屾槸鍚︿娇鐢ㄧ紦瀛樸��',
+      required: false,
+      options: [
+        {value: 'true', label: '缂撳瓨'},
+        {value: 'false', label: '瀹炴椂'},
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'align',
+      label: '琛ㄥ崟鎺掑垪',
+      initval: wrap.align || 'left_right',
+      required: false,
+      options: [
+        {value: 'left_right', label: '宸﹀彸'},
+        {value: 'up_down', label: '涓婁笅'},
+      ],
+      forbid: appType === 'mob'
+    },
+    {
+      type: 'radio',
+      field: 'verticalSpace',
+      label: '绔栧悜闂撮殭',
+      initval: wrap.verticalSpace || 'normal',
+      tooltip: '姝e父闂撮殭浼氶鐣欏嚭鎶ラ敊淇℃伅鐨勪綅缃紝闃叉琛ㄥ崟浣嶇疆鍙戠敓鍙樺寲銆�',
+      required: false,
+      options: [
+        {value: 'normal', label: '姝e父'},
+        {value: 'middle', label: '涓�'},
+        {value: 'small', label: '灏�'},
+      ],
+      forbid: appType === 'mob'
+    },
+    {
+      type: 'radio',
+      field: 'subEnable',
+      label: '鎻愪氦',
+      initval: wrap.enable || 'true',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄剧ず'},
+        {value: 'false', label: '闅愯棌'},
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'permission',
+      label: '鏉冮檺楠岃瘉',
+      initval: wrap.permission || 'false',
+      required: false,
+      options: [
+        {value: 'true', label: '鍚敤'},
+        {value: 'false', label: '绂佺敤'},
+      ],
+      forbid: !appType
+    },
+    {
+      type: 'cascader',
+      field: 'supModule',
+      label: '涓婄骇缁勪欢',
+      initval: wrap.supModule || [],
+      required: false,
+      options: modules,
+      allowClear: true
+    },
+    {
+      type: 'multiselect',
+      field: 'blacklist',
+      label: '榛戝悕鍗�',
+      initval: wrap.blacklist || [],
+      required: false,
+      options: roleList,
+      forbid: !!appType
+    },
+  ]
+
+  return wrapForm
+} 
\ No newline at end of file
diff --git a/src/menu/components/form/normal-form/index.jsx b/src/menu/components/form/step-form/index.jsx
similarity index 79%
rename from src/menu/components/form/normal-form/index.jsx
rename to src/menu/components/form/step-form/index.jsx
index e10544c..0a05e41 100644
--- a/src/menu/components/form/normal-form/index.jsx
+++ b/src/menu/components/form/step-form/index.jsx
@@ -31,7 +31,7 @@
 
 const { confirm } = Modal
 
-class PropCardEditComponent extends Component {
+class StepFormComponent extends Component {
   static propTpyes = {
     card: PropTypes.object,
     deletecomponent: PropTypes.func,
@@ -80,7 +80,7 @@
           style: {},
           fields: [],
           prevButton: {label: '涓婁竴姝�', type: 'prev', enable: 'false', style: {marginRight: '15px', paddingTop: '5px', paddingBottom: '5px'}},
-          subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
+          subButton: {label: '鎻愪氦', type: 'submit', intertype: 'system', reload: 'false', sqlType: 'update', sql: '', Ot: 'notRequired', execSuccess: 'never', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
           nextButton: {label: '璺宠繃', type: 'next', enable: 'false', style: {paddingTop: '5px', paddingBottom: '5px'}}
         }]
       }
@@ -106,10 +106,9 @@
         })
       }
       this.setState({
-        card: _card,
         group: _card.subcards[0] || null
       })
-      this.props.updateConfig(_card)
+      this.updateComponent(_card)
     } else {
       let _card = fromJS(card).toJS()
       this.setState({
@@ -159,15 +158,55 @@
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+    card.errors = []
+
+    if (card.wrap.datatype !== 'static') {
+      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+      } else if (!card.setting.primaryKey) {
+        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+      } else if (!card.setting.supModule) {
+        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+      }
+
+      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
+      if (supModule === 'empty') {
+        supModule = ''
+      }
+      let columns = card.columns.map(c => c.field)
+      let lowcols = card.columns.map(c => c.field.toLowerCase())
+
+      card.subcards.forEach(item => {
+        item.fields.forEach(m => {
+          if (m.type === 'linkMain' && !supModule) {
+            card.errors.push({ level: 1, detail: `鍒嗙粍鈥�${item.setting.title}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+          } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+            card.errors.push({ level: 1, detail: `鍒嗙粍鈥�${item.setting.title}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+          }
+        })
+      })
+    } else {
+      let supModule = card.wrap.supModule ? card.wrap.supModule[card.wrap.supModule.length - 1] : ''
+
+      card.subcards.forEach(item => {
+        item.fields.forEach(m => {
+          if (m.type === 'linkMain' && !supModule) {
+            card.errors.push({ level: 1, detail: `鍒嗙粍鈥�${item.setting.title}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+          }
+        })
+      })
+    }
+
     this.setState({
-      card: component
+      card: card
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
-
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   /**
@@ -181,9 +220,7 @@
       return item
     })
 
-    this.setState({card})
-
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   changeStyle = () => {
@@ -212,12 +249,8 @@
     if (comIds.length !== 1 || comIds[0] !== card.uuid) return
 
     let _card = {...card, style}
-
-    this.setState({
-      card: _card
-    })
     
-    this.props.updateConfig(_card)
+    this.updateComponent(_card)
   }
 
   addCard = () => {
@@ -230,17 +263,16 @@
       style: {},
       fields: [],
       prevButton: {label: '涓婁竴姝�', type: 'prev', enable: 'false', style: {marginRight: '15px', paddingTop: '5px', paddingBottom: '5px'}},
-      subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
+      subButton: {label: '鎻愪氦', type: 'submit', intertype: 'system', reload: 'false', sqlType: 'update', sql: '', Ot: 'notRequired', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
       nextButton: {label: '璺宠繃', type: 'next', enable: 'false', style: {paddingTop: '5px', paddingBottom: '5px'}}
     }
 
     card.subcards.push(newcard)
     
     this.setState({
-      card,
       group: newcard
     })
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   changecards = (list) => {
@@ -250,8 +282,7 @@
       return item
     })
 
-    this.setState({card})
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   selectGroup = (item) => {
@@ -279,8 +310,8 @@
           _group = card.subcards[0] || null
         }
 
-        _this.setState({card, group: _group})
-        _this.props.updateConfig(card)
+        _this.setState({group: _group})
+        _this.updateComponent(card)
       },
       onCancel() {}
     })
@@ -296,8 +327,8 @@
       return item
     })
 
-    this.setState({card, group})
-    this.props.updateConfig(card)
+    this.setState({group})
+    this.updateComponent(card)
   }
 
   plusFields = (items) => {
@@ -343,8 +374,8 @@
           }
           return item
         })
-        _this.setState({group: config, card})
-        _this.props.updateConfig(card)
+        _this.setState({group: config})
+        _this.updateComponent(card)
       },
       onCancel() {}
     })
@@ -363,12 +394,12 @@
       return item
     })
 
-    this.setState({card, group}, () => {
+    this.setState({group}, () => {
       if (newcard) {
         this.handleForm(newcard)
       }
     })
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   closeForm = (cell) => {
@@ -388,8 +419,8 @@
     confirm({
       content: `纭畾鍒犻櫎<<${cell.label}>>鍚楋紵`,
       onOk() {
-        _this.setState({card, group})
-        _this.props.updateConfig(card)
+        _this.setState({group})
+        _this.updateComponent(card)
       },
       onCancel() {}
     })
@@ -592,10 +623,10 @@
           LText: res.dataSource
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
         
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
 
         if (window.GLOB.mainSystemApi && res.database === 'sso') {
@@ -629,6 +660,41 @@
   }
 
   pasteForm = (res) => {
+    if (res.subtype === 'simpleform') {
+      res = res.subcards[0]
+    }
+    if (res.subButton) {
+      let card = fromJS(this.state.card).toJS()
+
+      res.uuid = Utils.getuuid()
+      res.sort = card.subcards.length + 1
+
+      res.fields.forEach(item => {
+        item.uuid = Utils.getuuid()
+      })
+
+      if (!res.prevButton) {
+        res.prevButton = {label: '涓婁竴姝�', type: 'prev', enable: 'false', style: {marginRight: '15px', paddingTop: '5px', paddingBottom: '5px'}}
+      }
+      if (!res.nextButton) {
+        res.nextButton = {label: '璺宠繃', type: 'next', enable: 'false', style: {paddingTop: '5px', paddingBottom: '5px'}}
+      }
+
+      card.subcards.push(res)
+      
+      this.setState({
+        group: res
+      })
+      this.updateComponent(card)
+
+      notification.success({
+        top: 92,
+        message: '绮樿创鎴愬姛锛�',
+        duration: 2
+      })
+      return
+    }
+
     let _config = fromJS(this.state.group).toJS()
     let fieldrepet = false // 瀛楁閲嶅
 
@@ -664,7 +730,17 @@
   }
 
   updateWrap = (res) => {
-    this.updateComponent({...this.state.card, wrap: res})
+    let _card = {...this.state.card, wrap: res}
+
+    if (res.datatype === 'static') {
+      if (res.supModule && res.supModule.length > 0) {
+        _card.setting.supModule = res.supModule
+      } else {
+        _card.setting.supModule = ''
+      }
+    }
+
+    this.updateComponent(_card)
   }
 
   clickComponent = (e) => {
@@ -686,7 +762,7 @@
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
             <CopyComponent type="stepform" card={card}/>
-            <PasteComponent config={card} options={['form']} updateConfig={this.pasteForm} />
+            <PasteComponent config={card} options={['form', 'formgroup', 'simpleform']} updateConfig={this.pasteForm} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
             <UserComponent config={card}/>
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} />
@@ -731,7 +807,20 @@
           />}
           <FormAction config={card} group={group} updateconfig={this.updateGroup}/>
         </div> : null}
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
         <Modal
           title={this.state.dict['model.edit']}
           visible={this.state.visible}
@@ -756,4 +845,4 @@
   }
 }
 
-export default PropCardEditComponent
\ No newline at end of file
+export default StepFormComponent
\ No newline at end of file
diff --git a/src/menu/components/form/normal-form/index.scss b/src/menu/components/form/step-form/index.scss
similarity index 93%
rename from src/menu/components/form/normal-form/index.scss
rename to src/menu/components/form/step-form/index.scss
index ff50139..506e5ff 100644
--- a/src/menu/components/form/normal-form/index.scss
+++ b/src/menu/components/form/step-form/index.scss
@@ -32,7 +32,6 @@
     position: relative;
     background: #ffffff;
     border-radius: 2px;
-    margin-bottom: 15px;
   }
   .form-area {
     position: relative;
@@ -68,6 +67,10 @@
       padding-top: 10px;
       padding-bottom: 30px;
     }
+    .modal-fields-row:not(.mob-form) {
+      padding-left: 10px;
+      padding-right: 10px;
+    }
     .am-list-item {
       background-color: transparent;
     }
diff --git a/src/menu/components/form/normal-form/options.jsx b/src/menu/components/form/step-form/options.jsx
similarity index 83%
rename from src/menu/components/form/normal-form/options.jsx
rename to src/menu/components/form/step-form/options.jsx
index 13dddcf..fa3eb97 100644
--- a/src/menu/components/form/normal-form/options.jsx
+++ b/src/menu/components/form/step-form/options.jsx
@@ -1,3 +1,6 @@
+import { fromJS } from 'immutable'
+import MenuUtils from '@/utils/utils-custom.js'
+
 /**
  * @description Wrap琛ㄥ崟閰嶇疆淇℃伅
  */
@@ -15,6 +18,10 @@
   } else {
     roleList = []
   }
+
+  let modules = []
+  let menu = fromJS(window.GLOB.customMenu).toJS()
+  modules = MenuUtils.getSupModules(menu.components, config.uuid) || []
 
   const wrapForm = [
     {
@@ -39,13 +46,16 @@
     {
       type: 'radio',
       field: 'datatype',
-      label: '鍒濆鍊�',
+      label: '鏁版嵁鏉ユ簮',
       initval: wrap.datatype || 'static',
       tooltip: '鍒濆鍊兼潵婧愪簬鏁版嵁婧愭垨琛ㄥ崟榛樿鍊笺��',
       required: false,
       options: [
         {value: 'dynamic', label: '鍔ㄦ��'},
         {value: 'static', label: '闈欐��'},
+      ],
+      controlFields: [
+        {field: 'supModule', values: ['static']},
       ]
     },
     {
@@ -104,6 +114,15 @@
       forbid: !appType
     },
     {
+      type: 'cascader',
+      field: 'supModule',
+      label: '涓婄骇缁勪欢',
+      initval: wrap.supModule || [],
+      required: false,
+      options: modules,
+      allowClear: true
+    },
+    {
       type: 'multiselect',
       field: 'blacklist',
       label: '榛戝悕鍗�',
diff --git a/src/menu/components/form/tab-form/index.jsx b/src/menu/components/form/tab-form/index.jsx
index 9457252..b8d88ec 100644
--- a/src/menu/components/form/tab-form/index.jsx
+++ b/src/menu/components/form/tab-form/index.jsx
@@ -12,7 +12,7 @@
 import { resetStyle } from '@/utils/utils-custom.js'
 import MKEmitter from '@/utils/events.js'
 import Utils from '@/utils/utils.js'
-import getWrapForm from '../normal-form/options'
+import getWrapForm from '../step-form/options'
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
 import './index.scss'
@@ -31,7 +31,7 @@
 
 const { confirm } = Modal
 
-class PropCardEditComponent extends Component {
+class TabFormComponent extends Component {
   static propTpyes = {
     card: PropTypes.object,
     deletecomponent: PropTypes.func,
@@ -79,21 +79,21 @@
           sort: 1,
           style: {},
           fields: [],
-          subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
+          subButton: {label: '鎻愪氦', type: 'submit', intertype: 'system', reload: 'false', sqlType: 'update', sql: '', Ot: 'notRequired', execSuccess: 'never', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
         }, {
           uuid: Utils.getuuid(),
           setting: {title: '鍒嗙粍2', align: 'left_right'},
           sort: 1,
           style: {},
           fields: [],
-          subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
+          subButton: {label: '鎻愪氦', type: 'submit', intertype: 'system', reload: 'false', sqlType: 'update', sql: '', Ot: 'notRequired', execSuccess: 'never', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
         }, {
           uuid: Utils.getuuid(),
           setting: {title: '鍒嗙粍3', align: 'left_right'},
           sort: 1,
           style: {},
           fields: [],
-          subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
+          subButton: {label: '鎻愪氦', type: 'submit', intertype: 'system', reload: 'false', sqlType: 'update', sql: '', Ot: 'notRequired', execSuccess: 'never', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
         }]
       }
 
@@ -118,10 +118,9 @@
         })
       }
       this.setState({
-        card: _card,
         group: _card.subcards[0] || null
       })
-      this.props.updateConfig(_card)
+      this.updateComponent(_card)
     } else {
       let _card = fromJS(card).toJS()
       this.setState({
@@ -171,15 +170,55 @@
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+    card.errors = []
+
+    if (card.wrap.datatype !== 'static') {
+      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+      } else if (!card.setting.primaryKey) {
+        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+      } else if (!card.setting.supModule) {
+        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+      }
+
+      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
+      if (supModule === 'empty') {
+        supModule = ''
+      }
+      let columns = card.columns.map(c => c.field)
+      let lowcols = card.columns.map(c => c.field.toLowerCase())
+
+      card.subcards.forEach(item => {
+        item.fields.forEach(m => {
+          if (m.type === 'linkMain' && !supModule) {
+            card.errors.push({ level: 1, detail: `鍒嗙粍鈥�${item.setting.title}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+          } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+            card.errors.push({ level: 1, detail: `鍒嗙粍鈥�${item.setting.title}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+          }
+        })
+      })
+    } else {
+      let supModule = card.wrap.supModule ? card.wrap.supModule[card.wrap.supModule.length - 1] : ''
+
+      card.subcards.forEach(item => {
+        item.fields.forEach(m => {
+          if (m.type === 'linkMain' && !supModule) {
+            card.errors.push({ level: 1, detail: `鍒嗙粍鈥�${item.setting.title}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+          }
+        })
+      })
+    }
+
     this.setState({
-      card: component
+      card: card
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
-
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   /**
@@ -193,9 +232,7 @@
       return item
     })
 
-    this.setState({card})
-
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   changeStyle = () => {
@@ -225,11 +262,7 @@
 
     let _card = {...card, style}
 
-    this.setState({
-      card: _card
-    })
-    
-    this.props.updateConfig(_card)
+    this.updateComponent(_card)
   }
 
   addCard = () => {
@@ -241,16 +274,15 @@
       sort: card.subcards.length + 1,
       style: {},
       fields: [],
-      subButton: {label: '鎻愪氦', type: 'submit', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
+      subButton: {label: '鎻愪氦', type: 'submit', intertype: 'system', reload: 'false', sqlType: 'update', sql: '', Ot: 'notRequired', enable: 'true', style: {backgroundColor: '#1890ff', color: '#ffffff', paddingLeft: '25px', paddingRight: '25px', paddingTop: '5px', paddingBottom: '5px'}},
     }
 
     card.subcards.push(newcard)
     
     this.setState({
-      card,
       group: newcard
     })
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   changecards = (list) => {
@@ -260,8 +292,7 @@
       return item
     })
 
-    this.setState({card})
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   selectGroup = (item) => {
@@ -285,8 +316,8 @@
           _group = card.subcards[0] || null
         }
 
-        _this.setState({card, group: _group})
-        _this.props.updateConfig(card)
+        _this.setState({group: _group})
+        _this.updateComponent(card)
       },
       onCancel() {}
     })
@@ -302,8 +333,8 @@
       return item
     })
 
-    this.setState({card, group})
-    this.props.updateConfig(card)
+    this.setState({group})
+    this.updateComponent(card)
   }
 
   plusFields = (items) => {
@@ -349,8 +380,8 @@
           }
           return item
         })
-        _this.setState({group: config, card})
-        _this.props.updateConfig(card)
+        _this.setState({group: config})
+        _this.updateComponent(card)
       },
       onCancel() {}
     })
@@ -369,12 +400,12 @@
       return item
     })
 
-    this.setState({card, group}, () => {
+    this.setState({group}, () => {
       if (newcard) {
         this.handleForm(newcard)
       }
     })
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   closeForm = (cell) => {
@@ -394,8 +425,8 @@
     confirm({
       content: `纭畾鍒犻櫎<<${cell.label}>>鍚楋紵`,
       onOk() {
-        _this.setState({card, group})
-        _this.props.updateConfig(card)
+        _this.setState({group})
+        _this.updateComponent(card)
       },
       onCancel() {}
     })
@@ -598,10 +629,10 @@
           LText: res.dataSource
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
         
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
 
         if (window.GLOB.mainSystemApi && res.database === 'sso') {
@@ -635,6 +666,37 @@
   }
 
   pasteForm = (res) => {
+    if (res.subtype === 'simpleform') {
+      res = res.subcards[0]
+    }
+    if (res.subButton) {
+      let card = fromJS(this.state.card).toJS()
+
+      res.uuid = Utils.getuuid()
+      res.sort = card.subcards.length + 1
+
+      res.fields.forEach(item => {
+        item.uuid = Utils.getuuid()
+      })
+
+      delete res.prevButton
+      delete res.nextButton
+
+      card.subcards.push(res)
+      
+      this.setState({
+        group: res
+      })
+      this.updateComponent(card)
+
+      notification.success({
+        top: 92,
+        message: '绮樿创鎴愬姛锛�',
+        duration: 2
+      })
+      return
+    }
+
     let _config = fromJS(this.state.group).toJS()
     let fieldrepet = false // 瀛楁閲嶅
 
@@ -670,7 +732,41 @@
   }
 
   updateWrap = (res) => {
-    this.updateComponent({...this.state.card, wrap: res})
+    let _card = {...this.state.card, wrap: res}
+
+    if (res.datatype === 'static') {
+      if (res.supModule && res.supModule.length > 0) {
+        _card.setting.supModule = res.supModule
+      } else {
+        _card.setting.supModule = ''
+      }
+    }
+
+    this.updateComponent(_card)
+  }
+
+  clearGroup = () => {
+    let group = fromJS(this.state.group).toJS()
+    let card = fromJS(this.state.card).toJS()
+    let _this = this
+
+    group.fields = []
+
+    card.subcards = card.subcards.map(item => {
+      if (item.uuid === group.uuid) {
+        return group
+      }
+      return item
+    })
+
+    confirm({
+      content: `纭畾娓呯┖琛ㄥ崟鍚楋紵`,
+      onOk() {
+        _this.setState({group})
+        _this.updateComponent(card)
+      },
+      onCancel() {}
+    })
   }
 
   clickComponent = (e) => {
@@ -692,7 +788,7 @@
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
             <CopyComponent type="tabform" card={card}/>
-            <PasteComponent config={card} options={['form']} updateConfig={this.pasteForm} />
+            <PasteComponent config={card} options={['form', 'formgroup', 'simpleform']} updateConfig={this.pasteForm} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
             <UserComponent config={card}/>
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} />
@@ -714,6 +810,7 @@
         {group ? <div className="form-area">
           <PlusOutlined className="plus" title="娣诲姞琛ㄥ崟" onClick={this.addForm}/>
           <FieldsComponent config={group} type="form" plusFields={this.plusFields} />
+          <span style={{color: 'red', marginLeft: '30px', cursor: 'pointer'}} onClick={this.clearGroup}>娓呯┖</span>
           <Switch checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={this.state.showField} onChange={(val) => this.setState({showField: val})} />
           {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(1)}>1鍒�</Button> : null}
           {appType !== 'mob' ? <Button className="mk-cols-change" onClick={() => this.changecols(2)}>2鍒�</Button> : null}
@@ -738,7 +835,20 @@
           />}
           <FormAction config={card} group={group} updateconfig={this.updateGroup}/>
         </div> : null}
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
         <Modal
           title={this.state.dict['model.edit']}
           visible={this.state.visible}
@@ -763,4 +873,4 @@
   }
 }
 
-export default PropCardEditComponent
\ No newline at end of file
+export default TabFormComponent
\ No newline at end of file
diff --git a/src/menu/components/form/tab-form/index.scss b/src/menu/components/form/tab-form/index.scss
index ff50139..506e5ff 100644
--- a/src/menu/components/form/tab-form/index.scss
+++ b/src/menu/components/form/tab-form/index.scss
@@ -32,7 +32,6 @@
     position: relative;
     background: #ffffff;
     border-radius: 2px;
-    margin-bottom: 15px;
   }
   .form-area {
     position: relative;
@@ -68,6 +67,10 @@
       padding-top: 10px;
       padding-bottom: 30px;
     }
+    .modal-fields-row:not(.mob-form) {
+      padding-left: 10px;
+      padding-right: 10px;
+    }
     .am-list-item {
       background-color: transparent;
     }
diff --git a/src/menu/components/group/groupcomponents/card.jsx b/src/menu/components/group/groupcomponents/card.jsx
index 29710b2..c01643a 100644
--- a/src/menu/components/group/groupcomponents/card.jsx
+++ b/src/menu/components/group/groupcomponents/card.jsx
@@ -14,7 +14,8 @@
 const EditTable = asyncComponent(() => import('@/menu/components/table/edit-table'))
 const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor'))
 const AntvScatter = asyncComponent(() => import('@/menu/components/chart/antv-scatter'))
-const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form'))
+const SimpleForm = asyncComponent(() => import('@/menu/components/form/simple-form'))
+const StepForm = asyncComponent(() => import('@/menu/components/form/step-form'))
 const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form'))
 const AntvDashboard = asyncComponent(() => import('@/menu/components/chart/antv-dashboard'))
 const CarouselDataCard = asyncComponent(() => import('@/menu/components/carousel/data-card'))
@@ -68,8 +69,10 @@
       return (<NormalTree card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'scatter') {
       return (<AntvScatter card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'form' && card.subtype === 'simpleform') {
+      return (<SimpleForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'form' && card.subtype === 'stepform') {
-      return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+      return (<StepForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'form' && card.subtype === 'tabform') {
       return (<TabForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'card' && card.subtype === 'datacard') {
diff --git a/src/menu/components/group/paste/index.jsx b/src/menu/components/group/paste/index.jsx
index 65ad511..2932f39 100644
--- a/src/menu/components/group/paste/index.jsx
+++ b/src/menu/components/group/paste/index.jsx
@@ -24,7 +24,7 @@
   }
 
   pasteSubmit = () => {
-    let options = ['datacard', 'propcard', 'balcony', 'timeline', 'stepform', 'tabform', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter', 'chart']
+    let options = ['datacard', 'propcard', 'balcony', 'timeline', 'simpleform', 'stepform', 'tabform', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter', 'chart']
     let types = {
       login: '鐧诲綍',
       navbar: '瀵艰埅鏍�',
diff --git a/src/menu/components/module/voucher/index.jsx b/src/menu/components/module/voucher/index.jsx
index e150d22..30d250f 100644
--- a/src/menu/components/module/voucher/index.jsx
+++ b/src/menu/components/module/voucher/index.jsx
@@ -49,11 +49,8 @@
         columns: [],
         scripts: [],
       }
-      
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+
+      this.updateComponent(_card)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -82,15 +79,15 @@
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+    
     this.setState({
-      card: component
+      card: card
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
-
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   changeStyle = () => {
@@ -105,22 +102,8 @@
     if (comIds[0] !== card.uuid || comIds.length !== 1) return
 
     let _card = {...card, style}
-
-    this.setState({
-      card: _card
-    })
     
-    this.props.updateConfig(_card)
-  }
-
-  /**
-   * @description 鏇存柊鎼滅储鏉′欢閰嶇疆淇℃伅
-   */
-  updateconfig = (config) => {
-    this.setState({
-      card: config
-    })
-    this.props.updateConfig(config)
+    this.updateComponent(_card)
   }
 
   getWrapForms = () => {
diff --git a/src/menu/components/search/main-search/dategroup/index.scss b/src/menu/components/search/main-search/dategroup/index.scss
index 6782732..3e0369e 100644
--- a/src/menu/components/search/main-search/dategroup/index.scss
+++ b/src/menu/components/search/main-search/dategroup/index.scss
@@ -9,6 +9,7 @@
     border-radius: 2px;
     margin-right: 2px;
     padding: 2px 6px;
+    background: #ffffff;
   }
   .ant-tag-checkable-checked {
     border-color: #1890ff;
diff --git a/src/menu/components/search/main-search/dragsearch/card.jsx b/src/menu/components/search/main-search/dragsearch/card.jsx
index 1508196..e9d558a 100644
--- a/src/menu/components/search/main-search/dragsearch/card.jsx
+++ b/src/menu/components/search/main-search/dragsearch/card.jsx
@@ -12,7 +12,7 @@
 const { Search } = Input
 const CheckCard = asyncComponent(() => import('@/templates/modalconfig/checkCard'))
 
-const Card = ({ id, card, showField, moveCard, copyCard, findCard, editCard, delCard }) => {
+const Card = ({ id, card, moveCard, copyCard, findCard, editCard, delCard }) => {
   const originalIndex = findCard(id).index
   const [{ isDragging }, drag] = useDrag({
     item: { type: 'search', id, originalIndex },
@@ -32,7 +32,7 @@
       moveCard(draggedId, overIndex)
     },
   })
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   let _defaultValue = '' // 涓嬫媺鎼滅储銆佹椂闂磋寖鍥寸被鍨嬶紝鍒濆鍊奸渶瑕侀澶勭悊
 
@@ -113,14 +113,14 @@
         <CloseOutlined className="close" onClick={() => delCard(id)} />
       </div>
     } trigger="hover">
-      <div className={'page-card ' + card.labelShow + ' ' + card.type} style={{ opacity: opacity}}>
+      <div className={'page-card ' + (card.labelShow === 'false' ? 'label-hide ' : '') + card.type + (card.advanced === 'true' ? ' advanced' : '')} 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 }}}
             label={card.labelShow !== 'false' ? card.label : ''}
             required={card.required === 'true'}
-            help={showField ? card.field + (card.datefield ? ', ' + card.datefield : '') : ''}
+            help={card.field + (card.datefield ? ', ' + card.datefield : '') + (card.advanced === 'true' ? '锛堥珮绾ф悳绱級' : '')}
           >
             {formItem}
           </Form.Item>
diff --git a/src/menu/components/search/main-search/dragsearch/index.jsx b/src/menu/components/search/main-search/dragsearch/index.jsx
index 0140d3e..a3cfd27 100644
--- a/src/menu/components/search/main-search/dragsearch/index.jsx
+++ b/src/menu/components/search/main-search/dragsearch/index.jsx
@@ -7,7 +7,7 @@
 import Card from './card'
 import './index.scss'
 
-const Container = ({list, showField, handleList, handleMenu, deleteMenu }) => {
+const Container = ({list, setting, handleList, handleMenu, deleteMenu }) => {
   const [cards, setCards] = useState(list)
   const moveCard = (id, atIndex) => {
     const { card, index } = findCard(id)
@@ -84,42 +84,36 @@
     drop() {}
   })
 
-  const appType = sessionStorage.getItem('appType')
+  let labelwidth = setting.searchLwidth !== undefined ? setting.searchLwidth : 33.3
+  let advanceType = setting.advanceType || 'modal'
 
   return (
     <div ref={drop} className="ant-row">
-      {cards.length > 0 ? <Col key="preaction" className="action pre-action" span={6}>
+      {cards.map(card => {
+        let _ratio = card.ratio || 6
+        if (card.advanced === 'true' && advanceType !== 'pulldown') {
+          _ratio = 6
+        }
+        return (
+          <Col className="mk-search-item-wrap" key={card.uuid} span={_ratio}>
+            <Card
+              id={`${card.uuid}`}
+              card={card}
+              moveCard={moveCard}
+              copyCard={copyCard}
+              editCard={editCard}
+              delCard={delCard}
+              findCard={findCard}
+            />
+          </Col>
+        )
+      })}
+      {cards.length > 0 ? <Col key="nextaction" className={'mk-search-item-wrap action' + (setting.show === 'false' ? ' hide-button' : '')} span={setting.searchRatio || 6}>
         <div className="ant-row ant-form-item" style={{lineHeight: '40px', height: '55px', marginBottom: 0}}>
-          <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8">
-          </div>
-          <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16" style={{whiteSpace: 'nowrap'}}>
+        <div className="ant-col ant-form-item-label" style={{width: labelwidth + '%'}}></div>
+          <div className="ant-col ant-form-item-control-wrapper" style={{whiteSpace: 'nowrap'}}>
             <Button type="primary">鎼滅储</Button>
-            {appType !== 'mob' ? <Button style={{ marginLeft: 8 }}>閲嶇疆</Button> : null}
-            <div style={{position: 'absolute', top: 0, bottom: 0, left: 0, right: 0}}></div>
-          </div>
-        </div>
-      </Col> : null}
-      {cards.map(card => (
-        <Col key={card.uuid} span={card.ratio || 6}>
-          <Card
-            id={`${card.uuid}`}
-            card={card}
-            showField={showField}
-            moveCard={moveCard}
-            copyCard={copyCard}
-            editCard={editCard}
-            delCard={delCard}
-            findCard={findCard}
-          />
-        </Col>
-      ))}
-      {cards.length > 0 ? <Col key="nextaction" className="action next-action" span={6}>
-        <div className="ant-row ant-form-item" style={{lineHeight: '40px', height: '55px', marginBottom: 0}}>
-          <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8">
-          </div>
-          <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16" style={{whiteSpace: 'nowrap'}}>
-            <Button type="primary">鎼滅储</Button>
-            {appType !== 'mob' ? <Button style={{ marginLeft: 8 }}>閲嶇疆</Button> : null}
+            <Button style={{ marginLeft: 8 }}>閲嶇疆</Button>
             <div style={{position: 'absolute', top: 0, bottom: 0, left: 0, right: 0}}></div>
           </div>
         </div>
diff --git a/src/menu/components/search/main-search/index.jsx b/src/menu/components/search/main-search/index.jsx
index 78e8eb4..0010681 100644
--- a/src/menu/components/search/main-search/index.jsx
+++ b/src/menu/components/search/main-search/index.jsx
@@ -282,10 +282,10 @@
           LText: res.dataSource
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
         
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
 
         if (window.GLOB.mainSystemApi && res.database === 'sso') {
@@ -416,12 +416,12 @@
     let _style = resetStyle(card.style)
 
     return (
-      <div className={`main-search-edit-list ${card.wrap.float} ${card.wrap.show || ''}`} onClick={this.clickComponent} id={card.uuid} style={_style}>
+      <div className={`main-search-edit-list ${card.wrap.float} ${showField ? 'show-field' : ''}`} onClick={this.clickComponent} id={card.uuid} style={_style}>
         <FieldsComponent config={card} type="search" />
         <Switch checkedChildren={dict['model.switch.open']} size="small" unCheckedChildren={dict['model.switch.close']} defaultChecked={showField} onChange={this.onFieldChange} />
         <DragElement
           list={card.search}
-          showField={showField}
+          setting={card.wrap}
           handleList={this.handleList}
           handleMenu={this.handleSearch}
           deleteMenu={this.deleteElement}
diff --git a/src/menu/components/search/main-search/index.scss b/src/menu/components/search/main-search/index.scss
index e3fa843..d68899b 100644
--- a/src/menu/components/search/main-search/index.scss
+++ b/src/menu/components/search/main-search/index.scss
@@ -29,12 +29,10 @@
       padding: 0 12px!important;
     }
   }
-  >.ant-row:not(.ant-form-item) {
-    > .ant-col {
-      display: inline-block;
-      float: none;
-      vertical-align: top;
-    }
+  .mk-search-item-wrap {
+    display: inline-block;
+    float: none;
+    vertical-align: top;
   }
   .ant-row.ant-form-item .ant-col {
     padding: 0;
@@ -58,6 +56,18 @@
           padding: 4px 20px 4px 5px;
           font-size: 13px;
         }
+        .check-card-edit-box {
+          .no-margin-bottom {
+            margin-bottom: 0px;
+          }
+          .card-cell {
+            padding: 4px 6px;
+          }
+          .card-color-cell {
+            padding: 4px 6px;
+            min-height: 32px;
+          }
+        }
       }
     }
     .ant-form-item::after {
@@ -78,13 +88,26 @@
       z-index: 2;
     }
   }
-  .page-card.false {
+  .page-card.label-hide {
     .ant-form-item-label {
       display: none;
     }
     .ant-form-item-control-wrapper {
       width: 100%;
     }
+  }
+  .page-card.advanced {
+    .ant-form-item-label label {
+      color: orange;
+    }
+  }
+  .mk-search-item-wrap.action {
+    .ant-form-item-label, .ant-form-item-control-wrapper {
+      display: inline-block;
+    }
+  }
+  .mk-search-item-wrap.action.hide-button {
+    display: none;
   }
   .ant-calendar-picker {
     min-width: 100px!important;
@@ -108,28 +131,19 @@
     }
   }
 }
-.main-search-edit-list:not(.right) {
-  .pre-action {
-    display: none!important;
-  }
-}
+
 .main-search-edit-list.right {
-  .next-action {
-    display: none!important;
-  }
   >.ant-row {
-    >.ant-col {
-      float: right;
-    }
+    text-align: right;
   }
 }
-.main-search-edit-list.false {
-  >.ant-row {
-    >.ant-col.action {
-      display: none;
-    }
+
+.main-search-edit-list:not(.show-field) {
+  .ant-form-explain {
+    display: none;
   }
 }
+
 .main-search-edit-list::after {
   display: block;
   content: ' ';
diff --git a/src/menu/components/search/main-search/options.jsx b/src/menu/components/search/main-search/options.jsx
index 117f5ff..e72fbb2 100644
--- a/src/menu/components/search/main-search/options.jsx
+++ b/src/menu/components/search/main-search/options.jsx
@@ -36,22 +36,72 @@
       required: true
     },
     {
+      type: 'radio',
+      field: 'advanceType',
+      label: '楂樼骇鎼滅储',
+      initval: wrap.advanceType || 'modal',
+      required: false,
+      options: [
+        {value: 'modal', label: '寮圭獥'},
+        {value: 'drawer', label: '鎶藉眽'},
+        {value: 'pulldown', label: '涓嬫媺'}
+      ],
+      controlFields: [
+        {field: 'advanceWidth', values: ['modal', 'drawer']},
+        {field: 'drawerPlacement', values: ['drawer']}
+      ]
+    },
+    {
+      type: 'radio',
+      field: 'drawerPlacement',
+      label: '鎶藉眽鏂瑰悜',
+      initval: wrap.drawerPlacement || 'right',
+      required: false,
+      options: [
+        {value: 'right', label: '鍙充晶'},
+        {value: 'left', label: '宸︿晶'},
+        {value: 'top', label: '涓婁晶'},
+        {value: 'bottom', label: '涓嬩晶'}
+      ]
+    },
+    {
       type: 'number',
       field: 'advanceWidth',
-      label: '楂樼骇鎼滅储',
+      label: '寮圭獥瀹藉害',
       initval: wrap.advanceWidth || 1000,
-      tooltip: '楂樼骇鎼滅储寮圭獥鐨勫搴︼紝娉細褰撳搴﹀�煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺��',
+      tooltip: '楂樼骇鎼滅储寮圭獥鐨勫搴︼紝娉細褰撳搴﹀�煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺�傚綋浣跨敤涓婁笅鏄剧ず鐨勬娊灞夋椂浠h〃鎶藉眽楂樺害銆�',
       min: 10,
       max: 3000,
       precision: 0,
       required: false
     },
     {
+      type: 'number',
+      field: 'searchRatio',
+      label: '鎸夐挳姣斾緥',
+      initval: wrap.searchRatio || 6,
+      tooltip: '鎼滅储鍙婇噸缃寜閽墍鍗犳瘮渚嬨�傛爡鏍煎竷灞�锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
+      min: 1,
+      max: 24,
+      precision: 0,
+      required: true
+    },
+    {
+      type: 'number',
+      field: 'searchLwidth',
+      label: '鎸夐挳鍋忕Щ',
+      initval: wrap.searchLwidth !== undefined ? wrap.searchLwidth : 33.3,
+      tooltip: '鎼滅储鎸夐挳璺濆乏渚х殑鐧惧垎姣旓紝鍙傜収鎼滅储鏉′欢鐨勫悕绉板搴︺��',
+      min: 0,
+      max: 100,
+      precision: 1,
+      required: true
+    },
+    {
       type: 'radio',
       field: 'float',
       label: '瀵归綈',
       initval: wrap.float || 'left',
-      tooltip: '鍙冲榻愭椂锛岄殣钘忔悳绱㈡寜閽��',
       required: false,
       options: [
         {value: 'left', label: '宸﹀榻�'},
diff --git a/src/menu/components/share/actioncomponent/actionform/index.jsx b/src/menu/components/share/actioncomponent/actionform/index.jsx
index dc8f3c3..2cfa4c0 100644
--- a/src/menu/components/share/actioncomponent/actionform/index.jsx
+++ b/src/menu/components/share/actioncomponent/actionform/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
-import { Form, Row, Col, Input, Select, Radio, Tooltip, InputNumber, Cascader } from 'antd'
+import { Form, Row, Col, Input, Select, Radio, Tooltip, InputNumber, Cascader, Checkbox, Typography } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 import { formRule } from '@/utils/option.js'
 
@@ -9,18 +9,19 @@
 import './index.scss'
 
 const { TextArea } = Input
+const { Paragraph } = Typography
 const MkEditIcon = asyncComponent(() => import('@/components/mkIcon'))
 const acTyOptions = {
-  pop: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'open', 'refreshTab', 'position', 'tipTitle', 'hidden'],
-  prompt: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'open', 'refreshTab', 'position', 'tipTitle', 'hidden'],
-  exec: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'open', 'refreshTab', 'hidden'],
-  excelIn: ['label', 'Ot', 'OpenType', 'intertype', 'show', 'icon', 'class', 'color', 'sheet', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'switchTab', 'width', 'hidden'],
-  excelOut: ['label', 'OpenType', 'intertype', 'show', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'resetPageIndex', 'pagination', 'search', 'width', 'hidden'],
-  popview: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'color', 'popClose', 'resetPageIndex', 'width', 'display', 'ratio', 'syncComponent', 'clickouter', 'hidden'],
+  pop: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'refreshTab', 'position', 'tipTitle', 'hidden'],
+  prompt: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'refreshTab', 'position', 'tipTitle', 'hidden'],
+  exec: ['label', 'OpenType', 'intertype', 'Ot', 'show', 'swipe', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'anchors', 'width', 'openmenu', 'refreshTab', 'hidden'],
+  excelIn: ['label', 'Ot', 'OpenType', 'intertype', 'show', 'icon', 'class', 'color', 'sheet', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'width', 'hidden'],
+  excelOut: ['label', 'OpenType', 'intertype', 'show', 'icon', 'class', 'color', 'execSuccess', 'execError', 'syncComponent', 'switchTab', 'pagination', 'search', 'width', 'hidden'],
+  popview: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'color', 'popClose', 'width', 'display', 'ratio', 'syncComponent', 'clickouter', 'hidden'],
   tab: ['label', 'Ot', 'OpenType', 'show', 'icon', 'class', 'color', 'linkmenu', 'width', 'hidden'],
-  innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'show', 'swipe', 'icon', 'class', 'color', 'width', 'open', 'hidden'],
+  innerpage: ['label', 'Ot', 'OpenType', 'pageTemplate', 'show', 'swipe', 'icon', 'class', 'color', 'width', 'hidden'],
   funcbutton: ['label', 'OpenType', 'funcType', 'show', 'swipe', 'icon', 'class', 'color', 'width', 'hidden'],
-  form: ['label', 'OpenType', 'formType', 'intertype', 'Ot', 'execSuccess', 'execError', 'resetPageIndex', 'syncComponent', 'width', 'open', 'refreshTab', 'title', 'hidden']
+  form: ['label', 'OpenType', 'formType', 'intertype', 'Ot', 'execSuccess', 'execError', 'syncComponent', 'width', 'refreshTab', 'title', 'hidden']
 }
 
 class ActionForm extends Component {
@@ -189,6 +190,16 @@
         shows.push('sql', 'sqlType', 'output')
       }
 
+      if (Ot === 'required') {
+        shows.push('progress')
+      }
+      if (this.record.openmenu && this.record.openmenu !== 'goback') {
+        shows.push('open')
+      }
+      if (this.record.execSuccess === 'grid' || this.record.execError === 'grid') {
+        shows.push('resetPageIndex')
+      }
+
       if (this.record.sqlType === 'insert') {
         reOptions.Ot = requireOptions.filter(op => op.value === 'notRequired')
       } else {
@@ -235,6 +246,9 @@
       if (this.record.execSuccess === 'goback') {
         shows.push('reload')
       }
+      if (this.record.execSuccess === 'grid' || this.record.execError === 'grid') {
+        shows.push('resetPageIndex')
+      }
 
       reOptions.Ot = requireOptions
       reOptions.sqlType = [{
@@ -263,6 +277,9 @@
         shows.push('innerFunc')
         reRequired.innerFunc = true
       }
+      if (this.record.execSuccess === 'grid' || this.record.execError === 'grid') {
+        shows.push('resetPageIndex')
+      }
     } else if (openType === 'excelOut') {
       reOptions.intertype = this.state.interTypeOptions.filter(op => op.value !== 'custom')
 
@@ -281,11 +298,17 @@
         shows.push('innerFunc')
         reRequired.innerFunc = true
       }
+      if (this.record.execSuccess === 'grid' || this.record.execError === 'grid') {
+        shows.push('resetPageIndex')
+      }
     } else if (openType === 'popview') {
       reOptions.Ot = requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
 
       if (this.record.display === 'drawer') {
         shows.push('placement')
+      }
+      if (this.record.popClose === 'grid') {
+        shows.push('resetPageIndex')
       }
     } else if (openType === 'tab') {
       reOptions.Ot = requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
@@ -296,9 +319,9 @@
       reOptions.Ot = requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
 
       if (this.record.pageTemplate === 'custom') {
-        shows.push('url', 'joint')
+        shows.push('url', 'joint', 'open')
       } else if (this.record.pageTemplate === 'linkpage') {
-        shows.push('linkmenu')
+        shows.push('linkmenu', 'open')
 
         if (Ot === 'requiredSgl') {
           shows.push('joint')
@@ -319,7 +342,7 @@
       let _funcType = this.record.funcType
 
       if (_funcType === 'print') {
-        shows.push('execMode', 'intertype', 'Ot', 'execSuccess', 'execError', 'resetPageIndex')
+        shows.push('execMode', 'intertype', 'Ot', 'execSuccess', 'execError')
         if (this.record.intertype === 'outer') {
           shows.push('innerFunc', 'sysInterface', 'interface', 'proInterface', 'outerFunc', 'callbackFunc')
           reRequired.innerFunc = false
@@ -335,6 +358,9 @@
           shows.push('innerFunc')
           reRequired.innerFunc = true
         }
+        if (this.record.execSuccess === 'grid' || this.record.execError === 'grid') {
+          shows.push('resetPageIndex')
+        }
       } else if (_funcType === 'mkBinding' || _funcType === 'mkUnBinding') {
         shows.push('execSuccess', 'execError')
       } else if (_funcType === 'closetab') {
@@ -344,10 +370,28 @@
 
         reRequired.linkmenu = false
         reTooltip.linkmenu = '浣跨敤鎵爜鐧诲綍鍔熻兘鎴栬彍鍗曡烦杞姛鑳芥椂锛岄渶閫夋嫨璺宠浆鐨勮彍鍗曘��'
+      } else if (_funcType === 'copyurl') {
+        shows.push('linkmenu')
+
+        reRequired.linkmenu = false
+        reTooltip.linkmenu = '鍙互鎸囧畾鍒嗕韩鐨勭洰鏍囧湴鍧�銆�'
+
+        if (this.record.linkmenu) {
+          shows.push('Ot')
+          reOptions.Ot = requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
+        }
       } else if (_funcType === 'goBack') {
         shows.push('reload')
       } else if (_funcType === 'megvii') {
-        shows.push('subFunc')
+        shows.push('subFunc', 'progress')
+      } else if (_funcType === 'filezip') {
+        reOptions.Ot = requireOptions
+        reRequired.innerFunc = false
+
+        shows.push('innerFunc', 'Ot', 'execSuccess', 'execError', 'urlkey')
+      } else if (_funcType === 'pay') {
+        shows.push('payType', 'Ot', 'execSuccess', 'execError', 'syncComponent', 'openmenu')
+        reOptions.Ot = requireOptions.filter(op => ['requiredSgl'].includes(op.value))
       }
     }
     
@@ -433,7 +477,6 @@
       if (value === 'pop' || value === 'prompt' || value === 'exec') {
         _fieldval.intertype = 'system'
         _fieldval.sqlType = ''
-  
       } else if (value === 'form') {
         _fieldval.Ot = 'requiredSgl'
 
@@ -453,9 +496,11 @@
         _fieldval.intertype = 'system'
         _fieldval.label = this.props.dict['model.form.excelOut']
         _fieldval.class = 'dgreen'
+        _fieldval.execSuccess = 'never'
         this.record.Ot = 'notRequired'
         this.record.label = this.props.dict['model.form.excelOut']
         this.record.class = 'dgreen'
+        this.record.execSuccess = 'never'
   
       } else if (value === 'popview') {
         _fieldval.display = 'modal'
@@ -520,7 +565,7 @@
         }
       } else if (value === 'audit') {
         _fieldval.label = '瀹℃牳'
-        _fieldval.Ot = 'requiredSgl'
+        _fieldval.Ot = 'required'
         if (hasclass) {
           _fieldval.class = 'primary'
         } else {
@@ -528,12 +573,18 @@
         }
       } else if (value === 'LogicDelete' || value === 'delete') {
         _fieldval.label = '鍒犻櫎'
-        _fieldval.Ot = 'requiredSgl'
+        _fieldval.Ot = 'required'
         if (hasclass) {
           _fieldval.class = 'danger'
         } else {
           _fieldval.color = 'danger'
         }
+      } else if (value === 'custom') {
+        _fieldval.Ot = 'required'
+      }
+
+      if (this.props.type === 'card' && _fieldval.Ot === 'required') { // 鍗$墖涓棤澶氳閫夐」
+        _fieldval.Ot = 'requiredSgl'
       }
 
       this.record.label = _fieldval.label || this.record.label || ''
@@ -632,7 +683,7 @@
         ]
   
         if (item.key === 'innerFunc') {
-          let str = '^(' + item.fields.join('|') + ')'
+          let str = item.fields && item.fields.length ? '^(' + item.fields.join('|') + ')' : '^'
           let _patten = new RegExp(str + formRule.func.innerPattern + '$', 'g')
           rules.push(
             { pattern: _patten, message: formRule.func.innerMessage },
@@ -643,6 +694,24 @@
             { pattern: formRule.func.pattern, message: formRule.func.message },
             { max: formRule.func.max, message: formRule.func.maxMessage }
           )
+        } else if (item.key === 'output') {
+          if (this.record.intertype === '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 })
         }
@@ -662,7 +731,7 @@
         if (item.extendName) {
           content = <Select
             showSearch
-            allowClear={item.allowClear === true}
+            allowClear={item.allowClear === true || !item.required}
             filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 ||
               option.props.extend.toLowerCase().indexOf(input.toLowerCase()) >= 0}
             onChange={(value) => {this.optionChange(item.key, value)}}
@@ -677,7 +746,7 @@
         } else {
           content = <Select
             showSearch
-            allowClear={item.allowClear === true}
+            allowClear={item.allowClear === true || !item.required}
             filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
             onChange={(value) => {this.optionChange(item.key, value)}}
             getPopupContainer={() => document.getElementById('winter')}
@@ -697,6 +766,14 @@
         content = <Radio.Group onChange={(e) => {this.optionChange(item.key, e.target.value)}}>
           {item.options.map(option => <Radio key={option.value} value={option.value}>{option.text}</Radio>)}
         </Radio.Group>
+      } else if (item.type === 'checkbox') {
+        rules = [
+          { required: item.required, message: dict['form.required.select'] + item.label + '!' }
+        ]
+
+        content = <Checkbox.Group>
+          {item.options.map(option => <Checkbox key={option.value} value={option.value}>{option.text}</Checkbox>)}
+        </Checkbox.Group>
       } else if (item.type === 'cascader') {
         initVal = item.initVal || []
         rules = [
@@ -722,7 +799,7 @@
 
       fields.push(
         <Col span={span} key={index}>
-          <Form.Item className={className} label={item.tooltip ?
+          <Form.Item className={className} help={item.help} label={item.tooltip ?
             <Tooltip placement="topLeft" title={item.tooltip}>
               <QuestionCircleOutlined className="mk-form-tip" />
               {item.label}
@@ -736,6 +813,17 @@
         </Col>
       )
     })
+
+    if (window.debugger && this.props.card.uuid) {
+      fields.push(
+        <Col span={12} key="uuid">
+          <Form.Item label="鎸夐挳ID">
+            <Paragraph copyable>{this.props.card.uuid}</Paragraph>
+          </Form.Item>
+        </Col>
+      )
+    }
+
     return fields
   }
 
diff --git a/src/menu/components/share/actioncomponent/actionform/index.scss b/src/menu/components/share/actioncomponent/actionform/index.scss
index 2573ed4..a056976 100644
--- a/src/menu/components/share/actioncomponent/actionform/index.scss
+++ b/src/menu/components/share/actioncomponent/actionform/index.scss
@@ -1,5 +1,10 @@
 .menu-action-list-form {
   min-height: 190px;
+  >.ant-row >.ant-col {
+    display: inline-block;
+    float: none;
+    vertical-align: top;
+  }
   .superconfig {
     color: #1890ff;
     cursor: pointer;
diff --git a/src/menu/components/share/actioncomponent/dragaction/card.jsx b/src/menu/components/share/actioncomponent/dragaction/card.jsx
index 2f251a7..5518861 100644
--- a/src/menu/components/share/actioncomponent/dragaction/card.jsx
+++ b/src/menu/components/share/actioncomponent/dragaction/card.jsx
@@ -28,7 +28,7 @@
       moveCard(draggedId, overIndex)
     },
   })
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   let hasProfile = false
   if (['pop', 'prompt', 'exec'].includes(card.OpenType)) {
diff --git a/src/menu/components/share/actioncomponent/formconfig.jsx b/src/menu/components/share/actioncomponent/formconfig.jsx
index 7dd44d3..6ffb4b4 100644
--- a/src/menu/components/share/actioncomponent/formconfig.jsx
+++ b/src/menu/components/share/actioncomponent/formconfig.jsx
@@ -89,6 +89,7 @@
     { value: 'print', text: '鏍囩鎵撳嵃' },
     { value: 'closetab', text: '鏍囩鍏抽棴' },
     { value: 'megvii', text: '鏃疯闈㈡澘鏈�' },
+    { value: 'filezip', text: '鏂囦欢鍘嬬缉鍖�' },
   ]
   
   if (isApp) {
@@ -107,11 +108,14 @@
     opentypes = opentypes.filter(item => ['pop', 'prompt', 'exec', 'innerpage', 'funcbutton'].includes(item.value))
     funTypes = [
       { value: 'scan', text: '鎵爜' },
-      { value: 'logout', text: '閫�鍑�' },
+      { value: 'pay', text: '鏀粯' },
+      { value: 'resetPwd', text: '淇敼瀵嗙爜'},
       { value: 'mkBinding', text: '寮�閫氭壂鐮佺櫥褰�' },
       { value: 'mkUnBinding', text: '鐢ㄦ埛瑙g粦' },
       { value: 'mkUnsubscribe', text: '娉ㄩ攢璐︽埛' },
       { value: 'reAuth', text: '鍒囨崲绯荤粺锛堟竻绌虹紦瀛�-灏忕▼搴忥級' },
+      { value: 'copyurl', text: '澶嶅埗閾炬帴鍦板潃' },
+      { value: 'logout', text: '閫�鍑�' },
       { value: 'goBack', text: '杩斿洖' },
     ]
     pageTemps = [
@@ -160,6 +164,19 @@
   }
   if (appType === 'mob' && card.control === 'parent') {
     card.control = ''
+  }
+
+  if (card.execSuccess === 'goback') {
+    card.openmenu = 'goback'
+    card.execSuccess = 'never'
+  }
+
+  let closetab = []
+  if (!appType) {
+    closetab = [{
+      value: 'closetab',
+      text: '鍏抽棴鏍囩'
+    }]
   }
 
   let forms = [
@@ -236,6 +253,20 @@
       required: true,
     },
     {
+      type: 'checkbox',
+      key: 'payType',
+      label: '鏀粯鏂瑰紡',
+      initVal: card.payType || [],
+      required: true,
+      options: [{
+        value: 'wxpay',
+        text: '寰俊'
+      }, {
+        value: 'alipay',
+        text: '鏀粯瀹�'
+      }]
+    },
+    {
       type: 'radio',
       key: 'procMode',
       label: '鍙傛暟澶勭悊',
@@ -272,6 +303,15 @@
       tooltip: functip,
       fields: usefulFields,
       required: false,
+    },
+    {
+      type: 'text',
+      key: 'urlkey',
+      label: '鍦板潃瀛楁',
+      initVal: card.urlkey || '',
+      tooltip: '鍥剧墖锛堟枃浠讹級閾炬帴鐨勫瓧娈靛悕銆�',
+      required: false,
+      readonly: false
     },
     {
       type: 'select',
@@ -427,10 +467,8 @@
       }, {
         value: 'mainline',
         text: '鍒锋柊涓婄骇缁勪欢 - 琛�'
-      }, {
-        value: !appType ? 'closetab' : 'goback',
-        text: !appType ? '鍏抽棴鏍囩' : '杩斿洖锛堜笂涓�涓〉闈級'
-      },
+      }, 
+      ...closetab,
       ...refresh]
     },
     {
@@ -631,7 +669,7 @@
       key: 'syncComponent',
       label: '鍒锋柊缁勪欢',
       initVal: card.syncComponent || [],
-      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栧脊绐楁爣绛惧叧闂椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑缁勪欢',
+      tooltip: '鎵ц鎴愬姛鍚庯紙鎴栧脊绐楁爣绛惧叧闂椂锛夛紝闇�瑕佸悓姝ュ埛鏂扮殑缁勪欢銆傛敞锛氶�夋嫨褰撳墠缁勪欢鐨勪笂绾х粍浠舵棤鏁堛��',
       required: false,
       options: modules
     },
@@ -640,7 +678,7 @@
       key: 'switchTab',
       label: '鍒囨崲鏍囩',
       initVal: card.switchTab || [],
-      tooltip: '鎵ц鎴愬姛鍚庯紝闇�瑕佸垏鎹㈢殑鏍囩椤�',
+      tooltip: '鎵ц鎴愬姛鍚庯紝闇�瑕佸垏鎹㈢殑鏍囩椤点��' + (appType === 'mob' ? '娉細灏忕▼搴忎腑鏃犳晥' : ''),
       required: false,
       options: tabs
     },
@@ -649,7 +687,7 @@
       key: 'anchors',
       label: '璺宠浆閿氱偣',
       initVal: card.anchors || [],
-      tooltip: '鎵ц鎴愬姛鍚庯紝闇�瑕佽烦杞殑閿氱偣',
+      tooltip: '鎵ц鎴愬姛鍚庯紝闇�瑕佽烦杞殑閿氱偣銆�' + (appType === 'mob' ? '娉細灏忕▼搴忎腑鏃犳晥' : ''),
       required: false,
       options: anchors
     },
@@ -669,16 +707,17 @@
       label: '鎵撳紑鑿滃崟',
       tooltip: '鎵ц鎴愬姛鍚庨渶瑕佹墦寮�鐨勮彍鍗曘��',
       initVal: card.openmenu || (!appType ? [] : ''),
+      help: appType === 'mob' || appType === 'pc' ? '鍙繑鍥炰笂涓�椤点��' : null,
       required: false,
       allowClear: true,
-      options: appType === 'mob' ? [...appMenus, {value: 'goback', text: '杩斿洖锛堜笂涓�椤碉級'}] : (appType === 'pc' ? appMenus : menulist),
+      options: appType === 'mob' || appType === 'pc' ? [...appMenus, {value: 'goback', text: '杩斿洖锛堜笂涓�椤碉級'}] : menulist,
       forbid: viewType === 'popview'
     },
     {
       type: 'text',
       key: 'output',
       label: '杩斿洖鍊�',
-      tooltip: '鎵ц鎴愬姛鍚庣殑杩斿洖鍊笺�備緥濡傦細@id',
+      tooltip: '鎵ц鎴愬姛鍚庣殑杩斿洖鍊笺�傜郴缁熷嚱鏁板彲鎸囧畾杩斿洖鐨勫彉閲忥紙浠绗﹀紑澶达紝濡侤id锛夛紱鑷畾涔夊嚱鏁板彲鎸囧畾杩斿洖瀛楁锛堝id锛夈��',
       initVal: card.output || '',
       required: false,
       forbid: viewType === 'popview'
@@ -696,15 +735,13 @@
       key: 'open',
       label: '鎵撳紑鏂瑰紡',
       initVal: card.open || 'blank',
+      tooltip: '鑿滃崟鎵撳紑鏂瑰紡銆�',
       required: true,
-      forbid: appType !== 'pc',
-      options: [{
-        value: 'blank',
-        text: '鏂扮獥鍙�'
-      }, {
-        value: 'self',
-        text: '褰撳墠绐楀彛'
-      }]
+      forbid: appType !== 'pc' && appType !== 'mob',
+      options: [
+        {value: 'blank', text: appType !== 'mob' ? '鏂扮獥鍙�' : '鏂伴〉闈�'},
+        {value: 'self', text: appType !== 'mob' ? '褰撳墠绐楀彛' : '褰撳墠椤甸潰'},
+      ]
     },
     {
       type: 'radio',
@@ -914,6 +951,21 @@
         value: 'true',
         text: '鏄�'
       }]
+    },
+    {
+      type: 'radio',
+      key: 'progress',
+      label: '杩涘害鎻愮ず',
+      initVal: card.progress || 'number',
+      required: false,
+      forbid: appType === 'mob',
+      options: [{
+        value: 'number',
+        text: '鍓╀綑鏁�'
+      }, {
+        value: 'progressbar',
+        text: '杩涘害鏉�'
+      }]
     }
   ]
 
diff --git a/src/menu/components/share/actioncomponent/index.jsx b/src/menu/components/share/actioncomponent/index.jsx
index 8204e57..8d5a172 100644
--- a/src/menu/components/share/actioncomponent/index.jsx
+++ b/src/menu/components/share/actioncomponent/index.jsx
@@ -173,6 +173,10 @@
     let functip = <div>
       <p style={{marginBottom: '5px'}}>{this.state.dict['model.tooltip.func.innerface'].replace('@ableField', ableField)}</p>
     </div>
+    
+    if (!ableField) { // 鏃犲瓧娈甸檺鍒�
+      functip = ''
+    }
 
     let menulist = sessionStorage.getItem('fstMenuList')
     if (menulist) {
@@ -184,8 +188,18 @@
     } else {
       menulist = []
     }
+
+    let supId = ''
+    if (config.setting && config.setting.supModule) {
+      let pid = config.setting.supModule[config.setting.supModule.length - 1]
+      if (pid && pid !== 'empty') {
+        supId = pid
+      } else {
+        supId = ''
+      }
+    }
     
-    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid) || []
+    let modules = MenuUtils.getSubModules(window.GLOB.customMenu.components, config.uuid, supId) || []
     let anchors = MenuUtils.getAnchors(window.GLOB.customMenu.components, config.uuid) || []
 
     this.setState({
@@ -315,6 +329,7 @@
       profVisible: true,
       card: element
     })
+    MKEmitter.emit('modalStatus', '楠岃瘉淇℃伅')
   }
 
   /**
@@ -342,6 +357,7 @@
       }, () => {
         this.props.updateaction({...config, action: _actionlist})
       })
+      MKEmitter.emit('modalStatus', false)
     })
   }
 
@@ -414,6 +430,8 @@
     if (element.OpenType === 'pop' || element.OpenType === 'popview' || element.execMode === 'pop') {
       this.props.setSubConfig(element)
     } else if (element.OpenType === 'innerpage' && element.pageTemplate === 'linkpage') {
+      MKEmitter.emit('changeEditMenu', {MenuID: element.linkmenu})
+    } else if (element.OpenType === 'funcbutton' && (element.funcType === 'copyurl' || element.funcType === 'scan') && element.linkmenu) {
       MKEmitter.emit('changeEditMenu', {MenuID: element.linkmenu})
     } else {
       this.handleAction(element)
@@ -548,9 +566,11 @@
             if (this.verifyRef.handleCancel) {
               this.verifyRef.handleCancel().then(() => {
                 this.setState({ profVisible: false })
+                MKEmitter.emit('modalStatus', false)
               })
             } else {
               this.setState({ profVisible: false })
+              MKEmitter.emit('modalStatus', false)
             }
           }}
           destroyOnClose
diff --git a/src/menu/components/share/clockcomponent/index.jsx b/src/menu/components/share/clockcomponent/index.jsx
index 2b1006d..9fb414d 100644
--- a/src/menu/components/share/clockcomponent/index.jsx
+++ b/src/menu/components/share/clockcomponent/index.jsx
@@ -33,7 +33,7 @@
       this.setState({
         visible: false
       })
-      this.props.updateConfig({...config, timer: res.timer, clearField: res.clearField || '', clearValue: res.clearValue || ''})
+      this.props.updateConfig({...config, timer: res.timer, timerRepeats: res.timerRepeats, clearField: res.clearField || '', clearValue: res.clearValue || ''})
     })
   }
 
diff --git a/src/menu/components/share/clockcomponent/settingform/index.jsx b/src/menu/components/share/clockcomponent/settingform/index.jsx
index 099f414..3e60007 100644
--- a/src/menu/components/share/clockcomponent/settingform/index.jsx
+++ b/src/menu/components/share/clockcomponent/settingform/index.jsx
@@ -1,6 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Row, Col, Select, Tooltip, Input } from 'antd'
+import { Form, Row, Col, Select, Tooltip, Input, InputNumber } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 
 import './index.scss'
@@ -69,6 +69,18 @@
                 )}
               </Form.Item>
             </Col>
+            {timer ? <Col span={22}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="瀹氭椂鍣ㄦ墽琛屾鏁般�傛敞锛�0琛ㄧず娌℃湁闄愬埗銆�">
+                  <QuestionCircleOutlined className="mk-form-tip" />
+                  鎵ц娆℃暟
+                </Tooltip>
+              }>
+                {getFieldDecorator('timerRepeats', {
+                  initialValue: config.timerRepeats || 0,
+                })(<InputNumber min={0} max={500} precision={0} />)}
+              </Form.Item>
+            </Col> : null}
             {(config.subtype === 'balcony' || config.subtype === 'propcard') && timer ? <Col span={22}>
               <Form.Item label={
                 <Tooltip placement="topLeft" title="鍙互鎸囧畾瀛楁鐢ㄤ簬鎺у埗瀹氭椂鍣ㄧ殑鍏抽棴銆�">
diff --git a/src/menu/components/share/copycomponent/index.jsx b/src/menu/components/share/copycomponent/index.jsx
index 74bacff..53404dc 100644
--- a/src/menu/components/share/copycomponent/index.jsx
+++ b/src/menu/components/share/copycomponent/index.jsx
@@ -7,8 +7,8 @@
 
 class CopyComponent extends Component {
   static propTpyes = {
-    btnlog: PropTypes.array,
-    handlelog: PropTypes.func
+    type: PropTypes.string,
+    card: PropTypes.object
   }
 
   trigger = () => {
@@ -24,6 +24,23 @@
         _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)
+        }
+      }
+
       _val = window.btoa(window.encodeURIComponent(JSON.stringify(_val)))
     } catch (e) {
       message.warning('澶嶅埗澶辫触锛岃閲嶈瘯锛�')
diff --git a/src/menu/components/share/normalheader/index.jsx b/src/menu/components/share/normalheader/index.jsx
index 802787f..e5345f5 100644
--- a/src/menu/components/share/normalheader/index.jsx
+++ b/src/menu/components/share/normalheader/index.jsx
@@ -63,19 +63,24 @@
 
   render() {
     const { config, hideSearch } = this.props
-    const { appType } = this.state
+    // const { appType } = this.state
 
     let title = config.plot ? config.plot.title : config.wrap.title
     let show = true
 
-    if (!title && appType === 'mob' && config.type === 'card' && config.subtype === 'datacard' && config.action && config.action.length) {
-      title = ' '
-    }
+    // if (!title && appType === 'mob' && config.type === 'card' && config.subtype === 'datacard' && config.action && config.action.length) {
+    //   title = ' '
+    // }
 
     if (!title && (!config.search || config.search.length === 0 || hideSearch === 'true')) {
       show = false
     }
     let _style = resetStyle(config.headerStyle)
+
+    let _s = {display: 'block', flex: 1}
+    if (show && ((config.wrap && config.wrap.searchable === 'true') || (hideSearch !== 'true' && config.search && config.search.length))) {
+      _s = null
+    }
 
     return (
       <div className={'normal-header' + (!show ? ' hidden' : '') + (config.wrap && config.wrap.searchable === 'true' ? ' tree-search' : '')} style={_style}>
@@ -84,7 +89,7 @@
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
           </div>
         } trigger="hover">
-          <span className="title">{title}</span>
+          <span className="title" style={_s}>{title}</span>
         </Popover>
         {config.wrap && config.wrap.searchable === 'true' ? <span className="ant-input-search ant-input-affix-wrapper"><span className="ant-input-suffix"><SearchOutlined /></span></span> : null}
         {hideSearch !== 'true' && config.search ? <SearchComponent config={config} updatesearch={this.props.updateComponent}/> : null}
diff --git a/src/menu/components/share/normalheader/index.scss b/src/menu/components/share/normalheader/index.scss
index 2bd66c6..9d23a2a 100644
--- a/src/menu/components/share/normalheader/index.scss
+++ b/src/menu/components/share/normalheader/index.scss
@@ -21,6 +21,9 @@
     flex: 1;
     padding-top: 5px;
   }
+  .search-length0 {
+    display: none;
+  }
   .ant-input-search.ant-input-affix-wrapper {
     width: 50%;
     max-width: 150px;
diff --git a/src/menu/components/share/searchcomponent/dragsearch/card.jsx b/src/menu/components/share/searchcomponent/dragsearch/card.jsx
index f6f78e3..7961d92 100644
--- a/src/menu/components/share/searchcomponent/dragsearch/card.jsx
+++ b/src/menu/components/share/searchcomponent/dragsearch/card.jsx
@@ -31,7 +31,7 @@
       moveCard(draggedId, overIndex)
     }
   })
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   let _defaultValue = '' // 涓嬫媺鎼滅储銆佹椂闂磋寖鍥寸被鍨嬶紝鍒濆鍊奸渶瑕侀澶勭悊
 
@@ -121,8 +121,6 @@
           <Form.Item
             labelCol={{style: {width: labelwidth + '%'}}}
             wrapperCol={{style: {width: (100 - labelwidth) + '%'}}}
-            // labelCol={{xs: { span: 24 }, sm: { span: 8 }}}
-            // wrapperCol = {{xs: { span: 24 }, sm: { span: 16 }}}
             label={card.labelShow !== 'false' ? card.label : ''}
             required={card.required === 'true'}
           >
diff --git a/src/menu/components/share/searchcomponent/index.jsx b/src/menu/components/share/searchcomponent/index.jsx
index 5c18abf..dc49dc5 100644
--- a/src/menu/components/share/searchcomponent/index.jsx
+++ b/src/menu/components/share/searchcomponent/index.jsx
@@ -115,7 +115,7 @@
     this.setState({
       visible: true,
       card: card,
-      formlist: getSearchForm(card, linkableFields)
+      formlist: getSearchForm(card, linkableFields, [], 'header')
     })
   }
 
@@ -223,10 +223,10 @@
           LText: res.dataSource
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
         
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
 
         if (window.GLOB.mainSystemApi && res.database === 'sso') {
@@ -289,7 +289,7 @@
     const { dict, searchlist, visible, sqlVerifing } = this.state
 
     return (
-      <div className="model-custom-header-search-list">
+      <div className={'model-custom-header-search-list search-length' + (searchlist.length)}>
         <DragElement
           list={searchlist}
           handleList={this.handleList}
diff --git a/src/menu/components/share/sourcecomponent/index.jsx b/src/menu/components/share/sourcecomponent/index.jsx
index 012c84e..ae5a6eb 100644
--- a/src/menu/components/share/sourcecomponent/index.jsx
+++ b/src/menu/components/share/sourcecomponent/index.jsx
@@ -20,11 +20,13 @@
   }
 
   UNSAFE_componentWillMount () {
-    const { value } = this.props
+    const { value, initialValue } = this.props
     let val = ''
 
     if (value) {
       val = value
+    } else if (initialValue) {
+      val = initialValue
     } else if (this.props['data-__meta']) {
       val = this.props['data-__meta'].initialValue || ''
     }
@@ -61,6 +63,7 @@
     const { url, visible } = this.state
     const { type } = this.props
     let name = url ? url.slice(url.lastIndexOf('/') + 1) : ''
+    // url !== '@icon@'
 
     return (
       <div className="mk-source-wrap">
@@ -69,11 +72,20 @@
           <Radio.Button value="upload" size="small" onClick={() => this.handleChange('upload')}>涓婁紶</Radio.Button>
           <Radio.Button value="system" size="small" onClick={() => this.handleChange('system')}>绯荤粺</Radio.Button>
         </Radio.Group> : null}
-        {url ? <div className={'mk-source-item-info' + (type !== 'video' ? ' picture' : '')}>
-          {type === 'video' ? <PaperClipOutlined /> : <img src={url} alt="" />}
+        {url && type === 'video' ? <div className="mk-source-item-info">
+          <PaperClipOutlined />
           <a target="_blank" rel="noopener noreferrer" href={url}>{name}</a>
           <DeleteOutlined title="鍒犻櫎鏂囦欢" onClick={this.deleteUrl}/>
         </div> : null}
+        {url && type !== 'video' && url !== '@icon@' ? <div className="mk-source-item-info picture">
+          <img src={url} alt="" />
+          <a target="_blank" rel="noopener noreferrer" href={url}>{name}</a>
+          <DeleteOutlined title="鍒犻櫎鏂囦欢" onClick={this.deleteUrl}/>
+        </div> : null}
+        {url && type !== 'video' && url === '@icon@' ? <div className="mk-source-item-info avatar">
+          <span className="mk-avatar">{name}</span>
+          <DeleteOutlined title="鍒犻櫎鏂囦欢" onClick={this.deleteUrl}/>
+        </div> : null}
         <Modal
           visible={!!visible}
           width={visible !== 'system' ? 600 : 1000}
diff --git a/src/menu/components/share/sourcecomponent/index.scss b/src/menu/components/share/sourcecomponent/index.scss
index ecf2c09..156af96 100644
--- a/src/menu/components/share/sourcecomponent/index.scss
+++ b/src/menu/components/share/sourcecomponent/index.scss
@@ -14,7 +14,7 @@
       top: 3px;
       right: 0px;
       padding-right: 6px;
-      color: rgba(0,0,0,.45);
+      color: #f5222d;
       cursor: pointer;
       display: none;
     }
@@ -26,6 +26,18 @@
       overflow: hidden;
       white-space: nowrap;
       text-overflow: ellipsis;
+    }
+    .mk-avatar {
+      color: #1890ff;
+      display: inline-block;
+      width: 100%;
+      padding-left: 5px;
+      padding-right: 14px;
+      overflow: hidden;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+      height: 32px;
+      line-height: 32px;
     }
   }
   .mk-source-item-info.picture {
@@ -42,6 +54,13 @@
       top: 8px;
     }
   }
+  .mk-source-item-info.avatar {
+    display: flex;
+    top: 0px;
+    .anticon-delete {
+      top: 8px;
+    }
+  }
   .mk-source-item-info:hover {
     background-color: #e6f7ff;
     .anticon-delete {
@@ -53,4 +72,7 @@
     height: 28px;
     line-height: 26px;
   }
+  .ant-radio-group {
+    white-space: nowrap;
+  }
 }
diff --git a/src/menu/components/table/edit-table/columns/editColumn/index.jsx b/src/menu/components/table/edit-table/columns/editColumn/index.jsx
index ca299fb..3997baa 100644
--- a/src/menu/components/table/edit-table/columns/editColumn/index.jsx
+++ b/src/menu/components/table/edit-table/columns/editColumn/index.jsx
@@ -85,7 +85,14 @@
   }
 
   editColumn = (column) => {
-    let formlist = getColumnForm(column, this.props.fields, this.props.columns)
+    let fields = fromJS(this.props.fields).toJS().map(item => {
+      if (item.label.toLowerCase() !== item.field.toLowerCase()) {
+        item.text = item.label + '锛�' + item.field + '锛�'
+      }
+      return item
+    })
+
+    let formlist = getColumnForm(column, fields, this.props.columns)
 
     this.column = fromJS(column).toJS()
     this.column.editType = this.column.editType || 'text'
@@ -132,7 +139,7 @@
         }
       })
     } else if (key === 'field') {
-      let values = {label: option.props.children}
+      let values = {label: option.props.label || option.props.children}
       if (/Decimal|int/ig.test(option.props.datatype)) {
         let decimal = 0
         if (/Decimal/ig.test(option.props.datatype)) {
@@ -270,7 +277,7 @@
           getPopupContainer={() => document.getElementById('edit-table-column-winter')}
         >
           {item.options.map((option, i) =>
-            <Select.Option key={i} datatype={option.datatype || ''} value={(option.value || option.field || option.MenuID)}>
+            <Select.Option key={i} datatype={option.datatype || ''} label={option.label || ''} value={(option.value || option.field || option.MenuID)}>
               {(option.text || option.label || option.MenuName)}
             </Select.Option>
           )}
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 baf0e0c..03bcb2d 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
@@ -37,7 +37,7 @@
     fields.push('jskey')
 
     let _sql = `Declare @${btn.sheet} table (${usefulfields.map(item => item.field + ' ' + item.type).join(',')},jskey nvarchar(50),data_type nvarchar(50),BID nvarchar(50))
-      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50),@ErrorCode nvarchar(50), @retmsg nvarchar(4000),@tbid Nvarchar(512)
+      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@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=''
     `
     
@@ -160,7 +160,8 @@
           LText: this.state.verifySql + _initCustomScript + _prevCustomScript + _backCustomScript + tail
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
 
         // 澶栬仈鏁版嵁搴撴浛鎹�
         if (window.GLOB.externalDatabase !== null) {
@@ -168,7 +169,6 @@
         }
 
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
         
         this.setState({loading: true})
@@ -274,7 +274,9 @@
           </Col>
           {usefulfields ? <Col span={24} className="sqlfield">
             <Form.Item label={'鍙敤瀛楁'}>
-            BID, ID, LoginUID, SessionUid, UserID, Appkey, UserName, FullName, RoleID, mk_departmentcode, mk_organization, login_city, {usefulfields},data_type锛堟敞锛歫skey涓轰富閿�硷紝鏂板鏃跺墠绔敓鎴愶紱data_type涓烘搷浣滅被鍨嬶紝鏂板 - add銆佷慨鏀� - upt銆佸垹闄� - del锛�
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><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>
           </Col> : null}
           <Col span={8} style={{whiteSpace: 'nowrap'}}>
diff --git a/src/menu/components/table/edit-table/columns/tableIn/index.jsx b/src/menu/components/table/edit-table/columns/tableIn/index.jsx
index 9e83517..61698fb 100644
--- a/src/menu/components/table/edit-table/columns/tableIn/index.jsx
+++ b/src/menu/components/table/edit-table/columns/tableIn/index.jsx
@@ -80,7 +80,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopTwoTone style={{marginLeft: '5px'}} twoToneColor="#ff4d4f" />
             </div>
           ) :
@@ -133,7 +133,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopTwoTone style={{marginLeft: '5px'}} twoToneColor="#ff4d4f" />
             </div>
           ) :
diff --git a/src/menu/components/table/edit-table/index.jsx b/src/menu/components/table/edit-table/index.jsx
index ed2e7f9..8e5ee1d 100644
--- a/src/menu/components/table/edit-table/index.jsx
+++ b/src/menu/components/table/edit-table/index.jsx
@@ -116,12 +116,8 @@
           _card.wrap.doubleClick = oriUids[_card.wrap.doubleClick] || ''
         }
       }
-      
-      this.setState({
-        card: _card
-      })
 
-      this.filterOrigin(_card)
+      this.updateComponent(_card)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -164,31 +160,91 @@
     }
   }
 
-  filterOrigin = (component) => {
-    if (component.isNew) {
-      let item = fromJS(component).toJS()
-      item.cols = item.cols.filter(a => !a.origin)
-
-      delete item.isNew
-
-      this.props.updateConfig(item)
-    } else {
-      this.props.updateConfig(component)
-    }
-  }
-
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+
+    if (!window.GLOB.styling || !card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌�
+      card.errors = []
+  
+      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+      } else if (!card.setting.primaryKey) {
+        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+      } else if (!card.setting.supModule) {
+        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+      }
+  
+      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
+      if (supModule === 'empty') {
+        supModule = ''
+      }
+  
+      let columns = card.columns.map(c => c.field)
+      let lowcols = card.columns.map(c => c.field.toLowerCase())
+  
+      card.action.forEach(cell => {
+        if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+          if (!cell.modal || cell.modal.fields.length === 0) {
+            card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+          } else {
+            cell.modal.fields.forEach(m => {
+              if (m.type === 'linkMain' && !supModule) {
+                card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+              } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+                card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+              }
+            })
+          }
+        }
+      })
+  
+      card.cols.forEach(col => {
+        if (col.type === 'action') {
+          col.elements.forEach(cell => {
+            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+              if (!cell.modal || cell.modal.fields.length === 0) {
+                card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+              } else {
+                cell.modal.fields.forEach(m => {
+                  if (m.type === 'linkMain' && !supModule) {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                  } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+                  }
+                })
+              }
+            }
+          })
+        } else if (col.type === 'custom') {
+          col.elements.forEach(cell => {
+            if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+              card.errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑鍔ㄦ�佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+            }
+          })
+        } else if (col.field && !columns.includes(col.field)) {
+          card.errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑瀛楁鈥�${col.field}鈥濇棤鏁坄})
+        }
+      })
+    }
+
     this.setState({
-      card: component
+      card: card
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
+    let _card = card.isNew ? fromJS(card).toJS() : card
+    if (_card.isNew) {
+      _card.cols = _card.cols.filter(a => !a.origin)
 
-    this.filterOrigin(component)
+      delete _card.isNew
+    }
+    
+    this.props.updateConfig(_card)
   }
 
   changeStyle = () => {
@@ -222,12 +278,8 @@
     _card.wrap.color = color
     _card.wrap.fontSize = fontSize
     _card.wrap.fontWeight = fontWeight
-
-    this.setState({
-      card: _card
-    })
     
-    this.filterOrigin(_card)
+    this.updateComponent(_card)
   }
 
   addColumns = () => {
@@ -272,16 +324,6 @@
     MKEmitter.emit('addButton', card.uuid, newcard)
   }
 
-  /**
-   * @description 鏇存柊鎼滅储鏉′欢閰嶇疆淇℃伅
-   */
-  updateconfig = (config) => {
-    this.setState({
-      card: config
-    })
-    this.filterOrigin(config)
-  }
-
   setSubConfig = (item) => {
     const { card, appType } = this.state
     let btn = fromJS(item).toJS()
@@ -318,8 +360,7 @@
       return cell
     })
 
-    this.setState({card})
-    this.filterOrigin(card)
+    this.updateComponent(card)
   }
 
   getWrapForms = () => {
@@ -334,6 +375,13 @@
     res.color = card.wrap.color
     res.fontSize = card.wrap.fontSize
     res.fontWeight = card.wrap.fontWeight
+
+    res.show = card.wrap.show || 'true'
+    res.advanceType = card.wrap.advanceType || 'modal'
+    res.advanceWidth = card.wrap.advanceWidth || 1000
+    res.drawerPlacement = card.wrap.drawerPlacement || 'right'
+    res.searchRatio = card.wrap.searchRatio || 6
+    res.searchLwidth = card.wrap.searchLwidth !== undefined ? card.wrap.searchLwidth : 33.3
 
     let _card = {...card, wrap: res}
 
@@ -376,10 +424,23 @@
         } trigger="hover">
           <ToolOutlined />
         </Popover>
-        <SearchComponent config={card} updatesearch={this.updateconfig}/>
+        <SearchComponent config={card} updatesearch={this.updateComponent}/>
         <ActionComponent type="editable" config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/>
-        <ColumnComponent config={card} updatecolumn={this.updateconfig}/>
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <ColumnComponent config={card} updatecolumn={this.updateComponent}/>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/table/edit-table/options.jsx b/src/menu/components/table/edit-table/options.jsx
index 3ed37ec..977367f 100644
--- a/src/menu/components/table/edit-table/options.jsx
+++ b/src/menu/components/table/edit-table/options.jsx
@@ -205,18 +205,18 @@
         {value: 'ghost', label: '閫忔槑'},
       ]
     },
-    {
-      type: 'radio',
-      field: 'show',
-      label: '鎼滅储鎸夐挳',
-      initval: wrap.show || 'true',
-      tooltip: '鎼滅储鏉′欢瀛樺湪鏃讹紝鍙�夋嫨鏄惁鏄剧ず鎼滅储鎸夐挳銆�',
-      required: false,
-      options: [
-        {value: 'true', label: '鏄剧ず'},
-        {value: 'false', label: '闅愯棌'},
-      ]
-    },
+    // {
+    //   type: 'radio',
+    //   field: 'show',
+    //   label: '鎼滅储鎸夐挳',
+    //   initval: wrap.show || 'true',
+    //   tooltip: '鎼滅储鏉′欢瀛樺湪鏃讹紝鍙�夋嫨鏄惁鏄剧ず鎼滅储鎸夐挳銆�',
+    //   required: false,
+    //   options: [
+    //     {value: 'true', label: '鏄剧ず'},
+    //     {value: 'false', label: '闅愯棌'},
+    //   ]
+    // },
     {
       type: 'color',
       field: 'borderColor',
@@ -243,17 +243,17 @@
     //   precision: 0,
     //   required: false
     // },
-    {
-      type: 'number',
-      field: 'advanceWidth',
-      label: '楂樼骇鎼滅储',
-      initval: wrap.advanceWidth || 1000,
-      tooltip: '楂樼骇鎼滅储寮圭獥鐨勫搴︼紝娉細褰撳搴﹀�煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺��',
-      min: 10,
-      max: 3000,
-      precision: 0,
-      required: false
-    },
+    // {
+    //   type: 'number',
+    //   field: 'advanceWidth',
+    //   label: '楂樼骇鎼滅储',
+    //   initval: wrap.advanceWidth || 1000,
+    //   tooltip: '楂樼骇鎼滅储寮圭獥鐨勫搴︼紝娉細褰撳搴﹀�煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺��',
+    //   min: 10,
+    //   max: 3000,
+    //   precision: 0,
+    //   required: false
+    // },
     {
       type: 'radio',
       field: 'permission',
diff --git a/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
index d8a652f..0c76b5f 100644
--- a/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
+++ b/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
@@ -154,7 +154,6 @@
       label: Formdict['model.sort'],
       initVal: card.IsSort || (card.isSub ? 'false' : 'true'),
       required: true,
-      // forbidden: card.isSub,
       options: [{
         value: 'true',
         text: Formdict['model.true']
@@ -415,7 +414,8 @@
       label: Formdict['header.form.blacklist'],
       initVal: card.blacklist || [],
       required: false,
-      options: roleList
+      options: roleList,
+      forbidden: appType === 'mob'
     }
   ]
 }
diff --git a/src/menu/components/table/normal-table/columns/editColumn/index.jsx b/src/menu/components/table/normal-table/columns/editColumn/index.jsx
index 7aa7940..5a41606 100644
--- a/src/menu/components/table/normal-table/columns/editColumn/index.jsx
+++ b/src/menu/components/table/normal-table/columns/editColumn/index.jsx
@@ -44,7 +44,14 @@
   }
 
   editColumn = (column) => {
-    let formlist = getColumnForm(column, this.props.fields)
+    let fields = fromJS(this.props.fields).toJS().map(item => {
+      if (item.label.toLowerCase() !== item.field.toLowerCase()) {
+        item.text = item.label + '锛�' + item.field + '锛�'
+      }
+      return item
+    })
+    
+    let formlist = getColumnForm(column, fields)
     let _options = fromJS(columnTypeOptions[column.type]).toJS()
     if (column.type === 'text' || column.type === 'number') {
       if (column.perspective === 'linkmenu') {
@@ -96,7 +103,7 @@
         }
       })
     } else if (key === 'field') {
-      let values = {label: option.props.children}
+      let values = {label: option.props.label || option.props.children}
       if (/Decimal|int/ig.test(option.props.datatype)) {
         let decimal = 0
         if (/Decimal/ig.test(option.props.datatype)) {
@@ -231,7 +238,7 @@
                   getPopupContainer={() => document.getElementById('columnwinter')}
                 >
                   {item.options.map((option, index) =>
-                    <Select.Option key={index} datatype={option.datatype || ''} value={(option.value || option.field || option.MenuID)}>
+                    <Select.Option key={index} datatype={option.datatype || ''} label={option.label || ''} value={(option.value || option.field || option.MenuID)}>
                       {(option.text || option.label || option.MenuName)}
                     </Select.Option>
                   )}
diff --git a/src/menu/components/table/normal-table/index.jsx b/src/menu/components/table/normal-table/index.jsx
index 30c4592..27556bd 100644
--- a/src/menu/components/table/normal-table/index.jsx
+++ b/src/menu/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 { Popover, notification } from 'antd'
+import { Popover } from 'antd'
 import { PlusOutlined, PlusCircleOutlined, PlusSquareOutlined, EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
 
 import asyncComponent from '@/utils/asyncComponent'
@@ -21,7 +21,7 @@
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
 const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent'))
 const PasteComponent = asyncIconComponent(() => import('@/menu/components/share/pastecomponent'))
-const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
+// const LogComponent = asyncIconComponent(() => import('@/menu/components/share/logcomponent'))
 const ColumnComponent = asyncComponent(() => import('./columns'))
 
 class TableCardEditComponent extends Component {
@@ -128,12 +128,8 @@
         _card.search = []
         _card.action = _card.action.filter(a => !a.origin)
       }
-      
-      this.setState({
-        card: _card
-      })
 
-      this.filterOrigin(_card)
+      this.updateComponent(_card)
     } else {
       let _card = fromJS(card).toJS()
       if (appType === 'mob') {
@@ -149,7 +145,7 @@
   componentDidMount () {
     MKEmitter.addListener('submitStyle', this.getStyle)
     MKEmitter.addListener('submitModal', this.handleSave)
-    MKEmitter.addListener('logButton', this.logButton)
+    // MKEmitter.addListener('logButton', this.logButton)
     MKEmitter.addListener('completeSave', this.completeSave)
   }
 
@@ -166,7 +162,7 @@
     }
     MKEmitter.removeListener('submitStyle', this.getStyle)
     MKEmitter.removeListener('submitModal', this.handleSave)
-    MKEmitter.removeListener('logButton', this.logButton)
+    // MKEmitter.removeListener('logButton', this.logButton)
     MKEmitter.removeListener('completeSave', this.completeSave)
   }
 
@@ -202,48 +198,116 @@
     return col
   }
 
-  filterOrigin = (component) => {
-    if (component.isNew) {
-      let item = fromJS(component).toJS()
-      item.search = item.search.filter(a => !a.origin)
-      item.action = item.action.filter(a => !a.origin)
-      item.cols = item.cols.filter(a => !a.origin)
-
-      delete item.isNew
-
-      this.props.updateConfig(item)
-    } else {
-      this.props.updateConfig(component)
-    }
-  }
-
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
-    this.setState({
-      card: component
-    })
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
-
-    this.filterOrigin(component)
-  }
-
-  logButton = (id, item) => {
-    const { card } = this.state
-
-    if (id !== card.uuid) return
-
-    let btnlog = card.btnlog || []
-    btnlog.push(item)
+    if (!window.GLOB.styling || !card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌�
+      card.errors = []
+  
+      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+      } else if (!card.setting.primaryKey) {
+        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+      } else if (!card.setting.supModule) {
+        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+      }
+  
+      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
+      if (supModule === 'empty') {
+        supModule = ''
+      }
+      let doubleClick = card.wrap.doubleClick || ''
+  
+      let columns = card.columns.map(c => c.field)
+      let lowcols = card.columns.map(c => c.field.toLowerCase())
+  
+      card.action.forEach(cell => {
+        if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+          if (!cell.modal || cell.modal.fields.length === 0) {
+            card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+          } else {
+            cell.modal.fields.forEach(m => {
+              if (m.type === 'linkMain' && !supModule) {
+                card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+              } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+                card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+              }
+            })
+          }
+        }
+        if (doubleClick === cell.uuid) {
+          doubleClick = ''
+        }
+      })
+  
+      card.cols.forEach(col => {
+        if (col.type === 'action') {
+          col.elements.forEach(cell => {
+            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+              if (!cell.modal || cell.modal.fields.length === 0) {
+                card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+              } else {
+                cell.modal.fields.forEach(m => {
+                  if (m.type === 'linkMain' && !supModule) {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                  } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+                  }
+                })
+              }
+            }
+            if (doubleClick === cell.uuid) {
+              doubleClick = ''
+            }
+          })
+        } else if (col.type === 'custom') {
+          col.elements.forEach(cell => {
+            if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+              card.errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑鍔ㄦ�佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+            }
+          })
+        } else if (col.field && !columns.includes(col.field)) {
+          card.errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑瀛楁鈥�${col.field}鈥濇棤鏁坄})
+        }
+      })
+      
+      if (doubleClick) {
+        card.errors.push({ level: 1, detail: `缁戝畾鐨勫弻鍑绘寜閽凡鍒犻櫎`})
+      }
+    }
 
     this.setState({
-      card: {...card, btnlog}
+      card: card
     })
-    this.filterOrigin({...card, btnlog})
+
+    let _card = card.isNew ? fromJS(card).toJS() : card
+    if (_card.isNew) {
+      _card.cols = _card.cols.filter(a => !a.origin)
+      _card.search = _card.search.filter(a => !a.origin)
+      _card.action = _card.action.filter(a => !a.origin)
+
+      delete _card.isNew
+    }
+    
+    this.props.updateConfig(_card)
   }
+
+  // logButton = (id, item) => {
+  //   const { card } = this.state
+
+  //   if (id !== card.uuid) return
+
+  //   let btnlog = card.btnlog || []
+  //   btnlog.push(item)
+
+  //   this.updateComponent({...card, btnlog})
+  // }
 
   changeStyle = () => {
     const { card } = this.state
@@ -277,11 +341,7 @@
     _card.wrap.fontSize = fontSize
     _card.wrap.fontWeight = fontWeight
 
-    this.setState({
-      card: _card
-    })
-    
-    this.filterOrigin(_card)
+    this.updateComponent(_card)
   }
 
   addColumns = () => {
@@ -326,16 +386,6 @@
     MKEmitter.emit('addButton', card.uuid, newcard)
   }
 
-  /**
-   * @description 鏇存柊鎼滅储鏉′欢閰嶇疆淇℃伅
-   */
-  updateconfig = (config) => {
-    this.setState({
-      card: config
-    })
-    this.filterOrigin(config)
-  }
-
   setSubConfig = (item) => {
     const { card, appType } = this.state
     let btn = fromJS(item).toJS()
@@ -372,49 +422,46 @@
       return cell
     })
 
-    this.setState({card})
-    this.filterOrigin(card)
+    this.updateComponent(card)
   }
 
-  handleLog = (type, logs, item) => {
-    let card = fromJS(this.state.card).toJS()
+  // handleLog = (type, logs, item) => {
+  //   let card = fromJS(this.state.card).toJS()
 
-    if (type === 'revert') {
-      let done = false
-      if (item.$parentId) {
-        card.cols.forEach(col => {
-          if (col.type !== 'action') return
-          if (item.$parentId === col.uuid) {
-            col.elements = col.elements ? [...col.elements, item] : [item]
-            done = true
-          }
-        })
-      }
+  //   if (type === 'revert') {
+  //     let done = false
+  //     if (item.$parentId) {
+  //       card.cols.forEach(col => {
+  //         if (col.type !== 'action') return
+  //         if (item.$parentId === col.uuid) {
+  //           col.elements = col.elements ? [...col.elements, item] : [item]
+  //           done = true
+  //         }
+  //       })
+  //     }
 
-      if (!done) {
-        card.action = card.action ? [...card.action, item] : [item]
-      }
+  //     if (!done) {
+  //       card.action = card.action ? [...card.action, item] : [item]
+  //     }
 
-      card.btnlog = logs
+  //     card.btnlog = logs
 
-      this.setState({ card })
-      this.filterOrigin(card)
-      notification.success({
-        top: 92,
-        message: '鎭㈠鎴愬姛锛�',
-        duration: 2
-      })
-    } else {
-      card.btnlog = logs
-      this.setState({ card })
-      this.filterOrigin(card)
-      notification.success({
-        top: 92,
-        message: '娓呴櫎鎴愬姛锛�',
-        duration: 2
-      })
-    }
-  }
+  //     this.updateComponent(card)
+  //     notification.success({
+  //       top: 92,
+  //       message: '鎭㈠鎴愬姛锛�',
+  //       duration: 2
+  //     })
+  //   } else {
+  //     card.btnlog = logs
+  //     this.updateComponent(card)
+  //     notification.success({
+  //       top: 92,
+  //       message: '娓呴櫎鎴愬姛锛�',
+  //       duration: 2
+  //     })
+  //   }
+  // }
 
   getWrapForms = () => {
     const { wrap, action, columns, cols } = this.state.card
@@ -435,6 +482,13 @@
     res.color = card.wrap.color
     res.fontSize = card.wrap.fontSize
     res.fontWeight = card.wrap.fontWeight
+
+    res.show = card.wrap.show || 'true'
+    res.advanceType = card.wrap.advanceType || 'modal'
+    res.advanceWidth = card.wrap.advanceWidth || 1000
+    res.drawerPlacement = card.wrap.drawerPlacement || 'right'
+    res.searchRatio = card.wrap.searchRatio || 6
+    res.searchLwidth = card.wrap.searchLwidth !== undefined ? card.wrap.searchLwidth : 33.3
 
     this.updateComponent({...card, wrap: res})
   }
@@ -469,7 +523,7 @@
             <CopyComponent type="normaltable" card={card}/>
             <PasteComponent config={card} options={options} updateConfig={this.updateComponent} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
-            <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} />
+            {/* <LogComponent btnlog={card.btnlog || []} handlelog={this.handleLog} /> */}
             <UserComponent config={card}/>
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} />
             <SettingComponent config={card} updateConfig={this.updateComponent} />
@@ -477,10 +531,23 @@
         } trigger="hover">
           <ToolOutlined />
         </Popover>
-        <SearchComponent config={card} updatesearch={this.updateconfig}/>
+        <SearchComponent config={card} updatesearch={this.updateComponent}/>
         <ActionComponent config={card} setSubConfig={this.setSubConfig} updateaction={this.updateComponent}/>
-        <ColumnComponent config={card} updatecolumn={this.updateconfig}/>
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <ColumnComponent config={card} updatecolumn={this.updateComponent}/>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/table/normal-table/options.jsx b/src/menu/components/table/normal-table/options.jsx
index cf01415..c6caecc 100644
--- a/src/menu/components/table/normal-table/options.jsx
+++ b/src/menu/components/table/normal-table/options.jsx
@@ -141,18 +141,18 @@
         {value: 'always', label: '鏁版嵁鍔犺浇'},
       ]
     },
-    {
-      type: 'radio',
-      field: 'show',
-      label: '鎼滅储鎸夐挳',
-      initval: wrap.show || 'true',
-      tooltip: '鎼滅储鏉′欢瀛樺湪鏃讹紝鍙�夋嫨鏄惁鏄剧ず鎼滅储鎸夐挳銆�',
-      required: false,
-      options: [
-        {value: 'true', label: '鏄剧ず'},
-        {value: 'false', label: '闅愯棌'},
-      ]
-    },
+    // {
+    //   type: 'radio',
+    //   field: 'show',
+    //   label: '鎼滅储鎸夐挳',
+    //   initval: wrap.show || 'true',
+    //   tooltip: '鎼滅储鏉′欢瀛樺湪鏃讹紝鍙�夋嫨鏄惁鏄剧ず鎼滅储鎸夐挳銆�',
+    //   required: false,
+    //   options: [
+    //     {value: 'true', label: '鏄剧ず'},
+    //     {value: 'false', label: '闅愯棌'},
+    //   ]
+    // },
     {
       type: 'color',
       field: 'borderColor',
@@ -179,18 +179,18 @@
     //   precision: 0,
     //   required: false
     // },
-    {
-      type: 'number',
-      field: 'advanceWidth',
-      label: '楂樼骇鎼滅储',
-      initval: wrap.advanceWidth || 1000,
-      tooltip: '楂樼骇鎼滅储寮圭獥鐨勫搴︼紝娉細褰撳搴﹀�煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺��',
-      min: 10,
-      max: 3000,
-      precision: 0,
-      required: false,
-      forbid: appType === 'mob'
-    },
+    // {
+    //   type: 'number',
+    //   field: 'advanceWidth',
+    //   label: '楂樼骇鎼滅储',
+    //   initval: wrap.advanceWidth || 1000,
+    //   tooltip: '楂樼骇鎼滅储寮圭獥鐨勫搴︼紝娉細褰撳搴﹀�煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺��',
+    //   min: 10,
+    //   max: 3000,
+    //   precision: 0,
+    //   required: false,
+    //   forbid: appType === 'mob'
+    // },
     {
       type: 'select',
       field: 'doubleClick',
@@ -218,9 +218,9 @@
     {
       type: 'text',
       field: 'controlVal',
-      label: '鎺у埗鍊�',
+      label: '绂佺敤鍊�',
       initval: wrap.controlVal || '',
-      tooltip: '褰撳瓧娈靛�间笌鎺у埗鍊肩浉绛夋椂锛岃鏁版嵁浼氱鐢紝澶氫釜鍊肩敤閫楀彿鍒嗛殧銆�',
+      tooltip: '褰撳瓧娈靛�间笌绂佺敤鍊肩浉绛夋椂锛岃鏁版嵁浼氱鐢紝澶氫釜鍊肩敤閫楀彿鍒嗛殧銆�',
       required: false
     },
     {
diff --git a/src/menu/components/tabs/antv-tabs/index.scss b/src/menu/components/tabs/antv-tabs/index.scss
index 7466ab4..330d975 100644
--- a/src/menu/components/tabs/antv-tabs/index.scss
+++ b/src/menu/components/tabs/antv-tabs/index.scss
@@ -44,6 +44,9 @@
   .ant-tabs-tabpane-active {
     min-height: 200px;
   }
+  .tab-shell-inner {
+    min-height: 100%;
+  }
 
   .ant-tabs .ant-tabs-top-bar > .ant-tabs-nav-container {
     >.ant-tabs-tab-next:not(.ant-tabs-tab-arrow-show) + .ant-tabs-nav-wrap > .ant-tabs-nav-scroll > .ant-tabs-nav {
diff --git a/src/menu/components/tabs/paste/index.jsx b/src/menu/components/tabs/paste/index.jsx
index 3e73e8d..ea3581c 100644
--- a/src/menu/components/tabs/paste/index.jsx
+++ b/src/menu/components/tabs/paste/index.jsx
@@ -71,7 +71,7 @@
 
   pasteSubmit = () => {
     const { Tab } = this.props
-    let options = ['tabs', 'group', 'datacard', 'propcard', 'timeline', 'balcony', 'normaltable', 'mainsearch', 'stepform', 'tabform', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter', 'chart']
+    let options = ['tabs', 'group', 'datacard', 'propcard', 'timeline', 'balcony', 'normaltable', 'mainsearch', 'simpleform', 'stepform', 'tabform', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter', 'chart']
     let types = {
       login: '鐧诲綍',
       navbar: '瀵艰埅鏍�',
diff --git a/src/menu/components/tabs/tabcomponents/card.jsx b/src/menu/components/tabs/tabcomponents/card.jsx
index 5b4ac68..e907928 100644
--- a/src/menu/components/tabs/tabcomponents/card.jsx
+++ b/src/menu/components/tabs/tabcomponents/card.jsx
@@ -17,7 +17,8 @@
 const CarouselDataCard = asyncComponent(() => import('@/menu/components/carousel/data-card'))
 const CarouselPropCard = asyncComponent(() => import('@/menu/components/carousel/prop-card'))
 const TableCard = asyncComponent(() => import('@/menu/components/card/table-card'))
-const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form'))
+const SimpleForm = asyncComponent(() => import('@/menu/components/form/simple-form'))
+const StepForm = asyncComponent(() => import('@/menu/components/form/step-form'))
 const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form'))
 const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table'))
 const EditTable = asyncComponent(() => import('@/menu/components/table/edit-table'))
@@ -73,8 +74,10 @@
       return (<NormalTree card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'scatter') {
       return (<AntvScatter card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'form' && card.subtype === 'simpleform') {
+      return (<SimpleForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'form' && card.subtype === 'stepform') {
-      return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+      return (<StepForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'form' && card.subtype === 'tabform') {
       return (<TabForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'tabs') {
diff --git a/src/menu/components/timeline/normal-timeline/index.jsx b/src/menu/components/timeline/normal-timeline/index.jsx
index d6ad7e9..1dcb7f4 100644
--- a/src/menu/components/timeline/normal-timeline/index.jsx
+++ b/src/menu/components/timeline/normal-timeline/index.jsx
@@ -48,7 +48,7 @@
         name: card.name,
         subtype: card.subtype,
         setting: { interType: 'system' },
-        wrap: { title: '', name: card.name, width: card.width || 24, color: '#1890ff', mode: 'left' },
+        wrap: { title: '', name: card.name, direction: 'vertical', width: card.width || 24, color: '#1890ff', mode: 'left' },
         style: { marginLeft: '0px', marginRight: '0px', marginTop: '0px', marginBottom: '0px' },
         subcards: [{
           uuid: Utils.getuuid(),
@@ -82,10 +82,8 @@
           return scard
         })
       }
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+
+      this.updateComponent(_card)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -114,15 +112,57 @@
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+    if (!window.GLOB.styling || !card.errors) { // 鏍峰紡淇敼鏃朵笉鍋氱瓫鏌�
+      card.errors = []
+  
+      if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+        card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+      } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+        card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+      } else if (!card.setting.primaryKey) {
+        card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+      } else if (!card.setting.supModule) {
+        card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+      }
+  
+      let supModule = card.setting.supModule ? card.setting.supModule[card.setting.supModule.length - 1] || '' : ''
+      if (supModule === 'empty') {
+        supModule = ''
+      }
+      let columns = card.columns.map(c => c.field)
+      let lowcols = card.columns.map(c => c.field.toLowerCase())
+  
+      card.subcards.forEach(col => {
+        col.elements.forEach(cell => {
+          if (cell.eleType === 'button') {
+            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+              if (!cell.modal || cell.modal.fields.length === 0) {
+                card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+              } else {
+                cell.modal.fields.forEach(m => {
+                  if (m.type === 'linkMain' && !supModule) {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑鍏宠仈涓昏〃琛ㄥ崟鈥�${m.label}鈥濇棤鏁坄})
+                  } else if (m.field && !columns.includes(m.field) && lowcols.includes(m.field.toLowerCase())) {
+                    card.errors.push({ level: 1, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟鈥�${m.label}鈥濆ぇ灏忓啓涓庡瓧娈甸泦涓嶄竴鑷碻})
+                  }
+                })
+              }
+            }
+          } else if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+            card.errors.push({ level: 1, detail: `鍗$墖涓姩鎬佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+          }
+        })
+      })
+    }
+    
     this.setState({
-      card: component
+      card: card
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
-
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   updateCard = (cell) => {
@@ -133,9 +173,7 @@
       return item
     })
 
-    this.setState({card})
-
-    this.props.updateConfig(card)
+    this.updateComponent(card)
   }
 
   changeStyle = () => {
@@ -150,12 +188,8 @@
     if (comIds.length !== 1 || comIds[0] !== card.uuid) return
 
     let _card = {...card, style}
-
-    this.setState({
-      card: _card
-    })
     
-    this.props.updateConfig(_card)
+    this.updateComponent(_card)
   }
 
   getWrapForms = () => {
@@ -166,6 +200,12 @@
 
   updateWrap = (res) => {
     delete res.quick
+
+    if (res.hmode) {
+      res.mode = res.hmode
+      delete res.hmode
+    }
+    
     this.updateComponent({...this.state.card, wrap: res})
   }
 
@@ -192,7 +232,20 @@
         </Popover>
         <NormalHeader hideSearch="true" config={card} updateComponent={this.updateComponent}/>
         {card.subcards.map(subcard => (<CardSimpleComponent key={subcard.uuid} cards={card} card={subcard} updateElement={this.updateCard}/>))}
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/components/timeline/normal-timeline/options.jsx b/src/menu/components/timeline/normal-timeline/options.jsx
index 61cc83d..fac7a50 100644
--- a/src/menu/components/timeline/normal-timeline/options.jsx
+++ b/src/menu/components/timeline/normal-timeline/options.jsx
@@ -44,9 +44,25 @@
     },
     {
       type: 'radio',
+      field: 'direction',
+      label: '杞寸嚎鏂瑰悜',
+      initval: wrap.direction || 'vertical',
+      required: false,
+      options: [
+        {value: 'vertical', label: '绾靛悜'},
+        {value: 'horizontal', label: '妯悜'},
+      ],
+      controlFields: [
+        {field: 'mode', values: ['vertical']},
+        {field: 'hmode', values: ['horizontal']},
+        {field: 'label', values: ['vertical']},
+      ]
+    },
+    {
+      type: 'radio',
       field: 'mode',
       label: '杞寸嚎浣嶇疆',
-      initval: wrap.mode || 'left',
+      initval: ['left', 'alternate', 'right'].includes(wrap.mode) ? wrap.mode : 'left',
       required: false,
       options: [
         {value: 'left', label: '宸︿晶'},
@@ -56,15 +72,26 @@
     },
     {
       type: 'radio',
-      field: 'reverse',
-      label: '鎺掑簭',
-      initval: wrap.reverse || 'false',
+      field: 'hmode',
+      label: '杞寸嚎浣嶇疆',
+      initval: ['up', 'down'].includes(wrap.mode) ? wrap.mode : 'up',
       required: false,
       options: [
-        {value: 'false', label: '姝e簭'},
-        {value: 'true', label: '鍊掑簭'},
+        {value: 'up', label: '涓婁晶'},
+        {value: 'down', label: '涓嬩晶'}
       ]
     },
+    // {
+    //   type: 'radio',
+    //   field: 'reverse',
+    //   label: '鎺掑簭',
+    //   initval: wrap.reverse || 'false',
+    //   required: false,
+    //   options: [
+    //     {value: 'false', label: '姝e簭'},
+    //     {value: 'true', label: '鍊掑簭'},
+    //   ]
+    // },
     {
       type: 'color',
       field: 'color',
diff --git a/src/menu/components/tree/antd-tree/index.jsx b/src/menu/components/tree/antd-tree/index.jsx
index c4d5801..50d2364 100644
--- a/src/menu/components/tree/antd-tree/index.jsx
+++ b/src/menu/components/tree/antd-tree/index.jsx
@@ -70,10 +70,7 @@
         _card.scripts = config.scripts
       }
       
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+      this.updateComponent(_card)
     } else {
       this.setState({
         card: fromJS(card).toJS()
@@ -102,15 +99,31 @@
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+
+    card.errors = []
+
+    if (card.setting.interType === 'system' && card.setting.execute !== 'false' && !card.setting.dataresource) {
+      card.errors.push({ level: 0, detail: '鏈缃暟鎹簮锛�'})
+    } else if (card.setting.interType === 'system' && card.setting.execute === 'false' && card.scripts.filter(script => script.status !== 'false').length === 0) {
+      card.errors.push({ level: 0, detail: '鏁版嵁婧愪腑鏃犲彲鐢ㄨ剼鏈紒'})
+    } else if (!card.setting.primaryKey) {
+      card.errors.push({ level: 0, detail: '鏈缃富閿紒'})
+    } else if (!card.setting.supModule) {
+      card.errors.push({ level: 0, detail: '鏈缃笂绾х粍浠讹紒'})
+    }
+
+    if (!card.wrap.parentField || !card.wrap.valueField || !card.wrap.labelField) {
+      card.errors.push({ level: 0, detail: '鏈缃熀鏈俊鎭紒'})
+    }
+
     this.setState({
-      card: component
+      card: card
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
-
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   changeStyle = () => {
@@ -126,21 +139,7 @@
 
     let _card = {...card, style}
 
-    this.setState({
-      card: _card
-    })
-    
-    this.props.updateConfig(_card)
-  }
-
-  /**
-   * @description 鏇存柊鎼滅储鏉′欢閰嶇疆淇℃伅
-   */
-  updateconfig = (config) => {
-    this.setState({
-      card: config
-    })
-    this.props.updateConfig(config)
+    this.updateComponent(_card)
   }
 
   getWrapForms = () => {
@@ -194,7 +193,20 @@
             </TreeNode>
           </Tree>
         </div>
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
diff --git a/src/menu/datasource/index.jsx b/src/menu/datasource/index.jsx
index f405cf1..fe889ab 100644
--- a/src/menu/datasource/index.jsx
+++ b/src/menu/datasource/index.jsx
@@ -7,6 +7,7 @@
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
 import VerifyCard from './verifycard'
+import MKEmitter from '@/utils/events.js'
 import './index.scss'
 
 class DataSource extends Component {
@@ -137,6 +138,8 @@
       visible: true,
       mainSearch: search
     })
+
+    MKEmitter.emit('modalStatus', '鏁版嵁婧�')
   }
 
   verifySubmit = () => {
@@ -188,6 +191,8 @@
 
       this.setState({loading: false, visible: false})
       this.props.updateConfig({...config, ...res})
+
+      MKEmitter.emit('modalStatus', false)
     }, () => {
       this.setState({loading: false})
     })
@@ -202,14 +207,14 @@
         <SettingOutlined title="鏁版嵁婧�" onClick={() => this.editDataSource()} />
         <Modal
           wrapClassName="popview-modal"
-          title={'鏁版嵁婧愰厤缃�'}
+          title="鏁版嵁婧愰厤缃�"
           visible={visible}
           width={'75vw'}
           maskClosable={false}
           okText={dict['model.submit']}
           onOk={this.verifySubmit}
           confirmLoading={loading}
-          onCancel={() => { this.setState({ visible: false }) }}
+          onCancel={() => { MKEmitter.emit('modalStatus', false);this.setState({ visible: false }) }}
           destroyOnClose
         >
           <VerifyCard
diff --git a/src/menu/datasource/verifycard/columnform/index.jsx b/src/menu/datasource/verifycard/columnform/index.jsx
index 9e2108d..2606571 100644
--- a/src/menu/datasource/verifycard/columnform/index.jsx
+++ b/src/menu/datasource/verifycard/columnform/index.jsx
@@ -16,10 +16,11 @@
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     this.props.form.validateFieldsAndScroll((err, values) => {
       if (!err) {
-        this.props.columnChange(values)
-        this.props.form.setFieldsValue({
-          label: '',
-          field: ''
+        this.props.columnChange(values, () => {
+          this.props.form.setFieldsValue({
+            label: '',
+            field: ''
+          })
         })
       }
     })
diff --git a/src/menu/datasource/verifycard/customscript/index.jsx b/src/menu/datasource/verifycard/customscript/index.jsx
index 2b009a3..ac493e7 100644
--- a/src/menu/datasource/verifycard/customscript/index.jsx
+++ b/src/menu/datasource/verifycard/customscript/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Form, Row, Col, Button, notification, Select } from 'antd'
+import { Form, Row, Col, Button, notification, Select, Tooltip } from 'antd'
 
 import Utils from '@/utils/utils.js'
 import CodeMirror from '@/templates/zshare/codemirror'
@@ -169,7 +169,9 @@
 
   selectScript = (value, option) => {
     let _sql = this.props.form.getFieldValue('sql')
-    if (_sql) {
+    if (_sql === ' ') {
+      _sql = ''
+    } else if (_sql) {
       _sql = _sql + ` 
 
       `
@@ -205,6 +207,8 @@
       }
     }
 
+    let urlFields = window.GLOB.urlFields ? window.GLOB.urlFields.join(', ') : ''
+
     return (
       <Form {...formItemLayout} className="modal-menu-setting-script">
         <Row gutter={24}>
@@ -220,7 +224,10 @@
           </Col>
           <Col span={24} className="sqlfield">
             <Form.Item label={'鍙敤瀛楁'}>
-              id, bid, loginuid, sessionuid, userid, username, fullname, RoleID, mk_departmentcode, mk_organization, login_city, appkey, time_id, orderBy, pageSize, pageIndex{usefulFields ? ', ' + usefulFields : ''}{window.GLOB.urlFields && window.GLOB.urlFields.length > 0 ? ', ' + window.GLOB.urlFields.join(', ') : ''}
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鎺掑簭銆佸垎椤典互鍙婃悳绱㈡潯浠跺彉閲忥紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}>orderBy, pageSize, pageIndex{usefulFields ? ', ' + usefulFields : ''}</Tooltip>
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'url鍙橀噺锛岃鎸夌収@xxx@鏍煎紡浣跨敤銆�'}>{urlFields ? ', ' : ''}<span style={{color: '#13c2c2'}}>{urlFields}</span></Tooltip>
             </Form.Item>
           </Col>
           <Col span={10} style={{width: '43%'}}>
diff --git a/src/menu/datasource/verifycard/index.jsx b/src/menu/datasource/verifycard/index.jsx
index 51338af..26d4e9d 100644
--- a/src/menu/datasource/verifycard/index.jsx
+++ b/src/menu/datasource/verifycard/index.jsx
@@ -1,8 +1,8 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
-import { Form, Tabs, Popconfirm, notification, Modal, Typography, Spin, message } from 'antd'
-import { StopOutlined, CheckCircleOutlined, EditOutlined, SwapOutlined, DeleteOutlined, CopyOutlined } from '@ant-design/icons'
+import { Form, Tabs, Popconfirm, notification, Modal, Typography, Spin, message, Button } from 'antd'
+import { StopOutlined, CheckCircleOutlined, EditOutlined, SwapOutlined, DeleteOutlined, CopyOutlined, BorderOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import Api from '@/api'
@@ -13,11 +13,13 @@
 import CustomScriptsForm from './customscript'
 import SettingForm from './settingform'
 import SettingUtils from './utils'
+import MinView from '@/assets/img/minview.png'
 import './index.scss'
 
 const { TabPane } = Tabs
 const { Paragraph } = Typography
 
+const CodeMirror = asyncComponent(() => import('@/templates/zshare/codemirror'))
 const FieldsComponent = asyncComponent(() => import('@/templates/sharecomponent/fieldscomponent'))
 const EditTable = asyncComponent(() => import('@/templates/zshare/editTable'))
 
@@ -36,6 +38,9 @@
     defaultsql: '',       // 榛樿Sql
     defaultSearch: '',
     systemScripts: [],
+    visible: false,
+    script: null,
+    scriptValue: '',
     colColumns: [
       {
         title: '鍚嶇О',
@@ -122,7 +127,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div style={{color: '#ff4d4f'}}>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopOutlined style={{marginLeft: '5px'}} />
             </div>
           ) :
@@ -238,7 +243,7 @@
     })
   }
 
-  columnChange = (values) => {
+  columnChange = (values, resolve) => {
     const { columns } = this.state
 
     let fields = columns.map(item => item.field.toLowerCase())
@@ -251,13 +256,21 @@
       return
     }
 
+    resolve()
+
     values.uuid = Utils.getuuid()
 
     this.setState({ columns: [...columns, values] })
   }
 
   deleteScript = (record) => {
-    this.setState({ scripts: this.state.scripts.filter(item => item.uuid !== record.uuid) })
+    const { script, scripts } = this.state
+
+    if (script && script.uuid === record.uuid) {
+      this.setState({script: null})
+    }
+    
+    this.setState({ scripts: scripts.filter(item => item.uuid !== record.uuid) })
   }
 
   handleEdit = (record) => {
@@ -572,7 +585,8 @@
     }
 
     if ((setting.interType === 'system' && setting.execute !== 'false') || _scripts.length > 0) {
-      let r = SettingUtils.getDebugSql(setting, _scripts, columns, searches, defaultSearch)
+      let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+      let r = SettingUtils.getDebugSql(setting, _scripts, columns, searches, defaultSearch, timestamp)
 
       if (r.error) {
         notification.warning({
@@ -590,8 +604,8 @@
         LText: r.sql
       }
       param.LText = Utils.formatOptions(param.LText)
-      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-      param.secretkey = Utils.encrypt('', param.timestamp)
+      param.timestamp = timestamp
+      param.secretkey = Utils.encrypt('', timestamp)
 
       let sumParam = null
       if (r.sumSql) {
@@ -633,6 +647,42 @@
     }
   }
 
+  triggerConfirm = () => {
+    const { script, scriptValue, scripts } = this.state
+    let _scripts = fromJS(scripts).toJS()
+
+    if (!scriptValue) {
+      notification.warning({
+        top: 92,
+        message: '璇疯緭鍏ql!',
+        duration: 5
+      })
+      return
+    }
+
+    if (script) {
+      _scripts = _scripts.map(item => {
+        if (script.uuid === item.uuid) {
+          item.sql = scriptValue
+        }
+        return item
+      })
+    } else {
+      let _script = {
+        uuid: Utils.getuuid(),
+        sql: scriptValue,
+        $index: _scripts.length + 1,
+        status: 'true'
+      }
+
+      _scripts.push(_script)
+    }
+
+    this.setState({loading: true})
+
+    this.sqlverify(() => {this.setState({scripts: _scripts, script: null, scriptValue: '', loading: false})}, () => {this.setState({loading: false})}, false, _scripts)
+  }
+
   updatefields = (columns) => {
     this.setState({
       columns: columns
@@ -671,7 +721,7 @@
 
   render() {
     const { config } = this.props
-    const { columns, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches, defaultsql } = this.state
+    const { columns, setting, scripts, colColumns, scriptsColumns, activeKey, loading, searches, defaultsql, visible, script, scriptValue } = this.state
 
     return (
       <div id="model-data-source-wrap">
@@ -703,6 +753,17 @@
               {scripts.length ? <span className="count-tip">{scripts.length}</span> : null}
             </span>
           } key="scripts">
+            <BorderOutlined className="full-scripts" onClick={() => {
+              if (this.scriptsForm && (this.scriptsForm.state.editItem || (this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))))) {
+                notification.warning({
+                  top: 92,
+                  message: '璇蜂繚瀛樿嚜瀹氫箟鑴氭湰锛�',
+                  duration: 5
+                })
+                return
+              }
+              this.setState({visible: true, script: null, scriptValue: ''})
+            }}/>
             <CustomScriptsForm
               setting={setting}
               searches={searches}
@@ -718,6 +779,63 @@
             <EditTable actions={['move']} data={scripts} columns={scriptsColumns} onChange={this.changeScripts}/>
           </TabPane>
         </Tabs>
+        <Modal
+          wrapClassName="model-custom-view-scripts-modal"
+          title="鑷畾涔夎剼鏈�"
+          visible={visible}
+          width={'95vw'}
+          maskClosable={false}
+          destroyOnClose
+        >
+          <img className="unfull-scripts" src={MinView} onClick={() => this.setState({visible: false, script: null})} alt=""/>
+          <div className="script-table-wrap">
+            {scripts.map(item => {
+              let title = item.sql.match(/^\s*\/\*.+\*\//)
+              title = title && title[0] ? title[0] : ''
+              let _text = title ? item.sql.replace(title, '') : item.sql
+
+              return (
+                <div className={'script-item ' + (script && script.uuid === item.uuid ? 'active' : '') } key={item.uuid}>
+                  <div style={{cursor: 'pointer'}} onClick={() => {
+                    this.setState({script: item, scriptValue: item.sql})
+                  }}>
+                    {title ? <div style={{color: '#a50', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>{title}</div> : null}
+                    <Paragraph copyable={{ text: item.sql }} ellipsis={{ rows: 4 }}>{_text}</Paragraph>
+                    <div>{item.status === 'false' ?
+                      <span style={{color: '#ff4d4f', marginLeft: '20px'}}>
+                        绂佺敤
+                        <StopOutlined style={{marginLeft: '5px'}} />
+                      </span> : 
+                      <span style={{color: '#26C281', marginLeft: '20px'}}>
+                        鍚敤
+                        <CheckCircleOutlined style={{marginLeft: '5px'}}/>
+                      </span>}
+                    </div>
+                  </div>
+                  <div style={{textAlign: 'right'}}>
+                    <span className="operation-btn" onClick={() => this.handleStatus(item)} style={{color: '#8E44AD'}}><SwapOutlined /></span>
+                    <Popconfirm
+                      overlayClassName="popover-confirm"
+                      title={this.props.dict['model.query.delete']}
+                      onConfirm={() => this.deleteScript(item)
+                    }>
+                      <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span>
+                    </Popconfirm>
+                  </div>
+                </div>
+              )
+            })}
+          </div>
+          <div className="script-button">
+            <Button onClick={this.triggerConfirm} loading={this.state.loading} className="mk-green" style={{marginBottom: 15, marginLeft: 40}}>
+              {script ? '淇濆瓨' : '娣诲姞'}
+            </Button>
+            <Button onClick={() => {this.setState({script: null, scriptValue: ''})}} style={{marginBottom: 15, marginLeft: 10}}>
+              鍙栨秷
+            </Button>
+          </div>
+          <CodeMirror value={scriptValue} onChange={(val) => {this.setState({scriptValue: val})}}></CodeMirror>
+        </Modal>
       </div>
     )
   }
diff --git a/src/menu/datasource/verifycard/index.scss b/src/menu/datasource/verifycard/index.scss
index bef6747..adf5445 100644
--- a/src/menu/datasource/verifycard/index.scss
+++ b/src/menu/datasource/verifycard/index.scss
@@ -81,4 +81,107 @@
       cursor: pointer;
     }
   }
+  .full-scripts {
+    position: absolute;
+    right: 0px;
+    top: -40px;
+    font-size: 18px;
+    color: #1890ff;
+  }
+}
+.model-custom-view-scripts-modal {
+  .ant-modal {
+    top: 30px;
+    .ant-modal-header {
+      padding: 10px 24px;
+    }
+    .ant-modal-footer {
+      display: none;
+    }
+    .ant-modal-close {
+      display: none;
+    }
+    .ant-modal-body {
+      padding: 0;
+      height: calc(100vh - 100px);
+      overflow: hidden;
+      display: flex;
+
+      .script-table-wrap {
+        width: 240px;
+        overflow-y: auto;
+        overflow-x: hidden;
+        height: calc(100vh - 100px);
+
+        .operation-btn {
+          display: inline-block;
+          font-size: 16px;
+          padding: 0 5px;
+          cursor: pointer;
+          margin-left: 5px;
+        }
+
+        .script-item {
+          border-bottom: 1px solid #eeeeee;
+          padding: 15px 10px 5px;
+        }
+        .script-item.active {
+          background-color: #bae7ff;
+        }
+        .ant-typography {
+          margin-bottom: 5px;
+        }
+      }
+
+      .script-table-wrap::-webkit-scrollbar {
+        width: 7px;
+      }
+      .script-table-wrap::-webkit-scrollbar-thumb {
+        border-radius: 5px;
+        box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+        background: rgba(0, 0, 0, 0.13);
+      }
+      .script-table-wrap::-webkit-scrollbar-track {
+        box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
+        border-radius: 3px;
+        border: 1px solid rgba(0, 0, 0, 0.07);
+        background: rgba(0, 0, 0, 0);
+      }
+
+      .unfull-scripts {
+        position: absolute;
+        right: 20px;
+        z-index: 2;
+        top: 10px;
+        color: #1890ff;
+        width: 26px;
+        cursor: pointer;
+        padding: 5px;
+      }
+
+      .script-button {
+        position: absolute;
+        top: 10px;
+        z-index: 1;
+        left: 240px;
+        .ant-btn {
+          height: 28px;
+        }
+        .mk-green {
+          margin-left: 0!important;
+          margin-right: 10px;
+        }
+      }
+      .code-mirror-wrap {
+        .CodeMirror {
+          height: calc(100vh - 100px);
+          border-radius: 0;
+        }
+        .code-mirror-area {
+          border-radius: 0;
+          width: calc(95vw - 240px);
+        }
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/menu/datasource/verifycard/utils.jsx b/src/menu/datasource/verifycard/utils.jsx
index 933ff02..7dc431d 100644
--- a/src/menu/datasource/verifycard/utils.jsx
+++ b/src/menu/datasource/verifycard/utils.jsx
@@ -7,7 +7,7 @@
    * @return {Object}  setting       椤甸潰璁剧疆
    * @return {Array}   columns       鏄剧ず瀛楁
    */
-  static getDebugSql (setting, scripts, columns, searches = [], defSearch) {
+  static getDebugSql (setting, scripts, columns, searches = [], defSearch, timestamp) {
     let sql = ''
     let error = ''
     let _dataresource = ''
@@ -40,6 +40,9 @@
     //   error = '绯荤粺鍑芥暟' + _customScript.match(/\$ex@.{1,50}@ex\$/g)[0].replace(/\$ex@|@ex\$/g, '') + '鏈畾涔�'
     // }
 
+    _dataresource = _dataresource.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${timestamp}'`)
+    _customScript = _customScript.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${timestamp}'`)
+
     _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
     _customScript = _customScript.replace(/@\$|\$@/ig, '')
     _dataresource = _dataresource.replace(/@select\$|\$select@/ig, '')
@@ -51,7 +54,7 @@
     _dataresource = _dataresource.replace(/@sum\$/ig, '@sum$*/')
 
     if (_customScript) {
-      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
         ${_customScript}
       `
     }
@@ -65,8 +68,8 @@
     if (window.GLOB.urlFields) {
       window.GLOB.urlFields.forEach(field => {
         let reg = new RegExp('@' + field + '@', 'ig')
-        _dataresource = _dataresource.replace(reg, '0')
-        _customScript = _customScript.replace(reg, '0')
+        _dataresource = _dataresource.replace(reg, `'0'`)
+        _customScript = _customScript.replace(reg, `'0'`)
       })
     }
 
@@ -137,8 +140,6 @@
 
     if (_customScript) {
       _regoptions.push({
-        reg: new RegExp('@login_city@', 'ig'),
-      }, {
         reg: new RegExp('@orderBy@', 'ig'),
       }, {
         reg: new RegExp('@UserName@', 'ig'),
@@ -173,7 +174,7 @@
         `
       } else {
         sumSql = `/* sql sum楠岃瘉 */
-          declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+          declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
           ${_sql}`
       }
     }
@@ -201,7 +202,7 @@
       `
     } else {
       sql = `/* sql 楠岃瘉 */
-        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
         ${_dataresource}`
     }
     sql = sql.replace(/\n\s{8}/ig, '\n')
diff --git a/src/menu/menushell/card.jsx b/src/menu/menushell/card.jsx
index 2331154..1450e45 100644
--- a/src/menu/menushell/card.jsx
+++ b/src/menu/menushell/card.jsx
@@ -19,7 +19,8 @@
 const TableCard = asyncComponent(() => import('@/menu/components/card/table-card'))
 const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table'))
 const EditTable = asyncComponent(() => import('@/menu/components/table/edit-table'))
-const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form'))
+const SimpleForm = asyncComponent(() => import('@/menu/components/form/simple-form'))
+const StepForm = asyncComponent(() => import('@/menu/components/form/step-form'))
 const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form'))
 const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group'))
 const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor'))
@@ -78,8 +79,10 @@
       return (<NormalTree card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'scatter') {
       return (<AntvScatter card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'form' && card.subtype === 'simpleform') {
+      return (<SimpleForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'form' && card.subtype === 'stepform') {
-      return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+      return (<StepForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'form' && card.subtype === 'tabform') {
       return (<TabForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'tabs') {
diff --git a/src/menu/modalconfig/index.jsx b/src/menu/modalconfig/index.jsx
index aba31bb..89d315a 100644
--- a/src/menu/modalconfig/index.jsx
+++ b/src/menu/modalconfig/index.jsx
@@ -278,10 +278,10 @@
           LText: res.dataSource
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
         
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
 
         if (window.GLOB.mainSystemApi && res.database === 'sso') {
diff --git a/src/menu/modalconfig/index.scss b/src/menu/modalconfig/index.scss
index 556a72a..814f0fc 100644
--- a/src/menu/modalconfig/index.scss
+++ b/src/menu/modalconfig/index.scss
@@ -134,6 +134,8 @@
           .ant-form-item-label {
             width: 100%!important;
             text-align: left;
+            height: 24px;
+            line-height: 28px;
           }
           .ant-form-item-control-wrapper {
             width: 100%!important;
@@ -212,7 +214,6 @@
           position: relative;
           background: #ffffff;
           border-radius: 2px;
-          margin-bottom: 15px;
           .ant-form-item {
             cursor: move;
             display: flex;
diff --git a/src/menu/modulesource/option.jsx b/src/menu/modulesource/option.jsx
index 8368f81..a0768d5 100644
--- a/src/menu/modulesource/option.jsx
+++ b/src/menu/modulesource/option.jsx
@@ -18,6 +18,7 @@
 import Carousel from '@/assets/mobimg/carousel.png'
 import Carousel1 from '@/assets/mobimg/carousel1.png'
 import form from '@/assets/mobimg/form.png'
+import simpleform from '@/assets/mobimg/simple-form.png'
 import tabForm from '@/assets/mobimg/tab-form.png'
 import dashboard from '@/assets/mobimg/dashboard.png'
 import ratioboard from '@/assets/mobimg/ratioboard.png'
@@ -34,6 +35,7 @@
   { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '鏁版嵁鍗�', width: 24 },
   { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '灞炴�у崱', width: 24 },
   { type: 'menu', url: card2, component: 'balcony', subtype: 'balcony', title: '娴姩鍗�', width: 24},
+  { type: 'menu', url: simpleform, component: 'form', subtype: 'simpleform', title: '琛ㄥ崟', width: 24, forbid: ['billPrint'] },
   { type: 'menu', url: form, component: 'form', subtype: 'stepform', title: '琛ㄥ崟锛堝垎姝ワ級', width: 24, forbid: ['billPrint'] },
   { type: 'menu', url: tabForm, component: 'form', subtype: 'tabform', title: '琛ㄥ崟锛坱ab椤碉級', width: 24, forbid: ['billPrint'] },
   { type: 'menu', url: Carousel, component: 'carousel', subtype: 'datacard', title: '杞挱-鍔ㄦ�佹暟鎹�', width: 24, forbid: ['billPrint'] },
diff --git a/src/menu/pastecontroller/index.jsx b/src/menu/pastecontroller/index.jsx
index 8ed2307..074d4f1 100644
--- a/src/menu/pastecontroller/index.jsx
+++ b/src/menu/pastecontroller/index.jsx
@@ -66,7 +66,7 @@
   }
 
   pasteSubmit = () => {
-    let options = ['tabs', 'menubar', 'topbar', 'timeline', 'datacard', 'propcard', 'mainsearch', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter']
+    let options = ['tabs', 'menubar', 'topbar', 'timeline', 'datacard', 'propcard', 'mainsearch', 'simpleform', 'stepform', 'tabform', 'balcony', 'group', 'normaltable', 'tablecard', 'line', 'bar', 'pie', 'dashboard', 'scatter']
 
     this.pasteFormRef.handleConfirm().then(res => {
       if ((res.copyType === 'menubar' || res.copyType === 'topbar') && sessionStorage.getItem('appType') !== 'mob') {
diff --git a/src/menu/popview/index.jsx b/src/menu/popview/index.jsx
index ff72ac6..8b4293f 100644
--- a/src/menu/popview/index.jsx
+++ b/src/menu/popview/index.jsx
@@ -560,32 +560,14 @@
         } else if (item.type === 'group') {
           check(item.components)
           return
+        } else if (!item.errors || item.errors.length === 0) {
+          return
         }
-        if (['propcard', 'brafteditor', 'sandbox', 'stepform', 'tabform'].includes(item.subtype) && item.wrap.datatype === 'static') return
-        if (['balcony'].includes(item.type) && item.wrap.datatype === 'static') return
-  
-        if (item.setting) {
-          if (item.setting.interType === 'system' && item.setting.execute !== 'false' && !item.setting.dataresource) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆鏁版嵁婧愶紒`
-          } else if (item.setting.interType === 'system' && item.setting.execute === 'false' && item.scripts.length === 0) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆鏁版嵁婧愶紒`
-          } else if (!item.setting.primaryKey) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆涓婚敭锛乣
-          } else if (!item.setting.supModule && item.type !== 'balcony') {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆涓婄骇缁勪欢锛乣
-          }
-        }
-        if (item.type === 'bar' || item.type === 'line' || item.type === 'pie') {
-          if (!item.plot.Xaxis) {
-            error = `缁勪欢銆�${item.name}銆嬪浘琛ㄥ瓧娈靛皻鏈缃紒`
-          }
-        } else if (item.type === 'dashboard' && !item.plot.valueField) {
-          error = `缁勪欢銆�${item.name}銆嬫樉绀哄�煎皻鏈缃紒`
-        } else if (item.type === 'scatter' && (!item.plot.Xaxis || !item.plot.Yaxis || !item.plot.gender)) {
-          error = `缁勪欢銆�${item.name}銆嬪潗鏍囪酱灏氭湭璁剧疆锛乣
-        } else if (item.type === 'tree' && (!item.wrap.valueField || !item.wrap.labelField || !item.wrap.parentField)) {
-          error = `缁勪欢銆�${item.name}銆嬪熀鏈俊鎭皻鏈缃紒`
-        }
+        
+        item.errors.forEach(err => {
+          if (err.level !== 0 || error) return
+          error = `缁勪欢銆�${item.name}銆�${err.detail}`
+        })
       })
     }
 
diff --git a/src/menu/stylecontroller/index.jsx b/src/menu/stylecontroller/index.jsx
index 4c50043..a98c24b 100644
--- a/src/menu/stylecontroller/index.jsx
+++ b/src/menu/stylecontroller/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Collapse, Form, Col, InputNumber, Select, Radio, Drawer, Button } from 'antd'
+import { Collapse, Form, Col, InputNumber, Input, Select, Radio, Drawer, Button } from 'antd'
 import {
   ColumnHeightOutlined,
   FontSizeOutlined,
@@ -29,6 +29,7 @@
   ArrowLeftOutlined,
   ArrowRightOutlined,
   SwapOutlined,
+  EnterOutlined,
 } from '@ant-design/icons'
 
 import MKEmitter from '@/utils/events.js'
@@ -49,6 +50,7 @@
 
   state = {
     card: null,
+    fonts: null,
     comIds: [],
     backgroundImage: '',
     options: [],
@@ -78,15 +80,31 @@
     if (style.backgroundImage && /^url/ig.test(style.backgroundImage)) {
       backgroundImage = style.backgroundImage.replace(/^url\(/ig, '').replace(/\)$/ig, '')
     }
+    let fonts = null
+    if (options.includes('font')) {
+      fonts = ['fontSize', 'fontWeight', 'lineHeight', 'letterSpacing', 'color', 'fontStyle', 'textAlign', 'textDecoration']
+    } else if (options.includes('font1')) {
+      fonts = ['fontSize', 'fontWeight', 'color']
+      if (options[0] === 'font1') {
+        options[0] = 'font'
+      }
+    } else if (options.includes('font2')) {
+      fonts = ['fontSize', 'fontWeight', 'lineHeight', 'letterSpacing', 'color', 'fontStyle', 'textAlign', 'textDecoration', 'textIndent', 'wordBreak']
+      if (options[0] === 'font2') {
+        options[0] = 'font'
+      }
+    }
 
     this.setState({
       visible: true,
+      fonts: fonts,
       comIds: comIds,
       card: fromJS(style).toJS(),
       options: options,
       borposition: 'outer',
       backgroundImage
     })
+    window.GLOB.styling = true
   }
 
   onCloseDrawer = () => {
@@ -126,6 +144,7 @@
       options: [],
       backgroundImage: ''
     })
+    window.GLOB.styling = false
   }
 
   updateStyle = (style) => {
@@ -183,10 +202,28 @@
   }
 
   /**
+   * @description 棣栬缂╄繘
+   */
+  changeTextIndent = (val) => {
+    let value = parseFloat(val)
+
+    if (isNaN(value) || value < 0 || value > 100) return
+
+    this.updateStyle({textIndent: `${value}px`})
+  }
+
+  /**
    * @description 淇敼瀛椾綋绮楃粏
    */
   boldChange = (val) => {
     this.updateStyle({fontWeight: val})
+  }
+
+  /**
+   * @description 鑷姩鎹㈣
+   */
+  wordBreakChange = (val) => {
+    this.updateStyle({wordBreak: val})
   }
 
   /**
@@ -222,6 +259,29 @@
    */
   changeBackgroundColor = (val) => {
     this.updateStyle({backgroundColor: val})
+  }
+
+  changeBackground = (val) => {
+    const { comIds, card } = this.state
+
+    let _style = { ...card }
+
+    _style.background = val
+
+    delete _style.backgroundColor
+    delete _style.backgroundImage
+
+    if (!val) {
+      delete _style.background
+    }
+
+    this.setState({
+      card: _style,
+    })
+
+    if (!val || /(^linear-gradient|^radial-gradient)\(.*\)$/.test(val)) {
+      MKEmitter.emit('submitStyle', comIds, _style)
+    }
   }
 
   /**
@@ -380,7 +440,7 @@
   }
 
   render () {
-    const { card, options, backgroundImage, borposition } = this.state
+    const { card, options, backgroundImage, borposition, fonts } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -433,13 +493,13 @@
                   </Form.Item>
                 </Col>
               </Panel> : null}
-              {options.includes('font') ? <Panel header="瀛椾綋" key="font">
-                <Col span={12}>
+              {fonts ? <Panel header="瀛椾綋" key="font">
+                {fonts.includes('fontSize') ? <Col span={12}>
                   <Form.Item colon={false} label={<FontSizeOutlined title="瀛椾綋澶у皬"/>}>
                     <InputNumber defaultValue={card.fontSize || 14} min={12} max={300} precision={0} onChange={this.changeFontSize} />
                   </Form.Item>
-                </Col>
-                <Col span={12}>
+                </Col> : null}
+                {fonts.includes('fontWeight') ? <Col span={12}>
                   <Form.Item colon={false} label={<BoldOutlined title="瀛椾綋绮楃粏"/>}>
                     <Select defaultValue={card.fontWeight || 'normal'} onChange={this.boldChange}>
                       <Option value="normal">normal</Option>
@@ -457,18 +517,31 @@
                       <Option value="900">900</Option>
                     </Select>
                   </Form.Item>
-                </Col>
-                <Col span={12}>
+                </Col> : null}
+                {fonts.includes('lineHeight') ? <Col span={12}>
                   <Form.Item colon={false} label={<LineHeightOutlined title="琛岄珮"/>}>
                     <InputNumber defaultValue={card.lineHeight || 1.5} min={1} max={10} precision={1} onChange={this.changeLineHeight} />
                   </Form.Item>
-                </Col>
-                <Col span={12}>
+                </Col> : null}
+                {fonts.includes('letterSpacing') ? <Col span={12}>
                   <Form.Item colon={false} label={<ColumnWidthOutlined title="瀛楅棿璺�"/>}>
                     <InputNumber defaultValue={card.letterSpacing || 0} min={0} max={100} precision={0} onChange={this.changeLetterSpacing}/>
                   </Form.Item>
-                </Col>
-                <Col span={24}>
+                </Col> : null}
+                {fonts.includes('textIndent') ? <Col span={12}>
+                  <Form.Item colon={false} label={<AlignRightOutlined title="棣栬缂╄繘"/>}>
+                    <InputNumber defaultValue={card.textIndent || 0} min={0} max={100} precision={0} onChange={this.changeTextIndent}/>
+                  </Form.Item>
+                </Col> : null}
+                {fonts.includes('wordBreak') ? <Col span={12}>
+                  <Form.Item colon={false} label={<EnterOutlined title="鑷姩鎹㈣"/>}>
+                    <Select defaultValue={card.wordBreak || 'normal'} onChange={this.wordBreakChange}>
+                      <Option value="normal">normal</Option>
+                      <Option value="break-all">break-all</Option>
+                    </Select>
+                  </Form.Item>
+                </Col> : null}
+                {fonts.includes('color') ? <Col span={24}>
                   <Form.Item
                     colon={false}
                     label={<FontColorsOutlined title="瀛椾綋棰滆壊"/>}
@@ -476,8 +549,8 @@
                   >
                     <ColorSketch value={card.color || 'rgba(0, 0, 0, 0.85)'} onChange={this.changeFontColor} />
                   </Form.Item>
-                </Col>
-                <Col span={24}>
+                </Col> : null}
+                {fonts.includes('fontStyle') ? <Col span={24}>
                   <Form.Item
                     colon={false}
                     label={' '}
@@ -489,8 +562,8 @@
                       <Radio.Button value="oblique" style={{fontStyle: 'oblique'}}><span title="鍊炬枩">B</span></Radio.Button>
                     </Radio.Group>
                   </Form.Item>
-                </Col>
-                <Col span={24}>
+                </Col> : null}
+                {fonts.includes('textAlign') ? <Col span={24}>
                   <Form.Item
                     colon={false}
                     label={' '}
@@ -502,8 +575,8 @@
                       <Radio.Button value="right"><AlignRightOutlined title="鍙冲榻�"/></Radio.Button>
                     </Radio.Group>
                   </Form.Item>
-                </Col>
-                <Col span={24}>
+                </Col> : null}
+                {fonts.includes('textDecoration') ? <Col span={24}>
                   <Form.Item
                     colon={false}
                     label={' '}
@@ -516,42 +589,7 @@
                       <Radio.Button value="overline" style={{textDecoration: 'overline'}}><span title="涓婂垝绾�">O</span></Radio.Button>
                     </Radio.Group>
                   </Form.Item>
-                </Col>
-              </Panel> : null}
-              {options.includes('font1') ? <Panel header="瀛椾綋" key="font1">
-                <Col span={12}>
-                  <Form.Item colon={false} label={<FontSizeOutlined title="瀛椾綋澶у皬"/>}>
-                    <InputNumber defaultValue={card.fontSize || 14} min={12} max={300} precision={0} onChange={this.changeFontSize} />
-                  </Form.Item>
-                </Col>
-                <Col span={12}>
-                  <Form.Item colon={false} label={<BoldOutlined title="瀛椾綋绮楃粏"/>}>
-                    <Select defaultValue={card.fontWeight || 'normal'} onChange={this.boldChange}>
-                      <Option value="normal">normal</Option>
-                      <Option value="bold">bold</Option>
-                      <Option value="bolder">bolder</Option>
-                      <Option value="lighter">lighter</Option>
-                      <Option value="100">100</Option>
-                      <Option value="200">200</Option>
-                      <Option value="300">300</Option>
-                      <Option value="400">400</Option>
-                      <Option value="500">500</Option>
-                      <Option value="600">600</Option>
-                      <Option value="700">700</Option>
-                      <Option value="800">800</Option>
-                      <Option value="900">900</Option>
-                    </Select>
-                  </Form.Item>
-                </Col>
-                <Col span={24}>
-                  <Form.Item
-                    colon={false}
-                    label={<FontColorsOutlined title="瀛椾綋棰滆壊"/>}
-                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
-                  >
-                    <ColorSketch value={card.color || 'rgba(0, 0, 0, 0.85)'} onChange={this.changeFontColor} />
-                  </Form.Item>
-                </Col>
+                </Col> : null}
               </Panel> : null}
               {options.includes('background') || options.includes('backgroundColor') ? <Panel header="鑳屾櫙" key="background">
                 <Col span={24}>
@@ -563,6 +601,15 @@
                     <ColorSketch value={card.backgroundColor || '#ffffff'} onChange={this.changeBackgroundColor} />
                   </Form.Item>
                 </Col>
+                {window.develop === true ? <Col span={24}>
+                  <Form.Item
+                    colon={false}
+                    label={<BgColorsOutlined title="鑳屾櫙棰滆壊"/>}
+                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
+                  >
+                    <Input value={card.background || ''} onChange={(e) => this.changeBackground(e.target.value)} />
+                  </Form.Item>
+                </Col> : null}
                 {!options.includes('backgroundColor') ? <Col span={24}>
                   <Form.Item
                     colon={false}
diff --git a/src/menu/stylecontroller/styleInput/index.jsx b/src/menu/stylecontroller/styleInput/index.jsx
index 6d9dee9..8eea049 100644
--- a/src/menu/stylecontroller/styleInput/index.jsx
+++ b/src/menu/stylecontroller/styleInput/index.jsx
@@ -106,7 +106,7 @@
     const { unit } = this.state
     let val = e.target.value
 
-    if (/\d+\.$|^-$/.test(val)) {
+    if (/\d+\.$|^-$|^-0$/.test(val)) {
       this.setState({
         value: val
       })
diff --git a/src/menu/sysinterface/settingform/simplescript/index.jsx b/src/menu/sysinterface/settingform/simplescript/index.jsx
index ea519cb..42a4ba4 100644
--- a/src/menu/sysinterface/settingform/simplescript/index.jsx
+++ b/src/menu/sysinterface/settingform/simplescript/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
-import { Form, Row, Col, Button, notification, Select, Popconfirm, Typography, Modal, Radio } from 'antd'
+import { Form, Row, Col, Button, notification, Select, Popconfirm, Typography, Modal, Radio, Tooltip } from 'antd'
 import { StopTwoTone, SwapOutlined, EditOutlined, CheckCircleTwoTone, DeleteOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
@@ -66,7 +66,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopTwoTone style={{marginLeft: '5px'}} twoToneColor="#ff4d4f" />
             </div>
           ) :
@@ -252,8 +252,10 @@
       exec_type: 'y',
       LText: SettingUtils.getCustomDebugSql(_scripts)
     }
-    param.LText = Utils.formatOptions(param.LText)
+
     param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    param.LText = param.LText.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
+    param.LText = Utils.formatOptions(param.LText)
     param.secretkey = Utils.encrypt('', param.timestamp)
     
     this.setState({loading: true})
@@ -395,7 +397,8 @@
             </Col>
             <Col span={24} className="sqlfield">
               <Form.Item label={'鍙敤瀛楁'}>
-                bid, loginuid, sessionuid, userid, username, fullname, RoleID, mk_departmentcode, mk_organization, login_city, appkey, time_id
+                <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
+                <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><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>
               </Form.Item>
             </Col>
             {type === 'back' ? <Col span={8} style={{whiteSpace: 'nowrap'}}>
diff --git a/src/menu/sysinterface/settingform/utils.jsx b/src/menu/sysinterface/settingform/utils.jsx
index 94c7839..60d5574 100644
--- a/src/menu/sysinterface/settingform/utils.jsx
+++ b/src/menu/sysinterface/settingform/utils.jsx
@@ -17,13 +17,13 @@
     })
 
     if (_customScript) {
-      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
         ${_customScript}
       `
     }
 
     _customScript = _customScript.replace(/@\$|\$@/ig, '')
-    _customScript = _customScript.replace(/@userName@|@fullName@|@login_city@/ig, `''`)
+    _customScript = _customScript.replace(/@userName@|@fullName@/ig, `''`)
     // 澶栬仈鏁版嵁搴撴浛鎹�
     if (window.GLOB.externalDatabase !== null) {
       _customScript = _customScript.replace(/@db@/ig, window.GLOB.externalDatabase)
diff --git a/src/mob/colorsketch/index.jsx b/src/mob/colorsketch/index.jsx
index c7ea1a8..d0190fc 100644
--- a/src/mob/colorsketch/index.jsx
+++ b/src/mob/colorsketch/index.jsx
@@ -61,9 +61,10 @@
 
   handleChange = (color) => {
     let _color = `rgba(${ color.rgb.r }, ${ color.rgb.g }, ${ color.rgb.b }, ${ color.rgb.a })`
+    let _hex = color.hex === 'transparent' ? '#ffffff' : color.hex
 
     this.setState({ color: _color }, () => {
-      this.props.onChange && this.props.onChange(_color)
+      this.props.onChange && this.props.onChange(_color, _hex)
     })
   }
 
diff --git a/src/mob/components/formdragelement/card.jsx b/src/mob/components/formdragelement/card.jsx
index 4c35773..d248a84 100644
--- a/src/mob/components/formdragelement/card.jsx
+++ b/src/mob/components/formdragelement/card.jsx
@@ -1,5 +1,6 @@
 import React from 'react'
 import { useDrag, useDrop } from 'react-dnd'
+import { fromJS } from 'immutable'
 import { Button, Popover, Switch, Checkbox, Form, Rate } from 'antd'
 import { ScanOutlined, RightOutlined, PlusOutlined, StarFilled, EditOutlined, CopyOutlined, CloseOutlined, FontColorsOutlined } from '@ant-design/icons'
 import moment from 'moment'
@@ -33,7 +34,7 @@
       }
     }
   })
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   const edit = () => {
     editCard(id)
@@ -48,9 +49,17 @@
   }
 
   const changeStyle = () => {
-    let options = ['font']
+    let options = ['font1', 'margin']
+    let style = fromJS(card.style || {}).toJS()
 
-    MKEmitter.emit('changeStyle', ['form', card.uuid], options, card.style || {})
+    if (card.marginTop && !style.marginTop) { // 澶栬竟璺濊缃浆绉�
+      style.marginTop = card.marginTop
+    }
+    if (card.marginBottom && !style.marginBottom) {
+      style.marginBottom = card.marginBottom
+    }
+
+    MKEmitter.emit('changeStyle', ['form', card.uuid], options, style)
   }
 
   let selectval = ''
@@ -67,13 +76,13 @@
 
   let formItem = null
   if (card.type === 'text' || card.type === 'linkMain') {
-    formItem = (<div className={'am-list-item input ' + (card.place || '')}><div className="am-list-line"><div className="am-input-label" style={card.style}>{card.label}</div><div className={'am-input-control ' + card.cursor}>{card.initval ? card.initval : <span style={{color: '#bcbcbc'}}>{card.placeholder || <span style={{color: 'transparent'}}>input</span>}</span> }</div>{card.scan && card.scan !== 'false' ? <div className="am-list-extra"><ScanOutlined /></div> : null}</div></div>)
+    formItem = (<div className={'am-list-item input ' + (card.place || '')}><div className="am-list-line"><div className="am-input-label">{card.label}</div><div className={'am-input-control ' + card.cursor}>{card.initval ? card.initval : <span style={{color: '#bcbcbc'}}>{card.placeholder || <span style={{color: 'transparent'}}>input</span>}</span> }</div>{card.scan && card.scan !== 'false' ? <div className="am-list-extra"><ScanOutlined /></div> : null}</div></div>)
   } else if (card.type === 'number') {
-    formItem = (<div className={'am-list-item input ' + (card.place || '')}><div className="am-list-line"><div className="am-input-label" style={card.style}>{card.label}</div><div className={'am-input-control ' + card.cursor}>{card.initval ? card.initval : <span style={{color: '#bcbcbc'}}><span style={{color: 'transparent'}}>input</span></span> }</div>{card.placeholder ? <div className="am-list-extra" style={{color: '#999999', width: 'auto', lineHeight: 1.5}}>{card.placeholder}</div> : null}</div></div>)
+    formItem = (<div className={'am-list-item input ' + (card.place || '')}><div className="am-list-line"><div className="am-input-label">{card.label}</div><div className={'am-input-control ' + card.cursor}>{card.initval ? card.initval : <span style={{color: '#bcbcbc'}}><span style={{color: 'transparent'}}>input</span></span> }</div>{card.placeholder ? <div className="am-list-extra" style={{color: '#999999', width: 'auto', lineHeight: 1.5}}>{card.placeholder}</div> : null}</div></div>)
   } else if (card.type === 'number') {
-    formItem = (<div className="am-list-item input"><div className="am-list-line"><div className="am-input-label" style={card.style}>{card.label}</div><div className={'am-input-control ' + card.cursor}>{card.initval || <span style={{color: 'transparent'}}>input</span>}</div></div></div>)
-  } else if (card.type === 'select' || card.type === 'link') {
-    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label" style={card.style}>{card.label}</div><div className="am-input-control">{selectval || '璇烽�夋嫨'}</div><div className="am-list-extra"><RightOutlined /></div></div></div>)
+    formItem = (<div className="am-list-item input"><div className="am-list-line"><div className="am-input-label">{card.label}</div><div className={'am-input-control ' + card.cursor}>{card.initval || <span style={{color: 'transparent'}}>input</span>}</div></div></div>)
+  } else if (card.type === 'select' || card.type === 'link' || card.type === 'cascader') {
+    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label">{card.label}</div><div className="am-input-control">{selectval || '璇烽�夋嫨'}</div><div className="am-list-extra"><RightOutlined /></div></div></div>)
   } else if (card.type === 'date') {
     let format = 'YYYY-MM-DD'
     if (card.precision === 'hour') {
@@ -83,16 +92,16 @@
     } else if (card.precision === 'second') {
       format = 'YYYY-MM-DD HH:mm:ss'
     }
-    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label" style={card.style}>{card.label}</div><div className="am-input-control">{card.initval ? moment().subtract(card.initval, 'days').format(format) : '璇烽�夋嫨'}</div><div className="am-list-extra"><RightOutlined /></div></div></div>)
+    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label">{card.label}</div><div className="am-input-control">{card.initval ? moment().subtract(card.initval, 'days').format(format) : '璇烽�夋嫨'}</div><div className="am-list-extra"><RightOutlined /></div></div></div>)
   } else if (card.type === 'datemonth') {
-    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label" style={card.style}>{card.label}</div><div className="am-input-control">{card.initval ? moment().subtract(card.initval, 'month').format('YYYY-MM') : '璇烽�夋嫨'}</div><div className="am-list-extra"><RightOutlined /></div></div></div>)
+    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label">{card.label}</div><div className="am-input-control">{card.initval ? moment().subtract(card.initval, 'month').format('YYYY-MM') : '璇烽�夋嫨'}</div><div className="am-list-extra"><RightOutlined /></div></div></div>)
   } else if (card.type === 'datetime') {
-    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label" style={card.style}>{card.label}</div><div className="am-input-control">{card.initval ? moment().subtract(card.initval, 'days').format('YYYY-MM-DD HH:mm') : '璇烽�夋嫨'}</div><div className="am-list-extra"><RightOutlined /></div></div></div>)
+    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label">{card.label}</div><div className="am-input-control">{card.initval ? moment().subtract(card.initval, 'days').format('YYYY-MM-DD HH:mm') : '璇烽�夋嫨'}</div><div className="am-list-extra"><RightOutlined /></div></div></div>)
   } else if (card.type === 'textarea') {
     let height = (card.maxRows || 2) * 25
     formItem = (<div className="am-list-item check-card">
       <div className="am-list-line">
-        <div className="am-input-label" style={card.style}>{card.label}</div>
+        <div className="am-input-label">{card.label}</div>
         <div className="am-input-control">
           <div style={{textAlign: 'left', position: 'relative', height, lineHeight: 1.5}}>
             {card.initval ? card.initval : <span style={{color: '#bcbcbc'}}>{card.placeholder || ''}</span> }
@@ -102,14 +111,14 @@
       </div>
     </div>)
   } else if (card.type === 'rate') {
-    formItem = (<div className={'am-list-item ' + (card.place || '')}><div className="am-list-line"><div className="am-input-label" style={card.style}>{card.label}</div><div style={{textAlign: 'left'}} className={'am-input-control ' + (card.place === 'up_down' ? 'left' : '')}>
+    formItem = (<div className={'am-list-item ' + (card.place || '')}><div className="am-list-line"><div className="am-input-label">{card.label}</div><div style={{textAlign: 'left'}} className={'am-input-control ' + (card.place === 'up_down' ? 'left' : '')}>
       <Rate value={card.initval || 0} count={card.rateCount || 5} character={card.character ? <MkIcon type={card.character}/> : <StarFilled />} allowHalf={card.allowHalf === 'true'} />
     </div></div></div>)
   } else if (card.type === 'fileupload') {
     formItem = (
       <div className="am-list-item checkbox">
         <div className="am-list-line">
-          <div className="am-input-label" style={card.style}>{card.label}</div>
+          <div className="am-input-label">{card.label}</div>
           <div className="am-input-control" style={{textAlign: 'left'}}>
             <Button style={{width: '100px', marginBottom: '10px', height: '100px', fontSize: '50px', color: '#d9d9d9'}}><PlusOutlined /></Button>
           </div>
@@ -117,9 +126,9 @@
       </div>
     )
   } else if (card.type === 'funcvar') {
-    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label" style={card.style}>{card.label}</div><div className="am-input-control">{card.linkfield}</div></div></div>)
+    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label">{card.label}</div><div className="am-input-control">{card.linkfield}</div></div></div>)
   } else if (card.type === 'switch') {
-    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label" style={card.style}>{card.label}</div><div className="am-list-switch"><Switch checked={card.initval}/></div></div></div>)
+    formItem = (<div className="am-list-item"><div className="am-list-line"><div className="am-input-label">{card.label}</div><div className="am-list-switch"><Switch checked={card.initval}/></div></div></div>)
   } else if (card.type === 'radio') {
     let options = null
     if (card.options && card.options.length > 0) {
@@ -135,7 +144,7 @@
     formItem = (
     <div className={'am-list-item checkbox mk-radio ' + (card.arrange || '')}>
       <div className="am-list-line">
-        <div className="am-input-label" style={card.style}>{card.label}</div>
+        <div className="am-input-label">{card.label}</div>
         <div className="am-input-control">
           {card.arrange !== 'line' ? <Checkbox.Group value={[card.initval]}>
             {options.map(cell => <Checkbox key={cell.key} value={cell.Value}>{cell.Text}</Checkbox>)}
@@ -164,7 +173,7 @@
     formItem = (
       <div className={'am-list-item checkbox ' + (card.arrange || '')}>
         <div className="am-list-line">
-          <div className="am-input-label" style={card.style}>{card.label}</div>
+          <div className="am-input-label">{card.label}</div>
           <div className="am-input-control">
             {<Checkbox.Group value={_val}>
               {options.map(cell => <Checkbox key={cell.key} value={cell.Value}>{cell.Text}</Checkbox>)}
@@ -177,23 +186,41 @@
   } else if (card.type === 'hint') {
     formItem = <div className="am-list-item hint">
       <div className="am-list-line">
-        <div className="am-input-label" style={card.style}>{card.label}</div>
-        <div className="am-input-control" style={card.style}>
+        <div className="am-input-label">{card.label}</div>
+        <div className="am-input-control">
           {card.message}  
         </div>
       </div>
     </div>
+  } else if (card.type === 'formula') {
+    formItem = <div className="am-list-item formula">
+      <div className="am-list-line">
+        <div className="am-input-label">{card.label}</div>
+        <div className="am-input-control">
+          {card.formula}{card.postfix || ''}
+        </div>
+      </div>
+    </div>
   } else if (card.type === 'split') {
-    formItem = <div className="split-line" style={card.style}>{card.label}</div>
+    formItem = <div className="split-line">{card.label}</div>
   } else if (card.type === 'checkcard') {
     formItem = (<div className="am-list-item check-card">
       <div className="am-list-line">
-        {card.hidelabel !== 'true' ? <div className="am-input-label" style={card.style}>{card.label}</div> : null}
+        {card.hidelabel !== 'true' ? <div className="am-input-label">{card.label}</div> : null}
         <div className="am-input-control">
           <CheckCard config={card} />
         </div>
       </div>
     </div>)
+  }
+
+  let style = {...card.style}
+
+  if (card.marginTop && !style.marginTop) { // 澶栬竟璺濊缃浆绉�
+    style.marginTop = card.marginTop
+  }
+  if (card.marginBottom && !style.marginBottom) {
+    style.marginBottom = card.marginBottom
   }
 
   return (
@@ -208,8 +235,9 @@
       <div className="page-card" style={{ opacity: opacity}}>
         <div ref={node => drag(drop(node))} style={{ border: '0.5px solid transparent'}} onDoubleClick={edit}>
           <Form.Item
-            style={{marginTop: card.marginTop || 0, marginBottom: card.marginBottom || 0}}
-            className={'ant-form-item' + (card.required === 'true' ? ' required' : '') + (card.splitline === 'false' ? ' no-boder' : '')}
+            style={style}
+            // style={{marginTop: card.marginTop || 0, marginBottom: card.marginBottom || 0}}
+            className={(card.required === 'true' ? ' required' : '') + (card.type === 'split' ? ' split-wrap' : '') + (card.splitline === 'false' ? ' no-boder' : '')}
           >
             {formItem}
             <div></div>
diff --git a/src/mob/components/formdragelement/index.jsx b/src/mob/components/formdragelement/index.jsx
index 45f4207..7ff6d39 100644
--- a/src/mob/components/formdragelement/index.jsx
+++ b/src/mob/components/formdragelement/index.jsx
@@ -119,6 +119,10 @@
     style.paddingRight = setting.paddingRight
   }
 
+  if (setting.display === 'drawer' && (setting.placement === 'top' || setting.placement === 'bottom') && setting.width !== 100) {
+    style.minHeight = 'auto'
+  }
+
   return (
     <div ref={drop} className="ant-row modal-fields-row mob-form" style={style}>
       {cards.map(card => {
diff --git a/src/mob/components/formdragelement/index.scss b/src/mob/components/formdragelement/index.scss
index e4b9d51..436e4e2 100644
--- a/src/mob/components/formdragelement/index.scss
+++ b/src/mob/components/formdragelement/index.scss
@@ -26,8 +26,7 @@
     }
   }
   .am-list-item {
-    font-size: 16px;
-    // padding-left: 10px;
+    // font-size: 16px;
     position: relative;
     display: flex;
     height: 44px;
@@ -49,8 +48,6 @@
       overflow: hidden;
       .am-input-label {
         width: 28%;
-        color: #000;
-        font-size: 16px;
         margin-left: 0;
         margin-right: 5px;
         text-align: left;
@@ -58,16 +55,21 @@
         overflow: hidden;
         padding: 2px 0;
         text-overflow: ellipsis;
+        color: inherit;
+        font-size: inherit;
+        font-weight: inherit;
       }
       .am-list-switch {
         flex: 1;
         text-align: right;
       }
       .am-input-control {
-        font-size: 16px;
         flex: 1 1;
         text-align: right;
         padding-right: 15px;
+        font-size: 16px;
+        font-weight: normal;
+        color: rgba(0, 0, 0, 0.65);
       }
       .am-input-control.left {
         text-align: left;
@@ -77,6 +79,9 @@
         width: 15px;
         height: 15px;
         margin-left: 8px;
+        font-size: 16px;
+        font-weight: normal;
+        color: rgba(0, 0, 0, 0.65);
         .anticon {
           vertical-align: top;
         }
@@ -124,10 +129,22 @@
         line-height: 2;
       }
       .am-input-control {
-        font-size: 14px;
         line-height: 1.5;
         text-align: left;
         padding-bottom: 5px;
+        color: inherit;
+        font-size: inherit;
+        font-weight: inherit;
+      }
+    }
+  }
+  .am-list-item.formula {
+    .am-list-line {
+      .am-input-control {
+        font-size: inherit;
+        font-weight: inherit;
+        color: inherit;
+        padding-right: 0px;
       }
     }
   }
@@ -231,8 +248,9 @@
     }
   }
   .split-line {
-    color: #1890ff;
-    font-size: 16px;
+    color: inherit;
+    font-size: inherit;
+    font-weight: inherit;
     padding-left: 10px;
     padding-top: 10px;
     border-bottom: 1px solid #e9e9e9;
@@ -240,10 +258,22 @@
   .check-card-edit-box .card-cell span {
     line-height: 1.5;
   }
+  .split-wrap.ant-form-item {
+    color: #1890ff;
+    font-size: 16px;
+  }
   .ant-form-item {
     cursor: move;
     display: flex;
     margin-bottom: 0px;
+    color: #000;
+    font-weight: normal;
+    font-size: 14px;
+
+    * {
+      font-weight: inherit;
+    }
+    
     .ant-form-item-control-wrapper::after {
       content: '';
       position: absolute;
diff --git a/src/mob/components/menubar/normal-menubar/index.jsx b/src/mob/components/menubar/normal-menubar/index.jsx
index bca54f3..53d4e1f 100644
--- a/src/mob/components/menubar/normal-menubar/index.jsx
+++ b/src/mob/components/menubar/normal-menubar/index.jsx
@@ -225,6 +225,22 @@
     }, 200)
   }
 
+  filterComponent = (config) => {
+    let item = null
+    config.subMenus.forEach(menu => {
+      if (menu.setting.type === 'linkmenu' && menu.setting.linkMenuId === '') {
+        item = menu
+      }
+    })
+    
+    this.updateComponent(config)
+    
+    setTimeout(() => {
+      let node = document.getElementById(item.uuid)
+      node && node.click()
+    }, 200)
+  }
+
   move = (item, direction) => {
     let card = fromJS(this.state.card).toJS()
 
@@ -286,7 +302,7 @@
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
             <CopyComponent type="menubar" card={card}/>
-            <PasteComponent config={card} options={['menucell']} updateConfig={this.updateComponent} />
+            <PasteComponent config={card} options={['menucell']} updateConfig={this.filterComponent} />
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} />
             <UserComponent config={card}/>
             <DeleteOutlined className="close" title="鍒犻櫎缁勪欢" onClick={() => this.props.deletecomponent(card.uuid)} />
diff --git a/src/mob/components/menubar/normal-menubar/menucomponent/index.jsx b/src/mob/components/menubar/normal-menubar/menucomponent/index.jsx
index daac1c6..863c894 100644
--- a/src/mob/components/menubar/normal-menubar/menucomponent/index.jsx
+++ b/src/mob/components/menubar/normal-menubar/menucomponent/index.jsx
@@ -160,7 +160,7 @@
             </div>}
             <div className="menu-name" style={{opacity: !card.setting.name ? 0 : 1}}>{card.setting.name || '鏄庣'}</div>
             <RightOutlined className="menu-right" />
-            {!card.setting.name ? <NormalForm title="鑿滃崟缂栬緫" width={900} update={this.updateSetting} cancel={() => this.props.deleteElement(card, 'direct')} getForms={this.getSettingForms}>
+            {!card.setting.name || (card.setting.type === 'linkmenu' && card.setting.linkMenuId === '') ? <NormalForm title="鑿滃崟缂栬緫" width={900} update={this.updateSetting} cancel={() => this.props.deleteElement(card, 'direct')} getForms={this.getSettingForms}>
               <span id={card.uuid}></span>
             </NormalForm> : null}
           </div>
diff --git a/src/mob/components/navbar/normal-navbar/index.scss b/src/mob/components/navbar/normal-navbar/index.scss
index 592454e..6414525 100644
--- a/src/mob/components/navbar/normal-navbar/index.scss
+++ b/src/mob/components/navbar/normal-navbar/index.scss
@@ -41,6 +41,24 @@
         margin-bottom: 0;
       }
     }
+    .am-tab-bar-tab.tab-zoomIn {
+      .am-tab-bar-tab-icon {
+        padding: 10px;
+        display: inline-block;
+        background: #1890ff;
+        color: #ffffff;
+        border-radius: 40px;
+        width: 42px;
+        height: 42px;
+        font-size: 15px;
+        transform: translate(0px, -25px);
+      }
+      .am-tab-bar-tab-title {
+        font-size: 1.2em;
+        color: #1890ff;
+        transform: translate(0px, -22px);
+      }
+    }
   }
 
   .anticon-tool {
diff --git a/src/mob/components/navbar/normal-navbar/menus/drags/card.jsx b/src/mob/components/navbar/normal-navbar/menus/drags/card.jsx
index fe9dd41..98cdcef 100644
--- a/src/mob/components/navbar/normal-navbar/menus/drags/card.jsx
+++ b/src/mob/components/navbar/normal-navbar/menus/drags/card.jsx
@@ -50,7 +50,7 @@
         <CloseOutlined className="close" title="鍒犻櫎" onClick={() => delCard(id)} />
       </div>
     } trigger="hover">
-      <div ref={node => drag(drop(node))} className="am-tab-bar-tab" style={{opacity: isDragging ? 0 : 1}} onDoubleClick={doubleClickCard}>
+      <div ref={node => drag(drop(node))} className={'am-tab-bar-tab tab-' + (card.class || 'default')} style={{opacity: isDragging ? 0 : 1}} onDoubleClick={doubleClickCard}>
         {card.icon ? <div className="am-tab-bar-tab-icon">
           <span className="am-badge am-tab-bar-tab-badge tab-badge">
             <MkIcon type={card.icon} />
diff --git a/src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx b/src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx
index 8efdcec..2ffce2b 100644
--- a/src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx
+++ b/src/mob/components/navbar/normal-navbar/menus/menuform/index.jsx
@@ -168,6 +168,23 @@
               )}
             </Form.Item>
           </Col>
+          {property === 'menu' || property === 'linkmenu' ? <Col span={12}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="鏇挎崲褰撳墠椤甸潰鎴栨墦寮�鏂伴〉闈紝鍦℉5鎴栧皬绋嬪簭涓湁鏁堛��">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鎵撳紑鏂瑰紡
+              </Tooltip>
+            }>
+              {getFieldDecorator('open', {
+                initialValue: menu.open || 'self'
+              })(
+                <Radio.Group>
+                  <Radio value="self">鏍囩椤�</Radio>
+                  <Radio value="blank">鏂伴〉闈�</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col> : null}
           {property === 'link' ? <Col span={24}>
             <Form.Item label="閾炬帴鍦板潃" className="textarea">
               {getFieldDecorator('link', {
@@ -244,6 +261,23 @@
               )}
             </Form.Item>
           </Col> : null}
+          <Col span={12}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="鍦℉5鎴栧皬绋嬪簭涓湁鏁堛��">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鑿滃崟鏍峰紡
+              </Tooltip>
+            }>
+              {getFieldDecorator('class', {
+                initialValue: menu.class || 'default'
+              })(
+                <Radio.Group>
+                  <Radio value="default">榛樿</Radio>
+                  <Radio value="zoomIn">鏀惧ぇ</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
         </Row>
       </Form>
     )
diff --git a/src/mob/components/tabs/antv-tabs/index.scss b/src/mob/components/tabs/antv-tabs/index.scss
index b38d227..32eddf3 100644
--- a/src/mob/components/tabs/antv-tabs/index.scss
+++ b/src/mob/components/tabs/antv-tabs/index.scss
@@ -29,6 +29,9 @@
   .ant-tabs-tabpane-active {
     min-height: 200px;
   }
+  .tab-shell-inner {
+    min-height: 100%;
+  }
 
   .ant-tabs .ant-tabs-top-bar > .ant-tabs-nav-container {
     >.ant-tabs-tab-next:not(.ant-tabs-tab-arrow-show) + .ant-tabs-nav-wrap > .ant-tabs-nav-scroll > .ant-tabs-nav {
diff --git a/src/mob/components/tabs/tabcomponents/card.jsx b/src/mob/components/tabs/tabcomponents/card.jsx
index bbd5724..743d449 100644
--- a/src/mob/components/tabs/tabcomponents/card.jsx
+++ b/src/mob/components/tabs/tabcomponents/card.jsx
@@ -16,7 +16,8 @@
 const CarouselDataCard = asyncComponent(() => import('@/menu/components/carousel/data-card'))
 const CarouselPropCard = asyncComponent(() => import('@/menu/components/carousel/prop-card'))
 const TableCard = asyncComponent(() => import('@/menu/components/card/table-card'))
-const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form'))
+const SimpleForm = asyncComponent(() => import('@/menu/components/form/simple-form'))
+const StepForm = asyncComponent(() => import('@/menu/components/form/step-form'))
 const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form'))
 const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table'))
 const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group'))
@@ -72,8 +73,10 @@
       return (<NormalTree card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'scatter') {
       return (<AntvScatter card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'form' && card.subtype === 'simpleform') {
+      return (<SimpleForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'form' && card.subtype === 'stepform') {
-      return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+      return (<StepForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'form' && card.subtype === 'tabform') {
       return (<TabForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'tabs') {
diff --git a/src/mob/components/topbar/normal-navbar/index.jsx b/src/mob/components/topbar/normal-navbar/index.jsx
index b8ece4c..9579b7e 100644
--- a/src/mob/components/topbar/normal-navbar/index.jsx
+++ b/src/mob/components/topbar/normal-navbar/index.jsx
@@ -220,7 +220,7 @@
       <div className="normal-topbar-edit-box" style={card.style} onClick={this.clickComponent} id={card.uuid}>
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
-            <NormalForm title="瀵艰埅鏍忚缃�" width={850} update={this.updateWrap} getForms={this.getWrapForms}>
+            <NormalForm title="瀵艰埅鏍忚缃�" width={900} update={this.updateWrap} getForms={this.getWrapForms}>
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
             <CopyComponent type="topbar" card={card}/>
@@ -232,7 +232,7 @@
         </Popover>
         <div className="am-navbar">
           <div className="am-navbar-left">
-            {card.wrap.back !== 'false' && card.wrap.menuPosition !== 'left' ? <LeftOutlined /> : null}
+            {card.wrap.back === 'true' && card.wrap.menuPosition !== 'left' ? <LeftOutlined /> : null}
             {card.wrap.menuPosition === 'left' ? <div className="img" style={{backgroundImage: `url(${avatar})`}}></div> : null}
           </div>
           {card.wrap.type !== 'search' ?
diff --git a/src/mob/components/topbar/normal-navbar/options.jsx b/src/mob/components/topbar/normal-navbar/options.jsx
index 5a016d9..2a395e0 100644
--- a/src/mob/components/topbar/normal-navbar/options.jsx
+++ b/src/mob/components/topbar/normal-navbar/options.jsx
@@ -7,6 +7,13 @@
 export default function (wrap) {
   let menulist = sessionStorage.getItem('appMenus')
   let searchable = true
+  let adapters = sessionStorage.getItem('adapter')
+  if (adapters) {
+    adapters = adapters.split(',')
+  } else {
+    adapters = []
+  }
+
   window.GLOB.customMenu.components.forEach(item => {
     if (item.type === 'search') {
       searchable = false
@@ -37,6 +44,9 @@
   if (wrap.refresh === 'true') {
     funs.push('refresh')
   }
+  if (wrap.resetPwd === 'true') {
+    funs.push('resetPwd')
+  }
 
   const topbarWrapForm = [
     {
@@ -56,34 +66,9 @@
       field: 'title',
       label: '鏍囬',
       initval: wrap.title || '',
-      tooltip: '浣跨敤鎼滅储妗嗘椂锛屾爣棰樼敤浜庢悳绱㈡潯浠堕殣钘忔椂锛堝綋鍚敤榛戝悕鍗曪紝鐧诲綍鐢ㄦ埛鏃犳潈闄愭椂锛夋樉绀恒��',
+      // tooltip: '浣跨敤鎼滅储妗嗘椂锛屾爣棰樼敤浜庢悳绱㈡潯浠堕殣钘忔椂锛堝綋鍚敤榛戝悕鍗曪紝鐧诲綍鐢ㄦ埛鏃犳潈闄愭椂锛夋樉绀恒�傛敞锛欯username浠h〃鐢ㄦ埛鍚嶏紝@fullname浠h〃濮撳悕銆�',
+      tooltip: '娉細@username浠h〃鐢ㄦ埛鍚嶏紝@fullname浠h〃濮撳悕銆�',
       required: false
-    },
-    {
-      type: 'radio',
-      field: 'menuPosition',
-      label: '鑿滃崟浣嶇疆',
-      initval: wrap.menuPosition || 'right',
-      tooltip: '鑷畾涔夎彍鍗曠殑浣嶇疆銆�',
-      required: false,
-      options: [
-        {value: 'left', label: '宸︿晶'},
-        {value: 'right', label: '鍙充晶'},
-      ],
-      controlFields: [
-        {field: 'back', values: ['right']},
-      ]
-    },
-    {
-      type: 'radio',
-      field: 'mode',
-      label: '寮规鑳屾櫙',
-      initval: wrap.mode || 'dark',
-      required: false,
-      options: [
-        {value: 'light', label: '鐧借壊'},
-        {value: 'dark', label: '榛戣壊'},
-      ]
     },
     {
       type: 'checkbox',
@@ -95,6 +80,7 @@
       options: [
         {value: 'back', label: '杩斿洖'},
         {value: 'scan', label: '鎵竴鎵�'},
+        {value: 'resetPwd', label: '淇敼瀵嗙爜'},
         {value: 'refresh', label: '鍒锋柊'},
         {value: 'logout', label: '閫�鍑�'},
       ],
@@ -103,6 +89,18 @@
         {field: 'linkmenu', values: ['scan']},
       ],
       span: 24
+    },
+    {
+      type: 'radio',
+      field: 'mode',
+      label: '寮规鑳屾櫙',
+      initval: wrap.mode || 'dark',
+      tooltip: '褰撳瓨鍦ㄦ墿灞曞姛鑳芥垨鑷畾涔夎彍鍗曟椂锛屽睍绀哄搴斾俊鎭脊绐楃殑鑳屾櫙棰滆壊銆�',
+      required: false,
+      options: [
+        {value: 'light', label: '鐧借壊'},
+        {value: 'dark', label: '榛戣壊'},
+      ]
     },
     // {
     //   type: 'radio',
@@ -181,6 +179,31 @@
       options: menulist
     },
     {
+      type: 'radio',
+      field: 'minishow',
+      label: '灏忕▼搴忎腑',
+      initval: wrap.minishow || 'false',
+      tooltip: '瀵艰埅鏍忓湪灏忕▼搴忎腑鏄惁鏄剧ず銆�',
+      required: false,
+      options: [
+        {value: 'true', label: '鏄剧ず'},
+        {value: 'false', label: '闅愯棌'},
+      ],
+      forbid: !adapters.includes('wxmini')
+    },
+    {
+      type: 'radio',
+      field: 'menuPosition',
+      label: '鑷畾涔夎彍鍗曚綅缃�',
+      initval: wrap.menuPosition || 'right',
+      tooltip: '鑷畾涔夎彍鍗曠殑浣嶇疆銆傛敞锛氳彍鍗曚綅浜庡乏渚ф椂浼氭樉绀哄ご鍍忥紝涓旇繑鍥炲姛鑳借绂佺敤銆�',
+      required: false,
+      options: [
+        {value: 'left', label: '宸︿晶'},
+        {value: 'right', label: '鍙充晶'},
+      ]
+    },
+    {
       type: 'table',
       field: 'menus',
       label: '鑷畾涔夎彍鍗�',
@@ -188,6 +211,7 @@
       required: false,
       span: 24,
       actions: ['view'],
+      tip: <span style={{fontSize: '12px', color: '#959595', position: 'relative', top: '-8px'}}>褰撲娇鐢ㄥ浘鏍�<MkIcon type="user"/>锛屼笖鍙充晶鍙湁涓�涓彍鍗曟椂锛屼細鏄剧ず鐢ㄦ埛澶村儚銆�</span>,
       columns: [
         {
           title: '鍥炬爣',
diff --git a/src/mob/mobshell/card.jsx b/src/mob/mobshell/card.jsx
index 7095000..263391c 100644
--- a/src/mob/mobshell/card.jsx
+++ b/src/mob/mobshell/card.jsx
@@ -16,7 +16,8 @@
 const CarouselPropCard = asyncComponent(() => import('@/menu/components/carousel/prop-card'))
 const TableCard = asyncComponent(() => import('@/menu/components/card/table-card'))
 const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table'))
-const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form'))
+const SimpleForm = asyncComponent(() => import('@/menu/components/form/simple-form'))
+const StepForm = asyncComponent(() => import('@/menu/components/form/step-form'))
 const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form'))
 const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group'))
 const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox'))
@@ -91,8 +92,10 @@
       return (<AntvDashboard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'scatter') {
       return (<AntvScatter card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'form' && card.subtype === 'simpleform') {
+      return (<SimpleForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'form' && card.subtype === 'stepform') {
-      return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+      return (<StepForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'form' && card.subtype === 'tabform') {
       return (<TabForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'tabs') {
diff --git a/src/mob/modalconfig/index.jsx b/src/mob/modalconfig/index.jsx
index 6be97f8..2bc3d6c 100644
--- a/src/mob/modalconfig/index.jsx
+++ b/src/mob/modalconfig/index.jsx
@@ -277,10 +277,10 @@
           LText: res.dataSource
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
         
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
 
         if (window.GLOB.mainSystemApi && res.database === 'sso') {
@@ -442,6 +442,7 @@
   }
 
   render () {
+    const { btn } = this.props
     const { config, dict, saving } = this.state
 
     return (
@@ -472,7 +473,7 @@
               <div className="mob-shell-inner">
                 <div className="am-navbar">
                   <LeftOutlined />
-                  <div className="am-navbar-title">{config.setting.title}</div>
+                  <div className="am-navbar-title">{btn.label}</div>
                   {config.setting.btnPosition === 'top' ? <Button className="modal-submit-top">{config.setting.btnName || '纭畾'}</Button> : null}
                 </div>
                 <DragElement
diff --git a/src/mob/modalconfig/source.jsx b/src/mob/modalconfig/source.jsx
index 42363a7..5a1a31a 100644
--- a/src/mob/modalconfig/source.jsx
+++ b/src/mob/modalconfig/source.jsx
@@ -54,13 +54,13 @@
   },
   {
     type: 'form',
-    label: CommonDict['header.form.fileupload'],
+    label: '鏂囦欢涓婁紶',
     subType: 'fileupload',
     url: ''
   },
   {
     type: 'form',
-    label: CommonDict['model.form.dateday'],
+    label: '鏃ユ湡锛堝ぉ锛�',
     subType: 'date',
     url: ''
   },
@@ -70,17 +70,16 @@
     subType: 'datemonth',
     url: ''
   },
-  // {
-  //   type: 'form',
-  //   label: '鏃ユ湡锛堝垎/绉掞級',
-  //   subType: 'datetime',
-  //   url: ''
-  // },
   {
     type: 'form',
     label: CommonDict['model.form.textarea'],
     subType: 'textarea',
     url: ''
+  },
+  {
+    type: 'form',
+    label: '绾ц仈鑿滃崟',
+    subType: 'cascader',
   },
   {
     type: 'form',
@@ -110,6 +109,11 @@
     type: 'form',
     label: '鍏宠仈涓昏〃',
     subType: 'linkMain',
+  },
+  {
+    type: 'form',
+    label: '鍏紡',
+    subType: 'formula',
   }
 ]
 
diff --git a/src/mob/modulesource/option.jsx b/src/mob/modulesource/option.jsx
index 34798d2..65b1e9c 100644
--- a/src/mob/modulesource/option.jsx
+++ b/src/mob/modulesource/option.jsx
@@ -19,7 +19,7 @@
 import Carousel1 from '@/assets/mobimg/carousel1.png'
 import form from '@/assets/mobimg/form.png'
 import tabForm from '@/assets/mobimg/tab-form.png'
-import Login from '@/assets/mobimg/login.png'
+import Login from '@/assets/mobimg/moblogin.jpg'
 // import dashboard from '@/assets/mobimg/dashboard.png'
 import NavTop from '@/assets/mobimg/navtop-mob.png'
 import scatter from '@/assets/mobimg/scatter.png'
@@ -38,6 +38,7 @@
   { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '鏁版嵁鍗�', width: 24 },
   { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '灞炴�у崱', width: 24 },
   { type: 'menu', url: card2, component: 'balcony', subtype: 'balcony', title: '娴姩鍗�', width: 24 },
+  { type: 'menu', url: form, component: 'form', subtype: 'simpleform', title: '琛ㄥ崟', width: 24 },
   { type: 'menu', url: form, component: 'form', subtype: 'stepform', title: '琛ㄥ崟锛堝垎姝ワ級', width: 24 },
   { type: 'menu', url: tabForm, component: 'form', subtype: 'tabform', title: '琛ㄥ崟锛坱ab椤碉級', width: 24 },
   { type: 'menu', url: Carousel, component: 'carousel', subtype: 'datacard', title: '杞挱-鍔ㄦ�佹暟鎹�', width: 24 },
@@ -57,5 +58,5 @@
   { type: 'menu', url: Editor, component: 'editor', subtype: 'brafteditor', title: '瀵屾枃鏈�', width: 24 },
   { 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: Login, component: 'login', subtype: 'normallogin', title: '娉ㄥ唽/鐧诲綍', width: 24 },
 ]
diff --git a/src/mob/searchconfig/groupdragelement/card.jsx b/src/mob/searchconfig/groupdragelement/card.jsx
index 16db7b0..5619ba8 100644
--- a/src/mob/searchconfig/groupdragelement/card.jsx
+++ b/src/mob/searchconfig/groupdragelement/card.jsx
@@ -26,7 +26,7 @@
       }
     }
   })
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   const edit = () => {
     editCard(id)
diff --git a/src/mob/searchconfig/index.jsx b/src/mob/searchconfig/index.jsx
index afd204d..a240a6c 100644
--- a/src/mob/searchconfig/index.jsx
+++ b/src/mob/searchconfig/index.jsx
@@ -238,10 +238,10 @@
           LText: res.dataSource
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
         
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
 
         if (window.GLOB.mainSystemApi && res.database === 'sso') {
diff --git a/src/mob/searchconfig/searchdragelement/card.jsx b/src/mob/searchconfig/searchdragelement/card.jsx
index 48d90df..13080ed 100644
--- a/src/mob/searchconfig/searchdragelement/card.jsx
+++ b/src/mob/searchconfig/searchdragelement/card.jsx
@@ -31,7 +31,7 @@
       }
     }
   })
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   const edit = () => {
     editCard(id)
diff --git a/src/mob/searchconfig/settingform/index.jsx b/src/mob/searchconfig/settingform/index.jsx
index 96693bb..f753ef8 100644
--- a/src/mob/searchconfig/settingform/index.jsx
+++ b/src/mob/searchconfig/settingform/index.jsx
@@ -1,6 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Row, Col, Input, Radio, Select, Tooltip } from 'antd'
+import { Form, Row, Col, Input, Radio, Tooltip } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 
 import asyncComponent from '@/utils/asyncComponent'
@@ -16,23 +16,23 @@
   }
 
   state = {
-    roleList: [],
+    // roleList: [],
     type: this.props.config.setting.type || 'title'
   }
 
   UNSAFE_componentWillMount() {
-    let roleList = sessionStorage.getItem('sysRoles')
-    if (roleList) {
-      try {
-        roleList = JSON.parse(roleList)
-      } catch (e) {
-        roleList = []
-      }
-    } else {
-      roleList = []
-    }
+    // let roleList = sessionStorage.getItem('sysRoles')
+    // if (roleList) {
+    //   try {
+    //     roleList = JSON.parse(roleList)
+    //   } catch (e) {
+    //     roleList = []
+    //   }
+    // } else {
+    //   roleList = []
+    // }
 
-    this.setState({roleList})
+    // this.setState({roleList})
   }
 
   handleConfirm = () => {
@@ -59,7 +59,7 @@
   render() {
     const { config } = this.props
     const { getFieldDecorator } = this.props.form
-    const { type, roleList } = this.state
+    const { type } = this.state
 
     const formItemLayout = {
       labelCol: {
@@ -234,7 +234,8 @@
               )}
             </Form.Item>
           </Col>
-          {type === 'search' ? <Col span={12}>
+          {/* 鍘婚櫎绉诲姩绔瓧娈垫潈闄� */}
+          {/* {type === 'search' ? <Col span={12}>
             <Form.Item label="榛戝悕鍗�">
               {getFieldDecorator('blacklist', {
                 initialValue: config.setting.blacklist || []
@@ -250,7 +251,7 @@
                 </Select>
               )}
             </Form.Item>
-          </Col> : null}
+          </Col> : null} */}
         </Row>
       </Form>
     )
diff --git a/src/pc/components/login/normal-login/index.jsx b/src/pc/components/login/normal-login/index.jsx
index 91ea5f3..226531c 100644
--- a/src/pc/components/login/normal-login/index.jsx
+++ b/src/pc/components/login/normal-login/index.jsx
@@ -13,9 +13,10 @@
 import './index.scss'
 
 const LoginForm = asyncComponent(() => import('./loginform'))
+const SignForm = asyncComponent(() => import('./signform'))
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 
-class PropCardEditComponent extends Component {
+class LoginComponent extends Component {
   static propTpyes = {
     card: PropTypes.object,
     deletecomponent: PropTypes.func,
@@ -24,7 +25,7 @@
 
   state = {
     card: null,
-    back: false
+    active: 'login'
   }
 
   UNSAFE_componentWillMount () {
@@ -41,13 +42,8 @@
         width: card.width || 24,
         name: card.name,
         subtype: card.subtype,
-        wrap: { name: card.name, width: card.width || 24, loginWays: ['uname_pwd'], shortcut: 'remember' },
-        style: { background: '#ffffff', width: '330px', borderRadius: '4px', marginLeft: '55vw'},
-        loginWays: [
-          {type: 'uname_pwd', label: '璐﹀彿鐧诲綍', shortcut: 'remember'},
-          {type: 'sms_vcode', label: '鐭俊鐧诲綍'},
-          {type: 'app_scan', label: '鎵爜鐧诲綍'},
-        ]
+        wrap: { name: card.name, width: card.width || 24, classify: 'login', loginWays: ['uname_pwd'], shortcut: 'remember' },
+        style: { background: '#ffffff', width: '330px', borderRadius: '4px', marginLeft: '55vw'}
       }
 
       if (ismob) {
@@ -65,19 +61,21 @@
         _card.wrap.name = card.name
         _card.style = config.style
       }
-      this.setState({
-        card: _card
-      })
-      this.props.updateConfig(_card)
+
+      this.updateComponent(_card)
     } else {
       let _card = fromJS(card).toJS()
-      if (_card.loginWays.length === 2) {
-        _card.loginWays.push({type: 'app_scan', label: '鎵爜鐧诲綍'})
-      }
       if (_card.wrap.link && _card.wrap.link === 'menu') {
         _card.wrap.linkmenu = _card.uuid
       }
+      _card.wrap.classify = _card.wrap.classify || 'login'
+
+      let active = 'login'
+      if (_card.wrap.classify === 'signin') {
+        active = 'signin'
+      }
       this.setState({
+        active,
         card: _card
       })
     }
@@ -104,15 +102,21 @@
   /**
    * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
    */
-  updateComponent = (component) => {
+  updateComponent = (card) => {
+    card.width = card.wrap.width
+    card.name = card.wrap.name
+
+    card.errors = []
+
+    if (!card.wrap.linkmenu) {
+      card.errors.push({ level: 0, detail: '鐧诲綍鍚庤烦杞彍鍗曟湭璁剧疆锛�'})
+    }
+    
     this.setState({
-      card: component
+      card: card
     })
 
-    component.width = component.wrap.width
-    component.name = component.wrap.name
-
-    this.props.updateConfig(component)
+    this.props.updateConfig(card)
   }
 
   changeStyle = () => {
@@ -127,12 +131,8 @@
     if (comIds.length !== 1 || comIds[0] !== card.uuid) return
 
     let _card = {...card, style}
-
-    this.setState({
-      card: _card
-    })
     
-    this.props.updateConfig(_card)
+    this.updateComponent(_card)
   }
 
   clickComponent = (e) => {
@@ -153,21 +153,26 @@
 
     card.wrap = res
 
-    if (res.shortcut) {
-      card.loginWays[0].shortcut = res.shortcut
+    let active = 'login'
+    if (res.classify === 'signin') {
+      active = 'signin'
     }
+    this.setState({
+      active
+    })
 
     this.updateComponent(card)
   }
 
   render() {
-    const { card } = this.state
+    const { card, active } = this.state
     let style = resetStyle(card.style)
-    if (card.wrap.maxWidth) {
-      style.maxWidth = card.wrap.maxWidth
+
+    if (card.style.width) {
       let left = style.marginLeft && style.marginLeft !== '0px' ? style.marginLeft : 'auto'
       let right = style.marginRight && style.marginRight !== '0px' ? style.marginRight : 'auto'
       style.margin = (style.marginTop || 0) + ' ' + right + ' ' + (style.marginBottom || 0) + ' ' + left
+      style.maxWidth = `calc(100% - ${style.marginLeft || '0px'} - ${style.marginRight || '0px'})`
       delete style.marginLeft
       delete style.marginRight
       delete style.marginTop
@@ -178,7 +183,7 @@
       <div className="login-edit-box" style={style} onClick={this.clickComponent} id={card.uuid}>
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
-            <NormalForm title="鐧诲綍璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
+            <NormalForm title="娉ㄥ唽/鐧诲綍璁剧疆" width={800} update={this.updateWrap} getForms={this.getWrapForms}>
               <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
             </NormalForm>
             <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
@@ -187,11 +192,25 @@
         } trigger="hover">
           <ToolOutlined />
         </Popover>
-        <LoginForm loginWays={card.loginWays} wrap={card.wrap} />
-        <div className="component-name"><div className="center">{card.name}</div></div>
+        {card.wrap.loginWays && active === 'login' ? <LoginForm wrap={card.wrap} changeway={() => this.setState({active: 'signin'})}/> : null}
+        {card.wrap.signWays && active === 'signin' ? <SignForm wrap={card.wrap} changeway={() => this.setState({active: 'login'})}/> : null}
+        <div className="component-name">
+          <div className="center">
+            <div className="title">{card.name}</div>
+            <div className="content">
+              {card.errors && card.errors.map((err, index) => {
+                if (err.level === 0) {
+                  return <span key={index} className="error">{err.detail}</span>
+                } else {
+                  return <span key={index} className="waring">{err.detail}锛�</span>
+                }
+              })}
+            </div>
+          </div>
+        </div>
       </div>
     )
   }
 }
 
-export default PropCardEditComponent
\ No newline at end of file
+export default LoginComponent
\ No newline at end of file
diff --git a/src/pc/components/login/normal-login/index.scss b/src/pc/components/login/normal-login/index.scss
index 95e396e..e1b347c 100644
--- a/src/pc/components/login/normal-login/index.scss
+++ b/src/pc/components/login/normal-login/index.scss
@@ -7,6 +7,7 @@
   background-repeat: no-repeat;
   background-size: cover;
   min-height: 100px;
+  max-width: 100%;
   
   .card-control {
     position: absolute;
@@ -38,15 +39,35 @@
         background: transparent;
       }
     }
-    button:not(.vercode) {
-      width: 100%;
-      height: 40px;
-      line-height: 1;
-      font-size: 18px;
-      margin-bottom: 15px;
+    .form-item-wrap {
+      .btn-login {
+        // margin-top: 45px;
+        .login-form-button {
+          width: 100%;
+          height: 40px;
+          line-height: 1;
+          font-size: 18px;
+          margin-bottom: 15px;
+          border-radius: 4px;
+        }
+        .sign-form-button {
+          width: 100%;
+          height: 40px;
+          line-height: 1;
+          font-size: 18px;
+          margin-bottom: 15px;
+          border-radius: 30px;
+        }
+      }
     }
     .ant-form-item:last-child {
       margin-bottom: 0;
+    }
+    .mk-jump-way {
+      cursor: pointer;
+      float: right;
+      color: #1890ff;
+      margin-bottom: 15px;
     }
   }
   .login-way-title {
@@ -93,7 +114,10 @@
   .protocol-wrap {
     padding: 0 20px 15px;
     span {
-      font-size: 13px;
+      font-size: 12px;
+    }
+    .ant-checkbox + span {
+      padding-right: 0px;
     }
     .protocol {
       color: #1890ff;
@@ -111,6 +135,53 @@
   }
   .login-ways.center {
     text-align: center;
+  }
+  .sign-ways {
+    clear: both;
+    text-align: center;
+    margin-top: 25px;
+    .title {
+      color: #959595;
+      display: flex;
+      padding: 0 15%;
+    }
+    .title::before, .title::after {
+      display: inline-block;
+      content: ' ';
+      height: 0.5px;
+      flex: 1;
+      background-color: rgba(0, 0, 0, 0.15);
+      position: relative;
+      top: 12px;
+    }
+    .title::before {
+      margin: 0 25px 0 0;
+    }
+    .title::after {
+      margin: 0 0 0 25px;
+    }
+    .content {
+      display: flex;
+      .item {
+        flex: 1;
+        cursor: pointer;
+        padding-top: 10px;
+        .anticon {
+          font-size: 20px;
+          width: 40px;
+          height: 40px;
+          line-height: 45px;
+          border-radius: 40px;
+          background: #e6f7ff;
+          color: #1890ff;
+        }
+        .name {
+          color: #000000;
+          display: block;
+          margin-top: 10px;
+        }
+      }
+    }
   }
 
   .form-scan-wrap {
@@ -157,9 +228,6 @@
 
 .mk-mob-view .login-edit-box {
   display: block;
-  // .login-way-wrap.simple {
-  //   display: none;
-  // }
   .login-way-wrap {
     padding: 0 15px;
     border-radius: 0;
@@ -186,4 +254,9 @@
     border: 0;
     border-radius: 0;
   }
+  .protocol-wrap {
+    span {
+      font-size: 13px;
+    }
+  }
 }
diff --git a/src/pc/components/login/normal-login/loginform.jsx b/src/pc/components/login/normal-login/loginform.jsx
index 0ca5d72..51a1189 100644
--- a/src/pc/components/login/normal-login/loginform.jsx
+++ b/src/pc/components/login/normal-login/loginform.jsx
@@ -12,8 +12,8 @@
 
 class LoginTabForm extends Component {
   static propTpyes = {
-    loginWays: PropTypes.array,
-    wrap: PropTypes.array,
+    wrap: PropTypes.object,
+    changeway: PropTypes.func
   }
 
   state = {
@@ -23,26 +23,41 @@
   }
 
   UNSAFE_componentWillMount () {
-    const { loginWays, wrap } = this.props
+    const { wrap } = this.props
 
-    let _loginWays = []
     let scanWay = null
-    loginWays.forEach(item => {
-      if (!wrap.loginWays || wrap.loginWays.includes(item.type)) {
-        if (item.type === 'sms_vcode') {
-          item.label = '鐭俊鐧诲綍'
-        } else if (item.type === 'uname_pwd') {
-          item.label = '璐﹀彿鐧诲綍'
-        } else if (item.type === 'app_scan') {
-          scanWay = item
+
+    let loginWays = []
+    wrap.loginWays.forEach(way => {
+      if (way === 'sms_vcode') {
+        loginWays.push({
+          type: 'sms_vcode',
+          label: '鐭俊鐧诲綍',
+          tempId: wrap.tempId,
+          sort: 2
+        })
+      } else if (way === 'uname_pwd') {
+        loginWays.push({
+          type: 'uname_pwd',
+          label: '璐﹀彿鐧诲綍',
+          shortcut: wrap.shortcut,
+          sort: 1
+        })
+      } else if (way === 'app_scan') {
+        scanWay = {
+          type: 'app_scan',
+          label: '鎵爜鐧诲綍',
+          sort: 3
         }
-        _loginWays.push(item)
+        loginWays.push(scanWay)
       }
     })
 
+    loginWays.sort((a, b) => a.sort - b.sort)
+
     this.setState({
-      loginWays: _loginWays,
-      activeWay: _loginWays[0],
+      loginWays: loginWays,
+      activeWay: loginWays[0],
       scanWay
     })
   }
@@ -51,24 +66,37 @@
     const { wrap } = this.props
 
     if (!is(fromJS(wrap), fromJS(nextProps.wrap))) {
-      let _loginWays = []
       let scanWay = null
-      nextProps.loginWays.forEach(item => {
-        if (!nextProps.wrap.loginWays || nextProps.wrap.loginWays.includes(item.type)) {
-          if (item.type === 'sms_vcode') {
-            item.label = '鐭俊鐧诲綍'
-          } else if (item.type === 'uname_pwd') {
-            item.label = '璐﹀彿鐧诲綍'
-          } else if (item.type === 'app_scan') {
-            scanWay = item
+      let loginWays = []
+      nextProps.wrap.loginWays.forEach(way => {
+        if (way === 'sms_vcode') {
+          loginWays.push({
+            type: 'sms_vcode',
+            label: '鐭俊鐧诲綍',
+            tempId: wrap.tempId,
+            sort: 2
+          })
+        } else if (way === 'uname_pwd') {
+          loginWays.push({
+            type: 'uname_pwd',
+            label: '璐﹀彿鐧诲綍',
+            shortcut: wrap.shortcut,
+            sort: 1
+          })
+        } else if (way === 'app_scan') {
+          scanWay = {
+            type: 'app_scan',
+            label: '鎵爜鐧诲綍',
+            sort: 3
           }
-          _loginWays.push(item)
+          loginWays.push(scanWay)
         }
       })
+      loginWays.sort((a, b) => a.sort - b.sort)
 
       this.setState({
-        loginWays: _loginWays,
-        activeWay: _loginWays[0],
+        loginWays: loginWays,
+        activeWay: loginWays[0],
         scanWay
       })
     }
@@ -108,6 +136,7 @@
   }
 
   render() {
+    const { wrap } = this.props
     const { activeWay, loginWays, scanWay } = this.state
 
     return (
@@ -167,9 +196,7 @@
           </div>
           璇蜂娇鐢ㄥ鎴风鎵竴鎵櫥褰�
         </div> : null}
-        {/* {wrap.protocol === 'true' ? <div className={'protocol-wrap '}>
-          <Checkbox>{wrap.tip}</Checkbox>{wrap.groups.map((item, i) => (<span className="protocol" key={i}>銆妠item.label}銆�</span>))}
-        </div> : null} */}
+        {wrap.classify !== 'login' ? <span className="mk-jump-way" onClick={() => this.props.changeway()}>娌℃湁璐﹀彿锛屽幓娉ㄥ唽锛�</span> : null}
         <div className={'login-ways ' + (activeWay.type === 'app_scan' ? 'center' : '')}>
           {loginWays.map(item => {
             if (item.type === 'app_scan' || activeWay.type === item.type) return null
diff --git a/src/pc/components/login/normal-login/options.jsx b/src/pc/components/login/normal-login/options.jsx
index bcdbea9..05fa848 100644
--- a/src/pc/components/login/normal-login/options.jsx
+++ b/src/pc/components/login/normal-login/options.jsx
@@ -41,6 +41,70 @@
       required: true
     },
     {
+      type: 'select',
+      field: 'linkmenu',
+      label: '鍏宠仈鑿滃崟',
+      initval: wrap.linkmenu || '',
+      required: true,
+      options: menulist
+    },
+    {
+      type: 'number',
+      field: 'width',
+      label: '瀹藉害',
+      initval: wrap.width || 24,
+      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
+      min: 1,
+      max: 24,
+      precision: 0,
+      required: true
+    },
+    // {
+    //   type: 'number',
+    //   field: 'maxWidth',
+    //   label: '鏈�澶у搴�',
+    //   initval: wrap.maxWidth || '',
+    //   tooltip: '鐧诲綍妗嗙殑鏈�澶у搴﹀�笺��',
+    //   min: 100,
+    //   max: 2000,
+    //   precision: 0,
+    //   required: false
+    // },
+    {
+      type: 'styleInput',
+      field: 'height',
+      label: '楂樺害',
+      initval: wrap.height || '',
+      tooltip: '缁勪欢鍗犵敤鐨勬渶灏忛珮搴︼紝鐢ㄤ簬椤甸潰甯冨眬銆�',
+      required: false,
+      options: ['px', 'vh', 'vw', '%']
+    },
+    {
+      type: 'radio',
+      field: 'classify',
+      label: '缁勪欢绫诲瀷',
+      initval: wrap.classify || 'login',
+      tooltip: '娉ㄥ唽鐧诲綍閮藉瓨鍦ㄦ椂锛屽湪鍏紬鍙蜂笌灏忕▼搴忎腑浼樺厛鏄剧ず娉ㄥ唽锛孉PP涓嶩5涓紭鍏堟樉绀虹櫥褰曘��',
+      required: true,
+      options: [
+        { label: '鐧诲綍', value: 'login' },
+        { label: '娉ㄥ唽', value: 'signin' },
+        { label: '娉ㄥ唽/鐧诲綍', value: 'all' },
+      ],
+      controlFields: [
+        {field: 'loginWays', values: ['login', 'all']},
+        {field: 'logintip', values: ['login', 'all']},
+        {field: 'signWays', values: ['signin', 'all']},
+        {field: 'protocol', values: ['signin', 'all']},
+        {field: 'signtip', values: ['signin', 'all']},
+      ]
+    },
+    {
+      type: 'hint',
+      field: 'logintip',
+      label: '鐧诲綍閰嶇疆'
+    },
+    {
       type: 'checkbox',
       field: 'loginWays',
       label: '鐧诲綍鏂瑰紡',
@@ -57,14 +121,6 @@
       ]
     },
     {
-      type: 'select',
-      field: 'linkmenu',
-      label: '鍏宠仈鑿滃崟',
-      initval: wrap.linkmenu || '',
-      required: true,
-      options: menulist
-    },
-    {
       type: 'select', // $楠岃瘉鐮�$  $mob$  $send_type$
       field: 'tempId',
       label: '鐭俊妯℃澘',
@@ -73,51 +129,6 @@
       required: true,
       options: msgTemps
     },
-    {
-      type: 'number',
-      field: 'width',
-      label: '瀹藉害',
-      initval: wrap.width || 24,
-      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
-      min: 1,
-      max: 24,
-      precision: 0,
-      required: true
-    },
-    {
-      type: 'number',
-      field: 'maxWidth',
-      label: '鏈�澶у搴�',
-      initval: wrap.maxWidth || '',
-      tooltip: '鐧诲綍妗嗙殑鏈�澶у搴﹀�笺��',
-      min: 100,
-      max: 2000,
-      precision: 0,
-      required: false
-    },
-    {
-      type: 'styleInput',
-      field: 'height',
-      label: '楂樺害',
-      initval: wrap.height || '',
-      tooltip: '缁勪欢鍗犵敤鐨勬渶灏忛珮搴︼紝鐢ㄤ簬椤甸潰甯冨眬銆�',
-      required: false,
-      options: ['px', 'vh', 'vw', '%']
-    },
-    // {
-    //   type: 'radio',
-    //   field: 'link',
-    //   label: '閾炬帴',
-    //   initval: wrap.link || 'menu',
-    //   required: false,
-    //   options: [
-    //     {value: 'menu', label: '鑿滃崟'},
-    //     {value: 'linkmenu', label: '鍏宠仈鑿滃崟'},
-    //   ],
-    //   controlFields: [
-    //     {field: 'linkmenu', values: ['linkmenu']}
-    //   ]
-    // },
     {
       type: 'radio',
       field: 'shortcut',
@@ -131,56 +142,86 @@
         {value: 'autologon', label: '鑷姩鐧诲綍'},
       ]
     },
-    // {
-    //   type: 'radio',
-    //   field: 'protocol',
-    //   label: '鍗忚',
-    //   initval: wrap.protocol || 'false',
-    //   required: false,
-    //   options: [
-    //     {value: 'false', label: '鏃�'},
-    //     {value: 'true', label: '鏈�'},
-    //   ],
-    //   controlFields: [
-    //     {field: 'tip', values: ['true']},
-    //     {field: 'groups', values: ['true']},
-    //   ]
-    // },
-    // {
-    //   type: 'text',
-    //   field: 'tip',
-    //   label: '鎻愮ず鏂囧瓧',
-    //   initval: wrap.tip || '鎴戝凡闃呰骞跺悓鎰�',
-    //   required: true
-    // },
-    // {
-    //   type: 'table',
-    //   field: 'groups',
-    //   label: '鍗忚缁�',
-    //   initval: wrap.groups || [],
-    //   required: true,
-    //   span: 24,
-    //   columns: [
-    //     {
-    //       title: '鏂囨湰',
-    //       dataIndex: 'label',
-    //       inputType: 'input',
-    //       editable: true,
-    //       unique: true,
-    //       required: true,
-    //       width: '35%'
-    //     },
-    //     {
-    //       title: '閾炬帴',
-    //       dataIndex: 'link',
-    //       inputType: 'input',
-    //       editable: true,
-    //       unique: true,
-    //       required: true,
-    //       width: '40%'
-    //     },
-    //   ]
-    // }
+    {
+      type: 'hint',
+      field: 'signtip',
+      label: '娉ㄥ唽閰嶇疆'
+    },
+    {
+      type: 'checkbox',
+      field: 'signWays',
+      label: '娉ㄥ唽鏂瑰紡',
+      initval: wrap.signWays || [],
+      tooltip: '寰俊鎺堟潈鍙湪灏忕▼搴忎腑鏈夋晥銆�',
+      required: true,
+      options: [
+        { label: '璐﹀彿', value: 'uname_pwd' },
+        { label: '鐭俊', value: 'sms_vcode' },
+        { label: '寰俊', value: 'weixin', disabled: appType !== 'mob' },
+      ],
+      controlFields: [
+        {field: 'signTempId', values: ['sms_vcode']}
+      ]
+    },
+    {
+      type: 'select', // $楠岃瘉鐮�$  $mob$  $send_type$
+      field: 'signTempId',
+      label: '鐭俊妯℃澘',
+      initval: wrap.signTempId || '',
+      tooltip: '鐭俊妯℃澘鍙湪 浜戠郴缁�->搴旂敤鏈嶅姟->寮�鍙戣�呬腑蹇�->鐭俊妯℃澘 澶勬坊鍔犮��',
+      required: true,
+      options: msgTemps
+    },
+    {
+      type: 'radio',
+      field: 'protocol',
+      label: '鍗忚',
+      initval: wrap.protocol || 'false',
+      required: false,
+      options: [
+        {value: 'false', label: '鏃�'},
+        {value: 'true', label: '鏈�'},
+      ],
+      controlFields: [
+        {field: 'tip', values: ['true']},
+        {field: 'groups', values: ['true']},
+      ]
+    },
+    {
+      type: 'text',
+      field: 'tip',
+      label: '鎻愮ず鏂囧瓧',
+      initval: wrap.tip || '鎴戝凡闃呰骞跺悓鎰�',
+      required: true
+    },
+    {
+      type: 'table',
+      field: 'groups',
+      label: '鍗忚缁�',
+      initval: wrap.groups || [],
+      required: true,
+      span: 24,
+      columns: [
+        {
+          title: '鏂囨湰',
+          dataIndex: 'label',
+          inputType: 'input',
+          editable: true,
+          unique: true,
+          required: true,
+          width: '35%'
+        },
+        {
+          title: '閾炬帴',
+          dataIndex: 'link',
+          inputType: 'input',
+          editable: true,
+          unique: true,
+          required: true,
+          width: '40%'
+        },
+      ]
+    }
   ]
 
   return wrapForm
diff --git a/src/pc/components/login/normal-login/signform.jsx b/src/pc/components/login/normal-login/signform.jsx
new file mode 100644
index 0000000..9410986
--- /dev/null
+++ b/src/pc/components/login/normal-login/signform.jsx
@@ -0,0 +1,217 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Form, Input, Button, notification, Checkbox } from 'antd'
+import { UserOutlined, LockOutlined, MobileOutlined, WechatOutlined } from '@ant-design/icons'
+
+import MKEmitter from '@/utils/events.js'
+import './index.scss'
+
+class LoginTabForm extends Component {
+  static propTpyes = {
+    wrap: PropTypes.object,
+    changeway: PropTypes.func
+  }
+
+  state = {
+    activeWay: null,
+    appType: sessionStorage.getItem('appType'),
+    signWays: []
+  }
+
+  UNSAFE_componentWillMount () {
+    const { wrap } = this.props
+
+    let signWays = []
+    wrap.signWays.forEach(way => {
+      if (way === 'sms_vcode') {
+        signWays.push({
+          type: 'sms_vcode',
+          label: '鎵嬫満鍙锋敞鍐�',
+          icon: <MobileOutlined />,
+          tempId: wrap.signTempId,
+          sort: 2
+        })
+      } else if (way === 'uname_pwd') {
+        signWays.push({
+          type: 'uname_pwd',
+          label: '璐﹀彿娉ㄥ唽',
+          icon: <LockOutlined />,
+          sort: 1
+        })
+      } else if (way === 'weixin') {
+        signWays.push({
+          type: 'weixin',
+          label: '寰俊鐧诲綍',
+          icon: <WechatOutlined />,
+          sort: 3
+        })
+      }
+    })
+
+    signWays.sort((a, b) => a.sort - b.sort)
+
+    this.setState({
+      signWays: signWays,
+      activeWay: signWays[0]
+    })
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    const { wrap } = this.props
+
+    if (!is(fromJS(wrap), fromJS(nextProps.wrap))) {
+      let signWays = []
+      nextProps.wrap.signWays.forEach(way => {
+        if (way === 'sms_vcode') {
+          signWays.push({
+            type: 'sms_vcode',
+            label: '鎵嬫満鍙锋敞鍐�',
+            tempId: nextProps.wrap.signTempId,
+            sort: 2
+          })
+        } else if (way === 'uname_pwd') {
+          signWays.push({
+            type: 'uname_pwd',
+            label: '璐﹀彿娉ㄥ唽',
+            sort: 1
+          })
+        } else if (way === 'weixin') {
+          signWays.push({
+            type: 'weixin',
+            label: '寰俊鐧诲綍',
+            sort: 3
+          })
+        }
+      })
+
+      signWays.sort((a, b) => a.sort - b.sort)
+
+      this.setState({
+        signWays: signWays,
+        activeWay: signWays[0]
+      })
+    }
+  }
+
+  onChangeTab = (activeWay) => {
+    if (activeWay.type === 'weixin') return
+
+    this.setState({activeWay})
+  }
+
+  changeMenu = () => {
+    const { wrap } = this.props
+
+    if (!wrap.linkmenu) {
+      notification.warning({
+        top: 92,
+        message: '璇疯缃叧鑱旇彍鍗曪紒',
+        duration: 5
+      })
+      return
+    }
+
+    MKEmitter.emit('changeEditMenu', {
+      MenuID: wrap.linkmenu,
+      copyMenuId: '',
+      MenuNo: '',
+      MenuName: ''
+    })
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  render() {
+    const { wrap } = this.props
+    const { activeWay, signWays, appType } = this.state
+
+    return (
+      <Form className="login-edit-form">
+        {appType === 'pc' ? <div className="login-way-title">{activeWay.label}</div> : null}
+        {activeWay.type === 'uname_pwd' ? <div className="form-item-wrap">
+          <Form.Item>
+            <Input
+              prefix={<UserOutlined style={{ color: 'rgba(0,0,0,.25)' }} />}
+              placeholder="鐢ㄦ埛鍚�"
+              autoComplete="off"
+            />
+          </Form.Item>
+          <Form.Item>
+            <Input.Password placeholder="瀵嗙爜" prefix={<LockOutlined style={{ color: 'rgba(0,0,0,.25)' }} />} />
+          </Form.Item>
+          {wrap.groups ? <div className="protocol-wrap">
+            <Checkbox>{wrap.tip}</Checkbox>{wrap.groups.map((item, i) => (<span><span className="protocol" key={i}>銆妠item.label}銆�</span>{wrap.groups.length > i + 1 ? (wrap.groups.length > i + 2 ? '銆�' : '鍜�') : null}</span>))}
+          </div> : null}
+          <Form.Item className="btn-login">
+            <Button type="primary" onDoubleClick={() => this.changeMenu()} className="sign-form-button">
+            娉ㄥ唽
+            </Button>
+          </Form.Item>
+        </div> : null}
+        {activeWay.type === 'sms_vcode' ? <div className="form-item-wrap">
+          <Form.Item>
+            <Input
+              placeholder="鎵嬫満鍙�"
+              autoComplete="off"
+            />
+          </Form.Item>
+          <Form.Item style={{marginBottom: wrap.groups ? '15px' : '35px'}}>
+            <Input
+              addonAfter={
+                <Button type="link" className="vercode" size="small">
+                  鑾峰彇楠岃瘉鐮�
+                </Button>
+              }
+              placeholder="楠岃瘉鐮�"
+              autoComplete="off"
+            />
+          </Form.Item>
+          {wrap.groups ? <div className="protocol-wrap">
+            <Checkbox>{wrap.tip}</Checkbox>{wrap.groups.map((item, i) => (<span><span className="protocol" key={i}>銆妠item.label}銆�</span>{wrap.groups.length > i + 1 ? (wrap.groups.length > i + 2 ? '銆�' : '鍜�') : null}</span>))}
+          </div> : null}
+          <Form.Item className="btn-login">
+            <Button type="primary" onDoubleClick={() => this.changeMenu()} className="sign-form-button">
+              娉ㄥ唽
+            </Button>
+          </Form.Item>
+        </div> : null}
+        {activeWay.type === 'weixin' ? <div className="form-item-wrap">
+          <Form.Item className="btn-login" style={{marginBottom: wrap.groups ? '0px' : '15px'}}>
+            <Button type="primary" onDoubleClick={() => this.changeMenu()} className="sign-form-button">
+              寰俊涓�閿櫥褰�
+            </Button>
+          </Form.Item>
+          {wrap.groups ? <div className="protocol-wrap">
+            <Checkbox>{wrap.tip}</Checkbox>{wrap.groups.map((item, i) => (<span><span className="protocol" key={i}>銆妠item.label}銆�</span>{wrap.groups.length > i + 1 ? (wrap.groups.length > i + 2 ? '銆�' : '鍜�') : null}</span>))}
+          </div> : null}
+        </div> : null}
+        {wrap.classify !== 'signin' ? <span className="mk-jump-way" onClick={() => this.props.changeway()}>宸叉湁璐﹀彿锛屽幓鐧婚檰锛�</span> : null}
+        {appType === 'mob' && signWays.length > 1 ? <div className="sign-ways">
+          <div className="title">鍏朵粬娉ㄥ唽鏂瑰紡</div>
+          <div className="content">
+            {signWays.map((item, i) => {
+              if (activeWay.type === item.type) return null
+              return (<div key={i} className="item" onClick={() => this.onChangeTab(item)}>{item.icon}<span className="name">{item.label}</span></div>)
+            })}
+          </div>
+        </div> : null}
+        {appType === 'pc' && signWays.length > 1 ? <div className="login-ways">
+          {signWays.map(item => {
+            if (activeWay.type === item.type) return null
+            return (<span key={item.type} onClick={() => this.onChangeTab(item)}>{item.label}</span>)
+          })}
+        </div> : null}
+      </Form>
+    )
+  }
+}
+
+export default LoginTabForm
\ No newline at end of file
diff --git a/src/pc/menushell/card.jsx b/src/pc/menushell/card.jsx
index bd25267..7ecb332 100644
--- a/src/pc/menushell/card.jsx
+++ b/src/pc/menushell/card.jsx
@@ -17,7 +17,8 @@
 const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table'))
 const EditTable = asyncComponent(() => import('@/menu/components/table/edit-table'))
 const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group'))
-const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form'))
+const SimpleForm = asyncComponent(() => import('@/menu/components/form/simple-form'))
+const StepForm = asyncComponent(() => import('@/menu/components/form/step-form'))
 const TabForm = asyncComponent(() => import('@/menu/components/form/tab-form'))
 const BraftEditor = asyncComponent(() => import('@/menu/components/editor/braft-editor'))
 const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox'))
@@ -84,8 +85,10 @@
       return (<AntvBar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'navbar') {
       return (<NormalNavbar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+    } else if (card.type === 'form' && card.subtype === 'simpleform') {
+      return (<SimpleForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'form' && card.subtype === 'stepform') {
-      return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
+      return (<StepForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'form' && card.subtype === 'tabform') {
       return (<TabForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
     } else if (card.type === 'search') {
diff --git a/src/pc/modulesource/option.jsx b/src/pc/modulesource/option.jsx
index 9214203..4795fe3 100644
--- a/src/pc/modulesource/option.jsx
+++ b/src/pc/modulesource/option.jsx
@@ -60,5 +60,5 @@
   { type: 'menu', url: Editor, component: 'editor', subtype: 'brafteditor', title: '瀵屾枃鏈�', width: 24 },
   { 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: Login, component: 'login', subtype: 'normallogin', title: '娉ㄥ唽/鐧诲綍', width: 24 },
 ]
diff --git a/src/router/index.js b/src/router/index.js
index 444f1bb..434fcd4 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -18,10 +18,12 @@
 const MobDesign = asyncLoadComponent(() => import('@/views/mobdesign'))
 const ImDesign = asyncLoadComponent(() => import('@/views/imdesign'))
 const MenuDesign = asyncLoadComponent(() => import('@/views/menudesign'))
+const BaseDesign = asyncLoadComponent(() => import('@/views/basedesign'))
 const BillPrint = asyncLoadComponent(() => import('@/views/billprint'))
 const PrintT = asyncLoadComponent(() => import('@/views/printTemplate'))
 const Interface = asyncLoadComponent(() => import('@/views/interface'))
 const RoleManage = asyncLoadComponent(() => import('@/views/rolemanage'))
+const SystemFunc = asyncLoadComponent(() => import('@/views/systemfunc'))
 
 const routers = [
   {path: '/login', name: 'login', component: Login, auth: false},
@@ -36,11 +38,13 @@
   {path: '/mobdesign/:param', name: 'mobdesign', component: MobDesign, auth: true},
   {path: '/imdesign/:param', name: 'imdesign', component: ImDesign, auth: true},
   {path: '/menudesign/:param', name: 'menudesign', component: MenuDesign, auth: true},
+  {path: '/basedesign/:param', name: 'basedesign', component: BaseDesign, auth: true},
   {path: '/billprint/:param', name: 'billprint', component: BillPrint, auth: true},
   {path: '/docprint/:menuId', name: 'docprint', component: BillPrint, auth: false},
   {path: '/docprint/:menuId/:id', name: 'docprint', component: BillPrint, auth: false},
   {path: '/paramsmain/:param', name: 'pmain', component: Main, auth: true},
   {path: '/role/:param', name: 'role', component: RoleManage, auth: true},
+  {path: '/hs', name: 'hs', component: SystemFunc, auth: true},
   {path: '/interface', name: 'interface', component: Interface, auth: true}
 ]
 
diff --git a/src/setupProxy.js b/src/setupProxy.js
index 3902dd3..4d69c53 100644
--- a/src/setupProxy.js
+++ b/src/setupProxy.js
@@ -1,9 +1,7 @@
-// const proxy = require('http-proxy-middleware')
-// const host = 'http://qingqiumarket.cn'
-// const service = 'mkwms/'
+const proxy = require('http-proxy-middleware')
+const options = require('../public/options.json')
 
-module.exports = function(app) {}
-// module.exports = function(app) {
+module.exports = function(app) {
 //   app.use(proxy('/webapi', { 
 //     target: `${host}/${service}webapi`,
 //     secure: false,
@@ -32,14 +30,11 @@
 //     }
 //   }))
 
-//   app.use(proxy('/wxpay', {
-//     target: `${host}/${service}wxpay`,
-//     secure: false,
-//     changeOrigin: true,
-//     pathRewrite: {
-//     '^/wxpay': '/'
-//     }
-//   }))
+  app.use(proxy('/wxpay', {
+    target: `${options.host}/${options.service}`,
+    secure: false,
+    changeOrigin: true
+  }))
 
 //   app.use(proxy('/trans', {
 //     target: `${host}/${service}`,
@@ -52,4 +47,4 @@
 //     secure: false,
 //     changeOrigin: true
 //   }))
-// }
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/store/action-type.js b/src/store/action-type.js
index 13cba48..c65f4df 100644
--- a/src/store/action-type.js
+++ b/src/store/action-type.js
@@ -19,8 +19,5 @@
 // 鍒濆鍖栬彍鍗曟潈闄�
 export const INIT_MENUPERMISSION = 'INIT_MENUPERMISSION'
 
-// 淇敼浼氬憳绛夌骇
-export const MODIFY_MEMBERLEVEL = 'MODIFY_MEMBERLEVEL'
-
 // 閫�鍑�
 export const LOGOUT = 'LOGOUT'
\ No newline at end of file
diff --git a/src/store/action.js b/src/store/action.js
index 5fed87e..b4bbf15 100644
--- a/src/store/action.js
+++ b/src/store/action.js
@@ -48,14 +48,6 @@
   }
 }
 
-// 鍒濆鍖栬彍鍗曟潈闄�
-export const modifyMemberLevel = (memberLevel) => {
-  return {
-    type: user.MODIFY_MEMBERLEVEL,
-    memberLevel: memberLevel
-  }
-}
-
 // 閫�鍑洪噸缃�
 export const logout = () => {
   return {
diff --git a/src/store/reducer.js b/src/store/reducer.js
index e262dfa..15db885 100644
--- a/src/store/reducer.js
+++ b/src/store/reducer.js
@@ -1,22 +1,9 @@
-import md5 from 'md5'
-import moment from 'moment'
 import * as Type from './action-type'
 
 let _mainMenu = null
 let _url = window.location.href.split('#')[0]
 let _collapse = localStorage.getItem('collapse') === 'true'
-let _level = 10
-let _Mlevel = sessionStorage.getItem('Member_Level')
 
-if (_Mlevel) {
-  if (_Mlevel === md5('mksoft' + moment().format('YYYYMM') + 10)) {
-    _level = 10
-  } else if (_Mlevel === md5('mksoft' + moment().format('YYYYMM') + 20)) {
-    _level = 20
-  } else if (_Mlevel === md5('mksoft' + moment().format('YYYYMM') + 30)) {
-    _level = 30
-  }
-}
 if (localStorage.getItem(_url + '-sideHidden') === 'true') {
   _mainMenu = ''
 }
@@ -28,7 +15,6 @@
   editLevel: null,      // 缂栬緫鑿滃崟绾у埆锛屽�间负level1銆乴evel2銆乴evel3銆丠S
   permAction: {},       // 鐢ㄦ埛鎸夐挳鏉冮檺
   permMenus: [],        // 鐢ㄦ埛涓夌骇鑿滃崟鍒楄〃
-  memberLevel: _level,  // 浼氬憳绛夌骇
 }
 
 // 鐢ㄦ埛娑堟伅
@@ -69,12 +55,6 @@
       return {
         ...state,
         permMenus: action.permMenus
-      }
-    case Type.MODIFY_MEMBERLEVEL:
-      // 淇敼浼氬憳绛夌骇
-      return {
-        ...state,
-        memberLevel: action.memberLevel
       }
     case Type.LOGOUT:
       return {
diff --git a/src/tabviews/calendar/index.jsx b/src/tabviews/calendar/index.jsx
index d78d54d..76671e6 100644
--- a/src/tabviews/calendar/index.jsx
+++ b/src/tabviews/calendar/index.jsx
@@ -76,7 +76,7 @@
       }
       
       // HS涓嶄娇鐢ㄨ嚜瀹氫箟璁剧疆
-      if (result.LongParamUser && this.props.menuType !== 'HS') {
+      if (result.LongParamUser && !window.GLOB.mkHS) {
         try { // 閰嶇疆淇℃伅瑙f瀽
           userConfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParamUser)))
           _curUserConfig = userConfig[this.props.MenuID]
@@ -106,7 +106,7 @@
       }
 
       // 鏉冮檺杩囨护
-      if (this.props.menuType !== 'HS') {
+      if (!window.GLOB.mkHS) {
         if (config.tab && !permAction[config.tab.linkTab]) {
           config.tab = null
         }
@@ -125,7 +125,7 @@
       // 瀛楁閫忚
       let hasReqFields = false
       config.search = config.search.map(item => {
-        if (['text', 'select', 'link'].includes(item.type) && param.$searchkey === item.field) {
+        if (param && ['text', 'select', 'link'].includes(item.type) && param.$searchkey === item.field) {
           item.initval = param.$searchval
         }
 
@@ -168,7 +168,6 @@
 
         let userName = sessionStorage.getItem('User_Name') || ''
         let fullName = sessionStorage.getItem('Full_Name') || ''
-        let city = sessionStorage.getItem('city') || ''
 
         if (sessionStorage.getItem('isEditState') === 'true') {
           userName = sessionStorage.getItem('CloudUserName') || ''
@@ -177,8 +176,7 @@
 
         let regs = [
           { reg: /@userName@/ig, value: `'${userName}'` },
-          { reg: /@fullName@/ig, value: `'${fullName}'` },
-          { reg: /@login_city@/ig, value: `'${city}'` }
+          { reg: /@fullName@/ig, value: `'${fullName}'` }
         ]
 
         regs.forEach(cell => {
@@ -300,7 +298,7 @@
     if (setting.interType === 'inner') {
       param.func = setting.innerFunc
     } else {
-      if (this.props.menuType === 'HS') {
+      if (window.GLOB.mkHS) {
         if (setting.sysInterface === 'true' && options.cloudServiceApi) {
           param.rduri = options.cloudServiceApi
         } else if (setting.sysInterface !== 'true') {
@@ -347,7 +345,12 @@
     let RoleID = sessionStorage.getItem('role_id') || ''
     let departmentcode = sessionStorage.getItem('departmentcode') || ''
     let organization = sessionStorage.getItem('organization') || ''
+    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+    let nation = sessionStorage.getItem('nation') || ''
+    let province = sessionStorage.getItem('province') || ''
     let city = sessionStorage.getItem('city') || ''
+    let district = sessionStorage.getItem('district') || ''
+    let address = sessionStorage.getItem('address') || ''
 
     if (sessionStorage.getItem('isEditState') === 'true') {
       userName = sessionStorage.getItem('CloudUserName') || ''
@@ -363,9 +366,6 @@
         }
       })
       regoptions.push({
-        reg: new RegExp('@login_city@', 'ig'),
-        value: city
-      }, {
         reg: new RegExp('@userName@', 'ig'),
         value: userName
       }, {
@@ -403,8 +403,8 @@
         param.custom_script = param.custom_script.replace(item.reg, item.value)
       })
       
-      param.custom_script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50)
-        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+      param.custom_script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100)
+        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
         ${param.custom_script}
       `
 
@@ -435,7 +435,7 @@
     param.secretkey = Utils.encrypt(param.LText, param.timestamp)
     param.DateCount = ''
 
-    if (this.props.menuType === 'HS') { // 浜戠鏁版嵁楠岃瘉
+    if (window.GLOB.mkHS) { // 浜戠鏁版嵁楠岃瘉
       param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
     }
 
@@ -538,17 +538,16 @@
   }
 
   render() {
-    const { menuType } = this.props
     const { BID, setting, searchlist, loadingview, viewlost, config, loading, data, triggerTime } = this.state
 
     return (
       <div className="calendar-page" id={this.state.ContainerId}>
         {loadingview && <Spin size="large" />}
         {searchlist && searchlist.length > 0 ?
-          <MainSearch BID={BID} searchlist={searchlist} setting={setting} menuType={menuType} refreshdata={this.refreshbysearch}/> : null
+          <MainSearch BID={BID} searchlist={searchlist} setting={setting} refreshdata={this.refreshbysearch}/> : null
         }
         {config && config.calendar ? <CalendarComponent calendar={config.calendar} loading={loading} data={data} triggerDate={this.triggerDate} changeDate={this.changeDate}/> : null}
-        {menuType !== 'HS' && window.GLOB.systemType !== 'production' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
+        {!window.GLOB.mkHS && window.GLOB.systemType !== 'production' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
         <Modal
           title={config.tab ? config.tab.label : ''}
           width={'80vw'}
@@ -575,7 +574,6 @@
 
 const mapStateToProps = (state) => {
   return {
-    menuType: state.editLevel,
     permAction: state.permAction
   }
 }
diff --git a/src/tabviews/commontable/index.jsx b/src/tabviews/commontable/index.jsx
index b16e840..255c26d 100644
--- a/src/tabviews/commontable/index.jsx
+++ b/src/tabviews/commontable/index.jsx
@@ -100,7 +100,7 @@
       }
       
       // HS涓嶄娇鐢ㄨ嚜瀹氫箟璁剧疆
-      if (result.LongParamUser && this.props.menuType !== 'HS') {
+      if (result.LongParamUser && !window.GLOB.mkHS) {
         try { // 閰嶇疆淇℃伅瑙f瀽
           let userConfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParamUser)))
           if (userConfig && !userConfig.version) {
@@ -158,7 +158,7 @@
       config = updateCommonTable(config)
 
       // 鏉冮檺杩囨护
-      if (this.props.menuType !== 'HS') {
+      if (!window.GLOB.mkHS) {
         config.action = config.action.filter(item => item.hidden !== 'true' && permAction[item.uuid])
         config.tabgroups.forEach(group => {
           group.sublist = group.sublist.filter(tab => {
@@ -264,7 +264,6 @@
 
         let userName = sessionStorage.getItem('User_Name') || ''
         let fullName = sessionStorage.getItem('Full_Name') || ''
-        let city = sessionStorage.getItem('city') || ''
 
         if (sessionStorage.getItem('isEditState') === 'true') {
           userName = sessionStorage.getItem('CloudUserName') || ''
@@ -273,8 +272,7 @@
 
         let regs = [
           { reg: /@userName@/ig, value: `'${userName}'` },
-          { reg: /@fullName@/ig, value: `'${fullName}'` },
-          { reg: /@login_city@/ig, value: `'${city}'` }
+          { reg: /@fullName@/ig, value: `'${fullName}'` }
         ]
 
         regs.forEach(cell => {
@@ -324,6 +322,7 @@
         }
         
         if (item.position === 'toolbar') {
+          item.$toolbtn = true
           _actions.push(item)
         } else if (item.position === 'grid') {
           _operations.push(item)
@@ -539,7 +538,7 @@
   loadOutResource = () => {
     const { setting, search, BID } = this.state
 
-    let param = UtilsDM.getPrevQueryParams(setting, search, BID, this.props.menuType)
+    let param = UtilsDM.getPrevQueryParams(setting, search, BID)
 
     if (setting.execType === 'sync') {
       this.setState({
@@ -631,7 +630,7 @@
   }
 
   customCallbackRequest = (result) => {
-    const { setting } = this.state
+    const { setting, BID } = this.state
     let errSql = ''
     if (result.$ErrCode === 'E') {
       errSql = `
@@ -653,13 +652,13 @@
       `))
       sql = sql.join('')
       
-      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql)
+      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql, BID)
 
-      if (this.state.BID) {
-        param.BID = this.state.BID
+      if (BID) {
+        param.BID = BID
       }
 
-      if (this.props.menuType === 'HS') { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
+      if (window.GLOB.mkHS) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
         param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
       }
     } else {
@@ -714,7 +713,7 @@
     })
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getQueryDataParams(setting, arr_field, search, _orderBy, pageIndex, pageSize, BID, this.props.menuType)
+    let param = UtilsDM.getQueryDataParams(setting, arr_field, search, _orderBy, pageIndex, pageSize, BID)
 
     let result = await Api.genericInterface(param)
 
@@ -798,7 +797,7 @@
     })
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getQueryDataParams(setting, arr_field, search, _orderBy, pageIndex, pageSize, BID, this.props.menuType, id)
+    let param = UtilsDM.getQueryDataParams(setting, arr_field, search, _orderBy, pageIndex, pageSize, BID, id)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -866,7 +865,7 @@
     if (statFields.length === 0 || !(setting.interType === 'system' || (setting.interType === 'custom' && setting.requestMode === 'system')) || !setting.dataresource) return
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getStatQueryDataParams(setting, statFields, search, _orderBy, BID, this.props.menuType)
+    let param = UtilsDM.getStatQueryDataParams(setting, statFields, search, _orderBy, BID)
 
     Api.genericInterface(param).then(res => {
       if (res.status) {
@@ -1125,14 +1124,14 @@
   }
 
   render() {
-    const { menuType, MenuID } = this.props
+    const { MenuID } = this.props
     const { BID, setting, searchlist, pageSize, actions, columns, loadingview, viewlost, pickup, config, chartId, search, selectedData, shortcuts, autoMatic } = this.state
 
     return (
       <div className="commontable" id={this.state.ContainerId}>
         {loadingview ? <Spin size="large" /> : null}
         {searchlist && searchlist.length ?
-          <MainSearch BID={BID} searchlist={searchlist} setting={setting} menuType={this.props.menuType} refreshdata={this.refreshbysearch}/> : null
+          <MainSearch BID={BID} searchlist={searchlist} setting={setting} refreshdata={this.refreshbysearch}/> : null
         }
         {setting && config.charts ? <Row className="chart-view" gutter={16}>
           {/* 瑙嗗浘缁� */}
@@ -1273,9 +1272,9 @@
             })}
           </Tabs>))
         }
-        {menuType !== 'HS' && autoMatic ? <AutoMatic autoMatic={autoMatic} config={config} /> : null}
-        {menuType !== 'HS' && window.GLOB.systemType !== 'production' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
-        {menuType !== 'HS' && shortcuts ? <SettingComponent config={config} dict={this.state.dict} shortcuts={shortcuts} permAction={this.props.permAction}/> : null}
+        {!window.GLOB.mkHS && autoMatic ? <AutoMatic autoMatic={autoMatic} config={config} /> : null}
+        {!window.GLOB.mkHS && window.GLOB.systemType !== 'production' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
+        {!window.GLOB.mkHS && shortcuts ? <SettingComponent config={config} dict={this.state.dict} shortcuts={shortcuts} permAction={this.props.permAction}/> : null}
         {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
       </div>
     )
@@ -1284,7 +1283,6 @@
 
 const mapStateToProps = (state) => {
   return {
-    menuType: state.editLevel,
     permAction: state.permAction,
     permMenus: state.permMenus
   }
diff --git a/src/tabviews/custom/components/card/balcony/index.jsx b/src/tabviews/custom/components/card/balcony/index.jsx
index 313f2b9..43ec2d1 100644
--- a/src/tabviews/custom/components/card/balcony/index.jsx
+++ b/src/tabviews/custom/components/card/balcony/index.jsx
@@ -18,7 +18,6 @@
     BID: PropTypes.any,
     data: PropTypes.array,
     config: PropTypes.object,
-    menuType: PropTypes.any,
   }
 
   state = {
@@ -65,7 +64,7 @@
 
     if (_config.wrap.position === 'fixed' || _config.wrap.position === 'absolute') {
       _config.style.position = _config.wrap.position
-      _config.style.zIndex = 2
+      _config.style.zIndex = 3
       _config.style.left = _config.wrap.left || ''
       _config.style.right = _config.wrap.right || ''
       _config.style.top = _config.wrap.top || ''
@@ -73,7 +72,7 @@
       _config.style.transform = _config.wrap.transform || ''
       _config.style.width = _config.wrap.realwidth || ''
     } else {
-      _config.style.zIndex = 2
+      _config.style.zIndex = 3
       _config.style.left = _config.wrap.left || ''
       _config.style.right = _config.wrap.right || ''
       _config.style.top = _config.wrap.top || ''
@@ -91,11 +90,8 @@
         }
         return item
       })
-    } else if (_config.wrap.linkType === 'sup') {
-      _config.wrap.supModule = _config.wrap.supModule.pop()
-      if (_config.wrap.supControl === 'hidden') {
-        show = false
-      }
+    } else if (_config.wrap.linkType === 'sup' && _config.wrap.supControl === 'hidden') {
+      show = false
     }
 
     this.setState({
@@ -194,22 +190,30 @@
         })
         return
       } else if (result.run_type) {
-        this.setState({timer})
+        let repeats = config.timerRepeats || 0
+        this.setState({timer, repeats})
         this.timer = setTimeout(() => {
-          this.timerTask()
+          this.timerTask(repeats)
         }, timer)
       }
     })
   }
 
-  timerTask = () => {
-    const { timer } = this.state
+  timerTask = (times) => {
+    const { timer, repeats } = this.state
     if (!timer) return
     
     this.loadData(true)
 
+    if (repeats) {
+      times = times - 1
+      if (times <= 0) {
+        clearTimeout(this.timer)
+        return
+      }
+    }
     this.timer = setTimeout(() => {
-      this.timerTask()
+      this.timerTask(times)
     }, timer)
   }
 
@@ -229,20 +233,10 @@
 
       this.loadData()
     } else {
-      let supModule = config.wrap.supModule
-
-      btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-      if (!btn.syncComponentId || btn.syncComponentId !== supModule) {
-        if (position === 'mainline' || position === 'popclose') { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
-          if (supModule && BID) {
-            MKEmitter.emit('reloadData', supModule, BID)
-          } else {
-            this.loadData()
-          }
-        } else {
-          this.loadData()
-        }
+      if ((position === 'mainline' || position === 'popclose') && config.wrap.supModule && BID) { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
+        MKEmitter.emit('reloadData', config.wrap.supModule, BID)
+      } else {
+        this.loadData()
       }
       
       if (position === 'popclose') {                                      // 鏍囩鍏抽棴鍒锋柊
@@ -310,7 +304,6 @@
   }
 
   async loadData (hastimer) {
-    const { menuType } = this.props
     const { config, arr_field, BID, BData } = this.state
 
     if (config.wrap.datatype === 'static') {
@@ -334,7 +327,7 @@
     }
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
diff --git a/src/tabviews/custom/components/card/cardItem/index.jsx b/src/tabviews/custom/components/card/cardItem/index.jsx
index a5a6694..6ba7e42 100644
--- a/src/tabviews/custom/components/card/cardItem/index.jsx
+++ b/src/tabviews/custom/components/card/cardItem/index.jsx
@@ -44,7 +44,7 @@
   openView = () => {
     const { card, data, cards } = this.props
 
-    if (!card.setting.click) return
+    if (!card.setting.click || data.$disabled) return
 
     if (card.setting.click === 'menus' && cards.subtype === 'datacard' && card.$cardType !== 'extendCard') {
       let menu = null
@@ -135,11 +135,11 @@
       window.open(src)
     } else if (card.setting.click === 'button' && card.setting.clickType !== 'multi' && card.setting.linkbtn) {
       if (data.$$type === 'extendCard') {
-        MKEmitter.emit('triggerBtnId', card.setting.linkbtn, [])
+        MKEmitter.emit('triggerBtnId', card.setting.linkbtn, data.$$selectedData || [])
       } else if (cards.subtype === 'datacard') {
         MKEmitter.emit('triggerBtnId', card.setting.linkbtn, [data], 'linkbtn')
       } else {
-        MKEmitter.emit('triggerBtnId', card.setting.linkbtn, [data])
+        MKEmitter.emit('triggerBtnId', card.setting.linkbtn, data.$$empty ? [] : [data])
       }
     }
   }
@@ -147,15 +147,15 @@
   doubleClick = () => {
     const { card, data, cards } = this.props
 
-    if (card.setting.click !== 'button' || card.setting.clickType !== 'multi') return
+    if (card.setting.click !== 'button' || card.setting.clickType !== 'multi' || data.$disabled) return
 
     if (card.setting.linkbtn) {
       if (data.$$type === 'extendCard') {
-        MKEmitter.emit('triggerBtnId', card.setting.linkbtn, [])
+        MKEmitter.emit('triggerBtnId', card.setting.linkbtn, data.$$selectedData || [])
       } else if (cards.subtype === 'datacard') {
         MKEmitter.emit('triggerBtnId', card.setting.linkbtn, [data], 'linkbtn')
       } else {
-        MKEmitter.emit('triggerBtnId', card.setting.linkbtn, [data])
+        MKEmitter.emit('triggerBtnId', card.setting.linkbtn, data.$$empty ? [] : [data])
       }
     }
   }
diff --git a/src/tabviews/custom/components/card/cardcellList/index.jsx b/src/tabviews/custom/components/card/cardcellList/index.jsx
index 34c8fe2..00b8a4e 100644
--- a/src/tabviews/custom/components/card/cardcellList/index.jsx
+++ b/src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Col, Tooltip, notification } from 'antd'
+import { Col, Tooltip, notification, Typography } from 'antd'
 import moment from 'moment'
 
 // import Api from '@/api'
@@ -13,6 +13,7 @@
 import LostPng from '@/assets/img/lost.png'
 import './index.scss'
 
+const { Paragraph } = Typography
 const NormalButton = asyncComponent(() => import('@/tabviews/zshare/actionList/normalbutton'))
 const ExcelInButton = asyncComponent(() => import('@/tabviews/zshare/actionList/excelInbutton'))
 const ExcelOutButton = asyncComponent(() => import('@/tabviews/zshare/actionList/exceloutbutton'))
@@ -22,6 +23,7 @@
 const ChangeUserButton = asyncComponent(() => import('@/tabviews/zshare/actionList/changeuserbutton'))
 const PrintButton = asyncComponent(() => import('@/tabviews/zshare/actionList/printbutton'))
 const FuncMegvii = asyncComponent(() => import('@/tabviews/zshare/actionList/funcMegvii'))
+const FuncZip = asyncComponent(() => import('@/tabviews/zshare/actionList/funczip'))
 const BarCode = asyncElementComponent(() => import('@/components/barcode'))
 const QrCode = asyncElementComponent(() => import('@/components/qrcode'))
 const MkProgress = asyncElementComponent(() => import('@/components/mkProgress'))
@@ -261,11 +263,11 @@
 
       if (card.datatype === 'static') {
         val = card.value || ''
-        if (/@username@|@fullName@|@login_city@/ig.test(val)) {
+        if (/@username@|@fullName@|@mk_city@/ig.test(val)) {
           let userName = sessionStorage.getItem('User_Name') || ''
           let fullName = sessionStorage.getItem('Full_Name') || ''
           let city = sessionStorage.getItem('city') || ''
-          val = val.replace(/@username@/ig, userName).replace(/@fullName@/ig, fullName).replace(/@login_city@/ig, city)
+          val = val.replace(/@username@/ig, userName).replace(/@fullName@/ig, fullName).replace(/@mk_city@/ig, city)
         }
       } else if (data.hasOwnProperty(card.field)) {
         val = data[card.field]
@@ -335,11 +337,15 @@
       }
 
       if (val !== '') {
+        let orival = val
         if (card.fixStyle === 'alone') {
           let _s = {fontSize: card.fixSize, color: card.fixColor, marginLeft: card.fixLeft, marginRight: card.fixRight}
           val = <><span style={_s}>{card.prefix || ''}</span>{val}<span style={_s}>{card.postfix || ''}</span></>
         } else {
           val = `${card.prefix || ''}${val}${card.postfix || ''}`
+        }
+        if (card.copyable === 'true') {
+          val = <Paragraph copyable={{ text: orival }}>{val}</Paragraph>
         }
       }
 
@@ -350,9 +356,9 @@
 
         if (mark.icon) {
           if (mark.position === 'front') {
-            val = <span><MkIcon style={{color: mark.color}} type={mark.icon} /> {val}</span>
+            val = <span><MkIcon style={mark.innerStyle} type={mark.icon} /> {val}</span>
           } else {
-            val = <span>{val} <MkIcon style={{color: mark.color}} type={mark.icon} /></span>
+            val = <span>{val} <MkIcon style={mark.innerStyle} type={mark.icon} /></span>
           }
         }
       }
@@ -431,9 +437,9 @@
 
         if (mark.icon) {
           if (mark.position === 'front') {
-            val = <span><MkIcon style={{color: mark.color}} type={mark.icon} /> {val}</span>
+            val = <span><MkIcon style={mark.innerStyle} type={mark.icon} /> {val}</span>
           } else {
-            val = <span>{val} <MkIcon style={{color: mark.color}} type={mark.icon} /></span>
+            val = <span>{val} <MkIcon style={mark.innerStyle} type={mark.icon} /></span>
           }
         }
       }
@@ -458,8 +464,8 @@
         <Col key={card.uuid} span={card.width}>
           <div style={card.style}>
             {val ? <Tooltip title={val}>
-              <MkIcon type={card.icon}/>
-            </Tooltip> : <MkIcon type={card.icon}/>}
+              <MkIcon className="ant-mk-icon" style={{height: card.innerHeight || 'auto'}} type={card.icon}/>
+            </Tooltip> : <MkIcon className="ant-mk-icon" style={{height: card.innerHeight || 'auto'}} type={card.icon}/>}
           </div>
         </Col>
       )
@@ -507,6 +513,9 @@
 
       if (card.datatype === 'static') {
         url = card.url || ''
+        if (url === '@icon@') {
+          url = sessionStorage.getItem('avatar') || ''
+        }
       } else {
         url = data[card.field] || ''
       }
@@ -600,10 +609,18 @@
         return null
       }
 
+      let poster = ''
+
+      if (card.posterType === 'dynamic') {
+        poster = data[card.posterField] || ''
+      } else {
+        poster = card.posterUrl || ''
+      }
+
       return (
         <Col key={card.uuid} span={card.width}>
-          <div style={card.style}>
-            <Video card={card} value={url}/>
+          <div className="video-wrap" style={card.style}>
+            <Video card={card} poster={poster} value={url}/>
           </div>
         </Col>
       )
@@ -717,9 +734,9 @@
 
         if (mark.icon) {
           if (mark.position === 'front') {
-            val = <span><MkIcon style={{color: mark.color}} type={mark.icon} /> {val}</span>
+            val = <span><MkIcon style={mark.innerStyle} type={mark.icon} /> {val}</span>
           } else {
-            val = <span>{val} <MkIcon style={{color: mark.color}} type={mark.icon} /></span>
+            val = <span>{val} <MkIcon style={mark.innerStyle} type={mark.icon} /></span>
           }
         }
       }
@@ -759,13 +776,10 @@
         return (
           <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
             <NormalButton
+              btn={card}
               BID={data.$$BID}
               BData={data.$$BData || ''}
               disabled={_disabled}
-              lineId={data.$$key || ''}
-              btn={card}
-              show={card.show}
-              style={card.style}
               setting={cards.setting}
               columns={cards.columns}
               selectedData={_data}
@@ -776,13 +790,10 @@
         return (
           <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
             <ExcelInButton
+              btn={card}
               BID={data.$$BID}
               BData={data.$$BData || ''}
               disabled={_disabled}
-              lineId={data.$$key || ''}
-              btn={card}
-              show={card.show}
-              style={card.style}
               setting={cards.setting}
               selectedData={_data}
             />
@@ -792,14 +803,12 @@
         return (
           <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
             <ExcelOutButton
+              btn={card}
               BID={data.$$BID}
               BData={data.$$BData || ''}
-              lineId={data.$$key || ''}
               disabled={_disabled}
-              btn={card}
-              show={card.show}
-              style={card.style}
               setting={cards.setting}
+              selectedData={_data}
             />
           </Col>
         )
@@ -807,13 +816,10 @@
         return (
           <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
             <PopupButton
+              btn={card}
               BID={data.$$BID}
               BData={data.$$BData || ''}
               disabled={_disabled}
-              lineId={data.$$key || ''}
-              btn={card}
-              show={card.show}
-              style={card.style}
               setting={cards.setting}
               selectedData={_data}
             />
@@ -823,12 +829,9 @@
         return (
           <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
             <TabButton
+              btn={card}
               BData={data.$$BData || ''}
               disabled={_disabled}
-              lineId={data.$$key || ''}
-              btn={card}
-              show={card.show}
-              style={card.style}
               setting={cards.setting}
               selectedData={_data}
             />
@@ -838,12 +841,9 @@
         return (
           <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
             <NewPageButton
+              btn={card}
               BData={data.$$BData || ''}
               disabled={_disabled}
-              lineId={data.$$key || ''}
-              btn={card}
-              show={card.show}
-              style={card.style}
               setting={cards.setting}
               selectedData={_data}
             />
@@ -854,13 +854,10 @@
           return (
             <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
               <ChangeUserButton
+                btn={card}
                 BID={data.$$BID}
                 BData={data.$$BData || ''}
                 disabled={_disabled}
-                lineId={data.$$key || ''}
-                btn={card}
-                show={card.show}
-                style={card.style}
                 setting={cards.setting}
                 selectedData={_data}
               />
@@ -870,13 +867,10 @@
           return (
             <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
               <PrintButton
+                btn={card}
                 BID={data.$$BID}
                 BData={data.$$BData || ''}
                 disabled={_disabled}
-                lineId={data.$$key || ''}
-                btn={card}
-                show={card.show}
-                style={card.style}
                 setting={cards.setting}
                 selectedData={_data}
               />
@@ -886,12 +880,21 @@
           return (
             <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
               <FuncMegvii
+                btn={card}
                 BID={data.$$BID}
                 disabled={_disabled}
-                lineId={data.$$key || ''}
+                setting={cards.setting}
+                selectedData={_data}
+              />
+            </Col>
+          )
+        } else if (card.funcType === 'filezip') {
+          return (
+            <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
+              <FuncZip
                 btn={card}
-                show={card.show}
-                style={card.style}
+                BID={data.$$BID}
+                disabled={_disabled}
                 setting={cards.setting}
                 selectedData={_data}
               />
diff --git a/src/tabviews/custom/components/card/cardcellList/index.scss b/src/tabviews/custom/components/card/cardcellList/index.scss
index ec32d1f..b584f3d 100644
--- a/src/tabviews/custom/components/card/cardcellList/index.scss
+++ b/src/tabviews/custom/components/card/cardcellList/index.scss
@@ -1,8 +1,21 @@
 
 .card-cell-list {
   position: relative;
+  line-height: 1.5;
+  
   .ant-btn {
     padding: 0;
+  }
+  .ant-typography {
+    margin: 0;
+    padding: 0;
+    font-style: inherit;
+    font-weight: inherit;
+    text-decoration: inherit;
+    color: inherit;
+    .anticon-copy {
+      color: var(--mk-sys-color);
+    }
   }
   .ant-mk-text {
     font-style: inherit;
@@ -16,6 +29,9 @@
       white-space: nowrap;
       border-radius: 50%;
       overflow: visible;
+    }
+    span {
+      text-indent: 0px;
     }
   }
   .ant-mk-text:not(.line1):not(.line) {
@@ -148,6 +164,10 @@
   .ant-mk-picture.scale {
     cursor: zoom-in;
   }
+  .ant-mk-icon {
+    vertical-align: top;
+    line-height: inherit;
+  }
   .ant-switch-large {
     min-width: 60px;
     height: 30px;
diff --git a/src/tabviews/custom/components/card/data-card/index.jsx b/src/tabviews/custom/components/card/data-card/index.jsx
index ff0e6b9..ff124ec 100644
--- a/src/tabviews/custom/components/card/data-card/index.jsx
+++ b/src/tabviews/custom/components/card/data-card/index.jsx
@@ -22,7 +22,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -258,13 +257,9 @@
     if (config.uuid !== menuId) return
 
     if (supComs) {
-      btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
       if (position === 'mainline' || position === 'popclose') { // 涓昏〃鍒锋柊锛屽幓闄ゅ悓姝ュ埛鏂扮粍浠�
         let supNode = supNodes[supNodes.length - 1]
         supComs.forEach((item, i) => {
-          if (item === btn.syncComponentId) return
-
           setTimeout(() => {
             if (supNode && supNode.key === item) {
               MKEmitter.emit('reloadData', item, supNode.value)
@@ -273,7 +268,7 @@
             }
           }, i * 10)
         })
-      } else if (!btn.syncComponentId || !supComs.includes(btn.syncComponentId)) {
+      } else {
         if (position === 'line') {
           if (lines && lines.length === 1) {
             this.loadLinedata(lines[0].$$uuid)
@@ -293,30 +288,22 @@
     } else {
       let supModule = config.setting.supModule
 
-      btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-      if (!btn.syncComponentId || btn.syncComponentId !== supModule) {
-        if (position === 'line') {
-          if (lines && lines.length === 1) {
-            this.loadLinedata(lines[0].$$uuid)
-          } else {
-            this.loadData(id)
-          }
-        } else if (position === 'mainline' || position === 'popclose') { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
-          if (supModule && BID) {
-            MKEmitter.emit('reloadData', supModule, BID)
-          } else {
-            this.loadData(id)
-          }
-        } else if (!btn || btn.resetPageIndex !== 'false') {
-          this.setState({
-            pageIndex: 1
-          }, () => {
-            this.loadData(id)
-          })
+      if (position === 'line') {
+        if (lines && lines.length === 1) {
+          this.loadLinedata(lines[0].$$uuid)
         } else {
           this.loadData(id)
         }
+      } else if ((position === 'mainline' || position === 'popclose') && supModule && BID) { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
+        MKEmitter.emit('reloadData', supModule, BID)
+      } else if (!btn || btn.resetPageIndex !== 'false') {
+        this.setState({
+          pageIndex: 1
+        }, () => {
+          this.loadData(id)
+        })
+      } else {
+        this.loadData(id)
       }
     }
 
@@ -328,7 +315,15 @@
   checkTopLine = (id) => {
     const { config, data } = this.state
 
-    if (!data || data.length === 0 || data[0].$disabled) {
+    let index = 0
+    if (id && data) {
+      index = data.findIndex(item => item.$$uuid === id)
+      if (index === -1) {
+        index = 0
+      }
+    }
+
+    if (!data || data.length === 0 || data[index].$disabled) {
       this.setState({
         activeKey: '',
         selectKeys: [],
@@ -340,14 +335,6 @@
         MKEmitter.emit('syncBalconyData', config.uuid, [], false)
       }
       return
-    }
-
-    let index = 0
-    if (id) {
-      index = data.findIndex(item => item.$$uuid === id)
-      if (index === -1) {
-        index = 0
-      }
     }
 
     this.setState({
@@ -465,7 +452,7 @@
   }
 
   async loadData (id) {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, pageIndex, search, BID, BData, selected } = this.state
 
     if (config.setting.supModule && !BID && config.wrap.supKey !== 'false') { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
@@ -515,7 +502,7 @@
     })
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, pageIndex, config.setting.pageSize, BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, pageIndex, config.setting.pageSize, BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -576,7 +563,7 @@
    * @description 鑾峰彇鍗曡鏁版嵁
    */ 
   async loadLinedata (id) {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, pageIndex, search, BID, BData } = this.state
 
     let searches = fromJS(search).toJS()
@@ -594,7 +581,7 @@
     })
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, pageIndex, config.setting.pageSize, BID, menuType, id)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, pageIndex, config.setting.pageSize, BID, id)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -751,7 +738,7 @@
             <Spin />
           </div> : null
         }
-        <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} />
+        <NormalHeader config={config} BID={BID} refresh={this.refreshSearch} />
         {config.action && config.action.length > 0 ?
           <MainAction
             BID={BID}
diff --git a/src/tabviews/custom/components/card/prop-card/index.jsx b/src/tabviews/custom/components/card/prop-card/index.jsx
index 34bbdfd..03898a1 100644
--- a/src/tabviews/custom/components/card/prop-card/index.jsx
+++ b/src/tabviews/custom/components/card/prop-card/index.jsx
@@ -20,7 +20,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -231,22 +230,30 @@
         })
         return
       } else if (result.run_type) {
-        this.setState({timer})
+        let repeats = config.timerRepeats || 0
+        this.setState({timer, repeats})
         this.timer = setTimeout(() => {
-          this.timerTask()
+          this.timerTask(repeats)
         }, timer)
       }
     })
   }
 
-  timerTask = () => {
-    const { timer } = this.state
+  timerTask = (times) => {
+    const { timer, repeats } = this.state
     if (!timer) return
     
     this.loadData(true)
 
+    if (repeats) {
+      times = times - 1
+      if (times <= 0) {
+        clearTimeout(this.timer)
+        return
+      }
+    }
     this.timer = setTimeout(() => {
-      this.timerTask()
+      this.timerTask(times)
     }, timer)
   }
 
@@ -261,20 +268,10 @@
 
     if (config.uuid !== menuId) return
 
-    let supModule = config.setting.supModule
-
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-    if (!btn.syncComponentId || btn.syncComponentId !== supModule) {
-      if (position === 'mainline' || position === 'popclose') { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
-        if (supModule && BID) {
-          MKEmitter.emit('reloadData', supModule, BID)
-        } else {
-          this.loadData()
-        }
-      } else {
-        this.loadData()
-      }
+    if ((position === 'mainline' || position === 'popclose') && config.setting.supModule && BID) { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
+      MKEmitter.emit('reloadData', config.setting.supModule, BID)
+    } else {
+      this.loadData()
     }
 
     if (position === 'popclose') { // 鎵ц鍚姩寮圭獥鐨勬寜閽墍閫夋嫨鐨勫埛鏂伴」
@@ -322,7 +319,7 @@
   }
 
   async loadData (hastimer) {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, BID, BData, selected } = this.state
 
     if (config.wrap.datatype === 'static') {
@@ -351,7 +348,7 @@
     }
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
diff --git a/src/tabviews/custom/components/card/table-card/index.jsx b/src/tabviews/custom/components/card/table-card/index.jsx
index bdc334c..314f10b 100644
--- a/src/tabviews/custom/components/card/table-card/index.jsx
+++ b/src/tabviews/custom/components/card/table-card/index.jsx
@@ -20,7 +20,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -169,20 +168,10 @@
 
     if (config.uuid !== menuId) return
 
-    let supModule = config.setting.supModule
-
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-    if (!btn.syncComponentId || btn.syncComponentId !== supModule) {
-      if (position === 'mainline' || position === 'popclose') { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
-        if (supModule && BID) {
-          MKEmitter.emit('reloadData', supModule, BID)
-        } else {
-          this.loadData()
-        }
-      } else {
-        this.loadData()
-      }
+    if ((position === 'mainline' || position === 'popclose') && config.setting.supModule && BID) { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
+      MKEmitter.emit('reloadData', config.setting.supModule, BID)
+    } else {
+      this.loadData()
     }
 
     if (position === 'popclose') { // 鎵ц鍚姩寮圭獥鐨勬寜閽墍閫夋嫨鐨勫埛鏂伴」
@@ -237,7 +226,7 @@
   }
 
   async loadData () {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, pageIndex, search, BID, BData } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
@@ -268,7 +257,7 @@
     })
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, pageIndex, config.setting.pageSize, BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, pageIndex, config.setting.pageSize, BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -429,7 +418,7 @@
             <Spin />
           </div> : null
         }
-        <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} />
+        <NormalHeader config={config} BID={BID} refresh={this.refreshSearch} />
         {data && data.length > 0 ? <Row className="card-row-list" style={{height: config.wrap.contentHeight}}>
           {data.map(item => this.getLines(item))}
         </Row> : null}
diff --git a/src/tabviews/custom/components/carousel/cardItem/index.jsx b/src/tabviews/custom/components/carousel/cardItem/index.jsx
index b5711fc..ad41768 100644
--- a/src/tabviews/custom/components/carousel/cardItem/index.jsx
+++ b/src/tabviews/custom/components/carousel/cardItem/index.jsx
@@ -43,6 +43,8 @@
   openView = () => {
     const { card, data, cards } = this.props
 
+    if (!card.setting.click || data.$disabled) return
+
     if (card.setting.click === 'menu' && card.setting.MenuID) {
       let menu = {
         MenuID: card.setting.MenuID,
@@ -83,7 +85,7 @@
       if (cards.subtype === 'datacard') {
         MKEmitter.emit('triggerBtnId', card.setting.linkbtn, [data], 'linkbtn')
       } else {
-        MKEmitter.emit('triggerBtnId', card.setting.linkbtn, [data])
+        MKEmitter.emit('triggerBtnId', card.setting.linkbtn, data.$$empty ? [] : [data])
       }
     }
   }
diff --git a/src/tabviews/custom/components/carousel/data-card/index.jsx b/src/tabviews/custom/components/carousel/data-card/index.jsx
index b4ca598..5765bce 100644
--- a/src/tabviews/custom/components/carousel/data-card/index.jsx
+++ b/src/tabviews/custom/components/carousel/data-card/index.jsx
@@ -17,7 +17,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -151,20 +150,10 @@
 
     if (config.uuid !== menuId) return
 
-    let supModule = config.setting.supModule
-
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-    if (!btn.syncComponentId || btn.syncComponentId !== supModule) {
-      if (position === 'mainline' || position === 'popclose') { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
-        if (supModule && BID) {
-          MKEmitter.emit('reloadData', supModule, BID)
-        } else {
-          this.loadData()
-        }
-      } else {
-        this.loadData()
-      }
+    if ((position === 'mainline' || position === 'popclose') && config.setting.supModule && BID) { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
+      MKEmitter.emit('reloadData', config.setting.supModule, BID)
+    } else {
+      this.loadData()
     }
 
     if (position === 'popclose') { // 鎵ц鍚姩寮圭獥鐨勬寜閽墍閫夋嫨鐨勫埛鏂伴」
@@ -203,7 +192,7 @@
   }
 
   async loadData () {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, BID, BData } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
@@ -225,7 +214,7 @@
     })
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
diff --git a/src/tabviews/custom/components/carousel/prop-card/index.jsx b/src/tabviews/custom/components/carousel/prop-card/index.jsx
index 10555d9..554226a 100644
--- a/src/tabviews/custom/components/carousel/prop-card/index.jsx
+++ b/src/tabviews/custom/components/carousel/prop-card/index.jsx
@@ -17,7 +17,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -152,20 +151,10 @@
 
     if (config.uuid !== menuId) return
 
-    let supModule = config.setting.supModule
-
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-    if (!btn.syncComponentId || btn.syncComponentId !== supModule) {
-      if (position === 'mainline' || position === 'popclose') { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
-        if (supModule && BID) {
-          MKEmitter.emit('reloadData', supModule, BID)
-        } else {
-          this.loadData()
-        }
-      } else {
-        this.loadData()
-      }
+    if ((position === 'mainline' || position === 'popclose') && config.setting.supModule && BID) { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
+      MKEmitter.emit('reloadData', config.setting.supModule, BID)
+    } else {
+      this.loadData()
     }
 
     if (position === 'popclose') { // 鎵ц鍚姩寮圭獥鐨勬寜閽墍閫夋嫨鐨勫埛鏂伴」
@@ -212,7 +201,7 @@
   }
 
   async loadData () {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, BID, BData } = this.state
 
     if (config.wrap.datatype === 'static') {
@@ -239,7 +228,7 @@
     })
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
diff --git a/src/tabviews/custom/components/chart/antv-bar-line/index.jsx b/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
index be150a4..b2449054 100644
--- a/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
@@ -26,7 +26,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -198,12 +197,14 @@
       _config.plot.$colors = colors
     }
 
+    let limit = _config.plot.XLimit || 11
+
     let xc = {label: {
       formatter: (val) => {
         if (!val || /^\s*$/.test(val)) return val
         let _val = `${val}`
-        if (_val.length <= 11) return val
-        return _val.substring(0, 8) + '...'
+        if (_val.length <= limit) return val
+        return _val.substring(0, limit) + '...'
       },
       style: { fill: _config.plot.color }
     }}
@@ -415,22 +416,30 @@
         })
         return
       } else if (result.run_type) {
-        this.setState({timer})
+        let repeats = config.timerRepeats || 0
+        this.setState({timer, repeats})
         this.timer = setTimeout(() => {
-          this.timerTask()
+          this.timerTask(repeats)
         }, timer)
       }
     })
   }
 
-  timerTask = () => {
-    const { timer } = this.state
+  timerTask = (times) => {
+    const { timer, repeats } = this.state
     if (!timer) return
     
     this.loadData(true)
-    
+
+    if (repeats) {
+      times = times - 1
+      if (times <= 0) {
+        clearTimeout(this.timer)
+        return
+      }
+    }
     this.timer = setTimeout(() => {
-      this.timerTask()
+      this.timerTask(times)
     }, timer)
   }
 
@@ -445,20 +454,10 @@
 
     if (config.uuid !== menuId) return
 
-    let supModule = config.setting.supModule
-
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-    if (!btn.syncComponentId || btn.syncComponentId !== supModule) {
-      if (position === 'mainline' || position === 'popclose') { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
-        if (supModule && BID) {
-          MKEmitter.emit('reloadData', supModule, BID)
-        } else {
-          this.loadData()
-        }
-      } else {
-        this.loadData()
-      }
+    if ((position === 'mainline' || position === 'popclose') && config.setting.supModule && BID) { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
+      MKEmitter.emit('reloadData', config.setting.supModule, BID)
+    } else {
+      this.loadData()
     }
 
     if (position === 'popclose') { // 鎵ц鍚姩寮圭獥鐨勬寜閽墍閫夋嫨鐨勫埛鏂伴」
@@ -516,7 +515,7 @@
    * @description 鏁版嵁鍔犺浇
    */
   async loadData (hastimer) {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, BID, search } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
@@ -550,7 +549,7 @@
     }
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -1018,6 +1017,9 @@
     }
     if (plot.label !== 'false') {
       _chart.label(_valfield, (value) => {
+        if (plot.labelValue === 'zero' && value === 0) {
+          return null
+        }
         if (plot.show === 'percent') {
           value = value + '%'
         }
@@ -1253,6 +1255,10 @@
         }
         if (plot.label !== 'false') {
           _chart.label('value*key', (value, key) => {
+            if (plot.labelValue === 'zero' && value === 0) {
+              return null
+            }
+
             if (plot.show === 'percent') {
               value = value + '%'
             }
@@ -1304,6 +1310,10 @@
         }
         if (plot.label !== 'false') {
           _chart.label('value*key', (value, key) => {
+            if (plot.labelValue === 'zero' && value === 0) {
+              return null
+            }
+
             if (plot.show === 'percent') {
               value = value + '%'
             }
@@ -1326,13 +1336,17 @@
       }
     }
 
-    const view2 = chart.createView({
-      region: {
-        start: { x: 0, y: 0 },
-        end: { x: 1, y: 1 }
-      },
-      padding
-    })
+    let view2 = chart
+
+    if (plot.Bar_axis) {
+      view2 = chart.createView({
+        region: {
+          start: { x: 0, y: 0 },
+          end: { x: 1, y: 1 }
+        },
+        padding
+      })
+    }
 
     view2.data(dv.rows)
     view2.legend(false)
@@ -1371,6 +1385,10 @@
         }
         if (item.label !== 'false') {
           _chart.label(item.name, (value) => {
+            if (plot.labelValue === 'zero' && value === 0) {
+              return null
+            }
+
             if (item.show === 'percent') {
               value = value + '%'
             }
@@ -1419,6 +1437,10 @@
 
         if (item.label === 'true') {
           _chart.label(item.name, (value) => {
+            if (plot.labelValue === 'zero' && value === 0) {
+              return null
+            }
+
             if (item.show === 'percent') {
               value = value + '%'
             }
@@ -1624,6 +1646,10 @@
       }
       if (plot.label !== 'false') {
         _chart.label(`${_valfield}*${_typefield}`, (value, key) => {
+          if (plot.labelValue === 'zero' && value === 0) {
+            return null
+          }
+
           if (plot.show === 'percent') {
             value = value + '%'
           }
@@ -1682,6 +1708,10 @@
       }
       if (plot.label !== 'false') {
         _chart.label(`${_valfield}*${_typefield}`, (value, key) => {
+          if (plot.labelValue === 'zero' && value === 0) {
+            return null
+          }
+
           if (plot.show === 'percent') {
             value = value + '%'
           }
@@ -1845,7 +1875,7 @@
             <Spin />
           </div> : null
         }
-        <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} />
+        <NormalHeader config={config} BID={BID} refresh={this.refreshSearch} />
         <div className="canvas-wrap" ref={ref => this.wrap = ref}>
           {config.plot.download === 'enable' && this.state.chart && !empty ? <DownloadOutlined onClick={this.downloadImage} className="system-color download"/> : null}
           <div className={'chart-action' + (config.plot.download === 'enable' ? ' downable' : '')}>
diff --git a/src/tabviews/custom/components/chart/antv-dashboard/index.jsx b/src/tabviews/custom/components/chart/antv-dashboard/index.jsx
index dd536e5..a20be1e 100644
--- a/src/tabviews/custom/components/chart/antv-dashboard/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-dashboard/index.jsx
@@ -56,7 +56,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -204,22 +203,30 @@
         })
         return
       } else if (result.run_type) {
-        this.setState({timer})
+        let repeats = config.timerRepeats || 0
+        this.setState({timer, repeats})
         this.timer = setTimeout(() => {
-          this.timerTask()
+          this.timerTask(repeats)
         }, timer)
       }
     })
   }
 
-  timerTask = () => {
-    const { timer } = this.state
+  timerTask = (times) => {
+    const { timer, repeats } = this.state
     if (!timer) return
     
     this.loadData(true)
-    
+
+    if (repeats) {
+      times = times - 1
+      if (times <= 0) {
+        clearTimeout(this.timer)
+        return
+      }
+    }
     this.timer = setTimeout(() => {
-      this.timerTask()
+      this.timerTask(times)
     }, timer)
   }
 
@@ -251,7 +258,7 @@
   }
 
   async loadData (hastimer) {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, BID } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
@@ -277,7 +284,7 @@
     }
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
diff --git a/src/tabviews/custom/components/chart/antv-pie/index.jsx b/src/tabviews/custom/components/chart/antv-pie/index.jsx
index 8599ad4..448b85b 100644
--- a/src/tabviews/custom/components/chart/antv-pie/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-pie/index.jsx
@@ -22,7 +22,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -160,22 +159,30 @@
         })
         return
       } else if (result.run_type) {
-        this.setState({timer})
+        let repeats = config.timerRepeats || 0
+        this.setState({timer, repeats})
         this.timer = setTimeout(() => {
-          this.timerTask()
+          this.timerTask(repeats)
         }, timer)
       }
     })
   }
 
-  timerTask = () => {
-    const { timer } = this.state
+  timerTask = (times) => {
+    const { timer, repeats } = this.state
     if (!timer) return
     
     this.loadData(true)
-    
+
+    if (repeats) {
+      times = times - 1
+      if (times <= 0) {
+        clearTimeout(this.timer)
+        return
+      }
+    }
     this.timer = setTimeout(() => {
-      this.timerTask()
+      this.timerTask(times)
     }, timer)
   }
 
@@ -214,7 +221,7 @@
   }
 
   async loadData (hastimer) {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, search, BID } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
@@ -248,7 +255,7 @@
     }
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -1061,7 +1068,7 @@
             <Spin />
           </div> : null
         }
-        <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} />
+        <NormalHeader config={config} BID={BID} refresh={this.refreshSearch} />
         <div className="canvas-wrap" ref={ref => this.wrap = ref}>
           {config.plot.download === 'enable' && this.state.chart && !empty ? <DownloadOutlined onClick={this.downloadImage} className="system-color download"/> : null}
           <div className={'canvas' + (empty ? ' empty' : '')} id={this.state.chartId}></div>
diff --git a/src/tabviews/custom/components/chart/antv-scatter/index.jsx b/src/tabviews/custom/components/chart/antv-scatter/index.jsx
index c650f3f..bad1040 100644
--- a/src/tabviews/custom/components/chart/antv-scatter/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-scatter/index.jsx
@@ -23,7 +23,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -154,22 +153,30 @@
         })
         return
       } else if (result.run_type) {
-        this.setState({timer})
+        let repeats = config.timerRepeats || 0
+        this.setState({timer, repeats})
         this.timer = setTimeout(() => {
-          this.timerTask()
+          this.timerTask(repeats)
         }, timer)
       }
     })
   }
 
-  timerTask = () => {
-    const { timer } = this.state
+  timerTask = (times) => {
+    const { timer, repeats } = this.state
     if (!timer) return
     
     this.loadData(true)
-    
+
+    if (repeats) {
+      times = times - 1
+      if (times <= 0) {
+        clearTimeout(this.timer)
+        return
+      }
+    }
     this.timer = setTimeout(() => {
-      this.timerTask()
+      this.timerTask(times)
     }, timer)
   }
 
@@ -184,20 +191,10 @@
 
     if (config.uuid !== menuId) return
 
-    let supModule = config.setting.supModule
-
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-    if (!btn.syncComponentId || btn.syncComponentId !== supModule) {
-      if (position === 'mainline' || position === 'popclose') { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
-        if (supModule && BID) {
-          MKEmitter.emit('reloadData', supModule, BID)
-        } else {
-          this.loadData()
-        }
-      } else {
-        this.loadData()
-      }
+    if ((position === 'mainline' || position === 'popclose') && config.setting.supModule && BID) { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
+      MKEmitter.emit('reloadData', config.setting.supModule, BID)
+    } else {
+      this.loadData()
     }
 
     if (position === 'popclose') { // 鎵ц鍚姩寮圭獥鐨勬寜閽墍閫夋嫨鐨勫埛鏂伴」
@@ -255,7 +252,7 @@
    * @description 鏁版嵁鍔犺浇
    */
   async loadData (hastimer) {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, BID, search } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
@@ -290,7 +287,7 @@
     }
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -454,7 +451,7 @@
             <Spin />
           </div> : null
         }
-        <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} />
+        <NormalHeader config={config} BID={BID} refresh={this.refreshSearch} />
         <div className="canvas-wrap" ref={ref => this.wrap = ref}>
           {config.plot.download === 'enable' && this.state.chart && !empty ? <DownloadOutlined onClick={this.downloadImage} className="system-color download"/> : null}
           <div className={'chart-action' + (config.plot.download === 'enable' ? ' downable' : '')}>
diff --git a/src/tabviews/custom/components/chart/custom-chart/index.jsx b/src/tabviews/custom/components/chart/custom-chart/index.jsx
index 5598d77..310c1ea 100644
--- a/src/tabviews/custom/components/chart/custom-chart/index.jsx
+++ b/src/tabviews/custom/components/chart/custom-chart/index.jsx
@@ -20,7 +20,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -149,22 +148,30 @@
         })
         return
       } else if (result.run_type) {
-        this.setState({timer})
+        let repeats = config.timerRepeats || 0
+        this.setState({timer, repeats})
         this.timer = setTimeout(() => {
-          this.timerTask()
+          this.timerTask(repeats)
         }, timer)
       }
     })
   }
 
-  timerTask = () => {
-    const { timer } = this.state
+  timerTask = (times) => {
+    const { timer, repeats } = this.state
     if (!timer) return
     
     this.loadData(true)
-    
+
+    if (repeats) {
+      times = times - 1
+      if (times <= 0) {
+        clearTimeout(this.timer)
+        return
+      }
+    }
     this.timer = setTimeout(() => {
-      this.timerTask()
+      this.timerTask(times)
     }, timer)
   }
 
@@ -179,20 +186,10 @@
 
     if (config.uuid !== menuId) return
 
-    let supModule = config.setting.supModule
-
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-    if (!btn.syncComponentId || btn.syncComponentId !== supModule) {
-      if (position === 'mainline' || position === 'popclose') { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
-        if (supModule && BID) {
-          MKEmitter.emit('reloadData', supModule, BID)
-        } else {
-          this.loadData()
-        }
-      } else {
-        this.loadData()
-      }
+    if ((position === 'mainline' || position === 'popclose') && config.setting.supModule && BID) { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
+      MKEmitter.emit('reloadData', config.setting.supModule, BID)
+    } else {
+      this.loadData()
     }
 
     if (position === 'popclose') { // 鎵ц鍚姩寮圭獥鐨勬寜閽墍閫夋嫨鐨勫埛鏂伴」
@@ -250,7 +247,7 @@
    * @description 鏁版嵁鍔犺浇
    */
   async loadData (hastimer) {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, BID, search } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
@@ -284,7 +281,7 @@
     }
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -387,7 +384,7 @@
             <Spin />
           </div> : null
         }
-        <NormalHeader config={config} BID={BID} menuType={this.props.menuType} refresh={this.refreshSearch} />
+        <NormalHeader config={config} BID={BID} refresh={this.refreshSearch} />
         <div className={'canvas' + (empty ? ' empty' : '')} ref={ref => this.wrap = ref}></div>
         {empty ? <Empty description={false}/> : null}
       </div>
diff --git a/src/tabviews/custom/components/code/sand-box/index.jsx b/src/tabviews/custom/components/code/sand-box/index.jsx
index 0938216..5eb969e 100644
--- a/src/tabviews/custom/components/code/sand-box/index.jsx
+++ b/src/tabviews/custom/components/code/sand-box/index.jsx
@@ -14,7 +14,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -124,7 +123,7 @@
   }
 
   async loadData () {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, BID } = this.state
 
     if (config.wrap.datatype === 'static') {
@@ -153,7 +152,7 @@
     })
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
diff --git a/src/tabviews/custom/components/editor/braft-editor/index.jsx b/src/tabviews/custom/components/editor/braft-editor/index.jsx
index 437de06..2f9c508 100644
--- a/src/tabviews/custom/components/editor/braft-editor/index.jsx
+++ b/src/tabviews/custom/components/editor/braft-editor/index.jsx
@@ -18,7 +18,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -122,7 +121,7 @@
   }
 
   async loadData () {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, BID } = this.state
 
     if (config.wrap.datatype === 'static') {
@@ -151,7 +150,7 @@
     })
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
diff --git a/src/tabviews/custom/components/form/simple-form/index.jsx b/src/tabviews/custom/components/form/simple-form/index.jsx
new file mode 100644
index 0000000..35fd004
--- /dev/null
+++ b/src/tabviews/custom/components/form/simple-form/index.jsx
@@ -0,0 +1,309 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { connect } from 'react-redux'
+import { Spin, notification } from 'antd'
+
+import Api from '@/api'
+import UtilsDM from '@/utils/utils-datamanage.js'
+import asyncComponent from '@/utils/asyncComponent'
+import asyncSpinComponent from '@/utils/asyncSpinComponent'
+import MKEmitter from '@/utils/events.js'
+import zhCN from '@/locales/zh-CN/main.js'
+import enUS from '@/locales/en-US/main.js'
+import './index.scss'
+
+const MutilForm = asyncSpinComponent(() => import('@/tabviews/zshare/mutilform'))
+const NormalButton = asyncComponent(() => import('@/tabviews/zshare/actionList/normalbutton'))
+const NormalHeader = asyncComponent(() => import('@/tabviews/custom/components/share/normalheader'))
+
+class SimpleForm extends Component {
+  static propTpyes = {
+    BID: PropTypes.any,              // 鐖剁骇Id
+    data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
+    config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
+    mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
+  }
+
+  state = {
+    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    BID: '',
+    config: null,
+    loading: false,
+    sync: false,
+    data: null,
+    group: null,
+    BData: '',
+    step: 0
+  }
+
+  UNSAFE_componentWillMount () {
+    const { data, BID, BData } = this.props
+    let config = fromJS(this.props.config).toJS()
+
+    let _data = null
+    let _sync = false
+
+    if (config.wrap.datatype !== 'static') {
+      _sync = config.setting.sync === 'true'
+
+      if (_sync && data && data[config.dataName]) {
+        _data = data[config.dataName]
+        if (Array.isArray(_data)) {
+          _data = _data[0] || {$$empty: true}
+        }
+        _sync = false
+      }
+    } else {
+      _data = {$$empty: true}
+    }
+
+    let _group = config.subcards[0]
+
+    if (_group.subButton.enable === 'false') {
+      _group.subButton.style.display = 'none'
+      _group.$button = 'no-button'
+    }
+
+    this.setState({
+      sync: _sync,
+      data: _data,
+      group: _group,
+      BID: BID || '',
+      BData: BData || '',
+      config: config,
+      arr_field: config.columns.map(col => col.field).join(','),
+    }, () => {
+      if (config.wrap.datatype !== 'static' && config.setting.sync !== 'true' && config.setting.onload === 'true') {
+        setTimeout(() => {
+          this.loadData()
+        }, config.setting.delay || 0)
+      }
+    })
+  }
+
+  componentDidMount () {
+    MKEmitter.addListener('reloadData', this.reloadData)
+    MKEmitter.addListener('mkFormSubmit', this.mkFormSubmit)
+    MKEmitter.addListener('resetSelectLine', this.resetParentParam)
+    MKEmitter.addListener('refreshByButtonResult', this.refreshByButtonResult)
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+    MKEmitter.removeListener('reloadData', this.reloadData)
+    MKEmitter.removeListener('mkFormSubmit', this.mkFormSubmit)
+    MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
+    MKEmitter.removeListener('refreshByButtonResult', this.refreshByButtonResult)
+  }
+
+  /**
+   * @description 鍥捐〃鏁版嵁鏇存柊锛屽埛鏂板唴瀹�
+   */
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    const { sync, config } = this.state
+
+    if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) {
+      let _data = {$$empty: true}
+      if (nextProps.data && nextProps.data[config.dataName]) {
+        _data = nextProps.data[config.dataName]
+        if (Array.isArray(_data)) {
+          _data = _data[0] || {$$empty: true}
+        }
+      }
+
+      this.setState({sync: false, data: _data})
+    } else if (config.setting.syncRefresh && nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) {
+      this.setState({}, () => {
+        this.loadData()
+      })
+    }
+  }
+
+  reloadData = (menuId, id) => {
+    const { config } = this.state
+
+    if (config.uuid !== menuId) return
+
+    this.loadData()
+  }
+
+  /**
+   * @description 鎸夐挳鎵ц瀹屾垚鍚庨〉闈㈠埛鏂�
+   * @param {*} menuId     // 鑿滃崟Id
+   * @param {*} position   // 鍒锋柊浣嶇疆
+   * @param {*} btn        // 鎵ц鐨勬寜閽�
+   */
+  refreshByButtonResult = (menuId, position, btn, id) => {
+    const { config, group, BID } = this.state
+
+    if (group.uuid !== menuId) return
+
+    if (position === 'mainline' && config.setting.supModule && BID) {
+      MKEmitter.emit('reloadData', config.setting.supModule, BID)
+    } else {
+      this.loadData()
+    }
+
+    if (id) {
+      MKEmitter.emit('resetSelectLine', config.uuid, id, '')
+    }
+
+    this.execSuccess(btn, id)
+  }
+
+  resetParentParam = (MenuID, id, data) => {
+    const { config } = this.state
+
+    if (!config.setting.supModule || config.setting.supModule !== MenuID) return
+    
+    if (id !== this.state.BID || id !== '') {
+      if (config.wrap.datatype === 'static' || (config.setting.supModule && !id)) {
+        this.setState({
+          data: null,
+          BID: id,
+          BData: data
+        }, () => {
+          this.setState({
+            data: {$$empty: true}
+          })
+        })
+      } else {
+        this.setState({ BID: id, BData: data }, () => {
+          this.loadData()
+        })
+      }
+    }
+  }
+
+  execSuccess = (btn, id) => {
+    if (btn.linkmenu && btn.linkmenu.length > 0) {
+      let menu_id = btn.linkmenu[btn.linkmenu.length - 1]
+      let menu = this.props.permMenus.filter(m => m.MenuID === menu_id)[0] || ''
+
+      if (!menu) return
+
+      let newtab = {
+        ...menu,
+        param: {$BID: id || ''}
+      }
+
+      if (['linkage_navigation', 'linkage', 'menu_board'].includes(window.GLOB.navBar)) {
+        MKEmitter.emit('modifyTabs', newtab, 'replace')
+      } else {
+        MKEmitter.emit('modifyTabs', newtab, 'plus', true)
+      }
+    }
+  }
+
+  async loadData () {
+    const { mainSearch } = this.props
+    const { config, arr_field, BID } = this.state
+
+    if (config.wrap.datatype === 'static' || (config.setting.supModule && !BID)) {
+      this.setState({
+        data: null
+      }, () => {
+        this.setState({data: {$$empty: true}})
+      })
+      return
+    }
+
+    let searches = config.setting.useMSearch && mainSearch ? mainSearch : []
+
+    let requireFields = searches.filter(item => item.required && item.value === '')
+    if (requireFields.length > 0) {
+      return
+    }
+
+    this.setState({
+      loading: true
+    })
+
+    let _orderBy = config.setting.order || ''
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID)
+
+    let result = await Api.genericInterface(param)
+    if (result.status) {
+      let _data = result.data && result.data[0] ? result.data[0] : {$$empty: true}
+
+      this.setState({
+        data: null,
+        loading: false
+      }, () => {
+        this.setState({data: _data})
+      })
+    } else {
+      this.setState({
+        loading: false,
+      })
+      notification.error({
+        top: 92,
+        message: result.message,
+        duration: 10
+      })
+    }
+  }
+
+  mkFormSubmit = (btnId) => {
+    const { group } = this.state
+
+    if (group.uuid !== btnId) return
+
+    this.formRef.handleConfirm().then(res => {
+      MKEmitter.emit('triggerFormSubmit', {menuId: btnId, form: res})
+    })
+  }
+
+  render() {
+    const { config, loading, BID, BData, data, group, dict } = this.state
+
+    return (
+      <div className="custom-simple-form-box" id={'anchor' + config.uuid} style={{...config.style}}>
+        {loading ?
+          <div className="loading-mask">
+            <div className="ant-spin-blur"></div>
+            <Spin />
+          </div> : null
+        }
+        <NormalHeader config={config} />
+        {data ? <MutilForm
+          BID={BID}
+          BData={BData}
+          dict={dict}
+          data={data}
+          action={group}
+          inputSubmit={() => this.mkFormSubmit(group.uuid)}
+          wrappedComponentRef={(inst) => this.formRef = inst}
+        /> : null}
+        {data ? <div className={'mk-form-action ' + (group.$button || '')}>
+          <NormalButton
+            BID={BID}
+            btn={group.subButton}
+            setting={config.setting}
+            columns={config.columns}
+            selectedData={data.$$empty ? [] : [data]}
+          />
+        </div> : null}
+      </div>
+    )
+  }
+}
+
+const mapStateToProps = (state) => {
+  return {
+    permMenus: state.permMenus,
+  }
+}
+
+const mapDispatchToProps = () => {
+  return {}
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(SimpleForm)
\ No newline at end of file
diff --git a/src/tabviews/custom/components/form/simple-form/index.scss b/src/tabviews/custom/components/form/simple-form/index.scss
new file mode 100644
index 0000000..123523e
--- /dev/null
+++ b/src/tabviews/custom/components/form/simple-form/index.scss
@@ -0,0 +1,53 @@
+.custom-simple-form-box {
+  background: #ffffff;
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-size: cover;
+  position: relative;
+  min-height: 50px;
+
+  .main-form-field {
+    padding-top: 20px;
+  }
+  .mk-form-action {
+    position: relative;
+    text-align: center;
+    padding-bottom: 10px;
+
+    .submit {
+      min-width: 70px;
+      border: none;
+    }
+  }
+  .mk-form-action.no-button {
+    padding: 0;
+    height: 0;
+  }
+  
+  .loading-mask {
+    position: absolute;
+    left: 40px;
+    top: 0;
+    right: 40px;
+    bottom: 0px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    text-align: justify;
+    z-index: 1;
+
+    .ant-spin-blur {
+      position: absolute;
+      width: 100%;
+      height: 100%;
+      opacity: 0.5;
+      background: #ffffff;
+    }
+  }
+}
+
+.custom-simple-form-box::after {
+  content: ' ';
+  display: block;
+  clear: both;
+}
diff --git a/src/tabviews/custom/components/form/normal-form/index.jsx b/src/tabviews/custom/components/form/step-form/index.jsx
similarity index 75%
rename from src/tabviews/custom/components/form/normal-form/index.jsx
rename to src/tabviews/custom/components/form/step-form/index.jsx
index a8ad272..91eb195 100644
--- a/src/tabviews/custom/components/form/normal-form/index.jsx
+++ b/src/tabviews/custom/components/form/step-form/index.jsx
@@ -5,7 +5,6 @@
 import { Spin, notification, Button } from 'antd'
 
 import Api from '@/api'
-import Utils from '@/utils/utils.js'
 import UtilsDM from '@/utils/utils-datamanage.js'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncSpinComponent from '@/utils/asyncSpinComponent'
@@ -17,28 +16,28 @@
 const MutilForm = asyncSpinComponent(() => import('@/tabviews/zshare/mutilform'))
 const NormalButton = asyncComponent(() => import('@/tabviews/zshare/actionList/normalbutton'))
 
-class NormalForm extends Component {
+class StepForm extends Component {
   static propTpyes = {
     BID: PropTypes.any,              // 鐖剁骇Id
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
     dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
-    BID: '',                   // 涓婄骇ID
-    config: null,              // 鍥捐〃閰嶇疆淇℃伅
-    loading: false,            // 鏁版嵁鍔犺浇鐘舵��
-    sync: false,               // 鏄惁缁熶竴璇锋眰鏁版嵁
-    data: null,                  // 鏁版嵁
+    BID: '',
+    config: null,
+    loading: false,
+    sync: false,
+    data: null,
     group: null,
+    BData: '',
     step: 0
   }
 
   UNSAFE_componentWillMount () {
-    const { data, BID } = this.props
+    const { data, BID, BData } = this.props
     let config = fromJS(this.props.config).toJS()
 
     let _data = null
@@ -66,20 +65,13 @@
       }
     }
 
-    let roleId = sessionStorage.getItem('role_id') || ''
-
-    config.subcards = config.subcards.map(group => {
-      group.subButton.uuid = group.uuid
-      group.subButton.$menuId = group.uuid
-      group.subButton.Ot = config.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
-      group.subButton.$forbid = true
-      group.subButton.OpenType = 'formSubmit'
-      group.subButton.execError = 'never'
-
-      group.subButton.syncComponentId = group.subButton.syncComponent ? group.subButton.syncComponent.pop() : ''
-
-      if (group.subButton.syncComponentId === config.uuid) {
-        group.subButton.syncComponentId = ''
+    config.subcards = config.subcards.map((group, i) => {
+      group.sort = i + 1
+      if (i === 0) {
+        group.prevButton.enable = 'false'
+      }
+      if (i + 1 === config.subcards.length) {
+        group.nextButton.enable = 'false'
       }
 
       if (group.subButton.enable === 'false') {
@@ -89,25 +81,6 @@
       if (group.prevButton.enable === 'false' && group.subButton.enable === 'false' && group.nextButton.enable === 'false') {
         group.$button = 'no-button'
       }
-
-      group.fields = group.fields.map(cell => {
-        // 鏁版嵁婧恠ql璇彞锛岄澶勭悊锛屾潈闄愰粦鍚嶅崟瀛楁璁剧疆涓洪殣钘忚〃鍗�
-        if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') {
-          let _option = Utils.getSelectQueryOptions(cell)
-  
-          cell.data_sql = Utils.formatOptions(_option.sql)
-          cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql))
-          cell.arr_field = _option.field
-        }
-  
-        // 瀛楁鏉冮檺榛戝悕鍗�
-        if (!cell.blacklist || !roleId || cell.blacklist.length === 0) return cell
-        if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) {
-          cell.hidden = 'true'
-        }
-  
-        return cell
-      })
 
       return group
     })
@@ -127,6 +100,7 @@
       group: _group,
       step: _group.sort - 1,
       BID: BID || '',
+      BData: BData || '',
       config: config,
       arr_field: config.columns.map(col => col.field).join(','),
     }, () => {
@@ -174,6 +148,7 @@
           _data = _data[0] || {$$empty: true}
         }
       }
+
       if (config.wrap.statusControl && _data[config.wrap.statusControl]) {
         let _status = _data[config.wrap.statusControl]
         let _groups = config.subcards.filter(item => item.setting.status === _status)[0]
@@ -203,16 +178,14 @@
    * @param {*} btn        // 鎵ц鐨勬寜閽�
    */
   refreshByButtonResult = (menuId, position, btn, id) => {
-    const { config, group } = this.state
+    const { config, group, BID } = this.state
 
     if (group.uuid !== menuId) return
 
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-    if (!btn.syncComponentId || btn.syncComponentId !== config.setting.supModule) {
-      if (config.wrap.datatype !== 'static' && config.setting) {
-        this.loadData()
-      }
+    if (position === 'mainline' && config.setting.supModule && BID) {
+      MKEmitter.emit('reloadData', config.setting.supModule, BID)
+    } else {
+      this.loadData()
     }
 
     if (id) {
@@ -222,15 +195,27 @@
     this.execSuccess(btn, id)
   }
 
-  resetParentParam = (MenuID, id) => {
+  resetParentParam = (MenuID, id, data) => {
     const { config } = this.state
 
-    if (config.wrap.datatype === 'static' || !config.setting.supModule || config.setting.supModule !== MenuID) return
+    if (!config.setting.supModule || config.setting.supModule !== MenuID) return
     
     if (id !== this.state.BID || id !== '') {
-      this.setState({ BID: id }, () => {
-        this.loadData()
-      })
+      if (config.wrap.datatype === 'static' || (config.setting.supModule && !id)) {
+        this.setState({
+          data: null,
+          BID: id,
+          BData: data
+        }, () => {
+          this.setState({
+            data: {$$empty: true}
+          })
+        })
+      } else {
+        this.setState({ BID: id, BData: data }, () => {
+          this.loadData()
+        })
+      }
     }
   }
 
@@ -267,12 +252,14 @@
   }
 
   async loadData (type) {
-    const { mainSearch, menuType } = this.props
-    const { config, arr_field, BID, group } = this.state
+    const { mainSearch } = this.props
+    const { config, arr_field, BID } = this.state
 
     if (config.wrap.datatype === 'static' || (config.setting.supModule && !BID)) {
       this.setState({
-        data: {$$empty: true}
+        data: null
+      }, () => {
+        this.setState({data: {$$empty: true}})
       })
       return
     }
@@ -289,12 +276,12 @@
     })
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
       let _data = result.data && result.data[0] ? result.data[0] : {$$empty: true}
-      let _group = group
+      let _group = this.state.group
 
       if (type === 'refresh') {
         _group = config.subcards[0]
@@ -305,10 +292,17 @@
         let _groups = config.subcards.filter(item => item.setting.status === _status)[0]
         _group = _groups || _group
       }
+
+      let step = this.state.step
+
+      if (config.subcards.length !== _group.sort || config.subcards.length !== step) {
+        step = _group.sort - 1
+      }
+
       this.setState({
         group: null,
-        step: _group.sort - 1,
-        data: _data || {$$empty: true},
+        step: step,
+        data: _data,
         loading: false
       }, () => {
         this.setState({group: _group})
@@ -356,7 +350,7 @@
   }
 
   render() {
-    const { config, loading, BID, data, group, dict, step } = this.state
+    const { config, loading, BID, BData, data, group, dict, step } = this.state
 
     return (
       <div className="custom-normal-form-box" id={'anchor' + config.uuid} style={{...config.style}}>
@@ -378,6 +372,7 @@
         </div> : null}
         {group && data ? <MutilForm
           BID={BID}
+          BData={BData}
           dict={dict}
           data={data}
           action={group}
@@ -385,16 +380,15 @@
           wrappedComponentRef={(inst) => this.formRef = inst}
         /> : null}
         {group && data ? <div className={'mk-form-action ' + (group.$button || '')}>
-          {group.sort !== 1 && group.prevButton.enable !== 'false' ? <Button type="link" className="prev" onClick={this.prevStep} style={group.prevButton.style}>{group.prevButton.label}</Button> : null}
+          {group.prevButton.enable === 'true' ? <Button type="link" className="prev" onClick={this.prevStep} style={group.prevButton.style}>{group.prevButton.label}</Button> : null}
           <NormalButton
             BID={BID}
-            position="form"
             btn={group.subButton}
             setting={config.setting}
             columns={config.columns}
             selectedData={data.$$empty ? [] : [data]}
           />
-          {group.nextButton.enable === 'true' && group.sort !== config.subcards.length ? <Button type="link" className="skip" onClick={this.nextStep} style={group.nextButton.style}>{group.nextButton.label}</Button> : null}
+          {group.nextButton.enable === 'true' ? <Button type="link" className="skip" onClick={this.nextStep} style={group.nextButton.style}>{group.nextButton.label}</Button> : null}
         </div> : null}
       </div>
     )
@@ -411,4 +405,4 @@
   return {}
 }
 
-export default connect(mapStateToProps, mapDispatchToProps)(NormalForm)
\ No newline at end of file
+export default connect(mapStateToProps, mapDispatchToProps)(StepForm)
\ No newline at end of file
diff --git a/src/tabviews/custom/components/form/normal-form/index.scss b/src/tabviews/custom/components/form/step-form/index.scss
similarity index 100%
rename from src/tabviews/custom/components/form/normal-form/index.scss
rename to src/tabviews/custom/components/form/step-form/index.scss
diff --git a/src/tabviews/custom/components/form/tab-form/index.jsx b/src/tabviews/custom/components/form/tab-form/index.jsx
index de65619..fc90e76 100644
--- a/src/tabviews/custom/components/form/tab-form/index.jsx
+++ b/src/tabviews/custom/components/form/tab-form/index.jsx
@@ -5,7 +5,6 @@
 import { Spin, notification } from 'antd'
 
 import Api from '@/api'
-import Utils from '@/utils/utils.js'
 import UtilsDM from '@/utils/utils-datamanage.js'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncSpinComponent from '@/utils/asyncSpinComponent'
@@ -23,7 +22,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -32,12 +30,13 @@
     config: null,              // 鍥捐〃閰嶇疆淇℃伅
     loading: false,            // 鏁版嵁鍔犺浇鐘舵��
     sync: false,               // 鏄惁缁熶竴璇锋眰鏁版嵁
-    data: null,                  // 鏁版嵁
+    data: null,
+    BData: '',
     group: null,
   }
 
   UNSAFE_componentWillMount () {
-    const { data, BID } = this.props
+    const { data, BID, BData } = this.props
     let config = fromJS(this.props.config).toJS()
 
     let _data = null
@@ -65,45 +64,11 @@
       }
     }
 
-    let roleId = sessionStorage.getItem('role_id') || ''
-
     config.subcards = config.subcards.map(group => {
-      group.subButton.uuid = group.uuid
-      group.subButton.$menuId = group.uuid
-      group.subButton.Ot = config.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
-      group.subButton.$forbid = true
-      group.subButton.OpenType = 'formSubmit'
-      group.subButton.execError = 'never'
-
-      group.subButton.syncComponentId = group.subButton.syncComponent ? group.subButton.syncComponent.pop() : ''
-
-      if (group.subButton.syncComponentId === config.uuid) {
-        group.subButton.syncComponentId = ''
-      }
-
       if (group.subButton.enable === 'false') {
         group.subButton.style.display = 'none'
         group.$button = 'no-button'
       }
-
-      group.fields = group.fields.map(cell => {
-        // 鏁版嵁婧恠ql璇彞锛岄澶勭悊锛屾潈闄愰粦鍚嶅崟瀛楁璁剧疆涓洪殣钘忚〃鍗�
-        if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') {
-          let _option = Utils.getSelectQueryOptions(cell)
-  
-          cell.data_sql = Utils.formatOptions(_option.sql)
-          cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql))
-          cell.arr_field = _option.field
-        }
-  
-        // 瀛楁鏉冮檺榛戝悕鍗�
-        if (!cell.blacklist || !roleId || cell.blacklist.length === 0) return cell
-        if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) {
-          cell.hidden = 'true'
-        }
-  
-        return cell
-      })
 
       return group
     })
@@ -113,6 +78,7 @@
       data: _data,
       group: config.subcards[0],
       BID: BID || '',
+      BData: BData || '',
       config: config,
       arr_field: config.columns.map(col => col.field).join(','),
     }, () => {
@@ -186,16 +152,14 @@
    * @param {*} btn        // 鎵ц鐨勬寜閽�
    */
   refreshByButtonResult = (menuId, position, btn, id) => {
-    const { config, group } = this.state
+    const { config, group, BID } = this.state
 
     if (group.uuid !== menuId) return
 
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-    if (!btn.syncComponentId || btn.syncComponentId !== config.setting.supModule) {
-      if (config.wrap.datatype !== 'static' && config.setting) {
-        this.loadData()
-      }
+    if (position === 'mainline' && config.setting.supModule && BID) {
+      MKEmitter.emit('reloadData', config.setting.supModule, BID)
+    } else {
+      this.loadData()
     }
 
     if (id) {
@@ -205,13 +169,26 @@
     this.execSuccess(btn, id)
   }
 
-  resetParentParam = (MenuID, id) => {
+  resetParentParam = (MenuID, id, data) => {
     const { config } = this.state
-    if (config.wrap.datatype === 'static' || !config.setting.supModule || config.setting.supModule !== MenuID) return
+    if (!config.setting.supModule || config.setting.supModule !== MenuID) return
+
     if (id !== this.state.BID || id !== '') {
-      this.setState({ BID: id }, () => {
-        this.loadData()
-      })
+      if (config.wrap.datatype === 'static' || (config.setting.supModule && !id)) {
+        this.setState({
+          data: null,
+          BID: id,
+          BData: data
+        }, () => {
+          this.setState({
+            data: {$$empty: true}
+          })
+        })
+      } else {
+        this.setState({ BID: id, BData: data }, () => {
+          this.loadData()
+        })
+      }
     }
   }
 
@@ -236,12 +213,14 @@
   }
 
   async loadData () {
-    const { mainSearch, menuType } = this.props
-    const { config, arr_field, BID, group } = this.state
+    const { mainSearch } = this.props
+    const { config, arr_field, BID } = this.state
 
     if (config.wrap.datatype === 'static' || (config.setting.supModule && !BID)) {
       this.setState({
-        data: {$$empty: true}
+        data: null
+      }, () => {
+        this.setState({data: {$$empty: true}})
       })
       return
     }
@@ -258,20 +237,17 @@
     })
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, 1, BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
       let _data = result.data && result.data[0] ? result.data[0] : {$$empty: true}
 
-      let _group = group
-
       this.setState({
-        group: null,
-        data: _data || {$$empty: true},
+        data: null,
         loading: false
       }, () => {
-        this.setState({group: _group})
+        this.setState({data: _data})
       })
     } else {
       this.setState({
@@ -304,7 +280,7 @@
   }
 
   render() {
-    const { config, loading, BID, data, group, dict } = this.state
+    const { config, loading, BID, BData, data, group, dict } = this.state
 
     return (
       <div className="custom-tab-form-box" id={'anchor' + config.uuid} style={{...config.style}}>
@@ -323,6 +299,7 @@
         </div> : null}
         {group && data ? <MutilForm
           BID={BID}
+          BData={BData}
           dict={dict}
           data={data}
           action={group}
@@ -332,7 +309,6 @@
         {group && data ? <div className={'mk-form-action ' + (group.$button || '')}>
           <NormalButton
             BID={BID}
-            position="form"
             btn={group.subButton}
             setting={config.setting}
             columns={config.columns}
diff --git a/src/tabviews/custom/components/form/tab-form/index.scss b/src/tabviews/custom/components/form/tab-form/index.scss
index f1fabf1..370f64a 100644
--- a/src/tabviews/custom/components/form/tab-form/index.scss
+++ b/src/tabviews/custom/components/form/tab-form/index.scss
@@ -59,10 +59,6 @@
       min-width: 70px;
       border: none;
     }
-    .skip {
-      float: right;
-      height: auto;
-    }
   }
   .mk-form-action.no-button {
     padding: 0;
diff --git a/src/tabviews/custom/components/group/normal-group/index.jsx b/src/tabviews/custom/components/group/normal-group/index.jsx
index 19c4411..7874b04 100644
--- a/src/tabviews/custom/components/group/normal-group/index.jsx
+++ b/src/tabviews/custom/components/group/normal-group/index.jsx
@@ -1,6 +1,5 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { connect } from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { Col, Empty, notification, Button, Row } from 'antd'
 
@@ -25,7 +24,7 @@
 const PropCard = asyncComponent(() => import('@/tabviews/custom/components/card/prop-card'))
 const BraftEditor = asyncComponent(() => import('@/tabviews/custom/components/editor/braft-editor'))
 const SandBox = asyncComponent(() => import('@/tabviews/custom/components/code/sand-box'))
-const NormalForm = asyncComponent(() => import('@/tabviews/custom/components/form/normal-form'))
+const NormalForm = asyncComponent(() => import('@/tabviews/custom/components/form/step-form'))
 const TabForm = asyncComponent(() => import('@/tabviews/custom/components/form/tab-form'))
 const NormalTree = asyncComponent(() => import('@/tabviews/custom/components/tree/antd-tree'))
 const CarouselDataCard = asyncComponent(() => import('@/tabviews/custom/components/carousel/data-card'))
@@ -39,7 +38,6 @@
     bids: PropTypes.any,             // 鐖剁骇Id闆�
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 鍏ㄥ眬鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -130,7 +128,7 @@
   }
 
   getComponents = () => {
-    const { menuType, BID, bids, config } = this.props
+    const { BID, bids, config } = this.props
     const { mainSearch, data } = this.state
 
     if (!config || !config.components || config.components.length === 0) return (<Empty description={false} />)
@@ -146,109 +144,109 @@
       if (item.type === 'bar' || item.type === 'line') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvBarAndLine data={data} config={item} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <AntvBarAndLine data={data} config={item} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'pie') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvPie data={data} config={item} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <AntvPie data={data} config={item} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'dashboard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvDashboard config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <AntvDashboard config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'form' && item.subtype === 'stepform') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <NormalForm config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <NormalForm config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'form' && item.subtype === 'tabform') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <TabForm config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <TabForm config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'scatter') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvScatter config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <AntvScatter config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'carousel' && item.subtype === 'datacard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <CarouselDataCard config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <CarouselDataCard config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'carousel' && item.subtype === 'propcard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <CarouselPropCard config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <CarouselPropCard config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'card' && item.subtype === 'datacard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <DataCard config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <DataCard config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'card' && item.subtype === 'propcard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <PropCard config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <PropCard config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'tablecard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <TableCard config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <TableCard config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'normaltable') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <NormalTable config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <NormalTable config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'editable') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <EditTable config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <EditTable config={item} data={data} BID={_bid} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'tree') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <NormalTree config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <NormalTree config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'editor') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <BraftEditor config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <BraftEditor config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'code') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <SandBox config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <SandBox config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'balcony') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <Balcony config={item} data={data} BID={_bid} menuType={menuType} />
+            <Balcony config={item} data={data} BID={_bid}/>
           </Col>
         )
       } else if (item.type === 'chart') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <CustomChart config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <CustomChart config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else {
@@ -342,14 +340,4 @@
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    menuType: state.editLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(TabTransfer)
\ No newline at end of file
+export default TabTransfer
\ No newline at end of file
diff --git a/src/tabviews/custom/components/share/normalTable/index.jsx b/src/tabviews/custom/components/share/normalTable/index.jsx
index c058330..99f8396 100644
--- a/src/tabviews/custom/components/share/normalTable/index.jsx
+++ b/src/tabviews/custom/components/share/normalTable/index.jsx
@@ -1,7 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import md5 from 'md5'
-import { connect } from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { Table, Typography, Col, Switch, message } from 'antd'
 
@@ -135,10 +134,12 @@
 
         if (mark.icon) {
           if (mark.position === 'front') {
-            content = <span><MkIcon style={{color: mark.color}} type={mark.icon} /> {content}</span>
+            content = <span><MkIcon style={mark.innerStyle} type={mark.icon} /> {content}</span>
           } else {
-            content = <span>{content} <MkIcon style={{color: mark.color}} type={mark.icon} /></span>
+            content = <span>{content} <MkIcon style={mark.innerStyle} type={mark.icon} /></span>
           }
+        } else if (mark.innerStyle) {
+          content = <span style={mark.innerStyle}>{content}</span>
         }
       }
       if (col.blur) {
@@ -195,10 +196,12 @@
 
         if (mark.icon) {
           if (mark.position === 'front') {
-            content = <span><MkIcon style={{color: mark.color}} type={mark.icon} /> {content}</span>
+            content = <span><MkIcon style={mark.innerStyle} type={mark.icon} /> {content}</span>
           } else {
-            content = <span>{content} <MkIcon style={{color: mark.color}} type={mark.icon} /></span>
+            content = <span>{content} <MkIcon style={mark.innerStyle} type={mark.icon} /></span>
           }
+        } else if (mark.innerStyle) {
+          content = <span style={mark.innerStyle}>{content}</span>
         }
       }
 
@@ -349,10 +352,12 @@
 
         if (mark.icon) {
           if (mark.position === 'front') {
-            content = <span><MkIcon style={{color: mark.color}} type={mark.icon} /> {content}</span>
+            content = <span><MkIcon style={mark.innerStyle} type={mark.icon} /> {content}</span>
           } else {
-            content = <span>{content} <MkIcon style={{color: mark.color}} type={mark.icon} /></span>
+            content = <span>{content} <MkIcon style={mark.innerStyle} type={mark.icon} /></span>
           }
+        } else if (mark.innerStyle) {
+          content = <span style={mark.innerStyle}>{content}</span>
         }
       }
 
@@ -409,18 +414,18 @@
   }
 
   UNSAFE_componentWillMount () {
-    const { menuType, memberLevel, setting, fields, columns } = this.props
+    const { setting, fields, columns } = this.props
     let radio = 5          // 铏氬寲姣斾緥
     let _format = false    // 鏄惁铏氬寲澶勭悊
     let rowspans = []
     let orderfields = {}
 
-    if (window.GLOB.dataFormat && menuType !== 'HS' && memberLevel) {
+    if (window.GLOB.dataFormat && !window.GLOB.mkHS) {
       _format = true
 
-      if (memberLevel >= 30) {
+      if (window.GLOB.memberLevel >= 30) {
         radio = 20
-      } else if (memberLevel >= 20) {
+      } else if (window.GLOB.memberLevel >= 20) {
         radio = 10
       }
     }
@@ -664,6 +669,7 @@
     let index = ''
     let _activeIndex = null
     if (selectedRowKeys.length > 0) {
+      selectedRowKeys = selectedRowKeys.filter(key => !data[key].$disabled)
       index = selectedRowKeys.slice(-1)[0]
     }
 
@@ -675,7 +681,7 @@
 
     this.setState({ selectedRowKeys, activeIndex: _activeIndex })
 
-    let selects = this.props.data.filter((item, _index) => selectedRowKeys.includes(_index) && !item.$disabled)
+    let selects = data.filter((item, _index) => selectedRowKeys.includes(_index) && !item.$disabled)
 
     this.props.chgSelectData(selects)
     if (setting.$hasSyncModule) {
@@ -843,7 +849,7 @@
     if (!setting.doubleClick) return
     if (record.$disabled) return
 
-    MKEmitter.emit('triggerBtnId', setting.doubleClick, [record])
+    MKEmitter.emit('triggerBtnId', setting.doubleClick, [record], 'linkbtn')
   }
 
   render() {
@@ -929,15 +935,4 @@
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    menuType: state.editLevel,
-    memberLevel: state.memberLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(NormalTable)
\ No newline at end of file
+export default NormalTable
\ No newline at end of file
diff --git a/src/tabviews/custom/components/share/normalTable/index.scss b/src/tabviews/custom/components/share/normalTable/index.scss
index e234a07..cdc9b52 100644
--- a/src/tabviews/custom/components/share/normalTable/index.scss
+++ b/src/tabviews/custom/components/share/normalTable/index.scss
@@ -26,6 +26,12 @@
   .mk-disabled {
     color: #bcbcbc;
     cursor: not-allowed;
+    --mk-table-color: #bcbcbc;
+
+    span, div {
+      color: #bcbcbc!important;
+    }
+
     .ant-btn {
       cursor: not-allowed;
     }
@@ -207,7 +213,7 @@
       font-size: var(--mk-table-font-size)!important;
       font-weight: var(--mk-table-font-weight)!important;
 
-      >span, div:not(.card-cell-list), div:not(.card-cell-list) div, div:not(.card-cell-list) span {
+      >span, >div:not(.card-cell-list) div, >div:not(.card-cell-list) span {
         font-weight: var(--mk-table-font-weight)!important;
       }
     }
diff --git a/src/tabviews/custom/components/share/normalheader/index.jsx b/src/tabviews/custom/components/share/normalheader/index.jsx
index 92848b7..0b19275 100644
--- a/src/tabviews/custom/components/share/normalheader/index.jsx
+++ b/src/tabviews/custom/components/share/normalheader/index.jsx
@@ -9,7 +9,6 @@
 class NormalHeader extends Component {
   static propTpyes = {
     BID: PropTypes.any,        // 涓婄骇涓婚敭鍊�
-    menuType: PropTypes.any,   // 鑿滃崟绫诲瀷
     config: PropTypes.object,  // 閰嶇疆淇℃伅
     refresh: PropTypes.func    // 鏉′欢鍒锋柊
   }
@@ -40,7 +39,7 @@
   }
 
   render() {
-    const { config, menuType, BID } = this.props
+    const { config, BID } = this.props
     const { title, show } = this.state
 
     if (!title && !show) return null
@@ -48,7 +47,7 @@
     return (
       <div className={'normal-header' + (show ? ' header-search' : '')} style={config.headerStyle}>
         <span className="title">{title}</span>
-        {show ? <SearchComponent config={config} BID={BID} menuType={menuType} refreshdata={this.props.refresh}/> : null}
+        {show ? <SearchComponent config={config} BID={BID} refreshdata={this.props.refresh}/> : null}
       </div>
     )
   }
diff --git a/src/tabviews/custom/components/share/normalheader/index.scss b/src/tabviews/custom/components/share/normalheader/index.scss
index 94dba47..e961d6e 100644
--- a/src/tabviews/custom/components/share/normalheader/index.scss
+++ b/src/tabviews/custom/components/share/normalheader/index.scss
@@ -41,6 +41,12 @@
     }
   }
 }
+.normal-header:not(.header-search) {
+  .title {
+    display: block;
+    float: none;
+  }
+}
 .header-search.normal-header {
   display: flex;
 }
diff --git a/src/tabviews/custom/components/share/tabtransfer/index.jsx b/src/tabviews/custom/components/share/tabtransfer/index.jsx
index 2754f25..1fbd303 100644
--- a/src/tabviews/custom/components/share/tabtransfer/index.jsx
+++ b/src/tabviews/custom/components/share/tabtransfer/index.jsx
@@ -1,6 +1,5 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { connect } from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { Row, Col, Empty, notification } from 'antd'
 
@@ -28,7 +27,8 @@
 const NormalGroup = asyncComponent(() => import('@/tabviews/custom/components/group/normal-group'))
 const BraftEditor = asyncComponent(() => import('@/tabviews/custom/components/editor/braft-editor'))
 const SandBox = asyncComponent(() => import('@/tabviews/custom/components/code/sand-box'))
-const NormalForm = asyncComponent(() => import('@/tabviews/custom/components/form/normal-form'))
+const SimpleForm = asyncComponent(() => import('@/tabviews/custom/components/form/simple-form'))
+const StepForm = asyncComponent(() => import('@/tabviews/custom/components/form/step-form'))
 const TabForm = asyncComponent(() => import('@/tabviews/custom/components/form/tab-form'))
 const NormalTree = asyncComponent(() => import('@/tabviews/custom/components/tree/antd-tree'))
 const CarouselDataCard = asyncComponent(() => import('@/tabviews/custom/components/carousel/data-card'))
@@ -41,7 +41,6 @@
     bids: PropTypes.any,             // 鐖剁骇Id闆�
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 鍏ㄥ眬鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -155,7 +154,7 @@
   }
 
   getComponents = () => {
-    const { menuType, bids, config } = this.props
+    const { bids, config } = this.props
     const { mainSearch, data } = this.state
 
     if (!config || !config.components || config.components.length === 0) return (<Empty description={false} />)
@@ -171,127 +170,133 @@
       if (item.type === 'bar' || item.type === 'line') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvBarAndLine data={data} config={item} BID={BID} mainSearch={mainSearch} menuType={menuType} />
+            <AntvBarAndLine data={data} config={item} BID={BID} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'pie') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvPie data={data} config={item} BID={BID} mainSearch={mainSearch} menuType={menuType} />
+            <AntvPie data={data} config={item} BID={BID} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'dashboard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvDashboard config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} />
+            <AntvDashboard config={item} data={data} BID={BID} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'scatter') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvScatter config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} />
+            <AntvScatter config={item} data={data} BID={BID} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'search') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <MainSearch config={item} BID={BID} menuType={menuType} refreshdata={this.resetSearch} />
+            <MainSearch config={item} BID={BID} refreshdata={this.resetSearch} />
           </Col>
         )
       } else if (item.type === 'tabs') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvTabs config={item} BID={BID} bids={bids} mainSearch={mainSearch} menuType={menuType} />
+            <AntvTabs config={item} BID={BID} bids={bids} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'card' && item.subtype === 'datacard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <DataCard config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <DataCard config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'card' && item.subtype === 'propcard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <PropCard config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <PropCard config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'carousel' && item.subtype === 'datacard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <CarouselDataCard config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <CarouselDataCard config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'carousel' && item.subtype === 'propcard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <CarouselPropCard config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <CarouselPropCard config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'tablecard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <TableCard config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <TableCard config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'normaltable') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <NormalTable config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <NormalTable config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'editable') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <EditTable config={item} BID={BID} BData={BData} mainSearch={mainSearch} menuType={menuType} />
+            <EditTable config={item} BID={BID} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'group' && item.subtype === 'normalgroup') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <NormalGroup config={item} BID={BID} bids={bids} mainSearch={mainSearch} menuType={menuType} />
+            <NormalGroup config={item} BID={BID} bids={bids} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'form' && item.subtype === 'simpleform') {
+        return (
+          <Col span={item.width} key={item.uuid}>
+            <SimpleForm config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'form' && item.subtype === 'stepform') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <NormalForm config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} />
+            <StepForm config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'form' && item.subtype === 'tabform') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <TabForm config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} />
+            <TabForm config={item} data={data} BID={BID} BData={BData} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'tree') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <NormalTree config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} />
+            <NormalTree config={item} data={data} BID={BID} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'editor') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <BraftEditor config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} />
+            <BraftEditor config={item} data={data} BID={BID} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'code') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <SandBox config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} />
+            <SandBox config={item} data={data} BID={BID} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'balcony') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <Balcony config={item} data={data} BID={BID} menuType={menuType} />
+            <Balcony config={item} data={data} BID={BID}/>
           </Col>
         )
       } else if (item.type === 'chart') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <CustomChart config={item} data={data} BID={BID} mainSearch={mainSearch} menuType={menuType} />
+            <CustomChart config={item} data={data} BID={BID} mainSearch={mainSearch}/>
           </Col>
         )
       } else {
@@ -307,14 +312,4 @@
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    menuType: state.editLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(TabTransfer)
\ No newline at end of file
+export default TabTransfer
\ No newline at end of file
diff --git a/src/tabviews/custom/components/table/edit-table/index.jsx b/src/tabviews/custom/components/table/edit-table/index.jsx
index 98aed40..f130dc6 100644
--- a/src/tabviews/custom/components/table/edit-table/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/index.jsx
@@ -1,6 +1,5 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { connect } from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { notification } from 'antd'
 
@@ -22,14 +21,12 @@
     BID: PropTypes.any,              // 鐖剁骇Id
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
     BID: '',              // 涓婄骇ID
     BData: '',            // 涓婄骇缁勪欢琛屾暟鎹�
     config: {},           // 椤甸潰閰嶇疆淇℃伅锛屽寘鎷寜閽�佹悳绱€�佹樉绀哄垪銆佹爣绛剧瓑
-    searchlist: null,     // 鎼滅储鏉′欢
     actions: null,        // 鎸夐挳闆�
     columns: null,        // 鏄剧ず鍒�
     arr_field: '',        // 浣跨敤 sPC_Get_TableData 鏃剁殑鏌ヨ瀛楁闆�
@@ -150,7 +147,6 @@
       title: _config.wrap.title,
       config: _config,
       setting: setting,
-      searchlist: _config.search,
       actions: _config.action,
       columns: _columns,
       arr_field: _config.columns.map(col => col.field).join(','),
@@ -204,7 +200,7 @@
     })
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, this.props.menuType)
+    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -267,7 +263,7 @@
     })
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, this.props.menuType, id)
+    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, id)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -358,7 +354,7 @@
     }
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getStatQueryDataParams(setting, config.statFields, searches, _orderBy, BID, this.props.menuType)
+    let param = UtilsDM.getStatQueryDataParams(setting, config.statFields, searches, _orderBy, BID)
 
     Api.genericInterface(param).then(res => {
       if (res.status) {
@@ -524,26 +520,16 @@
 
     if (config.uuid !== menuId) return
 
-    let supModule = config.setting.supModule
-
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-    if (!btn.syncComponentId || btn.syncComponentId !== supModule) {
-      if (position === 'line') {
-        if (lines && lines.length === 1) {
-          this.loadmainLinedata(lines[0].$$uuid)
-        } else {
-          this.reloadtable(btn)
-        }
-      } else if (position === 'mainline' || position === 'popclose') { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
-        if (supModule && BID) {
-          MKEmitter.emit('reloadData', supModule, BID)
-        } else {
-          this.reloadtable(btn)
-        }
+    if (position === 'line') {
+      if (lines && lines.length === 1) {
+        this.loadmainLinedata(lines[0].$$uuid)
       } else {
         this.reloadtable(btn)
       }
+    } else if ((position === 'mainline' || position === 'popclose') && config.setting.supModule && BID) { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
+      MKEmitter.emit('reloadData', config.setting.supModule, BID)
+    } else {
+      this.reloadtable(btn)
     }
 
     if (position === 'popclose') { // 鎵ц鍚姩寮圭獥鐨勬寜閽墍閫夋嫨鐨勫埛鏂伴」
@@ -586,13 +572,13 @@
   }
 
   render() {
-    const { BID, setting, searchlist, actions, config, columns, BData, selectedData, lock } = this.state
+    const { BID, setting, actions, config, columns, BData, selectedData, lock } = this.state
 
     return (
       <div className="custom-edit-table" id={'anchor' + config.uuid} style={config.style}>
         <NormalHeader config={config}/>
-        {searchlist && searchlist.length ?
-          <MainSearch BID={BID} setting={config.wrap} searchlist={searchlist} menuType={this.props.menuType} refreshdata={this.refreshbysearch}/> : null
+        {config.search && config.search.length ?
+          <MainSearch BID={BID} config={config} refreshdata={this.refreshbysearch}/> : null
         }
         <MainAction
           BID={BID}
@@ -623,14 +609,4 @@
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    menuType: state.editLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(EditableTable)
\ No newline at end of file
+export default EditableTable
\ No newline at end of file
diff --git a/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx b/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
index a628ea3..556364e 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
@@ -313,10 +313,12 @@
 
         if (mark.icon) {
           if (mark.position === 'front') {
-            content = <span><MkIcon style={{color: mark.color}} type={mark.icon} /> {content}</span>
+            content = <span><MkIcon style={mark.innerStyle} type={mark.icon} /> {content}</span>
           } else {
-            content = <span>{content} <MkIcon style={{color: mark.color}} type={mark.icon} /></span>
+            content = <span>{content} <MkIcon style={mark.innerStyle} type={mark.icon} /></span>
           }
+        } else if (mark.innerStyle) {
+          content = <span style={mark.innerStyle}>{content}</span>
         }
       }
 
@@ -405,10 +407,12 @@
 
         if (mark.icon) {
           if (mark.position === 'front') {
-            content = <span><MkIcon style={{color: mark.color}} type={mark.icon} /> {content}</span>
+            content = <span><MkIcon style={mark.innerStyle} type={mark.icon} /> {content}</span>
           } else {
-            content = <span>{content} <MkIcon style={{color: mark.color}} type={mark.icon} /></span>
+            content = <span>{content} <MkIcon style={mark.innerStyle} type={mark.icon} /></span>
           }
+        } else if (mark.innerStyle) {
+          content = <span style={mark.innerStyle}>{content}</span>
         }
       }
 
@@ -477,10 +481,12 @@
 
         if (mark.icon) {
           if (mark.position === 'front') {
-            content = <span><MkIcon style={{color: mark.color}} type={mark.icon} /> {content}</span>
+            content = <span><MkIcon style={mark.innerStyle} type={mark.icon} /> {content}</span>
           } else {
-            content = <span>{content} <MkIcon style={{color: mark.color}} type={mark.icon} /></span>
+            content = <span>{content} <MkIcon style={mark.innerStyle} type={mark.icon} /></span>
           }
+        } else if (mark.innerStyle) {
+          content = <span style={mark.innerStyle}>{content}</span>
         }
       }
 
@@ -728,10 +734,12 @@
 
           if (mark.icon) {
             if (mark.position === 'front') {
-              content = <span><MkIcon style={{color: mark.color}} type={mark.icon} /> {content}</span>
+              content = <span><MkIcon style={mark.innerStyle} type={mark.icon} /> {content}</span>
             } else {
-              content = <span>{content} <MkIcon style={{color: mark.color}} type={mark.icon} /></span>
+              content = <span>{content} <MkIcon style={mark.innerStyle} type={mark.icon} /></span>
             }
+          } else if (mark.innerStyle) {
+            content = <span style={mark.innerStyle}>{content}</span>
           }
         }
         children = content
@@ -779,10 +787,12 @@
 
           if (mark.icon) {
             if (mark.position === 'front') {
-              content = <span><MkIcon style={{color: mark.color}} type={mark.icon} /> {content}</span>
+              content = <span><MkIcon style={mark.innerStyle} type={mark.icon} /> {content}</span>
             } else {
-              content = <span>{content} <MkIcon style={{color: mark.color}} type={mark.icon} /></span>
+              content = <span>{content} <MkIcon style={mark.innerStyle} type={mark.icon} /></span>
             }
+          } else if (mark.innerStyle) {
+            content = <span style={mark.innerStyle}>{content}</span>
           }
         }
         children = content
@@ -836,10 +846,12 @@
 
         if (mark.icon) {
           if (mark.position === 'front') {
-            content = <span><MkIcon style={{color: mark.color}} type={mark.icon} /> {content}</span>
+            content = <span><MkIcon style={mark.innerStyle} type={mark.icon} /> {content}</span>
           } else {
-            content = <span>{content} <MkIcon style={{color: mark.color}} type={mark.icon} /></span>
+            content = <span>{content} <MkIcon style={mark.innerStyle} type={mark.icon} /></span>
           }
+        } else if (mark.innerStyle) {
+          content = <span style={mark.innerStyle}>{content}</span>
         }
       }
 
diff --git a/src/tabviews/custom/components/table/edit-table/normalTable/index.scss b/src/tabviews/custom/components/table/edit-table/normalTable/index.scss
index 0fa9c9f..754dda6 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.scss
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.scss
@@ -156,7 +156,7 @@
       left: 0px;
       right: 0px;
       bottom: 0px;
-      border: 1px solid var(--antd-wave-shadow-color);
+      border: 1px solid var(--mk-sys-color);
       height: auto;
       border-radius: 0;
       box-shadow: none!important;
@@ -196,7 +196,7 @@
         left: 0px;
         right: 0px;
         bottom: 0px;
-        border: 1px solid var(--antd-wave-shadow-color);
+        border: 1px solid var(--mk-sys-color);
       }
     }
     .anticon-exclamation-circle {
@@ -310,7 +310,7 @@
       font-size: var(--mk-table-font-size)!important;
       font-weight: var(--mk-table-font-weight)!important;
 
-      >span, div:not(.card-cell-list), div:not(.card-cell-list) div, div:not(.card-cell-list) span {
+      >span, >div:not(.card-cell-list) div, >div:not(.card-cell-list) span {
         font-weight: var(--mk-table-font-weight)!important;
       }
     }
diff --git a/src/tabviews/custom/components/table/normal-table/index.jsx b/src/tabviews/custom/components/table/normal-table/index.jsx
index 2cdf426..29532d5 100644
--- a/src/tabviews/custom/components/table/normal-table/index.jsx
+++ b/src/tabviews/custom/components/table/normal-table/index.jsx
@@ -1,6 +1,5 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import {connect} from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { notification, Collapse } from 'antd'
 
@@ -25,14 +24,12 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
     BID: '',              // 涓婄骇ID
     BData: '',            // 涓婄骇缁勪欢琛屾暟鎹�
     config: {},           // 椤甸潰閰嶇疆淇℃伅锛屽寘鎷寜閽�佹悳绱€�佹樉绀哄垪銆佹爣绛剧瓑
-    searchlist: null,     // 鎼滅储鏉′欢
     actions: null,        // 鎸夐挳闆�
     columns: null,        // 鏄剧ず鍒�
     arr_field: '',        // 浣跨敤 sPC_Get_TableData 鏃剁殑鏌ヨ瀛楁闆�
@@ -151,7 +148,6 @@
       data: _data,
       config: _config,
       setting: setting,
-      searchlist: _config.search,
       actions: _config.action,
       columns: _config.cols,
       arr_field: _config.columns.map(col => col.field).join(','),
@@ -212,7 +208,7 @@
     })
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, this.props.menuType)
+    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -292,7 +288,7 @@
     })
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, this.props.menuType, id)
+    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, id)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -375,7 +371,7 @@
     }
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getStatQueryDataParams(setting, config.statFields, searches, _orderBy, BID, this.props.menuType)
+    let param = UtilsDM.getStatQueryDataParams(setting, config.statFields, searches, _orderBy, BID)
 
     Api.genericInterface(param).then(res => {
       if (res.status) {
@@ -541,26 +537,16 @@
 
     if (config.uuid !== menuId) return
 
-    let supModule = config.setting.supModule
-
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-    if (!btn.syncComponentId || btn.syncComponentId !== supModule) {
-      if (position === 'line') {
-        if (lines && lines.length === 1) {
-          this.loadmainLinedata(lines[0].$$uuid)
-        } else {
-          this.reloadtable(btn, id)
-        }
-      } else if (position === 'mainline' || position === 'popclose') { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
-        if (supModule && BID) {
-          MKEmitter.emit('reloadData', supModule, BID)
-        } else {
-          this.reloadtable(btn, id)
-        }
+    if (position === 'line') {
+      if (lines && lines.length === 1) {
+        this.loadmainLinedata(lines[0].$$uuid)
       } else {
         this.reloadtable(btn, id)
       }
+    } else if ((position === 'mainline' || position === 'popclose') && config.setting.supModule && BID) { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
+      MKEmitter.emit('reloadData', config.setting.supModule, BID)
+    } else {
+      this.reloadtable(btn, id)
     }
 
     if (position === 'popclose') { // 鎵ц鍚姩寮圭獥鐨勬寜閽墍閫夋嫨鐨勫埛鏂伴」
@@ -635,7 +621,7 @@
   }
 
   render() {
-    const { BID, setting, searchlist, actions, config, columns, selectedData, BData, data } = this.state
+    const { BID, setting, actions, config, columns, selectedData, BData, data } = this.state
 
     let style = {...config.style}
     if (config.wrap.empty === 'hidden' && (!data || data.length === 0)) {
@@ -646,8 +632,8 @@
       <div className="custom-normal-table" id={'anchor' + config.uuid} style={style}>
         {config.wrap.collapse === 'true' ? <Collapse bordered={false} defaultActiveKey="1" expandIconPosition="right">
           <Panel forceRender={true} header={<NormalHeader config={config}/>} key="1">
-            {searchlist && searchlist.length ?
-              <MainSearch BID={BID} setting={config.wrap} searchlist={searchlist} menuType={this.props.menuType} refreshdata={this.refreshbysearch}/> : null
+            {config.search && config.search.length ?
+              <MainSearch BID={BID} config={config} refreshdata={this.refreshbysearch}/> : null
             }
             <MainAction
               BID={BID}
@@ -675,8 +661,8 @@
           </Panel>
         </Collapse> : <>
           <NormalHeader config={config}/>
-          {searchlist && searchlist.length ?
-            <MainSearch BID={BID} setting={config.wrap} searchlist={searchlist} menuType={this.props.menuType} refreshdata={this.refreshbysearch}/> : null
+          {config.search && config.search.length ?
+            <MainSearch BID={BID} config={config} refreshdata={this.refreshbysearch}/> : null
           }
           <MainAction
             BID={BID}
@@ -707,14 +693,4 @@
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    menuType: state.editLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(NormalTable)
\ No newline at end of file
+export default NormalTable
\ No newline at end of file
diff --git a/src/tabviews/custom/components/tabs/antv-tabs/index.jsx b/src/tabviews/custom/components/tabs/antv-tabs/index.jsx
index e098179..064a1d0 100644
--- a/src/tabviews/custom/components/tabs/antv-tabs/index.jsx
+++ b/src/tabviews/custom/components/tabs/antv-tabs/index.jsx
@@ -17,7 +17,6 @@
     bids: PropTypes.any,             // 鐖剁骇Id闆�
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
diff --git a/src/tabviews/custom/components/timeline/normal-timeline/index.jsx b/src/tabviews/custom/components/timeline/normal-timeline/index.jsx
index 2a62ef0..13127d8 100644
--- a/src/tabviews/custom/components/timeline/normal-timeline/index.jsx
+++ b/src/tabviews/custom/components/timeline/normal-timeline/index.jsx
@@ -19,7 +19,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -158,20 +157,10 @@
 
     if (config.uuid !== menuId) return
 
-    let supModule = config.setting.supModule
-
-    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
-
-    if (!btn.syncComponentId || btn.syncComponentId !== supModule) {
-      if (position === 'mainline' || position === 'popclose') { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
-        if (supModule && BID) {
-          MKEmitter.emit('reloadData', supModule, BID)
-        } else {
-          this.loadData()
-        }
-      } else {
-        this.loadData()
-      }
+    if ((position === 'mainline' || position === 'popclose') && config.setting.supModule && BID) { // 鍒锋柊婧愮粍浠舵椂锛岄檮甯﹀埛鏂颁笂绾ц涓庡綋鍓嶇粍浠�
+      MKEmitter.emit('reloadData', config.setting.supModule, BID)
+    } else {
+      this.loadData()
     }
 
     if (position === 'popclose') { // 鎵ц鍚姩寮圭獥鐨勬寜閽墍閫夋嫨鐨勫埛鏂伴」
@@ -226,7 +215,7 @@
   }
 
   async loadData () {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, BID, BData } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
@@ -256,7 +245,7 @@
     })
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, config.setting.pageSize, BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, 1, config.setting.pageSize, BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -314,6 +303,62 @@
     </Timeline.Item>)
   }
 
+  getMknodes = (data) => {
+    const { config, card } = this.state
+
+    let color = config.wrap.color
+    let dot = ''
+    let linebg = {}
+    if (config.wrap.node && card.nodes && card.nodes.length > 0) {
+      let sign = data[config.wrap.node]
+      card.nodes.some(item => {
+        if (sign === item.sign) {
+          color = item.color
+
+          if (item.icon) {
+            dot = <MkIcon type={item.icon}/>
+          }
+
+          if (item.linecolor) {
+            linebg = {borderColor: item.linecolor}
+          }
+          return true
+        }
+        return false
+      })
+    }
+
+    if (config.wrap.mode === 'down') {
+      return (<div className="mk-time-line-item" key={data.$Index}>
+        <div className="mk-timeline-item-content">
+          <div className="card-item-box" style={card.style}>
+            <CardCellComponent data={data} cards={config} cardCell={card} elements={card.elements}/>
+          </div>
+        </div>
+        <div className="mk-timeline-item-head">
+          <div className="mk-timeline-item-tail" style={linebg}></div>
+          <div className={'mk-dot ' + (dot ? 'mk-dot-icon' : '')} style={{background: color}}>
+            {dot}
+          </div>
+        </div>
+      </div>)
+    } else {
+      return (<div className="mk-time-line-item" key={data.$Index}>
+        <div className="mk-timeline-item-head">
+          <div className="mk-timeline-item-tail" style={linebg}></div>
+          <div className={'mk-dot ' + (dot ? 'mk-dot-icon' : '')} style={{background: color}}>
+            {dot}
+          </div>
+        </div>
+        <div className="mk-timeline-item-content">
+          <div className="card-item-box" style={card.style}>
+            <CardCellComponent data={data} cards={config} cardCell={card} elements={card.elements}/>
+          </div>
+        </div>
+      </div>)
+    }
+  }
+
   render() {
     const { config, loading, data } = this.state
 
@@ -326,9 +371,12 @@
           </div> : null
         }
         <NormalHeader config={config} />
-        {data && data.length > 0 ? <Timeline mode={config.wrap.mode} reverse={config.wrap.reverse === 'true'} className={'card-row-list ' + (config.wrap.line || '')} style={{height: config.wrap.contentHeight}}>
+        {config.wrap.direction !== 'horizontal' && data && data.length > 0 ? <Timeline mode={config.wrap.mode} className={'card-row-list ' + (config.wrap.line || '')} style={{height: config.wrap.contentHeight}}>
           {data.map(item => this.getnodes(item))}
         </Timeline> : null}
+        {config.wrap.direction === 'horizontal' && data && data.length > 0 ? <div className={'mk-time-line-wrap card-row-list ' + (config.wrap.line || '')} style={{height: config.wrap.contentHeight}}>
+          {data.map(item => this.getMknodes(item))}
+        </div> : null}
         {data && data.length === 0 ? <div className="card-row-list" style={{height: config.wrap.contentHeight}}>
           <Empty description={false}/>
         </div> : null}
diff --git a/src/tabviews/custom/components/timeline/normal-timeline/index.scss b/src/tabviews/custom/components/timeline/normal-timeline/index.scss
index 13333b6..3fecd28 100644
--- a/src/tabviews/custom/components/timeline/normal-timeline/index.scss
+++ b/src/tabviews/custom/components/timeline/normal-timeline/index.scss
@@ -39,9 +39,13 @@
     }
   }
 
+  .ant-timeline-item {
+    padding-bottom: 0px;
+  }
+
   .card-row-list {
     overflow-y: auto;
-    padding: 20px;
+    padding: 15px;
     .card-item-box {
       text-align: left;
       overflow: hidden;
@@ -94,6 +98,58 @@
       background: #ffffff;
     }
   }
+
+  .mk-time-line-wrap {
+    display: flex;
+    overflow-x: hidden;
+    .mk-time-line-item {
+      position: relative;
+      width: 5%;
+      flex: 1;
+    }
+    .mk-time-line-item:last-child {
+      .mk-timeline-item-tail {
+        display: none;
+      }
+    }
+    .mk-timeline-item-head {
+      position: relative;
+      height: 20px;
+      text-align: center;
+      .mk-dot {
+        position: absolute;
+        background: #e8e8e8;
+        padding: 5px;
+        display: inline-block;
+        border-radius: 20px;
+        z-index: 1;
+        top: 50%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+
+        .anticon {
+          font-size: 14px;
+          color: #ffffff;
+          width: 16px;
+          height: 16px;
+          vertical-align: top;
+        }
+      }
+      .mk-dot-icon {
+        width: 24px;
+        height: 24px;
+        padding: 4px;
+      }
+    }
+    .mk-timeline-item-tail {
+      position: absolute;
+      top: 10px;
+      left: 0px;
+      width: 100%;
+      transform: translate(50%, -1px);
+      border-top: 2px solid #e8e8e8;
+    } 
+  }
 }
 
 .normal-timeline-box::after {
diff --git a/src/tabviews/custom/components/tree/antd-tree/index.jsx b/src/tabviews/custom/components/tree/antd-tree/index.jsx
index da54069..9aaf9a1 100644
--- a/src/tabviews/custom/components/tree/antd-tree/index.jsx
+++ b/src/tabviews/custom/components/tree/antd-tree/index.jsx
@@ -20,7 +20,6 @@
     data: PropTypes.array,           // 缁熶竴鏌ヨ鏁版嵁
     config: PropTypes.object,        // 缁勪欢閰嶇疆淇℃伅
     mainSearch: PropTypes.any,       // 澶栧眰鎼滅储鏉′欢
-    menuType: PropTypes.any,         // 鑿滃崟绫诲瀷
   }
 
   state = {
@@ -146,22 +145,30 @@
         })
         return
       } else if (result.run_type) {
-        this.setState({timer})
+        let repeats = config.timerRepeats || 0
+        this.setState({timer, repeats})
         this.timer = setTimeout(() => {
-          this.timerTask()
+          this.timerTask(repeats)
         }, timer)
       }
     })
   }
 
-  timerTask = () => {
-    const { timer } = this.state
+  timerTask = (times) => {
+    const { timer, repeats } = this.state
     if (!timer) return
     
     this.loadData(true)
-    
+
+    if (repeats) {
+      times = times - 1
+      if (times <= 0) {
+        clearTimeout(this.timer)
+        return
+      }
+    }
     this.timer = setTimeout(() => {
-      this.timerTask()
+      this.timerTask(times)
     }, timer)
   }
 
@@ -188,7 +195,7 @@
    * @description 鏁版嵁鍔犺浇
    */
   async loadData (hastimer) {
-    const { mainSearch, menuType } = this.props
+    const { mainSearch } = this.props
     const { config, arr_field, BID } = this.state
 
     if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇�
@@ -214,7 +221,7 @@
     }
 
     let _orderBy = config.setting.order || ''
-    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID, menuType)
+    let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -470,7 +477,7 @@
           </div> : null
         }
         {config.wrap.title || config.wrap.searchable === 'true' ? <div className="tree-header" style={config.headerStyle}>
-          <span className="title">{config.wrap.title}</span>
+          <span className={'title ' + (config.wrap.searchable !== 'true' ? 'search-unable' : '')}>{config.wrap.title}</span>
           {config.wrap.searchable === 'true' ? <Search allowClear onSearch={this.treeFilter} /> : null}
         </div> : null}
         {treeNodes && treeNodes.length > 0 ? <div className="tree-box" style={{height: config.wrap.contentHeight}}>
diff --git a/src/tabviews/custom/components/tree/antd-tree/index.scss b/src/tabviews/custom/components/tree/antd-tree/index.scss
index 859f346..0ab6c56 100644
--- a/src/tabviews/custom/components/tree/antd-tree/index.scss
+++ b/src/tabviews/custom/components/tree/antd-tree/index.scss
@@ -24,6 +24,10 @@
       position: relative;
       z-index: 1;
     }
+    .title.search-unable {
+      display: block;
+      float: none;
+    }
     .ant-input-search.ant-input-affix-wrapper {
       width: 50%;
       max-width: 150px;
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index f3d603c..29a1d27 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -23,7 +23,8 @@
 const AntvScatter = asyncComponent(() => import('./components/chart/antv-scatter'))
 const DataCard = asyncComponent(() => import('./components/card/data-card'))
 const PropCard = asyncComponent(() => import('./components/card/prop-card'))
-const NormalForm = asyncComponent(() => import('./components/form/normal-form'))
+const SimpleForm = asyncComponent(() => import('./components/form/simple-form'))
+const StepForm = asyncComponent(() => import('./components/form/step-form'))
 const TabForm = asyncComponent(() => import('./components/form/tab-form'))
 const CarouselDataCard = asyncComponent(() => import('./components/carousel/data-card'))
 const CarouselPropCard = asyncComponent(() => import('./components/carousel/prop-card'))
@@ -92,7 +93,7 @@
       }
 
       // HS涓嶄娇鐢ㄨ嚜瀹氫箟璁剧疆
-      if (result.LongParamUser && this.props.menuType !== 'HS') {
+      if (result.LongParamUser && !window.GLOB.mkHS) {
         try { // 閰嶇疆淇℃伅瑙f瀽
           let userConfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParamUser)))
           if (userConfig) {
@@ -136,7 +137,7 @@
       // 鏉冮檺杩囨护
       let roleId = sessionStorage.getItem('role_id') || '' // 瑙掕壊ID
       let balMap = new Map()
-      let skip = config.permission === 'false' || this.props.menuType === 'HS'
+      let skip = config.permission === 'false' || window.GLOB.mkHS
       config.components = this.filterComponent(config.components, roleId, permAction, balMap, skip)
       
       // 鑾峰彇涓绘悳绱㈡潯浠�
@@ -168,7 +169,6 @@
 
       let userName = sessionStorage.getItem('User_Name') || ''
       let fullName = sessionStorage.getItem('Full_Name') || ''
-      let city = sessionStorage.getItem('city') || ''
 
       if (sessionStorage.getItem('isEditState') === 'true') {
         userName = sessionStorage.getItem('CloudUserName') || ''
@@ -177,8 +177,7 @@
 
       let regs = [
         { reg: /@userName@/ig, value: `'${userName}'` },
-        { reg: /@fullName@/ig, value: `'${fullName}'` },
-        { reg: /@login_city@/ig, value: `'${city}'` }
+        { reg: /@fullName@/ig, value: `'${fullName}'` }
       ]
       
       if (window.GLOB.externalDatabase !== null) {
@@ -304,7 +303,7 @@
 
   loadOutResource = (inters) => {
     let setting = inters.shift()
-    let param = UtilsDM.getPrevQueryParams(setting, [], this.state.BID, this.props.menuType)
+    let param = UtilsDM.getPrevQueryParams(setting, [], this.state.BID)
 
     Api.genericInterface(param).then(res => {
       if (res.status) {
@@ -405,13 +404,13 @@
       `))
       sql = sql.join('')
       
-      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql)
+      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql, this.state.BID)
 
       if (this.state.BID) {
         param.BID = this.state.BID
       }
 
-      if (this.props.menuType === 'HS') { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
+      if (window.GLOB.mkHS) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
         param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
       }
     } else {
@@ -523,23 +522,6 @@
         }
       }
 
-      if (item.wrap && item.wrap.supType === 'multi') { // 鏁版嵁鍗″涓婄骇缁勪欢
-        if (item.supNodes && item.supNodes[0]) {
-          item.setting.supModule = item.supNodes[0].componentId
-        } else {
-          item.wrap.supType = 'single'
-          item.supNodes = null
-          item.setting.supModule = ''
-        }
-      } else if (item.setting && item.setting.supModule) {
-        let pid = item.setting.supModule.pop()
-        if (pid && pid !== 'empty') {
-          item.setting.supModule = pid
-        } else {
-          item.setting.supModule = ''
-        }
-      }
-
       // 鎼滅储鏉′欢鍒濆鍖�
       if (item.search && item.search.length > 0) {
         item.search = Utils.initSearchVal(item.search)
@@ -569,6 +551,18 @@
               col.elements = col.elements.map(cell => {
                 if (['text', 'number', 'link'].includes(cell.eleType) && !cell.height) {
                   cell.innerHeight = 'auto'
+                } else if (cell.eleType === 'icon') {
+                  let fontSize = 14
+                  let lineHeight = 1.5
+            
+                  if (cell.style.fontSize) {
+                    fontSize = parseInt(cell.style.fontSize)
+                  }
+                  if (cell.style.lineHeight) {
+                    lineHeight = parseFloat(cell.style.lineHeight)
+                  }
+            
+                  cell.innerHeight = fontSize * lineHeight
                 }
                 return cell
               })
@@ -589,6 +583,19 @@
         item.statFields = statFields
       }
 
+      let mutil = false
+      if (item.wrap && item.wrap.supType === 'multi') { // 鏁版嵁鍗″涓婄骇缁勪欢
+        mutil = true
+        item.setting.supModule = item.supNodes[0].componentId
+      } else if (item.setting && item.setting.supModule) {
+        let pid = item.setting.supModule.pop()
+        if (pid && pid !== 'empty') {
+          item.setting.supModule = pid
+        } else {
+          item.setting.supModule = ''
+        }
+      }
+
       // 鏉冮檺杩囨护
       let tabId = this.props.Tab ? this.props.Tab.uuid : '' // 寮圭獥鏍囩鎸夐挳Id
       if (item.action && item.action.length > 0) {
@@ -602,8 +609,9 @@
           cell.$MenuID = this.props.MenuID
           cell.$tabId = tabId
           cell.$view = 'CustomPage'
+          cell.$toolbtn = true
 
-          if (cell.syncComponentId === item.uuid) {
+          if (!mutil && cell.syncComponentId === item.setting.supModule) {
             cell.syncComponentId = ''
           }
 
@@ -644,7 +652,7 @@
               cell.$tabId = tabId
               cell.$view = 'CustomPage'
 
-              if (cell.syncComponentId === item.uuid) {
+              if (!mutil && cell.syncComponentId === item.setting.supModule) {
                 cell.syncComponentId = ''
               }
 
@@ -657,6 +665,18 @@
               }
             } else if (['text', 'number', 'link'].includes(cell.eleType) && !cell.height && _hasheight) {
               cell.innerHeight = 'auto'
+            } else if (cell.eleType === 'icon') {
+              let fontSize = 14
+              let lineHeight = 1.5
+        
+              if (cell.style.fontSize) {
+                fontSize = parseInt(cell.style.fontSize)
+              }
+              if (cell.style.lineHeight) {
+                lineHeight = parseFloat(cell.style.lineHeight)
+              }
+        
+              cell.innerHeight = fontSize * lineHeight
             }
 
             return cell.eleType !== 'button' || skip || permAction[cell.uuid]
@@ -674,7 +694,7 @@
               cell.$tabId = tabId
               cell.$view = 'CustomPage'
 
-              if (cell.syncComponentId === item.uuid) {
+              if (!mutil && cell.syncComponentId === item.setting.supModule) {
                 cell.syncComponentId = ''
               }
 
@@ -687,7 +707,20 @@
               }
             } else if (['text', 'number', 'link'].includes(cell.eleType) && !cell.height && _hasheight) {
               cell.innerHeight = 'auto'
+            } else if (cell.eleType === 'icon') {
+              let fontSize = 14
+              let lineHeight = 1.5
+        
+              if (cell.style.fontSize) {
+                fontSize = parseInt(cell.style.fontSize)
+              }
+              if (cell.style.lineHeight) {
+                lineHeight = parseFloat(cell.style.lineHeight)
+              }
+        
+              cell.innerHeight = fontSize * lineHeight
             }
+            
             return cell.eleType !== 'button' || skip || permAction[cell.uuid]
           })
         })
@@ -695,6 +728,9 @@
         if (item.wrap.linkType === 'sync') {
           item.wrap.syncModuleId = item.wrap.syncModule.pop()
           balMap.set(item.wrap.syncModuleId, true)
+        } else if (item.wrap.linkType === 'sup') {
+          item.wrap.supModule = item.wrap.supModule.pop()
+          item.setting.supModule = item.wrap.supModule
         }
         item.elements = item.elements.filter(cell => {
           if (cell.eleType === 'button') {
@@ -708,7 +744,7 @@
             cell.$tabId = tabId
             cell.$view = 'CustomPage'
 
-            if (cell.syncComponentId === item.uuid) {
+            if (cell.syncComponentId === item.wrap.supModule) {
               cell.syncComponentId = ''
             }
 
@@ -717,6 +753,18 @@
             }
           } else if (['text', 'number', 'link'].includes(cell.eleType) && !cell.height) {
             cell.innerHeight = 'auto'
+          } else if (cell.eleType === 'icon') {
+            let fontSize = 14
+            let lineHeight = 1.5
+      
+            if (cell.style.fontSize) {
+              fontSize = parseInt(cell.style.fontSize)
+            }
+            if (cell.style.lineHeight) {
+              lineHeight = parseFloat(cell.style.lineHeight)
+            }
+      
+            cell.innerHeight = fontSize * lineHeight
           }
 
           return cell.eleType !== 'button' || skip || permAction[cell.uuid]
@@ -737,7 +785,7 @@
               cell.$tabId = tabId
               cell.$view = 'CustomPage'
 
-              if (cell.syncComponentId === item.uuid) {
+              if (cell.syncComponentId === item.setting.supModule) {
                 cell.syncComponentId = ''
               }
 
@@ -750,6 +798,18 @@
               }
             } else if (['text', 'number', 'link'].includes(cell.eleType) && !cell.height && _hasheight) {
               cell.innerHeight = 'auto'
+            } else if (cell.eleType === 'icon') {
+              let fontSize = 14
+              let lineHeight = 1.5
+        
+              if (cell.style.fontSize) {
+                fontSize = parseInt(cell.style.fontSize)
+              }
+              if (cell.style.lineHeight) {
+                lineHeight = parseFloat(cell.style.lineHeight)
+              }
+        
+              cell.innerHeight = fontSize * lineHeight
             }
             return cell.eleType !== 'button' || skip || permAction[cell.uuid]
           })
@@ -769,7 +829,7 @@
             cell.$tabId = tabId
             cell.$view = 'CustomPage'
 
-            if (cell.syncComponentId === item.uuid) {
+            if (cell.syncComponentId === item.setting.supModule) {
               cell.syncComponentId = ''
             }
 
@@ -791,14 +851,46 @@
           item.submit.logLabel = item.$menuname + '-鎻愪氦'
           item.submit.$menuId = item.uuid
         }
-      }
+      } else if (item.type === 'form') {
+        item.subcards = item.subcards.map(group => {
+          group.subButton.uuid = group.uuid
+          group.subButton.$menuId = group.uuid
+          // group.subButton.$forbid = true // 涓嶅0鏄庢暟鎹簮鍙橀噺
+          group.subButton.OpenType = 'formSubmit'
+          group.subButton.execError = 'never'
 
-      // if (item.wrap && item.wrap.doubleClick) {
-      //   let index = item.action.findIndex((btn) => btn.uuid === item.wrap.doubleClick)
-      //   if (index === -1) {
-      //     item.wrap.doubleClick = ''
-      //   }
-      // }
+          if (!group.subButton.Ot) {
+            group.subButton.Ot = item.wrap.datatype === 'static' ? 'notRequired' : 'requiredSgl'
+          }
+
+          group.subButton.syncComponentId = group.subButton.syncComponent ? group.subButton.syncComponent.pop() : ''
+
+          if (group.subButton.syncComponentId === item.setting.supModule) {
+            group.subButton.syncComponentId = ''
+          }
+
+          group.fields = group.fields.map(cell => {
+            // 鏁版嵁婧恠ql璇彞锛岄澶勭悊锛屾潈闄愰粦鍚嶅崟瀛楁璁剧疆涓洪殣钘忚〃鍗�
+            if (['select', 'link', 'multiselect', 'radio', 'checkbox', 'checkcard'].includes(cell.type) && cell.resourceType === '1') {
+              let _option = Utils.getSelectQueryOptions(cell)
+      
+              cell.data_sql = Utils.formatOptions(_option.sql)
+              cell.base_sql = window.btoa(window.encodeURIComponent(_option.sql))
+              cell.arr_field = _option.field
+            }
+      
+            // 瀛楁鏉冮檺榛戝悕鍗�
+            if (!cell.blacklist || !roleId || cell.blacklist.length === 0) return cell
+            if (cell.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) {
+              cell.hidden = 'true'
+            }
+      
+            return cell
+          })
+
+          return group
+        })
+      }
       
       return true
     })
@@ -975,7 +1067,7 @@
    * @description 涓昏〃鏁版嵁鍔犺浇
    */ 
   loadmaindata = (params) => {
-    let param = getStructuredParams(params, this.state.config, this.state.BID)
+    let param = getStructuredParams(params, this.state.config, this.state.BID || '')
 
     this.setState({loading: true, loadingview: false})
 
@@ -1066,7 +1158,6 @@
   }
 
   getComponents = () => {
-    const { menuType } = this.props
     const { config, BID, data, mainSearch } = this.state
 
     if (!config || !config.components) return
@@ -1080,43 +1171,49 @@
       if (item.type === 'bar' || item.type === 'line') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvBarAndLine config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <AntvBarAndLine config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'pie') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvPie config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <AntvPie config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'scatter') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvScatter config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <AntvScatter config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'dashboard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvDashboard config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <AntvDashboard config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'form' && item.subtype === 'simpleform') {
+        return (
+          <Col span={item.width} key={item.uuid}>
+            <SimpleForm config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'form' && item.subtype === 'stepform') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <NormalForm config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <StepForm config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'form' && item.subtype === 'tabform') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <TabForm config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <TabForm config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'search') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <MainSearch config={item} BID={BID} menuType={menuType} refreshdata={this.resetSearch} />
+            <MainSearch config={item} BID={BID} refreshdata={this.resetSearch} />
           </Col>
         )
       } else if (item.type === 'tabs') {
@@ -1128,85 +1225,85 @@
       } else if (item.type === 'card' && item.subtype === 'datacard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <DataCard config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <DataCard config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'card' && item.subtype === 'propcard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <PropCard config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <PropCard config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'balcony') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <Balcony config={item} data={data} BID={_bid} menuType={menuType} />
+            <Balcony config={item} data={data} BID={_bid}/>
           </Col>
         )
       } else if (item.type === 'timeline') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <TimeLine config={item} data={data} BID={_bid} menuType={menuType} />
+            <TimeLine config={item} data={data} BID={_bid}/>
           </Col>
         )
       } else if (item.type === 'carousel' && item.subtype === 'datacard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <CarouselDataCard config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <CarouselDataCard config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'carousel' && item.subtype === 'propcard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <CarouselPropCard config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <CarouselPropCard config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'tablecard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <TableCard config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <TableCard config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'normaltable') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <NormalTable config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <NormalTable config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'editable') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <EditTable config={item} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <EditTable config={item} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'group' && item.subtype === 'normalgroup') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <NormalGroup config={item} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <NormalGroup config={item} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'editor') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <BraftEditor config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <BraftEditor config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'tree') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <NormalTree config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <NormalTree config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'code') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <SandBox config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <SandBox config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'chart') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <CustomChart config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} />
+            <CustomChart config={item} data={data} BID={_bid} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'module' && item.subtype === 'voucher') {
@@ -1222,15 +1319,14 @@
   }
 
   render() {
-    const { menuType } = this.props
     const { loadingview, viewlost, config, loading, shortcuts } = this.state
 
     return (
       <div className={'custom-page-wrap ' + (loadingview || loading ? 'loading' : '')} id={this.state.ContainerId} style={config ? config.style : null}>
         {(loadingview || loading) ? <Spin className="view-spin" size="large" /> : null}
         <Row className="component-wrap">{this.getComponents()}</Row>
-        {menuType !== 'HS' && window.GLOB.systemType !== 'production' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
-        {menuType !== 'HS' && shortcuts ? <SettingComponent config={config} dict={this.state.dict} shortcuts={shortcuts} permAction={this.props.permAction}/> : null}
+        {!window.GLOB.mkHS && window.GLOB.systemType !== 'production' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
+        {!window.GLOB.mkHS && shortcuts ? <SettingComponent config={config} dict={this.state.dict} shortcuts={shortcuts} permAction={this.props.permAction}/> : null}
         {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
       </div>
     )
@@ -1239,7 +1335,6 @@
 
 const mapStateToProps = (state) => {
   return {
-    menuType: state.editLevel,
     refreshTab: state.refreshTab,
     permAction: state.permAction,
     permMenus: state.permMenus
diff --git a/src/tabviews/formtab/actionList/index.jsx b/src/tabviews/formtab/actionList/index.jsx
index 17b6493..a9f47c9 100644
--- a/src/tabviews/formtab/actionList/index.jsx
+++ b/src/tabviews/formtab/actionList/index.jsx
@@ -11,7 +11,6 @@
 
 class MainAction extends Component {
   static propTpyes = {
-    menuType: PropTypes.any,       // 鑿滃崟绫诲瀷锛屾櫘閫氳彍鍗曟垨HS
     MenuID: PropTypes.string,      // 鑿滃崟ID
     primaryId: PropTypes.string,   // 涓婚敭
     actions: PropTypes.array,      // 鎸夐挳缁�
@@ -142,7 +141,7 @@
         param.LText = Utils.formatOptions(param.LText)
       }
 
-      if (this.props.menuType === 'HS' && param.timestamp) { // 浜戠楠岃瘉
+      if (window.GLOB.mkHS && param.timestamp) { // 浜戠楠岃瘉
         param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
       }
 
@@ -208,7 +207,7 @@
         // 澶栭儴璇锋眰
         _outParam = JSON.parse(JSON.stringify(res))
   
-        if (this.props.menuType === 'HS') {
+        if (window.GLOB.mkHS) {
           if (btn.sysInterface === 'true' && options.cloudServiceApi) {
             res.rduri = options.cloudServiceApi
           } else if (btn.sysInterface !== 'true') {
diff --git a/src/tabviews/formtab/index.jsx b/src/tabviews/formtab/index.jsx
index a94d93b..9c15dfd 100644
--- a/src/tabviews/formtab/index.jsx
+++ b/src/tabviews/formtab/index.jsx
@@ -103,7 +103,7 @@
         config.tabgroups = _tabgroups
       }
 
-      if (this.props.menuType !== 'HS') {
+      if (!window.GLOB.mkHS) {
         config.action = config.action.filter(item => permAction[item.uuid])
         config.tabgroups.forEach(group => {
           group.sublist = group.sublist.filter(tab => {
@@ -214,7 +214,7 @@
           param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
           param.secretkey = Utils.encrypt(param.LText, param.timestamp)
 
-          if (this.props.menuType === 'HS') { // 浜戠鏁版嵁楠岃瘉
+          if (window.GLOB.mkHS) { // 浜戠鏁版嵁楠岃瘉
             param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
 
             if (item.database === 'sso' && options.cloudServiceApi) { // 瀛樺湪浜戠鍦板潃鏃讹紝浣跨敤浜戠绯荤粺鍙傛暟
@@ -438,7 +438,7 @@
     param.secretkey = Utils.encrypt(param.LText, param.timestamp)
     param.DateCount = ''
 
-    if (this.props.menuType !== 'HS') { // 浜戠鏁版嵁楠岃瘉
+    if (!window.GLOB.mkHS) { // 浜戠鏁版嵁楠岃瘉
       param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
     }
 
@@ -456,7 +456,7 @@
     if (setting.interType === 'inner') {
       param.func = setting.innerFunc
     } else {
-      if (this.props.menuType === 'HS') {
+      if (window.GLOB.mkHS) {
         if (setting.sysInterface === 'true' && options.cloudServiceApi) {
           param.rduri = options.cloudServiceApi
         } else if (setting.sysInterface !== 'true') {
@@ -622,7 +622,6 @@
         }
         {hasform ?
           <FormAction
-            menuType={this.props.menuType}
             setting={setting}
             actions={actions}
             dict={this.state.dict}
@@ -661,7 +660,7 @@
             )
           })
         }
-        {this.props.menuType !== 'HS' && window.GLOB.systemType !== 'production' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
+        {!window.GLOB.mkHS && window.GLOB.systemType !== 'production' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
         {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
       </div>
     )
@@ -670,7 +669,6 @@
 
 const mapStateToProps = (state) => {
   return {
-    menuType: state.editLevel,
     permAction: state.permAction
   }
 }
diff --git a/src/tabviews/scriptmanage/actionList/index.jsx b/src/tabviews/scriptmanage/actionList/index.jsx
index 0aa7502..6ddf524 100644
--- a/src/tabviews/scriptmanage/actionList/index.jsx
+++ b/src/tabviews/scriptmanage/actionList/index.jsx
@@ -277,7 +277,6 @@
         destroyOnClose
       >
         <MutilForm
-          menuType="HS"
           dict={this.props.dict}
           action={execAction}
           inputSubmit={this.handleOk}
diff --git a/src/tabviews/scriptmanage/index.jsx b/src/tabviews/scriptmanage/index.jsx
index 1773ebd..63947a9 100644
--- a/src/tabviews/scriptmanage/index.jsx
+++ b/src/tabviews/scriptmanage/index.jsx
@@ -308,7 +308,7 @@
 
     return (
       <div className="script-manage-table" id={this.state.ContainerId}>
-        <MainSearch searchlist={searchlist} menuType="HS" refreshdata={this.refreshbysearch}/>
+        <MainSearch searchlist={searchlist} refreshdata={this.refreshbysearch}/>
         <MainAction
           BID=""
           type="main"
diff --git a/src/tabviews/subtable/index.jsx b/src/tabviews/subtable/index.jsx
index b5fa826..8d8fc3f 100644
--- a/src/tabviews/subtable/index.jsx
+++ b/src/tabviews/subtable/index.jsx
@@ -133,7 +133,7 @@
       config = updateSubTable(config)
 
       // 鏉冮檺杩囨护
-      if (this.props.menuType !== 'HS') {
+      if (!window.GLOB.mkHS) {
         config.action = config.action.filter(item => item.hidden !== 'true' && permAction[item.uuid])
       } else {
         config.action = config.action.filter(item => item.hidden !== 'true')
@@ -251,6 +251,7 @@
           }
         }
         if (item.position === 'toolbar') {
+          item.$toolbtn = true
           _actions.push(item)
         } else if (item.position === 'grid') {
           _operations.push(item)
@@ -301,7 +302,6 @@
 
         let userName = sessionStorage.getItem('User_Name') || ''
         let fullName = sessionStorage.getItem('Full_Name') || ''
-        let city = sessionStorage.getItem('city') || ''
 
         if (sessionStorage.getItem('isEditState') === 'true') {
           userName = sessionStorage.getItem('CloudUserName') || ''
@@ -310,8 +310,7 @@
 
         let regs = [
           { reg: /@userName@/ig, value: `'${userName}'` },
-          { reg: /@fullName@/ig, value: `'${fullName}'` },
-          { reg: /@login_city@/ig, value: `'${city}'` }
+          { reg: /@fullName@/ig, value: `'${fullName}'` }
         ]
 
         regs.forEach(cell => {
@@ -431,7 +430,7 @@
   loadOutResource = (searches) => {
     const { setting, BID } = this.state
 
-    let param = UtilsDM.getPrevQueryParams(setting, searches, BID, this.props.menuType)
+    let param = UtilsDM.getPrevQueryParams(setting, searches, BID)
 
     if (setting.execType === 'sync') {
       this.setState({
@@ -545,13 +544,13 @@
       `))
       sql = sql.join('')
       
-      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql)
+      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql, BID)
 
       if (BID) {
         param.BID = BID
       }
 
-      if (this.props.menuType === 'HS') { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
+      if (window.GLOB.mkHS) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
         param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
       }
     } else {
@@ -612,7 +611,7 @@
     })
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, this.props.menuType)
+    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID)
 
     let result = await Api.genericInterface(param)
 
@@ -692,7 +691,7 @@
     })
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, this.props.menuType, id)
+    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, id)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -761,7 +760,7 @@
     if (statFields.length === 0 || !(setting.interType === 'system' || (setting.interType === 'custom' && setting.requestMode === 'system')) || !setting.dataresource) return
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getStatQueryDataParams(setting, statFields, searches, _orderBy, BID, this.props.menuType)
+    let param = UtilsDM.getStatQueryDataParams(setting, statFields, searches, _orderBy, BID)
 
     Api.genericInterface(param).then(res => {
       if (res.status) {
@@ -1000,7 +999,7 @@
       <div className="subtable" id={'subtable' + this.props.MenuID}>
         {loadingview && <Spin />}
         {searchlist && searchlist.length ?
-          <SubSearch BID={BID} setting={setting} searchlist={searchlist} menuType={this.props.menuType} refreshdata={this.refreshbysearch}/> : null
+          <SubSearch BID={BID} setting={setting} searchlist={searchlist} refreshdata={this.refreshbysearch}/> : null
         }
         {config && config.charts ? <Row className="chart-view" gutter={16}>
           {/* 瑙嗗浘缁� */}
@@ -1131,7 +1130,6 @@
 
 const mapStateToProps = (state) => {
   return {
-    menuType: state.editLevel,
     permAction: state.permAction,
     permMenus: state.permMenus,
   }
diff --git a/src/tabviews/subtabtable/index.jsx b/src/tabviews/subtabtable/index.jsx
index 5919a9d..4c89fbe 100644
--- a/src/tabviews/subtabtable/index.jsx
+++ b/src/tabviews/subtabtable/index.jsx
@@ -128,7 +128,7 @@
       }
 
       // 鏉冮檺杩囨护
-      if (this.props.menuType !== 'HS') {
+      if (!window.GLOB.mkHS) {
         config.action = config.action.filter(item => item.hidden !== 'true' && permAction[item.uuid])
       } else {
         config.action = config.action.filter(item => item.hidden !== 'true')
@@ -209,6 +209,7 @@
         item.$menuId = this.props.MenuID
 
         if (item.position === 'toolbar') {
+          item.$toolbtn = true
           _actions.push(item)
         } else if (item.position === 'grid') {
           _operations.push(item)
@@ -259,7 +260,6 @@
 
         let userName = sessionStorage.getItem('User_Name') || ''
         let fullName = sessionStorage.getItem('Full_Name') || ''
-        let city = sessionStorage.getItem('city') || ''
 
         if (sessionStorage.getItem('isEditState') === 'true') {
           userName = sessionStorage.getItem('CloudUserName') || ''
@@ -268,8 +268,7 @@
 
         let regs = [
           { reg: /@userName@/ig, value: `'${userName}'` },
-          { reg: /@fullName@/ig, value: `'${fullName}'` },
-          { reg: /@login_city@/ig, value: `'${city}'` }
+          { reg: /@fullName@/ig, value: `'${fullName}'` }
         ]
 
         regs.forEach(cell => {
@@ -370,7 +369,7 @@
   loadOutResource = (searches) => {
     const { setting } = this.state
 
-    let param = UtilsDM.getPrevQueryParams(setting, searches, this.props.BID, this.props.menuType)
+    let param = UtilsDM.getPrevQueryParams(setting, searches, this.props.BID)
 
     if (setting.execType === 'sync') {
       this.setState({
@@ -484,13 +483,13 @@
       `))
       sql = sql.join('')
       
-      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql)
+      param = UtilsDM.getCallBackQueryParams(setting, sql, errSql, this.props.BID)
 
       if (this.props.BID) {
         param.BID = this.props.BID
       }
 
-      if (this.props.menuType === 'HS') { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
+      if (window.GLOB.mkHS) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
         param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
       }
     } else {
@@ -549,7 +548,7 @@
     })
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, this.props.menuType)
+    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID)
 
     let result = await Api.genericInterface(param)
 
@@ -619,7 +618,7 @@
     if (statFields.length === 0 || !(setting.interType === 'system' || (setting.interType === 'custom' && setting.requestMode === 'system')) || !setting.dataresource) return
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getStatQueryDataParams(setting, statFields, searches, _orderBy, BID, this.props.menuType)
+    let param = UtilsDM.getStatQueryDataParams(setting, statFields, searches, _orderBy, BID)
 
     Api.genericInterface(param).then(res => {
       if (res.status) {
@@ -668,7 +667,7 @@
     })
 
     let _orderBy = orderBy || setting.order
-    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, this.props.menuType, id)
+    let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, id)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -856,7 +855,7 @@
       <div className="subtabtable" id={'subtabtable' + this.props.MenuID}>
         {loadingview && <Spin />}
         {searchlist && searchlist.length ?
-          <SubSearch BID={this.props.BID} setting={setting} searchlist={searchlist} menuType={this.props.menuType} refreshdata={this.refreshbysearch}/> : null
+          <SubSearch BID={this.props.BID} setting={setting} searchlist={searchlist} refreshdata={this.refreshbysearch}/> : null
         }
         {config ? <div style={{minHeight: '25px'}}>
           <SubAction
@@ -893,9 +892,7 @@
 
 const mapStateToProps = (state) => {
   return {
-    menuType: state.editLevel,
-    permAction: state.permAction,
-    memberLevel: state.memberLevel
+    permAction: state.permAction
   }
 }
 
diff --git a/src/tabviews/treepage/index.jsx b/src/tabviews/treepage/index.jsx
index 936dac9..f68831b 100644
--- a/src/tabviews/treepage/index.jsx
+++ b/src/tabviews/treepage/index.jsx
@@ -181,7 +181,6 @@
 
         let userName = sessionStorage.getItem('User_Name') || ''
         let fullName = sessionStorage.getItem('Full_Name') || ''
-        let city = sessionStorage.getItem('city') || ''
 
         if (sessionStorage.getItem('isEditState') === 'true') {
           userName = sessionStorage.getItem('CloudUserName') || ''
@@ -190,8 +189,7 @@
 
         let regs = [
           { reg: /@userName@/ig, value: `'${userName}'` },
-          { reg: /@fullName@/ig, value: `'${fullName}'` },
-          { reg: /@login_city@/ig, value: `'${city}'` }
+          { reg: /@fullName@/ig, value: `'${fullName}'` }
         ]
 
         regs.forEach(cell => {
@@ -276,7 +274,7 @@
     })
 
     let arr_field = `${setting.valueField},${setting.labelField},${setting.parentField}`
-    let param = UtilsDM.getQueryDataParams(setting, arr_field, [], setting.order, '', '', BID, this.props.menuType)
+    let param = UtilsDM.getQueryDataParams(setting, arr_field, [], setting.order, '', '', BID)
 
     let result = await Api.genericInterface(param)
     if (result.status) {
@@ -570,7 +568,6 @@
   }
 
   render() {
-    const { menuType } = this.props
     const { setting, loadingview, viewlost, config, tabgroups, treeNodes, treedata, expandedKeys, selectedKeys, shortcuts } = this.state
 
     return (
@@ -634,8 +631,8 @@
             )}
           </Col>
         </Row> : null}
-        {menuType !== 'HS' && window.GLOB.systemType !== 'production' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
-        {menuType !== 'HS' && shortcuts ? <SettingComponent config={config} dict={this.state.dict} shortcuts={shortcuts} permAction={this.props.permAction}/> : null}
+        {!window.GLOB.mkHS && window.GLOB.systemType !== 'production' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
+        {!window.GLOB.mkHS && shortcuts ? <SettingComponent config={config} dict={this.state.dict} shortcuts={shortcuts} permAction={this.props.permAction}/> : null}
         {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
       </div>
     )
@@ -644,9 +641,7 @@
 
 const mapStateToProps = (state) => {
   return {
-    menuType: state.editLevel,
-    permAction: state.permAction,
-    memberLevel: state.memberLevel
+    permAction: state.permAction
   }
 }
 
diff --git a/src/tabviews/verupmanage/actionList/index.jsx b/src/tabviews/verupmanage/actionList/index.jsx
index 23dd7ef..41c9e8b 100644
--- a/src/tabviews/verupmanage/actionList/index.jsx
+++ b/src/tabviews/verupmanage/actionList/index.jsx
@@ -37,7 +37,7 @@
     execAction: null,
     loadingUuid: '',
     configMap: {},
-    loadingNumber: ''
+    loadingNumber: '',
   }
 
   refreshdata = (item, type) => {
@@ -341,6 +341,11 @@
             _resolve()
           })
         } else { // 瓒呭嚭20涓姹傛椂寰幆鎵ц
+          if (btn.progress === 'progressbar') {
+            this.setState({
+              loadingTotal: _params.length
+            })
+          }
           this.innerLoopRequest(_params, btn, _resolve)
         }
       }
@@ -399,8 +404,14 @@
         })
       }
 
+      if (_params.length > 1 && btn.progress === 'progressbar') {
+        this.setState({
+          loadingTotal: _params.length
+        })
+      }
+
       // 寰幆璋冪敤澶栭儴鎺ュ彛锛堝寘鎷唴閮ㄥ強鍥炶皟鍑芥暟锛�
-      this.outerLoopRequest(_params, btn, _resolve, _params.length > 20)
+      this.outerLoopRequest(_params, btn, _resolve)
     }
   }
 
@@ -413,7 +424,7 @@
     let param = params.shift()
 
     this.setState({
-      loadingNumber: params.length || ''
+      loadingNumber: params.length
     })
 
     Api.genericInterface(param).then(res => {
@@ -434,7 +445,7 @@
   /**
    * @description 澶栭儴璇锋眰寰幆鎵ц
    */
-  outerLoopRequest = (params, btn, _resolve, widthNumber) => {
+  outerLoopRequest = (params, btn, _resolve) => {
     if (!params && params.length === 0) return
 
     let param = params.shift()
@@ -442,11 +453,9 @@
     let _localParam = null
     let errRes = null
 
-    if (widthNumber) {
-      this.setState({
-        loadingNumber: params.length || ''
-      })
-    }
+    this.setState({
+      loadingNumber: params.length
+    })
 
     new Promise(resolve => {
       // 鍐呴儴璇锋眰
@@ -535,7 +544,7 @@
             this.execSuccess(btn, response)
             _resolve()
           } else {
-            this.outerLoopRequest(params, btn, _resolve, widthNumber)
+            this.outerLoopRequest(params, btn, _resolve)
           }
         } else {
           this.execError(response, btn)
@@ -555,7 +564,7 @@
           this.execSuccess(btn, res)
           _resolve()
         } else {
-          this.outerLoopRequest(params, btn, _resolve, widthNumber)
+          this.outerLoopRequest(params, btn, _resolve)
         }
       } else {
         this.execError(res, btn)
@@ -569,7 +578,7 @@
           this.execSuccess(btn, res)
           _resolve()
         } else {
-          this.outerLoopRequest(params, btn, _resolve, widthNumber)
+          this.outerLoopRequest(params, btn, _resolve)
         }
       } else {
         this.execError(errRes || res, btn)
@@ -775,7 +784,6 @@
         destroyOnClose
       >
         <MutilForm
-          menuType="HS"
           dict={this.props.dict}
           action={execAction}
           inputSubmit={this.handleOk}
@@ -795,7 +803,7 @@
       <div className="verup-button-list verup-toolbar-button">
         {this.props.actions.map((item, index) => {
           let label = item.label
-          if (loadingUuid === item.uuid && loadingNumber !== '') {
+          if (loadingUuid === item.uuid && loadingNumber) {
             label = label + '(' + loadingNumber + ')'
           }
           return (
diff --git a/src/tabviews/verupmanage/config.jsx b/src/tabviews/verupmanage/config.jsx
index e6ee268..527dcec 100644
--- a/src/tabviews/verupmanage/config.jsx
+++ b/src/tabviews/verupmanage/config.jsx
@@ -16,8 +16,8 @@
     {label: '浼犺緭鍙�', field: 'VersionName', type: 'text', initval:'', oriInitval: '', required: false, match: 'like', uuid: '1581736007223d84ddmht4gdfb1850nh'}
   ],
   action:[
-    {label:'娣诲姞',OpenType:'pop',intertype:'outer',innerFunc:'',sysInterface:'true',outerFunc:'s_get_sVersiondetail_Up',interface:'http://cloud.mk9h.cn/webapi/dostars',callbackFunc:'s_sVersion_Local_add',position:'toolbar',Ot:'notRequired',execSuccess:'grid',execError:'never',icon:'',class:'green',uuid:'1583979660949vpssdb2p2lsqff9abkr'},
-    {label:'鍏抽棴',OpenType:'prompt',intertype:'inner',innerFunc:'',position:'toolbar',Ot:'requiredSgl',execSuccess:'grid',execError:'never',icon:'',class:'border-danger',sql:'sVersion',sqlType:'LogicDelete',uuid:'1583979660949msql0p8bgiiedlu4r82',
+    {label:'娣诲姞',OpenType:'pop',intertype:'outer',innerFunc:'',sysInterface:'true',outerFunc:'s_get_sVersiondetail_Up',interface:'http://cloud.mk9h.cn/webapi/dostars',callbackFunc:'s_sVersion_Local_add',position:'toolbar',$toolbtn: true,Ot:'notRequired',execSuccess:'grid',execError:'never',icon:'',class:'green',uuid:'1583979660949vpssdb2p2lsqff9abkr'},
+    {label:'鍏抽棴',OpenType:'prompt',intertype:'inner',innerFunc:'',position:'toolbar',$toolbtn: true,Ot:'requiredSgl',execSuccess:'grid',execError:'never',icon:'',class:'border-danger',sql:'sVersion',sqlType:'LogicDelete',uuid:'1583979660949msql0p8bgiiedlu4r82',
       verify: {
         default: 'false',
         invalid: 'true',
@@ -102,8 +102,8 @@
       {label:'缁煎悎鏌ヨ',field:'Remark,KeyWords,TypeName',type:'text',initval:'', oriInitval: '', required: false,match:'like','ratio':6,uuid:'1583983588787acl55md59fu9kpb52db'}
     ],
     action:[
-      {label:'鎵ц',OpenType:'pop',intertype:'outer',innerFunc:'',sysInterface:'true',outerFunc:'s_get_sVersionDetail_Ltext',interface:'http://cloud.mk9h.cn/webapi/dostars',callbackFunc:'s_sDataDictb_TBBack',position:'toolbar',execSuccess:'grid',execError:'never',icon:'',class:'primary',Ot:'required',uuid:'1583983849299g1qfd28g3c9n9e0e57a',verify:null},
-      {label:'鍏抽棴',OpenType:'prompt',intertype:'inner',innerFunc:'',position:'toolbar',Ot:'required',execSuccess:'grid',execError:'never',icon:'',class:'border-danger',sql:'sVersionDetail_Local',sqlType:'LogicDelete',uuid:'1583984089282i4i140hacimbki9s5gh',
+      {label:'鎵ц',OpenType:'pop',intertype:'outer',innerFunc:'',sysInterface:'true',outerFunc:'s_get_sVersionDetail_Ltext',interface:'http://cloud.mk9h.cn/webapi/dostars',callbackFunc:'s_sDataDictb_TBBack',position:'toolbar',$toolbtn: true,execSuccess:'grid',execError:'never',icon:'',class:'primary',Ot:'required',progress: 'progressbar',uuid:'1583983849299g1qfd28g3c9n9e0e57a',verify:null},
+      {label:'鍏抽棴',OpenType:'prompt',intertype:'inner',innerFunc:'',position:'toolbar',$toolbtn: true,Ot:'required',progress: 'progressbar',execSuccess:'grid',execError:'never',icon:'',class:'border-danger',sql:'sVersionDetail_Local',sqlType:'LogicDelete',uuid:'1583984089282i4i140hacimbki9s5gh',
         verify:{
           default: 'true',
           invalid: 'true',
diff --git a/src/tabviews/verupmanage/index.jsx b/src/tabviews/verupmanage/index.jsx
index fe65a69..9c1f4b3 100644
--- a/src/tabviews/verupmanage/index.jsx
+++ b/src/tabviews/verupmanage/index.jsx
@@ -110,6 +110,8 @@
         if (buttonConfig[item.uuid]) {
           item = {...buttonConfig[item.uuid], ...item}
         }
+        item.$toolbtn = true
+        
         return item
       }),
       columns: _columns,
@@ -454,7 +456,7 @@
 
     return (
       <div className="veruptable" id={this.state.ContainerId}>
-        <MainSearch searchlist={searchlist} menuType="HS" refreshdata={this.refreshbysearch}/>
+        <MainSearch searchlist={searchlist} refreshdata={this.refreshbysearch}/>
         <MainAction
           BID=""
           type="main"
diff --git a/src/tabviews/verupmanage/subtabtable/index.jsx b/src/tabviews/verupmanage/subtabtable/index.jsx
index a64b977..0d69d00 100644
--- a/src/tabviews/verupmanage/subtabtable/index.jsx
+++ b/src/tabviews/verupmanage/subtabtable/index.jsx
@@ -128,6 +128,7 @@
         if (buttonConfig[item.uuid]) {
           item = {...buttonConfig[item.uuid], ...item}
         }
+        item.$toolbtn = true
         return item
       }),
       columns: _columns,
@@ -418,7 +419,7 @@
     return (
       <div className="verup-subtable" id={'subtable' + this.props.MenuID}>
         {searchlist && searchlist.length ?
-          <MainSearch searchlist={searchlist} menuType="HS" refreshdata={this.refreshbysearch}/> : null
+          <MainSearch searchlist={searchlist} refreshdata={this.refreshbysearch}/> : null
         }
         {actions ?
           <div className="sub-action">
diff --git a/src/tabviews/zshare/actionList/changeuserbutton/index.jsx b/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
index 5f0839b..01f08c0 100644
--- a/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/changeuserbutton/index.jsx
@@ -14,7 +14,6 @@
 
 class NewPageButton extends Component {
   static propTpyes = {
-    show: PropTypes.any,              // 鎸夐挳鏄剧ず鏍峰紡鎺у埗
     MenuID: PropTypes.any,            // 鑿滃崟ID
     BData: PropTypes.any,             // 涓昏〃鏁版嵁
     BID: PropTypes.string,            // 涓昏〃ID
@@ -22,7 +21,6 @@
     selectedData: PropTypes.any,      // 瀛愯〃涓�夋嫨鏁版嵁
     setting: PropTypes.any,           // 椤甸潰閫氱敤璁剧疆
     disabled: PropTypes.any,          // 琛屾寜閽鐢�
-    lineId: PropTypes.any,            // 琛岀储寮�+涓婚敭鍊硷紝鐢ㄤ簬琛屾寜閽弻鍑�
   }
 
   state = {
@@ -119,12 +117,7 @@
     const { loading, disabled } = this.state
     
     if (loading || disabled) return
-    if (triggerId) {
-      if (btn.uuid !== triggerId) return
-      if (this.props.lineId && record && record[0] && this.props.lineId !== record[0].$$key) {
-        return
-      }
-    }
+    if (triggerId && btn.uuid !== triggerId) return
 
     if (btn.funcType === 'closetab') {
       MKEmitter.emit('closeTabView', MenuID || btn.$MenuID)
@@ -133,10 +126,8 @@
         MKEmitter.emit('reloadMenuView', btn.refreshTab[btn.refreshTab.length - 1], 'table')
       }
       return
-    } else if (type === 'linkbtn' && selectedData && selectedData.length === 1) {
-      if (record[0].$Index !== selectedData[0].$Index) {
-        return
-      }
+    } else if (type === 'linkbtn' && !btn.$toolbtn && !is(fromJS(selectedData || []), fromJS(record))) {
+      return
     }
     
     let data = record || selectedData || []
@@ -204,6 +195,7 @@
               sessionStorage.setItem('role_id', res.role_id || '')
               sessionStorage.setItem('departmentcode', res.departmentcode || '')
               sessionStorage.setItem('organization', res.organization || '')
+              sessionStorage.setItem('mk_user_type', res.mk_user_type || '')
               sessionStorage.setItem('localRole_id', res.role_id || '')
               
               sessionStorage.removeItem('CloudAvatar')
@@ -235,51 +227,47 @@
   }
 
   render() {
-    const { btn, show } = this.props
+    const { btn } = this.props
     const { loading, disabled, hidden } = this.state
 
     if (hidden) return null
 
-    if (show === 'actionList') {
-      return (
-        <Button
-          icon={btn.icon}
-          loading={loading}
-          disabled={disabled}
-          title={disabled ? (btn.reason || '') : ''}
-          className={'mk-btn mk-' + btn.class}
-          onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
-        >{btn.label}</Button>
-      )
-    } else { // icon銆乼ext銆� all 鍗$墖
-      let label = ''
-      let icon = ''
+    let label = ''
+    let icon = ''
+    let type = 'link'
+    let className = ''
 
-      if (show === 'button') {
-        label = btn.label
-        icon = btn.icon || ''
-      } else if (show === 'link') {
-        label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
-        icon = ''
-      } else if (show === 'icon') {
-        icon = btn.icon || ''
-      // } else if (show === 'text') {
-      } else {
-        label = btn.label
-      }
-
-      return (
-        <Button
-          type="link"
-          title={disabled ? (btn.reason || '') : (show === 'icon' ? btn.label : '')}
-          loading={loading}
-          disabled={disabled}
-          style={btn.style}
-          icon={icon}
-          onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
-        >{label}</Button>
-      )
+    if (btn.show === 'button') {
+      label = btn.label
+      icon = btn.icon || ''
+    } else if (btn.show === 'link') {
+      label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
+      icon = ''
+    } else if (btn.show === 'icon') {
+      icon = btn.icon || ''
+    } else if (!btn.$toolbtn) {
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
+    } else {
+      type = ''
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
     }
+
+    return (
+      <Button
+        type={type}
+        title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
+        loading={loading}
+        disabled={disabled}
+        style={btn.style}
+        icon={icon}
+        className={className}
+        onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
+      >{label}</Button>
+    )
   }
 }
 
diff --git a/src/tabviews/zshare/actionList/excelInbutton/index.jsx b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
index b535cfc..81148eb 100644
--- a/src/tabviews/zshare/actionList/excelInbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -1,7 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import moment from 'moment'
-import {connect} from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { Button, Modal, notification, message } from 'antd'
 
@@ -17,7 +16,6 @@
 
 class ExcelInButton extends Component {
   static propTpyes = {
-    show: PropTypes.any,              // 鏄剧ず鏍峰紡
     BID: PropTypes.string,            // 涓昏〃ID
     BData: PropTypes.any,             // 涓昏〃鏁版嵁
     selectedData: PropTypes.any,      // 瀛愯〃涓�夋嫨鏁版嵁
@@ -25,7 +23,6 @@
     btn: PropTypes.object,            // 鎸夐挳
     setting: PropTypes.any,           // 椤甸潰閫氱敤璁剧疆
     disabled: PropTypes.any,          // 琛屾寜閽鐢�
-    lineId: PropTypes.any,            // 琛岀储寮�+涓婚敭鍊硷紝鐢ㄤ簬琛屾寜閽弻鍑�
   }
 
   state = {
@@ -124,12 +121,7 @@
     const { loading, disabled } = this.state
 
     if (loading || disabled) return
-    if (triggerId) {
-      if (btn.uuid !== triggerId) return
-      if (this.props.lineId && record && record[0] && this.props.lineId !== record[0].$$key) {
-        return
-      }
-    }
+    if (triggerId && btn.uuid !== triggerId) return
 
     if (((Tab && Tab.supMenu) || setting.supModule) && !BID) {
       notification.warning({
@@ -138,10 +130,8 @@
         duration: 5
       })
       return
-    } else if (type === 'linkbtn' && selectedData && selectedData.length === 1) {
-      if (record[0].$Index !== selectedData[0].$Index) {
-        return
-      }
+    } else if (type === 'linkbtn' && !btn.$toolbtn && !is(fromJS(selectedData || []), fromJS(record))) {
+      return
     }
 
     let data = record || selectedData || []
@@ -213,9 +203,9 @@
       MKEmitter.emit('popclose')
     } else if (btn.execSuccess !== 'never') {
       MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess, btn, '', this.state.selines)
-    } else {
-      btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
     }
+    
+    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
     
     if (btn.switchTab && btn.switchTab.length > 0) {
       let id = btn.switchTab[btn.switchTab.length - 1]
@@ -352,7 +342,7 @@
       param.LText = Utils.formatOptions(result.sql)
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
       param.secretkey = Utils.encrypt(param.LText, param.timestamp)
-      if (this.props.menuType === 'HS' && param.timestamp) { // 浜戠楠岃瘉
+      if (window.GLOB.mkHS && param.timestamp) { // 浜戠楠岃瘉
         param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
       }
 
@@ -419,7 +409,7 @@
         // 澶栭儴璇锋眰
         _outParam = fromJS(res).toJS()
 
-        if (this.props.menuType === 'HS') {
+        if (window.GLOB.mkHS) {
           if (btn.sysInterface === 'true' && options.cloudServiceApi) {
             param.rduri = options.cloudServiceApi
           } else if (btn.sysInterface !== 'true') {
@@ -445,7 +435,7 @@
           res.func = btn.outerFunc
         }
         
-        if (this.props.menuType === 'HS' && res.func === 's_sDataDictb_excelIn') { // s_sDataDictb_excelIn 浜戠楠岃瘉
+        if (window.GLOB.mkHS && res.func === 's_sDataDictb_excelIn') { // s_sDataDictb_excelIn 浜戠楠岃瘉
           param.LText = Utils.formatOptions(result.sql)
           param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
           param.secretkey = Utils.encrypt(param.LText, param.timestamp)
@@ -485,64 +475,49 @@
   }
 
   render() {
-    const { btn, show } = this.props
+    const { btn } = this.props
     const { loading, disabled, hidden } = this.state
 
     if (hidden) return null
 
-    if (show === 'actionList') {
-      return <div style={{display: 'inline-block'}} onClick={(e) => e.stopPropagation()}>
-        <Button
-          icon={btn.icon}
-          loading={loading}
-          disabled={disabled}
-          title={disabled ? (btn.reason || '') : ''}
-          className={'mk-btn mk-' + btn.class}
-          onClick={() => {this.actionTrigger()}}
-        >{btn.label}</Button>
-        <ExcelIn btn={btn} triggerExcelIn={() => this.setState({ loading: true })} returndata={this.getexceldata} ref="excelIn" />
-      </div>
-    } else { // icon銆乼ext銆� all 鍗$墖
-      let label = ''
-      let icon = ''
+    let label = ''
+    let icon = ''
+    let type = 'link'
+    let className = ''
 
-      if (show === 'button') {
-        label = btn.label
-        icon = btn.icon || ''
-      } else if (show === 'link') {
-        label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
-        icon = ''
-      } else if (show === 'icon') {
-        icon = btn.icon || 'upload'
-      // } else if (show === 'text') {
-      } else {
-        label = btn.label
-      }
-
-      return <div style={{display: 'inline-block'}} onClick={(e) => e.stopPropagation()}>
-        <Button
-          type="link"
-          title={disabled ? (btn.reason || '') : (show === 'icon' ? btn.label : '')}
-          loading={loading}
-          disabled={disabled}
-          style={btn.style}
-          icon={icon}
-          onClick={() => {this.actionTrigger()}}
-        >{label}</Button>
-        <ExcelIn btn={btn} triggerExcelIn={() => this.setState({ loading: true })} returndata={this.getexceldata} ref="excelIn" />
-      </div>
+    if (btn.show === 'button') {
+      label = btn.label
+      icon = btn.icon || ''
+    } else if (btn.show === 'link') {
+      label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
+      icon = ''
+    } else if (btn.show === 'icon') {
+      icon = btn.icon || 'upload'
+    } else if (!btn.$toolbtn) {
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
+    } else {
+      type = ''
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
     }
+
+    return <>
+      <Button
+        type={type}
+        title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
+        loading={loading}
+        disabled={disabled}
+        style={btn.style}
+        icon={icon}
+        className={className}
+        onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
+      >{label}</Button>
+      <ExcelIn btn={btn} triggerExcelIn={() => this.setState({ loading: true })} returndata={this.getexceldata} ref="excelIn" />
+    </>
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    menuType: state.editLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(ExcelInButton)
\ No newline at end of file
+export default ExcelInButton
\ No newline at end of file
diff --git a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
index 3648ac6..437bf21 100644
--- a/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/exceloutbutton/index.jsx
@@ -1,7 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import moment from 'moment'
-import {connect} from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { Button, Modal, notification, message } from 'antd'
 import * as XLSX from 'xlsx'
@@ -19,13 +18,11 @@
   static propTpyes = {
     BID: PropTypes.string,            // 涓昏〃ID
     BData: PropTypes.any,             // 涓昏〃鏁版嵁
-    show: PropTypes.any,              // 鏄剧ず鏍峰紡
     Tab: PropTypes.any,               // 濡傛灉褰撳墠鍏冪礌涓烘爣绛炬椂锛宼ab涓烘爣绛句俊鎭�
     btn: PropTypes.object,            // 鎸夐挳
     setting: PropTypes.any,           // 椤甸潰閫氱敤璁剧疆
     updateStatus: PropTypes.func,     // 鎸夐挳鐘舵�佹洿鏂�
     disabled: PropTypes.any,          // 琛屾寜閽鐢�
-    lineId: PropTypes.any,            // 琛岀储寮�+涓婚敭鍊硷紝鐢ㄤ簬琛屾寜閽弻鍑�
   }
 
   state = {
@@ -117,17 +114,12 @@
   /**
    * @description 瑙﹀彂鎸夐挳鎿嶄綔
    */
-  actionTrigger = (triggerId, record) => {
+  actionTrigger = (triggerId, record, type) => {
     const { setting, Tab, BID, btn } = this.props
     const { loading, disabled } = this.state
 
     if (loading || disabled) return
-    if (triggerId) {
-      if (btn.uuid !== triggerId) return
-      if (this.props.lineId && record && record[0] && this.props.lineId !== record[0].$$key) {
-        return
-      }
-    }
+    if (triggerId && btn.uuid !== triggerId) return
 
     if (((Tab && Tab.supMenu) || setting.supModule) && !BID) {
       notification.warning({
@@ -135,6 +127,8 @@
         message: '闇�瑕佷笂绾т富閿�硷紒',
         duration: 5
       })
+      return
+    } else if (type === 'linkbtn' && !btn.$toolbtn && !is(fromJS(this.props.selectedData || []), fromJS(record))) {
       return
     }
 
@@ -249,7 +243,7 @@
       } else if (btn.intertype === 'outer' && !btn.innerFunc) { // 浣跨敤澶栭儴鍑芥暟
         let param = this.getExcelCustomParam(viewParam.orderBy, viewParam.search)
 
-        if (this.props.menuType === 'HS') {
+        if (window.GLOB.mkHS) {
           if (btn.sysInterface === 'true' && options.cloudServiceApi) {
             param.rduri = options.cloudServiceApi
           } else if (btn.sysInterface !== 'true') {
@@ -295,7 +289,7 @@
             delete res.message
             delete res.status
 
-            if (this.props.menuType === 'HS') {
+            if (window.GLOB.mkHS) {
               if (btn.sysInterface === 'true' && options.cloudServiceApi) {
                 res.rduri = options.cloudServiceApi
               } else if (btn.sysInterface !== 'true') {
@@ -364,7 +358,7 @@
         delete res.message
         delete res.status
 
-        if (this.props.menuType === 'HS') {
+        if (window.GLOB.mkHS) {
           if (btn.sysInterface === 'true' && options.cloudServiceApi) {
             res.rduri = options.cloudServiceApi
           } else if (btn.sysInterface !== 'true') {
@@ -436,7 +430,7 @@
     } else if (btn.intertype === 'outer' && !btn.innerFunc) { // 浣跨敤澶栭儴鍑芥暟
       param = this.getExcelCustomParam(viewParam.orderBy, viewParam.search, true, pageIndex, pageSize)
 
-      if (this.props.menuType === 'HS') {
+      if (window.GLOB.mkHS) {
         if (btn.sysInterface === 'true' && options.cloudServiceApi) {
           param.rduri = options.cloudServiceApi
         } else if (btn.sysInterface !== 'true') {
@@ -676,7 +670,7 @@
     param.secretkey = Utils.encrypt('', param.timestamp)
     param.LText = Utils.formatOptions(script)
 
-    if (this.props.menuType === 'HS') { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
+    if (window.GLOB.mkHS) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
       param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
     }
 
@@ -791,7 +785,12 @@
     let RoleID = sessionStorage.getItem('role_id') || ''
     let departmentcode = sessionStorage.getItem('departmentcode') || ''
     let organization = sessionStorage.getItem('organization') || ''
+    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+    let nation = sessionStorage.getItem('nation') || ''
+    let province = sessionStorage.getItem('province') || ''
     let city = sessionStorage.getItem('city') || ''
+    let district = sessionStorage.getItem('district') || ''
+    let address = sessionStorage.getItem('address') || ''
 
     if (sessionStorage.getItem('isEditState') === 'true') {
       userName = sessionStorage.getItem('CloudUserName') || ''
@@ -810,9 +809,6 @@
       })
 
       regoptions.push({
-        reg: new RegExp('@login_city@', 'ig'),
-        value: city
-      }, {
         reg: new RegExp('@userName@', 'ig'),
         value: userName
       }, {
@@ -846,7 +842,7 @@
     }
 
     if (param.custom_script) {
-      param.custom_script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+      param.custom_script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
         ${param.custom_script}
       `
       regoptions.forEach(item => {
@@ -867,7 +863,7 @@
         `
       }
     } else if (LText) {
-      LText = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+      LText = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
         ${LText}
       `
     }
@@ -884,7 +880,7 @@
     param.secretkey = Utils.encrypt(param.LText, param.timestamp)
     param.DateCount = ''
 
-    if (this.props.menuType === 'HS') { // 浜戠鏁版嵁楠岃瘉
+    if (window.GLOB.mkHS) { // 浜戠鏁版嵁楠岃瘉
       param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
     }
 
@@ -928,9 +924,9 @@
       MKEmitter.emit('popclose')
     } else if (btn.execSuccess !== 'never') {
       MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess, btn, '', [])
-    } else {
-      btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
     }
+    
+    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
     
     if (btn.switchTab && btn.switchTab.length > 0) {
       let id = btn.switchTab[btn.switchTab.length - 1]
@@ -981,62 +977,48 @@
   }
 
   render() {
-    const { btn, show } = this.props
+    const { btn } = this.props
     const { loading, hidden, disabled } = this.state
 
     if (hidden) return null
 
-    if (show === 'actionList') {
-      return (
-        <Button
-          className={'mk-btn mk-' + btn.class}
-          icon={btn.icon}
-          disabled={disabled}
-          title={disabled ? (btn.reason || '') : ''}
-          onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
-          loading={loading}
-        >{btn.label}</Button>
-      )
-    } else { // icon銆乼ext銆� all 鍗$墖
-      let label = ''
-      let icon = ''
+    let label = ''
+    let icon = ''
+    let type = 'link'
+    let className = ''
 
-      if (show === 'button') {
-        label = btn.label
-        icon = btn.icon || ''
-      } else if (show === 'link') {
-        label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
-        icon = ''
-      } else if (show === 'icon') {
-        icon = btn.icon || 'download'
-      // } else if (show === 'text') {
-      } else {
-        label = btn.label
-      }
-
-      return (
-        <Button
-          type="link"
-          title={disabled ? (btn.reason || '') : (show === 'icon' ? btn.label : '')}
-          loading={loading}
-          disabled={disabled}
-          style={btn.style}
-          icon={icon}
-          onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
-        >{label}</Button>
-      )
+    if (btn.show === 'button') {
+      label = btn.label
+      icon = btn.icon || ''
+    } else if (btn.show === 'link') {
+      label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
+      icon = ''
+    } else if (btn.show === 'icon') {
+      icon = btn.icon || 'download'
+    } else if (!btn.$toolbtn) {
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
+    } else {
+      type = ''
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
     }
+
+    return (
+      <Button
+        type={type}
+        title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
+        loading={loading}
+        disabled={disabled}
+        style={btn.style || null}
+        icon={icon}
+        className={className}
+        onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
+      >{label}</Button>
+    )
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    menuType: state.editLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(ExcelOutButton)
\ No newline at end of file
+export default ExcelOutButton
\ No newline at end of file
diff --git a/src/tabviews/zshare/actionList/funcMegvii/index.jsx b/src/tabviews/zshare/actionList/funcMegvii/index.jsx
index 0c80f56..246c2b5 100644
--- a/src/tabviews/zshare/actionList/funcMegvii/index.jsx
+++ b/src/tabviews/zshare/actionList/funcMegvii/index.jsx
@@ -1,8 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { withRouter } from 'react-router'
 import { is, fromJS } from 'immutable'
-import { Button, Modal, notification, message } from 'antd'
+import { Button, Modal, notification, message, Progress } from 'antd'
 import CryptoJS from 'crypto-js'
 import moment from 'moment'
 
@@ -26,6 +25,7 @@
     loading: false,
     disabled: false,
     loadingNumber: '',
+    loadingTotal: '',
     hidden: false,
     IpList: [],
     lines: [],
@@ -98,12 +98,7 @@
     const { loading, disabled } = this.state
 
     if (loading || disabled) return
-    if (triggerId) {
-      if (btn.uuid !== triggerId) return
-      if (this.props.lineId && record && record[0] && this.props.lineId !== record[0].$$key) {
-        return
-      }
-    }
+    if (triggerId && btn.uuid !== triggerId) return
 
     if (((Tab && Tab.supMenu) || setting.supModule) && !BID) {
       notification.warning({
@@ -112,10 +107,8 @@
         duration: 5
       })
       return
-    } else if (type === 'linkbtn' && selectedData && selectedData.length === 1) {
-      if (record[0].$Index !== selectedData[0].$Index) {
-        return
-      }
+    } else if (type === 'linkbtn' && !btn.$toolbtn && !is(fromJS(selectedData || []), fromJS(record))) {
+      return
     }
 
     let data = record || selectedData || []
@@ -135,7 +128,6 @@
       loading: true,
       lines: data
     })
-
     this.getIpList()
   }
 
@@ -195,6 +187,7 @@
   }
 
   loginDevice = () => {
+    const { btn } = this.props
     const { lines, selectIp } = this.state
 
     // 涓婃姤鎺ュ彛璁剧疆锛氬伐绋嬫ā寮�-鍦烘櫙妯″紡-寮�鏀炬帴鍙h缃�-鏁版嵁涓婃姤璁剧疆-鏁版嵁涓婃姤鏈嶅姟鍣ㄥ湴鍧�锛堝紑鍚湇鍔″櫒浜屾閴存潈锛�
@@ -244,6 +237,12 @@
           }
         })
 
+        if (data.length > 1 && btn.progress === 'progressbar') {
+          this.setState({
+            loadingTotal: data.length
+          })
+        }
+
         this.addUser(ip, data, result.session_id)
       })
     }, err => {
@@ -255,7 +254,7 @@
     let data = datas.shift()
 
     this.setState({
-      loadingNumber: datas.length || ''
+      loadingNumber: datas.length
     })
 
     let error = ''
@@ -332,7 +331,8 @@
 
     this.setState({
       loading: false,
-      loadingNumber: ''
+      loadingNumber: '',
+      loadingTotal: ''
     })
     
     // if (btn.execSuccess !== 'never') {
@@ -415,7 +415,8 @@
     
     this.setState({
       loading: false,
-      loadingNumber: ''
+      loadingNumber: '',
+      loadingTotal: ''
     })
 
     // if (btn.execError !== 'never') {
@@ -490,57 +491,56 @@
   }
 
   render() {
-    const { btn, show } = this.props
-    const { loading, disabled, hidden, loadingNumber } = this.state
+    const { btn } = this.props
+    const { loading, disabled, hidden, loadingNumber, loadingTotal } = this.state
 
     if (hidden) return null
 
-    if (show === 'actionList') {
-      return (
-        <>
-          <Button
-            icon={btn.icon}
-            loading={loading}
-            disabled={disabled}
-            title={disabled ? (btn.reason || '') : ''}
-            className={'mk-btn mk-' + btn.class}
-            onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
-          >{(loadingNumber ? `(${loadingNumber})` : '') + btn.label}</Button>
-          {this.getModels()}
-        </>
-      )
-    } else { // icon銆乼ext銆� all 鍗$墖
-      let label = ''
-      let icon = ''
+    let label = ''
+    let icon = ''
+    let type = 'link'
+    let className = ''
 
-      if (show === 'button') {
-        label = btn.label
-        icon = btn.icon || ''
-      } else if (show === 'link') {
-        label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
-        icon = ''
-      } else if (show === 'icon') {
-        icon = btn.icon || ''
-      } else {
-        label = btn.label
-      }
-
-      return (
-        <>
-          <Button
-            type="link"
-            title={disabled ? (btn.reason || '') : (show === 'icon' ? btn.label : '')}
-            loading={loading}
-            disabled={disabled}
-            style={btn.style}
-            icon={icon}
-            onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
-          >{label}</Button>
-          {this.getModels()}
-        </>
-      )
+    if (btn.show === 'button') {
+      label = btn.label
+      icon = btn.icon || ''
+    } else if (btn.show === 'link') {
+      label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
+      icon = ''
+    } else if (btn.show === 'icon') {
+      icon = btn.icon || ''
+    } else if (!btn.$toolbtn) {
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
+    } else {
+      type = ''
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
     }
+    
+    if (loadingNumber && !loadingTotal && btn.$toolbtn && (!btn.show || btn.show === 'button')) {
+      label = (loadingNumber && !loadingTotal ? `(${loadingNumber})` : '') + btn.label
+    }
+
+    return (
+      <>
+        <Button
+          type={type}
+          title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
+          loading={loading}
+          disabled={disabled}
+          style={btn.style}
+          icon={icon}
+          className={className}
+          onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
+        >{label}</Button>
+        {this.getModels()}
+        {loadingTotal ? <Progress className="mk-button-progress" percent={(loadingTotal - loadingNumber) / loadingTotal * 100} size="small" showInfo={false} /> : null}
+      </>
+    )
   }
 }
 
-export default withRouter(FuncButton)
\ No newline at end of file
+export default FuncButton
\ No newline at end of file
diff --git a/src/tabviews/zshare/actionList/funcMegvii/index.scss b/src/tabviews/zshare/actionList/funcMegvii/index.scss
index eed792c..8eccbd6 100644
--- a/src/tabviews/zshare/actionList/funcMegvii/index.scss
+++ b/src/tabviews/zshare/actionList/funcMegvii/index.scss
@@ -20,7 +20,7 @@
     }
   }
   .ip-item.active {
-    border-color: var(--antd-wave-shadow-color);
-    box-shadow: 0 0 2px var(--antd-wave-shadow-color);
+    border-color: var(--mk-sys-color);
+    box-shadow: 0 0 2px var(--mk-sys-color);
   }
 }
\ No newline at end of file
diff --git a/src/tabviews/zshare/actionList/funczip/index.jsx b/src/tabviews/zshare/actionList/funczip/index.jsx
new file mode 100644
index 0000000..2b4316f
--- /dev/null
+++ b/src/tabviews/zshare/actionList/funczip/index.jsx
@@ -0,0 +1,441 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Button, Modal, notification, message, Progress } from 'antd'
+import JSZip from 'jszip'
+import { saveAs } from 'file-saver'
+
+import Utils from '@/utils/utils.js'
+import Api from '@/api'
+import MKEmitter from '@/utils/events.js'
+import MkIcon from '@/components/mk-icon'
+
+import './index.scss'
+
+class FuncZip extends Component {
+  static propTpyes = {
+    btn: PropTypes.object,            // 鎸夐挳
+    disabled: PropTypes.any,          // 琛屾寜閽鐢�
+  }
+
+  state = {
+    loading: false,
+    disabled: false,
+    loadingNumber: '',
+    loadingTotal: '',
+    hidden: false,
+    visible: false
+  }
+
+  UNSAFE_componentWillMount () {
+    const { btn, selectedData } = this.props
+    let disabled = false
+
+    if (btn.controlField && selectedData && selectedData.length > 0) { // 琛ㄦ牸涓寜閽殣钘忔帶鍒�
+      selectedData.forEach(item => {
+        let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : ''
+        if (btn.controlVals.includes(s)) {
+          disabled = true
+        }
+      })
+      this.setState({hidden: disabled && btn.control === 'hidden'})
+    }
+
+    if (this.props.disabled || disabled) {
+      this.setState({disabled: true})
+    }
+  }
+
+  componentDidMount () {
+    MKEmitter.addListener('triggerBtnId', this.actionTrigger)
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    const { btn, selectedData } = this.props
+
+    let disabled = false
+    if (btn.controlField && !is(fromJS(nextProps.selectedData || []), fromJS(selectedData || []))) {
+      if (nextProps.selectedData && nextProps.selectedData.length > 0) { // 琛ㄦ牸涓寜閽殣钘忔帶鍒�
+        nextProps.selectedData.forEach(item => {
+          let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : ''
+          if (btn.controlVals.includes(s)) {
+            disabled = true
+          }
+        })
+      }
+      this.setState({hidden: disabled && btn.control === 'hidden'})
+    }
+
+    if (nextProps.disabled || disabled) {
+      this.setState({disabled: true})
+    } else {
+      this.setState({disabled: false})
+    }
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+    MKEmitter.removeListener('triggerBtnId', this.actionTrigger)
+  }
+
+  /**
+   * @description 瑙﹀彂鎸夐挳鎿嶄綔
+   */
+  actionTrigger = (triggerId, record, type) => {
+    const { Tab, BID, btn, selectedData, setting } = this.props
+    const { loading, disabled } = this.state
+
+    if (loading || disabled) return
+    if (triggerId && btn.uuid !== triggerId) return
+
+    if (((Tab && Tab.supMenu) || setting.supModule) && !BID) {
+      notification.warning({
+        top: 92,
+        message: '闇�瑕佷笂绾т富閿�硷紒',
+        duration: 5
+      })
+      return
+    } else if (type === 'linkbtn' && !btn.$toolbtn && !is(fromJS(selectedData || []), fromJS(record))) {
+      return
+    }
+
+    let data = record || selectedData || []
+    
+    if (btn.Ot !== 'notRequired' && data.length === 0) {
+      notification.warning({
+        top: 92,
+        message: '璇烽�夋嫨琛岋紒',
+        duration: 5
+      })
+      return
+    } else if (btn.Ot === 'requiredSgl' && data.length !== 1) {
+      notification.warning({
+        top: 92,
+        message: '璇烽�夋嫨鍗曡鏁版嵁锛�',
+        duration: 5
+      })
+      return
+    }
+
+    this.setState({
+      loading: true
+    })
+
+    if (btn.innerFunc) {
+      let params = []
+      let param = {
+        func: btn.innerFunc,
+        BID: BID || ''
+      }
+
+      if (btn.Ot === 'notRequired') {
+        params.push(param)
+      } else if (btn.Ot === 'requiredSgl') {
+        param.ID = data[0].$$uuid || ''
+        params.push(param)
+      } else if (btn.Ot === 'required') {
+        params = data.map(item => {
+          return {
+            ...param,
+            ID: item.$$uuid || ''
+          }
+        })
+      } else if (btn.Ot === 'requiredOnce') {
+        param.ID = data.map(item => item.$$uuid || '').filter(Boolean).join(',')
+        params.push(param)
+      }
+
+      this.getInnerData(params)
+    } else {
+      this.downloadZipImage(data, btn.urlkey).then((res) => {
+        if (res) {
+          this.execError({ErrCode: res})
+        } else {
+          this.execSuccess()
+        }
+      }, (err) => {
+        this.execError({ErrCode: err})
+      })
+    }
+  }
+
+  getInnerData = (params) => {
+    let param = params.shift()
+
+    Api.genericInterface(param).then(res => {
+      if (res.status) {
+        this.downloadZipImage(res.data, this.props.btn.urlkey).then((res) => {
+          if (params.length === 0) {
+            if (res) {
+              this.execError({ErrCode: res})
+            } else {
+              this.execSuccess()
+            }
+          } else {
+            this.getInnerData(params)
+          }
+        }, (err) => {
+          if (params.length === 0) {
+            this.execError({ErrCode: err})
+          } else {
+            this.getInnerData(params)
+          }
+        })
+      } else {
+        this.execError(res)
+      }
+    })
+  }
+
+  downloadZipImage = (imgArr, imgKey = '') => {
+    let images = []
+    if (imgArr && imgArr.length > 0) {
+      let names = []
+      let imgs = []
+      imgArr.forEach(item => {
+        let itemImg = imgKey ? item[imgKey] : item
+        
+        if (!itemImg || !/^data:image|jpg$|jpeg$|png$|gif$/.test(itemImg)) return
+        if (imgs.includes(itemImg)) return
+
+        let name = Utils.getguid() + '.png'
+
+        if (/.(jpg|jpeg|png|gif)$/.test(itemImg)) {
+          let _name = itemImg.replace(/.*\//ig, '')
+          if (!names.includes(_name)) {
+            name = _name
+          }
+        }
+
+        imgs.push(itemImg)
+        names.push(name)
+
+        images.push({url: itemImg, name: name})
+      })
+    }
+    
+    if (images.length === 0) {
+      return Promise.reject('01')
+    }
+
+    const zip = new JSZip()
+    const imgFolder = zip.folder('images') // 鍒涘缓images鏂囦欢澶�
+
+    return new Promise((resolve, reject) => {
+      let deffers = images.map((img) => {
+        return new Promise(resolve => {
+          this.getBase64(img.url).then((base64) => {
+            if (base64) {
+              base64 = base64.split('base64,')[1]
+              imgFolder.file(img.name, base64, {
+                base64: true
+              })
+              resolve(true)
+            } else {
+              resolve(false)
+            }
+          })
+        })
+      })
+  
+      Promise.all(deffers).then((res) => {
+        let hasSuccess = res.filter((m) => m).length > 0
+        let hasError = res.filter((m) => !m).length > 0
+
+        if (hasSuccess) {
+          zip.generateAsync({
+            type: 'blob'
+          }).then((blob) => {
+            saveAs(blob, Utils.getguid() + '.zip')
+            if (hasError) {
+              resolve('02')
+            } else {
+              resolve('')
+            }
+          })
+        } else {
+          reject('03')
+        }
+      })
+    })
+  }
+
+  /**
+   * 灏嗗浘鐗囪浆鎹㈡垚base64 骞惰繑鍥炶矾寰�
+   * @param img
+   * @param {number} width 璋冪敤鏃朵紶鍏ュ叿浣撳儚绱犲�硷紝鎺у埗澶у皬 ,涓嶄紶鍒欓粯璁ゅ浘鍍忓ぇ灏�
+   * @param {number} height
+   * @returns {string}
+   */
+  getBase64Image = (img, width = 0, height = 0) => {
+    const canvas = document.createElement('canvas')
+    canvas.width = width ? width : img.width
+    canvas.height = height ? height : img.height
+
+    const ctx = canvas.getContext('2d')
+    ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
+    const dataURL = canvas.toDataURL()
+    return dataURL
+  }
+
+  /**
+   * 鍔犺浇鍥剧墖 鍔犺浇鎴愬姛鍚庣粡鍥剧墖杩斿洖
+   * @param img
+   * @returns {Promise<any>}
+   */
+  getBase64 = (img) => {
+    if (/^data:image/.test(img)) {
+      return Promise.resolve(img)
+    } else {
+      const image = new Image()
+      image.crossOrigin = '*'
+      image.src = img
+      return new Promise((resolve, reject) => {
+        image.onload = () => {
+          let base64 = ''
+          try {
+            base64 = this.getBase64Image(image)
+          } catch (e) {
+            base64 = ''
+          }
+          resolve(base64)
+        }
+        image.onerror = () => {
+          resolve('')
+        }
+      })
+    }
+  }
+
+  /**
+   * @description 鎿嶄綔鎴愬姛鍚庡鐞�
+   * 1銆乪xcel瀵煎嚭锛屾垚鍔熷悗鍙栨秷瀵煎嚭鎸夐挳鍔犺浇涓姸鎬�
+   * 2銆佺姸鎬佺爜涓� S 鏃讹紝鏄剧ず鎴愬姛淇℃伅鍚庣郴缁熼粯璁や俊鎭�
+   * 3銆佺姸鎬佺爜涓� -1 鏃讹紝涓嶆樉绀轰换浣曚俊鎭�
+   * 4銆佹ā鎬佹鎵ц鎴愬姛鍚庢槸鍚﹀叧闂�
+   * 5銆侀�氱煡涓诲垪琛ㄥ埛鏂�
+   */
+  execSuccess = () => {
+    const { btn } = this.props
+
+    this.setState({
+      loading: false,
+      loadingNumber: '',
+      loadingTotal: ''
+    })
+    
+    if (btn.execSuccess !== 'never') {
+      MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess, btn)
+    }
+  }
+
+  /**
+   * @description 鎿嶄綔澶辫触鍚庡鐞�
+   */
+  execError = (res) => {
+    const { btn } = this.props
+
+    this.setState({
+      loading: false,
+      loadingNumber: '',
+      loadingTotal: ''
+    })
+
+    if (res.ErrCode === '01') {
+      message.error('鏈幏鍙栧埌涓嬭浇鏂囦欢銆�')
+      return
+    } else if (res.ErrCode === '02') {
+      Modal.error({
+        title: '閮ㄥ垎鏂囦欢涓嬭浇澶辫触锛�1銆佽妫�鏌ユ枃浠惰矾寰勬槸鍚︽纭紝2銆佽妫�鏌ユ枃浠舵槸鍚﹁法鍩熴��',
+      })
+      return
+    } else if (res.ErrCode === '03') {
+      Modal.error({
+        title: '鏂囦欢涓嬭浇澶辫触锛�1銆佽妫�鏌ユ枃浠惰矾寰勬槸鍚︽纭紝2銆佽妫�鏌ユ枃浠舵槸鍚﹁法鍩熴��',
+      })
+      return
+    } else if (res.ErrCode === 'E') {
+      Modal.error({
+        title: res.message || res.ErrMesg,
+      })
+    } else if (res.ErrCode === 'N') {
+      notification.error({
+        top: 92,
+        message: res.message || res.ErrMesg,
+        duration: 10
+      })
+    } else if (res.ErrCode === 'F') {
+      notification.error({
+        className: 'notification-custom-error',
+        top: 92,
+        message: res.message || res.ErrMesg,
+        duration: 10
+      })
+    } else if (res.ErrCode === 'NM') {
+      message.error(res.message || res.ErrMesg)
+    }
+
+    if (btn.execError !== 'never') {
+      MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execError, btn)
+    }
+  }
+
+  render() {
+    const { btn } = this.props
+    const { loading, disabled, hidden, loadingNumber, loadingTotal } = this.state
+
+    if (hidden) return null
+
+    let label = ''
+    let icon = ''
+    let type = 'link'
+    let className = ''
+
+    if (btn.show === 'button') {
+      label = btn.label
+      icon = btn.icon || ''
+    } else if (btn.show === 'link') {
+      label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
+      icon = ''
+    } else if (btn.show === 'icon') {
+      icon = btn.icon || ''
+    } else if (!btn.$toolbtn) {
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
+    } else {
+      type = ''
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
+    }
+    
+    if (loadingNumber && !loadingTotal && btn.$toolbtn && (!btn.show || btn.show === 'button')) {
+      label = (loadingNumber && !loadingTotal ? `(${loadingNumber})` : '') + btn.label
+    }
+
+    return (
+      <>
+        <Button
+          type={type}
+          title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
+          loading={loading}
+          disabled={disabled}
+          style={btn.style}
+          icon={icon}
+          className={className}
+          onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
+        >{label}</Button>
+        {loadingTotal ? <Progress className="mk-button-progress" percent={(loadingTotal - loadingNumber) / loadingTotal * 100} size="small" showInfo={false} /> : null}
+      </>
+    )
+  }
+}
+
+export default FuncZip
\ No newline at end of file
diff --git a/src/tabviews/zshare/actionList/funczip/index.scss b/src/tabviews/zshare/actionList/funczip/index.scss
new file mode 100644
index 0000000..8eccbd6
--- /dev/null
+++ b/src/tabviews/zshare/actionList/funczip/index.scss
@@ -0,0 +1,26 @@
+.ip-list-modal {
+  .ip-item {
+    display: inline-block;
+    border: 1px solid #d9d9d9;
+    padding: 10px;
+    height: 100px;
+    width: calc(33% - 20px);
+    margin: 10px;
+    cursor: pointer;
+    .ip {
+      color: #000000;
+    }
+    .remark {
+      word-break: break-all;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      -webkit-box-orient: vertical;
+      -webkit-line-clamp: 2;
+      overflow: hidden;
+    }
+  }
+  .ip-item.active {
+    border-color: var(--mk-sys-color);
+    box-shadow: 0 0 2px var(--mk-sys-color);
+  }
+}
\ No newline at end of file
diff --git a/src/tabviews/zshare/actionList/funczip/mock.js b/src/tabviews/zshare/actionList/funczip/mock.js
new file mode 100644
index 0000000..669ad8e
--- /dev/null
+++ b/src/tabviews/zshare/actionList/funczip/mock.js
@@ -0,0 +1,27 @@
+export const mockdata = {
+  data: [
+    {
+      "recognition_type": "staff",
+      "id": "2226169",
+      "type": "persons",
+      "is_admin": "true",
+      "person_name": "king",
+      "card_number": "mk001",
+      "person_code": "2018",
+      "id_number": "130982193002054729",
+      "group_list": "1",
+      "face_data":""
+    },
+    {
+      "recognition_type": "staff",
+      "id": "3272487",
+      "is_admin": 'false',
+      "person_name": "jinfei",
+      "card_number": "mk002",
+      "person_code": "02",
+      "id_number": "",
+      "group_list": "1",
+      "face_data": ""
+    }
+  ]
+}
\ No newline at end of file
diff --git a/src/tabviews/zshare/actionList/index.jsx b/src/tabviews/zshare/actionList/index.jsx
index 3b4c230..addbbd0 100644
--- a/src/tabviews/zshare/actionList/index.jsx
+++ b/src/tabviews/zshare/actionList/index.jsx
@@ -15,6 +15,7 @@
 const ChangeUserButton = asyncComponent(() => import('./changeuserbutton'))
 const PrintButton = asyncComponent(() => import('./printbutton'))
 const FuncMegvii = asyncComponent(() => import('./funcMegvii'))
+const FuncZip = asyncComponent(() => import('./funczip'))
 
 class ActionList extends Component {
   static propTpyes = {
@@ -164,6 +165,19 @@
               selectedData={selectedData}
             />
           )
+        } else if (item.funcType === 'filezip') {
+          return (
+            <FuncZip
+              key={item.uuid}
+              show={item.show || 'actionList'}
+              disabled={lock || false}
+              BID={BID}
+              Tab={Tab}
+              btn={item}
+              setting={setting}
+              selectedData={selectedData}
+            />
+          )
         }
       }
       return null
diff --git a/src/tabviews/zshare/actionList/newpagebutton/index.jsx b/src/tabviews/zshare/actionList/newpagebutton/index.jsx
index cb1f797..1237a91 100644
--- a/src/tabviews/zshare/actionList/newpagebutton/index.jsx
+++ b/src/tabviews/zshare/actionList/newpagebutton/index.jsx
@@ -13,13 +13,11 @@
 
 class NewPageButton extends Component {
   static propTpyes = {
-    show: PropTypes.any,              // 鎸夐挳鏄剧ず鏍峰紡鎺у埗
     BData: PropTypes.any,             // 涓昏〃鏁版嵁
     btn: PropTypes.object,            // 鎸夐挳
     selectedData: PropTypes.any,      // 瀛愯〃涓�夋嫨鏁版嵁
     setting: PropTypes.any,           // 椤甸潰閫氱敤璁剧疆
     disabled: PropTypes.any,          // 琛屾寜閽鐢�
-    lineId: PropTypes.any,            // 琛岀储寮�+涓婚敭鍊硷紝鐢ㄤ簬琛屾寜閽弻鍑�
   }
 
   state = {
@@ -116,17 +114,10 @@
     const { disabled } = this.state
 
     if (disabled) return
-    if (triggerId) {
-      if (btn.uuid !== triggerId) return
-      if (this.props.lineId && record && record[0] && this.props.lineId !== record[0].$$key) {
-        return
-      }
-    }
+    if (triggerId && btn.uuid !== triggerId) return
 
-    if (type === 'linkbtn' && selectedData && selectedData.length === 1) {
-      if (record[0].$Index !== selectedData[0].$Index) {
-        return
-      }
+    if (type === 'linkbtn' && !btn.$toolbtn && !is(fromJS(selectedData || []), fromJS(record))) {
+      return
     }
 
     let data = record || selectedData || []
@@ -233,49 +224,46 @@
   }
 
   render() {
-    const { btn, show } = this.props
+    const { btn } = this.props
     const { disabled, hidden } = this.state
 
     if (hidden) return null
 
-    if (show === 'actionList') {
-      return (
-        <Button
-          className={'mk-btn mk-' + btn.class}
-          icon={btn.icon}
-          disabled={disabled}
-          title={disabled ? (btn.reason || '') : ''}
-          onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
-        >{btn.label}</Button>
-      )
-    } else { // icon銆乼ext銆� all 鍗$墖
-      let label = ''
-      let icon = ''
+    let label = ''
+    let icon = ''
+    let type = 'link'
+    let className = ''
 
-      if (show === 'button') {
-        label = btn.label
-        icon = btn.icon || ''
-      } else if (show === 'link') {
-        label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
-        icon = ''
-      } else if (show === 'icon') {
-        icon = btn.icon || ''
-      // } else if (show === 'text') {
-      } else {
-        label = btn.label
-      }
-
-      return (
-        <Button
-          type="link"
-          title={disabled ? (btn.reason || '') : (show === 'icon' ? btn.label : '')}
-          style={btn.style}
-          disabled={disabled}
-          icon={icon}
-          onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
-        >{label}</Button>
-      )
+    if (btn.show === 'button') {
+      label = btn.label
+      icon = btn.icon || ''
+    } else if (btn.show === 'link') {
+      label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
+      icon = ''
+    } else if (btn.show === 'icon') {
+      icon = btn.icon || ''
+    } else if (!btn.$toolbtn) {
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
+    } else {
+      type = ''
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
     }
+
+    return (
+      <Button
+        type={type}
+        title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
+        style={btn.style || null}
+        disabled={disabled}
+        icon={icon}
+        className={className}
+        onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
+      >{label}</Button>
+    )
   }
 }
 
diff --git a/src/tabviews/zshare/actionList/normalbutton/index.jsx b/src/tabviews/zshare/actionList/normalbutton/index.jsx
index 3eff1c7..473d3e1 100644
--- a/src/tabviews/zshare/actionList/normalbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -1,9 +1,8 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import moment from 'moment'
-import {connect} from 'react-redux'
 import { is, fromJS } from 'immutable'
-import { Button, Modal, notification, message, Drawer, Switch, Checkbox } from 'antd'
+import { Button, Modal, notification, message, Drawer, Switch, Checkbox, Progress } from 'antd'
 
 import Api from '@/api'
 import Utils, { getSysDefaultSql } from '@/utils/utils.js'
@@ -21,8 +20,6 @@
 
 class NormalButton extends Component {
   static propTpyes = {
-    show: PropTypes.any,              // 鎸夐挳鏄剧ず鏍峰紡鎺у埗
-    position: PropTypes.any,          // 鎸夐挳浣嶇疆锛屽伐鍏锋爮涓簍oolbar
     BID: PropTypes.string,            // 涓昏〃ID
     BData: PropTypes.any,             // 涓昏〃鏁版嵁
     style: PropTypes.any,             // 鎸夐挳鏍峰紡
@@ -33,7 +30,6 @@
     setting: PropTypes.any,           // 椤甸潰閫氱敤璁剧疆
     ContainerId: PropTypes.any,       // tab椤甸潰ID锛岀敤浜庡脊绐楁帶鍒�
     disabled: PropTypes.any,          // 琛屾寜閽鐢�
-    lineId: PropTypes.any,            // 琛岀储寮�+涓婚敭鍊硷紝鐢ㄤ簬琛屾寜閽弻鍑�
   }
 
   state = {
@@ -45,6 +41,7 @@
     btnconfig: null,
     loading: false,
     loadingNumber: '',
+    loadingTotal: '',
     disabled: false,
     hidden: false,
     checkParam: null,
@@ -97,10 +94,10 @@
   }
 
   componentDidMount () {
-    const { position, btn } = this.props
+    const { btn } = this.props
 
     MKEmitter.addListener('triggerBtnId', this.actionTrigger)
-    if (position === 'form') {
+    if (btn.OpenType === 'formSubmit') {
       MKEmitter.addListener('triggerFormSubmit', this.actionSubmit)
     }
     MKEmitter.addListener('returnModuleParam', this.resetModuleParam)
@@ -234,12 +231,7 @@
     const { loading, disabled } = this.state
 
     if (loading || disabled) return
-    if (triggerId) {
-      if (btn.uuid !== triggerId) return
-      if (this.props.lineId && record && record[0] && this.props.lineId !== record[0].$$key) {
-        return
-      }
-    }
+    if (triggerId && btn.uuid !== triggerId) return
 
     if (((Tab && Tab.supMenu) || setting.supModule) && !BID) {
       notification.warning({
@@ -248,17 +240,15 @@
         duration: 5
       })
       return
-    } else if (type === 'linkbtn' && selectedData && selectedData.length === 1) {
-      if (record[0].$Index !== selectedData[0].$Index) {
-        return
-      }
+    } else if (type === 'linkbtn' && !btn.$toolbtn && !is(fromJS(selectedData || []), fromJS(record))) {
+      return
     }
 
     this.setState({autoMatic: type === 'autoMatic'})
 
     let _this = this
     let data = record || selectedData || []
-
+    
     if (btn.Ot !== 'notRequired' && data.length === 0) {
       // 闇�瑕侀�夋嫨琛屾椂锛屾牎楠屾暟鎹�
       notification.warning({
@@ -543,7 +533,7 @@
         }
       }
 
-      if (this.props.menuType === 'HS') { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
+      if (window.GLOB.mkHS) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
         param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
         if (check_param) {
           check_param.open_key = Utils.encryptOpenKey(check_param.secretkey, check_param.timestamp)
@@ -665,7 +655,7 @@
           }
         }
 
-        if (this.props.menuType === 'HS') { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
+        if (window.GLOB.mkHS) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
           param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
         }
 
@@ -714,7 +704,7 @@
         })
       }
 
-      if (this.props.menuType === 'HS' && param.func === 's_sDataDictb_TBBack' && param.LTextOut) { // 鍑芥暟 s_sDataDictb_TBBack 浜戠楠岃瘉
+      if (window.GLOB.mkHS && param.func === 's_sDataDictb_TBBack' && param.LTextOut) { // 鍑芥暟 s_sDataDictb_TBBack 浜戠楠岃瘉
         param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt(param.LTextOut, param.timestamp)
         param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
@@ -751,7 +741,7 @@
           param[setting.primaryKey] = primaryId
         }
 
-        if (this.props.menuType === 'HS' && param.func === 's_sDataDictb_TBBack' && param.LTextOut) { // 鍑芥暟 s_sDataDictb_TBBack 浜戠楠岃瘉
+        if (window.GLOB.mkHS && param.func === 's_sDataDictb_TBBack' && param.LTextOut) { // 鍑芥暟 s_sDataDictb_TBBack 浜戠楠岃瘉
           param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
           param.secretkey = Utils.encrypt(param.LTextOut, param.timestamp)
           param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
@@ -843,6 +833,10 @@
                     })
                   }, 600)
                 }
+
+                if (res.status) {
+                  this.triggerNote(res) // 娑堟伅
+                }
                 resolve(res)
               }, () => {
                 this.updateStatus()
@@ -870,6 +864,11 @@
           _resolve()
         })
       } else { // 瓒呭嚭20涓姹傛椂寰幆鎵ц
+        if (btn.progress === 'progressbar' && btn.$toolbtn) {
+          this.setState({
+            loadingTotal: params.length
+          })
+        }
         this.innerLoopRequest(params, btn, _resolve)
       }
     } else if (btn.intertype === 'outer') {
@@ -930,8 +929,14 @@
         })
       }
 
+      if (_params.length > 1 && btn.progress === 'progressbar' && btn.$toolbtn) {
+        this.setState({
+          loadingTotal: _params.length
+        })
+      }
+
       // 寰幆璋冪敤澶栭儴鎺ュ彛锛堝寘鎷唴閮ㄥ強鍥炶皟鍑芥暟锛�
-      this.outerLoopRequest(_params, btn, _resolve, _params.length > 20)
+      this.outerLoopRequest(_params, btn, _resolve)
     } else if (btn.intertype === 'custom') { // 绯荤粺鎺ュ彛
       let params = []
 
@@ -945,6 +950,12 @@
         params = this.getInnerParam(data, formdata)
       }
 
+      if (params.length > 1 && btn.progress === 'progressbar' && btn.$toolbtn) {
+        this.setState({
+          loadingTotal: params.length
+        })
+      }
+
       this.customLoopRequest(params, _resolve)
     }
   }
@@ -956,7 +967,7 @@
     let param = params.shift()
 
     this.setState({
-      loadingNumber: params.length || ''
+      loadingNumber: params.length
     })
 
     let record = {
@@ -1238,7 +1249,7 @@
         param.s_debug_type = 'Y'
       }
 
-      if (this.props.menuType === 'HS') { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
+      if (window.GLOB.mkHS) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
         param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
       }
     } else {
@@ -1287,7 +1298,7 @@
     let param = params.shift()
 
     this.setState({
-      loadingNumber: params.length || ''
+      loadingNumber: params.length
     })
 
     let _param = null
@@ -1319,6 +1330,9 @@
             })
           }, 600)
         }
+
+        this.triggerNote(res) // 娑堟伅
+
         if (params.length === 0) {
           this.execSuccess(res)
           _resolve()
@@ -1338,17 +1352,15 @@
   /**
    * @description 澶栭儴璇锋眰寰幆鎵ц
    */
-  outerLoopRequest = (params, btn, _resolve, widthNumber) => {
+  outerLoopRequest = (params, btn, _resolve) => {
     if (!params && params.length === 0) return
 
     let param = params.shift()
     let _outParam = null
 
-    if (widthNumber) {
-      this.setState({
-        loadingNumber: params.length || ''
-      })
-    }
+    this.setState({
+      loadingNumber: params.length
+    })
 
     new Promise(resolve => {
       // 鍐呴儴璇锋眰
@@ -1356,7 +1368,7 @@
         param.func = btn.innerFunc
 
         // 鍑芥暟 s_sDataDictb_TBBack 浜戠楠岃瘉
-        if (this.props.menuType === 'HS' && param.func === 's_sDataDictb_TBBack' && param.LTextOut) {
+        if (window.GLOB.mkHS && param.func === 's_sDataDictb_TBBack' && param.LTextOut) {
           param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
           param.secretkey = Utils.encrypt(param.LTextOut, param.timestamp)
           param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
@@ -1397,7 +1409,7 @@
       if (btn.outerFunc) {
         res.func = btn.outerFunc
       }
-      if (this.props.menuType === 'HS') {
+      if (window.GLOB.mkHS) {
         if (btn.sysInterface === 'true' && options.cloudServiceApi) {
           res.rduri = options.cloudServiceApi
         } else if (btn.sysInterface !== 'true') {
@@ -1440,7 +1452,7 @@
         let _callbackparam = {..._outParam, ...response}
 
         // 鍑芥暟 s_sDataDictb_TBBack 浜戠楠岃瘉
-        if (this.props.menuType === 'HS' && _callbackparam.func === 's_sDataDictb_TBBack' && _callbackparam.LTextOut) {
+        if (window.GLOB.mkHS && _callbackparam.func === 's_sDataDictb_TBBack' && _callbackparam.LTextOut) {
           _callbackparam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
           _callbackparam.secretkey = Utils.encrypt(_callbackparam.LTextOut, _callbackparam.timestamp)
           _callbackparam.open_key = Utils.encryptOpenKey(_callbackparam.secretkey, _callbackparam.timestamp)
@@ -1455,7 +1467,7 @@
             this.execSuccess(response)
             _resolve()
           } else {
-            this.outerLoopRequest(params, btn, _resolve, widthNumber)
+            this.outerLoopRequest(params, btn, _resolve)
           }
         } else {
           this.execError(response)
@@ -1470,7 +1482,7 @@
           this.execSuccess(res)
           _resolve()
         } else {
-          this.outerLoopRequest(params, btn, _resolve, widthNumber)
+          this.outerLoopRequest(params, btn, _resolve)
         }
       } else {
         this.execError(res)
@@ -1504,6 +1516,11 @@
     } else if (res && res.ErrCode === '-1') { // 瀹屾垚鍚庝笉鎻愮ず
 
     }
+
+    this.setState({
+      loadingNumber: '',
+      loadingTotal: '',
+    })
     
     if (autoMatic) {
       this.setState({
@@ -1519,13 +1536,13 @@
       })
     }
 
-    if (btn.verify && btn.verify.noteEnable === 'true') {
-      this.sendMessage()
-    }
-
     let id = ''
     if (btn.output) {
       id = res.mk_b_id || res[btn.output] || ''
+    }
+
+    if (res.mk_icon) {
+      sessionStorage.setItem('avatar', res.mk_icon)
     }
     let tabId = ''
     if (btn.refreshTab && btn.refreshTab.length > 0) {
@@ -1543,9 +1560,9 @@
       MKEmitter.emit('popclose')
     } else if (btn.execSuccess !== 'never') {
       MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess, btn, id, this.state.selines)
-    } else {
-      btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
     }
+    
+    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
 
     if (tabId) {
       MKEmitter.emit('reloadMenuView', tabId, 'table')
@@ -1562,7 +1579,7 @@
       node && node.scrollIntoView({behavior: 'smooth', block: 'center', inline: 'nearest'})
     }
 
-    if (btn.openmenu && btn.openmenu.length > 0 && btn.MenuID) {
+    if (btn.MenuID && Array.isArray(btn.openmenu) && btn.openmenu.length > 0) {
       let newtab = {
         MenuID: btn.MenuID,
         MenuName: btn.MenuName,
@@ -1581,13 +1598,139 @@
     }
   }
 
-  sendMessage = () => {
-    const { btn : { verify } } = this.props
+  triggerNote = (res) => {
+    const { btn } = this.props
 
+    if (!btn.verify) return
+    if (btn.verify.noteEnable !== 'true' && btn.verify.wxNote !== 'true') return
+
+    let id = ''
+    if (btn.output) {
+      id = res.mk_b_id || res[btn.output] || ''
+    }
+
+    if (!id) return
+
+    if (btn.verify.noteEnable === 'true') {
+      this.sendMessage(btn.verify, id)
+    }
+    if (btn.verify.wxNote === 'true') {
+      this.sendWxMessage(btn.verify, id)
+    }
+  }
+
+  sendWxMessage = (verify, id) => {
+    let param = {
+      func: 's_get_sms_weixin_local',
+      upid: id
+    }
+
+    param.LText = Utils.formatOptions(Utils.getuuid())
+    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+
+    Api.genericInterface(param).then(res => {
+      // res.data = [{openid: 'o2E7gvoSFvQRG7I8_gZxf4y3ONkQ', send_id: '2223333', first: '鎮ㄧ殑缂磋垂淇℃伅濡備笅', keyword1: '010000000001', keyword2: '2022骞�07鏈�03鏃�', keyword3: '渚涙殩缂磋垂', keyword4: '20鍏�', keyword5: '鎴愬姛', remark: '鎰熻阿鎮ㄧ殑浣跨敤锛�'}]
+      if (!res.status) {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+        return
+      } else if (!res.send_data || res.send_data.length === 0) {
+        return
+      }
+
+      let _param = {
+        touser: '',
+        template_id: verify.wxTemplateId,
+        data: {}
+      }
+
+      if (verify.wxNoteLink === 'url' && verify.wxNoteLinkUrl) {
+        _param.url = verify.wxNoteLinkUrl
+      } else if (verify.wxNoteLink === 'miniProgram' && window.GLOB.WXminiAppID) {
+        _param.miniprogram = {
+          appid: window.GLOB.WXminiAppID,
+          pagepath: '/pages/index/index'
+        }
+
+        if (verify.wxNoteLinkMenuId) {
+          _param.miniprogram.pagepath = `/pages/index/index?MenuId=${verify.wxNoteLinkMenuId}`
+        }
+      }
+
+      let keys = []
+      verify.wxNoteKeys.forEach(item => {
+        keys.push(item.key)
+
+        _param.data[item.key] = {value: '', color: item.color}
+      })
+
+      let params = res.send_data.map(item => {
+        let m = fromJS(_param).toJS()
+
+        m.touser = item.openid || ''
+        if (item.bid && m.miniprogram && m.miniprogram.pagepath.indexOf('MenuId') > -1) {
+          m.miniprogram.pagepath = m.miniprogram.pagepath + `&BID=${item.bid}`
+        }
+
+        if (item.send_id) { // 闃查噸鍏d
+          m.client_msg_id = item.send_id
+        }
+
+        keys.forEach(key => {
+          if (item[key] !== undefined) {
+            m.data[key].value = item[key]
+          }
+        })
+
+        return m
+      })
+
+      Api.wxAccessToken().then(res => {
+        if (!res.oa_access_token) return
+  
+        params.forEach(n => {
+          if (!n.touser) return
+
+          Api.wxNginxRequest(`cgi-bin/message/template/send?access_token=${res.oa_access_token}`, 'post', n).then(re => {
+            if (verify.wxNoteCallback === 'true') {
+              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',
+                msg_result: re.errmsg
+              }
+
+              _p.LText = Utils.formatOptions(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
+                  })
+                }
+              })
+            }
+          })
+        })
+      })
+    })
+  }
+
+  sendMessage = (verify, id) => {
     let param = {
       func: 's_get_sms_local',
       TypeCharOne: verify.noteTemp, // N涓嶅悓鍐呭锛孻鐩稿悓鍐呭
-      TypeCharTwo: verify.noteType  // N瀹氭椂锛孻瀹炴椂
+      TypeCharTwo: verify.noteType, // N瀹氭椂锛孻瀹炴椂
+      upid: id
     }
 
     param.LText = Utils.formatOptions(Utils.getuuid())
@@ -1666,13 +1809,14 @@
       }
 
       if (Ltext.length === 0) return
+
       Ltext = Ltext.join(';')
 
       _param.LText = window.btoa(window.encodeURIComponent(Ltext))
       _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
       _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
 
-      _param.rduri = 'http://sso.mk9h.cn/webapi/dostars'
+      _param.rduri = 'https://sso.mk9h.cn/webapi/dostars'
 
       _param.userid = 'bh0bapabtd45epsgra79segbch6c1ibk'
       _param.LoginUID = 'bh0bapabtd45epsgra79segbch6c1ibk'
@@ -1724,6 +1868,7 @@
       this.setState({
         loading: false,
         loadingNumber: '',
+        loadingTotal: '',
         visible: false
       })
       MKEmitter.emit('autoExecOver', btn.uuid, 'error')
@@ -1732,7 +1877,8 @@
     
     this.setState({
       loading: false,
-      loadingNumber: ''
+      loadingNumber: '',
+      loadingTotal: '',
     })
 
     if (res.ErrCode === 'C') {
@@ -2013,7 +2159,7 @@
 
     if (!btnconfig || !btnconfig.setting) return null
 
-    let title = btnconfig.setting.title
+    let title = btn.label
     let width = btnconfig.setting.width > 100 ? btnconfig.setting.width : btnconfig.setting.width + 'vw'
     let clickouter = btnconfig.setting.clickouter === 'close'
 
@@ -2038,7 +2184,6 @@
           <MutilForm
             BID={BID}
             dict={this.state.dict}
-            menuType={this.props.menuType}
             action={btnconfig}
             inputSubmit={this.handleOk}
             data={this.state.selines[0]}
@@ -2081,7 +2226,6 @@
           <MutilForm
             BID={BID}
             dict={this.state.dict}
-            menuType={this.props.menuType}
             action={btnconfig}
             inputSubmit={this.handleOk}
             data={this.state.selines[0]}
@@ -2094,81 +2238,62 @@
   }
 
   render() {
-    const { btn, show, style } = this.props
-    const { loadingNumber, loading, disabled, hidden, check } = this.state
+    const { btn } = this.props
+    const { loadingNumber, loadingTotal, loading, disabled, hidden, check } = this.state
 
     if (hidden) return null
 
     if (btn.OpenType === 'form') {
       if (btn.formType === 'switch') {
-        return <Switch loading={loading} checked={check} disabled={disabled || loading} title={disabled ? (btn.reason || '') : ''} onChange={(val,e) => {e.stopPropagation();this.actionTrigger()}} style={style} className={btn.size === 'large' ? 'ant-switch-large' : ''} size={btn.size} checkedChildren={btn.openText || ''} unCheckedChildren={btn.closeText || ''}/>
+        return <Switch loading={loading} checked={check} disabled={disabled || loading} title={disabled ? (btn.reason || '') : ''} onChange={(val,e) => {e.stopPropagation();this.actionTrigger()}} style={btn.style} className={btn.size === 'large' ? 'ant-switch-large' : ''} size={btn.size} checkedChildren={btn.openText || ''} unCheckedChildren={btn.closeText || ''}/>
       } else {
-        return <Checkbox disabled={disabled || loading} title={disabled ? (btn.reason || '') : ''} checked={check} onChange={(e) => {e.stopPropagation();this.actionTrigger()}} style={style}></Checkbox>
+        return <Checkbox disabled={disabled || loading} title={disabled ? (btn.reason || '') : ''} checked={check} onChange={(e) => {e.stopPropagation();this.actionTrigger()}} style={btn.style}></Checkbox>
       }
-    } else if (show === 'actionList') {
-      return <div style={{display: 'inline-block'}} onClick={(e) => e.stopPropagation()}>
-        <Button
-          style={style}
-          icon={btn.icon}
-          loading={loading}
-          disabled={disabled}
-          title={disabled ? (btn.reason || '') : ''}
-          className={'mk-btn mk-' + btn.class}
-          onClick={() => {this.actionTrigger()}}
-        >{(loadingNumber ? `(${loadingNumber})` : '') + btn.label}</Button>
-        {this.getModels()}
-      </div>
-    } else if (show && show.indexOf('plus') > -1) {
-      return <div style={{display: 'inline-block'}}>
-        <Button
-          type="link"
-          loading={loading}
-          icon={btn.icon || 'plus'}
-          style={{fontSize: show.substring(4) + 'px'}}
-          onClick={() => {this.actionTrigger()}}
-        ></Button>
-        {this.getModels()}
-      </div>
-    } else { // icon銆乼ext銆� all 鍗$墖
-      let label = ''
-      let icon = ''
-
-      if (show === 'button') {
-        label = btn.label
-        icon = btn.icon || ''
-      } else if (show === 'link') {
-        label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
-        icon = ''
-      } else if (show === 'icon') {
-        icon = btn.icon || ''
-      } else {
-        label = btn.label
-      }
-
-      return <div style={{display: 'inline-block'}} onClick={(e) => e.stopPropagation()}>
-        <Button
-          type="link"
-          title={disabled ? (btn.reason || '') : (show === 'icon' ? btn.label : '')}
-          loading={loading}
-          disabled={disabled}
-          style={btn.style || style}
-          icon={icon}
-          onClick={() => {this.actionTrigger()}}
-        >{label}</Button>
-        {this.getModels()}
-      </div>
     }
+
+    let label = ''
+    let icon = ''
+    let type = 'link'
+    let className = ''
+
+    if (btn.show === 'button') {
+      label = btn.label
+      icon = btn.icon || ''
+    } else if (btn.show === 'link') {
+      label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
+      icon = ''
+    } else if (btn.show === 'icon') {
+      icon = btn.icon || ''
+    } else if (!btn.$toolbtn) {
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + (btn.class || 'unset')
+    } else {
+      type = ''
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + (btn.class || 'unset')
+    }
+
+    if (loadingNumber && !loadingTotal && btn.$toolbtn && (!btn.show || btn.show === 'button')) {
+      label = (loadingNumber && !loadingTotal ? `(${loadingNumber})` : '') + btn.label
+    }
+
+    return <>
+      <Button
+        type={type}
+        icon={icon}
+        title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
+        loading={loading}
+        disabled={disabled}
+        style={btn.style}
+        className={className}
+        onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
+      >{label}</Button>
+      <span onClick={(e) => {e.stopPropagation()}}>{this.getModels()}</span>
+      {loadingTotal ? <Progress className="mk-button-progress" percent={(loadingTotal - loadingNumber) / loadingTotal * 100} size="small" showInfo={false} /> : null}
+    </>
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    menuType: state.editLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(NormalButton)
\ No newline at end of file
+export default NormalButton
\ No newline at end of file
diff --git a/src/tabviews/zshare/actionList/popupbutton/index.jsx b/src/tabviews/zshare/actionList/popupbutton/index.jsx
index 02ce0db..7a2ef97 100644
--- a/src/tabviews/zshare/actionList/popupbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/popupbutton/index.jsx
@@ -15,7 +15,6 @@
 
 class PopupButton extends Component {
   static propTpyes = {
-    show: PropTypes.any,              // 鎸夐挳鏄剧ず鏍峰紡鎺у埗
     BID: PropTypes.string,            // 涓昏〃ID
     BData: PropTypes.any,             // 涓昏〃鏁版嵁
     selectedData: PropTypes.any,      // 瀛愯〃涓�夋嫨鏁版嵁
@@ -24,7 +23,6 @@
     btn: PropTypes.object,            // 鎸夐挳
     setting: PropTypes.any,           // 椤甸潰閫氱敤璁剧疆
     disabled: PropTypes.any,          // 琛屾寜閽鐢�
-    lineId: PropTypes.any,            // 琛岀储寮�+涓婚敭鍊硷紝鐢ㄤ簬琛屾寜閽弻鍑�
   }
 
   state = {
@@ -158,12 +156,7 @@
     const { loading, disabled } = this.state
 
     if (loading || disabled) return
-    if (triggerId) {
-      if (btn.uuid !== triggerId) return
-      if (this.props.lineId && record && record[0] && this.props.lineId !== record[0].$$key) {
-        return
-      }
-    }
+    if (triggerId && btn.uuid !== triggerId) return
 
     if (((Tab && Tab.supMenu) || setting.supModule) && !BID) {
       notification.warning({
@@ -172,10 +165,8 @@
         duration: 5
       })
       return
-    } else if (type === 'linkbtn' && selectedData && selectedData.length === 1) {
-      if (record[0].$Index !== selectedData[0].$Index) {
-        return
-      }
+    } else if (type === 'linkbtn' && !btn.$toolbtn && !is(fromJS(selectedData || []), fromJS(record))) {
+      return
     }
 
     let data = record || selectedData || []
@@ -237,6 +228,8 @@
     if (btn.popClose !== 'never') {
       MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.popClose, btn)
     }
+
+    btn.syncComponentId && MKEmitter.emit('reloadData', btn.syncComponentId)
   }
 
   getPop = () => {
@@ -324,47 +317,49 @@
   }
 
   render() {
-    const { btn, show } = this.props
+    const { btn } = this.props
     const { loading, disabled, hidden } = this.state
 
     if (hidden) return null
 
     let label = ''
     let icon = ''
+    let type = 'link'
+    let className = ''
 
-    if (show === 'button') {
+    if (btn.show === 'button') {
       label = btn.label
       icon = btn.icon || ''
-    } else if (show === 'link') {
+    } else if (btn.show === 'link') {
       label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
       icon = ''
-    } else if (show === 'icon') {
+    } else if (btn.show === 'icon') {
       icon = btn.icon || ''
-    } else {
+    } else if (!btn.$toolbtn) {
+      icon = btn.icon || ''
       label = btn.label
+      className = 'mk-btn mk-' + btn.class
+    } else {
+      type = ''
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
     }
 
     return (
-      <div style={{display: 'inline-block'}} onClick={(e) => e.stopPropagation()}>
-        {show === 'actionList' ? <Button
-          className={'mk-btn mk-' + btn.class}
-          icon={btn.icon}
-          disabled={disabled}
-          title={disabled ? (btn.reason || '') : ''}
-          onClick={() => {this.actionTrigger()}}
-          loading={loading}
-        >{btn.label}</Button> : null}
-        {show !== 'actionList' ? <Button
-          type="link"
-          title={disabled ? (btn.reason || '') : (show === 'icon' ? btn.label : '')}
+      <>
+        <Button
+          type={type}
+          title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
           loading={loading}
           disabled={disabled}
           style={btn.style}
           icon={icon}
-          onClick={() => {this.actionTrigger()}}
-        >{label}</Button> : null}
-        {this.getPop()}
-      </div>
+          className={className}
+          onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
+        >{label}</Button>
+        <span onClick={(e) => {e.stopPropagation()}}>{this.getPop()}</span>
+      </>
     )
   }
 }
diff --git a/src/tabviews/zshare/actionList/printbutton/index.jsx b/src/tabviews/zshare/actionList/printbutton/index.jsx
index 6c14dd2..ff0cd12 100644
--- a/src/tabviews/zshare/actionList/printbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/printbutton/index.jsx
@@ -1,7 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import moment from 'moment'
-import {connect} from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { Button, Modal, notification, message } from 'antd'
 
@@ -22,7 +21,6 @@
 
 class PrintButton extends Component {
   static propTpyes = {
-    show: PropTypes.any,              // 鎸夐挳鏄剧ず鏍峰紡鎺у埗
     BID: PropTypes.string,            // 涓昏〃ID
     BData: PropTypes.any,             // 涓昏〃鏁版嵁
     selectedData: PropTypes.any,      // 瀛愯〃涓�夋嫨鏁版嵁
@@ -32,7 +30,6 @@
     setting: PropTypes.any,           // 椤甸潰閫氱敤璁剧疆
     ContainerId: PropTypes.any,       // tab椤甸潰ID锛岀敤浜庡脊绐楁帶鍒�
     disabled: PropTypes.any,          // 琛屾寜閽鐢�
-    lineId: PropTypes.any,            // 琛岀储寮�+涓婚敭鍊硷紝鐢ㄤ簬琛屾寜閽弻鍑�
   }
 
   state = {
@@ -44,7 +41,6 @@
     loading: false,
     disabled: false,
     hidden: false,
-    loadingNumber: '',
     autoMatic: false
   }
 
@@ -150,12 +146,7 @@
     const { loading, disabled } = this.state
 
     if (loading || disabled) return
-    if (triggerId) {
-      if (btn.uuid !== triggerId) return
-      if (this.props.lineId && record && record[0] && this.props.lineId !== record[0].$$key) {
-        return
-      }
-    }
+    if (triggerId && btn.uuid !== triggerId) return
 
     if (((Tab && Tab.supMenu) || setting.supModule) && !BID) {
       notification.warning({
@@ -164,10 +155,8 @@
         duration: 5
       })
       return
-    } else if (type === 'linkbtn' && selectedData && selectedData.length === 1) {
-      if (record[0].$Index !== selectedData[0].$Index) {
-        return
-      }
+    } else if (type === 'linkbtn' && !btn.$toolbtn && !is(fromJS(selectedData || []), fromJS(record))) {
+      return
     }
 
     this.setState({autoMatic: type === 'autoMatic'})
@@ -250,38 +239,77 @@
   triggerPrint = (data, formlist = []) => {
     const { btn } = this.props
     let formdata = {}
+    let baseCount = 1
+    let baseType = ''
+    let baseTemp = btn.verify.Template || ''
     
     formlist.forEach(_data => {
       formdata[_data.key] = _data.value
+
+      if (!_data.value) return
+
+      if (_data.key.toLowerCase() === 'printcount') {
+        baseCount = +_data.value
+      } else if (_data.key.toLowerCase() === 'printtype') {
+        baseType = _data.value
+      } else if (_data.key.toLowerCase() === 'templateid') {
+        baseTemp = _data.value
+      }
     })
 
     let printlist = []
     let templates = []
-    let printCount = +(formdata.printCount || formdata.PrintCount || formdata.printcount || formdata.Printcount || 1)
 
-    if (isNaN(printCount) || printCount < 1) {
-      printCount = 1
+    if (isNaN(baseCount) || baseCount < 1) {
+      baseCount = 1
     }
 
     new Promise(resolve => {
       if (btn.intertype === 'system') { // 浣跨敤绯荤粺鏃讹紝鐩存帴浠庤〃鏍兼垨琛ㄥ崟涓�夊彇鏁版嵁
-        let printcell = {}
-
-        printcell.printType = formdata.printType || formdata.PrintType || formdata.printtype || formdata.Printtype || ''
-        printcell.printCount = printCount
-        printcell.templateID = btn.verify.Template || ''
-
         if (btn.Ot === 'notRequired') {
+          let printcell = {}
+  
+          printcell.printType = baseType
+          printcell.printCount = baseCount
+          printcell.templateID = baseTemp
           printcell.data = [formdata]
+
+          templates.push(printcell.templateID)
+
+          printlist.push(printcell)
         } else {
-          printcell.data = data.map(cell => {
-            return {...cell, ...formdata}
+          data.forEach(cell => {
+            let _cell = {...cell, ...formdata}
+            
+            let printcell = {data: [_cell]}
+  
+            printcell.templateID = baseTemp
+            printcell.printType = baseType
+            printcell.printCount = 0
+
+            Object.keys(_cell).forEach(key => {
+              if (!_cell[key]) return
+
+              let _key = key.toLowerCase()
+
+              if (_key === 'templateid') {
+                printcell.templateID = _cell[key]
+              } else if (_key === 'printtype') {
+                printcell.printType = _cell[key]
+              } else if (_key === 'printcount') {
+                printcell.printCount = +_cell[key]
+              }
+            })
+
+            if (isNaN(printcell.printCount) || printcell.printCount < 1) {
+              printcell.printCount = baseCount
+            }
+
+            templates.push(printcell.templateID)
+
+            printlist.push(printcell)
           })
         }
-
-        templates.push(printcell.templateID)
-
-        printlist.push(printcell)
 
         resolve(true)
       } else {
@@ -291,16 +319,31 @@
               // 绯荤粺鎵撳嵃鏁版嵁锛屾牎楠宒ata瀛楁
               if (btn.verify.printMode !== 'custom' && (!cell.data || cell.data.length === 0)) return
 
-              cell.templateID = cell.templateID || cell.TemplateID || cell.Templateid || cell.templateid || btn.verify.Template
-              cell.printType = cell.printType || cell.PrintType || cell.printtype || cell.Printtype || formdata.printType || formdata.PrintType || formdata.printtype || formdata.Printtype || ''
+              let templateID = baseTemp
+              let printType = baseType
+              let printCount = 0
 
-              let _printCount = +(cell.printCount || cell.PrintCount || cell.printcount || cell.Printcount || 0)
+              Object.keys(cell).forEach(key => {
+                if (!cell[key]) return
 
-              if (isNaN(_printCount) || _printCount < 1) {
-                _printCount = printCount
+                let _key = key.toLowerCase()
+
+                if (_key === 'templateid') {
+                  templateID = cell[key]
+                } else if (_key === 'printtype') {
+                  printType = cell[key]
+                } else if (_key === 'printcount') {
+                  printCount = +cell[key]
+                }
+              })
+
+              cell.templateID = templateID
+              cell.printType = printType
+              cell.printCount = printCount
+
+              if (isNaN(cell.printCount) || cell.printCount < 1) {
+                cell.printCount = baseCount
               }
-              
-              cell.printCount = _printCount
 
               templates.push(cell.templateID)
 
@@ -772,7 +815,7 @@
       // 澶栭儴璇锋眰
       _outParam = JSON.parse(JSON.stringify(res))
 
-      if (this.props.menuType === 'HS') {
+      if (window.GLOB.mkHS) {
         if (btn.sysInterface === 'true' && options.cloudServiceApi) {
           res.rduri = options.cloudServiceApi
         } else if (btn.sysInterface !== 'true') {
@@ -887,7 +930,8 @@
       if (!configParam) {
         error = '鎵撳嵃妯℃澘瑙f瀽閿欒锛�'
       } else {
-        let control = configParam.elements.map(element => {
+        let control = []
+        configParam.elements.forEach(element => {
           let _field = element.field
 
           if (_field === 'other_field') {
@@ -923,11 +967,12 @@
             item.Trimming = ''
             if (!item.Width) {
               item.Width = item.BorderSize
-              item.Left = item.Left - item.Width
+              item.Left = item.Left - item.Width + 0.1
             } else if (!item.Height) {
               item.Height = item.BorderSize
-              item.Top = item.Top - item.Height
+              item.Top = item.Top - item.Height + 0.1
             }
+            item.BackColor = element.borderColor
             item.BorderSize = 0
           } else if (item.Type === 'image') {
             item.ImageWidth = element.imgWidth
@@ -967,7 +1012,7 @@
             }
           }
 
-          return item
+          control.push(item)
         })
 
         _configparam = {
@@ -1563,7 +1608,7 @@
 
     if (!this.state.visible || !btnconfig || !btnconfig.setting) return null
 
-    let title = btnconfig.setting.title
+    let title = btn.label
     let width = btnconfig.setting.width > 100 ? btnconfig.setting.width : btnconfig.setting.width + 'vw'
     let clickouter = false
     let container = document.body
@@ -1595,7 +1640,6 @@
         <MutilForm
           BID={BID}
           dict={this.state.dict}
-          menuType={this.props.menuType}
           action={btnconfig}
           inputSubmit={this.handleOk}
           data={this.state.selines[0]}
@@ -1607,64 +1651,49 @@
   }
 
   render() {
-    const { btn, show } = this.props
-    const { loadingNumber, loading, disabled, hidden } = this.state
+    const { btn } = this.props
+    const { loading, disabled, hidden } = this.state
 
     if (hidden) return null
 
-    if (show === 'actionList') {
-      return <div style={{display: 'inline-block'}} onClick={(e) => e.stopPropagation()}>
-        <Button
-          icon={btn.icon}
-          loading={loading}
-          disabled={disabled}
-          title={disabled ? (btn.reason || '') : ''}
-          className={'mk-btn mk-' + btn.class}
-          onClick={() => {this.actionTrigger()}}
-        >{loadingNumber ? `(${loadingNumber})` : '' + btn.label}</Button>
-        {this.getModels()}
-      </div>
-    } else { // icon銆乼ext銆� all 鍗$墖
-      let label = ''
-      let icon = ''
+    let label = ''
+    let icon = ''
+    let type = 'link'
+    let className = ''
 
-      if (show === 'button') {
-        label = btn.label
-        icon = btn.icon || ''
-      } else if (show === 'link') {
-        label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
-        icon = ''
-      } else if (show === 'icon') {
-        icon = btn.icon || ''
-      // } else if (show === 'text') {
-      } else {
-        label = btn.label
-      }
-
-      return <div style={{display: 'inline-block'}} onClick={(e) => e.stopPropagation()}>
-        <Button
-          type="link"
-          title={disabled ? (btn.reason || '') : (show === 'icon' ? btn.label : '')}
-          loading={loading}
-          disabled={disabled}
-          style={btn.style}
-          icon={icon}
-          onClick={() => {this.actionTrigger()}}
-        >{label}</Button>
-        {this.getModels()}
-      </div>
+    if (btn.show === 'button') {
+      label = btn.label
+      icon = btn.icon || ''
+    } else if (btn.show === 'link') {
+      label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
+      icon = ''
+    } else if (btn.show === 'icon') {
+      icon = btn.icon || ''
+    } else if (!btn.$toolbtn) {
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
+    } else {
+      type = ''
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
     }
+
+    return <>
+      <Button
+        type={type}
+        title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
+        loading={loading}
+        disabled={disabled}
+        style={btn.style || null}
+        icon={icon}
+        className={className}
+        onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
+      >{label}</Button>
+      <span onClick={(e) => {e.stopPropagation()}}>{this.getModels()}</span>
+    </>
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    menuType: state.editLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(PrintButton)
\ No newline at end of file
+export default PrintButton
\ No newline at end of file
diff --git a/src/tabviews/zshare/actionList/tabbutton/index.jsx b/src/tabviews/zshare/actionList/tabbutton/index.jsx
index 353a566..f3cd9cf 100644
--- a/src/tabviews/zshare/actionList/tabbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/tabbutton/index.jsx
@@ -12,14 +12,12 @@
 
 class TabButton extends Component {
   static propTpyes = {
-    show: PropTypes.any,              // 鎸夐挳鏄剧ず鏍峰紡鎺у埗
     BData: PropTypes.any,             // 涓昏〃鏁版嵁
     MenuID: PropTypes.string,         // 鑿滃崟ID
     btn: PropTypes.object,            // 鎸夐挳
     selectedData: PropTypes.any,      // 瀛愯〃涓�夋嫨鏁版嵁
     setting: PropTypes.any,           // 椤甸潰閫氱敤璁剧疆
     disabled: PropTypes.any,          // 琛屾寜閽鐢�
-    lineId: PropTypes.any,            // 琛岀储寮�+涓婚敭鍊硷紝鐢ㄤ簬琛屾寜閽弻鍑�
   }
 
   state = {
@@ -116,17 +114,10 @@
     const { disabled } = this.state
 
     if (disabled) return
-    if (triggerId) {
-      if (btn.uuid !== triggerId) return
-      if (this.props.lineId && record && record[0] && this.props.lineId !== record[0].$$key) {
-        return
-      }
-    }
+    if (triggerId && btn.uuid !== triggerId) return
 
-    if (type === 'linkbtn' && selectedData && selectedData.length === 1) {
-      if (record[0].$Index !== selectedData[0].$Index) {
-        return
-      }
+    if (type === 'linkbtn' && !btn.$toolbtn && !is(fromJS(selectedData || []), fromJS(record))) {
+      return
     }
     
     let data = record || selectedData || []
@@ -207,49 +198,46 @@
   }
 
   render() {
-    const { btn, show } = this.props
+    const { btn } = this.props
     const { disabled, hidden } = this.state
 
     if (hidden) return null
 
-    if (show === 'actionList') {
-      return (
-        <Button
-          className={'mk-btn mk-' + btn.class}
-          icon={btn.icon}
-          disabled={disabled}
-          title={disabled ? (btn.reason || '') : ''}
-          onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
-        >{btn.label}</Button>
-      )
-    } else { // icon銆乼ext銆� all 鍗$墖
-      let label = ''
-      let icon = ''
+    let label = ''
+    let icon = ''
+    let type = 'link'
+    let className = ''
 
-      if (show === 'button') {
-        label = btn.label
-        icon = btn.icon || ''
-      } else if (show === 'link') {
-        label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
-        icon = ''
-      } else if (show === 'icon') {
-        icon = btn.icon || ''
-      // } else if (show === 'text') {
-      } else {
-        label = btn.label
-      }
-
-      return (
-        <Button
-          type="link"
-          title={disabled ? (btn.reason || '') : (show === 'icon' ? btn.label : '')}
-          style={btn.style}
-          disabled={disabled}
-          icon={icon}
-          onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
-        >{label}</Button>
-      )
+    if (btn.show === 'button') {
+      label = btn.label
+      icon = btn.icon || ''
+    } else if (btn.show === 'link') {
+      label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span>
+      icon = ''
+    } else if (btn.show === 'icon') {
+      icon = btn.icon || ''
+    } else if (!btn.$toolbtn) {
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
+    } else {
+      type = ''
+      icon = btn.icon || ''
+      label = btn.label
+      className = 'mk-btn mk-' + btn.class
     }
+
+    return (
+      <Button
+        type={type}
+        title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
+        style={btn.style || null}
+        disabled={disabled}
+        icon={icon}
+        className={className}
+        onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
+      >{label}</Button>
+    )
   }
 }
 
diff --git a/src/tabviews/zshare/cardcomponent/index.jsx b/src/tabviews/zshare/cardcomponent/index.jsx
index 0480ba8..f9eac6c 100644
--- a/src/tabviews/zshare/cardcomponent/index.jsx
+++ b/src/tabviews/zshare/cardcomponent/index.jsx
@@ -111,13 +111,30 @@
     
     let extra = null
     if (card.header && card.header.actions) {
-      let actions = this.getActionList(card.header.actions, card.header.show)
+      let actions = card.header.actions.map(item => {
+        if (card.header.show === 'icon') {
+          item.show = 'icon'
+        } else {
+          item.show = 'button'
+        }
+        return item
+      })
+
+      actions = this.getActionList(actions)
       extra = actions[0]
     }
 
     let _actions = null
     if (card.bottom && card.bottom.actions) {
-      _actions = this.getActionList(card.bottom.actions, card.bottom.show)
+      _actions = card.bottom.actions.map(item => {
+        if (card.bottom.show === 'icon') {
+          item.show = 'icon'
+        } else {
+          item.show = 'button'
+        }
+        return item
+      })
+      _actions = this.getActionList(_actions)
     }
 
     this.setState({
@@ -129,7 +146,7 @@
   /**
    * @description 鑾峰彇鎸夐挳鍏冪礌
    */
-  getActionList = (actions, show) => {
+  getActionList = (actions) => {
     const { BData, Tab, setting, columns, ContainerId, data, MenuID } = this.props
     
     return actions.map(item => {
@@ -140,7 +157,6 @@
             BID={data.$$BID}
             Tab={Tab}
             btn={item}
-            show={show}
             BData={BData}
             setting={setting}
             columns={columns}
@@ -155,7 +171,6 @@
             BID={data.$$BID}
             Tab={Tab}
             btn={item}
-            show={show}
             BData={BData}
             setting={setting}
             selectedData={[data]}
@@ -166,7 +181,6 @@
           <TabButton
             key={item.uuid}
             btn={item}
-            show={show}
             MenuID={MenuID}
             setting={setting}
             selectedData={[data]}
@@ -177,7 +191,6 @@
           <NewPageButton
             key={item.uuid}
             btn={item}
-            show={show}
             setting={setting}
             selectedData={[data]}
           />
@@ -189,7 +202,6 @@
               key={item.uuid}
               BID={data.$$BID}
               btn={item}
-              show={show}
               setting={setting}
               selectedData={[data]}
             />
@@ -201,7 +213,6 @@
               BID={data.$$BID}
               Tab={Tab}
               btn={item}
-              show={show}
               BData={BData}
               setting={setting}
               selectedData={[data]}
@@ -440,6 +451,7 @@
         title = card.header.content
       }
     }
+    let style = {fontSize: plusSize + 'px'}
 
     return (
       <div className={'chart-card-box ' + card.outclass}>
@@ -487,8 +499,7 @@
             <NormalButton
               BID={this.props.BID}
               Tab={this.props.Tab}
-              btn={card.insertAction}
-              show={'plus' + plusSize}
+              btn={{...card.insertAction, style}}
               BData={this.props.BData}
               setting={this.props.setting}
               columns={this.props.columns}
@@ -555,8 +566,10 @@
       if ((item.Ot && item.Ot !== 'notRequired' && !['excelIn', 'excelOut'].includes(item.OpenType)) || item.funcType === 'changeuser') {
         actionMap.set(item.uuid, item)
       } else if (plot.extraAction && plot.extraAction === item.uuid && ['pop', 'prompt', 'exec'].includes(item.OpenType) && item.Ot === 'notRequired') {
+        item.show = 'icon'
         insertAction = item
       } else if (plot.actions && plot.actions.length > 0 && plot.actions.includes(item.uuid) && (item.OpenType === 'excelOut' || (item.OpenType === 'excelIn' && item.Ot === 'notRequired'))) {
+        item.show = 'icon'
         actionList.push(item)
       }
     })
@@ -681,6 +694,10 @@
 
     card.switch = plot.switch !== 'false'
 
+    if (insertAction && !insertAction.icon) {
+      insertAction.icon = 'plus'
+    }
+
     card.insertAction = insertAction // 娣诲姞鍗$墖
 
     this.setState({card: card, colMap: colMap, actionList: actionList})
@@ -761,7 +778,6 @@
                     key={action.uuid}
                     BID={BID}
                     Tab={Tab}
-                    show="icon"
                     btn={action}
                     setting={config.setting}
                   />
@@ -772,7 +788,6 @@
                     key={action.uuid}
                     BID={BID}
                     Tab={Tab}
-                    show="icon"
                     btn={action}
                     setting={config.setting}
                   />
diff --git a/src/tabviews/zshare/cardcomponent/index.scss b/src/tabviews/zshare/cardcomponent/index.scss
index 6d5b2b8..f4d3ec1 100644
--- a/src/tabviews/zshare/cardcomponent/index.scss
+++ b/src/tabviews/zshare/cardcomponent/index.scss
@@ -88,21 +88,17 @@
       right: 0;
       bottom: 0;
 
-      div {
+      .ant-btn {
+        border: 0;
         width: 100%;
         height: 100%;
-        .ant-btn {
-          border: 0;
-          width: 100%;
-          height: 100%;
-          color: #d9d9d9;
-          transition: color 0.3s linear;
-        }
+        color: #d9d9d9;
+        transition: color 0.3s linear;
       }
     }
     .mk-card-insert:hover {
       .ant-btn {
-        color: #1890ff;
+        color: var(--mk-sys-color);
       }
     }
   }
diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx
index 1db51b6..1496a1f 100644
--- a/src/tabviews/zshare/mutilform/index.jsx
+++ b/src/tabviews/zshare/mutilform/index.jsx
@@ -25,11 +25,12 @@
 const MKTextArea = asyncComponent(() => import('./mkTextArea'))
 const MKFileUpload = asyncComponent(() => import('../fileupload'))
 const MKColor = asyncComponent(() => import('./mkColor'))
+const MkFormula = asyncComponent(() => import('./mkFormula'))
+const MkCascader = asyncComponent(() => import('./mkCascader'))
 const MKEditor = asyncComponent(() => import('@/components/editor'))
 
 class MainSearch extends Component {
   static propTpyes = {
-    menuType: PropTypes.object,  // 鑿滃崟绫诲瀷锛屾槸鍚︿负HS
     action: PropTypes.object,    // 鎸夐挳淇℃伅銆佽〃鍗曞垪琛�
     data: PropTypes.any,         // 琛ㄦ牸鏁版嵁
     BID: PropTypes.any,          // 涓昏〃ID
@@ -77,7 +78,14 @@
         linkFields[item.linkField].push({field: item.field, uuid: item.uuid})
       }
 
-      if (item.type === 'split') return true
+      if (item.style) {
+        delete item.style.marginTop
+        delete item.style.marginBottom
+        delete item.style.marginLeft
+        delete item.style.marginRight
+      }
+
+      if (item.type === 'split' || item.type === 'formula') return true
       if (item.type === 'hint') {
         if (item.field && data && data[item.field]) {
           item.message = data[item.field]
@@ -91,7 +99,12 @@
         item.precision = 'second'
       }
 
-      if (!item.field || !['text', 'number', 'switch', 'rate', 'select', 'link', 'linkMain', 'funcvar', 'date', 'datemonth', 'radio', 'checkbox', 'checkcard', 'fileupload', 'textarea', 'multiselect', 'brafteditor', 'color'].includes(item.type)) return false
+      if (!item.field || !['text', 'number', 'switch', 'rate', 'select', 'link', 'cascader', 'linkMain', 'funcvar', 'date', 'datemonth', 'radio', 'checkbox', 'checkcard', 'fileupload', 'textarea', 'multiselect', 'brafteditor', 'color'].includes(item.type)) return false
+
+      if (/^\s+$/.test(item.label)) {
+        item.style = item.style || {}
+        item.style.color = 'transparent'
+      }
 
       // 鏁版嵁鑷姩濉厖
       let readin = item.readin !== 'false'
@@ -111,14 +124,8 @@
         item.initval = item.initval || 0
       }
 
-      if (['select', 'link', 'radio', 'checkbox', 'checkcard', 'multiselect'].includes(item.type)) {
+      if (['select', 'link', 'radio', 'checkbox', 'checkcard', 'multiselect', 'cascader'].includes(item.type)) {
         item.options = item.options || []
-        // item.options = item.options.map(cell => {
-        //   cell.value = cell.Value
-        //   cell.label = cell.Text
-
-        //   return cell
-        // })
         item.options = item.options.filter(cell => {
           cell.value = cell.Value
           cell.label = cell.Text
@@ -199,7 +206,7 @@
         item.initval = ''
       }
 
-      if (['select', 'link', 'radio', 'checkbox', 'checkcard', 'multiselect'].includes(item.type) && item.resourceType === '1') {
+      if (['select', 'link', 'radio', 'checkbox', 'checkcard', 'multiselect', 'cascader'].includes(item.type) && item.resourceType === '1') {
         deForms.push(item)
       } else if (item.type === 'rate') {
         item.rateCount = item.rateCount || 5
@@ -227,7 +234,15 @@
         }
         let _rules = [{
           pattern: /^[^']*$/ig,
-          message: formRule.input.quotemsg
+          message: '涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙凤紒'
+        }, {
+          validator: (rule, value, callback) => {
+            if (/--/ig.test(value)) {
+              callback('涓嶅彲浣跨敤 -- 锛�')
+            } else {
+              callback()
+            }
+          }
         }, {
           required: item.required === 'true',
           message: item.label + '涓嶅彲涓虹┖!'
@@ -253,13 +268,18 @@
             })
           } else if (item.regular === 'letter&number') {
             _rules.push({
-              pattern: /^[a-zA-Z0-9]*$/ig,
-              message: formRule.input.letternummsg
+              pattern: /^[a-zA-Z0-9@_.]*$/ig,
+              message: '璇疯緭鍏ユ暟瀛椼�佸瓧姣嶄互鍙夽_.'
             })
           } else if (item.regular === 'phone') {
             _rules.push({
               pattern: /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/ig,
               message: '璇锋纭緭鍏ユ墜鏈哄彿'
+            })
+          } else if (item.regular === 'email') {
+            _rules.push({
+              pattern: /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/,
+              message: '璇锋纭緭鍏ラ偖绠卞湴鍧�'
             })
           } else if (item.regular === 'funcname') {
             _rules.push({
@@ -291,7 +311,15 @@
         if (item.encryption !== 'true') {
           _rules.push({
             pattern: /^[^']*$/ig,
-            message: formRule.input.quotemsg
+            message: '涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙凤紒'
+          }, {
+            validator: (rule, value, callback) => {
+              if (/--/ig.test(value)) {
+                callback('涓嶅彲浣跨敤 -- 锛�')
+              } else {
+                callback()
+              }
+            }
           })
         }
         item.rules = _rules
@@ -364,7 +392,7 @@
       let item = fieldMap.get(cell.field)
 
       // 涓嬬骇琛ㄥ崟鎺у埗-瀛楁鍐欏叆
-      if ((['select', 'radio', 'link'].includes(item.type) || (item.type === 'checkcard' && item.multiple !== 'true')) && item.linkSubField) {
+      if ((['select', 'radio', 'link'].includes(item.type) || (item.type === 'checkcard' && item.multiple !== 'true') || (item.type === 'cascader' && item.resourceType !== '2')) && item.linkSubField) {
         item.subFields = []
         item.linkSubField.forEach(m => {
           let n = fieldMap.get(m)
@@ -404,7 +432,7 @@
         item.options = item.oriOptions.filter(option => option.ParentID === item.supInitVal || option.value === '')
       }
 
-      if (['select', 'link', 'radio'].includes(item.type) && item.resourceType !== '1') { // 閫変腑绗竴椤�
+      if (['select', 'link', 'radio'].includes(item.type) && item.resourceType === '0') { // 閫変腑绗竴椤�
         if (typeof(item.initval) === 'string' && item.initval.indexOf('$first') > -1) {
           item.initval = item.options[0] ? item.options[0].value : ''
         }
@@ -431,8 +459,12 @@
       }
 
       if (item.subFields && item.options.length > 0) {
+        let initval = item.initval
+        if (item.type === 'cascader' && item.separator) {
+          initval = initval.split(item.separator).pop()
+        }
         // eslint-disable-next-line
-        let option = item.options.filter(cell => item.initval == cell.value)[0]
+        let option = item.options.filter(cell => initval == cell.value)[0]
 
         if (option) {
           reFieldsVal = reFieldsVal || {}
@@ -466,7 +498,7 @@
       }
 
       if (deForms.length > 0) {
-        if (this.props.menuType !== 'HS' && options.sysType === 'local' && window.GLOB.systemType !== 'production') {
+        if (!window.GLOB.mkHS && options.sysType === 'local' && window.GLOB.systemType !== 'production') {
           this.improveSimpleActionForm(deForms)
         } else {
           this.improveActionForm(deForms)
@@ -479,7 +511,7 @@
    * @description 鑾峰彇涓嬫媺琛ㄥ崟閫夐」淇℃伅
    */
   improveActionForm = (deForms) => {
-    const { BID, menuType, action } = this.props
+    const { BID, action } = this.props
 
     let deffers = []
     let mainItems = []  // 浜戠鎴栧崟鐐规暟鎹�
@@ -494,7 +526,7 @@
       }
     })
     
-    if (menuType !== 'HS' && options.sysType !== 'local') {
+    if (!window.GLOB.mkHS && options.sysType !== 'local') {
       localItems = [...localItems, ...mainItems]
       mainItems = []
     }
@@ -514,7 +546,7 @@
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
       param.secretkey = Utils.encrypt(param.LText, param.timestamp)
 
-      if (menuType === 'HS') { // 浜戠鏁版嵁楠岃瘉
+      if (window.GLOB.mkHS) { // 浜戠鏁版嵁楠岃瘉
         param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
       }
 
@@ -549,7 +581,7 @@
       mainparam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
       mainparam.secretkey = Utils.encrypt(mainparam.LText, mainparam.timestamp)
 
-      if (menuType === 'HS') { // 浜戠鏁版嵁楠岃瘉
+      if (window.GLOB.mkHS) { // 浜戠鏁版嵁楠岃瘉
         mainparam.open_key = Utils.encryptOpenKey(mainparam.secretkey, mainparam.timestamp)
         if (options.cloudServiceApi) {
           mainparam.rduri = options.cloudServiceApi
@@ -642,7 +674,7 @@
   resetFormList = (result) => {
     let reFieldsVal = null
     let _formlist = fromJS(this.state.formlist).toJS().map(item => {
-      if (['select', 'link', 'radio', 'checkbox', 'checkcard', 'multiselect'].includes(item.type) && result[item.field] && result[item.field].length > 0) {
+      if (['select', 'link', 'radio', 'checkbox', 'checkcard', 'multiselect', 'cascader'].includes(item.type) && result[item.field] && result[item.field].length > 0) {
         let options = []
         result[item.field].forEach(cell => {
           let _cell = { key: Utils.getuuid() }
@@ -688,8 +720,12 @@
         }
 
         if (item.subFields && item.options.length > 0) {
+          let initval = item.initval
+          if (item.type === 'cascader' && item.separator) {
+            initval = initval.split(item.separator).pop()
+          }
           // eslint-disable-next-line
-          let option = item.options.filter(cell => item.initval == cell.value)[0]
+          let option = item.options.filter(cell => initval == cell.value)[0]
   
           if (option) {
             reFieldsVal = reFieldsVal || {}
@@ -731,9 +767,12 @@
         callback(item.label + '鏈�灏忓�间负 ' + item.min)
       } else if (typeof(item.max) === 'number' && val > item.max) {
         callback(item.label + '鏈�澶у�间负 ' + item.max)
+      } else {
+        callback()
       }
+    } else {
+      callback()
     }
-    callback()
   }
 
   recordChange = (values, item) => {
@@ -801,6 +840,14 @@
             </Form.Item>
           </Col>
         )
+      } else if (item.type === 'formula') {
+        fields.push(
+          <Col span={item.span || 24} key={index}>
+            <Form.Item className="hint" colon={false} label={<span className="mk-form-label" style={item.style}>{item.label}</span>} labelCol={item.labelCol} wrapperCol={item.wrapperCol}>
+              <MkFormula config={item} data={this.record}></MkFormula>
+            </Form.Item>
+          </Col>
+        )
       } else {
         let content = null
         let className = ''
@@ -814,6 +861,8 @@
           content = (<MKNumberInput config={item} onChange={(val, defer) => !defer && this.recordChange({[item.field]: val})} onSubmit={this.props.inputSubmit} />)
         } else if (item.type === 'select' || item.type === 'link' || item.type === 'multiselect') {
           content = (<MKSelect config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)} onSubmit={this.props.inputSubmit} />)
+        } else if (item.type === 'cascader') {
+          content = (<MkCascader config={item} onChange={(val, other) => this.recordChange({[item.field]: val, ...other}, item)}/>)
         } else if (item.type === 'color') {
           content = (<MKColor config={item} onChange={(val) => this.recordChange({[item.field]: val})}/>)
         } else if (item.type === 'checkcard') {
@@ -909,6 +958,9 @@
             if (item.declareType === 'nvarchar(50)') {
               _item.type = 'text'
             }
+          } else if (item.declare === 'decimal' && ['select', 'link', 'radio', 'checkcard'].includes(item.type)) {
+            _item.type = 'number'
+            _item.fieldlen = item.decimal || 0
           }
 
           if (item.type === 'text' && item.lenControl && item.lenControl !== 'limit') {
@@ -934,9 +986,13 @@
     if (action.setting && action.setting.align) {
       _align = action.setting.align
     }
+    let space = ' space-normal'
+    if (action.setting && action.setting.verticalSpace) {
+      space = ' space-' + action.setting.verticalSpace
+    }
 
     return (
-      <Form className={'main-form-field ' + _align}>
+      <Form className={'main-form-field ' + _align + space}>
         <Row gutter={24}>{this.getFields()}</Row>
       </Form>
     )
diff --git a/src/tabviews/zshare/mutilform/index.scss b/src/tabviews/zshare/mutilform/index.scss
index 3eeeb15..baebc0a 100644
--- a/src/tabviews/zshare/mutilform/index.scss
+++ b/src/tabviews/zshare/mutilform/index.scss
@@ -30,7 +30,12 @@
   .ant-form-item {
     display: flex;
   }
-  .ant-form-item.checkcard, .ant-form-item.file-upload {
+  .ant-form-item.checkcard {
+    .ant-form-item-control {
+      line-height: 1;
+    }
+  }
+  .ant-form-item.file-upload {
     margin-bottom: 10px;
     .ant-form-item-control {
       line-height: 1;
@@ -132,9 +137,21 @@
     .ant-form-item-label {
       width: 100%!important;
       text-align: left;
+      height: 24px;
+      line-height: 28px;
     }
     .ant-form-item-control-wrapper {
       width: 100%!important;
     }
   }
+}
+.main-form-field.space-middle {
+  .ant-form-item:not(.ant-form-item-with-help) {
+    margin-bottom: 15px;
+  }
+}
+.main-form-field.space-small {
+  .ant-form-item:not(.ant-form-item-with-help) {
+    margin-bottom: 5px;
+  }
 }
\ No newline at end of file
diff --git a/src/tabviews/zshare/mutilform/mkCascader/data.json b/src/tabviews/zshare/mutilform/mkCascader/data.json
new file mode 100644
index 0000000..4ce84a8
--- /dev/null
+++ b/src/tabviews/zshare/mutilform/mkCascader/data.json
@@ -0,0 +1,408 @@
+[
+	["鍖椾含甯�", [
+		["鍖椾含甯�", ["涓滃煄鍖�", "瑗垮煄鍖�", "鏈濋槼鍖�", "涓板彴鍖�", "鐭虫櫙灞卞尯", "娴锋穩鍖�", "闂ㄥご娌熷尯", "鎴垮北鍖�", "閫氬窞鍖�", "椤轰箟鍖�", "鏄屽钩鍖�", "澶у叴鍖�", "鎬�鏌斿尯", "骞宠胺鍖�", "瀵嗕簯鍖�", "寤跺簡鍖�"]]
+	]],
+	["澶╂触甯�", [
+		["澶╂触甯�", ["鍜屽钩鍖�", "娌充笢鍖�", "娌宠タ鍖�", "鍗楀紑鍖�", "娌冲寳鍖�", "绾㈡ˉ鍖�", "涓滀附鍖�", "瑗块潚鍖�", "娲ュ崡鍖�", "鍖楄景鍖�", "姝︽竻鍖�", "瀹濆澔鍖�", "婊ㄦ捣鏂板尯", "瀹佹渤鍖�", "闈欐捣鍖�", "钃熷窞鍖�"]]
+	]],
+	["娌冲寳鐪�", [
+		["鐭冲搴勫競", ["闀垮畨鍖�", "妗ヤ笢鍖�", "妗ヨタ鍖�", "鏂板崕鍖�", "浜曢檳鐭垮尯", "瑁曞崕鍖�", "浜曢檳鍘�", "姝e畾鍘�", "鏍惧煄鍘�", "琛屽攼鍘�", "鐏靛鍘�", "楂橀倯鍘�", "娣辨辰鍘�", "璧炵殗鍘�", "鏃犳瀬鍘�", "骞冲北鍘�", "鍏冩皬鍘�", "璧靛幙", "杈涢泦甯�", "钘佸煄甯�", "鏅嬪窞甯�", "鏂颁箰甯�", "楣挎硥甯�"]],
+		["鍞愬北甯�", ["璺崡鍖�", "璺寳鍖�", "鍙ゅ喍鍖�", "寮�骞冲尯", "涓板崡鍖�", "涓版鼎鍖�", "鏇瑰鐢稿尯", "婊﹀幙", "婊﹀崡鍘�", "涔愪涵鍘�", "杩佽タ鍘�", "鐜夌敯鍘�", "閬靛寲甯�", "杩佸畨甯�"]],
+		["绉︾殗宀涘競", ["娴锋腐鍖�", "灞辨捣鍏冲尯", "鍖楁埓娌冲尯", "闈掗緳婊℃棌鑷不鍘�", "鏄岄粠鍘�", "鎶氬畞鍘�", "鍗㈤緳鍘�"]],
+		["閭兏甯�", ["閭北鍖�", "涓涘彴鍖�", "澶嶅叴鍖�", "宄板嘲鐭垮尯", "閭兏鍘�", "涓存汲鍘�", "鎴愬畨鍘�", "澶у悕鍘�", "娑夊幙", "纾佸幙", "鑲ヤ埂鍘�", "姘稿勾鍘�", "閭卞幙", "楦℃辰鍘�", "骞垮钩鍘�", "棣嗛櫠鍘�", "榄忓幙", "鏇插懆鍘�", "姝﹀畨甯�"]],
+		["閭㈠彴甯�", ["妗ヤ笢鍖�", "妗ヨタ鍖�", "閭㈠彴鍘�", "涓村煄鍘�", "鍐呬笜鍘�", "鏌忎埂鍘�", "闅嗗哀鍘�", "浠诲幙", "鍗楀拰鍘�", "瀹佹檵鍘�", "宸ㄩ箍鍘�", "鏂版渤鍘�", "骞垮畻鍘�", "骞充埂鍘�", "濞佸幙", "娓呮渤鍘�", "涓磋タ鍘�", "鍗楀甯�", "娌欐渤甯�"]],
+		["淇濆畾甯�", ["鏂板競鍖�", "鍖楀競鍖�", "鍗楀競鍖�", "婊″煄鍘�", "娓呰嫅鍘�", "娑炴按鍘�", "闃滃钩鍘�", "寰愭按鍘�", "瀹氬叴鍘�", "鍞愬幙", "楂橀槼鍘�", "瀹瑰煄鍘�", "娑炴簮鍘�", "鏈涢兘鍘�", "瀹夋柊鍘�", "鏄撳幙", "鏇查槼鍘�", "锠″幙", "椤哄钩鍘�", "鍗氶噹鍘�", "闆勫幙", "娑垮窞甯�", "瀹氬窞甯�", "瀹夊浗甯�", "楂樼搴楀競"]],
+		["寮犲鍙e競", ["妗ヤ笢鍖�", "妗ヨタ鍖�", "瀹e寲鍖�", "涓嬭姳鍥尯", "瀹e寲鍘�", "寮犲寳鍘�", "搴蜂繚鍘�", "娌芥簮鍘�", "灏氫箟鍘�", "钄氬幙", "闃冲師鍘�", "鎬�瀹夊幙", "涓囧叏鍘�", "鎬�鏉ュ幙", "娑块箍鍘�", "璧ゅ煄鍘�", "宕囩ぜ鍘�"]],
+		["鎵垮痉甯�", ["鍙屾ˉ鍖�", "鍙屾沪鍖�", "楣版墜钀ュ瓙鐭垮尯", "鎵垮痉鍘�", "鍏撮殕鍘�", "骞虫硥鍘�", "婊﹀钩鍘�", "闅嗗寲鍘�", "涓板畞婊℃棌鑷不鍘�", "瀹藉煄婊℃棌鑷不鍘�", "鍥村満婊℃棌钂欏彜鏃忚嚜娌诲幙"]],
+		["娌у窞甯�", ["鏂板崕鍖�", "杩愭渤鍖�", "娌у幙", "闈掑幙", "涓滃厜鍘�", "娴峰叴鍘�", "鐩愬北鍘�", "鑲冨畞鍘�", "鍗楃毊鍘�", "鍚存ˉ鍘�", "鐚幙", "瀛熸潙鍥炴棌鑷不鍘�", "娉婂ご甯�", "浠讳笜甯�", "榛勯獏甯�", "娌抽棿甯�"]],
+		["寤婂潑甯�", ["瀹夋鍖�", "骞块槼鍖�", "鍥哄畨鍘�", "姘告竻鍘�", "棣欐渤鍘�", "澶у煄鍘�", "鏂囧畨鍘�", "澶у巶鍥炴棌鑷不鍘�", "闇稿窞甯�", "涓夋渤甯�"]],
+		["琛℃按甯�", ["妗冨煄鍖�", "鏋e己鍘�", "姝﹂倯鍘�", "姝﹀己鍘�", "楗堕槼鍘�", "瀹夊钩鍘�", "鏁呭煄鍘�", "鏅幙", "闃滃煄鍘�", "鍐�宸炲競", "娣卞窞甯�"]]
+	]],
+	["灞辫タ鐪�", [
+		["澶師甯�", ["灏忓簵鍖�", "杩庢辰鍖�", "鏉忚姳宀尯", "灏栬崏鍧尯", "涓囨煆鏋楀尯", "鏅嬫簮鍖�", "娓呭緪鍘�", "闃虫洸鍘�", "濞勭儲鍘�", "鍙や氦甯�"]],
+		["澶у悓甯�", ["鍩庡尯", "鐭垮尯", "鍗楅儕鍖�", "鏂拌崳鍖�", "闃抽珮鍘�", "澶╅晣鍘�", "骞跨伒鍘�", "鐏典笜鍘�", "娴戞簮鍘�", "宸︿簯鍘�", "澶у悓鍘�"]],
+		["闃虫硥甯�", ["鍩庡尯", "鐭垮尯", "閮婂尯", "骞冲畾鍘�", "鐩傚幙"]],
+		["闀挎不甯�", ["鍩庡尯", "閮婂尯", "闀挎不鍘�", "瑗勫灒鍘�", "灞暀鍘�", "骞抽『鍘�", "榛庡煄鍘�", "澹跺叧鍘�", "闀垮瓙鍘�", "姝︿埂鍘�", "娌佸幙", "娌佹簮鍘�", "娼炲煄甯�"]],
+		["鏅嬪煄甯�", ["鍩庡尯", "娌佹按鍘�", "闃冲煄鍘�", "闄靛窛鍘�", "娉藉窞鍘�", "楂樺钩甯�"]],
+		["鏈斿窞甯�", ["鏈斿煄鍖�", "骞抽瞾鍖�", "灞遍槾鍘�", "搴斿幙", "鍙崇帀鍘�", "鎬�浠佸幙"]],
+		["鏅嬩腑甯�", ["姒嗘鍖�", "姒嗙ぞ鍘�", "宸︽潈鍘�", "鍜岄『鍘�", "鏄旈槼鍘�", "瀵块槼鍘�", "澶胺鍘�", "绁佸幙", "骞抽仴鍘�", "鐏电煶鍘�", "浠嬩紤甯�"]],
+		["杩愬煄甯�", ["鐩愭箹鍖�", "涓寸寳鍘�", "涓囪崳鍘�", "闂诲枩鍘�", "绋峰北鍘�", "鏂扮粵鍘�", "缁涘幙", "鍨f洸鍘�", "澶忓幙", "骞抽檰鍘�", "鑺煄鍘�", "姘告祹甯�", "娌虫触甯�"]],
+		["蹇诲窞甯�", ["蹇诲簻鍖�", "瀹氳鍘�", "浜斿彴鍘�", "浠e幙", "绻佸硻鍘�", "瀹佹鍘�", "闈欎箰鍘�", "绁炴睜鍘�", "浜斿鍘�", "宀㈠矚鍘�", "娌虫洸鍘�", "淇濆痉鍘�", "鍋忓叧鍘�", "鍘熷钩甯�"]],
+		["涓存本甯�", ["灏ч兘鍖�", "鏇叉矁鍘�", "缈煎煄鍘�", "瑗勬本鍘�", "娲礊鍘�", "鍙ゅ幙", "瀹夋辰鍘�", "娴北鍘�", "鍚夊幙", "涔″畞鍘�", "澶у畞鍘�", "闅板幙", "姘稿拰鍘�", "钂插幙", "姹捐タ鍘�", "渚┈甯�", "闇嶅窞甯�"]],
+		["鍚曟甯�", ["绂荤煶鍖�", "鏂囨按鍘�", "浜ゅ煄鍘�", "鍏村幙", "涓村幙", "鏌虫灄鍘�", "鐭虫ゼ鍘�", "宀氬幙", "鏂瑰北鍘�", "涓槼鍘�", "浜ゅ彛鍘�", "瀛濅箟甯�", "姹鹃槼甯�"]]
+	]],
+	["鍐呰挋鍙よ嚜娌诲尯", [
+		["鍛煎拰娴╃壒甯�", ["鏂板煄鍖�", "鍥炴皯鍖�", "鐜夋硥鍖�", "璧涚綍鍖�", "鍦熼粯鐗瑰乏鏃�", "鎵樺厠鎵樺幙", "鍜屾灄鏍煎皵鍘�", "娓呮按娌冲幙", "姝﹀窛鍘�"]],
+		["鍖呭ご甯�", ["涓滄渤鍖�", "鏄嗛兘浠戝尯", "闈掑北鍖�", "鐭虫嫄鍖�", "鐧戒簯閯傚崥鐭垮尯", "涔濆師鍖�", "鍦熼粯鐗瑰彸鏃�", "鍥洪槼鍘�", "杈惧皵缃曡寕鏄庡畨鑱斿悎鏃�"]],
+		["涔屾捣甯�", ["娴峰媰婀惧尯", "娴峰崡鍖�", "涔岃揪鍖�"]],
+		["璧ゅ嘲甯�", ["绾㈠北鍖�", "鍏冨疂灞卞尯", "鏉惧北鍖�", "闃块瞾绉戝皵娌佹棗", "宸存灄宸︽棗", "宸存灄鍙虫棗", "鏋楄タ鍘�", "鍏嬩粈鍏嬭吘鏃�", "缈佺墰鐗规棗", "鍠�鍠囨瞾鏃�", "瀹佸煄鍘�", "鏁栨眽鏃�"]],
+		["閫氳窘甯�", ["绉戝皵娌佸尯", "绉戝皵娌佸乏缈间腑鏃�", "绉戝皵娌佸乏缈煎悗鏃�", "寮�椴佸幙", "搴撲鸡鏃�", "濂堟浖鏃�", "鎵庨瞾鐗规棗", "闇嶆灄閮嫆甯�"]],
+		["閯傚皵澶氭柉甯�", ["涓滆儨鍖�", "杈炬媺鐗规棗", "鍑嗘牸灏旀棗", "閯傛墭鍏嬪墠鏃�", "閯傛墭鍏嬫棗", "鏉敠鏃�", "涔屽鏃�", "浼婇噾闇嶆礇鏃�"]],
+		["鍛间鸡璐濆皵甯�", ["娴锋媺灏斿尯", "鎵庤祲璇哄皵鍖�", "闃胯崳鏃�", "鑾姏杈剧摝杈炬枴灏旀棌鑷不鏃�", "閯備鸡鏄ヨ嚜娌绘棗", "閯傛俯鍏嬫棌鑷不鏃�", "闄堝反灏旇檸鏃�", "鏂板反灏旇檸宸︽棗", "鏂板反灏旇檸鍙虫棗", "婊℃床閲屽競", "鐗欏厠鐭冲競", "鎵庡叞灞競", "棰濆皵鍙ょ撼甯�", "鏍规渤甯�"]],
+		["宸村溅娣栧皵甯�", ["涓存渤鍖�", "浜斿師鍘�", "纾村彛鍘�", "涔屾媺鐗瑰墠鏃�", "涔屾媺鐗逛腑鏃�", "涔屾媺鐗瑰悗鏃�", "鏉敠鍚庢棗"]],
+		["涔屽叞瀵熷竷甯�", ["闆嗗畞鍖�", "鍗撹祫鍘�", "鍖栧痉鍘�", "鍟嗛兘鍘�", "鍏村拰鍘�", "鍑夊煄鍘�", "瀵熷搱灏斿彸缈煎墠鏃�", "瀵熷搱灏斿彸缈间腑鏃�", "瀵熷搱灏斿彸缈煎悗鏃�", "鍥涘瓙鐜嬫棗", "涓伴晣甯�"]],
+		["鍏村畨鐩�", ["涔屽叞娴╃壒甯�", "闃垮皵灞卞競", "绉戝皵娌佸彸缈煎墠鏃�", "绉戝皵娌佸彸缈间腑鏃�", "鎵庤祲鐗规棗", "绐佹硥鍘�"]],
+		["閿℃灄閮嫆鐩�", ["浜岃繛娴╃壒甯�", "閿℃灄娴╃壒甯�", "闃垮反鍢庢棗", "鑻忓凹鐗瑰乏鏃�", "鑻忓凹鐗瑰彸鏃�", "涓滀箤鐝犵﹩娌佹棗", "瑗夸箤鐝犵﹩娌佹棗", "澶粏瀵烘棗", "闀堕粍鏃�", "姝i暥鐧芥棗", "姝h摑鏃�", "澶氫鸡鍘�"]],
+		["闃挎媺鍠勭洘", ["闃挎媺鍠勫乏鏃�", "闃挎媺鍠勫彸鏃�", "棰濇祹绾虫棗"]]
+	]],
+	["杈藉畞鐪�", [
+		["娌堥槼甯�", ["鍜屽钩鍖�", "娌堟渤鍖�", "澶т笢鍖�", "鐨囧鍖�", "閾佽タ鍖�", "鑻忓灞尯", "涓滈櫟鍖�", "娌堝寳鏂板尯", "浜庢椽鍖�", "杈戒腑鍘�", "搴峰钩鍘�", "娉曞簱鍘�", "鏂版皯甯�"]],
+		["澶ц繛甯�", ["涓北鍖�", "瑗垮矖鍖�", "娌欐渤鍙e尯", "鐢樹簳瀛愬尯", "鏃呴『鍙e尯", "閲戝窞鍖�", "闀挎捣鍘�", "鐡︽埧搴楀競", "鏅叞搴楀競", "搴勬渤甯�"]],
+		["闉嶅北甯�", ["閾佷笢鍖�", "閾佽タ鍖�", "绔嬪北鍖�", "鍗冨北鍖�", "鍙板畨鍘�", "宀博婊℃棌鑷不鍘�", "娴峰煄甯�"]],
+		["鎶氶『甯�", ["鏂版姎鍖�", "涓滄床鍖�", "鏈涜姳鍖�", "椤哄煄鍖�", "鎶氶『鍘�", "鏂板婊℃棌鑷不鍘�", "娓呭師婊℃棌鑷不鍘�"]],
+		["鏈邯甯�", ["骞冲北鍖�", "婧箹鍖�", "鏄庡北鍖�", "鍗楄姮鍖�", "鏈邯婊℃棌鑷不鍘�", "妗撲粊婊℃棌鑷不鍘�"]],
+		["涓逛笢甯�", ["鍏冨疂鍖�", "鎸叴鍖�", "鎸畨鍖�", "瀹界敻婊℃棌鑷不鍘�", "涓滄腐甯�", "鍑ゅ煄甯�"]],
+		["閿﹀窞甯�", ["鍙ゅ鍖�", "鍑屾渤鍖�", "澶拰鍖�", "榛戝北鍘�", "涔夊幙", "鍑屾捣甯�", "鍖楅晣甯�"]],
+		["钀ュ彛甯�", ["绔欏墠鍖�", "瑗垮競鍖�", "椴呴奔鍦堝尯", "鑰佽竟鍖�", "鐩栧窞甯�", "澶х煶妗ュ競"]],
+		["闃滄柊甯�", ["娴峰窞鍖�", "鏂伴偙鍖�", "澶钩鍖�", "娓呮渤闂ㄥ尯", "缁嗘渤鍖�", "闃滄柊钂欏彜鏃忚嚜娌诲幙", "褰版鍘�"]],
+		["杈介槼甯�", ["鐧藉鍖�", "鏂囧湥鍖�", "瀹忎紵鍖�", "寮撻暱宀尯", "澶瓙娌冲尯", "杈介槼鍘�", "鐏甯�"]],
+		["鐩橀敠甯�", ["鍙屽彴瀛愬尯", "鍏撮殕鍙板尯", "澶ф醇鍘�", "鐩樺北鍘�"]],
+		["閾佸箔甯�", ["閾跺窞鍖�", "娓呮渤鍖�", "閾佸箔鍘�", "瑗夸赴鍘�", "鏄屽浘鍘�", "璋冨叺灞卞競", "寮�鍘熷競"]],
+		["鏈濋槼甯�", ["鍙屽鍖�", "榫欏煄鍖�", "鏈濋槼鍘�", "寤哄钩鍘�", "鍠�鍠囨瞾宸︾考钂欏彜鏃忚嚜娌诲幙", "鍖楃エ甯�", "鍑屾簮甯�"]],
+		["钁姦宀涘競", ["杩炲北鍖�", "榫欐腐鍖�", "鍗楃エ鍖�", "缁ヤ腑鍘�", "寤烘槍鍘�", "鍏村煄甯�"]]
+	]],
+	["鍚夋灄鐪�", [
+		["闀挎槬甯�", ["鍗楀叧鍖�", "瀹藉煄鍖�", "鏈濋槼鍖�", "浜岄亾鍖�", "缁垮洯鍖�", "鍙岄槼鍖�", "鍐滃畨鍘�", "涔濆彴甯�", "姒嗘爲甯�", "寰锋儬甯�"]],
+		["鍚夋灄甯�", ["鏄岄倯鍖�", "榫欐江鍖�", "鑸硅惀鍖�", "涓版弧鍖�", "姘稿悏鍘�", "铔熸渤甯�", "妗︾敻甯�", "鑸掑叞甯�", "纾愮煶甯�"]],
+		["鍥涘钩甯�", ["閾佽タ鍖�", "閾佷笢鍖�", "姊ㄦ爲鍘�", "浼婇�氭弧鏃忚嚜娌诲幙", "鍏富宀競", "鍙岃窘甯�"]],
+		["杈芥簮甯�", ["榫欏北鍖�", "瑗垮畨鍖�", "涓滀赴鍘�", "涓滆窘鍘�"]],
+		["閫氬寲甯�", ["涓滄槍鍖�", "浜岄亾姹熷尯", "閫氬寲鍘�", "杈夊崡鍘�", "鏌虫渤鍘�", "姊呮渤鍙e競", "闆嗗畨甯�"]],
+		["鐧藉北甯�", ["娴戞睙鍖�", "姹熸簮鍖�", "鎶氭澗鍘�", "闈栧畤鍘�", "闀跨櫧鏈濋矞鏃忚嚜娌诲幙", "涓存睙甯�"]],
+		["鏉惧師甯�", ["瀹佹睙鍖�", "鍓嶉儹灏旂綏鏂挋鍙ゆ棌鑷不鍘�", "闀垮箔鍘�", "涔惧畨鍘�", "鎵朵綑甯�"]],
+		["鐧藉煄甯�", ["娲寳鍖�", "闀囪祲鍘�", "閫氭鍘�", "娲崡甯�", "澶у畨甯�"]],
+		["寤惰竟鏈濋矞鏃忚嚜娌诲窞", ["寤跺悏甯�", "鍥句滑甯�", "鏁﹀寲甯�", "鐝叉槬甯�", "榫欎簳甯�", "鍜岄緳甯�", "姹竻鍘�", "瀹夊浘鍘�"]]
+	]],
+	["榛戦緳姹熺渷", [
+		["鍝堝皵婊ㄥ競", ["閬撻噷鍖�", "鍗楀矖鍖�", "閬撳鍖�", "骞虫埧鍖�", "鏉惧寳鍖�", "棣欏潑鍖�", "鍛煎叞鍖�", "闃垮煄鍖�", "渚濆叞鍘�", "鏂规鍘�", "瀹惧幙", "宸村溅鍘�", "鏈ㄥ叞鍘�", "閫氭渤鍘�", "寤跺鍘�", "鍙屽煄甯�", "灏氬織甯�", "浜斿父甯�"]],
+		["榻愰綈鍝堝皵甯�", ["榫欐矙鍖�", "寤哄崕鍖�", "閾侀攱鍖�", "鏄傛槀婧尯", "瀵屾媺灏斿熀鍖�", "纰惧瓙灞卞尯", "姊呴噷鏂揪鏂″皵鏃忓尯", "榫欐睙鍘�", "渚濆畨鍘�", "娉版潵鍘�", "鐢樺崡鍘�", "瀵岃鍘�", "鍏嬪北鍘�", "鍏嬩笢鍘�", "鎷滄硥鍘�", "璁锋渤甯�"]],
+		["楦¤タ甯�", ["楦″啝鍖�", "鎭掑北鍖�", "婊撮亾鍖�", "姊ㄦ爲鍖�", "鍩庡瓙娌冲尯", "楹诲北鍖�", "楦′笢鍘�", "铏庢灄甯�", "瀵嗗北甯�"]],
+		["楣ゅ矖甯�", ["鍚戦槼鍖�", "宸ュ啘鍖�", "鍗楀北鍖�", "鍏村畨鍖�", "涓滃北鍖�", "鍏村北鍖�", "钀濆寳鍘�", "缁ユ花鍘�"]],
+		["鍙岄腑灞卞競", ["灏栧北鍖�", "宀笢鍖�", "鍥涙柟鍙板尯", "瀹濆北鍖�", "闆嗚搐鍘�", "鍙嬭皧鍘�", "瀹濇竻鍘�", "楗舵渤鍘�"]],
+		["澶у簡甯�", ["钀ㄥ皵鍥惧尯", "榫欏嚖鍖�", "璁╄儭璺尯", "绾㈠矖鍖�", "澶у悓鍖�", "鑲囧窞鍘�", "鑲囨簮鍘�", "鏋楃敻鍘�", "鏉滃皵浼壒钂欏彜鏃忚嚜娌诲幙"]],
+		["浼婃槬甯�", ["浼婃槬鍖�", "鍗楀矓鍖�", "鍙嬪ソ鍖�", "瑗挎灄鍖�", "缈犲肠鍖�", "鏂伴潚鍖�", "缇庢邯鍖�", "閲戝北灞尯", "浜旇惀鍖�", "涔岄┈娌冲尯", "姹ゆ椇娌冲尯", "甯﹀箔鍖�", "涔屼紛宀尯", "绾㈡槦鍖�", "涓婄敇宀尯", "鍢夎崼鍘�", "閾佸姏甯�"]],
+		["浣虫湪鏂競", ["鍚戦槼鍖�", "鍓嶈繘鍖�", "涓滈鍖�", "閮婂尯", "妗﹀崡鍘�", "妗﹀窛鍘�", "姹ゅ師鍘�", "鎶氳繙鍘�", "鍚屾睙甯�", "瀵岄敠甯�"]],
+		["涓冨彴娌冲競", ["鏂板叴鍖�", "妗冨北鍖�", "鑼勫瓙娌冲尯", "鍕冨埄鍘�"]],
+		["鐗′腹姹熷競", ["涓滃畨鍖�", "闃虫槑鍖�", "鐖辨皯鍖�", "瑗垮畨鍖�", "涓滃畞鍘�", "鏋楀彛鍘�", "缁ヨ姮娌冲競", "娴锋灄甯�", "瀹佸畨甯�", "绌嗘1甯�"]],
+		["榛戞渤甯�", ["鐖辫緣鍖�", "瀚╂睙鍘�", "閫婂厠鍘�", "瀛欏惔鍘�", "鍖楀畨甯�", "浜斿ぇ杩炴睜甯�"]],
+		["缁ュ寲甯�", ["鍖楁灄鍖�", "鏈涘鍘�", "鍏拌タ鍘�", "闈掑唸鍘�", "搴嗗畨鍘�", "鏄庢按鍘�", "缁ユ1鍘�", "瀹夎揪甯�", "鑲囦笢甯�", "娴蜂鸡甯�"]],
+		["澶у叴瀹夊箔鍦板尯", ["鍛肩帥鍘�", "濉旀渤鍘�", "婕犳渤鍘�"]]
+	]],
+	["涓婃捣甯�", [
+		["涓婃捣甯�", ["榛勬郸鍖�", "寰愭眹鍖�", "闀垮畞鍖�", "闈欏畨鍖�", "鏅檧鍖�", "闂稿寳鍖�", "铏瑰彛鍖�", "鏉ㄦ郸鍖�", "闂佃鍖�", "瀹濆北鍖�", "鍢夊畾鍖�", "娴︿笢鏂板尯", "閲戝北鍖�", "鏉炬睙鍖�", "闈掓郸鍖�", "濂夎搐鍖�", "宕囨槑鍖�"]]
+	]],
+	["姹熻嫃鐪�", [
+		["鍗椾含甯�", ["鐜勬鍖�", "绉︽樊鍖�", "寤洪偤鍖�", "榧撴ゼ鍖�", "娴﹀彛鍖�", "鏍栭湠鍖�", "闆ㄨ姳鍙板尯", "姹熷畞鍖�", "鍏悎鍖�", "婧ф按鍖�", "楂樻烦鍖�"]],
+		["鏃犻敗甯�", ["宕囧畨鍖�", "鍗楅暱鍖�", "鍖楀鍖�", "閿″北鍖�", "鎯犲北鍖�", "婊ㄦ箹鍖�", "姹熼槾甯�", "瀹滃叴甯�"]],
+		["寰愬窞甯�", ["榧撴ゼ鍖�", "浜戦緳鍖�", "璐炬豹鍖�", "娉夊北鍖�", "閾滃北鍖�", "涓板幙", "娌涘幙", "鐫㈠畞鍘�", "鏂版矀甯�", "閭冲窞甯�"]],
+		["甯稿窞甯�", ["澶╁畞鍖�", "閽熸ゼ鍖�", "鎴氬鍫板尯", "鏂板寳鍖�", "姝﹁繘鍖�", "婧ч槼甯�", "閲戝潧甯�"]],
+		["鑻忓窞甯�", ["铏庝笜鍖�", "鍚翠腑鍖�", "鐩稿煄鍖�", "濮戣嫃鍖�", "鍚存睙鍖�", "甯哥啛甯�", "寮犲娓競", "鏄嗗北甯�", "澶粨甯�"]],
+		["鍗楅�氬競", ["宕囧窛鍖�", "娓椄鍖�", "閫氬窞鍖�", "娴峰畨鍘�", "濡備笢鍘�", "鍚笢甯�", "濡傜殝甯�", "娴烽棬甯�"]],
+		["杩炰簯娓競", ["杩炰簯鍖�", "鏂版郸鍖�", "娴峰窞鍖�", "璧f鍘�", "涓滄捣鍘�", "鐏屼簯鍘�", "鐏屽崡鍘�"]],
+		["娣畨甯�", ["娓呮渤鍖�", "娣畨鍖�", "娣槾鍖�", "娓呮郸鍖�", "娑熸按鍘�", "娲辰鍘�", "鐩辩湙鍘�", "閲戞箹鍘�"]],
+		["鐩愬煄甯�", ["浜箹鍖�", "鐩愰兘鍖�", "鍝嶆按鍘�", "婊ㄦ捣鍘�", "闃滃畞鍘�", "灏勯槼鍘�", "寤烘箹鍘�", "涓滃彴甯�", "澶т赴甯�"]],
+		["鎵窞甯�", ["骞块櫟鍖�", "閭楁睙鍖�", "姹熼兘鍖�", "瀹濆簲鍘�", "浠緛甯�", "楂橀偖甯�"]],
+		["闀囨睙甯�", ["浜彛鍖�", "娑﹀窞鍖�", "涓瑰緬鍖�", "涓归槼甯�", "鎵腑甯�", "鍙ュ甯�"]],
+		["娉板窞甯�", ["娴烽櫟鍖�", "楂樻腐鍖�", "濮滃牥鍖�", "鍏村寲甯�", "闈栨睙甯�", "娉板叴甯�"]],
+		["瀹胯縼甯�", ["瀹垮煄鍖�", "瀹胯鲍鍖�", "娌槼鍘�", "娉楅槼鍘�", "娉楁椽鍘�"]]
+	]],
+	["娴欐睙鐪�", [
+		["鏉窞甯�", ["涓婂煄鍖�", "涓嬪煄鍖�", "姹熷共鍖�", "鎷卞鍖�", "瑗挎箹鍖�", "婊ㄦ睙鍖�", "钀у北鍖�", "浣欐澀鍖�", "妗愬簮鍘�", "娣冲畨鍘�", "寤哄痉甯�", "瀵岄槼甯�", "涓村畨甯�"]],
+		["瀹佹尝甯�", ["娴锋洐鍖�", "姹熶笢鍖�", "姹熷寳鍖�", "鍖椾粦鍖�", "闀囨捣鍖�", "閯炲窞鍖�", "璞″北鍘�", "瀹佹捣鍘�", "浣欏甯�", "鎱堟邯甯�", "濂夊寲甯�"]],
+		["娓╁窞甯�", ["楣垮煄鍖�", "榫欐咕鍖�", "鐡捣鍖�", "娲炲ご鍘�", "姘稿槈鍘�", "骞抽槼鍘�", "鑻嶅崡鍘�", "鏂囨垚鍘�", "娉伴『鍘�", "鐟炲畨甯�", "涔愭竻甯�"]],
+		["鍢夊叴甯�", ["鍗楁箹鍖�", "绉�娲插尯", "鍢夊杽鍘�", "娴风洂鍘�", "娴峰畞甯�", "骞虫箹甯�", "妗愪埂甯�"]],
+		["婀栧窞甯�", ["鍚村叴鍖�", "鍗楁禂鍖�", "寰锋竻鍘�", "闀垮叴鍘�", "瀹夊悏鍘�"]],
+		["缁嶅叴甯�", ["瓒婂煄鍖�", "缁嶅叴鍘�", "鏂版槍鍘�", "璇告毃甯�", "涓婅櫈甯�", "宓婂窞甯�"]],
+		["閲戝崕甯�", ["濠哄煄鍖�", "閲戜笢鍖�", "姝︿箟鍘�", "娴︽睙鍘�", "纾愬畨鍘�", "鍏版邯甯�", "涔変箤甯�", "涓滈槼甯�", "姘稿悍甯�"]],
+		["琛㈠窞甯�", ["鏌煄鍖�", "琛㈡睙鍖�", "甯稿北鍘�", "寮�鍖栧幙", "榫欐父鍘�", "姹熷北甯�"]],
+		["鑸熷北甯�", ["瀹氭捣鍖�", "鏅檧鍖�", "宀卞北鍘�", "宓婃硹鍘�"]],
+		["鍙板窞甯�", ["妞掓睙鍖�", "榛勫博鍖�", "璺ˉ鍖�", "鐜夌幆鍘�", "涓夐棬鍘�", "澶╁彴鍘�", "浠欏眳鍘�", "娓╁箔甯�", "涓存捣甯�"]],
+		["涓芥按甯�", ["鑾查兘鍖�", "闈掔敯鍘�", "缂欎簯鍘�", "閬傛槍鍘�", "鏉鹃槼鍘�", "浜戝拰鍘�", "搴嗗厓鍘�", "鏅畞鐣叉棌鑷不鍘�", "榫欐硥甯�"]]
+	]],
+	["瀹夊窘鐪�", [
+		["鍚堣偉甯�", ["鐟舵捣鍖�", "搴愰槼鍖�", "铚�灞卞尯", "鍖呮渤鍖�", "闀夸赴鍘�", "鑲ヤ笢鍘�", "鑲ヨタ鍘�", "搴愭睙鍘�", "宸㈡箹甯�"]],
+		["鑺滄箹甯�", ["闀滄箹鍖�", "寮嬫睙鍖�", "楦犳睙鍖�", "涓夊北鍖�", "鑺滄箹鍘�", "绻佹槍鍘�", "鍗楅櫟鍘�", "鏃犱负鍘�"]],
+		["铓屽煚甯�", ["榫欏瓙婀栧尯", "铓屽北鍖�", "绂逛細鍖�", "娣笂鍖�", "鎬�杩滃幙", "浜旀渤鍘�", "鍥洪晣鍘�"]],
+		["娣崡甯�", ["澶ч�氬尯", "鐢板搴靛尯", "璋㈠闆嗗尯", "鍏叕灞卞尯", "娼橀泦鍖�", "鍑ゅ彴鍘�"]],
+		["椹瀺灞卞競", ["鑺卞北鍖�", "闆ㄥ北鍖�", "鍗氭湜鍖�", "褰撴秱鍘�", "鍚北鍘�", "鍜屽幙"]],
+		["娣寳甯�", ["鏉滈泦鍖�", "鐩稿北鍖�", "鐑堝北鍖�", "婵夋邯鍘�"]],
+		["閾滈櫟甯�", ["閾滃畼灞卞尯", "鐙瓙灞卞尯", "閮婂尯", "閾滈櫟鍘�"]],
+		["瀹夊簡甯�", ["杩庢睙鍖�", "澶ц鍖�", "瀹滅鍖�", "鎬�瀹佸幙", "鏋為槼鍘�", "娼滃北鍘�", "澶箹鍘�", "瀹挎澗鍘�", "鏈涙睙鍘�", "宀宠タ鍘�", "妗愬煄甯�"]],
+		["榛勫北甯�", ["灞邯鍖�", "榛勫北鍖�", "寰藉窞鍖�", "姝欏幙", "浼戝畞鍘�", "榛熷幙", "绁侀棬鍘�"]],
+		["婊佸窞甯�", ["鐞呯悐鍖�", "鍗楄隘鍖�", "鏉ュ畨鍘�", "鍏ㄦ鍘�", "瀹氳繙鍘�", "鍑ら槼鍘�", "澶╅暱甯�", "鏄庡厜甯�"]],
+		["闃滈槼甯�", ["棰嶅窞鍖�", "棰嶄笢鍖�", "棰嶆硥鍖�", "涓存硥鍘�", "澶拰鍘�", "闃滃崡鍘�", "棰嶄笂鍘�", "鐣岄甯�"]],
+		["瀹垮窞甯�", ["鍩囨ˉ鍖�", "鐮�灞卞幙", "钀у幙", "鐏电挧鍘�", "娉楀幙"]],
+		["鍏畨甯�", ["閲戝畨鍖�", "瑁曞畨鍖�", "瀵垮幙", "闇嶉偙鍘�", "鑸掑煄鍘�", "閲戝鍘�", "闇嶅北鍘�"]],
+		["浜冲窞甯�", ["璋煄鍖�", "娑¢槼鍘�", "钂欏煄鍘�", "鍒╄緵鍘�"]],
+		["姹犲窞甯�", ["璐垫睜鍖�", "涓滆嚦鍘�", "鐭冲彴鍘�", "闈掗槼鍘�"]],
+		["瀹e煄甯�", ["瀹e窞鍖�", "閮庢邯鍘�", "骞垮痉鍘�", "娉惧幙", "缁╂邯鍘�", "鏃屽痉鍘�", "瀹佸浗甯�"]]
+	]],
+	["绂忓缓鐪�", [
+		["绂忓窞甯�", ["榧撴ゼ鍖�", "鍙版睙鍖�", "浠撳北鍖�", "椹熬鍖�", "鏅嬪畨鍖�", "闂戒警鍘�", "杩炴睙鍘�", "缃楁簮鍘�", "闂芥竻鍘�", "姘告嘲鍘�", "骞虫江鍘�", "绂忔竻甯�", "闀夸箰甯�"]],
+		["鍘﹂棬甯�", ["鎬濇槑鍖�", "娴锋钵鍖�", "婀栭噷鍖�", "闆嗙編鍖�", "鍚屽畨鍖�", "缈斿畨鍖�"]],
+		["鑾嗙敯甯�", ["鍩庡帰鍖�", "娑垫睙鍖�", "鑽斿煄鍖�", "绉�灞垮尯", "浠欐父鍘�"]],
+		["涓夋槑甯�", ["姊呭垪鍖�", "涓夊厓鍖�", "鏄庢邯鍘�", "娓呮祦鍘�", "瀹佸寲鍘�", "澶х敯鍘�", "灏ゆ邯鍘�", "娌欏幙", "灏嗕箰鍘�", "娉板畞鍘�", "寤哄畞鍘�", "姘稿畨甯�"]],
+		["娉夊窞甯�", ["椴ゅ煄鍖�", "涓版辰鍖�", "娲涙睙鍖�", "娉夋腐鍖�", "鎯犲畨鍘�", "瀹夋邯鍘�", "姘告槬鍘�", "寰峰寲鍘�", "閲戦棬鍘�", "鐭崇嫯甯�", "鏅嬫睙甯�", "鍗楀畨甯�"]],
+		["婕冲窞甯�", ["鑺楀煄鍖�", "榫欐枃鍖�", "浜戦渼鍘�", "婕虫郸鍘�", "璇忓畨鍘�", "闀挎嘲鍘�", "涓滃北鍘�", "鍗楅潠鍘�", "骞冲拰鍘�", "鍗庡畨鍘�", "榫欐捣甯�"]],
+		["鍗楀钩甯�", ["寤跺钩鍖�", "椤烘槍鍘�", "娴﹀煄鍘�", "鍏夋辰鍘�", "鏉炬邯鍘�", "鏀垮拰鍘�", "閭垫甯�", "姝﹀し灞卞競", "寤虹摨甯�", "寤洪槼甯�"]],
+		["榫欏博甯�", ["鏂扮綏鍖�", "闀挎眬鍘�", "姘稿畾鍘�", "涓婃澀鍘�", "姝﹀钩鍘�", "杩炲煄鍘�", "婕冲钩甯�"]],
+		["瀹佸痉甯�", ["钑夊煄鍖�", "闇炴郸鍘�", "鍙ょ敯鍘�", "灞忓崡鍘�", "瀵垮畞鍘�", "鍛ㄥ畞鍘�", "鏌樿崳鍘�", "绂忓畨甯�", "绂忛紟甯�"]]
+	]],
+	["姹熻タ鐪�", [
+		["鍗楁槍甯�", ["涓滄箹鍖�", "瑗挎箹鍖�", "闈掍簯璋卞尯", "婀鹃噷鍖�", "闈掑北婀栧尯", "鍗楁槍鍘�", "鏂板缓鍘�", "瀹変箟鍘�", "杩涜搐鍘�"]],
+		["鏅痉闀囧競", ["鏄屾睙鍖�", "鐝犲北鍖�", "娴鍘�", "涔愬钩甯�"]],
+		["钀嶄埂甯�", ["瀹夋簮鍖�", "婀樹笢鍖�", "鑾茶姳鍘�", "涓婃牀鍘�", "鑺︽邯鍘�"]],
+		["涔濇睙甯�", ["搴愬北鍖�", "娴旈槼鍖�", "涔濇睙鍘�", "姝﹀畞鍘�", "淇按鍘�", "姘镐慨鍘�", "寰峰畨鍘�", "鏄熷瓙鍘�", "閮芥槍鍘�", "婀栧彛鍘�", "褰辰鍘�", "鐟炴槍甯�", "鍏遍潚鍩庡競"]],
+		["鏂颁綑甯�", ["娓濇按鍖�", "鍒嗗疁鍘�"]],
+		["楣版江甯�", ["鏈堟箹鍖�", "浣欐睙鍘�", "璐垫邯甯�"]],
+		["璧e窞甯�", ["绔犺础鍖�", "璧e幙", "淇′赴鍘�", "澶т綑鍘�", "涓婄姽鍘�", "宕囦箟鍘�", "瀹夎繙鍘�", "榫欏崡鍘�", "瀹氬崡鍘�", "鍏ㄥ崡鍘�", "瀹侀兘鍘�", "浜庨兘鍘�", "鍏村浗鍘�", "浼氭槍鍘�", "瀵讳箤鍘�", "鐭冲煄鍘�", "鐟為噾甯�", "鍗楀悍甯�"]],
+		["鍚夊畨甯�", ["鍚夊窞鍖�", "闈掑師鍖�", "鍚夊畨鍘�", "鍚夋按鍘�", "宄℃睙鍘�", "鏂板共鍘�", "姘镐赴鍘�", "娉板拰鍘�", "閬傚窛鍘�", "涓囧畨鍘�", "瀹夌鍘�", "姘告柊鍘�", "浜曞唸灞卞競"]],
+		["瀹滄槬甯�", ["琚佸窞鍖�", "濂夋柊鍘�", "涓囪浇鍘�", "涓婇珮鍘�", "瀹滀赴鍘�", "闈栧畨鍘�", "閾滈紦鍘�", "涓板煄甯�", "妯熸爲甯�", "楂樺畨甯�"]],
+		["鎶氬窞甯�", ["涓村窛鍖�", "鍗楀煄鍘�", "榛庡窛鍘�", "鍗椾赴鍘�", "宕囦粊鍘�", "涔愬畨鍘�", "瀹滈粍鍘�", "閲戞邯鍘�", "璧勬邯鍘�", "涓滀埂鍘�", "骞挎槍鍘�"]],
+		["涓婇ザ甯�", ["淇″窞鍖�", "涓婇ザ鍘�", "骞夸赴鍘�", "鐜夊北鍘�", "閾呭北鍘�", "妯嘲鍘�", "寮嬮槼鍘�", "浣欏共鍘�", "閯遍槼鍘�", "涓囧勾鍘�", "濠烘簮鍘�", "寰峰叴甯�"]]
+	]],
+	["灞变笢鐪�", [
+		["娴庡崡甯�", ["鍘嗕笅鍖�", "甯備腑鍖�", "妲愯崼鍖�", "澶╂ˉ鍖�", "鍘嗗煄鍖�", "闀挎竻鍖�", "骞抽槾鍘�", "娴庨槼鍘�", "鍟嗘渤鍘�", "绔犱笜甯�"]],
+		["闈掑矝甯�", ["甯傚崡鍖�", "甯傚寳鍖�", "榛勫矝鍖�", "宕傚北鍖�", "鏉庢钵鍖�", "鍩庨槼鍖�", "鑳跺窞甯�", "鍗冲ⅷ甯�", "骞冲害甯�", "鑾辫タ甯�"]],
+		["娣勫崥甯�", ["娣勫窛鍖�", "寮犲簵鍖�", "鍗氬北鍖�", "涓存穭鍖�", "鍛ㄦ潙鍖�", "妗撳彴鍘�", "楂橀潚鍘�", "娌傛簮鍘�"]],
+		["鏋e簞甯�", ["甯備腑鍖�", "钖涘煄鍖�", "宄勫煄鍖�", "鍙板効搴勫尯", "灞变涵鍖�", "婊曞窞甯�"]],
+		["涓滆惀甯�", ["涓滆惀鍖�", "娌冲彛鍖�", "鍨﹀埄鍘�", "鍒╂触鍘�", "骞块ザ鍘�"]],
+		["鐑熷彴甯�", ["鑺濈綐鍖�", "绂忓北鍖�", "鐗熷钩鍖�", "鑾卞北鍖�", "闀垮矝鍘�", "榫欏彛甯�", "鑾遍槼甯�", "鑾卞窞甯�", "钃幈甯�", "鎷涜繙甯�", "鏍栭湠甯�", "娴烽槼甯�"]],
+		["娼嶅潑甯�", ["娼嶅煄鍖�", "瀵掍涵鍖�", "鍧婂瓙鍖�", "濂庢枃鍖�", "涓存湊鍘�", "鏄屼箰鍘�", "闈掑窞甯�", "璇稿煄甯�", "瀵垮厜甯�", "瀹変笜甯�", "楂樺瘑甯�", "鏄岄倯甯�"]],
+		["娴庡畞甯�", ["甯備腑鍖�", "浠诲煄鍖�", "寰北鍘�", "楸煎彴鍘�", "閲戜埂鍘�", "鍢夌ゥ鍘�", "姹朵笂鍘�", "娉楁按鍘�", "姊佸北鍘�", "鏇查槣甯�", "鍏栧窞甯�", "閭瑰煄甯�"]],
+		["娉板畨甯�", ["娉板北鍖�", "宀卞渤鍖�", "瀹侀槼鍘�", "涓滃钩鍘�", "鏂版嘲甯�", "鑲ュ煄甯�"]],
+		["濞佹捣甯�", ["鐜繝鍖�", "鏂囩櫥甯�", "鑽f垚甯�", "涔冲北甯�"]],
+		["鏃ョ収甯�", ["涓滄腐鍖�", "宀氬北鍖�", "浜旇幉鍘�", "鑾掑幙"]],
+		["鑾辫姕甯�", ["鑾卞煄鍖�", "閽㈠煄鍖�"]],
+		["涓存矀甯�", ["鍏板北鍖�", "缃楀簞鍖�", "娌充笢鍖�", "娌傚崡鍘�", "閮煄鍘�", "娌傛按鍘�", "鑻嶅北鍘�", "璐瑰幙", "骞抽倯鍘�", "鑾掑崡鍘�", "钂欓槾鍘�", "涓存箔鍘�"]],
+		["寰峰窞甯�", ["寰峰煄鍖�", "闄靛幙", "瀹佹触鍘�", "搴嗕簯鍘�", "涓撮倯鍘�", "榻愭渤鍘�", "骞冲師鍘�", "澶忔触鍘�", "姝﹀煄鍘�", "涔愰櫟甯�", "绂瑰煄甯�"]],
+		["鑱婂煄甯�", ["涓滄槍搴滃尯", "闃宠胺鍘�", "鑾樺幙", "鑼屽钩鍘�", "涓滈樋鍘�", "鍐犲幙", "楂樺攼鍘�", "涓存竻甯�"]],
+		["婊ㄥ窞甯�", ["婊ㄥ煄鍖�", "鎯犳皯鍘�", "闃充俊鍘�", "鏃犳#鍘�", "娌惧寲鍘�", "鍗氬叴鍘�", "閭瑰钩鍘�"]],
+		["鑿忔辰甯�", ["鐗′腹鍖�", "鏇瑰幙", "鍗曞幙", "鎴愭鍘�", "宸ㄩ噹鍘�", "閮撳煄鍘�", "閯勫煄鍘�", "瀹氶櫠鍘�", "涓滄槑鍘�"]]
+	]],
+	["娌冲崡鐪�", [
+		["閮戝窞甯�", ["涓師鍖�", "浜屼竷鍖�", "绠″煄鍥炴棌鍖�", "閲戞按鍖�", "涓婅鍖�", "鎯犳祹鍖�", "涓墴鍘�", "宸╀箟甯�", "鑽ラ槼甯�", "鏂板瘑甯�", "鏂伴儜甯�", "鐧诲皝甯�"]],
+		["寮�灏佸競", ["榫欎涵鍖�", "椤烘渤鍥炴棌鍖�", "榧撴ゼ鍖�", "绂圭帇鍙板尯", "閲戞槑鍖�", "鏉炲幙", "閫氳鍘�", "灏夋皬鍘�", "寮�灏佸幙", "鍏拌�冨幙"]],
+		["娲涢槼甯�", ["鑰佸煄鍖�", "瑗垮伐鍖�", "鐎嶆渤鍥炴棌鍖�", "娑цタ鍖�", "鍚夊埄鍖�", "娲涢緳鍖�", "瀛熸触鍘�", "鏂板畨鍘�", "鏍惧窛鍘�", "宓╁幙", "姹濋槼鍘�", "瀹滈槼鍘�", "娲涘畞鍘�", "浼婂窛鍘�", "鍋冨笀甯�"]],
+		["骞抽《灞卞競", ["鏂板崕鍖�", "鍗笢鍖�", "鐭抽緳鍖�", "婀涙渤鍖�", "瀹濅赴鍘�", "鍙跺幙", "椴佸北鍘�", "閮忓幙", "鑸為挗甯�", "姹濆窞甯�"]],
+		["瀹夐槼甯�", ["鏂囧嘲鍖�", "鍖楀叧鍖�", "娈烽兘鍖�", "榫欏畨鍖�", "瀹夐槼鍘�", "姹ら槾鍘�", "婊戝幙", "鍐呴粍鍘�", "鏋楀窞甯�"]],
+		["楣ゅ甯�", ["楣ゅ北鍖�", "灞卞煄鍖�", "娣囨花鍖�", "娴氬幙", "娣囧幙"]],
+		["鏂颁埂甯�", ["绾㈡棗鍖�", "鍗花鍖�", "鍑ゆ硥鍖�", "鐗ч噹鍖�", "鏂颁埂鍘�", "鑾峰槈鍘�", "鍘熼槼鍘�", "寤舵触鍘�", "灏佷笜鍘�", "闀垮灒鍘�", "鍗緣甯�", "杈夊幙甯�"]],
+		["鐒︿綔甯�", ["瑙f斁鍖�", "涓珯鍖�", "椹潙鍖�", "灞遍槼鍖�", "淇鍘�", "鍗氱埍鍘�", "姝﹂櫉鍘�", "娓╁幙", "娌侀槼甯�", "瀛熷窞甯�"]],
+		["婵槼甯�", ["鍗庨緳鍖�", "娓呬赴鍘�", "鍗椾箰鍘�", "鑼冨幙", "鍙板墠鍘�", "婵槼鍘�"]],
+		["璁告槍甯�", ["榄忛兘鍖�", "璁告槍鍘�", "閯㈤櫟鍘�", "瑗勫煄鍘�", "绂瑰窞甯�", "闀胯憶甯�"]],
+		["婕渤甯�", ["婧愭眹鍖�", "閮惧煄鍖�", "鍙櫟鍖�", "鑸為槼鍘�", "涓撮鍘�"]],
+		["涓夐棬宄″競", ["婀栨花鍖�", "娓戞睜鍘�", "闄曞幙", "鍗㈡皬鍘�", "涔夐┈甯�", "鐏靛疂甯�"]],
+		["鍗楅槼甯�", ["瀹涘煄鍖�", "鍗ч緳鍖�", "鍗楀彫鍘�", "鏂瑰煄鍘�", "瑗垮场鍘�", "闀囧钩鍘�", "鍐呬埂鍘�", "娣呭窛鍘�", "绀炬棗鍘�", "鍞愭渤鍘�", "鏂伴噹鍘�", "妗愭煆鍘�", "閭撳窞甯�"]],
+		["鍟嗕笜甯�", ["姊佸洯鍖�", "鐫㈤槼鍖�", "姘戞潈鍘�", "鐫㈠幙", "瀹侀櫟鍘�", "鏌樺煄鍘�", "铏炲煄鍘�", "澶忛倯鍘�", "姘稿煄甯�"]],
+		["淇¢槼甯�", ["娴夋渤鍖�", "骞虫ˉ鍖�", "缃楀北鍘�", "鍏夊北鍘�", "鏂板幙", "鍟嗗煄鍘�", "鍥哄鍘�", "娼㈠窛鍘�", "娣花鍘�", "鎭幙"]],
+		["鍛ㄥ彛甯�", ["宸濇眹鍖�", "鎵舵矡鍘�", "瑗垮崕鍘�", "鍟嗘按鍘�", "娌堜笜鍘�", "閮稿煄鍘�", "娣槼鍘�", "澶悍鍘�", "楣块倯鍘�", "椤瑰煄甯�"]],
+		["椹婚┈搴楀競", ["椹垮煄鍖�", "瑗垮钩鍘�", "涓婅敗鍘�", "骞宠垎鍘�", "姝i槼鍘�", "纭北鍘�", "娉岄槼鍘�", "姹濆崡鍘�", "閬傚钩鍘�", "鏂拌敗鍘�"]],
+		["鐪佺洿杈栧幙绾ц鏀垮尯鍒�", ["娴庢簮甯�"]]
+	]],
+	["婀栧寳鐪�", [
+		["姝︽眽甯�", ["姹熷哺鍖�", "姹熸眽鍖�", "纭氬彛鍖�", "姹夐槼鍖�", "姝︽槍鍖�", "闈掑北鍖�", "娲北鍖�", "涓滆タ婀栧尯", "姹夊崡鍖�", "钄$敻鍖�", "姹熷鍖�", "榛勯檪鍖�", "鏂版床鍖�"]],
+		["榛勭煶甯�", ["榛勭煶娓尯", "瑗垮灞卞尯", "涓嬮檰鍖�", "閾佸北鍖�", "闃虫柊鍘�", "澶у喍甯�"]],
+		["鍗佸牥甯�", ["鑼呯鍖�", "寮犳咕鍖�", "閮у幙", "閮цタ鍘�", "绔瑰北鍘�", "绔规邯鍘�", "鎴垮幙", "涓规睙鍙e競"]],
+		["瀹滄槍甯�", ["瑗块櫟鍖�", "浼嶅宀楀尯", "鐐瑰啗鍖�", "鐚囦涵鍖�", "澶烽櫟鍖�", "杩滃畨鍘�", "鍏村北鍘�", "绉綊鍘�", "闀块槼鍦熷鏃忚嚜娌诲幙", "浜斿嘲鍦熷鏃忚嚜娌诲幙", "瀹滈兘甯�", "褰撻槼甯�", "鏋濇睙甯�"]],
+		["瑗勯槼甯�", ["瑗勫煄鍖�", "妯婂煄鍖�", "瑗勫窞鍖�", "鍗楁汲鍘�", "璋峰煄鍘�", "淇濆悍鍘�", "鑰佹渤鍙e競", "鏋i槼甯�", "瀹滃煄甯�"]],
+		["閯傚窞甯�", ["姊佸瓙婀栧尯", "鍗庡鍖�", "閯傚煄鍖�"]],
+		["鑽嗛棬甯�", ["涓滃疂鍖�", "鎺囧垁鍖�", "浜北鍘�", "娌欐磱鍘�", "閽熺ゥ甯�"]],
+		["瀛濇劅甯�", ["瀛濆崡鍖�", "瀛濇槍鍘�", "澶ф偀鍘�", "浜戞ⅵ鍘�", "搴斿煄甯�", "瀹夐檰甯�", "姹夊窛甯�"]],
+		["鑽嗗窞甯�", ["娌欏競鍖�", "鑽嗗窞鍖�", "鍏畨鍘�", "鐩戝埄鍘�", "姹熼櫟鍘�", "鐭抽甯�", "娲箹甯�", "鏉炬粙甯�"]],
+		["榛勫唸甯�", ["榛勫窞鍖�", "鍥㈤鍘�", "绾㈠畨鍘�", "缃楃敯鍘�", "鑻卞北鍘�", "娴犳按鍘�", "钑叉槬鍘�", "榛勬鍘�", "楹诲煄甯�", "姝︾┐甯�"]],
+		["鍜稿畞甯�", ["鍜稿畨鍖�", "鍢夐奔鍘�", "閫氬煄鍘�", "宕囬槼鍘�", "閫氬北鍘�", "璧ゅ甯�"]],
+		["闅忓窞甯�", ["鏇鹃兘鍖�", "闅忓幙", "骞挎按甯�"]],
+		["鎭╂柦鍦熷鏃忚嫍鏃忚嚜娌诲窞", ["鎭╂柦甯�", "鍒╁窛甯�", "寤哄鍘�", "宸翠笢鍘�", "瀹f仼鍘�", "鍜镐赴鍘�", "鏉ュ嚖鍘�", "楣ゅ嘲鍘�"]],
+		["鐪佺洿杈栧幙绾ц鏀垮尯鍒�", ["浠欐甯�", "娼滄睙甯�", "澶╅棬甯�", "绁炲啘鏋舵灄鍖�"]]
+	]],
+	["婀栧崡鐪�", [
+		["闀挎矙甯�", ["鑺欒搲鍖�", "澶╁績鍖�", "宀抽簱鍖�", "寮�绂忓尯", "闆ㄨ姳鍖�", "鏈涘煄鍖�", "闀挎矙鍘�", "瀹佷埂鍘�", "娴忛槼甯�"]],
+		["鏍床甯�", ["鑽峰鍖�", "鑺︽窞鍖�", "鐭冲嘲鍖�", "澶╁厓鍖�", "鏍床鍘�", "鏀稿幙", "鑼堕櫟鍘�", "鐐庨櫟鍘�", "閱撮櫟甯�"]],
+		["婀樻江甯�", ["闆ㄦ箹鍖�", "宀冲鍖�", "婀樻江鍘�", "婀樹埂甯�", "闊跺北甯�"]],
+		["琛¢槼甯�", ["鐝犳櫀鍖�", "闆佸嘲鍖�", "鐭抽紦鍖�", "钂告箻鍖�", "鍗楀渤鍖�", "琛¢槼鍘�", "琛″崡鍘�", "琛″北鍘�", "琛′笢鍘�", "绁佷笢鍘�", "鑰掗槼甯�", "甯稿畞甯�"]],
+		["閭甸槼甯�", ["鍙屾竻鍖�", "澶хゥ鍖�", "鍖楀鍖�", "閭典笢鍘�", "鏂伴偟鍘�", "閭甸槼鍘�", "闅嗗洖鍘�", "娲炲彛鍘�", "缁ュ畞鍘�", "鏂板畞鍘�", "鍩庢鑻楁棌鑷不鍘�", "姝﹀唸甯�"]],
+		["宀抽槼甯�", ["宀抽槼妤煎尯", "浜戞邯鍖�", "鍚涘北鍖�", "宀抽槼鍘�", "鍗庡鍘�", "婀橀槾鍘�", "骞虫睙鍘�", "姹ㄧ綏甯�", "涓存箻甯�"]],
+		["甯稿痉甯�", ["姝﹂櫟鍖�", "榧庡煄鍖�", "瀹変埂鍘�", "姹夊鍘�", "婢у幙", "涓存晶鍘�", "妗冩簮鍘�", "鐭抽棬鍘�", "娲ュ競甯�"]],
+		["寮犲鐣屽競", ["姘稿畾鍖�", "姝﹂櫟婧愬尯", "鎱堝埄鍘�", "妗戞鍘�"]],
+		["鐩婇槼甯�", ["璧勯槼鍖�", "璧北鍖�", "鍗楀幙", "妗冩睙鍘�", "瀹夊寲鍘�", "娌呮睙甯�"]],
+		["閮村窞甯�", ["鍖楁箹鍖�", "鑻忎粰鍖�", "妗傞槼鍘�", "瀹滅珷鍘�", "姘稿叴鍘�", "鍢夌鍘�", "涓存鍘�", "姹濆煄鍘�", "妗備笢鍘�", "瀹変粊鍘�", "璧勫叴甯�"]],
+		["姘稿窞甯�", ["闆堕櫟鍖�", "鍐锋按婊╁尯", "绁侀槼鍘�", "涓滃畨鍘�", "鍙岀墝鍘�", "閬撳幙", "姹熸案鍘�", "瀹佽繙鍘�", "钃濆北鍘�", "鏂扮敯鍘�", "姹熷崕鐟舵棌鑷不鍘�"]],
+		["鎬�鍖栧競", ["楣ゅ煄鍖�", "涓柟鍘�", "娌呴櫟鍘�", "杈版邯鍘�", "婧嗘郸鍘�", "浼氬悓鍘�", "楹婚槼鑻楁棌鑷不鍘�", "鏂版檭渚楁棌鑷不鍘�", "鑺锋睙渚楁棌鑷不鍘�", "闈栧窞鑻楁棌渚楁棌鑷不鍘�", "閫氶亾渚楁棌鑷不鍘�", "娲睙甯�"]],
+		["濞勫簳甯�", ["濞勬槦鍖�", "鍙屽嘲鍘�", "鏂板寲鍘�", "鍐锋按姹熷競", "娑熸簮甯�"]],
+		["婀樿タ鍦熷鏃忚嫍鏃忚嚜娌诲窞", ["鍚夐甯�", "娉告邯鍘�", "鍑ゅ嚢鍘�", "鑺卞灒鍘�", "淇濋潠鍘�", "鍙や笀鍘�", "姘搁『鍘�", "榫欏北鍘�"]]
+	]],
+	["骞夸笢鐪�", [
+		["骞垮窞甯�", ["鑽旀咕鍖�", "瓒婄鍖�", "娴风彔鍖�", "澶╂渤鍖�", "鐧戒簯鍖�", "榛勫煍鍖�", "鐣鍖�", "鑺遍兘鍖�", "鍗楁矙鍖�", "钀濆矖鍖�", "澧炲煄甯�", "浠庡寲甯�"]],
+		["闊跺叧甯�", ["姝︽睙鍖�", "娴堟睙鍖�", "鏇叉睙鍖�", "濮嬪叴鍘�", "浠佸寲鍘�", "缈佹簮鍘�", "涔虫簮鐟舵棌鑷不鍘�", "鏂颁赴鍘�", "涔愭槍甯�", "鍗楅泟甯�"]],
+		["娣卞湷甯�", ["缃楁箹鍖�", "绂忕敯鍖�", "鍗楀北鍖�", "瀹濆畨鍖�", "榫欏矖鍖�", "鐩愮敯鍖�"]],
+		["鐝犳捣甯�", ["棣欐床鍖�", "鏂楅棬鍖�", "閲戞咕鍖�"]],
+		["姹曞ご甯�", ["榫欐箹鍖�", "閲戝钩鍖�", "婵犳睙鍖�", "娼槼鍖�", "娼崡鍖�", "婢勬捣鍖�", "鍗楁境鍘�"]],
+		["浣涘北甯�", ["绂呭煄鍖�", "鍗楁捣鍖�", "椤哄痉鍖�", "涓夋按鍖�", "楂樻槑鍖�"]],
+		["姹熼棬甯�", ["钃睙鍖�", "姹熸捣鍖�", "鏂颁細鍖�", "鍙板北甯�", "寮�骞冲競", "楣ゅ北甯�", "鎭╁钩甯�"]],
+		["婀涙睙甯�", ["璧ゅ潕鍖�", "闇炲北鍖�", "鍧″ご鍖�", "楹荤珷鍖�", "閬傛邯鍘�", "寰愰椈鍘�", "寤夋睙甯�", "闆峰窞甯�", "鍚村窛甯�"]],
+		["鑼傚悕甯�", ["鑼傚崡鍖�", "鑼傛腐鍖�", "鐢电櫧鍘�", "楂樺窞甯�", "鍖栧窞甯�", "淇″疁甯�"]],
+		["鑲囧簡甯�", ["绔窞鍖�", "榧庢箹鍖�", "骞垮畞鍘�", "鎬�闆嗗幙", "灏佸紑鍘�", "寰峰簡鍘�", "楂樿甯�", "鍥涗細甯�"]],
+		["鎯犲窞甯�", ["鎯犲煄鍖�", "鎯犻槼鍖�", "鍗氱綏鍘�", "鎯犱笢鍘�", "榫欓棬鍘�"]],
+		["姊呭窞甯�", ["姊呮睙鍖�", "姊呭幙", "澶у煍鍘�", "涓伴『鍘�", "浜斿崕鍘�", "骞宠繙鍘�", "钑夊箔鍘�", "鍏村畞甯�"]],
+		["姹曞熬甯�", ["鍩庡尯", "娴蜂赴鍘�", "闄嗘渤鍘�", "闄嗕赴甯�"]],
+		["娌虫簮甯�", ["婧愬煄鍖�", "绱噾鍘�", "榫欏窛鍘�", "杩炲钩鍘�", "鍜屽钩鍘�", "涓滄簮鍘�"]],
+		["闃虫睙甯�", ["姹熷煄鍖�", "闃宠タ鍘�", "闃充笢鍘�", "闃虫槬甯�"]],
+		["娓呰繙甯�", ["娓呭煄鍖�", "娓呮柊鍖�", "浣涘唸鍘�", "闃冲北鍘�", "杩炲北澹棌鐟舵棌鑷不鍘�", "杩炲崡鐟舵棌鑷不鍘�", "鑻卞痉甯�", "杩炲窞甯�"]],
+		["涓滆帪甯�"],
+		["涓北甯�"],
+		["娼窞甯�", ["婀樻ˉ鍖�", "娼畨鍖�", "楗跺钩鍘�"]],
+		["鎻槼甯�", ["姒曞煄鍖�", "鎻笢鍖�", "鎻タ鍘�", "鎯犳潵鍘�", "鏅畞甯�"]],
+		["浜戞诞甯�", ["浜戝煄鍖�", "鏂板叴鍘�", "閮佸崡鍘�", "浜戝畨鍘�", "缃楀畾甯�"]]
+	]],
+	["骞胯タ澹棌鑷不鍖�", [
+		["鍗楀畞甯�", ["鍏村畞鍖�", "闈掔鍖�", "姹熷崡鍖�", "瑗夸埂濉樺尯", "鑹簡鍖�", "閭曞畞鍖�", "姝﹂福鍘�", "闅嗗畨鍘�", "椹北鍘�", "涓婃灄鍘�", "瀹鹃槼鍘�", "妯幙"]],
+		["鏌冲窞甯�", ["鍩庝腑鍖�", "楸煎嘲鍖�", "鏌冲崡鍖�", "鏌冲寳鍖�", "鏌虫睙鍘�", "鏌冲煄鍘�", "楣垮鍘�", "铻嶅畨鍘�", "铻嶆按鑻楁棌鑷不鍘�", "涓夋睙渚楁棌鑷不鍘�"]],
+		["妗傛灄甯�", ["绉�宄板尯", "鍙犲僵鍖�", "璞″北鍖�", "涓冩槦鍖�", "闆佸北鍖�", "涓存鍖�", "闃虫湐鍘�", "鐏靛窛鍘�", "鍏ㄥ窞鍘�", "鍏村畨鍘�", "姘哥鍘�", "鐏岄槼鍘�", "榫欒儨鍚勬棌鑷不鍘�", "璧勬簮鍘�", "骞充箰鍘�", "鑽旀郸鍘�", "鎭煄鐟舵棌鑷不鍘�"]],
+		["姊у窞甯�", ["涓囩鍖�", "闀挎床鍖�", "榫欏湬鍖�", "鑻嶆ⅶ鍘�", "钘ゅ幙", "钂欏北鍘�", "宀戞邯甯�"]],
+		["鍖楁捣甯�", ["娴峰煄鍖�", "閾舵捣鍖�", "閾佸北娓尯", "鍚堟郸鍘�"]],
+		["闃插煄娓競", ["娓彛鍖�", "闃插煄鍖�", "涓婃�濆幙", "涓滃叴甯�"]],
+		["閽﹀窞甯�", ["閽﹀崡鍖�", "閽﹀寳鍖�", "鐏靛北鍘�", "娴﹀寳鍘�"]],
+		["璐垫腐甯�", ["娓寳鍖�", "娓崡鍖�", "瑕冨鍖�", "骞冲崡鍘�", "妗傚钩甯�"]],
+		["鐜夋灄甯�", ["鐜夊窞鍖�", "绂忕坏鍖�", "瀹瑰幙", "闄嗗窛鍘�", "鍗氱櫧鍘�", "鍏翠笟鍘�", "鍖楁祦甯�"]],
+		["鐧捐壊甯�", ["鍙虫睙鍖�", "鐢伴槼鍘�", "鐢颁笢鍘�", "骞虫灉鍘�", "寰蜂繚鍘�", "闈栬タ鍘�", "閭e潯鍘�", "鍑屼簯鍘�", "涔愪笟鍘�", "鐢版灄鍘�", "瑗挎灄鍘�", "闅嗘灄鍚勬棌鑷不鍘�"]],
+		["璐哄窞甯�", ["鍏鍖�", "鏄钩鍘�", "閽熷北鍘�", "瀵屽窛鐟舵棌鑷不鍘�"]],
+		["娌虫睜甯�", ["閲戝煄姹熷尯", "鍗椾腹鍘�", "澶╁敞鍘�", "鍑ゅ北鍘�", "涓滃叞鍘�", "缃楀煄浠浆鏃忚嚜娌诲幙", "鐜睙姣涘崡鏃忚嚜娌诲幙", "宸撮┈鐟舵棌鑷不鍘�", "閮藉畨鐟舵棌鑷不鍘�", "澶у寲鐟舵棌鑷不鍘�", "瀹滃窞甯�"]],
+		["鏉ュ甯�", ["鍏村鍖�", "蹇诲煄鍘�", "璞″窞鍘�", "姝﹀鍘�", "閲戠鐟舵棌鑷不鍘�", "鍚堝北甯�"]],
+		["宕囧乏甯�", ["姹熷窞鍖�", "鎵剁互鍘�", "瀹佹槑鍘�", "榫欏窞鍘�", "澶ф柊鍘�", "澶╃瓑鍘�", "鍑ゥ甯�"]]
+	]],
+	["娴峰崡鐪�", [
+		["娴峰彛甯�", ["绉�鑻卞尯", "榫欏崕鍖�", "鐞煎北鍖�", "缇庡叞鍖�"]],
+		["涓変簹甯�"],
+		["涓夋矙甯�", ["瑗挎矙缇ゅ矝", "鍗楁矙缇ゅ矝", "涓矙缇ゅ矝鐨勫矝绀佸強鍏舵捣鍩�"]],
+		["鐪佺洿杈栧幙绾ц鏀垮尯鍒�", ["浜旀寚灞卞競", "鐞兼捣甯�", "鍎嬪窞甯�", "鏂囨槍甯�", "涓囧畞甯�", "涓滄柟甯�", "瀹氬畨鍘�", "灞槍鍘�", "婢勮繄鍘�", "涓撮珮鍘�", "鐧芥矙榛庢棌鑷不鍘�", "鏄屾睙榛庢棌鑷不鍘�", "涔愪笢榛庢棌鑷不鍘�", "闄垫按榛庢棌鑷不鍘�", "淇濅涵榛庢棌鑻楁棌鑷不鍘�", "鐞间腑榛庢棌鑻楁棌鑷不鍘�"]]
+	]],
+	["閲嶅簡甯�", [
+		["閲嶅簡甯�", ["涓囧窞鍖�", "娑櫟鍖�", "娓濅腑鍖�", "澶ф浮鍙e尯", "姹熷寳鍖�", "娌欏潽鍧濆尯", "涔濋緳鍧″尯", "鍗楀哺鍖�", "鍖楃鍖�", "缍︽睙鍖�", "澶ц冻鍖�", "娓濆寳鍖�", "宸村崡鍖�", "榛旀睙鍖�", "闀垮鍖�", "姹熸触鍖�", "鍚堝窛鍖�", "姘稿窛鍖�", "鍗楀窛鍖�", "鐠у北鍖�", "閾滄鍖�", "娼煎崡鍖�", "鑽f槍鍖�", "寮�宸炲尯", "姊佸钩鍖�", "姝﹂殕鍖�", "鍩庡彛鍘�", "涓伴兘鍘�", "鍨睙鍘�", "蹇犲幙", "浜戦槼鍘�", "濂夎妭鍘�", "宸北鍘�", "宸邯鍘�", "鐭虫煴鍦熷鏃忚嚜娌诲幙", "绉�灞卞湡瀹舵棌鑻楁棌鑷不鍘�", "閰夐槼鍦熷鏃忚嫍鏃忚嚜娌诲幙", "褰按鑻楁棌鍦熷鏃忚嚜娌诲幙"]]
+	]],
+	["鍥涘窛鐪�", [
+		["鎴愰兘甯�", ["閿︽睙鍖�", "闈掔緤鍖�", "閲戠墰鍖�", "姝︿警鍖�", "鎴愬崕鍖�", "榫欐硥椹垮尯", "闈掔櫧姹熷尯", "鏂伴兘鍖�", "娓╂睙鍖�", "閲戝爞鍘�", "鍙屾祦鍘�", "閮幙", "澶ч倯鍘�", "钂叉睙鍘�", "鏂版触鍘�", "閮芥睙鍫板競", "褰窞甯�", "閭涘磧甯�", "宕囧窞甯�"]],
+		["鑷础甯�", ["鑷祦浜曞尯", "璐′簳鍖�", "澶у畨鍖�", "娌挎哗鍖�", "鑽e幙", "瀵岄『鍘�"]],
+		["鏀�鏋濊姳甯�", ["涓滃尯", "瑗垮尯", "浠佸拰鍖�", "绫虫槗鍘�", "鐩愯竟鍘�"]],
+		["娉稿窞甯�", ["姹熼槼鍖�", "绾虫邯鍖�", "榫欓┈娼尯", "娉稿幙", "鍚堟睙鍘�", "鍙欐案鍘�", "鍙よ敽鍘�"]],
+		["寰烽槼甯�", ["鏃岄槼鍖�", "涓睙鍘�", "缃楁睙鍘�", "骞挎眽甯�", "浠�閭″競", "缁电甯�"]],
+		["缁甸槼甯�", ["娑煄鍖�", "娓镐粰鍖�", "涓夊彴鍘�", "鐩愪涵鍘�", "瀹夊幙", "姊撴郊鍘�", "鍖楀窛缇屾棌鑷不鍘�", "骞虫鍘�", "姹熸补甯�"]],
+		["骞垮厓甯�", ["鍒╁窞鍖�", "鍏冨潩鍖�", "鏈濆ぉ鍖�", "鏃鸿媿鍘�", "闈掑窛鍘�", "鍓戦榿鍘�", "鑻嶆邯鍘�"]],
+		["閬傚畞甯�", ["鑸瑰北鍖�", "瀹夊眳鍖�", "钃邯鍘�", "灏勬椽鍘�", "澶ц嫳鍘�"]],
+		["鍐呮睙甯�", ["甯備腑鍖�", "涓滃叴鍖�", "濞佽繙鍘�", "璧勪腑鍘�", "闅嗘槍鍘�"]],
+		["涔愬北甯�", ["甯備腑鍖�", "娌欐咕鍖�", "浜旈�氭ˉ鍖�", "閲戝彛娌冲尯", "鐘嶄负鍘�", "浜曠爺鍘�", "澶规睙鍘�", "娌愬窛鍘�", "宄ㄨ竟褰濇棌鑷不鍘�", "椹竟褰濇棌鑷不鍘�", "宄ㄧ湁灞卞競"]],
+		["鍗楀厖甯�", ["椤哄簡鍖�", "楂樺潽鍖�", "鍢夐櫟鍖�", "鍗楅儴鍘�", "钀ュ北鍘�", "钃畨鍘�", "浠檱鍘�", "瑗垮厖鍘�", "闃嗕腑甯�"]],
+		["鐪夊北甯�", ["涓滃潯鍖�", "浠佸鍘�", "褰北鍘�", "娲泤鍘�", "涓规1鍘�", "闈掔鍘�"]],
+		["瀹滃甯�", ["缈犲睆鍖�", "鍗楁邯鍖�", "瀹滃鍘�", "姹熷畨鍘�", "闀垮畞鍘�", "楂樺幙", "鐝欏幙", "绛犺繛鍘�", "鍏存枃鍘�", "灞忓北鍘�"]],
+		["骞垮畨甯�", ["骞垮畨鍖�", "鍓嶉攱鍖�", "宀虫睜鍘�", "姝﹁儨鍘�", "閭绘按鍘�", "鍗庤摜甯�"]],
+		["杈惧窞甯�", ["閫氬窛鍖�", "杈惧窛鍖�", "瀹f眽鍘�", "寮�姹熷幙", "澶х鍘�", "娓犲幙", "涓囨簮甯�"]],
+		["闆呭畨甯�", ["闆ㄥ煄鍖�", "鍚嶅北鍖�", "鑽ョ粡鍘�", "姹夋簮鍘�", "鐭虫鍘�", "澶╁叏鍘�", "鑺﹀北鍘�", "瀹濆叴鍘�"]],
+		["宸翠腑甯�", ["宸村窞鍖�", "鎭╅槼鍖�", "閫氭睙鍘�", "鍗楁睙鍘�", "骞虫槍鍘�"]],
+		["璧勯槼甯�", ["闆佹睙鍖�", "瀹夊渤鍘�", "涔愯嚦鍘�", "绠�闃冲競"]],
+		["闃垮潩钘忔棌缇屾棌鑷不宸�", ["姹跺窛鍘�", "鐞嗗幙", "鑼傚幙", "鏉炬綐鍘�", "涔濆娌熷幙", "閲戝窛鍘�", "灏忛噾鍘�", "榛戞按鍘�", "椹皵搴峰幙", "澹ゅ鍘�", "闃垮潩鍘�", "鑻ュ皵鐩栧幙", "绾㈠師鍘�"]],
+		["鐢樺瓬钘忔棌鑷不宸�", ["搴峰畾鍘�", "娉稿畾鍘�", "涓瑰反鍘�", "涔濋緳鍘�", "闆呮睙鍘�", "閬撳瓪鍘�", "鐐夐湇鍘�", "鐢樺瓬鍘�", "鏂伴緳鍘�", "寰锋牸鍘�", "鐧界帀鍘�", "鐭虫笭鍘�", "鑹茶揪鍘�", "鐞嗗鍘�", "宸村鍘�", "涔″煄鍘�", "绋诲煄鍘�", "寰楄崳鍘�"]],
+		["鍑夊北褰濇棌鑷不宸�", ["瑗挎槍甯�", "鏈ㄩ噷钘忔棌鑷不鍘�", "鐩愭簮鍘�", "寰锋槍鍘�", "浼氱悊鍘�", "浼氫笢鍘�", "瀹佸崡鍘�", "鏅牸鍘�", "甯冩嫋鍘�", "閲戦槼鍘�", "鏄鍘�", "鍠滃痉鍘�", "鍐曞畞鍘�", "瓒婅タ鍘�", "鐢樻礇鍘�", "缇庡鍘�", "闆锋尝鍘�"]]
+	]],
+	["璐靛窞鐪�", [
+		["璐甸槼甯�", ["鍗楁槑鍖�", "浜戝博鍖�", "鑺辨邯鍖�", "涔屽綋鍖�", "鐧戒簯鍖�", "瑙傚北婀栧尯", "寮�闃冲幙", "鎭兘鍘�", "淇枃鍘�", "娓呴晣甯�"]],
+		["鍏洏姘村競", ["閽熷北鍖�", "鍏灊鐗瑰尯", "姘村煄鍘�", "鐩樺幙"]],
+		["閬典箟甯�", ["绾㈣姳宀楀尯", "姹囧窛鍖�", "閬典箟鍘�", "妗愭鍘�", "缁ラ槼鍘�", "姝e畨鍘�", "閬撶湡浠′浆鏃忚嫍鏃忚嚜娌诲幙", "鍔″窛浠′浆鏃忚嫍鏃忚嚜娌诲幙", "鍑ゅ唸鍘�", "婀勬江鍘�", "浣欏簡鍘�", "涔犳按鍘�", "璧ゆ按甯�", "浠佹��甯�"]],
+		["瀹夐『甯�", ["瑗跨鍖�", "骞冲潩鍘�", "鏅畾鍘�", "闀囧畞甯冧緷鏃忚嫍鏃忚嚜娌诲幙", "鍏冲箔甯冧緷鏃忚嫍鏃忚嚜娌诲幙", "绱簯鑻楁棌甯冧緷鏃忚嚜娌诲幙"]],
+		["姣曡妭甯�", ["涓冩槦鍏冲尯", "澶ф柟鍘�", "榛旇タ鍘�", "閲戞矙鍘�", "缁囬噾鍘�", "绾抽泹鍘�", "濞佸畞褰濇棌鍥炴棌鑻楁棌鑷不鍘�", "璧珷鍘�"]],
+		["閾滀粊甯�", ["纰ф睙鍖�", "涓囧北鍖�", "姹熷彛鍘�", "鐜夊睆渚楁棌鑷不鍘�", "鐭抽槨鍘�", "鎬濆崡鍘�", "鍗版睙鍦熷鏃忚嫍鏃忚嚜娌诲幙", "寰锋睙鍘�", "娌挎渤鍦熷鏃忚嚜娌诲幙", "鏉炬鑻楁棌鑷不鍘�"]],
+		["榛旇タ鍗楀竷渚濇棌鑻楁棌鑷不宸�", ["鍏翠箟甯�", "鍏翠粊鍘�", "鏅畨鍘�", "鏅撮殕鍘�", "璐炰赴鍘�", "鏈涜盁鍘�", "鍐屼酣鍘�", "瀹夐緳鍘�"]],
+		["榛斾笢鍗楄嫍鏃忎緱鏃忚嚜娌诲窞", ["鍑噷甯�", "榛勫钩鍘�", "鏂界鍘�", "涓夌鍘�", "闀囪繙鍘�", "宀戝珐鍘�", "澶╂煴鍘�", "閿﹀睆鍘�", "鍓戞渤鍘�", "鍙版睙鍘�", "榛庡钩鍘�", "姒曟睙鍘�", "浠庢睙鍘�", "闆峰北鍘�", "楹绘睙鍘�", "涓瑰鍘�"]],
+		["榛斿崡甯冧緷鏃忚嫍鏃忚嚜娌诲窞", ["閮藉寑甯�", "绂忔硥甯�", "鑽旀尝鍘�", "璐靛畾鍘�", "鐡畨鍘�", "鐙北鍘�", "骞冲鍘�", "缃楃敻鍘�", "闀块『鍘�", "榫欓噷鍘�", "鎯犳按鍘�", "涓夐兘姘存棌鑷不鍘�"]]
+	]],
+	["浜戝崡鐪�", [
+		["鏄嗘槑甯�", ["浜斿崕鍖�", "鐩橀緳鍖�", "瀹樻浮鍖�", "瑗垮北鍖�", "涓滃窛鍖�", "鍛堣础鍖�", "鏅嬪畞鍘�", "瀵屾皯鍘�", "瀹滆壇鍘�", "鐭虫灄褰濇棌鑷不鍘�", "宓╂槑鍘�", "绂勫姖褰濇棌鑻楁棌鑷不鍘�", "瀵荤敻鍥炴棌褰濇棌鑷不鍘�", "瀹夊畞甯�"]],
+		["鏇查潠甯�", ["楹掗簾鍖�", "椹緳鍘�", "闄嗚壇鍘�", "甯堝畻鍘�", "缃楀钩鍘�", "瀵屾簮鍘�", "浼氭辰鍘�", "娌剧泭鍘�", "瀹e▉甯�"]],
+		["鐜夋邯甯�", ["绾㈠鍖�", "姹熷窛鍘�", "婢勬睙鍘�", "閫氭捣鍘�", "鍗庡畞鍘�", "鏄撻棬鍘�", "宄ㄥ北褰濇棌鑷不鍘�", "鏂板钩褰濇棌鍌f棌鑷不鍘�", "鍏冩睙鍝堝凹鏃忓綕鏃忓偅鏃忚嚜娌诲幙"]],
+		["淇濆北甯�", ["闅嗛槼鍖�", "鏂界敻鍘�", "鑵惧啿鍘�", "榫欓櫟鍘�", "鏄屽畞鍘�"]],
+		["鏄�氬競", ["鏄槼鍖�", "椴佺敻鍘�", "宸у鍘�", "鐩愭触鍘�", "澶у叧鍘�", "姘稿杽鍘�", "缁ユ睙鍘�", "闀囬泟鍘�", "褰濊壇鍘�", "濞佷俊鍘�", "姘村瘜鍘�"]],
+		["涓芥睙甯�", ["鍙ゅ煄鍖�", "鐜夐緳绾宠タ鏃忚嚜娌诲幙", "姘歌儨鍘�", "鍗庡潽鍘�", "瀹佽挆褰濇棌鑷不鍘�"]],
+		["鏅幢甯�", ["鎬濊寘鍖�", "瀹佹幢鍝堝凹鏃忓綕鏃忚嚜娌诲幙", "澧ㄦ睙鍝堝凹鏃忚嚜娌诲幙", "鏅笢褰濇棌鑷不鍘�", "鏅胺鍌f棌褰濇棌鑷不鍘�", "闀囨矃褰濇棌鍝堝凹鏃忔媺绁滄棌鑷不鍘�", "姹熷煄鍝堝凹鏃忓綕鏃忚嚜娌诲幙", "瀛熻繛鍌f棌鎷夌鏃忎饯鏃忚嚜娌诲幙", "婢滄钵鎷夌鏃忚嚜娌诲幙", "瑗跨洘浣ゆ棌鑷不鍘�"]],
+		["涓存钵甯�", ["涓寸繑鍖�", "鍑ゅ簡鍘�", "浜戝幙", "姘稿痉鍘�", "闀囧悍鍘�", "鍙屾睙鎷夌鏃忎饯鏃忓竷鏈楁棌鍌f棌鑷不鍘�", "鑰块┈鍌f棌浣ゆ棌鑷不鍘�", "娌ф簮浣ゆ棌鑷不鍘�"]],
+		["妤氶泟褰濇棌鑷不宸�", ["妤氶泟甯�", "鍙屾煆鍘�", "鐗熷畾鍘�", "鍗楀崕鍘�", "濮氬畨鍘�", "澶у鍘�", "姘镐粊鍘�", "鍏冭皨鍘�", "姝﹀畾鍘�", "绂勪赴鍘�"]],
+		["绾㈡渤鍝堝凹鏃忓綕鏃忚嚜娌诲窞", ["涓棫甯�", "寮�杩滃競", "钂欒嚜甯�", "寮ュ嫆甯�", "灞忚竟鑻楁棌鑷不鍘�", "寤烘按鍘�", "鐭冲睆鍘�", "娉歌タ鍘�", "鍏冮槼鍘�", "绾㈡渤鍘�", "閲戝钩鑻楁棌鐟舵棌鍌f棌鑷不鍘�", "缁挎槬鍘�", "娌冲彛鐟舵棌鑷不鍘�"]],
+		["鏂囧北澹棌鑻楁棌鑷不宸�", ["鏂囧北甯�", "鐮氬北鍘�", "瑗跨暣鍘�", "楹绘牀鍧″幙", "椹叧鍘�", "涓樺寳鍘�", "骞垮崡鍘�", "瀵屽畞鍘�"]],
+		["瑗垮弻鐗堢撼鍌f棌鑷不宸�", ["鏅椽甯�", "鍕愭捣鍘�", "鍕愯厞鍘�"]],
+		["澶х悊鐧芥棌鑷不宸�", ["澶х悊甯�", "婕炬繛褰濇棌鑷不鍘�", "绁ヤ簯鍘�", "瀹惧窛鍘�", "寮ユ浮鍘�", "鍗楁锭褰濇棌鑷不鍘�", "宸嶅北褰濇棌鍥炴棌鑷不鍘�", "姘稿钩鍘�", "浜戦緳鍘�", "娲辨簮鍘�", "鍓戝窛鍘�", "楣ゅ簡鍘�"]],
+		["寰峰畯鍌f棌鏅鏃忚嚜娌诲窞", ["鐟炰附甯�", "鑺掑競", "姊佹渤鍘�", "鐩堟睙鍘�", "闄囧窛鍘�"]],
+		["鎬掓睙鍌堝兂鏃忚嚜娌诲窞", ["娉告按鍘�", "绂忚础鍘�", "璐″北鐙緳鏃忔�掓棌鑷不鍘�", "鍏板潽鐧芥棌鏅背鏃忚嚜娌诲幙"]],
+		["杩簡钘忔棌鑷不宸�", ["棣欐牸閲屾媺鍘�", "寰烽挦鍘�", "缁磋タ鍌堝兂鏃忚嚜娌诲幙"]]
+	]],
+	["瑗胯棌鑷不鍖�", [
+		["鎷夎惃甯�", ["鍩庡叧鍖�", "鏋楀懆鍘�", "褰撻泟鍘�", "灏兼湪鍘�", "鏇叉按鍘�", "鍫嗛緳寰峰簡鍘�", "杈惧瓬鍘�", "澧ㄧ宸ュ崱鍘�"]],
+		["鏄岄兘鍦板尯", ["鏄岄兘鍘�", "姹熻揪鍘�", "璐¤鍘�", "绫讳箤榻愬幙", "涓侀潚鍘�", "瀵熼泤鍘�", "鍏鍘�", "宸﹁础鍘�", "鑺掑悍鍘�", "娲涢殕鍘�", "杈瑰潩鍘�"]],
+		["灞卞崡鍦板尯", ["涔冧笢鍘�", "鎵庡泭鍘�", "璐″槑鍘�", "妗戞棩鍘�", "鐞肩粨鍘�", "鏇叉澗鍘�", "鎺編鍘�", "娲涙墡鍘�", "鍔犳煡鍘�", "闅嗗瓙鍘�", "閿欓偅鍘�", "娴崱瀛愬幙"]],
+		["鏃ュ杸鍒欏湴鍖�", ["鏃ュ杸鍒欏競", "鍗楁湪鏋楀幙", "姹熷瓬鍘�", "瀹氭棩鍘�", "钀ㄨ喀鍘�", "鎷夊瓬鍘�", "鏄備粊鍘�", "璋㈤�氶棬鍘�", "鐧芥湕鍘�", "浠佸竷鍘�", "搴烽┈鍘�", "瀹氱粨鍘�", "浠插反鍘�", "浜氫笢鍘�", "鍚夐殕鍘�", "鑱傛媺鏈ㄥ幙", "钀ㄥ槑鍘�", "宀楀反鍘�"]],
+		["閭f洸鍦板尯", ["閭f洸鍘�", "鍢夐粠鍘�", "姣斿鍘�", "鑱傝崳鍘�", "瀹夊鍘�", "鐢虫墡鍘�", "绱㈠幙", "鐝垐鍘�", "宸撮潚鍘�", "灏肩帥鍘�", "鍙屾箹鍘�"]],
+		["闃块噷鍦板尯", ["鏅叞鍘�", "鏈揪鍘�", "鍣跺皵鍘�", "鏃ュ湡鍘�", "闈╁悏鍘�", "鏀瑰垯鍘�", "鎺嫟鍘�"]],
+		["鏋楄姖鍦板尯", ["鏋楄姖鍘�", "宸ュ竷姹熻揪鍘�", "绫虫灄鍘�", "澧ㄨ劚鍘�", "娉㈠瘑鍘�", "瀵熼殔鍘�", "鏈楀幙"]]
+	]],
+	["闄曡タ鐪�", [
+		["瑗垮畨甯�", ["鏂板煄鍖�", "纰戞灄鍖�", "鑾叉箹鍖�", "鐏炴ˉ鍖�", "鏈ぎ鍖�", "闆佸鍖�", "闃庤壇鍖�", "涓存郊鍖�", "闀垮畨鍖�", "钃濈敯鍘�", "鍛ㄨ嚦鍘�", "鎴峰幙", "楂橀櫟鍘�"]],
+		["閾滃窛甯�", ["鐜嬬泭鍖�", "鍗板彴鍖�", "鑰�宸炲尯", "瀹滃悰鍘�"]],
+		["瀹濋浮甯�", ["娓花鍖�", "閲戝彴鍖�", "闄堜粨鍖�", "鍑ょ繑鍘�", "宀愬北鍘�", "鎵堕鍘�", "鐪夊幙", "闄囧幙", "鍗冮槼鍘�", "楹熸父鍘�", "鍑ゅ幙", "澶櫧鍘�"]],
+		["鍜搁槼甯�", ["绉﹂兘鍖�", "鏉ㄩ櫟鍖�", "娓煄鍖�", "涓夊師鍘�", "娉鹃槼鍘�", "涔惧幙", "绀兼硥鍘�", "姘稿鍘�", "褰幙", "闀挎鍘�", "鏃倯鍘�", "娣冲寲鍘�", "姝﹀姛鍘�", "鍏村钩甯�"]],
+		["娓崡甯�", ["涓存腑鍖�", "鍗庡幙", "娼煎叧鍘�", "澶ц崝鍘�", "鍚堥槼鍘�", "婢勫煄鍘�", "钂插煄鍘�", "鐧芥按鍘�", "瀵屽钩鍘�", "闊╁煄甯�", "鍗庨槾甯�"]],
+		["寤跺畨甯�", ["瀹濆鍖�", "寤堕暱鍘�", "寤跺窛鍘�", "瀛愰暱鍘�", "瀹夊鍘�", "蹇椾腹鍘�", "鍚磋捣鍘�", "鐢樻硥鍘�", "瀵屽幙", "娲涘窛鍘�", "瀹滃窛鍘�", "榛勯緳鍘�", "榛勯櫟鍘�"]],
+		["姹変腑甯�", ["姹夊彴鍖�", "鍗楅儜鍘�", "鍩庡浐鍘�", "娲嬪幙", "瑗夸埂鍘�", "鍕夊幙", "瀹佸己鍘�", "鐣ラ槼鍘�", "闀囧反鍘�", "鐣欏潩鍘�", "浣涘潽鍘�"]],
+		["姒嗘灄甯�", ["姒嗛槼鍖�", "绁炴湪鍘�", "搴滆胺鍘�", "妯北鍘�", "闈栬竟鍘�", "瀹氳竟鍘�", "缁ュ痉鍘�", "绫宠剛鍘�", "浣冲幙", "鍚村牎鍘�", "娓呮锭鍘�", "瀛愭床鍘�"]],
+		["瀹夊悍甯�", ["姹夋花鍖�", "姹夐槾鍘�", "鐭虫硥鍘�", "瀹侀檿鍘�", "绱槼鍘�", "宀氱殝鍘�", "骞冲埄鍘�", "闀囧潽鍘�", "鏃槼鍘�", "鐧芥渤鍘�"]],
+		["鍟嗘礇甯�", ["鍟嗗窞鍖�", "娲涘崡鍘�", "涓瑰嚖鍘�", "鍟嗗崡鍘�", "灞遍槼鍘�", "闀囧畨鍘�", "鏌炴按鍘�"]]
+	]],
+	["鐢樿們鐪�", [
+		["鍏板窞甯�", ["鍩庡叧鍖�", "涓冮噷娌冲尯", "瑗垮浐鍖�", "瀹夊畞鍖�", "绾㈠彜鍖�", "姘哥櫥鍘�", "鐨嬪叞鍘�", "姒嗕腑鍘�"]],
+		["鍢夊唱鍏冲競"],
+		["閲戞槍甯�", ["閲戝窛鍖�", "姘告槍鍘�"]],
+		["鐧介摱甯�", ["鐧介摱鍖�", "骞冲窛鍖�", "闈栬繙鍘�", "浼氬畞鍘�", "鏅嘲鍘�"]],
+		["澶╂按甯�", ["绉﹀窞鍖�", "楹︾Н鍖�", "娓呮按鍘�", "绉﹀畨鍘�", "鐢樿胺鍘�", "姝﹀北鍘�", "寮犲宸濆洖鏃忚嚜娌诲幙"]],
+		["姝﹀▉甯�", ["鍑夊窞鍖�", "姘戝嫟鍘�", "鍙ゆ氮鍘�", "澶╃钘忔棌鑷不鍘�"]],
+		["寮犳帠甯�", ["鐢樺窞鍖�", "鑲冨崡瑁曞浐鏃忚嚜娌诲幙", "姘戜箰鍘�", "涓存辰鍘�", "楂樺彴鍘�", "灞变腹鍘�"]],
+		["骞冲噳甯�", ["宕嗗硳鍖�", "娉惧窛鍘�", "鐏靛彴鍘�", "宕囦俊鍘�", "鍗庝涵鍘�", "搴勬氮鍘�", "闈欏畞鍘�"]],
+		["閰掓硥甯�", ["鑲冨窞鍖�", "閲戝鍘�", "鐡滃窞鍘�", "鑲冨寳钂欏彜鏃忚嚜娌诲幙", "闃垮厠濉炲搱钀ㄥ厠鏃忚嚜娌诲幙", "鐜夐棬甯�", "鏁︾厡甯�"]],
+		["搴嗛槼甯�", ["瑗垮嘲鍖�", "搴嗗煄鍘�", "鐜幙", "鍗庢睜鍘�", "鍚堟按鍘�", "姝e畞鍘�", "瀹佸幙", "闀囧師鍘�"]],
+		["瀹氳タ甯�", ["瀹夊畾鍖�", "閫氭腑鍘�", "闄囪タ鍘�", "娓簮鍘�", "涓存串鍘�", "婕冲幙", "宀峰幙"]],
+		["闄囧崡甯�", ["姝﹂兘鍖�", "鎴愬幙", "鏂囧幙", "瀹曟槍鍘�", "搴峰幙", "瑗垮拰鍘�", "绀煎幙", "寰藉幙", "涓ゅ綋鍘�"]],
+		["涓村鍥炴棌鑷不宸�", ["涓村甯�", "涓村鍘�", "搴蜂箰鍘�", "姘搁潠鍘�", "骞挎渤鍘�", "鍜屾斂鍘�", "涓滀埂鏃忚嚜娌诲幙", "绉煶灞变繚瀹夋棌涓滀埂鏃忔拻鎷夋棌鑷不鍘�"]],
+		["鐢樺崡钘忔棌鑷不宸�", ["鍚堜綔甯�", "涓存江鍘�", "鍗撳凹鍘�", "鑸熸洸鍘�", "杩儴鍘�", "鐜涙洸鍘�", "纰屾洸鍘�", "澶忔渤鍘�"]]
+	]],
+	["闈掓捣鐪�", [
+		["瑗垮畞甯�", ["鍩庝笢鍖�", "鍩庝腑鍖�", "鍩庤タ鍖�", "鍩庡寳鍖�", "澶ч�氬洖鏃忓湡鏃忚嚜娌诲幙", "婀熶腑鍘�", "婀熸簮鍘�"]],
+		["娴蜂笢甯�", ["涔愰兘鍖�", "骞冲畨鍘�", "姘戝拰鍥炴棌鍦熸棌鑷不鍘�", "浜掑姪鍦熸棌鑷不鍘�", "鍖栭殕鍥炴棌鑷不鍘�", "寰寲鎾掓媺鏃忚嚜娌诲幙"]],
+		["娴峰寳钘忔棌鑷不宸�", ["闂ㄦ簮鍥炴棌鑷不鍘�", "绁佽繛鍘�", "娴锋檹鍘�", "鍒氬療鍘�"]],
+		["榛勫崡钘忔棌鑷不宸�", ["鍚屼粊鍘�", "灏栨墡鍘�", "娉藉簱鍘�", "娌冲崡钂欏彜鏃忚嚜娌诲幙"]],
+		["娴峰崡钘忔棌鑷不宸�", ["鍏卞拰鍘�", "鍚屽痉鍘�", "璐靛痉鍘�", "鍏存捣鍘�", "璐靛崡鍘�"]],
+		["鏋滄礇钘忔棌鑷不宸�", ["鐜涙瞾鍘�", "鐝帥鍘�", "鐢樺痉鍘�", "杈炬棩鍘�", "涔呮不鍘�", "鐜涘鍘�"]],
+		["鐜夋爲钘忔棌鑷不宸�", ["鐜夋爲甯�", "鏉傚鍘�", "绉板鍘�", "娌诲鍘�", "鍥婅唉鍘�", "鏇查夯鑾卞幙"]],
+		["娴疯タ钂欏彜鏃忚棌鏃忚嚜娌诲窞", ["鏍煎皵鏈ㄥ競", "寰蜂护鍝堝競", "涔屽叞鍘�", "閮藉叞鍘�", "澶╁郴鍘�"]]
+	]],
+	["瀹佸鍥炴棌鑷不鍖�", [
+		["閾跺窛甯�", ["鍏村簡鍖�", "瑗垮鍖�", "閲戝嚖鍖�", "姘稿畞鍘�", "璐哄叞鍘�", "鐏垫甯�"]],
+		["鐭冲槾灞卞競", ["澶ф鍙e尯", "鎯犲啘鍖�", "骞崇綏鍘�"]],
+		["鍚村繝甯�", ["鍒╅�氬尯", "绾㈠鍫″尯", "鐩愭睜鍘�", "鍚屽績鍘�", "闈掗摐宄″競"]],
+		["鍥哄師甯�", ["鍘熷窞鍖�", "瑗垮悏鍘�", "闅嗗痉鍘�", "娉炬簮鍘�", "褰槼鍘�"]],
+		["涓崼甯�", ["娌欏潯澶村尯", "涓畞鍘�", "娴峰師鍘�"]]
+	]],
+	["鏂扮枂缁村惥灏旇嚜娌诲尯", [
+		["涔岄瞾鏈ㄩ綈甯�", ["澶╁北鍖�", "娌欎緷宸村厠鍖�", "鏂板競鍖�", "姘寸(娌熷尯", "澶村悲娌冲尯", "杈惧潅鍩庡尯", "绫充笢鍖�", "涔岄瞾鏈ㄩ綈鍘�"]],
+		["鍏嬫媺鐜涗緷甯�", ["鐙北瀛愬尯", "鍏嬫媺鐜涗緷鍖�", "鐧界⒈婊╁尯", "涔屽皵绂惧尯"]],
+		["鍚愰瞾鐣湴鍖�", ["鍚愰瞾鐣競", "閯杽鍘�", "鎵樺厠閫婂幙"]],
+		["鍝堝瘑鍦板尯", ["鍝堝瘑甯�", "宸撮噷鍧ゅ搱钀ㄥ厠鑷不鍘�", "浼婂惥鍘�"]],
+		["鏄屽悏鍥炴棌鑷不宸�", ["鏄屽悏甯�", "闃滃悍甯�", "鍛煎浘澹佸幙", "鐜涚撼鏂幙", "濂囧彴鍘�", "鍚夋湪钀ㄥ皵鍘�", "鏈ㄥ瀿鍝堣惃鍏嬭嚜娌诲幙"]],
+		["鍗氬皵濉旀媺钂欏彜鑷不宸�", ["鍗氫箰甯�", "闃挎媺灞卞彛甯�", "绮炬渤鍘�", "娓╂硥鍘�"]],
+		["宸撮煶閮钂欏彜鑷不宸�", ["搴撳皵鍕掑競", "杞彴鍘�", "灏夌妬鍘�", "鑻ョ緦鍘�", "涓旀湯鍘�", "鐒夎�嗗洖鏃忚嚜娌诲幙", "鍜岄潤鍘�", "鍜岀鍘�", "鍗氭箹鍘�"]],
+		["闃垮厠鑻忓湴鍖�", ["闃垮厠鑻忓競", "娓╁鍘�", "搴撹溅鍘�", "娌欓泤鍘�", "鏂板拰鍘�", "鎷滃煄鍘�", "涔屼粈鍘�", "闃跨摝鎻愬幙", "鏌潽鍘�"]],
+		["鍏嬪瓬鍕掕嫃鏌皵鍏嬪瓬鑷不宸�", ["闃垮浘浠�甯�", "闃垮厠闄跺幙", "闃垮悎濂囧幙", "涔屾伆鍘�"]],
+		["鍠�浠�鍦板尯", ["鍠�浠�甯�", "鐤忛檮鍘�", "鐤忓嫆鍘�", "鑻卞悏娌欏幙", "娉芥櫘鍘�", "鑾庤溅鍘�", "鍙跺煄鍘�", "楹︾洊鎻愬幙", "宀虫櫘婀栧幙", "浼藉笀鍘�", "宸存鍘�", "濉斾粈搴撳皵骞插鍚夊厠鑷不鍘�"]],
+		["鍜岀敯鍦板尯", ["鍜岀敯甯�", "鍜岀敯鍘�", "澧ㄧ帀鍘�", "鐨北鍘�", "娲涙郸鍘�", "绛栧嫆鍘�", "浜庣敯鍘�", "姘戜赴鍘�"]],
+		["浼婄妬鍝堣惃鍏嬭嚜娌诲窞", ["浼婂畞甯�", "濂庡悲甯�", "浼婂畞鍘�", "瀵熷竷鏌ュ皵閿′集鑷不鍘�", "闇嶅煄鍘�", "宸╃暀鍘�", "鏂版簮鍘�", "鏄嫃鍘�", "鐗瑰厠鏂幙", "灏煎嫆鍏嬪幙"]],
+		["濉斿煄鍦板尯", ["濉斿煄甯�", "涔岃嫃甯�", "棰濇晱鍘�", "娌欐咕鍘�", "鎵橀噷鍘�", "瑁曟皯鍘�", "鍜屽竷鍏嬭禌灏旇挋鍙よ嚜娌诲幙"]],
+		["闃垮嫆娉板湴鍖�", ["闃垮嫆娉板競", "甯冨皵娲ュ幙", "瀵岃暣鍘�", "绂忔捣鍘�", "鍝堝反娌冲幙", "闈掓渤鍘�", "鍚夋湪涔冨幙"]],
+		["鑷不鍖虹洿杈栧幙绾ц鏀垮尯鍒�", ["鐭虫渤瀛愬競", "闃挎媺灏斿競", "鍥炬湪鑸掑厠甯�", "浜斿娓犲競"]]
+	]],
+	["鍙版咕鐪�"],
+	["棣欐腐鐗瑰埆琛屾斂鍖�"],
+	["婢抽棬鐗瑰埆琛屾斂鍖�"]
+]
\ No newline at end of file
diff --git a/src/tabviews/zshare/mutilform/mkCascader/index.jsx b/src/tabviews/zshare/mutilform/mkCascader/index.jsx
new file mode 100644
index 0000000..34b1713
--- /dev/null
+++ b/src/tabviews/zshare/mutilform/mkCascader/index.jsx
@@ -0,0 +1,150 @@
+import React, {Component} from 'react'
+import { is, fromJS } from 'immutable'
+import { Cascader } from 'antd'
+
+import MKEmitter from '@/utils/events.js'
+
+const provinces = require('./data.json')
+
+class MKSelect extends Component {
+  constructor(props) {
+    super(props)
+    
+    const config = props.config
+    let value = config.initval
+    let options = fromJS(config.options).toJS()
+
+    if (value && config.separator) {
+      value = value.split(config.separator)
+    } else {
+      value = value ? [value] : []
+    }
+
+    if (config.resourceType === '2') {
+      options = provinces.map(pro => {
+        let _pro = {
+          label: pro[0],
+          value: pro[0]
+        }
+        if (pro[1]) {
+          _pro.children = pro[1].map(city => {
+            let _city = {
+              label: city[0],
+              value: city[0]
+            }
+            if (city[1]) {
+              _city.children = city[1].map(county => {
+                return {
+                  label: county,
+                  value: county
+                }
+              })
+            }
+            return _city
+          })
+        }
+        return _pro
+      })
+    } else if (options.length > 0) {
+      options = this.getOptionTree(options)
+    }
+
+    this.state = {
+      config: fromJS(config).toJS(),
+      options: options,
+      value,
+    }
+  }
+
+  componentDidMount () {
+
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    const { config } = this.state
+
+    if (config.resourceType === '1' && !is(fromJS(config.oriOptions), fromJS(nextProps.config.oriOptions))) {
+      let options = fromJS(nextProps.config.options).toJS()
+      
+      this.setState({
+        options: this.getOptionTree(options)
+      })
+    }
+  }
+
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  getOptionTree = (options) => {
+    const { config } = this.props
+
+    let _options = []
+
+    options = options.filter(option => {
+      if (option.ParentID === config.topmark) {
+        _options.push(option)
+        return false
+      }
+      return true
+    })
+    
+    return this.getTree(_options, options)
+  }
+
+  getTree = (parents, options) => {
+    parents.forEach(parent => {
+      parent.children = []
+
+      options = options.filter(option => {
+        if (option.ParentID === parent.value) {
+          parent.children.push(option)
+          return false
+        }
+        return true
+      })
+
+      if (parent.children.length === 0) {
+        parent.children = null
+      } else {
+        parent.children = this.getTree(parent.children, options)
+      }
+    })
+
+    return parents
+  }
+
+  selectChange = (val, option) => {
+    const { config } = this.state
+    let other = {}
+
+    let _value = val.join(config.separator)
+    let _option = option[option.length - 1]
+    
+    if (config.subFields && _option) {
+      config.subFields.forEach((n, i) => {
+        other[n.field] = _option[n.field]
+        setTimeout(() => {
+          MKEmitter.emit('mkFC', 'input', n.uuid, _option[n.field])
+        }, i * 5)
+      })
+    }
+
+    this.props.onChange(_value, other)
+    this.setState({value: val})
+  }
+
+  render() {
+    const { value, options } = this.state
+
+    return (<Cascader defaultValue={value} options={options} onChange={this.selectChange} placeholder="璇烽�夋嫨" />)
+  }
+}
+
+export default MKSelect
\ No newline at end of file
diff --git a/src/templates/menuconfig/editthdmenu/menuform/index.scss b/src/tabviews/zshare/mutilform/mkCascader/index.scss
similarity index 100%
copy from src/templates/menuconfig/editthdmenu/menuform/index.scss
copy to src/tabviews/zshare/mutilform/mkCascader/index.scss
diff --git a/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx b/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx
index d0b2c65..74100ed 100644
--- a/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx
+++ b/src/tabviews/zshare/mutilform/mkCheckCard/index.jsx
@@ -2,6 +2,7 @@
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
 import { Col, Row } from 'antd'
+import { CheckOutlined } from '@ant-design/icons'
 
 import MKEmitter from '@/utils/events.js'
 import './index.scss'
@@ -19,15 +20,28 @@
   }
 
   UNSAFE_componentWillMount() {
-    const { config } = this.props
+    let config = fromJS(this.props.config).toJS()
 
     let selectKeys = config.initval
     if (config.multiple === 'true') {
       selectKeys = config.initval ? config.initval.split(',') : []
     }
 
+    if (!config.selectStyle && config.backgroundColor) {
+      config.selectStyle = 'custom'
+    } else if (!config.selectStyle) {
+      config.selectStyle = 'background'
+    }
+
+    if (config.display === 'picture' && !config.picratio) { // 鍏煎鏃ф暟鎹�
+      config.picratio = config.ratio || '1:1'
+    }
+
+    config.selectClass = ` mk-${config.selectStyle} `
+    config.fields = config.fields || []
+
     this.setState({
-      config: fromJS(config).toJS(),
+      config: config,
       options: fromJS(config.options).toJS(),
       selectKeys: selectKeys
     })
@@ -46,11 +60,11 @@
   }
 
   UNSAFE_componentWillReceiveProps (nextProps) {
-    const { config } = this.props
+    const { config } = this.state
 
     if (!is(fromJS(config.oriOptions), fromJS(nextProps.config.oriOptions))) {
       this.setState({
-        config: fromJS(nextProps.config).toJS(),
+        config: {...config, oriOptions: nextProps.config.oriOptions},
         options: fromJS(nextProps.config.options).toJS()
       })
     }
@@ -163,54 +177,76 @@
 
   getCards = () => {
     const { selectKeys, options, config } = this.state
-    const { display, width, fields, ratio, multiple, backgroundColor, borderColor } = config
+    const { display, width, fields, picratio, multiple, backgroundColor, selectStyle, selectClass } = config
 
-    let paddingTop = '100%'
-    if (ratio === '4:3') {
-      paddingTop = '75%'
-    } else if (ratio === '3:2') {
-      paddingTop = '66.7%'
-    } else if (ratio === '16:9') {
-      paddingTop = '56.25%'
-    }
-
-    let style = borderColor ? {borderColor} : {}
-    let _style = backgroundColor ? {backgroundColor} : null
-
-    if (!options || options.length === 0) {
+    if (options.length === 0) {
       return null
-    } else if (display !== 'picture') {
-      if (!fields || fields.length === 0) {
-        return null
-      }
+    } else if (display === 'color') {
       return options.map(item => {
         let _active = false
-        if (multiple === 'true' && selectKeys.includes(item.$value)) {
-          _active = true
-        } else if (multiple !== 'true' && selectKeys === item.$value) {
-          _active = true
+        if (multiple === 'true') {
+          _active = selectKeys.includes(item.$value)
+        } else {
+          _active = selectKeys === item.$value
         }
 
         return <Col span={width} key={item.key}>
-          <div className={'card-cell' + (_active ? ' active' : '') + (_style ? ' bg-control' : '') + (item.$disabled ? ' disabled' : '')} style={style} onClick={() => this.changeCard(item)}>
+          <div className={'card-color-cell' + (_active ? ' active' : '') + (item.$disabled ? ' disabled' : '')} style={{background: item.$value}} onClick={() => this.changeCard(item)}>
+            {fields.map(col => {
+              return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
+            })}
+            <CheckOutlined />
+          </div>
+        </Col>
+      })
+    } else if (display !== 'picture') {
+      let _style = selectStyle === 'custom' ? {backgroundColor} : null
+
+      return options.map(item => {
+        let _active = false
+        if (multiple === 'true') {
+          _active = selectKeys.includes(item.$value)
+        } else {
+          _active = selectKeys === item.$value
+        }
+
+        return <Col span={width} key={item.key}>
+          <div className={'card-cell' + (_active ? ' active' : '') + selectClass + (item.$disabled ? ' disabled' : '')} onClick={() => this.changeCard(item)}>
             <div className="bg-mask" style={_style}></div>
             {fields.map(col => {
-              return <span key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
+              return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
             })}
           </div>
         </Col>
       })
     } else {
+      let paddingTop = '100%'
+      if (picratio === '4:3') {
+        paddingTop = '75%'
+      } else if (picratio === '3:2') {
+        paddingTop = '66.7%'
+      } else if (picratio === '16:9') {
+        paddingTop = '56.25%'
+      }
+
       return options.map(item => {
         let _active = false
-        if (multiple === 'true' && selectKeys.includes(item.$value)) {
-          _active = true
-        } else if (multiple !== 'true' && selectKeys === item.$value) {
-          _active = true
+        if (multiple === 'true') {
+          _active = selectKeys.includes(item.$value)
+        } else {
+          _active = selectKeys === item.$value
         }
 
         return <Col span={width} key={item.key}>
-          <div className={'card-pic-cell ' + (_active ? 'active' : '') + (item.$disabled ? ' disabled' : '')} onClick={() => this.changeCard(item)} style={{...style, paddingTop, backgroundImage: `url(${item.$url})`}}>
+          <div className={'card-pic-cell ' + (_active ? 'active' : '') + (item.$disabled ? ' disabled' : '')} onClick={() => this.changeCard(item)} style={{paddingTop, backgroundImage: `url(${item.$url})`}}>
+            <div className="content-wrap">
+              <div className="content-center">
+                {fields.map(col => {
+                  return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
+                })}
+              </div>
+              <CheckOutlined />
+            </div>
           </div>
         </Col>
       })
@@ -218,10 +254,16 @@
   }
 
   render() {
-    const { config } = this.state
+    const { config, options } = this.state
+
+    let extend = config.readonly ? 'readonly' : ''
+
+    if (options.length * config.width > 24) {
+      extend += ' mutile-line'
+    }
 
     return (
-      <div className={'check-card-form-box' + (config.readonly ? ' readonly' : '')}>
+      <div className={'check-card-form-box ' + extend}>
         <Row gutter={12}>{this.getCards()}</Row>
       </div>
     )
diff --git a/src/tabviews/zshare/mutilform/mkCheckCard/index.scss b/src/tabviews/zshare/mutilform/mkCheckCard/index.scss
index 1fb51b0..da3fdc4 100644
--- a/src/tabviews/zshare/mutilform/mkCheckCard/index.scss
+++ b/src/tabviews/zshare/mutilform/mkCheckCard/index.scss
@@ -1,64 +1,46 @@
 .check-card-form-box {
   margin-top: 5px;
-  // margin-bottom: -10px;
   .card-cell {
     position: relative;
     border: 1px solid #bcbcbc;
+    background: #ffffff;
     border-radius: 4px;
     padding: 6px;
-    margin-bottom: 12px;
+    margin-bottom: 2px;
     line-height: 1.5;
     transition: all 0.3s;
     cursor: pointer;
-    span {
-      display: block;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-      position: relative;
-      z-index: 1;
-    }
+    
     .bg-mask {
       position: absolute;
       top: 0;
       left: 0;
       right: 0;
       bottom: 0;
-      opacity: 0.5;
+      opacity: 0.6;
       border-radius: 4px;
       background-color: transparent;
       transition: opacity 0.3s;
     }
   }
-  .card-cell:not(.bg-control).active {
-    border-color: #1890ff;
-    background: #1890ff;
+
+  .content-line {
+    display: block;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    position: relative;
+    z-index: 1;
+    line-height: 1.5;
+  }
+  .card-cell.mk-background.active {
+    border-color: var(--mk-sys-color);
+    background: var(--mk-sys-color);
     span {
       color: #ffffff!important;
     }
   }
-  .card-cell.bg-control.active {
-    .bg-mask {
-      opacity: 1;
-    }
-  }
-  .card-pic-cell {
-    position: relative;
-    border: 1px solid #bcbcbc;
-    border-radius: 4px;
-    background-size: cover;
-    background-position: center;
-    margin-bottom: 12px;
-    line-height: 1.5;
-    cursor: pointer;
-    transition: all 0.3s;
-  }
-  .card-pic-cell.active {
-    border-color: #1890ff;
-    box-shadow: 0px 0px 4px #1890ff;
-  }
-
-  .card-cell:not(.bg-control).active::after {
+  .card-cell.mk-background.active::after {
     content: ' ';
     position: absolute;
     display: table;
@@ -71,7 +53,92 @@
     height: 12px;
     transform: rotate(45deg) scale(1) translate(-50%, -50%);
   }
+  .card-cell.mk-font.active {
+    border-color: var(--mk-sys-color);
+    span {
+      color: var(--mk-sys-color)!important;
+    }
+  }
+  .card-cell.mk-custom {
+    border-color: transparent;
+  }
+  .card-cell.mk-custom.active {
+    .bg-mask {
+      opacity: 1;
+    }
+  }
+  .card-pic-cell {
+    position: relative;
+    border: 1px solid #e8e8e8;
+    border-radius: 4px;
+    background-size: cover;
+    background-position: center;
+    margin-bottom: 2px;
+    line-height: 1.5;
+    cursor: pointer;
+    transition: all 0.3s;
+
+    .content-wrap {
+      position: absolute;
+      top: 6px;
+      left: 6px;
+      right: 6px;
+      bottom: 6px;
+      .content-center {
+        position: relative;
+        top: 50%;
+        transform: translate(0px, -50%);
+      }
+    }
+    .anticon-check {
+      display: none;
+      position: absolute;
+      color: #ffffff;
+      border-radius: 20px;
+      padding: 3px;
+      width: 18px;
+      height: 18px;
+      font-size: 12px;
+      right: -2px;
+      bottom: -2px;
+      background: var(--mk-sys-color);
+    }
+  }
+
+  .card-color-cell {
+    position: relative;
+    border: 1px solid transparent;
+    border-radius: 4px;
+    padding: 6px;
+    margin-bottom: 2px;
+    min-height: 35px;
+    cursor: pointer;
+
+    .anticon-check {
+      display: none;
+      position: absolute;
+      color: #ffffff;
+      border-radius: 20px;
+      padding: 3px;
+      width: 18px;
+      height: 18px;
+      font-size: 12px;
+      right: 0px;
+      bottom: 0px;
+      background: var(--mk-sys-color);
+    }
+  }
+
+  .card-pic-cell.active, .card-color-cell.active {
+    .anticon-check {
+      display: inline-block;
+    }
+  }
+
   .card-cell.disabled {
+    cursor: not-allowed;
+  }
+  .card-color-cell.disabled {
     cursor: not-allowed;
   }
   .card-pic-cell.disabled {
@@ -79,22 +146,41 @@
   }
 }
 
+.check-card-form-box.mutile-line {
+  .card-cell {
+    margin-bottom: 12px;
+  }
+  .card-pic-cell {
+    margin-bottom: 12px;
+  }
+  .card-color-cell {
+    margin-bottom: 12px;
+  }
+}
+
 .check-card-form-box:not(.readonly) {
-  .card-cell:not(.bg-control):not(.disabled):hover {
-    border-color: #1890ff;
-    background: #1890ff;
+  .card-cell.mk-background:not(.disabled):hover {
+    border-color: var(--mk-sys-color);
+    background: var(--mk-sys-color);
     span {
       color: #ffffff!important;
     }
   }
-  .card-cell.bg-control:not(.active):not(.disabled):hover {
+  .card-cell.mk-font:not(.disabled):hover {
+    border-color: var(--mk-sys-color);
+    span {
+      color: var(--mk-sys-color)!important;
+    }
+  }
+
+  .card-cell.mk-custom:not(.active):not(.disabled):hover {
     .bg-mask {
-      opacity: 0.7;
+      opacity: 0.8;
     }
   }
   .card-pic-cell:not(.disabled):hover {
-    border-color: #1890ff;
-    box-shadow: 0px 0px 4px #1890ff;
+    border-color: var(--mk-sys-color);
+    box-shadow: 0px 0px 4px var(--mk-sys-color);
   }
 }
 .check-card-form-box.readonly {
diff --git a/src/tabviews/zshare/mutilform/mkDatePicker/index.jsx b/src/tabviews/zshare/mutilform/mkDatePicker/index.jsx
index a3d0899..6643b2b 100644
--- a/src/tabviews/zshare/mutilform/mkDatePicker/index.jsx
+++ b/src/tabviews/zshare/mutilform/mkDatePicker/index.jsx
@@ -37,7 +37,7 @@
 
     this.state = {
       value,
-      minDate: config.minDate ? moment().add(config.minDate, 'days').endOf('day') : '',
+      minDate: config.minDate ? moment().add(config.minDate, 'days').startOf('day') : '',
       maxDate: config.maxDate ? moment().add(config.maxDate, 'days').endOf('day') : '',
       mode,
       format
@@ -76,7 +76,7 @@
     if (!current || (!maxDate && !minDate)) {
       return false
     }
-    
+
     if (!maxDate) {
       return current < minDate
     } else if (!minDate) {
diff --git a/src/tabviews/zshare/mutilform/mkFormula/index.jsx b/src/tabviews/zshare/mutilform/mkFormula/index.jsx
new file mode 100644
index 0000000..890a03e
--- /dev/null
+++ b/src/tabviews/zshare/mutilform/mkFormula/index.jsx
@@ -0,0 +1,44 @@
+import React, { Component } from 'react'
+// import { is, fromJS } from 'immutable'
+
+// import './index.scss'
+
+/**
+ * @description 鍏紡
+ */
+class MkFormula extends Component {
+  constructor(props) {
+    super(props)
+    
+    this.state = {}
+  }
+
+  render() {
+    const { config, data } = this.props
+
+    if (!data) return null
+    
+    let _val = config.formula
+    Object.keys(data).forEach(key => {
+      let reg = new RegExp('@' + key + '@', 'ig')
+      _val = _val.replace(reg, data[key])
+    })
+
+    if (config.eval !== 'false') {
+      try {
+        // eslint-disable-next-line
+        _val = eval(_val)
+      } catch (e) {
+        _val = ''
+      }
+    }
+
+    if (config.postfix && _val !== '') {
+      _val = _val + config.postfix
+    }
+
+    return <div className="message" style={config.style}>{_val}</div>
+  }
+}
+
+export default MkFormula
\ No newline at end of file
diff --git a/src/templates/menuconfig/editthdmenu/menuform/index.scss b/src/tabviews/zshare/mutilform/mkFormula/index.scss
similarity index 100%
copy from src/templates/menuconfig/editthdmenu/menuform/index.scss
copy to src/tabviews/zshare/mutilform/mkFormula/index.scss
diff --git a/src/tabviews/zshare/mutilform/mkNumberInput/index.jsx b/src/tabviews/zshare/mutilform/mkNumberInput/index.jsx
index 4b690c8..68e1a62 100644
--- a/src/tabviews/zshare/mutilform/mkNumberInput/index.jsx
+++ b/src/tabviews/zshare/mutilform/mkNumberInput/index.jsx
@@ -37,6 +37,7 @@
 
   mkFormHandle = (type, uuid, value) => {
     if (uuid !== this.props.config.uuid) return
+
     if (type === 'focus') {
       let node = document.getElementById(uuid)
       node.select()
diff --git a/src/tabviews/zshare/normalTable/index.jsx b/src/tabviews/zshare/normalTable/index.jsx
index 9c42ac2..555c45c 100644
--- a/src/tabviews/zshare/normalTable/index.jsx
+++ b/src/tabviews/zshare/normalTable/index.jsx
@@ -1,7 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import md5 from 'md5'
-import { connect } from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { Table, Affix, Typography } from 'antd'
 
@@ -61,7 +60,7 @@
   }
 
   UNSAFE_componentWillMount () {
-    const { menuType, memberLevel, pageSize, setting } = this.props
+    const { pageSize, setting } = this.props
     let columns = fromJS(this.props.columns).toJS()
     let lineMarks = []
     let _columns = []
@@ -105,12 +104,12 @@
         _columns.push(cell)
       })
     } else {
-      if (window.GLOB.dataFormat && menuType !== 'HS' && memberLevel) {
+      if (window.GLOB.dataFormat && !window.GLOB.mkHS) {
         _format = true
   
-        if (memberLevel >= 30) {
+        if (window.GLOB.memberLevel >= 30) {
           radio = 20
-        } else if (memberLevel >= 20) {
+        } else if (window.GLOB.memberLevel >= 20) {
           radio = 10
         }
       }
@@ -401,40 +400,30 @@
     let icon = ''
 
     marks.some(mark => {
-      let originVal = record[mark.field] + ''
+      let originVal = record[mark.field]
       let contrastVal = ''
       if (mark.contrastType === 'static') {
-        contrastVal = mark.contrastValue + ''
+        contrastVal = mark.contrastValue
       } else {
-        contrastVal = record[mark.contrastField] + ''
+        contrastVal = record[mark.contrastField]
       }
+
+      if (originVal === undefined || contrastVal === undefined) return false
 
       if (mark.match === '=') {
         className = originVal === contrastVal ? mark.color[1] : ''
       } else if (mark.match === '!=') {
         className = originVal !== contrastVal ? mark.color[1] : ''
       } else if (mark.match === 'like') {
+        originVal = originVal + ''
+        contrastVal = contrastVal + ''
         className = originVal.indexOf(contrastVal) > -1 ? mark.color[1] : ''
       } else if (mark.match === '>') {
-        try {
-          originVal = parseFloat(originVal)
-          contrastVal = parseFloat(contrastVal)
-        } catch (e) {
-          originVal = NaN
-        }
-
-        if (!isNaN(originVal) && !isNaN(contrastVal) && originVal > contrastVal) {
+        if (parseFloat(originVal) > parseFloat(contrastVal)) {
           className = mark.color[1]
         }
       } else if (mark.match === '<') {
-        try {
-          originVal = parseFloat(originVal)
-          contrastVal = parseFloat(contrastVal)
-        } catch (e) {
-          originVal = NaN
-        }
-
-        if (!isNaN(originVal) && !isNaN(contrastVal) && originVal < contrastVal) {
+        if (parseFloat(originVal) < parseFloat(contrastVal)) {
           className = mark.color[1]
         }
       }
@@ -749,7 +738,6 @@
                   btn={btn}
                   BID={record.$$BID}
                   disabled={record.$disabled}
-                  lineId={record.$$key || ''}
                   selectedData={[record]}
                   BData={this.props.BData}
                   setting={this.props.setting}
@@ -764,7 +752,6 @@
                   btn={btn}
                   BID={record.$$BID}
                   disabled={record.$disabled}
-                  lineId={record.$$key || ''}
                   selectedData={[record]}
                   BData={this.props.BData}
                   setting={this.props.setting}
@@ -776,7 +763,6 @@
                   key={btn.uuid}
                   btn={btn}
                   disabled={record.$disabled}
-                  lineId={record.$$key || ''}
                   selectedData={[record]}
                   BData={this.props.BData}
                   MenuID={this.props.MenuID}
@@ -789,7 +775,6 @@
                   key={btn.uuid}
                   btn={btn}
                   disabled={record.$disabled}
-                  lineId={record.$$key || ''}
                   selectedData={[record]}
                   BData={this.props.BData}
                   setting={this.props.setting}
@@ -1049,11 +1034,12 @@
    * 
    */
   onSelectChange = selectedRowKeys => {
-    const { setting } = this.props
+    const { setting, data } = this.props
 
     let index = ''
     let _activeIndex = null
     if (selectedRowKeys.length > 0) {
+      selectedRowKeys = selectedRowKeys.filter(key => !data[key].$disabled)
       index = selectedRowKeys.slice(-1)[0]
     }
 
@@ -1065,7 +1051,7 @@
 
     this.setState({ selectedRowKeys, activeIndex: _activeIndex })
 
-    let selects = this.props.data.filter((item, _index) => selectedRowKeys.includes(_index) && !item.$disabled)
+    let selects = data.filter((item, _index) => selectedRowKeys.includes(_index) && !item.$disabled)
 
     this.props.chgSelectData(selects)
   }
@@ -1210,7 +1196,7 @@
     if (!setting.doubleClick) return
     if (record.$disabled) return
 
-    MKEmitter.emit('triggerBtnId', setting.doubleClick, [record])
+    MKEmitter.emit('triggerBtnId', setting.doubleClick, [record], 'linkbtn')
   }
 
   render() {
@@ -1397,15 +1383,4 @@
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    menuType: state.editLevel,
-    memberLevel: state.memberLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(NormalTable)
\ No newline at end of file
+export default NormalTable
\ No newline at end of file
diff --git a/src/tabviews/zshare/topSearch/advanceform/index.jsx b/src/tabviews/zshare/topSearch/advanceform/index.jsx
index ae479bd..b8b3023 100644
--- a/src/tabviews/zshare/topSearch/advanceform/index.jsx
+++ b/src/tabviews/zshare/topSearch/advanceform/index.jsx
@@ -52,7 +52,7 @@
 
       if (content) {
         fields.push(
-          <Col span={item.ratio || 6} key={index}>
+          <Col className="mk-search-col" span={item.ratio || 6} key={index}>
             <Form.Item
               labelCol={item.labelCol}
               wrapperCol={item.wrapperCol}
diff --git a/src/tabviews/zshare/topSearch/advanceform/index.scss b/src/tabviews/zshare/topSearch/advanceform/index.scss
index 50a24d0..b16452d 100644
--- a/src/tabviews/zshare/topSearch/advanceform/index.scss
+++ b/src/tabviews/zshare/topSearch/advanceform/index.scss
@@ -1,10 +1,16 @@
 .advance-search {
   background: #ffffff;
   margin-bottom: 35px;
+
+  .mk-search-col {
+    display: inline-block;
+    float: none;
+    vertical-align: top;
+  }
   .ant-form-item {
     display: flex;
     margin-bottom: 0px;
-    min-height: 60px;
+    min-height: 55px;
     .ant-form-explain {
       white-space: nowrap;
     }
@@ -26,6 +32,18 @@
   .ant-calendar-picker-container {
     z-index: 10 !important;
   }
+  .check-card-form-box {
+    .no-margin-bottom {
+      margin-bottom: 0px;
+    }
+    .card-cell {
+      padding: 4px 6px;
+    }
+    .card-color-cell {
+      padding: 4px 6px;
+      min-height: 32px;
+    }
+  }
   .advance-button {
     position: absolute;
     left: 0;
diff --git a/src/tabviews/zshare/topSearch/dategroup/index.scss b/src/tabviews/zshare/topSearch/dategroup/index.scss
index c13982b..59410f2 100644
--- a/src/tabviews/zshare/topSearch/dategroup/index.scss
+++ b/src/tabviews/zshare/topSearch/dategroup/index.scss
@@ -43,6 +43,7 @@
     border-radius: 2px;
     margin-right: 2px;
     padding: 2px 6px;
+    background: #ffffff;
   }
   .ant-tag-checkable:active {
     background-color: #ffffff;
diff --git a/src/tabviews/zshare/topSearch/index.jsx b/src/tabviews/zshare/topSearch/index.jsx
index 58e423a..421f356 100644
--- a/src/tabviews/zshare/topSearch/index.jsx
+++ b/src/tabviews/zshare/topSearch/index.jsx
@@ -1,8 +1,8 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { is, fromJS } from 'immutable'
-import { Form, Row, Col, Button, notification, Modal } from 'antd'
-import { CloseOutlined } from '@ant-design/icons'
+import { fromJS } from 'immutable'
+import { Form, Row, Col, Button, notification, Modal, Drawer } from 'antd'
+import { CloseOutlined, DownOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import Api from '@/api'
@@ -10,8 +10,6 @@
 import asyncComponent from '@/utils/asyncComponent'
 import asyncSpinComponent from '@/utils/asyncSpinComponent'
 import Utils from '@/utils/utils.js'
-import zhCN from '@/locales/zh-CN/main.js'
-import enUS from '@/locales/en-US/main.js'
 import MKInput from './mkInput'
 import './index.scss'
 
@@ -24,7 +22,6 @@
 class MainSearch extends Component {
   static propTpyes = {
     BID: PropTypes.any,          // 鐖剁骇Id锛岀敤浜庢煡璇笅鎷夐�夋嫨椤�
-    menuType: PropTypes.any,     // 鑿滃崟鏉冮檺锛屾槸鍚︿负HS
     searchlist: PropTypes.array, // 鎼滅储鏉′欢鍒楄〃
     config: PropTypes.object,    // 缁勪欢閰嶇疆淇℃伅(鑷畾涔夐〉闈�)
     setting: PropTypes.object,   // 缁勪欢閰嶇疆淇℃伅(鑷畾涔夐〉闈�)
@@ -32,70 +29,89 @@
   }
 
   state = {
-    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
     searchlist: null,        // 鎼滅储椤�
-    reset: true,             // 鎺у埗缁勫悎鎼滅储椤归噸缃�
-    float: '',               // 娴姩
-    showButton: true,        // 鏄惁鏄剧ず鎼滅储鎸夐挳
-    showAdvanced: false,     // 鏄惁鏄剧ず楂樼骇鎼滅储
-    searchStyle: null,       // 鎼滅储鏉′欢鏍峰紡
+    setting: {},
     advanceValues: [],       // 楂樼骇鎼滅储鏉′欢淇濆瓨鍊�
     visible: false,
-    adModelWidth: '1000px',
     hasReqFields: false
   }
 
   record = {}
 
   UNSAFE_componentWillMount () {
-    const { config, menuType, searchlist, setting } = this.props
+    const { config, searchlist, setting } = this.props
 
     let _searchlist = []
     let fieldMap = new Map()
     let mainItems = []  // 浜戠鎴栧崟鐐规暟鎹�
     let localItems = [] // 鏈湴鏁版嵁
     let deForms = []    // 娴嬭瘯绯荤粺锛屽崟涓姹�
-    let float = ''
-    let showButton = true
-    let searchStyle = null
     let advanceValues = []
-    let showAdvanced = false
-    let adModelWidth = 1000
     let linkFields = {}
     let record = {}
     let hasReqFields = false
 
-    if (setting && setting.advanceWidth) {
-      adModelWidth = setting.advanceWidth
-    } else if (config && config.wrap && config.wrap.advanceWidth) {
-      adModelWidth = config.wrap.advanceWidth
+    let forbid = false // header涓笉璁剧疆楂樼骇鎼滅储
+    let _setting = {showAdv: false, show: false}
+    
+    if (setting) {
+      _setting.show = setting.show !== 'false'
+      _setting.float = setting.float || 'left'
+      _setting.advanceType = setting.advanceType || 'modal'
+      _setting.advWidth = setting.advanceWidth || 1000
+      _setting.placement = setting.drawerPlacement || 'right'
+      _setting.ratio = setting.searchRatio || 6
+      _setting.labelwidth = setting.searchLwidth !== undefined ? setting.searchLwidth : 33.3
+      _setting.labelCol = {style: {width: _setting.labelwidth + '%'}}
+      _setting.wrapperCol = {style: {width: (100 - _setting.labelwidth) + '%'}}
+      _setting.style = null
+    } else if (config) {
+      if (config.wrap) {
+        _setting.show = config.wrap.show !== 'false'
+        _setting.advanceType = config.wrap.advanceType || 'modal'
+        _setting.advWidth = config.wrap.advanceWidth || 1000
+        _setting.placement = config.wrap.drawerPlacement || 'right'
+        _setting.ratio = config.wrap.searchRatio || 6
+        _setting.labelwidth = config.wrap.searchLwidth !== undefined ? config.wrap.searchLwidth : 33.3
+        _setting.labelCol = {style: {width: _setting.labelwidth + '%'}}
+        _setting.wrapperCol = {style: {width: (100 - _setting.labelwidth) + '%'}}
+      }
+      _setting.style = null
+      
+      if (config.type === 'search') {
+        _setting.float = config.wrap.float || 'left'
+        _setting.style = config.style
+      } else if (config.type === 'table' && (config.subtype === 'normaltable' || config.subtype === 'editable')) {
+        _setting.float = 'left'
+      } else {
+        _setting.float = 'right'
+        _setting.show = false
+        forbid = true
+      }
     }
 
-    if (adModelWidth < 100) {
-      adModelWidth = adModelWidth + 'vw'
-    } else {
-      adModelWidth = adModelWidth + 'px'
+    if (_setting.advanceType === 'drawer' && _setting.advWidth) {
+      if (_setting.placement === 'top' || _setting.placement === 'bottom') {
+        _setting.advHeight = _setting.advWidth > 100 ? _setting.advWidth + 'px' : _setting.advWidth + 'vh'
+        _setting.advWidth = '100vw'
+      } else {
+        _setting.advWidth = _setting.advWidth > 100 ? _setting.advWidth + 'px' : _setting.advWidth + 'vw'
+      }
+    } else if (_setting.advanceType === 'modal' && _setting.advWidth) {
+      if (_setting.advWidth < 100) {
+        _setting.advWidth = _setting.advWidth + 'vw'
+      } else {
+        _setting.advWidth = _setting.advWidth + 'px'
+      }
     }
 
     if (searchlist) {
-      if (setting && setting.show === 'false') {
-        showButton = false
-      }
       _searchlist = fromJS(searchlist).toJS()
     } else if (config) {
       _searchlist = fromJS(config.search).toJS()
-      if (config.type === 'search' && config.subtype === 'mainsearch') {
-        float = config.wrap.float
-        showButton = config.wrap.show !== 'false'
-        searchStyle = config.style
-      } else {
-        showButton = false
-        float = 'right'
-      }
     }
 
     _searchlist.forEach(item => {
-      // if (item.type === 'link') {
       if (item.linkField) {
         linkFields[item.linkField] = linkFields[item.linkField] || []
         linkFields[item.linkField].push({field: item.field, uuid: item.uuid})
@@ -116,8 +132,8 @@
         hasReqFields = true
       }
 
-      if (showButton && item.advanced) {
-        showAdvanced = true
+      if (item.advanced && !forbid) {
+        _setting.showAdv = true
       } else {
         item.advanced = false
       }
@@ -143,6 +159,7 @@
       
       if (['select', 'link', 'multiselect', 'checkcard'].includes(item.type)) {
         item.options = item.options || []
+        item.options = item.options.filter(op => !op.Hide)
         if (item.setAll === 'true' && ['select', 'link'].includes(item.type)) {
           item.options.unshift({
             key: Utils.getuuid(),
@@ -157,7 +174,7 @@
           let _option = Utils.getSelectQueryOptions(item)
 
           // 娴嬭瘯绯荤粺鍗曚釜璇锋眰
-          if (menuType !== 'HS' && options.sysType === 'local' && !window.GLOB.systemType) {
+          if (!window.GLOB.mkHS && options.sysType === 'local' && !window.GLOB.systemType) {
             deForms.push({
               ...item,
               arr_field: _option.field,
@@ -206,16 +223,12 @@
     })
 
     this.setState({
-      float,
-      showButton,
-      searchStyle,
+      setting: _setting,
       hasReqFields,
-      showAdvanced,
-      adModelWidth,
       advanceValues,
       searchlist: _list
     }, () => {
-      if (menuType !== 'HS' && options.sysType === 'local' && !window.GLOB.systemType) {
+      if (!window.GLOB.mkHS && options.sysType === 'local' && !window.GLOB.systemType) {
         this.improveSimpleSearch(deForms)
       } else {
         this.improveSearch(mainItems, localItems)
@@ -223,16 +236,12 @@
     })
   }
 
-  shouldComponentUpdate (nextProps, nextState) {
-    return !is(fromJS(this.state), fromJS(nextState))
-  }
-
   // 鏌ヨ涓嬫媺鑿滃崟
   improveSearch = (mainItems, localItems) => {
-    const { menuType, BID } = this.props
+    const { BID } = this.props
     let deffers = []
 
-    if (menuType !== 'HS' && window.GLOB.systemType !== 'production') {
+    if (!window.GLOB.mkHS && window.GLOB.systemType !== 'production') {
       localItems = [...localItems, ...mainItems]
       mainItems = []
     }
@@ -255,7 +264,7 @@
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
       param.secretkey = Utils.encrypt(param.LText, param.timestamp)
 
-      if (menuType === 'HS') { // 浜戠鏁版嵁楠岃瘉
+      if (window.GLOB.mkHS) { // 浜戠鏁版嵁楠岃瘉
         param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
       }
 
@@ -293,7 +302,7 @@
       mainparam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
       mainparam.secretkey = Utils.encrypt(mainparam.LText, mainparam.timestamp)
 
-      if (menuType === 'HS') { // 浜戠鏁版嵁楠岃瘉
+      if (window.GLOB.mkHS) { // 浜戠鏁版嵁楠岃瘉
         mainparam.open_key = Utils.encryptOpenKey(mainparam.secretkey, mainparam.timestamp)
         if (options.cloudServiceApi) {
           mainparam.rduri = options.cloudServiceApi
@@ -468,12 +477,11 @@
 
   getFields() {
     const { getFieldDecorator } = this.props.form
-    const { dict, showButton, showAdvanced, float, visible } = this.state
+    const { visible, setting } = this.state
     const fields = []
-    let lastRadio = 6
 
     this.state.searchlist.forEach((item, index) => {
-      if (item.hidden || item.advanced) return
+      if (item.hidden || (item.advanced && (setting.advanceType !== 'pulldown' || !visible))) return
 
       const _rules = [
         {
@@ -483,9 +491,7 @@
       ]
 
       let content = null
-      let className = ''
       let field = item.field
-      lastRadio = item.ratio || 6
 
       if (item.type === 'text') {
         content = (<MKInput config={item} onInputSubmit={this.handleSubmit} />)
@@ -497,15 +503,13 @@
         field = item.datefield
         content = <DateGroup position={index} config={item} onChange={(val, type) => this.dateGroupChange(val, type, item)} />
       } else if (item.type === 'checkcard') {
-        className = 'checkcard'
         content = <MKCheckCard config={item} onChange={(val) => this.cardChange(val, item)} />
       }
 
       if (content) {
         fields.push(
-          <Col span={item.ratio || 6} key={index}>
+          <Col className="mk-search-col" span={item.ratio || 6} key={index}>
             <Form.Item
-              className={className}
               label={item.labelShow !== 'false' ? item.label : ''}
               labelCol={item.labelCol}
               wrapperCol={item.wrapperCol}
@@ -520,34 +524,71 @@
       }
     })
 
-    if (showButton) {
-      let action = (
-        <Col span={lastRadio < 6 ? 6 : lastRadio} style={{ whiteSpace: 'nowrap' }} className="search-button" key="actions">
-          <Form.Item label={' '} colon={false} style={{ minHeight: '40px' }}>
-            <Button type="primary" onClick={this.handleSubmit}>
-              {dict['main.search']}
-            </Button>
-            <Button style={{ marginLeft: 8 }} onClick={this.handleReset}>
-              {dict['main.reset']}
-            </Button>
-            {showAdvanced && !visible ? <Button type="link" onClick={this.handleAdvance}>
-              楂樼骇
+    if (setting.show || setting.showAdv) {
+      fields.push(
+        <Col span={setting.ratio} style={{ whiteSpace: 'nowrap' }} className="mk-search-col search-button" key="actions">
+          <Form.Item
+            label={' '}
+            colon={false}
+            labelCol={setting.labelCol}
+            wrapperCol={setting.wrapperCol}
+          >
+            {setting.show ? <Button type="primary" onClick={this.handleSubmit}>
+              鎼滅储
+            </Button> : null}
+            {setting.show ? <Button style={{ marginLeft: 8 }} onClick={this.handleReset}>
+              閲嶇疆
+            </Button> : null}
+            {setting.showAdv ? <Button className={visible ? 'visible' : ''} type="link" onClick={this.handleAdvance}>
+              楂樼骇{setting.advanceType === 'pulldown' ? <DownOutlined /> : null}
             </Button> : null}
           </Form.Item>
         </Col>
       )
-      if (float === 'right') {
-        fields.unshift(action)
-      } else {
-        fields.push(action)
-      }
     }
     
     return fields
   }
 
   handleAdvance = () => {
-    this.setState({visible: true})
+    const { setting, visible } = this.state
+
+    if (setting.advanceType !== 'pulldown' && visible) {
+      return
+    }
+
+    this.setState({visible: !visible})
+
+    if (setting.advanceType === 'pulldown') {
+      if (visible) {
+        let advanceValues = []
+        this.state.searchlist.forEach(item => {
+          if (!item.advanced) return
+    
+          let val = this.record[item.field]
+          if (val || val === 0) {
+            if (item.precision === 'hour') {
+              if (/,/ig.test(val)) {
+                val = val.split(',').map(m => m + ':00').join(',')
+              } else {
+                val = val + ':00'
+              }
+            }
+            advanceValues.push({field: item.field, type: item.type, label: item.label, value: val})
+          }
+        })
+        this.setState({advanceValues})
+      } else {
+        let list = this.state.searchlist.map(item => {
+          if (!item.advanced) return item
+    
+          item.initval = this.record[item.field]
+          
+          return item
+        })
+        this.setState({searchlist: list})
+      }
+    }
   }
 
   handleSubmit = () => {
@@ -572,7 +613,7 @@
       
             notification.warning({
               top: 92,
-              message: this.state.dict['form.required.input'] + labels.join('銆�') + ' !',
+              message: '璇疯緭鍏�' + labels.join('銆�') + ' !',
               duration: 3
             })
             return
@@ -660,6 +701,8 @@
         } else if (type === 'text' && !error) {
           if (/'/ig.test(val)) {
             error = `鎼滅储鏉′欢${item.label}涓紝涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙枫�俙
+          } else if (/--/ig.test(val)) {
+            error = `鎼滅储鏉′欢${item.label}涓紝涓嶅彲浣跨敤 -- 銆俙
           } else if (/(^|\s)select\s/ig.test(val)) {
             error = `鎼滅储鏉′欢${item.label}涓紝涓嶅彲浣跨敤鍏抽敭瀛梥elect銆俙
           } else if (/\sfrom(\s|\()/ig.test(val)) {
@@ -737,7 +780,7 @@
   }
 
   render() {
-    const { float, searchStyle, visible, searchlist, showAdvanced, advanceValues, adModelWidth } = this.state
+    const { visible, searchlist, advanceValues, setting } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -751,10 +794,10 @@
 
     return (
       <>
-        <Form {...formItemLayout} className={`top-search ${float}`} style={searchStyle}>
+        <Form {...formItemLayout} className={`top-search mk-float-${setting.float}`} style={setting.style}>
           <Row gutter={24}>{this.getFields()}</Row>
-          <Row gutter={24}>
-            {showAdvanced ? <div className="advanced-list">
+          {advanceValues.length && (setting.advanceType !== 'pulldown' || (setting.advanceType === 'pulldown' && !visible)) ? <Row gutter={24}>
+            <div className="advanced-list">
               {advanceValues.map((item, index) => {
                 return (
                   <div key={index}>
@@ -763,14 +806,14 @@
                     <CloseOutlined onClick={() => this.closeAdvanceForm(item)} />
                   </div>)
               })}
-            </div> : null}
-          </Row>
+            </div>
+          </Row> : null}
         </Form>
-        <Modal
+        {setting.advanceType === 'modal' ? <Modal
           title="楂樼骇鎼滅储"
           maskClosable={false}
           visible={visible}
-          width={adModelWidth}
+          width={setting.advWidth}
           closable={false}
           footer={null}
           destroyOnClose
@@ -781,7 +824,25 @@
             advanceSubmit={this.handleOk}
             handleClose={() => this.setState({visible: false})}
           />
-        </Modal>
+        </Modal> : null}
+        {setting.advanceType === 'drawer' ? <Drawer
+          title="楂樼骇鎼滅储"
+          className="mk-search-drawer"
+          width={setting.advWidth}
+          height={setting.advHeight}
+          maskClosable={false}
+          onClose={() => this.setState({visible: false})}
+          visible={visible}
+          placement={setting.placement}
+          destroyOnClose
+        >
+          <MutilForm
+            searchlist={searchlist}
+            record={this.record}
+            advanceSubmit={this.handleOk}
+            handleClose={() => this.setState({visible: false})}
+          />
+        </Drawer> : null}
       </>
     )
   }
diff --git a/src/tabviews/zshare/topSearch/index.scss b/src/tabviews/zshare/topSearch/index.scss
index 6529efb..1d7e1bc 100644
--- a/src/tabviews/zshare/topSearch/index.scss
+++ b/src/tabviews/zshare/topSearch/index.scss
@@ -1,16 +1,17 @@
 .top-search {
   background: #ffffff;
+
+  .mk-search-col {
+    display: inline-block;
+    float: none;
+    vertical-align: top;
+  }
   .ant-form-item {
     display: flex;
     margin-bottom: 0px;
-    min-height: 60px;
+    min-height: 55px;
     .ant-form-explain {
       white-space: nowrap;
-    }
-  }
-  .ant-form-item.checkcard {
-    .ant-form-item-control {
-      line-height: 1;
     }
   }
   .ant-form-item-control-wrapper {
@@ -41,8 +42,20 @@
       content: '*';
     }
   }
+  .check-card-form-box {
+    .no-margin-bottom {
+      margin-bottom: 0px;
+    }
+    .card-cell {
+      padding: 4px 6px;
+    }
+    .card-color-cell {
+      padding: 4px 6px;
+      min-height: 32px;
+    }
+  }
   .search-button {
-    min-height: 60px;
+    min-height: 55px;
     .ant-btn-link, .ant-btn-link:hover, .ant-btn-link:active{
       border-color: transparent;
       span {
@@ -54,16 +67,25 @@
       height: auto;
       min-height: 28px;
     }
+    .anticon-down {
+      transition: transform 0.3s;
+      margin-left: 2px;
+    }
+    .visible {
+      .anticon-down {
+        transform: rotate(180deg);
+      }
+    }
   }
   .advanced-list {
     font-size: 13px;
-    padding: 0 12px;
+    padding: 2px 12px;
+    text-align: left;
     > div {
       display: inline-block;
       margin-right: 10px;
-      border: 1px solid #dddddd;
       padding: 0 4px 0 4px;
-      background: rgba(0, 0, 0, 0.02);
+      box-shadow: 0 0 2px #dddddd;
 
       .anticon-close {
         margin-left: 5px;
@@ -92,10 +114,30 @@
     margin-top: 3px;
   }
 }
-.top-search.right {
+.top-search.mk-float-right {
   >.ant-row {
-    >.ant-col {
-      float: right;
+    text-align: right;
+  }
+}
+.mk-search-drawer {
+  .ant-drawer-wrapper-body {
+    position: relative;
+  }
+  .ant-drawer-header {
+    position: absolute;
+    top: 0;
+    width: 100%;
+  }
+  .ant-drawer-body {
+    padding-bottom: 50px;
+    position: relative;
+    min-height: calc(100% - 60px);
+    margin-top: 55px;
+    .advance-button {
+      background: #ffffff;
+    }
+    .advance-search {
+      margin-bottom: 15px;
     }
   }
 }
diff --git a/src/templates/calendarconfig/index.jsx b/src/templates/calendarconfig/index.jsx
index 8f8f352..fdceaff 100644
--- a/src/templates/calendarconfig/index.jsx
+++ b/src/templates/calendarconfig/index.jsx
@@ -1,6 +1,5 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import {connect} from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { DndProvider } from 'react-dnd'
 import HTML5Backend from 'react-dnd-html5-backend'
@@ -56,6 +55,7 @@
     activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
     openEdition: '',         // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
     mockdata: [],            // 娴嬭瘯鏁版嵁
+    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   /**
@@ -129,6 +129,15 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
+        if (this.state.modalStatus) {
+          notification.warning({
+            top: 92,
+            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            duration: 5
+          })
+          return false
+        }
+
         let node = document.getElementById('save-config')
         if (node && node.click) {
           node.click()
@@ -136,6 +145,7 @@
         return false
       }
     }
+    MKEmitter.addListener('modalStatus', this.modalStatus)
   }
 
   getMockData = (year) => {
@@ -238,6 +248,11 @@
       return
     }
     document.onkeydown = () => {}
+    MKEmitter.removeListener('modalStatus', this.modalStatus)
+  }
+
+  modalStatus = (val) => {
+    this.setState({modalStatus: val})
   }
 
   // 椤甸潰杩斿洖
@@ -800,7 +815,7 @@
                 <EditComponent dict={this.state.dict} type="table" options={['search', 'form']} config={this.state.config}/>
                 <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={this.state.config.enabled} onChange={this.onEnabledChange} />
                 <Button type="primary" id="save-config" onClick={this.submitConfig} loading={this.state.menuloading}>{this.state.dict['model.save']}</Button>
-                <Button onClick={this.cancelConfig}>{this.state.dict['model.back']}</Button>
+                <Button onClick={this.cancelConfig}>鍏抽棴</Button>
               </div>
             } style={{ width: '100%' }}>
               <SettingComponent
@@ -844,14 +859,4 @@
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    memberLevel: state.memberLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(SubTableConfig)
+export default SubTableConfig
diff --git a/src/templates/calendarconfig/index.scss b/src/templates/calendarconfig/index.scss
index dcfe8d0..a03c742 100644
--- a/src/templates/calendarconfig/index.scss
+++ b/src/templates/calendarconfig/index.scss
@@ -1,6 +1,6 @@
 .model-calendar-board {
   position: fixed;
-  z-index: 1070;
+  z-index: 1;
   padding-top: 48px;
   top: 0px;
   left: 0px;
diff --git a/src/templates/calendarconfig/source.jsx b/src/templates/calendarconfig/source.jsx
index fb3bceb..e009ac0 100644
--- a/src/templates/calendarconfig/source.jsx
+++ b/src/templates/calendarconfig/source.jsx
@@ -106,13 +106,13 @@
     },
     {
       type: 'search',
-      label: CommonDict['model.form.dateday'],
+      label: '鏃ユ湡锛堝ぉ锛�',
       subType: 'date',
       url: ''
     },
     {
       type: 'search',
-      label: CommonDict['model.form.dateweek'],
+      label: '鏃ユ湡锛堝懆锛�',
       subType: 'dateweek',
       url: ''
     },
diff --git a/src/templates/comtableconfig/index.jsx b/src/templates/comtableconfig/index.jsx
index f36afd9..7ec73f5 100644
--- a/src/templates/comtableconfig/index.jsx
+++ b/src/templates/comtableconfig/index.jsx
@@ -1,6 +1,5 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { connect } from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { DndProvider } from 'react-dnd'
 import HTML5Backend from 'react-dnd-html5-backend'
@@ -64,7 +63,8 @@
     thawButtons: [],         // 宸查�夋嫨瑕佽В鍐荤殑鎸夐挳
     activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
     chartview: null,         // 褰撳墠瑙嗗浘
-    openEdition: ''          // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
+    openEdition: '',         // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
+    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   /**
@@ -79,9 +79,6 @@
 
     if (!_LongParam) {
       _config = fromJS(Source.baseConfig).toJS()
-      if (!menu.isSubtable) { // 涓嶆槸閫夋嫨涓诲瓙琛ㄦ椂锛岄殣钘忔爣绛鹃〉
-        _config.tabgroups = [{ uuid: 'tabs', sublist: [] }]
-      }
       _config.isAdd = true
     } else {
       _config = _LongParam
@@ -169,6 +166,15 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
+        if (this.state.modalStatus) {
+          notification.warning({
+            top: 92,
+            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            duration: 5
+          })
+          return false
+        }
+
         let node = document.getElementById('save-config')
         if (node && node.click) {
           node.click()
@@ -176,6 +182,8 @@
         return false
       }
     }
+
+    MKEmitter.addListener('modalStatus', this.modalStatus)
   }
 
   /**
@@ -186,6 +194,11 @@
       return
     }
     document.onkeydown = () => {}
+    MKEmitter.removeListener('modalStatus', this.modalStatus)
+  }
+
+  modalStatus = (val) => {
+    this.setState({modalStatus: val})
   }
 
   /**
@@ -458,141 +471,143 @@
       param.open_edition = openEdition
     }
 
-    // 鏈夋寜閽垨鏍囩鍒犻櫎鏃讹紝鍏堣繘琛屽垹闄ゆ搷浣�
-    // 鍒犻櫎鎴愬姛鍚庯紝淇濆瓨椤甸潰閰嶇疆
-    new Promise(resolve => {
-      if (delActions.length > 0) {
-        let deffers = delActions.map(item => {
-          let _param = {
-            func: 'sPC_MainMenu_Del',
-            MenuID: item.card ? item.card.uuid : item.uuid
-          }
-
-          if (item.type === 'action') {
-            let _ParentParam = null
-
-            try {
-              _ParentParam = window.btoa(window.encodeURIComponent(JSON.stringify(item.card)))
-            } catch (e) {
-              console.warn('Stringify Failure')
-              _ParentParam = null
+    setTimeout(() => {
+      // 鏈夋寜閽垨鏍囩鍒犻櫎鏃讹紝鍏堣繘琛屽垹闄ゆ搷浣�
+      // 鍒犻櫎鎴愬姛鍚庯紝淇濆瓨椤甸潰閰嶇疆
+      new Promise(resolve => {
+        if (delActions.length > 0) {
+          let deffers = delActions.map(item => {
+            let _param = {
+              func: 'sPC_MainMenu_Del',
+              MenuID: item.card ? item.card.uuid : item.uuid
             }
 
-            if (_ParentParam) { // 鍒犻櫎鎸夐挳鏃讹紝淇濆瓨鎸夐挳閰嶇疆淇℃伅锛岀敤浜庢仮澶嶆寜閽�
-              _param.ParentParam = _ParentParam
-            }
-          }
+            if (item.type === 'action') {
+              let _ParentParam = null
 
-          return new Promise(resolve => {
-            Api.getSystemConfig(_param).then(response => {
-              resolve(response)
+              try {
+                _ParentParam = window.btoa(window.encodeURIComponent(JSON.stringify(item.card)))
+              } catch (e) {
+                console.warn('Stringify Failure')
+                _ParentParam = null
+              }
+
+              if (_ParentParam) { // 鍒犻櫎鎸夐挳鏃讹紝淇濆瓨鎸夐挳閰嶇疆淇℃伅锛岀敤浜庢仮澶嶆寜閽�
+                _param.ParentParam = _ParentParam
+              }
+            }
+
+            return new Promise(resolve => {
+              Api.getSystemConfig(_param).then(response => {
+                resolve(response)
+              })
             })
           })
-        })
-        Promise.all(deffers).then(result => {
-          let error = null
-          result.forEach(response => {
-            if (!response.status) {
-              error = response
+          Promise.all(deffers).then(result => {
+            let error = null
+            result.forEach(response => {
+              if (!response.status) {
+                error = response
+              }
+            })
+
+            if (error) {
+              this.setState({
+                menuloading: false,
+                menucloseloading: false
+              })
+              notification.warning({
+                top: 92,
+                message: error.message,
+                duration: 5
+              })
+              resolve(false)
+            } else {
+              this.setState({
+                delActions: []
+              })
+              resolve(true)
             }
           })
+        } else if (delActions.length === 0) {
+          resolve(true)
+        }
+      }).then(resp => {
+        if (resp === false) return
 
-          if (error) {
+        if (thawButtons.length > 0) {
+          let defers = thawButtons.map(item => {
+            return new Promise((resolve) => {
+              Api.getSystemConfig({
+                func: 'sPC_MainMenu_ReDel',
+                MenuID: item
+              }).then(res => {
+                if (res.status) {
+                  resolve('')
+                } else {
+                  resolve(res.message)
+                }
+              })
+            })
+          })
+
+          return Promise.all(defers)
+        } else {
+          return true
+        }
+      }).then(res => {
+        if (res === true || res === false) return res
+
+        let msg = res.filter(Boolean)[0]
+        if (msg) {
+          notification.warning({
+            top: 92,
+            message: msg,
+            duration: 5
+          })
+          return false
+        } else {
+          this.setState({
+            thawButtons: []
+          })
+          return true
+        }
+      }).then(resp => {
+        if (resp === false) return
+        let localParam = fromJS(param).toJS()
+        Api.getSystemConfig(param).then(response => {
+          if (response.status) {
+            this.setState({
+              config: _config,
+              openEdition: response.open_edition || '',
+              originMenu: fromJS(_config).toJS()
+            }, () => {
+              reload && MKEmitter.emit('revert')
+            })
+
+            localParam.func = 'sPC_TrdMenu_AddUpt_For_Local'
+            delete localParam.LongParam
+            delete localParam.PageParam
+            delete localParam.Template
+            delete localParam.Sort
+            delete localParam.EasyCode
+            delete localParam.open_edition
+
+            this.submitAction(btnParam, tabParam, localParam)
+          } else {
             this.setState({
               menuloading: false,
               menucloseloading: false
             })
             notification.warning({
               top: 92,
-              message: error.message,
+              message: response.message,
               duration: 5
             })
-            resolve(false)
-          } else {
-            this.setState({
-              delActions: []
-            })
-            resolve(true)
           }
         })
-      } else if (delActions.length === 0) {
-        resolve(true)
-      }
-    }).then(resp => {
-      if (resp === false) return
-
-      if (thawButtons.length > 0) {
-        let defers = thawButtons.map(item => {
-          return new Promise((resolve) => {
-            Api.getSystemConfig({
-              func: 'sPC_MainMenu_ReDel',
-              MenuID: item
-            }).then(res => {
-              if (res.status) {
-                resolve('')
-              } else {
-                resolve(res.message)
-              }
-            })
-          })
-        })
-
-        return Promise.all(defers)
-      } else {
-        return true
-      }
-    }).then(res => {
-      if (res === true || res === false) return res
-
-      let msg = res.filter(Boolean)[0]
-      if (msg) {
-        notification.warning({
-          top: 92,
-          message: msg,
-          duration: 5
-        })
-        return false
-      } else {
-        this.setState({
-          thawButtons: []
-        })
-        return true
-      }
-    }).then(resp => {
-      if (resp === false) return
-      let localParam = fromJS(param).toJS()
-      Api.getSystemConfig(param).then(response => {
-        if (response.status) {
-          this.setState({
-            config: _config,
-            openEdition: response.open_edition || '',
-            originMenu: fromJS(_config).toJS()
-          }, () => {
-            reload && MKEmitter.emit('revert')
-          })
-
-          localParam.func = 'sPC_TrdMenu_AddUpt_For_Local'
-          delete localParam.LongParam
-          delete localParam.PageParam
-          delete localParam.Template
-          delete localParam.Sort
-          delete localParam.EasyCode
-          delete localParam.open_edition
-
-          this.submitAction(btnParam, tabParam, localParam)
-        } else {
-          this.setState({
-            menuloading: false,
-            menucloseloading: false
-          })
-          notification.warning({
-            top: 92,
-            message: response.message,
-            duration: 5
-          })
-        }
       })
-    })
+    }, +sessionStorage.getItem('mkDelay'))
   }
 
   /**
@@ -1253,7 +1268,7 @@
                 <EditComponent dict={this.state.dict} type="table" options={['search', 'form', 'action', 'columns']} config={this.state.config} MenuID={this.props.menu.MenuID} thawButtons={this.state.thawButtons} refresh={this.editConfig}/>
                 <Switch className="big" checkedChildren={this.state.dict['model.enable']} unCheckedChildren={this.state.dict['model.disable']} checked={this.state.config.enabled} onChange={this.onEnabledChange} />
                 <Button type="primary" id="save-config" onClick={this.submitConfig} loading={this.state.menuloading}>{this.state.dict['model.save']}</Button>
-                <Button onClick={this.cancelConfig}>{this.state.dict['model.back']}</Button>
+                <Button onClick={this.cancelConfig}>鍏抽棴</Button>
               </div>
             } style={{ width: '100%' }}>
               <SettingComponent
@@ -1362,14 +1377,4 @@
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    memberLevel: state.memberLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(ComTableConfig)
+export default ComTableConfig
diff --git a/src/templates/comtableconfig/index.scss b/src/templates/comtableconfig/index.scss
index 05862cb..fc49fea 100644
--- a/src/templates/comtableconfig/index.scss
+++ b/src/templates/comtableconfig/index.scss
@@ -1,6 +1,6 @@
 .common-table-board {
   position: fixed;
-  z-index: 1070;
+  z-index: 1;
   padding-top: 48px;
   top: 0px;
   left: 0px;
diff --git a/src/templates/comtableconfig/source.jsx b/src/templates/comtableconfig/source.jsx
index 781963e..3491275 100644
--- a/src/templates/comtableconfig/source.jsx
+++ b/src/templates/comtableconfig/source.jsx
@@ -225,13 +225,13 @@
     },
     {
       type: 'search',
-      label: CommonDict['model.form.dateday'],
+      label: '鏃ユ湡锛堝ぉ锛�',
       subType: 'date',
       url: ''
     },
     {
       type: 'search',
-      label: CommonDict['model.form.dateweek'],
+      label: '鏃ユ湡锛堝懆锛�',
       subType: 'dateweek',
       url: ''
     },
diff --git a/src/templates/formtabconfig/dragelement/card.jsx b/src/templates/formtabconfig/dragelement/card.jsx
index db147f1..feab70f 100644
--- a/src/templates/formtabconfig/dragelement/card.jsx
+++ b/src/templates/formtabconfig/dragelement/card.jsx
@@ -31,7 +31,7 @@
       }
     }
   })
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   const edit = () => {
     editCard(id)
diff --git a/src/templates/formtabconfig/index.jsx b/src/templates/formtabconfig/index.jsx
index a13d249..c37b457 100644
--- a/src/templates/formtabconfig/index.jsx
+++ b/src/templates/formtabconfig/index.jsx
@@ -598,10 +598,10 @@
             LText: res.dataSource
           }
 
-          param.LText = param.LText.replace(/@\$|\$@/ig, '')
+          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+          param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
 
           param.LText = Utils.formatOptions(param.LText)
-          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
           param.secretkey = Utils.encrypt('', param.timestamp)
   
           if (window.GLOB.mainSystemApi && res.database === 'sso') {
@@ -1448,10 +1448,10 @@
           LText: res.dataresource
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
 
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
         
         Api.getLocalConfig(param).then(result => {
@@ -2098,6 +2098,7 @@
           <PasteForm
             dict={this.state.dict}
             wrappedComponentRef={(inst) => this.pasteFormRef = inst}
+            inputSubmit={this.pasteSubmit}
           />
         </Modal>
         {this.state.loading && <Spin size="large" />}
diff --git a/src/templates/menuconfig/editfirstmenu/index.jsx b/src/templates/menuconfig/editfirstmenu/index.jsx
deleted file mode 100644
index 200a619..0000000
--- a/src/templates/menuconfig/editfirstmenu/index.jsx
+++ /dev/null
@@ -1,411 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { is, fromJS } from 'immutable'
-import { DndProvider } from 'react-dnd'
-import HTML5Backend from 'react-dnd-html5-backend'
-import { notification, Modal, Spin } from 'antd'
-import moment from 'moment'
-
-import TransferForm from '@/templates/zshare/basetransferform'
-import DragElement from './dragelement'
-import MenuForm from './menuform'
-import Utils from '@/utils/utils.js'
-import zhCN from '@/locales/zh-CN/model.js'
-import enUS from '@/locales/en-US/model.js'
-import Api from '@/api'
-import './index.scss'
-
-import card1 from '@/assets/img/card-bg2.jpg'
-import card2 from '@/assets/img/card-bg5.jpg'
-import card3 from '@/assets/img/card-bg8.jpg'
-import card4 from '@/assets/img/card-bg7.jpg'
-import card5 from '@/assets/img/card-bg6.jpg'
-
-const { confirm } = Modal
-
-class EditMenu extends Component {
-  static propTpyes = {
-    menulist: PropTypes.any,
-    reload: PropTypes.func,
-    exitEdit: PropTypes.func
-  }
-
-  state = {
-    thawmenulist: null, // 宸插喕缁撶殑涓�绾ц彍鍗�
-    addMvisible: null,
-    menulist: null,
-    editMenu: null, // 缂栬緫鑿滃崟
-    editMvisible: false, // 缂栬緫鑿滃崟妯℃�佹
-    thawMvisible: false, // 瑙i櫎鍐荤粨妯℃�佹
-    confirmLoading: false, // 鎻愪氦涓�傘�傘��
-    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
-    targetKeys: [] // 瑙e喕鑿滃崟鍒楄〃
-  }
-
-  handlePreviewList = (List) => {
-    // 鑿滃崟椤哄簭鏀瑰彉鏃讹紝淇濆瓨涓棿鐘舵��
-    this.setState({menulist: List})
-  }
-
-  editMenuModal = (Menu) => {
-    // 鑿滃崟缂栬緫锛氫慨鏀�
-    const menu = fromJS(Menu).toJS()
-    if (!is(fromJS(this.state.menulist), fromJS(this.props.menulist))) {
-      notification.warning({
-        top: 92,
-        message: this.state.dict['model.menu.presave'],
-        duration: 5
-      })
-    } else {
-      this.setState({
-        editMvisible: true,
-        editMenu: menu.card
-      })
-    }
-  }
-
-  editMemuSubmit = () => {
-    // 缂栬緫鑿滃崟锛氭彁浜�
-    this.editMenuFormRef.handleConfirm().then(param => {
-      param.func = 'sPC_MainMenu_Upt'
-      this.setState({
-        confirmLoading: true
-      })
-      Api.getSystemConfig(param).then(res => {
-        if (res.status) {
-          this.setState({
-            confirmLoading: false,
-            editMvisible: false,
-            editMenu: null
-          })
-          this.props.reload()
-        } else {
-          this.setState({
-            confirmLoading: false
-          })
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 5
-          })
-        }
-      })
-    }, () => {})
-  }
-
-  editMemuCancel = () => {
-    // 缂栬緫鑿滃崟锛氬彇娑�
-    this.setState({
-      confirmLoading: false,
-      editMvisible: false,
-      editMenu: null
-    })
-  }
-
-  addMemuSubmit = () => {
-    // 鏂板缓鑿滃崟锛氭彁浜�
-    this.addMenuFormRef.handleConfirm().then(param => {
-      param.func = 'sPC_MainMenu_Add'
-      param.Sort = (this.props.menulist.length + 1) * 10
-      this.setState({
-        confirmLoading: true
-      })
-      Api.getSystemConfig(param).then(res => {
-        if (res.status) {
-          this.setState({
-            confirmLoading: false,
-            addMvisible: false,
-          })
-          this.props.reload()
-        } else {
-          this.setState({
-            confirmLoading: false
-          })
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 5
-          })
-        }
-      })
-    }, () => {})
-  }
-
-  addMemuCancel = () => {
-    // 鏂板缓鑿滃崟锛氬彇娑�
-    this.setState({
-      confirmLoading: false,
-      addMvisible: false
-    })
-  }
-
-  deleteMemu = (item) => {
-    let _this = this
-    confirm({
-      title: this.state.dict['model.menu.close'].replace('@M', item.MenuName),
-      content: '',
-      onOk() {
-        let param = {
-          func: 'sPC_MainMenu_Del',
-          MenuID: item.MenuID
-        }
-        return Api.getSystemConfig(param).then(res => {
-          if (res.status) {
-            _this.props.reload()
-          } else {
-            notification.warning({
-              top: 92,
-              message: res.message,
-              duration: 5
-            })
-          }
-        })
-      },
-      onCancel() {}
-    })
-  }
-
-  thawMemuSubmit = () => {
-    const { targetKeys } = this.state
-
-    if (targetKeys.length === 0) {
-      notification.warning({
-        top: 92,
-        message: this.state.dict['form.required.select'] + this.state.dict['model.menu'],
-        duration: 5
-      })
-    } else {
-      this.setState({
-        confirmLoading: true
-      })
-      let defers = targetKeys.map(item => {
-        return new Promise((resolve) => {
-          Api.getSystemConfig({
-            func: 'sPC_MainMenu_ReDel',
-            MenuID: item
-          }).then(res => {
-            if (res.status) {
-              resolve('')
-            } else {
-              resolve(res.message)
-            }
-          })
-        })
-      })
-      Promise.all(defers).then(res => {
-        let msg = res.filter(Boolean)[0]
-        if (msg) {
-          notification.error({
-            top: 92,
-            message: msg,
-            duration: 10
-          })
-        } else {
-          this.setState({
-            confirmLoading: false,
-            thawMvisible: false,
-            targetKeys: [],
-            thawmenulist: null
-          })
-          this.props.reload()
-        }
-      })
-    }
-  }
-
-  thawMemuCancel = () => {
-    this.setState({
-      thawMvisible: false,
-      targetKeys: [],
-      thawmenulist: null
-    })
-  }
-
-  
-  handleButton = (type) => {
-    // 鑿滃崟缂栬緫锛氭坊鍔狅紝纭畾锛屽彇娑�
-    let _menuchange = !is(fromJS(this.state.menulist), fromJS(this.props.menulist))
-
-    if ((type === 'add' || type === 'thawmenu') && _menuchange) {
-      notification.warning({
-        top: 92,
-        message: this.state.dict['model.menu.presave'],
-        duration: 5
-      })
-    } else if (type === 'add') {
-      this.setState({
-        addMvisible: true
-      })
-    } else if (type === 'confirm' && _menuchange) {
-      let _this = this
-      let param  = {
-        func: 'sPC_Menu_SortUpt',
-        LText: this.state.menulist.map((item, index) => {
-          return 'select \'' + item.MenuID + '\' as Menuid,' + (index + 1) * 10 + ' as sort'
-        })
-      }
-
-      param.LText = param.LText.join(' union ') // sql鎷兼帴
-      param.LText = Utils.formatOptions(param.LText) // 鍏抽敭瀛楃鏇挎崲锛宐ase64鍔犲瘑
-      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') // 鏃堕棿鎴�
-      param.secretkey = Utils.encrypt(param.LText, param.timestamp) // md5瀵嗛挜
-
-      confirm({
-        title: this.state.dict['model.menu.resetorder'],
-        content: '',
-        onOk() {
-          return Api.getSystemConfig(param).then(res => {
-            if (res.status) {
-              _this.props.reload()
-            } else {
-              notification.warning({
-                top: 92,
-                message: res.message,
-                duration: 5
-              })
-            }
-          })
-        },
-        onCancel() {}
-      })
-    } else if (type === 'cancel' && _menuchange) {
-      let _this = this
-
-      confirm({
-        title: '鑿滃崟椤哄簭宸茶皟鏁达紝鏀惧純淇濆瓨鍚楋紵',
-        content: '',
-        onOk() {
-          _this.props.exitEdit()
-        },
-        onCancel() {}
-      })
-    } else if (type === 'thawmenu') {
-      this.setState({
-        thawMvisible: true,
-        targetKeys: []
-      })
-      Api.getSystemConfig({
-        func: 'sPC_Get_FrozenMenu',
-        ParentID: '0',
-        TYPE: 10
-      }).then(res => {
-        if (res.status) {
-          this.setState({
-            thawmenulist: res.data.map(menu => {
-              return {
-                key: menu.MenuID,
-                title: menu.MenuName
-              }
-            })
-          })
-        } else {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 5
-          })
-        }
-      })
-    } else {
-      this.props.exitEdit()
-    }
-  }
-
-  UNSAFE_componentWillMount () {
-    this.setState({menulist: fromJS(this.props.menulist).toJS()})
-  }
-
-  UNSAFE_componentWillReceiveProps (nextProps) {
-    if (!is(fromJS(this.props.menulist), fromJS(nextProps.menulist))) {
-      this.setState({menulist: fromJS(nextProps.menulist).toJS()})
-    }
-  }
-
-  render () {
-    const { dict, menulist } = this.state
-
-    return (
-      <div className="header-edit-box">
-        <div className="mask">
-          <div className="tipcard card1" style={{backgroundImage: 'url(' + card1 + ')'}}>
-            鎷栧姩涓�绾ц彍鍗曞彲璋冩暣椤哄簭锛岄『搴忚皟鏁村悗锛岃鐐瑰嚮纭畾鎸夐挳淇濆瓨銆�
-          </div>
-          <div className="tipcard card2" style={{backgroundImage: 'url(' + card2 + ')'}}>
-            榧犳爣缁忚繃鑿滃崟鏃朵細鏄剧ず缂栬緫鍥炬爣锛岀偣鍑荤紪杈戝彲淇敼鍜屽垹闄よ彍鍗曘��
-          </div>
-          <div className="tipcard card3" style={{backgroundImage: 'url(' + card3 + ')'}}>
-            鐐瑰嚮瑙i櫎鍐荤粨鎸夐挳锛屽彲杩樺師宸插垹闄ょ殑涓�绾ц彍鍗曘��
-          </div>
-          <div className="tipcard card4" style={{backgroundImage: 'url(' + card4 + ')'}}>
-            鐐瑰嚮娣诲姞鍥炬爣锛屽彲鏂板涓�绾ц彍鍗曘��
-          </div>
-          <div className="tipcard card5" style={{backgroundImage: 'url(' + card5 + ')'}}>
-            <p>缂栬緫鐘舵�佷腑锛岃彍鍗曚箣澶栧尯鍩熶細閿佸畾锛屾煡鐪嬬郴缁熸暟鎹鐐瑰嚮銆�</p>
-            <div>
-              <span className="new-view" onClick={() => {window.open('#/main')}} >鏂伴〉闈�</span>
-            </div>
-          </div>
-        </div>
-        <DndProvider backend={HTML5Backend}>
-          <DragElement
-            dict={dict}
-            list={menulist}
-            handlePreviewList={this.handlePreviewList}
-            handleMenu={this.editMenuModal}
-            deleteMemu={this.deleteMemu}
-            handleButton={this.handleButton}
-          />
-        </DndProvider>
-        {/* 鏂板缓鑿滃崟妯℃�佹 */}
-        <Modal
-          title={dict['model.add'] + dict['model.menu']}
-          visible={this.state.addMvisible}
-          onOk={this.addMemuSubmit}
-          confirmLoading={this.state.confirmLoading}
-          onCancel={this.addMemuCancel}
-          destroyOnClose
-        >
-          <MenuForm
-            dict={dict}
-            type="add"
-            menu={null}
-            inputSubmit={this.addMemuSubmit}
-            wrappedComponentRef={(inst) => this.addMenuFormRef = inst}
-          />
-        </Modal>
-        {/* 瑙i櫎鍐荤粨鑿滃崟妯℃�佹 */}
-        <Modal
-          title={dict['model.thaw'] + dict['model.menu']}
-          visible={this.state.thawMvisible}
-          width={600}
-          onOk={this.thawMemuSubmit}
-          confirmLoading={this.state.confirmLoading}
-          onCancel={this.thawMemuCancel}
-          destroyOnClose
-        >
-          {!this.state.thawmenulist && <Spin style={{marginLeft: 'calc(50% - 22px)', marginTop: '70px', marginBottom: '70px'}} size="large" />}
-          {this.state.thawmenulist && <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={this.state.thawmenulist}/>}
-        </Modal>
-        {/* 缂栬緫鑿滃崟妯℃�佹 */}
-        <Modal
-          title={dict['model.edit'] + dict['model.menu']}
-          visible={this.state.editMvisible}
-          onOk={this.editMemuSubmit}
-          confirmLoading={this.state.confirmLoading}
-          onCancel={this.editMemuCancel}
-          destroyOnClose
-        >
-          <MenuForm
-            dict={dict}
-            type="edit"
-            menu={this.state.editMenu}
-            inputSubmit={this.editMemuSubmit}
-            wrappedComponentRef={(inst) => this.editMenuFormRef = inst}
-          />
-        </Modal>
-      </div>
-    )
-  }
-}
-
-export default EditMenu
\ No newline at end of file
diff --git a/src/templates/menuconfig/editfirstmenu/index.scss b/src/templates/menuconfig/editfirstmenu/index.scss
deleted file mode 100644
index ac8a533..0000000
--- a/src/templates/menuconfig/editfirstmenu/index.scss
+++ /dev/null
@@ -1,79 +0,0 @@
-.header-edit-box {
-  .mask {
-    position: fixed;
-    top: 0px;
-    left: 0px;
-    right: 0px;
-    bottom: 0px;
-    .tipcard {
-      position: absolute;
-      min-height: 100px;
-      font-size: 16px;
-      border-radius: 6px;
-      background-size: 100% 100%;
-      background-repeat: no-repeat;
-      padding: 15px;
-    }
-    .card1 {
-      left: 30%;
-      top: 20vh;
-      width: 230px;
-      min-height: 100px;
-      color: #000000;
-      font-style: oblique;
-    }
-    .card2 {
-      left: 60%;
-      top: 20vh;
-      width: 230px;
-      min-height: 100px;
-      color: #000000;
-      padding: 20px 30px;
-      font-style: oblique;
-    }
-    .card3 {
-      left: 30%;
-      top: 50vh;
-      width: 230px;
-      min-height: 140px;
-      color: #000000;
-      padding: 20px 30px;
-      font-style: oblique;
-    }
-    .card4 {
-      left: 60%;
-      top: 50vh;
-      width: 230px;
-      min-height: 140px;
-      color: #000000;
-      padding: 20px 30px;
-      font-style: oblique;
-    }
-    .card5 {
-      right: 5%;
-      top: 20vh;
-      width: 130px;
-      min-height: 240px;
-      color: #000000;
-      padding: 40px 15px 10px;
-      p {
-        margin: 0 0 5px;
-      }
-      div {
-        text-align: center;
-        .new-view {
-          display: inline-block;
-          cursor: pointer;
-          color: #fff;
-          padding: 2px 10px;
-          border-radius: 4px;
-          background-color: #1890ff;
-          border-color: #1890ff;
-          text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
-          -webkit-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
-          box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
-        }
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/src/templates/menuconfig/editsecmenu/index.jsx b/src/templates/menuconfig/editsecmenu/index.jsx
deleted file mode 100644
index c93ba0e..0000000
--- a/src/templates/menuconfig/editsecmenu/index.jsx
+++ /dev/null
@@ -1,463 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { is, fromJS } from 'immutable'
-import { DndProvider } from 'react-dnd'
-import HTML5Backend from 'react-dnd-html5-backend'
-import { notification, Modal, Button, Spin } from 'antd'
-import { PlusOutlined } from '@ant-design/icons'
-import moment from 'moment'
-import TransferForm from '@/templates/zshare/basetransferform'
-import Utils from '@/utils/utils.js'
-import DragElement from '../menuelement'
-import MenuForm from '../menuform'
-import Api from '@/api'
-import zhCN from '@/locales/zh-CN/model.js'
-import enUS from '@/locales/en-US/model.js'
-import './index.scss'
-
-import card1 from '@/assets/img/card-bg2.jpg'
-import card2 from '@/assets/img/card-bg5.jpg'
-import card3 from '@/assets/img/card-bg8.jpg'
-import card4 from '@/assets/img/card-bg7.jpg'
-import card5 from '@/assets/img/card-bg6.jpg'
-
-const { confirm } = Modal
-
-class EditMenu extends Component {
-  static propTpyes = {
-    menulist: PropTypes.any,      // 浜岀骇鑿滃崟鍒楄〃
-    menuTree: PropTypes.array,    // 涓�绾ц彍鍗曞垪琛�
-    supMenu: PropTypes.object,    // 浜岀骇鑿滃崟鎵�瀵瑰簲鐨勪竴绾ц彍鍗�
-    reload: PropTypes.func,       // 鍒锋柊浜岀骇鑿滃崟鏁版嵁
-    exitEdit: PropTypes.func      // 閫�鍑虹紪杈�
-  }
-
-  state = {
-    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
-    menulist: null,        // 鑿滃崟鍒楄〃
-    type: '',              // 缂栬緫绫诲瀷锛宎dd or edit
-    title: '',             // 妯℃�佹鏍囬
-    visible: null,         // 妯℃�佹鏄惁鍙
-    formlist: null,        // 琛ㄥ崟淇℃伅
-    editMenu: null,        // 缂栬緫鑿滃崟
-    thawmenulist: null,    // 宸插喕缁撶殑浜岀骇鑿滃崟
-    thawMvisible: false,   // 瑙i櫎鍐荤粨妯℃�佹
-    confirmLoading: false, // 鎻愪氦涓�傘�傘��
-    targetKeys: []         // 瑙e喕鑿滃崟鍒楄〃 
-  }
-
-  handlePreviewList = (List) => {
-    this.setState({
-      menulist: List
-    })
-  }
-
-  handleMenu = (menu) => {
-    const { dict } = this.state
-
-    // 鑿滃崟缂栬緫锛氫慨鏀广�佸垹闄わ紝濡傝彍鍗曢『搴忓凡鏀瑰彉锛屾彁绀轰繚瀛樿彍鍗曢『搴�
-    const _this = this
-    if (!is(fromJS(this.props.menulist), fromJS(this.state.menulist))) {
-      notification.warning({
-        top: 92,
-        message: dict['model.menu.presave'],
-        duration: 5
-      })
-    } else if (menu.type === 'close') {
-      confirm({
-        title: dict['model.menu.close'].replace('@M', menu.card.MenuName),
-        content: '',
-        onOk() {
-          let param = {
-            func: 'sPC_MainMenu_Del',
-            MenuID: menu.card.MenuID
-          }
-          return Api.getSystemConfig(param).then(res => {
-            if (res.status) {
-              _this.props.reload()
-            } else {
-              notification.warning({
-                top: 92,
-                message: res.message,
-                duration: 5
-              })
-            }
-          })
-        },
-        onCancel() {}
-      })
-    } else if (menu.type === 'edit') {
-      this.setState({
-        visible: true,
-        title: dict['model.edit'] + dict['model.menu'],
-        type: 'edit',
-        editMenu: menu.card,
-        formlist: [
-          { // 鐖剁骇鑿滃崟
-            type: 'select',
-            key: 'parentId',
-            label: dict['model.super'] + dict['model.menu'],
-            initVal: this.props.supMenu.MenuID,
-            required: true,
-            options: this.props.menuTree
-          },
-          { // 鑿滃崟鍚嶇О
-            type: 'text',
-            key: 'menuName',
-            label: dict['model.menu'] + dict['model.name'],
-            initVal: menu.card.MenuName,
-            required: true,
-            readonly: false
-          },
-          { // 鑿滃崟鍥炬爣
-            type: 'icon',
-            key: 'icon',
-            label: dict['model.icon'],
-            initVal: menu.card.PageParam.Icon || 'folder',
-            required: true
-          }
-        ]
-      })
-    }
-  }
-
-  handleSubBtn = (type) => {
-    const { dict } = this.state
-
-    // 鎿嶄綔鎸夐挳
-    if (type === 'add') { // 娣诲姞鏂拌彍鍗�
-      this.setState({
-        visible: true,
-        title: dict['model.add'] + dict['model.menu'],
-        type: 'add',
-        formlist: [
-          { // 鐖剁骇鑿滃崟
-            type: 'select',
-            key: 'parentId',
-            label: dict['model.super'] + dict['model.menu'],
-            initVal: this.props.supMenu.MenuID,
-            required: true,
-            options: this.props.menuTree
-          },
-          { // 鑿滃崟鍚嶇О
-            type: 'text',
-            key: 'menuName',
-            label: dict['model.menu'] + dict['model.name'],
-            initVal: '',
-            required: true,
-            readonly: false
-          },
-          { // 鑿滃崟鍥炬爣
-            type: 'icon',
-            key: 'icon',
-            label: dict['model.icon'],
-            initVal: 'folder',
-            required: true
-          }
-        ]
-      })
-    } else if (type === 'thaw') { // 瑙e喕宸叉湁鑿滃崟
-      this.setState({
-        thawMvisible: true,
-        targetKeys: []
-      })
-      Api.getSystemConfig({
-        func: 'sPC_Get_FrozenMenu',
-        ParentID: this.props.supMenu.MenuID,
-        TYPE: 20
-      }).then(res => {
-        if (res.status) {
-          this.setState({
-            thawmenulist: res.data.map(menu => {
-              return {
-                key: menu.MenuID,
-                title: menu.MenuName
-              }
-            })
-          })
-        } else {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 5
-          })
-        }
-      })
-    } else if (type === 'confirm') { // 纭畾鏃跺叆椤哄簭鏀瑰彉锛屽垯鎻愮ず淇濆瓨锛屽惁鍒欓��鍑虹紪杈�
-      if (!is(fromJS(this.props.menulist), fromJS(this.state.menulist))) {
-        let _this = this
-        let param  = {
-          func: 'sPC_Menu_SortUpt',
-          LText: this.state.menulist.map((item, index) => {
-            return 'select \'' + item.MenuID + '\' as Menuid,' + (index + 1) * 10 + ' as sort'
-          })
-        }
-
-        param.LText = param.LText.join(' union ') // sql鎷兼帴
-        param.LText = Utils.formatOptions(param.LText) // 鍏抽敭瀛楃鏇挎崲锛宐ase64鍔犲瘑
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') // 鏃堕棿鎴�
-        param.secretkey = Utils.encrypt(param.LText, param.timestamp) // md5瀵嗛挜
-
-        confirm({
-          title: this.state.dict['model.menu.resetorder'],
-          content: '',
-          onOk() {
-            return Api.getSystemConfig(param).then(res => {
-              if (res.status) {
-                _this.props.reload()
-              } else {
-                notification.warning({
-                  top: 92,
-                  message: res.message,
-                  duration: 5
-                })
-              }
-            })
-          },
-          onCancel() {}
-        })
-      } else {
-        this.props.exitEdit()
-      }
-    } else if (type === 'close') { // 閫�鍑虹紪杈�
-      if (!is(fromJS(this.props.menulist), fromJS(this.state.menulist))) {
-        let _this = this
-
-        confirm({
-          title: '鑿滃崟椤哄簭宸茶皟鏁达紝鏀惧純淇濆瓨鍚楋紵',
-          content: '',
-          onOk() {
-            _this.props.exitEdit()
-          },
-          onCancel() {}
-        })
-      } else {
-        this.props.exitEdit()
-      }
-    }
-  }
-
-  memuHandleSubmit = () => {
-    if (this.state.type === 'add') { // 鏂板缓鑿滃崟锛氭彁浜�
-      this.menuFormRef.handleConfirm().then(values => {
-        let param = {
-          ParentID: values.parentId,
-          MenuID: Utils.getuuid(),
-          MenuName: values.menuName,
-          PageParam: JSON.stringify({
-            Icon: values.icon
-          })
-        }
-        param.func = 'sPC_SndMenu_Add'
-        param.Sort = (this.props.menulist.length + 1) * 10
-        this.setState({
-          confirmLoading: true
-        })
-        Api.getSystemConfig(param).then(res => {
-          if (res.status) {
-            this.setState({
-              confirmLoading: false,
-              visible: false
-            })
-            this.props.reload()
-          } else {
-            this.setState({
-              confirmLoading: false
-            })
-            notification.warning({
-              top: 92,
-              message: res.message,
-              duration: 5
-            })
-          }
-        })
-      }, () => {})
-    } else if (this.state.type === 'edit') { // 缂栬緫鑿滃崟锛氭彁浜�
-      this.menuFormRef.handleConfirm().then(values => {
-        let param = {
-          func: 'sPC_SndMenu_Upt',
-          ParentID: values.parentId,
-          MenuID: this.state.editMenu.MenuID,
-          MenuName: values.menuName,
-          PageParam: JSON.stringify({
-            Icon: values.icon
-          })
-        }
-        this.setState({
-          confirmLoading: true
-        })
-        Api.getSystemConfig(param).then(res => {
-          if (res.status) {
-            this.setState({
-              confirmLoading: false,
-              visible: false
-            })
-            this.props.reload()
-          } else {
-            this.setState({
-              confirmLoading: false
-            })
-            notification.warning({
-              top: 92,
-              message: res.message,
-              duration: 5
-            })
-          }
-        })
-      }, () => {})
-    }
-  }
-
-  memuHandleCancel = () => { // 鍙栨秷鎿嶄綔锛屽叧闂ā鎬佹
-    this.setState({
-      visible: false,
-      type: '',
-      formlist: null,
-      editMenu: null
-    })
-  }
-
-  thawMemuSubmit = () => { // 瑙e喕鑿滃崟锛屾彁浜わ紝瀛樺湪澶氫釜鏃讹紝寰幆鎻愪氦
-    const { targetKeys } = this.state
-
-    if (targetKeys.length === 0) {
-      notification.warning({
-        top: 92,
-        message: this.state.dict['form.required.select'] + this.state.dict['model.menu'],
-        duration: 5
-      })
-    } else {
-      this.setState({
-        confirmLoading: true
-      })
-      let defers = targetKeys.map(item => {
-        return new Promise((resolve) => {
-          Api.getSystemConfig({
-            func: 'sPC_MainMenu_ReDel',
-            MenuID: item
-          }).then(res => {
-            if (res.status) {
-              resolve('')
-            } else {
-              resolve(res.message)
-            }
-          })
-        })
-      })
-      Promise.all(defers).then(res => {
-        let msg = res.filter(Boolean)[0]
-        if (msg) {
-          notification.error({
-            top: 92,
-            message: msg,
-            duration: 10
-          })
-        } else {
-          this.setState({
-            confirmLoading: false,
-            thawMvisible: false,
-            targetKeys: [],
-            thawmenulist: null
-          })
-          this.props.reload()
-        }
-      })
-    }
-  }
-
-  thawMemuCancel = () => { // 瑙e喕鑿滃崟鍙栨秷
-    this.setState({
-      thawMvisible: false,
-      targetKeys: [],
-      thawmenulist: null
-    })
-  }
-
-  UNSAFE_componentWillMount () {
-    this.setState({
-      menulist: this.props.menulist
-    })
-  }
-
-  UNSAFE_componentWillReceiveProps (nextProps) {
-    if (!is(fromJS(this.props.menulist), fromJS(nextProps.menulist))) {
-      this.setState({
-        menulist: nextProps.menulist
-      })
-    }
-  }
-
-  render () {
-    const { dict } = this.state
-
-    return (
-      <div className="second-edit-box">
-        <div className="mask">
-          <div className="tipcard card1" style={{backgroundImage: 'url(' + card1 + ')'}}>
-            鎷栧姩浜岀骇鑿滃崟鍙皟鏁撮『搴忥紝椤哄簭璋冩暣鍚庯紝璇风偣鍑荤‘瀹氭寜閽繚瀛樸��
-          </div>
-          <div className="tipcard card2" style={{backgroundImage: 'url(' + card2 + ')'}}>
-            鐐瑰嚮缂栬緫鍥炬爣鍙慨鏀硅彍鍗曞睘鎬э紝鐐瑰嚮鍒犻櫎鍥炬爣鍙垹闄よ彍鍗曘��
-          </div>
-          <div className="tipcard card3" style={{backgroundImage: 'url(' + card3 + ')'}}>
-            鐐瑰嚮瑙i櫎鍐荤粨鎸夐挳锛屽彲杩樺師宸插垹闄ょ殑浜岀骇鑿滃崟銆�
-          </div>
-          <div className="tipcard card4" style={{backgroundImage: 'url(' + card4 + ')'}}>
-            鐐瑰嚮娣诲姞鍥炬爣锛屽彲鏂板浜岀骇鑿滃崟銆�
-          </div>
-          <div className="tipcard card5" style={{backgroundImage: 'url(' + card5 + ')'}}>
-            <p>缂栬緫鐘舵�佷腑锛岃彍鍗曚箣澶栧尯鍩熶細閿佸畾锛屾煡鐪嬬郴缁熸暟鎹鐐瑰嚮銆�</p>
-            <div>
-              <span className="new-view" onClick={() => {window.open('#/main')}} >鏂伴〉闈�</span>
-            </div>
-          </div>
-        </div>
-        <DndProvider backend={HTML5Backend}>
-          {this.state.menulist && this.state.menulist.length > 0 ? <DragElement
-            list={this.state.menulist}
-            handlePreviewList={this.handlePreviewList}
-            handleMenu={this.handleMenu}
-          /> : null}
-        </DndProvider>
-        <div className="menu-add" onClick={() => {this.handleSubBtn('add')}}>
-          <PlusOutlined />
-        </div>
-        <div className="menu-btn">
-          <Button type="primary" onClick={() => {this.handleSubBtn('thaw')}}>{dict['model.thaw'] + dict['model.menu']}</Button>
-          <Button type="primary" onClick={() => {this.handleSubBtn('confirm')}}>{dict['model.confirm']}</Button>
-          <Button onClick={() => {this.handleSubBtn('close')}}>{dict['model.close']}</Button>
-        </div>
-        <Modal
-          title={this.state.title}
-          visible={this.state.visible}
-          onOk={this.memuHandleSubmit}
-          confirmLoading={this.state.confirmLoading}
-          onCancel={this.memuHandleCancel}
-          destroyOnClose
-        >
-          {this.state.formlist ?
-            <MenuForm
-              dict={dict}
-              inputSubmit={this.memuHandleSubmit}
-              formlist={this.state.formlist}
-              wrappedComponentRef={(inst) => this.menuFormRef = inst}
-            /> : null}
-        </Modal>
-        <Modal
-          title={dict['model.thaw'] + dict['model.menu']}
-          width={600}
-          visible={this.state.thawMvisible}
-          onOk={this.thawMemuSubmit}
-          confirmLoading={this.state.confirmLoading}
-          onCancel={this.thawMemuCancel}
-          destroyOnClose
-        >
-          {!this.state.thawmenulist && <Spin style={{marginLeft: 'calc(50% - 22px)', marginTop: '70px', marginBottom: '70px'}} size="large" />}
-          {this.state.thawmenulist && <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={this.state.thawmenulist}/>}
-        </Modal>
-      </div>
-    )
-  }
-}
-
-export default EditMenu
\ No newline at end of file
diff --git a/src/templates/menuconfig/editsecmenu/index.scss b/src/templates/menuconfig/editsecmenu/index.scss
deleted file mode 100644
index 59277cb..0000000
--- a/src/templates/menuconfig/editsecmenu/index.scss
+++ /dev/null
@@ -1,81 +0,0 @@
-.second-edit-box {
-  position: relative;
-  z-index: 10;
-  .mask {
-    position: fixed;
-    top: 0px;
-    left: 0px;
-    right: 0px;
-    bottom: 0px;
-    .tipcard {
-      position: absolute;
-      min-height: 100px;
-      font-size: 16px;
-      border-radius: 6px;
-      background-size: 100% 100%;
-      background-repeat: no-repeat;
-      padding: 15px;  
-    }
-    .card1 {
-      left: 30%;
-      top: 20vh;
-      width: 230px;
-      min-height: 100px;
-      color: #000000;
-      font-style: oblique;
-    }
-    .card2 {
-      left: 60%;
-      top: 20vh;
-      width: 230px;
-      min-height: 100px;
-      color: #000000;
-      padding: 20px 30px;
-      font-style: oblique;
-    }
-    .card3 {
-      left: 30%;
-      top: 50vh;
-      width: 230px;
-      min-height: 140px;
-      color: #000000;
-      padding: 20px 30px;
-      font-style: oblique;
-    }
-    .card4 {
-      left: 60%;
-      top: 50vh;
-      width: 230px;
-      min-height: 140px;
-      color: #000000;
-      padding: 20px 30px;
-      font-style: oblique;
-    }
-    .card5 {
-      right: 5%;
-      top: 20vh;
-      width: 130px;
-      min-height: 240px;
-      color: #000000;
-      padding: 40px 15px 10px;
-      p {
-        margin: 0 0 5px;
-      }
-      div {
-        text-align: center;
-        .new-view {
-          display: inline-block;
-          cursor: pointer;
-          color: #fff;
-          padding: 2px 10px;
-          border-radius: 4px;
-          background-color: #1890ff;
-          border-color: #1890ff;
-          text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
-          -webkit-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
-          box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
-        }
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/src/templates/menuconfig/editthdmenu/index.jsx b/src/templates/menuconfig/editthdmenu/index.jsx
deleted file mode 100644
index e66a6d3..0000000
--- a/src/templates/menuconfig/editthdmenu/index.jsx
+++ /dev/null
@@ -1,979 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-import { is, fromJS } from 'immutable'
-import { connect } from 'react-redux'
-import { DndProvider } from 'react-dnd'
-import { withRouter } from 'react-router-dom'
-import HTML5Backend from 'react-dnd-html5-backend'
-import { notification, Modal, Button, Spin, Col, Card, Tabs, Row, Input } from 'antd'
-import { PlusOutlined } from '@ant-design/icons'
-import moment from 'moment'
-
-import Api from '@/api'
-import { sysTemps } from '@/utils/option.js'
-import zhCN from '@/locales/zh-CN/model.js'
-import enUS from '@/locales/en-US/model.js'
-import mainsubtable from '@/assets/img/mainsubtable.jpg'
-import treepage from '@/assets/img/treepage.jpg'
-import calendar from '@/assets/img/calendar.jpg'
-import customImg from '@/assets/img/custom.jpg'
-import MkIcon from '@/components/mk-icon'
-import Preview from './preview'
-import MenuForm from './menuform'
-import TransferForm from '@/templates/zshare/basetransferform'
-import Utils from '@/utils/utils.js'
-import MenuUtils from '@/utils/utils-custom.js'
-import DragElement from '../menuelement'
-import asyncLoadComponent from '@/utils/asyncLoadComponent'
-import './index.scss'
-
-import card1 from '@/assets/img/card-bg2.jpg'
-import card2 from '@/assets/img/card-bg5.jpg'
-import card3 from '@/assets/img/card-bg8.jpg'
-import card4 from '@/assets/img/card-bg7.jpg'
-import card5 from '@/assets/img/card-bg6.jpg'
-
-const ComTableConfig = asyncLoadComponent(() => import('@/templates/comtableconfig'))
-const TreePageConfig = asyncLoadComponent(() => import('@/templates/treepageconfig'))
-const CalendarPageConfig = asyncLoadComponent(() => import('@/templates/calendarconfig'))
-const FormTabConfig = asyncLoadComponent(() => import('@/templates/formtabconfig'))
-const ModalConfig = asyncLoadComponent(() => import('@/templates/modalconfig'))
-const SubTable = asyncLoadComponent(() => import('@/templates/subtableconfig'))
-
-const { confirm } = Modal
-const { TabPane } = Tabs
-const { Search } = Input
-
-class EditMenu extends Component {
-  static propTpyes = {
-    reload: PropTypes.func,      // 鑿滃崟淇敼鍚庡埛鏂�
-    menulist: PropTypes.any,     // 涓夌骇鑿滃崟鍒楄〃
-    exitEdit: PropTypes.func,    // 閫�鍑虹紪杈戠姸鎬�
-    supMenu: PropTypes.object,   // 瀵瑰簲鐨勪笂绾ц彍鍗�
-    supMenuList: PropTypes.array // 涓婄骇鑿滃崟鍒楄〃锛岀敤浜庝笁绾ц彍鍗曞垏鎹笂绾ц彍鍗�
-  }
-
-  state = {
-    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
-    thawmenulist: null,     // 宸插喕缁撶殑浜岀骇鑿滃崟
-    type: '',               // 鎿嶄綔绫诲瀷锛屾柊寤烘垨缂栬緫鑿滃崟
-    thawMvisible: false,    // 瑙i櫎鍐荤粨妯℃�佹
-    confirmLoading: false,  // 鎻愪氦涓�傘�傘��
-    selectTemp: '',         // 閫夋嫨妯℃澘
-    usedTemplates: null,    // 宸蹭娇鐢ㄦā鏉垮垪琛�
-    tempSearchKey: '',      // 鑿滃崟鍚嶇О杩囨护鍊�
-    loading: false,         // 缂栬緫鑿滃崟鎴栦娇鐢ㄥ凡浣跨敤妯℃澘鏃讹紝鑾峰彇閰嶇疆淇℃伅
-    preview: null,          // 鍥剧墖棰勮url
-    pretemplate: null,      // 棰勮妯℃澘
-    btnParam: null,         // 缂栬緫鎸夐挳鐨勯厤缃俊鎭�
-    menulist: null,         // 缂栬緫涓殑鑿滃崟
-    sysTemplates: sysTemps, // 绯荤粺妯℃澘
-    tabview: '',            // 閫夋嫨妯℃澘绐楀彛锛坱emplate锛夈�佸熀纭�琛ㄦ牸閰嶇疆锛圕ommonTable锛夈�佽〃鍗曪紙Modal锛夈�佸瓙琛紙SubTable锛�
-    editMenu: null,         // 缂栬緫鑿滃崟
-    editAction: null,       // 缂栬緫鎸夐挳
-    editTab: null,          // 缂栬緫鏍囩
-    tabConfig: null,        // 鏍囩閰嶇疆淇℃伅
-    editSubTab: null,       // 缂栬緫瀛愭爣绛撅紙鏍囩涓殑鏍囩锛�
-    subTabConfig: null,     // 瀛愭爣绛鹃厤缃俊鎭�
-    subConfig: null,        // 瀛愰厤缃俊鎭�
-    btnTab: null,           // 鎵撳紑鏂版爣绛炬垨褰撳墠椤甸潰鍒锋柊鐨勬寜閽�
-    btnTabConfig: null,     // 鎵撳紑鏂版爣绛炬寜閽厤缃�
-    handleMVisible: false,  // 娣诲姞鎴栦慨鏀硅彍鍗曟ā鎬佹锛堣鑹叉潈闄愬垎閰嶇瓑锛�
-    sysMenu: false,         // 娣诲姞鎴栫紪杈戣彍鍗曪紙瑙掕壊鏉冮檺鍒嗛厤绛夛級
-    targetKeys: []          // 瑙e喕鑿滃崟鍒楄〃 
-  }
-
-  /**
-   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
-   */
-  componentWillUnmount () {
-    this.setState = () => {
-      return
-    }
-  }
-
-  /**
-   * @description 鑿滃崟椤哄簭鏀瑰彉鏃讹紝淇濆瓨涓棿鐘舵��
-   */
-  handlePreviewList = (List) => {
-    this.setState({
-      menulist: List
-    })
-  }
-
-  /**
-   * @description 鑿滃崟缂栬緫锛氫慨鏀广�佸垹闄�
-   * 1銆佽彍鍗曚慨鏀规垨鍒犻櫎鏃讹紝鍏堟煡鐪嬭彍鍗曢『搴忔槸鍚︽敼鍙�
-   * 2銆佽彍鍗曞垹闄�
-   * 3銆佽彍鍗曠紪杈戯紝鏌ヨ鑿滃崟閰嶇疆淇℃伅锛屼俊鎭纭紝杩涘叆瀵瑰簲缂栬緫椤甸潰
-   */
-  handleMenu = (menu) => {
-    const _this = this
-
-    if (!is(fromJS(this.props.menulist), fromJS(this.state.menulist))) {
-      notification.warning({
-        top: 92,
-        message: this.state.dict['model.menu.presave'],
-        duration: 5
-      })
-    } else if (menu.type === 'close') {
-      confirm({
-        title: this.state.dict['model.menu.close'].replace('@M', menu.card.MenuName),
-        content: '',
-        onOk() {
-          let param = {
-            func: 'sPC_MainMenu_Del',
-            MenuID: menu.card.MenuID
-          }
-          return Api.getSystemConfig(param).then(res => {
-            if (res.status) {
-              _this.props.reload()
-            } else {
-              notification.warning({
-                top: 92,
-                message: res.message,
-                duration: 5
-              })
-            }
-          })
-        },
-        onCancel() {}
-      })
-    } else if (menu.type === 'edit') {
-      let _menu = fromJS(menu.card).toJS()
-
-      if (_menu.PageParam && (_menu.PageParam.Template === 'RolePermission' || _menu.PageParam.Template === 'NewPage')) { // 鍗曢〉闈慨鏀�
-        _menu.Template = _menu.PageParam.Template
-        _menu.url = _menu.PageParam.url
-
-        _menu.fstMenuId = _menu.FstId
-        _menu.supMenuList = this.props.supMenuList
-        _menu.fstMenuList = this.props.menuTree
-  
-        this.setState({
-          handleMVisible: true,
-          sysMenu: _menu
-        })
-
-        return
-      }
-
-
-      let param = {
-        func: 'sPC_Get_LongParam',
-        MenuID: _menu.MenuID
-      }
-
-      this.setState({
-        loading: true
-      })
-
-      Api.getSystemConfig(param).then(res => {
-        if (res.status) {
-          let _LongParam = ''
-          if (res.LongParam) {
-            try {
-              _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
-            } catch (e) {
-              console.warn('Parse Failure')
-              _LongParam = ''
-            }
-          }
-
-          _menu.LongParam = _LongParam
-          _menu.fstMenuId = _menu.FstId
-          _menu.supMenuList = this.props.supMenuList
-          _menu.fstMenuList = this.props.menuTree
-          _menu.open_edition = res.open_edition || ''
-
-          // 妫�娴嬫ā鏉挎槸鍚﹀瓨鍦�
-          let _Template = this.state.sysTemplates.filter(temp => temp.type === _menu.PageParam.Template)
-
-          // 妯℃澘涓嶅瓨鍦ㄦ椂閿欒鎻愮ず
-          if (_Template.length === 0) {
-            notification.warning({
-              top: 92,
-              message: '鑿滃崟妯℃澘涓㈠け锛岃閲嶆柊閫夋嫨妯℃澘锛�',
-              duration: 5
-            })
-
-            this.setState({
-              type: 'edit',
-              editMenu: _menu,
-              loading: false,
-              tabview: 'template'
-            }, () => {
-              document.getElementById('root').style.overflowY = 'hidden'
-            })
-          } else {
-            this.setState({
-              type: 'edit',
-              editMenu: _menu,
-              loading: false,
-              tabview: _menu.PageParam.Template
-            }, () => {
-              document.getElementById('root').style.overflowY = 'hidden'
-            })
-          }
-        } else {
-          this.setState({
-            loading: false
-          })
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 5
-          })
-        }
-      })
-    }
-  }
-
-  handleSubBtn = (type) => {
-    // 鎿嶄綔鎸夐挳锛氭坊鍔犮�佽В闄ゅ喕缁撱�佺‘璁ゅ強鍏抽棴
-    if (type === 'add') { // 鐐瑰嚮娣诲姞鏃讹紝灞曞紑妯℃澘
-      if (!is(fromJS(this.props.menulist), fromJS(this.state.menulist))) {
-        notification.warning({
-          top: 92,
-          message: this.state.dict['model.menu.presave'],
-          duration: 5
-        })
-        return
-      }
-
-      this.setState({
-        tabview: 'template',
-        editMenu: {
-          MenuID: Utils.getuuid(),
-          MenuName: '',
-          MenuNo: '',
-          type: '',
-          PageParam: '',
-          LongParam: '',
-          isSubtable: '', // 鏄惁涓轰富瀛愯〃
-          ParentId: this.props.supMenu.MenuID,
-          supMenuList: this.props.supMenuList,
-          fstMenuId: this.props.mainMenu.MenuID,
-          fstMenuList: this.props.menuTree,
-          menuSort: (this.props.menulist.length + 1) * 10 // 鏂板缓鑿滃崟璁剧疆鎺掑簭
-        }
-      }, () => {
-        document.getElementById('root').style.overflowY = 'hidden'
-      })
-    } else if (type === 'thaw') {
-      if (!is(fromJS(this.props.menulist), fromJS(this.state.menulist))) {
-        notification.warning({
-          top: 92,
-          message: this.state.dict['model.menu.presave'],
-          duration: 5
-        })
-        return
-      }
-      this.setState({
-        thawMvisible: true,
-        targetKeys: []
-      })
-      Api.getSystemConfig({
-        func: 'sPC_Get_FrozenMenu',
-        ParentID: this.props.supMenu.MenuID,
-        TYPE: 30
-      }).then(res => {
-        if (res.status) {
-          this.setState({
-            thawmenulist: res.data.map(menu => {
-              return {
-                key: menu.MenuID,
-                title: menu.MenuName
-              }
-            })
-          })
-        } else {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 5
-          })
-        }
-      })
-    } else if (type === 'confirm') {
-      if (!is(fromJS(this.props.menulist), fromJS(this.state.menulist))) {
-        let _this = this
-        let param  = {
-          func: 'sPC_Menu_SortUpt',
-          LText: this.state.menulist.map((item, index) => {
-            return 'select \'' + item.MenuID + '\' as Menuid,' + (index + 1) * 10 + ' as sort'
-          })
-        }
-
-        param.LText = param.LText.join(' union ') // sql鎷兼帴
-        param.LText = Utils.formatOptions(param.LText) // 鍏抽敭瀛楃鏇挎崲锛宐ase64鍔犲瘑
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') // 鏃堕棿鎴�
-        param.secretkey = Utils.encrypt(param.LText, param.timestamp) // md5瀵嗛挜
-
-        confirm({
-          title: this.state.dict['model.menu.resetorder'],
-          content: '',
-          onOk() {
-            return Api.getSystemConfig(param).then(res => {
-              if (res.status) {
-                _this.props.reload()
-              } else {
-                notification.warning({
-                  top: 92,
-                  message: res.message,
-                  duration: 5
-                })
-              }
-            })
-          },
-          onCancel() {}
-        })
-      } else {
-        this.props.exitEdit()
-      }
-    } else if (type === 'close') {
-      if (!is(fromJS(this.props.menulist), fromJS(this.state.menulist))) {
-        let _this = this
-
-        confirm({
-          title: '鑿滃崟椤哄簭宸茶皟鏁达紝鏀惧純淇濆瓨鍚楋紵',
-          content: '',
-          onOk() {
-            _this.props.exitEdit()
-          },
-          onCancel() {}
-        })
-      } else {
-        this.props.exitEdit()
-      }
-    }
-  }
-
-  thawMemuSubmit = () => {
-    const { targetKeys } = this.state
-    // 涓夌骇鑿滃崟瑙i櫎鍐荤粨
-    if (targetKeys.length === 0) {
-      notification.warning({
-        top: 92,
-        message: this.state.dict['form.required.select'] + this.state.dict['model.menu'],
-        duration: 5
-      })
-    } else {
-      this.setState({
-        confirmLoading: true
-      })
-      let defers = targetKeys.map(item => {
-        return new Promise((resolve) => {
-          Api.getSystemConfig({
-            func: 'sPC_MainMenu_ReDel',
-            MenuID: item
-          }).then(res => {
-            if (res.status) {
-              resolve('')
-            } else {
-              resolve(res.message)
-            }
-          })
-        })
-      })
-      Promise.all(defers).then(res => {
-        let msg = res.filter(Boolean)[0]
-        if (msg) {
-          notification.error({
-            top: 92,
-            message: msg,
-            duration: 10
-          })
-        } else {
-          this.setState({
-            confirmLoading: false,
-            thawMvisible: false,
-            targetKeys: [],
-            thawmenulist: null
-          })
-          this.props.reload()
-        }
-      })
-    }
-  }
-
-  thawMemuCancel = () => {
-    // 瑙i櫎鍐荤粨-鍙栨秷
-    this.setState({
-      thawMvisible: false,
-      thawmenulist: null,
-      targetKeys: []
-    })
-  }
-
-  previewPicture = (template) => {
-    if (template.disabled) return
-    // 鍥剧墖棰勮
-    this.setState({
-      preview: template.url,
-      pretemplate: template
-    })
-  }
-
-  cancelPrePicture = () => {
-    // 鍏抽棴鍥剧墖棰勮
-    this.setState({
-      preview: null
-    })
-  }
-
-  /**
-   * @description 浣跨敤妯℃澘
-   * 1銆佷娇鐢ㄧ郴缁熸ā鏉挎椂锛屼娇鐢ㄧ郴缁熼厤缃�
-   * 2銆佷娇鐢ㄥ凡鏈夎彍鍗曟ā鏉挎椂锛岃幏鍙栬彍鍗曢厤缃俊鎭紝鏍囪涓簎ser锛堝鍒惰彍鍗曟寜閽級
-   */
-  useTemplate = (template, useType) => {
-    let editMenu = fromJS(this.state.editMenu).toJS()
-
-    editMenu.fstMenuId = this.props.mainMenu.MenuID
-    editMenu.fstMenuList = this.props.menuTree
-
-    if (useType === 'sys' && (template.type === 'RolePermission' || template.type === 'NewPage')) { // 鐙珛椤甸潰
-      let _menu = {
-        ...editMenu,
-        MenuID: Utils.getuuid(),
-        MenuName: template.title,
-        Template: template.type,
-        ParentId: this.props.supMenu.MenuID,
-        menuSort: (this.props.menulist.length + 1) * 10,
-        isSystem: true
-      }
-
-      this.setState({
-        handleMVisible: true,
-        sysMenu: _menu
-      })
-      return
-    } else if (template.type === 'CustomPage') {
-      let _menu = {
-        ...editMenu,
-        MenuID: Utils.getuuid(),
-        MenuName: template.title,
-        Template: template.type,
-        ParentId: this.props.supMenu.MenuID,
-        OriginMenuId: template.uuid || '',
-        menuSort: (this.props.menulist.length + 1) * 10,
-        isSystem: true
-      }
-
-      this.setState({
-        handleMVisible: true,
-        sysMenu: _menu
-      })
-      return
-    }
-
-    new Promise(resolve => {
-      if (useType === 'sys') {
-        resolve(true)
-      } else {
-        let param = {
-          func: 'sPC_Get_LongParam',
-          MenuID: template.uuid
-        }
-        this.setState({
-          loading: true
-        })
-
-        Api.getSystemConfig(param).then(result => {
-          if (!result.status) {
-            notification.warning({
-              top: 92,
-              message: result.message,
-              duration: 5
-            })
-            resolve(false)
-          } else {
-            let _config = ''
-            if (result.LongParam) {
-              try {
-                _config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
-                _config.type = 'user'
-              } catch (e) {
-                console.warn('Parse Failure')
-                _config = ''
-              }
-            }
-
-            if (_config) {
-              template.baseconfig = _config
-              resolve(true)
-            } else {
-              notification.warning({
-                top: 92,
-                message: '妯℃澘淇℃伅鑾峰彇澶辫触锛�',
-                duration: 5
-              })
-              resolve(false)
-            }
-          }
-        })
-      }
-    }).then(res => {
-      if (!res) { // 閿欒鏃讹紝閲嶇疆鐘舵��
-        this.setState({
-          loading: false
-        })
-        return
-      }
-
-      // 閫夋嫨妯℃澘锛氭坊鍔犺彍鍗曟椂(涓嶅瓨鍦╩enuId)
-      let _PageParam = {
-        OpenType: editMenu.PageParam ? editMenu.PageParam.OpenType : 'newtab',
-        Template: template.type
-      }
-
-      this.setState({
-        loading: false,
-        tabview: template.type,
-        editMenu: {
-          ...editMenu,
-          type: template.type,
-          PageParam: _PageParam,
-          LongParam: template.baseconfig,
-          isSubtable: template.isSubtable
-        }
-      })
-
-      document.getElementById('root').style.overflowY = 'hidden'
-    })
-  }
-
-  getUsedTemplate = () => {
-    const { memberLevel } = this.props
-    let { sysTemplates } = this.state
-    const illust = { // 妯℃澘鍥剧墖锛岀敤浜庡凡浣跨敤妯℃澘
-      CommonTable: mainsubtable,
-      TreePage: treepage,
-      CalendarPage: calendar,
-      CustomPage: customImg
-    }
-
-    Api.getSystemConfig({func: 'sPC_Get_UserTemp', TypeCharTwo: 'menu'}).then(res => {
-      let _templates = []
-
-      res.UserTemp.forEach(temp => {
-        if (temp.Template === 'NewPage' || temp.Template === 'RolePermission') {
-          return
-        } else if (temp.Template === 'CustomPage' && memberLevel < 20) {
-          temp.disabled = true
-          temp.disTitle = '浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��'
-        }
-        
-        _templates.push({
-          uuid: temp.MenuID,
-          title: temp.MenuName,
-          type: temp.Template,
-          url: illust[temp.Template],
-          disabled: temp.disabled || false,
-          disTitle: temp.disTitle || ''
-        })
-      })
-
-      sysTemplates = sysTemplates.map(temp => {
-        if (temp.type === 'CustomPage' && memberLevel < 20) {
-          temp.disabled = true
-          temp.disTitle = '浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��'
-        }
-
-        return temp
-      })
-
-      this.setState({
-        usedTemplates: _templates,
-        sysTemplates: sysTemplates
-      })
-    })
-  }
-
-  exittabview = () => {
-    this.setState({tabview: ''})
-    document.getElementById('root').style.overflowY = 'unset'
-  }
-
-  handleView = (param) => {
-    this.setState({
-      tabview: ''
-    }, () => {
-      if (param) {
-        this.setState(param)
-        document.getElementById('root').style.overflowY = 'hidden'
-      } else {
-        document.getElementById('root').style.overflowY = 'unset'
-      }
-    })
-  }
-
-  /**
-   * @description 涓夌骇鑿滃崟娣诲姞鎴栦慨鏀�
-   */
-  memuSubmit = () => {
-    const { sysMenu } = this.state
-    let sysTemplates = fromJS(this.state.sysTemplates).toJS()
-
-    // 瑙掕壊鏉冮檺鍒嗛厤妯℃澘锛屽彧鍙互娣诲姞涓�娆�
-    // if (sysMenu.isSystem && (sysMenu.Template === 'RolePermission')) {
-    //   sysTemplates = sysTemplates.map(temp => {
-    //     if (temp.type === sysMenu.type) {
-    //       temp.hidden = true
-    //     }
-
-    //     return temp
-    //   })
-    // }
-
-    this.menuFormRef.handleConfirm().then(res => {
-      let PageParam = {
-        Template: sysMenu.Template,
-        OpenType: 'newtab'
-      }
-
-      if (sysMenu.Template === 'NewPage') {
-        PageParam.OpenType = 'NewPage'
-        PageParam.url = res.url
-      }
-
-      let param = {
-        func: 'sPC_TrdMenu_AddUpt',
-        FstID: res.fstMenuId,
-        SndID: res.ParentID,
-        ParentID: res.ParentID,
-        MenuID: sysMenu.MenuID,
-        MenuNo: res.MenuNo,
-        Template: sysMenu.Template,
-        MenuName: res.MenuName,
-        PageParam: JSON.stringify(PageParam),
-        LongParam: '',
-        LText: '',
-        LTexttb: ''
-      }
-
-      if (sysMenu.menuSort) { // 鑿滃崟鏂板缓鏃惰缃帓搴�
-        param.Sort = sysMenu.menuSort
-      }
-
-      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-      param.secretkey = Utils.encrypt(param.LText, param.timestamp)
-
-      this.setState({
-        confirmLoading: true
-      })
-
-      if (sysMenu.Template === 'CustomPage' && sysMenu.OriginMenuId) {
-        this.copyMenu(param, sysMenu.OriginMenuId)
-      } else {
-        Api.getSystemConfig(param).then(response => {
-          if (response.status) {
-            this.setState({
-              sysTemplates: sysTemplates,
-              confirmLoading: false,
-              handleMVisible: false,
-              sysMenu: '',
-              tabview: ''
-            })
-  
-            this.props.reload()
-            document.getElementById('root').style.overflowY = 'unset'
-          } else {
-            this.setState({
-              confirmLoading: false
-            })
-            notification.warning({
-              top: 92,
-              message: response.message,
-              duration: 5
-            })
-          }
-        })
-      }
-    })
-  }
-
-  copyMenu = (param, MenuId) => {
-    Api.getSystemConfig({
-      func: 'sPC_Get_LongParam',
-      MenuID: MenuId
-    }).then(result => {
-      if (result.status) {
-        let config = null
-  
-        try {
-          config = result.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) : null
-        } catch (e) {
-          console.warn('Parse Failure')
-          config = null
-        }
-  
-        if (config) {
-          config.uuid = param.MenuID
-          config.MenuID = param.MenuID
-          config.parentId = param.ParentID
-          config.MenuName = param.MenuName
-          config.MenuNo = param.MenuNo
-          config.easyCode = ''
-          config.components = MenuUtils.resetConfig(config.components)
-          config.enabled = false
-
-          param.LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(config)))
-        }
-
-        Api.getSystemConfig(param).then(response => {
-          if (response.status) {
-            this.setState({
-              confirmLoading: false,
-              handleMVisible: false,
-              sysMenu: '',
-              tabview: ''
-            })
-  
-            this.props.reload()
-            document.getElementById('root').style.overflowY = 'unset'
-          } else {
-            this.setState({
-              confirmLoading: false
-            })
-            notification.warning({
-              top: 92,
-              message: response.message,
-              duration: 5
-            })
-          }
-        })
-      } else {
-        this.setState({
-          confirmLoading: false
-        })
-        notification.warning({
-          top: 92,
-          message: result.message,
-          duration: 5
-        })
-      }
-    })
-  }
-
-  UNSAFE_componentWillMount () {
-    this.getUsedTemplate()
-
-    this.setState({
-      menulist: this.props.menulist
-    })
-  }
-
-  UNSAFE_componentWillReceiveProps (nextProps) {
-    if (!is(fromJS(this.props.menulist), fromJS(nextProps.menulist))) {
-      this.setState({
-        menulist: nextProps.menulist
-      })
-    }
-  }
-
-  render () {
-    const { dict } = this.state
-    return (
-      <div className="third-edit-box">
-        {!this.state.tabview ?
-          <div className="mask">
-            <div className="tipcard card1" style={{backgroundImage: 'url(' + card1 + ')'}}>
-              鎷栧姩涓夌骇鑿滃崟鍙皟鏁撮『搴忥紝椤哄簭璋冩暣鍚庯紝璇风偣鍑荤‘瀹氭寜閽繚瀛樸��
-            </div>
-            <div className="tipcard card2" style={{backgroundImage: 'url(' + card2 + ')'}}>
-              鐐瑰嚮缂栬緫鍥炬爣浼氭牴鎹彍鍗曟ā鏉匡紝杩涘叆鐩稿簲鐨勬ā鏉跨紪杈戦〉闈紝鐐瑰嚮鍒犻櫎鍥炬爣鍙垹闄よ彍鍗曘��
-            </div>
-            <div className="tipcard card3" style={{backgroundImage: 'url(' + card3 + ')'}}>
-              鐐瑰嚮瑙i櫎鍐荤粨鎸夐挳锛屽彲杩樺師宸插垹闄ょ殑涓夌骇鑿滃崟銆�
-            </div>
-            <div className="tipcard card4" style={{backgroundImage: 'url(' + card4 + ')'}}>
-              鐐瑰嚮娣诲姞鍥炬爣锛屼細鏄剧ず绯荤粺妯℃澘鍜屽凡浣跨敤妯℃澘锛岄�夋嫨宸蹭娇鐢ㄦā鏉挎椂锛屼細澶嶅埗宸叉坊鍔犺彍鍗曠殑閰嶇疆淇℃伅銆�
-            </div>
-            <div className="tipcard card5" style={{backgroundImage: 'url(' + card5 + ')'}}>
-              <p>缂栬緫鐘舵�佷腑锛岃彍鍗曚箣澶栧尯鍩熶細閿佸畾锛屾煡鐪嬬郴缁熸暟鎹鐐瑰嚮銆�</p>
-              <div>
-                <span className="new-view" onClick={() => {window.open('#/main')}} >鏂伴〉闈�</span>
-              </div>
-            </div>
-          </div> : null
-        }
-        <div className="cus-submenu-title">
-          <MkIcon type={this.props.supMenu.PageParam.Icon} />
-          <span>{this.props.supMenu.MenuName}</span>
-        </div>
-        <DndProvider backend={HTML5Backend}>
-          <DragElement
-            list={this.state.menulist}
-            handlePreviewList={this.handlePreviewList}
-            handleMenu={this.handleMenu}
-          />
-        </DndProvider>
-        <div className="menu-add" onClick={() => {this.handleSubBtn('add')}}>
-          <PlusOutlined />
-        </div>
-        <div className="menu-btn">
-          <Button type="primary" onClick={() => {this.handleSubBtn('thaw')}}>{dict['model.thaw'] + dict['model.menu']}</Button>
-          <Button type="primary" onClick={() => {this.handleSubBtn('confirm')}}>{dict['model.confirm']}</Button>
-          <Button onClick={() => {this.handleSubBtn('close')}}>{dict['model.close']}</Button>
-        </div>
-        {this.state.tabview === 'template' ?
-          <div className="editboard">
-            <div className="workplace">
-              <Button className="top-btn mk-yellow" onClick={this.exittabview}>{dict['model.cancel']}</Button>
-              {this.state.tabview === 'template' && <Tabs defaultActiveKey="1">
-                <TabPane tab="绯荤粺妯℃澘" key="1">
-                  <Row>
-                    {this.state.sysTemplates.map((template, index) => {
-                      // if (template.hidden) return null
-
-                      return (
-                        <Col key={`${index}`} className={template.disabled ? 'disabled' : ''} title={template.disTitle || ''} span={8}>
-                          <Card
-                            title={template.title}>
-                            <img onClick={() => {this.previewPicture(template)}} src={template.url} alt=""/>
-                            <div className="card-operation">
-                              <Button type="primary" onClick={() => {this.useTemplate(template, 'sys')}}>浣跨敤妯℃澘</Button>
-                            </div>
-                          </Card>
-                        </Col>
-                      )
-                    })}
-                  </Row>
-                </TabPane>
-                <TabPane tab="宸蹭娇鐢ㄦā鏉�" key="2">
-                  <Row>
-                    <Col span={8}>
-                      <Search placeholder="璇疯緭鍏ヨ彍鍗曞悕绉�" defaultValue={this.state.tempSearchKey} onSearch={value => {this.setState({tempSearchKey: value})}} enterButton />
-                    </Col>
-                  </Row>
-                  <Row>
-                    {this.state.usedTemplates && this.state.usedTemplates.map((template, index) => {
-                      if (template.title.toLowerCase().indexOf(this.state.tempSearchKey.toLowerCase()) >= 0) {
-                        return (
-                          <Col key={template.type + index} className={template.disabled ? 'disabled' : ''} title={template.disTitle || ''} span={8}>
-                            <Card
-                              title={template.title}>
-                              <img onClick={() => {this.previewPicture(template)}} src={template.url} alt=""/>
-                              <div className="card-operation">
-                                <Button type="primary" onClick={() => {this.useTemplate(template, 'user')}}>浣跨敤妯℃澘</Button>
-                              </div>
-                            </Card>
-                          </Col>
-                        )
-                      } else {
-                        return ''
-                      }
-                    })}
-                  </Row>
-                </TabPane>
-              </Tabs>}
-            </div>
-          </div> : null
-        }
-        {this.state.tabview === 'TreePage' ?
-          <TreePageConfig
-            menu={this.state.editMenu}
-            reloadmenu={() => {this.props.reload()}}
-            handleView={this.handleView}
-          /> : null
-        }
-        {this.state.tabview === 'CalendarPage' ?
-          <CalendarPageConfig
-            menu={this.state.editMenu}
-            reloadmenu={() => {this.props.reload()}}
-            handleView={this.handleView}
-          /> : null
-        }
-        {this.state.tabview === 'CommonTable' ?
-          <ComTableConfig
-            menu={this.state.editMenu}
-            reloadmenu={() => {this.props.reload()}}
-            handleView={this.handleView}
-          /> : null
-        }
-        {this.state.tabview === 'Modal' ?
-          <ModalConfig
-            menu={this.state.editMenu}
-            editTab={this.state.editTab}
-            tabConfig={this.state.tabConfig}
-            editSubTab={this.state.editSubTab}
-            subTabConfig={this.state.subTabConfig}
-            btnTab={this.state.btnTab}
-            btnTabConfig={this.state.btnTabConfig}
-            editAction={this.state.editAction}
-            subConfig={this.state.subConfig}
-            handleView={this.handleView}
-          /> : null
-        }
-        {this.state.tabview === 'SubTable' ?
-          <SubTable
-            menu={this.state.editMenu}
-            editTab={this.state.editTab}
-            editSubTab={this.state.editSubTab}
-            tabConfig={this.state.tabConfig}
-            btnTab={this.state.btnTab}
-            btnTabConfig={this.state.btnTabConfig}
-            config={this.state.subConfig}
-            handleView={this.handleView}
-          /> : null
-        }
-        {this.state.tabview === 'FormTab' ?
-          <FormTabConfig
-            menu={this.state.editMenu}
-            btnTab={this.state.btnTab}
-            config={this.state.subConfig}
-            handleView={this.handleView}
-          /> : null
-        }
-        {/* 鍥剧墖棰勮 */}
-        <Preview cancel={this.cancelPrePicture} preview={this.state.preview} template={this.state.pretemplate} confirm={this.useTemplate}/>
-        {/* 瑙e喕鑿滃崟妯℃�佹 */}
-        <Modal
-          title={dict['model.thaw'] + dict['model.menu']}
-          width={600}
-          visible={this.state.thawMvisible}
-          onOk={this.thawMemuSubmit}
-          confirmLoading={this.state.confirmLoading}
-          onCancel={this.thawMemuCancel}
-          destroyOnClose
-        >
-          {!this.state.thawmenulist && <Spin style={{marginLeft: 'calc(50% - 22px)', marginTop: '70px', marginBottom: '70px'}} size="large" />}
-          {this.state.thawmenulist && <TransferForm onChange={(vals) => this.setState({targetKeys: vals})} menulist={this.state.thawmenulist}/>}
-        </Modal>
-        {/* 娣诲姞绯荤粺鑿滃崟 */}
-        <Modal
-          title={this.state.sysMenu && this.state.sysMenu.isSystem ? dict['model.add'] + dict['model.menu'] : dict['model.update'] + dict['model.menu']}
-          visible={this.state.handleMVisible}
-          onOk={this.memuSubmit}
-          confirmLoading={this.state.confirmLoading}
-          onCancel={() => {this.setState({handleMVisible: false})}}
-          destroyOnClose
-        >
-          <MenuForm
-            menu={this.state.sysMenu}
-            dict={dict}
-            inputSubmit={this.memuSubmit}
-            wrappedComponentRef={(inst) => this.menuFormRef = inst}
-          />
-        </Modal>
-        {this.state.loading && <Spin className="loading-thdmenu" size="large" />}
-      </div>
-    )
-  }
-}
-
-const mapStateToProps = (state) => {
-  return {
-    mainMenu: state.mainMenu,
-    menuTree: state.menuTree,
-    memberLevel: state.memberLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default withRouter(connect(mapStateToProps, mapDispatchToProps)(EditMenu))
\ No newline at end of file
diff --git a/src/templates/menuconfig/editthdmenu/index.scss b/src/templates/menuconfig/editthdmenu/index.scss
deleted file mode 100644
index 83a9525..0000000
--- a/src/templates/menuconfig/editthdmenu/index.scss
+++ /dev/null
@@ -1,196 +0,0 @@
-.third-edit-box {
-  position: relative;
-  z-index: 10;
-  .mask {
-    position: fixed;
-    top: 0px;
-    left: 0px;
-    right: 0px;
-    bottom: 0px;
-    .tipcard {
-      position: absolute;
-      min-height: 100px;
-      font-size: 16px;
-      border-radius: 6px;
-      background-size: 100% 100%;
-      background-repeat: no-repeat;
-      padding: 15px;  
-    }
-    .card1 {
-      left: 30%;
-      top: 20vh;
-      width: 250px;
-      min-height: 100px;
-      color: #000000;
-      font-style: oblique;
-    }
-    .card2 {
-      left: 60%;
-      top: 20vh;
-      width: 250px;
-      min-height: 100px;
-      color: #000000;
-      padding: 20px 30px;
-      font-style: oblique;
-    }
-    .card3 {
-      left: 30%;
-      top: 50vh;
-      width: 250px;
-      min-height: 150px;
-      color: #000000;
-      padding: 20px 30px;
-      font-style: oblique;
-    }
-    .card4 {
-      left: 60%;
-      top: 50vh;
-      width: 250px;
-      min-height: 150px;
-      color: #000000;
-      padding: 20px 30px;
-      font-style: oblique;
-    }
-    .card5 {
-      right: 5%;
-      top: 20vh;
-      width: 130px;
-      min-height: 240px;
-      color: #000000;
-      padding: 40px 15px 10px;
-      p {
-        margin: 0 0 5px;
-      }
-      div {
-        text-align: center;
-        .new-view {
-          display: inline-block;
-          cursor: pointer;
-          color: #fff;
-          padding: 2px 10px;
-          border-radius: 4px;
-          background-color: #1890ff;
-          border-color: #1890ff;
-          text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
-          -webkit-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
-          box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
-        }
-      }
-    }
-  }
-  .cus-submenu-title {
-    padding: 0px 24px;
-    background: #364150;
-    margin: 0;
-    height: 48px;
-    line-height: 48px;
-    width: 100%;
-    overflow: hidden;
-    font-size: 14px;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    .anticon {
-      margin-right: 10px;
-    }
-  }
-  .editboard {
-    position: fixed;
-    z-index: 1070;
-    padding-top: 48px;
-    top: 0px;
-    left: 0px;
-    right: 0px;
-    bottom: 0px;
-    background: rgba(0, 0, 0, 0.35);
-    .workplace {
-      position: relative;
-      width: calc(100vw - 235px);
-      height: 100%;
-      overflow-y: auto;
-      left: 235px;
-      background: #ffffff;
-
-      .top-btn {
-        position: absolute;
-        z-index: 1;
-        top: 12px;
-        right: 20px;
-        cursor: pointer;
-      }
-      .top-btn.submit {
-        right: 100px;
-      }
-      .ant-col {
-        padding: 10px;
-      }
-      .ant-col.disabled {
-        cursor: not-allowed;
-        .ant-card-head-title {
-          color: #959595;
-        }
-        .card-operation {
-          display: none;
-        }
-        img {
-          cursor: not-allowed;
-        }
-      }
-      .ant-card-head-title {
-        text-align: center;
-      }
-      .ant-card-body {
-        padding: 2px;
-        position: relative;
-        text-align: center;
-        overflow: hidden;
-        .card-operation {
-          position: absolute;
-          right: 0px;
-          top: 0;
-          height: 0px;
-          overflow: hidden;
-          transition: height 0.3s;
-          button {
-            height: 30px;
-            padding: 0 10px;
-            margin-top: 5px;
-            margin-right: 10px;
-            display: none;
-          }
-        }
-      }
-      .ant-card-body:hover {
-        .card-operation {
-          height: 40px;
-          button {
-            display: inline-block;
-          }
-        }
-      }
-      img {
-        max-width: 100%;
-        cursor: zoom-in;
-      }
-    }
-    .workplace::-webkit-scrollbar {
-      width: 7px;
-    }
-    .workplace::-webkit-scrollbar-thumb {
-      border-radius: 5px;
-      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
-      background: rgba(0, 0, 0, 0.13);
-    }
-    .workplace::-webkit-scrollbar-track {
-      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
-      border-radius: 3px;
-      border: 1px solid rgba(0, 0, 0, 0.07);
-      background: rgba(0, 0, 0, 0);
-    }
-  }
-  > .loading-thdmenu {
-    position: fixed;
-    left: calc(50vw - 22px);
-    top: calc(50vh - 70px);
-    z-index: 1100;
-  }
-}
diff --git a/src/templates/menuconfig/menuelement/card.jsx b/src/templates/menuconfig/menuelement/card.jsx
deleted file mode 100644
index 99b68ec..0000000
--- a/src/templates/menuconfig/menuelement/card.jsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import React from 'react'
-import { useDrag, useDrop } from 'react-dnd'
-import { EditOutlined, CloseOutlined } from '@ant-design/icons'
-import ItemTypes from './itemtypes'
-import MkIcon from '@/components/mk-icon'
-import './index.scss'
-
-const Card = ({ id, card, moveCard, findCard, editCard, closeCard }) => {
-  const originalIndex = findCard(id).index
-  const [{ isDragging }, drag] = useDrag({
-    item: { type: ItemTypes.CARD, id, originalIndex },
-    collect: monitor => ({
-      isDragging: monitor.isDragging(),
-    }),
-  })
-  const [, drop] = useDrop({
-    accept: ItemTypes.CARD,
-    canDrop: () => true,
-    drop({ id: draggedId }) {
-      if (draggedId !== id) {
-        const { index: overIndex } = findCard(id)
-        moveCard(draggedId, overIndex)
-      }
-    },
-  })
-  const opacity = isDragging ? 0 : 1
-
-  const edit = () => {
-    editCard(id)
-  }
-
-  const close = () => {
-    closeCard(id)
-  }
-
-  let _param = ''
-  if (card.type === 'CustomPage') {
-    _param = {
-      MenuType: 'custom',
-      MenuId: card.MenuID,
-      ParentId: card.ParentId,
-      MenuName: card.MenuName,
-      MenuNo: card.MenuNo
-    }
-    _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
-  }
-
-  return (
-    <div className="side-card" style={{ opacity }}>
-      <div ref={node => drag(drop(node))}>
-        {card.PageParam && card.PageParam.Icon && <MkIcon type={card.PageParam.Icon} />}
-        {card.MenuName}
-      </div>
-      {/* 鑷畾涔夋ā鏉匡紝鍦ㄦ柊椤甸潰缂栬緫 */}
-      {!card.forbidden && card.type !== 'CustomPage' ? <EditOutlined className="edit" onClick={edit} /> : null}
-      {!card.forbidden && card.type === 'CustomPage' ? <EditOutlined className="edit" onClick={() => {window.open(`#/menudesign/${_param}`)}}/> : null}
-      {card.forbidden && card.type === 'CustomPage' ? <EditOutlined className="edit" style={{color: '#959595', cursor: 'not-allowed'}} title="浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��"/> : null}
-      <CloseOutlined className="close" onClick={close} />
-    </div>
-  )
-}
-export default Card
diff --git a/src/templates/menuconfig/menuform/index.scss b/src/templates/menuconfig/menuform/index.scss
deleted file mode 100644
index 9914d8e..0000000
--- a/src/templates/menuconfig/menuform/index.scss
+++ /dev/null
@@ -1,17 +0,0 @@
-.ant-advanced-search-form.main-search {
-  padding: 0px 24px 20px;
-  border-bottom: 1px solid #d9d9d9;
-  .ant-form-item {
-    display: flex;
-    margin-bottom: 10px;
-  }
-  .ant-form-item-control-wrapper {
-    flex: 1;
-  }
-  .ant-form-item-label {
-    width: 100px;
-  }
-}
-.ant-advanced-search-form {
-  position: relative;
-}
diff --git a/src/templates/modalconfig/checkCard/index.jsx b/src/templates/modalconfig/checkCard/index.jsx
index 952f4db..1766dd0 100644
--- a/src/templates/modalconfig/checkCard/index.jsx
+++ b/src/templates/modalconfig/checkCard/index.jsx
@@ -10,61 +10,93 @@
     onChange: PropTypes.func,    // 鏁版嵁鍒囨崲
   }
 
-  state = {}
+  state = {
+    appType: sessionStorage.getItem('appType'),
+  }
 
   getCards = () => {
-    const { display, width, options, fields, ratio, picratio, backgroundColor, borderColor } = this.props.config
+    const { display, width, options, fields, ratio, picratio, backgroundColor } = this.props.config
 
-    let _ratio = picratio || ratio
-    let paddingTop = '100%'
-    if (_ratio === '4:3') {
-      paddingTop = '75%'
-    } else if (_ratio === '3:2') {
-      paddingTop = '66.7%'
-    } else if (_ratio === '16:9') {
-      paddingTop = '56.25%'
+    let _options = []
+    let _fields = fields || []
+
+    if (options) {
+      _options = options.filter(op => !op.Hide)
     }
 
-    let style = {}
-    
-    if (borderColor) {
-      style.borderColor = borderColor
+    let cls = ''
+    if (_options.length * width <= 24 && this.state.appType !== 'mob') {
+      cls = 'no-margin-bottom'
     }
-
-    if (display !== 'picture') {
-      let _style = backgroundColor ? {backgroundColor} : null
- 
-      if (!options || options.length === 0) {
+    if (display === 'picture') {
+      let _ratio = picratio || ratio
+      let paddingTop = '100%'
+      if (_ratio === '4:3') {
+        paddingTop = '75%'
+      } else if (_ratio === '3:2') {
+        paddingTop = '66.7%'
+      } else if (_ratio === '16:9') {
+        paddingTop = '56.25%'
+      }
+      if (_options.length === 0) {
         return <Col span={width}>
-          <div className="card-cell" style={style}>
-            <div className="bg-mask" style={_style}></div>
-            {fields ? fields.map(col => {
-              return <span key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{col.field}</span>
-            }) : null}
-            {!fields || fields.length === 0 ? <span style={{color: '#000000', fontSize: '14px', height: '21px'}}>绀轰緥</span> : null}
+          <div className="card-pic-cell no-margin-bottom" style={{paddingTop, background: '#91d5ff'}}>
           </div>
         </Col>
       }
-      return options.map(item => {
+      return _options.map(item => {
         return <Col span={width} key={item.key}>
-          <div className="card-cell" style={style}>
-            <div className="bg-mask" style={_style}></div>
-            {fields.map(col => {
-              return <span key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
+          <div className={'card-pic-cell ' + cls} style={{paddingTop, backgroundImage: `url(${item.$url})`}}>
+            <div className="content-wrap">
+              <div className="content-center">
+                {_fields.map(col => {
+                  return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
+                })}
+              </div>
+            </div>
+          </div>
+        </Col>
+      })
+    } else if (display === 'color') {
+      if (_options.length === 0) {
+        return <Col span={width}>
+          <div className="card-color-cell no-margin-bottom" style={{background: '#1890ff'}}>
+          </div>
+        </Col>
+      }
+      return _options.map(item => {
+        return <Col span={width} key={item.key}>
+          <div className={'card-color-cell ' + cls} style={{background: item.$value}}>
+            {_fields.map(col => {
+              return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
             })}
           </div>
         </Col>
       })
     } else {
-      if (!options || options.length === 0) {
+      let _style = null
+      let style = null
+
+      if (backgroundColor) {
+        _style = {backgroundColor}
+        style = {borderColor: 'transparent'}
+      }
+ 
+      if (_options.length === 0) {
         return <Col span={width}>
-          <div className="card-pic-cell" style={{...style, paddingTop, background: '#91d5ff'}}>
+          <div className="card-cell no-margin-bottom" style={style}>
+            <div className="bg-mask" style={_style}></div>
+            <span style={{color: '#000000', fontSize: '14px', height: '21px'}}>绀轰緥</span>
           </div>
         </Col>
       }
-      return options.map(item => {
+      return _options.map(item => {
         return <Col span={width} key={item.key}>
-          <div className="card-pic-cell" style={{...style, paddingTop, backgroundImage: `url(${item.$url})`}}>
+          <div className={'card-cell ' + cls} style={style}>
+            <div className="bg-mask" style={_style}></div>
+            {_fields.map(col => {
+              return <span className="content-line" key={col.key} style={{color: col.color, fontSize: col.fontSize + 'px', height: col.fontSize * 1.5 + 'px', textAlign: col.align}}>{item[col.field]}</span>
+            })}
           </div>
         </Col>
       })
diff --git a/src/templates/modalconfig/checkCard/index.scss b/src/templates/modalconfig/checkCard/index.scss
index 230aa8d..52cb625 100644
--- a/src/templates/modalconfig/checkCard/index.scss
+++ b/src/templates/modalconfig/checkCard/index.scss
@@ -9,14 +9,7 @@
     border-radius: 4px;
     padding: 6px;
     margin-bottom: 12px;
-    span {
-      display: block;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-      position: relative;
-      z-index: 1;
-    }
+    
     .bg-mask {
       position: absolute;
       top: 0;
@@ -29,10 +22,46 @@
     }
   }
   .card-pic-cell {
-    border: 1px solid #bcbcbc;
+    position: relative;
+    border: 1px solid #e8e8e8;
     border-radius: 4px;
     background-size: cover;
     background-position: center;
     margin-bottom: 12px;
+    overflow: hidden;
+
+    .content-wrap {
+      position: absolute;
+      top: 6px;
+      left: 6px;
+      right: 6px;
+      bottom: 6px;
+      .content-center {
+        position: relative;
+        top: 50%;
+        transform: translate(0px, -50%);
+      }
+    }
+  }
+  .card-color-cell {
+    border: 1px solid transparent;
+    border-radius: 4px;
+    padding: 6px;
+    background-size: cover;
+    background-position: center;
+    margin-bottom: 12px;
+    min-height: 35px;
+  }
+
+  .content-line {
+    display: block;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    position: relative;
+    z-index: 1;
+  }
+  .no-margin-bottom {
+    margin-bottom: 2px;
   }
 }
\ No newline at end of file
diff --git a/src/templates/modalconfig/dragelement/card.jsx b/src/templates/modalconfig/dragelement/card.jsx
index bbd5db0..3b2f64f 100644
--- a/src/templates/modalconfig/dragelement/card.jsx
+++ b/src/templates/modalconfig/dragelement/card.jsx
@@ -38,7 +38,7 @@
       }
     }
   })
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   const edit = () => {
     editCard(id)
@@ -53,7 +53,7 @@
   }
 
   const changeStyle = () => {
-    let options = ['font']
+    let options = ['font1']
 
     MKEmitter.emit('changeStyle', ['form', card.uuid], options, card.style || {})
   }
@@ -78,7 +78,7 @@
     formItem = (<Input style={{marginTop: '4px'}} placeholder={card.placeholder || ''} value={card.initval} />)
   } else if (card.type === 'number') {
     formItem = (<InputNumber value={card.initval} precision={card.decimal} />)
-  } else if (card.type === 'multiselect' || card.type === 'select' || card.type === 'link') {
+  } else if (card.type === 'multiselect' || card.type === 'select' || card.type === 'link' || card.type === 'cascader') {
     formItem = (<Select value={selectval}></Select>)
   } else if (card.type === 'color') {
     formItem = (<ColorSketch value={card.initval || 'transparent'}/>)
@@ -130,7 +130,9 @@
       <Checkbox value="D">D</Checkbox>
     </Checkbox.Group>)
   } else if (card.type === 'hint') {
-    formItem = <div style={{marginTop: '10px', color: 'rgba(0, 0, 0, 0.85)', lineHeight: '1.5', ...card.style}}>{card.message}</div>
+    formItem = <div style={{marginTop: '8px', color: 'rgba(0, 0, 0, 0.85)', lineHeight: '1.5', ...card.style}}>{card.message}</div>
+  } else if (card.type === 'formula') {
+    formItem = <div style={{marginTop: '8px', color: 'rgba(0, 0, 0, 0.85)', lineHeight: '1.5', ...card.style}}>{card.formula}{card.postfix || ''}</div>
   } else if (card.type === 'split') {
     formItem = <div className="split-line" style={card.style}>{card.label}</div>
   } else if (card.type === 'checkcard') {
@@ -146,6 +148,7 @@
   if (card.type === 'brafteditor' && card.hidelabel === 'true') {
     _label = null
   } else if (card.type === 'hint' && !card.label) {
+    className += ' no-label'
     _label = ' '
   }
 
diff --git a/src/templates/modalconfig/dragelement/index.jsx b/src/templates/modalconfig/dragelement/index.jsx
index e0dc731..a0f19a3 100644
--- a/src/templates/modalconfig/dragelement/index.jsx
+++ b/src/templates/modalconfig/dragelement/index.jsx
@@ -116,7 +116,7 @@
   })
 
   return (
-    <div ref={drop} className={'ant-row modal-fields-row ' + (setting.align || 'left_right')} >
+    <div ref={drop} className={'ant-row modal-fields-row ' + (setting.align || 'left_right') + ' space-' + (setting.verticalSpace || 'normal')} >
       {cards.map(card => {
         return <Col key={card.uuid} span={card.type === 'split' ? 24 : (card.span || 24)}>
           <Card
diff --git a/src/templates/modalconfig/dragelement/index.scss b/src/templates/modalconfig/dragelement/index.scss
index 50b59b2..a221984 100644
--- a/src/templates/modalconfig/dragelement/index.scss
+++ b/src/templates/modalconfig/dragelement/index.scss
@@ -131,9 +131,31 @@
     .ant-form-item-label {
       width: 100%!important;
       text-align: left;
+      height: 24px;
+      line-height: 28px;
     }
     .ant-form-item-control-wrapper {
       width: 100%!important;
     }
   }
+  .no-label {
+    .ant-form-item-label {
+      display: none;
+    }
+  }
+}
+.modal-fields-row.space-normal {
+  .page-card {
+    margin-bottom: 24px;
+  }
+}
+.modal-fields-row.space-middle {
+  .page-card {
+    margin-bottom: 15px;
+  }
+}
+.modal-fields-row.space-small {
+  .page-card {
+    margin-bottom: 5px;
+  }
 }
\ No newline at end of file
diff --git a/src/templates/modalconfig/index.jsx b/src/templates/modalconfig/index.jsx
index 92e35be..e6212f8 100644
--- a/src/templates/modalconfig/index.jsx
+++ b/src/templates/modalconfig/index.jsx
@@ -420,10 +420,10 @@
           LText: res.dataSource
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
         
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
 
         if (window.GLOB.mainSystemApi && res.database === 'sso') {
diff --git a/src/templates/modalconfig/index.scss b/src/templates/modalconfig/index.scss
index 55a0a3d..dfa0948 100644
--- a/src/templates/modalconfig/index.scss
+++ b/src/templates/modalconfig/index.scss
@@ -1,6 +1,6 @@
 .modal-form-board {
   position: fixed;
-  z-index: 1070;
+  z-index: 1;
   padding-top: 48px;
   top: 0px;
   left: 0px;
@@ -193,7 +193,7 @@
           position: relative;
           background: #ffffff;
           border-radius: 2px;
-          margin-bottom: 15px;
+          // margin-bottom: 15px;
         }
         .ant-calendar-picker {
           min-width: 100px!important;
diff --git a/src/templates/modalconfig/settingform/index.jsx b/src/templates/modalconfig/settingform/index.jsx
index f9abc14..db471a4 100644
--- a/src/templates/modalconfig/settingform/index.jsx
+++ b/src/templates/modalconfig/settingform/index.jsx
@@ -3,9 +3,9 @@
 import { Form, Row, Col, Input, Radio, InputNumber, Select, Tooltip } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 
-import { formRule } from '@/utils/option.js'
+// import { formRule } from '@/utils/option.js'
 import StyleInput from '@/menu/stylecontroller/styleInput'
-// import './index.scss'
+import './index.scss'
 
 class SettingForm extends Component {
   static propTpyes = {
@@ -16,29 +16,42 @@
 
   state = {
     fields: null,
-    display: this.props.config.setting.display,
-    appType: sessionStorage.getItem('appType')
+    display: this.props.config.setting.display || 'modal',
+    placement: this.props.config.setting.placement || 'right',
+    appType: sessionStorage.getItem('appType'),
+    dialogInput: false
   }
 
   UNSAFE_componentWillMount () {
     const { config } = this.props
     const { appType, display } = this.state
     let fields = []
+    let dialogInput = null
 
     config.fields.forEach(f => {
       if (f.field && ['select', 'link', 'text', 'number', 'textarea'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') {
         fields.push(f)
       }
+      if (f.field && f.hidden !== 'true' && f.readonly !== 'true') {
+        if (dialogInput === null) {
+          dialogInput = ['text', 'number'].includes(f.type)
+        } else {
+          dialogInput = false
+        }
+      }
     })
 
-    let _display = display 
-    if (appType === 'mob' && display !== 'prompt' && display !== 'drawer') {
+    let _display = display
+    if (appType === 'mob' && display === 'modal') {
       _display = 'drawer'
+    } else if (appType !== 'mob' && display === 'dialog') {
+      _display = 'modal'
     }
 
     this.setState({
       fields: fields,
-      display: _display
+      display: _display,
+      dialogInput
     })
   }
 
@@ -66,7 +79,7 @@
 
   render() {
     const { config } = this.props
-    const { fields, appType, display } = this.state
+    const { fields, appType, display, placement } = this.state
     const { getFieldDecorator } = this.props.form
 
     const formItemLayout = {
@@ -81,9 +94,9 @@
     }
 
     return (
-      <Form {...formItemLayout}>
+      <Form {...formItemLayout} className="form-setting-wrap">
         <Row gutter={24}>
-          <Col span={12}>
+          {/* <Col span={12}>
             <Form.Item label="鏍囬">
               {getFieldDecorator('title', {
                 initialValue: config.setting.title,
@@ -95,27 +108,40 @@
                 ]
               })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)}
             </Form.Item>
-          </Col>
-          {/* {appType !== 'mob' ? <Col span={12}>
-            <Form.Item label="瀹藉害锛�%锛�">
-              {getFieldDecorator('width', {
-                initialValue: config.setting.width
-              })(<InputNumber min={10} max={2000} precision={0} onPressEnter={this.handleSubmit}/>)}
-            </Form.Item>
-          </Col> : null} */}
-          <Col span={12}>
+          </Col> */}
+          <Col span={24}>
             <Form.Item label={
-              <Tooltip placement="topLeft" title="瀹藉害灏忎簬100鏃朵负鐧惧垎鐜囷紝澶т簬100鏃朵负缁濆鍊笺��">
+              <Tooltip placement="topLeft" title="瀵硅瘽妗嗗湪浠呮湁涓�涓彲杈撳叆琛ㄥ崟锛堥潪闅愯棌銆侀潪鍙鐨勬枃鏈垨鏁板瓧锛夋椂鏈夋晥銆�">
                 <QuestionCircleOutlined className="mk-form-tip" />
-                瀹藉害
+                鏄剧ず鏂瑰紡
+              </Tooltip>
+            }>
+              {getFieldDecorator('display', {
+                initialValue: display || 'modal'
+              })(
+                <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => this.setState({display: e.target.value})}>
+                  {appType !== 'mob' ? <Radio value="modal">妯℃�佹</Radio> : null}
+                  <Radio value="drawer">鎶藉眽</Radio>
+                  <Radio value="prompt">鏄惁妗�</Radio>
+                  <Radio value="exec">鐩存帴鎵ц</Radio>
+                  {appType !== 'mob' ? null : <Radio value="dialog">寮圭獥</Radio>}
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
+          {display === 'drawer' || display === 'modal' ? <Col span={12}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="灏忎簬100鏃朵负鐧惧垎鐜囷紝澶т簬100鏃朵负缁濆鍊笺��">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                {display === 'drawer' && (placement === 'top' || placement === 'bottom') ? '楂樺害' : '瀹藉害'}
               </Tooltip>
             }>
               {getFieldDecorator('width', {
-                initialValue: config.setting.width
+                initialValue: config.setting.width || (appType !== 'mob' ? 60 : 100)
               })(<InputNumber min={10} max={2000} precision={0} onPressEnter={this.handleSubmit}/>)}
             </Form.Item>
-          </Col>
-          <Col span={12}>
+          </Col> : null}
+          {['dialog', 'drawer', 'modal'].includes(display) ? <Col span={12}>
             <Form.Item label="鍒濆鐒︾偣">
               {getFieldDecorator('focus', {
                 initialValue: config.setting.focus || ''
@@ -133,8 +159,8 @@
                 </Select>
               )}
             </Form.Item>
-          </Col>
-          <Col span={12}>
+          </Col> : null}
+          {['drawer', 'modal'].includes(display) ? <Col span={12}>
             <Form.Item label={
               <Tooltip placement="topLeft" title="鎵ц澶辫触鏃堕渶瑕佽仛鐒︾殑琛ㄥ崟銆�">
                 <QuestionCircleOutlined className="mk-form-tip" />
@@ -157,20 +183,54 @@
                 </Select>
               )}
             </Form.Item>
-          </Col>
-          {appType !== 'mob' ? <Col span={12}>
-            <Form.Item label="琛ㄥ崟鎺掑垪">
-              {getFieldDecorator('align', {
-                initialValue: config.setting.align || 'left_right'
+          </Col> : null}
+          {appType === 'mob' && display === 'drawer' ? <Col span={12}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="琛ㄥ崟鍏冪礌涓庡乏渚ц竟鐣岀殑璺濈銆�">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                宸﹁竟璺�
+              </Tooltip>
+            }>
+              {getFieldDecorator('paddingLeft', {
+                initialValue: config.setting.paddingLeft || '10px'
               })(
-                <Radio.Group>
-                  <Radio value="left_right">宸﹀彸</Radio>
-                  <Radio value="up_down">涓婁笅</Radio>
-                </Radio.Group>
+                <StyleInput options={['px', '%']} />
               )}
             </Form.Item>
           </Col> : null}
-          <Col span={12}>
+          {appType === 'mob' && display === 'drawer' ? <Col span={12}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="琛ㄥ崟鍏冪礌涓庡彸渚ц竟鐣岀殑璺濈銆�">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鍙宠竟璺�
+              </Tooltip>
+            }>
+              {getFieldDecorator('paddingRight', {
+                initialValue: config.setting.paddingRight || '10px'
+              })(
+                <StyleInput options={['px', '%']} />
+              )}
+            </Form.Item>
+          </Col> : null}
+          {appType === 'mob' && display === 'drawer' ? <Col span={12}>
+            <Form.Item label="鎸夐挳鍚嶇О">
+              {getFieldDecorator('btnName', {
+                initialValue: config.setting.btnName || '纭畾'
+              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)}
+            </Form.Item>
+          </Col> : null}
+          {appType === 'mob' && display === 'drawer' ? <Col span={12}>
+            <Form.Item label="鎸夐挳浣嶇疆">
+              {getFieldDecorator('btnPosition', {
+                initialValue: config.setting.btnPosition || 'bottom'
+              })(
+                <Radio.Group style={{whiteSpace: 'nowrap'}}>
+                  <Radio value="bottom">涓嬩晶</Radio>
+                  <Radio value="top">涓婁晶</Radio>
+                </Radio.Group>)}
+            </Form.Item>
+          </Col> : null}
+          {['drawer', 'modal'].includes(display) ? <Col span={12}>
             <Form.Item label="瀹屾垚鍚�">
               {getFieldDecorator('finish', {
                 initialValue: config.setting.finish || 'close'
@@ -181,20 +241,8 @@
                 </Radio.Group>
               )}
             </Form.Item>
-          </Col>
-          <Col span={12}>
-            <Form.Item label="鐐瑰嚮钂欏眰">
-              {getFieldDecorator('clickouter', {
-                initialValue: config.setting.clickouter || 'unclose'
-              })(
-                <Radio.Group>
-                  <Radio value="unclose">涓嶅叧闂�</Radio>
-                  <Radio value="close">鍏抽棴</Radio>
-                </Radio.Group>
-              )}
-            </Form.Item>
-          </Col>
-          <Col span={12}>
+          </Col> : null}
+          {['dialog', 'drawer', 'modal'].includes(display) ? <Col span={12}>
             <Form.Item label={
               <Tooltip placement="topLeft" title="闇�瑕侀�氳繃鏁版嵁婧愭煡璇㈢殑閫夐」锛屾槸鍚︿娇鐢ㄧ紦瀛樸��">
                 <QuestionCircleOutlined className="mk-form-tip" />
@@ -210,48 +258,47 @@
                 </Radio.Group>
               )}
             </Form.Item>
-          </Col>
-          <Col span={12}>
-            <Form.Item label={
-              <Tooltip placement="topLeft" title="鎵撳嵃鎸夐挳涓棤鏁堛��">
-                <QuestionCircleOutlined className="mk-form-tip" />
-                鏄剧ず鏂瑰紡
-              </Tooltip>
-            }>
-              {getFieldDecorator('display', {
-                initialValue: display || 'modal'
-              })(
-                <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => this.setState({display: e.target.value})}>
-                  {appType !== 'mob' ? <Radio value="modal">妯℃�佹</Radio> : null}
-                  <Radio value="drawer">鎶藉眽</Radio>
-                  <Radio value="prompt">鏄惁妗�</Radio>
-                  <Radio value="exec">鐩存帴鎵ц</Radio>
-                </Radio.Group>
-              )}
-            </Form.Item>
-          </Col>
-          {!this.props.isSubTab && !appType && display === 'modal' ? <Col span={12}>
-            <Form.Item label="鎸傝浇瀵硅薄">
-              {getFieldDecorator('container', {
-                initialValue: config.setting.container || 'tab'
-              })(
-                <Radio.Group>
-                  <Radio value="view">椤甸潰</Radio>
-                  <Radio value="tab">鏍囩椤�</Radio>
-                </Radio.Group>
-              )}
-            </Form.Item>
           </Col> : null}
           {display === 'drawer' ? <Col span={12}>
             <Form.Item label="鎶藉眽鏂瑰悜">
               {getFieldDecorator('placement', {
-                initialValue: config.setting.placement || 'right'
+                initialValue: placement
               })(
-                <Radio.Group style={{whiteSpace: 'nowrap'}}>
+                <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => this.setState({placement: e.target.value})}>
                   <Radio value="right">鍙充晶</Radio>
                   <Radio value="left">宸︿晶</Radio>
                   <Radio value="top">涓婁晶</Radio>
                   <Radio value="bottom">涓嬩晶</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col> : null}
+          {appType !== 'mob' && (display === 'drawer' || display === 'modal') ? <Col span={12}>
+            <Form.Item label="琛ㄥ崟鎺掑垪">
+              {getFieldDecorator('align', {
+                initialValue: config.setting.align || 'left_right'
+              })(
+                <Radio.Group>
+                  <Radio value="left_right">宸﹀彸</Radio>
+                  <Radio value="up_down">涓婁笅</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col> : null}
+          {appType !== 'mob' && (display === 'drawer' || display === 'modal') ? <Col span={12}>
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="姝e父闂撮殭浼氶鐣欏嚭鎶ラ敊淇℃伅鐨勪綅缃紝闃叉琛ㄥ崟浣嶇疆鍙戠敓鍙樺寲銆�">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                绔栧悜闂撮殭
+              </Tooltip>
+            }>
+              {getFieldDecorator('verticalSpace', {
+                initialValue: config.setting.verticalSpace || 'normal'
+              })(
+                <Radio.Group>
+                  <Radio value="normal">姝e父</Radio>
+                  <Radio value="middle">涓�</Radio>
+                  <Radio value="small">灏�</Radio>
                 </Radio.Group>
               )}
             </Form.Item>
@@ -268,40 +315,28 @@
               )}
             </Form.Item>
           </Col> : null}
-          {appType === 'mob' ? <Col span={12}>
-            <Form.Item label="宸﹁竟璺�">
-              {getFieldDecorator('paddingLeft', {
-                initialValue: config.setting.paddingLeft || '10px'
+          {!this.props.isSubTab && !appType && display === 'modal' ? <Col span={12}>
+            <Form.Item label="鎸傝浇瀵硅薄">
+              {getFieldDecorator('container', {
+                initialValue: config.setting.container || 'tab'
               })(
-                <StyleInput options={['px', '%']} />
+                <Radio.Group>
+                  <Radio value="view">椤甸潰</Radio>
+                  <Radio value="tab">鏍囩椤�</Radio>
+                </Radio.Group>
               )}
             </Form.Item>
           </Col> : null}
-          {appType === 'mob' ? <Col span={12}>
-            <Form.Item label="鍙宠竟璺�">
-              {getFieldDecorator('paddingRight', {
-                initialValue: config.setting.paddingRight || '10px'
+          {['dialog', 'drawer', 'modal'].includes(display) ? <Col span={12}>
+            <Form.Item label="鐐瑰嚮钂欏眰">
+              {getFieldDecorator('clickouter', {
+                initialValue: config.setting.clickouter || 'unclose'
               })(
-                <StyleInput options={['px', '%']} />
+                <Radio.Group>
+                  <Radio value="unclose">涓嶅叧闂�</Radio>
+                  <Radio value="close">鍏抽棴</Radio>
+                </Radio.Group>
               )}
-            </Form.Item>
-          </Col> : null}
-          {appType === 'mob' ? <Col span={12}>
-            <Form.Item label="鎸夐挳鍚嶇О">
-              {getFieldDecorator('btnName', {
-                initialValue: config.setting.btnName || '纭畾'
-              })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)}
-            </Form.Item>
-          </Col> : null}
-          {appType === 'mob' ? <Col span={12}>
-            <Form.Item label="鎸夐挳浣嶇疆">
-              {getFieldDecorator('btnPosition', {
-                initialValue: config.setting.btnPosition || 'bottom'
-              })(
-                <Radio.Group style={{whiteSpace: 'nowrap'}}>
-                  <Radio value="bottom">涓嬩晶</Radio>
-                  <Radio value="top">涓婁晶</Radio>
-                </Radio.Group>)}
             </Form.Item>
           </Col> : null}
         </Row>
diff --git a/src/templates/modalconfig/settingform/index.scss b/src/templates/modalconfig/settingform/index.scss
index e69de29..01a0a3a 100644
--- a/src/templates/modalconfig/settingform/index.scss
+++ b/src/templates/modalconfig/settingform/index.scss
@@ -0,0 +1,8 @@
+.form-setting-wrap {
+  min-height: 100px;
+  .ant-col-24 {
+    .ant-form-item-label {
+      width: 16.5%;
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/templates/modalconfig/source.jsx b/src/templates/modalconfig/source.jsx
index deddd57..d3818c5 100644
--- a/src/templates/modalconfig/source.jsx
+++ b/src/templates/modalconfig/source.jsx
@@ -121,12 +121,12 @@
   },
   {
     type: 'form',
-    label: CommonDict['header.form.fileupload'],
+    label: '鏂囦欢涓婁紶',
     subType: 'fileupload',
   },
   {
     type: 'form',
-    label: CommonDict['model.form.dateday'],
+    label: '鏃ユ湡锛堝ぉ锛�',
     subType: 'date',
   },
   {
@@ -134,15 +134,15 @@
     label: CommonDict['model.form.datemonth'],
     subType: 'datemonth',
   },
-  // {
-  //   type: 'form',
-  //   label: '鏃ユ湡锛堝垎/绉掞級',
-  //   subType: 'datetime',
-  // },
   {
     type: 'form',
     label: CommonDict['model.form.textarea'],
     subType: 'textarea',
+  },
+  {
+    type: 'form',
+    label: '绾ц仈鑿滃崟',
+    subType: 'cascader',
   },
   {
     type: 'form',
@@ -178,6 +178,11 @@
     type: 'form',
     label: '鍏宠仈涓昏〃',
     subType: 'linkMain',
+  },
+  {
+    type: 'form',
+    label: '鍏紡',
+    subType: 'formula',
   }
 ]
 
diff --git a/src/templates/sharecomponent/actioncomponent/actionform/index.jsx b/src/templates/sharecomponent/actioncomponent/actionform/index.jsx
index e197357..e244c74 100644
--- a/src/templates/sharecomponent/actioncomponent/actionform/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/actionform/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
-import { Form, Row, Col, Input, Select, Radio, Tooltip, InputNumber, Cascader } from 'antd'
+import { Form, Row, Col, Input, Select, Radio, Tooltip, InputNumber, Cascader, Typography } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 
 import { formRule } from '@/utils/option.js'
@@ -12,6 +12,7 @@
 const MkEditIcon = asyncComponent(() => import('@/components/mkIcon'))
 
 const { TextArea } = Input
+const { Paragraph } = Typography
 const actionTypeOptions = {
   pop: ['label', 'position', 'OpenType', 'intertype', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'openmenu', 'output', 'tipTitle', 'hidden'],
   prompt: ['label', 'position', 'OpenType', 'intertype', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'openmenu', 'output', 'tipTitle', 'hidden'],
@@ -175,6 +176,10 @@
         shows.push('sql', 'sqlType', 'output')
       }
 
+      if (Ot === 'required') {
+        shows.push('progress')
+      }
+
       if (this.record.sqlType === 'insert') {
         reOptions.Ot = requireOptions.filter(op => op.value === 'notRequired')
       } else {
@@ -270,7 +275,12 @@
       } else if (_funcType === 'closetab') {
         shows.push('refreshTab')
       } else if (_funcType === 'megvii') {
-        shows.push('subFunc')
+        shows.push('subFunc', 'progress')
+      } else if (_funcType === 'filezip') {
+        reOptions.Ot = requireOptions
+        reRequired.innerFunc = false
+
+        shows.push('innerFunc', 'Ot', 'execSuccess', 'execError', 'urlkey')
       }
     }
 
@@ -332,7 +342,6 @@
       if (value === 'pop' || value === 'prompt' || value === 'exec') {
         _fieldval.intertype = 'system'
         _fieldval.sqlType = ''
-  
       } else if (value === 'excelIn') {
         _fieldval.intertype = 'system'
         _fieldval.Ot = 'notRequired'
@@ -342,15 +351,15 @@
         this.record.Ot = 'notRequired'
         this.record.label = this.props.dict['model.form.excelIn']
         this.record.class = 'dgreen'
-       
-  
       } else if (value === 'excelOut') {
         _fieldval.intertype = 'system'
         _fieldval.label = this.props.dict['model.form.excelOut']
         _fieldval.class = 'dgreen'
+        _fieldval.execSuccess = 'never'
         this.record.Ot = 'notRequired'
         this.record.label = this.props.dict['model.form.excelOut']
         this.record.class = 'dgreen'
+        this.record.execSuccess = 'never'
   
       } else if (value === 'popview') {
         _fieldval.display = 'modal'
@@ -415,12 +424,14 @@
         _fieldval.class = 'purple'
       } else if (value === 'audit') {
         _fieldval.label = '瀹℃牳'
-        _fieldval.Ot = 'requiredSgl'
+        _fieldval.Ot = 'required'
         _fieldval.class = 'primary'
       } else if (value === 'LogicDelete' || value === 'delete') {
         _fieldval.label = '鍒犻櫎'
-        _fieldval.Ot = 'requiredSgl'
+        _fieldval.Ot = 'required'
         _fieldval.class = 'danger'
+      } else if (value === 'custom') {
+        _fieldval.Ot = 'required'
       }
 
       if (this.record.position === 'grid') {
@@ -508,7 +519,7 @@
         ]
   
         if (item.key === 'innerFunc') {
-          let str = '^(' + item.fields.join('|') + ')'
+          let str = item.fields && item.fields.length ? '^(' + item.fields.join('|') + ')' : '^'
           let _patten = new RegExp(str + formRule.func.innerPattern + '$', 'g')
           rules.push(
             { pattern: _patten, message: formRule.func.innerMessage },
@@ -519,6 +530,24 @@
             { pattern: formRule.func.pattern, message: formRule.func.message },
             { max: formRule.func.max, message: formRule.func.maxMessage }
           )
+        } else if (item.key === 'output') {
+          if (this.record.intertype === '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 })
         }
@@ -595,6 +624,16 @@
         </Col>
       )
     })
+
+    if (window.debugger && this.props.card.uuid) {
+      fields.push(
+        <Col span={12} key="uuid">
+          <Form.Item label="鎸夐挳ID">
+            <Paragraph copyable>{this.props.card.uuid}</Paragraph>
+          </Form.Item>
+        </Col>
+      )
+    }
     return fields
   }
 
diff --git a/src/templates/sharecomponent/actioncomponent/dragaction/card.jsx b/src/templates/sharecomponent/actioncomponent/dragaction/card.jsx
index f4b209a..e350a80 100644
--- a/src/templates/sharecomponent/actioncomponent/dragaction/card.jsx
+++ b/src/templates/sharecomponent/actioncomponent/dragaction/card.jsx
@@ -26,7 +26,7 @@
       }
     }
   })
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   let hasProfile = false
   let forbidSql = false
diff --git a/src/templates/sharecomponent/actioncomponent/dragaction/index.jsx b/src/templates/sharecomponent/actioncomponent/dragaction/index.jsx
index e98d0a5..5369beb 100644
--- a/src/templates/sharecomponent/actioncomponent/dragaction/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/dragaction/index.jsx
@@ -131,6 +131,7 @@
         newcard.sysInterface = setting.sysInterface
         newcard.outerFunc = setting.outerFunc
         newcard.interface = setting.interface
+        newcard.execSuccess = 'never'
         newcard.class = 'dgreen'
       }
       
diff --git a/src/templates/sharecomponent/actioncomponent/index.jsx b/src/templates/sharecomponent/actioncomponent/index.jsx
index 6374f8a..9e10a8f 100644
--- a/src/templates/sharecomponent/actioncomponent/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/index.jsx
@@ -679,6 +679,8 @@
       profVisible: true,
       card: element
     })
+
+    MKEmitter.emit('modalStatus', '楠岃瘉淇℃伅')
   }
 
   /**
@@ -706,6 +708,8 @@
       }, () => {
         this.props.updateaction({...config, action: _actionlist})
       })
+
+      MKEmitter.emit('modalStatus', false)
     })
   }
 
@@ -962,9 +966,11 @@
             if (this.verifyRef.handleCancel) {
               this.verifyRef.handleCancel().then(() => {
                 this.setState({ profVisible: false })
+                MKEmitter.emit('modalStatus', false)
               })
             } else {
               this.setState({ profVisible: false })
+              MKEmitter.emit('modalStatus', false)
             }
           }}
           destroyOnClose
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
index 90f73ad..586de39 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/customscript/index.jsx
@@ -16,7 +16,7 @@
     scripts: PropTypes.array,       // 鑷畾涔夎剼鏈垪琛�
     usefulfields: PropTypes.any,    // 鍙敤瀛楁
     systemScripts: PropTypes.array, // 绯荤粺鑴氭湰
-    scriptsChange: PropTypes.func   // 琛ㄥ崟
+    scriptsChange: PropTypes.func
   }
 
   state = {
@@ -50,7 +50,7 @@
     }
 
     let _sql = `Declare @${btn.sheet} table (${_dec}jskey nvarchar(50) )
-      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50),@ErrorCode nvarchar(50), @retmsg nvarchar(4000),@tbid Nvarchar(512)
+      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@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=''
     `
     
@@ -173,7 +173,8 @@
           LText: this.state.verifySql + _initCustomScript + _prevCustomScript + _backCustomScript + tail
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
 
         // 澶栬仈鏁版嵁搴撴浛鎹�
         if (window.GLOB.externalDatabase !== null) {
@@ -181,7 +182,6 @@
         }
 
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
         
         this.setState({loading: true})
@@ -286,11 +286,13 @@
               ErrorCode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT锛�, retmsg
             </Form.Item>
           </Col>
-          {usefulfields ? <Col span={24} className="sqlfield">
+          <Col span={24} className="sqlfield">
             <Form.Item label={'鍙敤瀛楁'}>
-            BID, ID, LoginUID, SessionUid, UserID, Appkey, UserName, FullName, RoleID, mk_departmentcode, mk_organization, login_city, {usefulfields}
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><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}
+          </Col>
           <Col span={8} style={{whiteSpace: 'nowrap'}}>
             <Form.Item style={{marginBottom: 0}} label={
               <Tooltip placement="bottomLeft" title={'鑷畾涔夎剼鏈笌榛樿sql浣嶇疆鍏崇郴銆�'}>
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
index 9e5fcf7..50df4a3 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -155,7 +155,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div style={{color: '#ff4d4f'}}>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopOutlined style={{marginLeft: '5px'}} />
             </div>
           ) :
@@ -206,7 +206,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div style={{color: '#ff4d4f'}}>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopOutlined style={{marginLeft: '5px'}} />
             </div>
           ) :
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
index 7554b81..eb41078 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/customscript/index.jsx
@@ -39,7 +39,7 @@
     columns = columns.filter(item => item.Column !== '$Index')
     let fields = columns.map(item => item.Column)
 
-    let _sql = `Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50),@ErrorCode nvarchar(50), @retmsg nvarchar(4000)
+    let _sql = `Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@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)
     `
     
     this.setState({
@@ -161,7 +161,8 @@
           LText: this.state.verifySql + _initCustomScript + _prevCustomScript + _backCustomScript + tail
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
 
         // 澶栬仈鏁版嵁搴撴浛鎹�
         if (window.GLOB.externalDatabase !== null) {
@@ -169,7 +170,6 @@
         }
 
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
         
         this.setState({loading: true})
@@ -267,11 +267,13 @@
               ErrorCode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT锛�, retmsg
             </Form.Item>
           </Col>
-          {usefulfields ? <Col span={24} className="sqlfield">
+          <Col span={24} className="sqlfield">
             <Form.Item label={'鍙敤瀛楁'}>
-            BID, ID, LoginUID, SessionUid, UserID, Appkey, UserName, FullName, RoleID, mk_departmentcode, mk_organization, login_city, {usefulfields}
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><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}
+          </Col>
           <Col span={8} style={{whiteSpace: 'nowrap'}}>
             <Form.Item style={{marginBottom: 0}} label={
               <Tooltip placement="bottomLeft" title={'鑷畾涔夎剼鏈笌榛樿sql浣嶇疆鍏崇郴銆�'}>
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
index e32df92..fa8b86d 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -155,7 +155,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div style={{color: '#ff4d4f'}}>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopOutlined style={{marginLeft: '5px'}} />
             </div>
           ) :
@@ -648,10 +648,10 @@
           LText: values.sql
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
 
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
         
         this.setState({
@@ -877,15 +877,16 @@
   sqlverify = (_resolve, _reject, scripts) => {
     const { searches, verify } = this.state
 
-    let sql = SettingUtils.getDebugSql(verify, scripts, searches, Utils)
+    let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    let sql = SettingUtils.getDebugSql(verify, scripts, searches, Utils, timestamp)
     let param = {
       func: 's_debug_sql',
       exec_type: 'y',
       LText: sql
     }
     param.LText = Utils.formatOptions(param.LText)
-    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-    param.secretkey = Utils.encrypt('', param.timestamp)
+    param.timestamp = timestamp
+    param.secretkey = Utils.encrypt('', timestamp)
 
     Api.getLocalConfig(param).then(result => {
       if (result.status) {
diff --git a/src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx b/src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx
index 4b4fbe2..c8fa24e 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyexcelout/utils.jsx
@@ -5,7 +5,7 @@
   /**
    * @description 鐢熸垚椤甸潰鏌ヨ璇彞
    */
-  static getDebugSql (verify, scripts, searches, Utils) {
+  static getDebugSql (verify, scripts, searches, Utils, timestamp) {
     let sql = ''
     let _dataresource = verify.dataresource || ''
     let regoptions = this.getRegOptions(searches)
@@ -32,7 +32,7 @@
     })
 
     if (_customScript) {
-      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
         ${_customScript}
       `
     }
@@ -49,6 +49,8 @@
       })
     }
     
+    _dataresource = _dataresource.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${timestamp}'`)
+    _customScript = _customScript.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${timestamp}'`)
     _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
     _customScript = _customScript.replace(/@\$|\$@/ig, '')
 
@@ -68,9 +70,6 @@
     })
 
     _regoptions.push({
-      reg: new RegExp('@login_city@', 'ig'),
-      value: `''`
-    }, {
       reg: new RegExp('@userName@', 'ig'),
       value: `''`
     }, {
@@ -128,7 +127,7 @@
       `
     } else {
       sql = `/* sql 楠岃瘉 */
-        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
         ${_dataresource}`
     }
     sql = sql.replace(/\n\s{8}/ig, '\n')
diff --git a/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx b/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
index 5f7e68e..e39bcca 100644
--- a/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/verifyprint/index.jsx
@@ -348,8 +348,8 @@
                 <Col span={24} className="print-tip">
                   <Form.Item label={'鎻愮ず'}>
                     濡傛灉姝ゆ寜閽秹鍙婂绉嶆暟鎹被鍨嬬殑鎵撳嵃锛岄渶瑕佽缃笉鍚岀殑鎵撳嵃鏈烘椂锛岃娣诲姞鎵撳嵃绫诲瀷鎺у埗淇℃伅锛岀敤鎴峰湪鑷畾涔夎缃腑锛屽彲鏍规嵁鎵撳嵃绫诲瀷璁剧疆瀵瑰簲鐨勬墦鍗版満銆�
-                    鎵撳嵃鏃讹紝鏁版嵁鐨勬墦鍗扮被鍨嬪彇鍐充簬杩斿洖鍊硷紙鍐呴儴鎴栧閮ㄦ帴鍙o級涓殑 printType 瀛楁銆�
-                    娉細杩斿洖鍊间腑鐨� printCount銆乼emplateID 瀛楁锛屽彲鍒嗗埆鎺у埗鎵撳嵃鏁伴噺鍜屾墦鍗版ā鏉裤��
+                    鎵撳嵃鏃讹紝鎵撳嵃绫诲瀷鍙栧喅浜庢暟鎹腑鐨� printType 瀛楁銆�
+                    娉細鏁版嵁涓殑 printCount銆乼emplateID 瀛楁锛屽彲鍒嗗埆鎺у埗鎵撳嵃鏁伴噺鍜屾墦鍗版ā鏉裤��
                   </Form.Item>
                 </Col>
                 <Col span={24}>
diff --git a/src/templates/sharecomponent/cardcomponent/dragdetail/card.jsx b/src/templates/sharecomponent/cardcomponent/dragdetail/card.jsx
index 0cd8dbc..8d00ad1 100644
--- a/src/templates/sharecomponent/cardcomponent/dragdetail/card.jsx
+++ b/src/templates/sharecomponent/cardcomponent/dragdetail/card.jsx
@@ -14,7 +14,7 @@
     }),
   })
 
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   const [, drop] = useDrop({
     accept: 'detail',
diff --git a/src/templates/sharecomponent/cardcomponent/index.scss b/src/templates/sharecomponent/cardcomponent/index.scss
index 4971023..497936c 100644
--- a/src/templates/sharecomponent/cardcomponent/index.scss
+++ b/src/templates/sharecomponent/cardcomponent/index.scss
@@ -184,6 +184,7 @@
           width: unset;
           margin-right: 3px;
           color: rgba(0, 0, 0, 0.45);
+          vertical-align: middle;
         }
       }
       li:hover {
diff --git a/src/templates/sharecomponent/chartgroupcomponent/dragchartview/card.jsx b/src/templates/sharecomponent/chartgroupcomponent/dragchartview/card.jsx
index 533197b..d541fec 100644
--- a/src/templates/sharecomponent/chartgroupcomponent/dragchartview/card.jsx
+++ b/src/templates/sharecomponent/chartgroupcomponent/dragchartview/card.jsx
@@ -16,7 +16,7 @@
     }),
   })
 
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   const edit = () => {
     editCard(id)
diff --git a/src/templates/sharecomponent/columncomponent/dragcolumn/card.jsx b/src/templates/sharecomponent/columncomponent/dragcolumn/card.jsx
index 41c0125..b62ffe1 100644
--- a/src/templates/sharecomponent/columncomponent/dragcolumn/card.jsx
+++ b/src/templates/sharecomponent/columncomponent/dragcolumn/card.jsx
@@ -27,7 +27,7 @@
     }
   })
   
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   return (
     <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
diff --git a/src/templates/sharecomponent/searchcomponent/dategroup/index.scss b/src/templates/sharecomponent/searchcomponent/dategroup/index.scss
index 6782732..3e0369e 100644
--- a/src/templates/sharecomponent/searchcomponent/dategroup/index.scss
+++ b/src/templates/sharecomponent/searchcomponent/dategroup/index.scss
@@ -9,6 +9,7 @@
     border-radius: 2px;
     margin-right: 2px;
     padding: 2px 6px;
+    background: #ffffff;
   }
   .ant-tag-checkable-checked {
     border-color: #1890ff;
diff --git a/src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx b/src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx
index 6183e23..f65bb50 100644
--- a/src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx
+++ b/src/templates/sharecomponent/searchcomponent/dragsearch/card.jsx
@@ -12,7 +12,7 @@
 const { MonthPicker, WeekPicker, RangePicker } = DatePicker
 const CheckCard = asyncComponent(() => import('@/templates/modalconfig/checkCard'))
 
-const Card = ({ id, card, showField, moveCard, copyCard, findCard, editCard, delCard }) => {
+const Card = ({ id, card, moveCard, copyCard, findCard, editCard, delCard }) => {
   const originalIndex = findCard(id).index
   const [{ isDragging }, drag] = useDrag({
     item: { type: 'search', id, originalIndex },
@@ -34,7 +34,7 @@
       }
     }
   })
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   let _defaultValue = '' // 涓嬫媺鎼滅储銆佹椂闂磋寖鍥寸被鍨嬶紝鍒濆鍊奸渶瑕侀澶勭悊
 
@@ -126,16 +126,14 @@
         <CloseOutlined className="close" onClick={() => delCard(id)} />
       </div>
     } trigger="hover">
-      <div className={'page-card ' + (card.labelShow || '') + ' ' + type} style={{ opacity: opacity}}>
+      <div className={'page-card ' + (card.labelShow === 'false' ? 'label-hide ' : '') + type + (card.advanced === 'true' ? ' advanced' : '')} style={{ opacity: opacity}}>
         <div ref={node => drag(drop(node))} onDoubleClick={() => editCard(id)}>
           <Form.Item
             labelCol={{style: {width: labelwidth + '%'}}}
             wrapperCol={{style: {width: (100 - labelwidth) + '%'}}}
-            // labelCol={{xs: { span: 24 }, sm: { span: 8 }}}
-            // wrapperCol = {{xs: { span: 24 }, sm: { span: 16 }}}
             label={card.labelShow !== 'false' ? card.label : ''}
             required={card.required === 'true'}
-            help={showField ? card.field + (card.datefield ? ', ' + card.datefield : '') : ''}
+            help={(card.field || '') + (card.datefield ? ', ' + card.datefield : '') + (card.advanced === 'true' ? '锛堥珮绾ф悳绱級' : '')}
           >
             {formItem}
           </Form.Item>
diff --git a/src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx b/src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx
index c0907c6..f144c82 100644
--- a/src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/dragsearch/index.jsx
@@ -2,12 +2,14 @@
 import { useDrop } from 'react-dnd'
 import { is, fromJS } from 'immutable'
 import update from 'immutability-helper'
-import { Col, Button } from 'antd'
+import { Col, Button, Popover } from 'antd'
+import { EditOutlined } from '@ant-design/icons'
+
 import Utils from '@/utils/utils.js'
 import Card from './card'
 import './index.scss'
 
-const Container = ({list, show, showField, handleList, handleMenu, deleteMenu }) => {
+const Container = ({list, setting, handleList, handleMenu, deleteMenu, handleSetting }) => {
   const [cards, setCards] = useState(list)
   const moveCard = (id, atIndex) => {
     const { card, index } = findCard(id)
@@ -128,36 +130,45 @@
     }
   })
 
-  let radio = 6
-  if (cards.length > 0) {
-    radio = cards[cards.length - 1].ratio || 6
-  }
+  let radio = setting.searchRatio || 6
+  let labelwidth = setting.searchLwidth !== undefined ? setting.searchLwidth : 33.3
+  let advanceType = setting.advanceType || 'modal'
 
   return (
     <div ref={drop} className="ant-row">
-      {cards.map(card => (
-        <Col key={card.uuid} span={card.ratio || 6}>
-          <Card
-            id={`${card.uuid}`}
-            card={card}
-            showField={showField}
-            moveCard={moveCard}
-            copyCard={copyCard}
-            editCard={editCard}
-            delCard={delCard}
-            findCard={findCard}
-          />
-        </Col>
-      ))}
-      {cards.length > 0 && show !== 'false' ? <Col key="action" className="action" span={radio < 6 ? 6 : radio}>
+      {cards.map(card => {
+        let _ratio = card.ratio || 6
+        if (card.advanced === 'true' && advanceType !== 'pulldown') {
+          _ratio = 6
+        }
+        return (
+          <Col className="mk-search-item-wrap" key={card.uuid} span={_ratio}>
+            <Card
+              id={`${card.uuid}`}
+              card={card}
+              moveCard={moveCard}
+              copyCard={copyCard}
+              editCard={editCard}
+              delCard={delCard}
+              findCard={findCard}
+            />
+          </Col>
+        )
+      })}
+      {cards.length > 0 ? <Col className={'mk-search-item-wrap action ' + (setting.show === 'false' ? 'hide-button' : '')} key="action" span={radio}>
         <div className="ant-row ant-form-item" style={{whiteSpace: 'nowrap', lineHeight: '40px', height: '55px', marginBottom: 0}}>
-          <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8">
-          </div>
-          <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16">
-            <Button type="primary">鎼滅储</Button>
-            <Button style={{ marginLeft: 8 }}>閲嶇疆</Button>
-            <div style={{position: 'absolute', top: 0, bottom: 0, left: 0, right: 0}}></div>
-          </div>
+          <div className="ant-col ant-form-item-label" style={{width: labelwidth + '%'}}></div>
+          <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+            <div className="mk-popover-control">
+              <EditOutlined className="edit" onClick={() => handleSetting()} />
+            </div>
+          } trigger="hover">
+            <div className="ant-col ant-form-item-control-wrapper">
+              <Button type="primary">鎼滅储</Button>
+              <Button style={{ marginLeft: 8 }}>閲嶇疆</Button>
+              <div style={{position: 'absolute', top: 0, bottom: 0, left: 0, right: 0}}></div>
+            </div>
+          </Popover>
         </div>
       </Col> : null}
       {cards.length === 0 ?
diff --git a/src/templates/sharecomponent/searchcomponent/index.jsx b/src/templates/sharecomponent/searchcomponent/index.jsx
index 4f45d34..9be4910 100644
--- a/src/templates/sharecomponent/searchcomponent/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/index.jsx
@@ -12,8 +12,9 @@
 import { getSearchForm } from '@/templates/zshare/formconfig'
 import asyncComponent from '@/utils/asyncComponent'
 import MKEmitter from '@/utils/events.js'
-import SearchForm from './searchform'
 import DragElement from './dragsearch'
+import SearchForm from './searchform'
+import SettingForm from './settingform'
 import './index.scss'
 
 const { confirm } = Modal
@@ -28,11 +29,12 @@
 
   state = {
     dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
-    searchlist: null,    // 鎼滅储鏉′欢闆�
-    sqlVerifing: false,  // sql楠岃瘉涓�
-    visible: false,      // 妯℃�佹鎺у埗
+    searchlist: null,
+    sqlVerifing: false,
+    visible: false,
     showField: false,
-    card: null           // 缂栬緫涓厓绱�
+    setVisible: false,
+    card: null
   }
 
   /**
@@ -127,10 +129,17 @@
       })
     })
 
+    let columns = null
+    if (this.props.config.type === 'table') {
+      columns = this.props.config.columns.map(item => {
+        return {key: item.uuid, text: item.field, value: item.field, label: item.label}
+      })
+    }
+
     this.setState({
       visible: true,
       card: card,
-      formlist: getSearchForm(card, linkableFields)
+      formlist: getSearchForm(card, linkableFields, columns)
     })
   }
 
@@ -238,10 +247,10 @@
           LText: res.dataSource
         }
 
-        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@\$|\$@/ig, '').replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
         
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
 
         if (window.GLOB.mainSystemApi && res.database === 'sso') {
@@ -309,6 +318,31 @@
     })
   }
 
+  handleSetting = () => {
+    this.setState({
+      setVisible: true
+    })
+  }
+
+  settingSubmit = () => {
+    const { config } = this.props
+
+    this.settingFormRef.handleConfirm().then(res => {
+      this.setState({
+        setVisible: false
+      })
+
+      let _config = null
+
+      if (config.wrap) { // 鑷畾涔夐〉闈able
+        _config = {...config, wrap: {...config.wrap, ...res}}
+      } else {
+        _config = {...config, setting: {...config.setting, ...res}}
+      }
+
+      this.props.updatesearch(_config)
+    })
+  }
 
   /**
    * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
@@ -325,35 +359,30 @@
     if (!is(fromJS(this.state), fromJS(nextState))) {
       return true
     } else if (this.props.config.wrap) {
-      return this.props.config.wrap.show !== nextProps.config.wrap.show
+      return !is(fromJS(nextProps.config.wrap), fromJS(this.props.config.wrap))
     } else {
-      return this.props.config.setting.show !== nextProps.config.setting.show
+      return !is(fromJS(nextProps.config.setting), fromJS(this.props.config.setting))
     }
   }
 
   render() {
     const { config } = this.props
-    const { dict, searchlist, visible, sqlVerifing, card, showField } = this.state
-
-    let show = config.setting.show
-    if (config.wrap) {
-      show = config.wrap.show
-    }
+    const { dict, searchlist, visible, sqlVerifing, card, showField, setVisible } = this.state
 
     return (
-      <div className={'model-table-search-list length' + searchlist.length}>
+      <div className={'model-table-search-list length' + searchlist.length + (showField ? ' show-field' : '')}>
         <Tooltip placement="bottomLeft" overlayClassName="middle" title="鍦ㄥ乏渚у伐鍏锋爮銆婃悳绱€�嬩腑锛岄�夋嫨瀵瑰簲鎼滅储妗嗘嫋鑷虫澶勬坊鍔狅紱鎴栫偣鍑绘寜閽�婃坊鍔犳悳绱㈡潯浠躲�嬫壒閲忔坊鍔狅紝閫夋嫨鎵归噺娣诲姞鏃讹紝闇�鎻愬墠閫夋嫨浣跨敤琛ㄣ��">
           <QuestionCircleOutlined style={{color: '#c49f47', position: 'relative', left: '-15px', top: '5px'}} />
         </Tooltip>
         <FieldsComponent config={{uuid: config.uuid, search: searchlist}} type="search" />
-        <Switch checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={showField} onChange={this.onFieldChange} />
+        <Switch className="switch-field-show" checkedChildren={dict['model.switch.open']} unCheckedChildren={dict['model.switch.close']} defaultChecked={showField} onChange={this.onFieldChange} />
         <DragElement
           list={searchlist}
-          show={show}
-          showField={showField}
+          setting={config.wrap || config.setting}
           handleList={this.handleList}
           handleMenu={this.handleSearch}
           deleteMenu={this.deleteElement}
+          handleSetting={this.handleSetting}
         />
         {/* 缂栬緫鎼滅储鏉′欢 */}
         <Modal
@@ -374,6 +403,21 @@
             wrappedComponentRef={(inst) => this.searchFormRef = inst}
           />
         </Modal>
+        <Modal
+          title={'鎼滅储璁剧疆'}
+          visible={setVisible}
+          width={800}
+          maskClosable={false}
+          onOk={this.settingSubmit}
+          onCancel={() => this.setState({setVisible: false})}
+          destroyOnClose
+        >
+          <SettingForm
+            setting={config.wrap || config.setting}
+            inputSubmit={this.settingSubmit}
+            wrappedComponentRef={(inst) => this.settingFormRef = inst}
+          />
+        </Modal>
       </div>
     )
   }
diff --git a/src/templates/sharecomponent/searchcomponent/index.scss b/src/templates/sharecomponent/searchcomponent/index.scss
index 74c00ca..29bbb21 100644
--- a/src/templates/sharecomponent/searchcomponent/index.scss
+++ b/src/templates/sharecomponent/searchcomponent/index.scss
@@ -7,7 +7,7 @@
   .quickly-add {
     display: none;
   }
-  >.ant-switch {
+  .switch-field-show {
     position: absolute;
     z-index: 1;
     right: 20px;
@@ -19,10 +19,23 @@
       padding: 0 12px!important;
     }
   }
-  
-  .ant-row.ant-form-item .ant-col {
-    padding: 0;
+
+  .mk-search-item-wrap {
+    display: inline-block;
+    float: none;
+    vertical-align: top;
   }
+  .mk-search-item-wrap.action {
+    .ant-form-item-label, .ant-form-item-control-wrapper {
+      display: inline-block;
+    }
+  }
+  .mk-search-item-wrap.action.hide-button {
+    span {
+      text-decoration: line-through #ff4d4f;
+    }
+  }
+
   .page-card {
     position: relative;
     background: #ffffff;
@@ -50,6 +63,21 @@
           padding: 4px 20px 4px 5px;
           font-size: 13px;
         }
+        .check-card-edit-box {
+          .no-margin-bottom {
+            margin-bottom: 0px;
+          }
+          .card-cell {
+            padding: 4px 6px;
+          }
+          .card-color-cell {
+            padding: 4px 6px;
+            min-height: 32px;
+          }
+        }
+      }
+      .ant-form-explain {
+        display: none;
       }
     }
     >div::after {
@@ -65,7 +93,7 @@
       z-index: 2;
     }
   }
-  .page-card.false {
+  .page-card.label-hide {
     .ant-form-item-label {
       display: none;
     }
@@ -80,6 +108,11 @@
       }
     }
   }
+  .page-card.advanced {
+    .ant-form-item-label label {
+      color: orange;
+    }
+  }
   .ant-calendar-picker {
     min-width: 100px!important;
     width: 100%;
@@ -87,4 +120,11 @@
   .check-card-edit-box {
     margin-top: 5px!important;
   }
+}
+.model-table-search-list.show-field {
+  .page-card {
+    .ant-form-explain {
+      display: block;
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
index 2b3e7fd..06d7186 100644
--- a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
-import { Form, Row, Col, Input, Select, Radio, notification, Tooltip, InputNumber, Checkbox, Cascader } from 'antd'
+import { Form, Row, Col, Input, Select, Radio, notification, Tooltip, InputNumber, Checkbox, Cascader, AutoComplete } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 
 import { dateOptions, matchReg, formRule } from '@/utils/option.js'
@@ -119,7 +119,6 @@
     openType: null,          // 鎼滅储鏉′欢鏄剧ず绫诲瀷
     resourceType: null,      // 涓嬫媺鎼滅储鏃讹紝閫夐」鏉ユ簮绫诲瀷
     formlist: null,          // 琛ㄥ崟
-    display: null,
     cFields: [],
     textTooltip: '瀛楁鍚嶅彲浠ヤ娇鐢ㄩ�楀彿鍒嗛殧锛岃繘琛岀患鍚堟悳绱�',
   }
@@ -189,17 +188,28 @@
         shows.push('dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database')
       }
     } else if (type === 'checkcard') {
+      reRequired.fields = false
       if (this.record.display === 'picture') {
         if (this.record.resourceType === '0') {        // 鑷畾涔夎祫婧�
-          shows.push('options', 'picratio')
+          shows.push('options', 'fields', 'picratio')
         } else if (this.record.resourceType === '1') { // 鏁版嵁婧�
-          shows.push('dataSource', 'cardValField', 'urlField', 'orderBy', 'orderType', 'database', 'picratio')
+          shows.push('dataSource', 'cardValField', 'fields', 'urlField', 'orderBy', 'orderType', 'database', 'picratio')
+        }
+      } else if (this.record.display === 'color') {
+        if (this.record.resourceType === '0') {        // 鑷畾涔夎祫婧�
+          shows.push('options', 'fields')
+        } else if (this.record.resourceType === '1') { // 鏁版嵁婧�
+          shows.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'database')
         }
       } else {
+        reRequired.fields = true
         if (this.record.resourceType === '0') {        // 鑷畾涔夎祫婧�
-          shows.push('options', 'fields', 'backgroundColor', 'borderColor')
+          shows.push('options', 'fields', 'selectStyle')
         } else if (this.record.resourceType === '1') { // 鏁版嵁婧�
-          shows.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'database', 'backgroundColor', 'borderColor')
+          shows.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'database', 'selectStyle')
+        }
+        if (this.record.selectStyle === 'custom') {
+          shows.push('backgroundColor')
         }
       }
       shows.push('linkField')
@@ -419,6 +429,12 @@
     this.props.form.setFieldsValue({dataSource: resource})
   }
 
+  complete = (key, option) => {
+    let label = option.props.label
+
+    this.props.form.setFieldsValue({label: label})
+  }
+
   getFields() {
     const { getFieldDecorator } = this.props.form
     const { dict } = this.props
@@ -455,7 +471,20 @@
           })
         }
 
-        content = <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />
+        if (item.key === 'field' && item.options && item.options.length > 0) {
+          content = <AutoComplete
+            dataSource={item.options.map((cell) => <AutoComplete.Option label={cell.label} value={cell.value} key={cell.key}>
+              {cell.text}
+            </AutoComplete.Option>)}
+            filterOption={(input, option) => option.props.children.indexOf(input) > -1}
+            onSelect={this.complete}
+            placeholder=""
+          >
+            <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />
+          </AutoComplete>
+        } else {
+          content = <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />
+        }
       } else if (item.type === 'number') {
         rules = [
           { required: item.required, message: dict['form.required.input'] + item.label + '!' }
@@ -490,7 +519,7 @@
           { required: item.required, message: dict['form.required.select'] + item.label + '!' }
         ]
 
-        content = <Radio.Group onChange={(e) => {this.optionChange(item.key, e.target.value)}}>
+        content = <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.optionChange(item.key, e.target.value)}}>
           {item.options.map(option => {
             return (
               <Radio key={option.value} value={option.value}>{option.text}</Radio>
@@ -527,6 +556,10 @@
         span = 24
         className = 'text-area'
 
+        rules = [
+          { required: item.required, message: '璇锋坊鍔�' + item.label + '!' }
+        ]
+
         content = <FieldsTable dict={dict} onChange={this.changeField}/>
       } else if (item.type === 'checkbox') {
         rules = [
@@ -548,6 +581,10 @@
         content = <Cascader options={item.options} placeholder="" />
       } else if (item.type === 'color') {
         className = 'color-form-item'
+        rules = [
+          { required: item.required, message: dict['form.required.select'] + item.label + '!' }
+        ]
+        
         content = <ColorSketch allowClear={true}/>
       }
 
diff --git a/src/templates/sharecomponent/searchcomponent/searchform/index.scss b/src/templates/sharecomponent/searchcomponent/searchform/index.scss
index b1ed736..1f9373d 100644
--- a/src/templates/sharecomponent/searchcomponent/searchform/index.scss
+++ b/src/templates/sharecomponent/searchcomponent/searchform/index.scss
@@ -25,6 +25,7 @@
     }
   }
   .color-form-item {
+    margin-bottom: 24px;
     .ant-form-item-control {
       height: 40px;
       .color-sketch-block {
diff --git a/src/templates/sharecomponent/searchcomponent/settingform/index.jsx b/src/templates/sharecomponent/searchcomponent/settingform/index.jsx
new file mode 100644
index 0000000..e4e8adf
--- /dev/null
+++ b/src/templates/sharecomponent/searchcomponent/settingform/index.jsx
@@ -0,0 +1,151 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Form, Row, Col, Radio, Tooltip, InputNumber } from 'antd'
+import { QuestionCircleOutlined } from '@ant-design/icons'
+
+// import './index.scss'
+
+class SettingForm extends Component {
+  static propTpyes = {
+    setting: PropTypes.object,
+    inputSubmit: PropTypes.func
+  }
+
+  state = {
+    advanceType: ''
+  }
+
+  UNSAFE_componentWillMount () {
+    const { setting } = this.props
+
+    this.setState({
+      advanceType: setting.advanceType || 'modal'
+    })
+  }
+
+  handleConfirm = () => {
+    // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
+    return new Promise((resolve, reject) => {
+      this.props.form.validateFieldsAndScroll((err, values) => {
+        if (!err) {
+          resolve(values)
+        } else {
+          reject(err)
+        }
+      })
+    })
+  }
+
+  render() {
+    const { setting } = this.props
+    const { getFieldDecorator } = this.props.form
+    const { advanceType } = this.state
+
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
+    return (
+      <div className="model-table-datasource-setting-form-box">
+        <Form {...formItemLayout} className="model-setting-form">
+          <Row gutter={24}>
+            <Col span={12}>
+              <Form.Item label="鎼滅储鎸夐挳">
+                {getFieldDecorator('show', {
+                  initialValue: setting.show || 'true'
+                })(
+                  <Radio.Group>
+                    <Radio value="true">鏄剧ず</Radio>
+                    <Radio value="false">闅愯棌</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col>
+            <Col span={12}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="楂樼骇鎼滅储鐨勫睍寮�鏂瑰紡銆�">
+                  <QuestionCircleOutlined className="mk-form-tip" />
+                  楂樼骇鎼滅储
+                </Tooltip>
+              }>
+                {getFieldDecorator('advanceType', {
+                  initialValue: setting.advanceType || 'modal'
+                })(
+                  <Radio.Group onChange={(e) => this.setState({advanceType: e.target.value})}>
+                    <Radio value="modal">寮圭獥</Radio>
+                    <Radio value="drawer">鎶藉眽</Radio>
+                    <Radio value="pulldown">涓嬫媺</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col>
+            {advanceType === 'drawer' ? <Col span={12}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="鎶藉眽灞曞紑鐨勬柟鍚戙��">
+                  <QuestionCircleOutlined className="mk-form-tip" />
+                  鎶藉眽鏂瑰悜
+                </Tooltip>
+              }>
+                {getFieldDecorator('drawerPlacement', {
+                  initialValue: setting.drawerPlacement || 'right'
+                })(
+                  <Radio.Group style={{whiteSpace: 'nowrap'}}>
+                    <Radio value="right">鍙充晶</Radio>
+                    <Radio value="left">宸︿晶</Radio>
+                    <Radio value="top">涓婁晶</Radio>
+                    <Radio value="bottom">涓嬩晶</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col> : null}
+            {advanceType !== 'pulldown' ? <Col span={12}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="楂樼骇鎼滅储妗嗙殑瀹藉害锛屾敞锛氬綋瀹藉害鍊煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺�傚綋浣跨敤涓婁笅鏄剧ず鐨勬娊灞夋椂浠h〃鎶藉眽楂樺害銆�">
+                  <QuestionCircleOutlined className="mk-form-tip" />
+                  寮圭獥瀹藉害
+                </Tooltip>
+              }>
+                {getFieldDecorator('advanceWidth', {
+                  initialValue: setting.advanceWidth || 1000
+                })(<InputNumber min={10} max={3000} precision={0} onPressEnter={this.props.inputSubmit}/>)}
+              </Form.Item>
+            </Col> : null}
+            <Col span={12}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="鎼滅储鍙婇噸缃寜閽墍鍗犳瘮渚嬨�傛爡鏍煎竷灞�锛屾瘡琛岀瓑鍒嗕负24鍒椼��">
+                  <QuestionCircleOutlined className="mk-form-tip" />
+                  姣斾緥
+                </Tooltip>
+              }>
+                {getFieldDecorator('searchRatio', {
+                  initialValue: setting.searchRatio || 6,
+                })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.props.inputSubmit}/>)}
+              </Form.Item>
+            </Col>
+            <Col span={12}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="鎼滅储鎸夐挳璺濆乏渚х殑鐧惧垎姣旓紝鍙傜収鎼滅储鏉′欢鐨勫悕绉板搴︺��">
+                  <QuestionCircleOutlined className="mk-form-tip" />
+                  鎸夐挳鍋忕Щ
+                </Tooltip>
+              }>
+                {getFieldDecorator('searchLwidth', {
+                  initialValue: setting.searchLwidth !== undefined ? setting.searchLwidth : 33.3,
+                })(<InputNumber min={0} max={100} precision={1} onPressEnter={this.props.inputSubmit}/>)}
+              </Form.Item>
+            </Col>
+          </Row>
+        </Form>
+      </div>
+    )
+  }
+}
+
+export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/templates/menuconfig/editthdmenu/menuform/index.scss b/src/templates/sharecomponent/searchcomponent/settingform/index.scss
similarity index 100%
rename from src/templates/menuconfig/editthdmenu/menuform/index.scss
rename to src/templates/sharecomponent/searchcomponent/settingform/index.scss
diff --git a/src/templates/sharecomponent/settingcalcomponent/index.jsx b/src/templates/sharecomponent/settingcalcomponent/index.jsx
index 0054f25..0c7b0d2 100644
--- a/src/templates/sharecomponent/settingcalcomponent/index.jsx
+++ b/src/templates/sharecomponent/settingcalcomponent/index.jsx
@@ -7,6 +7,7 @@
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
 import VerifyCard from './verifycard'
+import MKEmitter from '@/utils/events.js'
 import './index.scss'
 
 class DataSource extends Component {
@@ -38,6 +39,7 @@
     this.setState({
       visible: true
     })
+    MKEmitter.emit('modalStatus', '鏁版嵁婧�')
   }
 
   verifySubmit = () => {
@@ -57,8 +59,17 @@
         })
       }
 
+      res.show = config.setting.show || 'true'
+      res.advanceType = config.setting.advanceType || 'modal'
+      res.advanceWidth = config.setting.advanceWidth || 1000
+      res.drawerPlacement = config.setting.drawerPlacement || 'right'
+      res.searchRatio = config.setting.searchRatio || 6
+      res.searchLwidth = config.setting.searchLwidth !== undefined ? config.setting.searchLwidth : 33.3
+
       this.setState({loading: false, visible: false})
       this.props.updateConfig({...config, ...res})
+
+      MKEmitter.emit('modalStatus', false)
     }, () => {
       this.setState({loading: false})
     })
@@ -73,14 +84,14 @@
         <SettingOutlined onClick={() => this.editDataSource()} />
         <Modal
           wrapClassName="popview-modal"
-          title={'鏁版嵁婧愰厤缃�'}
+          title="鏁版嵁婧愰厤缃�"
           visible={visible}
           width={'75vw'}
           maskClosable={false}
           okText={dict['model.submit']}
           onOk={this.verifySubmit}
           confirmLoading={loading}
-          onCancel={() => { this.setState({ visible: false }) }}
+          onCancel={() => { MKEmitter.emit('modalStatus', false); this.setState({ visible: false }) }}
           destroyOnClose
         >
           <VerifyCard
diff --git a/src/templates/sharecomponent/settingcalcomponent/verifycard/index.jsx b/src/templates/sharecomponent/settingcalcomponent/verifycard/index.jsx
index d8918a1..a478d38 100644
--- a/src/templates/sharecomponent/settingcalcomponent/verifycard/index.jsx
+++ b/src/templates/sharecomponent/settingcalcomponent/verifycard/index.jsx
@@ -291,14 +291,15 @@
     } else if (type === 'scripts' && _scripts.length === 0) {
       resolve()
     } else if (setting.execute !== 'false' || _scripts.length > 0) {
+      let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
       let param = {
         func: 's_debug_sql',
         exec_type: 'y',
-        LText: SettingUtils.getDebugSql(setting, _scripts, columns, this.getRegOptions(searches), config.calendar, config.urlFields)
+        LText: SettingUtils.getDebugSql(setting, _scripts, columns, this.getRegOptions(searches), config.calendar, config.urlFields, timestamp)
       }
       param.LText = Utils.formatOptions(param.LText)
-      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-      param.secretkey = Utils.encrypt('', param.timestamp)
+      param.timestamp = timestamp
+      param.secretkey = Utils.encrypt('', timestamp)
       
       Api.getLocalConfig(param).then(result => {
         if (result.status) {
diff --git a/src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.jsx b/src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.jsx
index b4622fd..c07d5f6 100644
--- a/src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.jsx
+++ b/src/templates/sharecomponent/settingcalcomponent/verifycard/settingform/index.jsx
@@ -1,6 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Row, Col, Input, Radio, Tooltip, notification, InputNumber } from 'antd'
+import { Form, Row, Col, Input, Radio, Tooltip, notification } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
@@ -313,7 +313,7 @@
                 </Radio.Group>)}
               </Form.Item>
             </Col>
-            <Col span={8}>
+            {/* <Col span={8}>
               <Form.Item label={
                 <Tooltip placement="topLeft" title="楂樼骇鎼滅储寮圭獥鐨勫搴︼紝娉細褰撳搴﹀�煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺��">
                   <QuestionCircleOutlined className="mk-form-tip" />
@@ -324,7 +324,7 @@
                   initialValue: setting.advanceWidth || 1000
                 })(<InputNumber min={10} max={3000} precision={0}/>)}
               </Form.Item>
-            </Col>
+            </Col> */}
           </Row>
         </Form>
       </div>
diff --git a/src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx b/src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx
index b5586e2..478739f 100644
--- a/src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx
+++ b/src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx
@@ -7,7 +7,7 @@
    * @return {Object}  setting       椤甸潰璁剧疆
    * @return {Array}   columns       鏄剧ず瀛楁
    */
-  static getDebugSql (setting, scripts, columns, searches, calendar, urlFields = []) {
+  static getDebugSql (setting, scripts, columns, searches, calendar, urlFields = [], timestamp) {
     let sql = ''
     let _dataresource = ''
     let _customScript = ''
@@ -22,7 +22,7 @@
     }
 
     if (_customScript) {
-      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
         ${_customScript}
       `
     }
@@ -39,6 +39,8 @@
       })
     }
     
+    _dataresource = _dataresource.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${timestamp}'`)
+    _customScript = _customScript.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${timestamp}'`)
     _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
     _customScript = _customScript.replace(/@\$|\$@/ig, '')
     
@@ -49,8 +51,8 @@
     }
 
     urlFields.forEach(field => {
-      _dataresource = _dataresource.replace(new RegExp('@' + field + '@', 'ig'), '0')
-      _customScript = _customScript.replace(new RegExp('@' + field + '@', 'ig'), '0')
+      _dataresource = _dataresource.replace(new RegExp('@' + field + '@', 'ig'), `'0'`)
+      _customScript = _customScript.replace(new RegExp('@' + field + '@', 'ig'), `'0'`)
     })
     
     // 姝e垯鏇挎崲
@@ -78,9 +80,6 @@
     }
 
     _regoptions.push({
-      reg: new RegExp('@login_city@', 'ig'),
-      value: `''`
-    }, {
       reg: new RegExp('@userName@', 'ig'),
       value: `''`
     }, {
@@ -134,7 +133,7 @@
       `
     } else {
       sql = `/* sql 楠岃瘉 */
-        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
         ${_dataresource}`
     }
     sql = sql.replace(/\n\s{8}/ig, '\n')
diff --git a/src/templates/sharecomponent/settingcomponent/index.jsx b/src/templates/sharecomponent/settingcomponent/index.jsx
index 51f4216..ca098d1 100644
--- a/src/templates/sharecomponent/settingcomponent/index.jsx
+++ b/src/templates/sharecomponent/settingcomponent/index.jsx
@@ -7,7 +7,7 @@
 import Utils, { FuncUtils } from '@/utils/utils.js'
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
-
+import MKEmitter from '@/utils/events.js'
 import SettingForm from './settingform'
 import CreateFunc from '@/templates/zshare/createfunc'
 import CreateInterface from '@/templates/zshare/createinterface'
@@ -51,6 +51,8 @@
       search: _search,
       menu: menu
     })
+
+    MKEmitter.emit('modalStatus', '鏁版嵁婧�')
   }
 
   /**
@@ -63,7 +65,7 @@
       loading: true
     })
     this.settingRef.handleConfirm().then(setting => {
-      let res = this.resetSetting(setting)
+      let res = this.resetSetting(setting, config.setting)
       this.setState({
         visible: false,
         loading: false
@@ -72,6 +74,8 @@
       res.columnfixed = res.columnfixed === 'true'
 
       this.props.updatesetting({...config, setting: res})
+
+      MKEmitter.emit('modalStatus', false)
     }, () => {
       this.setState({
         loading: false
@@ -87,7 +91,7 @@
     const { menu } = this.state
 
     this.settingRef.handleConfirm('loading').then(setting => {
-      let res = this.resetSetting(setting)
+      let res = this.resetSetting(setting, config.setting)
       let _config = {...config, setting: res}
       let newLText = Utils.formatOptions(FuncUtils.getTableFunc(setting, menu, _config)) // 鍒涘缓瀛樺偍杩囩▼sql
       let DelText = Utils.formatOptions(FuncUtils.dropfunc(setting.innerFunc))          // 鍒犻櫎瀛樺偍杩囩▼sql
@@ -104,7 +108,7 @@
     const { menu } = this.state
 
     this.settingRef.handleConfirm('loading').then(setting => {
-      let res = this.resetSetting(setting)
+      let res = this.resetSetting(setting, config.setting)
       let _config = {...config, setting: res}
       let _menu = {
         type: config.Template === 'CommonTable' ? 'main' : 'subtable',
@@ -117,9 +121,16 @@
     })
   }
 
-  resetSetting = (s) => {
+  resetSetting = (s, ori) => {
     let setting = fromJS(s).toJS()
     let maxScript = 0
+
+    setting.show = ori.show || 'true'
+    setting.advanceType = ori.advanceType || 'modal'
+    setting.advanceWidth = ori.advanceWidth || 1000
+    setting.drawerPlacement = ori.drawerPlacement || 'right'
+    setting.searchRatio = ori.searchRatio || 6
+    setting.searchLwidth = ori.searchLwidth !== undefined ? ori.searchLwidth : 33.3
 
     if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
       window.GLOB.funcs.forEach(m => {
@@ -175,15 +186,15 @@
         {/* 璁剧疆鍏ㄥ眬閰嶇疆鍙婂垪琛ㄦ暟鎹簮 */}
         <Modal
           wrapClassName="model-table-setting-verify-modal"
-          title={dict['model.edit']}
+          title="鏁版嵁婧愰厤缃�"
           visible={visible}
           width={900}
           maskClosable={false}
-          onCancel={() => { this.setState({ visible: false, loading: false })}}
+          onCancel={() => { MKEmitter.emit('modalStatus', false); this.setState({ visible: false, loading: false })}}
           footer={[
             record && record.interType === 'system' ? <CreateInterface key="interface" loading={this.state.interloading} dict={dict} ref="tableCreatInterface" trigger={this.tableCreatInterface}/> : null,
             record && record.interType === 'inner' ? <CreateFunc key="create" dict={dict} ref="funcCreatComponent" trigger={this.tableCreatFunc}/> : null,
-            <Button key="cancel" onClick={() => { this.setState({ visible: false, loading: false }) }}>{this.state.dict['model.cancel']}</Button>,
+            <Button key="cancel" onClick={() => { MKEmitter.emit('modalStatus', false); this.setState({ visible: false, loading: false }) }}>{this.state.dict['model.cancel']}</Button>,
             <Button key="confirm" type="primary" loading={this.state.loading} onClick={this.settingSave}>{this.state.dict['model.confirm']}</Button>
           ]}
           destroyOnClose
diff --git a/src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx b/src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx
index 4e7dce8..7a60231 100644
--- a/src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx
+++ b/src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx
@@ -682,7 +682,7 @@
                 </Radio.Group>)}
               </Form.Item>
             </Col>
-            <Col span={12}>
+            {/* <Col span={12}>
               <Form.Item label={
                 <Tooltip placement="topLeft" title="鍦ㄦ悳绱㈡潯浠跺瓨鍦ㄦ椂锛屾槸鍚︽樉绀烘悳绱㈠拰閲嶇疆鎸夐挳銆�">
                   <QuestionCircleOutlined className="mk-form-tip" />
@@ -697,7 +697,7 @@
                   <Radio value="false">闅愯棌</Radio>
                 </Radio.Group>)}
               </Form.Item>
-            </Col>
+            </Col> */}
             {tableType !== '' ? <Col span={12}>
               <Form.Item label={
                 <Tooltip placement="topLeft" title="褰撴寜閽墽琛屽畬鎴愬苟杩斿洖涓婚敭鍊兼椂锛岄粯璁ら�変腑涓婚敭鍊煎搴旇銆傛敞锛氬湪鍚敤鏃犱汉鍊煎畧鍔熻兘鏃舵棤鏁堛��">
@@ -727,7 +727,7 @@
                 })(<InputNumber min={1} max={500} precision={0} />)}
               </Form.Item>
             </Col>
-            <Col span={12}>
+            {/* <Col span={12}>
               <Form.Item label={
                 <Tooltip placement="topLeft" title="楂樼骇鎼滅储寮圭獥鐨勫搴︼紝娉細褰撳搴﹀�煎皬浜�100鏃惰〃绀哄崰绐楀彛鐨勭櫨鍒嗘瘮锛屽ぇ浜�100鏃惰〃绀哄搴︾殑缁濆鍊笺��">
                   <QuestionCircleOutlined className="mk-form-tip" />
@@ -738,7 +738,7 @@
                   initialValue: setting.advanceWidth || 1000
                 })(<InputNumber min={10} max={3000} precision={0}/>)}
               </Form.Item>
-            </Col>
+            </Col> */}
             <Col span={12}>
               <Form.Item label={
                 <Tooltip placement="topLeft" title="鍙屽嚮琛ㄦ牸涓锛岃Е鍙戠殑鎸夐挳銆�">
diff --git a/src/templates/sharecomponent/settingcomponent/settingform/index.jsx b/src/templates/sharecomponent/settingcomponent/settingform/index.jsx
index b60fc7f..2fec3e1 100644
--- a/src/templates/sharecomponent/settingcomponent/settingform/index.jsx
+++ b/src/templates/sharecomponent/settingcomponent/settingform/index.jsx
@@ -1,7 +1,8 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
-import { Form, notification, Modal, Spin, Tabs } from 'antd'
+import { Form, notification, Modal, Spin, Tabs, Typography, Popconfirm, Button } from 'antd'
+import { CheckCircleOutlined, StopOutlined, SwapOutlined, DeleteOutlined, BorderOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import Api from '@/api'
@@ -9,9 +10,12 @@
 import SettingUtils from './utils.jsx'
 import asyncComponent from '@/utils/asyncComponent'
 import DataSource from './datasource'
+import MinView from '@/assets/img/minview.png'
 import './index.scss'
 
 const { TabPane } = Tabs
+const { Paragraph } = Typography
+const CodeMirror = asyncComponent(() => import('@/templates/zshare/codemirror'))
 const CustomScript = asyncComponent(() => import('@/templates/zshare/customscript'))
 const SimpleScript = asyncComponent(() => import('./simplescript'))
 
@@ -33,6 +37,9 @@
     regoptions: [],
     setting: null,
     defaultSql: '',
+    visible: false,
+    script: null,
+    scriptValue: '',
     status: {}
   }
 
@@ -316,15 +323,16 @@
     } else if (type === 'scripts' && _scripts.length === 0) {
       _resolve()
     } else { // type 涓� submit 銆� verify 锛屼互鍙婂叾浠栭渶瑕侀獙璇佺殑鍦烘櫙
-      let r = SettingUtils.getDebugSql(setting, _scripts, arr_field, regoptions, search)
+      let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+      let r = SettingUtils.getDebugSql(setting, _scripts, arr_field, regoptions, search, timestamp)
       let param = {
         func: 's_debug_sql',
         exec_type: 'y',
         LText: r.sql
       }
       param.LText = Utils.formatOptions(param.LText)
-      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-      param.secretkey = Utils.encrypt('', param.timestamp)
+      param.timestamp = timestamp
+      param.secretkey = Utils.encrypt('', timestamp)
 
       let sumParam = null
       if (r.sumSql) {
@@ -478,6 +486,42 @@
     })
   }
 
+  triggerConfirm = () => {
+    const { script, scriptValue, scripts } = this.state
+    let _scripts = fromJS(scripts).toJS()
+
+    if (!scriptValue) {
+      notification.warning({
+        top: 92,
+        message: '璇疯緭鍏ql!',
+        duration: 5
+      })
+      return
+    }
+
+    if (script) {
+      _scripts = _scripts.map(item => {
+        if (script.uuid === item.uuid) {
+          item.sql = scriptValue
+        }
+        return item
+      })
+    } else {
+      let _script = {
+        uuid: Utils.getuuid(),
+        sql: scriptValue,
+        $index: _scripts.length + 1,
+        status: 'true'
+      }
+
+      _scripts.push(_script)
+    }
+
+    this.setState({loading: true})
+
+    this.sqlverify(() => {this.setState({scripts: _scripts, script: null, scriptValue: '', loading: false})}, () => {this.setState({loading: false})}, 'verify', _scripts)
+  }
+
   // 鑷畾涔夎剼鏈洿鏂�
   scriptsUpdate = (scripts) => {
     this.setState({scripts})
@@ -493,6 +537,26 @@
     this.setState({cbScripts})
   }
 
+  handleDelete = (item) => {
+    const { script, scripts } = this.state
+
+    if (script && script.uuid === item.uuid) {
+      this.setState({script: null})
+    }
+    this.setState({scripts: scripts.filter(cell => cell.uuid !== item.uuid)})
+  }
+
+  handleStatus = (item) => {
+    item.status = item.status === 'false' ? 'true' : 'false'
+
+    this.setState({scripts: this.state.scripts.map(cell => {
+      if (cell.uuid === item.uuid) {
+        return item
+      }
+      return cell
+    })})
+  }
+
   updateStatus = (status) => {
     let _status = {...this.state.status, ...status}
     this.setState({status: _status})
@@ -501,7 +565,7 @@
 
   render() {
     const { config, menu, dict } = this.props
-    const { loading, activeKey, setting, defaultSql, columns, scripts, preScripts, cbScripts, status, regoptions } = this.state
+    const { loading, activeKey, setting, defaultSql, columns, scripts, preScripts, cbScripts, status, regoptions, visible, script, scriptValue } = this.state
 
     return (
       <div className="model-table-setting-form-box" id="model-setting-form-body">
@@ -525,6 +589,17 @@
               {scripts.length ? <span className="count-tip">{scripts.length}</span> : null}
             </span>
           } disabled={!(status.interType === 'system' || (status.interType === 'custom' && status.requestMode === 'system'))} key="scripts">
+            <BorderOutlined className="full-scripts" onClick={() => {
+              if (this.scriptsForm && (this.scriptsForm.state.editItem || (this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))))) {
+                notification.warning({
+                  top: 92,
+                  message: '璇蜂繚瀛樿嚜瀹氫箟鑴氭湰锛�',
+                  duration: 5
+                })
+                return
+              }
+              this.setState({visible: true, script: null, scriptValue: ''})
+            }}/>
             <CustomScript
               dict={dict}
               setting={setting}
@@ -569,6 +644,63 @@
             />
           </TabPane>
         </Tabs>
+        <Modal
+          wrapClassName="model-custom-table-scripts-modal"
+          title="鑷畾涔夎剼鏈�"
+          visible={visible}
+          width={'95vw'}
+          maskClosable={false}
+          destroyOnClose
+        >
+          <img className="unfull-scripts" src={MinView} onClick={() => this.setState({visible: false, script: null})} alt=""/>
+          <div className="script-table-wrap">
+            {scripts.map(item => {
+              let title = item.sql.match(/^\s*\/\*.+\*\//)
+              title = title && title[0] ? title[0] : ''
+              let _text = title ? item.sql.replace(title, '') : item.sql
+
+              return (
+                <div className={'script-item ' + (script && script.uuid === item.uuid ? 'active' : '') } key={item.uuid}>
+                  <div style={{cursor: 'pointer'}} onClick={() => {
+                    this.setState({script: item, scriptValue: item.sql})
+                  }}>
+                    {title ? <div style={{color: '#a50', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>{title}</div> : null}
+                    <Paragraph copyable={{ text: item.sql }} ellipsis={{ rows: 4 }}>{_text}</Paragraph>
+                    <div>{item.status === 'false' ?
+                      <span style={{color: '#ff4d4f', marginLeft: '20px'}}>
+                        绂佺敤
+                        <StopOutlined style={{marginLeft: '5px'}} />
+                      </span> : 
+                      <span style={{color: '#26C281', marginLeft: '20px'}}>
+                        鍚敤
+                        <CheckCircleOutlined style={{marginLeft: '5px'}}/>
+                      </span>}
+                    </div>
+                  </div>
+                  <div style={{textAlign: 'right'}}>
+                    <span className="operation-btn" onClick={() => this.handleStatus(item)} style={{color: '#8E44AD'}}><SwapOutlined /></span>
+                    <Popconfirm
+                      overlayClassName="popover-confirm"
+                      title={this.props.dict['model.query.delete']}
+                      onConfirm={() => this.handleDelete(item)
+                    }>
+                      <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span>
+                    </Popconfirm>
+                  </div>
+                </div>
+              )
+            })}
+          </div>
+          <div className="script-button">
+            <Button onClick={this.triggerConfirm} loading={loading} className="mk-green" style={{marginBottom: 15, marginLeft: 40}}>
+              {script ? '淇濆瓨' : '娣诲姞'}
+            </Button>
+            <Button onClick={() => {this.setState({script: null, scriptValue: ''})}} style={{marginBottom: 15, marginLeft: 10}}>
+              鍙栨秷
+            </Button>
+          </div>
+          <CodeMirror value={scriptValue} onChange={(val) => {this.setState({scriptValue: val})}}></CodeMirror>
+        </Modal>
       </div>
     )
   }
diff --git a/src/templates/sharecomponent/settingcomponent/settingform/index.scss b/src/templates/sharecomponent/settingcomponent/settingform/index.scss
index 2166d9b..516889d 100644
--- a/src/templates/sharecomponent/settingcomponent/settingform/index.scss
+++ b/src/templates/sharecomponent/settingcomponent/settingform/index.scss
@@ -58,4 +58,108 @@
   .ant-tabs-nav-wrap {
     text-align: center;
   }
+  .full-scripts {
+    position: absolute;
+    right: 0px;
+    top: 18px;
+    font-size: 18px;
+    color: #1890ff;
+  }
+}
+
+.model-custom-table-scripts-modal {
+  .ant-modal {
+    top: 30px;
+    .ant-modal-header {
+      padding: 10px 24px;
+    }
+    .ant-modal-footer {
+      display: none;
+    }
+    .ant-modal-close {
+      display: none;
+    }
+    .ant-modal-body {
+      padding: 0;
+      height: calc(100vh - 100px);
+      overflow: hidden;
+      display: flex;
+
+      .script-table-wrap {
+        width: 240px;
+        overflow-y: auto;
+        overflow-x: hidden;
+        height: calc(100vh - 100px);
+
+        .operation-btn {
+          display: inline-block;
+          font-size: 16px;
+          padding: 0 5px;
+          cursor: pointer;
+          margin-left: 5px;
+        }
+
+        .script-item {
+          border-bottom: 1px solid #eeeeee;
+          padding: 15px 10px 5px;
+        }
+        .script-item.active {
+          background-color: #bae7ff;
+        }
+        .ant-typography {
+          margin-bottom: 5px;
+        }
+      }
+
+      .script-table-wrap::-webkit-scrollbar {
+        width: 7px;
+      }
+      .script-table-wrap::-webkit-scrollbar-thumb {
+        border-radius: 5px;
+        box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+        background: rgba(0, 0, 0, 0.13);
+      }
+      .script-table-wrap::-webkit-scrollbar-track {
+        box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
+        border-radius: 3px;
+        border: 1px solid rgba(0, 0, 0, 0.07);
+        background: rgba(0, 0, 0, 0);
+      }
+
+      .unfull-scripts {
+        position: absolute;
+        right: 20px;
+        z-index: 2;
+        top: 10px;
+        color: #1890ff;
+        width: 26px;
+        cursor: pointer;
+        padding: 5px;
+      }
+
+      .script-button {
+        position: absolute;
+        top: 10px;
+        z-index: 1;
+        left: 240px;
+        .ant-btn {
+          height: 28px;
+        }
+        .mk-green {
+          margin-left: 0!important;
+          margin-right: 10px;
+        }
+      }
+      .code-mirror-wrap {
+        .CodeMirror {
+          height: calc(100vh - 100px);
+          border-radius: 0;
+        }
+        .code-mirror-area {
+          border-radius: 0;
+          width: calc(95vw - 240px);
+        }
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx b/src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx
index 61ac6e4..4dad8fb 100644
--- a/src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx
+++ b/src/templates/sharecomponent/settingcomponent/settingform/simplescript/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
-import { Form, Row, Col, Button, notification, Select, Popconfirm, Typography, Modal, Radio } from 'antd'
+import { Form, Row, Col, Button, notification, Select, Popconfirm, Typography, Modal, Radio, Tooltip } from 'antd'
 import { StopOutlined, CheckCircleOutlined, EditOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
@@ -31,6 +31,7 @@
     editItem: null,
     loading: false,
     usefulFields: '',
+    urlFields: '',
     systemScripts: [],
     scriptsColumns: [
       {
@@ -69,7 +70,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div style={{color: '#ff4d4f'}}>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopOutlined style={{marginLeft: '5px'}} />
             </div>
           ) :
@@ -106,6 +107,7 @@
 
     let _usefulFields = []
     let scriptsColumns = fromJS(this.state.scriptsColumns).toJS()
+    let _urlFields = ''
 
     if (searches) {
       searches.forEach(item => {
@@ -120,14 +122,11 @@
         } else if (_usefulFields.includes(item.field)) {
           _usefulFields.push(item.field + '1')
         } else {
-          _usefulFields.push(item.field)
+          _usefulFields.push(item.field.replace(/,/ig, ', '))
         }
       })
 
-      if (urlFields) {
-        _usefulFields.push(...urlFields)
-      }
-      
+      _urlFields = urlFields ? urlFields.join(', ') : ''
       _usefulFields = _usefulFields.join(', ')
       scriptsColumns = scriptsColumns.filter(item => {
         if (item.dataIndex === 'sql') {
@@ -140,6 +139,7 @@
     }
 
     this.setState({
+      urlFields: _urlFields,
       usefulFields: _usefulFields,
       scripts: fromJS(scripts).toJS(),
       scriptsColumns
@@ -289,8 +289,10 @@
       exec_type: 'y',
       LText: SettingUtils.getCustomDebugSql(_scripts, this.props.regoptions)
     }
-    param.LText = Utils.formatOptions(param.LText)
+
     param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    param.LText = param.LText.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
+    param.LText = Utils.formatOptions(param.LText)
     param.secretkey = Utils.encrypt('', param.timestamp)
     
     this.setState({loading: true})
@@ -404,7 +406,7 @@
   render() {
     const { setting, scripts } = this.props
     const { getFieldDecorator } = this.props.form
-    const { usefulFields, scriptsColumns, systemScripts } = this.state
+    const { usefulFields, scriptsColumns, systemScripts, urlFields } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -430,16 +432,14 @@
                 ErrorCode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT锛�, retmsg
               </Form.Item>
             </Col>
-            {usefulFields ? <Col span={24} className="sqlfield">
+            <Col span={24} className="sqlfield">
               <Form.Item label={'鍙敤瀛楁'}>
-                id, bid, loginuid, sessionuid, userid, username, fullname, RoleID, mk_departmentcode, mk_organization, login_city, appkey, time_id{usefulFields ? ', ' + usefulFields : ''}
+                <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
+                <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address</span></Tooltip>
+                {usefulFields ? <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鎼滅储鏉′欢鍙橀噺锛岃鎸夌収@xxx@鏍煎紡浣跨敤銆�'}>, {usefulFields}</Tooltip> : ''}
+                {urlFields ?<Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'url鍙橀噺锛岃鎸夌収@xxx@鏍煎紡浣跨敤銆�'}>, <span style={{color: '#13c2c2'}}>{urlFields}</span></Tooltip> : ''}
               </Form.Item>
-            </Col> : null}
-            {!usefulFields ? <Col span={24} className="sqlfield">
-              <Form.Item label={'鍙敤瀛楁'}>
-                id, bid, loginuid, sessionuid, userid, username, fullname, RoleID, mk_departmentcode, mk_organization, login_city, appkey, time_id
-              </Form.Item>
-            </Col> : null}
+            </Col>
             {!usefulFields ? <Col span={8} style={{whiteSpace: 'nowrap'}}>
               <Form.Item style={{marginBottom: 0}} label="鎵ц浣嶇疆">
                 {getFieldDecorator('position', {
diff --git a/src/templates/sharecomponent/settingcomponent/settingform/utils.jsx b/src/templates/sharecomponent/settingcomponent/settingform/utils.jsx
index f98ee4f..a9f3e69 100644
--- a/src/templates/sharecomponent/settingcomponent/settingform/utils.jsx
+++ b/src/templates/sharecomponent/settingcomponent/settingform/utils.jsx
@@ -7,7 +7,7 @@
    * @return {Object}  setting       椤甸潰璁剧疆
    * @return {Array}   regoptions    鎼滅储鏉′欢姝e垯鏇挎崲
    */
-  static getDebugSql (setting, scripts, arr_field, regoptions, search) {
+  static getDebugSql (setting, scripts, arr_field, regoptions, search, timestamp) {
     let sql = ''
     let _dataresource = setting.dataresource || ''
     let _customScript = ''
@@ -18,7 +18,7 @@
     })
 
     if (_customScript) {
-      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
         ${_customScript}
       `
     }
@@ -35,6 +35,8 @@
       })
     }
     
+    _dataresource = _dataresource.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${timestamp}'`)
+    _customScript = _customScript.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${timestamp}'`)
     _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
     _customScript = _customScript.replace(/@\$|\$@/ig, '')
     _dataresource = _dataresource.replace(/@select\$|\$select@/ig, '')
@@ -61,9 +63,6 @@
     })
 
     _regoptions.push({
-      reg: new RegExp('@login_city@', 'ig'),
-      value: `''`
-    }, {
       reg: new RegExp('@userName@', 'ig'),
       value: `''`
     }, {
@@ -115,7 +114,7 @@
         `
       } else {
         sumSql = `/* sql sum楠岃瘉 */
-          declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+          declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
           ${_sql}`
       }
     }
@@ -139,7 +138,7 @@
       `
     } else {
       sql = `/* sql 楠岃瘉 */
-        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
         ${_dataresource}`
     }
     sql = sql.replace(/\n\s{8}/ig, '\n')
@@ -171,7 +170,7 @@
     })
 
     if (_customScript) {
-      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
         ${_customScript}
       `
     }
@@ -184,7 +183,7 @@
     }
 
     _customScript = _customScript.replace(/@\$|\$@/ig, '')
-    _customScript = _customScript.replace(/@userName@|@fullName@|@login_city@/ig, `''`)
+    _customScript = _customScript.replace(/@userName@|@fullName@/ig, `''`)
     // 澶栬仈鏁版嵁搴撴浛鎹�
     if (window.GLOB.externalDatabase !== null) {
       _customScript = _customScript.replace(/@db@/ig, window.GLOB.externalDatabase)
diff --git a/src/templates/sharecomponent/tabscomponent/tabdragelement/card.jsx b/src/templates/sharecomponent/tabscomponent/tabdragelement/card.jsx
index f4017f9..078536c 100644
--- a/src/templates/sharecomponent/tabscomponent/tabdragelement/card.jsx
+++ b/src/templates/sharecomponent/tabscomponent/tabdragelement/card.jsx
@@ -41,7 +41,7 @@
     delCard(id)
   }
 
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   return (
     <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
diff --git a/src/templates/sharecomponent/treesettingcomponent/index.jsx b/src/templates/sharecomponent/treesettingcomponent/index.jsx
index 17a1e80..141d90e 100644
--- a/src/templates/sharecomponent/treesettingcomponent/index.jsx
+++ b/src/templates/sharecomponent/treesettingcomponent/index.jsx
@@ -6,6 +6,7 @@
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
 import SettingForm from './settingform'
+import MKEmitter from '@/utils/events.js'
 
 import './index.scss'
 
@@ -34,6 +35,7 @@
       visible: true,
       menu: menu
     })
+    MKEmitter.emit('modalStatus', '鏁版嵁婧�')
   }
 
   /**
@@ -62,7 +64,16 @@
         loading: false
       })
 
+      res.show = config.setting.show || 'true'
+      res.advanceType = config.setting.advanceType || 'modal'
+      res.advanceWidth = config.setting.advanceWidth || 1000
+      res.drawerPlacement = config.setting.drawerPlacement || 'right'
+      res.searchRatio = config.setting.searchRatio || 6
+      res.searchLwidth = config.setting.searchLwidth !== undefined ? config.setting.searchLwidth : 33.3
+
       this.props.updatesetting({...config, setting: res})
+
+      MKEmitter.emit('modalStatus', false)
     }, () => {
       this.setState({
         loading: false
@@ -89,11 +100,11 @@
         {/* 璁剧疆鍏ㄥ眬閰嶇疆鍙婂垪琛ㄦ暟鎹簮 */}
         <Modal
           wrapClassName="model-tree-setting-verify-modal"
-          title={dict['model.edit']}
+          title="鏁版嵁婧愰厤缃�"
           visible={visible}
           width={900}
           maskClosable={false}
-          onCancel={() => { this.setState({ visible: false })}}
+          onCancel={() => { MKEmitter.emit('modalStatus', false); this.setState({ visible: false })}}
           confirmLoading={loading}
           onOk={this.settingSave}
           destroyOnClose
diff --git a/src/templates/sharecomponent/treesettingcomponent/settingform/index.jsx b/src/templates/sharecomponent/treesettingcomponent/settingform/index.jsx
index bb5ebe8..b3958a5 100644
--- a/src/templates/sharecomponent/treesettingcomponent/settingform/index.jsx
+++ b/src/templates/sharecomponent/treesettingcomponent/settingform/index.jsx
@@ -135,14 +135,15 @@
     } else if (type === 'scripts' && _scripts.length === 0) {
       _resolve()
     } else { // type 涓� submit 銆� verify 锛屼互鍙婂叾浠栭渶瑕侀獙璇佺殑鍦烘櫙
+      let timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
       let param = {
         func: 's_debug_sql',
         exec_type: 'y',
-        LText: SettingUtils.getDebugSql(setting, _scripts)
+        LText: SettingUtils.getDebugSql(setting, _scripts, timestamp)
       }
       param.LText = Utils.formatOptions(param.LText)
-      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
-      param.secretkey = Utils.encrypt('', param.timestamp)
+      param.timestamp = timestamp
+      param.secretkey = Utils.encrypt('', timestamp)
       
       Api.getLocalConfig(param).then(result => {
         if (result.status) {
diff --git a/src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx b/src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx
index 74d911e..4a49e77 100644
--- a/src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx
+++ b/src/templates/sharecomponent/treesettingcomponent/settingform/utils.jsx
@@ -5,7 +5,7 @@
    * @return {String}  scripts       鑷畾涔夎剼鏈�
    * @return {Object}  setting       椤甸潰璁剧疆
    */
-  static getDebugSql (setting, scripts) {
+  static getDebugSql (setting, scripts, timestamp) {
     let arr_field = `${setting.valueField},${setting.labelField},${setting.parentField}`
     let sql = ''
     let _dataresource = setting.dataresource || ''
@@ -18,7 +18,7 @@
     })
 
     if (_customScript) {
-      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
         ${_customScript}
       `
     }
@@ -35,6 +35,8 @@
       })
     }
     
+    _dataresource = _dataresource.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${timestamp}'`)
+    _customScript = _customScript.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${timestamp}'`)
     _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
     _customScript = _customScript.replace(/@\$|\$@/ig, '')
 
@@ -75,7 +77,7 @@
       `
     } else {
       sql = `/* sql 楠岃瘉 */
-        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50) select @ErrorCode='',@retmsg =''
+        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100) select @ErrorCode='',@retmsg =''
         ${_dataresource}`
     }
     sql = sql.replace(/\n\s{8}/ig, '\n')
diff --git a/src/templates/subtableconfig/index.jsx b/src/templates/subtableconfig/index.jsx
index 78e573a..4612793 100644
--- a/src/templates/subtableconfig/index.jsx
+++ b/src/templates/subtableconfig/index.jsx
@@ -1,6 +1,5 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import {connect} from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { DndProvider } from 'react-dnd'
 import HTML5Backend from 'react-dnd-html5-backend'
@@ -66,7 +65,8 @@
     thawButtons: [],         // 宸查�夋嫨瑕佽В鍐荤殑鎸夐挳
     activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
     chartview: null,         // 褰撳墠瑙嗗浘
-    openEdition: ''          // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
+    openEdition: '',         // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
+    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   /**
@@ -152,6 +152,15 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
+        if (this.state.modalStatus) {
+          notification.warning({
+            top: 92,
+            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            duration: 5
+          })
+          return false
+        }
+
         let node = document.getElementById('save-config')
         if (node && node.click) {
           node.click()
@@ -159,6 +168,7 @@
         return false
       }
     }
+    MKEmitter.addListener('modalStatus', this.modalStatus)
   }
 
   /**
@@ -219,6 +229,11 @@
       return
     }
     document.onkeydown = () => {}
+    MKEmitter.removeListener('modalStatus', this.modalStatus)
+  }
+
+  modalStatus = (val) => {
+    this.setState({modalStatus: val})
   }
 
   // 椤甸潰杩斿洖
@@ -1198,14 +1213,4 @@
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    memberLevel: state.memberLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(SubTableConfig)
+export default SubTableConfig
diff --git a/src/templates/subtableconfig/index.scss b/src/templates/subtableconfig/index.scss
index f17d953..0adcbba 100644
--- a/src/templates/subtableconfig/index.scss
+++ b/src/templates/subtableconfig/index.scss
@@ -1,6 +1,6 @@
 .model-subtable-board {
   position: fixed;
-  z-index: 1070;
+  z-index: 1;
   padding-top: 48px;
   top: 0px;
   left: 0px;
diff --git a/src/templates/subtableconfig/source.jsx b/src/templates/subtableconfig/source.jsx
index 478a464..bb48d97 100644
--- a/src/templates/subtableconfig/source.jsx
+++ b/src/templates/subtableconfig/source.jsx
@@ -203,13 +203,13 @@
     },
     {
       type: 'search',
-      label: CommonDict['model.form.dateday'],
+      label: '鏃ユ湡锛堝ぉ锛�',
       subType: 'date',
       url: ''
     },
     {
       type: 'search',
-      label: CommonDict['model.form.dateweek'],
+      label: '鏃ユ湡锛堝懆锛�',
       subType: 'dateweek',
       url: ''
     },
diff --git a/src/templates/treepageconfig/index.jsx b/src/templates/treepageconfig/index.jsx
index cb5a505..0d4a1ab 100644
--- a/src/templates/treepageconfig/index.jsx
+++ b/src/templates/treepageconfig/index.jsx
@@ -1,6 +1,5 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { connect } from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { DndProvider } from 'react-dnd'
 import HTML5Backend from 'react-dnd-html5-backend'
@@ -13,8 +12,8 @@
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
 
+import MKEmitter from '@/utils/events.js'
 import asyncComponent from '@/utils/asyncComponent'
-
 import MenuForm from '@/templates/comtableconfig/menuform'
 import SourceElement from '@/templates/zshare/dragsource'
 import Source from './source'
@@ -46,7 +45,8 @@
     delTabs: [],             // 鍒犻櫎鏍囩鍒楄〃
     tabviews: [],            // 鎵�鏈夋爣绛鹃〉
     activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
-    openEdition: ''          // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
+    openEdition: '',         // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
+    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   /**
@@ -130,6 +130,15 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
+        if (this.state.modalStatus) {
+          notification.warning({
+            top: 92,
+            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            duration: 5
+          })
+          return false
+        }
+
         let node = document.getElementById('save-config')
         if (node && node.click) {
           node.click()
@@ -137,6 +146,7 @@
         return false
       }
     }
+    MKEmitter.addListener('modalStatus', this.modalStatus)
   }
 
   /**
@@ -147,6 +157,11 @@
       return
     }
     document.onkeydown = () => {}
+    MKEmitter.removeListener('modalStatus', this.modalStatus)
+  }
+
+  modalStatus = (val) => {
+    this.setState({modalStatus: val})
   }
 
   /**
@@ -739,7 +754,7 @@
               <div>
                 <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={this.state.config.enabled} onChange={this.onEnabledChange} />
                 <Button type="primary" id="save-config" onClick={this.submitConfig} loading={this.state.menuloading}>{this.state.dict['model.save']}</Button>
-                <Button onClick={this.cancelConfig}>{this.state.dict['model.back']}</Button>
+                <Button onClick={this.cancelConfig}>鍏抽棴</Button>
               </div>
             } style={{ width: '100%' }}>
               <Row gutter={16}>
@@ -813,14 +828,4 @@
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    memberLevel: state.memberLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(ComTableConfig)
+export default ComTableConfig
diff --git a/src/templates/treepageconfig/index.scss b/src/templates/treepageconfig/index.scss
index 7f5f634..2ee9942 100644
--- a/src/templates/treepageconfig/index.scss
+++ b/src/templates/treepageconfig/index.scss
@@ -1,6 +1,6 @@
 .tree-page-board {
   position: fixed;
-  z-index: 1070;
+  z-index: 1;
   padding-top: 48px;
   top: 0px;
   left: 0px;
diff --git a/src/templates/zshare/customscript/index.jsx b/src/templates/zshare/customscript/index.jsx
index 8daf4ab..f68cca2 100644
--- a/src/templates/zshare/customscript/index.jsx
+++ b/src/templates/zshare/customscript/index.jsx
@@ -1,7 +1,7 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
-import { Form, Row, Col, Button, notification, Select, Popconfirm, Typography } from 'antd'
+import { Form, Row, Col, Button, notification, Select, Popconfirm, Typography, Tooltip } from 'antd'
 import { StopOutlined, CheckCircleOutlined, EditOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
@@ -31,6 +31,7 @@
     editItem: null,
     loading: false,
     usefulFields: '',
+    urlFields: '',
     systemScripts: [],
     scriptsColumns: [
       {
@@ -57,7 +58,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div style={{color: '#ff4d4f'}}>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopOutlined style={{marginLeft: '5px'}} />
             </div>
           ) :
@@ -105,15 +106,12 @@
       } else if (_usefulFields.includes(item.field)) {
         _usefulFields.push(item.field + '1')
       } else {
-        _usefulFields.push(item.field)
+        _usefulFields.push(item.field.replace(/,/ig, ', '))
       }
     })
 
-    if (urlFields) {
-      _usefulFields.push(...urlFields)
-    }
-
     this.setState({
+      urlFields: urlFields ? urlFields.join(', ') : '',
       usefulFields: _usefulFields.join(', '),
       scripts: fromJS(scripts).toJS()
     })
@@ -353,7 +351,7 @@
   render() {
     const { setting, defaultSql, scripts } = this.props
     const { getFieldDecorator } = this.props.form
-    const { usefulFields, scriptsColumns, systemScripts } = this.state
+    const { usefulFields, scriptsColumns, systemScripts, urlFields } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -381,7 +379,10 @@
             </Col>
             <Col span={24} className="sqlfield">
               <Form.Item label={'鍙敤瀛楁'}>
-                id, bid, loginuid, sessionuid, userid, username, fullname, RoleID, mk_departmentcode, mk_organization, login_city, appkey, time_id, orderBy{setting.laypage === 'true' ? ', pageSize, pageIndex': ''}{usefulFields ? ', ' + usefulFields : ''}
+                <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
+                <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address</span></Tooltip>,&nbsp;
+                <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鎺掑簭銆佸垎椤典互鍙婃悳绱㈡潯浠跺彉閲忥紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}>orderBy{setting.laypage === 'true' ? ', pageSize, pageIndex': ''}{usefulFields ? ', ' + usefulFields : ''}</Tooltip>
+                {urlFields ?<Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'url鍙橀噺锛岃鎸夌収@xxx@鏍煎紡浣跨敤銆�'}>, <span style={{color: '#13c2c2'}}>{urlFields}</span></Tooltip> : ''}
               </Form.Item>
             </Col>
             <Col span={10} className="quick-add">
diff --git a/src/templates/zshare/editTable/index.jsx b/src/templates/zshare/editTable/index.jsx
index ef0ff17..0319a12 100644
--- a/src/templates/zshare/editTable/index.jsx
+++ b/src/templates/zshare/editTable/index.jsx
@@ -81,14 +81,14 @@
 
 class EditableCell extends Component {
   getInput = (form) => {
-    const { inputType, options, min, max, unlimit } = this.props
+    const { inputType, options, min, max, unlimit, allowClear } = this.props
 
     if (inputType === 'number' && unlimit) {
       return <InputNumber onPressEnter={() => this.getValue(form)} />
     } else if (inputType === 'number') {
       return <InputNumber min={min} max={max} precision={0} onPressEnter={() => this.getValue(form)} />
     } else if (inputType === 'color') {
-      return <ColorSketch />
+      return <ColorSketch allowClear={allowClear} />
     } else if (inputType === 'icon') {
       return <MkEditIcon allowClear/>
     } else if (inputType === 'switch') {
@@ -582,6 +582,7 @@
           max: col.max || 500,
           unlimit: col.unlimit,
           required: col.required !== false ? true : false,
+          allowClear: col.allowClear === true,
           title: col.title,
           editing: this.isEditing(record),
           onSave: this.onSave,
@@ -632,7 +633,7 @@
             onCancel={() => {this.setState({visible: false})}}
             destroyOnClose
           >
-            <PasteForm dict={eTDict} wrappedComponentRef={(inst) => this.pasteFormRef = inst}/>
+            <PasteForm dict={eTDict} wrappedComponentRef={(inst) => this.pasteFormRef = inst} inputSubmit={this.pasteSubmit}/>
           </Modal>
         </div>
       </EditableContext.Provider>
diff --git a/src/templates/zshare/editcomponent/index.jsx b/src/templates/zshare/editcomponent/index.jsx
index f26d9e3..3029835 100644
--- a/src/templates/zshare/editcomponent/index.jsx
+++ b/src/templates/zshare/editcomponent/index.jsx
@@ -227,7 +227,7 @@
           onCancel={() => {this.setState({pasteVisible: false})}}
           destroyOnClose
         >
-          <PasteForm wrappedComponentRef={(inst) => this.pasteFormRef = inst}/>
+          <PasteForm wrappedComponentRef={(inst) => this.pasteFormRef = inst} inputSubmit={this.pasteSubmit}/>
         </Modal>
       </div>
     )
diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx
index f81c734..3ad7d6b 100644
--- a/src/templates/zshare/formconfig.jsx
+++ b/src/templates/zshare/formconfig.jsx
@@ -13,6 +13,17 @@
 export function getTreeSettingForm (setting, usefulFields = [], MenuID) {
   let str = '^(' + usefulFields.join('|') + ')'
   let _patten = new RegExp(str + formRule.func.innerPattern + '$', 'g')
+  let rules = [{
+    max: formRule.func.max,
+    message: formRule.func.maxMessage
+  }]
+
+  if (usefulFields.length > 0) {
+    rules.push({
+      pattern: _patten,
+      message: formRule.func.innerMessage
+    })
+  }
 
   return [
     {
@@ -103,19 +114,11 @@
       key: 'innerFunc',
       label: Formdict['header.form.innerFunc'],
       initVal: setting.innerFunc || '',
-      tooltip: '寮�澶村彲鐢ㄥ瓧绗︼細' + usefulFields.join(', '),
+      tooltip: usefulFields.length ? '寮�澶村彲鐢ㄥ瓧绗︼細' + usefulFields.join(', ') : '',
       placement: 'bottomLeft',
       required: false,
       readonly: false,
-      rules: [
-        {
-          pattern: _patten,
-          message: formRule.func.innerMessage
-        }, {
-          max: formRule.func.max,
-          message: formRule.func.maxMessage
-        }
-      ]
+      rules: rules
     },
     {
       type: 'datasource',
@@ -286,7 +289,7 @@
  * @param {object} card           // 鎼滅储鏉′欢瀵硅薄
  * @param {Array}  linkableFields // 鍙叧鑱斿瓧娈�
  */
-export function getSearchForm (card, linkableFields) {
+export function getSearchForm (card, linkableFields, columns, position) {
   let roleList = sessionStorage.getItem('sysRoles')
   let appType = sessionStorage.getItem('appType')
   if (roleList) {
@@ -318,7 +321,7 @@
       text: '閫夐」鍗�'
     }, {
       value: 'date',
-      text: Formdict['model.form.dateday']
+      text: '鏃ユ湡锛堝ぉ锛�'
     }, {
       value: 'datemonth',
       text: Formdict['model.form.datemonth']
@@ -345,10 +348,10 @@
       text: '閫夐」鍗�'
     }, {
       value: 'date',
-      text: Formdict['model.form.dateday']
+      text: '鏃ユ湡锛堝ぉ锛�'
     }, {
       value: 'dateweek',
-      text: Formdict['model.form.dateweek']
+      text: '鏃ユ湡锛堝懆锛�'
     }, {
       value: 'datemonth',
       text: Formdict['model.form.datemonth']
@@ -396,7 +399,8 @@
       key: 'field',
       label: Formdict['model.form.field'],
       initVal: card.field || '',
-      required: true
+      required: true,
+      options: columns
     },
     {
       type: 'select',
@@ -460,6 +464,9 @@
       }, {
         value: 'picture',
         text: '鍥剧墖'
+      }, {
+        value: 'color',
+        text: '鑹插潡'
       }]
     },
     {
@@ -786,8 +793,8 @@
       key: 'advanced',
       label: '楂樼骇鎼滅储',
       initVal: card.advanced || 'false',
-      tooltip: '鍦ㄩ殣钘忔悳绱㈡寜閽椂锛岄珮绾ф悳绱㈡棤鏁堛��',
-      forbid: appType === 'mob',
+      tooltip: '鍦ㄩ珮绾ф悳绱互妯℃�佹鎴栨娊灞夊睍寮�鏃讹紝鎼滅储鏉′欢鍦ㄥ紑鍙戠晫闈㈠崰姣斾负6锛屽疄闄呮晥鏋滆鍦ㄨ繍琛屾椂鏌ョ湅銆�',
+      forbid: appType === 'mob' || position === 'header',
       options: [{
         value: 'true',
         text: Formdict['model.true']
@@ -826,19 +833,29 @@
       }]
     },
     {
+      type: 'radio',
+      key: 'selectStyle',
+      label: '閫変腑鏁堟灉',
+      tooltip: '鑳屾櫙鍙婃枃瀛楀彉鍖栨椂浼氫娇鐢ㄧ郴缁熻壊銆�',
+      initVal: card.selectStyle || (card.backgroundColor ? 'custom' : 'background'),
+      options: [{
+        value: 'background',
+        text: '鑳屾櫙鍙樺寲'
+      }, {
+        value: 'font',
+        text: '鏂囧瓧鍙樺寲'
+      }, {
+        value: 'custom',
+        text: '鑷畾涔�'
+      }]
+    },
+    {
       type: 'color',
       key: 'backgroundColor',
       label: '鑳屾櫙鑹�',
       initVal: card.backgroundColor || '',
       tooltip: '璁剧疆鑳屾櫙鑹插悗锛岄�変腑鏁堟灉鐢辫儗鏅鑹叉帶鍒躲��',
-      required: false
-    },
-    {
-      type: 'color',
-      key: 'borderColor',
-      label: '杈规棰滆壊',
-      initVal: card.borderColor || '',
-      required: false
+      required: true
     },
     {
       type: 'multiselect',
@@ -846,7 +863,8 @@
       label: Formdict['header.form.blacklist'],
       initVal: card.blacklist || [],
       required: false,
-      options: roleList || []
+      options: roleList || [],
+      forbid: appType === 'mob'
     }
   ]
 }
@@ -956,6 +974,9 @@
       }, {
         value: 'megvii',
         text: '鏃疯闈㈡澘鏈�'
+      }, {
+        value: 'filezip',
+        text: '鏂囦欢鍘嬬缉鍖�'
       }]
     },
     { // 鏃疯闈㈡澘鏈烘帴鍙� 寰呮墿灞�
@@ -1035,9 +1056,18 @@
       key: 'innerFunc',
       label: Formdict['header.form.innerFunc'],
       initVal: card.innerFunc || '',
-      tooltip: `鍑芥暟鍚嶇О闇�浠�${usefulFields.join(', ')}绛夊瓧绗﹀紑濮嬨�俙,
+      tooltip: usefulFields.length ? `鍑芥暟鍚嶇О闇�浠�${usefulFields.join(', ')}绛夊瓧绗﹀紑濮嬨�俙 : '',
       fields: usefulFields,
       required: card.intertype === 'inner',
+      readonly: false
+    },
+    {
+      type: 'text',
+      key: 'urlkey',
+      label: '鍦板潃瀛楁',
+      initVal: card.urlkey || '',
+      tooltip: '鍥剧墖锛堟枃浠讹級閾炬帴鐨勫瓧娈靛悕銆�',
+      required: false,
       readonly: false
     },
     {
@@ -1322,7 +1352,7 @@
       type: 'text',
       key: 'output',
       label: '杩斿洖鍊�',
-      tooltip: '鎵ц鎴愬姛鍚庣殑杩斿洖鍊笺�備緥濡傦細@id',
+      tooltip: '鎵ц鎴愬姛鍚庣殑杩斿洖鍊笺�傜郴缁熷嚱鏁板彲鎸囧畾杩斿洖鐨勫彉閲忥紙浠绗﹀紑澶达紝濡侤id锛夛紱鑷畾涔夊嚱鏁板彲鎸囧畾杩斿洖瀛楁锛堝id锛夈��',
       initVal: card.output || '',
       required: false
     },
@@ -1447,7 +1477,7 @@
       key: 'preFunc',
       label: '鍓嶇疆鍑芥暟',
       initVal: card.preFunc || '',
-      tooltip: `鍑芥暟鍚嶇О闇�浠�${usefulFields.join(', ')}绛夊瓧绗﹀紑濮嬶紱鍓嶇疆鍑芥暟鎵ц瀹屾垚鍚庯紝缁撴灉浼氫紶鍏ュ唴閮ㄥ嚱鏁颁腑锛屾鏃跺唴閮ㄥ嚱鏁颁細寮傛鎵ц锛涘綋鍓嶇疆鍑芥暟杩斿洖涓璄rrCode绛変簬-1鏃讹紝灏嗕笉鍐嶆墽琛屽唴閮ㄥ嚱鏁般�俙,
+      tooltip: usefulFields.length ? `鍑芥暟鍚嶇О闇�浠�${usefulFields.join(', ')}绛夊瓧绗﹀紑濮嬶紱鍓嶇疆鍑芥暟鎵ц瀹屾垚鍚庯紝缁撴灉浼氫紶鍏ュ唴閮ㄥ嚱鏁颁腑锛屾鏃跺唴閮ㄥ嚱鏁颁細寮傛鎵ц锛涘綋鍓嶇疆鍑芥暟杩斿洖涓璄rrCode绛変簬-1鏃讹紝灏嗕笉鍐嶆墽琛屽唴閮ㄥ嚱鏁般�俙 : '',
       fields: usefulFields,
       required: false,
       readonly: false
@@ -1506,6 +1536,20 @@
       }, {
         value: 'true',
         text: '鏄�'
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'progress',
+      label: '杩涘害鎻愮ず',
+      initVal: card.progress || 'number',
+      required: false,
+      options: [{
+        value: 'number',
+        text: '鍓╀綑鏁�'
+      }, {
+        value: 'progressbar',
+        text: '杩涘害鏉�'
       }]
     }
   ]
@@ -2337,10 +2381,10 @@
     text: '閫夐」鍗�'
   }, {
     value: 'fileupload',
-    text: Formdict['header.form.fileupload']
+    text: '鏂囦欢涓婁紶'
   }, {
     value: 'date',
-    text: Formdict['model.form.dateday']
+    text: '鏃ユ湡锛堝ぉ锛�'
   }, {
     value: 'datemonth',
     text: Formdict['model.form.datemonth']
@@ -2350,6 +2394,9 @@
   }, {
     value: 'textarea',
     text: Formdict['model.form.textarea']
+  }, {
+    value: 'cascader',
+    text: '绾ц仈鑿滃崟'
   }, {
     value: 'rate',
     text: '璇勫垎'
@@ -2371,6 +2418,9 @@
   }, {
     value: 'linkMain',
     text: '鍏宠仈涓昏〃'
+  }, {
+    value: 'formula',
+    text: '鍏紡'
   }]
 
   let _fieldlength = 50
@@ -2402,10 +2452,10 @@
       text: '閫夐」鍗�'
     }, {
       value: 'fileupload',
-      text: Formdict['header.form.fileupload']
+      text: '鏂囦欢涓婁紶'
     }, {
       value: 'date',
-      text: Formdict['model.form.dateday']
+      text: '鏃ユ湡锛堝ぉ锛�'
     }, {
       value: 'datemonth',
       text: Formdict['model.form.datemonth']
@@ -2415,6 +2465,9 @@
     }, {
       value: 'textarea',
       text: Formdict['model.form.textarea']
+    }, {
+      value: 'cascader',
+      text: '绾ц仈鑿滃崟'
     }, {
       value: 'rate',
       text: '璇勫垎'
@@ -2430,6 +2483,9 @@
     }, {
       value: 'linkMain',
       text: '鍏宠仈涓昏〃'
+    }, {
+      value: 'formula',
+      text: '鍏紡'
     }]
   }
 
@@ -2539,10 +2595,10 @@
       required: true,
       options: [{
         value: '0',
-        text: Formdict['header.form.custom']
+        text: '鑷畾涔�'
       }, {
         value: '1',
-        text: Formdict['header.form.datasource']
+        text: '鏁版嵁婧�'
       }]
     },
     {
@@ -2557,6 +2613,9 @@
       }, {
         value: 'picture',
         text: '鍥剧墖'
+      }, {
+        value: 'color',
+        text: '鑹插潡'
       }]
     },
     {
@@ -2588,9 +2647,9 @@
     },
     {
       type: 'radio',
-      key: 'ratio',
+      key: 'picratio',
       label: '鍥剧墖姣斾緥',
-      initVal: card.ratio || '1:1',
+      initVal: card.picratio || card.ratio || '1:1',
       required: true,
       options: [{
         value: '1:1',
@@ -2669,6 +2728,14 @@
     },
     {
       type: 'text',
+      key: 'topmark',
+      label: '椤剁骇鏍囪瘑',
+      initVal: card.topmark || '',
+      tooltip: '鍏宠仈瀛楁鍊间笌椤剁骇鏍囪瘑鐩稿悓鏃讹紝瑙嗕负椤剁骇鑺傜偣銆�',
+      required: false
+    },
+    {
+      type: 'text',
       key: 'valueField',
       label: '鍊悸峰瓧娈�',
       initVal: card.valueField || '',
@@ -2712,16 +2779,6 @@
       tooltip: '璁剧疆绂佺敤瀛楁锛屼笖瀛楁鍊间负true鏃讹紝閫夐」涓嶅彲閫夈��',
       required: false,
       readonly: false
-    },
-    {
-      type: 'number',
-      key: 'decimal',
-      min: 0,
-      max: 18,
-      precision: 0,
-      label: Formdict['header.form.decimal'],
-      initVal: card.decimal || 0,
-      required: true
     },
     {
       type: 'number',
@@ -2857,6 +2914,53 @@
       }]
     },
     {
+      type: 'radio',
+      key: 'declareType',
+      label: '鏁版嵁绫诲瀷',
+      tooltip: '澹版槑鍙橀噺鏃剁殑绫诲瀷锛屾椂闂存牸寮廳atetime鎴栨枃鏈牸寮弉varchar(50)銆�',
+      initVal: card.declareType || 'datetime',
+      options: [{
+        value: 'datetime',
+        text: 'datetime'
+      }, {
+        value: 'nvarchar(50)',
+        text: 'nvarchar(50)'
+      }]
+    },
+    {
+      type: 'text',
+      key: 'separator',
+      label: '杩炴帴绗�',
+      initVal: card.separator || card.separator === undefined ? '/' : '',
+      tooltip: '琛ㄥ崟鎻愪氦鏃朵俊鎭箣闂寸殑杩炴帴绗︺�傛敞锛氳繛鎺ョ涓虹┖鏃讹紝鍒濆鍖栨椂濉厖鍏朵粬琛ㄥ崟鏃犳晥銆�',
+      required: false,
+      readonly: false
+    },
+    {
+      type: 'radio',
+      key: 'declare',
+      label: '鏁版嵁绫诲瀷',
+      initVal: card.declare || 'nvarchar',
+      tooltip: '澹版槑鍙橀噺鏃剁殑绫诲瀷銆備娇鐢� decimal 鏃讹紝璇风‘璁alue涓烘暟鍊硷紝涓斾笉鍙负绌恒��',
+      options: [{
+        value: 'nvarchar',
+        text: 'nvarchar'
+      }, {
+        value: 'decimal',
+        text: 'decimal'
+      }]
+    },
+    {
+      type: 'number',
+      key: 'decimal',
+      min: 0,
+      max: 18,
+      precision: 0,
+      label: Formdict['header.form.decimal'],
+      initVal: card.decimal || 0,
+      required: true
+    },
+    {
       type: 'number',
       key: 'fieldlength',
       min: 1,
@@ -2885,19 +2989,22 @@
       initVal: card.regular || '',
       options: [{
         value: '',
-        text: Formdict['model.empty']
+        text: '绌�'
       }, {
         value: 'number',
-        text: Formdict['model.form.number']
+        text: '鏁板瓧'
       }, {
         value: 'letter',
-        text: Formdict['header.form.letter']
+        text: '瀛楁瘝'
       }, {
         value: 'letter&number',
-        text: '瀛楁瘝+鏁板瓧'
+        text: '鏁板瓧銆佸瓧姣嶄互鍙奯@_.'
       }, {
         value: 'phone',
         text: '鎵嬫満鍙�'
+      }, {
+        value: 'email',
+        text: '閭'
       }]
     },
     {
@@ -3117,33 +3224,29 @@
       }]
     },
     {
+      type: 'radio',
+      key: 'selectStyle',
+      label: '閫変腑鏁堟灉',
+      tooltip: '鑳屾櫙鍙婃枃瀛楀彉鍖栨椂浼氫娇鐢ㄧ郴缁熻壊銆�',
+      initVal: card.selectStyle || (card.backgroundColor ? 'custom' : 'background'),
+      options: [{
+        value: 'background',
+        text: '鑳屾櫙鍙樺寲'
+      }, {
+        value: 'font',
+        text: '鏂囧瓧鍙樺寲'
+      }, {
+        value: 'custom',
+        text: '鑷畾涔�'
+      }]
+    },
+    {
       type: 'color',
       key: 'backgroundColor',
       label: '鑳屾櫙鑹�',
       initVal: card.backgroundColor || '',
       tooltip: '璁剧疆鑳屾櫙鑹插悗锛岄�変腑鏁堟灉鐢辫儗鏅鑹叉帶鍒躲��',
-      required: false
-    },
-    {
-      type: 'color',
-      key: 'borderColor',
-      label: '杈规棰滆壊',
-      initVal: card.borderColor || '',
-      required: false
-    },
-    {
-      type: 'radio',
-      key: 'declareType',
-      label: '鏁版嵁绫诲瀷',
-      tooltip: '澹版槑鍙橀噺鏃剁殑绫诲瀷锛屾椂闂存牸寮廳atetime鎴栨枃鏈牸寮弉varchar(50)銆�',
-      initVal: card.declareType || 'datetime',
-      options: [{
-        value: 'datetime',
-        text: 'datetime'
-      }, {
-        value: 'nvarchar(50)',
-        text: 'nvarchar(50)'
-      }]
+      required: true
     },
     // {
     //   type: 'radio',
@@ -3185,6 +3288,37 @@
         value: 'false',
         text: Formdict['model.false']
       }]
+    },
+    {
+      type: 'textarea',
+      key: 'formula',
+      label: '鍏紡',
+      initVal: card.formula || '',
+      tooltip: '鍔ㄦ�佹浛鎹㈢浉搴旂殑瀛楁锛屽睍绀鸿幏寰楃殑缁撴灉銆傚彲浣跨敤JS鐨勪竴浜涜娉曪紝濡傦細涓夊厓琛ㄨ揪寮� @field1@ > @field2@ ? 0 : 1锛汳ath瀵硅薄锛屽彇缁濆鍊� Math.abs(@field@)銆佸洓鑸嶄簲鍏� Math.round(@field@)绛�',
+      rows: 2,
+      required: true
+    },
+    {
+      type: 'radio',
+      key: 'eval',
+      label: '瑙f瀽',
+      initVal: card.eval || 'true',
+      tooltip: '褰撳叕寮忓唴瀹规秹鍙婅绠楁椂璇烽�夋嫨鈥滄槸鈥濓紝褰撳叕寮忓唴瀹逛负瀛楁鎷兼帴鏃惰閫夋嫨鈥滃惁鈥濄��',
+      required: false,
+      options: [{
+        value: 'true',
+        text: '鏄�'
+      }, {
+        value: 'false',
+        text: '鍚�'
+      }]
+    },
+    {
+      type: 'text',
+      key: 'postfix',
+      label: '鍚庣紑',
+      initVal: card.postfix || '',
+      required: false
     },
     {
       type: 'radio',
@@ -3456,35 +3590,36 @@
       initVal: card.linkSubField || [],
       options: inputfields
     },
-    {
-      type: 'number',
-      key: 'marginTop',
-      label: '涓婅竟璺濓紙px锛�',
-      initVal: card.marginTop || 0,
-      min: -100,
-      max: 1000,
-      precision: 0,
-      required: false,
-      forbid: appType !== 'mob'
-    },
-    {
-      type: 'number',
-      key: 'marginBottom',
-      label: '涓嬭竟璺濓紙px锛�',
-      initVal: card.marginBottom || 0,
-      min: -100,
-      max: 1000,
-      precision: 0,
-      required: false,
-      forbid: appType !== 'mob'
-    },
+    // {
+    //   type: 'number',
+    //   key: 'marginTop',
+    //   label: '涓婅竟璺濓紙px锛�',
+    //   initVal: card.marginTop || 0,
+    //   min: -100,
+    //   max: 1000,
+    //   precision: 0,
+    //   required: false,
+    //   forbid: appType !== 'mob'
+    // },
+    // {
+    //   type: 'number',
+    //   key: 'marginBottom',
+    //   label: '涓嬭竟璺濓紙px锛�',
+    //   initVal: card.marginBottom || 0,
+    //   min: -100,
+    //   max: 1000,
+    //   precision: 0,
+    //   required: false,
+    //   forbid: appType !== 'mob'
+    // },
     {
       type: 'multiselect',
       key: 'blacklist',
       label: Formdict['header.form.blacklist'],
       initVal: card.blacklist || [],
       required: false,
-      options: roleList
+      options: roleList,
+      forbid: appType === 'mob'
     }
   ]
 }
diff --git a/src/templates/zshare/modalform/datatable/index.jsx b/src/templates/zshare/modalform/datatable/index.jsx
index ec8b5a1..31e23ed 100644
--- a/src/templates/zshare/modalform/datatable/index.jsx
+++ b/src/templates/zshare/modalform/datatable/index.jsx
@@ -6,9 +6,11 @@
 import { PlusOutlined, EditOutlined, DeleteOutlined, SwapOutlined } from '@ant-design/icons'
 
 import Utils from '@/utils/utils.js'
-import FileUpload from '@/tabviews/zshare/fileupload'
+import asyncComponent from '@/utils/asyncComponent'
+// import FileUpload from '@/tabviews/zshare/fileupload'
 import './index.scss'
 
+const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent'))
 const EditableContext = React.createContext()
 let dragingIndex = -1
 
@@ -73,12 +75,13 @@
   getInput = (form) => {
     const { inputType, record } = this.props
     if (inputType === 'file') {
-      return <FileUpload config={{
-        initval: record ? (record.$url || '') : '',
-        suffix: '',
-        maxfile: 1,
-        fileType: 'picture-card'
-      }}/>
+      return <SourceComponent initialValue={record ? (record.$url || '') : ''} type="" placement="right"/>
+      // return <FileUpload config={{
+      //   initval: record ? (record.$url || '') : '',
+      //   suffix: '',
+      //   maxfile: 1,
+      //   fileType: 'picture-card'
+      // }}/>
     } else {
       return <Input onPressEnter={() => this.getValue(form)} />
     }
@@ -199,16 +202,16 @@
           return <span style={{display: 'block', width: '70px', height: '70px'}}><img style={{width: '100%', height: '100%'}} src={text} alt="" /></span>
         }
       })
-    } else {
-      columns = fields.map(item => {
-        keys.push(item.field)
-        return {
-          title: item.field,
-          dataIndex: item.field,
-          editable: true,
-        }
-      })
     }
+
+    fields.forEach(item => {
+      keys.push(item.field)
+      columns.push({
+        title: item.field,
+        dataIndex: item.field,
+        editable: true,
+      })
+    })
 
     if (linkSubFields.length > 0) {
       linkSubFields.forEach(m => {
@@ -369,11 +372,11 @@
 
     if (display === 'picture') {
       item.$url = ''
-    } else {
-      fields.forEach(f => {
-        item[f.field] = `${this.state.data.length + 1}`
-      })
     }
+
+    fields.forEach(f => {
+      item[f.field] = `${this.state.data.length + 1}`
+    })
 
     let data = [...this.state.data, item]
 
@@ -441,7 +444,7 @@
     })
 
     let addable = false
-    if (this.props.display === 'picture') {
+    if (this.props.display === 'picture' || this.props.display === 'color') {
       addable = true
     } else if (this.props.fields && this.props.fields.length > 0) {
       addable = true
diff --git a/src/templates/zshare/modalform/datatable/index.scss b/src/templates/zshare/modalform/datatable/index.scss
index fbd1e54..ac76a17 100644
--- a/src/templates/zshare/modalform/datatable/index.scss
+++ b/src/templates/zshare/modalform/datatable/index.scss
@@ -19,6 +19,7 @@
     }
     > td {
       padding: 13px 10px;
+      word-break: break-all;
     }
     .fileupload-form-container .ant-upload-list-picture-card .ant-upload-list-item {
       margin: 0;
@@ -76,4 +77,12 @@
   tr.drop-over-upward td {
     border-top: 2px dashed #1890ff;
   }
+  .mk-source-wrap {
+    .ant-radio-button-wrapper + .ant-radio-button-wrapper {
+      border-radius: 0 4px 4px 0;
+    }
+    .ant-radio-button-wrapper:last-child {
+      display: none;
+    }
+  }
 }
diff --git a/src/templates/zshare/modalform/fieldtable/index.jsx b/src/templates/zshare/modalform/fieldtable/index.jsx
index 0a64952..d9100da 100644
--- a/src/templates/zshare/modalform/fieldtable/index.jsx
+++ b/src/templates/zshare/modalform/fieldtable/index.jsx
@@ -11,7 +11,6 @@
 
 class EdiFieldsTable extends Component {
   static propTpyes = {
-    dict: PropTypes.object,         // 瀛楀吀椤�
     onChange: PropTypes.func        // 鏁版嵁鍙樺寲
   }
 
@@ -63,11 +62,20 @@
         editable: true,
         width: '20%',
         options: [
-          {value: 'left', text: 'left'},
-          {value: 'center', text: 'center'},
-          {value: 'right', text: 'right'},
-          {value: 'justify', text: 'justify'}
-        ]
+          {value: 'left', text: '灞呭乏'},
+          {value: 'center', text: '灞呬腑'},
+          {value: 'right', text: '灞呭彸'},
+          // {value: 'justify', text: 'justify'}
+        ],
+        render: (text, record) => {
+          if (text === 'center') {
+            return '灞呬腑'
+          } else if (text === 'right') {
+            return '灞呭彸'
+          } else {
+            return '灞呭乏'
+          }
+        }
       }
     ]
   }
@@ -109,6 +117,16 @@
         this.setState({loading: false})
       })
       return
+    } else if (fields.filter(f => f.toLowerCase() === 'value').length > 0) {
+      notification.warning({
+        top: 92,
+        message: '瀛楁鍚嶄笉鍙娇鐢╲alue锛�',
+        duration: 5
+      })
+      this.setState({loading: true}, () => {
+        this.setState({loading: false})
+      })
+      return
     }
 
     this.setState({ data }, () => {
@@ -121,7 +139,7 @@
 
     return (
       <div className="modal-card-field-table">
-        {data.length < 3 ? <PlusOutlined className="add-row" onClick={this.handleAdd} /> : null}
+        {data.length < 6 ? <PlusOutlined className="add-row" onClick={this.handleAdd} /> : null}
         {!loading ? <EditTable indexShow={false} actions={['edit', 'move', 'del']} data={data} columns={columns} onChange={this.changeData}/> : null}
       </div>
     )
diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx
index 0fca860..da963fa 100644
--- a/src/templates/zshare/modalform/index.jsx
+++ b/src/templates/zshare/modalform/index.jsx
@@ -21,22 +21,24 @@
 const modalTypeOptions = {
   text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'scan', 'splitline', 'placeholder', 'place', 'marginTop', 'marginBottom', 'lenControl'],
   number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'enter', 'cursor', 'splitline', 'place', 'marginTop', 'marginBottom'],
-  select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom'],
+  select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'setAll', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom'],
   checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'arrange', 'marginTop', 'marginBottom'],
-  radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'setAll', 'emptyText', 'splitline', 'arrange', 'marginTop', 'marginBottom'],
-  checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'display', 'tooltip', 'extra', 'width', 'multiple', 'splitline', 'marginTop', 'marginBottom'],
+  radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'setAll', 'emptyText', 'splitline', 'arrange', 'marginTop', 'marginBottom'],
+  checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'span', 'labelwidth', 'display', 'tooltip', 'extra', 'width', 'multiple', 'splitline', 'marginTop', 'marginBottom'],
   multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'marginTop', 'marginBottom'],
-  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom'],
+  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'declare', 'setAll', 'linkField', 'linkSubField', 'span', 'labelwidth', 'tooltip', 'extra', 'emptyText', 'enter', 'splitline', 'dropdown', 'marginTop', 'marginBottom'],
   fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'span', 'labelwidth', 'tooltip', 'extra', 'compress', 'splitline', 'marginTop', 'marginBottom'],
   switch: ['initval', 'openVal', 'closeVal', 'openText', 'closeText', 'readonly', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'marginTop', 'marginBottom'],
   date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'mode', 'splitline', 'marginTop', 'marginBottom', 'minDate', 'maxDate', 'precision'],
   datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'splitline', 'marginTop', 'marginBottom'],
   datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'declareType', 'mode', 'splitline', 'marginTop', 'marginBottom', 'minDate', 'maxDate'],
   textarea: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'span', 'labelwidth', 'maxRows', 'encryption', 'interception', 'tooltip', 'extra', 'count', 'placeholder', 'marginTop', 'marginBottom', 'enterReplace'],
+  cascader: ['readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'splitline', 'marginTop', 'marginBottom', 'separator'],
   color: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'tooltip', 'extra', 'marginTop', 'marginBottom'],
   rate: ['initval', 'readonly', 'required', 'hidden', 'readin', 'span', 'labelwidth', 'splitline', 'tooltip', 'extra', 'marginTop', 'marginBottom', 'allowHalf', 'rateCount', 'character', 'place'],
   hint: ['label', 'field', 'type', 'blacklist', 'message', 'span', 'labelwidth', 'splitline', 'marginTop', 'marginBottom'],
   split: ['label', 'type', 'marginTop', 'marginBottom', 'splitline'],
+  formula: ['label', 'type', 'marginTop', 'marginBottom', 'splitline', 'span', 'labelwidth', 'formula', 'eval', 'postfix'],
   brafteditor: ['required', 'hidelabel', 'hidden', 'readin', 'fieldlength', 'readonly', 'span', 'labelwidth', 'tooltip', 'extra', 'encryption', 'marginTop', 'marginBottom'],
   funcvar: ['span', 'labelwidth', 'splitline', 'marginTop', 'marginBottom'],
   linkMain: ['readonly', 'required', 'hidden', 'fieldlength', 'span', 'labelwidth', 'tooltip', 'extra', 'marginTop', 'marginBottom']
@@ -119,7 +121,7 @@
 
     reRequired.field = true
 
-    if (type === 'hint' || type === 'split') {
+    if (['hint', 'split', 'formula'].includes(type)) {
       reRequired.field = false
       shows = fromJS(modalTypeOptions[type]).toJS()
     }
@@ -161,24 +163,48 @@
         shows.push('linkField')
         reRequired.linkField = false
       }
+      if (['select', 'link', 'radio'].includes(type)) {
+        if (this.record.declare === 'nvarchar') {
+          shows.push('fieldlength')
+        } else if (this.record.declare === 'decimal') {
+          shows.push('decimal')
+        }
+      }
     } else if (type === 'checkcard') {
+      reRequired.fields = false
       if (this.record.display === 'picture') {
         if (this.record.resourceType === '0') {        // 鑷畾涔夎祫婧�
-          shows.push('options', 'ratio')
+          shows.push('options', 'fields', 'picratio')
         } else if (this.record.resourceType === '1') { // 鏁版嵁婧�
-          shows.push('dataSource', 'cardValField', 'urlField', 'orderBy', 'orderType', 'disableField', 'database', 'ratio')
+          shows.push('dataSource', 'cardValField', 'fields', 'urlField', 'orderBy', 'orderType', 'disableField', 'database', 'picratio')
+        }
+      } else if (this.record.display === 'color') {
+        if (this.record.resourceType === '0') {        // 鑷畾涔夎祫婧�
+          shows.push('options', 'fields')
+        } else if (this.record.resourceType === '1') { // 鏁版嵁婧�
+          shows.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'database')
         }
       } else {
+        reRequired.fields = true
         if (this.record.resourceType === '0') {        // 鑷畾涔夎祫婧�
-          shows.push('options', 'fields', 'backgroundColor', 'borderColor')
+          shows.push('options', 'fields', 'selectStyle')
         } else if (this.record.resourceType === '1') { // 鏁版嵁婧�
-          shows.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'disableField', 'database', 'backgroundColor', 'borderColor')
+          shows.push('dataSource', 'cardValField', 'fields', 'orderBy', 'orderType', 'disableField', 'database', 'selectStyle')
+        }
+        if (this.record.selectStyle === 'custom') {
+          shows.push('backgroundColor')
         }
       }
 
       if (this.record.multiple === 'false') {
-        shows.push('linkSubField')
+        shows.push('linkSubField', 'declare')
+        if (this.record.declare === 'nvarchar') {
+          shows.push('fieldlength')
+        } else if (this.record.declare === 'decimal') {
+          shows.push('decimal')
+        }
       } else {
+        shows.push('fieldlength')
         reTooltip.initval = '娣诲姞澶氫釜鍒濆鍊艰浣跨敤閫楀彿鍒嗛殧銆�'
       }
 
@@ -209,13 +235,43 @@
       }
     }
 
+    if (type === 'cascader') {
+      if (this.record.resourceType === '0') {        // 鑷畾涔夎祫婧�
+        shows.push('options', 'topmark', 'linkSubField')
+      } else if (this.record.resourceType === '1') { // 鏁版嵁婧�
+        shows.push('dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'disableField', 'database', 'topmark', 'linkField', 'linkSubField')
+      }
+      reTypes.linkField = 'text'
+      reTooltip.linkField = '鐢ㄤ簬鏋勫缓鏁版嵁缁撴瀯銆�'
+      reOptions.resourceType = [{
+        value: '0',
+        text: '鑷畾涔�'
+      }, {
+        value: '1',
+        text: '鏁版嵁婧�'
+      }, {
+        value: '2',
+        text: '鐪佸競鍖�'
+      }]
+    } else {
+      reTooltip.linkField = ''
+      reTypes.linkField = 'select'
+      reOptions.resourceType = [{
+        value: '0',
+        text: '鑷畾涔�'
+      }, {
+        value: '1',
+        text: '鏁版嵁婧�'
+      }]
+    }
+
     if (['multiselect', 'checkbox'].includes(type)) {
       reTooltip.initval = '娣诲姞澶氫釜鍒濆鍊艰浣跨敤閫楀彿鍒嗛殧銆�'
     } else if (['select', 'link', 'radio'].includes(type)) {
       reTooltip.initval = '浣跨敤$first琛ㄧず榛樿閫夋嫨绗竴椤广��'
     }
 
-    if (this.record.supField) {
+    if (this.record.supField && !['hint', 'split', 'formula'].includes(type)) {
       shows.push('supvalue')
     }
 
@@ -274,6 +330,16 @@
       if (value === 'linkMain') {
         this.record.hidden = 'true'
         _fieldval.hidden = 'true'
+      }
+      
+      if (this.record.type === 'cascader' && value !== 'cascader') {
+        this.record.linkField = ''
+        _fieldval.linkField = ''
+
+        if (this.record.resourceType === '2') {
+          this.record.resourceType = '0'
+          _fieldval.resourceType = '0'
+        }
       }
 
       if (this.record.options.length > 0) {
@@ -468,7 +534,11 @@
 
       if (item.type === 'text') {
         rules = [
-          { required: item.required, message: dict['form.required.input'] + item.label + '!' }
+          { required: item.required, message: dict['form.required.input'] + item.label + '!' },
+          {
+            pattern: /^[^']*$/ig,
+            message: '涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙凤紒'
+          }
         ]
         if (item.key === 'field') {
           rules.push({
@@ -536,7 +606,7 @@
         ]
         initVal = item.initVal
 
-        content = <Radio.Group onChange={(e) => {this.optionChange(item.key, e.target.value)}}>
+        content = <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => {this.optionChange(item.key, e.target.value)}}>
           {item.options.map(option => {
             return (
               <Radio key={option.value} value={option.value}>{option.text}</Radio>
@@ -571,11 +641,16 @@
         let linkSubFields = this.record.linkSubField || []
         
         if (type !== 'checkcard') {
-          if (!['select', 'radio', 'link'].includes(type)) {
+          if (!['select', 'radio', 'link', 'cascader'].includes(type)) {
             linkSubFields = []
           }
           if (type === 'radio' && this.record.linkField) {
             type = 'link'
+          } else if (type === 'cascader') {
+            type = 'link'
+            if (this.record.resourceType === '2') {        // 鑷畾涔夎祫婧�
+              linkSubFields = []
+            }
           }
           content = <EditTable type={type} module="form" transfield={transfield} linkSubFields={linkSubFields} onChange={this.changeOptions}/>
         } else {
@@ -590,10 +665,16 @@
       } else if (item.type === 'fields') {
         span = 24
         className = 'text-area'
+        rules = [
+          { required: item.required, message: '璇锋坊鍔�' + item.label + '!' }
+        ]
 
-        content = <FieldsTable dict={this.props.dict} onChange={this.changeField}/>
+        content = <FieldsTable onChange={this.changeField}/>
       } else if (item.type === 'color') {
         className = 'color-form-item'
+        rules = [
+          { required: item.required, message: dict['form.required.select'] + item.label + '!' }
+        ]
 
         content = <ColorSketch allowClear={true}/>
       } else if (item.type === 'icon') {
diff --git a/src/templates/zshare/modalform/index.scss b/src/templates/zshare/modalform/index.scss
index 6df9194..f2c7018 100644
--- a/src/templates/zshare/modalform/index.scss
+++ b/src/templates/zshare/modalform/index.scss
@@ -27,6 +27,7 @@
     white-space: nowrap;
   }
   .color-form-item {
+    margin-bottom: 24px;
     .ant-form-item-control {
       height: 40px;
       .color-sketch-block {
diff --git a/src/templates/zshare/pasteform/index.jsx b/src/templates/zshare/pasteform/index.jsx
index 6b5cd34..2facaa2 100644
--- a/src/templates/zshare/pasteform/index.jsx
+++ b/src/templates/zshare/pasteform/index.jsx
@@ -26,7 +26,17 @@
     return new Promise((resolve, reject) => {
       this.props.form.validateFieldsAndScroll((err, values) => {
         if (!err) {
-          let _config = values.config
+          let _config = values.config.replace(/(\n|\s)+/g, '')
+
+          if (!_config) {
+            notification.warning({
+              top: 92,
+              message: '璇疯緭鍏ラ厤缃俊鎭�',
+              duration: 5
+            })
+            reject()
+            return
+          }
           try {
             _config = JSON.parse(window.decodeURIComponent(window.atob(_config)))
 
@@ -63,6 +73,14 @@
     })
   }
 
+  enterPress = (e) => {
+    e.stopPropagation()
+
+    setTimeout(() => {
+      this.props.inputSubmit && this.props.inputSubmit()
+    }, 200)
+  }
+
   render() {
     const { getFieldDecorator } = this.props.form
     const formItemLayout = {
@@ -88,7 +106,7 @@
                     message: '璇疯緭鍏ラ厤缃俊鎭�!'
                   }
                 ]
-              })(<TextArea autoSize={{ minRows: 6, maxRows: 6 }}/>)}
+              })(<TextArea autoSize={{ minRows: 6, maxRows: 6 }} onPressEnter={this.enterPress}/>)}
             </Form.Item>
           </Col>
         </Row>
diff --git a/src/templates/zshare/verifycard/baseform/index.jsx b/src/templates/zshare/verifycard/baseform/index.jsx
new file mode 100644
index 0000000..5159200
--- /dev/null
+++ b/src/templates/zshare/verifycard/baseform/index.jsx
@@ -0,0 +1,371 @@
+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 { QuestionCircleOutlined } from '@ant-design/icons'
+
+import asyncComponent from '@/utils/asyncComponent'
+import './index.scss'
+
+const ColorSketch = asyncComponent(() => import('@/mob/colorsketch'))
+
+class BillCodeForm extends Component {
+  static propTpyes = {
+    card: PropTypes.object,
+    verify: PropTypes.object,
+    unionFields: PropTypes.array,
+    notes: PropTypes.array,
+    onChange: PropTypes.func
+  }
+
+  state = {
+    wxTemps: [],
+    miniTemps: [],
+  }
+
+  componentDidMount() {
+    let wxTemps = sessionStorage.getItem('wxTemplates')
+    let miniTemps = sessionStorage.getItem('wxMiniTemplates')
+
+    wxTemps = wxTemps ? JSON.parse(wxTemps) : []
+    miniTemps = miniTemps ? JSON.parse(miniTemps) : []
+
+    this.setState({wxTemps, miniTemps})
+  }
+
+  handleConfirm = () => {
+    const { verify } = this.props
+    
+    let error = ''
+    if (verify.noteEnable === 'true' && !verify.noteCode) { // 寮�鍚煭淇℃椂锛岄渶瑕佹ā鏉跨紪鐮�
+      error = '寮�鍚煭淇℃椂锛岄渶瑕侀�夋嫨鐭俊妯℃澘锛�'
+    } else if (verify.accountdate === 'true' && !verify.accountfield) {
+      error = '寮�鍚处鏈熸椂锛岄渶瑕侀�夋嫨楠岃瘉鍏徃锛�'
+    } else if (verify.wxNote === 'true') {
+      if (!verify.wxTemplateId) {
+        error = '寮�鍚叕浼楀彿娑堟伅鎺ㄩ�佹椂锛岄渶瑕侀�夋嫨娑堟伅妯℃澘锛�'
+      } else if (verify.wxNoteLink === 'url' && !verify.wxNoteLinkUrl) {
+        error = '璇峰~鍐欑綉鍧�锛�'
+      }
+
+    }
+
+    return error
+  }
+
+  onOptionChange = (value, key) => {
+    const { verify } = this.props
+
+    let _verify = {...verify, [key]: value}
+
+    if (_verify.noteEnable !== 'true') {
+      _verify.noteCode = ''
+    }
+    if (_verify.accountdate !== 'true') {
+      _verify.accountfield = ''
+      _verify.voucherdate = ''
+    }
+    if (_verify.wxNote !== 'true') {
+      _verify.wxTemplateId = ''
+      _verify.wxNoteLink = ''
+      _verify.wxNoteLinkUrl = ''
+      _verify.wxNoteLinkMenuId = ''
+      _verify.wxNoteCallback = 'false'
+      _verify.wxNoteKeys = null
+    }
+
+    this.props.onChange(_verify)
+  }
+
+  onNoteCodeChange = (val, option) => {
+    const { verify } = this.props
+
+    let _verify = {...verify, noteCode: val, noteId: option.props.id}
+
+    this.props.onChange(_verify)
+  }
+
+  onWxTemplateChange = (val, option) => {
+    const { verify } = this.props
+
+    let _verify = {...verify, wxTemplateId: val}
+
+    let keys = []
+    if (option.props.content) {
+      keys = option.props.content.match(/{{[a-zA-Z0-9]+\.DATA}}/g)
+      keys = keys.map(key => key.replace(/{{|\.DATA}}/g, ''))
+    }
+
+    let index = 1
+    _verify.wxNoteKeys = keys.map(key => {
+      let item = {
+        key: key,
+        color: '#000000',
+        readonly: false
+      }
+      if (key === 'first') {
+        item.value = 'first'
+        item.readonly = true
+      } else if (key === 'remark') {
+        item.value = 'remark'
+        item.readonly = true
+      } else {
+        item.value = 'p' + index
+        index++
+      }
+
+      return item
+    })
+
+    this.props.onChange(_verify)
+  }
+
+  onWxNoteKeyChange = (key, val) => {
+    let _verify = fromJS(this.props.verify).toJS()
+
+    _verify.wxNoteKeys = _verify.wxNoteKeys.map(m => {
+      if (m.key === key) {
+        m.value = val
+      }
+
+      return m
+    })
+
+    this.props.onChange(_verify)
+  }
+
+  onWxNoteColorChange = (key, val) => {
+    let _verify = fromJS(this.props.verify).toJS()
+
+    _verify.wxNoteKeys = _verify.wxNoteKeys.map(m => {
+      if (m.key === key) {
+        m.color = val
+      }
+
+      return m
+    })
+
+    this.props.onChange(_verify)
+  }
+
+  render() {
+    const { unionFields, verify, notes, card } = this.props
+    const { wxTemps } = this.state
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
+    return (
+      <Form {...formItemLayout}>
+        <Row gutter={24}>
+          {card.sqlType !== 'custom' && card.intertype !== 'inner' ? <Col span={8}>
+            <Form.Item label={
+              <Tooltip placement="bottomLeft" title={'榛樿sql鎵ц椤哄簭涓鸿嚜瀹氫箟鑴氭湰涔嬪墠'}>
+                <QuestionCircleOutlined className="mk-form-tip" />
+                榛樿sql
+              </Tooltip>
+            }>
+              <Radio.Group value={verify.default} onChange={(e) => {this.onOptionChange(e.target.value, 'default')}}>
+                <Radio value="true">鎵ц</Radio>
+                <Radio value="false">涓嶆墽琛�</Radio>
+              </Radio.Group>
+            </Form.Item>
+          </Col> : null}
+          {card.intertype !== 'inner' ? <Col span={8}>
+            <Form.Item label={'澶辨晥楠岃瘉'}>
+              <Radio.Group value={verify.invalid} onChange={(e) => {this.onOptionChange(e.target.value, 'invalid')}}>
+                <Radio value="true">寮�鍚�</Radio>
+                <Radio value="false">涓嶅紑鍚�</Radio>
+              </Radio.Group>
+            </Form.Item>
+          </Col> : null}
+          {card.intertype !== 'inner' ? <Col span={8}>
+            <Form.Item label={'璐︽湡楠岃瘉'}>
+              <Radio.Group value={verify.accountdate} onChange={(e) => {this.onOptionChange(e.target.value, 'accountdate')}}>
+                <Radio value="true">寮�鍚�</Radio>
+                <Radio value="false">涓嶅紑鍚�</Radio>
+              </Radio.Group>
+            </Form.Item>
+          </Col> : null}
+          {verify.accountdate === 'true' ? <Col span={8}>
+            <Form.Item label={'楠岃瘉鍏徃'} required>
+              <Select defaultValue={verify.accountfield || ''} onChange={(val) => {this.onOptionChange(val, 'accountfield')}}>
+                {unionFields.map(option =>
+                  <Select.Option key={option.uuid} value={option.field}>
+                    {option.label}
+                  </Select.Option>
+                )}
+              </Select>
+            </Form.Item>
+          </Col> : null}
+          {verify.accountdate === 'true' ? <Col span={8}>
+            <Form.Item label={
+              <Tooltip placement="bottomLeft" title={'楠岃瘉鏃ユ湡涓虹┖鏃讹紝榛樿涓哄綋澶┿��'}>
+                <QuestionCircleOutlined className="mk-form-tip" />
+                楠岃瘉鏃ユ湡
+              </Tooltip>
+            }>
+              <Select allowClear defaultValue={verify.voucherdate || ''} onChange={(val) => {this.onOptionChange(val, 'voucherdate')}}>
+                {unionFields.map(option =>
+                  <Select.Option key={option.uuid} value={option.field}>
+                    {option.label}
+                  </Select.Option>
+                )}
+              </Select>
+            </Form.Item>
+          </Col> : null}
+          <Col span={24}></Col>
+          <Col span={8}>
+            <Form.Item label={
+              <Tooltip placement="bottomLeft" title={'閫夋嫨鍙戦�佺煭淇℃椂锛岄渶瀹屽杽鐭俊璁剧疆銆�'}>
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鍙戦�佺煭淇�
+              </Tooltip>
+            }>
+              <Radio.Group value={verify.noteEnable} onChange={(e) => {this.onOptionChange(e.target.value, 'noteEnable')}}>
+                <Radio value="true">寮�鍚�</Radio>
+                <Radio value="false">涓嶅紑鍚�</Radio>
+              </Radio.Group>
+            </Form.Item>
+          </Col>
+          {verify.noteEnable === 'true' ? <Col span={8}>
+            <Form.Item label={
+              <Tooltip placement="bottomLeft" title={<span>鐭俊妯℃澘娣诲姞鍦板潃锛�<a target="_blank" rel="noopener noreferrer" href="https://cloud.mk9h.cn/admin/index.html">浜戜腑蹇�</a>-&gt;搴旂敤鏈嶅姟-&gt;寮�鍙戣�呬腑蹇�-&gt;鐭俊妯℃澘銆�</span>}>
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鐭俊妯℃澘
+              </Tooltip>
+            } required>
+              <Select value={verify.noteCode} onSelect={this.onNoteCodeChange}>
+                {notes.map(option =>
+                  <Select.Option key={option.value} id={option.id} value={option.value}>
+                    {option.name}
+                  </Select.Option>
+                )}
+              </Select>
+            </Form.Item>
+          </Col> : null}
+          {verify.noteEnable === 'true' ? <Col span={8}>
+            <Form.Item label={
+              <Tooltip placement="bottomLeft" title={'瀹炴椂鍙戦�佹渶澶氬悓鏃跺彂閫�5涓敤鎴凤紝瀹氭椂鍙戦�佹渶澶氬悓鏃跺彂閫�100涓敤鎴枫��'}>
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鍙戦�佹柟寮�
+              </Tooltip>
+            }>
+              <Radio.Group value={verify.noteType} onChange={(e) => {this.onOptionChange(e.target.value, 'noteType')}}>
+                <Radio value="Y">瀹炴椂</Radio>
+                <Radio value="N">瀹氭椂</Radio>
+              </Radio.Group>
+            </Form.Item>
+          </Col> : null}
+          {verify.noteEnable === 'true' ? <Col span={8}>
+            <Form.Item label={
+              <Tooltip placement="bottomLeft" title={'褰撳悜澶氫釜鐢ㄦ埛鍙戦�佺煭淇℃椂锛岀煭淇″唴瀹规槸鍚︾浉鍚屻��'}>
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鐭俊鍐呭
+              </Tooltip>
+            }>
+              <Radio.Group value={verify.noteTemp} onChange={(e) => {this.onOptionChange(e.target.value, 'noteTemp')}}>
+                <Radio value="Y">鐩稿悓</Radio>
+                <Radio value="N">涓嶅悓</Radio>
+              </Radio.Group>
+            </Form.Item>
+          </Col> : null}
+          <Col span={24}></Col>
+          <Col span={8}>
+            <Form.Item label={
+              <Tooltip placement="bottomLeft" title={'璇峰湪鏈嶅姟鍣ㄥ畬鎴愬叕浼楀彿閰嶇疆銆�'}>
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鍏紬鍙锋秷鎭�
+              </Tooltip>
+            }>
+              <Radio.Group value={verify.wxNote} onChange={(e) => {this.onOptionChange(e.target.value, 'wxNote')}}>
+                <Radio value="true">寮�鍚�</Radio>
+                <Radio value="false">涓嶅紑鍚�</Radio>
+              </Radio.Group>
+            </Form.Item>
+          </Col>
+          {verify.wxNote === 'true' ? <Col span={8}>
+            <Form.Item label="娑堟伅妯℃澘" required>
+              <Select value={verify.wxTemplateId} onSelect={this.onWxTemplateChange}>
+                {wxTemps.map(option =>
+                  <Select.Option key={option.template_id} content={option.content} value={option.template_id}>
+                    {option.title}
+                  </Select.Option>
+                )}
+              </Select>
+            </Form.Item>
+          </Col> : null}
+          {verify.wxNote === 'true' ? <Col span={8}>
+            <Form.Item label={
+              <Tooltip placement="bottomLeft" title={'鏄惁灏嗘秷鎭墽琛岀粨鏋滃洖浼犵郴缁熴��'}>
+                <QuestionCircleOutlined className="mk-form-tip" />
+                娑堟伅鍥炶皟
+              </Tooltip>
+            }>
+              <Radio.Group value={verify.wxNoteCallback || 'false'} onChange={(e) => {this.onOptionChange(e.target.value, 'wxNoteCallback')}}>
+                <Radio value="true">寮�鍚�</Radio>
+                <Radio value="false">涓嶅紑鍚�</Radio>
+              </Radio.Group>
+            </Form.Item>
+          </Col> : null}
+          {verify.wxNote === 'true' ? <Col span={8}>
+            <Form.Item label={
+              <Tooltip placement="bottomLeft" title={'鐐瑰嚮娑堟伅鏃剁殑璺宠浆鍦板潃銆�'}>
+                <QuestionCircleOutlined className="mk-form-tip" />
+                璺宠浆閾炬帴
+              </Tooltip>
+            }>
+              <Radio.Group value={verify.wxNoteLink || ''} onChange={(e) => {this.onOptionChange(e.target.value, 'wxNoteLink')}}>
+                <Radio value="">鏃�</Radio>
+                <Radio value="url">缃戝潃</Radio>
+                <Radio value="miniProgram">灏忕▼搴�</Radio>
+              </Radio.Group>
+            </Form.Item>
+          </Col> : null}
+          {verify.wxNoteLink === 'url' ? <Col span={8}>
+            <Form.Item label="缃戝潃" required>
+              <Input placeholder="" autoComplete="off" value={verify.wxNoteLinkUrl || ''} onChange={(e) => {this.onOptionChange(e.target.value, 'wxNoteLinkUrl')}}/>
+            </Form.Item>
+          </Col> : null}
+          {verify.wxNoteLink === 'miniProgram' ? <Col span={8}>
+            <Form.Item label={
+              <Tooltip placement="bottomLeft" title={`璺宠浆鑷冲皬绋嬪簭鎸囧畾鑿滃崟锛岀┖鍊奸粯璁よ烦杞嚦灏忕▼搴忛椤点�俙}>
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鑿滃崟ID
+              </Tooltip>
+            }>
+              <Input placeholder="" autoComplete="off" value={verify.wxNoteLinkMenuId || ''} onChange={(e) => {this.onOptionChange(e.target.value, 'wxNoteLinkMenuId')}}/>
+            </Form.Item>
+          </Col> : null}
+          {verify.wxNote === 'true' && verify.wxNoteKeys ? verify.wxNoteKeys.map(item => <Col span={8} key={item.key}>
+            <Form.Item className="mk-note-keyword" label={item.key} required>
+              <Select value={item.value} disabled={item.readonly} onSelect={(val) => this.onWxNoteKeyChange(item.key, val)}>
+                <Select.Option value="p1">p1</Select.Option>
+                <Select.Option value="p2">p2</Select.Option>
+                <Select.Option value="p3">p3</Select.Option>
+                <Select.Option value="p4">p4</Select.Option>
+                <Select.Option value="p5">p5</Select.Option>
+                <Select.Option value="p6">p6</Select.Option>
+                <Select.Option value="p7">p7</Select.Option>
+                <Select.Option value="p8">p8</Select.Option>
+                <Select.Option value="p9">p9</Select.Option>
+                <Select.Option value="p10">p10</Select.Option>
+              </Select>
+              <ColorSketch value={item.color || '#ffffff'} onChange={(val, hex) => {this.onWxNoteColorChange(item.key, hex)}} />
+            </Form.Item>
+          </Col>) : null}
+
+        </Row>
+      </Form>
+    )
+  }
+}
+
+export default Form.create()(BillCodeForm)
\ No newline at end of file
diff --git a/src/templates/zshare/verifycard/baseform/index.scss b/src/templates/zshare/verifycard/baseform/index.scss
new file mode 100644
index 0000000..1d1830e
--- /dev/null
+++ b/src/templates/zshare/verifycard/baseform/index.scss
@@ -0,0 +1,26 @@
+.mk-note-keyword {
+  .ant-select {
+    width: 50%;
+    .ant-select-selection {
+      border-radius: 4px 0px 0px 4px;
+    }
+  }
+  .color-sketch-block {
+    width: 50%;
+    display: inline-block;
+    vertical-align: top;
+    position: relative;
+    top: 4px;
+    .color-sketch-block-box {
+      width: calc(100% - 75px);
+      height: 32px;
+      border-radius: 0px 4px 4px 0px;
+      .color-sketch-block-inner {
+        border-radius: 0px 4px 4px 0px;
+      }
+    }
+    .color-sketch-value {
+      width: 75px;
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/templates/zshare/verifycard/billcodeform/index.jsx b/src/templates/zshare/verifycard/billcodeform/index.jsx
index a5ac2c7..b8368eb 100644
--- a/src/templates/zshare/verifycard/billcodeform/index.jsx
+++ b/src/templates/zshare/verifycard/billcodeform/index.jsx
@@ -4,11 +4,9 @@
 import { Form, Row, Col, Select, Button, InputNumber, Input, Tooltip } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 
-import { formRule } from '@/utils/option.js'
 import './index.scss'
 
-
-class UniqueForm extends Component {
+class BillCodeForm extends Component {
   static propTpyes = {
     dict: PropTypes.object,         // 瀛楀吀椤�
     btn: PropTypes.object,          // 鎸夐挳淇℃伅
@@ -366,7 +364,7 @@
                   },
                   {
                     pattern: /^[a-zA-Z0-9]*$/ig,
-                    message: formRule.input.letternummsg
+                    message: '璇疯緭鍏ユ暟瀛椼�佸瓧姣嶄互鍙奯'
                   }
                 ]
               })(<Input placeholder="" autoComplete="off" />)}
@@ -378,4 +376,4 @@
   }
 }
 
-export default Form.create()(UniqueForm)
\ No newline at end of file
+export default Form.create()(BillCodeForm)
\ No newline at end of file
diff --git a/src/templates/zshare/verifycard/callbackcustomscript/index.jsx b/src/templates/zshare/verifycard/callbackcustomscript/index.jsx
index 0f481b7..f14e1be 100644
--- a/src/templates/zshare/verifycard/callbackcustomscript/index.jsx
+++ b/src/templates/zshare/verifycard/callbackcustomscript/index.jsx
@@ -146,10 +146,12 @@
           param.LText = param.LText.replace(/@db@/ig, window.GLOB.externalDatabase)
         }
 
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
+
         console.info(`/* sql 楠岃瘉 */\n${param.LText.replace(/\n\s{6,20}/ig, '\n')}`)
 
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
         
         this.setState({loading: true})
@@ -220,6 +222,8 @@
       }
     }
 
+    // let _usefulfields = usefulfields ? usefulfields.replace(/(BID|ID|LoginUID|SessionUid|UserID|Appkey|UserName|FullName|RoleID|mk_departmentcode|mk_organization|mk_nation|mk_province|mk_city|mk_district|mk_address|mk_user_type|BillCode|BVoucher|FIBVoucherDate|FiYear|ModularDetailCode),\s/ig, '') : null
+
     return (
       <Form {...formItemLayout} className="verify-form verify-custom-callback-scripts" id="verify-custom-callback-scripts">
         <Row gutter={24}>
@@ -233,11 +237,14 @@
               ErrorCode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT锛�, retmsg
             </Form.Item>
           </Col>
-          {usefulfields ? <Col span={24} className="sqlfield">
+          <Col span={24} className="sqlfield">
             <Form.Item label={'鍙敤瀛楁'}>
-              {usefulfields}
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><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={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞跺湪鍗曞彿鐢熸垚鎴栧垱寤哄嚟璇佹椂浣跨敤銆�'}><span style={{color: '#13c2c2'}}>BillCode, BVoucher, FIBVoucherDate, FiYear, ModularDetailCode</span></Tooltip>
+              {usefulfields ? <span>, {usefulfields}</span> : ''}
             </Form.Item>
-          </Col> : null}
+          </Col>
           <Col span={8} style={{whiteSpace: 'nowrap'}}>
             <Form.Item style={{marginBottom: 0}} label={
               <Tooltip placement="bottomLeft" title={'鑷畾涔夎剼鏈笌榛樿sql浣嶇疆鍏崇郴銆�'}>
diff --git a/src/templates/zshare/verifycard/customform/index.jsx b/src/templates/zshare/verifycard/customform/index.jsx
index 0dc8608..6ae1a37 100644
--- a/src/templates/zshare/verifycard/customform/index.jsx
+++ b/src/templates/zshare/verifycard/customform/index.jsx
@@ -1,6 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Row, Col, Input, Select, Button, notification, Modal } from 'antd'
+import { Form, Row, Col, Input, Select, Button, notification, Modal, Tooltip } from 'antd'
 import moment from 'moment'
 
 import Utils from '@/utils/utils.js'
@@ -116,8 +116,10 @@
           param.LText = param.LText.replace(/@db@/ig, window.GLOB.externalDatabase)
         }
 
-        param.LText = Utils.formatOptions(param.LText)
         param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
+
+        param.LText = Utils.formatOptions(param.LText)
         param.secretkey = Utils.encrypt('', param.timestamp)
         
         this.setState({loading: true})
@@ -158,14 +160,20 @@
         sm: { span: 16 }
       }
     }
+
+    // let _usefulfields = usefulfields ? usefulfields.replace(/(BID|ID|LoginUID|SessionUid|UserID|Appkey|UserName|FullName|RoleID|mk_departmentcode|mk_organization|mk_nation|mk_province|mk_city|mk_district|mk_address|mk_user_type|BillCode|BVoucher|FIBVoucherDate|FiYear|ModularDetailCode),\s/ig, '') : null
+
     return (
       <Form {...formItemLayout} className="verify-form" id="verifycard2">
         <Row gutter={24}>
-          {usefulfields ? <Col span={21} className="sqlfield">
+          <Col span={21} className="sqlfield">
             <Form.Item label={'鍙敤瀛楁'}>
-              {usefulfields}
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><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={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞跺湪鍗曞彿鐢熸垚鎴栧垱寤哄嚟璇佹椂浣跨敤銆�'}><span style={{color: '#13c2c2'}}>BillCode, BVoucher, FIBVoucherDate, FiYear, ModularDetailCode</span></Tooltip>
+              {usefulfields ? <span>, {usefulfields}</span> : ''}
             </Form.Item>
-          </Col> : null}
+          </Col>
           <Col span={21} className="sql">
             <Form.Item label={'sql'}>
               {getFieldDecorator('sql', {
diff --git a/src/templates/zshare/verifycard/customscript/index.jsx b/src/templates/zshare/verifycard/customscript/index.jsx
index 1909699..9deb26b 100644
--- a/src/templates/zshare/verifycard/customscript/index.jsx
+++ b/src/templates/zshare/verifycard/customscript/index.jsx
@@ -45,9 +45,18 @@
   }
 
   handleConfirm = () => {
+    const { type } = this.props
     const { editItem } = this.state
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     this.props.form.validateFieldsAndScroll((err, values) => {
+      if (type === 'fullscreen' && err) {
+        notification.warning({
+          top: 92,
+          message: '璇疯緭鍏ql!',
+          duration: 5
+        })
+        return
+      }
       if (!err) {
         values.uuid = editItem ? editItem.uuid : ''
         values.position = values.position || (editItem ? editItem.position : 'front')
@@ -167,10 +176,12 @@
           param.LText = param.LText.replace(/@db@/ig, window.GLOB.externalDatabase)
         }
 
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.LText = param.LText.replace(/@(BID|ID|LoginUID|SessionUid|UserID|Appkey|time_id)@/ig, `'${param.timestamp}'`)
+
         console.info(`/* sql 楠岃瘉 */\n${param.LText.replace(/\n\s{6,20}/ig, '\n')}`)
 
         param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
         param.secretkey = Utils.encrypt('', param.timestamp)
         
         this.setState({loading: true})
@@ -231,6 +242,7 @@
   render() {
     const { usefulfields, systemScripts, btn, type } = this.props
     const { getFieldDecorator } = this.props.form
+    const { editItem } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -244,12 +256,14 @@
 
     let _type = type || ''
 
+    // let _usefulfields = usefulfields ? usefulfields.replace(/(BID|ID|LoginUID|SessionUid|UserID|Appkey|UserName|FullName|RoleID|mk_departmentcode|mk_organization|mk_nation|mk_province|mk_city|mk_district|mk_address|mk_user_type|BillCode|BVoucher|FIBVoucherDate|FiYear|ModularDetailCode),\s/ig, '') : null
+
     return (
       <Form {...formItemLayout} className="verify-form verify-custom-scripts" id={'verify-custom-scripts' + _type}>
         <Row gutter={24}>
-          {!_type && btn.sql ? <Col span={8}>
+          {!_type ? <Col span={8}>
             <Form.Item label={'琛ㄥ悕'} style={{whiteSpace: 'nowrap', margin: 0}}>
-              {btn.sql}
+              {btn.sql || ''}
             </Form.Item>
           </Col> : null}
           {!_type ? <Col span={10}>
@@ -257,9 +271,12 @@
               ErrorCode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT锛�, retmsg
             </Form.Item>
           </Col> : null}
-          {!_type && usefulfields ? <Col span={24} className="sqlfield">
+          {!_type ? <Col span={24} className="sqlfield">
             <Form.Item label={'鍙敤瀛楁'}>
-              {usefulfields}
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
+              <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><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={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞跺湪鍗曞彿鐢熸垚鎴栧垱寤哄嚟璇佹椂浣跨敤銆�'}><span style={{color: '#13c2c2'}}>BillCode, BVoucher, FIBVoucherDate, FiYear, ModularDetailCode</span></Tooltip>
+              {usefulfields ? <span>, {usefulfields}</span> : ''}
             </Form.Item>
           </Col> : null}
           {!_type ?<Col span={8} style={{whiteSpace: 'nowrap'}}>
@@ -300,7 +317,7 @@
           </Col> : null}
           <Col span={6} className="add">
             <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}}>
               鍙栨秷
diff --git a/src/templates/zshare/verifycard/index.jsx b/src/templates/zshare/verifycard/index.jsx
index b98a3c2..0ae5a3a 100644
--- a/src/templates/zshare/verifycard/index.jsx
+++ b/src/templates/zshare/verifycard/index.jsx
@@ -1,13 +1,16 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Form, Tabs, Row, Col, Radio, Button, Select, Popconfirm, notification, Modal, message, InputNumber, Tooltip, Typography } from 'antd'
-import { QuestionCircleOutlined, CheckCircleOutlined, StopOutlined, EditOutlined, SwapOutlined, DeleteOutlined, ExclamationOutlined, BorderOutlined } from '@ant-design/icons'
+import { Form, Tabs, Row, Col, Button, Popconfirm, notification, Modal, message, InputNumber, Typography } from 'antd'
+import { CheckCircleOutlined, StopOutlined, EditOutlined, SwapOutlined, DeleteOutlined, ExclamationOutlined, BorderOutlined } from '@ant-design/icons'
+import Toast from 'antd-mobile/es/components/toast'
+import Dialog from 'antd-mobile/es/components/dialog'
 import moment from 'moment'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
 import options from '@/store/options.js'
+import BaseForm from './baseform'
 import UniqueForm from './uniqueform'
 import ContrastForm from './contrastform'
 import CustomForm from './customform'
@@ -37,6 +40,9 @@
 
   state = {
     initsql: '',            // sql楠岃瘉鏃跺彉閲忓0鏄庡強璧嬪��
+    verifyInter: 'system',  // 鎺ュ彛绫诲瀷
+    activeKey: 'base',
+    appType: sessionStorage.getItem('appType'),
     notes: [],              // 鐭俊妯℃澘
     setting: null,
     visible: false,
@@ -102,7 +108,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div style={{color: '#ff4d4f'}}>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopOutlined style={{marginLeft: '5px'}} />
             </div>
           ) :
@@ -138,7 +144,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div style={{color: '#ff4d4f'}}>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopOutlined style={{marginLeft: '5px'}} />
             </div>
           ) :
@@ -212,7 +218,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div style={{color: '#ff4d4f'}}>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopOutlined style={{marginLeft: '5px'}} />
             </div>
           ) :
@@ -264,7 +270,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div style={{color: '#ff4d4f'}}>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopOutlined style={{marginLeft: '5px'}} />
             </div>
           ) :
@@ -333,7 +339,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div style={{color: '#ff4d4f'}}>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopOutlined style={{marginLeft: '5px'}} />
             </div>
           ) :
@@ -400,7 +406,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div style={{color: '#ff4d4f'}}>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopOutlined style={{marginLeft: '5px'}} />
             </div>
           ) :
@@ -501,7 +507,7 @@
         render: (text, record) => record.status === 'false' ?
           (
             <div style={{color: '#ff4d4f'}}>
-              {this.props.dict['model.status.forbidden']}
+              绂佺敤
               <StopOutlined style={{marginLeft: '5px'}} />
             </div>
           ) :
@@ -547,6 +553,7 @@
     }
 
     _verify.default = _verify.default || 'true'
+    _verify.wxNote = _verify.wxNote || 'false'         // 鍏紬鍙锋秷鎭帹閫佹槸鍚﹀紑鍚�
     _verify.noteEnable = _verify.noteEnable || 'false' // 鐭俊鍙戦�佹槸鍚﹀紑鍚�
     _verify.noteType = _verify.noteType || 'N'         // 鐭俊鍙戦�佹ā寮忥細Y锛堝疄鏃讹級銆丯锛堝畾鏃讹級
     _verify.noteTemp = _verify.noteTemp || 'Y'         // 鐭俊鍙戦�佹ā鏉匡細Y锛堢浉鍚岋級銆丯锛堜笉鍚岋級
@@ -587,7 +594,11 @@
       item.$index = i + 1
     })
 
+    let verifyInter = card.intertype === 'system' || (card.intertype === 'custom' && card.procMode === 'system') ? 'system' : 'inner'
+
     this.setState({
+      activeKey: verifyInter === 'system' || card.intertype === 'inner' ? 'base' : 'tip',
+      verifyInter: verifyInter,
       setting: config.setting || {},
       verify: _verify,
       oriVerify: fromJS(_verify).toJS()
@@ -649,11 +660,13 @@
         resolve(_fields)
       }
     }).then(_fields => {
-      let _usefulfields = ['UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'login_city', 'BillCode', 'BVoucher', 'FIBVoucherDate', 'FiYear', 'ModularDetailCode']
-      let _declare = ['@UserName nvarchar(50)', '@FullName nvarchar(50)', '@RoleID nvarchar(512)', '@mk_departmentcode nvarchar(50)', '@mk_organization nvarchar(50)', '@login_city nvarchar(50)', '@ErrorCode nvarchar(50)', '@retmsg nvarchar(4000)', '@BillCode nvarchar(50)', '@BVoucher nvarchar(50)', '@FIBVoucherDate nvarchar(50)', '@FiYear nvarchar(50)', '@ModularDetailCode nvarchar(50)', '@bid nvarchar(50)']
-      let _select = ['@UserName=\'\'', '@FullName=\'\'', '@RoleID=\'\'', '@mk_departmentcode=\'\'', '@mk_organization=\'\'', '@login_city=\'\'', '@ErrorCode=\'\'', '@retmsg=\'\'', '@BillCode=\'\'', '@BVoucher=\'\'', '@FIBVoucherDate=\'\'', '@FiYear=\'\'', '@ModularDetailCode=\'\'', '@bid=\'\'']
+      let _usefulfields = ['UserName', 'FullName', 'RoleID', 'mk_departmentcode', 'mk_organization', 'mk_user_type', 'mk_nation', 'mk_province', 'mk_city', 'mk_district', 'mk_address', 'BillCode', 'BVoucher', 'FIBVoucherDate', 'FiYear', 'ModularDetailCode']
+      let _declare = ['@UserName nvarchar(50)', '@FullName nvarchar(50)', '@RoleID nvarchar(512)', '@mk_departmentcode nvarchar(50)', '@mk_organization nvarchar(50)', '@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)', '@BillCode nvarchar(50)', '@BVoucher nvarchar(50)', '@FIBVoucherDate nvarchar(50)', '@FiYear nvarchar(50)', '@ModularDetailCode nvarchar(50)', '@bid 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=\'\'', '@BillCode=\'\'', '@BVoucher=\'\'', '@FIBVoucherDate=\'\'', '@FiYear=\'\'', '@ModularDetailCode=\'\'', '@bid=\'\'']
       let fieldArr = _usefulfields.map(_f => _f.toLowerCase())
       let hasBid = false
+
+      _usefulfields = []
       
       fieldArr.push('bid')
 
@@ -772,6 +785,7 @@
       let _defaultsql = ''
       let _insertsql = ''
       let _updatesql = ''
+      let _primaryKey = config.setting.primaryKey || 'id'
 
       if (card.sqlType === 'insert' || card.sqlType === 'insertOrUpdate') {
         let keys = []
@@ -789,8 +803,8 @@
           }
         })
 
-        if (config.setting.primaryKey && !keys.includes(config.setting.primaryKey.toLowerCase())) {
-          keys.push(config.setting.primaryKey.toLowerCase())
+        if (!keys.includes(_primaryKey.toLowerCase())) {
+          keys.push(_primaryKey.toLowerCase())
           values.push('@ID@')
         }
         if (!keys.includes('createuserid')) {
@@ -865,7 +879,7 @@
         }
 
         _form = _form.join(', ')
-        _updatesql = `update ${card.sql} set ${_form} where ${config.setting.primaryKey || 'id'}${card.Ot !== 'requiredOnce' ? '=@ID@' : ' in (select ID  from dbo.SplitComma(@ID@))'};`
+        _updatesql = `update ${card.sql} set ${_form} where ${_primaryKey}${card.Ot !== 'requiredOnce' ? '=@ID@' : ' in (select ID  from dbo.SplitComma(@ID@))'};`
       }
 
       if (card.sqlType === 'insert') {
@@ -874,7 +888,7 @@
         _defaultsql = _updatesql
       } else if (card.sqlType === 'insertOrUpdate') {
         _defaultsql += `select @tbid=''
-          select @tbid='X' from ${card.sql} where ${config.setting.primaryKey || 'id'}=@ID@
+          select @tbid='X' from ${card.sql} where ${_primaryKey}=@ID@
           if @tbid=''
             begin
             ${_insertsql}
@@ -889,7 +903,7 @@
         if (_verify.voucher && _verify.voucher.enabled) {
           _voucher = ',BVoucher=@BVoucher,FIBVoucherDate=@FIBVoucherDate,FiYear=@FiYear'
         }
-        _defaultsql = `update ${card.sql} set deleted=1,modifydate=getdate(),modifyuser=@username,modifyuserid=@userid@${_voucher} where ${config.setting.primaryKey || 'id'}${card.Ot !== 'requiredOnce' ? '=@ID@' : ' in (select ID  from dbo.SplitComma(@ID@))'};`
+        _defaultsql = `update ${card.sql} set deleted=1,modifydate=getdate(),modifyuser=@username,modifyuserid=@userid@${_voucher} where ${_primaryKey}${card.Ot !== 'requiredOnce' ? '=@ID@' : ' in (select ID  from dbo.SplitComma(@ID@))'};`
       } else if (card.sqlType === 'delete') {
         let _msg = ''
         if (columns && columns.length > 0 && card.Ot !== 'notRequired' && card.Ot !== 'requiredOnce') {
@@ -901,7 +915,7 @@
             _index++
           })
         }
-        _defaultsql += `insert into snote (remark,createuserid,CreateUser,CreateStaff) select left('鍒犻櫎琛�:${card.sql} 鏁版嵁: ${_msg}${config.setting.primaryKey || 'id'}='+@ID@,200),@userid@,@username,@fullname delete ${card.sql} where ${config.setting.primaryKey}${card.Ot !== 'requiredOnce' ? '=@ID@' : ' in (select ID  from dbo.SplitComma(@ID@))'};`
+        _defaultsql += `insert into snote (remark,createuserid,CreateUser,CreateStaff) select left('鍒犻櫎琛�:${card.sql} 鏁版嵁: ${_msg}${_primaryKey}='+@ID@,200),@userid@,@username,@fullname delete ${card.sql} where ${_primaryKey}${card.Ot !== 'requiredOnce' ? '=@ID@' : ' in (select ID  from dbo.SplitComma(@ID@))'};`
       }
 
       let _columns = []
@@ -920,13 +934,13 @@
           _columns.unshift({ uuid: 'BID', field: 'BID', label: 'BID', type: 'text' })
         }
       }
-      
+
       this.setState({
         fields: _fields,
         columnsFields: _columns,
         initsql: _sql,
         defaultsql: _defaultsql,
-        usefulfields: ['BID', 'ID', 'LoginUID', 'SessionUid', 'UserID', 'Appkey', ..._usefulfields].join(', '),
+        usefulfields: _usefulfields.join(', '),
         uniqueColumns: this.state.uniqueColumns.map(col => {
           if (col.dataIndex === 'field') {
             col.options = uniqueFields
@@ -1144,39 +1158,6 @@
     this.setState({ verify })
   }
 
-  onNoteCodeChange = (val, option) => {
-    const { verify } = this.state
-
-    this.setState({
-      verify: {...verify, noteCode: val, noteId: option.props.id}
-    })
-  }
-
-  onOptionChange = (e, key) => {
-    const { verify } = this.state
-    let value = e.target.value
-
-    this.setState({
-      verify: {...verify, [key]: value}
-    })
-  }
-
-  changeAccField = (val) => {
-    const { verify } = this.state
-
-    this.setState({
-      verify: {...verify, accountfield: val}
-    })
-  }
-
-  changeAccDate = (val) => {
-    const { verify } = this.state
-
-    this.setState({
-      verify: {...verify, voucherdate: val}
-    })
-  }
-
   handleDelete = (record, type) => {
     const { verify } = this.state
 
@@ -1273,35 +1254,66 @@
   }
 
   showError = (errorType) => {
+    const { verify, appType } = this.state
+
     if (errorType === 'S') {
-      notification.success({
-        top: 92,
-        message: '鎵ц鎴愬姛锛�',
-        duration: 2
-      })
+      let time = verify.stime || 2
+      if (appType === 'mob') {
+        Toast.show({ icon: 'success', content: '鎵ц鎴愬姛锛�', duration: time * 1000 })
+      } else {
+        notification.success({
+          top: 92,
+          message: '鎵ц鎴愬姛锛�',
+          duration: time
+        })
+      }
+      
     } else if (errorType === 'Y') {
-      Modal.success({
-        title: '鎵ц鎴愬姛锛�'
-      })
+      if (appType === 'mob') {
+        Dialog.alert({content: '鎵ц鎴愬姛锛�', confirmText: '鐭ラ亾浜�'})
+      } else {
+        Modal.success({
+          title: '鎵ц鎴愬姛锛�'
+        })
+      }
     } else if (errorType === 'F') {
-      notification.error({
-        className: 'notification-custom-error',
-        top: 92,
-        message: '鎵ц澶辫触锛�',
-        duration: 10
-      })
+      if (appType === 'mob') {
+        let time = verify.ftime || 3
+        Toast.show({ icon: 'fail', content: '鎵ц澶辫触锛�', duration: time * 1000 })
+      } else {
+        notification.error({
+          className: 'notification-custom-error',
+          top: 92,
+          message: '鎵ц澶辫触锛�',
+          duration: verify.ftime || 10
+        })
+      }
     } else if (errorType === 'N') {
-      notification.error({
-        top: 92,
-        message: '鎵ц澶辫触锛�',
-        duration: 10
-      })
+      if (appType === 'mob') {
+        let time = verify.ntime || 3
+        Toast.show({ content: '鎵ц澶辫触锛�', duration: time * 1000 })
+      } else {
+        notification.error({
+          top: 92,
+          message: '鎵ц澶辫触锛�',
+          duration: verify.ntime || 10
+        })
+      }
     } else if (errorType === 'E') {
-      Modal.error({
-        title: '鎵ц澶辫触锛�'
-      })
+      if (appType === 'mob') {
+        Dialog.alert({content: '鎵ц澶辫触锛�', confirmText: '鐭ラ亾浜�'})
+      } else {
+        Modal.error({
+          title: '鎵ц澶辫触锛�'
+        })
+      }
     } else if (errorType === 'NM') {
-      message.error('鎵ц澶辫触锛�')
+      if (appType === 'mob') {
+        let time = verify.ntime || 3
+        Toast.show({ content: '鎵ц澶辫触锛�', duration: time * 1000 })
+      } else {
+        message.error('鎵ц澶辫触锛�')
+      }
     }
   }
 
@@ -1349,8 +1361,21 @@
 
   handleConfirm = () => {
     const { card } = this.props
-    const { setting } = this.state
+    const { setting, activeKey } = this.state
     let verify = fromJS(this.state.verify).toJS()
+
+    if (activeKey === 'base') {
+      let msg = this.baseForm.handleConfirm()
+
+      if (msg) {
+        notification.warning({
+          top: 92,
+          message: msg,
+          duration: 5
+        })
+        return Promise.reject()
+      }
+    }
     
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     return new Promise((resolve, reject) => {
@@ -1358,13 +1383,6 @@
         notification.warning({
           top: 92,
           message: '涓嶆墽琛岄粯璁ql鏃讹紝蹇呴』璁剧疆鑷畾涔夎剼鏈紒',
-          duration: 5
-        })
-        return
-      } else if (verify.accountdate === 'true' && !verify.accountfield) {
-        notification.warning({
-          top: 92,
-          message: '寮�鍚处鏈熸椂锛岄渶瑕侀�夋嫨楠岃瘉鍏徃锛�',
           duration: 5
         })
         return
@@ -1388,12 +1406,6 @@
         msg = '鑷畾涔夎剼鏈�'
       } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) {
         msg = '鑷畾涔夎剼鏈�'
-      }
-
-      if (verify.noteEnable === 'true' && !verify.noteCode) { // 寮�鍚煭淇℃椂锛岄渶瑕佹ā鏉跨紪鐮�
-        verify.noteEnable = 'false'
-      } else if (verify.noteEnable !== 'true' && verify.noteCode) {
-        verify.noteCode = ''
       }
 
       if (window.GLOB.funcs && window.GLOB.funcs.length > 0) {
@@ -1443,6 +1455,26 @@
     })
   }
 
+  changeTab = (val) => {
+    const { activeKey } = this.state
+
+    if (activeKey === 'base') {
+      let msg = this.baseForm.handleConfirm()
+
+      if (msg) {
+        notification.warning({
+          top: 92,
+          message: msg,
+          duration: 5
+        })
+        return
+      }
+    }
+    this.setState({
+      activeKey: val
+    })
+  }
+
   /**
    * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
    */
@@ -1454,7 +1486,7 @@
 
   render() {
     const { card } = this.props
-    const { verify, fields, visible, uniqueFields, uniqueColumns, unionFields, onceUniqueColumns, columnsFields, contrastColumns, customColumns, orderColumns, scriptsColumns, cbScriptsColumns, orderModular, orderModularDetail, voucher, voucherDetail, notes } = this.state
+    const { activeKey, verifyInter, verify, fields, visible, uniqueFields, uniqueColumns, unionFields, onceUniqueColumns, columnsFields, contrastColumns, customColumns, orderColumns, scriptsColumns, cbScriptsColumns, orderModular, orderModularDetail, voucher, voucherDetail, notes, appType } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -1468,134 +1500,30 @@
 
     return (
       <div id="verify-card-box-tab">
-        <Tabs defaultActiveKey="1" className="verify-card-box">
-          {card.intertype === 'system' || (card.intertype === 'custom' && card.procMode === 'system') ? <TabPane tab={
+        <Tabs activeKey={activeKey} className="verify-card-box" onChange={this.changeTab}>
+          {verifyInter === 'system' || card.intertype === 'inner' ? <TabPane tab={
             <span>
               鍩虹楠岃瘉
               {verify.default === 'false' ? <span className="count-tip"><ExclamationOutlined style={{color: 'orange'}}/></span> : null}
             </span>
-          } key="1">
-            <Form {...formItemLayout}>
-              <Row gutter={24}>
-                {this.props.card.sqlType !== 'custom' ? <Col span={8}>
-                  <Form.Item label={
-                    <Tooltip placement="bottomLeft" title={'榛樿sql鎵ц椤哄簭涓鸿嚜瀹氫箟鑴氭湰涔嬪墠'}>
-                      <QuestionCircleOutlined className="mk-form-tip" />
-                      榛樿sql
-                    </Tooltip>
-                  }>
-                    <Radio.Group value={verify.default} onChange={(e) => {this.onOptionChange(e, 'default')}}>
-                      <Radio value="true">鎵ц</Radio>
-                      <Radio value="false">涓嶆墽琛�</Radio>
-                    </Radio.Group>
-                  </Form.Item>
-                </Col> : null}
-                <Col span={8}>
-                  <Form.Item label={'璐︽湡楠岃瘉'}>
-                    <Radio.Group value={verify.accountdate} onChange={(e) => {this.onOptionChange(e, 'accountdate')}}>
-                      <Radio value="true">寮�鍚�</Radio>
-                      <Radio value="false">涓嶅紑鍚�</Radio>
-                    </Radio.Group>
-                  </Form.Item>
-                </Col>
-                {verify.accountdate === 'true' ? <Col span={8}>
-                  <Form.Item label={'楠岃瘉鍏徃'} required>
-                    <Select defaultValue={verify.accountfield || ''} onChange={this.changeAccField}>
-                      {unionFields.map(option =>
-                        <Select.Option key={option.uuid} value={option.field}>
-                          {option.label}
-                        </Select.Option>
-                      )}
-                    </Select>
-                  </Form.Item>
-                </Col> : null}
-                {verify.accountdate === 'true' ? <Col span={8}>
-                  <Form.Item label={
-                    <Tooltip placement="bottomLeft" title={'楠岃瘉鏃ユ湡涓虹┖鏃讹紝榛樿涓哄綋澶┿��'}>
-                      <QuestionCircleOutlined className="mk-form-tip" />
-                      楠岃瘉鏃ユ湡
-                    </Tooltip>
-                  }>
-                    <Select allowClear defaultValue={verify.voucherdate || ''} onChange={this.changeAccDate}>
-                      {unionFields.map(option =>
-                        <Select.Option key={option.uuid} value={option.field}>
-                          {option.label}
-                        </Select.Option>
-                      )}
-                    </Select>
-                  </Form.Item>
-                </Col> : null}
-                <Col span={8}>
-                  <Form.Item label={'澶辨晥楠岃瘉'}>
-                    <Radio.Group value={verify.invalid} onChange={(e) => {this.onOptionChange(e, 'invalid')}}>
-                      <Radio value="true">寮�鍚�</Radio>
-                      <Radio value="false">涓嶅紑鍚�</Radio>
-                    </Radio.Group>
-                  </Form.Item>
-                </Col>
-                <Col span={8}>
-                  <Form.Item label={
-                    <Tooltip placement="bottomLeft" title={'閫夋嫨鍙戦�佺煭淇℃椂锛岄渶瀹屽杽鐭俊璁剧疆銆�'}>
-                      <QuestionCircleOutlined className="mk-form-tip" />
-                      鍙戦�佺煭淇�
-                    </Tooltip>
-                  }>
-                    <Radio.Group value={verify.noteEnable} onChange={(e) => {this.onOptionChange(e, 'noteEnable')}}>
-                      <Radio value="true">寮�鍚�</Radio>
-                      <Radio value="false">涓嶅紑鍚�</Radio>
-                    </Radio.Group>
-                  </Form.Item>
-                </Col>
-                {verify.noteEnable === 'true' ? <Col span={8}>
-                  <Form.Item label="鐭俊妯℃澘">
-                    <Select value={verify.noteCode} onSelect={this.onNoteCodeChange}>
-                      {notes.map(option =>
-                        <Select.Option key={option.value} id={option.id} value={option.value}>
-                          {option.name}
-                        </Select.Option>
-                      )}
-                    </Select>
-                  </Form.Item>
-                </Col> : null}
-                {verify.noteEnable === 'true' ? <Col span={8}>
-                  <Form.Item label={
-                    <Tooltip placement="bottomLeft" title={'瀹炴椂鍙戦�佹渶澶氬悓鏃跺彂閫�5涓敤鎴凤紝瀹氭椂鍙戦�佹渶澶氬悓鏃跺彂閫�100涓敤鎴枫��'}>
-                      <QuestionCircleOutlined className="mk-form-tip" />
-                      鍙戦�佹柟寮�
-                    </Tooltip>
-                  }>
-                    <Radio.Group value={verify.noteType} onChange={(e) => {this.onOptionChange(e, 'noteType')}}>
-                      <Radio value="Y">瀹炴椂</Radio>
-                      <Radio value="N">瀹氭椂</Radio>
-                    </Radio.Group>
-                  </Form.Item>
-                </Col> : null}
-                {verify.noteEnable === 'true' ? <Col span={8}>
-                  <Form.Item label="鐭俊鍐呭">
-                    <Radio.Group value={verify.noteTemp} onChange={(e) => {this.onOptionChange(e, 'noteTemp')}}>
-                      <Radio value="Y">鐩稿悓</Radio>
-                      <Radio value="N">涓嶅悓</Radio>
-                    </Radio.Group>
-                  </Form.Item>
-                </Col> : null}
-              </Row>
-            </Form>
+          } key="base">
+            <BaseForm card={card} unionFields={unionFields} verify={verify} notes={notes} onChange={(verify) => this.setState({verify})} wrappedComponentRef={(inst) => this.baseForm = inst}/>
           </TabPane> : null}
-          {card.intertype === 'system' || (card.intertype === 'custom' && card.procMode === 'system') ? <TabPane tab={
+          {verifyInter === 'system' ? <TabPane tab={
             <span>
               姣旇緝楠岃瘉
               {verify.contrasts.length ? <span className="count-tip">{verify.contrasts.length}</span> : null}
             </span>
-          } key="2x">
+          } key="contrasts">
             <ContrastForm dict={this.props.dict} contrastChange={this.contrastChange}/>
             <EditTable actions={['edit', 'move', 'copy', 'del', 'status']} type="contrastverify" data={verify.contrasts} columns={contrastColumns} onChange={(contrasts) => this.setState({verify: {...verify, contrasts}})}/>
           </TabPane> : null}
-          {card.intertype === 'system' || (card.intertype === 'custom' && card.procMode === 'system') ? <TabPane tab={
+          {verifyInter === 'system' ? <TabPane tab={
             <span>
               鑷畾涔夐獙璇�
               {verify.customverifys.length ? <span className="count-tip">{verify.customverifys.length}</span> : null}
             </span>
-          } key="3">
+          } key="customverifys">
             <CustomForm
               dict={this.props.dict}
               btn={this.props.card}
@@ -1606,12 +1534,12 @@
             />
             <EditTable actions={['move']} data={verify.customverifys} columns={customColumns} onChange={(customverifys) => {this.setState({verify: {...verify, customverifys}})}}/>
           </TabPane> : null}
-          {card.intertype === 'system' || (card.intertype === 'custom' && card.procMode === 'system') ? <TabPane tab={
+          {verifyInter === 'system' ? <TabPane tab={
             <span>
               鍗曞彿鐢熸垚
               {verify.billcodes.length ? <span className="count-tip">{verify.billcodes.length}</span> : null}
             </span>
-          } key="4">
+          } key="billcodes">
             <BillcodeForm
               fields={fields}
               btn={this.props.card}
@@ -1625,12 +1553,12 @@
             />
             <EditTable actions={['move']} data={verify.billcodes} columns={orderColumns} onChange={(billcodes) => {this.setState({verify: {...verify, billcodes}})}}/>
           </TabPane> : null}
-          {card.intertype === 'system' || (card.intertype === 'custom' && card.procMode === 'system') ? <TabPane tab={
+          {verifyInter === 'system' ? <TabPane tab={
             <span>
               {card.Ot !== 'requiredOnce' ? '鍞竴鎬ч獙璇�' : '鍚岀被鏁版嵁楠岃瘉'}
               {verify.uniques.length ? <span className="count-tip">{verify.uniques.length}</span> : null}
             </span>
-          } key="2">
+          } key="uniques">
             <UniqueForm
               btn={card}
               fields={card.Ot !== 'requiredOnce' ? uniqueFields : columnsFields}
@@ -1639,12 +1567,12 @@
             />
             <EditTable actions={['edit', 'move', 'del', 'status']} data={verify.uniques} columns={card.Ot !== 'requiredOnce' ? uniqueColumns : onceUniqueColumns} onChange={this.changeUniques}/>
           </TabPane> : null}
-          {card.intertype === 'system' || (card.intertype === 'custom' && card.procMode === 'system') ? <TabPane tab={
+          {verifyInter === 'system' ? <TabPane tab={
             <span>
               鍒涘缓鍑瘉
               {verify.voucher && verify.voucher.enabled ? <span className="count-tip">1</span> : null}
             </span>
-          } key="5">
+          } key="voucher">
             <VoucherForm
               dict={this.props.dict}
               voucher={voucher}
@@ -1655,13 +1583,12 @@
               wrappedComponentRef={(inst) => this.voucherForm = inst}
             />
           </TabPane> : null}
-          {card.intertype === 'system' || (card.intertype === 'custom' && card.procMode === 'system') ? <TabPane tab={
+          {verifyInter === 'system' ? <TabPane tab={
             <span>
               鑷畾涔夎剼鏈�
               {verify.scripts.length ? <span className="count-tip">{verify.scripts.length}</span> : null}
             </span>
-          } key="6">
-            
+          } key="scripts">
             <BorderOutlined className="full-scripts" onClick={() => {
               if (this.scriptsForm && (this.scriptsForm.state.editItem || (this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))))) {
                 notification.warning({
@@ -1691,7 +1618,7 @@
               鍥炶皟鑴氭湰
               {verify.cbScripts.length ? <span className="count-tip">{verify.cbScripts.length}</span> : null}
             </span>
-          } key="6a">
+          } key="cbScripts">
             <CallBackCustomScript
               btn={this.props.card}
               dict={this.props.dict}
@@ -1704,7 +1631,7 @@
             />
             <EditTable actions={['move']} data={verify.cbScripts} columns={cbScriptsColumns} onChange={(cbScripts) => {this.setState({verify: {...verify, cbScripts}})}}/>
           </TabPane> : null}
-          <TabPane tab="淇℃伅鎻愮ず" key="7">
+          <TabPane tab="淇℃伅鎻愮ず" key="tip">
             <Form {...formItemLayout}>
               <Row gutter={24}>
                 <Col offset={6} span={6}>
@@ -1742,7 +1669,7 @@
                 </Col>
                 <Col span={8}>
                   <Form.Item label={'鍋滅暀鏃堕棿'}>
-                    <InputNumber defaultValue={verify.ntime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} />
+                    <InputNumber defaultValue={verify.ntime || (appType === 'mob' ? 3 : 10)} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} />
                   </Form.Item>
                 </Col>
               </Row>
@@ -1757,7 +1684,7 @@
                 </Col>
                 <Col span={8}>
                   <Form.Item label={'鍋滅暀鏃堕棿'}>
-                    <InputNumber defaultValue={verify.ftime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} />
+                    <InputNumber defaultValue={verify.ftime || (appType === 'mob' ? 3 : 10)} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} />
                   </Form.Item>
                 </Col>
               </Row>
diff --git a/src/templates/zshare/verifycard/index.scss b/src/templates/zshare/verifycard/index.scss
index da0eef1..af61eaa 100644
--- a/src/templates/zshare/verifycard/index.scss
+++ b/src/templates/zshare/verifycard/index.scss
@@ -209,4 +209,20 @@
       }
     }
   }
+}
+.adm-mask {
+  z-index: 2000!important;
+}
+.adm-dialog {
+  z-index: 2000!important;
+  .adm-center-popup-body {
+    background-color: #ffffff;
+  }
+  .adm-center-popup-wrap {
+    z-index: 2000;
+  }
+  .adm-button {
+    color: #1890ff;
+    border-top: 1px solid #e9e9e9;
+  }
 }
\ No newline at end of file
diff --git a/src/utils/option.js b/src/utils/option.js
index 2c6f1d5..6e6bb25 100644
--- a/src/utils/option.js
+++ b/src/utils/option.js
@@ -1,10 +1,11 @@
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
 import nortable from '@/assets/img/normaltable.jpg'
-import mainsubtable from '@/assets/img/mainsubtable.jpg'
+// import mainsubtable from '@/assets/img/mainsubtable.jpg'
 import treepage from '@/assets/img/treepage.jpg'
 import calendar from '@/assets/img/calendar.jpg'
 import customImg from '@/assets/img/custom.jpg'
+import newpage from '@/assets/img/newpage.jpg'
 import rolemanage from '@/assets/img/rolemanage.jpg'
 
 const _dict =  sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
@@ -17,8 +18,6 @@
     formMessage: '鏈�澶欯max涓瓧绗︺��', // 鏂囨湰琛ㄥ崟鏈�澶ф彁绀�
     numbermsg: '璇疯緭鍏ユ暟瀛楋紒',
     lettermsg: '璇疯緭鍏ュ瓧姣嶏紒',
-    letternummsg: '璇疯緭鍏ユ暟瀛楁垨瀛楁瘝锛�',
-    quotemsg: '涓嶅彲浣跨敤鑻辨枃鐘舵�佺殑鍗曞紩鍙凤紒',
     funcname: '璇疯緭鍏ユ暟瀛椼�佸瓧姣嶃�佹眽瀛椾互鍙奯'
   },
   field: { // 瀛楁鍚�
@@ -57,14 +56,14 @@
     baseconfig: '',
     isSystem: true
   },
-  {
-    title: '涓诲瓙琛ㄨ〃鏍�',
-    type: 'CommonTable',
-    url: mainsubtable,
-    baseconfig: '',
-    isSystem: true,
-    isSubtable: true
-  },
+  // {
+  //   title: '涓诲瓙琛ㄨ〃鏍�',
+  //   type: 'CommonTable',
+  //   url: mainsubtable,
+  //   baseconfig: '',
+  //   isSystem: true,
+  //   isSubtable: true
+  // },
   {
     title: '鑷畾涔�',
     type: 'CustomPage',
@@ -89,7 +88,7 @@
   {
     title: '澶栭儴椤甸潰',
     type: 'NewPage',
-    url: customImg,
+    url: newpage,
     baseconfig: '',
     isSystem: true
   },
@@ -102,7 +101,7 @@
 ]
 
 // 鍥捐〃鑹茬郴
-export const chartColors = ['rgb(91, 143, 249)', 'rgb(90, 216, 166)', 'rgb(93, 112, 146)', 'rgb(246, 189, 22)', 'rgb(232, 100, 82)', 'rgb(109, 200, 236)', 'rgb(148, 95, 185)', 'rgb(246, 189, 22)', 'rgb(205, 221, 253)', 'rgb(248, 208, 203)']
+export const chartColors = ['rgb(91, 143, 249)', 'rgb(90, 216, 166)', 'rgb(93, 112, 146)', 'rgb(246, 189, 22)', 'rgb(232, 100, 82)', 'rgb(109, 200, 236)', 'rgb(148, 95, 185)', 'rgb(205, 221, 253)', 'rgb(248, 208, 203)', 'rgb(145, 213, 255)', 'rgb(211, 173, 247)']
 
 // 鏃ユ湡榛樿鍊奸�夋嫨鑼冨洿
 export const dateOptions = {
diff --git a/src/utils/utils-custom.js b/src/utils/utils-custom.js
index eafbca4..630ecc0 100644
--- a/src/utils/utils-custom.js
+++ b/src/utils/utils-custom.js
@@ -3,16 +3,17 @@
    * @description 鑾峰彇涓嬬骇妯″潡
    * @return {String}  selfId  褰撳墠缁勪欢id
    */
-  static getSubModules (components, selfId) {
+  static getSubModules (components, selfId, supId) {
     let modules = components.map(item => {
-      if (item.uuid === selfId) {
+      if (item.uuid === selfId || item.type === 'navbar') {
         return {
           children: null
         }
       } else if (item.format) { // 鏁版嵁鏍煎紡锛屽瓨鍦ㄦ暟鎹簮
         return {
           value: item.uuid,
-          label: item.name
+          label: item.name,
+          disabled: supId === item.uuid
         }
       } else if (item.type === 'tabs') {
         let _item = {
@@ -575,6 +576,17 @@
             return col
           })
         }
+      } else if (item.type === 'form') {
+        item.subcards = item.subcards.map(cell => {
+          cell.uuid = this.getuuid()
+  
+          cell.fields = cell.fields.map(m => {
+            m.uuid = this.getuuid()
+    
+            return m
+          })
+          return cell
+        })
       }
   
       if (item.btnlog) {
diff --git a/src/utils/utils-datamanage.js b/src/utils/utils-datamanage.js
index 13628af..a7411ae 100644
--- a/src/utils/utils-datamanage.js
+++ b/src/utils/utils-datamanage.js
@@ -13,16 +13,15 @@
    * @param {Number}   pageIndex    椤电爜
    * @param {Number}   pageSize     姣忛〉鏁伴噺
    * @param {String}   BID          涓婄骇ID
-   * @param {String}   menuType     鑿滃崟绫诲瀷锛屾櫘閫氳彍鍗曚笌HS
    * @return {Object}  param
    */
-  static getQueryDataParams (setting, arrFields, search = [], orderBy = '', pageIndex = 1, pageSize = 10, BID, menuType, id) {
+  static getQueryDataParams (setting, arrFields, search = [], orderBy = '', pageIndex = 1, pageSize = 10, BID, id) {
     let param = null
 
     if (setting.interType === 'system' || (setting.interType === 'custom' && setting.requestMode === 'system')) {
-      param = this.getDefaultQueryParam(setting, arrFields, search, orderBy, pageIndex, pageSize, menuType, id)
+      param = this.getDefaultQueryParam(setting, arrFields, search, orderBy, pageIndex, pageSize, id, BID)
     } else {
-      param = this.getCustomQueryParam(setting, search, orderBy, pageIndex, pageSize, menuType, id)
+      param = this.getCustomQueryParam(setting, search, orderBy, pageIndex, pageSize, id)
     }
 
     if (BID) {
@@ -39,7 +38,7 @@
   /**
    * @description 鑾峰彇鐢ㄦ埛鑷畾涔夊瓨鍌ㄨ繃绋嬩紶鍙�
    */
-  static getCustomQueryParam (setting, search, orderBy, pageIndex, pageSize, menuType, id) {
+  static getCustomQueryParam (setting, search, orderBy, pageIndex, pageSize, id) {
     let param = Utils.formatCustomMainSearch(search)
 
     if (orderBy) {
@@ -56,7 +55,7 @@
     if (setting.interType === 'inner' || (setting.interType === 'custom' && setting.requestMode === 'inner')) {
       param.func = setting.innerFunc
     } else {
-      if (menuType === 'HS') {
+      if (window.GLOB.mkHS) {
         if (setting.sysInterface === 'true' && options.cloudServiceApi) {
           param.rduri = options.cloudServiceApi
         } else if (setting.sysInterface !== 'true') {
@@ -81,7 +80,7 @@
   /**
    * @description 鑾峰彇绯荤粺瀛樺偍杩囩▼ sPC_Get_TableData 鐨勫弬鏁�
    */
-  static getDefaultQueryParam (setting, arrFields, search, orderBy, pageIndex, pageSize, menuType, id) {
+  static getDefaultQueryParam (setting, arrFields, search, orderBy, pageIndex, pageSize, id, BID) {
     let param = {
       func: 'sPC_Get_TableData',
       obj_name: 'data',
@@ -99,7 +98,12 @@
     let RoleID = sessionStorage.getItem('role_id') || ''
     let departmentcode = sessionStorage.getItem('departmentcode') || ''
     let organization = sessionStorage.getItem('organization') || ''
+    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+    let nation = sessionStorage.getItem('nation') || ''
+    let province = sessionStorage.getItem('province') || ''
     let city = sessionStorage.getItem('city') || ''
+    let district = sessionStorage.getItem('district') || ''
+    let address = sessionStorage.getItem('address') || ''
 
     if (sessionStorage.getItem('isEditState') === 'true') {
       userName = sessionStorage.getItem('CloudUserName') || ''
@@ -110,8 +114,8 @@
     let _customScript = ''
     
     if (setting.customScript) {
-      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50)
-        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100)
+        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
         ${setting.customScript}
       `
     }
@@ -122,6 +126,22 @@
     _dataresource = _dataresource.replace(/@sum\$/ig, '*/')
     _customScript = _customScript.replace(/\$sum@/ig, '/*')
     _customScript = _customScript.replace(/@sum\$/ig, '*/')
+
+    let time_id = Utils.getguid().substring(0, 32) || ''
+    _dataresource = _dataresource.replace(/@ID@/ig, `''`)
+    _customScript = _customScript.replace(/@ID@/ig, `''`)
+    _dataresource = _dataresource.replace(/@BID@/ig, `'${BID || ''}'`)
+    _customScript = _customScript.replace(/@BID@/ig, `'${BID || ''}'`)
+    _dataresource = _dataresource.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
+    _customScript = _customScript.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
+    _dataresource = _dataresource.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
+    _customScript = _customScript.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
+    _dataresource = _dataresource.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
+    _customScript = _customScript.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
+    _dataresource = _dataresource.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+    _customScript = _customScript.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+    _dataresource = _dataresource.replace(/@time_id@/ig, `'${time_id}'`)
+    _customScript = _customScript.replace(/@time_id@/ig, `'${time_id}'`)
 
     let regoptions = null
     if (setting.queryType === 'statistics' || _customScript) {
@@ -198,8 +218,8 @@
         `
       }
     } else {
-      LText = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50)
-        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+      LText = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100)
+        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
         ${LText}
       `
     }
@@ -242,7 +262,7 @@
     param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
     param.secretkey = Utils.encrypt('', param.timestamp)
 
-    if (menuType === 'HS') { // 浜戠鏁版嵁楠岃瘉
+    if (window.GLOB.mkHS) { // 浜戠鏁版嵁楠岃瘉
       param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
     }
 
@@ -252,7 +272,7 @@
   /**
    * @description 鑾峰彇绯荤粺瀛樺偍杩囩▼ sPC_Get_TableData 鍚堣鍊肩殑鍙傛暟
    */
-  static getStatQueryDataParams (setting, statFields, search, orderBy, BID, menuType) {
+  static getStatQueryDataParams (setting, statFields, search, orderBy, BID) {
     let param = {
       func: 'sPC_Get_TableData',
       obj_name: 'data',
@@ -272,7 +292,12 @@
     let RoleID = sessionStorage.getItem('role_id') || ''
     let departmentcode = sessionStorage.getItem('departmentcode') || ''
     let organization = sessionStorage.getItem('organization') || ''
+    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+    let nation = sessionStorage.getItem('nation') || ''
+    let province = sessionStorage.getItem('province') || ''
     let city = sessionStorage.getItem('city') || ''
+    let district = sessionStorage.getItem('district') || ''
+    let address = sessionStorage.getItem('address') || ''
 
     if (sessionStorage.getItem('isEditState') === 'true') {
       userName = sessionStorage.getItem('CloudUserName') || ''
@@ -280,8 +305,8 @@
     }
     
     if (setting.customScript) {
-      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50)
-        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+      _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100)
+        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
         ${setting.customScript}
       `
     }
@@ -292,6 +317,22 @@
     _dataresource = _dataresource.replace(/@select\$/ig, '*/')
     _customScript = _customScript.replace(/\$select@/ig, '/*')
     _customScript = _customScript.replace(/@select\$/ig, '*/')
+
+    let time_id = Utils.getguid().substring(0, 32) || ''
+    _dataresource = _dataresource.replace(/@ID@/ig, `''`)
+    _customScript = _customScript.replace(/@ID@/ig, `''`)
+    _dataresource = _dataresource.replace(/@BID@/ig, `'${BID || ''}'`)
+    _customScript = _customScript.replace(/@BID@/ig, `'${BID || ''}'`)
+    _dataresource = _dataresource.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
+    _customScript = _customScript.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
+    _dataresource = _dataresource.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
+    _customScript = _customScript.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
+    _dataresource = _dataresource.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
+    _customScript = _customScript.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
+    _dataresource = _dataresource.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+    _customScript = _customScript.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+    _dataresource = _dataresource.replace(/@time_id@/ig, `'${time_id}'`)
+    _customScript = _customScript.replace(/@time_id@/ig, `'${time_id}'`)
 
     let regoptions = null
     if (setting.queryType === 'statistics' || _customScript) {
@@ -342,8 +383,8 @@
           insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@ 
       `
     } else {
-      LText = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50)
-        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+      LText = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100)
+        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
         ${LText}
       `
     }
@@ -365,7 +406,7 @@
     param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
     param.secretkey = Utils.encrypt('', param.timestamp)
 
-    if (menuType === 'HS') { // 浜戠鏁版嵁楠岃瘉
+    if (window.GLOB.mkHS) { // 浜戠鏁版嵁楠岃瘉
       param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
     }
 
@@ -390,14 +431,13 @@
    * @param {Number}   pageIndex    椤电爜
    * @param {Number}   pageSize     姣忛〉鏁伴噺
    * @param {String}   BID          涓婄骇ID
-   * @param {String}   menuType     鑿滃崟绫诲瀷锛屾櫘閫氳彍鍗曚笌HS
    * @return {Object}  param
    */
-  static getPrevQueryParams (setting, search = [], BID, menuType) {
+  static getPrevQueryParams (setting, search = [], BID) {
     let param = null
 
     if (setting.procMode !== 'inner') {
-      param = this.getDefaultPrevQueryParam(setting, search, menuType)
+      param = this.getDefaultPrevQueryParam(setting, search, BID)
     } else {
       param = Utils.formatCustomMainSearch(search)
       param.func = setting.prevFunc || ''
@@ -413,7 +453,7 @@
   /**
    * @description 鑾峰彇绯荤粺鍓嶇疆鑴氭湰
    */
-  static getDefaultPrevQueryParam (setting, search, menuType) {
+  static getDefaultPrevQueryParam (setting, search, BID) {
     let param = {
       func: 'sPC_TableData_InUpDe',
       exec_type: 'y',
@@ -426,7 +466,12 @@
     let RoleID = sessionStorage.getItem('role_id') || ''
     let departmentcode = sessionStorage.getItem('departmentcode') || ''
     let organization = sessionStorage.getItem('organization') || ''
+    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+    let nation = sessionStorage.getItem('nation') || ''
+    let province = sessionStorage.getItem('province') || ''
     let city = sessionStorage.getItem('city') || ''
+    let district = sessionStorage.getItem('district') || ''
+    let address = sessionStorage.getItem('address') || ''
 
     if (sessionStorage.getItem('isEditState') === 'true') {
       userName = sessionStorage.getItem('CloudUserName') || ''
@@ -441,8 +486,8 @@
 
     if (sql) {
       sql = `/*鍓嶇疆鑴氭湰*/
-        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50)
-        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+        declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100)
+        Select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
         ${sql}
         aaa:
           if @ErrorCode!=''
@@ -450,26 +495,27 @@
       `
 
       let allSearch = Utils.getAllSearchOptions(search)
-      let regoptions = allSearch.map(item => {
-        return {
-          reg: new RegExp('@' + item.key + '@', 'ig'),
-          value: `'${item.value}'`
-        }
-      })
-      regoptions.push({
-        reg: new RegExp('@login_city@', 'ig'),
-        value: `'${city}'`
-      }, {
-        reg: new RegExp('@userName@', 'ig'),
-        value: `'${userName}'`
-      }, {
-        reg: new RegExp('@fullName@', 'ig'),
-        value: `'${fullName}'`
+      allSearch.forEach(item => {
+        sql = sql.replace(new RegExp('@' + item.key + '@', 'ig'), `'${item.value}'`)
       })
 
-      regoptions.forEach(item => {
-        sql = sql.replace(item.reg, item.value)
-      })
+      if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺
+        sql = sql.replace(/\$@/ig, '/*')
+        sql = sql.replace(/@\$/ig, '*/')
+      } else {
+        sql = sql.replace(/@\$|\$@/ig, '')
+      }
+  
+      sql = sql.replace(/@userName@/ig, `'${userName}'`)
+      sql = sql.replace(/@fullName@/ig, `'${fullName}'`)
+
+      sql = sql.replace(/@ID@/ig, `''`)
+      sql = sql.replace(/@BID@/ig, `'${BID || ''}'`)
+      sql = sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
+      sql = sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
+      sql = sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
+      sql = sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+      sql = sql.replace(/@time_id@/ig, `'${Utils.getguid().substring(0, 32) || ''}'`)
 
       // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
       if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
@@ -477,18 +523,11 @@
       }
     }
 
-    if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺
-      sql = sql.replace(/\$@/ig, '/*')
-      sql = sql.replace(/@\$/ig, '*/')
-    } else {
-      sql = sql.replace(/@\$|\$@/ig, '')
-    }
-
     param.LText = Utils.formatOptions(sql)
     param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
     param.secretkey = Utils.encrypt('', param.timestamp)
 
-    if (menuType === 'HS') { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
+    if (window.GLOB.mkHS) { // 鍑芥暟 sPC_TableData_InUpDe 浜戠楠岃瘉
       param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
     }
 
@@ -500,7 +539,7 @@
   /**
    * @description 鑾峰彇绯荤粺鍥炶皟鑴氭湰
    */
-  static getCallBackQueryParams (setting, sql, errSql) {
+  static getCallBackQueryParams (setting, sql, errSql, BID) {
     let param = {
       func: 'sPC_TableData_InUpDe',
       exec_type: 'y',
@@ -511,15 +550,20 @@
     let RoleID = sessionStorage.getItem('role_id') || ''
     let departmentcode = sessionStorage.getItem('departmentcode') || ''
     let organization = sessionStorage.getItem('organization') || ''
+    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+    let nation = sessionStorage.getItem('nation') || ''
+    let province = sessionStorage.getItem('province') || ''
     let city = sessionStorage.getItem('city') || ''
+    let district = sessionStorage.getItem('district') || ''
+    let address = sessionStorage.getItem('address') || ''
 
     if (sessionStorage.getItem('isEditState') === 'true') {
       userName = sessionStorage.getItem('CloudUserName') || ''
       fullName = sessionStorage.getItem('CloudFullName') || ''
     }
 
-    let _prevCustomScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50)
-        Select @ErrorCode='',@retmsg='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+    let _prevCustomScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100)
+        Select @ErrorCode='',@retmsg='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
         ${errSql}
     `
     let _backCustomScript = `
@@ -546,19 +590,27 @@
 
     sql = _prevCustomScript + sql
     sql = sql + _backCustomScript
+    
+    if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺
+      sql = sql.replace(/\$@/ig, '/*')
+      sql = sql.replace(/@\$/ig, '*/')
+    } else {
+      sql = sql.replace(/@\$|\$@/ig, '')
+    }
+
+    sql = sql.replace(/@ID@/ig, `''`)
+    sql = sql.replace(/@BID@/ig, `'${BID || ''}'`)
+    sql = sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`)
+    sql = sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
+    sql = sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`)
+    sql = sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+    sql = sql.replace(/@time_id@/ig, `'${Utils.getguid().substring(0, 32) || ''}'`)
 
     if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
       console.info(sql.replace(/\n\s{8}/ig, '\n'))
     }
 
     param.LText = sql
-    
-    if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺
-      param.LText = param.LText.replace(/\$@/ig, '/*')
-      param.LText = param.LText.replace(/@\$/ig, '*/')
-    } else {
-      param.LText = param.LText.replace(/@\$|\$@/ig, '')
-    }
 
     param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
     param.secretkey = Utils.encrypt('', param.timestamp)
@@ -692,26 +744,26 @@
     let RoleID = sessionStorage.getItem('role_id') || ''
     let departmentcode = sessionStorage.getItem('departmentcode') || ''
     let organization = sessionStorage.getItem('organization') || ''
+    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+    let nation = sessionStorage.getItem('nation') || ''
+    let province = sessionStorage.getItem('province') || ''
     let city = sessionStorage.getItem('city') || ''
+    let district = sessionStorage.getItem('district') || ''
+    let address = sessionStorage.getItem('address') || ''
   
     if (sessionStorage.getItem('isEditState') === 'true') {
       userName = sessionStorage.getItem('CloudUserName') || ''
       fullName = sessionStorage.getItem('CloudFullName') || ''
     }
-    _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50)
-      select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+    _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100)
+      select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
       ${_customScript}
     `
   }
 
-  // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
-  if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
-    _customScript && console.info(`${setting.$name ? `/*${setting.$name} 鑷畾涔夎剼鏈紙鍚屾鏌ヨ锛�*/\n` : ''}${_dataresource ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${_customScript}`)
-    _dataresource && console.info(`${setting.$name ? `/*${setting.$name} 鏁版嵁婧愶紙鍚屾鏌ヨ锛�*/\n` : ''}` + _dataresource)
-  }
-
   return {
     name: dataName,
+    $name: setting.$name,
     columns: columns,
     par_tablename: '',
     type: format === 'array' ? format : '',
@@ -727,13 +779,18 @@
  * @description 鐢熸垚sPC_Get_structured_data璇锋眰鍙傛暟
  * 1銆佹妸澶ф帴鍙PC_Get_structured_data鐨刲text鎷嗘垚涓変唤锛岀涓�娈碉細@LText1锛岀浜屾@LText锛岀涓夋@LText2
  */
-export function getStructuredParams (params, config, BID = '') {
+export function getStructuredParams (params, config, BID) {
   let LText_field = []
   let diffUser = false
   let transaction = false
-  
+  let time_id = Utils.getguid().substring(0, 32) || ''
+  let loginId = `'${sessionStorage.getItem('LoginUID') || ''}'`
+  let sessionId = `'${localStorage.getItem('SessionUid') || ''}'`
+  let userId = `'${sessionStorage.getItem('UserID') || ''}'`
+
   let _LText = params.map((item, index) => {
     let _script = item.script
+    let _sql = item.sql
 
     if (!diffUser && (/@userid@/ig.test(item.sql) || /@userid@/ig.test(_script))) {
       diffUser = true
@@ -742,10 +799,31 @@
       transaction = true
     }
 
+    _sql = _sql.replace(/@ID@/ig, `''`)
+    _script = _script.replace(/@ID@/ig, `''`)
+    _sql = _sql.replace(/@BID@/ig, `'${BID || ''}'`)
+    _script = _script.replace(/@BID@/ig, `'${BID || ''}'`)
+    _sql = _sql.replace(/@LoginUID@/ig, loginId)
+    _script = _script.replace(/@LoginUID@/ig, loginId)
+    _sql = _sql.replace(/@SessionUid@/ig, sessionId)
+    _script = _script.replace(/@SessionUid@/ig, sessionId)
+    _sql = _sql.replace(/@UserID@/ig, userId)
+    _script = _script.replace(/@UserID@/ig, userId)
+    _sql = _sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+    _script = _script.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+    _sql = _sql.replace(/@time_id@/ig, `'${time_id}'`)
+    _script = _script.replace(/@time_id@/ig, `'${time_id}'`)
+
+    // 娴嬭瘯绯荤粺鎵撳嵃鏌ヨ璇彞
+    if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
+      _script && console.info(`${item.$name ? `/*${item.$name} 鑷畾涔夎剼鏈紙鍚屾鏌ヨ锛�*/\n` : ''}${_sql ? '' : '/*涓嶆墽琛岄粯璁ql*/\n'}${_script}`)
+      _sql && console.info(`${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`)
     })
-    return `Select '${item.name}' as tablename,'${window.btoa(window.encodeURIComponent(item.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.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`
   })
 
   let param = {
diff --git a/src/utils/utils.js b/src/utils/utils.js
index 413aa1e..a15f80a 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -39,6 +39,26 @@
 
 export default class Utils {
   /**
+   * @description 鑾峰彇浼氬憳绛夌骇
+   * @return {String}  level
+   */
+  static getMemberLevel () {
+    let _level = 10
+    let _Mlevel = sessionStorage.getItem('Member_Level')
+
+    if (_Mlevel) {
+      if (_Mlevel === md5('mksoft' + window.GLOB.appkey + new Date().getFullYear() + new Date().getMonth() + 10)) {
+        _level = 10
+      } else if (_Mlevel === md5('mksoft' + window.GLOB.appkey + new Date().getFullYear() + new Date().getMonth() + 20)) {
+        _level = 20
+      } else if (_Mlevel === md5('mksoft' + window.GLOB.appkey + new Date().getFullYear() + new Date().getMonth() + 30)) {
+        _level = 30
+      }
+    }
+    return _level
+  }
+
+  /**
    * @description 鏁版嵁婧愬悕绉帮紝鐢ㄤ簬缁熶竴鏌ヨ
    * @return {String}  name
    */
@@ -74,12 +94,11 @@
   static getguid () {
     // 浜х敓涓�涓柊鐨凣UID鍊�
     let uuid = []
-    let d = new Date()
     let options = '0123456789abcdefghigklmnopqrstuv'
     for (let i = 0; i < 19; i++) {
       uuid.push(options.substr(Math.floor(Math.random() * 0x20), 1))
     }
-    uuid = moment().format('YYYYMMDDHHmmss') + d.getMilliseconds() + uuid.join('')
+    uuid = moment().format('YYYYMMDDHHmmssSSS') + uuid.join('')
     return uuid.toUpperCase()
   }
 
@@ -748,7 +767,7 @@
     let arrfield = [item.valueField, item.valueText]
 
     if (item.type === 'checkcard') {
-      arrfield = item.fields.map(f => f.field)
+      arrfield = item.fields ? item.fields.map(f => f.field) : []
       arrfield.push(item.cardValField)
       if (item.urlField) {
         arrfield.push(item.urlField)
@@ -796,6 +815,9 @@
       sql = sql.replace(/@db@/ig, window.GLOB.externalDatabase)
     }
 
+    sql = sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`)
+    sql = sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`)
+
     if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
       console.info(sql)
     }
@@ -822,7 +844,12 @@
   let RoleID = sessionStorage.getItem('role_id') || ''
   let departmentcode = sessionStorage.getItem('departmentcode') || ''
   let organization = sessionStorage.getItem('organization') || ''
+  let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+  let nation = sessionStorage.getItem('nation') || ''
+  let province = sessionStorage.getItem('province') || ''
   let city = sessionStorage.getItem('city') || ''
+  let district = sessionStorage.getItem('district') || ''
+  let address = sessionStorage.getItem('address') || ''
   let _sheet = item.sheet
 
   if (sessionStorage.getItem('isEditState') === 'true') {
@@ -1069,9 +1096,9 @@
     _sql = `
       /* 绯荤粺鐢熸垚 */
       declare @${sheet} table (${declarefields.join(',')},jskey nvarchar(50),BID nvarchar(50) )
-      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)
+      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)
       
-      Select  @ErrorCode='', @retmsg='', @UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+      Select  @ErrorCode='', @retmsg='', @UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
       ${_initCustomScript}
       `
     _sqlInsert = `Insert into @${sheet} (${fields},jskey,BID)`
@@ -1104,9 +1131,9 @@
     _sql = `
       /* 绯荤粺鐢熸垚 */
       declare @${sheet} table (jskey nvarchar(50))
-      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)
+      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)
       
-      Select  @ErrorCode='', @retmsg='', @UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+      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}'
       `
   }
 
@@ -1136,7 +1163,13 @@
   let RoleID = sessionStorage.getItem('role_id') || ''
   let departmentcode = sessionStorage.getItem('departmentcode') || ''
   let organization = sessionStorage.getItem('organization') || ''
+  let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+  let nation = sessionStorage.getItem('nation') || ''
+  let province = sessionStorage.getItem('province') || ''
   let city = sessionStorage.getItem('city') || ''
+  let district = sessionStorage.getItem('district') || ''
+  let address = sessionStorage.getItem('address') || ''
+
   let _sheet = btn.sheet
   let BID = data[0].$$BID || ''
 
@@ -1281,9 +1314,9 @@
     _sql = `
       /* 绯荤粺鐢熸垚 */
       declare @${sheet} table (${declarefields.join(',')},jskey nvarchar(50),data_type nvarchar(50),BID nvarchar(50) )
-      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)
+      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)
       
-      Select  @ErrorCode='', @retmsg='', @UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+      Select  @ErrorCode='', @retmsg='', @UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
       ${_initCustomScript}
       `
     _sqlInsert = `Insert into @${sheet} (${fields},jskey,data_type,BID)`
@@ -1316,9 +1349,9 @@
     _sql = `
       /* 绯荤粺鐢熸垚 */
       declare @${sheet} table (jskey nvarchar(50))
-      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)
+      Declare @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)
       
-      Select  @ErrorCode='', @retmsg='', @UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+      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}'
       `
   }
 
@@ -1385,7 +1418,7 @@
   })
 
   // 闇�瑕佸0鏄庣殑鍙橀噺闆�
-  let _vars = ['tbid', 'errorcode', 'retmsg', 'billcode', 'bvoucher', 'fibvoucherdate', 'fiyear', 'username', 'fullname', 'modulardetailcode', 'roleid', 'mk_departmentcode', 'mk_organization', 'login_city', 'bid']
+  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', 'bid']
 
   // 涓婚敭瀛楁
   let primaryKey = setting.primaryKey || 'id'
@@ -1450,7 +1483,7 @@
   }
 
   // 娣诲姞鏁版嵁涓瓧娈碉紝琛ㄥ崟鍊间紭鍏�(鎸夐挳涓嶉�夎鎴栧琛屾嫾鎺ユ椂璺宠繃)
-  if (data && !btn.$forbid && btn.Ot !== 'notRequired' && btn.Ot !== 'requiredOnce') {
+  if (data && btn.Ot !== 'notRequired' && btn.Ot !== 'requiredOnce') {
     datavars = {...data, ...datavars}
 
     const setField = (col) => {
@@ -1511,7 +1544,7 @@
     _declarefields = ',' + _declarefields
   }
   _sql = `/* 绯荤粺鐢熸垚 */
-      Declare @tbid nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@BillCode nvarchar(50),@BVoucher nvarchar(50),@FIBVoucherDate nvarchar(50), @FiYear nvarchar(50), @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50),@bid nvarchar(50),@ModularDetailCode nvarchar(50)${_declarefields}
+      Declare @tbid nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@BillCode nvarchar(50),@BVoucher nvarchar(50),@FIBVoucherDate nvarchar(50), @FiYear nvarchar(50),@ModularDetailCode nvarchar(50), @UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@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)${_declarefields}
     `
 
   let userName = sessionStorage.getItem('User_Name') || ''
@@ -1519,7 +1552,12 @@
   let RoleID = sessionStorage.getItem('role_id') || ''
   let departmentcode = sessionStorage.getItem('departmentcode') || ''
   let organization = sessionStorage.getItem('organization') || ''
+  let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+  let nation = sessionStorage.getItem('nation') || ''
+  let province = sessionStorage.getItem('province') || ''
   let city = sessionStorage.getItem('city') || ''
+  let district = sessionStorage.getItem('district') || ''
+  let address = sessionStorage.getItem('address') || ''
 
   if (sessionStorage.getItem('isEditState') === 'true') {
     userName = sessionStorage.getItem('CloudUserName') || ''
@@ -1529,7 +1567,7 @@
   // 鍒濆鍖栧嚟璇佸強鐢ㄦ埛淇℃伅瀛楁
   _sql += `
       /* 鍑瘉鍙婄敤鎴蜂俊鎭垵濮嬪寲璧嬪�� */
-      select @BVoucher='',@FIBVoucherDate='',@FiYear='',@ErrorCode='',@retmsg='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}', @BillCode='', @ModularDetailCode=''
+      select @BVoucher='',@FIBVoucherDate='',@FiYear='',@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}', @BillCode='', @ModularDetailCode=''
       `
 
   // 琛ㄥ崟鍙橀噺璧嬪��
@@ -1609,9 +1647,6 @@
         }
       })
       regoptions.push({
-        reg: new RegExp('@login_city@', 'ig'),
-        value: `'${city}'`
-      }, {
         reg: new RegExp('@userName@', 'ig'),
         value: `'${userName}'`
       }, {
@@ -2047,6 +2082,22 @@
       aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
   }
 
+  let time_id = []
+  let options = '0123456789abcdefghigklmnopqrstuv'
+  for (let i = 0; i < 15; i++) {
+    time_id.push(options.substr(Math.floor(Math.random() * 0x20), 1))
+  }
+  time_id = moment().format('YYYYMMDDHHmmssSSS') + time_id.join('')
+  time_id = time_id.toUpperCase()
+
+  _sql = _sql.replace(/@ID@/ig, `'${primaryId || ''}'`)
+  _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(/@time_id@/ig, `'${time_id}'`)
+
   if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
     // _sql = _sql.replace(/\n\s{8}/ig, '\n')
     console.info(_sql)
@@ -2067,26 +2118,30 @@
  */
 export function getMark (marks, record, style = {}) {
   let icon = null
-  let color = null
+  let innerStyle = null
   let position = null
   style = JSON.parse(JSON.stringify(style))
 
   marks.some(mark => {
-    let originVal = record[mark.field[0]] + ''
+    let originVal = record[mark.field[0]]
     let contrastVal = ''
     let result = false
 
     if (mark.field[1] === 'static') {
-      contrastVal = mark.contrastValue + ''
+      contrastVal = mark.contrastValue
     } else {
-      contrastVal = record[mark.field[2]] + ''
+      contrastVal = record[mark.field[2]]
     }
+
+    if (originVal === undefined || contrastVal === undefined) return false
 
     if (mark.match === '=') {
       result = originVal === contrastVal
     } else if (mark.match === '!=') {
       result = originVal !== contrastVal
     } else if (mark.match === 'like') {
+      originVal = originVal + ''
+      contrastVal = contrastVal + ''
       result = originVal.indexOf(contrastVal) > -1
     } else if (mark.match === '>') {
       result = parseFloat(originVal) > parseFloat(contrastVal)
@@ -2100,20 +2155,24 @@
 
     if (type === 'font') {
       style.color = mark.color
+      innerStyle = {color: mark.color}
     } else if (type === 'background') {
       style.background = mark.color
       if (mark.fontColor) {
         style.color = mark.fontColor
+        innerStyle = {color: mark.fontColor}
       }
     } else if (type === 'underline') {
       style.textDecoration = 'underline'
       style.color = mark.color
+      innerStyle = {color: mark.color, textDecoration: 'underline'}
     } else if (type === 'line-through') {
       style.textDecoration = 'line-through'
       style.color = mark.color
+      innerStyle = {color: mark.color, textDecoration: 'line-through'}
     } else if (type.indexOf('icon') > -1) {
       icon = mark.signType[mark.signType.length - 1]
-      color = mark.color
+      innerStyle = {color: mark.color}
       if (type === 'iconfront' || mark.signType[1] === 'front') {
         position = 'front'
       } else {
@@ -2127,7 +2186,7 @@
   return {
     style,
     icon,
-    color,
+    innerStyle,
     position
   }
 }
diff --git a/src/views/appmanage/index.jsx b/src/views/appmanage/index.jsx
index bfff01d..7e3734a 100644
--- a/src/views/appmanage/index.jsx
+++ b/src/views/appmanage/index.jsx
@@ -1238,7 +1238,7 @@
             <ScriptForm applist={applist} wrappedComponentRef={(inst) => this.scriptRef = inst} inputSubmit={this.submitScript} />
           </Modal>
           <Modal
-            title={'缂栬緫瀛愬簲鐢�'}
+            title={subVisible === 'plus' ? '娣诲姞瀛愬簲鐢�' : '缂栬緫瀛愬簲鐢�'}
             width={'850px'}
             maskClosable={false}
             visible={subVisible !== false}
diff --git a/src/views/appmanage/scriptform/index.jsx b/src/views/appmanage/scriptform/index.jsx
index be8c9af..67c6224 100644
--- a/src/views/appmanage/scriptform/index.jsx
+++ b/src/views/appmanage/scriptform/index.jsx
@@ -17,7 +17,7 @@
   }
 
   state = {
-    type: 'subapp',
+    type: 'view',
     sublist: [],
     views: [],
     appId: '',
@@ -43,7 +43,9 @@
 
     this.viewList = {}
 
-    this.setState({sublist, appId, subAppId})
+    this.setState({sublist, appId, subAppId}, () => {
+      this.getViews()
+    })
   }
 
   /**
@@ -166,7 +168,7 @@
               </Tooltip>
             }>
               {getFieldDecorator('VType', {
-                initialValue: 'subapp',
+                initialValue: 'view',
                 rules: [{
                   required: true,
                   message: '璇烽�夋嫨绫诲瀷!'
diff --git a/src/views/appmanage/submutilform/index.jsx b/src/views/appmanage/submutilform/index.jsx
index 8f21434..59809f0 100644
--- a/src/views/appmanage/submutilform/index.jsx
+++ b/src/views/appmanage/submutilform/index.jsx
@@ -138,20 +138,20 @@
                 initialValue: card ? card.css : 'bg_black_style_blue'
               })(
                 <Select>
-                  <Select.Option value="bg_black_style_blue">钃濊壊</Select.Option>
-                  <Select.Option value="bg_black_style_red">绾㈣壊</Select.Option>
-                  <Select.Option value="bg_black_style_orange_red">姗欑孩鑹�</Select.Option>
-                  <Select.Option value="bg_black_style_orange">姗欒壊</Select.Option>
-                  <Select.Option value="bg_black_style_orange_yellow">姗欓粍鑹�</Select.Option>
-                  <Select.Option value="bg_black_style_yellow">榛勮壊</Select.Option>
-                  <Select.Option value="bg_black_style_yellow_green">榛勭豢鑹�</Select.Option>
-                  <Select.Option value="bg_black_style_green">缁胯壊</Select.Option>
-                  <Select.Option value="bg_black_style_cyan">闈掕壊</Select.Option>
-                  <Select.Option value="bg_black_style_blue_purple">钃濈传鑹�</Select.Option>
-                  <Select.Option value="bg_black_style_purple">绱壊</Select.Option>
-                  <Select.Option value="bg_black_style_magenta">娲嬬孩鑹�</Select.Option>
-                  <Select.Option value="bg_black_style_grass_green">鑽夌豢鑹�</Select.Option>
-                  <Select.Option value="bg_black_style_deep_red">娣辩孩鑹�</Select.Option>
+                  <Select.Option value="bg_black_style_blue"><span className="color-block" style={{background: '#1890ff'}}></span>钃濊壊</Select.Option>
+                  <Select.Option value="bg_black_style_red"><span className="color-block" style={{background: '#f5222d'}}></span>绾㈣壊</Select.Option>
+                  <Select.Option value="bg_black_style_orange_red"><span className="color-block" style={{background: '#fa541c'}}></span>姗欑孩鑹�</Select.Option>
+                  <Select.Option value="bg_black_style_orange"><span className="color-block" style={{background: '#fa8c16'}}></span>姗欒壊</Select.Option>
+                  <Select.Option value="bg_black_style_orange_yellow"><span className="color-block" style={{background: '#faad14'}}></span>姗欓粍鑹�</Select.Option>
+                  <Select.Option value="bg_black_style_yellow"><span className="color-block" style={{background: '#fadb14'}}></span>榛勮壊</Select.Option>
+                  <Select.Option value="bg_black_style_yellow_green"><span className="color-block" style={{background: '#a0d911'}}></span>榛勭豢鑹�</Select.Option>
+                  <Select.Option value="bg_black_style_green"><span className="color-block" style={{background: '#52c41a'}}></span>缁胯壊</Select.Option>
+                  <Select.Option value="bg_black_style_cyan"><span className="color-block" style={{background: '#13c2c2'}}></span>闈掕壊</Select.Option>
+                  <Select.Option value="bg_black_style_blue_purple"><span className="color-block" style={{background: '#2f54eb'}}></span>钃濈传鑹�</Select.Option>
+                  <Select.Option value="bg_black_style_purple"><span className="color-block" style={{background: '#722ed1'}}></span>绱壊</Select.Option>
+                  <Select.Option value="bg_black_style_magenta"><span className="color-block" style={{background: '#eb2f96'}}></span>娲嬬孩鑹�</Select.Option>
+                  <Select.Option value="bg_black_style_grass_green"><span className="color-block" style={{background: '#aeb303'}}></span>鑽夌豢鑹�</Select.Option>
+                  <Select.Option value="bg_black_style_deep_red"><span className="color-block" style={{background: '#c32539'}}></span>娣辩孩鑹�</Select.Option>
                 </Select>
               )}
             </Form.Item>
@@ -237,7 +237,12 @@
             </Form.Item>
           </Col> : null}
           {exts.includes('share') ? <Col span={12}>
-            <Form.Item label="鍒嗕韩閾炬帴">
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="鍒嗕韩鐨勯摼鎺ヤ负鐢ㄦ埛娴忚鐨勯〉闈㈠湴鍧�鎴栧綋鍓嶅簲鐢ㄧ殑鍏ュ彛鍦板潃銆傛敞锛氬彲鍦ㄩ〉闈腑鑷畾涔夎缃��">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鍒嗕韩閾炬帴
+              </Tooltip>
+            }>
               {getFieldDecorator('share_link', {
                 initialValue: card ? card.share_link || 'main' : 'main'
               })(
@@ -282,7 +287,7 @@
               </Tooltip>
             }>
               {getFieldDecorator('delay', {
-                initialValue: card ? card.delay || 0 : 0
+                initialValue: card ? card.delay || 0 : 200
               })(<InputNumber min={0} max={5000} precision={0} onPressEnter={this.handleSubmit}/>)}
             </Form.Item>
           </Col> : null}
diff --git a/src/views/appmanage/submutilform/index.scss b/src/views/appmanage/submutilform/index.scss
index 7b121c8..3bed946 100644
--- a/src/views/appmanage/submutilform/index.scss
+++ b/src/views/appmanage/submutilform/index.scss
@@ -20,4 +20,24 @@
       padding-top: 7px;
     }
   }
+  .color-block {
+    display: inline-block;
+    width: 16px;
+    height: 16px;
+    margin-right: 5px;
+    vertical-align: middle;
+    position: relative;
+    top: -2px;
+  }
+}
+.ant-select-dropdown {
+  .color-block {
+    display: inline-block;
+    width: 16px;
+    height: 16px;
+    margin-right: 5px;
+    vertical-align: middle;
+    position: relative;
+    top: -2px;
+  }
 }
\ No newline at end of file
diff --git a/src/views/basedesign/index.jsx b/src/views/basedesign/index.jsx
new file mode 100644
index 0000000..b742a63
--- /dev/null
+++ b/src/views/basedesign/index.jsx
@@ -0,0 +1,253 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { notification, Spin, ConfigProvider } from 'antd'
+import enUS from 'antd/es/locale/en_US'
+import zhCN from 'antd/es/locale/zh_CN'
+
+import Api from '@/api'
+import asyncComponent from '@/utils/asyncComponent'
+import asyncLoadComponent from '@/utils/asyncLoadComponent'
+import './index.scss'
+
+const _locale = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
+const Header = asyncComponent(() => import('@/menu/header'))
+const ComTableConfig = asyncLoadComponent(() => import('@/templates/comtableconfig'))
+const TreePageConfig = asyncLoadComponent(() => import('@/templates/treepageconfig'))
+const CalendarPageConfig = asyncLoadComponent(() => import('@/templates/calendarconfig'))
+const FormTabConfig = asyncLoadComponent(() => import('@/templates/formtabconfig'))
+const ModalConfig = asyncLoadComponent(() => import('@/templates/modalconfig'))
+const SubTable = asyncLoadComponent(() => import('@/templates/subtableconfig'))
+
+document.body.className = ''
+sessionStorage.setItem('isEditState', 'true')
+
+class BaseDesign extends Component {
+  static propTpyes = {
+    menulist: PropTypes.any,     // 涓夌骇鑿滃崟鍒楄〃
+    exitEdit: PropTypes.func,    // 閫�鍑虹紪杈戠姸鎬�
+    supMenu: PropTypes.object,   // 瀵瑰簲鐨勪笂绾ц彍鍗�
+    supMenuList: PropTypes.array // 涓婄骇鑿滃崟鍒楄〃锛岀敤浜庝笁绾ц彍鍗曞垏鎹笂绾ц彍鍗�
+  }
+
+  state = {
+    loading: false,         // 缂栬緫鑿滃崟鎴栦娇鐢ㄥ凡浣跨敤妯℃澘鏃讹紝鑾峰彇閰嶇疆淇℃伅
+    btnParam: null,         // 缂栬緫鎸夐挳鐨勯厤缃俊鎭�
+    menulist: null,         // 缂栬緫涓殑鑿滃崟
+    tabview: '',            // 閫夋嫨妯℃澘绐楀彛锛坱emplate锛夈�佸熀纭�琛ㄦ牸閰嶇疆锛圕ommonTable锛夈�佽〃鍗曪紙Modal锛夈�佸瓙琛紙SubTable锛�
+    editMenu: null,         // 缂栬緫鑿滃崟
+    editAction: null,       // 缂栬緫鎸夐挳
+    editTab: null,          // 缂栬緫鏍囩
+    tabConfig: null,        // 鏍囩閰嶇疆淇℃伅
+    editSubTab: null,       // 缂栬緫瀛愭爣绛撅紙鏍囩涓殑鏍囩锛�
+    subTabConfig: null,     // 瀛愭爣绛鹃厤缃俊鎭�
+    subConfig: null,        // 瀛愰厤缃俊鎭�
+    btnTab: null,           // 鎵撳紑鏂版爣绛炬垨褰撳墠椤甸潰鍒锋柊鐨勬寜閽�
+    btnTabConfig: null,     // 鎵撳紑鏂版爣绛炬寜閽厤缃�
+    handleMVisible: false,  // 娣诲姞鎴栦慨鏀硅彍鍗曟ā鎬佹锛堣鑹叉潈闄愬垎閰嶇瓑锛�
+    sysMenu: null,          // 娣诲姞鎴栫紪杈戣彍鍗曪紙瑙掕壊鏉冮檺鍒嗛厤绛夛級
+    change: false
+  }
+
+  UNSAFE_componentWillMount() {
+    try {
+      let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
+
+      this.getMenuParam(param)
+    } catch (e) {
+      notification.warning({
+        top: 92,
+        message: '鑿滃崟淇℃伅瑙f瀽閿欒锛�',
+        duration: 5
+      })
+    }
+  }
+
+  getMenuParam = (editMenu) => {
+    editMenu.fstMenuId = editMenu.FstId
+    editMenu.supMenuList = []
+    editMenu.fstMenuList = []
+
+    let tree = sessionStorage.getItem('menuTree')
+    if (tree) {
+      tree = JSON.parse(tree)
+      editMenu.fstMenuList = tree
+
+      tree.forEach(item => {
+        if (item.MenuID === editMenu.FstId) {
+          editMenu.supMenuList = item.children
+        }
+      })
+    }
+
+    let param = {
+      func: 'sPC_Get_LongParam',
+      MenuID: editMenu.MenuID
+    }
+
+    this.setState({
+      loading: true
+    })
+
+    Api.getSystemConfig(param).then(res => {
+      if (res.status) {
+        editMenu.open_edition = res.open_edition || ''
+        editMenu.LongParam = ''
+
+        if (res.LongParam) {
+          let _LongParam = ''
+          try {
+            _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
+          } catch (e) {
+            console.warn('Parse Failure')
+            _LongParam = ''
+          }
+          editMenu.LongParam = _LongParam
+        } else if (editMenu.PageParam.copyMenuId) {
+          let _param = {
+            func: 'sPC_Get_LongParam',
+            MenuID: editMenu.PageParam.copyMenuId
+          }
+      
+          Api.getSystemConfig(_param).then(res => {
+            if (res.status) {
+              if (res.LongParam) {
+                let _LongParam = ''
+                try {
+                  _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
+                  _LongParam.type = 'user'
+                } catch (e) {
+                  console.warn('Parse Failure')
+                  _LongParam = ''
+                }
+                editMenu.LongParam = _LongParam
+              }
+              
+              this.setState({
+                editMenu: editMenu,
+                loading: false,
+                tabview: editMenu.type
+              })
+            } else {
+              this.setState({
+                loading: false
+              })
+              notification.warning({
+                top: 92,
+                message: res.message,
+                duration: 5
+              })
+            }
+          })
+          return
+        }
+        
+        this.setState({
+          editMenu: editMenu,
+          loading: false,
+          tabview: editMenu.type
+        })
+      } else {
+        this.setState({
+          loading: false
+        })
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  handleView = (param) => {
+    this.setState({
+      tabview: ''
+    }, () => {
+      if (param) {
+        this.setState(param)
+      } else {
+        window.close()
+      }
+    })
+  }
+
+  render () {
+    const { loading } = this.state
+
+    return (
+      <div className="mk-base-design-wrap">
+        <ConfigProvider locale={_locale}>
+          
+          <Header/>
+          {this.state.tabview === 'TreePage' ?
+            <TreePageConfig
+              menu={this.state.editMenu}
+              reloadmenu={() => {localStorage.setItem('menuUpdate', new Date().getTime())}}
+              handleView={this.handleView}
+            /> : null
+          }
+          {this.state.tabview === 'CalendarPage' ?
+            <CalendarPageConfig
+              menu={this.state.editMenu}
+              reloadmenu={() => {localStorage.setItem('menuUpdate', new Date().getTime())}}
+              handleView={this.handleView}
+            /> : null
+          }
+          {this.state.tabview === 'CommonTable' ?
+            <ComTableConfig
+              menu={this.state.editMenu}
+              reloadmenu={() => {localStorage.setItem('menuUpdate', new Date().getTime())}}
+              handleView={this.handleView}
+            /> : null
+          }
+          {this.state.tabview === 'Modal' ?
+            <ModalConfig
+              menu={this.state.editMenu}
+              editTab={this.state.editTab}
+              tabConfig={this.state.tabConfig}
+              editSubTab={this.state.editSubTab}
+              subTabConfig={this.state.subTabConfig}
+              btnTab={this.state.btnTab}
+              btnTabConfig={this.state.btnTabConfig}
+              editAction={this.state.editAction}
+              subConfig={this.state.subConfig}
+              handleView={this.handleView}
+            /> : null
+          }
+          {this.state.tabview === 'SubTable' ?
+            <SubTable
+              menu={this.state.editMenu}
+              editTab={this.state.editTab}
+              editSubTab={this.state.editSubTab}
+              tabConfig={this.state.tabConfig}
+              btnTab={this.state.btnTab}
+              btnTabConfig={this.state.btnTabConfig}
+              config={this.state.subConfig}
+              handleView={this.handleView}
+            /> : null
+          }
+          {this.state.tabview === 'FormTab' ?
+            <FormTabConfig
+              menu={this.state.editMenu}
+              btnTab={this.state.btnTab}
+              config={this.state.subConfig}
+              handleView={this.handleView}
+            /> : null
+          }
+          {loading ? <Spin className="loading-view" size="large"/> : null}
+        </ConfigProvider>
+      </div>
+    )
+  }
+}
+
+export default BaseDesign
\ No newline at end of file
diff --git a/src/views/basedesign/index.scss b/src/views/basedesign/index.scss
new file mode 100644
index 0000000..e6d64bb
--- /dev/null
+++ b/src/views/basedesign/index.scss
@@ -0,0 +1,7 @@
+.mk-base-design-wrap {
+  .loading-view {
+    position: absolute;
+    left: calc(50vw - 22px);
+    top: calc(30vh + 48px);
+  }
+}
diff --git a/src/templates/menuconfig/editthdmenu/menuform/index.jsx b/src/views/basedesign/menuform/index.jsx
similarity index 84%
rename from src/templates/menuconfig/editthdmenu/menuform/index.jsx
rename to src/views/basedesign/menuform/index.jsx
index c86cde8..5e09244 100644
--- a/src/templates/menuconfig/editthdmenu/menuform/index.jsx
+++ b/src/views/basedesign/menuform/index.jsx
@@ -8,18 +8,16 @@
 class MainSearch extends Component {
   static propTpyes = {
     menu: PropTypes.object,      // 鑿滃崟淇℃伅
-    dict: PropTypes.object,      // 瀛楀吀椤�
-    supMenuList: PropTypes.any,  // 琛ㄦ牸鏁版嵁
     inputSubmit: PropTypes.func  // 鍥炶溅鎻愪氦
   }
 
   state = {
-    menu: null
+    supMenuList: []
   }
 
   UNSAFE_componentWillMount () {
     this.setState({
-      menu: this.props.menu
+      supMenuList: this.props.menu.supMenuList
     })
   }
 
@@ -30,9 +28,15 @@
 
     if (submenu) {
       this.setState({
-        menu: {...menu, supMenuList: submenu.children}
+        supMenuList: submenu.children
       }, () => {
         this.props.form.setFieldsValue({ParentID: submenu.children[0] ? submenu.children[0].MenuID : ''})
+      })
+    } else {
+      this.setState({
+        supMenuList: []
+      }, () => {
+        this.props.form.setFieldsValue({ParentID: ''})
       })
     }
   }
@@ -74,14 +78,14 @@
     return (
       <Form {...formItemLayout} style={{paddingRight: '20px'}} onKeyDown={this.onEnterSubmit}>
         <Row gutter={24}>
-          <Col span={24}>
+          <Col span={22}>
             <Form.Item label={'涓�绾ц彍鍗�'}>
               {getFieldDecorator('fstMenuId', {
                 initialValue: menu.fstMenuId,
                 rules: [
                   {
                     required: true,
-                    message: this.props.dict['form.required.select'] + '涓婄骇鑿滃崟!'
+                    message: '璇烽�夋嫨涓婄骇鑿滃崟!'
                   }
                 ]
               })(
@@ -97,14 +101,14 @@
               )}
             </Form.Item>
           </Col>
-          <Col span={24}>
+          <Col span={22}>
             <Form.Item label={'浜岀骇鑿滃崟'}>
               {getFieldDecorator('ParentID', {
                 initialValue: menu.ParentId,
                 rules: [
                   {
                     required: true,
-                    message: this.props.dict['form.required.select'] + '涓婄骇鑿滃崟!'
+                    message: '璇烽�夋嫨涓婄骇鑿滃崟!'
                   }
                 ]
               })(
@@ -119,40 +123,40 @@
               )}
             </Form.Item>
           </Col>
-          <Col span={24}>
+          <Col span={22}>
             <Form.Item label={'鑿滃崟鍚嶇О'}>
               {getFieldDecorator('MenuName', {
                 initialValue: menu.MenuName || '',
                 rules: [
                   {
                     required: true,
-                    message: this.props.dict['form.required.input'] + '鑿滃崟鍚嶇О!'
+                    message: '璇疯緭鍏ヨ彍鍗曞悕绉�!'
                   }
                 ]
               })(<Input placeholder="" autoFocus autoComplete="off" />)}
             </Form.Item>
           </Col>
-          <Col span={24}>
+          <Col span={22}>
             <Form.Item label={'鑿滃崟鍙傛暟'}>
               {getFieldDecorator('MenuNo', {
                 initialValue: menu.MenuNo || '',
                 rules: [
                   {
                     required: true,
-                    message: this.props.dict['form.required.input'] + '鑿滃崟鍙傛暟!'
+                    message: '璇疯緭鍏ヨ彍鍗曞弬鏁�!'
                   }
                 ]
               })(<Input placeholder="" autoComplete="off" />)}
             </Form.Item>
           </Col>
-          {menu.Template === 'NewPage' ? <Col span={24}>
+          {menu.Template === 'NewPage' ? <Col span={22}>
             <Form.Item label={'閾炬帴鍦板潃'}>
               {getFieldDecorator('url', {
                 initialValue: menu.url || '',
                 rules: [
                   {
                     required: true,
-                    message: this.props.dict['form.required.input'] + '椤甸潰鍦板潃!'
+                    message: '璇疯緭鍏ラ〉闈㈠湴鍧�!'
                   },
                   {
                     max: 1024,
diff --git a/src/templates/menuconfig/editthdmenu/menuform/index.scss b/src/views/basedesign/menuform/index.scss
similarity index 100%
copy from src/templates/menuconfig/editthdmenu/menuform/index.scss
copy to src/views/basedesign/menuform/index.scss
diff --git a/src/views/billprint/index.jsx b/src/views/billprint/index.jsx
index d1e8084..a571e21 100644
--- a/src/views/billprint/index.jsx
+++ b/src/views/billprint/index.jsx
@@ -37,6 +37,7 @@
     data: '',
     tempId: '',
     config: null,
+    urlParam: null,
     auto: true
   }
 
@@ -58,7 +59,8 @@
         sessionStorage.setItem('localDataM', param.dataM || '')
         this.setState({
           BID: param.id || '',
-          tempId: param.tempId
+          tempId: param.tempId,
+          urlParam: param
         }, () => {
           this.getMenuParam()
         })
@@ -135,7 +137,7 @@
   }
 
   getMenuParam = () => {
-    const { tempId, BID } = this.state
+    const { tempId, BID, urlParam } = this.state
 
     let _param = {
       func: 'sPC_Get_LongParam',
@@ -225,7 +227,6 @@
 
         let userName = sessionStorage.getItem('User_Name') || ''
         let fullName = sessionStorage.getItem('Full_Name') || ''
-        let city = sessionStorage.getItem('city') || ''
 
         if (sessionStorage.getItem('isEditState') === 'true') {
           userName = sessionStorage.getItem('CloudUserName') || ''
@@ -234,14 +235,23 @@
 
         let regs = [
           { reg: /@userName@/ig, value: `'${userName}'` },
-          { reg: /@fullName@/ig, value: `'${fullName}'` },
-          { reg: /@login_city@/ig, value: `'${city}'` }
+          { reg: /@fullName@/ig, value: `'${fullName}'` }
         ]
         
         if (window.GLOB.externalDatabase !== null) {
           regs.push({
             reg: /@db@/ig,
             value: window.GLOB.externalDatabase
+          })
+        }
+
+        if (config.urlFields) {
+          config.urlFields.forEach(field => {
+            let val = `'${urlParam ? (urlParam[field] || '') : ''}'`
+            regs.push({
+              reg: new RegExp('@' + field + '@', 'ig'),
+              value: val
+            })
           })
         }
 
@@ -322,7 +332,7 @@
             _pars.push(param)
           } else {
             let arr_field = component.columns.map(col => col.field).join(',')
-            let param = UtilsDM.getQueryDataParams(component.setting, arr_field, [], component.setting.order || '', 1, 1000, BID, '')
+            let param = UtilsDM.getQueryDataParams(component.setting, arr_field, [], component.setting.order || '', 1, 1000, BID)
             
             param.componentId = component.uuid
 
@@ -340,7 +350,20 @@
           params.unshift(_pars)
         }
 
+        if (config.everyPCount && !config.printPage) { // 鍏煎
+          config.printPage = 'page'
+        }
+
+        config.printPage = config.printPage || 'auto'
+
+        if (config.printPage === 'auto') {
+          config.everyPCount = 99999
+        }
+
+        config.limit = config.everyPCount || 15
+
         this.setState({
+          auto: config.printPage === 'auto',
           config
         }, () => {
           if (params.length === 0) {
@@ -417,7 +440,12 @@
     let RoleID = sessionStorage.getItem('role_id') || ''
     let departmentcode = sessionStorage.getItem('departmentcode') || ''
     let organization = sessionStorage.getItem('organization') || ''
+    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
+    let nation = sessionStorage.getItem('nation') || ''
+    let province = sessionStorage.getItem('province') || ''
     let city = sessionStorage.getItem('city') || ''
+    let district = sessionStorage.getItem('district') || ''
+    let address = sessionStorage.getItem('address') || ''
   
     if (sessionStorage.getItem('isEditState') === 'true') {
       userName = sessionStorage.getItem('CloudUserName') || ''
@@ -429,8 +457,8 @@
       let _script = item.script
 
       if (index === 0) {
-        _script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@login_city nvarchar(50)
-          select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @login_city='${city}'
+        _script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(50),@mk_organization nvarchar(50),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100)
+          select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
           ${_script}
         `
       }
@@ -467,7 +495,7 @@
    * @description 涓昏〃鏁版嵁鍔犺浇
    */ 
   loadmaindata = (params) => {
-    const { components, everyPCount, firstCount, lastCount } = this.state.config
+    const { components, limit } = this.state.config
 
     let deffers = params.map(item => {
       let componentId = item.componentId
@@ -517,19 +545,11 @@
         this.setState({loadingview: false, pages})
       }
 
-      let auto = true
-
-      if (comps[comps.length - 1].wrap && comps[comps.length - 1].wrap.printHeight) {
-        auto = false
-      }
-
       while (!over) {
         let page = []
         let count = 0
         let _pageover = false
         let pagesover = false
-
-        let limit = pageIndex === 1 ? (firstCount || 20) : (everyPCount || 20)
 
         comps.forEach((_item, index) => {
           let item = fromJS(_item).toJS()
@@ -568,7 +588,11 @@
     
                 if (count >= limit) {
                   _pageover = true
+                } else if (_item.dataArray.length > 0) {
+                  _pageover = true
+
                 }
+
                 page.push(item)
               }
               _item.added = true
@@ -600,95 +624,15 @@
           }
         })
 
-        if (pagesover && lastCount && count > lastCount) {
-          pagesover = false
-          page = []
-          count = 0
-          _pageover = false
-
-          if (pageIndex === 1) {
-            limit = (everyPCount - firstCount) + (everyPCount - lastCount)
-
-            if (limit <= 0) {
-              limit = firstCount
-            }
-          } else {
-            limit = lastCount
-          }
-
-          comps.forEach((_item, index) => {
-            let item = fromJS(_item).toJS()
-            if (item.wrap && item.wrap.printType === 'headerOrfooter') { // 椤电湁椤佃剼
-              page.push(item)
-            } else if (_pageover) {
-              return
-            } else if (item.subtype === 'datacard' || item.type === 'table') {
-              if (_item.dataArray && _item.dataArray.length > 0) {
-                if (item.subtype === 'datacard' && item.wrap.layout === 'flex') {
-                  if (!item.added && item.wrap.printHeight) {
-                    count += item.wrap.printHeight
-                    if (count >= limit) {
-                      _pageover = true
-                    }
-                    if (count <= limit) {
-                      _item.added = true
-                      page.push(item)
-                    }
-                  } else if (!item.added) {
-                    _item.added = true
-                    page.push(item)
-                  }
-                } else {
-                  item.data = []
-
-                  while (count + 1 <= limit && _item.dataArray.length > 0) {
-                    item.data.push(_item.dataArray.shift())
-                    count++
-                  }
-      
-                  if (count >= limit) {
-                    _pageover = true
-                  }
-                  page.push(item)
-                }
-                _item.added = true
-              } else if (!item.added) {
-                _item.added = true
-                page.push(item)
-              }
-            } else if (!item.added && item.wrap && item.wrap.printHeight) {
-              if (item.wrap.empty === 'hidden' && (!item.data || item.data.length === 0)) {
-                _item.added = true
-                return
-              }
-              count += item.wrap.printHeight
-              if (count >= limit) {
-                _pageover = true
-              }
-              if (count <= limit) {
-                _item.added = true
-                page.push(item)
-              }
-            } else if (!item.added) {
-              _item.added = true
-              page.push(item)
-            }
-  
-            if (index + 1 === length && !_pageover) {
-              pagesover = true
-            }
-          })
-        }
-
         pages.push(page)
         pageIndex++
 
-        if (pageIndex >= 200 || pagesover) {
+        if (pageIndex >= 2000 || pagesover) {
           over = true
         }
       }
 
-      this.setState({loadingview: false, pages, auto})
+      this.setState({loadingview: false, pages})
     })
   }
 
@@ -750,67 +694,67 @@
       if (item.type === 'bar' || item.type === 'line') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvBarAndLine config={item} initdata={item.data} mainSearch={[]} menuType="" />
+            <AntvBarAndLine config={item} initdata={item.data} mainSearch={[]} />
           </Col>
         )
       } else if (item.type === 'pie') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvPie config={item} initdata={item.data} mainSearch={[]} menuType="" />
+            <AntvPie config={item} initdata={item.data} mainSearch={[]} />
           </Col>
         )
       } else if (item.type === 'scatter') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvScatter config={item} initdata={item.data} mainSearch={[]} menuType="" />
+            <AntvScatter config={item} initdata={item.data} mainSearch={[]}/>
           </Col>
         )
       } else if (item.type === 'dashboard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <AntvDashboard config={item} initdata={item.data} mainSearch={[]} menuType="" />
+            <AntvDashboard config={item} initdata={item.data} mainSearch={[]}/>
           </Col>
         )
       } else if (item.type === 'card' && item.subtype === 'datacard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <DataCard config={item} initdata={item.data} mainSearch={[]} menuType="" />
+            <DataCard config={item} initdata={item.data} mainSearch={[]} />
           </Col>
         )
       } else if (item.type === 'card' && item.subtype === 'propcard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <PropCard config={item} initdata={item.data} mainSearch={[]} menuType="" />
+            <PropCard config={item} initdata={item.data} mainSearch={[]} />
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'tablecard') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <TableCard config={item} initdata={item.data} mainSearch={[]} menuType="" />
+            <TableCard config={item} initdata={item.data} mainSearch={[]}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'normaltable') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <NormalTable config={item} initdata={item.data} mainSearch={[]} menuType="" />
+            <NormalTable config={item} initdata={item.data} mainSearch={[]}/>
           </Col>
         )
       } else if (item.type === 'code') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <SandBox config={item} initdata={item.data} mainSearch={[]} menuType="" />
+            <SandBox config={item} initdata={item.data} mainSearch={[]}/>
           </Col>
         )
       } else if (item.type === 'balcony') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <Balcony config={item} initdata={item.data} menuType="" />
+            <Balcony config={item} initdata={item.data}/>
           </Col>
         )
       } else if (item.type === 'timeline') {
         return (
           <Col span={item.width} key={item.uuid}>
-            <TimeLine config={item} initdata={item.data} menuType="" />
+            <TimeLine config={item} initdata={item.data}/>
           </Col>
         )
       } else {
diff --git a/src/templates/menuconfig/editfirstmenu/dragelement/card.jsx b/src/views/design/header/editfirstmenu/dragelement/card.jsx
similarity index 96%
rename from src/templates/menuconfig/editfirstmenu/dragelement/card.jsx
rename to src/views/design/header/editfirstmenu/dragelement/card.jsx
index b278434..b147e9b 100644
--- a/src/templates/menuconfig/editfirstmenu/dragelement/card.jsx
+++ b/src/views/design/header/editfirstmenu/dragelement/card.jsx
@@ -23,7 +23,7 @@
       }
     },
   })
-  const opacity = isDragging ? 0 : 1
+  const opacity = isDragging ? 0.5 : 1
 
   const edit = () => {
     editCard(id)
diff --git a/src/templates/menuconfig/editfirstmenu/dragelement/index.jsx b/src/views/design/header/editfirstmenu/dragelement/index.jsx
similarity index 72%
rename from src/templates/menuconfig/editfirstmenu/dragelement/index.jsx
rename to src/views/design/header/editfirstmenu/dragelement/index.jsx
index 44aa6ac..d707e8b 100644
--- a/src/templates/menuconfig/editfirstmenu/dragelement/index.jsx
+++ b/src/views/design/header/editfirstmenu/dragelement/index.jsx
@@ -1,14 +1,13 @@
 import React, { useState } from 'react'
 import { useDrop } from 'react-dnd'
 import { Button } from 'antd'
-import { PlusOutlined } from '@ant-design/icons'
 import { is, fromJS } from 'immutable'
 import update from 'immutability-helper'
 import Card from './card'
 import ItemTypes from './itemtypes'
 import './index.scss'
 
-const Container = ({dict, list, handlePreviewList, handleMenu, deleteMemu, handleButton }) => {
+const Container = ({change, list, handlePreviewList, handleMenu, deleteMemu, handleButton }) => {
   const [cards, setCards] = useState(list)
   const moveCard = (id, atIndex) => {
     const { card, index } = findCard(id)
@@ -43,20 +42,12 @@
     deleteMemu(card)
   }
 
-  const add = () => {
-    handleButton('add')
-  }
-  
   const confirm = () => {
     handleButton('confirm')
   }
 
   const cancel = () => {
     handleButton('cancel')
-  }
-
-  const thawmenu = () => {
-    handleButton('thawmenu')
   }
 
   const [, drop] = useDrop({ accept: ItemTypes.CARD })
@@ -73,12 +64,8 @@
           findCard={findCard}
         />
       ))}
-      <div className="card-add" onClick={add}>
-        <PlusOutlined />
-      </div>
-      <Button type="primary" onClick={thawmenu}>{dict['model.thaw'] + dict['model.menu']}</Button>
-      <Button type="primary" onClick={confirm}>{dict['model.confirm']}</Button>
-      <Button onClick={cancel}>{dict['model.close']}</Button>
+      <Button type="primary" className="mk-save-menu" disabled={!change} onClick={confirm}>淇濆瓨</Button>
+      <Button onClick={cancel}>鍏抽棴</Button>
     </div>
   )
 }
diff --git a/src/templates/menuconfig/editfirstmenu/dragelement/index.scss b/src/views/design/header/editfirstmenu/dragelement/index.scss
similarity index 77%
rename from src/templates/menuconfig/editfirstmenu/dragelement/index.scss
rename to src/views/design/header/editfirstmenu/dragelement/index.scss
index 27d0004..458e6ad 100644
--- a/src/templates/menuconfig/editfirstmenu/dragelement/index.scss
+++ b/src/views/design/header/editfirstmenu/dragelement/index.scss
@@ -5,28 +5,20 @@
   float: left;
   background: #001529;
   padding-bottom: 5px;
-  .card-add {
-    border: 1px dashed gray;
-    padding: 4px;
-    margin-top: 9px;
-    margin-left: 10px;
-    width: 50px;
-    float: left;
-    text-align: center;
-    cursor: pointer;
-  }
+
   button {
     margin-top: 14px;
     margin-left: 10px;
     padding: 0 10px;
     height: 26px;
   }
+  
   .btn-group {
     display: inline-block;
   }
   .card {
     position: relative;
-    border: 1px dashed gray;
+    border: 1px dashed #535353;
     margin-top: 8px;
     margin-right: 5px;
     float: left;
diff --git a/src/templates/menuconfig/editfirstmenu/dragelement/itemtypes.js b/src/views/design/header/editfirstmenu/dragelement/itemtypes.js
similarity index 100%
rename from src/templates/menuconfig/editfirstmenu/dragelement/itemtypes.js
rename to src/views/design/header/editfirstmenu/dragelement/itemtypes.js
diff --git a/src/views/design/header/editfirstmenu/index.jsx b/src/views/design/header/editfirstmenu/index.jsx
new file mode 100644
index 0000000..c565b22
--- /dev/null
+++ b/src/views/design/header/editfirstmenu/index.jsx
@@ -0,0 +1,217 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { DndProvider } from 'react-dnd'
+import HTML5Backend from 'react-dnd-html5-backend'
+import { notification, Modal } from 'antd'
+import moment from 'moment'
+
+import DragElement from './dragelement'
+import MenuForm from './menuform'
+import Utils from '@/utils/utils.js'
+import Api from '@/api'
+// import './index.scss'
+
+const { confirm } = Modal
+
+class EditMenu extends Component {
+  static propTpyes = {
+    menulist: PropTypes.any,
+    reload: PropTypes.func,
+    exitEdit: PropTypes.func
+  }
+
+  state = {
+    menulist: null,
+    editMenu: null,  // 缂栬緫鑿滃崟
+    visible: false,  // 缂栬緫鑿滃崟妯℃�佹
+    loading: false,  // 鎻愪氦涓�傘�傘��
+    change: false
+  }
+
+  handlePreviewList = (List) => {
+    // 鑿滃崟椤哄簭鏀瑰彉鏃讹紝淇濆瓨涓棿鐘舵��
+    this.setState({menulist: List, change: !is(fromJS(List), fromJS(this.props.menulist))})
+  }
+
+  editMenuModal = (Menu) => {
+    // 鑿滃崟缂栬緫锛氫慨鏀�
+    const menu = fromJS(Menu).toJS()
+    if (this.state.change) {
+      notification.warning({
+        top: 92,
+        message: '鑿滃崟椤哄簭宸茶皟鏁达紝璇蜂繚瀛橈紒',
+        duration: 5
+      })
+      return
+    }
+
+    this.setState({
+      visible: true,
+      editMenu: menu.card,
+      loading: false
+    })
+  }
+
+  editMemuSubmit = () => {
+    // 缂栬緫鑿滃崟锛氭彁浜�
+    this.editMenuFormRef.handleConfirm().then(param => {
+      param.func = 'sPC_MainMenu_Upt'
+      this.setState({
+        loading: true
+      })
+      Api.getSystemConfig(param).then(res => {
+        if (res.status) {
+          this.setState({
+            loading: false,
+            visible: false,
+            editMenu: null
+          })
+          this.props.reload()
+        } else {
+          this.setState({
+            loading: false
+          })
+          notification.warning({
+            top: 92,
+            message: res.message,
+            duration: 5
+          })
+        }
+      })
+    }, () => {})
+  }
+
+  deleteMemu = (item) => {
+    if (this.state.change) {
+      notification.warning({
+        top: 92,
+        message: '鑿滃崟椤哄簭宸茶皟鏁达紝璇蜂繚瀛橈紒',
+        duration: 5
+      })
+      return
+    }
+    
+    let _this = this
+    confirm({
+      title: `纭畾鍒犻櫎鑿滃崟銆�${item.MenuName}銆嬪悧锛焋,
+      content: '',
+      onOk() {
+        let param = {
+          func: 'sPC_MainMenu_Del',
+          MenuID: item.MenuID
+        }
+        return Api.getSystemConfig(param).then(res => {
+          if (res.status) {
+            _this.props.reload()
+          } else {
+            notification.warning({
+              top: 92,
+              message: res.message,
+              duration: 5
+            })
+          }
+        })
+      },
+      onCancel() {}
+    })
+  }
+  
+  handleButton = (type) => {
+    // 鑿滃崟缂栬緫锛氭坊鍔狅紝纭畾锛屽彇娑�
+    let _menuchange = !is(fromJS(this.state.menulist), fromJS(this.props.menulist))
+
+    if (type === 'confirm' && _menuchange) {
+      let _this = this
+      let param  = {
+        func: 'sPC_Menu_SortUpt',
+        LText: this.state.menulist.map((item, index) => {
+          return 'select \'' + item.MenuID + '\' as Menuid,' + (index + 1) * 10 + ' as sort'
+        })
+      }
+
+      param.LText = param.LText.join(' union ') // sql鎷兼帴
+      param.LText = Utils.formatOptions(param.LText) // 鍏抽敭瀛楃鏇挎崲锛宐ase64鍔犲瘑
+      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') // 鏃堕棿鎴�
+      param.secretkey = Utils.encrypt(param.LText, param.timestamp) // md5瀵嗛挜
+
+      confirm({
+        title: '纭璋冩暣鑿滃崟椤哄簭鍚楋紵',
+        content: '',
+        onOk() {
+          return Api.getSystemConfig(param).then(res => {
+            if (res.status) {
+              _this.props.reload()
+            } else {
+              notification.warning({
+                top: 92,
+                message: res.message,
+                duration: 5
+              })
+            }
+          })
+        },
+        onCancel() {}
+      })
+    } else if (type === 'cancel' && _menuchange) {
+      let _this = this
+
+      confirm({
+        title: '鑿滃崟椤哄簭宸茶皟鏁达紝鏀惧純淇濆瓨鍚楋紵',
+        content: '',
+        onOk() {
+          _this.props.exitEdit()
+        },
+        onCancel() {}
+      })
+    } else {
+      this.props.exitEdit()
+    }
+  }
+
+  UNSAFE_componentWillMount () {
+    this.setState({menulist: fromJS(this.props.menulist).toJS()})
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    if (!is(fromJS(this.props.menulist), fromJS(nextProps.menulist))) {
+      this.setState({menulist: fromJS(nextProps.menulist).toJS(), change: false})
+    }
+  }
+
+  render () {
+    const { menulist, change } = this.state
+
+    return (
+      <>
+        <DndProvider backend={HTML5Backend}>
+          <DragElement
+            change={change}
+            list={menulist}
+            handlePreviewList={this.handlePreviewList}
+            handleMenu={this.editMenuModal}
+            deleteMemu={this.deleteMemu}
+            handleButton={this.handleButton}
+          />
+        </DndProvider>
+        {/* 缂栬緫鑿滃崟妯℃�佹 */}
+        <Modal
+          title="缂栬緫鑿滃崟"
+          visible={this.state.visible}
+          onOk={this.editMemuSubmit}
+          confirmLoading={this.state.loading}
+          onCancel={() => this.setState({visible: false})}
+          destroyOnClose
+        >
+          <MenuForm
+            menu={this.state.editMenu}
+            inputSubmit={this.editMemuSubmit}
+            wrappedComponentRef={(inst) => this.editMenuFormRef = inst}
+          />
+        </Modal>
+      </>
+    )
+  }
+}
+
+export default EditMenu
\ No newline at end of file
diff --git a/src/templates/menuconfig/editthdmenu/menuform/index.scss b/src/views/design/header/editfirstmenu/index.scss
similarity index 100%
copy from src/templates/menuconfig/editthdmenu/menuform/index.scss
copy to src/views/design/header/editfirstmenu/index.scss
diff --git a/src/templates/menuconfig/editfirstmenu/menuform/index.jsx b/src/views/design/header/editfirstmenu/menuform/index.jsx
similarity index 66%
rename from src/templates/menuconfig/editfirstmenu/menuform/index.jsx
rename to src/views/design/header/editfirstmenu/menuform/index.jsx
index e263eba..998f74f 100644
--- a/src/templates/menuconfig/editfirstmenu/menuform/index.jsx
+++ b/src/views/design/header/editfirstmenu/menuform/index.jsx
@@ -1,13 +1,13 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Row, Col, Input, Select, Radio } from 'antd'
+import { Form, Row, Col, Input, Radio } from 'antd'
+
 import Utils from '@/utils/utils.js'
 import './index.scss'
 
 class MainSearch extends Component {
   static propTpyes = {
     menu: PropTypes.any,         // 鑿滃崟淇℃伅锛屾柊寤烘椂涓簄ull
-    dict: PropTypes.object,      // 瀛楀吀椤�
     type: PropTypes.string,      // 鎿嶄綔绫诲瀷
     inputSubmit: PropTypes.func
   }
@@ -18,7 +18,7 @@
       {
         type: 'text',
         key: 'menuName',
-        label: this.props.dict['model.menu'] + this.props.dict['model.name'],
+        label: '鑿滃崟鍚嶇О',
         initVal: '',
         required: true,
         readonly: false
@@ -26,12 +26,12 @@
       {
         type: 'radio',
         key: 'openType',
-        label: this.props.dict['model.openway'],
+        label: '鎵撳紑鏂瑰紡',
         initVal: 'menu',
         required: true,
         options: [{
           id: 'menu',
-          text: this.props.dict['model.menu']
+          text: '鑿滃崟'
         }, {
           id: 'outpage',
           text: '澶栭儴椤甸潰'
@@ -51,7 +51,7 @@
   UNSAFE_componentWillMount () {
     const { menu } = this.props
 
-    if (this.props.type === 'add') {
+    if (!menu) {
       this.setState({
         formlist: this.state.defaultMenu
       })
@@ -113,14 +113,14 @@
                 rules: [
                   {
                     required: !!item.required,
-                    message: this.props.dict['form.required.input'] + item.label + '!'
+                    message: '璇疯緭鍏�' + item.label + '!'
                   }
                 ]
               })(<Input placeholder="" autoFocus={item.key.toLowerCase() === 'menuname'} autoComplete="off" disabled={item.readonly} />)}
             </Form.Item>
           </Col>
         )
-      } else if (item.type === 'select') { // 涓嬫媺鎼滅储
+      } else if (item.type === 'radio') {
         fields.push(
           <Col span={24} key={index}>
             <Form.Item label={item.label}>
@@ -129,34 +129,7 @@
                 rules: [
                   {
                     required: !!item.required,
-                    message: this.props.dict['form.required.select'] + item.label + '!'
-                  }
-                ]
-              })(
-                <Select
-                  showSearch
-                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
-                  onChange={(value) => {this.openTypeChange(item.key, value)}}
-                  getPopupContainer={() => document.getElementById('first-menu-form-box')}
-                >
-                  {item.options.map(option =>
-                    <Select.Option key={option.id} value={option.id}>{option.text}</Select.Option>
-                  )}
-                </Select>
-              )}
-            </Form.Item>
-          </Col>
-        )
-      } else if (item.type === 'radio') { // 涓嬫媺鎼滅储
-        fields.push(
-          <Col span={24} key={index}>
-            <Form.Item label={item.label}>
-              {getFieldDecorator(item.key, {
-                initialValue: item.initVal || '',
-                rules: [
-                  {
-                    required: !!item.required,
-                    message: this.props.dict['form.required.select'] + item.label + '!'
+                    message: '璇烽�夋嫨' + item.label + '!'
                   }
                 ]
               })(
@@ -180,31 +153,31 @@
   }
 
   handleConfirm = () => {
+    const { menu } = this.props
+
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     return new Promise((resolve, reject) => {
       this.props.form.validateFieldsAndScroll((err, values) => {
-        if (!err) {
-          if (this.props.type === 'add') {
-            resolve({
-              MenuID: Utils.getuuid(),
-              MenuName: values.menuName,
-              PageParam: JSON.stringify({
-                OpenType: values.openType,
-                linkUrl: values.openType !== 'menu' ? values.linkUrl : ''
-              })
+        if (err) return
+
+        if (!menu) {
+          resolve({
+            MenuID: Utils.getuuid(),
+            MenuName: values.menuName,
+            PageParam: JSON.stringify({
+              OpenType: values.openType,
+              linkUrl: values.openType !== 'menu' ? values.linkUrl : ''
             })
-          } else {
-            resolve({
-              MenuID: this.props.menu.MenuID,
-              MenuName: values.menuName,
-              PageParam: JSON.stringify({
-                OpenType: values.openType,
-                linkUrl: values.openType !== 'menu' ? values.linkUrl : ''
-              })
-            })
-          }
+          })
         } else {
-          reject(err)
+          resolve({
+            MenuID: menu.MenuID,
+            MenuName: values.menuName,
+            PageParam: JSON.stringify({
+              OpenType: values.openType,
+              linkUrl: values.openType !== 'menu' ? values.linkUrl : ''
+            })
+          })
         }
       })
     })
diff --git a/src/templates/menuconfig/editfirstmenu/menuform/index.scss b/src/views/design/header/editfirstmenu/menuform/index.scss
similarity index 100%
rename from src/templates/menuconfig/editfirstmenu/menuform/index.scss
rename to src/views/design/header/editfirstmenu/menuform/index.scss
diff --git a/src/views/design/header/index.jsx b/src/views/design/header/index.jsx
index 7146bae..eac3170 100644
--- a/src/views/design/header/index.jsx
+++ b/src/views/design/header/index.jsx
@@ -1,9 +1,8 @@
 import React, {Component} from 'react'
 import { withRouter } from 'react-router-dom'
 import {connect} from 'react-redux'
-import { is, fromJS } from 'immutable'
-import { Dropdown, Menu, Modal, notification, Switch, Button } from 'antd'
-import { MenuFoldOutlined, EditOutlined, AppstoreOutlined, DownOutlined, HomeOutlined, ApiOutlined } from '@ant-design/icons'
+import { Dropdown, Menu, Modal, notification, Switch, Button, Popover } from 'antd'
+import { MenuFoldOutlined, SettingOutlined, AppstoreOutlined, DownOutlined, HomeOutlined, ApiOutlined, PlusOutlined, SwapOutlined, MenuOutlined } from '@ant-design/icons'
 
 import asyncComponent from '@/utils/asyncComponent'
 import {
@@ -14,31 +13,33 @@
 } from '@/store/action'
 import Api from '@/api'
 import options from '@/store/options.js'
-import zhCN from '@/locales/zh-CN/main.js'
-import enUS from '@/locales/en-US/main.js'
 import Utils from '@/utils/utils.js'
 import avatar from '@/assets/img/avatar.jpg'
 import MainLogo from '@/assets/img/main-logo.png'
 import MKEmitter from '@/utils/events.js'
 import './index.scss'
 
-const EditMenu = asyncComponent(() => import('@/templates/menuconfig/editfirstmenu'))
+const EditMenu = asyncComponent(() => import('./editfirstmenu'))
 const VersionsUp = asyncComponent(() => import('./versions'))
+const ThawMenu = asyncComponent(() => import('@/components/thawmenu'))
+const MenuForm = asyncComponent(() => import('./editfirstmenu/menuform'))
 const { confirm } = Modal
 
 class Header extends Component {
   state = {
     menulist: null, // 涓�绾ц彍鍗�
-    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
     userName: sessionStorage.getItem('CloudUserName'),
     avatar: Utils.getrealurl(sessionStorage.getItem('CloudAvatar')),
+    memberLevel: Utils.getMemberLevel(),
+    visible: false,
+    loading: false
   }
 
   logout = () => {
     // 閫�鍑虹櫥褰�
     let _this = this
     confirm({
-      title: this.state.dict['main.logout.hint'],
+      title: '鎮ㄧ‘瀹氳閫�鍑哄悧?',
       content: '',
       onOk() {
         sessionStorage.clear()
@@ -51,10 +52,6 @@
 
   changeMenu (value) {
     // 涓昏彍鍗曞垏鎹�
-    if (this.props.editLevel) {
-      // 缂栬緫鐘舵�佷笅锛屼笉鍙垏鎹㈣彍鍗�
-      return
-    }
     if (value.PageParam.OpenType === 'menu') {
       this.props.modifyMainMenu(value)
     } else if (value.PageParam.OpenType === 'outpage') {
@@ -77,10 +74,21 @@
 
       this.setState({ menulist })
 
-      this.props.modifyMenuTree(menulist)
-      if (window.GLOB.systemType !== 'production') { // 闈炴寮忕郴缁熼�夋嫨绗竴椤�
-        this.props.modifyMainMenu(menulist[0] || null)
+      let mainMenu = menulist[0] || null
+
+      if (this.props.editLevel === 'level1') {
+        mainMenu = null
+      } else if (this.props.mainMenu && this.props.mainMenu.MenuID) {
+        let _menu = menulist.filter(item => item.MenuID === this.props.mainMenu.MenuID)[0]
+        mainMenu = _menu || mainMenu
+
+        if (!_menu && (this.props.editLevel === 'level2' || this.props.editLevel === 'level3')) {
+          this.props.resetEditLevel(false)
+        }
       }
+
+      this.props.modifyMenuTree(menulist)
+      this.props.modifyMainMenu(mainMenu)
     } else {
       notification.error({
         top: 92,
@@ -116,7 +124,8 @@
             MenuID: snd.MenuID,
             MenuName: snd.MenuName,
             PageParam: {Icon: 'folder'},
-            children: []
+            children: [],
+            level: 'second'
           }
 
           if (snd.PageParam) {
@@ -137,7 +146,8 @@
                 MenuNo: trd.MenuNo,
                 EasyCode: trd.EasyCode,
                 type: 'CommonTable',            // 榛樿鍊间负甯哥敤琛�
-                OpenType: 'newtab'              // 鎵撳紑鏂瑰紡
+                OpenType: 'newtab',             // 鎵撳紑鏂瑰紡
+                level: 'third'
               }
   
               if (trd.LinkUrl && iframes.includes(trd.LinkUrl.split('?')[0])) {
@@ -154,7 +164,7 @@
                 trdItem.type = trdItem.PageParam.Template || trdItem.type
                 trdItem.OpenType = trdItem.PageParam.OpenType || trdItem.OpenType
 
-                if (trdItem.type === 'CustomPage' && this.props.memberLevel < 20) { // 浼氬憳绛夌骇澶т簬绛変簬20鏃讹紝鏈夌紪杈戞潈闄�
+                if (trdItem.type === 'CustomPage' && this.state.memberLevel < 20) { // 浼氬憳绛夌骇澶т簬绛変簬20鏃讹紝鏈夌紪杈戞潈闄�
                   trdItem.forbidden = true
                 }
               }
@@ -188,40 +198,45 @@
   enterEdit = () => {
     // 杩涘叆缂栬緫鐘舵��
     this.props.resetEditLevel('level1')
-  }
-
-  enterEditManage = () => {
-    const { editLevel } = this.props
-
-    if (editLevel === 'HS')  return
-
-    this.props.resetEditLevel('HS')
-    this.props.modifyMainMenu({
-      MenuID: 'systemManageView'
-    })
-  }
-
-  /**
-   * @description 閫�鍑虹鐞嗙晫闈㈣彍鍗�
-   */
-  exitManage = () => {
-    const { menulist } = this.state
-
-    if (window.GLOB.systemType === 'production') { // 姝e紡绯荤粺鐗堟湰鍗囩骇鍚庯紝椤甸潰鍒锋柊
-      this.props.history.replace('/main')
-      window.location.reload()
-      return
-    }
-
-    this.props.modifyMainMenu(menulist[0] || null)
-    this.props.resetEditLevel(false)
-
-    MKEmitter.emit('modifyTabs', null, 'replace')
+    this.props.modifyMainMenu(null)
   }
   
   exitEdit = () => {
     // 閫�鍑虹紪杈戠姸鎬�
     this.props.resetEditLevel(false)
+    this.props.modifyMainMenu(this.state.menulist[0] || null)
+  }
+
+  
+  addMemuSubmit = () => {
+    // 鏂板缓鑿滃崟锛氭彁浜�
+    this.addMenuFormRef.handleConfirm().then(param => {
+      param.func = 'sPC_MainMenu_Add'
+      param.Sort = (this.state.menulist.length + 1) * 10
+
+      this.setState({
+        loading: true
+      })
+      Api.getSystemConfig(param).then(res => {
+        if (res.status) {
+          this.setState({
+            loading: false,
+            visible: false,
+          })
+          
+          this.loadmenu()
+        } else {
+          this.setState({
+            loading: false
+          })
+          notification.warning({
+            top: 92,
+            message: res.message,
+            duration: 5
+          })
+        }
+      })
+    }, () => {})
   }
   
   UNSAFE_componentWillMount () {
@@ -230,14 +245,6 @@
     
     // 缁勪欢鍔犺浇鏃讹紝鑾峰彇鑿滃崟鏁版嵁
     this.loadmenu()
-  }
-
-  UNSAFE_componentWillReceiveProps (nextProps) {
-    if (!is(fromJS(this.props.menuTree), fromJS(nextProps.menuTree)) && !is(fromJS(this.state.menulist), fromJS(nextProps.menuTree))) {
-      this.setState({
-        menulist: nextProps.menuTree
-      })
-    }
   }
 
   componentDidMount () {
@@ -272,16 +279,14 @@
           }
         })
       }, 50)
-    } else if (window.GLOB.systemType === 'production') {
-      this.props.resetEditLevel('HS')
-      this.props.modifyMainMenu({
-        MenuID: 'systemManageView'
-      })
     }
-  }
 
-  shouldComponentUpdate (nextProps, nextState) {
-    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
+    window.addEventListener('storage', (e) => {
+      if (e.key !== 'menuUpdate') return
+
+      this.reload()
+    })
+    MKEmitter.addListener('mkUpdateMenuList', this.reload)
   }
 
   /**
@@ -291,6 +296,7 @@
     this.setState = () => {
       return
     }
+    MKEmitter.removeListener('mkUpdateMenuList', this.reload)
   }
 
   gotoDoc = () => {
@@ -305,10 +311,10 @@
 
   render () {
     const { mainMenu, editLevel } = this.props
-    const { menulist } = this.state
+    const { menulist, memberLevel, visible, loading } = this.state
 
     return (
-      <header className={'sys-header-container ant-menu-dark ' + (['level2', 'level3', 'HS'].includes(editLevel) ? 'mask' : '')} id="main-header-container">
+      <header className={'sys-header-container ant-menu-dark ' + (['level2', 'level3'].includes(editLevel) ? 'mask' : '')} id="main-header-container">
         <div className="header-logo"><img src={MainLogo} alt=""/></div>
         <div className="header-collapse">
           <MenuFoldOutlined/>
@@ -323,71 +329,77 @@
                 </li>
               )
             })}
-            {!editLevel || editLevel === 'HS' ?
-              <li key="HS" onClick={this.enterEditManage} className={editLevel === 'HS' ? 'active' : ''}>
+            {!editLevel ?
+              <li key="HS" onClick={() => window.open('#/hs')}>
                 <span>HS</span>
               </li> : null
             }
           </ul> : null
         }
-        {editLevel === 'HS' ? <Button className="level4-close" type="primary" onClick={this.exitManage}>閫�鍑�</Button> : null}
         {/* 杩涘叆缂栬緫鎸夐挳 */}
-        {!editLevel && menulist ? <EditOutlined onClick={this.enterEdit} className="edit-check" /> : null}
-        {!editLevel && window.GLOB.systemType !== 'production' ?
-          <div className="app-entrance entrance">
-            <div className="icon"><AppstoreOutlined /></div>
-            <div className="title">搴旂敤绠$悊</div>
-            <div className="detail">鍙垱寤哄強绠$悊PC銆乸ad鍙婄Щ鍔ㄧ绛変笉鍚岃澶囩殑搴旂敤锛屽疄鐜版槑绉戜簯APP銆佸井淇″叕浼楀彿銆佸皬绋嬪簭绛夊骞冲彴鐨勫簲鐢ㄥ叡浜��</div>
-            <Button type="primary" disabled={!(this.props.memberLevel >= 20)} title={this.props.memberLevel >= 20 ? '' : '浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��'} onClick={() => {window.open('#/appmanage')}}>
-              缂栬緫
-            </Button>
-          </div> : null
-        }
-        {editLevel === 'HS' && window.GLOB.systemType === 'production' ?
-          <div className="app-prod-entrance entrance">
-            <div className="icon"><AppstoreOutlined /></div>
-            <div className="title">搴旂敤绠$悊</div>
-            <div className="detail">鍙垱寤哄強绠$悊PC銆乸ad鍙婄Щ鍔ㄧ绛変笉鍚岃澶囩殑搴旂敤锛屽疄鐜版槑绉戜簯APP銆佸井淇″叕浼楀彿銆佸皬绋嬪簭绛夊骞冲彴鐨勫簲鐢ㄥ叡浜��</div>
-            <Button type="primary" disabled={!(this.props.memberLevel >= 20)} title={this.props.memberLevel >= 20 ? '' : '浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��'} onClick={() => {window.open('#/appcheck')}}>
-              鏌ョ湅
-            </Button>
-          </div> : null
-        }
-        {!editLevel ?
-          <div className="api-entrance entrance">
-            <div className="icon"><ApiOutlined /></div>
-            <div className="title">鎺ュ彛璋冭瘯</div>
-            <div className="detail">鍙嚜鍔ㄥ鐞嗙櫥褰曟帴鍙g殑鍙傛暟鍔犲瘑锛屼互鍙婁笟鍔℃帴鍙g殑绛惧悕璁$畻锛屾柟渚垮紑鍙戜汉鍛樼殑鎺ュ彛娴嬭瘯宸ヤ綔銆�</div>
-            <Button type="primary" disabled={!(this.props.memberLevel >= 20)} title={this.props.memberLevel >= 20 ? '' : '浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��'} onClick={() => {window.open('#/interface')}}>
-              缂栬緫
-            </Button>
-          </div> : null
-        }
+        {!editLevel && window.GLOB.systemType !== 'production' && menulist ? <Popover overlayClassName="mk-popover-control-wrap mk-menu-control" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+          <div className="mk-popover-control">
+            <PlusOutlined onClick={() => this.setState({visible: true, loading: false})}/>
+            <SwapOutlined onClick={this.enterEdit}/>
+            <div style={{display: 'inline-block', minWidth: '32px'}}><ThawMenu ParentId="0" Type="10"/></div>
+          </div>
+        } trigger="hover">
+          <SettingOutlined className="edit-check"/>
+        </Popover> : null}
         {/* window.btoa(window.encodeURIComponent(JSON.stringify({ MenuType: 'home', MenuId: 'home_page_id', MenuName: '棣栭〉' }))) */}
-        {!editLevel && window.GLOB.systemType !== 'production' ?
+        {window.GLOB.systemType !== 'production' ?
           <div className="home-entrance entrance">
             <div className="icon"><HomeOutlined /></div>
             <div className="title">棣栭〉</div>
             <div className="detail">鍩轰簬鑷畾涔夐〉闈㈢殑棣栭〉璁捐锛屽彲瀹炵幇鐏垫椿鐨勫厓绱犻厤缃強鏍峰紡璋冩暣锛屽睍鐜板綋鍓嶇郴缁熺殑椋庢牸銆�</div>
-            <Button type="primary" disabled={!(this.props.memberLevel >= 20)} title={this.props.memberLevel >= 20 ? '' : '浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��'} onClick={() => {window.open('#/menudesign/JTdCJTIyTWVudVR5cGUlMjIlM0ElMjJob21lJTIyJTJDJTIyTWVudUlkJTIyJTNBJTIyaG9tZV9wYWdlX2lkJTIyJTJDJTIyTWVudU5hbWUlMjIlM0ElMjIlRTklQTYlOTYlRTklQTElQjUlMjIlN0Q=')}}>
+            <Button type="primary" disabled={!(memberLevel >= 20)} title={memberLevel >= 20 ? '' : '浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��'} onClick={() => {window.open('#/menudesign/JTdCJTIyTWVudVR5cGUlMjIlM0ElMjJob21lJTIyJTJDJTIyTWVudUlkJTIyJTNBJTIyaG9tZV9wYWdlX2lkJTIyJTJDJTIyTWVudU5hbWUlMjIlM0ElMjIlRTklQTYlOTYlRTklQTElQjUlMjIlN0Q=')}}>
               缂栬緫
             </Button>
           </div> : null
         }
+        <div className="api-entrance entrance">
+          <div className="icon"><ApiOutlined /></div>
+          <div className="title">鎺ュ彛璋冭瘯</div>
+          <div className="detail">鍙嚜鍔ㄥ鐞嗙櫥褰曟帴鍙g殑鍙傛暟鍔犲瘑锛屼互鍙婁笟鍔℃帴鍙g殑绛惧悕璁$畻锛屾柟渚垮紑鍙戜汉鍛樼殑鎺ュ彛娴嬭瘯宸ヤ綔銆�</div>
+          <Button type="primary" disabled={!(memberLevel >= 20)} title={memberLevel >= 20 ? '' : '浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��'} onClick={() => {window.open('#/interface')}}>
+            缂栬緫
+          </Button>
+        </div>
+        <div className="app-entrance entrance">
+          <div className="icon"><AppstoreOutlined /></div>
+          <div className="title">搴旂敤绠$悊</div>
+          <div className="detail">鍙垱寤哄強绠$悊PC銆乸ad鍙婄Щ鍔ㄧ绛変笉鍚岃澶囩殑搴旂敤锛屽疄鐜版槑绉戜簯APP銆佸井淇″叕浼楀彿銆佸皬绋嬪簭绛夊骞冲彴鐨勫簲鐢ㄥ叡浜��</div>
+          {window.GLOB.systemType !== 'production' ? 
+            <Button type="primary" disabled={!(memberLevel >= 20)} title={memberLevel >= 20 ? '' : '浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��'} onClick={() => {window.open('#/appmanage')}}>
+              缂栬緫
+            </Button> :
+            <Button type="primary" disabled={!(memberLevel >= 20)} title={memberLevel >= 20 ? '' : '浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��'} onClick={() => {window.open('#/appcheck')}}>
+              鏌ョ湅
+            </Button>
+          }
+        </div>
+        {window.GLOB.systemType !== 'production' ? <div className="menu-entrance entrance">
+          <div className="icon"><MenuOutlined /></div>
+          <div className="title">鑿滃崟鎿嶄綔璇存槑</div>
+          <div className="detail">榧犳爣鎮仠 <SettingOutlined style={{color: '#1890ff'}}/> 鍙樉绀鸿彍鍗曠殑娣诲姞銆佹帓搴忥紙鍖呮嫭缂栬緫銆佸垹闄わ級涓庤В鍐诲姛鑳斤紝鍙屽嚮涓夌骇鑿滃崟鍙繘鍏ョ紪杈戠獥鍙c��</div>
+          <Button type="primary" onClick={() => {window.open('#/main')}}>
+            鏂扮獥鍙�
+          </Button>
+        </div> : null}
         {/* 缂栬緫鑿滃崟 */}
         {editLevel === 'level1' ? <EditMenu menulist={this.state.menulist} reload={this.reload} exitEdit={this.exitEdit}/> : null}
         {/* 澶村儚銆佺敤鎴峰悕 */}
         <Dropdown className="header-setting" overlay={
           <Menu className="header-dropdown">
             <Menu.Item key="switch">
-              {this.state.dict['main.edit']}
+              缂栬緫
               <Switch size="small" style={{marginLeft: '7px'}} disabled={!!editLevel} checked={true} onChange={this.changeEditState} />
             </Menu.Item>
-            <Menu.Item key="doc" onClick={this.gotoDoc}>{this.state.dict['main.doc']}</Menu.Item>
+            <Menu.Item key="doc" onClick={this.gotoDoc}>鏂囨。涓績</Menu.Item>
             {options.sysType !== 'cloud' ? <Menu.Item style={{padding: 0}} key="verup">
               <VersionsUp />
             </Menu.Item> : null}
-            <Menu.Item key="logout" onClick={this.logout}>{this.state.dict['main.logout']}</Menu.Item>
+            <Menu.Item key="logout" onClick={this.logout}>閫�鍑�</Menu.Item>
           </Menu>
         }>
           <div style={{zIndex: 1, position: 'relative'}}>
@@ -397,6 +409,20 @@
             </span>
           </div>
         </Dropdown>
+        <Modal
+          title="娣诲姞鑿滃崟"
+          visible={visible}
+          onOk={this.addMemuSubmit}
+          confirmLoading={loading}
+          onCancel={() => this.setState({visible: false})}
+          destroyOnClose
+        >
+          <MenuForm
+            menu={null}
+            inputSubmit={this.addMemuSubmit}
+            wrappedComponentRef={(inst) => this.addMenuFormRef = inst}
+          />
+        </Modal>
       </header>
     )
   }
@@ -406,9 +432,7 @@
   return {
     menuTree: state.menuTree,
     mainMenu: state.mainMenu,
-    editLevel: state.editLevel,
-    permAction: state.permAction,
-    memberLevel: state.memberLevel
+    editLevel: state.editLevel
   }
 }
 
diff --git a/src/views/design/header/index.scss b/src/views/design/header/index.scss
index 4da19da..587ca14 100644
--- a/src/views/design/header/index.scss
+++ b/src/views/design/header/index.scss
@@ -136,16 +136,16 @@
     cursor: pointer;
   }
   .home-entrance {
-    left: 300px;
+    left: 260px;
   }
   .api-entrance {
-    left: 600px;
+    left: 540px;
   }
   .app-entrance {
-    left: 900px;
+    left: 820px;
   }
-  .app-prod-entrance {
-    left: 300px;
+  .menu-entrance {
+    left: 1100px;
   }
   .entrance {
     position: absolute;
diff --git a/src/views/design/index.jsx b/src/views/design/index.jsx
index 8942896..d596e2f 100644
--- a/src/views/design/index.jsx
+++ b/src/views/design/index.jsx
@@ -3,6 +3,7 @@
 import enUS from 'antd/es/locale/en_US'
 import zhCN from 'antd/es/locale/zh_CN'
 
+import Api from '@/api'
 import asyncComponent from '@/utils/asyncComponent'
 import Header from './header'
 import { setGLOBFuncs } from '@/utils/utils.js'
@@ -16,6 +17,39 @@
 class Design extends Component {
   componentDidMount() {
     setGLOBFuncs()
+
+    // 鑾峰彇寰俊鍏紬鍙峰強灏忕▼搴忔秷鎭ā鏉�
+    if (window.GLOB.systemType !== 'production' && window.GLOB.WXAppID && !sessionStorage.getItem('wxTemplates')) {
+      Api.wxAccessToken().then(res => {
+        let wxtoken = res.oa_access_token || ''
+        wxtoken = '59_DH0hrAp0B8jtdJvU-7BV_-nG01qh2rUU1L8ihj-2pMWlUFLE2eEtVv4zZYAUIKcxCit4SgOTwxvUGdYHltaha3RmgnZqkQSgkxXRm9hz18kGbGhMc5r11W5Iv9Xr50Pz-Sz7FUVHCM-6GZLXJPIjAIAVBU'
+        let minitoken = res.mini_access_token || ''
+  
+        if (wxtoken) {
+          Api.wxNginxRequest(`cgi-bin/template/get_all_private_template?access_token=${wxtoken}`, 'get').then(res => {
+            if (res.template_list) {
+              let temps = res.template_list.filter(item => item.primary_industry)
+              sessionStorage.setItem('wxTemplates', JSON.stringify(temps))
+            } else if (res.errcode === 0) {
+              sessionStorage.setItem('wxTemplates', JSON.stringify([]))
+            }
+          })
+        } else {
+          sessionStorage.setItem('wxTemplates', JSON.stringify([]))
+        }
+        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([]))
+        }
+      })
+    }
   }
   
   render () {
diff --git a/src/views/design/index.scss b/src/views/design/index.scss
index 223fa26..1c544d6 100644
--- a/src/views/design/index.scss
+++ b/src/views/design/index.scss
@@ -2,6 +2,10 @@
   display: flex;
   flex: auto;
   min-height: 100%;
+
+  .mk-save-menu[disabled] {
+    background: #ffffff!important;
+  }
 }
 .mk-design-view {
   #mk-tabview-wrap {
@@ -16,4 +20,24 @@
   #mk-tabview-wrap.hastab + .sys-header-container .app-prod-entrance {
     display: none;
   }
+}
+.mk-popover-control-wrap {
+  .anticon-plus {
+    color: #26C281;
+  }
+  .anticon-swap {
+    position: relative;
+    z-index: 2;
+    color: #1890ff;
+  }
+  .mk-swap {
+    transform: rotate(90deg);
+  }
+  .mk-swap.disabled {
+    cursor: not-allowed!important;
+    color: #959595;
+  }
+}
+.mk-menu-control.mk-popover-control-wrap {
+  padding-bottom: 0px;
 }
\ No newline at end of file
diff --git a/src/views/design/sidemenu/editsecmenu/index.jsx b/src/views/design/sidemenu/editsecmenu/index.jsx
new file mode 100644
index 0000000..c76db28
--- /dev/null
+++ b/src/views/design/sidemenu/editsecmenu/index.jsx
@@ -0,0 +1,252 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { DndProvider } from 'react-dnd'
+import HTML5Backend from 'react-dnd-html5-backend'
+import { notification, Modal, Button } from 'antd'
+import moment from 'moment'
+
+import Utils from '@/utils/utils.js'
+import DragElement from '../menuelement'
+import MenuForm from '../menuform'
+import Api from '@/api'
+import MKEmitter from '@/utils/events.js'
+import './index.scss'
+
+const { confirm } = Modal
+
+class EditMenu extends Component {
+  static propTpyes = {
+    menulist: PropTypes.any,      // 浜岀骇鑿滃崟鍒楄〃
+    menuTree: PropTypes.array,    // 涓�绾ц彍鍗曞垪琛�
+    supMenu: PropTypes.object,    // 浜岀骇鑿滃崟鎵�瀵瑰簲鐨勪竴绾ц彍鍗�
+    exitEdit: PropTypes.func      // 閫�鍑虹紪杈�
+  }
+
+  state = {
+    menulist: null,        // 鑿滃崟鍒楄〃
+    visible: null,         // 妯℃�佹鏄惁鍙
+    formlist: null,        // 琛ㄥ崟淇℃伅
+    editMenu: null,        // 缂栬緫鑿滃崟
+    loading: false,        // 鎻愪氦涓�傘�傘��
+    change: false
+  }
+
+  handlePreviewList = (List) => {
+    this.setState({
+      menulist: List,
+      change: !is(fromJS(List), fromJS(this.props.menulist))
+    })
+  }
+
+  handleMenu = (menu) => {
+    // 鑿滃崟缂栬緫锛氫慨鏀广�佸垹闄わ紝濡傝彍鍗曢『搴忓凡鏀瑰彉锛屾彁绀轰繚瀛樿彍鍗曢『搴�
+    if (this.state.change) {
+      notification.warning({
+        top: 92,
+        message: '鑿滃崟椤哄簭宸茶皟鏁达紝璇蜂繚瀛橈紒',
+        duration: 5
+      })
+      return
+    }
+    if (menu.type === 'close') {
+      confirm({
+        title: `纭畾鍒犻櫎鑿滃崟銆�${menu.card.MenuName}銆嬪悧锛焋,
+        content: '',
+        onOk() {
+          let param = {
+            func: 'sPC_MainMenu_Del',
+            MenuID: menu.card.MenuID
+          }
+          return Api.getSystemConfig(param).then(res => {
+            if (res.status) {
+              MKEmitter.emit('mkUpdateMenuList')
+            } else {
+              notification.warning({
+                top: 92,
+                message: res.message,
+                duration: 5
+              })
+            }
+          })
+        },
+        onCancel() {}
+      })
+    } else if (menu.type === 'edit') {
+      this.setState({
+        visible: true,
+        editMenu: menu.card,
+        formlist: [
+          { // 鐖剁骇鑿滃崟
+            type: 'select',
+            key: 'parentId',
+            label: '涓婄骇鑿滃崟',
+            initVal: this.props.supMenu.MenuID,
+            required: true,
+            options: this.props.menuTree
+          },
+          { // 鑿滃崟鍚嶇О
+            type: 'text',
+            key: 'menuName',
+            label: '鑿滃崟鍚嶇О',
+            initVal: menu.card.MenuName,
+            required: true,
+            readonly: false
+          },
+          { // 鑿滃崟鍥炬爣
+            type: 'icon',
+            key: 'icon',
+            label: '鍥炬爣',
+            initVal: menu.card.PageParam.Icon || 'folder',
+            required: true
+          }
+        ]
+      })
+    }
+  }
+
+  handleSubBtn = (type) => {
+    if (type === 'confirm') { // 淇濆瓨璋冩暣鍚庣殑椤哄簭
+      let param  = {
+        func: 'sPC_Menu_SortUpt',
+        LText: this.state.menulist.map((item, index) => {
+          return 'select \'' + item.MenuID + '\' as Menuid,' + (index + 1) * 10 + ' as sort'
+        })
+      }
+
+      param.LText = param.LText.join(' union ') // sql鎷兼帴
+      param.LText = Utils.formatOptions(param.LText) // 鍏抽敭瀛楃鏇挎崲锛宐ase64鍔犲瘑
+      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') // 鏃堕棿鎴�
+      param.secretkey = Utils.encrypt(param.LText, param.timestamp) // md5瀵嗛挜
+
+      confirm({
+        title: '纭璋冩暣鑿滃崟椤哄簭鍚楋紵',
+        content: '',
+        onOk() {
+          return Api.getSystemConfig(param).then(res => {
+            if (res.status) {
+              MKEmitter.emit('mkUpdateMenuList')
+            } else {
+              notification.warning({
+                top: 92,
+                message: res.message,
+                duration: 5
+              })
+            }
+          })
+        },
+        onCancel() {}
+      })
+    } else if (type === 'close') { // 閫�鍑虹紪杈�
+      if (this.state.change) {
+        let _this = this
+
+        confirm({
+          title: '鑿滃崟椤哄簭宸茶皟鏁达紝鏀惧純淇濆瓨鍚楋紵',
+          content: '',
+          onOk() {
+            _this.props.exitEdit()
+          },
+          onCancel() {}
+        })
+      } else {
+        this.props.exitEdit()
+      }
+    }
+  }
+
+  memuHandleSubmit = () => {
+    this.menuFormRef.handleConfirm().then(values => {
+      let param = {
+        func: 'sPC_SndMenu_Upt',
+        ParentID: values.parentId,
+        MenuID: this.state.editMenu.MenuID,
+        MenuName: values.menuName,
+        PageParam: JSON.stringify({
+          Icon: values.icon
+        })
+      }
+      this.setState({
+        loading: true
+      })
+      Api.getSystemConfig(param).then(res => {
+        if (res.status) {
+          this.setState({
+            loading: false,
+            visible: false
+          })
+          MKEmitter.emit('mkUpdateMenuList')
+        } else {
+          this.setState({
+            loading: false
+          })
+          notification.warning({
+            top: 92,
+            message: res.message,
+            duration: 5
+          })
+        }
+      })
+    }, () => {})
+  }
+
+  memuHandleCancel = () => { // 鍙栨秷鎿嶄綔锛屽叧闂ā鎬佹
+    this.setState({
+      visible: false,
+      formlist: null,
+      editMenu: null
+    })
+  }
+
+  UNSAFE_componentWillMount () {
+    this.setState({
+      menulist: this.props.menulist
+    })
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    if (!is(fromJS(this.props.menulist), fromJS(nextProps.menulist))) {
+      this.setState({
+        menulist: nextProps.menulist,
+        change: false
+      })
+    }
+  }
+
+  render () {
+    const { change, loading } = this.state
+
+    return (
+      <>
+        <DndProvider backend={HTML5Backend}>
+          <DragElement
+            list={this.state.menulist}
+            handlePreviewList={this.handlePreviewList}
+            handleMenu={this.handleMenu}
+          />
+        </DndProvider>
+        <div className="menu-btn">
+          <Button type="primary" className="mk-save-menu" disabled={!change} onClick={() => {this.handleSubBtn('confirm')}}>淇濆瓨</Button>
+          <Button onClick={() => {this.handleSubBtn('close')}}>鍏抽棴</Button>
+        </div>
+        <Modal
+          title="淇敼鑿滃崟"
+          visible={this.state.visible}
+          onOk={this.memuHandleSubmit}
+          confirmLoading={loading}
+          onCancel={this.memuHandleCancel}
+          destroyOnClose
+        >
+          {this.state.formlist ?
+            <MenuForm
+              inputSubmit={this.memuHandleSubmit}
+              formlist={this.state.formlist}
+              wrappedComponentRef={(inst) => this.menuFormRef = inst}
+            /> : null}
+        </Modal>
+      </>
+    )
+  }
+}
+
+export default EditMenu
\ No newline at end of file
diff --git a/src/templates/menuconfig/editthdmenu/menuform/index.scss b/src/views/design/sidemenu/editsecmenu/index.scss
similarity index 100%
copy from src/templates/menuconfig/editthdmenu/menuform/index.scss
copy to src/views/design/sidemenu/editsecmenu/index.scss
diff --git a/src/views/design/sidemenu/editthdmenu/index.jsx b/src/views/design/sidemenu/editthdmenu/index.jsx
new file mode 100644
index 0000000..82c9b25
--- /dev/null
+++ b/src/views/design/sidemenu/editthdmenu/index.jsx
@@ -0,0 +1,314 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { connect } from 'react-redux'
+import { DndProvider } from 'react-dnd'
+import HTML5Backend from 'react-dnd-html5-backend'
+import { notification, Modal, Button } from 'antd'
+import moment from 'moment'
+
+import Api from '@/api'
+import MKEmitter from '@/utils/events.js'
+import MkIcon from '@/components/mk-icon'
+import Utils from '@/utils/utils.js'
+import DragElement from '../menuelement'
+import asyncLoadComponent from '@/utils/asyncLoadComponent'
+import './index.scss'
+
+const MenuForm = asyncLoadComponent(() => import('../thdmenuform'))
+
+const { confirm } = Modal
+
+class EditMenu extends Component {
+  static propTpyes = {
+    menulist: PropTypes.any,     // 涓夌骇鑿滃崟鍒楄〃
+    exitEdit: PropTypes.func,    // 閫�鍑虹紪杈戠姸鎬�
+    supMenu: PropTypes.object,   // 瀵瑰簲鐨勪笂绾ц彍鍗�
+    supMenuList: PropTypes.array // 涓婄骇鑿滃崟鍒楄〃锛岀敤浜庝笁绾ц彍鍗曞垏鎹笂绾ц彍鍗�
+  }
+
+  state = {
+    confirmLoading: false,  // 鎻愪氦涓�傘�傘��
+    loading: false,         // 缂栬緫鑿滃崟鎴栦娇鐢ㄥ凡浣跨敤妯℃澘鏃讹紝鑾峰彇閰嶇疆淇℃伅
+    menulist: null,         // 缂栬緫涓殑鑿滃崟
+    handleMVisible: false,  // 娣诲姞鎴栦慨鏀硅彍鍗曟ā鎬佹锛堣鑹叉潈闄愬垎閰嶇瓑锛�
+    sysMenu: null,          // 娣诲姞鎴栫紪杈戣彍鍗曪紙瑙掕壊鏉冮檺鍒嗛厤绛夛級
+    change: false
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  /**
+   * @description 鑿滃崟椤哄簭鏀瑰彉鏃讹紝淇濆瓨涓棿鐘舵��
+   */
+  handlePreviewList = (List) => {
+    this.setState({
+      menulist: List,
+      change: !is(fromJS(List), fromJS(this.props.menulist))
+    })
+  }
+
+  /**
+   * @description 鑿滃崟缂栬緫锛氫慨鏀广�佸垹闄�
+   * 1銆佽彍鍗曚慨鏀规垨鍒犻櫎鏃讹紝鍏堟煡鐪嬭彍鍗曢『搴忔槸鍚︽敼鍙�
+   * 2銆佽彍鍗曞垹闄�
+   * 3銆佽彍鍗曠紪杈戯紝鏌ヨ鑿滃崟閰嶇疆淇℃伅锛屼俊鎭纭紝杩涘叆瀵瑰簲缂栬緫椤甸潰
+   */
+  handleMenu = (menu) => {
+    if (this.state.change) {
+      notification.warning({
+        top: 92,
+        message: '鑿滃崟椤哄簭宸茶皟鏁达紝璇蜂繚瀛橈紒',
+        duration: 5
+      })
+      return
+    }
+    
+    if (menu.type === 'close') {
+      confirm({
+        title: `纭畾鍒犻櫎鑿滃崟銆�${menu.card.MenuName}銆嬪悧锛焋,
+        content: '',
+        onOk() {
+          let param = {
+            func: 'sPC_MainMenu_Del',
+            MenuID: menu.card.MenuID
+          }
+          return Api.getSystemConfig(param).then(res => {
+            if (res.status) {
+              MKEmitter.emit('mkUpdateMenuList')
+            } else {
+              notification.warning({
+                top: 92,
+                message: res.message,
+                duration: 5
+              })
+            }
+          })
+        },
+        onCancel() {}
+      })
+    } else if (menu.type === 'edit') {
+      let _menu = fromJS(menu.card).toJS()
+
+      if (['RolePermission', 'NewPage'].includes(_menu.PageParam.Template)) { // 鍗曢〉闈慨鏀�
+        _menu.Template = _menu.PageParam.Template
+        _menu.url = _menu.PageParam.url || ''
+
+        _menu.fstMenuId = _menu.FstId
+        _menu.supMenuList = this.props.supMenuList
+        _menu.fstMenuList = this.props.menuTree
+  
+        this.setState({
+          handleMVisible: true,
+          sysMenu: _menu
+        })
+      } else if (['CommonTable', 'TreePage', 'CalendarPage'].includes(_menu.PageParam.Template)) {
+        sessionStorage.setItem('menuTree', JSON.stringify(this.props.menuTree))
+        let _param = window.btoa(window.encodeURIComponent(JSON.stringify(_menu)))
+
+        window.open(`#/basedesign/${_param}`)
+      } else if (_menu.PageParam.Template === 'CustomPage') {
+        let _param = {
+          MenuType: 'custom',
+          MenuId: _menu.MenuID,
+          ParentId: _menu.ParentId,
+          MenuName: _menu.MenuName,
+          MenuNo: _menu.MenuNo
+        }
+
+        _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
+
+        window.open(`#/menudesign/${_param}`)
+      }
+    }
+  }
+
+  handleSubBtn = (type) => {
+    // 鎿嶄綔鎸夐挳锛氭坊鍔犮�佽В闄ゅ喕缁撱�佺‘璁ゅ強鍏抽棴
+    if (type === 'confirm') {
+      let param  = {
+        func: 'sPC_Menu_SortUpt',
+        LText: this.state.menulist.map((item, index) => {
+          return 'select \'' + item.MenuID + '\' as Menuid,' + (index + 1) * 10 + ' as sort'
+        })
+      }
+
+      param.LText = param.LText.join(' union ') // sql鎷兼帴
+      param.LText = Utils.formatOptions(param.LText) // 鍏抽敭瀛楃鏇挎崲锛宐ase64鍔犲瘑
+      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') // 鏃堕棿鎴�
+      param.secretkey = Utils.encrypt(param.LText, param.timestamp) // md5瀵嗛挜
+
+      confirm({
+        title: '纭璋冩暣鑿滃崟椤哄簭鍚楋紵',
+        content: '',
+        onOk() {
+          return Api.getSystemConfig(param).then(res => {
+            if (res.status) {
+              MKEmitter.emit('mkUpdateMenuList')
+            } else {
+              notification.warning({
+                top: 92,
+                message: res.message,
+                duration: 5
+              })
+            }
+          })
+        },
+        onCancel() {}
+      })
+    } else if (type === 'close') {
+      if (this.state.change) {
+        let _this = this
+
+        confirm({
+          title: '鑿滃崟椤哄簭宸茶皟鏁达紝鏀惧純淇濆瓨鍚楋紵',
+          content: '',
+          onOk() {
+            _this.props.exitEdit()
+          },
+          onCancel() {}
+        })
+      } else {
+        this.props.exitEdit()
+      }
+    }
+  }
+
+  /**
+   * @description 涓夌骇鑿滃崟娣诲姞鎴栦慨鏀�
+   */
+  memuSubmit = () => {
+    const { sysMenu } = this.state
+
+    this.menuFormRef.handleConfirm().then(res => {
+      let PageParam = {
+        Template: sysMenu.Template,
+        OpenType: 'newtab'
+      }
+
+      if (sysMenu.Template === 'NewPage') {
+        PageParam.OpenType = 'NewPage'
+        PageParam.url = res.url
+      }
+
+      let param = {
+        func: 'sPC_TrdMenu_AddUpt',
+        FstID: res.fstMenuId,
+        SndID: res.ParentID,
+        ParentID: res.ParentID,
+        MenuID: sysMenu.MenuID,
+        MenuNo: res.MenuNo,
+        Template: sysMenu.Template,
+        MenuName: res.MenuName,
+        PageParam: JSON.stringify(PageParam),
+        LongParam: '',
+        LText: '',
+        LTexttb: ''
+      }
+
+      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+      param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+
+      this.setState({
+        confirmLoading: true
+      })
+
+      Api.getSystemConfig(param).then(response => {
+        if (response.status) {
+          this.setState({
+            confirmLoading: false,
+            handleMVisible: false,
+            sysMenu: null
+          })
+
+          MKEmitter.emit('mkUpdateMenuList')
+          document.getElementById('root').style.overflowY = 'unset'
+        } else {
+          this.setState({
+            confirmLoading: false
+          })
+          notification.warning({
+            top: 92,
+            message: response.message,
+            duration: 5
+          })
+        }
+      })
+    })
+  }
+
+  UNSAFE_componentWillMount () {
+    this.setState({
+      menulist: this.props.menulist
+    })
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    if (!is(fromJS(this.props.menulist), fromJS(nextProps.menulist))) {
+      this.setState({
+        menulist: nextProps.menulist,
+        change: false
+      })
+    }
+  }
+
+  render () {
+    const { change } = this.state
+
+    return (
+      <div className="third-edit-box">
+        <div className="cus-submenu-title">
+          <MkIcon type={this.props.supMenu.PageParam.Icon} />
+          <span>{this.props.supMenu.MenuName}</span>
+        </div>
+        <DndProvider backend={HTML5Backend}>
+          <DragElement
+            list={this.state.menulist}
+            handlePreviewList={this.handlePreviewList}
+            handleMenu={this.handleMenu}
+          />
+        </DndProvider>
+        <div className="menu-btn">
+          <Button type="primary" className="mk-save-menu" disabled={!change} onClick={() => {this.handleSubBtn('confirm')}}>淇濆瓨</Button>
+          <Button onClick={() => {this.handleSubBtn('close')}}>鍏抽棴</Button>
+        </div>
+        {/* 娣诲姞绯荤粺鑿滃崟 */}
+        <Modal
+          title="淇敼鑿滃崟"
+          visible={this.state.handleMVisible}
+          width={600}
+          onOk={this.memuSubmit}
+          confirmLoading={this.state.loading}
+          onCancel={() => {this.setState({handleMVisible: false})}}
+          destroyOnClose
+        >
+          <MenuForm
+            menu={this.state.sysMenu}
+            inputSubmit={this.memuSubmit}
+            wrappedComponentRef={(inst) => this.menuFormRef = inst}
+          />
+        </Modal>
+      </div>
+    )
+  }
+}
+
+const mapStateToProps = (state) => {
+  return {
+    mainMenu: state.mainMenu,
+    menuTree: state.menuTree
+  }
+}
+
+const mapDispatchToProps = () => {
+  return {}
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(EditMenu)
\ No newline at end of file
diff --git a/src/views/design/sidemenu/editthdmenu/index.scss b/src/views/design/sidemenu/editthdmenu/index.scss
new file mode 100644
index 0000000..dcf0ae3
--- /dev/null
+++ b/src/views/design/sidemenu/editthdmenu/index.scss
@@ -0,0 +1,19 @@
+.third-edit-box {
+  position: relative;
+  z-index: 10;
+  .cus-submenu-title {
+    padding: 0px 24px;
+    background: #364150;
+    margin: 0;
+    height: 48px;
+    line-height: 48px;
+    width: 100%;
+    overflow: hidden;
+    font-size: 14px;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    .anticon {
+      margin-right: 10px;
+    }
+  }
+}
diff --git a/src/views/design/sidemenu/index.jsx b/src/views/design/sidemenu/index.jsx
index 06454bb..f46de51 100644
--- a/src/views/design/sidemenu/index.jsx
+++ b/src/views/design/sidemenu/index.jsx
@@ -1,35 +1,41 @@
 import React, {Component} from 'react'
 import { connect } from 'react-redux'
 import { is, fromJS } from 'immutable'
-import { Menu, notification } from 'antd'
-import { EditOutlined } from '@ant-design/icons'
+import { Menu, Popover, Modal, notification } from 'antd'
+import { SwapOutlined, PlusOutlined, SettingOutlined } from '@ant-design/icons'
+import moment from 'moment'
 
 import asyncComponent from '@/utils/asyncComponent'
-import { resetEditLevel, modifyMenuTree, modifyMainMenu } from '@/store/action'
-import { SySMenuList } from './config'
-import options from '@/store/options.js'
+import { resetEditLevel } from '@/store/action'
+import Utils from '@/utils/utils.js'
 import Api from '@/api'
 import MKEmitter from '@/utils/events.js'
 import MkIcon from '@/components/mk-icon'
 import './index.scss'
 
-const EditSecMenu = asyncComponent(() => import('@/templates/menuconfig/editsecmenu'))
-const EditThdMenu = asyncComponent(() => import('@/templates/menuconfig/editthdmenu'))
+const EditSecMenu = asyncComponent(() => import('./editsecmenu'))
+const EditThdMenu = asyncComponent(() => import('./editthdmenu'))
+const ThawMenu = asyncComponent(() => import('@/components/thawmenu'))
+const AddThdMenu = asyncComponent(() => import('./thdmenuplus'))
+const ThdMenuForm = asyncComponent(() => import('./thdmenuform'))
+const MenuForm = asyncComponent(() => import('./menuform'))
 const { SubMenu } = Menu
 
 class Sidemenu extends Component {
   state = {
-    subMenulist: [],         // 浜岀骇鑿滃崟
     editMenu: null,          // 缂栬緫涓夌骇鑿滃崟鏃惰缃�
     rootSubmenuKeys: null,
     openKeys: null,
-    preview: null
+    preview: null,
+    loading: false,
+    thdVisible: false,
+    sysMenu: null,
+    formlist: []
   }
 
   async loadsubmenu (menu) {
     if (!menu || !menu.MenuID) { // 娌℃湁涓昏彍鍗曟椂锛屾竻绌轰笅绾ц彍鍗�
       this.setState({
-        subMenulist: [],
         rootSubmenuKeys: [],
         openKeys: [],
         editMenu: null
@@ -45,57 +51,20 @@
     }
 
     this.setState({
-      subMenulist: menu.children,
       rootSubmenuKeys: menu.children.map(item => item.MenuID),
       openKeys: openKey ? [openKey] : [],
       editMenu: this.props.editLevel === 'level3' ? menu.children.filter(_menu => _menu.MenuID === this.state.editMenu.MenuID)[0] : null
     })
   }
 
-  enterManageView = () => {
-    let menulist = SySMenuList
-
-    if (window.GLOB.systemType === 'production') {
-      menulist.forEach(menu => {
-        menu.children = menu.children.filter(item => item.systems && item.systems.includes(window.GLOB.systemType))
-      })
-
-      menulist = menulist.filter(menu => menu.children.length > 0)
-    } else {
-      menulist.forEach(menu => {
-        menu.children = menu.children.filter(item => !item.systems || item.systems.includes(options.sysType))
-      })
-
-      menulist = menulist.filter(menu => menu.children.length > 0)
-    }
-
-    this.setState({
-      subMenulist: menulist,
-      rootSubmenuKeys: menulist.map(item => item.MenuID),
-      openKeys: [menulist[0].MenuID]
-    })
-  }
-
-  changemenu(e, menu) {
-    e.preventDefault()
-    if (this.props.editLevel !== 'HS') {
-      return
-    }
-
-    MKEmitter.emit('modifyTabs', menu, 'plus')
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
   }
 
   UNSAFE_componentWillReceiveProps (nextProps) {
-    if (!is(fromJS(this.props.mainMenu), fromJS(nextProps.mainMenu)) && nextProps.mainMenu && nextProps.mainMenu.MenuID === 'systemManageView') {
-      this.enterManageView()
-    } else if (!is(fromJS(this.props.mainMenu), fromJS(nextProps.mainMenu))) {
-      // 涓昏彍鍗曞垏鎹紝璇锋眰2銆�3绾ц彍鍗曟暟鎹�
+    if (!is(fromJS(this.props.mainMenu), fromJS(nextProps.mainMenu))) {
       this.loadsubmenu(nextProps.mainMenu)
     }
-  }
-
-  shouldComponentUpdate(nextProps, nextState) {
-    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
   }
 
   onOpenChange = openKeys => {
@@ -112,6 +81,9 @@
   enterSubEdit = (e) => {
     // 缂栬緫浜岀骇鑿滃崟
     e.stopPropagation()
+
+    if (this.props.mainMenu.children.length === 0) return
+
     this.props.resetEditLevel('level2')
   }
 
@@ -122,110 +94,6 @@
     this.setState({editMenu: menu})
   }
 
-  reload = () => {
-    const { mainMenu } = this.props
-    let _param = {func: 's_get_pc_menus', systemType: options.sysType, debug: 'Y'}
-    _param.pro_sys = window.GLOB.systemType === 'production' ? 'Y' : ''
-
-    Api.getSystemConfig(_param).then(result => {
-      // 鐧诲綍瓒呮椂
-      if (!result) return
-  
-      if (result.status) {
-        let res = this.getMenulist(result)
-        let _mainMenu = res.menulist.filter(item => item.MenuID === mainMenu.MenuID)[0]
-  
-        this.props.modifyMenuTree(res.menulist)
-        this.props.modifyMainMenu(_mainMenu || null)
-      } else {
-        notification.error({
-          top: 92,
-          message: result.message,
-          duration: 10
-        })
-      }
-      this.loadsubmenu(this.props.mainMenu)
-    })
-  }
-
-  getMenulist = (result) => {
-    let iframes = ['Main/Index', 'bda/rdt', 'Home/rdt']
-    let menulist = result.fst_menu.map(fst => {
-      let fstItem = {
-        MenuID: fst.MenuID,
-        MenuName: fst.MenuName,
-        PageParam: {OpenType: 'menu', linkUrl: ''},
-        children: []
-      }
-      if (fst.PageParam) {
-        try {
-          fstItem.PageParam = JSON.parse(fst.PageParam)
-        } catch (e) {
-          fstItem.PageParam = {OpenType: 'menu', linkUrl: ''}
-        }
-      }
-
-      if (fst.snd_menu) {
-        fstItem.children = fst.snd_menu.map(snd => {
-          let sndItem = {
-            ParentId: fst.MenuID,
-            MenuID: snd.MenuID,
-            MenuName: snd.MenuName,
-            PageParam: {Icon: 'folder'},
-            children: []
-          }
-
-          if (snd.PageParam) {
-            try {
-              sndItem.PageParam = JSON.parse(snd.PageParam)
-            } catch (e) {
-              sndItem.PageParam = {Icon: 'folder'}
-            }
-          }
-
-          if (snd.trd_menu) {
-            sndItem.children = snd.trd_menu.map(trd => {
-              let trdItem = {
-                FstId: fst.MenuID,
-                ParentId: snd.MenuID,
-                MenuID: trd.MenuID,
-                MenuName: trd.MenuName,
-                MenuNo: trd.MenuNo,
-                EasyCode: trd.EasyCode,
-                type: 'CommonTable',            // 榛樿鍊间负甯哥敤琛�
-                OpenType: 'newtab'              // 鎵撳紑鏂瑰紡
-              }
-  
-              if (trd.LinkUrl && iframes.includes(trd.LinkUrl.split('?')[0])) {
-                trdItem.type = 'iframe'
-                trdItem.LinkUrl = trd.LinkUrl.replace('&amp;', '&')
-                trdItem.forbidden = true
-              } else {
-                try {
-                  trdItem.PageParam = trd.PageParam ? JSON.parse(trd.PageParam) : {OpenType: 'newtab'}
-                } catch (e) {
-                  trdItem.PageParam = {OpenType: 'newtab'}
-                }
-
-                trdItem.type = trdItem.PageParam.Template || trdItem.type
-                trdItem.OpenType = trdItem.PageParam.OpenType || trdItem.OpenType
-
-                if (trdItem.type === 'CustomPage' && this.props.memberLevel < 20) { // 浼氬憳绛夌骇澶т簬绛変簬20鏃讹紝鏈夌紪杈戞潈闄�
-                  trdItem.forbidden = true
-                }
-              }
-              return trdItem
-            })
-          }
-          return sndItem
-        })
-      }
-      return fstItem
-    })
-
-    return { menulist }
-  }
-
   exitEdit = () => {
     if (this.props.editLevel === 'level3') {
       this.setState({editMenu: null})
@@ -233,57 +101,272 @@
     this.props.resetEditLevel(false)
   }
 
+  editmenu = (cell) => {
+    if (cell.type === 'CustomPage') {
+      let _param = {
+        MenuType: 'custom',
+        MenuId: cell.MenuID,
+        ParentId: cell.ParentId,
+        MenuName: cell.MenuName,
+        MenuNo: cell.MenuNo
+      }
+      _param = window.btoa(window.encodeURIComponent(JSON.stringify(_param)))
+      window.open(`#/menudesign/${_param}`)
+    } else if (['CommonTable', 'TreePage', 'CalendarPage'].includes(cell.type)) {
+      sessionStorage.setItem('menuTree', JSON.stringify(this.props.menuTree))
+      let _param = window.btoa(window.encodeURIComponent(JSON.stringify(cell)))
+
+      window.open(`#/basedesign/${_param}`)
+    } else if (['RolePermission', 'NewPage'].includes(cell.type)) {
+      let _cell = fromJS(cell).toJS()
+      _cell.Template = _cell.PageParam.Template
+      _cell.url = _cell.PageParam.url || ''
+
+      _cell.fstMenuId = _cell.FstId
+      _cell.supMenuList = this.props.mainMenu.children
+      _cell.fstMenuList = this.props.menuTree
+
+      this.setState({
+        thdVisible: true,
+        loading: false,
+        sysMenu: _cell
+      })
+    } else {
+      notification.warning({
+        top: 92,
+        message: '褰撳墠鑿滃崟涓嶅彲缂栬緫',
+        duration: 5
+      })
+    }
+  }
+
+  addSecMenu = () => {
+    this.setState({
+      visible: true,
+      loading: false,
+      formlist: [
+        { // 鐖剁骇鑿滃崟
+          type: 'select',
+          key: 'parentId',
+          label: '涓婄骇鑿滃崟',
+          initVal: this.props.mainMenu.MenuID,
+          required: true,
+          options: this.props.menuTree
+        },
+        { // 鑿滃崟鍚嶇О
+          type: 'text',
+          key: 'menuName',
+          label: '鑿滃崟鍚嶇О',
+          initVal: '',
+          required: true,
+          readonly: false
+        },
+        { // 鑿滃崟鍥炬爣
+          type: 'icon',
+          key: 'icon',
+          label: '鍥炬爣',
+          initVal: 'folder',
+          required: true
+        }
+      ]
+    })
+  }
+
+  secSubmit = () => {
+    this.menuFormRef.handleConfirm().then(values => {
+      let param = {
+        ParentID: values.parentId,
+        MenuID: Utils.getuuid(),
+        MenuName: values.menuName,
+        PageParam: JSON.stringify({
+          Icon: values.icon
+        })
+      }
+      param.func = 'sPC_SndMenu_Add'
+      param.Sort = (this.props.mainMenu.children.length + 1) * 10
+
+      this.setState({
+        loading: true
+      })
+      Api.getSystemConfig(param).then(res => {
+        if (res.status) {
+          this.setState({
+            loading: false,
+            visible: false
+          })
+          MKEmitter.emit('mkUpdateMenuList')
+        } else {
+          this.setState({
+            loading: false
+          })
+          notification.warning({
+            top: 92,
+            message: res.message,
+            duration: 5
+          })
+        }
+      })
+    })
+  }
+
+  /**
+   * @description 涓夌骇鑿滃崟淇敼
+   */
+  thdSubmit = () => {
+    const { sysMenu } = this.state
+
+    this.menuThdFormRef.handleConfirm().then(res => {
+      let PageParam = {
+        Template: sysMenu.Template,
+        OpenType: 'newtab'
+      }
+
+      if (sysMenu.Template === 'NewPage') {
+        PageParam.OpenType = 'NewPage'
+        PageParam.url = res.url
+      }
+
+      let param = {
+        func: 'sPC_TrdMenu_AddUpt',
+        FstID: res.fstMenuId,
+        SndID: res.ParentID,
+        ParentID: res.ParentID,
+        MenuID: sysMenu.MenuID,
+        MenuNo: res.MenuNo,
+        Template: sysMenu.Template,
+        MenuName: res.MenuName,
+        PageParam: JSON.stringify(PageParam),
+        LongParam: '',
+        LText: '',
+        LTexttb: ''
+      }
+
+      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+      param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+
+      this.setState({
+        loading: true
+      })
+
+      Api.getSystemConfig(param).then(response => {
+        if (response.status) {
+          this.setState({
+            loading: false,
+            thdVisible: false,
+            sysMenu: null
+          })
+          MKEmitter.emit('mkUpdateMenuList')
+        } else {
+          this.setState({
+            loading: false
+          })
+          notification.warning({
+            top: 92,
+            message: response.message,
+            duration: 5
+          })
+        }
+      })
+    })
+  }
+
   render () {
-    const { mainMenu } = this.props
+    const { mainMenu, editLevel } = this.props
+    const { visible, loading, thdVisible } = this.state
 
     return (
       <aside className="mk-sys-side-menu ant-menu-dark mk-edit">
-        {!(this.props.editLevel === 'level2' || this.props.editLevel === 'level3') &&
+        {editLevel !== 'level2' && editLevel !== 'level3' && mainMenu ?
           <Menu openKeys={this.state.openKeys} onOpenChange={this.onOpenChange} mode="inline" theme="dark">
-          {!this.props.editLevel && mainMenu ? <li className="sup-menu"><EditOutlined onClick={this.enterSubEdit} className="edit-check"/></li> : null}
-          {this.state.subMenulist && this.state.subMenulist.map((item, index) => {
+          <li className="sup-menu">
+            <Popover overlayClassName="mk-popover-control-wrap mk-menu-control" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+              <div className="mk-popover-control">
+                <PlusOutlined onClick={this.addSecMenu}/>
+                <SwapOutlined onClick={this.enterSubEdit} className={'mk-swap' + (mainMenu.children.length === 0 ? ' disabled' : '')}/>
+                <div style={{display: 'inline-block', minWidth: '32px'}}><ThawMenu ParentId={mainMenu.MenuID} Type="20"/></div>
+              </div>
+            } trigger="hover" placement="top">
+              <SettingOutlined className="edit-check"/>
+            </Popover>
+          </li>
+          {mainMenu.children.map((item, index) => {
             return (
               <SubMenu
                 key={item.MenuID}
                 title={
-                  <span className={!this.props.editLevel && index === 0 ? 'edit-control' : ''}>
+                  <span className={!editLevel && index === 0 ? 'edit-control' : ''}>
                     <MkIcon type={item.PageParam.Icon} />
                     <span>{item.MenuName}</span>
                   </span>
                 }
               >
-                {!this.props.editLevel ? <li className={'ant-menu-item ' + (item.children.length > 0 ? 'sub-menu' : '')}>
-                  <EditOutlined onClick={(e) => {this.enterThrEdit(e, item)}} className="edit-check"/>
-                </li> : null}
+                <li className={'ant-menu-item ' + (item.children.length > 0 ? 'sub-menu' : '')}>
+                  <Popover overlayClassName="mk-popover-control-wrap mk-menu-control" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+                    <div className="mk-popover-control">
+                      <div style={{display: 'inline-block', minWidth: '32px'}}><AddThdMenu mainMenu={mainMenu} supMenu={item} menuTree={this.props.menuTree}/></div>
+                      <SwapOutlined onClick={(e) => {this.enterThrEdit(e, item)}} className="mk-swap"/>
+                      <div style={{display: 'inline-block', minWidth: '32px'}}><ThawMenu ParentId={item.MenuID} Type="30"/></div>
+                    </div>
+                  } trigger="hover" placement="top">
+                    <SettingOutlined className="edit-check"/>
+                  </Popover>
+                </li>
                 {item.children.map(cell => {
                   return (
                     <Menu.Item key={cell.MenuID}>
-                      <a href={cell.src} id={cell.MenuID} onClick={(e) => this.changemenu(e, cell)}>{cell.MenuName}</a>
+                      <span className="editable-menu-item" onDoubleClick={() => this.editmenu(cell)}>{cell.MenuName}</span>
                     </Menu.Item>
                   )
                 })}
               </SubMenu>
             )
           })}
-        </Menu>}
-        {this.props.editLevel === 'level2' ?
+        </Menu> : null}
+        {editLevel === 'level2' && mainMenu ?
           <EditSecMenu
-            menulist={this.state.subMenulist}
+            menulist={mainMenu.children}
             menuTree={this.props.menuTree}
             supMenu={this.props.mainMenu}
-            reload={this.reload}
             exitEdit={this.exitEdit}
           /> : null
         }
-        {this.props.editLevel === 'level3' && this.state.editMenu ?
+        {editLevel === 'level3' && mainMenu && this.state.editMenu ?
           <EditThdMenu
             menulist={this.state.editMenu.children}
-            supMenuList={this.state.subMenulist}
+            supMenuList={mainMenu.children}
             supMenu={this.state.editMenu}
-            reload={this.reload}
             exitEdit={this.exitEdit}
           /> : null
         }
+        <Modal
+          title="娣诲姞鑿滃崟"
+          visible={visible}
+          onOk={this.secSubmit}
+          // confirmLoading={loading}
+          onCancel={() => this.setState({visible: false})}
+          destroyOnClose
+        >
+          <MenuForm
+            inputSubmit={this.secSubmit}
+            formlist={this.state.formlist}
+            wrappedComponentRef={(inst) => this.menuFormRef = inst}
+          />
+        </Modal>
+        <Modal
+          title="淇敼鑿滃崟"
+          visible={thdVisible}
+          width={600}
+          onOk={this.thdSubmit}
+          confirmLoading={loading}
+          onCancel={() => {this.setState({thdVisible: false})}}
+          destroyOnClose
+        >
+          <ThdMenuForm
+            menu={this.state.sysMenu}
+            inputSubmit={this.thdSubmit}
+            wrappedComponentRef={(inst) => this.menuThdFormRef = inst}
+          />
+        </Modal>
       </aside>
     )
   }
@@ -293,15 +376,12 @@
   return {
     mainMenu: state.mainMenu,
     menuTree: state.menuTree,
-    memberLevel: state.memberLevel,
     editLevel: state.editLevel
   }
 }
 
 const mapDispatchToProps = (dispatch) => {
   return {
-    modifyMenuTree: (menuTree) => dispatch(modifyMenuTree(menuTree)),
-    modifyMainMenu: (mainMenu) => dispatch(modifyMainMenu(mainMenu)),
     resetEditLevel: (level) => dispatch(resetEditLevel(level))
   }
 }
diff --git a/src/views/design/sidemenu/index.scss b/src/views/design/sidemenu/index.scss
index c3e8ff7..22cc2fa 100644
--- a/src/views/design/sidemenu/index.scss
+++ b/src/views/design/sidemenu/index.scss
@@ -11,6 +11,11 @@
     a {
       padding-left: 48px;
     }
+    .editable-menu-item {
+      display: block;
+      padding-left: 48px;
+      cursor: pointer;
+    }
   }
   .ant-menu-sub.ant-menu-inline {
     position: relative;
@@ -58,6 +63,7 @@
       color: #ffffff;
     }
   }
+  
   .edit-control + .ant-menu-submenu-arrow {
     display: none;
   }
@@ -116,4 +122,4 @@
   a {
     cursor: pointer;
   }
-}
\ No newline at end of file
+}
diff --git a/src/views/design/sidemenu/menuelement/card.jsx b/src/views/design/sidemenu/menuelement/card.jsx
new file mode 100644
index 0000000..b9133a4
--- /dev/null
+++ b/src/views/design/sidemenu/menuelement/card.jsx
@@ -0,0 +1,61 @@
+import React from 'react'
+import { useDrag, useDrop } from 'react-dnd'
+import { EditOutlined, CloseOutlined } from '@ant-design/icons'
+import ItemTypes from './itemtypes'
+import MkIcon from '@/components/mk-icon'
+import './index.scss'
+
+const Card = ({ id, card, moveCard, findCard, editCard, closeCard }) => {
+  const originalIndex = findCard(id).index
+  const [{ isDragging }, drag] = useDrag({
+    item: { type: ItemTypes.CARD, id, originalIndex },
+    collect: monitor => ({
+      isDragging: monitor.isDragging(),
+    }),
+  })
+  const [, drop] = useDrop({
+    accept: ItemTypes.CARD,
+    canDrop: () => true,
+    drop({ id: draggedId }) {
+      if (draggedId !== id) {
+        const { index: overIndex } = findCard(id)
+        moveCard(draggedId, overIndex)
+      }
+    },
+  })
+  const opacity = isDragging ? 0.5 : 1
+
+  const edit = () => {
+    editCard(id)
+  }
+
+  const close = () => {
+    closeCard(id)
+  }
+
+  if (card.level === 'second') {
+    return (
+      <div className="side-card" style={{ opacity }}>
+        <div ref={node => drag(drop(node))}>
+          {card.PageParam && card.PageParam.Icon && <MkIcon type={card.PageParam.Icon} />}
+          {card.MenuName}
+        </div>
+        <EditOutlined className="edit" onClick={edit} />
+        <CloseOutlined className="close" onClick={close} />
+      </div>
+    )
+  } else {
+    return (
+      <div className="side-card" style={{ opacity }}>
+        <div ref={node => drag(drop(node))}>
+          {card.MenuName}
+        </div>
+        {/* 鑷畾涔夋ā鏉匡紝鍦ㄦ柊椤甸潰缂栬緫 */}
+        {!card.forbidden ? <EditOutlined className="edit" onClick={edit} /> : null}
+        {card.forbidden && card.type === 'CustomPage' ? <EditOutlined className="edit" style={{color: '#959595', cursor: 'not-allowed'}} title="浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��"/> : null}
+        <CloseOutlined className="close" onClick={close} />
+      </div>
+    )
+  }
+}
+export default Card
diff --git a/src/templates/menuconfig/menuelement/index.jsx b/src/views/design/sidemenu/menuelement/index.jsx
similarity index 100%
rename from src/templates/menuconfig/menuelement/index.jsx
rename to src/views/design/sidemenu/menuelement/index.jsx
diff --git a/src/templates/menuconfig/menuelement/index.scss b/src/views/design/sidemenu/menuelement/index.scss
similarity index 81%
rename from src/templates/menuconfig/menuelement/index.scss
rename to src/views/design/sidemenu/menuelement/index.scss
index 7a53089..2ec4117 100644
--- a/src/templates/menuconfig/menuelement/index.scss
+++ b/src/views/design/sidemenu/menuelement/index.scss
@@ -5,16 +5,7 @@
   float: left;
   background: #001529;
   padding-bottom: 5px;
-  .card-add {
-    border: 1px dashed gray;
-    padding: 2px;
-    margin-top: 13px;
-    margin-left: 10px;
-    width: 50px;
-    float: left;
-    text-align: center;
-    cursor: pointer;
-  }
+
   button {
     margin-top: 14px;
     margin-left: 10px;
@@ -24,7 +15,7 @@
 }
 .side-card {
   position: relative;
-  border: 1px dashed gray;
+  border: 1px dashed #535353;
   margin-top: 8px;
   height: 40px;
   width: 98%;
diff --git a/src/templates/menuconfig/menuelement/itemtypes.js b/src/views/design/sidemenu/menuelement/itemtypes.js
similarity index 100%
rename from src/templates/menuconfig/menuelement/itemtypes.js
rename to src/views/design/sidemenu/menuelement/itemtypes.js
diff --git a/src/templates/menuconfig/menuform/index.jsx b/src/views/design/sidemenu/menuform/index.jsx
similarity index 84%
rename from src/templates/menuconfig/menuform/index.jsx
rename to src/views/design/sidemenu/menuform/index.jsx
index 8a1ae15..fa06332 100644
--- a/src/templates/menuconfig/menuform/index.jsx
+++ b/src/views/design/sidemenu/menuform/index.jsx
@@ -3,13 +3,12 @@
 import { Form, Row, Col, Input, Select } from 'antd'
 
 import asyncComponent from '@/utils/asyncComponent'
-import './index.scss'
+// import './index.scss'
 
 const MkEditIcon = asyncComponent(() => import('@/components/mkIcon'))
 
-class MainSearch extends Component {
+class MainForm extends Component {
   static propTpyes = {
-    dict: PropTypes.object,     // 瀛楀吀椤�
     formlist: PropTypes.array,
     inputSubmit: PropTypes.func
   }
@@ -48,10 +47,10 @@
                 rules: [
                   {
                     required: !!item.required,
-                    message: this.props.dict['form.required.input'] + item.label + '!'
+                    message: '璇疯緭鍏�' + item.label + '!'
                   }
                 ]
-              })(<Input placeholder="" autoFocus={item.key.toLowerCase() === 'menuname'} autoComplete="off" disabled={item.readonly} />)}
+              })(<Input placeholder="" autoFocus={item.key.toLowerCase() === 'menuname'} autoComplete="off" disabled={item.readonly} onPressEnter={() => this.props.inputSubmit()}/>)}
             </Form.Item>
           </Col>
         )
@@ -64,7 +63,7 @@
                 rules: [
                   {
                     required: !!item.required,
-                    message: this.props.dict['form.required.select'] + item.label + '!'
+                    message: '璇烽�夋嫨' + item.label + '!'
                   }
                 ]
               })(
@@ -93,7 +92,7 @@
                 rules: [
                   {
                     required: !!item.required,
-                    message: this.props.dict['form.required.select'] + item.label + '!'
+                    message: '璇烽�夋嫨' + item.label + '!'
                   }
                 ]
               })(
@@ -120,13 +119,6 @@
     })
   }
 
-  onEnterSubmit = (e) => {
-    // 琛ㄥ崟鍥炶溅鎻愪氦
-    if (e.key !== 'Enter') return
-    
-    this.props.inputSubmit && this.props.inputSubmit()
-  }
-
   render() {
     const formItemLayout = {
       labelCol: {
@@ -139,11 +131,11 @@
       }
     }
     return (
-      <Form {...formItemLayout} className="ant-advanced-search-form" id="form-box" onKeyDown={this.onEnterSubmit}>
+      <Form {...formItemLayout} id="form-box">
         <Row gutter={24}>{this.getFields()}</Row>
       </Form>
     )
   }
 }
 
-export default Form.create()(MainSearch)
\ No newline at end of file
+export default Form.create()(MainForm)
\ No newline at end of file
diff --git a/src/views/design/sidemenu/menuform/index.scss b/src/views/design/sidemenu/menuform/index.scss
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/views/design/sidemenu/menuform/index.scss
@@ -0,0 +1 @@
+
diff --git a/src/templates/menuconfig/editthdmenu/menuform/index.jsx b/src/views/design/sidemenu/thdmenuform/index.jsx
similarity index 76%
copy from src/templates/menuconfig/editthdmenu/menuform/index.jsx
copy to src/views/design/sidemenu/thdmenuform/index.jsx
index c86cde8..1d68f35 100644
--- a/src/templates/menuconfig/editthdmenu/menuform/index.jsx
+++ b/src/views/design/sidemenu/thdmenuform/index.jsx
@@ -1,38 +1,43 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
+import { fromJS } from 'immutable'
 import { Form, Row, Col, Input, Select } from 'antd'
-import './index.scss'
+// import './index.scss'
 
 const { TextArea } = Input
 
 class MainSearch extends Component {
   static propTpyes = {
     menu: PropTypes.object,      // 鑿滃崟淇℃伅
-    dict: PropTypes.object,      // 瀛楀吀椤�
-    supMenuList: PropTypes.any,  // 琛ㄦ牸鏁版嵁
     inputSubmit: PropTypes.func  // 鍥炶溅鎻愪氦
   }
 
   state = {
-    menu: null
+    supMenuList: []
   }
 
   UNSAFE_componentWillMount () {
     this.setState({
-      menu: this.props.menu
+      supMenuList: fromJS(this.props.menu.supMenuList).toJS()
     })
   }
 
   changeMenu = (val) => {
-    const { menu } = this.state
+    const { menu } = this.props
 
     let submenu = menu.fstMenuList.filter(item => item.MenuID === val)[0]
 
     if (submenu) {
       this.setState({
-        menu: {...menu, supMenuList: submenu.children}
+        supMenuList: submenu.children
       }, () => {
         this.props.form.setFieldsValue({ParentID: submenu.children[0] ? submenu.children[0].MenuID : ''})
+      })
+    } else {
+      this.setState({
+        supMenuList: []
+      }, () => {
+        this.props.form.setFieldsValue({ParentID: ''})
       })
     }
   }
@@ -50,16 +55,10 @@
     })
   }
 
-  onEnterSubmit = (e) => {
-    // 琛ㄥ崟鍥炶溅鎻愪氦
-    if (e.key !== 'Enter') return
-    
-    this.props.inputSubmit && this.props.inputSubmit()
-  }
-
   render() {
+    const { menu } = this.props
     const { getFieldDecorator } = this.props.form
-    const { menu } = this.state
+    const { supMenuList } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -72,16 +71,16 @@
     }
 
     return (
-      <Form {...formItemLayout} style={{paddingRight: '20px'}} onKeyDown={this.onEnterSubmit}>
+      <Form {...formItemLayout} style={{paddingRight: '20px'}}>
         <Row gutter={24}>
-          <Col span={24}>
+          <Col span={22}>
             <Form.Item label={'涓�绾ц彍鍗�'}>
               {getFieldDecorator('fstMenuId', {
                 initialValue: menu.fstMenuId,
                 rules: [
                   {
                     required: true,
-                    message: this.props.dict['form.required.select'] + '涓婄骇鑿滃崟!'
+                    message: '璇烽�夋嫨涓婄骇鑿滃崟!'
                   }
                 ]
               })(
@@ -97,14 +96,14 @@
               )}
             </Form.Item>
           </Col>
-          <Col span={24}>
+          <Col span={22}>
             <Form.Item label={'浜岀骇鑿滃崟'}>
               {getFieldDecorator('ParentID', {
                 initialValue: menu.ParentId,
                 rules: [
                   {
                     required: true,
-                    message: this.props.dict['form.required.select'] + '涓婄骇鑿滃崟!'
+                    message: '璇烽�夋嫨涓婄骇鑿滃崟!'
                   }
                 ]
               })(
@@ -112,47 +111,47 @@
                   showSearch
                   filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                 >
-                  {menu.supMenuList.map(option =>
+                  {supMenuList.map(option =>
                     <Select.Option key={option.MenuID} value={option.MenuID}>{option.text || option.MenuName}</Select.Option>
                   )}
                 </Select>
               )}
             </Form.Item>
           </Col>
-          <Col span={24}>
+          <Col span={22}>
             <Form.Item label={'鑿滃崟鍚嶇О'}>
               {getFieldDecorator('MenuName', {
                 initialValue: menu.MenuName || '',
                 rules: [
                   {
                     required: true,
-                    message: this.props.dict['form.required.input'] + '鑿滃崟鍚嶇О!'
+                    message: '璇疯緭鍏ヨ彍鍗曞悕绉�!'
                   }
                 ]
-              })(<Input placeholder="" autoFocus autoComplete="off" />)}
+              })(<Input placeholder="" autoFocus autoComplete="off" onPressEnter={() => this.props.inputSubmit()}/>)}
             </Form.Item>
           </Col>
-          <Col span={24}>
+          <Col span={22}>
             <Form.Item label={'鑿滃崟鍙傛暟'}>
               {getFieldDecorator('MenuNo', {
                 initialValue: menu.MenuNo || '',
                 rules: [
                   {
                     required: true,
-                    message: this.props.dict['form.required.input'] + '鑿滃崟鍙傛暟!'
+                    message: '璇疯緭鍏ヨ彍鍗曞弬鏁�!'
                   }
                 ]
-              })(<Input placeholder="" autoComplete="off" />)}
+              })(<Input placeholder="" autoComplete="off" onPressEnter={() => this.props.inputSubmit()}/>)}
             </Form.Item>
           </Col>
-          {menu.Template === 'NewPage' ? <Col span={24}>
+          {menu.Template === 'NewPage' ? <Col span={22}>
             <Form.Item label={'閾炬帴鍦板潃'}>
               {getFieldDecorator('url', {
                 initialValue: menu.url || '',
                 rules: [
                   {
                     required: true,
-                    message: this.props.dict['form.required.input'] + '椤甸潰鍦板潃!'
+                    message: '璇疯緭鍏ラ〉闈㈠湴鍧�!'
                   },
                   {
                     max: 1024,
diff --git a/src/templates/menuconfig/editthdmenu/menuform/index.scss b/src/views/design/sidemenu/thdmenuform/index.scss
similarity index 100%
copy from src/templates/menuconfig/editthdmenu/menuform/index.scss
copy to src/views/design/sidemenu/thdmenuform/index.scss
diff --git a/src/views/design/sidemenu/thdmenuplus/index.jsx b/src/views/design/sidemenu/thdmenuplus/index.jsx
new file mode 100644
index 0000000..bbf051e
--- /dev/null
+++ b/src/views/design/sidemenu/thdmenuplus/index.jsx
@@ -0,0 +1,357 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Modal, notification, Col, Card, Tabs, Row, Input, Button } from 'antd'
+import { PlusOutlined } from '@ant-design/icons'
+import moment from 'moment'
+
+import Api from '@/api'
+import { sysTemps } from '@/utils/option.js'
+import MKEmitter from '@/utils/events.js'
+import Utils from '@/utils/utils.js'
+import Preview from './preview'
+import MenuUtils from '@/utils/utils-custom.js'
+import asyncComponent from '@/utils/asyncComponent'
+
+import mainsubtable from '@/assets/img/mainsubtable.jpg'
+import treepage from '@/assets/img/treepage.jpg'
+import calendar from '@/assets/img/calendar.jpg'
+import customImg from '@/assets/img/custom.jpg'
+
+import './index.scss'
+
+const MenuForm = asyncComponent(() => import('../thdmenuform'))
+const { TabPane } = Tabs
+const { Search } = Input
+
+class ThdMenuAdd extends Component {
+  static propTpyes = {
+    mainMenu: PropTypes.object,
+    supMenu: PropTypes.object,
+    menuTree: PropTypes.array,
+    Type: PropTypes.string
+  }
+
+  state = {
+    sysTemplates: [],
+    usedTemplates: [],
+    tempSearchKey: '',
+    addVisible: false,
+    preview: null,
+    visible: false,
+    sysMenu: null,
+    loading: false
+  }
+
+  UNSAFE_componentWillMount() {
+    this.getUsedTemplate()
+  }
+
+  getUsedTemplate = () => {
+    let { sysTemplates } = this.state
+    let memberLevel = Utils.getMemberLevel()
+    const illust = { // 妯℃澘鍥剧墖锛岀敤浜庡凡浣跨敤妯℃澘
+      CommonTable: mainsubtable,
+      TreePage: treepage,
+      CalendarPage: calendar,
+      CustomPage: customImg
+    }
+
+    Api.getSystemConfig({func: 'sPC_Get_UserTemp', TypeCharTwo: 'menu'}).then(res => {
+      let _templates = []
+
+      res.UserTemp.forEach(temp => {
+        if (!['CommonTable', 'TreePage', 'CalendarPage', 'CustomPage'].includes(temp.Template)) {
+          return
+        } else if (temp.Template === 'CustomPage' && memberLevel < 20) {
+          temp.disabled = true
+          temp.disTitle = '浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��'
+        }
+        
+        _templates.push({
+          uuid: temp.MenuID,
+          title: temp.MenuName,
+          type: temp.Template,
+          url: illust[temp.Template],
+          disabled: temp.disabled || false,
+          disTitle: temp.disTitle || ''
+        })
+      })
+
+      sysTemplates = sysTemps.map(temp => {
+        if (temp.type === 'CustomPage' && memberLevel < 20) {
+          temp.disabled = true
+          temp.disTitle = '浼氬憳绛夌骇涓嶅锛屾棤寮�鍙戞潈闄愩��'
+        }
+
+        return temp
+      })
+
+      this.setState({
+        usedTemplates: _templates,
+        sysTemplates: sysTemplates
+      })
+    })
+  }
+
+  trigger = () => {
+    this.setState({
+      visible: true
+    })
+    document.getElementById('root').style.overflowY = 'hidden'
+  }
+
+  previewPicture = (template) => {
+    if (template.disabled) return
+    // 鍥剧墖棰勮
+    this.setState({
+      preview: template.url,
+      pretemplate: template
+    })
+  }
+
+  cancelPrePicture = () => {
+    // 鍏抽棴鍥剧墖棰勮
+    this.setState({
+      preview: null
+    })
+  }
+
+  useTemplate = (template) => {
+    const { mainMenu, supMenu, menuTree } = this.props
+
+    let sysMenu = {
+      MenuID: Utils.getuuid(),
+      MenuName: template.title,
+      Template: template.type,
+      fstMenuId: mainMenu.MenuID,
+      ParentId: supMenu.MenuID,
+      menuSort: (supMenu.children.length + 1) * 10,
+      copyId: template.uuid || '',
+      fstMenuList: menuTree,
+      supMenuList: mainMenu.children
+    }
+
+    this.setState({
+      visible: false
+    }, () => {
+      this.setState({
+        addVisible: true,
+        sysMenu: sysMenu
+      })
+      document.getElementById('root').style.overflowY = 'unset'
+    })
+  }
+
+  memuSubmit = () => {
+    const { sysMenu } = this.state
+
+    this.menuFormRef.handleConfirm().then(values => {
+      let PageParam = {
+        Template: sysMenu.Template,
+        OpenType: 'newtab'
+      }
+
+      if (sysMenu.Template === 'NewPage') {
+        PageParam.OpenType = 'NewPage'
+        PageParam.url = values.url
+      }
+
+      if (sysMenu.copyId && sysMenu.Template !== 'CustomPage') {
+        PageParam.copyMenuId = sysMenu.copyId
+      }
+
+      let param = {
+        func: 'sPC_TrdMenu_AddUpt',
+        FstID: values.fstMenuId,
+        SndID: values.ParentID,
+        ParentID: values.ParentID,
+        MenuID: sysMenu.MenuID,
+        MenuNo: values.MenuNo,
+        Template: sysMenu.Template,
+        MenuName: values.MenuName,
+        PageParam: JSON.stringify(PageParam),
+        LongParam: '',
+        LText: '',
+        LTexttb: '',
+        Sort: sysMenu.menuSort
+      }
+
+      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+      param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+
+      this.setState({
+        loading: true
+      })
+
+      if (sysMenu.Template === 'CustomPage' && sysMenu.copyId) {
+        this.copyMenu(param, sysMenu.copyId)
+      } else {
+        Api.getSystemConfig(param).then(response => {
+          if (response.status) {
+            this.setState({
+              loading: false,
+              addVisible: false,
+              sysMenu: null
+            })
+  
+            MKEmitter.emit('mkUpdateMenuList')
+          } else {
+            this.setState({
+              loading: false
+            })
+            notification.warning({
+              top: 92,
+              message: response.message,
+              duration: 5
+            })
+          }
+        })
+      }
+    })
+  }
+
+  copyMenu = (param, MenuId) => {
+    Api.getSystemConfig({
+      func: 'sPC_Get_LongParam',
+      MenuID: MenuId
+    }).then(result => {
+      if (result.status) {
+        let config = null
+
+        try {
+          config = result.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) : null
+        } catch (e) {
+          console.warn('Parse Failure')
+          config = null
+        }
+  
+        if (config) {
+          config.uuid = param.MenuID
+          config.MenuID = param.MenuID
+          config.parentId = param.ParentID
+          config.MenuName = param.MenuName
+          config.MenuNo = param.MenuNo
+          config.easyCode = ''
+          config.components = MenuUtils.resetConfig(config.components)
+          config.enabled = false
+
+          param.LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(config)))
+        }
+
+        Api.getSystemConfig(param).then(response => {
+          if (response.status) {
+            this.setState({
+              loading: false,
+              addVisible: false,
+              sysMenu: null
+            })
+  
+            MKEmitter.emit('mkUpdateMenuList')
+            document.getElementById('root').style.overflowY = 'unset'
+          } else {
+            this.setState({
+              loading: false
+            })
+            notification.warning({
+              top: 92,
+              message: response.message,
+              duration: 5
+            })
+          }
+        })
+      } else {
+        this.setState({
+          confirmLoading: false
+        })
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+      }
+    })
+  }
+
+  render() {
+    const { visible, loading, tempSearchKey } = this.state
+
+    return (
+      <>
+        <PlusOutlined onClick={this.trigger}/>
+        <Modal
+          className="mk-template-modal"
+          visible={visible}
+          onOk={this.submit}
+          onCancel={() => this.setState({visible: false}, () => {document.getElementById('root').style.overflowY = 'unset'})}
+          destroyOnClose
+        >
+          <Tabs defaultActiveKey="1">
+            <TabPane tab="绯荤粺妯℃澘" key="1">
+              <Row>
+                {this.state.sysTemplates.map((template, index) => {
+                  return (
+                    <Col key={`${index}`} className={template.disabled ? 'disabled' : ''} title={template.disTitle || ''} span={8}>
+                      <Card
+                        title={template.title}>
+                        <img onClick={() => {this.previewPicture(template)}} src={template.url} alt=""/>
+                        <div className="card-operation">
+                          <Button type="primary" onClick={() => {this.useTemplate(template, 'sys')}}>浣跨敤妯℃澘</Button>
+                        </div>
+                      </Card>
+                    </Col>
+                  )
+                })}
+              </Row>
+            </TabPane>
+            <TabPane tab="宸蹭娇鐢ㄦā鏉�" key="2">
+              <Row>
+                <Col span={8}>
+                  <Search placeholder="璇疯緭鍏ヨ彍鍗曞悕绉�" defaultValue={''} onSearch={value => {this.setState({tempSearchKey: value})}} enterButton />
+                </Col>
+              </Row>
+              <Row>
+                {this.state.usedTemplates.map((template, index) => {
+                  if (!tempSearchKey || template.title.toLowerCase().indexOf(tempSearchKey.toLowerCase()) >= 0) {
+                    return (
+                      <Col key={template.type + index} className={template.disabled ? 'disabled' : ''} title={template.disTitle || ''} span={6}>
+                        <Card
+                          title={template.title}>
+                          <img onClick={() => {this.previewPicture(template)}} src={template.url} alt=""/>
+                          <div className="card-operation">
+                            <Button type="primary" onClick={() => {this.useTemplate(template, 'user')}}>浣跨敤妯℃澘</Button>
+                          </div>
+                        </Card>
+                      </Col>
+                    )
+                  } else {
+                    return null
+                  }
+                })}
+              </Row>
+            </TabPane>
+          </Tabs>
+          {/* 鍥剧墖棰勮 */}
+          <Preview cancel={this.cancelPrePicture} preview={this.state.preview} template={this.state.pretemplate} confirm={this.useTemplate}/>
+        </Modal>
+        {/* 娣诲姞绯荤粺鑿滃崟 */}
+        <Modal
+          title="娣诲姞鑿滃崟"
+          visible={this.state.addVisible}
+          width={600}
+          onOk={this.memuSubmit}
+          confirmLoading={loading}
+          onCancel={() => {this.setState({addVisible: false})}}
+          destroyOnClose
+        >
+          <MenuForm
+            menu={this.state.sysMenu}
+            inputSubmit={this.memuSubmit}
+            wrappedComponentRef={(inst) => this.menuFormRef = inst}
+          />
+        </Modal>
+      </>
+    )
+  }
+}
+
+export default ThdMenuAdd
\ No newline at end of file
diff --git a/src/views/design/sidemenu/thdmenuplus/index.scss b/src/views/design/sidemenu/thdmenuplus/index.scss
new file mode 100644
index 0000000..86c37fa
--- /dev/null
+++ b/src/views/design/sidemenu/thdmenuplus/index.scss
@@ -0,0 +1,137 @@
+.editboard {
+  position: fixed;
+  z-index: 1070;
+  padding-top: 48px;
+  top: 0px;
+  left: 0px;
+  right: 0px;
+  bottom: 0px;
+  background: rgba(0, 0, 0, 0.35);
+  .workplace {
+    position: relative;
+    width: calc(100vw - 235px);
+    height: 100%;
+    overflow-y: auto;
+    left: 235px;
+    background: #ffffff;
+
+    .top-btn {
+      position: absolute;
+      z-index: 1;
+      top: 12px;
+      right: 20px;
+      cursor: pointer;
+    }
+    .top-btn.submit {
+      right: 100px;
+    }
+    
+  }
+  .workplace::-webkit-scrollbar {
+    width: 7px;
+  }
+  .workplace::-webkit-scrollbar-thumb {
+    border-radius: 5px;
+    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+    background: rgba(0, 0, 0, 0.13);
+  }
+  .workplace::-webkit-scrollbar-track {
+    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
+    border-radius: 3px;
+    border: 1px solid rgba(0, 0, 0, 0.07);
+    background: rgba(0, 0, 0, 0);
+  }
+}
+.mk-template-modal {
+  width: calc(100vw - 235px)!important;
+  left: 117px;
+  top: 48px;
+  padding-bottom: 0px;
+  .ant-modal-close {
+    .ant-modal-close-x {
+      height: 50px;
+      line-height: 50px;
+    }
+  }
+  .ant-modal-header {
+    display: none;
+  }
+  .ant-modal-footer {
+    display: none;
+  }
+  .ant-modal-body {
+    padding: 0px;
+
+    .ant-tabs-tabpane {
+      height: calc(100vh - 110px);
+      overflow-y: auto;
+      padding: 0 15px 20px 15px;
+
+      .ant-col {
+        padding: 10px;
+      }
+      .ant-col.disabled {
+        cursor: not-allowed;
+        .ant-card-head-title {
+          color: #959595;
+        }
+        .card-operation {
+          display: none;
+        }
+        img {
+          cursor: not-allowed;
+        }
+      }
+      .ant-card-head-title {
+        text-align: center;
+      }
+      .ant-card-body {
+        padding: 2px;
+        position: relative;
+        text-align: center;
+        overflow: hidden;
+        .card-operation {
+          position: absolute;
+          right: 0px;
+          top: 0;
+          height: 0px;
+          overflow: hidden;
+          transition: height 0.3s;
+          button {
+            height: 30px;
+            padding: 0 10px;
+            margin-top: 5px;
+            margin-right: 10px;
+            display: none;
+          }
+        }
+      }
+      .ant-card-body:hover {
+        .card-operation {
+          height: 40px;
+          button {
+            display: inline-block;
+          }
+        }
+      }
+      img {
+        max-width: 100%;
+        cursor: zoom-in;
+      }
+    }
+    .ant-tabs-tabpane::-webkit-scrollbar {
+      width: 7px;
+    }
+    .ant-tabs-tabpane::-webkit-scrollbar-thumb {
+      border-radius: 5px;
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+      background: rgba(0, 0, 0, 0.13);
+    }
+    .ant-tabs-tabpane::-webkit-scrollbar-track {
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
+      border-radius: 3px;
+      border: 1px solid rgba(0, 0, 0, 0.07);
+      background: rgba(0, 0, 0, 0);
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/templates/menuconfig/editthdmenu/preview/index.jsx b/src/views/design/sidemenu/thdmenuplus/preview/index.jsx
similarity index 100%
rename from src/templates/menuconfig/editthdmenu/preview/index.jsx
rename to src/views/design/sidemenu/thdmenuplus/preview/index.jsx
diff --git a/src/templates/menuconfig/editthdmenu/preview/index.scss b/src/views/design/sidemenu/thdmenuplus/preview/index.scss
similarity index 100%
rename from src/templates/menuconfig/editthdmenu/preview/index.scss
rename to src/views/design/sidemenu/thdmenuplus/preview/index.scss
diff --git a/src/views/interface/header/index.jsx b/src/views/interface/header/index.jsx
index 03804df..903325e 100644
--- a/src/views/interface/header/index.jsx
+++ b/src/views/interface/header/index.jsx
@@ -1,8 +1,6 @@
 import React, {Component} from 'react'
-import { withRouter } from 'react-router-dom'
 
 import Utils from '@/utils/utils.js'
-import options from '@/store/options.js'
 import avatar from '@/assets/img/avatar.jpg'
 import MainLogo from '@/assets/img/main-logo.png'
 import './index.scss'
@@ -13,12 +11,7 @@
     avatar: Utils.getrealurl(sessionStorage.getItem('CloudAvatar')),
   }
 
-  UNSAFE_componentWillMount() {
-    if (options.sysType !== 'local' || !sessionStorage.getItem('LoginUID')) {
-      sessionStorage.clear()
-      this.props.history.replace('/login')
-    }
-  }
+  UNSAFE_componentWillMount() {}
 
   close = () => {
     window.close()
@@ -42,4 +35,4 @@
   }
 }
 
-export default withRouter(Header)
\ No newline at end of file
+export default Header
\ No newline at end of file
diff --git a/src/views/interface/history/index.jsx b/src/views/interface/history/index.jsx
index 42fea84..a8d4321 100644
--- a/src/views/interface/history/index.jsx
+++ b/src/views/interface/history/index.jsx
@@ -195,30 +195,42 @@
   }
 
   uselogon = () => {
+    let baseurl = ''
+    if (process.env.NODE_ENV === 'production') {
+      baseurl = document.location.origin + '/' + window.GLOB.service
+    } else {
+      baseurl = window.GLOB.location + '/' + window.GLOB.service
+    }
     let m = {
       active: 'raw',
       createDate: '',
       formData: [],
       headers: [],
-      interface: 'dologon / logon',
+      interface: baseurl + 'webapi/logon',
       method: 'POST',
       params: [],
-      raw: "{\n \"UserName\":\"******\",\n \"Password\":\"******\",\n \"systemType\":\"local\",\n \"Type\":\"鍏挜\",\n \"privatekey\":\"绉侀挜\",\n \"timestamp\":\"YYYY-MM-DD HH:mm:ss\",\n \"appkey\":\"******\"\n}",
+      raw: "{\n \"UserName\":\"******\",\n \"Password\":\"******\",\n \"systemType\":\"local\",\n \"Type\":\"鍏挜\",\n \"privatekey\":\"绉侀挜\",\n \"timestamp\":\"" + moment().format('YYYY-MM-DD HH:mm:ss') + "\",\n \"appkey\":\"" + window.GLOB.appkey + "\"\n}",
       uuid: 'dologon'
     }
     MKEmitter.emit('useInterface', m)
   }
 
   usedostars = () => {
+    let baseurl = ''
+    if (process.env.NODE_ENV === 'production') {
+      baseurl = document.location.origin + '/' + window.GLOB.service
+    } else {
+      baseurl = window.GLOB.location + '/' + window.GLOB.service
+    }
     let m = {
       active: 'raw',
       createDate: '',
       formData: [],
       headers: [],
-      interface: 'dostars',
+      interface: baseurl + 'webapi/dostars',
       method: 'POST',
       params: [],
-      raw: "{\n \"LoginUID\":\"******\",\n \"UserID\":\"******\",\n \"func\":\"******\"\n}",
+      raw: "{\n \"func\":\"******\",\n \"LoginUID\":\"******\",\n \"UserID\":\"******\",\n \"nonc\":\"" + Utils.getguid() + "\",\n \"t\":" + parseInt(new Date().getTime() / 1000) + "\n}",
       uuid: 'dologon'
     }
     MKEmitter.emit('useInterface', m)
@@ -269,7 +281,7 @@
             <div className="line-title">绀轰緥</div>
               <div className="line-item" key="dologon">
                 <div className="method">POST</div>
-                <div className="inter" style={{lineHeight: '40px'}}>dologon / logon</div>
+                <div className="inter" style={{lineHeight: '40px'}}>logon</div>
                 <div className="action" style={{paddingLeft: '40px'}}>
                   <RightOutlined onClick={this.uselogon} />
                 </div>
diff --git a/src/views/interface/workspace/request/index.jsx b/src/views/interface/workspace/request/index.jsx
index 5c2536c..ae73278 100644
--- a/src/views/interface/workspace/request/index.jsx
+++ b/src/views/interface/workspace/request/index.jsx
@@ -157,6 +157,7 @@
     } else if (/dostars/ig.test(url)) {
       if (n) {
         n = JSON.parse(n)
+
         n = this.encryptParam(n)
         n = JSON.stringify(n)
       }
@@ -200,13 +201,13 @@
   }
 
   encryptParam (param) {
-    param.nonc = Utils.getuuid()
+    param.nonc = param.nonc || Utils.getuuid()
       
     let keys = Object.keys(param).sort()
     let values = ''
     keys.forEach(key => {
-      if (key.toLowerCase() === 'rduri') return
-      if (key.toLowerCase() === 't' || key.toLowerCase() === 'sign' || param[key] === undefined) {
+      if (key.toLowerCase() === 'rduri' || key === 't') return
+      if (key.toLowerCase() === 'sign' || param[key] === undefined) {
         delete param[key]
         return
       }
@@ -220,8 +221,9 @@
         values += key + param[key]
       }
     })
+
     param.sign = md5(values)
-    param.t = new Date().getTime()
+    param.t = param.t || new Date().getTime()
 
     return param
   }
diff --git a/src/views/login/index.jsx b/src/views/login/index.jsx
index 09d4090..ef494ff 100644
--- a/src/views/login/index.jsx
+++ b/src/views/login/index.jsx
@@ -1,6 +1,5 @@
 import React, { Component } from 'react'
 import { message, Modal, notification } from 'antd'
-import { connect } from 'react-redux'
 import md5 from 'md5'
 import moment from 'moment'
 
@@ -11,7 +10,6 @@
 import enUS from '@/locales/en-US/login.js'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncLoadComponent from '@/utils/asyncLoadComponent'
-import { modifyMemberLevel } from '@/store/action'
 import './index.scss'
 
 const LoginForm = asyncLoadComponent(() => import('./loginform'))
@@ -91,6 +89,7 @@
       sessionStorage.setItem('role_id', res.role_id || '')
       sessionStorage.setItem('departmentcode', res.departmentcode || '')
       sessionStorage.setItem('organization', res.organization || '')
+      sessionStorage.setItem('mk_user_type', res.mk_user_type || '')
       sessionStorage.setItem('localRole_id', res.role_id || '')
 
       localStorage.setItem(_href + 'lang', param.lang || 'zh-CN')
@@ -186,6 +185,7 @@
       sessionStorage.setItem('role_id', res.role_id || '')
       sessionStorage.setItem('departmentcode', res.departmentcode || '')
       sessionStorage.setItem('organization', res.organization || '')
+      sessionStorage.setItem('mk_user_type', res.mk_user_type || '')
       sessionStorage.setItem('localRole_id', res.role_id || '')
 
       localStorage.setItem(_href + 'lang', param.lang || 'zh-CN')
@@ -231,6 +231,7 @@
         sessionStorage.setItem('role_id', res.role_id || '')
         sessionStorage.setItem('departmentcode', res.departmentcode || '')
         sessionStorage.setItem('organization', res.organization || '')
+        sessionStorage.setItem('mk_user_type', res.mk_user_type || '')
         sessionStorage.setItem('localRole_id', res.role_id || '')
   
         sessionStorage.removeItem('visitorUserID')
@@ -311,10 +312,7 @@
 
     const _addressUrl = _href + 'queryAddress'
 
-    if (localStorage.getItem(_addressUrl) !== 'true') {
-      sessionStorage.setItem('city', '')
-      sessionStorage.setItem('ipAddress', '')
-    } else {
+    if (localStorage.getItem(_addressUrl) === 'true') {
       this.queryAddress()
     }
 
@@ -517,6 +515,26 @@
             // res.indexlogo = res.indexlogo ? res.indexlogo.replace(/:8080/ig, '').replace(/http:/ig, 'https:') : ''
             // res.loginlogo = res.loginlogo ? res.loginlogo.replace(/:8080/ig, '').replace(/http:/ig, 'https:') : ''
 
+            if (options.sysType === 'local' && window.GLOB.systemType !== 'production') {
+              if (md5(('mk' + window.GLOB.appkey + res.sys_datetime + res.member_type + res.registry_date).toLowerCase()) !== res.secret_key) {
+                Modal.warning({
+                  title: '瀵嗛挜閿欒锛岃鑱旂郴绠$悊鍛橈紒',
+                  okText: '鐭ラ亾浜�'
+                })
+                this.setState({
+                  auth: false,
+                  authError: '瀵嗛挜閿欒锛岃鑱旂郴绠$悊鍛橈紒'
+                })
+                return
+              } else if (res.member_type === 'personal' && res.registry_date) {
+                let saveDelay = 0
+                try {
+                  saveDelay = parseInt((new Date().getTime() - new Date(res.registry_date).getTime()) / 4320000)
+                  sessionStorage.setItem('mkDelay', saveDelay)
+                } catch(e) {}
+              }
+            }
+
             let _url = _href + 'system'
             let systemMsg = {
               favicon: res.titlelogo || '',
@@ -619,8 +637,8 @@
             let memberLevel = res.member_level
 
             if (typeof(memberLevel) === 'number' && memberLevel > 10 && parseInt(memberLevel / 10) * 10 === memberLevel) {
-              sessionStorage.setItem('Member_Level', md5('mksoft' + moment().format('YYYYMM') + memberLevel))
-              this.props.modifyMemberLevel(memberLevel)
+              sessionStorage.setItem('Member_Level', md5('mksoft' + window.GLOB.appkey + new Date().getFullYear() + new Date().getMonth() + memberLevel))
+              window.GLOB.memberLevel = memberLevel
             }
 
             // positecgroup
@@ -676,8 +694,12 @@
   queryAddress = () => {
     window.callbackFunction = (res) => {
       if (res.result && res.result.ad_info) {
-        sessionStorage.setItem('city', res.result.ad_info.city)
-        sessionStorage.setItem('ipAddress', res.result.ip)
+        sessionStorage.setItem('nation', res.result.ad_info.nation || '')
+        sessionStorage.setItem('province', res.result.ad_info.province || '')
+        sessionStorage.setItem('city', res.result.ad_info.city || '')
+        sessionStorage.setItem('district', res.result.ad_info.district || '')
+        sessionStorage.setItem('address', res.result.ad_info.address || '')
+        sessionStorage.setItem('ipAddress', res.result.ip || '')
       }
     }
 
@@ -873,14 +895,4 @@
   }
 }
 
-const mapStateToProps = () => {
-  return {}
-}
-
-const mapDispatchToProps = (dispatch) => {
-  return {
-    modifyMemberLevel: (memberLevel) => dispatch(modifyMemberLevel(memberLevel))
-  }
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(Login)
\ No newline at end of file
+export default Login
\ No newline at end of file
diff --git a/src/views/login/loginform.jsx b/src/views/login/loginform.jsx
index cd4e3be..899f6d0 100644
--- a/src/views/login/loginform.jsx
+++ b/src/views/login/loginform.jsx
@@ -299,7 +299,7 @@
       param.LText = md5(`${_phone}mingke${window.GLOB.appkey}${param.timestamp}`)
       param.secretkey = md5(`${param.LText}mingke${param.timestamp}`)
 
-      param.rduri = 'http://sso.mk9h.cn/webapi/dostars'
+      param.rduri = 'https://sso.mk9h.cn/webapi/dostars'
       param.userid = 'bh0bapabtd45epsgra79segbch6c1ibk'
       param.LoginUID = 'bh0bapabtd45epsgra79segbch6c1ibk'
   
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index 05c041b..0f24503 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -75,7 +75,8 @@
     customComponents: [],
     comloading: false,
     settingshow: true,
-    eyeopen: false
+    eyeopen: false,
+    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   UNSAFE_componentWillMount() {
@@ -106,6 +107,7 @@
 
   componentDidMount () {
     MKEmitter.addListener('delButtons', this.delButtons)
+    MKEmitter.addListener('modalStatus', this.modalStatus)
     MKEmitter.addListener('thawButtons', this.thawButtons)
     MKEmitter.addListener('copyButtons', this.copyButtons)
     MKEmitter.addListener('changePopview', this.initPopview)
@@ -138,6 +140,15 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
+        if (this.state.modalStatus) {
+          notification.warning({
+            top: 92,
+            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            duration: 5
+          })
+          return false
+        }
+
         let node = document.getElementById('save-modal-config')
         if (!node) {
           node = document.getElementById('save-pop-config')
@@ -162,12 +173,17 @@
       return
     }
     MKEmitter.removeListener('delButtons', this.delButtons)
+    MKEmitter.removeListener('modalStatus', this.modalStatus)
     MKEmitter.removeListener('thawButtons', this.thawButtons)
     MKEmitter.removeListener('copyButtons', this.copyButtons)
     MKEmitter.removeListener('changePopview', this.initPopview)
     MKEmitter.removeListener('triggerMenuSave', this.triggerMenuSave)
     MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle)
     MKEmitter.removeListener('updateCustomComponent', this.updateCustomComponent)
+  }
+
+  modalStatus = (val) => {
+    this.setState({modalStatus: val})
   }
 
   triggerMenuSave = () => {
@@ -436,9 +452,13 @@
           config.parentId = 'BillPrintTemp'
           config.MenuName = MenuName
           config.MenuNo = MenuNo
-          config.firstCount = config.firstCount || 15
+
+          if (config.everyPCount && !config.printPage) {
+            config.printPage = 'page'
+          }
+
+          config.printPage = config.printPage || 'auto'
           config.everyPCount = config.everyPCount || 15
-          config.lastCount = config.lastCount || ''
         }
 
         config.open_edition = result.open_edition || ''
@@ -593,7 +613,7 @@
     const { MenuType, copyButtons, thawButtons } = this.state
     let config = fromJS(this.state.config).toJS()
 
-    if (MenuType === 'billPrint' && (!config.firstCount || !config.everyPCount)) {
+    if (MenuType === 'billPrint' && config.printPage === 'page' && !config.everyPCount) {
       notification.warning({
         top: 92,
         message: '璇峰畬鍠勫熀鏈俊鎭紒',
@@ -771,6 +791,12 @@
         if (!res) return
 
         if (res.status) {
+          if (MenuType !== 'billPrint') { // 鍩烘湰淇℃伅鏀瑰彉鏃讹紝閫氱煡鑿滃崟鍒楄〃鏇存柊
+            let ori = this.state.oriConfig
+            if (config.MenuName !== ori.MenuName || config.MenuNo !== ori.MenuNo || config.parentId !== ori.parentId) {
+              localStorage.setItem('menuUpdate', new Date().getTime())
+            }
+          }
           config.open_edition = res.open_edition || ''
           this.setState({
             config,
@@ -906,7 +932,7 @@
         }
         MKEmitter.emit('completeSave')
       })
-    }, 300)
+    }, 300 + (+sessionStorage.getItem('mkDelay')))
   }
 
   getRoleFields = () => {
@@ -959,6 +985,7 @@
     let check = (components) => {
       components.forEach(item => {
         if (error) return
+        
         if (item.type === 'tabs') {
           item.subtabs.forEach(tab => {
             check(tab.components)
@@ -967,46 +994,14 @@
         } else if (item.type === 'group') {
           check(item.components)
           return
-        } else if (item.subtype === 'propcard' && item.subcards.length === 0) {
-          error = `缁勪欢銆�${item.name}銆嬩腑鍗$墖涓嶅彲涓虹┖锛乣
+        } else if (!item.errors || item.errors.length === 0) {
           return
         }
-        
-        if (['voucher'].includes(item.subtype)) return
-        if (['propcard', 'brafteditor', 'sandbox', 'stepform', 'tabform'].includes(item.subtype) && item.wrap.datatype === 'static') return
-        if (['balcony'].includes(item.type) && item.wrap.datatype === 'static') return
-  
-        if (item.setting) {
-          if (item.setting.interType === 'system' && item.setting.execute !== 'false' && !item.setting.dataresource) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆鏁版嵁婧愶紒`
-          } else if (item.setting.interType === 'system' && item.setting.execute === 'false' && item.scripts.length === 0) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆鏁版嵁婧愶紒`
-          } else if (!item.setting.primaryKey) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆涓婚敭锛乣
-          } else if (!item.setting.supModule && item.type !== 'balcony' && (!item.wrap || item.wrap.supType !== 'multi')) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆涓婄骇缁勪欢锛乣
-          }
-        }
-        if (item.type === 'bar' || item.type === 'line' || item.type === 'pie') {
-          if (!item.plot.Xaxis) {
-            error = `缁勪欢銆�${item.name}銆嬪浘琛ㄥ瓧娈靛皻鏈缃紒`
-          }
-        } else if (item.type === 'dashboard' && !item.plot.valueField) {
-          error = `缁勪欢銆�${item.name}銆嬫樉绀哄�煎皻鏈缃紒`
-        } else if (item.type === 'scatter' && (!item.plot.Xaxis || !item.plot.Yaxis || !item.plot.gender)) {
-          error = `缁勪欢銆�${item.name}銆嬪潗鏍囪酱灏氭湭璁剧疆锛乣
-        } else if (item.type === 'tree' && (!item.wrap.valueField || !item.wrap.labelField || !item.wrap.parentField)) {
-          error = `缁勪欢銆�${item.name}銆嬪熀鏈俊鎭皻鏈缃紒`
-        } else if (item.type === 'table' && item.wrap.doubleClick) {
-          let _actions = [...item.action]
-          item.cols.forEach(col => {
-            if (col.type !== 'action') return
-            _actions.push(...col.elements)
-          })
-          if (_actions.findIndex((m) => m.uuid === item.wrap.doubleClick) === -1) {
-            error = `缁勪欢銆�${item.name}銆嬬粦瀹氱殑鍙屽嚮鎸夐挳宸插垹闄わ紒`
-          }
-        }
+
+        item.errors.forEach(err => {
+          if (err.level !== 0 || error) return
+          error = `缁勪欢銆�${item.name}銆�${err.detail}`
+        })
       })
     }
 
@@ -1100,7 +1095,7 @@
   }
 
   render () {
-    const { activeKey, comloading, MenuType, popBtn, visible, dict, MenuId, config, settingshow, ParentId, MenuName, MenuNo, menuloading, customComponents, eyeopen } = this.state
+    const { activeKey, comloading, MenuType, popBtn, visible, dict, MenuId, config, settingshow, ParentId, menuloading, customComponents, eyeopen } = this.state
 
     return (
       <ConfigProvider locale={_locale}>
@@ -1121,8 +1116,8 @@
                       config={config}
                       MenuId={MenuId}
                       parentId={ParentId}
-                      MenuName={MenuName}
-                      MenuNo={MenuNo}
+                      MenuName={config.MenuName}
+                      MenuNo={config.MenuNo}
                       updateConfig={this.updateConfig}
                     /> : null}
                     {config && MenuType === 'home' ? <HomeForm
diff --git a/src/views/menudesign/index.scss b/src/views/menudesign/index.scss
index 208e23e..1c3cc47 100644
--- a/src/views/menudesign/index.scss
+++ b/src/views/menudesign/index.scss
@@ -26,7 +26,7 @@
     right: 0;
     top: 0;
     bottom: 0;
-    background: rgba(255, 255, 255, 0.8);
+    background: rgba(255, 255, 255, 0.9);
     border: 1px solid #1890ff;
     .center {
       position: absolute;
@@ -35,6 +35,18 @@
       top: 50%;
       color: #1890ff;
       transform: translate(-50%, -50%);
+      max-width: 70%;
+      .title {
+        text-align: center;
+      }
+    }
+    .error {
+      text-align: center;
+      color: red;
+      display: block;
+    }
+    .waring {
+      color: orange;
     }
   }
   >.menu-body {
diff --git a/src/views/menudesign/printmenuform/index.jsx b/src/views/menudesign/printmenuform/index.jsx
index 9b099fc..3831b6a 100644
--- a/src/views/menudesign/printmenuform/index.jsx
+++ b/src/views/menudesign/printmenuform/index.jsx
@@ -12,12 +12,12 @@
     updateConfig: PropTypes.func
   }
 
-  changeFirstCount = (val) => {
-    if (typeof(val) !== 'number') {
-      val = ''
-    }
-    this.props.updateConfig({...this.props.config, firstCount: val})
-  }
+  // changeFirstCount = (val) => {
+  //   if (typeof(val) !== 'number') {
+  //     val = ''
+  //   }
+  //   this.props.updateConfig({...this.props.config, firstCount: val})
+  // }
 
   changeCount = (val) => {
     if (typeof(val) !== 'number') {
@@ -40,12 +40,16 @@
     this.props.updateConfig({...this.props.config, printHeight: val})
   }
 
-  changeLastCount = (val) => {
-    if (typeof(val) !== 'number') {
-      val = ''
-    }
-    this.props.updateConfig({...this.props.config, lastCount: val})
+  onPrintPageChange = (val) => {
+    this.props.updateConfig({...this.props.config, printPage: val})
   }
+
+  // changeLastCount = (val) => {
+  //   if (typeof(val) !== 'number') {
+  //     val = ''
+  //   }
+  //   this.props.updateConfig({...this.props.config, lastCount: val})
+  // }
 
   pageSizeChange = (val) => {
     this.props.updateConfig({...this.props.config, pageSize: val})
@@ -185,6 +189,18 @@
             </Form.Item>
           </Col>
           <Col span={24}>
+            <Form.Item label="椤甸潰甯冨眬">
+              {getFieldDecorator('printPage', {
+                initialValue: config.printPage || 'auto'
+              })(
+                <Radio.Group onChange={(e) => {this.onPrintPageChange(e.target.value)}}>
+                  <Radio value="auto">鑷�傚簲</Radio>
+                  <Radio value="page">鍒嗛〉</Radio>
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
+          {/* <Col span={24}>
             <Form.Item label="棣栭〉鏁�(鏉�)">
               {getFieldDecorator('firstCount', {
                 initialValue: config.firstCount,
@@ -196,11 +212,11 @@
                 ]
               })(<InputNumber min={1} max={1000} precision={1} onChange={this.changeFirstCount}/>)}
             </Form.Item>
-          </Col>
-          <Col span={24}>
+          </Col> */}
+          {config.printPage === 'page' ? <Col span={24}>
             <Form.Item label="姣忛〉鏁�(鏉�)">
               {getFieldDecorator('everyPCount', {
-                initialValue: config.everyPCount,
+                initialValue: config.everyPCount || 15,
                 rules: [
                   {
                     required: true,
@@ -209,14 +225,14 @@
                 ]
               })(<InputNumber min={1} max={1000} precision={1} onChange={this.changeCount}/>)}
             </Form.Item>
-          </Col>
-          <Col span={24}>
+          </Col> : null}
+          {/* <Col span={24}>
             <Form.Item label="灏鹃〉鏁�(鏉�)">
               {getFieldDecorator('lastCount', {
                 initialValue: config.lastCount
               })(<InputNumber min={1} max={1000} precision={1} onChange={this.changeLastCount}/>)}
             </Form.Item>
-          </Col>
+          </Col> */}
           <Col span={24}>
             <Form.Item label={
               <Tooltip placement="topLeft" title="閽堝涓嶈鍒欑焊寮狅紝鍙嚜瀹氫箟璁剧疆鎵撳嵃楂樺害鍜屽搴︼紝娉細鍚屾椂璁剧疆鎵撳嵃瀹藉害鍜岄珮搴﹀悗鏂瑰彲鐢熸晥銆�">
diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index f2fdb32..f22b547 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -1,5 +1,4 @@
 import React, { Component } from 'react'
-import { connect } from 'react-redux'
 import { DndProvider } from 'react-dnd'
 import { withRouter } from 'react-router'
 import { is, fromJS } from 'immutable'
@@ -56,6 +55,8 @@
 window.GLOB.urlFields = []               // url鍙橀噺
 window.GLOB.customMenu = null            // 淇濆瓨鑿滃崟淇℃伅
 
+const memberLevel = Utils.getMemberLevel()
+
 class MobDesign extends Component {
   state = {
     localedict: sessionStorage.getItem('lang') !== 'en-US' ? antdZhCN : antdEnUS,
@@ -75,11 +76,12 @@
     comloading: false,
     adapters: [],
     viewType: 'menu',
-    eyeopen: false
+    eyeopen: false,
+    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   UNSAFE_componentWillMount() {
-    if (this.props.memberLevel < 30) return
+    if (memberLevel < 30) return
     try {
       let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
 
@@ -149,12 +151,13 @@
   }
 
   componentDidMount () {
-    if (this.props.memberLevel < 30) {
+    if (memberLevel < 30) {
       document.getElementById('mk-mob-design-view').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh; height: 100vh; background: #fff;">鏈簲鐢ㄦ病鏈塒C绔〉闈㈢殑缂栬緫鏉冮檺锛岃鑱旂郴绠$悊鍛橈紒</div>'
       return
     }
-    MKEmitter.addListener('changeEditMenu', this.changeEditMenu)
+    MKEmitter.addListener('modalStatus', this.modalStatus)
     MKEmitter.addListener('triggerMenuSave', this.submitConfig)
+    MKEmitter.addListener('changeEditMenu', this.changeEditMenu)
     MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle)
     MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent)
     setTimeout(() => {
@@ -183,6 +186,15 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
+        if (this.state.modalStatus) {
+          notification.warning({
+            top: 92,
+            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            duration: 5
+          })
+          return false
+        }
+
         let node = document.getElementById('save-modal-config')
         if (!node) {
           node = document.getElementById('save-config')
@@ -203,10 +215,15 @@
     this.setState = () => {
       return
     }
-    MKEmitter.removeListener('changeEditMenu', this.changeEditMenu)
+    MKEmitter.removeListener('modalStatus', this.modalStatus)
     MKEmitter.removeListener('triggerMenuSave', this.submitConfig)
+    MKEmitter.removeListener('changeEditMenu', this.changeEditMenu)
     MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle)
     MKEmitter.removeListener('updateCustomComponent', this.updateCustomComponent)
+  }
+
+  modalStatus = (val) => {
+    this.setState({modalStatus: val})
   }
 
   getSmStemp = () => {
@@ -994,12 +1011,14 @@
             }
           })
         } else if (item.type === 'form') {
-          m.children = item.subcards.map(m => {
-            return {
-              key: m.uuid,
-              title: m.setting.title
-            }
-          })
+          if (item.subtype !== 'simpleform') {
+            m.children = item.subcards.map(m => {
+              return {
+                key: m.uuid,
+                title: m.setting.title
+              }
+            })
+          }
         } else if (item.type === 'table' && item.subtype === 'normaltable') {
           item.action && item.action.forEach(btn => {
             if (btn.hidden === 'true') return
@@ -1326,6 +1345,19 @@
 
       if (adapters.includes('wxmini')) {
         config = this.getMiniStyle(config)
+
+        if (config.statusBarbgColor && !config.statusBarHexColor && /^rgba/ig.test(config.statusBarbgColor)) {
+          let hexify = (color) => {
+            let values = color.replace(/rgba?\(/, '').replace(/\)/, '').replace(/[\s+]/g, '').split(',')
+            let a = parseFloat(values[3] || 1)
+            let r = Math.floor(a * parseInt(values[0]) + (1 - a) * 255)
+            let g = Math.floor(a * parseInt(values[1]) + (1 - a) * 255)
+            let b = Math.floor(a * parseInt(values[2]) + (1 - a) * 255)
+            
+            return '#' + ('0' + r.toString(16)).slice(-2) + ('0' + g.toString(16)).slice(-2) + ('0' + b.toString(16)).slice(-2)
+          }
+          config.statusBarHexColor = hexify(config.statusBarbgColor)
+        }
       }
 
       let subMenus = this.getSubMenus()
@@ -1540,7 +1572,7 @@
         }
         MKEmitter.emit('completeSave')
       })
-    }, 300)
+    }, 300 + (+sessionStorage.getItem('mkDelay')))
   }
 
   getRoleFields = () => {
@@ -1615,42 +1647,15 @@
           if (!item.wrap.field) {
             error = `鎼滅储鏉′欢銆�${item.name}銆嬫湭璁剧疆鎼滅储瀛楁锛乣
           }
-        } else if (item.subtype === 'propcard' && item.subcards.length === 0) {
-          error = `缁勪欢銆�${item.name}銆嬩腑鍗$墖涓嶅彲涓虹┖锛乣
-          return
-        } else if (item.type === 'login' && !item.wrap.linkmenu && item.wrap.link !== 'menu') {
-          error = '鐧诲綍缁勪欢鏈缃叧鑱旇彍鍗曪紒'
-          return
         }
-        if (item.wrap && item.wrap.pagestyle === 'slide') {
+        if (item.wrap && item.wrap.pagestyle === 'slide' && item.pageable && item.setting.laypage !== 'false') {
           swipes.push(item.name)
         }
 
-        if (['voucher'].includes(item.subtype)) return
-        if (['propcard', 'brafteditor', 'sandbox', 'tabbar', 'stepform', 'tabform'].includes(item.subtype) && item.wrap.datatype === 'static') return
-        if (['balcony'].includes(item.type) && item.wrap.datatype === 'static') return
-        if (['menubar'].includes(item.type) && item.wrap.datatype !== 'dynamic') return
-
-        if (item.setting) {
-          if (item.setting.interType === 'system' && item.setting.execute !== 'false' && !item.setting.dataresource) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆鏁版嵁婧愶紒`
-          } else if (item.setting.interType === 'system' && item.setting.execute === 'false' && item.scripts.length === 0) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆鏁版嵁婧愶紒`
-          } else if (!item.setting.primaryKey) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆涓婚敭锛乣
-          } else if (!item.setting.supModule && !['navbar', 'balcony', 'menubar'].includes(item.type)) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆涓婄骇缁勪欢锛乣
-          }
-        }
-        if (item.type === 'bar' || item.type === 'line' || item.type === 'pie') {
-          if (!item.plot.Xaxis) {
-            error = `缁勪欢銆�${item.name}銆嬪浘琛ㄥ瓧娈靛皻鏈缃紒`
-          }
-        } else if (item.type === 'dashboard' && !item.plot.valueField) {
-          error = `缁勪欢銆�${item.name}銆嬫樉绀哄�煎皻鏈缃紒`
-        } else if (item.type === 'scatter' && (!item.plot.Xaxis || !item.plot.Yaxis || !item.plot.gender)) {
-          error = `缁勪欢銆�${item.name}銆嬪潗鏍囪酱灏氭湭璁剧疆锛乣
-        }
+        item.errors && item.errors.forEach(err => {
+          if (err.level !== 0 || error) return
+          error = `缁勪欢銆�${item.name}銆�${err.detail}`
+        })
       })
     }
 
@@ -1985,14 +1990,4 @@
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    memberLevel: state.memberLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default withRouter(connect(mapStateToProps, mapDispatchToProps)(MobDesign))
\ No newline at end of file
+export default withRouter(MobDesign)
\ No newline at end of file
diff --git a/src/views/mobdesign/index.scss b/src/views/mobdesign/index.scss
index c77ea28..273160d 100644
--- a/src/views/mobdesign/index.scss
+++ b/src/views/mobdesign/index.scss
@@ -17,7 +17,7 @@
     right: 0;
     top: 0;
     bottom: 0;
-    background: rgba(255, 255, 255, 0.8);
+    background: rgba(255, 255, 255, 0.9);
     border: 1px solid #1890ff;
     .center {
       position: absolute;
@@ -26,6 +26,18 @@
       top: 50%;
       color: #1890ff;
       transform: translate(-50%, -50%);
+      max-width: 70%;
+      .title {
+        text-align: center;
+      }
+    }
+    .error {
+      text-align: center;
+      color: red;
+      display: block;
+    }
+    .waring {
+      color: orange;
     }
   }
 
diff --git a/src/views/mobdesign/menuform/index.jsx b/src/views/mobdesign/menuform/index.jsx
index 38fb28c..13e2920 100644
--- a/src/views/mobdesign/menuform/index.jsx
+++ b/src/views/mobdesign/menuform/index.jsx
@@ -22,10 +22,14 @@
   state = {}
 
   // 涓�浜岀骇鑿滃崟鍒囨崲
-  selectChange = (key, value) => {
-    const { config } = this.props
+  selectChange = (key, value, hex) => {
+    let _config = {...this.props.config, [key]: value}
 
-    this.props.updateConfig({...config, [key]: value})
+    if (key === 'statusBarbgColor' && hex) {
+      _config.statusBarHexColor = hex
+    }
+
+    this.props.updateConfig(_config)
     // if (key === 'cacheUseful') {
     //   this.props.updateConfig({...config, cacheUseful: value})
     // } else if (key === 'timeUnit') {
@@ -203,10 +207,27 @@
             <Form.Item className="status-bar" label={
               <Tooltip placement="topLeft" title="鍦ㄦ槑绉戜簯APP鎴栧皬绋嬪簭涓紝鐘舵�佹爮鐨勮儗鏅壊銆�">
                 <QuestionCircleOutlined className="mk-form-tip" />
-                鐘舵�佹爮
+                鐘舵�佹爮鑳屾櫙
               </Tooltip>
             }>
-              <ColorSketch value={config.statusBarbgColor || '#ffffff'} onChange={(val) => {this.selectChange('statusBarbgColor', val)}} />
+              <ColorSketch value={config.statusBarbgColor || '#ffffff'} onChange={(val, hex) => {this.selectChange('statusBarbgColor', val, hex)}} />
+            </Form.Item>
+          </Col> : null}
+          {adapters.includes('wxmini') ? <Col span={24}>
+            <Form.Item className="status-bar-color" label={
+              <Tooltip placement="topLeft" title="鍦ㄤ娇鐢ㄥ皬绋嬪簭鏃讹紝鐘舵�佹爮鐨勫瓧浣撻鑹层��">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鐘舵�佹爮瀛椾綋
+              </Tooltip>
+            }>
+              {getFieldDecorator('statusBarColor', {
+                initialValue: config.statusBarColor || 'black'
+              })(
+                <Radio.Group onChange={(e) => {this.selectChange('statusBarColor', e.target.value)}}>
+                  <Radio value="black">榛戣壊</Radio>
+                  <Radio value="white">鐧借壊</Radio>
+                </Radio.Group>
+              )}
             </Form.Item>
           </Col> : null}
           {adapters.includes('app') ? <Col span={24}>
@@ -244,18 +265,24 @@
             </Form.Item>
           </Col> : null}
           {adapters.includes('weixin') || adapters.includes('wxmini') ? <Col span={24}>
-            <Form.Item label="鍒嗕韩">
+            <Form.Item label={
+              <Tooltip placement="topLeft" title="浣跨敤榛樿鏃惰鍦ㄥ瓙搴旂敤璁剧疆鍒嗕韩淇℃伅锛屼娇鐢╱rl鍙傛暟浼氫娇鐢ㄤ笂椤靛弬鏁版浛鎹㈢浉搴斿瓧娈碉紙@field@锛夈�傛敞锛氫娇鐢ㄨ嚜瀹氫箟鎴杣rl鍙傛暟鏃朵細鍒嗕韩褰撳墠椤甸潰銆�">
+                <QuestionCircleOutlined className="mk-form-tip" />
+                鍒嗕韩
+              </Tooltip>
+            }>
               {getFieldDecorator('share', {
                 initialValue: config.share || 'default'
               })(
-                <Radio.Group onChange={(e) => {this.selectChange('share', e.target.value)}}>
+                <Radio.Group className="mini-radio" onChange={(e) => {this.selectChange('share', e.target.value)}}>
                   <Radio value="default">榛樿</Radio>
                   <Radio value="custom">鑷畾涔�</Radio>
+                  <Radio value="url">url鍙傛暟</Radio>
                 </Radio.Group>
               )}
             </Form.Item>
           </Col> : null}
-          {config.share === 'custom' && (adapters.includes('weixin') || adapters.includes('wxmini')) ? <Col span={24}>
+          {['custom', 'url'].includes(config.share) && (adapters.includes('weixin') || adapters.includes('wxmini')) ? <Col span={24}>
             <Form.Item label="鍒嗕韩鏍囬">
               {getFieldDecorator('share_title', {
                 initialValue: config.share_title || '',
@@ -268,7 +295,7 @@
               })(<Input placeholder="" autoComplete="off" onChange={(e) => {this.selectChange('share_title', e.target.value)}}/>)}
             </Form.Item>
           </Col> : null}
-          {config.share === 'custom' && (adapters.includes('weixin') || adapters.includes('wxmini')) ? <Col span={24}>
+          {['custom', 'url'].includes(config.share) && (adapters.includes('weixin') || adapters.includes('wxmini')) ? <Col span={24}>
             <Form.Item label="鍒嗕韩鎻忚堪">
               {getFieldDecorator('share_des', {
                 initialValue: config.share_des || ''
@@ -284,6 +311,15 @@
               )}
             </Form.Item>
           </Col> : null}
+          {config.share === 'url' && (adapters.includes('weixin') || adapters.includes('wxmini')) ? <Col span={24}>
+            <Form.Item label="鍒嗕韩鍥剧墖">
+              {getFieldDecorator('share_url', {
+                initialValue: config.share_url || ''
+              })(
+                <Input placeholder="" autoComplete="off" onChange={(e) => {this.selectChange('share_url', e.target.value)}}/>
+              )}
+            </Form.Item>
+          </Col> : null}
           <Col span={24}>
             <Form.Item label="澶囨敞">
               {getFieldDecorator('Remark', {
diff --git a/src/views/mobdesign/menuform/index.scss b/src/views/mobdesign/menuform/index.scss
index 6bfb57a..9c0c867 100644
--- a/src/views/mobdesign/menuform/index.scss
+++ b/src/views/mobdesign/menuform/index.scss
@@ -22,4 +22,21 @@
       }
     }
   }
+  .status-bar-color, .status-bar {
+    .ant-form-item-label {
+      overflow: visible;
+      label {
+        left: -10px;
+      }
+    }
+  }
+  .mini-radio {
+    .ant-radio-wrapper {
+      margin-right: 5px;
+      .ant-radio + span {
+        padding-right: 3px;
+        padding-left: 3px;
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx
index c574d3e..b26500d 100644
--- a/src/views/pcdesign/index.jsx
+++ b/src/views/pcdesign/index.jsx
@@ -1,5 +1,4 @@
 import React, { Component } from 'react'
-import { connect } from 'react-redux'
 import { DndProvider } from 'react-dnd'
 import { withRouter } from 'react-router'
 import { is, fromJS } from 'immutable'
@@ -56,6 +55,8 @@
 window.GLOB.urlFields = []               // url鍙橀噺
 window.GLOB.customMenu = null            // 淇濆瓨鑿滃崟淇℃伅
 
+const memberLevel = Utils.getMemberLevel()
+
 class MenuDesign extends Component {
   state = {
     localedict: sessionStorage.getItem('lang') !== 'en-US' ? antdZhCN : antdEnUS,
@@ -77,11 +78,12 @@
     settingshow: sessionStorage.getItem('settingshow') !== 'false',
     controlshow: sessionStorage.getItem('controlshow') !== 'false',
     comloading: false,
-    eyeopen: false
+    eyeopen: false,
+    modalStatus: false       // 寮圭獥鏄惁寮�鍚紝鍒ゆ柇ctrl+s鏄惁鍙敤
   }
 
   UNSAFE_componentWillMount() {
-    if (this.props.memberLevel < 30) return
+    if (memberLevel < 30) return
     try {
       let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
 
@@ -125,11 +127,12 @@
   }
 
   componentDidMount () {
-    if (this.props.memberLevel < 30) {
+    if (memberLevel < 30) {
       document.getElementById('mk-pc-design-view').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh; height: 100vh; background: #fff;">鏈簲鐢ㄦ病鏈塒C绔〉闈㈢殑缂栬緫鏉冮檺锛岃鑱旂郴绠$悊鍛橈紒</div>'
       return
     }
     MKEmitter.addListener('delButtons', this.delButtons)
+    MKEmitter.addListener('modalStatus', this.modalStatus)
     MKEmitter.addListener('thawButtons', this.thawButtons)
     MKEmitter.addListener('copyButtons', this.copyButtons)
     MKEmitter.addListener('changePopview', this.initPopview)
@@ -163,6 +166,15 @@
       let _shortcut = `${preKey}+${keyCode}`
 
       if (_shortcut === 'ctrl+83') {
+        if (this.state.modalStatus) {
+          notification.warning({
+            top: 92,
+            message: '璇蜂繚瀛�' + this.state.modalStatus,
+            duration: 5
+          })
+          return false
+        }
+
         let node = document.getElementById('save-modal-config')
         if (!node) {
           node = document.getElementById('save-pop-config')
@@ -187,6 +199,7 @@
       return
     }
     MKEmitter.removeListener('delButtons', this.delButtons)
+    MKEmitter.removeListener('modalStatus', this.modalStatus)
     MKEmitter.removeListener('thawButtons', this.thawButtons)
     MKEmitter.removeListener('copyButtons', this.copyButtons)
     MKEmitter.removeListener('changePopview', this.initPopview)
@@ -194,6 +207,10 @@
     MKEmitter.removeListener('triggerMenuSave', this.triggerMenuSave)
     MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle)
     MKEmitter.removeListener('updateCustomComponent', this.updateCustomComponent)
+  }
+
+  modalStatus = (val) => {
+    this.setState({modalStatus: val})
   }
 
   triggerMenuSave = () => {
@@ -995,12 +1012,14 @@
             }
           })
         } else if (item.type === 'form') {
-          m.children = item.subcards.map(m => {
-            return {
-              key: m.uuid,
-              title: m.setting.title
-            }
-          })
+          if (item.subtype !== 'simpleform') {
+            m.children = item.subcards.map(m => {
+              return {
+                key: m.uuid,
+                title: m.setting.title
+              }
+            })
+          }
         } else if (item.type === 'table' && (item.subtype === 'normaltable' || item.subtype === 'editable')) {
           item.action && item.action.forEach(btn => {
             if (btn.hidden === 'true') return
@@ -1600,7 +1619,7 @@
         }
         MKEmitter.emit('completeSave')
       })
-    }, 300)
+    }, 300 + (+sessionStorage.getItem('mkDelay')))
   }
 
   getRoleFields = () => {
@@ -1662,49 +1681,14 @@
         } else if (item.type === 'group') {
           check(item.components)
           return
-        } else if (item.subtype === 'propcard' && item.subcards.length === 0) {
-          error = `缁勪欢銆�${item.name}銆嬩腑鍗$墖涓嶅彲涓虹┖锛乣
-          return
-        } else if (item.type === 'login' && !item.wrap.linkmenu && item.wrap.link !== 'menu') {
-          error = '鐧诲綍缁勪欢鏈缃叧鑱旇彍鍗曪紒'
+        } else if (!item.errors || item.errors.length === 0) {
           return
         }
         
-        if (['voucher'].includes(item.subtype)) return
-        if (['propcard', 'brafteditor', 'sandbox', 'stepform', 'tabform'].includes(item.subtype) && item.wrap.datatype === 'static') return
-        if (['balcony'].includes(item.type) && item.wrap.datatype === 'static') return
-        
-        if (item.setting) {
-          if (item.setting.interType === 'system' && item.setting.execute !== 'false' && !item.setting.dataresource) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆鏁版嵁婧愶紒`
-          } else if (item.setting.interType === 'system' && item.setting.execute === 'false' && item.scripts.length === 0) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆鏁版嵁婧愶紒`
-          } else if (!item.setting.primaryKey) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆涓婚敭锛乣
-          } else if (!item.setting.supModule && item.type !== 'balcony' && (!item.wrap || item.wrap.supType !== 'multi')) {
-            error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆涓婄骇缁勪欢锛乣
-          }
-        }
-        if (item.type === 'bar' || item.type === 'line' || item.type === 'pie') {
-          if (!item.plot.Xaxis) {
-            error = `缁勪欢銆�${item.name}銆嬪浘琛ㄥ瓧娈靛皻鏈缃紒`
-          }
-        } else if (item.type === 'dashboard' && !item.plot.valueField) {
-          error = `缁勪欢銆�${item.name}銆嬫樉绀哄�煎皻鏈缃紒`
-        } else if (item.type === 'scatter' && (!item.plot.Xaxis || !item.plot.Yaxis || !item.plot.gender)) {
-          error = `缁勪欢銆�${item.name}銆嬪潗鏍囪酱灏氭湭璁剧疆锛乣
-        } else if (item.type === 'tree' && (!item.wrap.valueField || !item.wrap.labelField || !item.wrap.parentField)) {
-          error = `缁勪欢銆�${item.name}銆嬪熀鏈俊鎭皻鏈缃紒`
-        } else if (item.type === 'table' && item.wrap.doubleClick) {
-          let _actions = [...item.action]
-          item.cols.forEach(col => {
-            if (col.type !== 'action') return
-            _actions.push(...col.elements)
-          })
-          if (_actions.findIndex((m) => m.uuid === item.wrap.doubleClick) === -1) {
-            error = `缁勪欢銆�${item.name}銆嬬粦瀹氱殑鍙屽嚮鎸夐挳宸插垹闄わ紒`
-          }
-        }
+        item.errors.forEach(err => {
+          if (err.level !== 0 || error) return
+          error = `缁勪欢銆�${item.name}銆�${err.detail}`
+        })
       })
     }
 
@@ -1980,14 +1964,4 @@
   }
 }
 
-const mapStateToProps = (state) => {
-  return {
-    memberLevel: state.memberLevel
-  }
-}
-
-const mapDispatchToProps = () => {
-  return {}
-}
-
-export default withRouter(connect(mapStateToProps, mapDispatchToProps)(MenuDesign))
\ No newline at end of file
+export default withRouter(MenuDesign)
\ No newline at end of file
diff --git a/src/views/pcdesign/index.scss b/src/views/pcdesign/index.scss
index fd27dd7..60a0d03 100644
--- a/src/views/pcdesign/index.scss
+++ b/src/views/pcdesign/index.scss
@@ -21,7 +21,7 @@
     right: 0;
     top: 0;
     bottom: 0;
-    background: rgba(255, 255, 255, 0.8);
+    background: rgba(255, 255, 255, 0.9);
     border: 1px solid #1890ff;
     .center {
       position: absolute;
@@ -30,6 +30,18 @@
       top: 50%;
       color: #1890ff;
       transform: translate(-50%, -50%);
+      max-width: 70%;
+      .title {
+        text-align: center;
+      }
+    }
+    .error {
+      text-align: center;
+      color: red;
+      display: block;
+    }
+    .waring {
+      color: orange;
     }
   }
 
diff --git a/src/views/printTemplate/mutilform/index.jsx b/src/views/printTemplate/mutilform/index.jsx
index 4824e2b..d9d7a0e 100644
--- a/src/views/printTemplate/mutilform/index.jsx
+++ b/src/views/printTemplate/mutilform/index.jsx
@@ -186,7 +186,12 @@
 
         fields.push(
           <Col span={24} key={index}>
-            <Form.Item label={item.label}>
+            <Form.Item label={
+              item.tooltip ? <Tooltip placement="bottomLeft" title={item.tooltip}>
+                <QuestionCircleOutlined className="mk-form-tip" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
               {getFieldDecorator(item.key, {
                 initialValue: item.initval,
                 rules: [
@@ -305,11 +310,11 @@
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
-        sm: { span: 8 }
+        sm: { span: 9 }
       },
       wrapperCol: {
         xs: { span: 24 },
-        sm: { span: 16 }
+        sm: { span: 15 }
       }
     }
     return (
diff --git a/src/views/printTemplate/option.js b/src/views/printTemplate/option.js
index 1671000..690ae65 100644
--- a/src/views/printTemplate/option.js
+++ b/src/views/printTemplate/option.js
@@ -425,6 +425,7 @@
       key: 'borderSize',
       label: '杈规瀹藉害',
       initval: item.borderSize,
+      tooltip: '娉細杈规瀹藉害鐨勮閲忓崟浣嶆槸姝e父鍊肩殑鍗佸垎涔嬩竴銆�',
       precision: 1,
       required: true
     },
@@ -555,6 +556,7 @@
       key: 'borderSize',
       label: '杈规瀹藉害',
       initval: item.borderSize,
+      tooltip: '娉細杈规瀹藉害鐨勮閲忓崟浣嶆槸姝e父鍊肩殑鍗佸垎涔嬩竴銆�',
       precision: 1,
       required: true
     },
@@ -717,6 +719,7 @@
       key: 'borderSize',
       label: '杈规瀹藉害',
       initval: item.borderSize,
+      tooltip: '娉細杈规瀹藉害鐨勮閲忓崟浣嶆槸姝e父鍊肩殑鍗佸垎涔嬩竴銆�',
       precision: 1,
       required: true
     },
@@ -863,6 +866,7 @@
       key: 'borderSize',
       label: '杈规瀹藉害',
       initval: item.borderSize,
+      tooltip: '娉細杈规瀹藉害鐨勮閲忓崟浣嶆槸姝e父鍊肩殑鍗佸垎涔嬩竴銆�',
       precision: 1,
       required: true
     },
diff --git a/src/views/printTemplate/print.js b/src/views/printTemplate/print.js
index de60e3d..d6c75cb 100644
--- a/src/views/printTemplate/print.js
+++ b/src/views/printTemplate/print.js
@@ -94,6 +94,7 @@
     // 缁樺埗杈规
     // context.rect(element.left + element.borderSize / 2, element.top + element.borderSize / 2, element.width - element.borderSize, element.height - element.borderSize)
     if (element.borderSize >= 1) {
+      context.beginPath()
       context.strokeStyle = element.borderColor
       context.lineWidth = element.borderSize
       context.rect(element.left, element.top, element.width, element.height)
diff --git a/src/views/rolemanage/index.jsx b/src/views/rolemanage/index.jsx
index 608da40..55b7111 100644
--- a/src/views/rolemanage/index.jsx
+++ b/src/views/rolemanage/index.jsx
@@ -27,7 +27,12 @@
     loading: false,
     menulist: [],
     columns: [
-      { title: '鑿滃崟鍚嶇О', dataIndex: 'MenuName', key: 'MenuName', align: 'center' },
+      { title: '鑿滃崟鍚嶇О', dataIndex: 'MenuName', key: 'MenuName', align: 'center', render: (text, record) => {
+        if (record.extra) {
+          return <span style={{color: '#1890ff'}}>{text}</span>
+        }
+        return text
+      } },
       {
         title: '鎿嶄綔',
         key: 'action',
@@ -151,10 +156,12 @@
             delete item.menus_rolelist
           }
 
-          if (!ub && app.userbind === item.MenuID) {
+          if (app.userbind === item.MenuID) {
+            item.extra = true
             ub = true
           }
-          if (!im && app.instantMessage === item.MenuID) {
+          if (app.instantMessage === item.MenuID) {
+            item.extra = true
             im = true
           }
           
@@ -162,10 +169,10 @@
         })
 
         if (!im) {
-          menus.push({nodes: '', type: 'none', MenuID: app.instantMessage, MenuName: '鍗虫椂閫氫俊'})
+          menus.push({nodes: '', type: 'none', extra: true, MenuID: app.instantMessage, MenuName: '鍗虫椂閫氫俊'})
         }
         if (!ub) {
-          menus.push({nodes: '', type: 'none', MenuID: app.userbind, MenuName: '鐢ㄦ埛缁戝畾'})
+          menus.push({nodes: '', type: 'none', extra: true, MenuID: app.userbind, MenuName: '鐢ㄦ埛缁戝畾'})
         }
 
         this.setState({
diff --git a/src/views/sso/index.jsx b/src/views/sso/index.jsx
index 8847f11..05b6b59 100644
--- a/src/views/sso/index.jsx
+++ b/src/views/sso/index.jsx
@@ -1,13 +1,11 @@
 import React, {Component} from 'react'
 import { Spin, notification } from 'antd'
-import { connect } from 'react-redux'
 import md5 from 'md5'
 import moment from 'moment'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js' 
 import { styles } from '@/store/options.js'
-import { modifyMemberLevel } from '@/store/action'
 import './index.scss'
 
 class SSOLogin extends Component {
@@ -39,6 +37,7 @@
         sessionStorage.setItem('role_id', res.role_id || '')
         sessionStorage.setItem('departmentcode', res.departmentcode || '')
         sessionStorage.setItem('organization', res.organization || '')
+        sessionStorage.setItem('mk_user_type', res.mk_user_type || '')
         sessionStorage.setItem('localRole_id', res.role_id || '')
         
         this.getMessage()
@@ -139,8 +138,8 @@
         let memberLevel = res.member_level
 
         if (typeof(memberLevel) === 'number' && memberLevel > 10 && parseInt(memberLevel / 10) * 10 === memberLevel) {
-          sessionStorage.setItem('Member_Level', md5('mksoft' + moment().format('YYYYMM') + memberLevel))
-          this.props.modifyMemberLevel(memberLevel)
+          sessionStorage.setItem('Member_Level', md5('mksoft' + window.GLOB.appkey + new Date().getFullYear() + new Date().getMonth() + memberLevel))
+          window.GLOB.memberLevel = memberLevel
         }
         this.props.history.replace('/main')
       } else {
@@ -165,14 +164,4 @@
   }
 }
 
-const mapStateToProps = () => {
-  return {}
-}
-
-const mapDispatchToProps = (dispatch) => {
-  return {
-    modifyMemberLevel: (memberLevel) => dispatch(modifyMemberLevel(memberLevel))
-  }
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(SSOLogin)
\ No newline at end of file
+export default SSOLogin
\ No newline at end of file
diff --git a/src/views/systemfunc/header/index.jsx b/src/views/systemfunc/header/index.jsx
new file mode 100644
index 0000000..1d793a5
--- /dev/null
+++ b/src/views/systemfunc/header/index.jsx
@@ -0,0 +1,47 @@
+import React, {Component} from 'react'
+
+import avatar from '@/assets/img/avatar.jpg'
+import MainLogo from '@/assets/img/main-logo.png'
+import './index.scss'
+
+class Header extends Component {
+  state = {
+    userName: sessionStorage.getItem('CloudUserName'),
+    avatar: sessionStorage.getItem('CloudAvatar') || avatar,
+  }
+
+  exitManage = () => {
+    window.close()
+  }
+
+  UNSAFE_componentWillMount () {
+
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  render () {
+    return (
+      <header className="sys-header-container ant-menu-dark">
+        <div className="header-logo"><img src={MainLogo} alt=""/></div>
+        <div className="title">HS</div>
+        <div className="close" onClick={() => window.close()}>鍏抽棴</div>
+        <div className="header-setting">
+          <img src={this.state.avatar} alt=""/>
+          <span>
+            <span className="username">{this.state.userName}</span>
+          </span>
+        </div>
+      </header>
+    )
+  }
+}
+
+export default Header
\ No newline at end of file
diff --git a/src/views/systemfunc/header/index.scss b/src/views/systemfunc/header/index.scss
new file mode 100644
index 0000000..5311911
--- /dev/null
+++ b/src/views/systemfunc/header/index.scss
@@ -0,0 +1,66 @@
+.sys-header-container {
+  position: fixed;
+  z-index: 22;
+  left: 0;
+  top: 0;
+  font-weight: bold!important;
+  width: 100%;
+  height: 48px;
+
+  .header-logo {
+    float: left;
+    width: 180px;
+    line-height: 48px;
+    text-align: center;
+    padding-left: 5px;
+    box-sizing: border-box;
+    opacity: 1;
+    transition: width 0.2s, opacity 0.15s;
+    img {
+      max-width: 100%;
+      max-height: 40px;
+    }
+  }
+
+  .title {
+    position: absolute;
+    font-size: 20px;
+    color: #ffffff;
+    left: 250px;
+    top: 10px;
+  }
+
+  .close {
+    position: absolute;
+    font-size: 16px;
+    color: #ffffff;
+    right: 90px;
+    top: 12px;
+    cursor: pointer;
+  }
+
+  .header-setting {
+    position: relative;
+    float: right;
+    line-height: 48px;
+    margin-right: 10px;
+    img {
+      width: 29px;
+      height: 29px;
+      border-radius: 30px;
+      margin-right: 7px;
+    }
+    span {
+      color: #ffffff;
+      font-size: 0.95rem;
+      .username {
+        display: inline-block;
+        height: 30px;
+        max-width: 95px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+    }
+  }
+}
diff --git a/src/views/systemfunc/index.jsx b/src/views/systemfunc/index.jsx
new file mode 100644
index 0000000..b52f35d
--- /dev/null
+++ b/src/views/systemfunc/index.jsx
@@ -0,0 +1,34 @@
+import React, {Component} from 'react'
+import { ConfigProvider } from 'antd'
+import enUS from 'antd/es/locale/en_US'
+import zhCN from 'antd/es/locale/zh_CN'
+
+import asyncComponent from '@/utils/asyncComponent'
+import Header from './header'
+import Sidemenu from './sidemenu'
+
+import './index.scss'
+
+const Tabview = asyncComponent(() => import('@/components/tabview'))
+const _locale = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
+
+class Design extends Component {
+  UNSAFE_componentWillMount() {
+    sessionStorage.setItem('isEditState', 'true')
+    window.GLOB.mkHS = true
+  }
+  
+  render () {
+    return (
+      <div className="mk-hs-view">
+        <ConfigProvider locale={_locale}>
+          <Sidemenu key="sidemenu"/>
+          <Tabview key="tabview"/>
+          <Header key="header"/>
+        </ConfigProvider>
+      </div>
+    )
+  }
+}
+
+export default Design
\ No newline at end of file
diff --git a/src/views/systemfunc/index.scss b/src/views/systemfunc/index.scss
new file mode 100644
index 0000000..8f5e059
--- /dev/null
+++ b/src/views/systemfunc/index.scss
@@ -0,0 +1,5 @@
+.mk-hs-view {
+  display: flex;
+  flex: auto;
+  min-height: 100%;
+}
diff --git a/src/views/design/sidemenu/config.jsx b/src/views/systemfunc/sidemenu/config.jsx
similarity index 100%
rename from src/views/design/sidemenu/config.jsx
rename to src/views/systemfunc/sidemenu/config.jsx
diff --git a/src/views/systemfunc/sidemenu/index.jsx b/src/views/systemfunc/sidemenu/index.jsx
new file mode 100644
index 0000000..152739e
--- /dev/null
+++ b/src/views/systemfunc/sidemenu/index.jsx
@@ -0,0 +1,89 @@
+import React, {Component} from 'react'
+import { Menu } from 'antd'
+import { FolderOutlined } from '@ant-design/icons'
+
+import { SySMenuList } from './config'
+import options from '@/store/options.js'
+import MKEmitter from '@/utils/events.js'
+import './index.scss'
+
+const { SubMenu } = Menu
+
+class Sidemenu extends Component {
+  state = {
+    subMenulist: [],         // 浜岀骇鑿滃崟
+    rootSubmenuKeys: [],
+    openKeys: []
+  }
+
+  changemenu(e, menu) {
+    e.preventDefault()
+
+    MKEmitter.emit('modifyTabs', menu, 'plus')
+  }
+
+  componentDidMount () {
+    let menulist = SySMenuList
+
+    if (window.GLOB.systemType === 'production') {
+      menulist.forEach(menu => {
+        menu.children = menu.children.filter(item => item.systems && item.systems.includes(window.GLOB.systemType))
+      })
+
+      menulist = menulist.filter(menu => menu.children.length > 0)
+    } else {
+      menulist.forEach(menu => {
+        menu.children = menu.children.filter(item => !item.systems || item.systems.includes(options.sysType))
+      })
+
+      menulist = menulist.filter(menu => menu.children.length > 0)
+    }
+
+    this.setState({
+      subMenulist: menulist,
+      rootSubmenuKeys: menulist.map(item => item.MenuID),
+      openKeys: [menulist[0].MenuID]
+    })
+  }
+
+  onOpenChange = openKeys => {
+    const latestOpenKey = openKeys.find(key => this.state.openKeys.indexOf(key) === -1)
+    if (this.state.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
+      this.setState({ openKeys })
+    } else {
+      this.setState({
+        openKeys: latestOpenKey ? [latestOpenKey] : []
+      })
+    }
+  }
+
+  render () {
+    return (
+      <aside className="mk-sys-side-menu ant-menu-dark mk-edit">
+        <Menu openKeys={this.state.openKeys} onOpenChange={this.onOpenChange} mode="inline" theme="dark">
+        {this.state.subMenulist && this.state.subMenulist.map((item, index) => {
+          return (
+            <SubMenu
+              key={item.MenuID}
+              title={
+                <span><FolderOutlined /> {item.MenuName}</span>
+              }
+            >
+              {item.children.map(cell => {
+                return (
+                  <Menu.Item key={cell.MenuID}>
+                    <a href={cell.src} id={cell.MenuID} onClick={(e) => this.changemenu(e, cell)}>{cell.MenuName}</a>
+                  </Menu.Item>
+                )
+              })}
+            </SubMenu>
+          )
+        })}
+      </Menu>
+        
+      </aside>
+    )
+  }
+}
+
+export default Sidemenu
\ No newline at end of file
diff --git a/src/views/systemfunc/sidemenu/index.scss b/src/views/systemfunc/sidemenu/index.scss
new file mode 100644
index 0000000..f614913
--- /dev/null
+++ b/src/views/systemfunc/sidemenu/index.scss
@@ -0,0 +1,123 @@
+.mk-sys-side-menu {
+  flex: 0 0 235px;
+  width: 235px;
+  padding: 48px 0 40px;
+  transition: width 0.2s, flex 0.2s;
+  .ant-menu-item {
+    padding-left: 0!important;
+    cursor: default;
+    a {
+      padding-left: 48px;
+    }
+    .editable-menu-item {
+      display: block;
+      padding-left: 48px;
+      cursor: pointer;
+    }
+  }
+  .ant-menu-sub.ant-menu-inline {
+    position: relative;
+  }
+  .ant-menu-sub.ant-menu-inline > .ant-menu-item {
+    height: 38px;
+    line-height: 38px;
+    margin: 0px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    a {
+      display: inline-block;
+    }
+    .edit-check {
+      top: -5px;
+    }
+  }
+  .ant-menu-sub.ant-menu-inline > .ant-menu-item.ant-menu-item-active {
+    background: #06b4f7;
+  }
+  .ant-menu-sub.ant-menu-inline > .ant-menu-item.ant-menu-item-selected {
+    background: #06b4f7;
+  }
+  .ant-menu-inline .ant-menu-item {
+    font-size: 1.1rem;
+  }
+  .ant-menu-dark.ant-menu-inline .ant-menu-submenu-title {
+    margin: 0;
+    height: 48px;
+    line-height: 48px;
+  }
+  .ant-menu-dark.ant-menu-inline .ant-menu-submenu-open .ant-menu-submenu-title {
+    background: #364150;
+  }
+  .edit-check {
+    font-size: 18px;
+    position: absolute;
+    cursor: pointer;
+    padding: 10px 15px;
+    margin-right: 0px;
+    right: 0px;
+    top: 0px;
+    :hover {
+      color: #ffffff;
+    }
+  }
+  
+  .edit-control + .ant-menu-submenu-arrow {
+    display: none;
+  }
+  .menu-add {
+    position: relative;
+    border: 1px dashed gray;
+    margin: 8px 0px;
+    height: 40px;
+    line-height: 40px;
+    width: 98%;
+    clear: both;
+    text-align: center;
+    cursor: pointer;
+    .anticon {
+      font-size: 20px;
+    }
+  }
+  .menu-btn {
+    .ant-btn {
+      padding: 0 10px;
+      margin-left: 5px;
+    }
+  }
+  .sup-menu {
+    position: relative;
+    z-index: 1;
+  }
+  .ant-menu-sub.ant-menu-inline .sub-menu {
+    position: absolute;
+    z-index: 1;
+    width: 48px;
+    left: 187px;
+  }
+}
+.mk-sys-side-menu.mk-edit { // 缂栬緫鏃舵帶鍒惰彍鍗曞簳鑹�
+  .ant-menu-sub.ant-menu-inline {
+    > .ant-menu-item.ant-menu-item-selected {
+      background: unset;
+    }
+    > .ant-menu-item.ant-menu-item-active {
+      background: unset;
+    }
+  }
+}
+.ant-menu-submenu.ant-menu-submenu-popup {
+  max-height: 80vh;
+  overflow-y: scroll;
+  &::-webkit-scrollbar {
+    display: none;
+  }
+}
+.ant-menu-vertical .ant-menu-item {
+  cursor: default;
+  height: 30px;
+  line-height: 30px;
+  a {
+    cursor: pointer;
+  }
+}

--
Gitblit v1.8.0